1 /*
2 * $Id: args.c,v 1.6 2000/08/10 21:02:49 danny Exp $
3 *
4 * Copyright � 1993, 1999 Free Software Foundation, Inc.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2, or (at your option)
9 * any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this software; see the file COPYING. If not, write to
18 * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20
21 #ifdef HAVE_CONFIG_H
22 #include "config.h"
23 #endif
24
25 #ifdef WITH_DMALLOC
26 #include <dmalloc.h>
27 #endif
28
29 #include <ctype.h>
30 #include "global.h"
31 #define DEFINE_STYLES 1
32 #include "args.h"
33 #include "cmd.h"
34 #include "io-abstract.h"
35 #include "io-generic.h"
36 #include "io-edit.h"
37 #include "io-utils.h"
38 #include "format.h"
39
40
41
42 /* These commands define the syntax and editting modes of command arguments.
43 * Each _verify function parses some kind of argument and stores its value
44 * in a command_arg structure. An error message or NULL is returned.
45 * If the match succeeds, a string pointer is advanced to the end of what was
46 * parsed.
47 *
48 * Several arguments may be listed on one line separated only by
49 * whitespace. A _verify function should stop after its argument and ignore
50 * everything after that.
51 */
52
53 char *
char_verify(char ** end,struct command_arg * arg)54 char_verify (char ** end, struct command_arg * arg)
55 {
56 if (!**end)
57 return "No character specified";
58 else
59 {
60 int ch = string_to_char (end);
61 if (ch < 0)
62 {
63 setn_edit_line ("", 0);
64 return "Illegal character constant.";
65 }
66 else
67 {
68 arg->val.integer = ch;
69 return 0;
70 }
71 }
72 }
73
74 char *
symbol_verify(char ** end,struct command_arg * arg)75 symbol_verify (char ** end, struct command_arg * arg)
76 {
77 char * e = *end;
78 char * start = *end;
79 if (isalpha (*e) || (*e == '-') || (*e == '_') || (*e == (Global->a0 ? '$' : ':')))
80 {
81 while (isalpha(*e) || isdigit(*e) || (*e == '-') || (*e == '_')
82 || (*e == (Global->a0 ? '$' : ':')))
83 ++e;
84 if (!isspace(*e) && *e)
85 goto bad_symbol;
86 *end = e;
87 arg->val.string = (char *)ck_malloc (e - start + 1);
88 if (e - start)
89 bcopy (start, arg->val.string, e - start);
90 arg->val.string[e - start] = '\0';
91 return 0;
92 }
93 bad_symbol:
94 if (arg->arg_desc[1] == '\'')
95 {
96 arg->val.string = 0;
97 return 0;
98 }
99 else
100 return "Invalid symbol name.";
101 }
102
103 char *
word_verify(end,arg)104 word_verify (end, arg)
105 char ** end;
106 struct command_arg * arg;
107 {
108 char * e = *end;
109 char * start = *end;
110 if (!isspace (*e))
111 {
112 while (*e && !isspace(*e))
113 ++e;
114 *end = e;
115 arg->val.string = (char *)ck_malloc (e - start + 1);
116 if (e - start)
117 bcopy (start, arg->val.string, e - start);
118 arg->val.string[e - start] = '\0';
119 return 0;
120 }
121 else if (arg->arg_desc[1] == '\'')
122 {
123 arg->val.string = 0;
124 return 0;
125 }
126 else
127 return "Invalid symbol name.";
128 }
129
130 void
symbol_destroy(struct command_arg * arg)131 symbol_destroy (struct command_arg * arg)
132 {
133 if (arg->val.string)
134 ck_free (arg->val.string);
135 }
136
137 char *
command_verify(char ** end,struct command_arg * arg)138 command_verify (char ** end, struct command_arg * arg)
139 {
140 char * error = symbol_verify (end, arg);
141 char * str;
142 if (error)
143 return error;
144 str = arg->val.string;
145 if (!(find_function (0, 0, arg->val.string, strlen(arg->val.string))
146 && get_abs_rng (&str, 0)))
147 return 0;
148 else
149 return "Not a command or macro address.";
150 }
151
152 char *
read_file_verify(char ** end,struct command_arg * arg)153 read_file_verify (char ** end, struct command_arg * arg)
154 {
155 FILE * fp = xopen_with_backup (arg->text.buf, "r");
156 *end = 0;
157 if (!fp)
158 {
159 io_error_msg ("Can't open file '%s':%s", arg->text.buf, err_msg ());
160 return "";
161 }
162 else
163 {
164 arg->val.fp = fp;
165 return 0;
166 }
167 }
168
169 void
read_file_destroy(struct command_arg * arg)170 read_file_destroy (struct command_arg * arg)
171 {
172 int num;
173 num = xclose (arg->val.fp);
174 if (num)
175 io_error_msg ("Can't close '%s': Error code %d: %s",
176 arg->text.buf, num, err_msg ());
177 }
178
179
180 char *
write_file_verify(char ** end,struct command_arg * arg)181 write_file_verify (char ** end, struct command_arg * arg)
182 {
183 FILE * fp = xopen_with_backup (arg->text.buf, "w");
184 *end = 0;
185 if (!fp)
186 {
187 io_error_msg ("Can't open file '%s':%s", arg->text.buf, err_msg ());
188 return "";
189 }
190 else
191 {
192 arg->val.fp = fp;
193 return 0;
194 }
195 }
196
197 void
write_file_destroy(struct command_arg * arg)198 write_file_destroy (struct command_arg * arg)
199 {
200 int num;
201
202 num = xclose (arg->val.fp);
203 if (num)
204 io_error_msg ("Can't close '%s': Error code %d: %s",
205 arg->text.buf, num, err_msg ());
206 }
207
208 /* As a special case, cmd_loop makes sure that keyseq arguments are only read
209 * interactively.
210 */
211
212 char *
keyseq_verify(char ** end,struct command_arg * arg)213 keyseq_verify (char ** end, struct command_arg * arg)
214 {
215 *end = 0;
216 return 0;
217 }
218
219
220 char *
keymap_verify(char ** end,struct command_arg * arg)221 keymap_verify (char ** end, struct command_arg * arg)
222 {
223 char * start = *end;
224 char * error = symbol_verify (end, arg);
225 int id;
226 if (error)
227 return error;
228 id = map_idn (start, *end - start);
229 return (id >= 0
230 ? (char *) 0
231 : "No such keymap.");
232 }
233
234
235 char *
number_verify(char ** end,struct command_arg * arg)236 number_verify (char ** end, struct command_arg * arg)
237 {
238 char * e = *end;
239
240 while (*e && isspace (*e))
241 ++e;
242 if (isdigit(*e) || (*e == '-'))
243 {
244 arg->val.integer = astol (end);
245 if (arg->arg_desc[1] == '[')
246 {
247 char * prompt = arg->arg_desc + 2;
248 {
249 long low = 0;
250 long high = -1;
251 low = astol (&prompt);
252 while (*prompt && isspace (*prompt)) ++prompt;
253 if (*prompt == ',') ++prompt;
254 high = astol (&prompt);
255 while (*prompt && isspace (*prompt)) ++prompt;
256 if (*prompt == ']') ++prompt;
257 if ( (low > arg->val.integer)
258 || (high < arg->val.integer))
259 io_error_msg ("Out of range %d (should be in [%d - %d]).",
260 arg->val.integer, low, high); /* no return */
261 }
262 }
263 return 0;
264 }
265 else
266 return "Not a number.";
267 }
268
269
270 char *
double_verify(char ** end,struct command_arg * arg)271 double_verify (char ** end, struct command_arg * arg)
272 {
273 char * e = *end;
274
275 while (*e && isspace (*e))
276 ++e;
277 if (isdigit(*e) || ((*e == '-') && isdigit (*(e + 1))))
278 {
279 arg->val.floating = astof (end);
280 return 0;
281 }
282 else
283 return "Not a number.";
284 }
285
286
287 char *
range_verify(char ** end,struct command_arg * arg)288 range_verify (char ** end, struct command_arg * arg)
289 {
290 union command_arg_val * val = &arg->val;
291 *end = arg->text.buf;
292 if (get_abs_rng (end, &val->range))
293 return "Not a range.";
294 else
295 return 0;
296 }
297
298 char *
string_verify(char ** end,struct command_arg * arg)299 string_verify (char ** end, struct command_arg * arg)
300 {
301 arg->val.string = arg->text.buf;
302 *end = 0;
303 return 0;
304 }
305
306 /* Unlike most verify functions, this
307 * one may destroy the command frame that it is
308 * operating on. It's purpose is to allow user's
309 * to abort commands.
310 */
311 char *
yes_verify(char ** end,struct command_arg * arg)312 yes_verify (char ** end, struct command_arg * arg)
313 {
314 if (words_imatch (end, "no"))
315 {
316 pop_unfinished_command ();
317 return "Aborted.";
318 }
319 else if (words_imatch (end, "yes"))
320 return 0;
321 else
322 {
323 setn_edit_line ("", 0);
324 return "Please answer yes or no.";
325 }
326 }
327
328 char *
incremental_cmd_verify(char ** end,struct command_arg * arg)329 incremental_cmd_verify (char ** end, struct command_arg * arg)
330 {
331 return 0;
332 }
333
334
335 char *
menu_verify(char ** end,struct command_arg * arg)336 menu_verify (char ** end, struct command_arg * arg)
337 {
338 char * error = char_verify (end, arg);
339 if (error)
340 return error;
341
342 {
343 int pick = arg->val.integer;
344 char * key = arg->arg_desc + 1;
345 while (*key && (*key != ']'))
346 {
347 if (*key == '\\')
348 {
349 ++key;
350 if (!*key)
351 break;
352 }
353 if (pick == *key)
354 return 0;
355 else
356 ++key;
357 }
358 setn_edit_line ("", 0);
359 return "No such menu option.";
360 }
361 }
362
363
364 char *
format_verify(char ** end,struct command_arg * arg)365 format_verify (char ** end, struct command_arg * arg)
366 {
367 arg->val.integer = str_to_fmt (*end);
368 if (arg->val.integer < 0)
369 return "Unknown format.";
370 *end = 0;
371 return 0;
372 }
373
374
375 char *
noop_verify(char ** end,struct command_arg * arg)376 noop_verify (char ** end, struct command_arg * arg)
377 {
378 return 0;
379 }
380