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