64a4a11a4a4723feaec3d89a98be2d45812f9162
[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 "../shell.h"
50 #include "common.h"
51 #include "bashgetopt.h"
52
53 #if defined (READLINE)
54 #include "../bashline.h"
55 #include <readline/readline.h>
56 #endif
57
58 #define issep(c)        (strchr (ifs_chars, (c)))
59
60 extern int interrupt_immediately;
61
62 #if defined (READLINE)
63 static char *edit_line ();
64 #endif
65 static SHELL_VAR *bind_read_variable ();
66
67 /* Read the value of the shell variables whose names follow.
68    The reading is done from the current input stream, whatever
69    that may be.  Successive words of the input line are assigned
70    to the variables mentioned in LIST.  The last variable in LIST
71    gets the remainder of the words on the line.  If no variables
72    are mentioned in LIST, then the default variable is $REPLY. */
73 int
74 read_builtin (list)
75      WORD_LIST *list;
76 {
77   register char *varname;
78   int size, i, raw, pass_next, saw_escape, eof, opt, retval, edit;
79   char c;
80   char *input_string, *orig_input_string, *ifs_chars, *prompt, *arrayname;
81   char *e, *t, *t1;
82   SHELL_VAR *var;
83 #if defined (ARRAY_VARS)
84   WORD_LIST *alist;
85 #endif
86 #if defined (READLINE)
87   char *rlbuf;
88   int rlind;
89 #endif
90
91   i = 0;                /* Index into the string that we are reading. */
92   raw = edit = 0;       /* Not reading raw input by default. */
93   arrayname = prompt = (char *)NULL;
94
95 #if defined (READLINE)
96   rlbuf = (char *)0;
97   rlind = 0;
98 #endif
99
100   reset_internal_getopt ();
101   while ((opt = internal_getopt (list, "erp:a:")) != -1)
102     {
103       switch (opt)
104         {
105         case 'r':
106           raw = 1;
107           break;
108         case 'p':
109           prompt = list_optarg;
110           break;
111         case 'e':
112 #if defined (READLINE)
113           edit = 1;
114 #endif
115           break;
116 #if defined (ARRAY_VARS)
117         case 'a':
118           arrayname = list_optarg;
119           break;
120 #endif
121         default:
122           builtin_usage ();
123           return (EX_USAGE);
124         }
125     }
126   list = loptend;
127
128   /* IF IFS is unset, we use the default of " \t\n". */
129   var = find_variable ("IFS");
130   ifs_chars = var ? value_cell (var) : " \t\n";
131   if (ifs_chars == 0)           /* XXX */
132     ifs_chars = "";             /* XXX */
133
134   input_string = xmalloc (size = 128);
135
136   begin_unwind_frame ("read_builtin");
137   add_unwind_protect (xfree, input_string);
138 #if defined (READLINE)
139   add_unwind_protect (xfree, rlbuf);
140 #endif
141   interrupt_immediately++;
142
143   /* If the -p or -e flags were given, but input is not coming from the
144      terminal, turn them off. */
145   if ((prompt || edit) && (isatty (0) == 0))
146     {
147       prompt = (char *)NULL;
148       edit = 0;
149     }
150
151   if (prompt && edit == 0)
152     {
153       fprintf (stderr, "%s", prompt);
154       fflush (stderr);
155     }
156
157   pass_next = 0;        /* Non-zero signifies last char was backslash. */
158   saw_escape = 0;       /* Non-zero signifies that we saw an escape char */
159
160   for (eof = 0;;)
161     {
162 #if defined (READLINE)
163       if (edit)
164         {
165           if (rlbuf && rlbuf[rlind] == '\0')
166             {
167               xfree (rlbuf);
168               rlbuf = (char *)0;
169             }
170           if (rlbuf == 0)
171             {
172               rlbuf = edit_line (prompt ? prompt : "");
173               rlind = 0;
174             }
175           if (rlbuf == 0)
176             {
177               eof = 1;
178               break;
179             }
180           c = rlbuf[rlind++];
181         }
182       else
183 #endif   
184       if (read (0, &c, 1) != 1)
185         {
186           eof = 1;
187           break;
188         }
189
190       if (i + 2 >= size)
191         input_string = xrealloc (input_string, size += 128);
192
193       /* If the next character is to be accepted verbatim, a backslash
194          newline pair still disappears from the input. */
195       if (pass_next)
196         {
197           if (c == '\n')
198             i--;                /* back up over the CTLESC */
199           else
200             input_string[i++] = c;
201           pass_next = 0;
202           continue;
203         }
204
205       if (c == '\\' && raw == 0)
206         {
207           pass_next++;
208           saw_escape++;
209           input_string[i++] = CTLESC;
210           continue;
211         }
212
213       if (c == '\n')
214         break;
215
216       if (c == CTLESC || c == CTLNUL)
217         {
218           saw_escape++;
219           input_string[i++] = CTLESC;
220         }
221
222       input_string[i++] = c;
223     }
224   input_string[i] = '\0';
225
226   interrupt_immediately--;
227   discard_unwind_frame ("read_builtin");
228
229   retval = eof ? EXECUTION_FAILURE : EXECUTION_SUCCESS;
230
231 #if defined (ARRAY_VARS)
232   /* If -a was given, take the string read, break it into a list of words,
233      an assign them to `arrayname' in turn. */
234   if (arrayname)
235     {
236       var = find_variable (arrayname);
237       if (var == 0)
238         var = make_new_array_variable (arrayname);
239       else if (array_p (var) == 0)
240         var = convert_var_to_array (var);
241
242       empty_array (array_cell (var));
243
244       alist = list_string (input_string, ifs_chars, 0);
245       if (alist)
246         {
247           assign_array_var_from_word_list (var, alist);
248           dispose_words (alist);
249         }
250       xfree (input_string);
251       return (retval);
252     }
253 #endif /* ARRAY_VARS */ 
254
255   /* If there are no variables, save the text of the line read to the
256      variable $REPLY.  ksh93 strips leading and trailing IFS whitespace,
257      so that `read x ; echo "$x"' and `read ; echo "$REPLY"' behave the
258      same way, but I believe that the difference in behaviors is useful
259      enough to not do it.  Without the bash behavior, there is no way
260      to read a line completely without interpretation or modification.
261      If you disagree, change the occurrences of `#if 0' to `#if 1' below. */
262   if (list == 0)
263     {
264 #if 0
265       orig_input_string = input_string;
266       for (t = input_string; ifs_chars && *ifs_chars && spctabnl(*t) && issep(*t); t++)
267         ;
268       input_string = t;
269       input_string = strip_trailing_ifs_whitespace (input_string, ifs_chars, saw_escape);
270 #endif
271
272       if (saw_escape)
273         {
274           t = dequote_string (input_string);
275           var = bind_variable ("REPLY", t);
276           free (t);
277         }
278       else
279         var = bind_variable ("REPLY", input_string);
280       var->attributes &= ~att_invisible;
281 #if 0
282       free (orig_input_string);
283 #else
284       free (input_string);
285 #endif
286       return (retval);
287     }
288
289   /* This code implements the Posix.2 spec for splitting the words
290      read and assigning them to variables. */
291   orig_input_string = input_string;
292
293   /* Remove IFS white space at the beginning of the input string.  If
294      $IFS is null, no field splitting is performed. */
295   for (t = input_string; ifs_chars && *ifs_chars && spctabnl(*t) && issep(*t); t++)
296     ;
297   input_string = t;
298
299   for (; list->next; list = list->next)
300     {
301       varname = list->word->word;
302 #if defined (ARRAY_VARS)
303       if (legal_identifier (varname) == 0 && valid_array_reference (varname) == 0)
304 #else
305       if (legal_identifier (varname) == 0)
306 #endif
307         {
308           builtin_error ("`%s': not a valid identifier", varname);
309           free (orig_input_string);
310           return (EXECUTION_FAILURE);
311         }
312
313       /* If there are more variables than words read from the input,
314          the remaining variables are set to the empty string. */
315       if (*input_string)
316         {
317           /* This call updates INPUT_STRING. */
318           t = get_word_from_string (&input_string, ifs_chars, &e);
319           if (t)
320             *e = '\0';
321           /* Don't bother to remove the CTLESC unless we added one
322              somewhere while reading the string. */
323           if (t && saw_escape)
324             {
325               t1 = dequote_string (t);
326               var = bind_read_variable (varname, t1);
327               free (t1);
328             }
329           else
330             var = bind_read_variable (varname, t);
331         }
332       else
333         {
334           t = (char *)0;
335           var = bind_read_variable (varname, "");
336         }
337
338       FREE (t);
339       if (var == 0)
340         {
341           free (orig_input_string);
342           return (EXECUTION_FAILURE);
343         }
344
345       stupidly_hack_special_variables (varname);
346       var->attributes &= ~att_invisible;
347     }
348
349   /* Now assign the rest of the line to the last variable argument. */
350 #if defined (ARRAY_VARS)
351   if (legal_identifier (list->word->word) == 0 && valid_array_reference (list->word->word) == 0)
352 #else
353   if (legal_identifier (list->word->word) == 0)
354 #endif
355     {
356       builtin_error ("`%s': not a valid identifier", list->word->word);
357       free (orig_input_string);
358       return (EXECUTION_FAILURE);
359     }
360
361   /* This has to be done this way rather than using string_list
362      and list_string because Posix.2 says that the last variable gets the
363      remaining words and their intervening separators. */
364   input_string = strip_trailing_ifs_whitespace (input_string, ifs_chars, saw_escape);
365
366   if (saw_escape)
367     {
368       t = dequote_string (input_string);
369       var = bind_read_variable (list->word->word, t);
370       free (t);
371     }
372   else
373     var = bind_read_variable (list->word->word, input_string);
374   stupidly_hack_special_variables (list->word->word);
375   if (var)
376     var->attributes &= ~att_invisible;
377   free (orig_input_string);
378
379   return (retval);
380 }
381
382 static SHELL_VAR *
383 bind_read_variable (name, value)
384      char *name, *value;
385 {
386 #if defined (ARRAY_VARS)
387   if (valid_array_reference (name) == 0)
388     {
389       if (legal_identifier (name) == 0)
390         {
391           builtin_error ("`%s': not a valid identifier", name);
392           return ((SHELL_VAR *)NULL);
393         }
394       return (bind_variable (name, value));
395     }
396   else
397     return (do_array_element_assignment (name, value));
398 #else
399   return bind_variable (name, value);
400 #endif
401 }
402
403 #if defined (READLINE)
404 static char *
405 edit_line (p)
406      char *p;
407 {
408   char *ret;
409   int len;
410
411   if (!bash_readline_initialized)
412     initialize_readline ();
413   ret = readline (p);
414   if (ret == 0)
415     return ret;
416   len = strlen (ret);
417   ret = xrealloc (ret, len + 2);
418   ret[len++] = '\n';
419   ret[len] = '\0';
420   return ret;
421 }
422 #endif