xref: /openbsd/gnu/usr.bin/texinfo/info/variables.c (revision 78b63d65)
1 /* variables.c -- How to manipulate user visible variables in Info.
2    $Id: variables.c,v 1.3 2000/02/09 02:18:40 espie Exp $
3 
4    This file is part of GNU Info, a program for reading online documentation
5    stored in Info format.
6 
7    Copyright (C) 1993, 97 Free Software Foundation, Inc.
8 
9    This program is free software; you can redistribute it and/or modify
10    it under the terms of the GNU General Public License as published by
11    the Free Software Foundation; either version 2, or (at your option)
12    any later version.
13 
14    This program is distributed in the hope that it will be useful,
15    but WITHOUT ANY WARRANTY; without even the implied warranty of
16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17    GNU General Public License for more details.
18 
19    You should have received a copy of the GNU General Public License
20    along with this program; if not, write to the Free Software
21    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 
23    Written by Brian Fox (bfox@ai.mit.edu). */
24 
25 #include "info.h"
26 #include "variables.h"
27 
28 /* **************************************************************** */
29 /*                                                                  */
30 /*                  User Visible Variables in Info                  */
31 /*                                                                  */
32 /* **************************************************************** */
33 
34 /* Choices used by the completer when reading a zero/non-zero value for
35    a variable. */
36 static char *on_off_choices[] = { "Off", "On", (char *)NULL };
37 
38 VARIABLE_ALIST info_variables[] = {
39   { "automatic-footnotes",
40       N_("When \"On\", footnotes appear and disappear automatically"),
41       &auto_footnotes_p, (char **)on_off_choices },
42 
43   { "automatic-tiling",
44       N_("When \"On\", creating or deleting a window resizes other windows"),
45       &auto_tiling_p, (char **)on_off_choices },
46 
47   { "visible-bell",
48       N_("When \"On\", flash the screen instead of ringing the bell"),
49       &terminal_use_visible_bell_p, (char **)on_off_choices },
50 
51   { "errors-ring-bell",
52       N_("When \"On\", errors cause the bell to ring"),
53       &info_error_rings_bell_p, (char **)on_off_choices },
54 
55   { "gc-compressed-files",
56       N_("When \"On\", Info garbage collects files which had to be uncompressed"),
57       &gc_compressed_files, (char **)on_off_choices },
58   { "show-index-match",
59       N_("When \"On\", the portion of the matched search string is highlighted"),
60       &show_index_match, (char **)on_off_choices },
61 
62   { "scroll-behaviour",
63       N_("Controls what happens when scrolling is requested at the end of a node"),
64       &info_scroll_behaviour, (char **)info_scroll_choices },
65 
66   { "scroll-step",
67       N_("The number lines to scroll when the cursor moves out of the window"),
68       &window_scroll_step, (char **)NULL },
69 
70   { "ISO-Latin",
71       N_("When \"On\", Info accepts and displays ISO Latin characters"),
72       &ISO_Latin_p, (char **)on_off_choices },
73 
74   { (char *)NULL, (char *)NULL, (int *)NULL, (char **)NULL }
75 };
76 
77 DECLARE_INFO_COMMAND (describe_variable, _("Explain the use of a variable"))
78 {
79   VARIABLE_ALIST *var;
80   char *description;
81 
82   /* Get the variable's name. */
83   var = read_variable_name (_("Describe variable: "), window);
84 
85   if (!var)
86     return;
87 
88   description = (char *)xmalloc (20 + strlen (var->name)
89 				 + strlen (_(var->doc)));
90 
91   if (var->choices)
92     sprintf (description, "%s (%s): %s.",
93              var->name, var->choices[*(var->value)], _(var->doc));
94   else
95     sprintf (description, "%s (%d): %s.",
96 	     var->name, *(var->value), _(var->doc));
97 
98   window_message_in_echo_area ("%s", description);
99   free (description);
100 }
101 
102 DECLARE_INFO_COMMAND (set_variable, _("Set the value of an Info variable"))
103 {
104   VARIABLE_ALIST *var;
105   char *line;
106 
107   /* Get the variable's name and value. */
108   var = read_variable_name (_("Set variable: "), window);
109 
110   if (!var)
111     return;
112 
113   /* Read a new value for this variable. */
114   {
115     char prompt[100];
116 
117     if (!var->choices)
118       {
119         int potential_value;
120 
121         if (info_explicit_arg || count != 1)
122           potential_value = count;
123         else
124           potential_value = *(var->value);
125 
126         sprintf (prompt, _("Set %s to value (%d): "),
127                  var->name, potential_value);
128         line = info_read_in_echo_area (active_window, prompt);
129 
130         /* If no error was printed, clear the echo area. */
131         if (!info_error_was_printed)
132           window_clear_echo_area ();
133 
134         /* User aborted? */
135         if (!line)
136           return;
137 
138         /* If the user specified a value, get that, otherwise, we are done. */
139         canonicalize_whitespace (line);
140         if (*line)
141           *(var->value) = atoi (line);
142         else
143           *(var->value) = potential_value;
144 
145         free (line);
146       }
147     else
148       {
149         register int i;
150         REFERENCE **array = (REFERENCE **)NULL;
151         int array_index = 0;
152         int array_slots = 0;
153 
154         for (i = 0; var->choices[i]; i++)
155           {
156             REFERENCE *entry;
157 
158             entry = (REFERENCE *)xmalloc (sizeof (REFERENCE));
159             entry->label = xstrdup (var->choices[i]);
160             entry->nodename = (char *)NULL;
161             entry->filename = (char *)NULL;
162 
163             add_pointer_to_array
164               (entry, array_index, array, array_slots, 10, REFERENCE *);
165           }
166 
167         sprintf (prompt, _("Set %s to value (%s): "),
168                  var->name, var->choices[*(var->value)]);
169 
170         /* Ask the completer to read a variable value for us. */
171         line = info_read_completing_in_echo_area (window, prompt, array);
172 
173         info_free_references (array);
174 
175         if (!echo_area_is_active)
176           window_clear_echo_area ();
177 
178         /* User aborted? */
179         if (!line)
180           {
181             info_abort_key (active_window, 0, 0);
182             return;
183           }
184 
185         /* User accepted default choice?  If so, no change. */
186         if (!*line)
187           {
188             free (line);
189             return;
190           }
191 
192         /* Find the choice in our list of choices. */
193         for (i = 0; var->choices[i]; i++)
194           if (strcmp (var->choices[i], line) == 0)
195             break;
196 
197         if (var->choices[i])
198           *(var->value) = i;
199       }
200   }
201 }
202 
203 /* Read the name of an Info variable in the echo area and return the
204    address of a VARIABLE_ALIST member.  A return value of NULL indicates
205    that no variable could be read. */
206 VARIABLE_ALIST *
207 read_variable_name (prompt, window)
208      char *prompt;
209      WINDOW *window;
210 {
211   register int i;
212   char *line;
213   REFERENCE **variables;
214 
215   /* Get the completion array of variable names. */
216   variables = make_variable_completions_array ();
217 
218   /* Ask the completer to read a variable for us. */
219   line =
220     info_read_completing_in_echo_area (window, prompt, variables);
221 
222   info_free_references (variables);
223 
224   if (!echo_area_is_active)
225     window_clear_echo_area ();
226 
227   /* User aborted? */
228   if (!line)
229     {
230       info_abort_key (active_window, 0, 0);
231       return ((VARIABLE_ALIST *)NULL);
232     }
233 
234   /* User accepted "default"?  (There is none.) */
235   if (!*line)
236     {
237       free (line);
238       return ((VARIABLE_ALIST *)NULL);
239     }
240 
241   /* Find the variable in our list of variables. */
242   for (i = 0; info_variables[i].name; i++)
243     if (strcmp (info_variables[i].name, line) == 0)
244       break;
245 
246   if (!info_variables[i].name)
247     return ((VARIABLE_ALIST *)NULL);
248   else
249     return (&(info_variables[i]));
250 }
251 
252 /* Make an array of REFERENCE which actually contains the names of the
253    variables available in Info. */
254 REFERENCE **
255 make_variable_completions_array ()
256 {
257   register int i;
258   REFERENCE **array = (REFERENCE **)NULL;
259   int array_index = 0, array_slots = 0;
260 
261   for (i = 0; info_variables[i].name; i++)
262     {
263       REFERENCE *entry;
264 
265       entry = (REFERENCE *) xmalloc (sizeof (REFERENCE));
266       entry->label = xstrdup (info_variables[i].name);
267       entry->nodename = (char *)NULL;
268       entry->filename = (char *)NULL;
269 
270       add_pointer_to_array
271         (entry, array_index, array, array_slots, 200, REFERENCE *);
272     }
273 
274   return (array);
275 }
276