Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] upstream nshlib add var expansion in nsh parse #4

Closed
wants to merge 1 commit into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
98 changes: 74 additions & 24 deletions nshlib/nsh_parse.c
Original file line number Diff line number Diff line change
Expand Up @@ -170,9 +170,9 @@ static void nsh_dequote(FAR char *cmdline);
#endif

static FAR char *nsh_argexpand(FAR struct nsh_vtbl_s *vtbl, FAR char *cmdline,
FAR char **allocation);
FAR char **allocation, int* isenvvar);
static FAR char *nsh_argument(FAR struct nsh_vtbl_s *vtbl, char **saveptr,
FAR NSH_MEMLIST_TYPE *memlist);
FAR NSH_MEMLIST_TYPE *memlist, int* isenvvar);

#ifndef CONFIG_NSH_DISABLESCRIPT
#ifndef CONFIG_NSH_DISABLE_LOOPS
Expand Down Expand Up @@ -1122,7 +1122,7 @@ static void nsh_dequote(FAR char *cmdline)

#if defined(CONFIG_NSH_ARGCAT) && defined(HAVE_MEMLIST)
static FAR char *nsh_argexpand(FAR struct nsh_vtbl_s *vtbl, FAR char *cmdline,
FAR char **allocation)
FAR char **allocation, int* isenvvar)
{
FAR char *working = cmdline;
#ifdef CONFIG_NSH_QUOTE
Expand Down Expand Up @@ -1285,8 +1285,8 @@ static FAR char *nsh_argexpand(FAR struct nsh_vtbl_s *vtbl, FAR char *cmdline,
*allocation = argument;

/* Find the end of the environment variable reference. If the
* dollar sign ('$') is followed by a right bracket ('{') then the
* variable name is terminated with the left bracket character
* dollar sign ('$') is followed by a left bracket ('{') then the
* variable name is terminated with the right bracket character
* ('}'). Otherwise, the variable name goes to the end of the
* argument.
*/
Expand Down Expand Up @@ -1329,6 +1329,10 @@ static FAR char *nsh_argexpand(FAR struct nsh_vtbl_s *vtbl, FAR char *cmdline,
* nsh_envexpand will return the NULL string.
*/

if (isenvvar) {
*isenvvar = 1;
}

envstr = nsh_envexpand(vtbl, ptr);

#ifndef CONFIG_NSH_DISABLESCRIPT
Expand Down Expand Up @@ -1364,7 +1368,7 @@ static FAR char *nsh_argexpand(FAR struct nsh_vtbl_s *vtbl, FAR char *cmdline,

#else
static FAR char *nsh_argexpand(FAR struct nsh_vtbl_s *vtbl, FAR char *cmdline,
FAR char **allocation)
FAR char **allocation, int* isenvvar)
{
FAR char *argument = (FAR char *)g_nullstring;
#ifdef CONFIG_NSH_QUOTE
Expand Down Expand Up @@ -1414,6 +1418,9 @@ static FAR char *nsh_argexpand(FAR struct nsh_vtbl_s *vtbl, FAR char *cmdline,

if (*cmdline == '$')
{
if (isenvvar) {
*isenvvar = 1;
}
argument = nsh_envexpand(vtbl, cmdline + 1);
}
else
Expand All @@ -1435,7 +1442,7 @@ static FAR char *nsh_argexpand(FAR struct nsh_vtbl_s *vtbl, FAR char *cmdline,
****************************************************************************/

static FAR char *nsh_argument(FAR struct nsh_vtbl_s *vtbl, FAR char **saveptr,
FAR NSH_MEMLIST_TYPE *memlist)
FAR NSH_MEMLIST_TYPE *memlist, int* isenvvar)
{
FAR char *pbegin = *saveptr;
FAR char *pend = NULL;
Expand Down Expand Up @@ -1512,6 +1519,12 @@ static FAR char *nsh_argument(FAR struct nsh_vtbl_s *vtbl, FAR char **saveptr,

pbegin++;
term = "\"";

/* If this is an environment variable in double quotes, we don't want it split into
* multiple arguments. So just invalidate the flag pointer which would otherwise
* communictate such back up the call tree.
*/
isenvvar = NULL;
}
else
{
Expand Down Expand Up @@ -1676,11 +1689,11 @@ static FAR char *nsh_argument(FAR struct nsh_vtbl_s *vtbl, FAR char **saveptr,

/* Perform expansions as necessary for the argument */

argument = nsh_argexpand(vtbl, pbegin, &allocation);
argument = nsh_argexpand(vtbl, pbegin, &allocation, isenvvar);
}

/* If any memory was allocated for this argument, make sure that it is
* added to the list of memory to be freed at the end of commend
* added to the list of memory to be freed at the end of command
* processing.
*/

Expand Down Expand Up @@ -1797,7 +1810,7 @@ static int nsh_loop(FAR struct nsh_vtbl_s *vtbl, FAR char **ppcmd,

/* Get the cmd following the "while" or "until" */

*ppcmd = nsh_argument(vtbl, saveptr, memlist);
*ppcmd = nsh_argument(vtbl, saveptr, memlist, 0);
if (*ppcmd == NULL || **ppcmd == '\0')
{
nsh_error(vtbl, g_fmtarginvalid, cmd);
Expand Down Expand Up @@ -1854,7 +1867,7 @@ static int nsh_loop(FAR struct nsh_vtbl_s *vtbl, FAR char **ppcmd,
{
/* Get the cmd following the "do" -- there may or may not be one */

*ppcmd = nsh_argument(vtbl, saveptr, memlist);
*ppcmd = nsh_argument(vtbl, saveptr, memlist, 0);

/* Verify that "do" is valid in this context */

Expand All @@ -1874,7 +1887,7 @@ static int nsh_loop(FAR struct nsh_vtbl_s *vtbl, FAR char **ppcmd,
{
/* Get the cmd following the "done" -- there should be one */

*ppcmd = nsh_argument(vtbl, saveptr, memlist);
*ppcmd = nsh_argument(vtbl, saveptr, memlist, 0);
if (*ppcmd)
{
nsh_error(vtbl, g_fmtarginvalid, "done");
Expand Down Expand Up @@ -1980,7 +1993,7 @@ static int nsh_itef(FAR struct nsh_vtbl_s *vtbl, FAR char **ppcmd,
{
/* Get the cmd following the if */

*ppcmd = nsh_argument(vtbl, saveptr, memlist);
*ppcmd = nsh_argument(vtbl, saveptr, memlist, 0);
if (*ppcmd == NULL || **ppcmd == '\0')
{
nsh_error(vtbl, g_fmtarginvalid, "if");
Expand All @@ -1995,7 +2008,7 @@ static int nsh_itef(FAR struct nsh_vtbl_s *vtbl, FAR char **ppcmd,

/* Get the next cmd */

*ppcmd = nsh_argument(vtbl, saveptr, memlist);
*ppcmd = nsh_argument(vtbl, saveptr, memlist, 0);
if (*ppcmd == NULL || **ppcmd == '\0')
{
nsh_error(vtbl, g_fmtarginvalid, "if");
Expand Down Expand Up @@ -2035,7 +2048,7 @@ static int nsh_itef(FAR struct nsh_vtbl_s *vtbl, FAR char **ppcmd,
{
/* Get the cmd following the "then" -- there may or may not be one */

*ppcmd = nsh_argument(vtbl, saveptr, memlist);
*ppcmd = nsh_argument(vtbl, saveptr, memlist, 0);

/* Verify that "then" is valid in this context */

Expand All @@ -2054,7 +2067,7 @@ static int nsh_itef(FAR struct nsh_vtbl_s *vtbl, FAR char **ppcmd,
{
/* Get the cmd following the "else" -- there may or may not be one */

*ppcmd = nsh_argument(vtbl, saveptr, memlist);
*ppcmd = nsh_argument(vtbl, saveptr, memlist, 0);

/* Verify that "else" is valid in this context */

Expand All @@ -2073,7 +2086,7 @@ static int nsh_itef(FAR struct nsh_vtbl_s *vtbl, FAR char **ppcmd,
{
/* Get the cmd following the fi -- there should be one */

*ppcmd = nsh_argument(vtbl, saveptr, memlist);
*ppcmd = nsh_argument(vtbl, saveptr, memlist, 0);
if (*ppcmd)
{
nsh_error(vtbl, g_fmtarginvalid, "fi");
Expand Down Expand Up @@ -2146,10 +2159,10 @@ static int nsh_nice(FAR struct nsh_vtbl_s *vtbl, FAR char **ppcmd,

/* Get the cmd (or -d option of nice command) */

cmd = nsh_argument(vtbl, saveptr, memlist);
cmd = nsh_argument(vtbl, saveptr, memlist, 0);
if (cmd && strcmp(cmd, "-d") == 0)
{
FAR char *val = nsh_argument(vtbl, saveptr, memlist);
FAR char *val = nsh_argument(vtbl, saveptr, memlist, 0);
if (val)
{
char *endptr;
Expand All @@ -2160,7 +2173,7 @@ static int nsh_nice(FAR struct nsh_vtbl_s *vtbl, FAR char **ppcmd,
nsh_error(vtbl, g_fmtarginvalid, "nice");
return ERROR;
}
cmd = nsh_argument(vtbl, saveptr, memlist);
cmd = nsh_argument(vtbl, saveptr, memlist, 0);
}
}

Expand Down Expand Up @@ -2230,7 +2243,7 @@ static int nsh_parse_cmdparm(FAR struct nsh_vtbl_s *vtbl, FAR char *cmdline,
/* Parse out the command at the beginning of the line */

saveptr = cmdline;
cmd = nsh_argument(vtbl, &saveptr, &memlist);
cmd = nsh_argument(vtbl, &saveptr, &memlist, 0);

/* Check if any command was provided -OR- if command processing is
* currently disabled.
Expand Down Expand Up @@ -2264,7 +2277,7 @@ static int nsh_parse_cmdparm(FAR struct nsh_vtbl_s *vtbl, FAR char *cmdline,
argv[0] = cmd;
for (argc = 1; argc < MAX_ARGV_ENTRIES-1; argc++)
{
argv[argc] = nsh_argument(vtbl, &saveptr, &memlist);
argv[argc] = nsh_argument(vtbl, &saveptr, &memlist, 0);
if (!argv[argc])
{
break;
Expand Down Expand Up @@ -2331,7 +2344,7 @@ static int nsh_parse_command(FAR struct nsh_vtbl_s *vtbl, FAR char *cmdline)
/* Parse out the command at the beginning of the line */

saveptr = cmdline;
cmd = nsh_argument(vtbl, &saveptr, &memlist);
cmd = nsh_argument(vtbl, &saveptr, &memlist, 0);

#ifndef CONFIG_NSH_DISABLESCRIPT
#ifndef CONFIG_NSH_DISABLE_LOOPS
Expand Down Expand Up @@ -2401,13 +2414,50 @@ static int nsh_parse_command(FAR struct nsh_vtbl_s *vtbl, FAR char *cmdline)
argv[0] = cmd;
for (argc = 1; argc < MAX_ARGV_ENTRIES-1; argc++)
{
argv[argc] = nsh_argument(vtbl, &saveptr, &memlist);

int isenvvar = 0; /* flag for if an enviroment variable gets expanded */

argv[argc] = nsh_argument(vtbl, &saveptr, &memlist, &isenvvar);

if (!argv[argc])
{
break;
}

if (isenvvar)
{
while (argc < MAX_ARGV_ENTRIES-1)
{
FAR char *pbegin = argv[argc];

/* Find the end of the current token */
for (; *pbegin && !strchr(g_token_separator, *pbegin); pbegin++);

/* If end of string, we've processed the last token and we're done */
if ('\0' == *pbegin)
{
break;
}

/* Terminate the token to complete the argv variable */
*pbegin = '\0';

/* We've inserted an extra parameter, so bump the count */
argc++;

/* Move to the next character in the string of tokens */
pbegin++;

/* Throw away any extra separator chars between tokens */
for (; *pbegin && strchr(g_token_separator, *pbegin) != NULL; pbegin++);

/* Prepare to loop again on the next argument token */
argv[argc] = pbegin;
}
}
}

/* Last argument vector must be empty */
argv[argc] = NULL;

/* Check if the command should run in background */
Expand Down