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-2016 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 [-d delim] [-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 -d delim Use DELIM to terminate lines, instead of newline
35 -n count Copy at most COUNT lines. If COUNT is 0, all lines are copied
36 -O origin Begin assigning to ARRAY at index ORIGIN. The default index is 0
37 -s count Discard the first COUNT lines read
38 -t Remove a trailing DELIM from each line read (default newline)
39 -u fd Read lines from file descriptor FD instead of the standard input
40 -C callback Evaluate CALLBACK each time QUANTUM lines are read
41 -c quantum Specify the number of lines read between each call to
45 ARRAY Array variable name to use for file data
47 If -C is supplied without -c, the default quantum is 5000. When
48 CALLBACK is evaluated, it is supplied the index of the next array
49 element to be assigned and the line to be assigned to that element
50 as additional arguments.
52 If not supplied with an explicit origin, mapfile will clear ARRAY before
56 Returns success unless an invalid option is given or ARRAY is readonly or
61 $FUNCTION mapfile_builtin
62 $SHORT_DOC readarray [-n count] [-O origin] [-s count] [-t] [-u fd] [-C callback] [-c quantum] [array]
63 Read lines from a file into an array variable.
65 A synonym for `mapfile'.
71 #include "posixstat.h"
73 #if defined (HAVE_UNISTD_H)
83 #include "../bashintl.h"
86 #include "bashgetopt.h"
92 #if defined (ARRAY_VARS)
94 static int run_callback __P((const char *, unsigned int, const char *));
96 #define DEFAULT_ARRAY_NAME "MAPFILE"
97 #define DEFAULT_VARIABLE_NAME "MAPLINE" /* not used right now */
99 /* The value specifying how frequently `mapfile' calls the callback. */
100 #define DEFAULT_QUANTUM 5000
102 /* Values for FLAGS */
103 #define MAPF_CLEARARRAY 0x01
104 #define MAPF_CHOP 0x02
109 run_callback (callback, curindex, curline)
110 const char *callback;
111 unsigned int curindex;
114 unsigned int execlen;
115 char *execstr, *qline;
118 qline = sh_single_quote (curline);
119 execlen = strlen (callback) + strlen (qline) + 10;
120 /* 1 for each space between %s and %d,
121 another 1 for the last nul char for C string. */
123 execstr = xmalloc (execlen);
125 flags = SEVAL_NOHIST;
128 flags |= SEVAL_INTERACT;
130 snprintf (execstr, execlen, "%s %d %s", callback, curindex, qline);
132 return evalstring (execstr, NULL, flags);
142 length = strlen (line);
143 if (length && line[length-1] == delim)
144 line[length-1] = '\0';
148 mapfile (fd, line_count_goal, origin, nskip, callback_quantum, callback, array_name, delim, flags)
150 long line_count_goal, origin, nskip, callback_quantum;
151 char *callback, *array_name;
157 unsigned int array_index, line_count;
165 /* The following check should be done before reading any lines. Doing it
166 here allows us to call bind_array_element instead of bind_array_variable
167 and skip the variable lookup on every call. */
168 entry = find_or_make_array_variable (array_name, 1);
169 if (entry == 0 || readonly_p (entry) || noassign_p (entry))
171 if (entry && readonly_p (entry))
172 err_readonly (array_name);
174 return (EXECUTION_FAILURE);
176 else if (array_p (entry) == 0)
178 builtin_error (_("%s: not an indexed array"), array_name);
179 return (EXECUTION_FAILURE);
181 else if (invisible_p (entry))
182 VUNSETATTR (entry, att_invisible); /* no longer invisible */
184 if (flags & MAPF_CLEARARRAY)
185 array_flush (array_cell (entry));
188 unbuffered_read = (lseek (fd, 0L, SEEK_CUR) < 0) && (errno == ESPIPE);
198 /* Skip any lines at beginning of file? */
199 for (line_count = 0; line_count < nskip; line_count++)
200 if (zgetline (fd, &line, &line_length, delim, unbuffered_read) < 0)
206 /* Reset the buffer for bash own stream */
207 for (array_index = origin, line_count = 1;
208 zgetline (fd, &line, &line_length, delim, unbuffered_read) != -1;
211 /* Remove trailing newlines? */
212 if (flags & MAPF_CHOP)
213 do_chop (line, delim);
215 /* Has a callback been registered and if so is it time to call it? */
216 if (callback && line_count && (line_count % callback_quantum) == 0)
218 run_callback (callback, array_index, line);
220 /* Reset the buffer for bash own stream. */
221 if (unbuffered_read == 0)
225 /* XXX - bad things can happen if the callback modifies ENTRY, e.g.,
226 unsetting it or changing it to a non-indexed-array type. */
227 bind_array_element (entry, array_index, line, 0);
229 /* Have we exceeded # of lines to store? */
231 if (line_count_goal != 0 && line_count > line_count_goal)
237 if (unbuffered_read == 0)
240 return EXECUTION_SUCCESS;
244 mapfile_builtin (list)
247 int opt, code, fd, clear_array, flags;
249 long lines, origin, nskip, callback_quantum;
250 char *array_name, *callback;
254 lines = origin = nskip = 0;
255 flags = MAPF_CLEARARRAY;
256 callback_quantum = DEFAULT_QUANTUM;
260 reset_internal_getopt ();
261 while ((opt = internal_getopt (list, "d:u:n:O:tC:c:s:")) != -1)
266 delim = *list_optarg;
269 code = legal_number (list_optarg, &intval);
270 if (code == 0 || intval < 0 || intval != (int)intval)
272 builtin_error (_("%s: invalid file descriptor specification"), list_optarg);
273 return (EXECUTION_FAILURE);
278 if (sh_validfd (fd) == 0)
280 builtin_error (_("%d: invalid file descriptor: %s"), fd, strerror (errno));
281 return (EXECUTION_FAILURE);
286 code = legal_number (list_optarg, &intval);
287 if (code == 0 || intval < 0 || intval != (unsigned)intval)
289 builtin_error (_("%s: invalid line count"), list_optarg);
290 return (EXECUTION_FAILURE);
297 code = legal_number (list_optarg, &intval);
298 if (code == 0 || intval < 0 || intval != (unsigned)intval)
300 builtin_error (_("%s: invalid array origin"), list_optarg);
301 return (EXECUTION_FAILURE);
305 flags &= ~MAPF_CLEARARRAY;
311 callback = list_optarg;
314 code = legal_number (list_optarg, &intval);
315 if (code == 0 || intval <= 0 || intval != (unsigned)intval)
317 builtin_error (_("%s: invalid callback quantum"), list_optarg);
318 return (EXECUTION_FAILURE);
321 callback_quantum = intval;
324 code = legal_number (list_optarg, &intval);
325 if (code == 0 || intval < 0 || intval != (unsigned)intval)
327 builtin_error (_("%s: invalid line count"), list_optarg);
328 return (EXECUTION_FAILURE);
342 array_name = DEFAULT_ARRAY_NAME;
343 else if (list->word == 0 || list->word->word == 0)
345 builtin_error ("internal error: getting variable name");
346 return (EXECUTION_FAILURE);
348 else if (list->word->word[0] == '\0')
350 builtin_error (_("empty array variable name"));
354 array_name = list->word->word;
356 if (legal_identifier (array_name) == 0)
358 sh_invalidid (array_name);
359 return (EXECUTION_FAILURE);
362 return mapfile (fd, lines, origin, nskip, callback_quantum, callback, array_name, delim, flags);
368 mapfile_builtin (list)
371 builtin_error (_("array variable support required"));
372 return (EXECUTION_FAILURE);
375 #endif /* ARRAY_VARS */