diff options
-rw-r--r-- | contrib/texinfo/info/doc.c | 6 | ||||
-rw-r--r-- | contrib/texinfo/info/funs.h | 4 | ||||
-rw-r--r-- | contrib/texinfo/info/infomap.c | 192 | ||||
-rw-r--r-- | contrib/texinfo/info/nodemenu.c | 124 | ||||
-rw-r--r-- | contrib/texinfo/info/session.c | 2900 | ||||
-rw-r--r-- | contrib/texinfo/info/signals.c | 126 | ||||
-rw-r--r-- | contrib/texinfo/info/terminal.c | 261 | ||||
-rw-r--r-- | contrib/texinfo/makeinfo/makeinfo.c | 6226 | ||||
-rw-r--r-- | contrib/texinfo/util/install-info.c | 271 |
9 files changed, 5286 insertions, 4824 deletions
diff --git a/contrib/texinfo/info/doc.c b/contrib/texinfo/info/doc.c index 9c3b615..6738396 100644 --- a/contrib/texinfo/info/doc.c +++ b/contrib/texinfo/info/doc.c @@ -5,7 +5,7 @@ Source files groveled to make this file include: ./session.c - ./echo_area.c + ./echo-area.c ./infodoc.c ./m-x.c ./indices.c @@ -52,7 +52,6 @@ FUNCTION_DOC function_doc_array[] = { { info_up_node, "up-node", "Select the `Up' node" }, { info_last_node, "last-node", "Select the last node in this file" }, { info_first_node, "first-node", "Select the first node in this file" }, - { info_history_node, "history-node", "Select the most recently selected node" }, { info_last_menu_item, "last-menu-item", "Select the last item in this node's menu" }, { info_menu_digit, "menu-digit", "Select this menu item" }, { info_menu_item, "menu-item", "Read a menu item and select its node" }, @@ -63,6 +62,7 @@ FUNCTION_DOC function_doc_array[] = { { info_man, "man", "Read a manpage reference and select it" }, { info_top_node, "top-node", "Select the node `Top' in this file" }, { info_dir_node, "dir-node", "Select the node `(dir)'" }, + { info_history_node, "history-node", "Select the most recently selected node" }, { info_kill_node, "kill-node", "Kill this node" }, { info_view_file, "view-file", "Read the name of a file and select it" }, { info_print_node, "print-node", "Pipe the contents of this node through INFO_PRINT_COMMAND" }, @@ -80,7 +80,7 @@ FUNCTION_DOC function_doc_array[] = { { info_add_digit_to_numeric_arg, "add-digit-to-numeric-arg", "Add this digit to the current numeric argument" }, { info_universal_argument, "universal-argument", "Start (or multiply by 4) the current numeric argument" }, { info_numeric_arg_digit_loop, "numeric-arg-digit-loop", "Internally used by \\[universal-argument]" }, -/* Commands found in "./echo_area.c". */ +/* Commands found in "./echo-area.c". */ { ea_forward, "echo-area-forward", "Move forward a character" }, { ea_backward, "echo-area-backward", "Move backward a character" }, { ea_beg_of_line, "echo-area-beg-of-line", "Move to the start of this line" }, diff --git a/contrib/texinfo/info/funs.h b/contrib/texinfo/info/funs.h index b91880c..32d80d5 100644 --- a/contrib/texinfo/info/funs.h +++ b/contrib/texinfo/info/funs.h @@ -29,7 +29,6 @@ extern void info_prev_node (); extern void info_up_node (); extern void info_last_node (); extern void info_first_node (); -extern void info_history_node (); extern void info_last_menu_item (); extern void info_menu_digit (); extern void info_menu_item (); @@ -40,6 +39,7 @@ extern void info_goto_node (); extern void info_man (); extern void info_top_node (); extern void info_dir_node (); +extern void info_history_node (); extern void info_kill_node (); extern void info_view_file (); extern void info_print_node (); @@ -58,7 +58,7 @@ extern void info_add_digit_to_numeric_arg (); extern void info_universal_argument (); extern void info_numeric_arg_digit_loop (); -/* Functions declared in "./echo_area.c". */ +/* Functions declared in "./echo-area.c". */ extern void ea_forward (); extern void ea_backward (); extern void ea_beg_of_line (); diff --git a/contrib/texinfo/info/infomap.c b/contrib/texinfo/info/infomap.c index e67712f..7591283 100644 --- a/contrib/texinfo/info/infomap.c +++ b/contrib/texinfo/info/infomap.c @@ -1,9 +1,7 @@ -/* infomap.c -- Keymaps for Info. */ +/* infomap.c -- Keymaps for Info. + $Id: infomap.c,v 1.7 1997/07/31 20:37:32 karl Exp $ -/* This file is part of GNU Info, a program for reading online documentation - stored in Info format. - - Copyright (C) 1993 Free Software Foundation, Inc. + Copyright (C) 1993, 97 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 @@ -21,16 +19,10 @@ Written by Brian Fox (bfox@ai.mit.edu). */ -#include "stdio.h" -#include "ctype.h" +#include "info.h" #include "infomap.h" #include "funs.h" -#include "info.h" - -static void add_function_key(char *, VFunction *, Keymap); - -extern char *term_ku, *term_kd, *term_kr, *term_kl; -extern char *term_kP, *term_kN, *term_kh, *term_kH; +#include "terminal.h" /* Return a new keymap which has all the uppercase letters mapped to run the function info_do_lowercase_version (). */ @@ -88,18 +80,65 @@ keymap_discard_keymap (map) for (i = 0; i < 256; i++) { switch (map[i].type) - { - case ISFUNC: - break; + { + case ISFUNC: + break; - case ISKMAP: - keymap_discard_keymap ((Keymap)map[i].function); - break; + case ISKMAP: + keymap_discard_keymap ((Keymap)map[i].function); + break; - } + } } } +/* Conditionally bind key sequence. */ +int +keymap_bind_keyseq (map, keyseq, keyentry) + Keymap map; + const unsigned char *keyseq; + KEYMAP_ENTRY *keyentry; +{ + register Keymap m = map; + register const unsigned char *s = keyseq; + register int c; + + if (s == NULL || *s == '\0') return 0; + + while ((c = *s++) != '\0') + { + switch (m[c].type) + { + case ISFUNC: + if (!(m[c].function == NULL || + (m != map && m[c].function == info_do_lowercase_version))) + return 0; + + if (*s != '\0') + { + m[c].type = ISKMAP; + m[c].function = (VFunction *)keymap_make_keymap (); + } + break; + + case ISKMAP: + if (*s == '\0') + return 0; + break; + } + if (*s != '\0') + { + m = (Keymap)m[c].function; + } + else + { + m[c] = *keyentry; + } + } + + return 1; +} + /* Initialize the standard info keymaps. */ Keymap info_keymap = (Keymap)NULL; @@ -123,15 +162,15 @@ initialize_info_keymaps () echo_area_keymap[ESC].function = (VFunction *)keymap_make_keymap (); echo_area_keymap[Control ('x')].type = ISKMAP; echo_area_keymap[Control ('x')].function = - (VFunction *)keymap_make_keymap (); + (VFunction *)keymap_make_keymap (); } /* Bind numeric arg functions for both echo area and info window maps. */ for (i = '0'; i < '9' + 1; i++) { ((Keymap) info_keymap[ESC].function)[i].function = - ((Keymap) echo_area_keymap[ESC].function)[i].function = - info_add_digit_to_numeric_arg; + ((Keymap) echo_area_keymap[ESC].function)[i].function = + info_add_digit_to_numeric_arg; } ((Keymap) info_keymap[ESC].function)['-'].function = ((Keymap) echo_area_keymap[ESC].function)['-'].function = @@ -188,6 +227,31 @@ initialize_info_keymaps () map['o'].function = info_next_window; map[DEL].function = ea_backward_kill_line; + /* Arrow key bindings for echo area keymaps. It seems that some + terminals do not match their termcap entries, so it's best to just + define everything with both of the usual prefixes. */ + map = echo_area_keymap; + keymap_bind_keyseq (map, term_ku, &map[Control ('p')]); /* up */ + keymap_bind_keyseq (map, "\033OA", &map[Control ('p')]); + keymap_bind_keyseq (map, "\033[A", &map[Control ('p')]); + keymap_bind_keyseq (map, term_kd, &map[Control ('n')]); /* down */ + keymap_bind_keyseq (map, "\033OB", &map[Control ('n')]); + keymap_bind_keyseq (map, "\033[B", &map[Control ('n')]); + keymap_bind_keyseq (map, term_kr, &map[Control ('f')]); /* right */ + keymap_bind_keyseq (map, "\033OC", &map[Control ('f')]); + keymap_bind_keyseq (map, "\033[C", &map[Control ('f')]); + keymap_bind_keyseq (map, term_kl, &map[Control ('b')]); /* left */ + keymap_bind_keyseq (map, "\033OD", &map[Control ('b')]); + keymap_bind_keyseq (map, "\033[D", &map[Control ('b')]); + + map = (Keymap)echo_area_keymap[ESC].function; + keymap_bind_keyseq (map, term_kl, &map['b']); /* left */ + keymap_bind_keyseq (map, "\033OA", &map['b']); + keymap_bind_keyseq (map, "\033[A", &map['b']); + keymap_bind_keyseq (map, term_kr, &map['f']); /* right */ + keymap_bind_keyseq (map, "\033OB", &map['f']); + keymap_bind_keyseq (map, "\033[B", &map['f']); + /* Bind commands for Info window keymaps. */ map = info_keymap; map[TAB].function = info_move_to_next_xref; @@ -271,58 +335,34 @@ initialize_info_keymaps () map['t'].function = info_tile_windows; map['w'].function = info_toggle_wrap; - /* Add functions for the arrow keys, PageUp, PageDown, Home, HomeDown */ - add_function_key(term_ku, info_prev_line, info_keymap); - add_function_key(term_kd, info_next_line, info_keymap); - add_function_key(term_kl, info_backward_char, info_keymap); - add_function_key(term_kr, info_forward_char, info_keymap); - add_function_key(term_kP, info_scroll_backward, info_keymap); - add_function_key(term_kN, info_scroll_forward, info_keymap); - add_function_key(term_kh, info_beginning_of_node, info_keymap); - add_function_key(term_kH, info_end_of_node, info_keymap); -} + /* Arrow key bindings for Info windows keymap. */ + map = info_keymap; + keymap_bind_keyseq (map, term_kN, &map[Control ('v')]); /* pagedown */ + keymap_bind_keyseq (map, term_ku, &map[Control ('p')]); /* up */ + keymap_bind_keyseq (map, "\033OA", &map[Control ('p')]); + keymap_bind_keyseq (map, "\033[A", &map[Control ('p')]); + keymap_bind_keyseq (map, term_kd, &map[Control ('n')]); /* down */ + keymap_bind_keyseq (map, "\033OB", &map[Control ('n')]); + keymap_bind_keyseq (map, "\033[B", &map[Control ('n')]); + keymap_bind_keyseq (map, term_kr, &map[Control ('f')]); /* right */ + keymap_bind_keyseq (map, "\033OC", &map[Control ('f')]); + keymap_bind_keyseq (map, "\033[C", &map[Control ('f')]); + keymap_bind_keyseq (map, term_kl, &map[Control ('b')]); /* left */ + keymap_bind_keyseq (map, "\033OD", &map[Control ('b')]); + keymap_bind_keyseq (map, "\033[D", &map[Control ('b')]); -static void add_function_key(char *esc_seq, VFunction *func, Keymap map) -{ - char *end_str, *p; - - if (!esc_seq) - return; /* don't add keys which don't exist */ - - end_str = esc_seq + strlen(esc_seq); - - for (p = esc_seq; p < end_str; p++) - { - if (isupper(*p)) - *p = tolower(*p); - switch (map[*p].type) - { - case ISKMAP: /* Go one level down. Also has the effect - that we're not overwriting a previous - binding if we're at the end of p */ - map = (Keymap)map[*p].function; - break; - case ISFUNC: /* two possibilities here: - 1. map[*p].function == NULL means we have - a virgin keymap to fill; - 2. else this entry is already taken */ - if (map[*p].function == NULL) - { - if (p == end_str - 1) - { - map[*p].function = func; - return; - } - map[*p].type = ISKMAP; - map[*p].function = (VFunction *)keymap_make_keymap(); - map = (Keymap)map[*p].function; - } else - return; - break; - default: /* can't happen */ - info_error("unknown keymap type (%d).", map[*p].type); - break; - } - } - return; + map = (Keymap)info_keymap[ESC].function; + keymap_bind_keyseq (map, term_kl, &map['b']); /* left */ + keymap_bind_keyseq (map, "\033OA", &map['b']); + keymap_bind_keyseq (map, "\033[A", &map['b']); + keymap_bind_keyseq (map, term_kr, &map['f']); /* right */ + keymap_bind_keyseq (map, "\033OB", &map['f']); + keymap_bind_keyseq (map, "\033[B", &map['f']); + keymap_bind_keyseq (map, term_kN, &map[Control ('v')]); /* pagedown */ + + /* The alternative to this definition of a `main map' key in the + `ESC map' section, is something like: + keymap_bind_keyseq (map, term_kP, &((KeyMap)map[ESC].function).map['v']); + */ + keymap_bind_keyseq (info_keymap/*sic*/, term_kP, &map['v']); /* pageup */ } diff --git a/contrib/texinfo/info/nodemenu.c b/contrib/texinfo/info/nodemenu.c index 7704170..2632657 100644 --- a/contrib/texinfo/info/nodemenu.c +++ b/contrib/texinfo/info/nodemenu.c @@ -1,9 +1,7 @@ -/* nodemenu.c -- Produce a menu of all visited nodes. */ +/* nodemenu.c -- Produce a menu of all visited nodes. + $Id: nodemenu.c,v 1.7 1997/07/24 21:30:30 karl Exp $ -/* This file is part of GNU Info, a program for reading online documentation - stored in Info format. - - Copyright (C) 1993 Free Software Foundation, Inc. + Copyright (C) 1993, 97 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 @@ -27,10 +25,10 @@ static char * nodemenu_format_info () { - return ("\n\ + return (_("\n\ * Menu:\n\ (File)Node Lines Size Containing File\n\ - ---------- ----- ---- ---------------"); + ---------- ----- ---- ---------------")); } /* Produce a formatted line of information about NODE. Here is what we want @@ -41,7 +39,7 @@ nodemenu_format_info () ---------- ----- ---- --------------- * (emacs)Buffers:: 48 2230 /usr/gnu/info/emacs/emacs-1 * (autoconf)Writing configure.in:: 123 58789 /usr/gnu/info/autoconf/autoconf-1 -* (dir)Top:: 40 589 /usr/gnu/info/dir +* (dir)Top:: 40 589 /usr/gnu/info/dir */ static char * format_node_info (node) @@ -58,7 +56,7 @@ format_node_info (node) { parent = filename_non_directory (node->parent); if (!parent) - parent = node->parent; + parent = node->parent; } else parent = (char *)NULL; @@ -72,15 +70,15 @@ format_node_info (node) char *file = (char *)NULL; if (parent) - file = parent; + file = parent; else - file = filename_non_directory (containing_file); + file = filename_non_directory (containing_file); if (!file) - file = containing_file; + file = containing_file; if (!*file) - file = "dir"; + file = "dir"; sprintf (line_buffer, "* (%s)%s::", file, node->nodename); } @@ -92,7 +90,7 @@ format_node_info (node) for (i = 0; i < node->nodelen; i++) if (node->contents[i] == '\n') - lines++; + lines++; sprintf (line_buffer + len, "%d", lines); } @@ -106,7 +104,7 @@ format_node_info (node) sprintf (line_buffer + len, node->filename); } - return (strdup (line_buffer)); + return xstrdup (line_buffer); } /* Little string comparison routine for qsort (). */ @@ -137,26 +135,26 @@ get_visited_nodes (filter_func) if (!info_windows) return ((NODE *)NULL); - for (iw_index = 0; info_win = info_windows[iw_index]; iw_index++) + for (iw_index = 0; (info_win = info_windows[iw_index]); iw_index++) { for (i = 0; i < info_win->nodes_index; i++) - { - node = info_win->nodes[i]; - - /* We skip mentioning "*Node Menu*" nodes. */ - if (internal_info_node_p (node) && - (strcmp (node->nodename, nodemenu_nodename) == 0)) - continue; - - if (node && (!filter_func || (*filter_func) (node))) - { - char *line; - - line = format_node_info (node); - add_pointer_to_array - (line, lines_index, lines, lines_slots, 20, char *); - } - } + { + node = info_win->nodes[i]; + + /* We skip mentioning "*Node Menu*" nodes. */ + if (internal_info_node_p (node) && + (strcmp (node->nodename, nodemenu_nodename) == 0)) + continue; + + if (node && (!filter_func || (*filter_func) (node))) + { + char *line; + + line = format_node_info (node); + add_pointer_to_array + (line, lines_index, lines, lines_slots, 20, char *); + } + } } /* Sort the array of information lines, if there are any. */ @@ -169,22 +167,22 @@ get_visited_nodes (filter_func) /* Delete duplicates. */ for (i = 0, newlen = 1; i < lines_index - 1; i++) - { - if (strcmp (lines[i], lines[i + 1]) == 0) - { - free (lines[i]); - lines[i] = (char *)NULL; - } - else - newlen++; - } + { + if (strcmp (lines[i], lines[i + 1]) == 0) + { + free (lines[i]); + lines[i] = (char *)NULL; + } + else + newlen++; + } /* We have free ()'d and marked all of the duplicate slots. - Copy the live slots rather than pruning the dead slots. */ + Copy the live slots rather than pruning the dead slots. */ temp = (char **)xmalloc ((1 + newlen) * sizeof (char *)); for (i = 0, j = 0; i < lines_index; i++) - if (lines[i]) - temp[j++] = lines[i]; + if (lines[i]) + temp[j++] = lines[i]; temp[j] = (char *)NULL; free (lines); @@ -196,8 +194,8 @@ get_visited_nodes (filter_func) printf_to_message_buffer ("%s", replace_in_documentation - ("Here is the menu of nodes you have recently visited.\n\ -Select one from this menu, or use `\\[history-node]' in another window.\n")); + (_("Here is the menu of nodes you have recently visited.\n\ +Select one from this menu, or use `\\[history-node]' in another window.\n"))); printf_to_message_buffer ("%s\n", nodemenu_format_info ()); @@ -216,7 +214,7 @@ Select one from this menu, or use `\\[history-node]' in another window.\n")); } DECLARE_INFO_COMMAND (list_visited_nodes, - "Make a window containing a menu of all of the currently visited nodes") + _("Make a window containing a menu of all of the currently visited nodes")) { WINDOW *new; NODE *node; @@ -229,14 +227,20 @@ DECLARE_INFO_COMMAND (list_visited_nodes, node = new->node; if (internal_info_node_p (node) && - (strcmp (node->nodename, nodemenu_nodename) == 0)) - break; + (strcmp (node->nodename, nodemenu_nodename) == 0)) + break; } /* If we couldn't find an existing window, try to use the next window in the chain. */ - if (!new && window->next) - new = window->next; + if (!new) + { + if (window->next) + new = window->next; + /* If there is more than one window, wrap around. */ + else if (window != windows) + new = windows; + } /* If we still don't have a window, make a new one to contain the list. */ if (!new) @@ -258,10 +262,16 @@ DECLARE_INFO_COMMAND (list_visited_nodes, node = get_visited_nodes ((Function *)NULL); name_internal_node (node, nodemenu_nodename); +#if 0 /* Even if this is an internal node, we don't want the window system to treat it specially. So we turn off the internalness of it here. */ + /* Why? We depend on internal_info_node_p returning true, so we must + not remove the flag. Otherwise, the *Node Menu* nodes themselves + appear in the node menu. --Andreas Schwab + <schwab@issan.informatik.uni-dortmund.de>. */ node->flags &= ~N_IsInternal; +#endif /* If this window is already showing a node menu, reuse the existing node slot. */ @@ -270,7 +280,7 @@ DECLARE_INFO_COMMAND (list_visited_nodes, #if defined (NOTDEF) if (internal_info_node_p (new->node) && - (strcmp (new->node->nodename, nodemenu_nodename) == 0)) + (strcmp (new->node->nodename, nodemenu_nodename) == 0)) remember_me = 0; #endif /* NOTDEF */ @@ -284,7 +294,7 @@ DECLARE_INFO_COMMAND (list_visited_nodes, } DECLARE_INFO_COMMAND (select_visited_node, - "Select a node which has been previously visited in a visible window") + _("Select a node which has been previously visited in a visible window")) { char *line; NODE *node; @@ -296,7 +306,7 @@ DECLARE_INFO_COMMAND (select_visited_node, free (node); line = - info_read_completing_in_echo_area (window, "Select visited node: ", menu); + info_read_completing_in_echo_area (window, _("Select visited node: "), menu); window = active_window; @@ -316,9 +326,9 @@ DECLARE_INFO_COMMAND (select_visited_node, entry = info_get_labeled_reference (line, menu); if (!entry) - info_error ("The reference disappeared! (%s).", line); + info_error (_("The reference disappeared! (%s)."), line); else - info_select_reference (window, entry); + info_select_reference (window, entry); } free (line); diff --git a/contrib/texinfo/info/session.c b/contrib/texinfo/info/session.c index 494c4a1..63a6ecd 100644 --- a/contrib/texinfo/info/session.c +++ b/contrib/texinfo/info/session.c @@ -1,9 +1,7 @@ -/* session.c -- The user windowing interface to Info. */ +/* session.c -- The user windowing interface to Info. + $Id: session.c,v 1.13 1998/02/22 22:38:30 karl Exp $ -/* This file is part of GNU Info, a program for reading online documentation - stored in Info format. - - Copyright (C) 1993, 96 Free Software Foundation, Inc. + Copyright (C) 1993, 96, 97 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 @@ -22,12 +20,7 @@ Written by Brian Fox (bfox@ai.mit.edu). */ #include "info.h" -#if defined (HAVE_SYS_FILE_H) -#include <sys/file.h> -#endif /* HAVE_SYS_FILE_H */ #include <sys/ioctl.h> -#include <fcntl.h> -#include <stdlib.h> #if defined (HAVE_SYS_TIME_H) # include <sys/time.h> @@ -42,28 +35,28 @@ static void info_clear_pending_input (), info_set_pending_input (); static void info_handle_pointer (); /* **************************************************************** */ -/* */ -/* Running an Info Session */ -/* */ +/* */ +/* Running an Info Session */ +/* */ /* **************************************************************** */ /* The place that we are reading input from. */ -static FILE *info_input_stream = (FILE *)NULL; +static FILE *info_input_stream = NULL; /* The last executed command. */ -VFunction *info_last_executed_command = (VFunction *)NULL; +VFunction *info_last_executed_command = NULL; /* Becomes non-zero when 'q' is typed to an Info window. */ int quit_info_immediately = 0; /* Array of structures describing for each window which nodes have been visited in that window. */ -INFO_WINDOW **info_windows = (INFO_WINDOW **)NULL; +INFO_WINDOW **info_windows = NULL; /* Where to add the next window, if we need to add one. */ static int info_windows_index = 0; -/* Number of slots allocated to INFO_WINDOWS. */ +/* Number of slots allocated to `info_windows'. */ static int info_windows_slots = 0; void remember_window_and_node (), forget_window_and_nodes (); @@ -88,52 +81,52 @@ begin_multiple_window_info_session (filename, nodenames) node = info_get_node (filename, nodenames[i]); if (!node) - break; + break; /* If this is the first node, initialize the info session. */ if (!window) - { - initialize_info_session (node); - window = active_window; - } + { + initialize_info_session (node, 1); + window = active_window; + } else - { - /* Find the largest window in WINDOWS, and make that be the active - one. Then split it and add our window and node to the list - of remembered windows and nodes. Then tile the windows. */ - register WINDOW *win, *largest = (WINDOW *)NULL; - int max_height = 0; - - for (win = windows; win; win = win->next) - if (win->height > max_height) - { - max_height = win->height; - largest = win; - } - - if (!largest) - { - display_update_display (windows); - info_error (CANT_FIND_WIND); - info_session (); - exit (0); - } - - active_window = largest; - window = window_make_window (node); - if (window) - { - window_tile_windows (TILE_INTERNALS); - remember_window_and_node (window, node); - } - else - { - display_update_display (windows); - info_error (WIN_TOO_SMALL); - info_session (); - exit (0); - } - } + { + /* Find the largest window in WINDOWS, and make that be the active + one. Then split it and add our window and node to the list + of remembered windows and nodes. Then tile the windows. */ + register WINDOW *win, *largest = (WINDOW *)NULL; + int max_height = 0; + + for (win = windows; win; win = win->next) + if (win->height > max_height) + { + max_height = win->height; + largest = win; + } + + if (!largest) + { + display_update_display (windows); + info_error (CANT_FIND_WIND); + info_session (); + exit (0); + } + + active_window = largest; + window = window_make_window (node); + if (window) + { + window_tile_windows (TILE_INTERNALS); + remember_window_and_node (window, node); + } + else + { + display_update_display (windows); + info_error (WIN_TOO_SMALL); + info_session (); + exit (0); + } + } } display_startup_message_and_start (); } @@ -146,7 +139,7 @@ begin_info_session_with_error (initial_node, format, arg) char *format; void *arg; { - initialize_info_session (initial_node); + initialize_info_session (initial_node, 1); info_error (format, arg, (void *)NULL); info_session (); } @@ -156,7 +149,7 @@ void begin_info_session (initial_node) NODE *initial_node; { - initialize_info_session (initial_node); + initialize_info_session (initial_node, 1); display_startup_message_and_start (); } @@ -166,7 +159,7 @@ display_startup_message_and_start () char *format; format = replace_in_documentation - ("Welcome to Info version %s. \"\\[get-help-window]\" for help, \"\\[menu-item]\" for menu item."); + (_("Welcome to Info version %s. \"\\[get-help-window]\" for help, \"\\[menu-item]\" for menu item.")); window_message_in_echo_area (format, version_string ()); info_session (); @@ -176,9 +169,8 @@ display_startup_message_and_start () void info_session () { - terminal_prep_terminal (); display_update_display (windows); - info_last_executed_command = (VFunction *)NULL; + info_last_executed_command = NULL; info_read_and_dispatch (); /* On program exit, leave the cursor at the bottom of the window, and restore the terminal I/O. */ @@ -203,19 +195,19 @@ info_read_and_dispatch () int lk; /* If we haven't just gone up or down a line, there is no - goal column for this window. */ + goal column for this window. */ if ((info_last_executed_command != info_next_line) && - (info_last_executed_command != info_prev_line)) - active_window->goal_column = -1; + (info_last_executed_command != info_prev_line)) + active_window->goal_column = -1; if (echo_area_is_active) - { - lk = echo_area_last_command_was_kill; - echo_area_prep_read (); - } + { + lk = echo_area_last_command_was_kill; + echo_area_prep_read (); + } if (!info_any_buffered_input_p ()) - display_update_display (windows); + display_update_display (windows); display_cursor_at_point (active_window); info_initialize_numeric_arg (); @@ -224,9 +216,9 @@ info_read_and_dispatch () key = info_get_input_char (); /* No errors yet. We just read a character, that's all. Only clear - the echo_area if it is not currently active. */ + the echo_area if it is not currently active. */ if (!echo_area_is_active) - window_clear_echo_area (); + window_clear_echo_area (); info_error_was_printed = 0; @@ -234,26 +226,26 @@ info_read_and_dispatch () info_dispatch_on_key (key, active_window->keymap); if (echo_area_is_active) - { - /* Echo area commands that do killing increment the value of - ECHO_AREA_LAST_COMMAND_WAS_KILL. Thus, if there is no - change in the value of this variable, the last command - executed was not a kill command. */ - if (lk == echo_area_last_command_was_kill) - echo_area_last_command_was_kill = 0; - - if (ea_last_executed_command == ea_newline || - info_aborted_echo_area) - { - ea_last_executed_command = (VFunction *)NULL; - done = 1; - } - - if (info_last_executed_command == info_quit) - quit_info_immediately = 1; - } + { + /* Echo area commands that do killing increment the value of + ECHO_AREA_LAST_COMMAND_WAS_KILL. Thus, if there is no + change in the value of this variable, the last command + executed was not a kill command. */ + if (lk == echo_area_last_command_was_kill) + echo_area_last_command_was_kill = 0; + + if (ea_last_executed_command == ea_newline || + info_aborted_echo_area) + { + ea_last_executed_command = (VFunction *)NULL; + done = 1; + } + + if (info_last_executed_command == info_quit) + quit_info_immediately = 1; + } else if (info_last_executed_command == info_quit) - done = 1; + done = 1; } } @@ -261,26 +253,30 @@ info_read_and_dispatch () extern void initialize_info_signal_handler (); /* Initialize the first info session by starting the terminal, window, - and display systems. */ + and display systems. If CLEAR_SCREEN is 0, don't clear the screen. */ void -initialize_info_session (node) +initialize_info_session (node, clear_screen) NODE *node; + int clear_screen; { - char *getenv (), *term_name; - - term_name = getenv ("TERM"); + char *term_name = getenv ("TERM"); terminal_initialize_terminal (term_name); if (terminal_is_dumb_p) { if (!term_name) - term_name = "dumb"; + term_name = "dumb"; info_error (TERM_TOO_DUMB, term_name); exit (1); } - terminal_clear_screen (); + if (clear_screen) + { + terminal_prep_terminal (); + terminal_clear_screen (); + } + initialize_info_keymaps (); window_initialize_windows (screenwidth, screenheight); initialize_info_signal_handler (); @@ -291,9 +287,13 @@ initialize_info_session (node) asynchronously deleted (e.g., user resizes window very small). */ window_deletion_notifier = forget_window_and_nodes; - /* If input has not been redirected yet, make it come from STDIN. */ + /* If input has not been redirected yet, make it come from unbuffered + standard input. */ if (!info_input_stream) - info_input_stream = stdin; + { + setbuf(stdin, NULL); + info_input_stream = stdin; + } info_windows_initialized_p = 1; } @@ -362,10 +362,8 @@ remember_window_and_node (window, node) WINDOW *window; NODE *node; { - INFO_WINDOW *info_win; - /* See if we already have this window in our list. */ - info_win = get_info_window_of_window (window); + INFO_WINDOW *info_win = get_info_window_of_window (window); /* If the window wasn't already on our list, then make a new entry. */ if (!info_win) @@ -380,21 +378,19 @@ remember_window_and_node (window, node) info_win->nodes_slots = 0; add_pointer_to_array (info_win, info_windows_index, info_windows, - info_windows_slots, 10, INFO_WINDOW *); + info_windows_slots, 10, INFO_WINDOW *); } /* If this node, the current pagetop, and the current point are the - same as the last saved node and pagetop, don't really add this to - the list of history nodes. */ - { - int ni = info_win->nodes_index - 1; - - if ((ni != -1) && - (info_win->nodes[ni]->contents == node->contents) && - (info_win->pagetops[ni] == window->pagetop) && - (info_win->points[ni] == window->point)) - return; - } + same as the current saved node and pagetop, don't really add this to + the list of history nodes. This may happen only at the very + beginning of the program, I'm not sure. --karl */ + if (info_win->nodes + && info_win->current >= 0 + && info_win->nodes[info_win->current]->contents == node->contents + && info_win->pagetops[info_win->current] == window->pagetop + && info_win->points[info_win->current] == window->point) + return; /* Remember this node, the currently displayed pagetop, and the current location of point in this window. Because we are updating pagetops @@ -402,22 +398,20 @@ remember_window_and_node (window, node) add_pointer_to_array macro here. */ if (info_win->nodes_index + 2 >= info_win->nodes_slots) { - info_win->nodes = (NODE **) - xrealloc (info_win->nodes, - (info_win->nodes_slots += 20) * sizeof (NODE *)); - - info_win->pagetops = (int *) - xrealloc (info_win->pagetops, info_win->nodes_slots * sizeof (int)); - - info_win->points = (long *) - xrealloc (info_win->points, info_win->nodes_slots * sizeof (long)); + info_win->nodes_slots += 20; + info_win->nodes = (NODE **) xrealloc (info_win->nodes, + info_win->nodes_slots * sizeof (NODE *)); + info_win->pagetops = (int *) xrealloc (info_win->pagetops, + info_win->nodes_slots * sizeof (int)); + info_win->points = (long *) xrealloc (info_win->points, + info_win->nodes_slots * sizeof (long)); } info_win->nodes[info_win->nodes_index] = node; info_win->pagetops[info_win->nodes_index] = window->pagetop; info_win->points[info_win->nodes_index] = window->point; info_win->current = info_win->nodes_index++; - info_win->nodes[info_win->nodes_index] = (NODE *)NULL; + info_win->nodes[info_win->nodes_index] = NULL; info_win->pagetops[info_win->nodes_index] = 0; info_win->points[info_win->nodes_index] = 0; } @@ -428,18 +422,17 @@ static void consistency_check_info_windows () { register int i; - INFO_WINDOW *info_win; for (i = 0; i < info_windows_index; i++) { WINDOW *win; for (win = windows; win; win = win->next) - if (win == info_windows[i]->window) - break; + if (win == info_windows[i]->window) + break; if (!win) - abort (); + abort (); } } #endif /* DEBUG_FORGET_WINDOW_AND_NODES */ @@ -460,27 +453,27 @@ forget_window_and_nodes (window) if (info_win) { while (i < info_windows_index) - { - info_windows[i] = info_windows[i + 1]; - i++; - } + { + info_windows[i] = info_windows[i + 1]; + i++; + } info_windows_index--; info_windows[info_windows_index] = (INFO_WINDOW *)NULL; if (info_win->nodes) - { - /* Free the node structures which held onto internal node contents - here. This doesn't free the contents; we have a garbage collector - which does that. */ - for (i = 0; info_win->nodes[i]; i++) - if (internal_info_node_p (info_win->nodes[i])) - free (info_win->nodes[i]); - free (info_win->nodes); - - maybe_free (info_win->pagetops); - maybe_free (info_win->points); - } + { + /* Free the node structures which held onto internal node contents + here. This doesn't free the contents; we have a garbage collector + which does that. */ + for (i = 0; info_win->nodes[i]; i++) + if (internal_info_node_p (info_win->nodes[i])) + free (info_win->nodes[i]); + free (info_win->nodes); + + maybe_free (info_win->pagetops); + maybe_free (info_win->points); + } free (info_win); } @@ -511,9 +504,9 @@ info_set_node_of_window (window, node) /* **************************************************************** */ -/* */ -/* Info Movement Commands */ -/* */ +/* */ +/* Info Movement Commands */ +/* */ /* **************************************************************** */ /* Change the pagetop of WINDOW to DESIRED_TOP, perhaps scrolling the screen @@ -557,8 +550,8 @@ set_window_pagetop (window, desired_top) amount = desired_top - old_pagetop; if ((amount >= window->height) || - (((window->height - amount) * 10) < window->height)) - return; + (((window->height - amount) * 10) < window->height)) + return; start = amount + window->first_row; end = window->height + window->first_row; @@ -572,8 +565,8 @@ set_window_pagetop (window, desired_top) amount = old_pagetop - desired_top; if ((amount >= window->height) || - (((window->height - amount) * 10) < window->height)) - return; + (((window->height - amount) * 10) < window->height)) + return; start = window->first_row; end = (window->first_row + window->height) - amount; @@ -621,7 +614,7 @@ move_to_new_line (old, new, window) int goal; if (new >= window->line_count || new < 0) - return; + return; goal = window_get_goal_column (window); window->goal_column = goal; @@ -633,7 +626,7 @@ move_to_new_line (old, new, window) } /* Move WINDOW's point down to the next line if possible. */ -DECLARE_INFO_COMMAND (info_next_line, "Move down to the next line") +DECLARE_INFO_COMMAND (info_next_line, _("Move down to the next line")) { int old_line, new_line; @@ -648,7 +641,7 @@ DECLARE_INFO_COMMAND (info_next_line, "Move down to the next line") } /* Move WINDOW's point up to the previous line if possible. */ -DECLARE_INFO_COMMAND (info_prev_line, "Move up to the previous line") +DECLARE_INFO_COMMAND (info_prev_line, _("Move up to the previous line")) { int old_line, new_line; @@ -663,7 +656,7 @@ DECLARE_INFO_COMMAND (info_prev_line, "Move up to the previous line") } /* Move WINDOW's point to the end of the true line. */ -DECLARE_INFO_COMMAND (info_end_of_line, "Move to the end of the line") +DECLARE_INFO_COMMAND (info_end_of_line, _("Move to the end of the line")) { register int point, len; register char *buffer; @@ -683,7 +676,7 @@ DECLARE_INFO_COMMAND (info_end_of_line, "Move to the end of the line") } /* Move WINDOW's point to the beginning of the true line. */ -DECLARE_INFO_COMMAND (info_beginning_of_line, "Move to the start of the line") +DECLARE_INFO_COMMAND (info_beginning_of_line, _("Move to the start of the line")) { register int point; register char *buffer; @@ -702,7 +695,7 @@ DECLARE_INFO_COMMAND (info_beginning_of_line, "Move to the start of the line") } /* Move point forward in the node. */ -DECLARE_INFO_COMMAND (info_forward_char, "Move forward a character") +DECLARE_INFO_COMMAND (info_forward_char, _("Move forward a character")) { if (count < 0) info_backward_char (window, -count, key); @@ -711,14 +704,14 @@ DECLARE_INFO_COMMAND (info_forward_char, "Move forward a character") window->point += count; if (window->point >= window->node->nodelen) - window->point = window->node->nodelen - 1; + window->point = window->node->nodelen - 1; info_show_point (window); } } /* Move point backward in the node. */ -DECLARE_INFO_COMMAND (info_backward_char, "Move backward a character") +DECLARE_INFO_COMMAND (info_backward_char, _("Move backward a character")) { if (count < 0) info_forward_char (window, -count, key); @@ -727,7 +720,7 @@ DECLARE_INFO_COMMAND (info_backward_char, "Move backward a character") window->point -= count; if (window->point < 0) - window->point = 0; + window->point = 0; info_show_point (window); } @@ -736,7 +729,7 @@ DECLARE_INFO_COMMAND (info_backward_char, "Move backward a character") #define alphabetic(c) (islower (c) || isupper (c) || isdigit (c)) /* Move forward a word in this node. */ -DECLARE_INFO_COMMAND (info_forward_word, "Move forward a word") +DECLARE_INFO_COMMAND (info_forward_word, _("Move forward a word")) { long point; char *buffer; @@ -755,37 +748,37 @@ DECLARE_INFO_COMMAND (info_forward_word, "Move forward a word") while (count) { if (point + 1 >= end) - return; + return; /* If we are not in a word, move forward until we are in one. - Then, move forward until we hit a non-alphabetic character. */ + Then, move forward until we hit a non-alphabetic character. */ c = buffer[point]; if (!alphabetic (c)) - { - while (++point < end) - { - c = buffer[point]; - if (alphabetic (c)) - break; - } - } + { + while (++point < end) + { + c = buffer[point]; + if (alphabetic (c)) + break; + } + } if (point >= end) return; while (++point < end) - { - c = buffer[point]; - if (!alphabetic (c)) - break; - } + { + c = buffer[point]; + if (!alphabetic (c)) + break; + } --count; } window->point = point; info_show_point (window); } -DECLARE_INFO_COMMAND (info_backward_word, "Move backward a word") +DECLARE_INFO_COMMAND (info_backward_word, _("Move backward a word")) { long point; char *buffer; @@ -803,31 +796,31 @@ DECLARE_INFO_COMMAND (info_backward_word, "Move backward a word") while (count) { if (point == 0) - break; + break; /* Like info_forward_word (), except that we look at the - characters just before point. */ + characters just before point. */ c = buffer[point - 1]; if (!alphabetic (c)) - { - while (--point) - { - c = buffer[point - 1]; - if (alphabetic (c)) - break; - } - } + { + while (--point) + { + c = buffer[point - 1]; + if (alphabetic (c)) + break; + } + } while (point) - { - c = buffer[point - 1]; - if (!alphabetic (c)) - break; - else - --point; - } + { + c = buffer[point - 1]; + if (!alphabetic (c)) + break; + else + --point; + } --count; } window->point = point; @@ -859,9 +852,9 @@ times_description (count) break; if (counter_names[i]) - sprintf (td_buffer, "%s%s", counter_names[i], count > 2 ? " times" : ""); + sprintf (td_buffer, "%s%s", counter_names[i], count > 2 ? _(" times") : ""); else - sprintf (td_buffer, "%d times", count); + sprintf (td_buffer, _("%d times"), count); return (td_buffer); } @@ -870,11 +863,11 @@ times_description (count) already at the bottom of a node. Possible values are defined in session.h. The meanings are: - IS_Continuous Try to get first menu item, or failing that, the - "Next:" pointer, or failing that, the "Up:" and - "Next:" of the up. - IS_NextOnly Try to get "Next:" menu item. - IS_PageOnly Simply give up at the bottom of a node. */ + IS_Continuous Try to get first menu item, or failing that, the + "Next:" pointer, or failing that, the "Up:" and + "Next:" of the up. + IS_NextOnly Try to get "Next:" menu item. + IS_PageOnly Simply give up at the bottom of a node. */ int info_scroll_behaviour = IS_Continuous; @@ -899,136 +892,136 @@ forward_move_node_structure (window, behaviour) case IS_NextOnly: info_next_label_of_node (window->node); if (!info_parsed_nodename && !info_parsed_filename) - info_error ("No \"Next\" pointer for this node."); + info_error (_("No \"Next\" pointer for this node.")); else - { - window_message_in_echo_area ("Following \"Next\" node..."); - info_handle_pointer ("Next", window); - } + { + window_message_in_echo_area (_("Following \"Next\" node...")); + info_handle_pointer (_("Next"), window); + } break; case IS_Continuous: { - /* First things first. If this node contains a menu, move down - into the menu. */ - { - REFERENCE **menu; - - menu = info_menu_of_node (window->node); - - if (menu) - { - info_free_references (menu); - window_message_in_echo_area ("Selecting first menu item..."); - info_menu_digit (window, 1, '1'); - return; - } - } - - /* Okay, this node does not contain a menu. If it contains a - "Next:" pointer, use that. */ - info_next_label_of_node (window->node); - if (info_label_was_found) - { - window_message_in_echo_area ("Selecting \"Next\" node..."); - info_handle_pointer ("Next", window); - return; - } - - /* Okay, there wasn't a "Next:" for this node. Move "Up:" until we - can move "Next:". If that isn't possible, complain that there - are no more nodes. */ - { - int up_counter, old_current; - INFO_WINDOW *info_win; - - /* Remember the current node and location. */ - info_win = get_info_window_of_window (window); - old_current = info_win->current; - - /* Back up through the "Up:" pointers until we have found a "Next:" - that isn't the same as the first menu item found in that node. */ - up_counter = 0; - while (!info_error_was_printed) - { - info_up_label_of_node (window->node); - if (info_label_was_found) - { - info_handle_pointer ("Up", window); - if (info_error_was_printed) - continue; - - up_counter++; - - info_next_label_of_node (window->node); - - /* If no "Next" pointer, keep backing up. */ - if (!info_label_was_found) - continue; - - /* If this node's first menu item is the same as this node's - Next pointer, keep backing up. */ - if (!info_parsed_filename) - { - REFERENCE **menu; - char *next_nodename; - - /* Remember the name of the Next node, since reading - the menu can overwrite the contents of the - info_parsed_xxx strings. */ - next_nodename = strdup (info_parsed_nodename); - - menu = info_menu_of_node (window->node); - if (menu && - (strcmp - (menu[0]->nodename, next_nodename) == 0)) - { - info_free_references (menu); - free (next_nodename); - continue; - } - else - { - /* Restore the world to where it was before - reading the menu contents. */ - info_free_references (menu); - free (next_nodename); - info_next_label_of_node (window->node); - } - } - - /* This node has a "Next" pointer, and it is not the - same as the first menu item found in this node. */ - window_message_in_echo_area - ("Moving \"Up\" %s, then \"Next\".", - times_description (up_counter)); - - info_handle_pointer ("Next", window); - return; - } - else - { - /* No more "Up" pointers. Print an error, and call it - quits. */ - register int i; - - for (i = 0; i < up_counter; i++) - { - info_win->nodes_index--; - free (info_win->nodes[info_win->nodes_index]); - info_win->nodes[info_win->nodes_index] = (NODE *)NULL; - } - info_win->current = old_current; - window->node = info_win->nodes[old_current]; - window->pagetop = info_win->pagetops[old_current]; - window->point = info_win->points[old_current]; - recalculate_line_starts (window); - window->flags |= W_UpdateWindow; - info_error ("No more nodes."); - } - } - } - break; + /* First things first. If this node contains a menu, move down + into the menu. */ + { + REFERENCE **menu; + + menu = info_menu_of_node (window->node); + + if (menu) + { + info_free_references (menu); + window_message_in_echo_area (_("Selecting first menu item...")); + info_menu_digit (window, 1, '1'); + return; + } + } + + /* Okay, this node does not contain a menu. If it contains a + "Next:" pointer, use that. */ + info_next_label_of_node (window->node); + if (info_label_was_found) + { + window_message_in_echo_area (_("Selecting \"Next\" node...")); + info_handle_pointer (_("Next"), window); + return; + } + + /* Okay, there wasn't a "Next:" for this node. Move "Up:" until we + can move "Next:". If that isn't possible, complain that there + are no more nodes. */ + { + int up_counter, old_current; + INFO_WINDOW *info_win; + + /* Remember the current node and location. */ + info_win = get_info_window_of_window (window); + old_current = info_win->current; + + /* Back up through the "Up:" pointers until we have found a "Next:" + that isn't the same as the first menu item found in that node. */ + up_counter = 0; + while (!info_error_was_printed) + { + info_up_label_of_node (window->node); + if (info_label_was_found) + { + info_handle_pointer (_("Up"), window); + if (info_error_was_printed) + continue; + + up_counter++; + + info_next_label_of_node (window->node); + + /* If no "Next" pointer, keep backing up. */ + if (!info_label_was_found) + continue; + + /* If this node's first menu item is the same as this node's + Next pointer, keep backing up. */ + if (!info_parsed_filename) + { + REFERENCE **menu; + char *next_nodename; + + /* Remember the name of the Next node, since reading + the menu can overwrite the contents of the + info_parsed_xxx strings. */ + next_nodename = xstrdup (info_parsed_nodename); + + menu = info_menu_of_node (window->node); + if (menu && + (strcmp + (menu[0]->nodename, next_nodename) == 0)) + { + info_free_references (menu); + free (next_nodename); + continue; + } + else + { + /* Restore the world to where it was before + reading the menu contents. */ + info_free_references (menu); + free (next_nodename); + info_next_label_of_node (window->node); + } + } + + /* This node has a "Next" pointer, and it is not the + same as the first menu item found in this node. */ + window_message_in_echo_area + ("Moving \"Up\" %s, then \"Next\".", + times_description (up_counter)); + + info_handle_pointer (_("Next"), window); + return; + } + else + { + /* No more "Up" pointers. Print an error, and call it + quits. */ + register int i; + + for (i = 0; i < up_counter; i++) + { + info_win->nodes_index--; + free (info_win->nodes[info_win->nodes_index]); + info_win->nodes[info_win->nodes_index] = (NODE *)NULL; + } + info_win->current = old_current; + window->node = info_win->nodes[old_current]; + window->pagetop = info_win->pagetops[old_current]; + window->point = info_win->points[old_current]; + recalculate_line_starts (window); + window->flags |= W_UpdateWindow; + info_error (_("No more nodes.")); + } + } + } + break; } } } @@ -1048,115 +1041,115 @@ backward_move_node_structure (window, behaviour) case IS_NextOnly: info_prev_label_of_node (window->node); if (!info_parsed_nodename && !info_parsed_filename) - info_error ("No \"Prev\" for this node."); + info_error (_("No \"Prev\" for this node.")); else - { - window_message_in_echo_area ("Moving \"Prev\" in this window."); - info_handle_pointer ("Prev", window); - } + { + window_message_in_echo_area (_("Moving \"Prev\" in this window.")); + info_handle_pointer (_("Prev"), window); + } break; case IS_Continuous: info_prev_label_of_node (window->node); if (!info_parsed_nodename && !info_parsed_filename) - { - info_up_label_of_node (window->node); - if (!info_parsed_nodename && !info_parsed_filename) - info_error ("No \"Prev\" or \"Up\" for this node."); - else - { - window_message_in_echo_area ("Moving \"Up\" in this window."); - info_handle_pointer ("Up", window); - } - } + { + info_up_label_of_node (window->node); + if (!info_parsed_nodename && !info_parsed_filename) + info_error (_("No \"Prev\" or \"Up\" for this node.")); + else + { + window_message_in_echo_area (_("Moving \"Up\" in this window.")); + info_handle_pointer (_("Up"), window); + } + } else - { - REFERENCE **menu; - int inhibit_menu_traversing = 0; - - /* Watch out! If this node's Prev is the same as the Up, then - move Up. Otherwise, we could move Prev, and then to the last - menu item in the Prev. This would cause the user to loop - through a subsection of the info file. */ - if (!info_parsed_filename && info_parsed_nodename) - { - char *pnode; - - pnode = strdup (info_parsed_nodename); - info_up_label_of_node (window->node); - - if (!info_parsed_filename && info_parsed_nodename && - strcmp (info_parsed_nodename, pnode) == 0) - { - /* The nodes are the same. Inhibit moving to the last - menu item. */ - free (pnode); - inhibit_menu_traversing = 1; - } - else - { - free (pnode); - info_prev_label_of_node (window->node); - } - } - - /* Move to the previous node. If this node now contains a menu, - and we have not inhibited movement to it, move to the node - corresponding to the last menu item. */ - window_message_in_echo_area ("Moving \"Prev\" in this window."); - info_handle_pointer ("Prev", window); - - if (!inhibit_menu_traversing) - { - while (!info_error_was_printed && - (menu = info_menu_of_node (window->node))) - { - info_free_references (menu); - window_message_in_echo_area - ("Moving to \"Prev\"'s last menu item."); - info_menu_digit (window, 1, '0'); - } - } - } + { + REFERENCE **menu; + int inhibit_menu_traversing = 0; + + /* Watch out! If this node's Prev is the same as the Up, then + move Up. Otherwise, we could move Prev, and then to the last + menu item in the Prev. This would cause the user to loop + through a subsection of the info file. */ + if (!info_parsed_filename && info_parsed_nodename) + { + char *pnode; + + pnode = xstrdup (info_parsed_nodename); + info_up_label_of_node (window->node); + + if (!info_parsed_filename && info_parsed_nodename && + strcmp (info_parsed_nodename, pnode) == 0) + { + /* The nodes are the same. Inhibit moving to the last + menu item. */ + free (pnode); + inhibit_menu_traversing = 1; + } + else + { + free (pnode); + info_prev_label_of_node (window->node); + } + } + + /* Move to the previous node. If this node now contains a menu, + and we have not inhibited movement to it, move to the node + corresponding to the last menu item. */ + window_message_in_echo_area (_("Moving \"Prev\" in this window.")); + info_handle_pointer (_("Prev"), window); + + if (!inhibit_menu_traversing) + { + while (!info_error_was_printed && + (menu = info_menu_of_node (window->node))) + { + info_free_references (menu); + window_message_in_echo_area + (_("Moving to \"Prev\"'s last menu item.")); + info_menu_digit (window, 1, '0'); + } + } + } break; } } /* Move continuously forward through the node structure of this info file. */ DECLARE_INFO_COMMAND (info_global_next_node, - "Move forwards or down through node structure") + _("Move forwards or down through node structure")) { if (count < 0) info_global_prev_node (window, -count, key); else { while (count && !info_error_was_printed) - { - forward_move_node_structure (window, IS_Continuous); - count--; - } + { + forward_move_node_structure (window, IS_Continuous); + count--; + } } } /* Move continuously backward through the node structure of this info file. */ DECLARE_INFO_COMMAND (info_global_prev_node, - "Move backwards or up through node structure") + _("Move backwards or up through node structure")) { if (count < 0) info_global_next_node (window, -count, key); else { while (count && !info_error_was_printed) - { - backward_move_node_structure (window, IS_Continuous); - count--; - } + { + backward_move_node_structure (window, IS_Continuous); + count--; + } } } /* Show the next screen of WINDOW's node. */ -DECLARE_INFO_COMMAND (info_scroll_forward, "Scroll forward in this window") +DECLARE_INFO_COMMAND (info_scroll_forward, _("Scroll forward in this window")) { if (count < 0) info_scroll_backward (window, -count, key); @@ -1165,43 +1158,43 @@ DECLARE_INFO_COMMAND (info_scroll_forward, "Scroll forward in this window") int desired_top; /* Without an explicit numeric argument, scroll the bottom two - lines to the top of this window, Or, if at bottom of window, - and the user wishes to scroll through nodes get the "Next" node - for this window. */ + lines to the top of this window, Or, if at bottom of window, + and the user wishes to scroll through nodes get the "Next" node + for this window. */ if (!info_explicit_arg && count == 1) - { - desired_top = window->pagetop + (window->height - 2); - - /* If there are no more lines to scroll here, error, or get - another node, depending on INFO_SCROLL_BEHAVIOUR. */ - if (desired_top > window->line_count) - { - int behaviour = info_scroll_behaviour; - - /* Here is a hack. If the key being used is not SPC, do the - PageOnly behaviour. */ - if (key != SPC && key != DEL) - behaviour = IS_PageOnly; - - forward_move_node_structure (window, behaviour); - return; - } - } + { + desired_top = window->pagetop + (window->height - 2); + + /* If there are no more lines to scroll here, error, or get + another node, depending on INFO_SCROLL_BEHAVIOUR. */ + if (desired_top > window->line_count) + { + int behaviour = info_scroll_behaviour; + + /* Here is a hack. If the key being used is not SPC, do the + PageOnly behaviour. */ + if (key != SPC && key != DEL) + behaviour = IS_PageOnly; + + forward_move_node_structure (window, behaviour); + return; + } + } else - desired_top = window->pagetop + count; + desired_top = window->pagetop + count; if (desired_top >= window->line_count) - desired_top = window->line_count - 2; + desired_top = window->line_count - 2; if (window->pagetop > desired_top) - return; + return; else - set_window_pagetop (window, desired_top); + set_window_pagetop (window, desired_top); } } /* Show the previous screen of WINDOW's node. */ -DECLARE_INFO_COMMAND (info_scroll_backward, "Scroll backward in this window") +DECLARE_INFO_COMMAND (info_scroll_backward, _("Scroll backward in this window")) { if (count < 0) info_scroll_forward (window, -count, key); @@ -1210,58 +1203,58 @@ DECLARE_INFO_COMMAND (info_scroll_backward, "Scroll backward in this window") int desired_top; /* Without an explicit numeric argument, scroll the top two lines - to the bottom of this window, or move to the previous, or Up'th - node. */ + to the bottom of this window, or move to the previous, or Up'th + node. */ if (!info_explicit_arg && count == 1) - { - desired_top = window->pagetop - (window->height - 2); - - if ((desired_top < 0) && (window->pagetop == 0)) - { - int behaviour = info_scroll_behaviour; - - /* Same kind of hack as in info_scroll_forward. If the key - used to invoke this command is not DEL, do only the PageOnly - behaviour. */ - if (key != DEL && key != SPC) - behaviour = IS_PageOnly; - - backward_move_node_structure (window, behaviour); - return; - } - } + { + desired_top = window->pagetop - (window->height - 2); + + if ((desired_top < 0) && (window->pagetop == 0)) + { + int behaviour = info_scroll_behaviour; + + /* Same kind of hack as in info_scroll_forward. If the key + used to invoke this command is not DEL, do only the PageOnly + behaviour. */ + if (key != DEL && key != SPC) + behaviour = IS_PageOnly; + + backward_move_node_structure (window, behaviour); + return; + } + } else - desired_top = window->pagetop - count; + desired_top = window->pagetop - count; if (desired_top < 0) - desired_top = 0; + desired_top = 0; set_window_pagetop (window, desired_top); } } /* Move to the beginning of the node. */ -DECLARE_INFO_COMMAND (info_beginning_of_node, "Move to the start of this node") +DECLARE_INFO_COMMAND (info_beginning_of_node, _("Move to the start of this node")) { window->pagetop = window->point = 0; window->flags |= W_UpdateWindow; } /* Move to the end of the node. */ -DECLARE_INFO_COMMAND (info_end_of_node, "Move to the end of this node") +DECLARE_INFO_COMMAND (info_end_of_node, _("Move to the end of this node")) { window->point = window->node->nodelen - 1; info_show_point (window); } /* **************************************************************** */ -/* */ -/* Commands for Manipulating Windows */ -/* */ +/* */ +/* Commands for Manipulating Windows */ +/* */ /* **************************************************************** */ /* Make the next window in the chain be the active window. */ -DECLARE_INFO_COMMAND (info_next_window, "Select the next window") +DECLARE_INFO_COMMAND (info_next_window, _("Select the next window")) { if (count < 0) { @@ -1279,20 +1272,20 @@ DECLARE_INFO_COMMAND (info_next_window, "Select the next window") while (count--) { if (window->next) - window = window->next; + window = window->next; else - { - if (window == the_echo_area || !echo_area_is_active) - window = windows; - else - window = the_echo_area; - } + { + if (window == the_echo_area || !echo_area_is_active) + window = windows; + else + window = the_echo_area; + } } if (active_window != window) { if (auto_footnotes_p) - info_get_or_remove_footnotes (window); + info_get_or_remove_footnotes (window); window->flags |= W_UpdateWindow; active_window = window; @@ -1300,7 +1293,7 @@ DECLARE_INFO_COMMAND (info_next_window, "Select the next window") } /* Make the previous window in the chain be the active window. */ -DECLARE_INFO_COMMAND (info_prev_window, "Select the previous window") +DECLARE_INFO_COMMAND (info_prev_window, _("Select the previous window")) { if (count < 0) { @@ -1319,30 +1312,30 @@ DECLARE_INFO_COMMAND (info_prev_window, "Select the previous window") while (count--) { /* If we are in the echo area, or if the echo area isn't active and we - are in the first window, find the last window in the chain. */ + are in the first window, find the last window in the chain. */ if (window == the_echo_area || - (window == windows && !echo_area_is_active)) - { - register WINDOW *win, *last; + (window == windows && !echo_area_is_active)) + { + register WINDOW *win, *last; - for (win = windows; win; win = win->next) - last = win; + for (win = windows; win; win = win->next) + last = win; - window = last; - } + window = last; + } else - { - if (window == windows) - window = the_echo_area; - else - window = window->prev; - } + { + if (window == windows) + window = the_echo_area; + else + window = window->prev; + } } if (active_window != window) { if (auto_footnotes_p) - info_get_or_remove_footnotes (window); + info_get_or_remove_footnotes (window); window->flags |= W_UpdateWindow; active_window = window; @@ -1351,7 +1344,7 @@ DECLARE_INFO_COMMAND (info_prev_window, "Select the previous window") /* Split WINDOW into two windows, both showing the same node. If we are automatically tiling windows, re-tile after the split. */ -DECLARE_INFO_COMMAND (info_split_window, "Split the current window") +DECLARE_INFO_COMMAND (info_split_window, _("Split the current window")) { WINDOW *split, *old_active; int pagetop; @@ -1375,54 +1368,54 @@ DECLARE_INFO_COMMAND (info_split_window, "Split the current window") #if defined (SPLIT_BEFORE_ACTIVE) /* Try to scroll the old window into its new postion. */ if (pagetop == window->pagetop) - { - int start, end, amount; - - start = split->first_row; - end = start + window->height; - amount = split->height + 1; - display_scroll_display (start, end, amount); - } + { + int start, end, amount; + + start = split->first_row; + end = start + window->height; + amount = split->height + 1; + display_scroll_display (start, end, amount); + } #else /* !SPLIT_BEFORE_ACTIVE */ /* Make sure point still appears in the active window. */ info_show_point (window); #endif /* !SPLIT_BEFORE_ACTIVE */ /* If the window just split was one internal to Info, try to display - something else in it. */ + something else in it. */ if (internal_info_node_p (split->node)) - { - register int i, j; - INFO_WINDOW *iw; - NODE *node = (NODE *)NULL; - char *filename; - - for (i = 0; iw = info_windows[i]; i++) - { - for (j = 0; j < iw->nodes_index; j++) - if (!internal_info_node_p (iw->nodes[j])) - { - if (iw->nodes[j]->parent) - filename = iw->nodes[j]->parent; - else - filename = iw->nodes[j]->filename; - - node = info_get_node (filename, iw->nodes[j]->nodename); - if (node) - { - window_set_node_of_window (split, node); - i = info_windows_index - 1; - break; - } - } - } - } + { + register int i, j; + INFO_WINDOW *iw; + NODE *node = (NODE *)NULL; + char *filename; + + for (i = 0; (iw = info_windows[i]); i++) + { + for (j = 0; j < iw->nodes_index; j++) + if (!internal_info_node_p (iw->nodes[j])) + { + if (iw->nodes[j]->parent) + filename = iw->nodes[j]->parent; + else + filename = iw->nodes[j]->filename; + + node = info_get_node (filename, iw->nodes[j]->nodename); + if (node) + { + window_set_node_of_window (split, node); + i = info_windows_index - 1; + break; + } + } + } + } split->pagetop = window->pagetop; if (auto_tiling_p) - window_tile_windows (DONT_TILE_INTERNALS); + window_tile_windows (DONT_TILE_INTERNALS); else - window_adjust_pagetop (split); + window_adjust_pagetop (split); remember_window_and_node (split, split->node); } @@ -1432,7 +1425,7 @@ DECLARE_INFO_COMMAND (info_split_window, "Split the current window") automatically displaying footnotes, show or remove the footnotes window. If we are automatically tiling windows, re-tile after the deletion. */ -DECLARE_INFO_COMMAND (info_delete_window, "Delete the current window") +DECLARE_INFO_COMMAND (info_delete_window, _("Delete the current window")) { if (!windows->next) { @@ -1440,17 +1433,17 @@ DECLARE_INFO_COMMAND (info_delete_window, "Delete the current window") } else if (window->flags & W_WindowIsPerm) { - info_error ("Cannot delete a permanent window"); + info_error (_("Cannot delete a permanent window")); } else { info_delete_window_internal (window); if (auto_footnotes_p) - info_get_or_remove_footnotes (active_window); + info_get_or_remove_footnotes (active_window); if (auto_tiling_p) - window_tile_windows (DONT_TILE_INTERNALS); + window_tile_windows (DONT_TILE_INTERNALS); } } @@ -1463,19 +1456,19 @@ info_delete_window_internal (window) if (windows->next && ((window->flags & W_WindowIsPerm) == 0)) { /* We not only delete the window from the display, we forget it from - our list of remembered windows. */ + our list of remembered windows. */ forget_window_and_nodes (window); window_delete_window (window); if (echo_area_is_active) - echo_area_inform_of_deleted_window (window); + echo_area_inform_of_deleted_window (window); } } /* Just keep WINDOW, deleting all others. */ -DECLARE_INFO_COMMAND (info_keep_one_window, "Delete all other windows") +DECLARE_INFO_COMMAND (info_keep_one_window, _("Delete all other windows")) { - int num_deleted; /* The number of windows we deleted. */ + int num_deleted; /* The number of windows we deleted. */ int pagetop, start, end; /* Remember a few things about this window. We may be able to speed up @@ -1491,14 +1484,14 @@ DECLARE_INFO_COMMAND (info_keep_one_window, "Delete all other windows") WINDOW *win; /* Find an eligible window and delete it. If no eligible windows - are found, we are done. A window is eligible for deletion if - is it not permanent, and it is not WINDOW. */ + are found, we are done. A window is eligible for deletion if + is it not permanent, and it is not WINDOW. */ for (win = windows; win; win = win->next) - if (win != window && ((win->flags & W_WindowIsPerm) == 0)) - break; + if (win != window && ((win->flags & W_WindowIsPerm) == 0)) + break; if (!win) - break; + break; info_delete_window_internal (win); num_deleted++; @@ -1519,7 +1512,7 @@ DECLARE_INFO_COMMAND (info_keep_one_window, "Delete all other windows") } /* Scroll the "other" window of WINDOW. */ -DECLARE_INFO_COMMAND (info_scroll_other_window, "Scroll the other window") +DECLARE_INFO_COMMAND (info_scroll_other_window, _("Scroll the other window")) { WINDOW *other; @@ -1539,7 +1532,7 @@ DECLARE_INFO_COMMAND (info_scroll_other_window, "Scroll the other window") } /* Change the size of WINDOW by AMOUNT. */ -DECLARE_INFO_COMMAND (info_grow_window, "Grow (or shrink) this window") +DECLARE_INFO_COMMAND (info_grow_window, _("Grow (or shrink) this window")) { window_change_window_height (window, count); } @@ -1550,22 +1543,22 @@ int auto_tiling_p = 0; /* Tile all of the visible windows. */ DECLARE_INFO_COMMAND (info_tile_windows, - "Divide the available screen space among the visible windows") + _("Divide the available screen space among the visible windows")) { window_tile_windows (TILE_INTERNALS); } /* Toggle the state of this window's wrapping of lines. */ DECLARE_INFO_COMMAND (info_toggle_wrap, - "Toggle the state of line wrapping in the current window") + _("Toggle the state of line wrapping in the current window")) { window_toggle_wrap (window); } /* **************************************************************** */ -/* */ -/* Info Node Commands */ -/* */ +/* */ +/* Info Node Commands */ +/* */ /* **************************************************************** */ /* Using WINDOW for various defaults, select the node referenced by ENTRY @@ -1587,12 +1580,12 @@ info_select_reference (window, entry) filename = window->node->filename; if (filename) - filename = strdup (filename); + filename = xstrdup (filename); if (entry->nodename) - nodename = strdup (entry->nodename); + nodename = xstrdup (entry->nodename); else - nodename = strdup ("Top"); + nodename = xstrdup ("Top"); node = info_get_node (filename, nodename); @@ -1602,25 +1595,25 @@ info_select_reference (window, entry) if (!node) { if (info_recent_file_error) - file_system_error = strdup (info_recent_file_error); + file_system_error = xstrdup (info_recent_file_error); if (entry->nodename && (strcmp (entry->nodename, entry->label) == 0)) - { - node = info_get_node (entry->label, "Top"); - if (!node && info_recent_file_error) - { - maybe_free (file_system_error); - file_system_error = strdup (info_recent_file_error); - } - } + { + node = info_get_node (entry->label, "Top"); + if (!node && info_recent_file_error) + { + maybe_free (file_system_error); + file_system_error = xstrdup (info_recent_file_error); + } + } } if (!node) { if (file_system_error) - info_error (file_system_error); + info_error (file_system_error); else - info_error (CANT_FIND_NODE, nodename); + info_error (CANT_FIND_NODE, nodename); } maybe_free (file_system_error); @@ -1670,42 +1663,42 @@ info_handle_pointer (label, window) filename = nodename = (char *)NULL; if (info_parsed_filename) - filename = strdup (info_parsed_filename); + filename = xstrdup (info_parsed_filename); else - { - if (window->node->parent) - filename = strdup (window->node->parent); - else if (window->node->filename) - filename = strdup (window->node->filename); - } + { + if (window->node->parent) + filename = xstrdup (window->node->parent); + else if (window->node->filename) + filename = xstrdup (window->node->filename); + } if (info_parsed_nodename) - nodename = strdup (info_parsed_nodename); + nodename = xstrdup (info_parsed_nodename); else - nodename = strdup ("Top"); + nodename = xstrdup ("Top"); node = info_get_node (filename, nodename); if (node) - { - INFO_WINDOW *info_win; - - info_win = get_info_window_of_window (window); - if (info_win) - { - info_win->pagetops[info_win->current] = window->pagetop; - info_win->points[info_win->current] = window->point; - } - set_remembered_pagetop_and_point (window); - info_set_node_of_window (window, node); - } + { + INFO_WINDOW *info_win; + + info_win = get_info_window_of_window (window); + if (info_win) + { + info_win->pagetops[info_win->current] = window->pagetop; + info_win->points[info_win->current] = window->point; + } + set_remembered_pagetop_and_point (window); + info_set_node_of_window (window, node); + } else - { - if (info_recent_file_error) - info_error (info_recent_file_error); - else - info_error (CANT_FILE_NODE, filename, nodename); - } + { + if (info_recent_file_error) + info_error (info_recent_file_error); + else + info_error (CANT_FILE_NODE, filename, nodename); + } free (filename); free (nodename); @@ -1718,30 +1711,30 @@ info_handle_pointer (label, window) /* Make WINDOW display the "Next:" node of the node currently being displayed. */ -DECLARE_INFO_COMMAND (info_next_node, "Select the `Next' node") +DECLARE_INFO_COMMAND (info_next_node, _("Select the `Next' node")) { info_next_label_of_node (window->node); - info_handle_pointer ("Next", window); + info_handle_pointer (_("Next"), window); } /* Make WINDOW display the "Prev:" node of the node currently being displayed. */ -DECLARE_INFO_COMMAND (info_prev_node, "Select the `Prev' node") +DECLARE_INFO_COMMAND (info_prev_node, _("Select the `Prev' node")) { info_prev_label_of_node (window->node); - info_handle_pointer ("Prev", window); + info_handle_pointer (_("Prev"), window); } /* Make WINDOW display the "Up:" node of the node currently being displayed. */ -DECLARE_INFO_COMMAND (info_up_node, "Select the `Up' node") +DECLARE_INFO_COMMAND (info_up_node, _("Select the `Up' node")) { info_up_label_of_node (window->node); - info_handle_pointer ("Up", window); + info_handle_pointer (_("Up"), window); } /* Make WINDOW display the last node of this info file. */ -DECLARE_INFO_COMMAND (info_last_node, "Select the last node in this file") +DECLARE_INFO_COMMAND (info_last_node, _("Select the last node in this file")) { register int i; FILE_BUFFER *fb = file_buffer_of_window (window); @@ -1754,7 +1747,7 @@ DECLARE_INFO_COMMAND (info_last_node, "Select the last node in this file") } if (!node) - info_error ("This window has no additional nodes"); + info_error (_("This window has no additional nodes")); else { set_remembered_pagetop_and_point (window); @@ -1763,7 +1756,7 @@ DECLARE_INFO_COMMAND (info_last_node, "Select the last node in this file") } /* Make WINDOW display the first node of this info file. */ -DECLARE_INFO_COMMAND (info_first_node, "Select the first node in this file") +DECLARE_INFO_COMMAND (info_first_node, _("Select the first node in this file")) { FILE_BUFFER *fb = file_buffer_of_window (window); NODE *node = (NODE *)NULL; @@ -1772,7 +1765,7 @@ DECLARE_INFO_COMMAND (info_first_node, "Select the first node in this file") node = info_get_node (fb->filename, fb->tags[0]->nodename); if (!node) - info_error ("This window has no additional nodes"); + info_error (_("This window has no additional nodes")); else { set_remembered_pagetop_and_point (window); @@ -1780,55 +1773,15 @@ DECLARE_INFO_COMMAND (info_first_node, "Select the first node in this file") } } -/* Make WINDOW display the previous node displayed in this window. */ -DECLARE_INFO_COMMAND (info_history_node, - "Select the most recently selected node") -{ - INFO_WINDOW *info_win; - - /* Find the INFO_WINDOW which contains WINDOW. */ - info_win = get_info_window_of_window (window); - - if (!info_win) - { - info_error ("Requested window is not present!"); - return; - } - - set_remembered_pagetop_and_point (window); - if (!info_win->current) - { - if (info_win->nodes_index > 1) - { - window_message_in_echo_area - ("Now wrapped around to beginning of history."); - info_win->current = info_win->nodes_index; - } - else - { - info_error ("No earlier nodes in this window."); - return; - } - } - - info_win->current--; - window_set_node_of_window (window, info_win->nodes[info_win->current]); - window->pagetop = info_win->pagetops[info_win->current]; - window->point = info_win->points[info_win->current]; - window->flags |= W_UpdateWindow; - if (auto_footnotes_p) - info_get_or_remove_footnotes (window); -} - /* Select the last menu item in WINDOW->node. */ DECLARE_INFO_COMMAND (info_last_menu_item, - "Select the last item in this node's menu") + _("Select the last item in this node's menu")) { info_menu_digit (window, 1, '0'); } /* Use KEY (a digit) to select the Nth menu item in WINDOW->node. */ -DECLARE_INFO_COMMAND (info_menu_digit, "Select this menu item") +DECLARE_INFO_COMMAND (info_menu_digit, _("Select this menu item")) { register int i, item; register REFERENCE *entry, **menu; @@ -1849,15 +1802,15 @@ DECLARE_INFO_COMMAND (info_menu_digit, "Select this menu item") for (i = 0; menu[i + 1]; i++); else { - for (i = 0; entry = menu[i]; i++) - if (i == item - 1) - break; + for (i = 0; (entry = menu[i]); i++) + if (i == item - 1) + break; } if (menu[i]) info_select_reference (window, menu[i]); else - info_error ("There aren't %d items in this menu.", item); + info_error (_("There aren't %d items in this menu."), item); info_free_references (menu); return; @@ -1884,9 +1837,9 @@ info_menu_or_ref_item (window, count, key, builder, ask_p) if (!menu) { if (builder == info_menu_of_node) - info_error (NO_MENU_NODE); + info_error (NO_MENU_NODE); else - info_error (NO_XREF_NODE); + info_error (NO_XREF_NODE); return; } @@ -1900,77 +1853,77 @@ info_menu_or_ref_item (window, count, key, builder, ask_p) if (point_line != -1) { - SEARCH_BINDING binding; - - binding.buffer = window->node->contents; - binding.start = window->line_starts[point_line] - binding.buffer; - if (window->line_starts[point_line + 1]) - binding.end = window->line_starts[point_line + 1] - binding.buffer; - else - binding.end = window->node->nodelen; - binding.flags = 0; - - if (builder == info_menu_of_node) - { - if (point_line) - { - binding.start--; - refs = info_menu_items (&binding); - } - } - else - { + SEARCH_BINDING binding; + + binding.buffer = window->node->contents; + binding.start = window->line_starts[point_line] - binding.buffer; + if (window->line_starts[point_line + 1]) + binding.end = window->line_starts[point_line + 1] - binding.buffer; + else + binding.end = window->node->nodelen; + binding.flags = 0; + + if (builder == info_menu_of_node) + { + if (point_line) + { + binding.start--; + refs = info_menu_items (&binding); + } + } + else + { #if defined (HANDLE_MAN_PAGES) - if (window->node->flags & N_IsManPage) - refs = manpage_xrefs_in_binding (window->node, &binding); - else + if (window->node->flags & N_IsManPage) + refs = manpage_xrefs_in_binding (window->node, &binding); + else #endif /* HANDLE_MAN_PAGES */ - refs = info_xrefs (&binding); - } - - if (refs) - { - if ((strcmp (refs[0]->label, "Menu") != 0) || - (builder == info_xrefs_of_node)) - { - int which = 0; - - /* Find the closest reference to point. */ - if (builder == info_xrefs_of_node) - { - int closest = -1; - - for (; refs[which]; which++) - { - if ((window->point >= refs[which]->start) && - (window->point <= refs[which]->end)) - { - closest = which; - break; - } - else if (window->point < refs[which]->start) - { - break; - } - } - if (closest == -1) - which--; - else - which = closest; - } - - defentry = (REFERENCE *)xmalloc (sizeof (REFERENCE)); - defentry->label = strdup (refs[which]->label); - defentry->filename = refs[which]->filename; - defentry->nodename = refs[which]->nodename; - - if (defentry->filename) - defentry->filename = strdup (defentry->filename); - if (defentry->nodename) - defentry->nodename = strdup (defentry->nodename); - } - info_free_references (refs); - } + refs = info_xrefs (&binding); + } + + if (refs) + { + if ((strcmp (refs[0]->label, "Menu") != 0) || + (builder == info_xrefs_of_node)) + { + int which = 0; + + /* Find the closest reference to point. */ + if (builder == info_xrefs_of_node) + { + int closest = -1; + + for (; refs[which]; which++) + { + if ((window->point >= refs[which]->start) && + (window->point <= refs[which]->end)) + { + closest = which; + break; + } + else if (window->point < refs[which]->start) + { + break; + } + } + if (closest == -1) + which--; + else + which = closest; + } + + defentry = (REFERENCE *)xmalloc (sizeof (REFERENCE)); + defentry->label = xstrdup (refs[which]->label); + defentry->filename = refs[which]->filename; + defentry->nodename = refs[which]->nodename; + + if (defentry->filename) + defentry->filename = xstrdup (defentry->filename); + if (defentry->nodename) + defentry->nodename = xstrdup (defentry->nodename); + } + info_free_references (refs); + } } } @@ -1981,24 +1934,24 @@ info_menu_or_ref_item (window, count, key, builder, ask_p) /* Build the prompt string. */ if (defentry) - prompt = (char *)xmalloc (20 + strlen (defentry->label)); + prompt = (char *)xmalloc (20 + strlen (defentry->label)); else - prompt = (char *)xmalloc (20); + prompt = (char *)xmalloc (20); if (builder == info_menu_of_node) - { - if (defentry) - sprintf (prompt, "Menu item (%s): ", defentry->label); - else - sprintf (prompt, "Menu item: "); - } + { + if (defentry) + sprintf (prompt, _("Menu item (%s): "), defentry->label); + else + sprintf (prompt, _("Menu item: ")); + } else - { - if (defentry) - sprintf (prompt, "Follow xref (%s): ", defentry->label); - else - sprintf (prompt, "Follow xref: "); - } + { + if (defentry) + sprintf (prompt, _("Follow xref (%s): "), defentry->label); + else + sprintf (prompt, _("Follow xref: ")); + } line = info_read_completing_in_echo_area (window, prompt, menu); free (prompt); @@ -2007,31 +1960,31 @@ info_menu_or_ref_item (window, count, key, builder, ask_p) /* User aborts, just quit. */ if (!line) - { - maybe_free (defentry); - info_free_references (menu); - info_abort_key (window, 0, 0); - return; - } + { + maybe_free (defentry); + info_free_references (menu); + info_abort_key (window, 0, 0); + return; + } /* If we had a default and the user accepted it, use that. */ if (!*line) - { - free (line); - if (defentry) - line = strdup (defentry->label); - else - line = (char *)NULL; - } + { + free (line); + if (defentry) + line = xstrdup (defentry->label); + else + line = (char *)NULL; + } } else { /* Not going to ask any questions. If we have a default entry, use - that, otherwise return. */ + that, otherwise return. */ if (!defentry) - return; + return; else - line = strdup (defentry->label); + line = xstrdup (defentry->label); } if (line) @@ -2040,42 +1993,42 @@ info_menu_or_ref_item (window, count, key, builder, ask_p) entry = info_get_labeled_reference (line, menu); if (!entry && defentry) - info_error ("The reference disappeared! (%s).", line); + info_error (_("The reference disappeared! (%s)."), line); else - { - NODE *orig; - - orig = window->node; - info_select_reference (window, entry); - if ((builder == info_xrefs_of_node) && (window->node != orig)) - { - long offset; - long start; - - if (window->line_count > 0) - start = window->line_starts[1] - window->node->contents; - else - start = 0; - - offset = - info_target_search_node (window->node, entry->label, start); - - if (offset != -1) - { - window->point = offset; - window_adjust_pagetop (window); - } - } - } + { + NODE *orig; + + orig = window->node; + info_select_reference (window, entry); + if ((builder == info_xrefs_of_node) && (window->node != orig)) + { + long offset; + long start; + + if (window->line_count > 0) + start = window->line_starts[1] - window->node->contents; + else + start = 0; + + offset = + info_target_search_node (window->node, entry->label, start); + + if (offset != -1) + { + window->point = offset; + window_adjust_pagetop (window); + } + } + } free (line); if (defentry) - { - free (defentry->label); - maybe_free (defentry->filename); - maybe_free (defentry->nodename); - free (defentry); - } + { + free (defentry->label); + maybe_free (defentry->filename); + maybe_free (defentry->nodename); + free (defentry); + } } info_free_references (menu); @@ -2086,7 +2039,7 @@ info_menu_or_ref_item (window, count, key, builder, ask_p) /* Read a line (with completion) which is the name of a menu item, and select that item. */ -DECLARE_INFO_COMMAND (info_menu_item, "Read a menu item and select its node") +DECLARE_INFO_COMMAND (info_menu_item, _("Read a menu item and select its node")) { info_menu_or_ref_item (window, count, key, info_menu_of_node, 1); } @@ -2094,13 +2047,13 @@ DECLARE_INFO_COMMAND (info_menu_item, "Read a menu item and select its node") /* Read a line (with completion) which is the name of a reference to follow, and select the node. */ DECLARE_INFO_COMMAND - (info_xref_item, "Read a footnote or cross reference and select its node") + (info_xref_item, _("Read a footnote or cross reference and select its node")) { info_menu_or_ref_item (window, count, key, info_xrefs_of_node, 1); } /* Position the cursor at the start of this node's menu. */ -DECLARE_INFO_COMMAND (info_find_menu, "Move to the start of this node's menu") +DECLARE_INFO_COMMAND (info_find_menu, _("Move to the start of this node's menu")) { SEARCH_BINDING binding; long position; @@ -2124,7 +2077,7 @@ DECLARE_INFO_COMMAND (info_find_menu, "Move to the start of this node's menu") /* Visit as many menu items as is possible, each in a separate window. */ DECLARE_INFO_COMMAND (info_visit_menu, - "Visit as many menu items at once as possible") + _("Visit as many menu items at once as possible")) { register int i; REFERENCE *entry, **menu; @@ -2142,20 +2095,19 @@ DECLARE_INFO_COMMAND (info_visit_menu, window_tile_windows (TILE_INTERNALS); if (!new) - info_error (WIN_TOO_SMALL); + info_error (WIN_TOO_SMALL); else - { - active_window = new; - info_select_reference (new, entry); - } + { + active_window = new; + info_select_reference (new, entry); + } } } /* Read a line of input which is a node name, and go to that node. */ -DECLARE_INFO_COMMAND (info_goto_node, "Read a node name and select it") +DECLARE_INFO_COMMAND (info_goto_node, _("Read a node name and select it")) { char *line; - NODE *node; #define GOTO_COMPLETES #if defined (GOTO_COMPLETES) @@ -2171,54 +2123,54 @@ DECLARE_INFO_COMMAND (info_goto_node, "Read a node name and select it") for (fbi = 0; info_loaded_files && info_loaded_files[fbi]; fbi++) { - FILE_BUFFER *fb; - REFERENCE *entry; - int this_is_the_current_fb; - - fb = info_loaded_files[fbi]; - this_is_the_current_fb = (current == fb); - - entry = (REFERENCE *)xmalloc (sizeof (REFERENCE)); - entry->filename = entry->nodename = (char *)NULL; - entry->label = (char *)xmalloc (4 + strlen (fb->filename)); - sprintf (entry->label, "(%s)*", fb->filename); - - add_pointer_to_array - (entry, items_index, items, items_slots, 10, REFERENCE *); - - if (fb->tags) - { - for (i = 0; fb->tags[i]; i++) - { - entry = (REFERENCE *)xmalloc (sizeof (REFERENCE)); - entry->filename = entry->nodename = (char *)NULL; - entry->label = (char *) xmalloc - (4 + strlen (fb->filename) + strlen (fb->tags[i]->nodename)); - sprintf (entry->label, "(%s)%s", - fb->filename, fb->tags[i]->nodename); - - add_pointer_to_array - (entry, items_index, items, items_slots, 100, REFERENCE *); - } - - if (this_is_the_current_fb) - { - for (i = 0; fb->tags[i]; i++) - { - entry = (REFERENCE *)xmalloc (sizeof (REFERENCE)); - entry->filename = entry->nodename = (char *)NULL; - entry->label = strdup (fb->tags[i]->nodename); - add_pointer_to_array (entry, items_index, items, - items_slots, 100, REFERENCE *); - } - } - } + FILE_BUFFER *fb; + REFERENCE *entry; + int this_is_the_current_fb; + + fb = info_loaded_files[fbi]; + this_is_the_current_fb = (current == fb); + + entry = (REFERENCE *)xmalloc (sizeof (REFERENCE)); + entry->filename = entry->nodename = (char *)NULL; + entry->label = (char *)xmalloc (4 + strlen (fb->filename)); + sprintf (entry->label, "(%s)*", fb->filename); + + add_pointer_to_array + (entry, items_index, items, items_slots, 10, REFERENCE *); + + if (fb->tags) + { + for (i = 0; fb->tags[i]; i++) + { + entry = (REFERENCE *)xmalloc (sizeof (REFERENCE)); + entry->filename = entry->nodename = (char *)NULL; + entry->label = (char *) xmalloc + (4 + strlen (fb->filename) + strlen (fb->tags[i]->nodename)); + sprintf (entry->label, "(%s)%s", + fb->filename, fb->tags[i]->nodename); + + add_pointer_to_array + (entry, items_index, items, items_slots, 100, REFERENCE *); + } + + if (this_is_the_current_fb) + { + for (i = 0; fb->tags[i]; i++) + { + entry = (REFERENCE *)xmalloc (sizeof (REFERENCE)); + entry->filename = entry->nodename = (char *)NULL; + entry->label = xstrdup (fb->tags[i]->nodename); + add_pointer_to_array (entry, items_index, items, + items_slots, 100, REFERENCE *); + } + } + } } - line = info_read_maybe_completing (window, "Goto Node: ", items); + line = info_read_maybe_completing (window, _("Goto Node: "), items); info_free_references (items); } #else /* !GOTO_COMPLETES */ - line = info_read_in_echo_area (window, "Goto Node: "); + line = info_read_in_echo_area (window, _("Goto Node: ")); #endif /* !GOTO_COMPLETES */ /* If the user aborted, quit now. */ @@ -2239,12 +2191,11 @@ DECLARE_INFO_COMMAND (info_goto_node, "Read a node name and select it") } #if defined (HANDLE_MAN_PAGES) -DECLARE_INFO_COMMAND (info_man, "Read a manpage reference and select it") +DECLARE_INFO_COMMAND (info_man, _("Read a manpage reference and select it")) { char *line; - NODE *node; - line = info_read_in_echo_area (window, "Get Manpage: "); + line = info_read_in_echo_area (window, _("Get Manpage: ")); if (!line) { @@ -2259,7 +2210,7 @@ DECLARE_INFO_COMMAND (info_man, "Read a manpage reference and select it") char *goto_command; goto_command = (char *)xmalloc - (4 + strlen (MANPAGE_FILE_BUFFER_NAME) + strlen (line)); + (4 + strlen (MANPAGE_FILE_BUFFER_NAME) + strlen (line)); sprintf (goto_command, "(%s)%s", MANPAGE_FILE_BUFFER_NAME, line); @@ -2274,61 +2225,70 @@ DECLARE_INFO_COMMAND (info_man, "Read a manpage reference and select it") #endif /* HANDLE_MAN_PAGES */ /* Move to the "Top" node in this file. */ -DECLARE_INFO_COMMAND (info_top_node, "Select the node `Top' in this file") +DECLARE_INFO_COMMAND (info_top_node, _("Select the node `Top' in this file")) { - info_parse_and_select ("Top", window); + info_parse_and_select (_("Top"), window); } /* Move to the node "(dir)Top". */ -DECLARE_INFO_COMMAND (info_dir_node, "Select the node `(dir)'") +DECLARE_INFO_COMMAND (info_dir_node, _("Select the node `(dir)'")) { info_parse_and_select ("(dir)Top", window); } -/* Try to delete the current node appearing in this window, showing the most - recently selected node in this window. */ -DECLARE_INFO_COMMAND (info_kill_node, "Kill this node") + +/* Read the name of a node to kill. The list of available nodes comes + from the nodes appearing in the current window configuration. */ +static char * +read_nodename_to_kill (window) + WINDOW *window; { - register int iw, i; - register INFO_WINDOW *info_win; - char *nodename = (char *)NULL; - NODE *temp = (NODE *)NULL; + int iw; + char *nodename; + INFO_WINDOW *info_win; + REFERENCE **menu = NULL; + int menu_index = 0, menu_slots = 0; + char *default_nodename = xstrdup (active_window->node->nodename); + char *prompt = xmalloc (40 + strlen (default_nodename)); - /* Read the name of a node to kill. The list of available nodes comes - from the nodes appearing in the current window configuration. */ - { - REFERENCE **menu = (REFERENCE **)NULL; - int menu_index = 0, menu_slots = 0; - char *default_nodename, *prompt; + sprintf (prompt, _("Kill node (%s): "), default_nodename); - for (iw = 0; info_win = info_windows[iw]; iw++) - { - REFERENCE *entry; + for (iw = 0; (info_win = info_windows[iw]); iw++) + { + REFERENCE *entry = (REFERENCE *)xmalloc (sizeof (REFERENCE)); + entry->label = xstrdup (info_win->window->node->nodename); + entry->filename = entry->nodename = (char *)NULL; - entry = (REFERENCE *)xmalloc (sizeof (REFERENCE)); - entry->label = strdup (info_win->window->node->nodename); - entry->filename = entry->nodename = (char *)NULL; + add_pointer_to_array (entry, menu_index, menu, menu_slots, 10, + REFERENCE *); + } - add_pointer_to_array - (entry, menu_index, menu, menu_slots, 10, REFERENCE *); - } + nodename = info_read_completing_in_echo_area (window, prompt, menu); + free (prompt); + info_free_references (menu); + if (nodename && !*nodename) + { + free (nodename); + nodename = default_nodename; + } + else + free (default_nodename); - default_nodename = strdup (active_window->node->nodename); - prompt = (char *)xmalloc (40 + strlen (default_nodename)); - sprintf (prompt, "Kill node (%s): ", default_nodename); + return nodename; +} - nodename = info_read_completing_in_echo_area (window, prompt, menu); - free (prompt); - info_free_references (menu); - if (nodename && !*nodename) - { - free (nodename); - nodename = default_nodename; - } - else - free (default_nodename); - } +/* Delete NODENAME from this window, showing the most + recently selected node in this window. */ +static void +kill_node (window, nodename) + WINDOW *window; + char *nodename; +{ + int iw, i; + INFO_WINDOW *info_win; + NODE *temp; + /* If there is no nodename to kill, quit now. */ if (!nodename) { @@ -2337,16 +2297,16 @@ DECLARE_INFO_COMMAND (info_kill_node, "Kill this node") } /* If there is a nodename, find it in our window list. */ - for (iw = 0; info_win = info_windows[iw]; iw++) + for (iw = 0; (info_win = info_windows[iw]); iw++) if (strcmp (nodename, info_win->nodes[info_win->current]->nodename) == 0) break; if (!info_win) { if (*nodename) - info_error ("Cannot kill the node `%s'", nodename); + info_error (_("Cannot kill node `%s'"), nodename); else - window_clear_echo_area (); + window_clear_echo_area (); return; } @@ -2354,13 +2314,12 @@ DECLARE_INFO_COMMAND (info_kill_node, "Kill this node") /* If there are no more nodes left anywhere to view, complain and exit. */ if (info_windows_index == 1 && info_windows[0]->nodes_index == 1) { - info_error ("Cannot kill the last node"); + info_error (_("Cannot kill the last node")); return; } - /* INFO_WIN contains the node that the user wants to stop viewing. - Delete this node from the list of nodes previously shown in this - window. */ + /* INFO_WIN contains the node that the user wants to stop viewing. Delete + this node from the list of nodes previously shown in this window. */ for (i = info_win->current; i < info_win->nodes_index; i++) info_win->nodes[i] = info_win->nodes[i++]; @@ -2379,41 +2338,40 @@ DECLARE_INFO_COMMAND (info_kill_node, "Kill this node") long point; if (info_windows[iw + 1]) - stealer = info_windows[iw + 1]; + stealer = info_windows[iw + 1]; else - stealer = info_windows[0]; + stealer = info_windows[0]; /* If the node being displayed in the next window is not the most - recently loaded one, get the most recently loaded one. */ + recently loaded one, get the most recently loaded one. */ if ((stealer->nodes_index - 1) != stealer->current) - which = stealer->nodes_index - 1; + which = stealer->nodes_index - 1; /* Else, if there is another node behind the stealers current node, - use that one. */ + use that one. */ else if (stealer->current > 0) - which = stealer->current - 1; + which = stealer->current - 1; /* Else, just use the node appearing in STEALER's window. */ else - which = stealer->current; + which = stealer->current; /* Copy this node. */ { - NODE *copy; - - temp = stealer->nodes[which]; - point = stealer->points[which]; - pagetop = stealer->pagetops[which]; - - copy = (NODE *)xmalloc (sizeof (NODE)); - copy->filename = temp->filename; - copy->parent = temp->parent; - copy->nodename = temp->nodename; - copy->contents = temp->contents; - copy->nodelen = temp->nodelen; - copy->flags = temp->flags; - - temp = copy; + NODE *copy = xmalloc (sizeof (NODE)); + + temp = stealer->nodes[which]; + point = stealer->points[which]; + pagetop = stealer->pagetops[which]; + + copy->filename = temp->filename; + copy->parent = temp->parent; + copy->nodename = temp->nodename; + copy->contents = temp->contents; + copy->nodelen = temp->nodelen; + copy->flags = temp->flags; + + temp = copy; } window_set_node_of_window (info_win->window, temp); @@ -2426,16 +2384,39 @@ DECLARE_INFO_COMMAND (info_kill_node, "Kill this node") temp = info_win->nodes[info_win->current]; window_set_node_of_window (info_win->window, temp); } + if (!info_error_was_printed) window_clear_echo_area (); + + if (auto_footnotes_p) + info_get_or_remove_footnotes (window); +} + +/* Kill current node, thus going back one in the node history. I (karl) + do not think this is completely correct yet, because of the + window-changing stuff in kill_node, but it's a lot better than the + previous implementation, which did not account for nodes being + visited twice at all. */ +DECLARE_INFO_COMMAND (info_history_node, + _("Select the most recently selected node")) +{ + kill_node (window, active_window->node->nodename); +} + +/* Kill named node. */ +DECLARE_INFO_COMMAND (info_kill_node, _("Kill this node")) +{ + char *nodename = read_nodename_to_kill (window); + kill_node (window, nodename); } + /* Read the name of a file and select the entire file. */ -DECLARE_INFO_COMMAND (info_view_file, "Read the name of a file and select it") +DECLARE_INFO_COMMAND (info_view_file, _("Read the name of a file and select it")) { char *line; - line = info_read_in_echo_area (window, "Find file: "); + line = info_read_in_echo_area (window, _("Find file: ")); if (!line) { info_abort_key (active_window, 1, 0); @@ -2448,17 +2429,17 @@ DECLARE_INFO_COMMAND (info_view_file, "Read the name of a file and select it") node = info_get_node (line, "*"); if (!node) - { - if (info_recent_file_error) - info_error (info_recent_file_error); - else - info_error ("Cannot find \"%s\".", line); - } + { + if (info_recent_file_error) + info_error (info_recent_file_error); + else + info_error (_("Cannot find \"%s\"."), line); + } else - { - set_remembered_pagetop_and_point (active_window); - info_set_node_of_window (window, node); - } + { + set_remembered_pagetop_and_point (active_window); + info_set_node_of_window (window, node); + } free (line); } @@ -2467,9 +2448,9 @@ DECLARE_INFO_COMMAND (info_view_file, "Read the name of a file and select it") } /* **************************************************************** */ -/* */ -/* Dumping and Printing Nodes */ -/* */ +/* */ +/* Dumping and Printing Nodes */ +/* */ /* **************************************************************** */ #define VERBOSE_NODE_DUMPING @@ -2499,7 +2480,7 @@ dump_nodes_to_file (filename, nodenames, output_filename, dump_subnodes) if (!output_stream) { - info_error ("Could not create output file \"%s\".", output_filename); + info_error (_("Could not create output file \"%s\"."), output_filename); return; } @@ -2512,7 +2493,7 @@ dump_nodes_to_file (filename, nodenames, output_filename, dump_subnodes) fclose (output_stream); #if defined (VERBOSE_NODE_DUMPING) - info_error ("Done."); + info_error (_("Done.")); #endif /* VERBOSE_NODE_DUMPING */ } @@ -2544,15 +2525,15 @@ dump_node_to_stream (filename, nodename, stream, dump_subnodes) if (!node) { if (info_recent_file_error) - info_error (info_recent_file_error); + info_error (info_recent_file_error); else - { - if (filename && *nodename != '(') - info_error - (CANT_FILE_NODE, filename_non_directory (filename), nodename); - else - info_error (CANT_FIND_NODE, nodename); - } + { + if (filename && *nodename != '(') + info_error + (CANT_FILE_NODE, filename_non_directory (filename), nodename); + else + info_error (CANT_FIND_NODE, nodename); + } return; } @@ -2560,19 +2541,19 @@ dump_node_to_stream (filename, nodename, stream, dump_subnodes) for (i = 0; i < dumped_already_index; i++) if (strcmp (node->nodename, dumped_already[i]) == 0) { - free (node); - return; + free (node); + return; } add_pointer_to_array (node->nodename, dumped_already_index, dumped_already, - dumped_already_slots, 50, char *); + dumped_already_slots, 50, char *); #if defined (VERBOSE_NODE_DUMPING) /* Maybe we should print some information about the node being output. */ if (node->filename) - info_error ("Writing node \"(%s)%s\"...", - filename_non_directory (node->filename), node->nodename); + info_error (_("Writing node \"(%s)%s\"..."), + filename_non_directory (node->filename), node->nodename); else - info_error ("Writing node \"%s\"...", node->nodename); + info_error (_("Writing node \"%s\"..."), node->nodename); #endif /* VERBOSE_NODE_DUMPING */ write_node_to_stream (node, stream); @@ -2585,20 +2566,20 @@ dump_node_to_stream (filename, nodename, stream, dump_subnodes) /* If this node is an Index, do not dump the menu references. */ if (string_in_line ("Index", node->nodename) == -1) - menu = info_menu_of_node (node); + menu = info_menu_of_node (node); if (menu) - { - for (i = 0; menu[i]; i++) - { - /* We don't dump Info files which are different than the - current one. */ - if (!menu[i]->filename) - dump_node_to_stream - (filename, menu[i]->nodename, stream, dump_subnodes); - } - info_free_references (menu); - } + { + for (i = 0; menu[i]; i++) + { + /* We don't dump Info files which are different than the + current one. */ + if (!menu[i]->filename) + dump_node_to_stream + (filename, menu[i]->nodename, stream, dump_subnodes); + } + info_free_references (menu); + } } free (node); @@ -2624,7 +2605,7 @@ dump_node_to_file (node, filename, dump_subnodes) if (!output_stream) { - info_error ("Could not create output file \"%s\".", filename); + info_error (_("Could not create output file \"%s\"."), filename); return; } @@ -2641,7 +2622,7 @@ dump_node_to_file (node, filename, dump_subnodes) fclose (output_stream); #if defined (VERBOSE_NODE_DUMPING) - info_error ("Done."); + info_error (_("Done.")); #endif /* VERBOSE_NODE_DUMPING */ } @@ -2650,7 +2631,7 @@ dump_node_to_file (node, filename, dump_subnodes) #endif /* !DEFAULT_INFO_PRINT_COMMAND */ DECLARE_INFO_COMMAND (info_print_node, - "Pipe the contents of this node through INFO_PRINT_COMMAND") + _("Pipe the contents of this node through INFO_PRINT_COMMAND")) { print_node (window->node); } @@ -2660,10 +2641,8 @@ void print_node (node) NODE *node; { - char *print_command, *getenv (); FILE *printer_pipe; - - print_command = getenv ("INFO_PRINT_COMMAND"); + char *print_command = getenv ("INFO_PRINT_COMMAND"); if (!print_command || !*print_command) print_command = DEFAULT_INFO_PRINT_COMMAND; @@ -2672,24 +2651,24 @@ print_node (node) if (!printer_pipe) { - info_error ("Cannot open pipe to \"%s\".", print_command); + info_error (_("Cannot open pipe to \"%s\"."), print_command); return; } #if defined (VERBOSE_NODE_DUMPING) /* Maybe we should print some information about the node being output. */ if (node->filename) - info_error ("Printing node \"(%s)%s\"...", - filename_non_directory (node->filename), node->nodename); + info_error (_("Printing node \"(%s)%s\"..."), + filename_non_directory (node->filename), node->nodename); else - info_error ("Printing node \"%s\"...", node->nodename); + info_error (_("Printing node \"%s\"..."), node->nodename); #endif /* VERBOSE_NODE_DUMPING */ write_node_to_stream (node, printer_pipe); pclose (printer_pipe); #if defined (VERBOSE_NODE_DUMPING) - info_error ("Done."); + info_error (_("Done.")); #endif /* VERBOSE_NODE_DUMPING */ } @@ -2702,9 +2681,9 @@ write_node_to_stream (node, stream) } /* **************************************************************** */ -/* */ -/* Info Searching Commands */ -/* */ +/* */ +/* Info Searching Commands */ +/* */ /* **************************************************************** */ /* Variable controlling the garbage collection of files briefly visited @@ -2779,7 +2758,7 @@ info_search_in_node (string, node, start, window, dir) { set_remembered_pagetop_and_point (window); if (window->node != node) - window_set_node_of_window (window, node); + window_set_node_of_window (window, node); window->point = offset; window_adjust_pagetop (window); } @@ -2799,7 +2778,7 @@ info_target_search_node (node, string, start) long offset; char *target; - target = strdup (string); + target = xstrdup (string); i = strlen (target); /* Try repeatedly searching for this string while removing words from @@ -2810,7 +2789,7 @@ info_target_search_node (node, string, start) offset = info_search_in_node (target, node, start, (WINDOW *)NULL, 1); if (offset != -1) - break; + break; /* Delete the last word from TARGET. */ for (; i && (!whitespace (target[i]) && (target[i] != ',')); i--); @@ -2844,22 +2823,22 @@ info_search_internal (string, window, dir) (strcmp (last_searched_for_string, string) == 0)) { ret = info_search_in_node - (string, window->node, window->point + dir, window, dir); + (string, window->node, window->point + dir, window, dir); } else { ret = info_search_in_node - (string, window->node, window->point, window, dir); + (string, window->node, window->point, window, dir); } maybe_free (last_searched_for_string); - last_searched_for_string = strdup (string); + last_searched_for_string = xstrdup (string); if (ret != -1) { /* We won! */ if (!echo_area_is_active && !isearch_is_active) - window_clear_echo_area (); + window_clear_echo_area (); return (0); } @@ -2880,91 +2859,91 @@ info_search_internal (string, window, dir) /* Find number of tags and current tag. */ last_subfile = (char *)NULL; for (i = 0; file_buffer->tags[i]; i++) - if (strcmp (initial_nodename, file_buffer->tags[i]->nodename) == 0) - { - current_tag = i; - last_subfile = file_buffer->tags[i]->filename; - } + if (strcmp (initial_nodename, file_buffer->tags[i]->nodename) == 0) + { + current_tag = i; + last_subfile = file_buffer->tags[i]->filename; + } number_of_tags = i; /* If there is no last_subfile, our tag wasn't found. */ if (!last_subfile) - return (-1); + return (-1); /* Search through subsequent nodes, wrapping around to the top - of the info file until we find the string or return to this - window's node and point. */ + of the info file until we find the string or return to this + window's node and point. */ while (1) - { - NODE *node; - - /* Allow C-g to quit the search, failing it if pressed. */ - return_if_control_g (-1); - - current_tag += dir; - - if (current_tag < 0) - current_tag = number_of_tags - 1; - else if (current_tag == number_of_tags) - current_tag = 0; - - tag = file_buffer->tags[current_tag]; - - if (!echo_area_is_active && (last_subfile != tag->filename)) - { - window_message_in_echo_area - ("Searching subfile \"%s\"...", - filename_non_directory (tag->filename)); - - last_subfile = tag->filename; - } - - node = info_get_node (file_buffer->filename, tag->nodename); - - if (!node) - { - /* If not doing i-search... */ - if (!echo_area_is_active) - { - if (info_recent_file_error) - info_error (info_recent_file_error); - else - info_error (CANT_FILE_NODE, - filename_non_directory (file_buffer->filename), - tag->nodename); - } - return (-1); - } - - if (dir < 0) - start = tag->nodelen; - - ret = - info_search_in_node (string, node, start, window, dir); - - /* Did we find the string in this node? */ - if (ret != -1) - { - /* Yes! We win. */ - remember_window_and_node (window, node); - if (!echo_area_is_active) - window_clear_echo_area (); - return (0); - } - - /* No. Free this node, and make sure that we haven't passed - our starting point. */ - free (node); - - if (strcmp (initial_nodename, tag->nodename) == 0) - return (-1); - } + { + NODE *node; + + /* Allow C-g to quit the search, failing it if pressed. */ + return_if_control_g (-1); + + current_tag += dir; + + if (current_tag < 0) + current_tag = number_of_tags - 1; + else if (current_tag == number_of_tags) + current_tag = 0; + + tag = file_buffer->tags[current_tag]; + + if (!echo_area_is_active && (last_subfile != tag->filename)) + { + window_message_in_echo_area + (_("Searching subfile \"%s\"..."), + filename_non_directory (tag->filename)); + + last_subfile = tag->filename; + } + + node = info_get_node (file_buffer->filename, tag->nodename); + + if (!node) + { + /* If not doing i-search... */ + if (!echo_area_is_active) + { + if (info_recent_file_error) + info_error (info_recent_file_error); + else + info_error (CANT_FILE_NODE, + filename_non_directory (file_buffer->filename), + tag->nodename); + } + return (-1); + } + + if (dir < 0) + start = tag->nodelen; + + ret = + info_search_in_node (string, node, start, window, dir); + + /* Did we find the string in this node? */ + if (ret != -1) + { + /* Yes! We win. */ + remember_window_and_node (window, node); + if (!echo_area_is_active) + window_clear_echo_area (); + return (0); + } + + /* No. Free this node, and make sure that we haven't passed + our starting point. */ + free (node); + + if (strcmp (initial_nodename, tag->nodename) == 0) + return (-1); + } } return (-1); } -DECLARE_INFO_COMMAND (info_search, "Read a string and search for it") +DECLARE_INFO_COMMAND (info_search, _("Read a string and search for it")) { char *line, *prompt; int result, old_pagetop; @@ -2984,9 +2963,9 @@ DECLARE_INFO_COMMAND (info_search, "Read a string and search for it") prompt = (char *)xmalloc (50 + strlen (search_string)); - sprintf (prompt, "%s for string [%s]: ", - direction < 0 ? "Search backward" : "Search", - search_string); + sprintf (prompt, _("%s for string [%s]: "), + direction < 0 ? _("Search backward") : _("Search"), + search_string); line = info_read_in_echo_area (window, prompt); free (prompt); @@ -3000,8 +2979,8 @@ DECLARE_INFO_COMMAND (info_search, "Read a string and search for it") if (*line) { if (strlen (line) + 1 > search_string_size) - search_string = (char *) - xrealloc (search_string, (search_string_size += 50 + strlen (line))); + search_string = (char *) + xrealloc (search_string, (search_string_size += 50 + strlen (line))); strcpy (search_string, line); search_string_index = strlen (line); @@ -3012,7 +2991,7 @@ DECLARE_INFO_COMMAND (info_search, "Read a string and search for it") result = info_search_internal (search_string, active_window, direction); if (result != 0 && !info_error_was_printed) - info_error ("Search failed."); + info_error (_("Search failed.")); else if (old_pagetop != active_window->pagetop) { int new_pagetop; @@ -3021,7 +3000,7 @@ DECLARE_INFO_COMMAND (info_search, "Read a string and search for it") active_window->pagetop = old_pagetop; set_window_pagetop (active_window, new_pagetop); if (auto_footnotes_p) - info_get_or_remove_footnotes (active_window); + info_get_or_remove_footnotes (active_window); } /* Perhaps free the unreferenced file buffers that were searched, but @@ -3030,21 +3009,21 @@ DECLARE_INFO_COMMAND (info_search, "Read a string and search for it") } /* **************************************************************** */ -/* */ -/* Incremental Searching */ -/* */ +/* */ +/* Incremental Searching */ +/* */ /* **************************************************************** */ static void incremental_search (); DECLARE_INFO_COMMAND (isearch_forward, - "Search interactively for a string as you type it") + _("Search interactively for a string as you type it")) { incremental_search (window, count, key); } DECLARE_INFO_COMMAND (isearch_backward, - "Search interactively for a string as you type it") + _("Search interactively for a string as you type it")) { incremental_search (window, -count, key); } @@ -3061,10 +3040,10 @@ static unsigned char isearch_terminate_search_key = ESC; /* Structure defining the current state of an incremental search. */ typedef struct { - WINDOW_STATE_DECL; /* The node, pagetop and point. */ - int search_index; /* Offset of the last char in the search string. */ - int direction; /* The direction that this search is heading in. */ - int failing; /* Whether or not this search failed. */ + WINDOW_STATE_DECL; /* The node, pagetop and point. */ + int search_index; /* Offset of the last char in the search string. */ + int direction; /* The direction that this search is heading in. */ + int failing; /* Whether or not this search failed. */ } SEARCH_STATE; /* Array of search states. */ @@ -3087,7 +3066,7 @@ push_isearch (window, search_index, direction, failing) state->failing = failing; add_pointer_to_array (state, isearch_states_index, isearch_states, - isearch_states_slots, 20, SEARCH_STATE *); + isearch_states_slots, 20, SEARCH_STATE *); } /* Pop the state of this search to WINDOW, SEARCH_INDEX, and DIRECTION. */ @@ -3138,9 +3117,9 @@ show_isearch_prompt (dir, string, failing_p) int prompt_len, p_rep_index, p_rep_size; if (dir < 0) - prefix = "I-search backward: "; + prefix = _("I-search backward: "); else - prefix = "I-search: "; + prefix = _("I-search: "); p_rep_index = p_rep_size = 0; p_rep = (char *)NULL; @@ -3149,15 +3128,15 @@ show_isearch_prompt (dir, string, failing_p) char *rep; switch (string[i]) - { - case ' ': rep = " "; break; - case LFD: rep = "\\n"; break; - case TAB: rep = "\\t"; break; - default: - rep = pretty_keyname (string[i]); - } + { + case ' ': rep = " "; break; + case LFD: rep = "\\n"; break; + case TAB: rep = "\\t"; break; + default: + rep = pretty_keyname (string[i]); + } if ((p_rep_index + strlen (rep) + 1) >= p_rep_size) - p_rep = (char *)xrealloc (p_rep, p_rep_size += 100); + p_rep = (char *)xrealloc (p_rep, p_rep_size += 100); strcpy (p_rep + p_rep_index, rep); p_rep_index += strlen (rep); @@ -3165,8 +3144,8 @@ show_isearch_prompt (dir, string, failing_p) prompt_len = strlen (prefix) + p_rep_index + 20; prompt = (char *)xmalloc (prompt_len); - sprintf (prompt, "%s%s%s", failing_p ? "Failing " : "", prefix, - p_rep ? p_rep : ""); + sprintf (prompt, "%s%s%s", failing_p ? _("Failing ") : "", prefix, + p_rep ? p_rep : ""); window_message_in_echo_area ("%s", prompt); maybe_free (p_rep); @@ -3209,202 +3188,202 @@ incremental_search (window, count, ignore) int quoted = 0; /* If a recent display was interrupted, then do the redisplay now if - it is convenient. */ + it is convenient. */ if (!info_any_buffered_input_p () && display_was_interrupted_p) - { - display_update_one_window (window); - display_cursor_at_point (active_window); - } + { + display_update_one_window (window); + display_cursor_at_point (active_window); + } /* Read a character and dispatch on it. */ key = info_get_input_char (); window_get_state (window, &mystate); if (key == DEL) - { - /* User wants to delete one level of search? */ - if (!isearch_states_index) - { - terminal_ring_bell (); - continue; - } - else - { - pop_isearch - (window, &isearch_string_index, &dir, &search_result); - isearch_string[isearch_string_index] = '\0'; - show_isearch_prompt (dir, isearch_string, search_result); - goto after_search; - } - } + { + /* User wants to delete one level of search? */ + if (!isearch_states_index) + { + terminal_ring_bell (); + continue; + } + else + { + pop_isearch + (window, &isearch_string_index, &dir, &search_result); + isearch_string[isearch_string_index] = '\0'; + show_isearch_prompt (dir, isearch_string, search_result); + goto after_search; + } + } else if (key == Control ('q')) - { - key = info_get_input_char (); - quoted = 1; - } + { + key = info_get_input_char (); + quoted = 1; + } /* We are about to search again, or quit. Save the current search. */ push_isearch (window, isearch_string_index, dir, search_result); if (quoted) - goto insert_and_search; + goto insert_and_search; if (!Meta_p (key) || (ISO_Latin_p && key < 160)) - { - func = window->keymap[key].function; - - /* If this key invokes an incremental search, then this means that - we will either search again in the same direction, search - again in the reverse direction, or insert the last search - string that was accepted through incremental searching. */ - if (func == isearch_forward || func == isearch_backward) - { - if ((func == isearch_forward && dir > 0) || - (func == isearch_backward && dir < 0)) - { - /* If the user has typed no characters, then insert the - last successful search into the current search string. */ - if (isearch_string_index == 0) - { - /* Of course, there must be something to insert. */ - if (last_isearch_accepted) - { - if (strlen (last_isearch_accepted) + 1 >= - isearch_string_size) - isearch_string = (char *) - xrealloc (isearch_string, - isearch_string_size += 10 + - strlen (last_isearch_accepted)); - strcpy (isearch_string, last_isearch_accepted); - isearch_string_index = strlen (isearch_string); - goto search_now; - } - else - continue; - } - else - { - /* Search again in the same direction. This means start - from a new place if the last search was successful. */ - if (search_result == 0) - window->point += dir; - } - } - else - { - /* Reverse the direction of the search. */ - dir = -dir; - } - } - else if (isprint (key) || func == (VFunction *)NULL) - { - insert_and_search: - - if (isearch_string_index + 2 >= isearch_string_size) - isearch_string = (char *)xrealloc - (isearch_string, isearch_string_size += 100); - - isearch_string[isearch_string_index++] = key; - isearch_string[isearch_string_index] = '\0'; - goto search_now; - } - else if (func == info_abort_key) - { - /* If C-g pressed, and the search is failing, pop the search - stack back to the last unfailed search. */ - if (isearch_states_index && (search_result != 0)) - { - terminal_ring_bell (); - while (isearch_states_index && (search_result != 0)) - pop_isearch - (window, &isearch_string_index, &dir, &search_result); - isearch_string[isearch_string_index] = '\0'; - show_isearch_prompt (dir, isearch_string, search_result); - continue; - } - else - goto exit_search; - } - else - goto exit_search; - } + { + func = window->keymap[key].function; + + /* If this key invokes an incremental search, then this means that + we will either search again in the same direction, search + again in the reverse direction, or insert the last search + string that was accepted through incremental searching. */ + if (func == isearch_forward || func == isearch_backward) + { + if ((func == isearch_forward && dir > 0) || + (func == isearch_backward && dir < 0)) + { + /* If the user has typed no characters, then insert the + last successful search into the current search string. */ + if (isearch_string_index == 0) + { + /* Of course, there must be something to insert. */ + if (last_isearch_accepted) + { + if (strlen (last_isearch_accepted) + 1 >= + isearch_string_size) + isearch_string = (char *) + xrealloc (isearch_string, + isearch_string_size += 10 + + strlen (last_isearch_accepted)); + strcpy (isearch_string, last_isearch_accepted); + isearch_string_index = strlen (isearch_string); + goto search_now; + } + else + continue; + } + else + { + /* Search again in the same direction. This means start + from a new place if the last search was successful. */ + if (search_result == 0) + window->point += dir; + } + } + else + { + /* Reverse the direction of the search. */ + dir = -dir; + } + } + else if (isprint (key) || func == (VFunction *)NULL) + { + insert_and_search: + + if (isearch_string_index + 2 >= isearch_string_size) + isearch_string = (char *)xrealloc + (isearch_string, isearch_string_size += 100); + + isearch_string[isearch_string_index++] = key; + isearch_string[isearch_string_index] = '\0'; + goto search_now; + } + else if (func == info_abort_key) + { + /* If C-g pressed, and the search is failing, pop the search + stack back to the last unfailed search. */ + if (isearch_states_index && (search_result != 0)) + { + terminal_ring_bell (); + while (isearch_states_index && (search_result != 0)) + pop_isearch + (window, &isearch_string_index, &dir, &search_result); + isearch_string[isearch_string_index] = '\0'; + show_isearch_prompt (dir, isearch_string, search_result); + continue; + } + else + goto exit_search; + } + else + goto exit_search; + } else - { - exit_search: - /* The character is not printable, or it has a function which is - non-null. Exit the search, remembering the search string. If - the key is not the same as the isearch_terminate_search_key, - then push it into pending input. */ - if (isearch_string_index && func != info_abort_key) - { - maybe_free (last_isearch_accepted); - last_isearch_accepted = strdup (isearch_string); - } - - if (key != isearch_terminate_search_key) - info_set_pending_input (key); - - if (func == info_abort_key) - { - if (isearch_states_index) - window_set_state (window, &orig_state); - } - - if (!echo_area_is_active) - window_clear_echo_area (); - - if (auto_footnotes_p) - info_get_or_remove_footnotes (active_window); - - isearch_is_active = 0; - continue; - } + { + exit_search: + /* The character is not printable, or it has a function which is + non-null. Exit the search, remembering the search string. If + the key is not the same as the isearch_terminate_search_key, + then push it into pending input. */ + if (isearch_string_index && func != info_abort_key) + { + maybe_free (last_isearch_accepted); + last_isearch_accepted = xstrdup (isearch_string); + } + + if (key != isearch_terminate_search_key) + info_set_pending_input (key); + + if (func == info_abort_key) + { + if (isearch_states_index) + window_set_state (window, &orig_state); + } + + if (!echo_area_is_active) + window_clear_echo_area (); + + if (auto_footnotes_p) + info_get_or_remove_footnotes (active_window); + + isearch_is_active = 0; + continue; + } /* Search for the contents of isearch_string. */ search_now: show_isearch_prompt (dir, isearch_string, search_result); if (search_result == 0) - { - /* Check to see if the current search string is right here. If - we are looking at it, then don't bother calling the search - function. */ - if (((dir < 0) && - (strncasecmp (window->node->contents + window->point, - isearch_string, isearch_string_index) == 0)) || - ((dir > 0) && - ((window->point - isearch_string_index) >= 0) && - (strncasecmp (window->node->contents + - (window->point - (isearch_string_index - 1)), - isearch_string, isearch_string_index) == 0))) - { - if (dir > 0) - window->point++; - } - else - search_result = info_search_internal (isearch_string, window, dir); - } + { + /* Check to see if the current search string is right here. If + we are looking at it, then don't bother calling the search + function. */ + if (((dir < 0) && + (strncasecmp (window->node->contents + window->point, + isearch_string, isearch_string_index) == 0)) || + ((dir > 0) && + ((window->point - isearch_string_index) >= 0) && + (strncasecmp (window->node->contents + + (window->point - (isearch_string_index - 1)), + isearch_string, isearch_string_index) == 0))) + { + if (dir > 0) + window->point++; + } + else + search_result = info_search_internal (isearch_string, window, dir); + } /* If this search failed, and we didn't already have a failed search, - then ring the terminal bell. */ + then ring the terminal bell. */ if (search_result != 0 && last_search_result == 0) - terminal_ring_bell (); + terminal_ring_bell (); after_search: show_isearch_prompt (dir, isearch_string, search_result); if (search_result == 0) - { - if ((mystate.node == window->node) && - (mystate.pagetop != window->pagetop)) - { - int newtop = window->pagetop; - window->pagetop = mystate.pagetop; - set_window_pagetop (window, newtop); - } - display_update_one_window (window); - display_cursor_at_point (window); - } + { + if ((mystate.node == window->node) && + (mystate.pagetop != window->pagetop)) + { + int newtop = window->pagetop; + window->pagetop = mystate.pagetop; + set_window_pagetop (window, newtop); + } + display_update_one_window (window); + display_cursor_at_point (window); + } last_search_result = search_result; } @@ -3434,52 +3413,52 @@ info_gc_file_buffers () if (!info_loaded_files) return; - for (fb_index = 0; fb = info_loaded_files[fb_index]; fb_index++) + for (fb_index = 0; (fb = info_loaded_files[fb_index]); fb_index++) { int fb_referenced_p = 0; /* If already gc-ed, do nothing. */ if (!fb->contents) - continue; + continue; /* If this file had to be uncompressed, check to see if we should - gc it. This means that the user-variable "gc-compressed-files" - is non-zero. */ + gc it. This means that the user-variable "gc-compressed-files" + is non-zero. */ if ((fb->flags & N_IsCompressed) && !gc_compressed_files) - continue; + continue; /* If this file's contents are not gc-able, move on. */ if (fb->flags & N_CannotGC) - continue; + continue; /* Check each INFO_WINDOW to see if it has any nodes which reference - this file. */ - for (iw_index = 0; iw = info_windows[iw_index]; iw_index++) - { - for (i = 0; iw->nodes && iw->nodes[i]; i++) - { - if ((strcmp (fb->fullpath, iw->nodes[i]->filename) == 0) || - (strcmp (fb->filename, iw->nodes[i]->filename) == 0)) - { - fb_referenced_p = 1; - break; - } - } - } + this file. */ + for (iw_index = 0; (iw = info_windows[iw_index]); iw_index++) + { + for (i = 0; iw->nodes && iw->nodes[i]; i++) + { + if ((strcmp (fb->fullpath, iw->nodes[i]->filename) == 0) || + (strcmp (fb->filename, iw->nodes[i]->filename) == 0)) + { + fb_referenced_p = 1; + break; + } + } + } /* If this file buffer wasn't referenced, free its contents. */ if (!fb_referenced_p) - { - free (fb->contents); - fb->contents = (char *)NULL; - } + { + free (fb->contents); + fb->contents = (char *)NULL; + } } } /* **************************************************************** */ -/* */ -/* Traversing and Selecting References */ -/* */ +/* */ +/* Traversing and Selecting References */ +/* */ /* **************************************************************** */ /* Move to the next or previous cross reference in this node. */ @@ -3514,8 +3493,8 @@ info_move_to_xref (window, count, key, dir) char *text = node->contents + firstmenu; if (strncmp (text, INFO_MENU_LABEL, strlen (INFO_MENU_LABEL)) == 0) - firstmenu = info_search_in_node - (INFO_MENU_ENTRY_LABEL, node, firstmenu + dir, (WINDOW *)NULL, dir); + firstmenu = info_search_in_node + (INFO_MENU_ENTRY_LABEL, node, firstmenu + dir, (WINDOW *)NULL, dir); } firstxref = @@ -3530,7 +3509,7 @@ info_move_to_xref (window, count, key, dir) if (firstmenu == -1 && firstxref == -1) { - info_error ("No cross references in this node."); + info_error (_("No cross references in this node.")); return; } @@ -3554,8 +3533,8 @@ info_move_to_xref (window, count, key, dir) char *text = node->contents + nextmenu; if (strncmp (text, INFO_MENU_LABEL, strlen (INFO_MENU_LABEL)) == 0) - nextmenu = info_search_in_node - (INFO_MENU_ENTRY_LABEL, node, nextmenu + dir, (WINDOW *)NULL, dir); + nextmenu = info_search_in_node + (INFO_MENU_ENTRY_LABEL, node, nextmenu + dir, (WINDOW *)NULL, dir); } /* If there is both a next menu entry, and a next xref entry, choose the @@ -3564,10 +3543,10 @@ info_move_to_xref (window, count, key, dir) if (nextmenu != -1 && nextxref != -1) { if (((dir == 1) && (nextmenu < nextxref)) || - ((dir == -1) && (nextmenu > nextxref))) - placement = nextmenu + 1; + ((dir == -1) && (nextmenu > nextxref))) + placement = nextmenu + 1; else - placement = nextxref; + placement = nextxref; } else if (nextmenu != -1) placement = nextmenu + 1; @@ -3579,17 +3558,17 @@ info_move_to_xref (window, count, key, dir) if (placement == -1) { if (firstmenu != -1 && firstxref != -1) - { - if (((dir == 1) && (firstmenu < firstxref)) || - ((dir == -1) && (firstmenu > firstxref))) - placement = firstmenu + 1; - else - placement = firstxref; - } + { + if (((dir == 1) && (firstmenu < firstxref)) || + ((dir == -1) && (firstmenu > firstxref))) + placement = firstmenu + 1; + else + placement = firstxref; + } else if (firstmenu != -1) - placement = firstmenu + 1; + placement = firstmenu + 1; else - placement = firstxref; + placement = firstxref; } window->point = placement; window_adjust_pagetop (window); @@ -3597,7 +3576,7 @@ info_move_to_xref (window, count, key, dir) } DECLARE_INFO_COMMAND (info_move_to_prev_xref, - "Move to the previous cross reference") + _("Move to the previous cross reference")) { if (count < 0) info_move_to_prev_xref (window, -count, key); @@ -3606,7 +3585,7 @@ DECLARE_INFO_COMMAND (info_move_to_prev_xref, } DECLARE_INFO_COMMAND (info_move_to_next_xref, - "Move to the next cross reference") + _("Move to the next cross reference")) { if (count < 0) info_move_to_next_xref (window, -count, key); @@ -3616,7 +3595,7 @@ DECLARE_INFO_COMMAND (info_move_to_next_xref, /* Select the menu item or reference that appears on this line. */ DECLARE_INFO_COMMAND (info_select_reference_this_line, - "Select reference or menu item appearing on this line") + _("Select reference or menu item appearing on this line")) { char *line; NODE *orig; @@ -3632,20 +3611,20 @@ DECLARE_INFO_COMMAND (info_select_reference_this_line, } /* **************************************************************** */ -/* */ -/* Miscellaneous Info Commands */ -/* */ +/* */ +/* Miscellaneous Info Commands */ +/* */ /* **************************************************************** */ /* What to do when C-g is pressed in a window. */ -DECLARE_INFO_COMMAND (info_abort_key, "Cancel current operation") +DECLARE_INFO_COMMAND (info_abort_key, _("Cancel current operation")) { /* If error printing doesn't oridinarily ring the bell, do it now, since C-g always rings the bell. Otherwise, let the error printer do it. */ if (!info_error_rings_bell_p) terminal_ring_bell (); - info_error ("Quit"); + info_error (_("Quit")); info_initialize_numeric_arg (); info_clear_pending_input (); @@ -3654,7 +3633,7 @@ DECLARE_INFO_COMMAND (info_abort_key, "Cancel current operation") /* Move the cursor to the desired line of the window. */ DECLARE_INFO_COMMAND (info_move_to_window_line, - "Move to the cursor to a specific line of the window") + _("Move to the cursor to a specific line of the window")) { int line; @@ -3664,9 +3643,9 @@ DECLARE_INFO_COMMAND (info_move_to_window_line, else { if (count < 0) - line = (window->height + count) + window->pagetop; + line = (window->height + count) + window->pagetop; else - line = window->pagetop + count; + line = window->pagetop + count; } /* If the line doesn't appear in this window, make it do so. */ @@ -3686,7 +3665,7 @@ DECLARE_INFO_COMMAND (info_move_to_window_line, /* Clear the screen and redraw its contents. Given a numeric argument, move the line the cursor is on to the COUNT'th line of the window. */ -DECLARE_INFO_COMMAND (info_redraw_display, "Redraw the display") +DECLARE_INFO_COMMAND (info_redraw_display, _("Redraw the display")) { if ((!info_explicit_arg && count == 1) || echo_area_is_active) { @@ -3703,18 +3682,18 @@ DECLARE_INFO_COMMAND (info_redraw_display, "Redraw the display") point_line = window_line_of_point (window) - window->pagetop; if (count < 0) - desired_line = window->height + count; + desired_line = window->height + count; else - desired_line = count; + desired_line = count; if (desired_line < 0) - desired_line = 0; + desired_line = 0; if (desired_line >= window->height) - desired_line = window->height - 1; + desired_line = window->height - 1; if (desired_line == point_line) - return; + return; new_pagetop = window->pagetop + (point_line - desired_line); @@ -3723,14 +3702,14 @@ DECLARE_INFO_COMMAND (info_redraw_display, "Redraw the display") } /* This command does nothing. It is the fact that a key is bound to it that has meaning. See the code at the top of info_session (). */ -DECLARE_INFO_COMMAND (info_quit, "Quit using Info") +DECLARE_INFO_COMMAND (info_quit, _("Quit using Info")) {} /* **************************************************************** */ -/* */ -/* Reading Keys and Dispatching on Them */ -/* */ +/* */ +/* Reading Keys and Dispatching on Them */ +/* */ /* **************************************************************** */ /* Declaration only. Special cased in info_dispatch_on_key (). */ @@ -3746,14 +3725,14 @@ dispatch_error (keyseq) rep = pretty_keyseq (keyseq); if (!echo_area_is_active) - info_error ("Unknown command (%s).", rep); + info_error (_("Unknown command (%s)."), rep); else { char *temp; - temp = (char *)xmalloc (1 + strlen (rep) + strlen ("\"\" is invalid")); + temp = (char *)xmalloc (1 + strlen (rep) + strlen (_("\"\" is invalid"))); - sprintf (temp, "\"%s\" is invalid", rep); + sprintf (temp, _("\"%s\" is invalid"), rep); terminal_ring_bell (); inform_in_echo_area (temp); free (temp); @@ -3799,8 +3778,8 @@ pretty_keyseq (keyseq) for (i = 0; keyseq[i]; i++) { sprintf (keyseq_rep + strlen (keyseq_rep), "%s%s", - strlen (keyseq_rep) ? " " : "", - pretty_keyname (keyseq[i])); + strlen (keyseq_rep) ? " " : "", + pretty_keyname (keyseq[i])); } return (keyseq_rep); @@ -3833,25 +3812,30 @@ display_info_keyseq (expecting_future_input) unsigned char info_get_another_input_char () { - int ready = 0; + int ready = !info_keyseq_displayed_p; /* ready if new and pending key */ /* If there isn't any input currently available, then wait a moment looking for input. If we don't get it fast enough, prompt a little bit with the current key sequence. */ - if (!info_keyseq_displayed_p && - !info_any_buffered_input_p () && - !info_input_pending_p ()) + if (!info_keyseq_displayed_p) { + ready = 1; + if (!info_any_buffered_input_p () && + !info_input_pending_p ()) + { #if defined (FD_SET) - struct timeval timer; - fd_set readfds; - - FD_ZERO (&readfds); - FD_SET (fileno (info_input_stream), &readfds); - timer.tv_sec = 0; - timer.tv_usec = 0; - ready = select (1, &readfds, (fd_set *)NULL, (fd_set *)NULL, &timer); + struct timeval timer; + fd_set readfds; + + FD_ZERO (&readfds); + FD_SET (fileno (info_input_stream), &readfds); + timer.tv_sec = 1; + timer.tv_usec = 750; + ready = select (fileno(info_input_stream)+1, &readfds, (fd_set *)NULL, (fd_set *)NULL, &timer); +#else + ready = 0; #endif /* FD_SET */ + } } if (!ready) @@ -3870,16 +3854,16 @@ info_dispatch_on_key (key, map) if (Meta_p (key) && (!ISO_Latin_p || map[key].function != ea_insert)) { if (map[ESC].type == ISKMAP) - { - map = (Keymap)map[ESC].function; - add_char_to_keyseq (ESC); - key = UnMeta (key); - info_dispatch_on_key (key, map); - } + { + map = (Keymap)map[ESC].function; + add_char_to_keyseq (ESC); + key = UnMeta (key); + info_dispatch_on_key (key, map); + } else - { - dispatch_error (info_keyseq); - } + { + dispatch_error (info_keyseq); + } return; } @@ -3887,74 +3871,74 @@ info_dispatch_on_key (key, map) { case ISFUNC: { - VFunction *func; - - func = map[key].function; - if (func != (VFunction *)NULL) - { - /* Special case info_do_lowercase_version (). */ - if (func == info_do_lowercase_version) - { - info_dispatch_on_key (tolower (key), map); - return; - } - - add_char_to_keyseq (key); - - if (info_keyseq_displayed_p) - display_info_keyseq (0); - - { - WINDOW *where; - - where = active_window; - (*map[key].function) - (active_window, info_numeric_arg * info_numeric_arg_sign, key); - - /* If we have input pending, then the last command was a prefix - command. Don't change the value of the last function vars. - Otherwise, remember the last command executed in the var - appropriate to the window in which it was executed. */ - if (!info_input_pending_p ()) - { - if (where == the_echo_area) - ea_last_executed_command = map[key].function; - else - info_last_executed_command = map[key].function; - } - } - } - else - { - add_char_to_keyseq (key); - dispatch_error (info_keyseq); - return; - } + VFunction *func; + + func = map[key].function; + if (func != (VFunction *)NULL) + { + /* Special case info_do_lowercase_version (). */ + if (func == info_do_lowercase_version) + { + info_dispatch_on_key (tolower (key), map); + return; + } + + add_char_to_keyseq (key); + + if (info_keyseq_displayed_p) + display_info_keyseq (0); + + { + WINDOW *where; + + where = active_window; + (*map[key].function) + (active_window, info_numeric_arg * info_numeric_arg_sign, key); + + /* If we have input pending, then the last command was a prefix + command. Don't change the value of the last function vars. + Otherwise, remember the last command executed in the var + appropriate to the window in which it was executed. */ + if (!info_input_pending_p ()) + { + if (where == the_echo_area) + ea_last_executed_command = map[key].function; + else + info_last_executed_command = map[key].function; + } + } + } + else + { + add_char_to_keyseq (key); + dispatch_error (info_keyseq); + return; + } } break; case ISKMAP: add_char_to_keyseq (key); if (map[key].function != (VFunction *)NULL) - { - unsigned char newkey; + { + unsigned char newkey; - newkey = info_get_another_input_char (); - info_dispatch_on_key (newkey, (Keymap)map[key].function); - } + newkey = info_get_another_input_char (); + info_dispatch_on_key (newkey, (Keymap)map[key].function); + } else - { - dispatch_error (info_keyseq); - return; - } + { + dispatch_error (info_keyseq); + return; + } break; } } /* **************************************************************** */ -/* */ -/* Numeric Arguments */ -/* */ +/* */ +/* Numeric Arguments */ +/* */ /* **************************************************************** */ /* Handle C-u style numeric args, as well as M--, and M-digits. */ @@ -3971,7 +3955,7 @@ int info_numeric_arg = 1; /* Add the current digit to the argument in progress. */ DECLARE_INFO_COMMAND (info_add_digit_to_numeric_arg, - "Add this digit to the current numeric argument") + _("Add this digit to the current numeric argument")) { info_numeric_arg_digit_loop (window, 0, key); } @@ -3980,7 +3964,7 @@ DECLARE_INFO_COMMAND (info_add_digit_to_numeric_arg, Read a key. If the key has nothing to do with arguments, then dispatch on it. If the key is the abort character then abort. */ DECLARE_INFO_COMMAND (info_universal_argument, - "Start (or multiply by 4) the current numeric argument") + _("Start (or multiply by 4) the current numeric argument")) { info_numeric_arg *= 4; info_numeric_arg_digit_loop (window, 0, 0); @@ -3995,7 +3979,7 @@ info_initialize_numeric_arg () } DECLARE_INFO_COMMAND (info_numeric_arg_digit_loop, - "Internally used by \\[universal-argument]") + _("Internally used by \\[universal-argument]")) { unsigned char pure_key; Keymap keymap = window->keymap; @@ -4003,64 +3987,64 @@ DECLARE_INFO_COMMAND (info_numeric_arg_digit_loop, while (1) { if (key) - pure_key = key; + pure_key = key; else - { - if (display_was_interrupted_p && !info_any_buffered_input_p ()) - display_update_display (windows); + { + if (display_was_interrupted_p && !info_any_buffered_input_p ()) + display_update_display (windows); - if (active_window != the_echo_area) - display_cursor_at_point (active_window); + if (active_window != the_echo_area) + display_cursor_at_point (active_window); - pure_key = key = info_get_another_input_char (); + pure_key = key = info_get_another_input_char (); - if (Meta_p (key)) - add_char_to_keyseq (ESC); + if (Meta_p (key)) + add_char_to_keyseq (ESC); - add_char_to_keyseq (UnMeta (key)); - } + add_char_to_keyseq (UnMeta (key)); + } if (Meta_p (key)) - key = UnMeta (key); + key = UnMeta (key); if (keymap[key].type == ISFUNC && - keymap[key].function == info_universal_argument) - { - info_numeric_arg *= 4; - key = 0; - continue; - } + keymap[key].function == info_universal_argument) + { + info_numeric_arg *= 4; + key = 0; + continue; + } if (isdigit (key)) - { - if (info_explicit_arg) - info_numeric_arg = (info_numeric_arg * 10) + (key - '0'); - else - info_numeric_arg = (key - '0'); - info_explicit_arg = 1; - } + { + if (info_explicit_arg) + info_numeric_arg = (info_numeric_arg * 10) + (key - '0'); + else + info_numeric_arg = (key - '0'); + info_explicit_arg = 1; + } else - { - if (key == '-' && !info_explicit_arg) - { - info_numeric_arg_sign = -1; - info_numeric_arg = 1; - } - else - { - info_keyseq_index--; - info_dispatch_on_key (pure_key, keymap); - return; - } - } + { + if (key == '-' && !info_explicit_arg) + { + info_numeric_arg_sign = -1; + info_numeric_arg = 1; + } + else + { + info_keyseq_index--; + info_dispatch_on_key (pure_key, keymap); + return; + } + } key = 0; } } /* **************************************************************** */ -/* */ -/* Input Character Buffering */ -/* */ +/* */ +/* Input Character Buffering */ +/* */ /* **************************************************************** */ /* Character waiting to be read next. */ @@ -4109,7 +4093,7 @@ info_push_typeahead (key) { info_input_buffer[push_index++] = key; if (push_index >= sizeof (info_input_buffer)) - push_index = 0; + push_index = 0; } } @@ -4148,23 +4132,6 @@ info_any_buffered_input_p () return (push_index != pop_index); } -/* Push KEY into the *front* of the input buffer. Returns non-zero if - successful, zero if there is no space left in the buffer. */ -static int -info_replace_key_to_typeahead (key) - unsigned char key; -{ - if (info_input_buffer_space_available ()) - { - pop_index--; - if (pop_index < 0) - pop_index = sizeof (info_input_buffer) - 1; - info_input_buffer[pop_index] = key; - return (1); - } - return (0); -} - /* If characters are available to be read, then read them and stuff them into info_input_buffer. Otherwise, do nothing. */ void @@ -4189,7 +4156,7 @@ info_gather_typeahead () chars_avail = space_avail; if (chars_avail) - read (tty, &input[0], chars_avail); + chars_avail = read (tty, &input[0], chars_avail); } #else /* !FIONREAD */ # if defined (O_NDELAY) @@ -4231,34 +4198,55 @@ info_get_input_char () else if (info_get_key_from_typeahead (&keystroke) == 0) { int rawkey; + unsigned char c; + int tty = fileno (info_input_stream); + + /* Using stream I/O causes FIONREAD etc to fail to work + so unless someone can find a portable way of finding + out how many characters are currently buffered, we + should stay with away from stream I/O. + --Egil Kvaleberg <egilk@sn.no>, January 1997. */ +#ifdef EINTR + /* Keep reading if we got EINTR, so that we don't just exit. + --Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>, + 22 Dec 1997. */ + { + int n; + do + n = read (tty, &c, 1); + while (n == -1 && errno == EINTR); + rawkey = n == 1 ? c : EOF; + } +#else + rawkey = (read (tty, &c, 1) == 1) ? c : EOF; +#endif - rawkey = getc (info_input_stream); keystroke = rawkey; if (rawkey == EOF) - { - if (info_input_stream != stdin) - { - fclose (info_input_stream); - info_input_stream = stdin; - display_inhibited = 0; - display_update_display (windows); - display_cursor_at_point (active_window); - rawkey = getc (info_input_stream); - keystroke = rawkey; - } - - if (rawkey == EOF) - { - terminal_unprep_terminal (); - close_dribble_file (); - exit (0); - } - } + { + if (info_input_stream != stdin) + { + fclose (info_input_stream); + info_input_stream = stdin; + display_inhibited = 0; + display_update_display (windows); + display_cursor_at_point (active_window); + rawkey = (read (tty, &c, 1) == 1) ? c : EOF; + keystroke = rawkey; + } + + if (rawkey == EOF) + { + terminal_unprep_terminal (); + close_dribble_file (); + exit (0); + } + } } if (info_dribble_file) dribble (keystroke); - return (keystroke); + return keystroke; } diff --git a/contrib/texinfo/info/signals.c b/contrib/texinfo/info/signals.c index 4f48e89..e5a427c 100644 --- a/contrib/texinfo/info/signals.c +++ b/contrib/texinfo/info/signals.c @@ -25,9 +25,9 @@ #include "signals.h" /* **************************************************************** */ -/* */ -/* Pretending That We Have POSIX Signals */ -/* */ +/* */ +/* Pretending That We Have POSIX Signals */ +/* */ /* **************************************************************** */ #if !defined (HAVE_SIGPROCMASK) && defined (HAVE_SIGSETMASK) @@ -57,36 +57,32 @@ sigprocmask (operation, newset, oldset) #endif /* !HAVE_SIGPROCMASK && HAVE_SIGSETMASK */ /* **************************************************************** */ -/* */ -/* Signal Handling for Info */ -/* */ +/* */ +/* Signal Handling for Info */ +/* */ /* **************************************************************** */ -typedef void SigHandlerType; -typedef SigHandlerType SigHandler (); +typedef RETSIGTYPE signal_handler (); -static SigHandlerType info_signal_handler (); -static SigHandler *old_TSTP, *old_TTOU, *old_TTIN; -static SigHandler *old_WINCH, *old_INT, *old_CONT; +static RETSIGTYPE info_signal_handler (); +static signal_handler *old_TSTP, *old_TTOU, *old_TTIN; +static signal_handler *old_WINCH, *old_INT; void initialize_info_signal_handler () { #if defined (SIGTSTP) - old_TSTP = (SigHandler *) signal (SIGTSTP, info_signal_handler); - old_TTOU = (SigHandler *) signal (SIGTTOU, info_signal_handler); - old_TTIN = (SigHandler *) signal (SIGTTIN, info_signal_handler); + old_TSTP = (signal_handler *) signal (SIGTSTP, info_signal_handler); + old_TTOU = (signal_handler *) signal (SIGTTOU, info_signal_handler); + old_TTIN = (signal_handler *) signal (SIGTTIN, info_signal_handler); #endif /* SIGTSTP */ #if defined (SIGWINCH) - old_WINCH = (SigHandler *) signal (SIGWINCH, info_signal_handler); -#if defined (SIGCONT) - old_CONT = (SigHandler *) signal (SIGCONT, info_signal_handler); -#endif /* SIGCONT */ -#endif /* SIGWINCH */ + old_WINCH = (signal_handler *) signal (SIGWINCH, info_signal_handler); +#endif #if defined (SIGINT) - old_INT = (SigHandler *) signal (SIGINT, info_signal_handler); + old_INT = (signal_handler *) signal (SIGINT, info_signal_handler); #endif } @@ -101,11 +97,11 @@ redisplay_after_signal () fflush (stdout); } -static SigHandlerType +static RETSIGTYPE info_signal_handler (sig) int sig; { - SigHandler **old_signal_handler; + signal_handler **old_signal_handler; switch (sig) { @@ -119,33 +115,33 @@ info_signal_handler (sig) #endif { #if defined (SIGTSTP) - if (sig == SIGTSTP) - old_signal_handler = &old_TSTP; - if (sig == SIGTTOU) - old_signal_handler = &old_TTOU; - if (sig == SIGTTIN) - old_signal_handler = &old_TTIN; + if (sig == SIGTSTP) + old_signal_handler = &old_TSTP; + if (sig == SIGTTOU) + old_signal_handler = &old_TTOU; + if (sig == SIGTTIN) + old_signal_handler = &old_TTIN; #endif /* SIGTSTP */ - if (sig == SIGINT) - old_signal_handler = &old_INT; - - /* For stop signals, restore the terminal IO, leave the cursor - at the bottom of the window, and stop us. */ - terminal_goto_xy (0, screenheight - 1); - terminal_clear_to_eol (); - fflush (stdout); - terminal_unprep_terminal (); - signal (sig, *old_signal_handler); - UNBLOCK_SIGNAL (sig); - kill (getpid (), sig); - - /* The program is returning now. Restore our signal handler, - turn on terminal handling, redraw the screen, and place the - cursor where it belongs. */ - terminal_prep_terminal (); - *old_signal_handler = (SigHandler *) signal (sig, info_signal_handler); - redisplay_after_signal (); - fflush (stdout); + if (sig == SIGINT) + old_signal_handler = &old_INT; + + /* For stop signals, restore the terminal IO, leave the cursor + at the bottom of the window, and stop us. */ + terminal_goto_xy (0, screenheight - 1); + terminal_clear_to_eol (); + fflush (stdout); + terminal_unprep_terminal (); + signal (sig, *old_signal_handler); + UNBLOCK_SIGNAL (sig); + kill (getpid (), sig); + + /* The program is returning now. Restore our signal handler, + turn on terminal handling, redraw the screen, and place the + cursor where it belongs. */ + terminal_prep_terminal (); + *old_signal_handler = (signal_handler *) signal (sig, info_signal_handler); + redisplay_after_signal (); + fflush (stdout); } break; @@ -161,23 +157,23 @@ info_signal_handler (sig) #if defined (SIGWINCH) case SIGWINCH: { - /* Turn off terminal IO, tell our parent that the window has changed, - then reinitialize the terminal and rebuild our windows. */ - old_signal_handler = &old_WINCH; - terminal_goto_xy (0, 0); - fflush (stdout); - terminal_unprep_terminal (); - signal (sig, *old_signal_handler); - UNBLOCK_SIGNAL (sig); - kill (getpid (), sig); - - /* After our old signal handler returns... */ - terminal_get_screen_size (); - terminal_prep_terminal (); - display_initialize_display (screenwidth, screenheight); - window_new_screen_size (screenwidth, screenheight, (VFunction *)NULL); - *old_signal_handler = (SigHandler *) signal (sig, info_signal_handler); - redisplay_after_signal (); + /* Turn off terminal IO, tell our parent that the window has changed, + then reinitialize the terminal and rebuild our windows. */ + old_signal_handler = &old_WINCH; + terminal_goto_xy (0, 0); + fflush (stdout); + terminal_unprep_terminal (); + signal (sig, *old_signal_handler); + UNBLOCK_SIGNAL (sig); + kill (getpid (), sig); + + /* After our old signal handler returns... */ + terminal_get_screen_size (); + terminal_prep_terminal (); + display_initialize_display (screenwidth, screenheight); + window_new_screen_size (screenwidth, screenheight, (VFunction *)NULL); + *old_signal_handler = (signal_handler *) signal (sig, info_signal_handler); + redisplay_after_signal (); } break; #endif /* SIGWINCH */ diff --git a/contrib/texinfo/info/terminal.c b/contrib/texinfo/info/terminal.c index fcf5137..8eb47c2 100644 --- a/contrib/texinfo/info/terminal.c +++ b/contrib/texinfo/info/terminal.c @@ -1,12 +1,8 @@ -/* terminal.c -- How to handle the physical terminal for Info. */ +/* terminal.c -- How to handle the physical terminal for Info. + $Id: terminal.c,v 1.9 1998/02/22 00:05:15 karl Exp $ -/* This file is part of GNU Info, a program for reading online documentation - stored in Info format. - - This file has appeared in prior works by the Free Software Foundation; - thus it carries copyright dates from 1988 through 1993. - - Copyright (C) 1988, 89, 90, 91, 92, 93, 96 Free Software Foundation, Inc. + Copyright (C) 1988, 89, 90, 91, 92, 93, 96, 97, 98 + 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 @@ -24,20 +20,33 @@ Written by Brian Fox (bfox@ai.mit.edu). */ -#include <stdio.h> -#include <stdlib.h> -#include <sys/types.h> +#include "info.h" #include "terminal.h" #include "termdep.h" -extern void *xmalloc (), *xrealloc (); +#include <sys/types.h> +#include <signal.h> /* The Unix termcap interface code. */ +#ifdef HAVE_NCURSES_TERMCAP_H +#include <ncurses/termcap.h> +#else +#ifdef HAVE_TERMCAP_H +#include <termcap.h> +#else +/* On Solaris2, sys/types.h #includes sys/reg.h, which #defines PC. + Unfortunately, PC is a global variable used by the termcap library. */ +#undef PC +/* Termcap requires these variables, whether we access them or not. */ +char *BC, *UP; +char PC; /* Pad character */ +short ospeed; /* Terminal output baud rate */ extern int tgetnum (), tgetflag (), tgetent (); extern char *tgetstr (), *tgoto (); -extern char *getenv (); extern void tputs (); +#endif /* not HAVE_TERMCAP_H */ +#endif /* not HAVE_NCURSES_TERMCAP_H */ /* Function "hooks". If you make one of these point to a function, that function is called when appropriate instead of its namesake. Your @@ -61,20 +70,11 @@ VFunction *terminal_write_chars_hook = (VFunction *)NULL; VFunction *terminal_scroll_terminal_hook = (VFunction *)NULL; /* **************************************************************** */ -/* */ -/* Terminal and Termcap */ -/* */ +/* */ +/* Terminal and Termcap */ +/* */ /* **************************************************************** */ -/* On Solaris2, sys/types.h #includes sys/reg.h, which #defines PC. - Unfortunately, PC is a global variable used by the termcap library. */ -#undef PC - -/* TERMCAP requires these variables, whether we access them or not. */ -char PC; -char *BC, *UP; -short ospeed; - /* A buffer which holds onto the current terminal description, and a pointer used to float within it. */ static char *term_buffer = (char *)NULL; @@ -85,6 +85,8 @@ static char *term_goto, *term_clreol, *term_cr, *term_clrpag; static char *term_begin_use, *term_end_use; static char *term_AL, *term_DL, *term_al, *term_dl; +static char *term_keypad_on, *term_keypad_off; + /* How to go up a line. */ static char *term_up; @@ -115,11 +117,15 @@ static char *term_ks; /* The string to turn off keypad transmit mode, if this term has one. */ static char *term_ke; -static void +/* Although I can't find any documentation that says this is supposed to + return its argument, all the code I've looked at (termutils, less) + does so, so fine. */ +static int output_character_function (c) int c; { putc (c, stdout); + return c; } /* Macro to send STRING to the terminal. */ @@ -129,29 +135,65 @@ output_character_function (c) tputs (string, 1, output_character_function); \ } while (0) -/* Tell the terminal that we will be doing cursor addressable motion. */ +/* Tell the terminal that we will be doing cursor addressable motion. */ static void terminal_begin_using_terminal () { + RETSIGTYPE (*sigsave) (); + + if (term_keypad_on) + send_to_terminal (term_keypad_on); + + if (!term_begin_use || !*term_begin_use) + return; + +#ifdef SIGWINCH + sigsave = signal (SIGWINCH, SIG_IGN); +#endif + send_to_terminal (term_begin_use); - if (term_ks) - send_to_terminal(term_ks); + /* Without this fflush and sleep, running info in a shelltool or + cmdtool (TERM=sun-cmd) with scrollbars loses -- the scrollbars are + not restored properly. + From: strube@physik3.gwdg.de (Hans Werner Strube). */ + fflush (stdout); + sleep (1); + +#ifdef SIGWINCH + signal (SIGWINCH, sigsave); +#endif } -/* Tell the terminal that we will not be doing any more cursor addressable - motion. */ +/* Tell the terminal that we will not be doing any more cursor + addressable motion. */ static void terminal_end_using_terminal () { - if (term_ke) - send_to_terminal(term_ke); + RETSIGTYPE (*sigsave) (); + + if (term_keypad_off) + send_to_terminal (term_keypad_off); + + if (!term_end_use || !*term_end_use) + return; + +#ifdef SIGWINCH + sigsave = signal (SIGWINCH, SIG_IGN); +#endif + send_to_terminal (term_end_use); + fflush (stdout); + sleep (1); + +#ifdef SIGWINCH + signal (SIGWINCH, sigsave); +#endif } /* **************************************************************** */ -/* */ -/* Necessary Terminal Functions */ -/* */ +/* */ +/* Necessary Terminal Functions */ +/* */ /* **************************************************************** */ /* The functions and variables on this page implement the user visible @@ -180,11 +222,8 @@ char *term_ku = (char *)NULL; char *term_kd = (char *)NULL; char *term_kr = (char *)NULL; char *term_kl = (char *)NULL; -char *term_kP = (char *)NULL; -char *term_kN = (char *)NULL; -char *term_kh = (char *)NULL; -char *term_kH = (char *)NULL; - +char *term_kP = (char *)NULL; /* page-up */ +char *term_kN = (char *)NULL; /* page-down */ /* Move the cursor to the terminal location of X and Y. */ void @@ -196,7 +235,7 @@ terminal_goto_xy (x, y) else { if (term_goto) - tputs (tgoto (term_goto, x, y), 1, output_character_function); + tputs (tgoto (term_goto, x, y), 1, output_character_function); } } @@ -224,7 +263,7 @@ terminal_write_chars (string, nchars) else { if (nchars) - fwrite (string, 1, nchars, stdout); + fwrite (string, 1, nchars, stdout); } } @@ -310,9 +349,9 @@ terminal_ring_bell () else { if (terminal_has_visible_bell_p && terminal_use_visible_bell_p) - send_to_terminal (visible_bell); + send_to_terminal (visible_bell); else - send_to_terminal (audible_bell); + send_to_terminal (audible_bell); } } @@ -334,7 +373,7 @@ terminal_delete_lines (start, count) else { while (count--) - tputs (term_dl, lines, output_character_function); + tputs (term_dl, lines, output_character_function); } fflush (stdout); @@ -359,7 +398,7 @@ terminal_insert_lines (start, count) else { while (count--) - tputs (term_al, lines, output_character_function); + tputs (term_al, lines, output_character_function); } fflush (stdout); @@ -385,22 +424,22 @@ terminal_scroll_terminal (start, end, amount) else { /* If we are scrolling down, delete AMOUNT lines at END. Then insert - AMOUNT lines at START. */ + AMOUNT lines at START. */ if (amount > 0) - { - terminal_delete_lines (end, amount); - terminal_insert_lines (start, amount); - } + { + terminal_delete_lines (end, amount); + terminal_insert_lines (start, amount); + } /* If we are scrolling up, delete AMOUNT lines before START. This - actually does the upwards scroll. Then, insert AMOUNT lines - after the already scrolled region (i.e., END - AMOUNT). */ + actually does the upwards scroll. Then, insert AMOUNT lines + after the already scrolled region (i.e., END - AMOUNT). */ if (amount < 0) - { - int abs_amount = -amount; - terminal_delete_lines (start - abs_amount, abs_amount); - terminal_insert_lines (end - abs_amount, abs_amount); - } + { + int abs_amount = -amount; + terminal_delete_lines (start - abs_amount, abs_amount); + terminal_insert_lines (end - abs_amount, abs_amount); + } } } @@ -430,55 +469,55 @@ terminal_get_screen_size () #if defined (TIOCGWINSZ) { - struct winsize window_size; + struct winsize window_size; - if (ioctl (fileno (stdout), TIOCGWINSZ, &window_size) == 0) - { - screenwidth = (int) window_size.ws_col; - screenheight = (int) window_size.ws_row; - } + if (ioctl (fileno (stdout), TIOCGWINSZ, &window_size) == 0) + { + screenwidth = (int) window_size.ws_col; + screenheight = (int) window_size.ws_row; + } } -#endif /* TIOCGWINSZ */ +#endif /* TIOCGWINSZ */ /* Environment variable COLUMNS overrides setting of "co". */ if (screenwidth <= 0) - { - char *sw = getenv ("COLUMNS"); + { + char *sw = getenv ("COLUMNS"); - if (sw) - screenwidth = atoi (sw); + if (sw) + screenwidth = atoi (sw); - if (screenwidth <= 0) - screenwidth = tgetnum ("co"); - } + if (screenwidth <= 0) + screenwidth = tgetnum ("co"); + } /* Environment variable LINES overrides setting of "li". */ if (screenheight <= 0) - { - char *sh = getenv ("LINES"); + { + char *sh = getenv ("LINES"); - if (sh) - screenheight = atoi (sh); + if (sh) + screenheight = atoi (sh); - if (screenheight <= 0) - screenheight = tgetnum ("li"); - } + if (screenheight <= 0) + screenheight = tgetnum ("li"); + } /* If all else fails, default to 80x24 terminal. */ if (screenwidth <= 0) - screenwidth = 80; + screenwidth = 80; if (screenheight <= 0) - screenheight = 24; + screenheight = 24; } } -/* Initialize the terminal which is known as TERMINAL_NAME. If this terminal - doesn't have cursor addressability, TERMINAL_IS_DUMB_P becomes non-zero. - The variables SCREENHEIGHT and SCREENWIDTH are set to the dimensions that - this terminal actually has. The variable TERMINAL_HAS_META_P becomes non- - zero if this terminal supports a Meta key. Finally, the terminal screen is - cleared. */ +/* Initialize the terminal which is known as TERMINAL_NAME. If this + terminal doesn't have cursor addressability, `terminal_is_dumb_p' + becomes nonzero. The variables SCREENHEIGHT and SCREENWIDTH are set + to the dimensions that this terminal actually has. The variable + TERMINAL_HAS_META_P becomes nonzero if this terminal supports a Meta + key. Finally, the terminal screen is cleared. */ void terminal_initialize_terminal (terminal_name) char *terminal_name; @@ -516,7 +555,7 @@ terminal_initialize_terminal (terminal_name) term_cr = "\r"; term_up = term_dn = audible_bell = visible_bell = (char *)NULL; term_ku = term_kd = term_kl = term_kr = (char *)NULL; - term_kP = term_kN = term_kh = term_kH = (char *)NULL; + term_kP = term_kN = (char *)NULL; return; } @@ -534,7 +573,7 @@ terminal_initialize_terminal (terminal_name) } #else ospeed = B9600; -#endif /* !TIOCGETP */ +#endif /* !TIOCGETP */ term_cr = tgetstr ("cr", &buffer); term_clreol = tgetstr ("ce", &buffer); @@ -570,6 +609,9 @@ terminal_initialize_terminal (terminal_name) term_begin_use = tgetstr ("ti", &buffer); term_end_use = tgetstr ("te", &buffer); + term_keypad_on = tgetstr ("ks", &buffer); + term_keypad_off = tgetstr ("ke", &buffer); + /* Check to see if this terminal has a meta key. */ terminal_has_meta_p = (tgetflag ("km") || tgetflag ("MT")); if (terminal_has_meta_p) @@ -588,26 +630,19 @@ terminal_initialize_terminal (terminal_name) term_kd = tgetstr ("kd", &buffer); term_kr = tgetstr ("kr", &buffer); term_kl = tgetstr ("kl", &buffer); + term_kP = tgetstr ("kP", &buffer); term_kN = tgetstr ("kN", &buffer); - term_kh = tgetstr ("kh", &buffer); - term_kH = tgetstr ("kH", &buffer); - - /* Enable keypad and cursor keys if ks defined */ - term_ks = tgetstr ("ks", &buffer); - term_ke = tgetstr ("ke", &buffer); /* If this terminal is not cursor addressable, then it is really dumb. */ if (!term_goto) terminal_is_dumb_p = 1; - - terminal_begin_using_terminal (); } /* **************************************************************** */ -/* */ -/* How to Read Characters From the Terminal */ -/* */ +/* */ +/* How to Read Characters From the Terminal */ +/* */ /* **************************************************************** */ #if defined (TIOCGETC) @@ -648,6 +683,8 @@ terminal_prep_terminal () return; } + terminal_begin_using_terminal (); + tty = fileno (stdin); #if defined (HAVE_TERMIOS_H) @@ -662,7 +699,14 @@ terminal_prep_terminal () #if defined (HAVE_TERMIOS_H) || defined (HAVE_TERMIO_H) ttybuff.c_iflag &= (~ISTRIP & ~INLCR & ~IGNCR & ~ICRNL & ~IXON); - ttybuff.c_oflag &= (~ONLCR); +/* These output flags are not part of POSIX, so only use them if they + are defined. */ +#ifdef ONLCR + ttybuff.c_oflag &= ~ONLCR ; +#endif +#ifdef OCRNL + ttybuff.c_oflag &= ~OCRNL; +#endif ttybuff.c_lflag &= (~ICANON & ~ECHO); ttybuff.c_cc[VMIN] = 1; @@ -673,7 +717,12 @@ terminal_prep_terminal () if (ttybuff.c_cc[VQUIT] == '\177') ttybuff.c_cc[VQUIT] = -1; -#endif + +#ifdef VLNEXT + if (ttybuff.c_cc[VLNEXT] == '\026') + ttybuff.c_cc[VLNEXT] = -1; +#endif /* VLNEXT */ +#endif /* TERMIOS or TERMIO */ #if defined (HAVE_TERMIOS_H) tcsetattr (tty, TCSANOW, &ttybuff); @@ -737,9 +786,9 @@ terminal_prep_terminal () temp = original_ltchars; /* Make the interrupt keys go away. Just enough to make people happy. */ - temp.t_lnextc = -1; /* C-v. */ - temp.t_dsuspc = -1; /* C-y. */ - temp.t_flushc = -1; /* C-o. */ + temp.t_lnextc = -1; /* C-v. */ + temp.t_dsuspc = -1; /* C-y. */ + temp.t_flushc = -1; /* C-o. */ ioctl (tty, TIOCSLTC, &temp); } # endif /* TIOCGLTC */ diff --git a/contrib/texinfo/makeinfo/makeinfo.c b/contrib/texinfo/makeinfo/makeinfo.c index f30d366..ef892db 100644 --- a/contrib/texinfo/makeinfo/makeinfo.c +++ b/contrib/texinfo/makeinfo/makeinfo.c @@ -1,7 +1,8 @@ -/* Makeinfo -- convert texinfo format files into info files. - $Id: makeinfo.c,v 1.37 1996/10/04 18:20:52 karl Exp $ +/* Makeinfo -- convert Texinfo source files into Info files. + $Id: makeinfo.c,v 1.60 1998/02/25 20:36:22 karl Exp $ - Copyright (C) 1987, 92, 93, 94, 95, 96 Free Software Foundation, Inc. + Copyright (C) 1987, 92, 93, 94, 95, 96, 97, 98 + 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,12 +18,58 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - Makeinfo is authored by Brian Fox (bfox@ai.mit.edu). */ + Makeinfo was authored by Brian Fox (bfox@ai.mit.edu). */ + +/* Indent #pragma so that older Cpp's don't try to parse it. */ +#ifdef _AIX + #pragma alloca +#endif /* _AIX */ int major_version = 1; -int minor_version = 67; +int minor_version = 68; + +#include "system.h" +#include "getopt.h" + +#ifdef TM_IN_SYS_TIME +#include <sys/time.h> +#else +#include <time.h> +#endif /* !TM_IN_SYS_TIME */ + +#ifdef __GNUC__ +# undef alloca +# define alloca __builtin_alloca +#else +# ifdef HAVE_ALLOCA_H +# include <alloca.h> +# else +# ifndef _AIX +char *alloca (); +# endif +# endif +#endif + +/* We'd like to take advantage of _doprnt if it's around, a la error.c, + but then we'd have no VA_SPRINTF. */ +#if HAVE_VPRINTF +# if __STDC__ +# include <stdarg.h> +# define VA_START(args, lastarg) va_start(args, lastarg) +# else +# include <varargs.h> +# define VA_START(args, lastarg) va_start(args) +# endif +# define VA_FPRINTF(file, fmt, ap) vfprintf (file, fmt, ap) +# define VA_SPRINTF(str, fmt, ap) vsprintf (str, fmt, ap) +#else /* not HAVE_VPRINTF */ +# define VA_START(args, lastarg) +# define va_alist a1, a2, a3, a4, a5, a6, a7, a8 +# define va_dcl char *a1, *a2, *a3, *a4, *a5, *a6, *a7, *a8; +# define va_end(args) +#endif -/* You can change some of the behaviour of Makeinfo by changing the +/* You can change some of the behavior of Makeinfo by changing the following defines: */ /* Define INDENT_PARAGRAPHS_IN_TABLE if you want the paragraphs which @@ -50,113 +97,48 @@ int minor_version = 67; #define DEFAULT_PARAGRAPH_SPACING 1 /* Define HAVE_MACROS to enable the macro facility of Texinfo. Using this - facility, users can create their own command procedures with arguments. */ + facility, users can create their own command procedures with + arguments. Must always be defined. */ #define HAVE_MACROS -/* Indent #pragma so that older Cpp's don't try to parse it. */ -#if defined (_AIX) - # pragma alloca -#endif /* _AIX */ - -#include <stdio.h> -#include <sys/types.h> -#include <ctype.h> -#include <sys/stat.h> -#include <pwd.h> -#include <errno.h> - -#if defined (HAVE_VARARGS_H) -#include <varargs.h> -#endif /* HAVE_VARARGS_H */ -#include "getopt.h" - -#if defined (HAVE_UNISTD_H) -#include <unistd.h> -#endif /* HAVE_UNISTD_H */ - -#if defined (VMS) -#include <perror.h> -#endif - -#if defined (HAVE_STRING_H) -#include <string.h> -#else -#include <strings.h> -#endif /* !HAVE_STRING_H */ - -#if defined (TM_IN_SYS_TIME) -#include <sys/time.h> -#else -#include <time.h> -#endif /* !TM_IN_SYS_TIME */ - -#if defined (HAVE_SYS_FCNTL_H) -#include <sys/fcntl.h> -#else -#include <fcntl.h> -#endif /* !HAVE_SYS_FCNTL_H */ - -#if defined (HAVE_SYS_FILE_H) -#include <sys/file.h> -#endif /* HAVE_SYS_FILE_H */ - -#if defined (__GNUC__) -#define alloca __builtin_alloca -#else -#if defined(HAVE_ALLOCA_H) -#include <alloca.h> -#else /* !HAVE_ALLOCA_H */ -#if !defined (_AIX) -extern char *alloca (); -#endif /* !_AIX */ -#endif /* !HAVE_ALLOCA_H */ -#endif /* !__GNUC__ */ - -void *xmalloc (), *xrealloc (); -#if defined (__osf__) -extern void *malloc (), *realloc (); -#endif /* __osf__ */ - -char **get_brace_args (); -int array_len (); -void free_array (); -static void isolate_nodename (); - #define COMPILING_MAKEINFO #include "makeinfo.h" -/* Non-zero means that we are currently hacking the insides of an +/* Nonzero means that we are currently hacking the insides of an insertion which would use a fixed width font. */ static int in_fixed_width_font = 0; -/* Non-zero means that start_paragraph () MUST be called before we pay +/* Nonzero means that start_paragraph () MUST be called before we pay any attention to close_paragraph () calls. */ int must_start_paragraph = 0; -/* Non-zero means a string is in execution, as opposed to a file. */ +/* Nonzero means a string is in execution, as opposed to a file. */ static int executing_string = 0; +/* Nonzero means a macro string is in execution, as opposed to a file. */ +static int me_executing_string = 0; + #if defined (HAVE_MACROS) /* If non-NULL, this is an output stream to write the full macro expansion - of the input text to. The resultant file is another texinfo file, but + of the input text to. The result is another texinfo file, but missing @include, @infoinclude, @macro, and macro invocations. Instead, all of the text is placed within the file. */ FILE *macro_expansion_output_stream = (FILE *)NULL; +char *macro_expansion_filename; /* Here is a structure used to remember input text strings and offsets within them. */ typedef struct { - char *pointer; /* Pointer to the input text. */ - int offset; /* Offset of the last character output. */ + char *pointer; /* Pointer to the input text. */ + int offset; /* Offset of the last character output. */ } ITEXT; static ITEXT **itext_info = (ITEXT **)NULL; static int itext_size = 0; -/* Non-zero means to inhibit the writing of macro expansions to the output - stream. This is used in special cases where the output has already been - written. */ +/* Nonzero means to inhibit writing macro expansions to the output + stream, because it has already been written. */ int me_inhibit_expansion = 0; ITEXT *remember_itext (); @@ -165,19 +147,17 @@ void append_to_expansion_output (), write_region_to_macro_output (); void maybe_write_itext (), me_execute_string (); #endif /* HAVE_MACROS */ -/* Some systems don't declare this function in pwd.h. */ -struct passwd *getpwnam (); /* **************************************************************** */ -/* */ -/* Global Variables */ -/* */ +/* */ +/* Global Variables */ +/* */ /* **************************************************************** */ /* Global pointer to argv[0]. */ char *progname; -/* Return non-zero if STRING is the text at input_text + input_text_offset, +/* Return nonzero if STRING is the text at input_text + input_text_offset, else zero. */ #define looking_at(string) \ (strncmp (input_text + input_text_offset, string, strlen (string)) == 0) @@ -196,24 +176,20 @@ char *command_output_filename = (char *)NULL; with @include. This can be controlled with the `-I' option to makeinfo. */ char *include_files_path = (char *)NULL; -/* Current output stream. */ -FILE *output_stream; - /* Position in the output file. */ int output_position; #define INITIAL_PARAGRAPH_SPACE 5000 int paragraph_buffer_len = INITIAL_PARAGRAPH_SPACE; -/* Filling.. */ -/* Non-zero indicates that filling will take place on long lines. */ +/* Nonzero indicates that filling will take place on long lines. */ int filling_enabled = 1; -/* Non-zero means that words are not to be split, even in long lines. This +/* Nonzero means that words are not to be split, even in long lines. This gets changed for cm_w (). */ int non_splitting_words = 0; -/* Non-zero indicates that filling a line also indents the new line. */ +/* Nonzero indicates that filling a line also indents the new line. */ int indented_fill = 0; /* The amount of indentation to add at the starts of paragraphs. @@ -226,7 +202,7 @@ int indented_fill = 0; this is 3. */ int paragraph_start_indent = PARAGRAPH_START_INDENT; -/* Non-zero means that the use of paragraph_start_indent is inhibited. +/* Nonzero means that the use of paragraph_start_indent is inhibited. @example uses this to line up the left columns of the example text. A negative value for this variable is incremented each time it is used. @noindent uses this to inhibit indentation for a single paragraph. */ @@ -240,17 +216,17 @@ int pending_indent = 0; /* The amount that indentation increases/decreases by. */ int default_indentation_increment = DEFAULT_INDENTATION_INCREMENT; -/* Non-zero indicates that indentation is temporarily turned off. */ +/* Nonzero indicates that indentation is temporarily turned off. */ int no_indent = 1; -/* Non-zero means forcing output text to be flushright. */ +/* Nonzero means forcing output text to be flushright. */ int force_flush_right = 0; -/* Non-zero means that the footnote style for this document was set on +/* Nonzero means that the footnote style for this document was set on the command line, which overrides any other settings. */ int footnote_style_preset = 0; -/* Non-zero means that we automatically number footnotes that have no +/* Nonzero means that we automatically number footnotes that have no specified marker. */ int number_footnotes = 1; @@ -267,16 +243,16 @@ int command_index; /* A search string which is used to find a line defining a node. */ char node_search_string[] = - { '\n', COMMAND_PREFIX, 'n', 'o', 'd', 'e', ' ', '\0' }; + { '\n', COMMAND_PREFIX, 'n', 'o', 'd', 'e', ' ', 0 }; /* A search string which is used to find a line defining a menu. */ char menu_search_string[] = - { '\n', COMMAND_PREFIX, 'm', 'e', 'n', 'u', '\0' }; + { '\n', COMMAND_PREFIX, 'm', 'e', 'n', 'u', 0 }; /* A search string which is used to find the first @setfilename. */ char setfilename_search[] = { COMMAND_PREFIX, - 's', 'e', 't', 'f', 'i', 'l', 'e', 'n', 'a', 'm', 'e', '\0' }; + 's', 'e', 't', 'f', 'i', 'l', 'e', 'n', 'a', 'm', 'e', 0 }; /* A stack of file information records. If a new file is read in with "@input", we remember the old input file state on this stack. */ @@ -306,15 +282,15 @@ char *node_filename = (char *)NULL; typedef struct tentry { struct tentry *next_ent; - char *node; /* name of this node. */ - char *prev; /* name of "Prev:" for this node. */ - char *next; /* name of "Next:" for this node. */ - char *up; /* name of "Up:" for this node. */ - int position; /* output file position of this node. */ - int line_no; /* defining line in source file. */ - char *filename; /* The file that this node was found in. */ - int touched; /* non-zero means this node has been referenced. */ - int flags; /* Room for growth. Right now, contains 1 bit. */ + char *node; /* name of this node. */ + char *prev; /* name of "Prev:" for this node. */ + char *next; /* name of "Next:" for this node. */ + char *up; /* name of "Up:" for this node. */ + int position; /* output file position of this node. */ + int line_no; /* defining line in source file. */ + char *filename; /* The file that this node was found in. */ + int touched; /* Nonzero means this node has been referenced. */ + int flags; /* Room for growth. Right now, contains 1 bit. */ } TAG_ENTRY; /* If node-a has a "Next" for node-b, but node-b has no "Prev" for node-a, @@ -324,24 +300,30 @@ typedef struct tentry #define PREV_ERROR 0x1 #define NEXT_ERROR 0x2 #define UP_ERROR 0x4 -#define NO_WARN 0x8 -#define IS_TOP 0x10 +#define NO_WARN 0x8 +#define IS_TOP 0x10 TAG_ENTRY *tag_table = (TAG_ENTRY *) NULL; +/* Values for calling handle_variable_internal (). */ +#define SET 1 +#define CLEAR 2 +#define IFSET 3 +#define IFCLEAR 4 + #if defined (HAVE_MACROS) -#define ME_RECURSE 0x01 -#define ME_QUOTE_ARG 0x02 +#define ME_RECURSE 0x01 +#define ME_QUOTE_ARG 0x02 /* Macro definitions for user-defined commands. */ typedef struct { - char *name; /* Name of the macro. */ - char **arglist; /* Args to replace when executing. */ - char *body; /* Macro body. */ - char *source_file; /* File where this macro is defined. */ - int source_lineno; /* Line number within FILENAME. */ - int inhibited; /* Non-zero means make find_macro () fail. */ - int flags; /* ME_RECURSE, ME_QUOTE_ARG, etc. */ + char *name; /* Name of the macro. */ + char **arglist; /* Args to replace when executing. */ + char *body; /* Macro body. */ + char *source_file; /* File where this macro is defined. */ + int source_lineno; /* Line number within FILENAME. */ + int inhibited; /* Nonzero means make find_macro () fail. */ + int flags; /* ME_RECURSE, ME_QUOTE_ARG, etc. */ } MACRO_DEF; void add_macro (), execute_macro (); @@ -361,12 +343,12 @@ enum reftype typedef struct node_ref { struct node_ref *next; - char *node; /* Name of node referred to. */ - char *containing_node; /* Name of node containing this reference. */ - int line_no; /* Line number where the reference occurs. */ - int section; /* Section level where the reference occurs. */ - char *filename; /* Name of file where the reference occurs. */ - enum reftype type; /* Type of reference, either menu or note. */ + char *node; /* Name of node referred to. */ + char *containing_node; /* Name of node containing this reference. */ + int line_no; /* Line number where the reference occurs. */ + int section; /* Section level where the reference occurs. */ + char *filename; /* Name of file where the reference occurs. */ + enum reftype type; /* Type of reference, either menu or note. */ } NODE_REF; /* The linked list of such structures. */ @@ -378,21 +360,24 @@ int in_menu = 0; /* Flag which tells us how to examine menu lines. */ int in_detailmenu = 0; -/* Non-zero means that we have seen "@top" once already. */ +/* Nonzero means that we have seen "@top" once already. */ int top_node_seen = 0; -/* Non-zero means that we have seen a non-"@top" node already. */ +/* Nonzero means that we have seen a non-"@top" node already. */ int non_top_node_seen = 0; /* Flags controlling the operation of the program. */ +/* Default is to remove output if there were errors. */ +int force = 0; + /* Default is to notify users of bad choices. */ int print_warnings = 1; /* Default is to check node references. */ int validating = 1; -/* Non-zero means do not output "Node: Foo" for node separations. */ +/* Nonzero means do not output "Node: Foo" for node separations. */ int no_headers = 0; /* Number of errors that we tolerate on a given fileset. */ @@ -401,11 +386,11 @@ int max_error_level = 100; /* Maximum number of references to a single node before complaining. */ int reference_warning_limit = 1000; -/* Non-zero means print out information about what is going on when it +/* Nonzero means print out information about what is going on when it is going on. */ int verbose_mode = 0; -/* Non-zero means to be relaxed about the input file. This is useful when +/* Nonzero means to be relaxed about the input file. This is useful when we can successfully format the input, but it doesn't strictly match our somewhat pedantic ideas of correctness. Right now, it affects what @table and @itemize do without arguments. */ @@ -431,17 +416,12 @@ typedef struct brace_element BRACE_ELEMENT *brace_stack = (BRACE_ELEMENT *) NULL; -/* Forward declarations. */ -#if !defined (HAVE_STRDUP) -extern char *strdup (); -#endif /* HAVE_STRDUP */ - extern void do_multitable (); void print_version_info (); void usage (); void push_node_filename (), pop_node_filename (); -void remember_error (); +void remember_error (), flush_file_stack (); void convert_from_stream (), convert_from_file (), convert_from_loaded_file (); void init_internals (), init_paragraph (), init_brace_stack (); void init_insertion_stack (), init_indices (); @@ -449,21 +429,34 @@ void init_tag_table (), write_tag_table (), write_tag_table_internal (); void validate_file (), validate_other_references (), split_file (); void free_node_references (), do_enumeration (), handle_variable (); void handle_variable_internal (); -void execute_string (); void normalize_node_name (); void undefindex (), top_defindex (), gen_defindex (); void define_user_command (); void free_pending_notes (), output_pending_notes (); +char **get_brace_args (); +char *expansion (); +int array_len (); +void free_array (); +static int end_of_sentence_p (); +static void isolate_nodename (); void reader_loop (), read_command (); void remember_brace (), remember_brace_1 (); void pop_and_call_brace (), discard_braces (); -void add_word_args (), add_word (), add_char (), insert (), flush_output (); +void add_word (), add_char (), insert (), flush_output (); void insert_string (); void close_paragraph_with_lines (), close_paragraph (); void ignore_blank_line (); -void do_flush_right_indentation (); +void do_flush_right_indentation (), discard_insertions (); void start_paragraph (), indent (); +#if defined (VA_FPRINTF) && __STDC__ +/* Unfortunately we must use prototypes if we are to use <stdarg.h>. */ +void add_word_args (char *, ...); +void execute_string (char *, ...); +#else +void add_word_args (); +void execute_string (); +#endif /* will not use prototypes */ void insert_self (), insert_space (), cm_ignore_line (); @@ -471,8 +464,8 @@ void cm_TeX (), cm_asterisk (), cm_bullet (), cm_cite (), cm_code (), cm_copyright (), cm_ctrl (), cm_dfn (), cm_dircategory (), cm_direntry (), cm_dots (), cm_emph (), cm_enddots (), - cm_kbd (), cm_angle_brackets (), cm_no_op (), cm_not_fixed_width (), - cm_strong (), cm_var (), cm_w (); + cm_kbd (), cm_key (), cm_no_op (), cm_no_op_line_arg (), + cm_not_fixed_width (), cm_strong (), cm_var_sc (), cm_w (), cm_image (); /* Sectioning. */ void @@ -483,21 +476,22 @@ void cm_heading (), cm_chapheading (), cm_subheading (), cm_subsubheading (), cm_majorheading (), cm_raisesections (), cm_lowersections (); -/* All @defxxx commands map to cm_defun, most accent commands map to +/* All @def... commands map to cm_defun, most accent commands map to cm_accent, most non-English letters map to cm_special_char. */ void cm_defun (), cm_accent (), cm_special_char (), cm_dotless (); void cm_node (), cm_menu (), cm_xref (), cm_ftable (), cm_vtable (), cm_pxref (), - cm_inforef (), cm_quotation (), cm_display (), cm_itemize (), + cm_inforef (), cm_uref (), cm_email (), cm_quotation (), + cm_display (), cm_itemize (), cm_enumerate (), cm_tab (), cm_table (), cm_itemx (), cm_noindent (), cm_setfilename (), cm_br (), cm_sp (), cm_page (), cm_group (), cm_center (), cm_include (), cm_bye (), cm_item (), cm_end (), - cm_ifinfo (), cm_kindex (), cm_cindex (), + cm_ifinfo (), cm_ifnothtml (), cm_ifnottex (), cm_kindex (), cm_cindex (), cm_findex (), cm_pindex (), cm_vindex (), cm_tindex (), cm_synindex (), cm_printindex (), cm_minus (), cm_footnote (), cm_example (), cm_smallexample (), cm_lisp (), cm_format (), cm_exdent (), - cm_defindex (), cm_defcodeindex (), cm_sc (), cm_result (), cm_expansion (), + cm_defindex (), cm_defcodeindex (), cm_result (), cm_expansion (), cm_equiv (), cm_print (), cm_error (), cm_point (), cm_today (), cm_flushleft (), cm_flushright (), cm_smalllisp (), cm_finalout (), cm_cartouche (), cm_detailmenu (), cm_multitable (); @@ -532,7 +526,7 @@ int user_command_array_len = 0; #define NO_BRACE_ARGS 0 #define BRACE_ARGS 1 -static COMMAND CommandTable[] = { +static COMMAND command_table[] = { { "\t", insert_space, NO_BRACE_ARGS }, { "\n", insert_space, NO_BRACE_ARGS }, { " ", insert_self, NO_BRACE_ARGS }, @@ -632,7 +626,7 @@ static COMMAND CommandTable[] = { { "dotaccent", cm_accent, BRACE_ARGS }, { "dotless", cm_dotless, BRACE_ARGS }, { "dots", cm_dots, BRACE_ARGS }, - { "email", cm_angle_brackets, BRACE_ARGS }, + { "email", cm_email, BRACE_ARGS }, { "emph", cm_emph, BRACE_ARGS }, { "end", cm_end, NO_BRACE_ARGS }, { "enddots", cm_enddots, BRACE_ARGS }, @@ -655,29 +649,33 @@ static COMMAND CommandTable[] = { { "group", cm_group, NO_BRACE_ARGS }, { "heading", cm_heading, NO_BRACE_ARGS }, { "headings", cm_ignore_line, NO_BRACE_ARGS }, + { "html", command_name_condition, NO_BRACE_ARGS }, { "hyphenation", cm_no_op, BRACE_ARGS }, { "i", cm_not_fixed_width, BRACE_ARGS }, { "ifclear", cm_ifclear, NO_BRACE_ARGS }, { "ifeq", cm_ifeq, NO_BRACE_ARGS }, { "ifhtml", command_name_condition, NO_BRACE_ARGS }, { "ifinfo", cm_ifinfo, NO_BRACE_ARGS }, + { "ifnothtml", cm_ifnothtml, NO_BRACE_ARGS }, + { "ifnotinfo", command_name_condition, NO_BRACE_ARGS }, + { "ifnottex", cm_ifnottex, NO_BRACE_ARGS }, { "ifset", cm_ifset, NO_BRACE_ARGS }, { "iftex", command_name_condition, NO_BRACE_ARGS }, { "ignore", command_name_condition, NO_BRACE_ARGS }, + { "image", cm_image, BRACE_ARGS }, { "include", cm_include, NO_BRACE_ARGS }, { "inforef", cm_inforef, BRACE_ARGS }, { "item", cm_item, NO_BRACE_ARGS }, { "itemize", cm_itemize, NO_BRACE_ARGS }, { "itemx", cm_itemx, NO_BRACE_ARGS }, { "kbd", cm_kbd, BRACE_ARGS }, - { "key", cm_angle_brackets, BRACE_ARGS }, + { "kbdinputstyle", cm_no_op_line_arg, NO_BRACE_ARGS }, + { "key", cm_key, BRACE_ARGS }, { "kindex", cm_kindex, NO_BRACE_ARGS }, { "l", cm_special_char, BRACE_ARGS }, { "lisp", cm_lisp, NO_BRACE_ARGS }, { "lowersections", cm_lowersections, NO_BRACE_ARGS }, -#if defined (HAVE_MACROS) { "macro", cm_macro, NO_BRACE_ARGS }, -#endif { "majorheading", cm_majorheading, NO_BRACE_ARGS }, { "math", cm_no_op, BRACE_ARGS }, { "menu", cm_menu, NO_BRACE_ARGS }, @@ -706,7 +704,7 @@ static COMMAND CommandTable[] = { { "result", cm_result, BRACE_ARGS }, { "ringaccent", cm_accent, BRACE_ARGS }, { "samp", cm_code, BRACE_ARGS }, - { "sc", cm_sc, BRACE_ARGS }, + { "sc", cm_var_sc, BRACE_ARGS }, { "section", cm_section, NO_BRACE_ARGS }, { "set", cm_set, NO_BRACE_ARGS }, { "setchapternewpage", cm_ignore_line, NO_BRACE_ARGS }, @@ -748,10 +746,11 @@ static COMMAND CommandTable[] = { { "unnumberedsec", cm_unnumberedsec, NO_BRACE_ARGS }, { "unnumberedsubsec", cm_unnumberedsubsec, NO_BRACE_ARGS }, { "unnumberedsubsubsec", cm_unnumberedsubsubsec, NO_BRACE_ARGS }, + { "uref", cm_uref, BRACE_ARGS }, { "url", cm_code, BRACE_ARGS }, { "v", cm_accent, BRACE_ARGS }, { "value", cm_value, BRACE_ARGS }, - { "var", cm_var, BRACE_ARGS }, + { "var", cm_var_sc, BRACE_ARGS }, { "vindex", cm_vindex, NO_BRACE_ARGS }, { "vtable", cm_vtable, NO_BRACE_ARGS }, { "w", cm_w, BRACE_ARGS }, @@ -772,46 +771,159 @@ static COMMAND CommandTable[] = { { "iunnumberedsubsec", cm_ideprecated, NO_BRACE_ARGS }, { "iunnumberedsubsubsec", cm_ideprecated, NO_BRACE_ARGS }, - /* Now @include does what this was supposed to. */ + /* Now @include does what this was used to. */ { "infoinclude", cm_obsolete, NO_BRACE_ARGS }, { "titlespec", cm_obsolete, NO_BRACE_ARGS }, - {(char *) NULL, (COMMAND_FUNCTION *) NULL}, NO_BRACE_ARGS}; + { NULL, NULL, NO_BRACE_ARGS } +}; struct option long_options[] = { - { "error-limit", 1, 0, 'e' }, /* formerly -el */ - { "fill-column", 1, 0, 'f' }, /* formerly -fc */ - { "footnote-style", 1, 0, 's' }, /* formerly -ft */ - { "no-headers", 0, &no_headers, 1 }, /* Do not output Node: foo */ + { "error-limit", 1, 0, 'e' }, /* formerly -el */ + { "fill-column", 1, 0, 'f' }, /* formerly -fc */ + { "footnote-style", 1, 0, 's' }, /* formerly -ft */ + { "force", 0, 0, 'F' }, /* do not remove output */ + { "no-headers", 0, &no_headers, 1 }, /* do not output Node: foo */ { "no-pointer-validate", 0, &validating, 0 }, /* formerly -nv */ - { "no-validate", 0, &validating, 0 }, /* formerly -nv */ - { "no-split", 0, &splitting, 0 }, /* formerly -ns */ - { "no-warn", 0, &print_warnings, 0 }, /* formerly -nw */ -#if defined (HAVE_MACROS) + { "no-validate", 0, &validating, 0 }, /* formerly -nv */ + { "no-split", 0, &splitting, 0 }, /* formerly -ns */ + { "no-warn", 0, &print_warnings, 0 }, /* formerly -nw */ { "macro-expand", 1, 0, 'E' }, -#endif /* HAVE_MACROS */ { "number-footnotes", 0, &number_footnotes, 1 }, { "no-number-footnotes", 0, &number_footnotes, 0 }, { "output", 1, 0, 'o' }, - { "paragraph-indent", 1, 0, 'p' }, /* formerly -pi */ - { "reference-limit", 1, 0, 'r' }, /* formerly -rl */ - { "verbose", 0, &verbose_mode, 1 }, /* formerly -verbose */ + { "paragraph-indent", 1, 0, 'p' }, /* formerly -pi */ + { "reference-limit", 1, 0, 'r' }, /* formerly -rl */ + { "verbose", 0, &verbose_mode, 1 }, /* formerly -verbose */ { "help", 0, 0, 'h' }, { "version", 0, 0, 'V' }, {NULL, 0, NULL, 0} }; -/* Values for calling handle_variable_internal (). */ -#define SET 1 -#define CLEAR 2 -#define IFSET 3 -#define IFCLEAR 4 +/* **************************************************************** */ +/* */ +/* Error Handling */ +/* */ +/* **************************************************************** */ + +/* Number of errors encountered. */ +int errors_printed = 0; + +/* Print the last error gotten from the file system. */ +int +fs_error (filename) + char *filename; +{ + remember_error (); + perror (filename); + return (0); +} + +/* Print an error message, and return false. */ +void +#if defined (VA_FPRINTF) && __STDC__ +error (char *format, ...) +#else +error (format, va_alist) + char *format; + va_dcl +#endif +{ +#ifdef VA_FPRINTF + va_list ap; +#endif + + remember_error (); + + VA_START (ap, format); +#ifdef VA_FPRINTF + VA_FPRINTF (stderr, format, ap); +#else + fprintf (stderr, format, a1, a2, a3, a4, a5, a6, a7, a8); +#endif /* not VA_FPRINTF */ + va_end (ap); + + putc ('\n', stderr); +} + +/* Just like error (), but print the line number as well. */ +void +#if defined (VA_FPRINTF) && __STDC__ +line_error (char *format, ...) +#else +line_error (format, va_alist) + char *format; + va_dcl +#endif +{ +#ifdef VA_FPRINTF + va_list ap; +#endif + + remember_error (); + fprintf (stderr, "%s:%d: ", input_filename, line_number); + + VA_START (ap, format); +#ifdef VA_FPRINTF + VA_FPRINTF (stderr, format, ap); +#else + fprintf (stderr, format, a1, a2, a3, a4, a5, a6, a7, a8); +#endif /* not VA_FPRINTF */ + va_end (ap); + + fprintf (stderr, ".\n"); +} + +void +#if defined (VA_FPRINTF) && __STDC__ +warning (char *format, ...) +#else +warning (format, va_alist) + char *format; + va_dcl +#endif +{ +#ifdef VA_FPRINTF + va_list ap; +#endif + + if (print_warnings) + { + fprintf (stderr, _("%s:%d: warning: "), input_filename, line_number); + + VA_START (ap, format); +#ifdef VA_FPRINTF + VA_FPRINTF (stderr, format, ap); +#else + fprintf (stderr, format, a1, a2, a3, a4, a5, a6, a7, a8); +#endif /* not VA_FPRINTF */ + va_end (ap); + fprintf (stderr, ".\n"); + } +} + + +/* Remember that an error has been printed. If more than + max_error_level have been printed, then exit the program. */ +void +remember_error () +{ + errors_printed++; + if (max_error_level && (errors_printed > max_error_level)) + { + fprintf (stderr, _("Too many errors! Gave up.\n")); + flush_file_stack (); + cm_bye (); + exit (FATAL); + } +} + /* **************************************************************** */ -/* */ -/* Main () Start of code */ -/* */ +/* */ +/* Main () Start of code */ +/* */ /* **************************************************************** */ /* For each file mentioned in the command line, process it, turning @@ -829,144 +941,174 @@ main (argc, argv) /* The name of this program is the last filename in argv[0]. */ progname = filename_part (argv[0]); +#ifdef HAVE_SETLOCALE + /* Do not use LC_ALL, because LC_NUMERIC screws up the scanf parsing + of the argument to @multicolumn. */ + setlocale (LC_TIME, ""); + setlocale (LC_MESSAGES, ""); +#endif + + /* Set the text message domain. */ + bindtextdomain (PACKAGE, LOCALEDIR); + textdomain (PACKAGE); + /* Parse argument flags from the input line. */ - while ((c = getopt_long - (argc, argv, -#if defined (HAVE_MACROS) - "D:E:U:I:f:o:p:e:r:s:V", -#else - "D:U:I:f:o:p:e:r:s:V", -#endif /* !HAVE_MACROS */ - long_options, &ind)) - != EOF) + while ((c = getopt_long (argc, argv, "D:e:E:f:I:o:p:P:r:s:U:V", + long_options, &ind)) != EOF) { if (c == 0 && long_options[ind].flag == 0) - c = long_options[ind].val; + c = long_options[ind].val; switch (c) - { - /* User specified variable to set or clear? */ - case 'D': - case 'U': - handle_variable_internal ((c == 'D') ? SET : CLEAR, optarg); - break; - -#if defined (HAVE_MACROS) - /* Use specified a macro expansion output file? */ - case 'E': - if (!macro_expansion_output_stream) - { - macro_expansion_output_stream = fopen (optarg, "w"); - if (!macro_expansion_output_stream) - error ("Couldn't open macro expansion output \"%s\"", optarg); - } - else - error ("Cannot specify more than one macro expansion output"); - break; -#endif /* HAVE_MACROS */ - - /* User specified include file path? */ - case 'I': - if (!include_files_path) - include_files_path = strdup ("."); - - include_files_path = (char *) - xrealloc (include_files_path, - 2 + strlen (include_files_path) + strlen (optarg)); - strcat (include_files_path, ":"); - strcat (include_files_path, optarg); - break; - - /* User specified fill_column? */ - case 'f': - if (sscanf (optarg, "%d", &fill_column) != 1) - { - fprintf (stderr, - "%s: --fill-column arg must be numeric, not `%s'.\n", - progname, optarg); - usage (FATAL); - } - break; - - /* User specified output file? */ - case 'o': - command_output_filename = strdup (optarg); - break; - - /* User specified paragraph indent (paragraph_start_index)? */ - case 'p': - if (set_paragraph_indent (optarg) < 0) - { - fprintf (stderr, - "%s: --paragraph-indent arg must be numeric/none/asis, not `%s'.\n", - progname, optarg); - usage (FATAL); - } - break; - - /* User specified error level? */ - case 'e': - if (sscanf (optarg, "%d", &max_error_level) != 1) - { - fprintf (stderr, - "%s: --error-limit arg must be numeric, not `%s'.\n", - progname, optarg); - } - usage (stderr, FATAL); - break; - - /* User specified reference warning limit? */ - case 'r': - if (sscanf (optarg, "%d", &reference_warning_limit) != 1) - { - fprintf (stderr, - "%s: --reference-limit arg must be numeric, not `%s'.\n", + { + case 'D': + case 'U': + /* User specified variable to set or clear. */ + handle_variable_internal ((c == 'D') ? SET : CLEAR, optarg); + break; + + case 'e': + /* User specified error level. */ + if (sscanf (optarg, "%d", &max_error_level) != 1) + { + fprintf (stderr, + _("%s: %s arg must be numeric, not `%s'.\n"), + "--error-limit", progname, optarg); + usage (stderr, FATAL); + } + break; + + case 'E': + /* User specified a macro expansion output file. */ + if (!macro_expansion_output_stream) + { + macro_expansion_filename = optarg; + macro_expansion_output_stream + = strcmp (optarg, "-") == 0 ? stdout : fopen (optarg, "w"); + if (!macro_expansion_output_stream) + error (_("Couldn't open macro expansion output `%s'"), optarg); + } + else + error (_("Cannot specify more than one macro expansion output")); + break; + + case 'f': + /* User specified fill_column. */ + if (sscanf (optarg, "%d", &fill_column) != 1) + { + fprintf (stderr, + _("%s: %s arg must be numeric, not `%s'.\n"), + "--fill-column", progname, optarg); + usage (FATAL); + } + break; + + case 'F': + force++; /* Do not remove erroneous output. */ + break; + + case 'h': + usage (NO_ERROR); + break; + + case 'I': + /* Append user-specified dir to include file path. */ + if (!include_files_path) + include_files_path = xstrdup ("."); + + include_files_path = (char *) + xrealloc (include_files_path, + 2 + strlen (include_files_path) + strlen (optarg)); + strcat (include_files_path, ":"); + strcat (include_files_path, optarg); + break; + + case 'o': + /* User specified output file. */ + command_output_filename = xstrdup (optarg); + break; + + case 'p': + /* User specified paragraph indent (paragraph_start_index). */ + if (set_paragraph_indent (optarg) < 0) + { + fprintf (stderr, + _("%s: --paragraph-indent arg must be numeric/`none'/`asis', not `%s'.\n"), progname, optarg); - usage (FATAL); - } - break; - - /* User specified footnote style? */ - case 's': - if (set_footnote_style (optarg) < 0) - { - fprintf (stderr, - "%s: --footnote-style arg must be `separate' or `end', not `%s'.\n", + usage (FATAL); + } + break; + + case 'P': + /* Prepend user-specified include dir to include path. */ + if (!include_files_path) + { + include_files_path = xstrdup (optarg); + include_files_path = (char *) xrealloc (include_files_path, + strlen (include_files_path) + 3); /* 3 for ":.\0" */ + strcat (include_files_path, ":."); + } + else + { + char *tmp = xstrdup (include_files_path); + include_files_path = (char *) xrealloc (include_files_path, + strlen (include_files_path) + strlen (optarg) + 2); /* 2 for ":\0" */ + strcpy (include_files_path, optarg); + strcat (include_files_path, ":"); + strcat (include_files_path, tmp); + free (tmp); + } + break; + + case 'r': + /* User specified reference warning limit. */ + if (sscanf (optarg, "%d", &reference_warning_limit) != 1) + { + fprintf (stderr, + _("%s: %s arg must be numeric, not `%s'.\n"), + "--reference-limit", progname, optarg); + usage (FATAL); + } + break; + + case 's': + /* User specified footnote style. */ + if (set_footnote_style (optarg) < 0) + { + fprintf (stderr, + _("%s: --footnote-style arg must be `separate' or `end', not `%s'.\n"), progname, optarg); - usage (FATAL); - } - footnote_style_preset = 1; - break; - - case 'h': - usage (NO_ERROR); - break; - - /* User requested version info? */ - case 'V': - print_version_info (); - puts ("Copyright (C) 1996 Free Software Foundation, Inc.\n\ + usage (FATAL); + } + footnote_style_preset = 1; + break; + + case 'V': + /* User requested version info. */ + print_version_info (); + printf (_("Copyright (C) %s Free Software Foundation, Inc.\n\ There is NO warranty. You may redistribute this software\n\ under the terms of the GNU General Public License.\n\ -For more information about these matters, see the files named COPYING."); - exit (NO_ERROR); - break; - - case '?': - usage (FATAL); - break; - } +For more information about these matters, see the files named COPYING.\n"), + "1998"); + exit (NO_ERROR); + break; + + case '?': + usage (FATAL); + break; + } } if (optind == argc) { /* Check to see if input is a file. If so, process that. */ if (!isatty (fileno (stdin))) - reading_from_stdin = 1; + reading_from_stdin = 1; else { - fprintf (stderr, "%s: missing file argument.\n", progname); - usage (FATAL); + fprintf (stderr, _("%s: missing file argument.\n"), progname); + usage (FATAL); } } @@ -978,10 +1120,9 @@ For more information about these matters, see the files named COPYING."); { splitting = 0; - /* If the user has not specified an output file, then use stdout by - default. */ + /* If the user has not specified an output file, use stdout. */ if (!command_output_filename) - command_output_filename = strdup ("-"); + command_output_filename = xstrdup ("-"); } if (verbose_mode) @@ -992,7 +1133,7 @@ For more information about these matters, see the files named COPYING."); if (!reading_from_stdin) { while (optind != argc) - convert_from_file (argv[optind++]); + convert_from_file (argv[optind++]); } else convert_from_stream (stdin, "stdin"); @@ -1007,7 +1148,8 @@ For more information about these matters, see the files named COPYING."); void print_version_info () { - printf ("GNU Makeinfo (Texinfo 3.9) %d.%d\n", major_version, minor_version); + printf ("makeinfo (GNU %s %s) %d.%d\n", PACKAGE, VERSION, + major_version, minor_version); } /* **************************************************************** */ @@ -1057,12 +1199,6 @@ xrealloc (pointer, nbytes) else temp = (void *)realloc (pointer, nbytes); - if (nbytes && !temp) - memory_error ("xrealloc", nbytes); - - return (temp); -} - /* If EXIT_VALUE is zero, print the full usage message to stdout. Otherwise, just say to use --help for more info. Then exit with EXIT_VALUE. */ @@ -1071,17 +1207,18 @@ usage (exit_value) int exit_value; { if (exit_value != 0) - fprintf (stderr, "Try `%s --help' for more information.\n", progname); + fprintf (stderr, _("Try `%s --help' for more information.\n"), progname); else - printf ("Usage: %s [OPTION]... TEXINFO-FILE...\n\ + printf (_("Usage: %s [OPTION]... TEXINFO-FILE...\n\ \n\ Translate Texinfo source documentation to a format suitable for reading\n\ with GNU Info.\n\ \n\ Options:\n\ -D VAR define a variable, as with @set.\n\ --E MACRO-OFILE process macros only, output texinfo source.\n\ --I DIR add DIR to the directory search list for @include.\n\ +-E MACRO-OFILE process macros only, output texinfo source.\n\ +-I DIR append DIR to the @include directory search path.\n\ +-P DIR prepend DIR to the @include directory search path.\n\ -U VAR undefine a variable, as with @clear.\n\ --error-limit NUM quit after NUM errors (default %d).\n\ --fill-column NUM break lines at NUM characters (default %d).\n\ @@ -1089,21 +1226,24 @@ Options:\n\ `separate' to place footnotes in their own node,\n\ `end' to place the footnotes at the end of\n\ the node in which they are defined (the default).\n\ +--force preserve output even if errors.\n\ --help display this help and exit.\n\ --no-validate suppress node cross-reference validation.\n\ --no-warn suppress warnings (but not errors).\n\ --no-split suppress splitting of large files.\n\ --no-headers suppress node separators and Node: Foo headers.\n\ --output FILE, -o FILE output to FILE, and ignore any @setfilename.\n\ ---paragraph-indent NUM indent paragraphs with NUM spaces (default %d).\n\ +--paragraph-indent VAL indent paragraphs with VAL spaces (default %d).\n\ + if VAL is `none', do not indent; if VAL is `asis',\n\ + preserve any existing indentation.\n\ --reference-limit NUM complain about at most NUM references (default %d).\n\ --verbose report about what is being done.\n\ --version display version information and exit.\n\ \n\ -Email bug reports to bug-texinfo@prep.ai.mit.edu.\n\ -", - progname, paragraph_start_indent, - fill_column, max_error_level, reference_warning_limit); +Email bug reports to bug-texinfo@gnu.org.\n\ +"), + progname, max_error_level, fill_column, + paragraph_start_indent, reference_warning_limit); exit (exit_value); } @@ -1143,7 +1283,7 @@ find_and_load (filename) { struct stat fileinfo; long file_size; - int file = -1, n, i, count = 0; + int file = -1, count = 0; char *fullpath, *result, *get_file_info_in_path (); result = fullpath = (char *)NULL; @@ -1160,31 +1300,35 @@ find_and_load (filename) if (file < 0) goto error_exit; - /* Load the file. */ - result = (char *)xmalloc (1 + file_size); + /* Load the file, with enough room for a newline and a null. */ + result = xmalloc (file_size + 2); /* VMS stat lies about the st_size value. The actual number of readable bytes is always less than this value. The arcane mysteries of VMS/RMS are too much to probe, so this hack suffices to make things work. */ -#if defined (VMS) +#if defined (VMS) || defined (WIN32) +#ifdef VMS while ((n = read (file, result + count, file_size)) > 0) +#else /* WIN32 */ + while ((n = read (file, result + count, 1)) > 0) +#endif /* WIN32 */ count += n; if (n == -1) -#else /* !VMS */ +#else /* !VMS && !WIN32 */ count = file_size; if (read (file, result, file_size) != file_size) -#endif /* !VMS */ +#endif /* !VMS && !WIN32 */ error_exit: { if (result) - free (result); + free (result); if (fullpath) - free (fullpath); + free (fullpath); if (file != -1) - close (file); + close (file); return ((char *) NULL); } @@ -1194,13 +1338,15 @@ find_and_load (filename) input_text = result; size_of_input_text = count; input_filename = fullpath; - node_filename = strdup (fullpath); + node_filename = xstrdup (fullpath); input_text_offset = 0; line_number = 1; /* Not strictly necessary. This magic prevents read_token () from doing extra unnecessary work each time it is called (that is a lot of times). - The SIZE_OF_INPUT_TEXT is one past the actual end of the text. */ + SIZE_OF_INPUT_TEXT is one past the actual end of the text. */ input_text[size_of_input_text] = '\n'; + /* This, on the other hand, is always necessary. */ + input_text[size_of_input_text+1] = 0; return (result); } @@ -1227,7 +1373,7 @@ popfile () FSTACK *tos = filestack; if (!tos) - abort (); /* My fault. I wonder what I did? */ + abort (); /* My fault. I wonder what I did? */ #if defined (HAVE_MACROS) if (macro_expansion_output_stream) @@ -1241,7 +1387,7 @@ popfile () filestack = filestack->next; /* Make sure that commands with braces have been satisfied. */ - if (!executing_string) + if (!executing_string && !me_executing_string) discard_braces (); /* Get the top of the stack into the globals. */ @@ -1306,7 +1452,7 @@ filename_part (filename) else basename++; - basename = strdup (basename); + basename = xstrdup (basename); #if defined (REMOVE_OUTPUT_EXTENSIONS) /* See if there is an extension to remove. If so, remove it. */ @@ -1315,7 +1461,7 @@ filename_part (filename) temp = strrchr (basename, '.'); if (temp) - *temp = '\0'; + *temp = 0; } #endif /* REMOVE_OUTPUT_EXTENSIONS */ return (basename); @@ -1343,7 +1489,7 @@ pathname_part (filename) { result = (char *)xmalloc (1 + i); strncpy (result, filename, i); - result[i] = '\0'; + result[i] = 0; } free (filename); return (result); @@ -1357,9 +1503,9 @@ filename_non_directory (name) for (i = strlen (name) - 1; i; i--) if (name[i] == '/') - return (strdup (name + i + 1)); + return (xstrdup (name + i + 1)); - return (strdup (name)); + return (xstrdup (name)); } /* Return the expansion of FILENAME. */ @@ -1377,24 +1523,24 @@ expand_filename (filename, input_name) filename = filename_non_directory (input_name); if (!*filename) - { - free (filename); - filename = strdup ("noname.texi"); - } + { + free (filename); + filename = xstrdup ("noname.texi"); + } for (i = strlen (filename) - 1; i; i--) - if (filename[i] == '.') - break; + if (filename[i] == '.') + break; if (!i) - i = strlen (filename); + i = strlen (filename); if (i + 6 > (strlen (filename))) - filename = (char *)xrealloc (filename, i + 6); + filename = (char *)xrealloc (filename, i + 6); strcpy (filename + i, ".info"); return (filename); } - + if (filename[0] == '.' || filename[0] == '/') return (filename); @@ -1409,10 +1555,10 @@ expand_filename (filename, input_name) strcpy (result, input_name); while (result[i] != '/' && i) - i--; + i--; if (result[i] == '/') - i++; + i++; strcpy (&result[i], filename); free (filename); @@ -1431,13 +1577,13 @@ full_pathname (filename) /* No filename given? */ if (!filename || !(initial_character = *filename)) - return (strdup ("")); + return (xstrdup ("")); /* Already absolute? */ if ((initial_character == '/') || ((strncmp (filename, "./", 2) == 0) || (strncmp (filename, "../", 3) == 0))) - return (strdup (filename)); + return (xstrdup (filename)); if (initial_character != '~') { @@ -1447,66 +1593,68 @@ full_pathname (filename) #if defined (HAVE_GETCWD) if (!getcwd (localdir, 1024)) #else /* !HAVE_GETCWD */ - if (!getwd (localdir)) + if (!getwd (localdir)) #endif /* !HAVE_GETCWD */ - { - fprintf (stderr, "%s: getwd: %s, %s\n", - progname, filename, localdir); - exit (1); - } + { + fprintf (stderr, _("%s: getwd: %s, %s\n"), + progname, filename, localdir); + exit (1); + } strcat (localdir, "/"); strcat (localdir, filename); - result = strdup (localdir); + result = xstrdup (localdir); free (localdir); } else { +#ifndef WIN32 if (filename[1] == '/') - { - /* Return the concatenation of the environment variable HOME - and the rest of the string. */ - char *temp_home; - - temp_home = (char *) getenv ("HOME"); - result = (char *)xmalloc (strlen (&filename[1]) - + 1 - + temp_home ? strlen (temp_home) - : 0); - *result = '\0'; - - if (temp_home) - strcpy (result, temp_home); - - strcat (result, &filename[1]); - } + { + /* Return the concatenation of the environment variable HOME + and the rest of the string. */ + char *temp_home; + + temp_home = (char *) getenv ("HOME"); + result = (char *)xmalloc (strlen (&filename[1]) + + 1 + + temp_home ? strlen (temp_home) + : 0); + *result = 0; + + if (temp_home) + strcpy (result, temp_home); + + strcat (result, &filename[1]); + } else - { - struct passwd *user_entry; - int i, c; - char *username = (char *)xmalloc (257); - - for (i = 1; c = filename[i]; i++) - { - if (c == '/') - break; - else - username[i - 1] = c; - } - if (c) - username[i - 1] = '\0'; - - user_entry = getpwnam (username); - - if (!user_entry) - return (strdup (filename)); - - result = (char *)xmalloc (1 + strlen (user_entry->pw_dir) - + strlen (&filename[i])); - strcpy (result, user_entry->pw_dir); - strcat (result, &filename[i]); - } + { + struct passwd *user_entry; + int i, c; + char *username = (char *)xmalloc (257); + + for (i = 1; (c = filename[i]); i++) + { + if (c == '/') + break; + else + username[i - 1] = c; + } + if (c) + username[i - 1] = 0; + + user_entry = getpwnam (username); + + if (!user_entry) + return (xstrdup (filename)); + + result = (char *)xmalloc (1 + strlen (user_entry->pw_dir) + + strlen (&filename[i])); + strcpy (result, user_entry->pw_dir); + strcat (result, &filename[i]); + } } +#endif /* not WIN32 */ return (result); } @@ -1518,139 +1666,9 @@ output_name_from_input_name (name) } /* **************************************************************** */ -/* */ -/* Error Handling */ -/* */ -/* **************************************************************** */ - -/* Number of errors encountered. */ -int errors_printed = 0; - -/* Print the last error gotten from the file system. */ -int -fs_error (filename) - char *filename; -{ - remember_error (); - perror (filename); - return (0); -} - -/* Print an error message, and return false. */ -#if defined (HAVE_VARARGS_H) && defined (HAVE_VFPRINTF) - -int -error (va_alist) - va_dcl -{ - char *format; - va_list args; - - remember_error (); - va_start (args); - format = va_arg (args, char *); - vfprintf (stderr, format, args); - va_end (args); - putc ('\n', stderr); -} - -/* Just like error (), but print the line number as well. */ -int -line_error (va_alist) - va_dcl -{ - char *format; - va_list args; - - remember_error (); - va_start (args); - format = va_arg (args, char *); - fprintf (stderr, "%s:%d: ", input_filename, line_number); - vfprintf (stderr, format, args); - fprintf (stderr, ".\n"); - va_end (args); - return ((int) 0); -} - -int -warning (va_alist) - va_dcl -{ - char *format; - va_list args; - - va_start (args); - format = va_arg (args, char *); - if (print_warnings) - { - fprintf (stderr, "%s:%d: Warning: ", input_filename, line_number); - vfprintf (stderr, format, args); - fprintf (stderr, ".\n"); - } - va_end (args); - return ((int) 0); -} - -#else /* !(HAVE_VARARGS_H && HAVE_VFPRINTF) */ - -int -error (format, arg1, arg2, arg3, arg4, arg5) - char *format; -{ - remember_error (); - fprintf (stderr, format, arg1, arg2, arg3, arg4, arg5); - putc ('\n', stderr); - return ((int) 0); -} - -/* Just like error (), but print the line number as well. */ -int -line_error (format, arg1, arg2, arg3, arg4, arg5) - char *format; -{ - remember_error (); - fprintf (stderr, "%s:%d: ", input_filename, line_number); - fprintf (stderr, format, arg1, arg2, arg3, arg4, arg5); - fprintf (stderr, ".\n"); - return ((int) 0); -} - -int -warning (format, arg1, arg2, arg3, arg4, arg5) - char *format; -{ - if (print_warnings) - { - fprintf (stderr, "%s:%d: Warning: ", input_filename, line_number); - fprintf (stderr, format, arg1, arg2, arg3, arg4, arg5); - fprintf (stderr, ".\n"); - } - return ((int) 0); -} - -#endif /* !(HAVE_VARARGS_H && HAVE_VFPRINTF) */ - -/* Remember that an error has been printed. If this is the first - error printed, then tell them which program is printing them. - If more than max_error_level have been printed, then exit the - program. */ -void -remember_error () -{ - errors_printed++; - if (max_error_level && (errors_printed > max_error_level)) - { - fprintf (stderr, "Too many errors! Gave up.\n"); - flush_file_stack (); - cm_bye (); - exit (1); - } -} - -/* **************************************************************** */ -/* */ -/* Hacking Tokens and Strings */ -/* */ +/* */ +/* Hacking Tokens and Strings */ +/* */ /* **************************************************************** */ /* Return the next token as a string pointer. We cons the string. */ @@ -1668,24 +1686,24 @@ read_token () input_text_offset++; if (character == '\n') - line_number++; + line_number++; - result = strdup (" "); + result = xstrdup (" "); *result = character; return (result); } for (i = 0; ((input_text_offset != size_of_input_text) - && (character = curchar ()) - && command_char (character)); + && (character = curchar ()) + && command_char (character)); i++, input_text_offset++); result = (char *)xmalloc (i + 1); memcpy (result, &input_text[input_text_offset - i], i); - result[i] = '\0'; + result[i] = 0; return (result); } -/* Return non-zero if CHARACTER is self-delimiting. */ +/* Return nonzero if CHARACTER is self-delimiting. */ int self_delimiting (character) int character; @@ -1709,17 +1727,17 @@ canon_white (string) for (x = 0; x < len; x++) { if (!cr_or_whitespace (string[x])) - { - strcpy (string, string + x); - break; - } + { + strcpy (string, string + x); + break; + } } len = strlen (string); if (len) len--; while (len > -1 && cr_or_whitespace (string[len])) len--; - string[len + 1] = '\0'; + string[len + 1] = 0; } /* Bash STRING, replacing all whitespace with just one space. */ @@ -1739,15 +1757,15 @@ fix_whitespace (string) c = temp[temp_index++] = string[string_index++]; if (c == ' ' || c == '\n' || c == '\t') - { - temp[temp_index - 1] = ' '; - while ((c = string[string_index]) && (c == ' ' || - c == '\t' || - c == '\n')) - string_index++; - } - } - temp[temp_index] = '\0'; + { + temp[temp_index - 1] = ' '; + while ((c = string[string_index]) && (c == ' ' || + c == '\t' || + c == '\n')) + string_index++; + } + } + temp[temp_index] = 0; strcpy (string, temp); free (temp); } @@ -1773,10 +1791,10 @@ discard_until (string) input_text_offset = size_of_input_text - strlen (string); if (strcmp (string, "\n") != 0) - { - line_error ("Expected `%s'", string); - return; - } + { + line_error (_("Expected `%s'"), string); + return; + } } else input_text_offset = temp; @@ -1810,7 +1828,7 @@ get_until (match, string) *string = (char *)xmalloc (len + 1); memcpy (*string, &input_text[current_point], len); - (*string)[len] = '\0'; + (*string)[len] = 0; /* Now leave input_text_offset in a consistent state. */ input_text_offset = tem; @@ -1824,18 +1842,68 @@ get_until (match, string) /* Read characters from the file until we are at MATCH or end of line. Place the characters read into STRING. */ void -get_until_in_line (match, string) +get_until_in_line (expand, match, string) + int expand; char *match, **string; { - int real_bottom, temp; - - real_bottom = size_of_input_text; - temp = search_forward ("\n", input_text_offset); - - if (temp < 0) - temp = size_of_input_text; + int real_bottom = size_of_input_text; + int limit = search_forward ("\n", input_text_offset); + if (limit < 0) + limit = size_of_input_text; + + /* Replace input_text[input_text_offset .. limit-1] with its macro + expansion (actually, we expand all commands). This allows the node + names themselves to be constructed via a macro, as in: + @macro foo{p, q} + Together: \p\ & \q\. + @end macro + + @node @foo{A,B}, next, prev, top + + Otherwise, the `,' separating the macro args A and B is taken as + the node argument separator, so the node name is `@foo{A'. This + expansion is only necessary on the first call, since we expand the + whole line then. + + Furthermore, if we're executing a string, don't do it -- we'll end + up shrinking the execution string which is currently aliased to + `input_text', so it might get moved, and not updated in the + `execution_strings' array. This happens when processing the + (synthetic) Overview-Footnotes node in the Texinfo manual. */ + + if (expand && !executing_string && !me_executing_string) + { + char *xp; + unsigned xp_len, new_len; + + /* Get original string from input. */ + unsigned raw_len = limit - input_text_offset; + char *str = xmalloc (raw_len + 1); + strncpy (str, input_text + input_text_offset, raw_len); + str[raw_len] = 0; + + /* Expand it. */ + xp = expansion (str, 0); + xp_len = strlen (xp); + free (str); + + /* Plunk the expansion into the middle of `input_text' -- + which is terminated by a newline, not a null. */ + str = xmalloc (real_bottom - limit + 1); + strncpy (str, input_text + limit, real_bottom - limit + 1); + new_len = input_text_offset + xp_len + real_bottom - limit + 1; + input_text = xrealloc (input_text, new_len); + strcpy (input_text + input_text_offset, xp); + strncpy (input_text + input_text_offset + xp_len, str, + real_bottom - limit + 1); + free (str); + free (xp); + + limit += xp_len - raw_len; + real_bottom += xp_len - raw_len; + } - size_of_input_text = temp; + size_of_input_text = limit; get_until (match, string); size_of_input_text = real_bottom; } @@ -1847,7 +1915,7 @@ get_rest_of_line (string) get_until ("\n", string); canon_white (*string); - if (curchar () == '\n') /* as opposed to the end of the file... */ + if (curchar () == '\n') /* as opposed to the end of the file... */ { line_number++; input_text_offset++; @@ -1863,7 +1931,7 @@ backup_input_pointer () { input_text_offset--; if (curchar () == '\n') - line_number--; + line_number--; } } @@ -1873,36 +1941,36 @@ void get_until_in_braces (match, string) char *match, **string; { + char *temp; int i, brace = 0; int match_len = strlen (match); - char *temp; for (i = input_text_offset; i < size_of_input_text; i++) { if (input_text[i] == '{') - brace++; + brace++; else if (input_text[i] == '}') - brace--; + brace--; else if (input_text[i] == '\n') - line_number++; + line_number++; if (brace < 0 || - (brace == 0 && strncmp (input_text + i, match, match_len) == 0)) - break; + (brace == 0 && strncmp (input_text + i, match, match_len) == 0)) + break; } match_len = i - input_text_offset; temp = (char *)xmalloc (2 + match_len); strncpy (temp, input_text + input_text_offset, match_len); - temp[match_len] = '\0'; + temp[match_len] = 0; input_text_offset = i; *string = temp; } /* **************************************************************** */ -/* */ -/* Converting the File */ -/* */ +/* */ +/* Converting the File */ +/* */ /* **************************************************************** */ /* Convert the file named by NAME. The output is saved on the file @@ -1934,7 +2002,7 @@ initialize_conversion () on unix systems. */ #define READ_BUFFER_GROWTH (4 * 4096) -/* Convert the texinfo file coming from the open stream STREAM. Assume the +/* Convert the Texinfo file coming from the open stream STREAM. Assume the source of the stream is named NAME. */ void convert_from_stream (stream, name) @@ -1954,27 +2022,27 @@ convert_from_stream (stream, name) int count; if (buffer_offset + (READ_BUFFER_GROWTH + 1) >= buffer_size) - buffer = (char *) - xrealloc (buffer, (buffer_size += READ_BUFFER_GROWTH)); + buffer = (char *) + xrealloc (buffer, (buffer_size += READ_BUFFER_GROWTH)); count = fread (buffer + buffer_offset, 1, READ_BUFFER_GROWTH, stream); if (count < 0) - { - perror (name); - exit (FATAL); - } + { + perror (name); + exit (FATAL); + } buffer_offset += count; if (count == 0) - break; + break; } /* Set the globals to the new file. */ input_text = buffer; size_of_input_text = buffer_offset; - input_filename = strdup (name); - node_filename = strdup (name); + input_filename = xstrdup (name); + node_filename = xstrdup (name); input_text_offset = 0; line_number = 1; @@ -2004,14 +2072,14 @@ convert_from_file (name) strcat (filename, suffixes[i]); if (find_and_load (filename)) - break; + break; if (!suffixes[i][0] && strrchr (filename, '.')) - { - fs_error (filename); - free (filename); - return; - } + { + fs_error (filename); + free (filename); + return; + } } if (!suffixes[i]) @@ -2043,47 +2111,47 @@ convert_from_loaded_file (name) while (input_text_offset >= 0) { input_text_offset = - search_forward (setfilename_search, input_text_offset); + search_forward (setfilename_search, input_text_offset); if ((input_text_offset == 0) || - ((input_text_offset > 0) && - (input_text[input_text_offset -1] == '\n'))) - break; + ((input_text_offset > 0) && + (input_text[input_text_offset -1] == '\n'))) + break; else if (input_text_offset > 0) - input_text_offset++; + input_text_offset++; } if (input_text_offset < 0) { if (!command_output_filename) - { + { #if defined (REQUIRE_SETFILENAME) - error ("No `%s' found in `%s'", setfilename_search, name); - goto finished; + error (_("No `%s' found in `%s'"), setfilename_search, name); + goto finished; #else - register int i, end_of_first_line; - - /* Find the end of the first line in the file. */ - for (i = 0; i < size_of_input_text - 1; i++) - if (input_text[i] == '\n') - break; - - end_of_first_line = i + 1; - - input_text_offset = 0; - - for (i = 0; i < end_of_first_line; i++) - { - if ((input_text[i] == '\\') && - (strncmp (input_text + i + 1, "include", 7) == 0)) - { - input_text_offset = end_of_first_line; - break; - } - } - command_output_filename = output_name_from_input_name (name); + register int i, end_of_first_line; + + /* Find the end of the first line in the file. */ + for (i = 0; i < size_of_input_text - 1; i++) + if (input_text[i] == '\n') + break; + + end_of_first_line = i + 1; + + input_text_offset = 0; + + for (i = 0; i < end_of_first_line; i++) + { + if ((input_text[i] == '\\') && + (strncmp (input_text + i + 1, "include", 7) == 0)) + { + input_text_offset = end_of_first_line; + break; + } + } + command_output_filename = output_name_from_input_name (name); #endif /* !REQUIRE_SETFILENAME */ - } + } } else input_text_offset += strlen (setfilename_search); @@ -2093,9 +2161,9 @@ convert_from_loaded_file (name) else { if (input_text_offset != -1) - discard_until ("\n"); + discard_until ("\n"); else - input_text_offset = 0; + input_text_offset = 0; real_output_filename = output_filename = command_output_filename; command_output_filename = (char *)NULL; @@ -2103,25 +2171,31 @@ convert_from_loaded_file (name) canon_white (output_filename); - if (real_output_filename && - strcmp (real_output_filename, "-") == 0) + if (real_output_filename && strcmp (real_output_filename, "-") == 0) { - real_output_filename = strdup (real_output_filename); + if (macro_expansion_filename + && strcmp (macro_expansion_filename, "-") == 0) + { + fprintf (stderr, _("%s: Skipping macro expansion to stdout as Info output is going there.\n"), + progname); + macro_expansion_output_stream = NULL; + } + real_output_filename = xstrdup (real_output_filename); output_stream = stdout; - splitting = 0; /* Cannot split when writing to stdout. */ + splitting = 0; /* Cannot split when writing to stdout. */ } else { if (!real_output_filename) - real_output_filename = expand_filename (output_filename, name); + real_output_filename = expand_filename (output_filename, name); else - real_output_filename = strdup (real_output_filename); + real_output_filename = xstrdup (real_output_filename); output_stream = fopen (real_output_filename, "w"); } - if (verbose_mode && output_stream != stdout) - printf ("Making %s file `%s' from `%s'.\n", + if (output_stream != stdout) + printf (_("Making %s file `%s' from `%s'.\n"), no_headers ? "text" : "info", output_filename, input_filename); if (output_stream == NULL) @@ -2135,7 +2209,7 @@ convert_from_loaded_file (name) if (output_stream != stdout) pretty_output_filename = filename_part (output_filename); else - pretty_output_filename = strdup ("stdout"); + pretty_output_filename = xstrdup ("stdout"); /* For this file only, count the number of newlines from the top of the file to here. This way, we keep track of line numbers for @@ -2146,50 +2220,69 @@ convert_from_loaded_file (name) line_number = 1; while (temp != input_text_offset) if (input_text[temp++] == '\n') - line_number++; + line_number++; } if (!no_headers) { - add_word_args ("This is Info file %s, produced by Makeinfo version %d.%d", - output_filename, major_version, minor_version); - add_word_args (" from the input file %s.\n", input_filename); + add_word_args (_("This is Info file %s, produced by Makeinfo version %d.%d"), + output_filename, major_version, minor_version); + add_word_args (_(" from the input file %s.\n"), input_filename); } close_paragraph (); reader_loop (); finished: + discard_insertions (0); close_paragraph (); flush_file_stack (); #if defined (HAVE_MACROS) if (macro_expansion_output_stream) - fclose (macro_expansion_output_stream); + { + fclose (macro_expansion_output_stream); + if (errors_printed && !force + && strcmp (macro_expansion_filename, "-") != 0 + && strcmp (macro_expansion_filename, "/dev/null") != 0) + { + fprintf (stderr, _("%s: Removing macro output file `%s' due to errors; use --force to preserve.\n"), + progname, macro_expansion_filename); + if (unlink (macro_expansion_filename) < 0) + perror (macro_expansion_filename); + } + } #endif /* HAVE_MACROS */ - if (output_stream != NULL) + if (output_stream) { output_pending_notes (); free_pending_notes (); if (tag_table != NULL) - { - tag_table = (TAG_ENTRY *) reverse_list (tag_table); - if (!no_headers) - write_tag_table (); - } + { + tag_table = (TAG_ENTRY *) reverse_list (tag_table); + if (!no_headers) + write_tag_table (); + } if (output_stream != stdout) - fclose (output_stream); + fclose (output_stream); /* If validating, then validate the entire file right now. */ if (validating) - validate_file (tag_table); - - /* This used to test && !errors_printed. - But some files might have legit warnings. So split anyway. */ - if (splitting) - split_file (real_output_filename, 0); + validate_file (tag_table); + + if (splitting && (!errors_printed || force)) + split_file (real_output_filename, 0); + else if (errors_printed && !force + && strcmp (real_output_filename, "-") != 0 + && strcmp (real_output_filename, "/dev/null") != 0) + { /* If there were errors, and no --force, remove the output. */ + fprintf (stderr, _("%s: Removing output file `%s' due to errors; use --force to preserve.\n"), + progname, real_output_filename); + if (unlink (real_output_filename) < 0) + perror (real_output_filename); + } } free (real_output_filename); } @@ -2198,7 +2291,7 @@ void free_and_clear (pointer) char **pointer; { - if ((*pointer) != (char *) NULL) + if (*pointer) { free (*pointer); *pointer = (char *) NULL; @@ -2209,13 +2302,13 @@ free_and_clear (pointer) void init_internals () { - free_and_clear (¤t_node); free_and_clear (&output_filename); free_and_clear (&command); free_and_clear (&input_filename); free_node_references (); init_insertion_stack (); init_brace_stack (); + current_node = NULL; /* sometimes already freed */ command_index = 0; in_menu = 0; in_detailmenu = 0; @@ -2228,7 +2321,7 @@ init_paragraph () { free_and_clear (&output_paragraph); output_paragraph = (unsigned char *)xmalloc (paragraph_buffer_len); - output_paragraph[0] = '\0'; + output_paragraph[0] = 0; output_paragraph_offset = 0; output_column = 0; paragraph_is_open = 0; @@ -2250,100 +2343,99 @@ reader_loop () while (!done) { if (input_text_offset >= size_of_input_text) - break; + break; character = curchar (); if (!in_fixed_width_font && - (character == '\'' || character == '`') && - input_text[input_text_offset + 1] == character) - { - input_text_offset++; - character = '"'; - } + (character == '\'' || character == '`') && + input_text[input_text_offset + 1] == character) + { + input_text_offset++; + character = '"'; + } if (character == '-') - { - dash_count++; - if (dash_count == 2 && !in_fixed_width_font) - { - input_text_offset++; - continue; - } - } + { + dash_count++; + if (dash_count == 2 && !in_fixed_width_font) + { + input_text_offset++; + continue; + } + } else - { - dash_count = 0; - } + { + dash_count = 0; + } /* If this is a whitespace character, then check to see if the line - is blank. If so, advance to the carriage return. */ + is blank. If so, advance to the carriage return. */ if (whitespace (character)) - { - register int i = input_text_offset + 1; + { + register int i = input_text_offset + 1; - while (i < size_of_input_text && whitespace (input_text[i])) - i++; + while (i < size_of_input_text && whitespace (input_text[i])) + i++; - if (i == size_of_input_text || input_text[i] == '\n') - { - if (i == size_of_input_text) - i--; + if (i == size_of_input_text || input_text[i] == '\n') + { + if (i == size_of_input_text) + i--; - input_text_offset = i; - character = curchar (); - } - } + input_text_offset = i; + character = curchar (); + } + } if (character == '\n') - { - line_number++; - - /* Check for a menu entry here, since the "escape sequence" - that begins menu entries is "\n* ". */ - if (in_menu && input_text_offset + 1 < size_of_input_text) - { - char *glean_node_from_menu (), *tem; - - /* Note that the value of TEM is discarded, since it is - gauranteed to be NULL when glean_node_from_menu () is - called with a non-zero argument. */ - if (!in_detailmenu) - tem = glean_node_from_menu (1); - } - } + { + line_number++; + + /* Check for a menu entry here, since the "escape sequence" + that begins menu entries is "\n* ". */ + if (in_menu && input_text_offset + 1 < size_of_input_text) + { + char *glean_node_from_menu (), *tem; + + /* Note that the value of TEM is discarded, since it is + gauranteed to be NULL when glean_node_from_menu () is + called with a Nonzero argument. */ + if (!in_detailmenu) + tem = glean_node_from_menu (1); + } + } switch (character) - { - case COMMAND_PREFIX: - read_command (); - break; - - case '{': - - /* Special case. I'm not supposed to see this character by itself. - If I do, it means there is a syntax error in the input text. - Report the error here, but remember this brace on the stack so - you can ignore its partner. */ - - line_error ("Misplaced `{'"); - remember_brace (misplaced_brace); - - /* Don't advance input_text_offset since this happens in - remember_brace (). - input_text_offset++; + { + case COMMAND_PREFIX: + read_command (); + break; + + case '{': + /* Special case. I'm not supposed to see this character by itself. + If I do, it means there is a syntax error in the input text. + Report the error here, but remember this brace on the stack so + you can ignore its partner. */ + + line_error (_("Misplaced %c"), '{'); + remember_brace (misplaced_brace); + + /* Don't advance input_text_offset since this happens in + remember_brace (). + input_text_offset++; */ - break; + break; - case '}': - pop_and_call_brace (); - input_text_offset++; - break; + case '}': + pop_and_call_brace (); + input_text_offset++; + break; - default: - add_char (character); - input_text_offset++; - } + default: + add_char (character); + input_text_offset++; + } } #if defined (HAVE_MACROS) if (macro_expansion_output_stream) @@ -2360,18 +2452,18 @@ get_command_entry (string) { register int i; - for (i = 0; CommandTable[i].name; i++) - if (strcmp (CommandTable[i].name, string) == 0) - return (&CommandTable[i]); + for (i = 0; command_table[i].name; i++) + if (strcmp (command_table[i].name, string) == 0) + return (&command_table[i]); /* This command is not in our predefined command table. Perhaps it is a user defined command. */ for (i = 0; i < user_command_array_len; i++) if (user_command_array[i] && - (strcmp (user_command_array[i]->name, string) == 0)) + (strcmp (user_command_array[i]->name, string) == 0)) return (user_command_array[i]); - /* Nope, we never heard of this command. */ + /* We never heard of this command. */ return ((COMMAND *) -1); } @@ -2395,26 +2487,25 @@ read_command () if (def) { - /* We disallow recursive use of a macro call. Inhibit the expansion - of this macro during the life of its execution. */ - if (!(def->flags & ME_RECURSE)) - def->inhibited = 1; + /* We disallow recursive use of a macro call. Inhibit the expansion + of this macro during the life of its execution. */ + if (!(def->flags & ME_RECURSE)) + def->inhibited = 1; - execute_macro (def); + execute_macro (def); - if (!(def->flags & ME_RECURSE)) - def->inhibited = 0; + if (!(def->flags & ME_RECURSE)) + def->inhibited = 0; - return; + return; } } #endif /* HAVE_MACROS */ entry = get_command_entry (command); - if (entry == (COMMAND *)-1) { - line_error ("Unknown command `%s'", command); + line_error (_("Unknown command `%s'"), command); return; } @@ -2431,10 +2522,10 @@ find_proc_name (proc) { register int i; - for (i = 0; CommandTable[i].name; i++) - if (proc == CommandTable[i].proc) - return (CommandTable[i].name); - return ("NO_NAME!"); + for (i = 0; command_table[i].name; i++) + if (proc == command_table[i].proc) + return command_table[i].name; + return _("NO_NAME!"); } void @@ -2448,7 +2539,7 @@ remember_brace (proc) COMMAND_FUNCTION *proc; { if (curchar () != '{') - line_error ("%c%s expected `{..}'", COMMAND_PREFIX, command); + line_error (_("%c%s expected `{...}'"), COMMAND_PREFIX, command); else input_text_offset++; remember_brace_1 (proc, output_paragraph_offset); @@ -2481,7 +2572,7 @@ pop_and_call_brace () if (brace_stack == (BRACE_ELEMENT *) NULL) { - line_error ("Unmatched }"); + line_error (_("Unmatched }")); return; } @@ -2505,7 +2596,7 @@ adjust_braces_following (here, amount) while (stack) { if (stack->pos >= here) - stack->pos += amount; + stack->pos += amount; stack = stack->next; } } @@ -2523,23 +2614,23 @@ discard_braces () while (brace_stack) { if (brace_stack->proc != misplaced_brace) - { - char *proc_name; - int temp_line_number = line_number; - - line_number = brace_stack->line; - proc_name = find_proc_name (brace_stack->proc); - line_error ("%c%s missing close brace", COMMAND_PREFIX, proc_name); - line_number = temp_line_number; - pop_and_call_brace (); - } + { + char *proc_name; + int temp_line_number = line_number; + + line_number = brace_stack->line; + proc_name = find_proc_name (brace_stack->proc); + line_error (_("%c%s missing close brace"), COMMAND_PREFIX, proc_name); + line_number = temp_line_number; + pop_and_call_brace (); + } else - { - BRACE_ELEMENT *temp; - temp = brace_stack->next; - free (brace_stack); - brace_stack = temp; - } + { + BRACE_ELEMENT *temp; + temp = brace_stack->next; + free (brace_stack); + brace_stack = temp; + } } } @@ -2555,9 +2646,9 @@ get_char_len (character) case '\t': len = (output_column + 8) & 0xf7; if (len > fill_column) - len = fill_column - output_column; + len = fill_column - output_column; else - len = len - output_column; + len = len - output_column; break; case '\n': @@ -2565,44 +2656,42 @@ get_char_len (character) break; default: - if (character < ' ') - len = 2; + /* ASCII control characters appear as two characters in the output + (e.g., ^A). But characters with the high bit set are just one + on suitable terminals, so don't count them as two for line + breaking purposes. */ + if (0 <= character && character < ' ') + len = 2; else - len = 1; + len = 1; } return (len); } -#if defined (HAVE_VARARGS_H) && defined (HAVE_VSPRINTF) - void -add_word_args (va_alist) - va_dcl +#if defined (VA_FPRINTF) && __STDC__ +add_word_args (char *format, ...) +#else +add_word_args (format, va_alist) + char *format; + va_dcl +#endif { char buffer[1000]; - char *format; - va_list args; - - va_start (args); - format = va_arg (args, char *); - vsprintf (buffer, format, args); - va_end (args); - add_word (buffer); -} - -#else /* !(HAVE_VARARGS_H && HAVE_VSPRINTF) */ +#ifdef VA_FPRINTF + va_list ap; +#endif -void -add_word_args (format, arg1, arg2, arg3, arg4, arg5) - char *format; -{ - char buffer[1000]; - sprintf (buffer, format, arg1, arg2, arg3, arg4, arg5); + VA_START (ap, format); +#ifdef VA_SPRINTF + VA_SPRINTF (buffer, format, ap); +#else + sprintf (temp_string, format, a1, a2, a3, a4, a5, a6, a7, a8); +#endif /* not VA_SPRINTF */ + va_end (ap); add_word (buffer); } -#endif /* !(HAVE_VARARGS_H && HAVE_VSPRINTF) */ - /* Add STRING to output_paragraph. */ void add_word (string) @@ -2612,26 +2701,26 @@ add_word (string) add_char (*string++); } -/* Non-zero if the last character inserted has the syntax class of NEWLINE. */ +/* Nonzero if the last character inserted has the syntax class of NEWLINE. */ int last_char_was_newline = 1; /* The actual last inserted character. Note that this may be something other than NEWLINE even if last_char_was_newline is 1. */ int last_inserted_character = 0; -/* Non-zero means that a newline character has already been +/* Nonzero means that a newline character has already been inserted, so close_paragraph () should insert one less. */ int line_already_broken = 0; -/* When non-zero we have finished an insertion (see end_insertion ()) and we +/* When nonzero we have finished an insertion (see `end_insertion') and we want to ignore false continued paragraph closings. */ int insertion_paragraph_closed = 0; -/* Non-zero means attempt to make all of the lines have fill_column width. */ +/* Nonzero means attempt to make all of the lines have fill_column width. */ int do_justification = 0; /* Add the character to the current paragraph. If filling_enabled is - non-zero, then do filling as well. */ + nonzero, then do filling as well. */ void add_char (character) int character; @@ -2646,12 +2735,12 @@ add_char (character) if (must_start_paragraph && character != '\n') { must_start_paragraph = 0; - line_already_broken = 0; /* The line is no longer broken. */ + line_already_broken = 0; /* The line is no longer broken. */ if (current_indent > output_column) - { - indent (current_indent - output_column); - output_column = current_indent; - } + { + indent (current_indent - output_column); + output_column = current_indent; + } } if (non_splitting_words && member (character, " \t\n")) @@ -2663,168 +2752,168 @@ add_char (character) { case '\n': if (!filling_enabled) - { - insert ('\n'); - - if (force_flush_right) - { - close_paragraph (); - /* Hack to force single blank lines out in this mode. */ - flush_output (); - } - - output_column = 0; - - if (!no_indent && paragraph_is_open) - indent (output_column = current_indent); - break; - } + { + insert ('\n'); + + if (force_flush_right) + { + close_paragraph (); + /* Hack to force single blank lines out in this mode. */ + flush_output (); + } + + output_column = 0; + + if (!no_indent && paragraph_is_open) + indent (output_column = current_indent); + break; + } else /* CHARACTER is newline, and filling is enabled. */ - { - if (sentence_ender (last_inserted_character)) - { - insert (' '); - output_column++; - last_inserted_character = character; - } - } + { + if (end_of_sentence_p ()) + { + insert (' '); + output_column++; + last_inserted_character = character; + } + } if (last_char_was_newline) - { - close_paragraph (); - pending_indent = 0; - } + { + close_paragraph (); + pending_indent = 0; + } else - { - last_char_was_newline = 1; - insert (' '); - output_column++; - } + { + last_char_was_newline = 1; + insert (' '); + output_column++; + } break; default: { - int len = get_char_len (character); - int suppress_insert = 0; - - if ((character == ' ') && (last_char_was_newline)) - { - if (!paragraph_is_open) - { - pending_indent++; - return; - } - } - - if (!paragraph_is_open) - { - start_paragraph (); - - /* If the paragraph is supposed to be indented a certain way, - then discard all of the pending whitespace. Otherwise, we - let the whitespace stay. */ - if (!paragraph_start_indent) - indent (pending_indent); - pending_indent = 0; - } - - if ((output_column += len) > fill_column) - { - if (filling_enabled) - { - int temp = output_paragraph_offset; - while (--temp > 0 && output_paragraph[temp] != '\n') - { - /* If we have found a space, we have the place to break - the line. */ - if (output_paragraph[temp] == ' ') - { - /* Remove trailing whitespace from output. */ - while (temp && whitespace (output_paragraph[temp - 1])) - temp--; - - output_paragraph[temp++] = '\n'; - - /* We have correctly broken the line where we want - to. What we don't want is spaces following where - we have decided to break the line. We get rid of - them. */ - { - int t1 = temp; - - for (;; t1++) - { - if (t1 == output_paragraph_offset) - { - if (whitespace (character)) - suppress_insert = 1; - break; - } - if (!whitespace (output_paragraph[t1])) - break; - } - - if (t1 != temp) - { - adjust_braces_following (temp, (- (t1 - temp))); - strncpy ((char *) &output_paragraph[temp], - (char *) &output_paragraph[t1], - (output_paragraph_offset - t1)); - output_paragraph_offset -= (t1 - temp); - } - } - - /* Filled, but now indent if that is right. */ - if (indented_fill && current_indent) - { - int buffer_len = ((output_paragraph_offset - temp) - + current_indent); - char *temp_buffer = (char *)xmalloc (buffer_len); - int indentation = 0; - - /* We have to shift any markers that are in - front of the wrap point. */ - adjust_braces_following (temp, current_indent); - - while (current_indent > 0 && - indentation != current_indent) - temp_buffer[indentation++] = ' '; - - strncpy ((char *) &temp_buffer[current_indent], - (char *) &output_paragraph[temp], - buffer_len - current_indent); - - if (output_paragraph_offset + buffer_len - >= paragraph_buffer_len) - { - unsigned char *tt = xrealloc - (output_paragraph, - (paragraph_buffer_len += buffer_len)); - output_paragraph = tt; - } - strncpy ((char *) &output_paragraph[temp], - temp_buffer, buffer_len); - output_paragraph_offset += current_indent; - free (temp_buffer); - } - output_column = 0; - while (temp < output_paragraph_offset) - output_column += - get_char_len (output_paragraph[temp++]); - output_column += len; - break; - } - } - } - } - - if (!suppress_insert) - { - insert (character); - last_inserted_character = character; - } - last_char_was_newline = 0; - line_already_broken = 0; + int len = get_char_len (character); + int suppress_insert = 0; + + if ((character == ' ') && (last_char_was_newline)) + { + if (!paragraph_is_open) + { + pending_indent++; + return; + } + } + + if (!paragraph_is_open) + { + start_paragraph (); + + /* If the paragraph is supposed to be indented a certain way, + then discard all of the pending whitespace. Otherwise, we + let the whitespace stay. */ + if (!paragraph_start_indent) + indent (pending_indent); + pending_indent = 0; + } + + if ((output_column += len) > fill_column) + { + if (filling_enabled) + { + int temp = output_paragraph_offset; + while (--temp > 0 && output_paragraph[temp] != '\n') + { + /* If we have found a space, we have the place to break + the line. */ + if (output_paragraph[temp] == ' ') + { + /* Remove trailing whitespace from output. */ + while (temp && whitespace (output_paragraph[temp - 1])) + temp--; + + output_paragraph[temp++] = '\n'; + + /* We have correctly broken the line where we want + to. What we don't want is spaces following where + we have decided to break the line. We get rid of + them. */ + { + int t1 = temp; + + for (;; t1++) + { + if (t1 == output_paragraph_offset) + { + if (whitespace (character)) + suppress_insert = 1; + break; + } + if (!whitespace (output_paragraph[t1])) + break; + } + + if (t1 != temp) + { + adjust_braces_following (temp, (- (t1 - temp))); + strncpy ((char *) &output_paragraph[temp], + (char *) &output_paragraph[t1], + (output_paragraph_offset - t1)); + output_paragraph_offset -= (t1 - temp); + } + } + + /* Filled, but now indent if that is right. */ + if (indented_fill && current_indent) + { + int buffer_len = ((output_paragraph_offset - temp) + + current_indent); + char *temp_buffer = (char *)xmalloc (buffer_len); + int indentation = 0; + + /* We have to shift any markers that are in + front of the wrap point. */ + adjust_braces_following (temp, current_indent); + + while (current_indent > 0 && + indentation != current_indent) + temp_buffer[indentation++] = ' '; + + strncpy ((char *) &temp_buffer[current_indent], + (char *) &output_paragraph[temp], + buffer_len - current_indent); + + if (output_paragraph_offset + buffer_len + >= paragraph_buffer_len) + { + unsigned char *tt = xrealloc + (output_paragraph, + (paragraph_buffer_len += buffer_len)); + output_paragraph = tt; + } + strncpy ((char *) &output_paragraph[temp], + temp_buffer, buffer_len); + output_paragraph_offset += current_indent; + free (temp_buffer); + } + output_column = 0; + while (temp < output_paragraph_offset) + output_column += + get_char_len (output_paragraph[temp++]); + output_column += len; + break; + } + } + } + } + + if (!suppress_insert) + { + insert (character); + last_inserted_character = character; + } + last_char_was_newline = 0; + line_already_broken = 0; } } } @@ -2838,7 +2927,7 @@ insert (character) if (output_paragraph_offset == paragraph_buffer_len) { output_paragraph = - xrealloc (output_paragraph, (paragraph_buffer_len += 100)); + xrealloc (output_paragraph, (paragraph_buffer_len += 100)); } } @@ -2851,6 +2940,23 @@ insert_string (string) insert (*string++); } + +/* Sentences might have these characters after the period (or whatever). */ +#define post_sentence(c) ((c) == ')' || (c) == '\'' || (c) == '"' \ + || (c) == ']') + +/* Return true if at an end-of-sentence character, possibly followed by + post-sentence punctuation to ignore. */ +static int +end_of_sentence_p () +{ + int loc = output_paragraph_offset - 1; + while (loc > 0 && post_sentence (output_paragraph[loc])) + loc--; + return sentence_ender (output_paragraph[loc]); +} + + /* Remove upto COUNT characters of whitespace from the the current output line. If COUNT is less than zero, then remove until none left. */ @@ -2863,24 +2969,24 @@ kill_self_indent (count) { output_column = 0; while (output_paragraph_offset) - { - if (whitespace (output_paragraph[output_paragraph_offset - 1])) - output_paragraph_offset--; - else - break; - } + { + if (whitespace (output_paragraph[output_paragraph_offset - 1])) + output_paragraph_offset--; + else + break; + } } else { while (output_paragraph_offset && count--) - if (whitespace (output_paragraph[output_paragraph_offset - 1])) - output_paragraph_offset--; - else - break; + if (whitespace (output_paragraph[output_paragraph_offset - 1])) + output_paragraph_offset--; + else + break; } } -/* Non-zero means do not honor calls to flush_output (). */ +/* Nonzero means do not honor calls to flush_output (). */ static int flushing_ignored = 0; /* Prevent calls to flush_output () from having any effect. */ @@ -2913,7 +3019,7 @@ flush_output () { int temp = UNMETA (output_paragraph[i]); if (temp == ' ') - output_paragraph[i] &= 0x7f; + output_paragraph[i] &= 0x7f; } } @@ -2947,30 +3053,28 @@ close_insertion_paragraph () /* Close the current paragraph, breaking the line. */ close_single_paragraph (); - /* Start a new paragraph here, inserting whatever indention is correct - for the now current insertion level (one above the one that we are - ending). */ + /* Start a new paragraph, with the correct indentation for the now + current insertion level (one above the one that we are ending). */ start_paragraph (); - /* Tell close_paragraph () that the previous line has already been - broken, so it should insert one less newline. */ + /* Tell `close_paragraph' that the previous line has already been + broken, so it should insert one less newline. */ line_already_broken = 1; - /* Let functions such as add_char () know that we have already found a - newline. */ + /* Tell functions such as `add_char' we've already found a newline. */ ignore_blank_line (); } else { /* If the insertion paragraph is closed already, then we are seeing - two `@end' commands in a row. Note that the first one we saw was - handled in the first part of this if-then-else clause, and at that - time start_paragraph () was called, partially to handle the proper - indentation of the current line. However, the indentation level - may have just changed again, so we may have to outdent the current - line to the new indentation level. */ + two `@end' commands in a row. Note that the first one we saw was + handled in the first part of this if-then-else clause, and at that + time `start_paragraph' was called, partially to handle the proper + indentation of the current line. However, the indentation level + may have just changed again, so we may have to outdent the current + line to the new indentation level. */ if (current_indent < output_column) - kill_self_indent (output_column - current_indent); + kill_self_indent (output_column - current_indent); } insertion_paragraph_closed = 1; @@ -3002,37 +3106,37 @@ close_paragraph () tindex = output_paragraph_offset; /* Back up to last non-newline/space character, forcing all such - subsequent characters to be newlines. This isn't strictly - necessary, but a couple of functions use the presence of a newline - to make decisions. */ + subsequent characters to be newlines. This isn't strictly + necessary, but a couple of functions use the presence of a newline + to make decisions. */ for (tindex = output_paragraph_offset - 1; tindex >= 0; --tindex) - { - c = output_paragraph[tindex]; + { + c = output_paragraph[tindex]; - if (c == ' '|| c == '\n') - output_paragraph[tindex] = '\n'; - else - break; - } + if (c == ' '|| c == '\n') + output_paragraph[tindex] = '\n'; + else + break; + } /* All trailing whitespace is ignored. */ output_paragraph_offset = ++tindex; /* Break the line if that is appropriate. */ if (paragraph_spacing >= 0) - insert ('\n'); + insert ('\n'); - /* Add as many blank lines as is specified in PARAGRAPH_SPACING. */ + /* Add as many blank lines as is specified in `paragraph_spacing'. */ if (!force_flush_right) - { - for (i = 0; i < (paragraph_spacing - line_already_broken); i++) - insert ('\n'); - } + { + for (i = 0; i < (paragraph_spacing - line_already_broken); i++) + insert ('\n'); + } /* If we are doing flush right indentation, then do it now - on the paragraph (really a single line). */ + on the paragraph (really a single line). */ if (force_flush_right) - do_flush_right_indentation (); + do_flush_right_indentation (); flush_output (); paragraph_is_open = 0; @@ -3061,28 +3165,28 @@ do_flush_right_indentation () if (output_paragraph[0] != '\n') { - output_paragraph[output_paragraph_offset] = '\0'; + output_paragraph[output_paragraph_offset] = 0; if (output_paragraph_offset < fill_column) - { - register int i; + { + register int i; - if (fill_column >= paragraph_buffer_len) - output_paragraph = - xrealloc (output_paragraph, - (paragraph_buffer_len += fill_column)); + if (fill_column >= paragraph_buffer_len) + output_paragraph = + xrealloc (output_paragraph, + (paragraph_buffer_len += fill_column)); - temp_len = strlen ((char *)output_paragraph); - temp = (char *)xmalloc (temp_len + 1); - memcpy (temp, (char *)output_paragraph, temp_len); + temp_len = strlen ((char *)output_paragraph); + temp = (char *)xmalloc (temp_len + 1); + memcpy (temp, (char *)output_paragraph, temp_len); - for (i = 0; i < fill_column - output_paragraph_offset; i++) - output_paragraph[i] = ' '; + for (i = 0; i < fill_column - output_paragraph_offset; i++) + output_paragraph[i] = ' '; - memcpy ((char *)output_paragraph + i, temp, temp_len); - free (temp); - output_paragraph_offset = fill_column; - } + memcpy ((char *)output_paragraph + i, temp, temp_len); + free (temp); + output_paragraph_offset = fill_column; + } } } @@ -3109,25 +3213,25 @@ start_paragraph () /* If doing indentation, then insert the appropriate amount. */ if (!no_indent) - { - if (inhibit_paragraph_indentation) - { - amount_to_indent = current_indent; - if (inhibit_paragraph_indentation < 0) - inhibit_paragraph_indentation++; - } - else if (paragraph_start_indent < 0) - amount_to_indent = current_indent; - else - amount_to_indent = current_indent + paragraph_start_indent; - - if (amount_to_indent >= output_column) - { - amount_to_indent -= output_column; - indent (amount_to_indent); - output_column += amount_to_indent; - } - } + { + if (inhibit_paragraph_indentation) + { + amount_to_indent = current_indent; + if (inhibit_paragraph_indentation < 0) + inhibit_paragraph_indentation++; + } + else if (paragraph_start_indent < 0) + amount_to_indent = current_indent; + else + amount_to_indent = current_indent + paragraph_start_indent; + + if (amount_to_indent >= output_column) + { + amount_to_indent -= output_column; + indent (amount_to_indent); + output_column += amount_to_indent; + } + } } else must_start_paragraph = 0; @@ -3145,7 +3249,7 @@ indent (amount) while (elt) { if (elt->pos >= output_paragraph_offset) - elt->pos += amount; + elt->pos += amount; elt = elt->next; } @@ -3165,7 +3269,7 @@ search_forward (string, from) while (from < size_of_input_text) { if (strncmp (input_text + from, string, len) == 0) - return (from); + return (from); from++; } return (-1); @@ -3187,13 +3291,13 @@ strcasecmp (string1, string2) ch2 = *string2++; if (!(ch1 | ch2)) - return (0); + return (0); ch1 = coerce_to_upper (ch1); ch2 = coerce_to_upper (ch2); if (ch1 != ch2) - return (ch1 - ch2); + return (ch1 - ch2); } } #endif /* !HAVE_STRCASECMP */ @@ -3230,18 +3334,20 @@ current_item_function () while (!done && (elt != NULL)) { switch (elt->insertion) - { - case ifinfo: - case ifset: - case ifclear: - case cartouche: - elt = elt->next; - level--; - break; - - default: - done = 1; - } + { + case ifinfo: + case ifnothtml: + case ifnottex: + case ifset: + case ifclear: + case cartouche: + elt = elt->next; + level--; + break; + + default: + done = 1; + } } if (!level) @@ -3256,7 +3362,6 @@ get_item_function () char *item_function; get_rest_of_line (&item_function); backup_input_pointer (); - canon_white (item_function); return (item_function); } @@ -3273,7 +3378,7 @@ push_insertion (type, item_function) new->indented_fill = indented_fill; new->insertion = type; new->line_number = line_number; - new->filename = strdup (input_filename); + new->filename = xstrdup (input_filename); new->inhibited = inhibit_paragraph_indentation; new->in_fixed_width_font = in_fixed_width_font; new->next = insertion_stack; @@ -3311,7 +3416,7 @@ insertion_type_pname (type) if ((int) type < (int) bad_type) return (insertion_type_names[(int) type]); else - return ("Broken-Type in insertion_type_pname"); + return (_("Broken-Type in insertion_type_pname")); } /* Return the insertion_type associated with NAME. @@ -3324,7 +3429,7 @@ find_type_from_name (name) while (index < (int) bad_type) { if (strcmp (name, insertion_type_names[index]) == 0) - return (enum insertion_type) index; + return (enum insertion_type) index; index++; } return (bad_type); @@ -3377,7 +3482,7 @@ start_enumerating (at, type) { if ((enumstack_offset + 1) == max_stack_depth) { - line_error ("Enumeration stack overflow"); + line_error (_("Enumeration stack overflow")); return; } enumstack[enumstack_offset].enumtype = current_enumtype; @@ -3407,10 +3512,10 @@ enumerate_item () if (current_enumtype == ENUM_ALPHA) { if (current_enumval == ('z' + 1) || current_enumval == ('Z' + 1)) - { - current_enumval = ((current_enumval - 1) == 'z' ? 'a' : 'A'); - warning ("Lettering overflow, restarting at %c", current_enumval); - } + { + current_enumval = ((current_enumval - 1) == 'z' ? 'a' : 'A'); + warning (_("lettering overflow, restarting at %c"), current_enumval); + } sprintf (temp, "%c. ", current_enumval); } else @@ -3432,7 +3537,7 @@ begin_insertion (type) if (defun_insertion (type)) { - push_insertion (type, strdup ("")); + push_insertion (type, xstrdup ("")); no_discard++; } else @@ -3442,30 +3547,29 @@ begin_insertion (type) { case menu: if (!no_headers) - close_paragraph (); + close_paragraph (); filling_enabled = no_indent = 0; inhibit_paragraph_indentation = 1; if (!no_headers) - add_word ("* Menu:\n"); + add_word (_("* Menu:\n")); in_menu++; no_discard++; break; case detailmenu: - if (!in_menu) - { - if (!no_headers) - close_paragraph (); + { + if (!no_headers) + close_paragraph (); - filling_enabled = no_indent = 0; - inhibit_paragraph_indentation = 1; + filling_enabled = no_indent = 0; + inhibit_paragraph_indentation = 1; - no_discard++; - } + no_discard++; + } in_detailmenu++; break; @@ -3478,7 +3582,7 @@ begin_insertion (type) break; /* I think @quotation is meant to do filling. - If you don't want filling, then use @display. */ + If you don't want filling, then use @display. */ case quotation: close_single_paragraph (); last_char_was_newline = no_indent = 0; @@ -3494,16 +3598,13 @@ begin_insertion (type) case smalllisp: /* Just like @example, but no indentation. */ case format: - close_single_paragraph (); inhibit_paragraph_indentation = 1; in_fixed_width_font++; filling_enabled = 0; last_char_was_newline = 0; - if (type != format) - current_indent += default_indentation_increment; - + current_indent += default_indentation_increment; break; case multitable: @@ -3525,20 +3626,20 @@ begin_insertion (type) /* Make things work for losers who forget the itemize syntax. */ if (allow_lax_format && (type == itemize)) - { - if (!(*insertion_stack->item_function)) - { - free (insertion_stack->item_function); - insertion_stack->item_function = strdup ("@bullet"); - insertion_stack->item_function[0] = COMMAND_PREFIX; - } - } + { + if (!(*insertion_stack->item_function)) + { + free (insertion_stack->item_function); + insertion_stack->item_function = xstrdup ("@bullet"); + insertion_stack->item_function[0] = COMMAND_PREFIX; + } + } if (!*insertion_stack->item_function) - { - line_error ("%s requires an argument: the formatter for %citem", - insertion_type_pname (type), COMMAND_PREFIX); - } + { + line_error (_("%s requires an argument: the formatter for %citem"), + insertion_type_pname (type), COMMAND_PREFIX); + } break; case enumerate: @@ -3554,26 +3655,28 @@ begin_insertion (type) filling_enabled = indented_fill = 1; if (isdigit (*enumeration_arg)) - start_enumerating (atoi (enumeration_arg), ENUM_DIGITS); + start_enumerating (atoi (enumeration_arg), ENUM_DIGITS); else - start_enumerating (*enumeration_arg, ENUM_ALPHA); + start_enumerating (*enumeration_arg, ENUM_ALPHA); break; /* Does nothing special in makeinfo. */ case group: /* Only close the paragraph if we are not inside of an @example. */ if (!insertion_stack->next || - insertion_stack->next->insertion != example) - close_single_paragraph (); + insertion_stack->next->insertion != example) + close_single_paragraph (); break; /* Insertions that are no-ops in info, but do something in TeX. */ case ifinfo: + case ifnothtml: + case ifnottex: case ifset: case ifclear: case cartouche: if (in_menu) - no_discard++; + no_discard++; break; case deffn: @@ -3617,11 +3720,10 @@ begin_insertion (type) discard_until ("\n"); } -/* Try to end the insertion with the specified TYPE. - TYPE, with a value of bad_type, gets translated to match - the value currently on top of the stack. - Otherwise, if TYPE doesn't match the top of the insertion stack, - give error. */ +/* Try to end the insertion with the specified TYPE. With a value of + `bad_type', TYPE gets translated to match the value currently on top + of the stack. Otherwise, if TYPE doesn't match the top of the + insertion stack, give error. */ void end_insertion (type) enum insertion_type type; @@ -3639,8 +3741,8 @@ end_insertion (type) if (type != temp_type) { line_error - ("`%cend' expected `%s', but saw `%s'", COMMAND_PREFIX, - insertion_type_pname (temp_type), insertion_type_pname (type)); + (_("`%cend' expected `%s', but saw `%s'"), COMMAND_PREFIX, + insertion_type_pname (temp_type), insertion_type_pname (type)); return; } @@ -3649,6 +3751,8 @@ end_insertion (type) switch (type) { /* Insertions which have no effect on paragraph formatting. */ + case ifnothtml: + case ifnottex: case ifinfo: case ifset: case ifclear: @@ -3660,18 +3764,18 @@ end_insertion (type) break; case detailmenu: - in_detailmenu--; /* No longer hacking menus. */ + in_detailmenu--; /* No longer hacking menus. */ if (!in_menu) - { - if (!no_headers) - close_insertion_paragraph (); - } + { + if (!no_headers) + close_insertion_paragraph (); + } break; case menu: - in_menu--; /* No longer hacking menus. */ + in_menu--; /* No longer hacking menus. */ if (!no_headers) - close_insertion_paragraph (); + close_insertion_paragraph (); break; case multitable: @@ -3697,14 +3801,13 @@ end_insertion (type) case lisp: case smalllisp: case quotation: - /* @format is the only fixed_width insertion without a change - in indentation. */ + in indentation. */ if (type != format) - current_indent -= default_indentation_increment; + current_indent -= default_indentation_increment; /* The ending of one of these insertions always marks the - start of a new paragraph. */ + start of a new paragraph. */ close_insertion_paragraph (); break; @@ -3729,33 +3832,32 @@ end_insertion (type) } /* Insertions cannot cross certain boundaries, such as node beginnings. In - code that creates such boundaries, you should call discard_insertions () + code that creates such boundaries, you should call `discard_insertions' before doing anything else. It prints the errors for you, and cleans up - the insertion stack. */ + the insertion stack. With nonzero SPECIALS_OK, allows unmatched + ifinfo, ifset, ifclear, otherwise not. */ void -discard_insertions () +discard_insertions (specials_ok) + int specials_ok; { int real_line_number = line_number; while (insertion_stack) { - if (insertion_stack->insertion == ifinfo || - insertion_stack->insertion == ifset || - insertion_stack->insertion == ifclear) - break; + if (specials_ok && (insertion_stack->insertion == ifinfo + || insertion_stack->insertion == ifset + || insertion_stack->insertion == ifclear)) + break; else - { - char *offender; - char *current_filename; - - current_filename = input_filename; - offender = (char *)insertion_type_pname (insertion_stack->insertion); - input_filename = insertion_stack->filename; - line_number = insertion_stack->line_number; - line_error ("This `%s' doesn't have a matching `%cend %s'", offender, - COMMAND_PREFIX, offender); - input_filename = current_filename; - pop_insertion (); - } + { + char *offender = insertion_type_pname (insertion_stack->insertion); + char *current_filename = input_filename; + + input_filename = insertion_stack->filename; + line_number = insertion_stack->line_number; + line_error (_("No matching `%cend %s'"), COMMAND_PREFIX, offender); + input_filename = current_filename; + pop_insertion (); + } } line_number = real_line_number; } @@ -3784,9 +3886,7 @@ void cm_asterisk () { close_single_paragraph (); -#if !defined (ASTERISK_NEW_PARAGRAPH) cm_noindent (); -#endif /* ASTERISK_NEW_PARAGRAPH */ } /* Insert ellipsis. */ @@ -3893,7 +3993,7 @@ cm_special_char (arg) else if (strcmp (command, "questiondown") == 0) add_char ('?'); else - fprintf (stderr, "How did @%s end up in cm_special_char?\n", command); + fprintf (stderr, _("How did @%s end up in cm_special_char?\n"), command); } } @@ -3907,12 +4007,12 @@ cm_dotless (arg, start, end) if (output_paragraph[start] != 'i' && output_paragraph[start] != 'j') /* This error message isn't perfect if the argument is multiple characters, but it doesn't seem worth getting right. */ - line_error ("%c%s expects `i' or `j' as argument, not `%c'", + line_error (_("%c%s expects `i' or `j' as argument, not `%c'"), COMMAND_PREFIX, command, output_paragraph[start]); else if (end - start != 1) - line_error ("%c%s expects a single character `i' or `j' as argument", - COMMAND_PREFIX, command); + line_error (_("%c%s expects a single character `i' or `j' as argument"), + COMMAND_PREFIX, command); /* We've already inserted the `i' or `j', so nothing to do. */ } @@ -3922,18 +4022,16 @@ void cm_today (arg) int arg; { - static char * months [12] = - { "January", "February", "March", "April", "May", "June", "July", - "August", "September", "October", "November", "December" }; + static char *months [12] = + { N_("January"), N_("February"), N_("March"), N_("April"), N_("May"), + N_("June"), N_("July"), N_("August"), N_("September"), N_("October"), + N_("November"), N_("December") }; if (arg == START) { time_t timer = time (0); struct tm *ts = localtime (&timer); - add_word_args - ("%d %s %d", - (ts -> tm_mday), - (months [ts -> tm_mon]), - ((ts -> tm_year) + 1900)); + add_word_args ("%d %s %d", ts->tm_mday, _(months[ts->tm_mon]), + ts->tm_year + 1900); } } @@ -3948,12 +4046,12 @@ cm_code (arg) in_fixed_width_font++; if (!printing_index) - add_char ('`'); + add_char ('`'); } else { if (!printing_index) - add_char ('\''); + add_char ('\''); } } @@ -3968,7 +4066,7 @@ cm_kbd (arg) } void -cm_angle_brackets (arg) +cm_key (arg) int arg; { add_char (arg == START ? '<' : '>'); @@ -3985,17 +4083,17 @@ cm_ctrl (arg, start, end) register int i, character; #if defined (NO_MULTIPLE_CTRL) if ((end - start) != 1) - line_error ("%c%s expects a single character as an argument", - COMMAND_PREFIX, command); + line_error (_("%c%s expects a single character as an argument"), + COMMAND_PREFIX, command); else #endif - for (i = start; i < end; i++) - { - character = output_paragraph[i]; + for (i = start; i < end; i++) + { + character = output_paragraph[i]; - if (isletter (character)) - output_paragraph[i] = CTL (coerce_to_upper (character)); - } + if (isletter (character)) + output_paragraph[i] = CTL (coerce_to_upper (character)); + } } } @@ -4008,9 +4106,9 @@ not_fixed_width (arg) in_fixed_width_font = 0; } -/* Small caps in makeinfo has to do just all caps. */ +/* Small caps and @var in makeinfo just uppercase the text. */ void -cm_sc (arg, start_pos, end_pos) +cm_var_sc (arg, start_pos, end_pos) int arg, start_pos, end_pos; { not_fixed_width (arg); @@ -4018,29 +4116,11 @@ cm_sc (arg, start_pos, end_pos) if (arg == END) { while (start_pos < end_pos) - { - output_paragraph[start_pos] = - coerce_to_upper (output_paragraph[start_pos]); - start_pos++; - } - } -} - -/* @var in makeinfo just uppercases the text. */ -void -cm_var (arg, start_pos, end_pos) - int arg, start_pos, end_pos; -{ - not_fixed_width (arg); - - if (arg == END) - { - while (start_pos < end_pos) - { - output_paragraph[start_pos] = - coerce_to_upper (output_paragraph[start_pos]); - start_pos++; - } + { + output_paragraph[start_pos] = + coerce_to_upper (output_paragraph[start_pos]); + start_pos++; + } } } @@ -4083,12 +4163,21 @@ cm_not_fixed_width (arg, start, end) not_fixed_width (arg); } -/* Various commands are NOP's. */ +/* Various commands are no-op's. */ void cm_no_op () { } +/* No-op that eats its argument on same line. */ +void +cm_no_op_line_arg () +{ + char *temp; + get_rest_of_line (&temp); + free (temp); +} + /* Prevent the argument from being split across two lines. */ void cm_w (arg, start, end) @@ -4108,7 +4197,7 @@ cm_obsolete (arg, start, end) int arg, start, end; { if (arg == START) - warning ("The command `%c%s' is obsolete", COMMAND_PREFIX, command); + warning (_("%c%s is obsolete"), COMMAND_PREFIX, command); } /* Insert the text following input_text_offset up to the end of the line @@ -4128,7 +4217,7 @@ insert_and_underscore (with_char) no_indent = 1; #if defined (HAVE_MACROS) - if (macro_expansion_output_stream) + if (macro_expansion_output_stream && !executing_string) append_to_expansion_output (input_text_offset + 1); #endif /* HAVE_MACROS */ @@ -4136,11 +4225,9 @@ insert_and_underscore (with_char) starting_pos = output_position + output_paragraph_offset; #if defined (HAVE_MACROS) - if (macro_expansion_output_stream) + if (macro_expansion_output_stream && !executing_string) { - char *temp1; - - temp1 = (char *)xmalloc (2 + strlen (temp)); + char *temp1 = (char *) xmalloc (2 + strlen (temp)); sprintf (temp1, "%s\n", temp); remember_itext (input_text, input_text_offset); me_execute_string (temp1); @@ -4148,7 +4235,7 @@ insert_and_underscore (with_char) } else #endif /* HAVE_MACROS */ - execute_string ("%s\n", temp); + execute_string ("%s\n", temp); ending_pos = output_position + output_paragraph_offset; free (temp); @@ -4237,20 +4324,20 @@ what_section (text) for (j = 0; text[j] && !cr_or_whitespace (text[j]); j++); - for (i = 0; t = section_alist[i].name; i++) + for (i = 0; (t = section_alist[i].name); i++) { if (j == strlen (t) && strncmp (t, text, j) == 0) - { - int return_val; + { + int return_val; - return_val = (section_alist[i].level + section_alist_offset); + return_val = (section_alist[i].level + section_alist_offset); - if (return_val < 0) - return_val = 0; - else if (return_val > 5) - return_val = 5; - return (return_val); - } + if (return_val < 0) + return_val = 0; + else if (return_val > 5) + return_val = 5; + return (return_val); + } } return (-1); } @@ -4265,9 +4352,9 @@ set_top_section_level (level) for (i = 0; section_alist[i].name; i++) if (strcmp (section_alist[i].name, "top") == 0) { - result = section_alist[i].level; - section_alist[i].level = level; - break; + result = section_alist[i].level; + section_alist[i].level = level; + break; } return (result); } @@ -4282,25 +4369,25 @@ cm_top () { TAG_ENTRY *tag = tag_table; - line_error ("There already is a node having %ctop as a section", - COMMAND_PREFIX); + line_error (_("Node with %ctop as a section already exists"), + COMMAND_PREFIX); while (tag != (TAG_ENTRY *)NULL) - { - if ((tag->flags & IS_TOP)) - { - int old_line_number = line_number; - char *old_input_filename = input_filename; - - line_number = tag->line_no; - input_filename = tag->filename; - line_error ("Here is the %ctop node", COMMAND_PREFIX); - input_filename = old_input_filename; - line_number = old_line_number; - return; - } - tag = tag->next_ent; - } + { + if ((tag->flags & IS_TOP)) + { + int old_line_number = line_number; + char *old_input_filename = input_filename; + + line_number = tag->line_no; + input_filename = tag->filename; + line_error (_("Here is the %ctop node"), COMMAND_PREFIX); + input_filename = old_input_filename; + line_number = old_line_number; + return; + } + tag = tag->next_ent; + } } else { @@ -4308,16 +4395,16 @@ cm_top () /* It is an error to use @top before you have used @node. */ if (!tag_table) - { - char *top_name; - - get_rest_of_line (&top_name); - free (top_name); - line_error ("%ctop used before %cnode, defaulting to %s", - COMMAND_PREFIX, COMMAND_PREFIX, top_name); - execute_string ("@node Top, , (dir), (dir)\n@top %s\n", top_name); - return; - } + { + char *top_name; + + get_rest_of_line (&top_name); + free (top_name); + line_error (_("%ctop used before %cnode, defaulting to %s"), + COMMAND_PREFIX, COMMAND_PREFIX, top_name); + execute_string ("@node Top, , (dir), (dir)\n@top %s\n", top_name); + return; + } cm_unnumbered (); @@ -4326,33 +4413,33 @@ cm_top () /* Now set the logical hierarchical level of the Top node. */ { - int orig_offset = input_text_offset; + int orig_offset = input_text_offset; - input_text_offset = search_forward (node_search_string, orig_offset); + input_text_offset = search_forward (node_search_string, orig_offset); - if (input_text_offset > 0) - { - int this_section; + if (input_text_offset > 0) + { + int this_section; - /* We have encountered a non-top node, so mark that one exists. */ - non_top_node_seen = 1; + /* We have encountered a non-top node, so mark that one exists. */ + non_top_node_seen = 1; - /* Move to the end of this line, and find out what the - sectioning command is here. */ - while (input_text[input_text_offset] != '\n') - input_text_offset++; + /* Move to the end of this line, and find out what the + sectioning command is here. */ + while (input_text[input_text_offset] != '\n') + input_text_offset++; - if (input_text_offset < size_of_input_text) - input_text_offset++; + if (input_text_offset < size_of_input_text) + input_text_offset++; - this_section = what_section (input_text + input_text_offset); + this_section = what_section (input_text + input_text_offset); - /* If we found a sectioning command, then give the top section - a level of this section - 1. */ - if (this_section != -1) - set_top_section_level (this_section - 1); - } - input_text_offset = orig_offset; + /* If we found a sectioning command, then give the top section + a level of this section - 1. */ + if (this_section != -1) + set_top_section_level (this_section - 1); + } + input_text_offset = orig_offset; } } } @@ -4388,8 +4475,8 @@ void cm_ideprecated (arg, start, end) int arg, start, end; { - warning ("The command `%c%s' is obsolete; use `%c%s' instead", - COMMAND_PREFIX, command, COMMAND_PREFIX, command + 1); + warning (_("%c%s is obsolete; use %c%s instead"), + COMMAND_PREFIX, command, COMMAND_PREFIX, command + 1); sectioning_underscore (command + 1); } @@ -4512,9 +4599,9 @@ cm_subsubheading () } /* **************************************************************** */ -/* */ -/* Adding nodes, and making tags */ -/* */ +/* */ +/* Adding nodes, and making tags */ +/* */ /* **************************************************************** */ /* Start a new tag table. */ @@ -4536,7 +4623,7 @@ init_tag_table () void write_tag_table () { - write_tag_table_internal (0); /* Not indirect. */ + write_tag_table_internal (0); /* Not indirect. */ } void @@ -4580,11 +4667,12 @@ write_tag_table_internal (indirect_p) } char * -get_node_token () +get_node_token (expand) + int expand; { char *string; - get_until_in_line (",", &string); + get_until_in_line (expand, ",", &string); if (curchar () == ',') input_text_offset++; @@ -4617,7 +4705,7 @@ find_node (name) while (tag != (TAG_ENTRY *) NULL) { if (strcmp (tag->node, name) == 0) - return (tag); + return (tag); tag = tag->next_ent; } return ((TAG_ENTRY *) NULL); @@ -4634,11 +4722,12 @@ remember_node (node, prev, next, up, position, line_no, no_warn) { register TAG_ENTRY *tag = find_node (node); if (tag) - { - line_error ("Node `%s' multiply defined (%d is first definition)", - node, tag->line_no); - return; - } + { + line_error ( + _("Node `%s' multiply defined (line %d is first definition at)"), + node, tag->line_no); + return; + } } /* First, make this the current node. */ @@ -4654,7 +4743,7 @@ remember_node (node, prev, next, up, position, line_no, no_warn) new->position = position; new->line_no = line_no; new->filename = node_filename; - new->touched = 0; /* not yet referenced. */ + new->touched = 0; /* not yet referenced. */ new->flags = 0; if (no_warn) new->flags |= NO_WARN; @@ -4684,7 +4773,7 @@ cm_node () /* There also might be insertions left lying around that haven't been ended yet. Do that also. */ - discard_insertions (); + discard_insertions (1); if (!already_outputting_pending_notes) { @@ -4698,17 +4787,20 @@ cm_node () current_footnote_number = 1; #if defined (HAVE_MACROS) - if (macro_expansion_output_stream) + if (macro_expansion_output_stream && !executing_string) append_to_expansion_output (input_text_offset + 1); #endif /* HAVE_MACROS */ - node = get_node_token (); - next = get_node_token (); - prev = get_node_token (); - up = get_node_token (); + node = get_node_token (1); + next = get_node_token (0); + prev = get_node_token (0); + up = get_node_token (0); + if (verbose_mode) + printf (_("Formatting node %s...\n"), node); + #if defined (HAVE_MACROS) - if (macro_expansion_output_stream) + if (macro_expansion_output_stream && !executing_string) remember_itext (input_text, input_text_offset); #endif /* HAVE_MACROS */ @@ -4718,18 +4810,16 @@ cm_node () add_word_args ("\037\nFile: %s, Node: ", pretty_output_filename); #if defined (HAVE_MACROS) - if (macro_expansion_output_stream) - me_execute_string (node); + if (macro_expansion_output_stream && !executing_string) + me_execute_string (node); else #endif /* HAVE_MACROS */ - execute_string ("%s", node); + execute_string ("%s", node); filling_enabled = indented_fill = 0; } /* Check for defaulting of this node's next, prev, and up fields. */ - defaulting = ((strlen (next) == 0) && - (strlen (prev) == 0) && - (strlen (up) == 0)); + defaulting = (*next == 0 && *prev == 0 && *up == 0); this_section = what_section (input_text + input_text_offset); @@ -4744,164 +4834,164 @@ cm_node () NODE_REF *ref = node_references; if ((this_section < 0) && (strcmp (node, "Top") != 0)) - { - char *polite_section_name = "top"; - int i; - - for (i = 0; section_alist[i].name; i++) - if (section_alist[i].level == current_section + 1) - { - polite_section_name = section_alist[i].name; - break; - } - - line_error - ("Node `%s' requires a sectioning command (e.g. %c%s)", - node, COMMAND_PREFIX, polite_section_name); - } + { + char *polite_section_name = "top"; + int i; + + for (i = 0; section_alist[i].name; i++) + if (section_alist[i].level == current_section + 1) + { + polite_section_name = section_alist[i].name; + break; + } + + line_error + (_("Node `%s' requires a sectioning command (e.g. %c%s)"), + node, COMMAND_PREFIX, polite_section_name); + } else - { - if (strcmp (node, "Top") == 0) - { - /* Default the NEXT pointer to be the first menu item in - this node, if there is a menu in this node. We have to - try very hard to find the menu, as it may be obscured - by execution_strings which are on the filestack. For - every member of the filestack which has a FILENAME - member which is identical to the current INPUT_FILENAME, - search forward from that offset. */ - int saved_input_text_offset = input_text_offset; - int saved_size_of_input_text = size_of_input_text; - char *saved_input_text = input_text; - FSTACK *next_file = filestack; - - int orig_offset, orig_size; - char *glean_node_from_menu (); - - /* No matter what, make this file point back at `(dir)'. */ - free (up); up = strdup ("(dir)"); - - while (1) - { - orig_offset = input_text_offset; - orig_size = - search_forward (node_search_string, orig_offset); - - if (orig_size < 0) - orig_size = size_of_input_text; - - input_text_offset = - search_forward (menu_search_string, orig_offset); - - if (input_text_offset > -1) - { - char *nodename_from_menu = (char *)NULL; - - input_text_offset = - search_forward ("\n* ", input_text_offset); - - if (input_text_offset != -1) - nodename_from_menu = glean_node_from_menu (0); - - if (nodename_from_menu) - { - free (next); next = nodename_from_menu; - break; - } - } - - /* We got here, so it hasn't been found yet. Try - the next file on the filestack if there is one. */ - if (next_file && - (strcmp (next_file->filename, input_filename) == 0)) - { - input_text = next_file->text; - input_text_offset = next_file->offset; - size_of_input_text = next_file->size; - next_file = next_file->next; - } - else - { - /* No more input files to check. */ - break; - } - } - - input_text = saved_input_text; - input_text_offset = saved_input_text_offset; - size_of_input_text = saved_size_of_input_text; - } - } + { + if (strcmp (node, "Top") == 0) + { + /* Default the NEXT pointer to be the first menu item in + this node, if there is a menu in this node. We have to + try very hard to find the menu, as it may be obscured + by execution_strings which are on the filestack. For + every member of the filestack which has a FILENAME + member which is identical to the current INPUT_FILENAME, + search forward from that offset. */ + int saved_input_text_offset = input_text_offset; + int saved_size_of_input_text = size_of_input_text; + char *saved_input_text = input_text; + FSTACK *next_file = filestack; + + int orig_offset, orig_size; + char *glean_node_from_menu (); + + /* No matter what, make this file point back at `(dir)'. */ + free (up); up = xstrdup ("(dir)"); + + while (1) + { + orig_offset = input_text_offset; + orig_size = + search_forward (node_search_string, orig_offset); + + if (orig_size < 0) + orig_size = size_of_input_text; + + input_text_offset = + search_forward (menu_search_string, orig_offset); + + if (input_text_offset > -1) + { + char *nodename_from_menu = (char *)NULL; + + input_text_offset = + search_forward ("\n* ", input_text_offset); + + if (input_text_offset != -1) + nodename_from_menu = glean_node_from_menu (0); + + if (nodename_from_menu) + { + free (next); next = nodename_from_menu; + break; + } + } + + /* We got here, so it hasn't been found yet. Try + the next file on the filestack if there is one. */ + if (next_file && + (strcmp (next_file->filename, input_filename) == 0)) + { + input_text = next_file->text; + input_text_offset = next_file->offset; + size_of_input_text = next_file->size; + next_file = next_file->next; + } + else + { + /* No more input files to check. */ + break; + } + } + + input_text = saved_input_text; + input_text_offset = saved_input_text_offset; + size_of_input_text = saved_size_of_input_text; + } + } /* Fix the level of the menu references in the Top node, iff it - was declared with @top, and no subsequent reference was found. */ + was declared with @top, and no subsequent reference was found. */ if (top_node_seen && !non_top_node_seen) - { - /* Then this is the first non-@top node seen. */ - int level; + { + /* Then this is the first non-@top node seen. */ + int level; - level = set_top_section_level (this_section - 1); - non_top_node_seen = 1; + level = set_top_section_level (this_section - 1); + non_top_node_seen = 1; - while (ref) - { - if (ref->section == level) - ref->section = this_section - 1; - ref = ref->next; - } + while (ref) + { + if (ref->section == level) + ref->section = this_section - 1; + ref = ref->next; + } - ref = node_references; - } + ref = node_references; + } while (ref) - { - if (ref->section == (this_section - 1) && - ref->type == menu_reference && - strcmp (ref->node, node) == 0) - { - char *containing_node = ref->containing_node; - - free (up); - up = strdup (containing_node); - - if (last_ref && - last_ref->type == menu_reference && - (strcmp (last_ref->containing_node, - containing_node) == 0)) - { - free (next); - next = strdup (last_ref->node); - } - - while ((ref->section == this_section - 1) && - (ref->next) && - (ref->next->type != menu_reference)) - ref = ref->next; - - if (ref->next && ref->type == menu_reference && - (strcmp (ref->next->containing_node, - containing_node) == 0)) - { - free (prev); - prev = strdup (ref->next->node); - } - else if (!ref->next && - strcasecmp (ref->containing_node, "Top") == 0) - { - free (prev); - prev = strdup (ref->containing_node); - } - break; - } - last_ref = ref; - ref = ref->next; - } + { + if (ref->section == (this_section - 1) && + ref->type == menu_reference && + strcmp (ref->node, node) == 0) + { + char *containing_node = ref->containing_node; + + free (up); + up = xstrdup (containing_node); + + if (last_ref && + last_ref->type == menu_reference && + (strcmp (last_ref->containing_node, + containing_node) == 0)) + { + free (next); + next = xstrdup (last_ref->node); + } + + while ((ref->section == this_section - 1) && + (ref->next) && + (ref->next->type != menu_reference)) + ref = ref->next; + + if (ref->next && ref->type == menu_reference && + (strcmp (ref->next->containing_node, + containing_node) == 0)) + { + free (prev); + prev = xstrdup (ref->next->node); + } + else if (!ref->next && + strcasecmp (ref->containing_node, "Top") == 0) + { + free (prev); + prev = xstrdup (ref->containing_node); + } + break; + } + last_ref = ref; + ref = ref->next; + } } #if defined (HAVE_MACROS) /* Insert the correct args if we are expanding macros, and the node's pointers weren't defaulted. */ - if (macro_expansion_output_stream && !defaulting) + if (macro_expansion_output_stream && !executing_string && !defaulting) { char *temp; int op_orig = output_paragraph_offset; @@ -4929,29 +5019,29 @@ cm_node () { #if defined (HAVE_MACROS) if (macro_expansion_output_stream) - me_inhibit_expansion++; + me_inhibit_expansion++; #endif /* HAVE_MACROS */ if (*next) - { - execute_string (", Next: %s", next); - filling_enabled = indented_fill = 0; - } + { + execute_string (", Next: %s", next); + filling_enabled = indented_fill = 0; + } if (*prev) - { - execute_string (", Prev: %s", prev); - filling_enabled = indented_fill = 0; - } + { + execute_string (", Prev: %s", prev); + filling_enabled = indented_fill = 0; + } if (*up) - { - execute_string (", Up: %s", up); - filling_enabled = indented_fill = 0; - } + { + execute_string (", Up: %s", up); + filling_enabled = indented_fill = 0; + } #if defined (HAVE_MACROS) if (macro_expansion_output_stream) - me_inhibit_expansion--; + me_inhibit_expansion--; #endif /* HAVE_MACROS */ } @@ -4961,7 +5051,7 @@ cm_node () if (!*node) { line_error ("No node name specified for `%c%s' command", - COMMAND_PREFIX, command); + COMMAND_PREFIX, command); free (node); free (next); free (prev); @@ -5012,141 +5102,141 @@ validate_file (tag_table) /* If this is a "no warn" node, don't validate it in any way. */ if (tags->flags & NO_WARN) - { - tags = tags->next_ent; - continue; - } + { + tags = tags->next_ent; + continue; + } /* If this node has a Next, then make sure that the Next exists. */ if (tags->next) - { - validate (tags->next, tags->line_no, "Next"); - - /* If the Next node exists, and there is no Up, then make - sure that the Prev of the Next points back. */ - if (temp_tag = find_node (tags->next)) - { - char *prev; - - if (temp_tag->flags & NO_WARN) - { - /* Do nothing if we aren't supposed to issue warnings - about this node. */ - } - else - { - prev = temp_tag->prev; - if (!prev || (strcmp (prev, tags->node) != 0)) - { - line_error ("Node `%s''s Next field not pointed back to", - tags->node); - line_number = temp_tag->line_no; - input_filename = temp_tag->filename; - line_error - ("This node (`%s') is the one with the bad `Prev'", - temp_tag->node); - input_filename = tags->filename; - line_number = tags->line_no; - temp_tag->flags |= PREV_ERROR; - } - } - } - } + { + validate (tags->next, tags->line_no, "Next"); + + /* If the Next node exists, and there is no Up, then make + sure that the Prev of the Next points back. */ + temp_tag = find_node (tags->next); + if (temp_tag) + { + char *prev; + + if (temp_tag->flags & NO_WARN) + { + /* Do nothing if we aren't supposed to issue warnings + about this node. */ + } + else + { + prev = temp_tag->prev; + if (!prev || (strcmp (prev, tags->node) != 0)) + { + line_error (_("Node `%s''s Next field not pointed back to"), + tags->node); + line_number = temp_tag->line_no; + input_filename = temp_tag->filename; + line_error + (_("This node (`%s') is the one with the bad `Prev'"), + temp_tag->node); + input_filename = tags->filename; + line_number = tags->line_no; + temp_tag->flags |= PREV_ERROR; + } + } + } + } /* Validate the Prev field if there is one, and we haven't already - complained about it in some way. You don't have to have a Prev - field at this stage. */ + complained about it in some way. You don't have to have a Prev + field at this stage. */ if (!(tags->flags & PREV_ERROR) && tags->prev) - { - int valid = validate (tags->prev, tags->line_no, "Prev"); - - if (!valid) - tags->flags |= PREV_ERROR; - else - { - /* If the Prev field is not the same as the Up field, - then the node pointed to by the Prev field must have - a Next field which points to this node. */ - if (tags->up && (strcmp (tags->prev, tags->up) != 0)) - { - temp_tag = find_node (tags->prev); - - /* If we aren't supposed to issue warnings about the - target node, do nothing. */ - if (!temp_tag || (temp_tag->flags & NO_WARN)) - { - /* Do nothing. */ - } - else - { - if (!temp_tag->next || - (strcmp (temp_tag->next, tags->node) != 0)) - { - line_error - ("Node `%s''s Prev field not pointed back to", - tags->node); - line_number = temp_tag->line_no; - input_filename = temp_tag->filename; - line_error - ("This node (`%s') is the one with the bad `Next'", - temp_tag->node); - input_filename = tags->filename; - line_number = tags->line_no; - temp_tag->flags |= NEXT_ERROR; - } - } - } - } - } - - if (!tags->up && (strcasecmp (tags->node, "Top") != 0)) - line_error ("Node `%s' is missing an \"Up\" field", tags->node); + { + int valid_p = validate (tags->prev, tags->line_no, "Prev"); + + if (!valid_p) + tags->flags |= PREV_ERROR; + else + { + /* If the Prev field is not the same as the Up field, + then the node pointed to by the Prev field must have + a Next field which points to this node. */ + if (tags->up && (strcmp (tags->prev, tags->up) != 0)) + { + temp_tag = find_node (tags->prev); + + /* If we aren't supposed to issue warnings about the + target node, do nothing. */ + if (!temp_tag || (temp_tag->flags & NO_WARN)) + { + /* Do nothing. */ + } + else + { + if (!temp_tag->next || + (strcmp (temp_tag->next, tags->node) != 0)) + { + line_error + (_("Node `%s's Prev field not pointed back to"), + tags->node); + line_number = temp_tag->line_no; + input_filename = temp_tag->filename; + line_error (_("This node (`%s') has the bad Next"), + temp_tag->node); + input_filename = tags->filename; + line_number = tags->line_no; + temp_tag->flags |= NEXT_ERROR; + } + } + } + } + } + + if (!tags->up && (strcasecmp (tags->node, _("Top")) != 0)) + line_error (_("Node `%s' missing Up field"), tags->node); else if (tags->up) - { - int valid = validate (tags->up, tags->line_no, "Up"); - - /* If node X has Up: Y, then warn if Y fails to have a menu item - or note pointing at X, if Y isn't of the form "(Y)". */ - if (valid && *tags->up != '(') - { - NODE_REF *nref, *tref, *list; - NODE_REF *find_node_reference (); - - tref = (NODE_REF *) NULL; - list = node_references; - - for (;;) - { - if (!(nref = find_node_reference (tags->node, list))) - break; - - if (strcmp (nref->containing_node, tags->up) == 0) - { - if (nref->type != menu_reference) - { - tref = nref; - list = nref->next; - } - else - break; - } - list = nref->next; - } - - if (!nref) - { - temp_tag = find_node (tags->up); - line_number = temp_tag->line_no; - input_filename = temp_tag->filename; - if (!tref) - line_error ( -"`%s' has an Up field of `%s', but `%s' has no menu item for `%s'", - tags->node, tags->up, tags->up, tags->node); - line_number = tags->line_no; - input_filename = tags->filename; - } - } - } + { + int valid_p = validate (tags->up, tags->line_no, "Up"); + + /* If node X has Up: Y, then warn if Y fails to have a menu item + or note pointing at X, if Y isn't of the form "(Y)". */ + if (valid_p && *tags->up != '(') + { + NODE_REF *nref, *tref, *list; + NODE_REF *find_node_reference (); + + tref = (NODE_REF *) NULL; + list = node_references; + + for (;;) + { + if (!(nref = find_node_reference (tags->node, list))) + break; + + if (strcmp (nref->containing_node, tags->up) == 0) + { + if (nref->type != menu_reference) + { + tref = nref; + list = nref->next; + } + else + break; + } + list = nref->next; + } + + if (!nref) + { + temp_tag = find_node (tags->up); + line_number = temp_tag->line_no; + input_filename = temp_tag->filename; + if (!tref) + line_error ( +_("`%s' has an Up field of `%s', but `%s' has no menu item for `%s'"), + tags->node, tags->up, tags->up, tags->node); + line_number = tags->line_no; + input_filename = tags->filename; + } + } + } tags = tags->next_ent; } @@ -5159,32 +5249,32 @@ validate_file (tag_table) { /* If this node is a "no warn" node, do nothing. */ if (tags->flags & NO_WARN) - { - tags = tags->next_ent; - continue; - } + { + tags = tags->next_ent; + continue; + } /* Special hack. If the node in question appears to have been referenced more than REFERENCE_WARNING_LIMIT times, give a warning. */ if (tags->touched > reference_warning_limit) - { - input_filename = tags->filename; - line_number = tags->line_no; - warning ("Node `%s' has been referenced %d times", - tags->node, tags->touched); - } + { + input_filename = tags->filename; + line_number = tags->line_no; + warning (_("node `%s' has been referenced %d times"), + tags->node, tags->touched); + } if (tags->touched == 0) - { - input_filename = tags->filename; - line_number = tags->line_no; - - /* Notice that the node "Top" is special, and doesn't have to - be referenced. */ - if (strcasecmp (tags->node, "Top") != 0) - warning ("Unreferenced node `%s'", tags->node); - } + { + input_filename = tags->filename; + line_number = tags->line_no; + + /* Notice that the node "Top" is special, and doesn't have to + be referenced. */ + if (strcasecmp (tags->node, _("Top")) != 0) + warning (_("unreferenced node `%s'"), tags->node); + } tags = tags->next_ent; } input_filename = old_input_filename; @@ -5210,9 +5300,7 @@ validate (tag, line, label) if (!result) { line_number = line; - line_error ( -"Validation error. `%s' field points to node `%s', which doesn't exist", - label, tag); + line_error (_("%s reference to nonexistent node `%s'"), label, tag); return (0); } result->touched++; @@ -5256,7 +5344,7 @@ split_file (filename, size) root_pathname = pathname_part (filename); if (!root_pathname) - root_pathname = strdup (""); + root_pathname = xstrdup (""); /* Start splitting the file. Walk along the tag table outputting sections of the file. When we have written @@ -5275,122 +5363,122 @@ split_file (filename, size) while (tags) { - int file_top, file_bot, limit; - - /* Have to include the Control-_. */ - file_top = file_bot = tags->position; - limit = file_top + size; - - /* If the rest of this file is only one node, then - that is the entire subfile. */ - if (!tags->next_ent) - { - int i = tags->position + 1; - char last_char = the_file[i]; - - while (i < file_size) - { - if ((the_file[i] == '\037') && - ((last_char == '\n') || - (last_char == '\014'))) - break; - else - last_char = the_file[i]; - i++; - } - file_bot = i; - tags = tags->next_ent; - goto write_region; - } - - /* Otherwise, find the largest number of nodes that can fit in - this subfile. */ - for (; tags; tags = tags->next_ent) - { - if (!tags->next_ent) - { - /* This entry is the last node. Search forward for the end - of this node, and that is the end of this file. */ - int i = tags->position + 1; - char last_char = the_file[i]; - - while (i < file_size) - { - if ((the_file[i] == '\037') && - ((last_char == '\n') || - (last_char == '\014'))) - break; - else - last_char = the_file[i]; - i++; - } - file_bot = i; - - if (file_bot < limit) - { - tags = tags->next_ent; - goto write_region; - } - else - { - /* Here we want to write out everything before the last - node, and then write the last node out in a file - by itself. */ - file_bot = tags->position; - goto write_region; - } - } - - if (tags->next_ent->position > limit) - { - if (tags->position == file_top) - tags = tags->next_ent; - - file_bot = tags->position; - - write_region: - { - int fd; - char *split_filename; - - split_filename = (char *) xmalloc - (10 + strlen (root_pathname) + strlen (root_filename)); - sprintf - (split_filename, - "%s%s-%d", root_pathname, root_filename, which_file); - - fd = open - (split_filename, O_WRONLY | O_TRUNC | O_CREAT, 0666); - - if ((fd < 0) || - (write (fd, the_header, header_size) != header_size) || - (write (fd, the_file + file_top, file_bot - file_top) - != (file_bot - file_top)) || - ((close (fd)) < 0)) - { - perror (split_filename); - if (fd != -1) - close (fd); - exit (FATAL); - } - - if (!indirect_info) - { - indirect_info = the_file + file_top; - sprintf (indirect_info, "\037\nIndirect:\n"); - indirect_info += strlen (indirect_info); - } - - sprintf (indirect_info, "%s-%d: %d\n", - root_filename, which_file, file_top); - - free (split_filename); - indirect_info += strlen (indirect_info); - which_file++; - break; - } - } - } + int file_top, file_bot, limit; + + /* Have to include the Control-_. */ + file_top = file_bot = tags->position; + limit = file_top + size; + + /* If the rest of this file is only one node, then + that is the entire subfile. */ + if (!tags->next_ent) + { + int i = tags->position + 1; + char last_char = the_file[i]; + + while (i < file_size) + { + if ((the_file[i] == '\037') && + ((last_char == '\n') || + (last_char == '\014'))) + break; + else + last_char = the_file[i]; + i++; + } + file_bot = i; + tags = tags->next_ent; + goto write_region; + } + + /* Otherwise, find the largest number of nodes that can fit in + this subfile. */ + for (; tags; tags = tags->next_ent) + { + if (!tags->next_ent) + { + /* This entry is the last node. Search forward for the end + of this node, and that is the end of this file. */ + int i = tags->position + 1; + char last_char = the_file[i]; + + while (i < file_size) + { + if ((the_file[i] == '\037') && + ((last_char == '\n') || + (last_char == '\014'))) + break; + else + last_char = the_file[i]; + i++; + } + file_bot = i; + + if (file_bot < limit) + { + tags = tags->next_ent; + goto write_region; + } + else + { + /* Here we want to write out everything before the last + node, and then write the last node out in a file + by itself. */ + file_bot = tags->position; + goto write_region; + } + } + + if (tags->next_ent->position > limit) + { + if (tags->position == file_top) + tags = tags->next_ent; + + file_bot = tags->position; + + write_region: + { + int fd; + char *split_filename; + + split_filename = (char *) xmalloc + (10 + strlen (root_pathname) + strlen (root_filename)); + sprintf + (split_filename, + "%s%s-%d", root_pathname, root_filename, which_file); + + fd = open + (split_filename, O_WRONLY | O_TRUNC | O_CREAT, 0666); + + if ((fd < 0) || + (write (fd, the_header, header_size) != header_size) || + (write (fd, the_file + file_top, file_bot - file_top) + != (file_bot - file_top)) || + ((close (fd)) < 0)) + { + perror (split_filename); + if (fd != -1) + close (fd); + exit (FATAL); + } + + if (!indirect_info) + { + indirect_info = the_file + file_top; + sprintf (indirect_info, "\037\nIndirect:\n"); + indirect_info += strlen (indirect_info); + } + + sprintf (indirect_info, "%s-%d: %d\n", + root_filename, which_file, file_top); + + free (split_filename); + indirect_info += strlen (indirect_info); + which_file++; + break; + } + } + } } /* We have sucessfully created the subfiles. Now write out the @@ -5399,8 +5487,8 @@ split_file (filename, size) output_stream = fopen (filename, "w"); if (!output_stream) { - perror (filename); - exit (FATAL); + perror (filename); + exit (FATAL); } { @@ -5419,10 +5507,8 @@ split_file (filename, size) } } -/* Some menu hacking. This is used to remember menu references while - reading the input file. After the output file has been written, if - validation is on, then we use the contents of NODE_REFERENCES as a - list of nodes to validate. */ +/* The strings here are followed in the message by `reference to...' in + the `validate' routine. */ char * reftype_type_string (type) enum reftype type; @@ -5432,13 +5518,16 @@ reftype_type_string (type) case menu_reference: return ("Menu"); case followed_reference: - return ("Followed-Reference"); + return ("Cross"); default: return ("Internal-bad-reference-type"); } } -/* Remember this node name for later validation use. */ +/* Remember this node name for later validation use. This is used to + remember menu references while reading the input file. After the + output file has been written, if validation is on, then we use the + contents of `node_references' as a list of nodes to validate. */ void remember_node_reference (node, line, type) char *node; @@ -5448,11 +5537,11 @@ remember_node_reference (node, line, type) NODE_REF *temp = (NODE_REF *) xmalloc (sizeof (NODE_REF)); temp->next = node_references; - temp->node = strdup (node); + temp->node = xstrdup (node); temp->line_no = line; temp->section = current_section; temp->type = type; - temp->containing_node = strdup (current_node ? current_node : ""); + temp->containing_node = xstrdup (current_node ? current_node : ""); temp->filename = node_filename; node_references = temp; @@ -5468,7 +5557,7 @@ validate_other_references (ref_list) { input_filename = ref_list->filename; validate (ref_list->node, ref_list->line_no, - reftype_type_string (ref_list->type)); + reftype_type_string (ref_list->type)); ref_list = ref_list->next; } input_filename = old_input_filename; @@ -5483,7 +5572,7 @@ find_node_reference (node, ref_list) while (ref_list) { if (strcmp (node, ref_list->node) == 0) - break; + break; ref_list = ref_list->next; } return (ref_list); @@ -5520,13 +5609,13 @@ glean_node_from_menu (remember_reference) char *nodename; if (strncmp (&input_text[input_text_offset + 1], - menu_starter, - strlen (menu_starter)) != 0) + menu_starter, + strlen (menu_starter)) != 0) return ((char *)NULL); else input_text_offset += strlen (menu_starter) + 1; - get_until_in_line (":", &nodename); + get_until_in_line (0, ":", &nodename); if (curchar () == ':') input_text_offset++; canon_white (nodename); @@ -5552,7 +5641,7 @@ save_node: normalize_node_name (nodename); i = strlen (nodename); if (i && nodename[i - 1] == ':') - nodename[i - 1] = '\0'; + nodename[i - 1] = 0; if (remember_reference) { @@ -5579,7 +5668,7 @@ isolate_nodename (nodename) if (*nodename == '.' || !*nodename) { - *nodename = '\0'; + *nodename = 0; return; } @@ -5590,32 +5679,32 @@ isolate_nodename (nodename) i++; } - for (; c = nodename[i]; i++) + for (; (c = nodename[i]); i++) { if (paren) - { - if (c == '(') - paren++; - else if (c == ')') - paren--; + { + if (c == '(') + paren++; + else if (c == ')') + paren--; - continue; - } + continue; + } /* If the character following the close paren is a space, then this - node has no more characters associated with it. */ + node has no more characters associated with it. */ if (c == '\t' || - c == '\n' || - c == ',' || - ((paren_seen && nodename[i - 1] == ')') && - (c == ' ' || c == '.')) || - (c == '.' && - ((!nodename[i + 1] || - (cr_or_whitespace (nodename[i + 1])) || - (nodename[i + 1] == ')'))))) - break; + c == '\n' || + c == ',' || + ((paren_seen && nodename[i - 1] == ')') && + (c == ' ' || c == '.')) || + (c == '.' && + ((!nodename[i + 1] || + (cr_or_whitespace (nodename[i + 1])) || + (nodename[i + 1] == ')'))))) + break; } - nodename[i] = '\0'; + nodename[i] = 0; } void @@ -5623,8 +5712,8 @@ cm_menu () { if (current_node == (char *)NULL) { - warning ("%cmenu seen before a node has been defined", COMMAND_PREFIX); - warning ("Creating `TOP' node."); + warning (_("%cmenu seen before first node"), COMMAND_PREFIX); + warning (_("creating `Top' node")); execute_string ("@node Top"); } begin_insertion (menu); @@ -5635,19 +5724,21 @@ cm_detailmenu () { if (current_node == (char *)NULL) { - warning ("%cmenu seen before a node has been defined", COMMAND_PREFIX); - warning ("Creating `TOP' node."); + warning (_("%cmenu seen before first node"), COMMAND_PREFIX); + warning (_("creating `Top' node")); execute_string ("@node Top"); } begin_insertion (detailmenu); } /* **************************************************************** */ -/* */ -/* Cross Reference Hacking */ -/* */ +/* */ +/* Cross Reference Hacking */ +/* */ /* **************************************************************** */ +/* Return next comma-delimited argument, but do not cross a close-brace + boundary. Clean up whitespace, too. */ char * get_xref_token () { @@ -5660,7 +5751,7 @@ get_xref_token () return (string); } -int px_ref_flag = 0; /* Controls initial output string. */ +int px_ref_flag = 0; /* Controls initial output string. */ /* Make a cross reference. */ void @@ -5679,45 +5770,45 @@ cm_xref (arg) add_word_args ("%s", px_ref_flag ? "*note " : "*Note "); if (*arg5 || *arg4) - { - char *node_name; - - if (!*arg2) - { - if (*arg3) - node_name = arg3; - else - node_name = arg1; - } - else - node_name = arg2; - - execute_string ("%s: (%s)%s", node_name, arg4, arg1); - /* Free all of the arguments found. */ - if (arg1) free (arg1); - if (arg2) free (arg2); - if (arg3) free (arg3); - if (arg4) free (arg4); - if (arg5) free (arg5); - return; - } + { + char *node_name; + + if (!*arg2) + { + if (*arg3) + node_name = arg3; + else + node_name = arg1; + } + else + node_name = arg2; + + execute_string ("%s: (%s)%s", node_name, arg4, arg1); + /* Free all of the arguments found. */ + if (arg1) free (arg1); + if (arg2) free (arg2); + if (arg3) free (arg3); + if (arg4) free (arg4); + if (arg5) free (arg5); + return; + } else - remember_node_reference (arg1, line_number, followed_reference); + remember_node_reference (arg1, line_number, followed_reference); if (*arg3) - { - if (!*arg2) - execute_string ("%s: %s", arg3, arg1); - else - execute_string ("%s: %s", arg2, arg1); - } + { + if (!*arg2) + execute_string ("%s: %s", arg3, arg1); + else + execute_string ("%s: %s", arg2, arg1); + } else - { - if (*arg2) - execute_string ("%s: %s", arg2, arg1); - else - execute_string ("%s::", arg1); - } + { + if (*arg2) + execute_string ("%s: %s", arg2, arg1); + else + execute_string ("%s::", arg1); + } /* Free all of the arguments found. */ if (arg1) free (arg1); @@ -5734,26 +5825,25 @@ cm_xref (arg) int temp = input_text_offset + 1; if (output_paragraph[output_paragraph_offset - 2] == ':' && - output_paragraph[output_paragraph_offset - 1] == ':') - return; + output_paragraph[output_paragraph_offset - 1] == ':') + return; while (temp < size_of_input_text) - { - if (cr_or_whitespace (input_text[temp])) - temp++; - else - { - if (input_text[temp] == '.' || - input_text[temp] == ',' || - input_text[temp] == '\t') - return; - else - { - line_error ( - "Cross-reference must be terminated with a period or a comma"); - return; - } - } - } + { + if (cr_or_whitespace (input_text[temp])) + temp++; + else + { + if (input_text[temp] != '.' + && input_text[temp] != ',' + && input_text[temp] != '\t') + { + line_error ( + _("`.' or `,' must follow cross reference, not %c"), + input_text[temp]); + } + break; + } + } } } @@ -5777,20 +5867,159 @@ cm_inforef (arg) { if (arg == START) { - char *node, *pname, *file; + char *node = get_xref_token (); + char *pname = get_xref_token (); + char *file = get_xref_token (); + + if (*pname) + execute_string ("*note %s: (%s)%s", pname, file, node); + else + execute_string ("*note (%s)%s::", file, node); + + free (node); + free (pname); + free (file); + } +} + +/* A URL reference. */ +void +cm_uref (arg, start_pos, end_pos) + int arg, start_pos, end_pos; +{ + if (arg == END) + { + char *comma; + char *arg = (char *) &output_paragraph[start_pos]; + + output_paragraph[end_pos] = 0; + output_column -= end_pos - start_pos; + output_paragraph_offset = start_pos; + + arg = xstrdup (arg); + comma = strchr (arg, ','); /* let's hope for no commas in the url */ + if (comma) + { + *comma = 0; + /* Ignore spaces at beginning of second arg. */ + for (comma++; isspace (*comma); comma++) + ; + add_word (comma); + add_char (' '); + add_char ('('); + add_word (arg); + add_char (')'); + } + else + { + extern int printing_index; + + if (!printing_index) + add_char ('`'); + + add_word (arg); + + if (!printing_index) + add_char ('\''); + } + free (arg); + } +} + +/* An email reference. */ +void +cm_email (arg, start_pos, end_pos) + int arg, start_pos, end_pos; +{ + if (arg == END) + { + char *comma; + char *arg = (char *) &output_paragraph[start_pos]; - node = get_xref_token (); - pname = get_xref_token (); - file = get_xref_token (); + output_paragraph[end_pos] = 0; + output_column -= end_pos - start_pos; + output_paragraph_offset = start_pos; - execute_string ("*note %s: (%s)%s", pname, file, node); + arg = xstrdup (arg); + comma = strchr (arg, ','); + if (comma) + { + *comma = 0; + for (comma++; isspace (*comma); comma++) + ; + add_word (comma); + add_char (' '); + } + add_char ('<'); + add_word (arg); + add_char ('>'); + free (arg); + } +} + +/* An external image is a reference, kind of. The parsing is (not + coincidentally) similar, anyway. */ +void +cm_image (arg) + int arg; +{ + if (arg == START) + { + char *name_arg = get_xref_token (); + /* We don't yet care about any other args, but read them so they + don't end up in the text. */ + char *arg = get_xref_token (); + if (arg) free (arg); + arg = get_xref_token (); + if (arg) free (arg); + + if (*name_arg) + { + /* Try to open foo.txt. */ + FILE *image_file; + char *name = xmalloc (strlen (name_arg) + 4); + strcpy (name, name_arg); + strcat (name, ".txt"); + image_file = fopen (name, "r"); + if (image_file) + { + int ch; + int save_inhibit_indentation = inhibit_paragraph_indentation; + int save_filling_enabled = filling_enabled; + + inhibit_paragraph_indentation = 1; + filling_enabled = 0; + last_char_was_newline = 0; + + /* Maybe we need to remove the final newline if the image + file is only one line to allow in-line images. On the + other hand, they could just make the file without a + final newline. */ + while ((ch = getc (image_file)) != EOF) + add_char (ch); + + inhibit_paragraph_indentation = save_inhibit_indentation; + filling_enabled = save_filling_enabled; + + if (fclose (image_file) != 0) { + perror (name); + } + } + else + warning (_("@image file `%s' unreadable: %s"), name, + strerror (errno)); + } + else + line_error (_("@image missing filename argument")); + + if (name_arg) free (name_arg); } } /* **************************************************************** */ -/* */ -/* Insertion Command Stubs */ -/* */ +/* */ +/* Insertion Command Stubs */ +/* */ /* **************************************************************** */ void @@ -5824,7 +6053,7 @@ cm_smalllisp () } /* @cartouche/@end cartouche draws box with rounded corners in - TeX output. Right now, just a NOP insertion. */ + TeX output. Right now, just a no-op insertion. */ void cm_cartouche () { @@ -5871,26 +6100,26 @@ do_enumeration (type, default_string) int type; char *default_string; { - get_until_in_line (".", &enumeration_arg); + get_until_in_line (0, ".", &enumeration_arg); canon_white (enumeration_arg); if (!*enumeration_arg) { free (enumeration_arg); - enumeration_arg = strdup (default_string); + enumeration_arg = xstrdup (default_string); } if (!isdigit (*enumeration_arg) && !isletter (*enumeration_arg)) { - warning ("%s requires a letter or a digit", insertion_type_pname (type)); + warning (_("%s requires letter or digit"), insertion_type_pname (type)); switch (type) - { - case enumerate: - default_string = "1"; - break; - } - enumeration_arg = strdup (default_string); + { + case enumerate: + default_string = "1"; + break; + } + enumeration_arg = xstrdup (default_string); } begin_insertion (type); } @@ -5904,7 +6133,7 @@ cm_table () void cm_multitable () { - begin_insertion (multitable); /* @@ */ + begin_insertion (multitable); /* @@ */ } void @@ -5931,6 +6160,18 @@ cm_ifinfo () begin_insertion (ifinfo); } +void +cm_ifnothtml () +{ + begin_insertion (ifnothtml); +} + +void +cm_ifnottex () +{ + begin_insertion (ifnottex); +} + /* Begin an insertion where the lines are not filled or indented. */ void cm_flushleft () @@ -5945,11 +6186,40 @@ cm_flushright () { begin_insertion (flushright); } + +/* End existing insertion block. */ +void +cm_end () +{ + char *temp; + enum insertion_type type; + + if (!insertion_level) + { + line_error (_("Unmatched `%c%s'"), COMMAND_PREFIX, command); + return; + } + + get_rest_of_line (&temp); + + if (temp[0] == 0) + line_error (_("`%c%s' needs something after it"), COMMAND_PREFIX, command); + + type = find_type_from_name (temp); + + if (type == bad_type) + { + line_error (_("Bad argument to `%s', `%s', using `%s'"), + command, temp, insertion_type_pname (current_insertion_type ())); + } + end_insertion (type); + free (temp); +} /* **************************************************************** */ -/* */ -/* Conditional Handling */ -/* */ +/* */ +/* Conditional Handling */ +/* */ /* **************************************************************** */ /* A structure which contains `defined' variables. */ @@ -5973,15 +6243,15 @@ set (name, value) for (temp = defines; temp; temp = temp->next) if (strcmp (name, temp->name) == 0) { - free (temp->value); - temp->value = strdup (value); - return; + free (temp->value); + temp->value = xstrdup (value); + return; } temp = (DEFINE *)xmalloc (sizeof (DEFINE)); temp->next = defines; - temp->name = strdup (name); - temp->value = strdup (value); + temp->name = xstrdup (name); + temp->value = xstrdup (value); defines = temp; } @@ -5998,17 +6268,17 @@ clear (name) while (temp) { if (strcmp (temp->name, name) == 0) - { - if (last) - last->next = temp->next; - else - defines = temp->next; - - free (temp->name); - free (temp->value); - free (temp); - break; - } + { + if (last) + last->next = temp->next; + else + defines = temp->next; + + free (temp->name); + free (temp->value); + free (temp); + break; + } last = temp; temp = temp->next; } @@ -6078,7 +6348,6 @@ cm_ifclear () void cm_ifeq () { - register int i; char **arglist; arglist = get_brace_args (0); @@ -6086,11 +6355,11 @@ cm_ifeq () if (arglist) { if (array_len (arglist) > 1) - { - if ((strcasecmp (arglist[0], arglist[1]) == 0) && - (arglist[2] != (char *)NULL)) - execute_string ("%s\n", arglist[2]); - } + { + if ((strcasecmp (arglist[0], arglist[1]) == 0) && + (arglist[2] != (char *)NULL)) + execute_string ("%s\n", arglist[2]); + } free_array (arglist); } @@ -6102,10 +6371,10 @@ cm_value (arg, start_pos, end_pos) { if (arg == END) { - char *name, *value; - name = (char *)&output_paragraph[start_pos]; - output_paragraph[end_pos] = '\0'; - name = strdup (name); + char *name = (char *) &output_paragraph[start_pos]; + char *value; + output_paragraph[end_pos] = 0; + name = xstrdup (name); value = set_p (name); output_column -= end_pos - start_pos; output_paragraph_offset = start_pos; @@ -6113,7 +6382,7 @@ cm_value (arg, start_pos, end_pos) if (value) execute_string ("%s", value); else - add_word_args ("{No Value For \"%s\"}", name); + add_word_args (_("{No Value For \"%s\"}"), name); free (name); } @@ -6128,7 +6397,6 @@ handle_variable (action) get_rest_of_line (&name); backup_input_pointer (); - canon_white (name); handle_variable_internal (action, name); free (name); } @@ -6148,12 +6416,12 @@ handle_variable_internal (action, name) { /* #if defined (SET_WITH_EQUAL) */ if (*temp == '"' || *temp == '\'') - { - if (*temp == delimiter) - delimiter = 0; - else - delimiter = *temp; - } + { + if (*temp == delimiter) + delimiter = 0; + else + delimiter = *temp; + } /* #endif SET_WITH_EQUAL */ temp++; } @@ -6161,135 +6429,146 @@ handle_variable_internal (action, name) if (*temp) additional_text_present++; - *temp = '\0'; + *temp = 0; if (!*name) - line_error ("%c%s requires a name", COMMAND_PREFIX, command); + line_error (_("%c%s requires a name"), COMMAND_PREFIX, command); else { switch (action) - { - case SET: - { - char *value; + { + case SET: + { + char *value; #if defined (SET_WITH_EQUAL) - /* Allow a value to be saved along with a variable. The value is - the text following an `=' sign in NAME, if any is present. */ + /* Allow a value to be saved along with a variable. The value is + the text following an `=' sign in NAME, if any is present. */ - for (value = name; *value && *value != '='; value++); + for (value = name; *value && *value != '='; value++); - if (*value) - *value++ = '\0'; + if (*value) + *value++ = 0; - if (*value == '"' || *value == '\'') - { - value++; - value[strlen (value) - 1] = '\0'; - } + if (*value == '"' || *value == '\'') + { + value++; + value[strlen (value) - 1] = 0; + } #else /* !SET_WITH_EQUAL */ - /* The VALUE of NAME is the remainder of the line sans - whitespace. */ - if (additional_text_present) - { - value = temp + 1; - canon_white (value); - } - else - value = ""; + /* The VALUE of NAME is the remainder of the line sans + whitespace. */ + if (additional_text_present) + { + value = temp + 1; + canon_white (value); + } + else + value = ""; #endif /* !SET_WITH_VALUE */ - set (name, value); - } - break; - - case CLEAR: - clear (name); - break; - - case IFSET: - case IFCLEAR: - /* If IFSET and NAME is not set, or if IFCLEAR and NAME is set, - read lines from the the file until we reach a matching - "@end CONDITION". This means that we only take note of - "@ifset/clear" and "@end" commands. */ - { - char condition[8]; - int condition_len; - - if (action == IFSET) - strcpy (condition, "ifset"); - else - strcpy (condition, "ifclear"); - - condition_len = strlen (condition); - - if ((action == IFSET && !set_p (name)) || - (action == IFCLEAR && set_p (name))) - { - int level = 0, done = 0; - - while (!done) - { - char *freeable_line, *line; - - get_rest_of_line (&freeable_line); - - for (line = freeable_line; whitespace (*line); line++); - - if (*line == COMMAND_PREFIX && - (strncmp (line + 1, condition, condition_len) == 0)) - level++; - else if (strncmp (line, "@end", 4) == 0) - { - char *cname = line + 4; - char *temp; - - while (*cname && whitespace (*cname)) - cname++; - temp = cname; - - while (*temp && !whitespace (*temp)) - temp++; - *temp = '\0'; - - if (strcmp (cname, condition) == 0) - { - if (!level) - { - done = 1; - } - else - level--; - } - } - free (freeable_line); - } - /* We found the end of a false @ifset/ifclear. If we are - in a menu, back up over the newline that ends the ifset, - since that newline may also begin the next menu entry. */ - break; - } - else - { - if (action == IFSET) - begin_insertion (ifset); - else - begin_insertion (ifclear); - } - } - break; - } + set (name, value); + } + break; + + case CLEAR: + clear (name); + break; + + case IFSET: + case IFCLEAR: + /* If IFSET and NAME is not set, or if IFCLEAR and NAME is set, + read lines from the the file until we reach a matching + "@end CONDITION". This means that we only take note of + "@ifset/clear" and "@end" commands. */ + { + char condition[8]; + int condition_len; + int orig_line_number = line_number; + + if (action == IFSET) + strcpy (condition, "ifset"); + else + strcpy (condition, "ifclear"); + + condition_len = strlen (condition); + + if ((action == IFSET && !set_p (name)) + || (action == IFCLEAR && set_p (name))) + { + int level = 0, done = 0; + + while (!done && input_text_offset < size_of_input_text) + { + char *freeable_line, *line; + + get_rest_of_line (&freeable_line); + + for (line = freeable_line; whitespace (*line); line++); + + if (*line == COMMAND_PREFIX && + (strncmp (line + 1, condition, condition_len) == 0)) + level++; + else if (strncmp (line, "@end", 4) == 0) + { + char *cname = line + 4; + char *temp; + + while (*cname && whitespace (*cname)) + cname++; + temp = cname; + + while (*temp && !whitespace (*temp)) + temp++; + *temp = 0; + + if (strcmp (cname, condition) == 0) + { + if (!level) + { + done = 1; + } + else + level--; + } + } + free (freeable_line); + } + + if (!done) + { + int save = line_number; + line_number = orig_line_number; + line_error (_("Reached eof before matching @end %s"), + condition); + line_number = save; + } + + /* We found the end of a false @ifset/ifclear. If we are + in a menu, back up over the newline that ends the ifset, + since that newline may also begin the next menu entry. */ + break; + } + else + { + if (action == IFSET) + begin_insertion (ifset); + else + begin_insertion (ifclear); + } + } + break; + } } } /* Execution of random text not in file. */ typedef struct { - char *string; /* The string buffer. */ - int size; /* The size of the buffer. */ - int in_use; /* Non-zero means string currently in use. */ + char *string; /* The string buffer. */ + int size; /* The size of the buffer. */ + int in_use; /* Nonzero means string currently in use. */ } EXECUTION_STRING; static EXECUTION_STRING **execution_strings = (EXECUTION_STRING **)NULL; @@ -6306,26 +6585,26 @@ get_execution_string (initial_size) if (execution_strings) { for (i = 0; i < execution_strings_index; i++) - if (execution_strings[i] && (execution_strings[i]->in_use == 0)) - { - es = execution_strings[i]; - break; - } + if (execution_strings[i] && (execution_strings[i]->in_use == 0)) + { + es = execution_strings[i]; + break; + } } if (!es) { if (execution_strings_index + 1 >= execution_strings_slots) - { - execution_strings = (EXECUTION_STRING **)xrealloc - (execution_strings, - (execution_strings_slots += 3) * sizeof (EXECUTION_STRING *)); - for (; i < execution_strings_slots; i++) - execution_strings[i] = (EXECUTION_STRING *)NULL; - } + { + execution_strings = (EXECUTION_STRING **)xrealloc + (execution_strings, + (execution_strings_slots += 3) * sizeof (EXECUTION_STRING *)); + for (; i < execution_strings_slots; i++) + execution_strings[i] = (EXECUTION_STRING *)NULL; + } execution_strings[execution_strings_index] = - (EXECUTION_STRING *)xmalloc (sizeof (EXECUTION_STRING)); + (EXECUTION_STRING *)xmalloc (sizeof (EXECUTION_STRING)); es = execution_strings[execution_strings_index]; execution_strings_index++; @@ -6344,46 +6623,37 @@ get_execution_string (initial_size) /* Execute the string produced by formatting the ARGs with FORMAT. This is like submitting a new file with @include. */ -#if defined (HAVE_VARARGS_H) && defined (HAVE_VSPRINTF) void -execute_string (va_alist) - va_dcl -{ - EXECUTION_STRING *es; - char *temp_string; - char *format; - va_list args; - - es = get_execution_string (4000); - temp_string = es->string; - es->in_use = 1; - - va_start (args); - format = va_arg (args, char *); - vsprintf (temp_string, format, args); - va_end (args); - -#else /* !(HAVE_VARARGS_H && HAVE_VSPRINTF) */ - -void -execute_string (format, arg1, arg2, arg3, arg4, arg5) - char *format; +#if defined (VA_FPRINTF) && __STDC__ +execute_string (char *format, ...) +#else +execute_string (format, va_alist) + char *format; + va_dcl +#endif { EXECUTION_STRING *es; char *temp_string; +#ifdef VA_FPRINTF + va_list ap; +#endif es = get_execution_string (4000); temp_string = es->string; es->in_use = 1; - sprintf (temp_string, format, arg1, arg2, arg3, arg4, arg5); - -#endif /* !(HAVE_VARARGS_H && HAVE_VSPRINTF) */ + VA_START (ap, format); +#ifdef VA_SPRINTF + VA_SPRINTF (temp_string, format, ap); +#else + sprintf (temp_string, format, a1, a2, a3, a4, a5, a6, a7, a8); +#endif /* not VA_SPRINTF */ + va_end (ap); pushfile (); input_text_offset = 0; input_text = temp_string; - input_filename = strdup (input_filename); + input_filename = xstrdup (input_filename); size_of_input_text = strlen (temp_string); executing_string++; @@ -6412,6 +6682,7 @@ expansion (str, implicit_code) int saved_paragraph_is_open = paragraph_is_open; inhibit_output_flushing (); + paragraph_is_open = 1; execute_string (implicit_code ? "@code{%s}" : "%s", str); uninhibit_output_flushing (); @@ -6455,179 +6726,183 @@ cm_item () original_input_text_offset = input_text_offset; get_rest_of_line (&rest_of_line); - canon_white (rest_of_line); item_func = current_item_function (); /* Okay, do the right thing depending on which insertion function - is active. */ + is active. */ switch_top: switch (stack->insertion) - { - case multitable: - multitable_item (); - /* Ultra special hack. It appears that some people incorrectly - place text directly after the @item, instead of on a new line - by itself. This happens to work in TeX, so I make it work - here. */ - if (*rest_of_line) - { - line_number--; - input_text_offset = original_input_text_offset; - } - break; - - case ifinfo: - case ifset: - case ifclear: - case cartouche: - stack = stack->next; - if (!stack) - goto no_insertion; - else - goto switch_top; - break; - - case menu: - case quotation: - case example: - case smallexample: - case lisp: - case format: - case display: - case group: - line_error ("The `%c%s' command is meaningless within a `@%s' block", - COMMAND_PREFIX, command, - insertion_type_pname (current_insertion_type ())); - break; - - case itemize: - case enumerate: - if (itemx_flag) - { - line_error ("%citemx is not meaningful inside of a `%s' block", - COMMAND_PREFIX, - insertion_type_pname (current_insertion_type ())); - } - else - { - start_paragraph (); - kill_self_indent (-1); - filling_enabled = indented_fill = 1; - - if (current_insertion_type () == itemize) - { - indent (output_column = current_indent - 2); - - /* I need some way to determine whether this command - takes braces or not. I believe the user can type - either "@bullet" or "@bullet{}". Of course, they - can also type "o" or "#" or whatever else they want. */ - if (item_func && *item_func) - { - if (*item_func == COMMAND_PREFIX) - if (item_func[strlen (item_func) - 1] != '}') - execute_string ("%s{}", item_func); - else - execute_string ("%s", item_func); - else - execute_string ("%s", item_func); - } - insert (' '); - output_column++; - } - else - enumerate_item (); - - /* Special hack. This makes close paragraph ignore you until - the start_paragraph () function has been called. */ - must_start_paragraph = 1; - - /* Ultra special hack. It appears that some people incorrectly - place text directly after the @item, instead of on a new line - by itself. This happens to work in TeX, so I make it work - here. */ - if (*rest_of_line) - { - line_number--; - input_text_offset = original_input_text_offset; - } - } - break; - - case table: - case ftable: - case vtable: - { - /* Get rid of extra characters. */ - kill_self_indent (-1); - - /* close_paragraph () almost does what we want. The problem - is when paragraph_is_open, and last_char_was_newline, and - the last newline has been turned into a space, because - filling_enabled. I handle it here. */ - if (last_char_was_newline && filling_enabled && paragraph_is_open) - insert ('\n'); - close_paragraph (); + { + case multitable: + multitable_item (); + /* Ultra special hack. It appears that some people incorrectly + place text directly after the @item, instead of on a new line + by itself. This happens to work in TeX, so I make it work + here. */ + if (*rest_of_line) + { + line_number--; + input_text_offset = original_input_text_offset; + } + break; + + case ifinfo: + case ifset: + case ifclear: + case cartouche: + stack = stack->next; + if (!stack) + goto no_insertion; + else + goto switch_top; + break; + + case menu: + case quotation: + case example: + case smallexample: + case lisp: + case format: + case display: + case group: + line_error (_("The `%c%s' command is meaningless within a `@%s' block"), + COMMAND_PREFIX, command, + insertion_type_pname (current_insertion_type ())); + break; + + case itemize: + case enumerate: + if (itemx_flag) + { + line_error (_("%citemx is not meaningful inside of a `%s' block"), + COMMAND_PREFIX, + insertion_type_pname (current_insertion_type ())); + } + else + { + start_paragraph (); + kill_self_indent (-1); + filling_enabled = indented_fill = 1; + + if (current_insertion_type () == itemize) + { + indent (output_column = current_indent - 2); + + /* I need some way to determine whether this command + takes braces or not. I believe the user can type + either "@bullet" or "@bullet{}". Of course, they + can also type "o" or "#" or whatever else they want. */ + if (item_func && *item_func) + { + if (*item_func == COMMAND_PREFIX) + if (item_func[strlen (item_func) - 1] != '}') + execute_string ("%s{}", item_func); + else + execute_string ("%s", item_func); + else + execute_string ("%s", item_func); + } + insert (' '); + output_column++; + } + else + enumerate_item (); + + /* Special hack. This makes `close_paragraph' a no-op until + `start_paragraph' has been called. */ + must_start_paragraph = 1; + + /* Handle text directly after the @item. */ + if (*rest_of_line) + { + line_number--; + input_text_offset = original_input_text_offset; + } + } + break; + + case table: + case ftable: + case vtable: + { + /* We need this to determine if we have two @item's in a row + (see test just below). */ + static int last_item_output_position = 0; + + /* Get rid of extra characters. */ + kill_self_indent (-1); + + /* If we have one @item followed directly by another @item, + we need to insert a blank line. This is not true for + @itemx, though. */ + if (!itemx_flag && last_item_output_position == output_position) + insert ('\n'); + + /* `close_paragraph' almost does what we want. The problem + is when paragraph_is_open, and last_char_was_newline, and + the last newline has been turned into a space, because + filling_enabled. I handle it here. */ + if (last_char_was_newline && filling_enabled && paragraph_is_open) + insert ('\n'); + close_paragraph (); #if defined (INDENT_PARAGRAPHS_IN_TABLE) - /* Indent on a new line, but back up one indentation level. */ - { - int t; - - t = inhibit_paragraph_indentation; - inhibit_paragraph_indentation = 1; - /* At this point, inserting any non-whitespace character will - force the existing indentation to be output. */ - add_char ('i'); - inhibit_paragraph_indentation = t; - } + /* Indent on a new line, but back up one indentation level. */ + { + int save = inhibit_paragraph_indentation; + inhibit_paragraph_indentation = 1; + /* At this point, inserting any non-whitespace character will + force the existing indentation to be output. */ + add_char ('i'); + inhibit_paragraph_indentation = save; + } #else /* !INDENT_PARAGRAPHS_IN_TABLE */ - add_char ('i'); + add_char ('i'); #endif /* !INDENT_PARAGRAPHS_IN_TABLE */ - output_paragraph_offset--; - kill_self_indent (default_indentation_increment + 1); - - /* Add item's argument to the line. */ - filling_enabled = 0; - if (item_func && *item_func) - execute_string ("%s{%s}", item_func, rest_of_line); - else - execute_string ("%s", rest_of_line); - - if (current_insertion_type () == ftable) - execute_string ("%cfindex %s\n", COMMAND_PREFIX, rest_of_line); - - if (current_insertion_type () == vtable) - execute_string ("%cvindex %s\n", COMMAND_PREFIX, rest_of_line); - - /* Start a new line, and let start_paragraph () - do the indenting of it for you. */ - close_single_paragraph (); - indented_fill = filling_enabled = 1; - } - } + output_paragraph_offset--; + kill_self_indent (default_indentation_increment + 1); + + /* Add item's argument to the line. */ + filling_enabled = 0; + if (item_func && *item_func) + execute_string ("%s{%s}", item_func, rest_of_line); + else + execute_string ("%s", rest_of_line); + + if (current_insertion_type () == ftable) + execute_string ("%cfindex %s\n", COMMAND_PREFIX, rest_of_line); + else if (current_insertion_type () == vtable) + execute_string ("%cvindex %s\n", COMMAND_PREFIX, rest_of_line); + + /* Start a new line, and let start_paragraph () + do the indenting of it for you. */ + close_single_paragraph (); + indented_fill = filling_enabled = 1; + last_item_output_position = output_position; + } + } free (rest_of_line); } else { no_insertion: - line_error ("%c%s found outside of an insertion block", - COMMAND_PREFIX, command); + line_error (_("%c%s found outside of an insertion block"), + COMMAND_PREFIX, command); } } /* **************************************************************** */ -/* */ -/* Defun and Friends */ -/* */ +/* */ +/* Defun and Friends */ +/* */ /* **************************************************************** */ -#define DEFUN_SELF_DELIMITING(c) \ - (((c) == '(') \ - || ((c) == ')') \ - || ((c) == '[') \ +#define DEFUN_SELF_DELIMITING(c) \ + (((c) == '(') \ + || ((c) == ')') \ + || ((c) == '[') \ || ((c) == ']')) struct token_accumulator @@ -6655,7 +6930,7 @@ accumulate_token (accumulator, token) { (accumulator->length) += 10; (accumulator->tokens) = (char **) xrealloc - (accumulator->tokens, (accumulator->length * sizeof (char *))); + (accumulator->tokens, (accumulator->length * sizeof (char *))); } accumulator->tokens[accumulator->index] = token; accumulator->index += 1; @@ -6675,7 +6950,7 @@ copy_substring (start, end) while (scan < end) *scan_result++ = *scan++; - *scan_result = '\0'; + *scan_result = 0; return (result); } @@ -6694,25 +6969,25 @@ scan_group_in_string (string_pointer) while (1) { if (level == 0) - { - (*string_pointer) = scan_string; - return (1); - } + { + (*string_pointer) = scan_string; + return (1); + } c = (*scan_string++); - if (c == '\0') - { - /* Tweak line_number to compensate for fact that - we gobbled the whole line before coming here. */ - line_number -= 1; - line_error ("Missing `}' in %cdef arg", COMMAND_PREFIX); - line_number += 1; - (*string_pointer) = (scan_string - 1); - return (0); - } + if (c == 0) + { + /* Tweak line_number to compensate for fact that + we gobbled the whole line before coming here. */ + line_number -= 1; + line_error (_("Missing `}' in %cdef arg"), COMMAND_PREFIX); + line_number += 1; + (*string_pointer) = (scan_string - 1); + return (0); + } if (c == '{') - level += 1; + level += 1; if (c == '}') - level -= 1; + level -= 1; } } @@ -6730,103 +7005,103 @@ args_from_string (string) initialize_token_accumulator (&accumulator); - while ((*scan_string) != '\0') + while ((*scan_string) != 0) { /* Replace arbitrary whitespace by a single space. */ if (whitespace (*scan_string)) - { - scan_string += 1; - while (whitespace (*scan_string)) - scan_string += 1; - accumulate_token ((&accumulator), (strdup (" "))); - continue; - } + { + scan_string += 1; + while (whitespace (*scan_string)) + scan_string += 1; + accumulate_token ((&accumulator), (xstrdup (" "))); + continue; + } /* Commands count as single tokens. */ if ((*scan_string) == COMMAND_PREFIX) - { - token_start = scan_string; - scan_string += 1; - if (self_delimiting (*scan_string)) - scan_string += 1; - else - { - register int c; - while (1) - { - c = *scan_string++; - - if ((c == '\0') || (c == '{') || (whitespace (c))) - { - scan_string -= 1; - break; - } - } - - if (*scan_string == '{') - { - char *s = scan_string; - (void) scan_group_in_string (&s); - scan_string = s; - } - } - token_end = scan_string; - } + { + token_start = scan_string; + scan_string += 1; + if (self_delimiting (*scan_string)) + scan_string += 1; + else + { + register int c; + while (1) + { + c = *scan_string++; + + if ((c == 0) || (c == '{') || (whitespace (c))) + { + scan_string -= 1; + break; + } + } + + if (*scan_string == '{') + { + char *s = scan_string; + (void) scan_group_in_string (&s); + scan_string = s; + } + } + token_end = scan_string; + } /* Parentheses and brackets are self-delimiting. */ else if (DEFUN_SELF_DELIMITING (*scan_string)) - { - token_start = scan_string; - scan_string += 1; - token_end = scan_string; - } + { + token_start = scan_string; + scan_string += 1; + token_end = scan_string; + } /* Open brace introduces a group that is a single token. */ else if (*scan_string == '{') - { - char *s = scan_string; - int balanced = scan_group_in_string (&s); + { + char *s = scan_string; + int balanced = scan_group_in_string (&s); - token_start = scan_string + 1; - scan_string = s; - token_end = balanced ? (scan_string - 1) : scan_string; - } + token_start = scan_string + 1; + scan_string = s; + token_end = balanced ? (scan_string - 1) : scan_string; + } /* Otherwise a token is delimited by whitespace, parentheses, - brackets, or braces. A token is also ended by a command. */ + brackets, or braces. A token is also ended by a command. */ else - { - token_start = scan_string; + { + token_start = scan_string; - while (1) - { - register int c; + while (1) + { + register int c; - c = *scan_string++; + c = *scan_string++; /* Do not back up if we're looking at a }; since the only valid }'s are those matched with {'s, we want to give an error. If we back up, we go into an infinite loop. */ - if (!c || whitespace (c) || DEFUN_SELF_DELIMITING (c) - || c == '{') - { - scan_string--; - break; - } - - /* If we encounter a command embedded within a token, - then end the token. */ - if (c == COMMAND_PREFIX) - { - scan_string--; - break; - } - } - token_end = scan_string; - } + if (!c || whitespace (c) || DEFUN_SELF_DELIMITING (c) + || c == '{') + { + scan_string--; + break; + } + + /* If we encounter a command embedded within a token, + then end the token. */ + if (c == COMMAND_PREFIX) + { + scan_string--; + break; + } + } + token_end = scan_string; + } accumulate_token - (&accumulator, copy_substring (token_start, token_end)); + (&accumulator, copy_substring (token_start, token_end)); } accumulate_token (&accumulator, NULL); return (accumulator.tokens); @@ -6844,30 +7119,30 @@ process_defun_args (defun_args, auto_var_p) char *defun_arg = *defun_args++; if (defun_arg == NULL) - break; + break; if (defun_arg[0] == ' ') - { - pending_space = 1; - continue; - } + { + pending_space = 1; + continue; + } if (pending_space) - { - add_char (' '); - pending_space = 0; - } + { + add_char (' '); + pending_space = 0; + } if (DEFUN_SELF_DELIMITING (defun_arg[0])) - add_char (defun_arg[0]); + add_char (defun_arg[0]); else if (defun_arg[0] == '&') - add_word (defun_arg); + add_word (defun_arg); else if (defun_arg[0] == COMMAND_PREFIX) - execute_string ("%s", defun_arg); + execute_string ("%s", defun_arg); else if (auto_var_p) - execute_string ("%cvar{%s}", COMMAND_PREFIX, defun_arg); + execute_string ("%cvar{%s}", COMMAND_PREFIX, defun_arg); else - add_word (defun_arg); + add_word (defun_arg); } } @@ -6891,7 +7166,7 @@ next_nonwhite_defun_arg (arg_pointer) /* Make the defun type insertion. TYPE says which insertion this is. - X_P says not to start a new insertion if non-zero. */ + X_P, if nonzero, says not to start a new insertion. */ void defun_internal (type, x_p) enum insertion_type type; @@ -6913,43 +7188,43 @@ defun_internal (type, x_p) switch (type) { case defun: - category = "Function"; + category = _("Function"); base_type = deffn; break; case defmac: - category = "Macro"; + category = _("Macro"); base_type = deffn; break; case defspec: - category = "Special Form"; + category = _("Special Form"); base_type = deffn; break; case defvar: - category = "Variable"; + category = _("Variable"); base_type = defvr; break; case defopt: - category = "User Option"; + category = _("User Option"); base_type = defvr; break; case deftypefun: - category = "Function"; + category = _("Function"); base_type = deftypefn; break; case deftypevar: - category = "Variable"; + category = _("Variable"); base_type = deftypevr; break; case defivar: - category = "Instance Variable"; + category = _("Instance Variable"); base_type = defcv; break; case defmethod: - category = "Method"; + category = _("Method"); base_type = defop; break; case deftypemethod: - category = "Method"; + category = _("Method"); base_type = deftypemethod; break; default: @@ -7015,7 +7290,7 @@ defun_internal (type, x_p) break; case deftypemethod: execute_string (" -- %s on %s: %s %s", category, type_name, type_name2, - defined_name); + defined_name); break; } current_indent += default_indentation_increment; @@ -7032,38 +7307,42 @@ defun_internal (type, x_p) case defop: process_defun_args (scan_args, 1); break; - case deftp: - case deftypefn: - case deftypemethod: + + /* Through Makeinfo 1.67 we processed remaining args only for deftp, + deftypefn, and deftypemethod. But the libc manual, for example, + needs to say: + @deftypevar {char *} tzname[2] + And simply allowing the extra text seems far simpler than trying + to invent yet more defn commands. In any case, we should either + output it or give an error, not silently ignore it. */ + default: process_defun_args (scan_args, 0); break; } current_indent -= default_indentation_increment; close_single_paragraph (); - if (!macro_expansion_output_stream) - /* Make an entry in the appropriate index unless we are just - expanding macros. */ - switch (base_type) - { - case deffn: - case deftypefn: - execute_string ("%cfindex %s\n", COMMAND_PREFIX, defined_name); - break; - case defvr: - case deftypevr: - case defcv: - execute_string ("%cvindex %s\n", COMMAND_PREFIX, defined_name); - break; - case defop: - case deftypemethod: - execute_string ("%cfindex %s on %s\n", - COMMAND_PREFIX, defined_name, type_name); - break; - case deftp: - execute_string ("%ctindex %s\n", COMMAND_PREFIX, defined_name); - break; - } + /* Make an entry in the appropriate index. */ + switch (base_type) + { + case deffn: + case deftypefn: + execute_string ("%cfindex %s\n", COMMAND_PREFIX, defined_name); + break; + case defvr: + case deftypevr: + case defcv: + execute_string ("%cvindex %s\n", COMMAND_PREFIX, defined_name); + break; + case defop: + case deftypemethod: + execute_string ("%cfindex %s on %s\n", + COMMAND_PREFIX, defined_name, type_name); + break; + case deftp: + execute_string ("%ctindex %s\n", COMMAND_PREFIX, defined_name); + break; + } /* Deallocate the token list. */ scan_args = defun_args; @@ -7071,7 +7350,7 @@ defun_internal (type, x_p) { char * arg = (*scan_args++); if (arg == NULL) - break; + break; free (arg); } free (defun_args); @@ -7085,12 +7364,12 @@ cm_defun () { int x_p; enum insertion_type type; - char *temp = strdup (command); + char *temp = xstrdup (command); x_p = (command[strlen (command) - 1] == 'x'); if (x_p) - temp[strlen (temp) - 1] = '\0'; + temp[strlen (temp) - 1] = 0; type = find_type_from_name (temp); free (temp); @@ -7100,8 +7379,8 @@ cm_defun () if (x_p && (!insertion_level || insertion_stack->insertion != type)) { - line_error ("Must be in a `%s' insertion in order to use `%s'x", - command, command); + line_error (_("Must be in a `%s' insertion in order to use `%s'x"), + command, command); discard_until ("\n"); return; } @@ -7109,40 +7388,10 @@ cm_defun () defun_internal (type, x_p); } -/* End existing insertion block. */ -void -cm_end () -{ - char *temp; - enum insertion_type type; - - if (!insertion_level) - { - line_error ("Unmatched `%c%s'", COMMAND_PREFIX, command); - return; - } - - get_rest_of_line (&temp); - canon_white (temp); - - if (strlen (temp) == 0) - line_error ("`%c%s' needs something after it", COMMAND_PREFIX, command); - - type = find_type_from_name (temp); - - if (type == bad_type) - { - line_error ("Bad argument to `%s', `%s', using `%s'", - command, temp, insertion_type_pname (current_insertion_type ())); - } - end_insertion (type); - free (temp); -} - /* **************************************************************** */ -/* */ -/* Other Random Commands */ -/* */ +/* */ +/* Other Random Commands */ +/* */ /* **************************************************************** */ /* This says to inhibit the indentation of the next paragraph, but @@ -7202,15 +7451,15 @@ cm_sp () if (sscanf (line, "%d", &lines) != 1) { - line_error ("%csp requires a positive numeric argument", COMMAND_PREFIX); + line_error (_("%csp requires a positive numeric argument"), COMMAND_PREFIX); } else { if (lines < 0) - lines = 0; + lines = 0; while (lines--) - add_char ('\n'); + add_char ('\n'); } free (line); } @@ -7221,11 +7470,11 @@ cm_sp () void cm_dircategory () { - char *line, *p; + char *line; get_rest_of_line (&line);; - if (! no_headers) + if (!no_headers) { insert_string ("INFO-DIR-SECTION "); insert_string (line); @@ -7257,7 +7506,7 @@ cm_center () i = output_paragraph_offset - 1; while (i > (start - 1) && output_paragraph[i] == '\n') - i--; + i--; output_paragraph_offset = ++i; length = output_paragraph_offset - start; @@ -7271,10 +7520,10 @@ cm_center () output_paragraph_offset = start; while (i--) - insert (' '); + insert (' '); for (i = 0; i < length; i++) - insert (line[i]); + insert (line[i]); free (line); } @@ -7357,20 +7606,6 @@ cm_exdent () close_single_paragraph (); } -#if !defined (HAVE_STRERROR) -extern char *sys_errlist[]; -extern int sys_nerr; - -char * -strerror (num) - int num; -{ - if (num >= sys_nerr) - return ("Unknown file system error"); - else - return (sys_errlist[num]); -} -#endif /* !HAVE_STRERROR */ /* Remember this file, and move onto the next. */ void @@ -7379,7 +7614,7 @@ cm_include () char *filename; #if defined (HAVE_MACROS) - if (macro_expansion_output_stream) + if (macro_expansion_output_stream && !executing_string) me_append_before_this_command (); #endif /* HAVE_MACROS */ @@ -7387,7 +7622,7 @@ cm_include () get_rest_of_line (&filename); #if defined (HAVE_MACROS) - if (macro_expansion_output_stream) + if (macro_expansion_output_stream && !executing_string) remember_itext (input_text, input_text_offset); #endif /* HAVE_MACROS */ @@ -7416,8 +7651,8 @@ cm_include () line_number--; /* Cannot "@include foo", in line 5 of "/wh/bar". */ - line_error ("`%c%s %s': %s", COMMAND_PREFIX, command, filename, - strerror (errno)); + line_error ("%c%s %s: %s", COMMAND_PREFIX, command, filename, + strerror (errno)); free (filename); return; @@ -7425,8 +7660,8 @@ cm_include () else { #if defined (HAVE_MACROS) - if (macro_expansion_output_stream) - remember_itext (input_text, input_text_offset); + if (macro_expansion_output_stream && !executing_string) + remember_itext (input_text, input_text_offset); #endif /* HAVE_MACROS */ reader_loop (); } @@ -7438,7 +7673,7 @@ cm_include () void misplaced_brace () { - line_error ("Misplaced `}'"); + line_error (_("Misplaced %c"), '}'); } /* Signals end of processing. Easy to make this happen. */ @@ -7447,11 +7682,51 @@ cm_bye () { input_text_offset = size_of_input_text; } + +/* Set the paragraph indentation variable to the value specified in STRING. + Values can be: + `asis': Don't change existing indentation. + `none': Remove existing indentation. + NUM: Indent NUM spaces at the starts of paragraphs. + If NUM is zero, we assume `none'. + Returns 0 if successful, or nonzero if STRING isn't one of the above. */ +int +set_paragraph_indent (string) + char *string; +{ + if (strcmp (string, "asis") == 0 || strcmp (string, _("asis")) == 0) + paragraph_start_indent = 0; + else if (strcmp (string, "none") == 0 || strcmp (string, _("none")) == 0) + paragraph_start_indent = -1; + else + { + if (sscanf (string, "%d", ¶graph_start_indent) != 1) + return (-1); + else + { + if (paragraph_start_indent == 0) + paragraph_start_indent = -1; + } + } + return (0); +} + +void +cm_paragraphindent () +{ + char *arg; + + get_rest_of_line (&arg); + if (set_paragraph_indent (arg) != 0) + line_error (_("Bad argument to %c%s"), COMMAND_PREFIX, command); + + free (arg); +} /* **************************************************************** */ -/* */ -/* Indexing Stuff */ -/* */ +/* */ +/* Indexing Stuff */ +/* */ /* **************************************************************** */ @@ -7459,21 +7734,48 @@ cm_bye () typedef struct index_elt { struct index_elt *next; - char *entry; /* The index entry itself. */ - char *node; /* The node from whence it came. */ - int code; /* Non-zero means add `@code{...}' when - printing this element. */ - int defining_line; /* Line number where this entry was written. */ + char *entry; /* The index entry itself. */ + char *node; /* The node from whence it came. */ + int code; /* Nonzero means add `@code{...}' when + printing this element. */ + int defining_line; /* Line number where this entry was written. */ + char *defining_file; /* Source file for defining_line. */ } INDEX_ELT; -/* A list of short-names for each index, and the index to that index in our - index array, the_indices. In addition, for each index, it is remembered - whether that index is a code index or not. Code indices have @code{} - inserted around the first word when they are printed with printindex. */ +/* A list of short-names for each index. + + There are two indices into the the_indices array. + + * read_index is the index that points to the list of index + entries that we will find if we ask for the list of entries for + this name. + + * write_index is the index that points to the list of index entries + that we will add new entries to. + + Initially, read_index and write index are the same, but the + @syncodeindex and @synindex commands can change the list we add + entries to. + + For example, after the commands + + @cindex foo + @defindex ii + @synindex cp ii + @cindex bar + + the cp index will contain the entry `foo', and the new ii + index will contain the entry `bar'. This is consistent with the + way texinfo.tex handles the same situation. + + In addition, for each index, it is remembered whether that index is + a code index or not. Code indices have @code{} inserted around the + first word when they are printed with printindex. */ typedef struct { char *name; - int index; + int read_index; /* index entries for `name' */ + int write_index; /* store index entries here, @synindex can change it */ int code; } INDEX_ALIST; @@ -7487,14 +7789,6 @@ INDEX_ELT **the_indices = (INDEX_ELT **) NULL; /* The number of defined indices. */ int defined_indices = 0; -/* We predefine these. */ -#define program_index 0 -#define function_index 1 -#define concept_index 2 -#define variable_index 3 -#define datatype_index 4 -#define key_index 5 - void init_indices () { @@ -7506,26 +7800,38 @@ init_indices () if (!the_indices) { the_indices = (INDEX_ELT **) xmalloc ((1 + defined_indices) * - sizeof (INDEX_ELT *)); + sizeof (INDEX_ELT *)); the_indices[defined_indices] = (INDEX_ELT *) NULL; name_index_alist = (INDEX_ALIST **) xmalloc ((1 + defined_indices) * - sizeof (INDEX_ALIST *)); + sizeof (INDEX_ALIST *)); name_index_alist[defined_indices] = (INDEX_ALIST *) NULL; } /* If there were existing indices, get rid of them now. */ for (i = 0; i < defined_indices; i++) - undefindex (name_index_alist[i]->name); + { + undefindex (name_index_alist[i]->name); + if (name_index_alist[i]) + { /* Suppose we're called with two input files, and the first + does a @synindex pg cp. Then, when we get here to start + the second file, the "pg" element won't get freed by + undefindex (because it's pointing to "cp"). So free it + here; otherwise, when we try to define the pg index again + just below, it will still point to cp. */ + free (name_index_alist[i]->name); + free (name_index_alist[i]); + name_index_alist[i] = (INDEX_ALIST *) NULL; + } + } /* Add the default indices. */ - top_defindex ("pg", 0); - top_defindex ("fn", 1); /* "fn" is a code index. */ - top_defindex ("cp", 0); - top_defindex ("vr", 0); - top_defindex ("tp", 0); - top_defindex ("ky", 0); - + top_defindex ("cp", 0); /* cp is the only non-code index. */ + top_defindex ("fn", 1); + top_defindex ("ky", 1); + top_defindex ("pg", 1); + top_defindex ("tp", 1); + top_defindex ("vr", 1); } /* Find which element in the known list of indices has this name. @@ -7537,8 +7843,8 @@ find_index_offset (name) register int i; for (i = 0; i < defined_indices; i++) if (name_index_alist[i] && - strcmp (name, name_index_alist[i]->name) == 0) - return (name_index_alist[i]->index); + strcmp (name, name_index_alist[i]->name) == 0) + return (i); return (-1); } @@ -7564,7 +7870,7 @@ translate_index (name) INDEX_ALIST *which = find_index (name); if (which) - return (which->index); + return (which->read_index); else return (-1); } @@ -7591,13 +7897,16 @@ free_index (index) while ((temp = index) != (INDEX_ELT *) NULL) { free (temp->entry); - free (temp->node); + /* Do not free the node, because we already freed the tag table, + which freed all the node names. */ + /* free (temp->node); */ index = index->next; free (temp); } } -/* Flush an index by name. */ +/* Flush an index by name. This will delete the list of entries that + would be written by a @printindex command for this index. */ void undefindex (name) char *name; @@ -7605,10 +7914,12 @@ undefindex (name) int i; int which = find_index_offset (name); - if (which < 0) + /* The index might have already been freed if this was the target of + an @synindex. */ + if (which < 0 || !name_index_alist[which]) return; - i = name_index_alist[which]->index; + i = name_index_alist[which]->read_index; free_index (the_indices[i]); the_indices[i] = (INDEX_ELT *) NULL; @@ -7619,7 +7930,7 @@ undefindex (name) } /* Define an index known as NAME. We assign the slot number. - CODE if non-zero says to make this a code index. */ + CODE if Nonzero says to make this a code index. */ void defindex (name, code) char *name; @@ -7635,8 +7946,8 @@ defindex (name, code) for (i = 0; i < defined_indices; i++) if (!name_index_alist[i]) { - slot = i; - break; + slot = i; + break; } if (slot < 0) @@ -7646,17 +7957,18 @@ defindex (name, code) defined_indices++; name_index_alist = (INDEX_ALIST **) - xrealloc ((char *)name_index_alist, - (1 + defined_indices) * sizeof (INDEX_ALIST *)); + xrealloc ((char *)name_index_alist, + (1 + defined_indices) * sizeof (INDEX_ALIST *)); the_indices = (INDEX_ELT **) - xrealloc ((char *)the_indices, - (1 + defined_indices) * sizeof (INDEX_ELT *)); + xrealloc ((char *)the_indices, + (1 + defined_indices) * sizeof (INDEX_ELT *)); } /* We have a slot. Start assigning. */ name_index_alist[slot] = (INDEX_ALIST *) xmalloc (sizeof (INDEX_ALIST)); - name_index_alist[slot]->name = strdup (name); - name_index_alist[slot]->index = slot; + name_index_alist[slot]->name = xstrdup (name); + name_index_alist[slot]->read_index = slot; + name_index_alist[slot]->write_index = slot; name_index_alist[slot]->code = code; the_indices[slot] = (INDEX_ELT *) NULL; @@ -7673,10 +7985,10 @@ index_add_arg (name) tem = find_index (name); - which = tem ? tem->index : -1; + which = tem ? tem->write_index : -1; #if defined (HAVE_MACROS) - if (macro_expansion_output_stream) + if (macro_expansion_output_stream && !executing_string) append_to_expansion_output (input_text_offset + 1); #endif /* HAVE_MACROS */ @@ -7684,7 +7996,7 @@ index_add_arg (name) ignore_blank_line (); #if defined (HAVE_MACROS) - if (macro_expansion_output_stream) + if (macro_expansion_output_stream && !executing_string) { int op_orig; @@ -7698,7 +8010,7 @@ index_add_arg (name) if (which < 0) { - line_error ("Unknown index reference `%s'", name); + line_error (_("Unknown index `%s'"), name); free (index_entry); } else @@ -7709,6 +8021,7 @@ index_add_arg (name) new->node = current_node; new->code = tem->code; new->defining_line = line_number - 1; + new->defining_file = input_filename; the_indices[which] = new; } } @@ -7719,9 +8032,9 @@ index_add_arg (name) void gen_index () { - char *name = strdup (command); + char *name = xstrdup (command); if (strlen (name) >= strlen ("index")) - name[strlen (name) - strlen ("index")] = '\0'; + name[strlen (name) - strlen ("index")] = 0; index_add_arg (name); free (name); } @@ -7762,7 +8075,7 @@ gen_defindex (code) if (find_index (name)) { - line_error ("Index `%s' already exists", name); + line_error (_("Index `%s' already exists"), name); free (name); return; } @@ -7776,96 +8089,68 @@ gen_defindex (code) } } -/* Append LIST2 to LIST1. Return the head of the list. */ -INDEX_ELT * -index_append (head, tail) - INDEX_ELT *head, *tail; -{ - register INDEX_ELT *t_head = head; - - if (!t_head) - return (tail); - - while (t_head->next) - t_head = t_head->next; - t_head->next = tail; - return (head); -} - /* Expects 2 args, on the same line. Both are index abbreviations. Make the first one be a synonym for the second one, i.e. make the first one have the same index as the second one. */ void cm_synindex () { - int redirector, redirectee; - char *temp; + int source, target; + char *abbrev1, *abbrev2; skip_whitespace (); - get_until_in_line (" ", &temp); - redirectee = find_index_offset (temp); + get_until_in_line (0, " ", &abbrev1); + target = find_index_offset (abbrev1); skip_whitespace (); - free_and_clear (&temp); - get_until_in_line (" ", &temp); - redirector = find_index_offset (temp); - free (temp); - if (redirector < 0 || redirectee < 0) + get_until_in_line (0, " ", &abbrev2); + source = find_index_offset (abbrev2); + if (source < 0 || target < 0) { - line_error ("Unknown index reference"); + line_error (_("Unknown index `%s' and/or `%s' in @synindex"), + abbrev1, abbrev2); } else { - /* I think that we should let the user make indices synonymous to - each other without any lossage of info. This means that one can - say @synindex cp dt anywhere in the file, and things that used to - be in cp will go into dt. */ - INDEX_ELT *i1 = the_indices[redirectee], *i2 = the_indices[redirector]; - - if (i1 || i2) - { - if (i1) - the_indices[redirectee] = index_append (i1, i2); - else - the_indices[redirectee] = index_append (i2, i1); - } - - name_index_alist[redirectee]->index = - name_index_alist[redirector]->index; + name_index_alist[target]->write_index + = name_index_alist[source]->write_index; } + + free (abbrev1); + free (abbrev2); } void -cm_pindex () /* Pinhead index. */ +cm_pindex () /* Pinhead index. */ { index_add_arg ("pg"); } void -cm_vindex () /* Variable index. */ +cm_vindex () /* Variable index. */ { index_add_arg ("vr"); } void -cm_kindex () /* Key index. */ +cm_kindex () /* Key index. */ { index_add_arg ("ky"); } void -cm_cindex () /* Concept index. */ +cm_cindex () /* Concept index. */ { index_add_arg ("cp"); } void -cm_findex () /* Function index. */ +cm_findex () /* Function index. */ { index_add_arg ("fn"); } void -cm_tindex () /* Data Type index. */ +cm_tindex () /* Data Type index. */ { index_add_arg ("tp"); } @@ -7893,14 +8178,14 @@ make_index_entries_unique (array, count) for (i = 0, j = 0; i < count; i++) { if ((i == (count - 1)) || - (array[i]->node != array[i + 1]->node) || - (strcmp (array[i]->entry, array[i + 1]->entry) != 0)) - copy[j++] = array[i]; + (array[i]->node != array[i + 1]->node) || + (strcmp (array[i]->entry, array[i + 1]->entry) != 0)) + copy[j++] = array[i]; else - { - free (array[i]->entry); - free (array[i]); - } + { + free (array[i]->entry); + free (array[i]); + } } copy[j] = (INDEX_ELT *)NULL; @@ -7913,20 +8198,20 @@ make_index_entries_unique (array, count) copy[i]->next = copy[i + 1]; /* Fix entry names which are the same. They point to different nodes, - so we make the entry name unique. */ + so we make the entry name unique. */ if ((copy[i + 1] != (INDEX_ELT *)NULL) && - (strcmp (copy[i]->entry, copy[i + 1]->entry) == 0)) - { - char *new_entry_name; - - new_entry_name = (char *)xmalloc (10 + strlen (copy[i]->entry)); - sprintf (new_entry_name, "%s <%d>", copy[i]->entry, counter); - free (copy[i]->entry); - copy[i]->entry = new_entry_name; - counter++; - } + (strcmp (copy[i]->entry, copy[i + 1]->entry) == 0)) + { + char *new_entry_name; + + new_entry_name = (char *)xmalloc (10 + strlen (copy[i]->entry)); + sprintf (new_entry_name, "%s <%d>", copy[i]->entry, counter); + free (copy[i]->entry); + copy[i]->entry = new_entry_name; + counter++; + } else - counter = 1; + counter = 1; array[i] = copy[i]; } @@ -7944,9 +8229,11 @@ INDEX_ELT ** sort_index (index) INDEX_ELT *index; { - INDEX_ELT *temp = index; INDEX_ELT **array; + INDEX_ELT *temp = index; int count = 0; + int save_line_number = line_number; + char *save_input_filename = input_filename; while (temp != (INDEX_ELT *) NULL) { @@ -7964,16 +8251,20 @@ sort_index (index) { array[count++] = temp; - /* Maybe should set line number to the defining_line? Any errors - have already been given, though, I think. */ + /* Set line number and input filename to the source line for this + index entry, as this expansion finds any errors. */ + line_number = array[count - 1]->defining_line; + input_filename = array[count - 1]->defining_file; /* If this particular entry should be printed as a "code" index, - then wrap the entry with "@code{...}". */ + then wrap the entry with "@code{...}". */ array[count - 1]->entry = expansion (temp->entry, index->code); temp = temp->next; } - array[count] = (INDEX_ELT *) NULL; /* terminate the array. */ + array[count] = (INDEX_ELT *) NULL; /* terminate the array. */ + line_number = save_line_number; + input_filename = save_input_filename; /* Sort the array. */ qsort (array, count, sizeof (INDEX_ELT *), index_element_compare); @@ -7981,7 +8272,7 @@ sort_index (index) return (array); } -/* Non-zero means that we are in the middle of printing an index. */ +/* Nonzero means that we are in the middle of printing an index. */ int printing_index = 0; /* Takes one arg, a short name of an index to print. @@ -8004,7 +8295,7 @@ cm_printindex () index = index_list (index_name); if (index == (INDEX_ELT *)-1) { - line_error ("Unknown index name `%s'", index_name); + line_error (_("Unknown index `%s' in @printindex"), index_name); free (index_name); return; } @@ -8019,7 +8310,7 @@ cm_printindex () array = sort_index (index); close_paragraph (); - add_word ("* Menu:\n\n"); + add_word (_("* Menu:\n\n")); #if defined (HAVE_MACROS) me_inhibit_expansion++; @@ -8034,11 +8325,15 @@ cm_printindex () /* A pathological document might have an index entry outside of any node. Don't crash. Perhaps should warn. */ char *index_node = index->node ? index->node : "(none)"; - unsigned new_length = strlen (index->entry) + strlen (index_node); + unsigned new_length = strlen (index->entry); + + if (new_length < 37) /* minimum length used below */ + new_length = 37; + new_length += strlen (index_node) + 7; /* * : .\n\0 */ if (new_length > line_length) { - line_length = new_length + 6; /* * : .\0 */ + line_length = new_length; line = xrealloc (line, line_length); } @@ -8066,8 +8361,8 @@ cm_printindex () filling_enabled = saved_filling_enabled; inhibit_paragraph_indentation = saved_inhibit_paragraph_indentation; } - -/* User-defined commands. */ + +/* User-defined commands, which happens only from user-defined indexes. */ void define_user_command (name, proc, needs_braces_p) @@ -8082,68 +8377,27 @@ define_user_command (name, proc, needs_braces_p) user_command_array = (COMMAND **) xmalloc (1 * sizeof (COMMAND *)); user_command_array = (COMMAND **) xrealloc (user_command_array, - (1 + user_command_array_len) * - sizeof (COMMAND *)); + (1 + user_command_array_len) * + sizeof (COMMAND *)); user_command_array[slot] = (COMMAND *) xmalloc (sizeof (COMMAND)); - user_command_array[slot]->name = strdup (name); + user_command_array[slot]->name = xstrdup (name); user_command_array[slot]->proc = proc; user_command_array[slot]->argument_in_braces = needs_braces_p; } - -/* Set the paragraph indentation variable to the value specified in STRING. - Values can be: - `asis': Don't change existing indentation. - `none': Remove existing indentation. - NUM: Indent NUM spaces at the starts of paragraphs. - Note that if NUM is zero, we assume `none'. - - Returns 0 if successful, or non-zero if STRING isn't one of the above. */ -int -set_paragraph_indent (string) - char *string; -{ - if (strcmp (string, "asis") == 0) - paragraph_start_indent = 0; - else if (strcmp (string, "none") == 0) - paragraph_start_indent = -1; - else - { - if (sscanf (string, "%d", ¶graph_start_indent) != 1) - return (-1); - else - { - if (paragraph_start_indent == 0) - paragraph_start_indent = -1; - } - } - return (0); -} - -void -cm_paragraphindent () -{ - char *arg; - - get_rest_of_line (&arg); - if (set_paragraph_indent (arg) != 0) - line_error ("Bad argument to %c%s", COMMAND_PREFIX, command); - - free (arg); -} - + /* Some support for footnotes. */ /* Footnotes are a new construct in Info. We don't know the best method of implementing them for sure, so we present two possiblities. SeparateNode: - Make them look like followed references, with the reference - destinations in a makeinfo manufactured node or, + Make them look like followed references, with the reference + destinations in a makeinfo manufactured node or, EndNode: - Make them appear at the bottom of the node that they originally - appeared in. */ + Make them appear at the bottom of the node that they originally + appeared in. */ #define SeparateNode 0 #define EndNode 1 @@ -8160,7 +8414,7 @@ set_footnote_style (string) (strcasecmp (string, "MN") == 0)) footnote_style = SeparateNode; else if ((strcasecmp (string, "end") == 0) || - (strcasecmp (string, "EN") == 0)) + (strcasecmp (string, "EN") == 0)) footnote_style = EndNode; else return (-1); @@ -8199,8 +8453,8 @@ remember_note (marker, note) { FN *temp = (FN *) xmalloc (sizeof (FN)); - temp->marker = strdup (marker); - temp->note = strdup (note); + temp->marker = xstrdup (marker); + temp->note = xstrdup (note); temp->next = pending_notes; pending_notes = temp; footnote_count++; @@ -8227,7 +8481,7 @@ free_pending_notes () /* Handle a "footnote". footnote *{this is a footnote} - where "*" is the marker character for this note. */ + where "*" is the (optional) marker character for this note. */ void cm_footnote () { @@ -8237,48 +8491,67 @@ cm_footnote () get_until ("{", &marker); canon_white (marker); + if (macro_expansion_output_stream && !executing_string) + append_to_expansion_output (input_text_offset + 1); /* include the { */ + /* Read the argument in braces. */ if (curchar () != '{') { - line_error ("`%c%s' expected more than just `%s'. It needs something in `{...}'", - COMMAND_PREFIX, command, marker); + line_error (_("`%c%s' needs an argument `{...}', not just `%s'"), + COMMAND_PREFIX, command, marker); free (marker); return; } else { - int braces = 1; - int temp = ++input_text_offset; int len; + int braces = 1; + int loc = ++input_text_offset; while (braces) - { - if (temp == size_of_input_text) - { - line_error ("No closing brace for footnote `%s'", marker); - return; - } - - if (input_text[temp] == '{') - braces++; - else if (input_text[temp] == '}') - braces--; - else if (input_text[temp] == '\n') - line_number ++; - - temp++; - } - - len = (temp - input_text_offset) - 1; + { + if (loc == size_of_input_text) + { + line_error (_("No closing brace for footnote `%s'"), marker); + return; + } + + if (input_text[loc] == '{') + braces++; + else if (input_text[loc] == '}') + braces--; + else if (input_text[loc] == '\n') + line_number++; + + loc++; + } + + len = (loc - input_text_offset) - 1; note = (char *)xmalloc (len + 1); strncpy (note, &input_text[input_text_offset], len); - note[len] = '\0'; - input_text_offset = temp; + note[len] = 0; + input_text_offset = loc; + } + + /* Must write the macro-expanded argument to the macro expansion + output stream. This is like the case in index_add_arg. */ + if (macro_expansion_output_stream && !executing_string) + { + int op_orig; + + remember_itext (input_text, input_text_offset); + op_orig = output_paragraph_offset; + me_execute_string (note); + /* Calling me_execute_string on a lone } provokes an error, since + as far as the reader knows there is no matching {. We wrote + the { above in the call to append_to_expansion_output. */ + write_region_to_macro_output ("}", 0, 1); + output_paragraph_offset = op_orig; } if (!current_node || !*current_node) { - line_error ("Footnote defined without parent node"); + line_error (_("Footnote defined without parent node")); free (marker); free (note); return; @@ -8289,13 +8562,13 @@ cm_footnote () free (marker); if (number_footnotes) - { - marker = (char *)xmalloc (10); - sprintf (marker, "%d", current_footnote_number); - current_footnote_number++; - } + { + marker = (char *)xmalloc (10); + sprintf (marker, "%d", current_footnote_number); + current_footnote_number++; + } else - marker = strdup ("*"); + marker = xstrdup ("*"); } remember_note (marker, note); @@ -8306,19 +8579,19 @@ cm_footnote () case SeparateNode: add_word_args ("(%s)", marker); if (first_footnote_this_node) - { - char *temp_string; - - temp_string = (char *) - xmalloc ((strlen (current_node)) + (strlen ("-Footnotes")) + 1); - - add_word_args (" (*note %s-Footnotes::)", current_node); - strcpy (temp_string, current_node); - strcat (temp_string, "-Footnotes"); - remember_node_reference (temp_string, line_number, followed_reference); - free (temp_string); - first_footnote_this_node = 0; - } + { + char *temp_string; + + temp_string = (char *) + xmalloc ((strlen (current_node)) + (strlen (_("-Footnotes"))) + 1); + + add_word_args (" (*note %s-Footnotes::)", current_node); + strcpy (temp_string, current_node); + strcat (temp_string, "-Footnotes"); + remember_node_reference (temp_string, line_number, followed_reference); + free (temp_string); + first_footnote_this_node = 0; + } break; case EndNode: @@ -8332,7 +8605,7 @@ cm_footnote () free (note); } -/* Non-zero means that we are currently in the process of outputting +/* Nonzero means that we are currently in the process of outputting footnotes. */ int already_outputting_pending_notes = 0; @@ -8349,23 +8622,23 @@ output_pending_notes () { case SeparateNode: { - char *old_current_node = current_node; - char *old_command = strdup (command); - - already_outputting_pending_notes++; - execute_string ("%cnode %s-Footnotes,,,%s\n", - COMMAND_PREFIX, current_node, current_node); - already_outputting_pending_notes--; - current_node = old_current_node; - free (command); - command = old_command; + char *old_current_node = current_node; + char *old_command = xstrdup (command); + + already_outputting_pending_notes++; + execute_string ("%cnode %s-Footnotes,,,%s\n", + COMMAND_PREFIX, current_node, current_node); + already_outputting_pending_notes--; + current_node = old_current_node; + free (command); + command = old_command; } break; case EndNode: close_paragraph (); in_fixed_width_font++; - execute_string ("---------- Footnotes ----------\n\n"); + execute_string (_("---------- Footnotes ----------\n\n")); in_fixed_width_font--; break; } @@ -8378,24 +8651,17 @@ output_pending_notes () while (--footnote_count > -1) { - array[footnote_count] = footnote; - footnote = footnote->next; + array[footnote_count] = footnote; + footnote = footnote->next; } filling_enabled = 1; indented_fill = 1; - while (footnote = array[++footnote_count]) + while ((footnote = array[++footnote_count])) { - - switch (footnote_style) - { - case SeparateNode: - case EndNode: - execute_string ("(%s) %s", footnote->marker, footnote->note); - close_paragraph (); - break; - } + execute_string ("(%s) %s", footnote->marker, footnote->note); + close_paragraph (); } close_paragraph (); free (array); @@ -8404,7 +8670,7 @@ output_pending_notes () /* **************************************************************** */ /* */ -/* User definable Macros (text substitution) */ +/* User definable Macros (text substitution) */ /* */ /* **************************************************************** */ @@ -8413,8 +8679,8 @@ output_pending_notes () /* Array of macros and definitions. */ MACRO_DEF **macro_list = (MACRO_DEF **)NULL; -int macro_list_len = 0; /* Number of elements. */ -int macro_list_size = 0; /* Number of slots in total. */ +int macro_list_len = 0; /* Number of elements. */ +int macro_list_size = 0; /* Number of slots in total. */ /* Return the macro definition of NAME or NULL if NAME is not defined. */ MACRO_DEF * @@ -8428,7 +8694,7 @@ find_macro (name) for (i = 0; macro_list && (def = macro_list[i]); i++) { if ((!def->inhibited) && (strcmp (def->name, name) == 0)) - break; + break; } return (def); } @@ -8453,8 +8719,8 @@ add_macro (name, arglist, body, source_file, source_lineno, flags) if (!def) { if (macro_list_len + 2 >= macro_list_size) - macro_list = (MACRO_DEF **)xrealloc - (macro_list, ((macro_list_size += 10) * sizeof (MACRO_DEF *))); + macro_list = (MACRO_DEF **)xrealloc + (macro_list, ((macro_list_size += 10) * sizeof (MACRO_DEF *))); macro_list[macro_list_len] = (MACRO_DEF *)xmalloc (sizeof (MACRO_DEF)); macro_list[macro_list_len + 1] = (MACRO_DEF *)NULL; @@ -8468,30 +8734,29 @@ add_macro (name, arglist, body, source_file, source_lineno, flags) char *temp_filename = input_filename; int temp_line = line_number; - warning ("The macro `%s' is previously defined", name); + warning (_("macro `%s' previously defined"), name); input_filename = def->source_file; line_number = def->source_lineno; - - warning ("Here is the previous definition of `%s'", name); + warning (_("here is the previous definition of `%s'"), name); input_filename = temp_filename; line_number = temp_line; if (def->arglist) - { - register int i; + { + register int i; - for (i = 0; def->arglist[i]; i++) - free (def->arglist[i]); + for (i = 0; def->arglist[i]; i++) + free (def->arglist[i]); - free (def->arglist); - } + free (def->arglist); + } free (def->source_file); free (def->body); } - def->source_file = strdup (source_file); + def->source_file = xstrdup (source_file); def->source_lineno = source_lineno; def->body = body; def->arglist = arglist; @@ -8514,9 +8779,10 @@ delete_macro (name) for (i = 0; macro_list && (def = macro_list[i]); i++) if (strcmp (def->name, name) == 0) { - memmove (macro_list + i, macro_list + i + 1, - ((macro_list_len + 1) - i) * sizeof (MACRO_DEF *)); - break; + memmove (macro_list + i, macro_list + i + 1, + ((macro_list_len + 1) - i) * sizeof (MACRO_DEF *)); + macro_list_len--; + break; } return (def); } @@ -8527,7 +8793,7 @@ int braces_required_for_macro_args = 0; char ** get_macro_args (def) - MACRO_DEF *def; + MACRO_DEF *def; { register int i; char *word; @@ -8541,35 +8807,38 @@ get_macro_args (def) if (input_text[i] != '{') { if (braces_required_for_macro_args) - { - return ((char **)NULL); - } + { + return ((char **)NULL); + } else - { - /* Braces are not required to fill out the macro arguments. If - this macro takes one argument, it is considered to be the - remainder of the line, sans whitespace. */ - if (def->arglist && def->arglist[0] && !def->arglist[1]) - { - char **arglist; - - get_rest_of_line (&word); - if (input_text[input_text_offset - 1] == '\n') - input_text_offset--; - /* canon_white (word); */ - arglist = (char **)xmalloc (2 * sizeof (char *)); - arglist[0] = word; - arglist[1] = (char *)NULL; - return (arglist); - } - else - { - /* The macro either took no arguments, or took more than - one argument. In that case, it must be invoked with - arguments surrounded by braces. */ - return ((char **)NULL); - } - } + { + /* Braces are not required to fill out the macro arguments. If + this macro takes one argument, it is considered to be the + remainder of the line, sans whitespace. */ + if (def->arglist && def->arglist[0] && !def->arglist[1]) + { + char **arglist; + + get_rest_of_line (&word); + if (input_text[input_text_offset - 1] == '\n') + { + input_text_offset--; + line_number--; + } + /* canon_white (word); */ + arglist = (char **)xmalloc (2 * sizeof (char *)); + arglist[0] = word; + arglist[1] = (char *)NULL; + return (arglist); + } + else + { + /* The macro either took no arguments, or took more than + one argument. In that case, it must be invoked with + arguments surrounded by braces. */ + return ((char **)NULL); + } + } } return (get_brace_args (def->flags & ME_QUOTE_ARG)); } @@ -8596,66 +8865,69 @@ apply (named, actuals, body) while (1) { if (!body[i]) - break; + break; if (body[i] != '\\') - new_body[new_body_index++] = body[i++]; + new_body[new_body_index++] = body[i++]; else - { - /* Snarf parameter name, check against named parameters. */ - char *param; - int param_start, which, len; - - param_start = ++i; - while ((body[i]) && (body[i] != '\\')) - i++; - - len = i - param_start; - param = (char *)xmalloc (1 + len); - memcpy (param, body + param_start, len); - param[len] = '\0'; - - if (body[i]) - i++; - - /* Now check against named parameters. */ - for (which = 0; named && named[which]; which++) - if (strcmp (named[which], param) == 0) - break; - - if (named[which]) - { - if (which < length_of_actuals) - text = actuals[which]; - else - text = (char *)NULL; - - if (!text) - text = ""; - - len = strlen (text); - } - else - { - len += 2; - text = (char *)xmalloc (1 + len); - sprintf (text, "\\%s\\", param); - } - - if ((2 + strlen (param)) < len) - new_body = (char *)xrealloc - (new_body, new_body_size += (1 + len)); - - free (param); - - strcpy (new_body + new_body_index, text); - new_body_index += len; - - if (!named[which]) - free (text); - } - } - new_body[new_body_index] = '\0'; + { + /* Snarf parameter name, check against named parameters. */ + char *param; + int param_start, which, len; + + param_start = ++i; + while ((body[i]) && (body[i] != '\\')) + i++; + + len = i - param_start; + param = (char *)xmalloc (1 + len); + memcpy (param, body + param_start, len); + param[len] = 0; + + if (body[i]) /* move past \ */ + i++; + + /* Now check against named parameters. */ + for (which = 0; named && named[which]; which++) + if (strcmp (named[which], param) == 0) + break; + + if (named && named[which]) + { + if (which < length_of_actuals) + text = actuals[which]; + else + text = (char *)NULL; + + if (!text) + text = ""; + + len = strlen (text); + } + else + { /* not a parameter, restore \'s */ + i = body[i] ? (i - 1) : i; + len++; + text = xmalloc (1 + len); + sprintf (text, "\\%s", param); + } + + if ((2 + strlen (param)) < len) + { + new_body_size += len + 1; + new_body = xrealloc (new_body, new_body_size); + } + + free (param); + + strcpy (new_body + new_body_index, text); + new_body_index += len; + + if (!named || !named[which]) + free (text); + } + } + new_body[new_body_index] = 0; return (new_body); } @@ -8664,12 +8936,11 @@ void execute_macro (def) MACRO_DEF *def; { - register int i; char **arglist; int num_args; char *execution_string = (char *)NULL; - if (macro_expansion_output_stream && !me_inhibit_expansion) + if (macro_expansion_output_stream && !executing_string && !me_inhibit_expansion) me_append_before_this_command (); /* Find out how many arguments this macro definition takes. */ @@ -8681,7 +8952,7 @@ execute_macro (def) if (num_args < array_len (arglist)) { free_array (arglist); - line_error ("Macro `%s' called with too many args", def->name); + line_error (_("Macro `%s' called with too many args"), def->name); return; } @@ -8692,13 +8963,13 @@ execute_macro (def) if (def->body) { - if (macro_expansion_output_stream && !me_inhibit_expansion) - { - remember_itext (input_text, input_text_offset); - me_execute_string (execution_string); - } + if (macro_expansion_output_stream && !executing_string && !me_inhibit_expansion) + { + remember_itext (input_text, input_text_offset); + me_execute_string (execution_string); + } else - execute_string ("%s", execution_string); + execute_string ("%s", execution_string); free (execution_string); } @@ -8720,7 +8991,7 @@ cm_macro () body_size = 0; body_index = 0; - if (macro_expansion_output_stream) + if (macro_expansion_output_stream && !executing_string) me_append_before_this_command (); skip_whitespace (); @@ -8732,15 +9003,15 @@ cm_macro () int len; for (i = start; - (i < size_of_input_text) && - (input_text[i] != '{') && - (!cr_or_whitespace (input_text[i])); - i++); + (i < size_of_input_text) && + (input_text[i] != '{') && + (!cr_or_whitespace (input_text[i])); + i++); len = i - start; name = (char *)xmalloc (1 + len); strncpy (name, input_text + start, len); - name[len] = '\0'; + name[len] = 0; input_text_offset = i; } @@ -8756,71 +9027,71 @@ cm_macro () int character; /* Read the words inside of the braces which determine the arglist. - These words will be replaced within the body of the macro at - execution time. */ + These words will be replaced within the body of the macro at + execution time. */ input_text_offset++; skip_whitespace_and_newlines (); while (gathering_words) - { - int len; - - for (i = input_text_offset; - character = input_text[i]; - i++) - { - switch (character) - { - case '\n': - line_number++; - case ' ': - case '\t': - case ',': - case '}': - /* Found the end of the current arglist word. Save it. */ - len = i - input_text_offset; - word = (char *)xmalloc (1 + len); - strncpy (word, input_text + input_text_offset, len); - word[len] = '\0'; - input_text_offset = i; - - /* Advance to the comma or close-brace that signified - the end of the argument. */ - while ((character = curchar ()) - && character != ',' - && character != '}') - { - input_text_offset++; - if (character == '\n') - line_number++; - } - - /* Add the word to our list of words. */ - if ((arglist_index + 2) >= arglist_size) - arglist = (char **)xrealloc - (arglist, (arglist_size += 10) * sizeof (char *)); - - arglist[arglist_index++] = word; - arglist[arglist_index] = (char *)NULL; - break; - } - - if (character == '}') - { - input_text_offset++; - gathering_words = 0; - break; - } - - if (character == ',') - { - input_text_offset++; - skip_whitespace_and_newlines (); - i = input_text_offset - 1; - } - } - } + { + int len; + + for (i = input_text_offset; + (character = input_text[i]); + i++) + { + switch (character) + { + case '\n': + line_number++; + case ' ': + case '\t': + case ',': + case '}': + /* Found the end of the current arglist word. Save it. */ + len = i - input_text_offset; + word = (char *)xmalloc (1 + len); + strncpy (word, input_text + input_text_offset, len); + word[len] = 0; + input_text_offset = i; + + /* Advance to the comma or close-brace that signified + the end of the argument. */ + while ((character = curchar ()) + && character != ',' + && character != '}') + { + input_text_offset++; + if (character == '\n') + line_number++; + } + + /* Add the word to our list of words. */ + if ((arglist_index + 2) >= arglist_size) + arglist = (char **)xrealloc + (arglist, (arglist_size += 10) * sizeof (char *)); + + arglist[arglist_index++] = word; + arglist[arglist_index] = (char *)NULL; + break; + } + + if (character == '}') + { + input_text_offset++; + gathering_words = 0; + break; + } + + if (character == ',') + { + input_text_offset++; + skip_whitespace_and_newlines (); + i = input_text_offset - 1; + } + } + } } /* Read the text carefully until we find an "@end macro" which @@ -8830,84 +9101,94 @@ cm_macro () while (depth) { if ((input_text_offset + 9) > size_of_input_text) - { - int temp_line = line_number; - line_number = defining_line; - line_error ("%cend macro not found", COMMAND_PREFIX); - line_number = temp_line; - return; - } + { + int temp_line = line_number; + line_number = defining_line; + line_error (_("%cend macro not found"), COMMAND_PREFIX); + line_number = temp_line; + return; + } get_rest_of_line (&line); /* Handle commands only meaningful within a macro. */ if ((*line == COMMAND_PREFIX) && (depth == 1) && - (strncmp (line + 1, "allow-recursion", 15) == 0) && - (line[16] == '\0' || whitespace (line[16]))) - { - for (i = 16; whitespace (line[i]); i++); - strcpy (line, line + i); - flags |= ME_RECURSE; - if (!*line) - { - free (line); - continue; - } - } + (strncmp (line + 1, "allow-recursion", 15) == 0) && + (line[16] == 0 || whitespace (line[16]))) + { + for (i = 16; whitespace (line[i]); i++); + strcpy (line, line + i); + flags |= ME_RECURSE; + if (!*line) + { + free (line); + continue; + } + } if ((*line == COMMAND_PREFIX) && (depth == 1) && - (strncmp (line + 1, "quote-arg", 9) == 0) && - (line[10] == '\0' || whitespace (line[10]))) - { - for (i = 10; whitespace (line[i]); i++); - strcpy (line, line + i); - - if (arglist && arglist[0] && !arglist[1]) - { - flags |= ME_QUOTE_ARG; - if (!*line) - { - free (line); - continue; - } - } - else - { - line_error ("%cquote-arg only useful when the macro takes a single argument", - COMMAND_PREFIX); - } - } + (strncmp (line + 1, "quote-arg", 9) == 0) && + (line[10] == 0 || whitespace (line[10]))) + { + for (i = 10; whitespace (line[i]); i++); + strcpy (line, line + i); + + if (arglist && arglist[0] && !arglist[1]) + { + flags |= ME_QUOTE_ARG; + if (!*line) + { + free (line); + continue; + } + } + else + { + line_error (_("%cquote-arg only useful when the macro takes a single argument"), + COMMAND_PREFIX); + } + } if ((*line == COMMAND_PREFIX) && - (strncmp (line + 1, "macro ", 6) == 0)) - depth++; + (strncmp (line + 1, "macro ", 6) == 0)) + depth++; if ((*line == COMMAND_PREFIX) && - (strncmp (line + 1, "end macro", 9) == 0)) - depth--; + (strncmp (line + 1, "end macro", 9) == 0)) + depth--; if (depth) - { - if ((body_index + strlen (line) + 3) >= body_size) - body = (char *)xrealloc - (body, body_size += 3 + strlen (line)); - strcpy (body + body_index, line); - body_index += strlen (line); - body[body_index++] = '\n'; - body[body_index] = '\0'; - } + { + if ((body_index + strlen (line) + 3) >= body_size) + body = (char *)xrealloc + (body, body_size += 3 + strlen (line)); + strcpy (body + body_index, line); + body_index += strlen (line); + body[body_index++] = '\n'; + body[body_index] = 0; + } free (line); } + /* If it was an empty macro like + @macro foo + @end macro + create an empty body. (Otherwise, the macro is not expanded.) */ + if (!body) + { + body = (char *)malloc(1); + *body = 0; + } + /* We now have the name, the arglist, and the body. However, BODY includes the final newline which preceded the `@end macro' text. Delete it. */ if (body && strlen (body)) - body[strlen (body) - 1] = '\0'; + body[strlen (body) - 1] = 0; add_macro (name, arglist, body, input_filename, defining_line, flags); - if (macro_expansion_output_stream) + if (macro_expansion_output_stream && !executing_string) remember_itext (input_text, input_text_offset); } @@ -8918,16 +9199,15 @@ cm_unmacro () char *line, *name; MACRO_DEF *def; - if (macro_expansion_output_stream) + if (macro_expansion_output_stream && !executing_string) me_append_before_this_command (); get_rest_of_line (&line); - canon_white (line); for (i = 0; line[i] && !whitespace (line[i]); i++); - name = (char *)xmalloc (i); + name = (char *)xmalloc (i + 1); strncpy (name, line, i); - name[i] = '\0'; + name[i] = 0; def = delete_macro (name); @@ -8938,14 +9218,14 @@ cm_unmacro () free (def->body); if (def->arglist) - { - register int i; + { + register int i; - for (i = 0; def->arglist[i]; i++) - free (def->arglist[i]); + for (i = 0; def->arglist[i]; i++) + free (def->arglist[i]); - free (def->arglist); - } + free (def->arglist); + } free (def); } @@ -8953,7 +9233,7 @@ cm_unmacro () free (line); free (name); - if (macro_expansion_output_stream) + if (macro_expansion_output_stream && !executing_string) remember_itext (input_text, input_text_offset); } @@ -8973,38 +9253,38 @@ remember_itext (pointer, offset) { itext_info = (ITEXT **)xmalloc ((itext_size = 10) * sizeof (ITEXT *)); for (i = 0; i < itext_size; i++) - itext_info[i] = (ITEXT *)NULL; + itext_info[i] = (ITEXT *)NULL; } /* If the pointer is already present in the list, then set the offset. */ for (i = 0; i < itext_size; i++) if ((itext_info[i] != (ITEXT *)NULL) && - (itext_info[i]->pointer == pointer)) + (itext_info[i]->pointer == pointer)) { - itext = itext_info[i]; - itext_info[i]->offset = offset; - break; + itext = itext_info[i]; + itext_info[i]->offset = offset; + break; } if (i == itext_size) { - /* Find a blank slot, (or create a new one), and remember the - pointer and offset. */ + /* Find a blank slot (or create a new one), and remember the + pointer and offset. */ for (i = 0; i < itext_size; i++) - if (itext_info[i] == (ITEXT *)NULL) - break; + if (itext_info[i] == (ITEXT *)NULL) + break; /* If not found, then add some slots. */ if (i == itext_size) - { - register int j; + { + register int j; - itext_info = (ITEXT **)xrealloc - (itext_info, (itext_size += 10) * sizeof (ITEXT *)); + itext_info = (ITEXT **)xrealloc + (itext_info, (itext_size += 10) * sizeof (ITEXT *)); - for (j = i; j < itext_size; j++) - itext_info[j] = (ITEXT *)NULL; - } + for (j = i; j < itext_size; j++) + itext_info[j] = (ITEXT *)NULL; + } /* Now add the pointer and the offset. */ itext_info[i] = (ITEXT *)xmalloc (sizeof (ITEXT)); @@ -9025,9 +9305,9 @@ forget_itext (pointer) for (i = 0; i < itext_size; i++) if (itext_info[i] && (itext_info[i]->pointer == pointer)) { - free (itext_info[i]); - itext_info[i] = (ITEXT *)NULL; - break; + free (itext_info[i]); + itext_info[i] = (ITEXT *)NULL; + break; } } @@ -9051,15 +9331,15 @@ me_execute_string (execution_string) pushfile (); input_text_offset = 0; input_text = execution_string; - input_filename = strdup (input_filename); + input_filename = xstrdup (input_filename); size_of_input_text = strlen (execution_string); remember_itext (execution_string, 0); - executing_string++; + me_executing_string++; reader_loop (); popfile (); - executing_string--; + me_executing_string--; } /* Append the text which appears in input_text from the last offset to @@ -9074,17 +9354,17 @@ append_to_expansion_output (offset) for (i = 0; i < itext_size; i++) if (itext_info[i] && itext_info[i]->pointer == input_text) { - itext = itext_info[i]; - break; + itext = itext_info[i]; + break; } if (!itext) - itext = remember_itext (input_text, 0); + return; if (offset > itext->offset) { write_region_to_macro_output - (input_text, itext->offset, offset); + (input_text, itext->offset, offset); remember_itext (input_text, offset); } } @@ -9101,8 +9381,8 @@ maybe_write_itext (pointer, offset) for (i = 0; i < itext_size; i++) if (itext_info[i] && (itext_info[i]->pointer == pointer)) { - itext = itext_info[i]; - break; + itext = itext_info[i]; + break; } if (itext && (itext->offset < offset)) @@ -9145,7 +9425,7 @@ free_array (array) register int i; for (i = 0; array[i] != (char *)NULL; i++) - free (array[i]); + free (array[i]); free (array); } @@ -9174,64 +9454,64 @@ get_brace_args (quote_single) start = input_text_offset; escape_seen = 0; - while (character = curchar ()) + while ((character = curchar ())) { if (character == '\\') - { - input_text_offset += 2; - escape_seen = 1; - } + { + input_text_offset += 2; + escape_seen = 1; + } else if (character == '{') - { - depth++; - input_text_offset++; - } + { + depth++; + input_text_offset++; + } else if ((character == ',' && !quote_single) || - ((character == '}') && depth == 1)) - { - int len = input_text_offset - start; - - if (len || (character != '}')) - { - word = (char *)xmalloc (1 + len); - strncpy (word, input_text + start, len); - word[len] = '\0'; - - /* Clean up escaped characters. */ - if (escape_seen) - { - register int i; - - for (i = 0; word[i]; i++) - if (word[i] == '\\') - memmove (word + i, word + i + 1, - 1 + strlen (word + i + 1)); - } - - if (arglist_index + 2 >= arglist_size) - arglist = (char **)xrealloc - (arglist, (arglist_size += 10) * sizeof (char *)); - - arglist[arglist_index++] = word; - arglist[arglist_index] = (char *)NULL; - } - - input_text_offset++; - if (character == '}') - break; - else - goto get_arg; - } + ((character == '}') && depth == 1)) + { + int len = input_text_offset - start; + + if (len || (character != '}')) + { + word = (char *)xmalloc (1 + len); + strncpy (word, input_text + start, len); + word[len] = 0; + + /* Clean up escaped characters. */ + if (escape_seen) + { + register int i; + + for (i = 0; word[i]; i++) + if (word[i] == '\\') + memmove (word + i, word + i + 1, + 1 + strlen (word + i + 1)); + } + + if (arglist_index + 2 >= arglist_size) + arglist = (char **)xrealloc + (arglist, (arglist_size += 10) * sizeof (char *)); + + arglist[arglist_index++] = word; + arglist[arglist_index] = (char *)NULL; + } + + input_text_offset++; + if (character == '}') + break; + else + goto get_arg; + } else if (character == '}') - { - depth--; - input_text_offset++; - } + { + depth--; + input_text_offset++; + } else - { - input_text_offset++; - if (character == '\n') line_number++; - } + { + input_text_offset++; + if (character == '\n') line_number++; + } } return (arglist); } @@ -9274,10 +9554,10 @@ extract_colon_unit (string, index) if (i == start) { if (string[i]) - (*index)++; + (*index)++; /* Return "" in the case of a trailing `:'. */ - return (strdup ("")); + return (xstrdup ("")); } else { @@ -9285,7 +9565,7 @@ extract_colon_unit (string, index) value = (char *)xmalloc (1 + (i - start)); strncpy (value, &string[start], (i - start)); - value [i - start] = '\0'; + value [i - start] = 0; return (value); } @@ -9310,23 +9590,29 @@ get_file_info_in_path (filename, path, finfo) if (*filename == '/' || (*filename == '.' && (filename[1] == '/' || - (filename[1] == '.' && filename[2] == '/')))) + (filename[1] == '.' && filename[2] == '/'))) +#ifdef WIN32 + /* Handle names that look like "d:/foo/bar" */ + || (isalpha (*filename) && filename [1] == ':' + && (filename [2] == '/' || filename [2] == '\\')) +#endif + ) { if (stat (filename, finfo) == 0) - return (strdup (filename)); + return (xstrdup (filename)); else - return ((char *)NULL); + return ((char *)NULL); } - while (dir = extract_colon_unit (path, &index)) + while ((dir = extract_colon_unit (path, &index))) { char *fullpath; if (!*dir) - { - free (dir); - dir = strdup ("."); - } + { + free (dir); + dir = xstrdup ("."); + } fullpath = (char *)xmalloc (2 + strlen (dir) + strlen (filename)); sprintf (fullpath, "%s/%s", dir, filename); @@ -9335,9 +9621,9 @@ get_file_info_in_path (filename, path, finfo) result = stat (fullpath, finfo); if (result == 0) - return (fullpath); + return (fullpath); else - free (fullpath); + free (fullpath); } - return ((char *)NULL); + return NULL; } diff --git a/contrib/texinfo/util/install-info.c b/contrib/texinfo/util/install-info.c index b6a7a91..afa9a68 100644 --- a/contrib/texinfo/util/install-info.c +++ b/contrib/texinfo/util/install-info.c @@ -1,37 +1,27 @@ /* install-info -- create Info directory entry(ies) for an Info file. - Copyright (C) 1996 Free Software Foundation, Inc. + $Id: install-info.c,v 1.21 1998/03/01 15:38:45 karl Exp $ -$Id: install-info.c,v 1.12 1996/10/03 23:13:36 karl Exp $ + Copyright (C) 1996, 97, 98 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 -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. + 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 + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.*/ -#define INSTALL_INFO_VERSION_STRING "GNU install-info (Texinfo 3.9) 1.2" - -#include <stdio.h> -#include <errno.h> +#include "system.h" #include <getopt.h> -#include <sys/types.h> - -/* Get O_RDONLY. */ -#ifdef HAVE_SYS_FCNTL_H -#include <sys/fcntl.h> -#else -#include <fcntl.h> -#endif /* !HAVE_SYS_FCNTL_H */ -#ifdef HAVE_SYS_FILE_H -#include <sys/file.h> + +#ifdef HAVE_LIBZ +#include <zlib.h> #endif /* Name this program was invoked with. */ @@ -47,9 +37,8 @@ struct spec_entry; /* Data structures. */ -/* Record info about a single line from a file - as read into core. */ +/* Record info about a single line from a file as read into core. */ struct line_data { /* The start of the line. */ @@ -66,9 +55,9 @@ struct line_data int delete; }; + /* This is used for a list of the specified menu section names in which entries should be added. */ - struct spec_section { struct spec_section *next; @@ -78,16 +67,16 @@ struct spec_section int missing; }; -/* This is used for a list of the entries specified to be added. */ +/* This is used for a list of the entries specified to be added. */ struct spec_entry { struct spec_entry *next; char *text; }; - -/* This is used for a list of nodes found by parsing the dir file. */ + +/* This is used for a list of nodes found by parsing the dir file. */ struct node { struct node *next; @@ -108,9 +97,9 @@ struct node struct menu_section *last_section; }; + /* This is used for a list of sections found in a node's menu. Each struct node has such a list in the sections field. */ - struct menu_section { struct menu_section *next; @@ -124,7 +113,6 @@ struct menu_section /* Memory allocation and string operations. */ /* Like malloc but get fatal error if memory is exhausted. */ - void * xmalloc (size) unsigned int size; @@ -132,12 +120,11 @@ xmalloc (size) extern void *malloc (); void *result = malloc (size); if (result == NULL) - fatal ("virtual memory exhausted", 0); + fatal (_("virtual memory exhausted"), 0); return result; } -/* Like malloc but get fatal error if memory is exhausted. */ - +/* Like realloc but get fatal error if memory is exhausted. */ void * xrealloc (obj, size) void *obj; @@ -146,12 +133,12 @@ xrealloc (obj, size) extern void *realloc (); void *result = realloc (obj, size); if (result == NULL) - fatal ("virtual memory exhausted", 0); + fatal (_("virtual memory exhausted"), 0); return result; } -/* Return a newly-allocated string whose contents concatenate those of s1, s2, s3. */ - +/* Return a newly-allocated string + whose contents concatenate those of S1, S2, S3. */ char * concat (s1, s2, s3) char *s1, *s2, *s3; @@ -185,7 +172,7 @@ copy_string (string, size) /* Error message functions. */ -/* Print error message. `s1' is printf control string, `s2' is arg for it. */ +/* Print error message. S1 is printf control string, S2 and S3 args for it. */ /* VARARGS1 */ void @@ -194,7 +181,7 @@ error (s1, s2, s3) { fprintf (stderr, "%s: ", progname); fprintf (stderr, s1, s2, s3); - fprintf (stderr, "\n"); + putc ('\n', stderr); } /* VARARGS1 */ @@ -202,9 +189,9 @@ void warning (s1, s2, s3) char *s1, *s2, *s3; { - fprintf (stderr, "%s: Warning: ", progname); + fprintf (stderr, _("%s: warning: "), progname); fprintf (stderr, s1, s2, s3); - fprintf (stderr, "\n"); + putc ('\n', stderr); } /* Print error message and exit. */ @@ -223,7 +210,7 @@ void pfatal_with_name (name) char *name; { - char *s = concat ("", strerror (errno), " for %s"); + char *s = concat ("", strerror (errno), _(" for %s")); fatal (s, name); } @@ -292,7 +279,7 @@ extract_menu_file_name (item_text) void suggest_asking_for_help () { - fprintf (stderr, "\tTry `%s --help' for a complete list of options.\n", + fprintf (stderr, _("\tTry `%s --help' for a complete list of options.\n"), progname); exit (1); } @@ -300,8 +287,9 @@ suggest_asking_for_help () void print_help () { - printf ("%s [OPTION]... [INFO-FILE [DIR-FILE]]\n\ - Install INFO-FILE in the Info directory file DIR-FILE.\n\ + printf (_("Usage: %s [OPTION]... [INFO-FILE [DIR-FILE]]\n\ +\n\ +Install INFO-FILE in the Info directory file DIR-FILE.\n\ \n\ Options:\n\ --delete Delete existing entries in INFO-FILE;\n\ @@ -334,33 +322,80 @@ Options:\n\ from information in the Info file itself.\n\ --version Display version information and exit.\n\ \n\ -Email bug reports to bug-texinfo@prep.ai.mit.edu.\n\ -", progname); +Email bug reports to bug-texinfo@gnu.org.\n\ +"), progname); } +/* If DIRFILE does not exist, create a minimal one (or abort). If it + already exists, do nothing. */ + +void +ensure_dirfile_exists (dirfile) + char *dirfile; +{ + int desc = open (dirfile, O_RDONLY); + if (desc < 0 && errno == ENOENT) + { + FILE *f; + char *readerr = strerror (errno); + close (desc); + f = fopen (dirfile, "w"); + if (f) + { + fputs (_("This is the file .../info/dir, which contains the\n\ +topmost node of the Info hierarchy, called (dir)Top.\n\ +The first time you invoke Info you start off looking at this node.\n\ +\n\ +File: dir,\tNode: Top,\tThis is the top of the INFO tree\n\ +\n\ + This (the Directory node) gives a menu of major topics.\n\ + Typing \"q\" exits, \"?\" lists all Info commands, \"d\" returns here,\n\ + \"h\" gives a primer for first-timers,\n\ + \"mEmacs<Return>\" visits the Emacs manual, etc.\n\ +\n\ + In Emacs, you can click mouse button 2 on a menu item or cross reference\n\ + to select it.\n\ +\n\ +* Menu:\n\ +"), f); + if (fclose (f) < 0) + pfatal_with_name (dirfile); + } + else + { + /* Didn't exist, but couldn't open for writing. */ + fprintf (stderr, + _("%s: could not read (%s) and could not create (%s)\n"), + dirfile, readerr, strerror (errno)); + exit (1); + } + } + else + close (desc); /* It already existed, so fine. */ +} + /* This table defines all the long-named options, says whether they use an argument, and maps them into equivalent single-letter options. */ struct option longopts[] = { - { "delete", no_argument, NULL, 'r' }, - { "defentry", required_argument, NULL, 'E' }, - { "defsection", required_argument, NULL, 'S' }, - { "dir-file", required_argument, NULL, 'd' }, - { "entry", required_argument, NULL, 'e' }, - { "forceentry", required_argument, NULL, 'f' }, - { "help", no_argument, NULL, 'h' }, - { "info-dir", required_argument, NULL, 'D' }, - { "info-file", required_argument, NULL, 'i' }, - { "item", required_argument, NULL, 'e' }, - { "quiet", no_argument, NULL, 'q' }, - { "remove", no_argument, NULL, 'r' }, - { "section", required_argument, NULL, 's' }, - { "version", no_argument, NULL, 'V' }, + { "delete", no_argument, NULL, 'r' }, + { "dir-file", required_argument, NULL, 'd' }, + { "entry", required_argument, NULL, 'e' }, + { "help", no_argument, NULL, 'h' }, + { "info-dir", required_argument, NULL, 'D' }, + { "info-file", required_argument, NULL, 'i' }, + { "item", required_argument, NULL, 'e' }, + { "quiet", no_argument, NULL, 'q' }, + { "remove", no_argument, NULL, 'r' }, + { "section", required_argument, NULL, 's' }, + { "version", no_argument, NULL, 'V' }, { 0 } }; + +int main (argc, argv) int argc; char **argv; @@ -407,6 +442,15 @@ main (argc, argv) progname = argv[0]; +#ifdef HAVE_SETLOCALE + /* Set locale via LC_ALL. */ + setlocale (LC_ALL, ""); +#endif + + /* Set the text message domain. */ + bindtextdomain (PACKAGE, LOCALEDIR); + textdomain (PACKAGE); + while (1) { int opt = getopt_long (argc, argv, "i:d:e:s:hHr", longopts, 0); @@ -427,7 +471,7 @@ main (argc, argv) case 'd': if (dirfile) { - fprintf (stderr, "%s: Specify the Info directory only once.\n", + fprintf (stderr, _("%s: Specify the Info directory only once.\n"), progname); suggest_asking_for_help (); } @@ -437,7 +481,7 @@ main (argc, argv) case 'D': if (dirfile) { - fprintf (stderr, "%s: Specify the Info directory only once.\n", + fprintf (stderr, _("%s: Specify the Info directory only once.\n"), progname); suggest_asking_for_help (); } @@ -476,7 +520,7 @@ main (argc, argv) case 'i': if (infile) { - fprintf (stderr, "%s: Specify the Info file only once.\n", + fprintf (stderr, _("%s: Specify the Info file only once.\n"), progname); suggest_asking_for_help (); } @@ -507,12 +551,13 @@ main (argc, argv) break; case 'V': - puts (INSTALL_INFO_VERSION_STRING); -puts ("Copyright (C) 1996 Free Software Foundation, Inc.\n\ + printf ("install-info (GNU %s) %s\n", PACKAGE, VERSION); + printf (_("Copyright (C) %s Free Software Foundation, Inc.\n\ There is NO warranty. You may redistribute this software\n\ under the terms of the GNU General Public License.\n\ -For more information about these matters, see the files named COPYING."); - exit (0); +For more information about these matters, see the files named COPYING.\n"), + "1998"); + exit (0); default: suggest_asking_for_help (); @@ -530,13 +575,13 @@ For more information about these matters, see the files named COPYING."); else if (dirfile == 0) dirfile = argv[optind]; else - error ("excess command line argument `%s'", argv[optind]); + error (_("excess command line argument `%s'"), argv[optind]); } if (!infile) - fatal ("No input file specified"); + fatal (_("No input file specified; try --help for more information.")); if (!dirfile) - fatal ("No dir file specified"); + fatal (_("No dir file specified; try --help for more information.")); /* Read the Info file and parse it into lines. */ @@ -595,7 +640,7 @@ For more information about these matters, see the files named COPYING."); && sizeof ("START-INFO-DIR-ENTRY") - 1 == input_lines[i].size) { if (start_of_this_entry != 0) - fatal ("START-INFO-DIR-ENTRY without matching END-INFO-DIR-ENTRY"); + fatal (_("START-INFO-DIR-ENTRY without matching END-INFO-DIR-ENTRY")); start_of_this_entry = input_lines[i + 1].start; } if (!strncmp ("END-INFO-DIR-ENTRY", input_lines[i].start, @@ -621,18 +666,26 @@ For more information about these matters, see the files named COPYING."); start_of_this_entry = 0; } else - fatal ("END-INFO-DIR-ENTRY without matching START-INFO-DIR-ENTRY"); + fatal (_("END-INFO-DIR-ENTRY without matching START-INFO-DIR-ENTRY")); } } if (start_of_this_entry != 0) - fatal ("START-INFO-DIR-ENTRY without matching END-INFO-DIR-ENTRY"); + fatal (_("START-INFO-DIR-ENTRY without matching END-INFO-DIR-ENTRY")); } if (!delete_flag) if (entries_to_add == 0) - fatal ("no info dir entry in `%s'", infile); + { /* No need to abort here, the original info file may not have + the requisite Texinfo commands. This is not something an + installer should have to correct (it's a problem for the + maintainer), and there's no need to cause subsequent parts of + `make install' to fail. */ + warning (_("no info dir entry in `%s'"), infile); + exit (0); + } /* Now read in the Info dir file. */ + ensure_dirfile_exists (dirfile); dir_data = readfile (dirfile, &dir_size); dir_lines = findlines (dir_data, dir_size, &dir_nlines); @@ -641,7 +694,6 @@ For more information about these matters, see the files named COPYING."); .info suffix. */ { unsigned basename_len; - extern char *strrchr (); char *infile_basename = strrchr (infile, '/'); if (infile_basename) infile_basename++; @@ -761,10 +813,13 @@ For more information about these matters, see the files named COPYING."); p++; if ((dir_lines[i].size > (p - dir_lines[i].start + infilelen_sans_info)) - && !strncmp(p, infile_sans_info, infilelen_sans_info) - && ( p[infilelen_sans_info] == ')' || - strncmp (p + infilelen_sans_info, ".info)", 6) == 0)) - dir_lines[i].delete = 1; + && !strncmp (p, infile_sans_info, infilelen_sans_info) + && (p[infilelen_sans_info] == ')' + || !strncmp (p + infilelen_sans_info, ".info)", 6))) + { + dir_lines[i].delete = 1; + something_deleted = 1; + } } } /* Treat lines that start with whitespace @@ -836,7 +891,7 @@ For more information about these matters, see the files named COPYING."); dir_lines[i].start, dir_lines[i].size) && !dir_lines[i].delete) - fatal ("menu item `%s' already exists, for file `%s'", + fatal (_("menu item `%s' already exists, for file `%s'"), extract_menu_item_name (entry->text), extract_menu_file_name (dir_lines[i].start)); if (dir_lines[i].start[0] == '*' @@ -859,7 +914,7 @@ For more information about these matters, see the files named COPYING."); } if (delete_flag && !something_deleted && !quiet_flag) - warning ("no entries found for `%s'; nothing deleted", infile); + warning (_("no entries found for `%s'; nothing deleted"), infile); /* Output the old dir file, interpolating the new sections and/or new entries where appropriate. */ @@ -951,19 +1006,49 @@ readfile (filename, sizep) char *filename; int *sizep; { + int desc; int data_size = 1024; char *data = (char *) xmalloc (data_size); int filled = 0; int nread = 0; +#ifdef HAVE_LIBZ + int isGZ = 0; + gzFile zdesc; +#endif - int desc = open (filename, O_RDONLY); - + desc = open (filename, O_RDONLY); if (desc < 0) pfatal_with_name (filename); +#ifdef HAVE_LIBZ + /* The file should always be two bytes long. */ + if (read (desc, data, 2) != 2) + pfatal_with_name (filename); + + /* Undo that read. */ + lseek (desc, 0, SEEK_SET); + + /* If we see gzip magic, use gzdopen. */ + if (data[0] == '\x1f' && data[1] == '\x8b') + { + isGZ = 1; + zdesc = gzdopen (desc, "r"); + if (zdesc == NULL) { + close (desc); + pfatal_with_name (filename); + } + } +#endif /* HAVE_LIBZ */ + while (1) { - nread = read (desc, data + filled, data_size - filled); +#ifdef HAVE_LIBZ + if (isGZ) + nread = gzread (zdesc, data + filled, data_size - filled); + else +#endif + nread = read (desc, data + filled, data_size - filled); + if (nread < 0) pfatal_with_name (filename); if (nread == 0) @@ -978,6 +1063,14 @@ readfile (filename, sizep) } *sizep = filled; + +#ifdef HAVE_LIBZ + if (isGZ) + gzclose (zdesc); + else +#endif + close(desc); + return data; } |