diff --git NuttX/apps/nshlib/nsh_parse.c NuttX/apps/nshlib/nsh_parse.c index 30f7ef5..f6fa2e0 100644 --- NuttX/apps/nshlib/nsh_parse.c +++ NuttX/apps/nshlib/nsh_parse.c @@ -156,9 +156,9 @@ static FAR char *nsh_envexpand(FAR struct nsh_vtbl_s *vtbl, #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 @@ -1009,7 +1009,7 @@ static FAR char *nsh_envexpand(FAR struct nsh_vtbl_s *vtbl, #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; FAR char *argument = NULL; @@ -1128,8 +1128,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. */ @@ -1167,6 +1167,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); /* Concatenate the result of the operation with the accumulated @@ -1187,7 +1191,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; @@ -1223,6 +1227,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 @@ -1245,7 +1252,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; @@ -1317,6 +1324,13 @@ 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 argument should CONFIG_NSH_ENABLEPX4PARSING be defined + * So just invalidate the flag pointer which would otherwise communictate such + * back up the call tree. + */ + isenvvar = NULL; } else { @@ -1376,11 +1390,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. */ @@ -1497,7 +1511,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) { nsh_output(vtbl, g_fmtarginvalid, "if"); @@ -1554,7 +1568,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 */ @@ -1574,7 +1588,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_output(vtbl, g_fmtarginvalid, "done"); @@ -1679,7 +1693,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) { nsh_output(vtbl, g_fmtarginvalid, "if"); @@ -1717,7 +1731,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 */ @@ -1736,7 +1750,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 */ @@ -1755,7 +1769,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_output(vtbl, g_fmtarginvalid, "fi"); @@ -1827,10 +1841,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; @@ -1841,7 +1855,7 @@ static int nsh_nice(FAR struct nsh_vtbl_s *vtbl, FAR char **ppcmd, nsh_output(vtbl, g_fmtarginvalid, "nice"); return ERROR; } - cmd = nsh_argument(vtbl, saveptr, memlist); + cmd = nsh_argument(vtbl, saveptr, memlist, 0); } } @@ -1909,7 +1923,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. @@ -1943,7 +1957,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; @@ -2010,7 +2024,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 @@ -2078,15 +2092,54 @@ static int nsh_parse_command(FAR struct nsh_vtbl_s *vtbl, FAR char *cmdline) */ argv[0] = cmd; + +#define CONFIG_NSH_ENABLEPX4PARSING + 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; } + +#ifdef CONFIG_NSH_ENABLEPX4PARSING + if (isenvvar) + { + while (argc < MAX_ARGV_ENTRIES-1) /* TODO: check this bounds check is correct */ + { + 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; + } + } +#endif /* CONFIG_NSH_ENABLEPX4PARSING */ } + /* Last argument vector must be empty */ argv[argc] = NULL; /* Check if the command should run in background */