Implement $(cmd) subcommand syntax in commands (issue #27)
Add $() for inline subcommand substitution that runs a command and
inserts its stdout (trailing newlines stripped) into the outer command
string. Supports nesting, and mixing with ${expr} and $NAME.
This commit is contained in:
21
llex.c
21
llex.c
@@ -193,6 +193,7 @@ void luaX_setinput (lua_State *L, LexState *ls, ZIO *z, TString *source,
|
||||
so they cannot be collected */
|
||||
ls->cmd_mode = 0;
|
||||
ls->cmd_envvar = NULL;
|
||||
ls->cmd_subcmd = 0;
|
||||
ls->envn = luaS_newliteral(L, LUA_ENV); /* get env string */
|
||||
ls->brkn = luaS_newliteral(L, "break"); /* get "break" string */
|
||||
#if defined(LUA_COMPAT_GLOBAL)
|
||||
@@ -516,6 +517,15 @@ static int read_command_body (LexState *ls, SemInfo *seminfo) {
|
||||
ls->saved_cmd_mode = ls->cmd_mode; /* save for readcommandcont */
|
||||
return interactive ? TK_INTERACTIVE : TK_COMMAND;
|
||||
}
|
||||
else if (ls->current == '(') {
|
||||
next(ls); /* skip '(' */
|
||||
/* $() subcommand interpolation */
|
||||
seminfo->ts = luaX_newstring(ls, luaZ_buffer(ls->buff),
|
||||
luaZ_bufflen(ls->buff));
|
||||
ls->saved_cmd_mode = ls->cmd_mode;
|
||||
ls->cmd_subcmd = 1;
|
||||
return interactive ? TK_INTERACTIVE : TK_COMMAND;
|
||||
}
|
||||
else if (lislalpha(ls->current)) {
|
||||
/* $NAME envvar expansion */
|
||||
seminfo->ts = luaX_newstring(ls, luaZ_buffer(ls->buff),
|
||||
@@ -532,6 +542,17 @@ static int read_command_body (LexState *ls, SemInfo *seminfo) {
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ')': {
|
||||
if (ls->cmd_mode == 3) {
|
||||
next(ls); /* skip closing ')' */
|
||||
seminfo->ts = luaX_newstring(ls, luaZ_buffer(ls->buff),
|
||||
luaZ_bufflen(ls->buff));
|
||||
ls->cmd_mode = 0;
|
||||
return TK_COMMAND;
|
||||
}
|
||||
save_and_next(ls); /* literal ')' in non-subcommand mode */
|
||||
break;
|
||||
}
|
||||
case '`': {
|
||||
if (interactive) {
|
||||
/* backtick is literal in interactive mode */
|
||||
|
||||
Reference in New Issue
Block a user