From 516a7433444ad4234c468c9729bf9990f4752e65 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Sat, 11 Aug 2018 07:53:22 -0600 Subject: [PATCH] =?UTF-8?q?apps/nshlib:=20=20Extend=20=20Beat=20K=C3=BCng'?= =?UTF-8?q?s=20commit=20888ad352eb41b656d271183b563142472ad712ad=20so=20th?= =?UTF-8?q?at=20inverted=20logic=20may=20also=20be=20used=20in=20repeat=20?= =?UTF-8?q?and=20while=20loops.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- nshlib/README.txt | 8 ++++---- nshlib/nsh.h | 3 ++- nshlib/nsh_parse.c | 51 ++++++++++++++++++++++++++++++++++------------ 3 files changed, 44 insertions(+), 18 deletions(-) diff --git a/nshlib/README.txt b/nshlib/README.txt index 68b5d7852..926fda85a 100644 --- a/nshlib/README.txt +++ b/nshlib/README.txt @@ -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 ; do ; done + while [!] ; do ; done Execute as long as has an exit status of - zero. + zero (OR nonzero if inverted with '!'). - until ; do ; done + until [!] ; do ; done Execute as long as 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 diff --git a/nshlib/nsh.h b/nshlib/nsh.h index 187cc5696..018badcdb 100644 --- a/nshlib/nsh.h +++ b/nshlib/nsh.h @@ -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 ! ') */ + 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 */ diff --git a/nshlib/nsh_parse.c b/nshlib/nsh_parse.c index c25e9ae6d..4abe135a1 100644 --- a/nshlib/nsh_parse.c +++ b/nshlib/nsh_parse.c @@ -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" */