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-2010 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 and the line to be assigned to that element
48 as additional arguments.
50 If not supplied with an explicit origin, mapfile will clear ARRAY before
54 Returns success unless an invalid option is given or ARRAY is readonly or
59 $FUNCTION mapfile_builtin
60 $SHORT_DOC readarray [-n count] [-O origin] [-s count] [-t] [-u fd] [-C callback] [-c quantum] [array]
61 Read lines from a file into an array variable.
63 A synonym for `mapfile'.
69 #include "posixstat.h"
71 #if defined (HAVE_UNISTD_H)
81 #include "../bashintl.h"
84 #include "bashgetopt.h"
90 #if defined (ARRAY_VARS)
92 static int run_callback __P((const char *, unsigned int, const char *));
94 #define DEFAULT_ARRAY_NAME "MAPFILE"
95 #define DEFAULT_VARIABLE_NAME "MAPLINE" /* not used right now */
97 /* The value specifying how frequently `mapfile' calls the callback. */
98 #define DEFAULT_QUANTUM 5000
100 /* Values for FLAGS */
101 #define MAPF_CLEARARRAY 0x01
102 #define MAPF_CHOP 0x02
105 run_callback (callback, curindex, curline)
106 const char *callback;
107 unsigned int curindex;
110 unsigned int execlen;
111 char *execstr, *qline;
114 qline = sh_single_quote (curline);
115 execlen = strlen (callback) + strlen (qline) + 10;
116 /* 1 for each space between %s and %d,
117 another 1 for the last nul char for C string. */
119 execstr = xmalloc (execlen);
121 flags = SEVAL_NOHIST;
124 flags |= SEVAL_INTERACT;
126 snprintf (execstr, execlen, "%s %d %s", callback, curindex, qline);
128 return parse_and_execute (execstr, NULL, flags);
137 length = strlen (line);
138 if (length && line[length-1] == '\n')
139 line[length-1] = '\0';
143 mapfile (fd, line_count_goal, origin, nskip, callback_quantum, callback, array_name, flags)
145 long line_count_goal, origin, nskip, callback_quantum;
146 char *callback, *array_name;
151 unsigned int array_index, line_count;
159 /* The following check should be done before reading any lines. Doing it
160 here allows us to call bind_array_element instead of bind_array_variable
161 and skip the variable lookup on every call. */
162 entry = find_or_make_array_variable (array_name, 1);
163 if (entry == 0 || readonly_p (entry) || noassign_p (entry))
165 if (entry && readonly_p (entry))
166 err_readonly (array_name);
168 return (EXECUTION_FAILURE);
170 else if (array_p (entry) == 0)
172 builtin_error (_("%s: not an indexed array"), array_name);
173 return (EXECUTION_FAILURE);
176 if (flags & MAPF_CLEARARRAY)
177 array_flush (array_cell (entry));
180 unbuffered_read = (lseek (fd, 0L, SEEK_CUR) < 0) && (errno == ESPIPE);
187 /* Skip any lines at beginning of file? */
188 for (line_count = 0; line_count < nskip; line_count++)
189 if (zgetline (fd, &line, &line_length, unbuffered_read) < 0)
195 /* Reset the buffer for bash own stream */
196 interrupt_immediately++;
197 for (array_index = origin, line_count = 1;
198 zgetline (fd, &line, &line_length, unbuffered_read) != -1;
201 /* Remove trailing newlines? */
202 if (flags & MAPF_CHOP)
205 /* Has a callback been registered and if so is it time to call it? */
206 if (callback && line_count && (line_count % callback_quantum) == 0)
208 run_callback (callback, array_index, line);
210 /* Reset the buffer for bash own stream. */
211 if (unbuffered_read == 0)
215 bind_array_element (entry, array_index, line, 0);
217 /* Have we exceeded # of lines to store? */
219 if (line_count_goal != 0 && line_count > line_count_goal)
225 if (unbuffered_read == 0)
228 interrupt_immediately--;
229 return EXECUTION_SUCCESS;
233 mapfile_builtin (list)
236 int opt, code, fd, clear_array, flags;
238 long lines, origin, nskip, callback_quantum;
239 char *array_name, *callback;
243 lines = origin = nskip = 0;
244 flags = MAPF_CLEARARRAY;
245 callback_quantum = DEFAULT_QUANTUM;
248 reset_internal_getopt ();
249 while ((opt = internal_getopt (list, "u:n:O:tC:c:s:")) != -1)
254 code = legal_number (list_optarg, &intval);
255 if (code == 0 || intval < 0 || intval != (int)intval)
257 builtin_error (_("%s: invalid file descriptor specification"), list_optarg);
258 return (EXECUTION_FAILURE);
263 if (sh_validfd (fd) == 0)
265 builtin_error (_("%d: invalid file descriptor: %s"), fd, strerror (errno));
266 return (EXECUTION_FAILURE);
271 code = legal_number (list_optarg, &intval);
272 if (code == 0 || intval < 0 || intval != (unsigned)intval)
274 builtin_error (_("%s: invalid line count"), list_optarg);
275 return (EXECUTION_FAILURE);
282 code = legal_number (list_optarg, &intval);
283 if (code == 0 || intval < 0 || intval != (unsigned)intval)
285 builtin_error (_("%s: invalid array origin"), list_optarg);
286 return (EXECUTION_FAILURE);
290 flags &= ~MAPF_CLEARARRAY;
296 callback = list_optarg;
299 code = legal_number (list_optarg, &intval);
300 if (code == 0 || intval <= 0 || intval != (unsigned)intval)
302 builtin_error (_("%s: invalid callback quantum"), list_optarg);
303 return (EXECUTION_FAILURE);
306 callback_quantum = intval;
309 code = legal_number (list_optarg, &intval);
310 if (code == 0 || intval < 0 || intval != (unsigned)intval)
312 builtin_error (_("%s: invalid line count"), list_optarg);
313 return (EXECUTION_FAILURE);
326 array_name = DEFAULT_ARRAY_NAME;
327 else if (list->word == 0 || list->word->word == 0)
329 builtin_error ("internal error: getting variable name");
330 return (EXECUTION_FAILURE);
332 else if (list->word->word[0] == '\0')
334 builtin_error (_("empty array variable name"));
338 array_name = list->word->word;
340 if (legal_identifier (array_name) == 0 && valid_array_reference (array_name) == 0)
342 sh_invalidid (array_name);
343 return (EXECUTION_FAILURE);
346 return mapfile (fd, lines, origin, nskip, callback_quantum, callback, array_name, flags);
352 mapfile_builtin (list)
355 builtin_error (_("array variable support required"));
356 return (EXECUTION_FAILURE);
359 #endif /* ARRAY_VARS */