Imported from ../bash-2.01.1.tar.gz.
[platform/upstream/bash.git] / builtins / read.def
1 This file is read.def, from which is created read.c.
2 It implements the builtin "read" in Bash.
3
4 Copyright (C) 1987, 1989, 1991 Free Software Foundation, Inc.
5
6 This file is part of GNU Bash, the Bourne Again SHell.
7
8 Bash is free software; you can redistribute it and/or modify it under
9 the terms of the GNU General Public License as published by the Free
10 Software Foundation; either version 1, or (at your option) any later
11 version.
12
13 Bash is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
16 for more details.
17
18 You should have received a copy of the GNU General Public License along
19 with Bash; see the file COPYING.  If not, write to the Free Software
20 Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
21
22 $PRODUCES read.c
23
24 $BUILTIN read
25 $FUNCTION read_builtin
26 $SHORT_DOC read [-r] [-p prompt] [-a array] [-e] [name ...]
27 One line is read from the standard input, and the first word is
28 assigned to the first NAME, the second word to the second NAME, and so
29 on, with leftover words assigned to the last NAME.  Only the characters
30 found in $IFS are recognized as word delimiters.  The return code is
31 zero, unless end-of-file is encountered.  If no NAMEs are supplied, the
32 line read is stored in the REPLY variable.  If the -r option is given,
33 this signifies `raw' input, and backslash escaping is disabled.  If
34 the `-p' option is supplied, the string supplied as an argument is
35 output without a trailing newline before attempting to read.  If -a is
36 supplied, the words read are assigned to sequential indices of ARRAY,
37 starting at zero.  If -e is supplied and the shell is interactive,
38 readline is used to obtain the line.
39 $END
40
41 #include <config.h>
42
43 #include <stdio.h>
44
45 #if defined (HAVE_UNISTD_H)
46 #  include <unistd.h>
47 #endif
48
49 #include <errno.h>
50
51 #include "../shell.h"
52 #include "common.h"
53 #include "bashgetopt.h"
54
55 #if defined (READLINE)
56 #include "../bashline.h"
57 #include <readline/readline.h>
58 #endif
59
60 #if !defined(errno)
61 extern int errno;
62 #endif
63
64 #define issep(c)        (strchr (ifs_chars, (c)))
65
66 extern int interrupt_immediately;
67
68 #if defined (READLINE)
69 static char *edit_line ();
70 #endif
71 static SHELL_VAR *bind_read_variable ();
72
73 /* Read the value of the shell variables whose names follow.
74    The reading is done from the current input stream, whatever
75    that may be.  Successive words of the input line are assigned
76    to the variables mentioned in LIST.  The last variable in LIST
77    gets the remainder of the words on the line.  If no variables
78    are mentioned in LIST, then the default variable is $REPLY. */
79 int
80 read_builtin (list)
81      WORD_LIST *list;
82 {
83   register char *varname;
84   int size, i, raw, pass_next, saw_escape, eof, opt, retval, edit;
85   char c;
86   char *input_string, *orig_input_string, *ifs_chars, *prompt, *arrayname;
87   char *e, *t, *t1;
88   SHELL_VAR *var;
89 #if defined (ARRAY_VARS)
90   WORD_LIST *alist;
91 #endif
92 #if defined (READLINE)
93   char *rlbuf;
94   int rlind;
95 #endif
96
97   i = 0;                /* Index into the string that we are reading. */
98   raw = edit = 0;       /* Not reading raw input by default. */
99   arrayname = prompt = (char *)NULL;
100
101 #if defined (READLINE)
102   rlbuf = (char *)0;
103   rlind = 0;
104 #endif
105
106   reset_internal_getopt ();
107   while ((opt = internal_getopt (list, "erp:a:")) != -1)
108     {
109       switch (opt)
110         {
111         case 'r':
112           raw = 1;
113           break;
114         case 'p':
115           prompt = list_optarg;
116           break;
117         case 'e':
118 #if defined (READLINE)
119           edit = 1;
120 #endif
121           break;
122 #if defined (ARRAY_VARS)
123         case 'a':
124           arrayname = list_optarg;
125           break;
126 #endif
127         default:
128           builtin_usage ();
129           return (EX_USAGE);
130         }
131     }
132   list = loptend;
133
134   /* IF IFS is unset, we use the default of " \t\n". */
135   var = find_variable ("IFS");
136   ifs_chars = var ? value_cell (var) : " \t\n";
137   if (ifs_chars == 0)           /* XXX */
138     ifs_chars = "";             /* XXX */
139
140   input_string = xmalloc (size = 128);
141
142   begin_unwind_frame ("read_builtin");
143   add_unwind_protect (xfree, input_string);
144 #if defined (READLINE)
145   add_unwind_protect (xfree, rlbuf);
146 #endif
147   interrupt_immediately++;
148
149   /* If the -p or -e flags were given, but input is not coming from the
150      terminal, turn them off. */
151   if ((prompt || edit) && (isatty (0) == 0))
152     {
153       prompt = (char *)NULL;
154       edit = 0;
155     }
156
157   if (prompt && edit == 0)
158     {
159       fprintf (stderr, "%s", prompt);
160       fflush (stderr);
161     }
162
163   pass_next = 0;        /* Non-zero signifies last char was backslash. */
164   saw_escape = 0;       /* Non-zero signifies that we saw an escape char */
165
166   for (eof = 0;;)
167     {
168 #if defined (READLINE)
169       if (edit)
170         {
171           if (rlbuf && rlbuf[rlind] == '\0')
172             {
173               xfree (rlbuf);
174               rlbuf = (char *)0;
175             }
176           if (rlbuf == 0)
177             {
178               rlbuf = edit_line (prompt ? prompt : "");
179               rlind = 0;
180             }
181           if (rlbuf == 0)
182             {
183               eof = 1;
184               break;
185             }
186           c = rlbuf[rlind++];
187         }
188       else
189 #endif
190
191       while (((retval = read (0, &c, 1)) < 0) && errno == EINTR)
192         ;
193       if (retval <= 0)
194         {
195           eof = 1;
196           break;
197         }
198
199       if (i + 2 >= size)
200         input_string = xrealloc (input_string, size += 128);
201
202       /* If the next character is to be accepted verbatim, a backslash
203          newline pair still disappears from the input. */
204       if (pass_next)
205         {
206           if (c == '\n')
207             i--;                /* back up over the CTLESC */
208           else
209             input_string[i++] = c;
210           pass_next = 0;
211           continue;
212         }
213
214       if (c == '\\' && raw == 0)
215         {
216           pass_next++;
217           saw_escape++;
218           input_string[i++] = CTLESC;
219           continue;
220         }
221
222       if (c == '\n')
223         break;
224
225       if (c == CTLESC || c == CTLNUL)
226         {
227           saw_escape++;
228           input_string[i++] = CTLESC;
229         }
230
231       input_string[i++] = c;
232     }
233   input_string[i] = '\0';
234
235   interrupt_immediately--;
236   discard_unwind_frame ("read_builtin");
237
238   retval = eof ? EXECUTION_FAILURE : EXECUTION_SUCCESS;
239
240 #if defined (ARRAY_VARS)
241   /* If -a was given, take the string read, break it into a list of words,
242      an assign them to `arrayname' in turn. */
243   if (arrayname)
244     {
245       var = find_variable (arrayname);
246       if (var == 0)
247         var = make_new_array_variable (arrayname);
248       else if (array_p (var) == 0)
249         var = convert_var_to_array (var);
250
251       empty_array (array_cell (var));
252
253       alist = list_string (input_string, ifs_chars, 0);
254       if (alist)
255         {
256           assign_array_var_from_word_list (var, alist);
257           dispose_words (alist);
258         }
259       xfree (input_string);
260       return (retval);
261     }
262 #endif /* ARRAY_VARS */ 
263
264   /* If there are no variables, save the text of the line read to the
265      variable $REPLY.  ksh93 strips leading and trailing IFS whitespace,
266      so that `read x ; echo "$x"' and `read ; echo "$REPLY"' behave the
267      same way, but I believe that the difference in behaviors is useful
268      enough to not do it.  Without the bash behavior, there is no way
269      to read a line completely without interpretation or modification.
270      If you disagree, change the occurrences of `#if 0' to `#if 1' below. */
271   if (list == 0)
272     {
273 #if 0
274       orig_input_string = input_string;
275       for (t = input_string; ifs_chars && *ifs_chars && spctabnl(*t) && issep(*t); t++)
276         ;
277       input_string = t;
278       input_string = strip_trailing_ifs_whitespace (input_string, ifs_chars, saw_escape);
279 #endif
280
281       if (saw_escape)
282         {
283           t = dequote_string (input_string);
284           var = bind_variable ("REPLY", t);
285           free (t);
286         }
287       else
288         var = bind_variable ("REPLY", input_string);
289       var->attributes &= ~att_invisible;
290 #if 0
291       free (orig_input_string);
292 #else
293       free (input_string);
294 #endif
295       return (retval);
296     }
297
298   /* This code implements the Posix.2 spec for splitting the words
299      read and assigning them to variables. */
300   orig_input_string = input_string;
301
302   /* Remove IFS white space at the beginning of the input string.  If
303      $IFS is null, no field splitting is performed. */
304   for (t = input_string; ifs_chars && *ifs_chars && spctabnl(*t) && issep(*t); t++)
305     ;
306   input_string = t;
307
308   for (; list->next; list = list->next)
309     {
310       varname = list->word->word;
311 #if defined (ARRAY_VARS)
312       if (legal_identifier (varname) == 0 && valid_array_reference (varname) == 0)
313 #else
314       if (legal_identifier (varname) == 0)
315 #endif
316         {
317           builtin_error ("`%s': not a valid identifier", varname);
318           free (orig_input_string);
319           return (EXECUTION_FAILURE);
320         }
321
322       /* If there are more variables than words read from the input,
323          the remaining variables are set to the empty string. */
324       if (*input_string)
325         {
326           /* This call updates INPUT_STRING. */
327           t = get_word_from_string (&input_string, ifs_chars, &e);
328           if (t)
329             *e = '\0';
330           /* Don't bother to remove the CTLESC unless we added one
331              somewhere while reading the string. */
332           if (t && saw_escape)
333             {
334               t1 = dequote_string (t);
335               var = bind_read_variable (varname, t1);
336               free (t1);
337             }
338           else
339             var = bind_read_variable (varname, t);
340         }
341       else
342         {
343           t = (char *)0;
344           var = bind_read_variable (varname, "");
345         }
346
347       FREE (t);
348       if (var == 0)
349         {
350           free (orig_input_string);
351           return (EXECUTION_FAILURE);
352         }
353
354       stupidly_hack_special_variables (varname);
355       var->attributes &= ~att_invisible;
356     }
357
358   /* Now assign the rest of the line to the last variable argument. */
359 #if defined (ARRAY_VARS)
360   if (legal_identifier (list->word->word) == 0 && valid_array_reference (list->word->word) == 0)
361 #else
362   if (legal_identifier (list->word->word) == 0)
363 #endif
364     {
365       builtin_error ("`%s': not a valid identifier", list->word->word);
366       free (orig_input_string);
367       return (EXECUTION_FAILURE);
368     }
369
370   /* This has to be done this way rather than using string_list
371      and list_string because Posix.2 says that the last variable gets the
372      remaining words and their intervening separators. */
373   input_string = strip_trailing_ifs_whitespace (input_string, ifs_chars, saw_escape);
374
375   if (saw_escape)
376     {
377       t = dequote_string (input_string);
378       var = bind_read_variable (list->word->word, t);
379       free (t);
380     }
381   else
382     var = bind_read_variable (list->word->word, input_string);
383   stupidly_hack_special_variables (list->word->word);
384   if (var)
385     var->attributes &= ~att_invisible;
386   free (orig_input_string);
387
388   return (retval);
389 }
390
391 static SHELL_VAR *
392 bind_read_variable (name, value)
393      char *name, *value;
394 {
395 #if defined (ARRAY_VARS)
396   if (valid_array_reference (name) == 0)
397     {
398       if (legal_identifier (name) == 0)
399         {
400           builtin_error ("`%s': not a valid identifier", name);
401           return ((SHELL_VAR *)NULL);
402         }
403       return (bind_variable (name, value));
404     }
405   else
406     return (do_array_element_assignment (name, value));
407 #else
408   return bind_variable (name, value);
409 #endif
410 }
411
412 #if defined (READLINE)
413 static char *
414 edit_line (p)
415      char *p;
416 {
417   char *ret;
418   int len;
419
420   if (!bash_readline_initialized)
421     initialize_readline ();
422   ret = readline (p);
423   if (ret == 0)
424     return ret;
425   len = strlen (ret);
426   ret = xrealloc (ret, len + 2);
427   ret[len++] = '\n';
428   ret[len] = '\0';
429   return ret;
430 }
431 #endif