It implements the builtin "mapfile" in Bash.
Copyright (C) 2005-2006 Rocky Bernstein for Free Software Foundation, Inc.
-Copyright (C) 2008,2009 Free Software Foundation, Inc.
+Copyright (C) 2008-2012 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
If -C is supplied without -c, the default quantum is 5000. When
CALLBACK is evaluated, it is supplied the index of the next array
-element to be assigned as an additional argument.
+element to be assigned and the line to be assigned to that element
+as additional arguments.
If not supplied with an explicit origin, mapfile will clear ARRAY before
assigning to it.
#if defined (ARRAY_VARS)
+static int run_callback __P((const char *, unsigned int, const char *));
+
#define DEFAULT_ARRAY_NAME "MAPFILE"
+#define DEFAULT_VARIABLE_NAME "MAPLINE" /* not used right now */
/* The value specifying how frequently `mapfile' calls the callback. */
#define DEFAULT_QUANTUM 5000
#define MAPF_CHOP 0x02
static int
-run_callback(callback, current_index)
+run_callback (callback, curindex, curline)
const char *callback;
- unsigned int current_index;
+ unsigned int curindex;
+ const char *curline;
{
unsigned int execlen;
- char *execstr;
+ char *execstr, *qline;
int flags;
- execlen = strlen (callback) + 10;
- /* 1 for space between %s and %d,
+ qline = sh_single_quote (curline);
+ execlen = strlen (callback) + strlen (qline) + 10;
+ /* 1 for each space between %s and %d,
another 1 for the last nul char for C string. */
- execlen += 2;
+ execlen += 3;
execstr = xmalloc (execlen);
flags = SEVAL_NOHIST;
if (interactive)
flags |= SEVAL_INTERACT;
#endif
- snprintf (execstr, execlen, "%s %d", callback, current_index);
- return parse_and_execute(execstr, NULL, flags);
+ snprintf (execstr, execlen, "%s %d %s", callback, curindex, qline);
+ free (qline);
+ return evalstring (execstr, NULL, flags);
}
static void
builtin_error (_("%s: not an indexed array"), array_name);
return (EXECUTION_FAILURE);
}
+ else if (invisible_p (entry))
+ VUNSETATTR (entry, att_invisible); /* no longer invisible */
if (flags & MAPF_CLEARARRAY)
array_flush (array_cell (entry));
line_length = 0;
/* Reset the buffer for bash own stream */
- interrupt_immediately++;
for (array_index = origin, line_count = 1;
- zgetline (fd, &line, &line_length, unbuffered_read) != -1;
- array_index++, line_count++)
+ zgetline (fd, &line, &line_length, unbuffered_read) != -1;
+ array_index++)
{
- /* Have we exceeded # of lines to store? */
- if (line_count_goal != 0 && line_count > line_count_goal)
- break;
-
/* Remove trailing newlines? */
if (flags & MAPF_CHOP)
do_chop (line);
/* Has a callback been registered and if so is it time to call it? */
if (callback && line_count && (line_count % callback_quantum) == 0)
{
- run_callback (callback, array_index);
+ run_callback (callback, array_index, line);
/* Reset the buffer for bash own stream. */
if (unbuffered_read == 0)
zsyncfd (fd);
}
+ /* XXX - bad things can happen if the callback modifies ENTRY, e.g.,
+ unsetting it or changing it to a non-indexed-array type. */
bind_array_element (entry, array_index, line, 0);
+
+ /* Have we exceeded # of lines to store? */
+ line_count++;
+ if (line_count_goal != 0 && line_count > line_count_goal)
+ break;
}
xfree (line);
if (unbuffered_read == 0)
zsyncfd (fd);
- interrupt_immediately--;
return EXECUTION_SUCCESS;
}