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 array variable.
29 Read lines from the standard input into the array variable ARRAY, or from
30 file descriptor FD if the -u option is supplied. The variable MAPFILE is
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.
57 $FUNCTION mapfile_builtin
58 $SHORT_DOC readarray [-n count] [-O origin] [-s count] [-t] [-u fd] [-C callback] [-c quantum] [array]
59 Read lines from a file into an array variable.
61 A synonym for `mapfile'.
67 #include "posixstat.h"
69 #if defined (HAVE_UNISTD_H)
78 #include "../bashintl.h"
81 #include "bashgetopt.h"
87 #if defined (ARRAY_VARS)
89 #define DEFAULT_ARRAY_NAME "MAPFILE"
91 /* The value specifying how frequently `mapfile' calls the callback. */
92 #define DEFAULT_QUANTUM 5000
94 /* Values for FLAGS */
95 #define MAPF_CLEARARRAY 0x01
96 #define MAPF_CHOP 0x02
99 run_callback(callback, current_index)
100 const char *callback;
101 unsigned int current_index;
103 unsigned int execlen;
107 execlen = strlen (callback) + 10;
108 /* 1 for space between %s and %d,
109 another 1 for the last nul char for C string. */
111 execstr = xmalloc (execlen);
116 flags |= SEVAL_NOHIST|SEVAL_INTERACT;
118 snprintf (execstr, execlen, "%s %d", callback, current_index);
119 return parse_and_execute(execstr, NULL, flags);
128 length = strlen (line);
129 if (length && line[length-1] == '\n')
130 line[length-1] = '\0';
134 mapfile (fd, line_count_goal, origin, nskip, callback_quantum, callback, array_name, flags)
136 long line_count_goal, origin, nskip, callback_quantum;
137 char *callback, *array_name;
142 unsigned int array_index, line_count;
150 /* The following check should be done before reading any lines. Doing it
151 here allows us to call bind_array_element instead of bind_array_variable
152 and skip the variable lookup on every call. */
153 entry = find_or_make_array_variable (array_name, 1);
154 if (entry == 0 || readonly_p (entry) || noassign_p (entry))
156 if (readonly_p (entry))
157 err_readonly (array_name);
159 return (EXECUTION_FAILURE);
161 if (flags & MAPF_CLEARARRAY)
162 array_flush (array_cell (entry));
165 unbuffered_read = (lseek (fd, 0L, SEEK_CUR) < 0) && (errno == ESPIPE);
172 /* Skip any lines at beginning of file? */
173 for (line_count = 0; line_count < nskip; line_count++)
174 if (zgetline (fd, &line, &line_length, unbuffered_read) < 0)
180 /* Reset the buffer for bash own stream */
181 interrupt_immediately++;
182 for (array_index = origin, line_count = 1;
183 zgetline (fd, &line, &line_length, unbuffered_read) != -1;
184 array_index++, line_count++)
186 /* Have we exceeded # of lines to store? */
187 if (line_count_goal != 0 && line_count > line_count_goal)
190 /* Remove trailing newlines? */
191 if (flags & MAPF_CHOP)
194 /* Has a callback been registered and if so is it time to call it? */
195 if (callback && line_count && (line_count % callback_quantum) == 0)
197 run_callback (callback, array_index);
199 /* Reset the buffer for bash own stream. */
200 if (unbuffered_read == 0)
204 bind_array_element (entry, array_index, line, 0);
209 if (unbuffered_read == 0)
212 interrupt_immediately--;
213 return EXECUTION_SUCCESS;
217 mapfile_builtin (list)
220 int opt, code, fd, clear_array, flags;
222 long lines, origin, nskip, callback_quantum;
223 char *array_name, *callback;
227 lines = origin = nskip = 0;
228 flags = MAPF_CLEARARRAY;
229 callback_quantum = DEFAULT_QUANTUM;
232 reset_internal_getopt ();
233 while ((opt = internal_getopt (list, "u:n:O:tC:c:s:")) != -1)
238 code = legal_number (list_optarg, &intval);
239 if (code == 0 || intval < 0 || intval != (int)intval)
241 builtin_error (_("%s: invalid file descriptor specification"), list_optarg);
242 return (EXECUTION_FAILURE);
247 if (sh_validfd (fd) == 0)
249 builtin_error (_("%d: invalid file descriptor: %s"), fd, strerror (errno));
250 return (EXECUTION_FAILURE);
255 code = legal_number (list_optarg, &intval);
256 if (code == 0 || intval < 0 || intval != (unsigned)intval)
258 builtin_error (_("%s: invalid line count"), list_optarg);
259 return (EXECUTION_FAILURE);
266 code = legal_number (list_optarg, &intval);
267 if (code == 0 || intval < 0 || intval != (unsigned)intval)
269 builtin_error (_("%s: invalid array origin"), list_optarg);
270 return (EXECUTION_FAILURE);
274 flags &= ~MAPF_CLEARARRAY;
280 callback = list_optarg;
283 code = legal_number (list_optarg, &intval);
284 if (code == 0 || intval < 0 || intval != (unsigned)intval)
286 builtin_error (_("%s: invalid callback quantum"), list_optarg);
287 return (EXECUTION_FAILURE);
290 callback_quantum = intval;
293 code = legal_number (list_optarg, &intval);
294 if (code == 0 || intval < 0 || intval != (unsigned)intval)
296 builtin_error (_("%s: invalid line count"), list_optarg);
297 return (EXECUTION_FAILURE);
310 array_name = DEFAULT_ARRAY_NAME;
311 else if (list->word == 0 || list->word->word == 0)
313 builtin_error ("internal error: getting variable name");
314 return (EXECUTION_FAILURE);
316 else if (list->word->word[0] == '\0')
318 builtin_error (_("empty array variable name"));
322 array_name = list->word->word;
324 if (legal_identifier (array_name) == 0 && valid_array_reference (array_name) == 0)
326 sh_invalidid (array_name);
327 return (EXECUTION_FAILURE);
330 return mapfile (fd, lines, origin, nskip, callback_quantum, callback, array_name, flags);
336 mapfile_builtin (list)
339 builtin_error (_("array variable support required"));
340 return (EXECUTION_FAILURE);
343 #endif /* ARRAY_VARS */