1 This file is mapfile.def, from which is created mapfile.c.
2 It implements the builtin "mapfile" in Bash.
4 Copyright (C) 2005-2006 Rocky Bernstein for Free Software Foundation, Inc.
5 Copyright (C) 2008,2009 Free Software Foundation, Inc.
7 This file is part of GNU Bash, the Bourne Again SHell.
9 Bash is free software: you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version.
14 Bash is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with Bash. If not, see <http://www.gnu.org/licenses/>.
25 $FUNCTION mapfile_builtin
26 $SHORT_DOC mapfile [-n count] [-O origin] [-s count] [-t] [-u fd] [-C callback] [-c quantum] [array]
27 Read lines from the standard input into an indexed array variable.
29 Read lines from the standard input into the indexed array variable ARRAY, or
30 from file descriptor FD if the -u option is supplied. The variable MAPFILE
34 -n count Copy at most COUNT lines. If COUNT is 0, all lines are copied.
35 -O origin Begin assigning to ARRAY at index ORIGIN. The default index is 0.
36 -s count Discard the first COUNT lines read.
37 -t Remove a trailing newline from each line read.
38 -u fd Read lines from file descriptor FD instead of the standard input.
39 -C callback Evaluate CALLBACK each time QUANTUM lines are read.
40 -c quantum Specify the number of lines read between each call to CALLBACK.
43 ARRAY Array variable name to use for file data.
45 If -C is supplied without -c, the default quantum is 5000. When
46 CALLBACK is evaluated, it is supplied the index of the next array
47 element to be assigned as an additional argument.
49 If not supplied with an explicit origin, mapfile will clear ARRAY before
53 Returns success unless an invalid option is given or ARRAY is readonly or
58 $FUNCTION mapfile_builtin
59 $SHORT_DOC readarray [-n count] [-O origin] [-s count] [-t] [-u fd] [-C callback] [-c quantum] [array]
60 Read lines from a file into an array variable.
62 A synonym for `mapfile'.
68 #include "posixstat.h"
70 #if defined (HAVE_UNISTD_H)
80 #include "../bashintl.h"
83 #include "bashgetopt.h"
89 #if defined (ARRAY_VARS)
91 #define DEFAULT_ARRAY_NAME "MAPFILE"
93 /* The value specifying how frequently `mapfile' calls the callback. */
94 #define DEFAULT_QUANTUM 5000
96 /* Values for FLAGS */
97 #define MAPF_CLEARARRAY 0x01
98 #define MAPF_CHOP 0x02
101 run_callback(callback, current_index)
102 const char *callback;
103 unsigned int current_index;
105 unsigned int execlen;
109 execlen = strlen (callback) + 10;
110 /* 1 for space between %s and %d,
111 another 1 for the last nul char for C string. */
113 execstr = xmalloc (execlen);
115 flags = SEVAL_NOHIST;
118 flags |= SEVAL_INTERACT;
120 snprintf (execstr, execlen, "%s %d", callback, current_index);
121 return parse_and_execute(execstr, NULL, flags);
130 length = strlen (line);
131 if (length && line[length-1] == '\n')
132 line[length-1] = '\0';
136 mapfile (fd, line_count_goal, origin, nskip, callback_quantum, callback, array_name, flags)
138 long line_count_goal, origin, nskip, callback_quantum;
139 char *callback, *array_name;
144 unsigned int array_index, line_count;
152 /* The following check should be done before reading any lines. Doing it
153 here allows us to call bind_array_element instead of bind_array_variable
154 and skip the variable lookup on every call. */
155 entry = find_or_make_array_variable (array_name, 1);
156 if (entry == 0 || readonly_p (entry) || noassign_p (entry))
158 if (entry && readonly_p (entry))
159 err_readonly (array_name);
161 return (EXECUTION_FAILURE);
163 else if (array_p (entry) == 0)
165 builtin_error (_("%s: not an indexed array"), array_name);
166 return (EXECUTION_FAILURE);
169 if (flags & MAPF_CLEARARRAY)
170 array_flush (array_cell (entry));
173 unbuffered_read = (lseek (fd, 0L, SEEK_CUR) < 0) && (errno == ESPIPE);
180 /* Skip any lines at beginning of file? */
181 for (line_count = 0; line_count < nskip; line_count++)
182 if (zgetline (fd, &line, &line_length, unbuffered_read) < 0)
188 /* Reset the buffer for bash own stream */
189 interrupt_immediately++;
190 for (array_index = origin, line_count = 1;
191 zgetline (fd, &line, &line_length, unbuffered_read) != -1;
192 array_index++, line_count++)
194 /* Have we exceeded # of lines to store? */
195 if (line_count_goal != 0 && line_count > line_count_goal)
198 /* Remove trailing newlines? */
199 if (flags & MAPF_CHOP)
202 /* Has a callback been registered and if so is it time to call it? */
203 if (callback && line_count && (line_count % callback_quantum) == 0)
205 run_callback (callback, array_index);
207 /* Reset the buffer for bash own stream. */
208 if (unbuffered_read == 0)
212 bind_array_element (entry, array_index, line, 0);
217 if (unbuffered_read == 0)
220 interrupt_immediately--;
221 return EXECUTION_SUCCESS;
225 mapfile_builtin (list)
228 int opt, code, fd, clear_array, flags;
230 long lines, origin, nskip, callback_quantum;
231 char *array_name, *callback;
235 lines = origin = nskip = 0;
236 flags = MAPF_CLEARARRAY;
237 callback_quantum = DEFAULT_QUANTUM;
240 reset_internal_getopt ();
241 while ((opt = internal_getopt (list, "u:n:O:tC:c:s:")) != -1)
246 code = legal_number (list_optarg, &intval);
247 if (code == 0 || intval < 0 || intval != (int)intval)
249 builtin_error (_("%s: invalid file descriptor specification"), list_optarg);
250 return (EXECUTION_FAILURE);
255 if (sh_validfd (fd) == 0)
257 builtin_error (_("%d: invalid file descriptor: %s"), fd, strerror (errno));
258 return (EXECUTION_FAILURE);
263 code = legal_number (list_optarg, &intval);
264 if (code == 0 || intval < 0 || intval != (unsigned)intval)
266 builtin_error (_("%s: invalid line count"), list_optarg);
267 return (EXECUTION_FAILURE);
274 code = legal_number (list_optarg, &intval);
275 if (code == 0 || intval < 0 || intval != (unsigned)intval)
277 builtin_error (_("%s: invalid array origin"), list_optarg);
278 return (EXECUTION_FAILURE);
282 flags &= ~MAPF_CLEARARRAY;
288 callback = list_optarg;
291 code = legal_number (list_optarg, &intval);
292 if (code == 0 || intval <= 0 || intval != (unsigned)intval)
294 builtin_error (_("%s: invalid callback quantum"), list_optarg);
295 return (EXECUTION_FAILURE);
298 callback_quantum = intval;
301 code = legal_number (list_optarg, &intval);
302 if (code == 0 || intval < 0 || intval != (unsigned)intval)
304 builtin_error (_("%s: invalid line count"), list_optarg);
305 return (EXECUTION_FAILURE);
318 array_name = DEFAULT_ARRAY_NAME;
319 else if (list->word == 0 || list->word->word == 0)
321 builtin_error ("internal error: getting variable name");
322 return (EXECUTION_FAILURE);
324 else if (list->word->word[0] == '\0')
326 builtin_error (_("empty array variable name"));
330 array_name = list->word->word;
332 if (legal_identifier (array_name) == 0 && valid_array_reference (array_name) == 0)
334 sh_invalidid (array_name);
335 return (EXECUTION_FAILURE);
338 return mapfile (fd, lines, origin, nskip, callback_quantum, callback, array_name, flags);
344 mapfile_builtin (list)
347 builtin_error (_("array variable support required"));
348 return (EXECUTION_FAILURE);
351 #endif /* ARRAY_VARS */