/* 3.9.4.1 parse a grouping compound * * The format for grouping commands is a s follows: * * (compound-list) Execute compound-list in a subshell environment; * Variable assignments and built-in commands that * affect the environment shall not remain in effect * after the list finishes. * * { compound-list;} Execute compound-list in the current process * environment. * * ----------------------------------------------------------------------- */ union node *parse_grouping(struct parser *p) { enum tok_flag tok; union node **rptr; union node *grouping; union node *compound_list; /* return NULL on empty compound */ grouping = NULL; if(!(tok = parse_expect(p, P_DEFAULT, T_BEGIN|T_LP, NULL))) return NULL; /* parse compound content and create a compound node if there are commands */ if((compound_list = parse_compound_list(p))) { grouping = tree_newnode(tok == T_BEGIN ? N_CMDLIST : N_SUBSHELL); grouping->ngrp.cmds = compound_list; } /* expect the appropriate ending token */ if(!parse_expect(p, P_DEFAULT, tok << 1, grouping)) return NULL; if(grouping) { tree_init(grouping->ngrp.rdir, rptr); /* now any redirections may follow */ while(parse_gettok(p, P_DEFAULT) & T_REDIR) tree_move(p->tree, rptr); p->pushback++; } return grouping; }
/* parse a compound- or a simple-command * (pipeline and lists are done outside this) * ----------------------------------------------------------------------- */ union node *parse_command(struct parser *p, int tempflags) { enum tok_flag tok; union node *command; union node **rptr; tok = parse_gettok(p, tempflags); switch(tok) { /* T_FOR begins an iteration statement */ case T_FOR: command = parse_for(p); break; /* T_IF begins a case match statement */ case T_CASE: command = parse_case(p); break; /* T_IF begins a conditional statement */ case T_IF: command = parse_if(p); break; /* T_WHILE/T_UNTIL begin a for-loop statement */ case T_WHILE: case T_UNTIL: command = parse_loop(p); break; /* T_LP/T_BEGIN start a grouping compound */ case T_LP: case T_BEGIN: p->pushback++; command = parse_grouping(p); break; /* handle simple commands */ case T_NAME: case T_WORD: case T_REDIR: case T_ASSIGN: p->pushback++; command = parse_simple_command(p); break; /* it wasn't a compound command, return now */ default: p->pushback++; return NULL; } if(command) { /* they all can have redirections, so parse these now */ rptr = &command->ncmd.rdir; /* * in the case of a simple command there are maybe already * redirections in the list (because in a simple command they * can appear between arguments), so skip to the end of the list. */ while(*rptr) tree_next(rptr); while(parse_gettok(p, P_DEFAULT) & T_REDIR) tree_move(p->tree, rptr); } p->pushback++; return command; }
static cb_ret_t tree_execute_cmd (WTree * tree, long command) { cb_ret_t res = MSG_HANDLED; if (command != CK_Search) tree->searching = 0; switch (command) { case CK_Help: { ev_help_t event_data = { NULL, "[Directory Tree]" }; mc_event_raise (MCEVENT_GROUP_CORE, "help", &event_data); } break; case CK_Forget: tree_forget (tree); break; case CK_ToggleNavigation: tree_toggle_navig (tree); break; case CK_Copy: tree_copy (tree, ""); break; case CK_Move: tree_move (tree, ""); break; case CK_Up: tree_move_up (tree); break; case CK_Down: tree_move_down (tree); break; case CK_Top: tree_move_home (tree); break; case CK_Bottom: tree_move_end (tree); break; case CK_PageUp: tree_move_pgup (tree); break; case CK_PageDown: tree_move_pgdn (tree); break; case CK_Enter: tree_chdir_sel (tree); break; case CK_Reread: tree_rescan (tree); break; case CK_Search: tree_start_search (tree); break; case CK_Delete: tree_rmdir (tree); break; case CK_Quit: if (!tree->is_panel) dlg_stop (WIDGET (tree)->owner); return res; default: res = MSG_NOT_HANDLED; } show_tree (tree); return res; }
static void tree_move_cmd (void *data) { WTree *tree = data; tree_move (tree, ""); }