apps/nshlib: Extend Beat Küng's commit 888ad352eb so that inverted logic may also be used in repeat and while loops.

This commit is contained in:
Gregory Nutt 2018-08-11 07:53:22 -06:00
parent 888ad352eb
commit 516a743344
3 changed files with 44 additions and 18 deletions

View File

@ -114,15 +114,15 @@ Looping
These works from the command line but are primarily intended for use
within NSH scripts (see the sh command). The syntax is as follows:
while <test-cmd>; do <cmd-sequence>; done
while [!] <test-cmd>; do <cmd-sequence>; done
Execute <cmd-sequence> as long as <test-cmd> has an exit status of
zero.
zero (OR nonzero if inverted with '!').
until <test-cmd>; do <cmd-sequence>; done
until [!] <test-cmd>; do <cmd-sequence>; done
Execute <cmd-sequence> as long as <test-cmd> has a non-zero exit
status.
status (OR nonzero if inverted with '!').
A break command is also supported. The break command is only meaningful
within the body of the a while or until loop, between the do and done

View File

@ -776,7 +776,8 @@ enum nsh_lp_e
struct nsh_loop_s
{
uint8_t lp_enable : 1; /* Loop command processing is enabled */
uint8_t lp_unused : 5;
uint8_t lp_inverted : 1; /* TRUE: inverted logic ('while ! <cmd>') */
uint8_t lp_unused : 4;
uint8_t lp_state : 2; /* Loop state (see enume nsh_lp_e) */
#ifndef CONFIG_NSH_DISABLE_ITEF
uint8_t lp_iendx; /* Saved if-then-else-fi index */

View File

@ -439,6 +439,8 @@ static int nsh_saveresult(FAR struct nsh_vtbl_s *vtbl, bool result)
if (np->np_lpstate[np->np_lpndx].lp_state == NSH_LOOP_WHILE)
{
result ^= np->np_lpstate[np->np_lpndx].lp_inverted;
np->np_fail = false;
np->np_lpstate[np->np_lpndx].lp_enable = (result == OK);
return OK;
@ -455,6 +457,8 @@ static int nsh_saveresult(FAR struct nsh_vtbl_s *vtbl, bool result)
else if (np->np_lpstate[np->np_lpndx].lp_state == NSH_LOOP_UNTIL)
{
result ^= np->np_lpstate[np->np_lpndx].lp_inverted;
np->np_fail = false;
np->np_lpstate[np->np_lpndx].lp_enable = (result != OK);
return OK;
@ -1770,6 +1774,7 @@ static int nsh_loop(FAR struct nsh_vtbl_s *vtbl, FAR char **ppcmd,
bool whilematch;
bool untilmatch;
bool enable;
bool inverted = false;
int ret;
if (cmd)
@ -1788,10 +1793,26 @@ static int nsh_loop(FAR struct nsh_vtbl_s *vtbl, FAR char **ppcmd,
*ppcmd = nsh_argument(vtbl, saveptr, memlist);
if (!*ppcmd)
{
nsh_output(vtbl, g_fmtarginvalid, "if");
nsh_output(vtbl, g_fmtarginvalid, cmd);
goto errout;
}
/* Check for inverted logic */
if (strcmp(*ppcmd, "!") == 0)
{
inverted = true;
/* Get the next cmd */
*ppcmd = nsh_argument(vtbl, saveptr, memlist);
if (!*ppcmd)
{
nsh_output(vtbl, g_fmtarginvalid, cmd);
goto errout;
}
}
/* Verify that "while" or "until" is valid in this context */
if (
@ -1828,12 +1849,13 @@ static int nsh_loop(FAR struct nsh_vtbl_s *vtbl, FAR char **ppcmd,
np->np_jump = false;
#endif
np->np_lpndx++;
np->np_lpstate[np->np_lpndx].lp_state = state;
np->np_lpstate[np->np_lpndx].lp_enable = enable;
np->np_lpstate[np->np_lpndx].lp_state = state;
np->np_lpstate[np->np_lpndx].lp_enable = enable;
np->np_lpstate[np->np_lpndx].lp_inverted = inverted;
#ifndef CONFIG_NSH_DISABLE_ITEF
np->np_lpstate[np->np_lpndx].lp_iendx = np->np_iendx;
np->np_lpstate[np->np_lpndx].lp_iendx = np->np_iendx;
#endif
np->np_lpstate[np->np_lpndx].lp_topoffs = offset;
np->np_lpstate[np->np_lpndx].lp_topoffs = offset;
}
/* Check if the token is "do" */
@ -1937,12 +1959,13 @@ static int nsh_loop(FAR struct nsh_vtbl_s *vtbl, FAR char **ppcmd,
errout:
#ifndef NSH_DISABLE_SEMICOLON
np->np_jump = false;
np->np_jump = false;
#endif
np->np_lpndx = 0;
np->np_lpstate[0].lp_state = NSH_LOOP_NORMAL;
np->np_lpstate[0].lp_enable = true;
np->np_lpstate[0].lp_topoffs = 0;
np->np_lpndx = 0;
np->np_lpstate[0].lp_state = NSH_LOOP_NORMAL;
np->np_lpstate[0].lp_enable = true;
np->np_lpstate[0].lp_inverted = false;
np->np_lpstate[0].lp_topoffs = 0;
return ERROR;
}
#endif
@ -1958,7 +1981,7 @@ static int nsh_itef(FAR struct nsh_vtbl_s *vtbl, FAR char **ppcmd,
FAR struct nsh_parser_s *np = &vtbl->np;
FAR char *cmd = *ppcmd;
bool disabled;
bool inverted_result = false;
bool inverted = false;
if (cmd)
{
@ -1976,11 +1999,13 @@ static int nsh_itef(FAR struct nsh_vtbl_s *vtbl, FAR char **ppcmd,
}
/* Check for inverted logic */
if (strcmp(*ppcmd, "!") == 0)
{
inverted_result = true;
inverted = true;
/* Get the next cmd */
*ppcmd = nsh_argument(vtbl, saveptr, memlist);
if (!*ppcmd)
{
@ -2012,7 +2037,7 @@ static int nsh_itef(FAR struct nsh_vtbl_s *vtbl, FAR char **ppcmd,
np->np_iestate[np->np_iendx].ie_state = NSH_ITEF_IF;
np->np_iestate[np->np_iendx].ie_disabled = disabled;
np->np_iestate[np->np_iendx].ie_ifcond = false;
np->np_iestate[np->np_iendx].ie_inverted = inverted_result;
np->np_iestate[np->np_iendx].ie_inverted = inverted;
}
/* Check if the token is "then" */