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