diff options
author | Gregory Nutt <gnutt@nuttx.org> | 2014-01-18 09:39:16 -0600 |
---|---|---|
committer | Gregory Nutt <gnutt@nuttx.org> | 2014-01-18 09:39:16 -0600 |
commit | c9e72e0eed21a1c8c679bc094b0960dabf31c84d (patch) | |
tree | 9ef30c27fc3d15efa8db04cb1112d916316f3998 /apps/nshlib/nsh_parse.c | |
parent | 1cc717520d36623c08f8b60f9cd7fede1bd8f1c1 (diff) | |
download | nuttx-c9e72e0eed21a1c8c679bc094b0960dabf31c84d.tar.gz nuttx-c9e72e0eed21a1c8c679bc094b0960dabf31c84d.tar.bz2 nuttx-c9e72e0eed21a1c8c679bc094b0960dabf31c84d.zip |
NSH: Add a break command; if-then-else and looping behavior can not be configured out of the build for small systems that need minimal scripting capability
Diffstat (limited to 'apps/nshlib/nsh_parse.c')
-rw-r--r-- | apps/nshlib/nsh_parse.c | 86 |
1 files changed, 70 insertions, 16 deletions
diff --git a/apps/nshlib/nsh_parse.c b/apps/nshlib/nsh_parse.c index c7505f34d..9641cd416 100644 --- a/apps/nshlib/nsh_parse.c +++ b/apps/nshlib/nsh_parse.c @@ -160,14 +160,22 @@ static FAR char *nsh_argument(FAR struct nsh_vtbl_s *vtbl, char **saveptr, FAR NSH_MEMLIST_TYPE *memlist); #ifndef CONFIG_NSH_DISABLESCRIPT +#ifndef CONFIG_NSH_DISABLE_LOOPS static bool nsh_loop_enabled(FAR struct nsh_vtbl_s *vtbl); +#endif +#ifndef CONFIG_NSH_DISABLE_ITEF static bool nsh_itef_enabled(FAR struct nsh_vtbl_s *vtbl); +#endif static bool nsh_cmdenabled(FAR struct nsh_vtbl_s *vtbl); +#ifndef CONFIG_NSH_DISABLE_LOOPS static int nsh_loop(FAR struct nsh_vtbl_s *vtbl, FAR char **ppcmd, FAR char **saveptr, FAR NSH_MEMLIST_TYPE *memlist); +#endif +#ifndef CONFIG_NSH_DISABLE_ITEF static int nsh_itef(FAR struct nsh_vtbl_s *vtbl, FAR char **ppcmd, FAR char **saveptr, FAR NSH_MEMLIST_TYPE *memlist); #endif +#endif #ifndef CONFIG_NSH_DISABLEBG static int nsh_nice(FAR struct nsh_vtbl_s *vtbl, FAR char **ppcmd, @@ -396,6 +404,7 @@ static int nsh_saveresult(FAR struct nsh_vtbl_s *vtbl, bool result) struct nsh_parser_s *np = &vtbl->np; #ifndef CONFIG_NSH_DISABLESCRIPT +#ifndef CONFIG_NSH_DISABLE_LOOPS /* Check if we are waiting for the condition associated with a while * token. * @@ -421,16 +430,19 @@ static int nsh_saveresult(FAR struct nsh_vtbl_s *vtbl, bool result) * status. */ - else if (np->np_lpstate[np->np_lpndx].lp_state == NSH_LOOP_UNTIL) + else if (np->np_lpstate[np->np_lpndx].lp_state == NSH_LOOP_UNTIL) { np->np_fail = false; np->np_lpstate[np->np_lpndx].lp_enable = (result != OK); return OK; } + else +#endif +#ifndef CONFIG_NSH_DISABLE_ITEF /* Check if we are waiting for the condition associated with an if token */ - else if (np->np_iestate[np->np_iendx].ie_state == NSH_ITEF_IF) + if (np->np_iestate[np->np_iendx].ie_state == NSH_ITEF_IF) { np->np_fail = false; np->np_iestate[np->np_iendx].ie_ifcond = result; @@ -438,6 +450,7 @@ static int nsh_saveresult(FAR struct nsh_vtbl_s *vtbl, bool result) } else #endif +#endif { np->np_fail = result; return result ? ERROR : OK; @@ -1369,7 +1382,7 @@ static FAR char *nsh_argument(FAR struct nsh_vtbl_s *vtbl, FAR char **saveptr, * Name: nsh_loop_enabled ****************************************************************************/ -#ifndef CONFIG_NSH_DISABLESCRIPT +#if !defined(CONFIG_NSH_DISABLESCRIPT) && !defined(CONFIG_NSH_DISABLE_LOOPS) static bool nsh_loop_enabled(FAR struct nsh_vtbl_s *vtbl) { FAR struct nsh_parser_s *np = &vtbl->np; @@ -1388,13 +1401,15 @@ static bool nsh_loop_enabled(FAR struct nsh_vtbl_s *vtbl) return true; } +#else +# define nsh_loop_enabled(vtbl) true #endif /**************************************************************************** * Name: nsh_itef_enabled ****************************************************************************/ -#ifndef CONFIG_NSH_DISABLESCRIPT +#if !defined(CONFIG_NSH_DISABLESCRIPT) && !defined(CONFIG_NSH_DISABLE_ITEF) static bool nsh_itef_enabled(FAR struct nsh_vtbl_s *vtbl) { FAR struct nsh_parser_s *np = &vtbl->np; @@ -1420,6 +1435,8 @@ static bool nsh_itef_enabled(FAR struct nsh_vtbl_s *vtbl) return ret; } +#else +# define nsh_itef_enabled(vtbl) true #endif /**************************************************************************** @@ -1442,7 +1459,7 @@ static bool nsh_cmdenabled(FAR struct nsh_vtbl_s *vtbl) * Name: nsh_loop ****************************************************************************/ -#ifndef CONFIG_NSH_DISABLESCRIPT +#if !defined(CONFIG_NSH_DISABLESCRIPT) && !defined(CONFIG_NSH_DISABLE_LOOPS) static int nsh_loop(FAR struct nsh_vtbl_s *vtbl, FAR char **ppcmd, FAR char **saveptr, FAR NSH_MEMLIST_TYPE *memlist) { @@ -1476,7 +1493,10 @@ static int nsh_loop(FAR struct nsh_vtbl_s *vtbl, FAR char **ppcmd, /* Verify that "while" or "until" is valid in this context */ - if (np->np_iestate[np->np_iendx].ie_state == NSH_ITEF_IF || + if ( +#ifndef CONFIG_NSH_DISABLE_ITEF + np->np_iestate[np->np_iendx].ie_state == NSH_ITEF_IF || +#endif np->np_lpstate[np->np_lpndx].lp_state == NSH_LOOP_WHILE || np->np_lpstate[np->np_lpndx].lp_state == NSH_LOOP_UNTIL || np->np_stream == NULL || np->np_foffs < 0) @@ -1509,6 +1529,9 @@ static int nsh_loop(FAR struct nsh_vtbl_s *vtbl, FAR char **ppcmd, np->np_lpndx++; np->np_lpstate[np->np_lpndx].lp_state = state; np->np_lpstate[np->np_lpndx].lp_enable = enable; +#ifndef CONFIG_NSH_DISABLE_ITEF + np->np_lpstate[np->np_lpndx].lp_iendx = np->np_iendx; +#endif np->np_lpstate[np->np_lpndx].lp_topoffs = offset; } @@ -1516,14 +1539,9 @@ static int nsh_loop(FAR struct nsh_vtbl_s *vtbl, FAR char **ppcmd, else if (strcmp(cmd, "do") == 0) { - /* Get the cmd following the "do" -- there shouldn't be one */ + /* Get the cmd following the "do" -- there may or may not be one */ *ppcmd = nsh_argument(vtbl, saveptr, memlist); - if (*ppcmd) - { - nsh_output(vtbl, g_fmtarginvalid, "do"); - goto errout; - } /* Verify that "do" is valid in this context */ @@ -1632,7 +1650,7 @@ errout: * Name: nsh_itef ****************************************************************************/ -#ifndef CONFIG_NSH_DISABLESCRIPT +#if !defined(CONFIG_NSH_DISABLESCRIPT) && !defined(CONFIG_NSH_DISABLE_ITEF) static int nsh_itef(FAR struct nsh_vtbl_s *vtbl, FAR char **ppcmd, FAR char **saveptr, FAR NSH_MEMLIST_TYPE *memlist) { @@ -1982,6 +2000,7 @@ static int nsh_parse_command(FAR struct nsh_vtbl_s *vtbl, FAR char *cmdline) cmd = nsh_argument(vtbl, &saveptr, &memlist); #ifndef CONFIG_NSH_DISABLESCRIPT +#ifndef CONFIG_NSH_DISABLE_LOOPS /* Handle while-do-done and until-do-done loops */ if (nsh_loop(vtbl, &cmd, &saveptr, &memlist) != 0) @@ -1989,7 +2008,9 @@ static int nsh_parse_command(FAR struct nsh_vtbl_s *vtbl, FAR char *cmdline) NSH_MEMLIST_FREE(&memlist); return nsh_saveresult(vtbl, true); } +#endif +#ifndef CONFIG_NSH_DISABLE_ITEF /* Handle if-then-else-fi */ if (nsh_itef(vtbl, &cmd, &saveptr, &memlist) != 0) @@ -1997,6 +2018,8 @@ static int nsh_parse_command(FAR struct nsh_vtbl_s *vtbl, FAR char *cmdline) NSH_MEMLIST_FREE(&memlist); return nsh_saveresult(vtbl, true); } + +#endif #endif /* Handle nice */ @@ -2137,7 +2160,7 @@ int nsh_parse(FAR struct nsh_vtbl_s *vtbl, FAR char *cmdline) return nsh_parse_command(vtbl, cmdline); #else -#ifndef CONFIG_NSH_DISABLESCRIPT +#if !defined(CONFIG_NSH_DISABLESCRIPT) && !defined(CONFIG_NSH_DISABLE_LOOPS) FAR struct nsh_parser_s *np = &vtbl->np; #endif FAR char *start = cmdline; @@ -2151,13 +2174,13 @@ int nsh_parse(FAR struct nsh_vtbl_s *vtbl, FAR char *cmdline) * at the top of the loop. */ -#ifndef CONFIG_NSH_DISABLESCRIPT +#if !defined(CONFIG_NSH_DISABLESCRIPT) && !defined(CONFIG_NSH_DISABLE_LOOPS) for (np->np_jump = false; !np->np_jump; ) #else for (;;) #endif { -#ifndef CONFIG_NSH_DISABLESCRIPT +#if !defined(CONFIG_NSH_DISABLESCRIPT) && !defined(CONFIG_NSH_DISABLE_LOOPS) /* Save the offset on the line to the start of the command */ np->np_loffs = (uint16_t)(working - cmdline); @@ -2241,3 +2264,34 @@ int nsh_parse(FAR struct nsh_vtbl_s *vtbl, FAR char *cmdline) #endif #endif } + +/**************************************************************************** + * Name: cmd_break + ****************************************************************************/ + +#if !defined(CONFIG_NSH_DISABLESCRIPT) && !defined(CONFIG_NSH_DISABLE_LOOPS) +int cmd_break(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv) +{ + FAR struct nsh_parser_s *np = &vtbl->np; + + /* Break outside of a loop is ignored */ + + if (np->np_lpstate[np->np_lpndx].lp_state == NSH_LOOP_DO) + { +#ifndef CONFIG_NSH_DISABLE_ITEF + /* Yes... pop the original if-then-else-if state */ + + np->np_iendx = np->np_lpstate[np->np_lpndx].lp_iendx; +#endif + /* Disable all command processing until 'done' is encountered. */ + + np->np_lpstate[np->np_lpndx].lp_enable = false; + } + + /* No syntax errors are detected(?). Break is a nop everywhere except + * the supported context. + */ + + return OK; +} +#endif |