Imported from ../bash-1.14.7.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] [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, etc.
29 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 the -r option is given,
32 this signifies `raw' input, and backslash processing is disabled.
33 $END
34
35 #include <stdio.h>
36 #include "../shell.h"
37 #include "common.h"
38
39 #define issep(c)        (strchr (ifs_chars, (c)) != (char *)0)
40
41 static int stream_close ();
42
43 extern int interrupt_immediately;
44
45 /* Read the value of the shell variables whose names follow.
46    The reading is done from the current input stream, whatever
47    that may be.  Successive words of the input line are assigned
48    to the variables mentioned in LIST.  The last variable in LIST
49    gets the remainder of the words on the line.  If no variables
50    are mentioned in LIST, then the default variable is $REPLY.
51
52    S. R. Bourne's shell complains if you don't name a variable
53    to receive the stuff that is read.  GNU's shell doesn't.  This
54    allows you to let the user type random things. */
55 read_builtin (list)
56      WORD_LIST *list;
57 {
58   register char *varname;
59   int size, c, i, fildes, raw_mode, pass_next, saw_escape, retval;
60   char *input_string, *orig_input_string, *ifs_chars, *t;
61   FILE *input_stream;
62   SHELL_VAR *var;
63
64   i = 0;                /* Index into the string that we are reading. */
65   raw_mode = 0;         /* Not reading raw input be default. */
66
67   while (list)
68     {
69       if (ISOPTION (list->word->word, 'r'))
70         {
71           raw_mode = 1;
72           list = list->next;
73         }
74       else if (ISOPTION (list->word->word, '-'))
75         {
76           list = list->next;
77           break;
78         }
79       else if (*list->word->word == '-')
80         {
81           bad_option (list->word->word);
82           builtin_error ("usage: read [-r] [name ...]");
83           return (EX_USAGE);
84         }
85       else
86         break;
87     }
88
89   /* We need unbuffered input from stdin.  So we make a new stream with
90      the same file descriptor as stdin, then unbuffer it. */
91   fildes = dup (fileno (stdin));
92
93   if (fildes == -1)
94     return (EXECUTION_FAILURE);
95
96   input_stream = fdopen (fildes, "r");
97
98   if (!input_stream)
99     {
100       close (fildes);
101       return (EXECUTION_FAILURE);
102     }
103
104   var = find_variable ("IFS");
105   ifs_chars = var ? value_cell (var) : " \t\n";
106   
107   input_string = xmalloc (size = 128);
108
109   setbuf (input_stream, (char *)NULL);
110
111   begin_unwind_frame ("read_builtin");
112   add_unwind_protect (xfree, input_string);
113   add_unwind_protect (stream_close, input_stream);
114   interrupt_immediately++;
115
116   pass_next = 0;        /* Non-zero signifies last char was backslash. */
117   saw_escape = 0;       /* Non-zero signifies that we saw an escape char */
118
119   while ((c = getc (input_stream)) != EOF)
120     {
121       if (i + 2 >= size)
122         input_string = xrealloc (input_string, size += 128);
123
124       /* If the next character is to be accepted verbatim, a backslash
125          newline pair still disappears from the input. */
126       if (pass_next)
127         {
128           if (c == '\n')
129             i--;                /* back up over the CTLESC */
130           else
131             input_string[i++] = c;
132           pass_next = 0;
133           continue;
134         }
135
136       if (c == '\\' && !raw_mode)
137         {
138           pass_next++;
139           saw_escape++;
140           input_string[i++] = CTLESC;
141           continue;
142         }
143
144       if (c == '\n')
145         break;
146
147       if (c == CTLESC || c == CTLNUL)
148         {
149           saw_escape++;
150           input_string[i++] = CTLESC;
151         }
152
153       input_string[i++] = c;
154     }
155   input_string[i] = '\0';
156
157   interrupt_immediately--;
158   discard_unwind_frame ("read_builtin");
159
160   fclose (input_stream);
161
162   if (c == EOF)
163     {
164       retval = EXECUTION_FAILURE;
165       /* input_string[0] = '\0'; */
166     }
167   else
168     retval = EXECUTION_SUCCESS;
169
170   if (!list)
171     {
172       if (saw_escape)
173         {
174           t = dequote_string (input_string);
175           var = bind_variable ("REPLY", t);
176           free (t);
177         }
178       else
179         var = bind_variable ("REPLY", input_string);
180       var->attributes &= ~att_invisible;
181       free (input_string);
182     }
183   else
184     {
185       /* This code implements the Posix.2 spec for splitting the words
186          read and assigning them to variables.  If $IFS is unset, we
187          use the default value of " \t\n". */
188       orig_input_string = input_string;
189
190       /* Remove IFS white space at the beginning of the input string.  If
191          $IFS is null, no field splitting is performed. */
192       for (t = input_string; *ifs_chars && spctabnl (*t) && issep (*t); t++)
193         ;
194       input_string = t;
195
196       for (; list->next; list = list->next)
197         {
198           char *e, *t1;
199
200           varname = list->word->word;
201           if (legal_identifier (varname) == 0)
202             {
203               builtin_error ("%s: not a legal variable name", varname);
204               free (orig_input_string);
205               return (EXECUTION_FAILURE);
206             }
207
208           /* If there are more variables than words read from the input,
209              the remaining variables are set to the empty string. */
210           if (*input_string)
211             {
212               /* This call updates INPUT_STRING. */
213               t = get_word_from_string (&input_string, ifs_chars, &e);
214               if (t)
215                 *e = '\0';
216               /* Don't bother to remove the CTLESC unless we added one
217                  somewhere while reading the string. */
218               if (t && saw_escape)
219                 {
220                   t1 = dequote_string (t);
221                   var = bind_variable (varname, t1);
222                   free (t1);
223                 }
224               else
225                 var = bind_variable (varname, t);
226             }
227           else
228             {
229               t = (char *)0;
230               var = bind_variable (varname, "");
231             }
232
233           stupidly_hack_special_variables (varname);
234           var->attributes &= ~att_invisible;
235
236           if (t)
237             free (t);
238         }
239
240       if (legal_identifier (list->word->word) == 0)
241         {
242           builtin_error ("%s: not a legal variable name", list->word->word);
243           free (orig_input_string);
244           return (EXECUTION_FAILURE);
245         }
246
247       /* This has to be done this way rather than using string_list
248          and list_string because Posix.2 says that the last variable gets the
249          remaining words and their intervening separators. */
250       input_string = strip_trailing_ifs_whitespace (input_string, ifs_chars,
251                                                       saw_escape);
252
253       if (saw_escape)
254         {
255           t = dequote_string (input_string);
256           var = bind_variable (list->word->word, t);
257           free (t);
258         }
259       else
260         var = bind_variable (list->word->word, input_string);
261       stupidly_hack_special_variables (list->word->word);
262       var->attributes &= ~att_invisible;
263       free (orig_input_string);
264     }
265
266   return (retval);
267 }
268
269 /* This way I don't have to know whether fclose () is a
270    function or a macro. */
271 static int
272 stream_close (file)
273      FILE *file;
274 {
275   return (fclose (file));
276 }