aboutsummaryrefslogtreecommitdiffhomepage
path: root/exec.cpp
diff options
context:
space:
mode:
authorGravatar ridiculousfish <corydoras@ridiculousfish.com>2013-12-27 01:38:43 -0800
committerGravatar ridiculousfish <corydoras@ridiculousfish.com>2013-12-27 01:38:43 -0800
commit6ce4b344e45baaa06bf593a5c0983da7a22eb64e (patch)
tree2358b60e771c42d29aeb26a03dd95f22cbd8ca15 /exec.cpp
parenta6ca809a4e4873f3fd16e4a763001a109afc2185 (diff)
Hook up for statements, if statements, and function definition in new
parser
Diffstat (limited to 'exec.cpp')
-rw-r--r--exec.cpp51
1 files changed, 38 insertions, 13 deletions
diff --git a/exec.cpp b/exec.cpp
index 6d7a19e8..c1fb54be 100644
--- a/exec.cpp
+++ b/exec.cpp
@@ -394,12 +394,13 @@ static void io_cleanup_fds(const std::vector<int> &opened_fds)
repeatedly reopened for every command in the block, which would
reset the cursor position.
- \return the transmogrified chain on sucess, or 0 on failiure
+ \return true on success, false on failure. Returns the output chain and opened_fds by reference
*/
-static bool io_transmogrify(const io_chain_t &in_chain, io_chain_t &out_chain, std::vector<int> &out_opened_fds)
+static bool io_transmogrify(const io_chain_t &in_chain, io_chain_t *out_chain, std::vector<int> *out_opened_fds)
{
ASSERT_IS_MAIN_THREAD();
- assert(out_chain.empty());
+ assert(out_chain != NULL && out_opened_fds != NULL);
+ assert(out_chain->empty());
/* Just to be clear what we do for an empty chain */
if (in_chain.empty())
@@ -479,8 +480,8 @@ static bool io_transmogrify(const io_chain_t &in_chain, io_chain_t &out_chain, s
if (success)
{
/* Yay */
- out_chain.swap(result_chain);
- out_opened_fds.swap(opened_fds);
+ out_chain->swap(result_chain);
+ out_opened_fds->swap(opened_fds);
}
else
{
@@ -496,19 +497,24 @@ static bool io_transmogrify(const io_chain_t &in_chain, io_chain_t &out_chain, s
Morph an io redirection chain into redirections suitable for
passing to eval, call eval, and clean up morphed redirections.
- \param def the code to evaluate
+ \param def the code to evaluate, or the empty string if none
+ \param node_offset the offset of the node to evalute, or NODE_OFFSET_INVALID
\param block_type the type of block to push on evaluation
\param io the io redirections to be performed on this block
*/
static void internal_exec_helper(parser_t &parser,
- const wchar_t *def,
+ const wcstring &def,
+ node_offset_t node_offset,
enum block_type_t block_type,
const io_chain_t &ios)
{
+ // If we have a valid node offset, then we must not have a string to execute
+ assert(node_offset == NODE_OFFSET_INVALID || def.empty());
+
io_chain_t morphed_chain;
std::vector<int> opened_fds;
- bool transmorgrified = io_transmogrify(ios, morphed_chain, opened_fds);
+ bool transmorgrified = io_transmogrify(ios, &morphed_chain, &opened_fds);
int is_block_old=is_block;
is_block=1;
@@ -524,7 +530,14 @@ static void internal_exec_helper(parser_t &parser,
signal_unblock();
- parser.eval(def, morphed_chain, block_type);
+ if (node_offset == NODE_OFFSET_INVALID)
+ {
+ parser.eval(def, morphed_chain, block_type);
+ }
+ else
+ {
+ parser.eval_block_node(node_offset, morphed_chain, block_type);
+ }
signal_block();
@@ -926,7 +939,7 @@ void exec_job(parser_t &parser, job_t *j)
if (! exec_error)
{
- internal_exec_helper(parser, def.c_str(), TOP, process_net_io_chain);
+ internal_exec_helper(parser, def, NODE_OFFSET_INVALID, TOP, process_net_io_chain);
}
parser.allow_function();
@@ -936,12 +949,14 @@ void exec_job(parser_t &parser, job_t *j)
}
case INTERNAL_BLOCK:
+ case INTERNAL_BLOCK_NODE:
{
if (p->next)
{
block_output_io_buffer.reset(io_buffer_t::create(0));
if (block_output_io_buffer.get() == NULL)
{
+ /* We failed (e.g. no more fds could be created). */
exec_error = true;
job_mark_process_as_failed(j, p);
}
@@ -954,12 +969,21 @@ void exec_job(parser_t &parser, job_t *j)
if (! exec_error)
{
- internal_exec_helper(parser, p->argv0(), TOP, process_net_io_chain);
+ if (p->type == INTERNAL_BLOCK)
+ {
+ /* The block contents (as in, fish code) are stored in argv0 (ugh) */
+ assert(p->argv0() != NULL);
+ internal_exec_helper(parser, p->argv0(), NODE_OFFSET_INVALID, TOP, process_net_io_chain);
+ }
+ else
+ {
+ assert(p->type == INTERNAL_BLOCK_NODE);
+ internal_exec_helper(parser, wcstring(), p->internal_block_node, TOP, process_net_io_chain);
+ }
}
break;
-
}
-
+
case INTERNAL_BUILTIN:
{
int builtin_stdin=0;
@@ -1115,6 +1139,7 @@ void exec_job(parser_t &parser, job_t *j)
{
case INTERNAL_BLOCK:
+ case INTERNAL_BLOCK_NODE:
case INTERNAL_FUNCTION:
{
int status = proc_get_last_status();