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
This commit is contained in:
parent
45121c8709
commit
612d8ed14c
@ -796,4 +796,9 @@
|
|||||||
a command to be on the same line as the then and else tokens like:
|
a command to be on the same line as the then and else tokens like:
|
||||||
"if true; then echo true; else echo false; fi". Much more like bash!
|
"if true; then echo true; else echo false; fi". Much more like bash!
|
||||||
(2014-1-17).
|
(2014-1-17).
|
||||||
|
* apps/nshlib/Kconfig, README.txt, nsh.h, nsh_command.c, and
|
||||||
|
nsh_script.c: Add an option to conditionally compile out support for
|
||||||
|
loop and for if-then-else-fi sequence (2014-1-17).
|
||||||
|
* apps/nshlib/nsh.h, nsh_command.c, and nsh_parse.c: Add a break
|
||||||
|
command that can be executed with a loop to terminate the loop
|
||||||
|
immediately (2014-1-17).
|
||||||
|
@ -345,6 +345,27 @@ config NSH_DISABLESCRIPT
|
|||||||
if-then[-else]-fi construct. This would only be set on systems
|
if-then[-else]-fi construct. This would only be set on systems
|
||||||
where a minimal footprint is a necessity and scripting is not.
|
where a minimal footprint is a necessity and scripting is not.
|
||||||
|
|
||||||
|
if !NSH_DISABLESCRIPT
|
||||||
|
|
||||||
|
config NSH_DISABLE_ITEF
|
||||||
|
bool "Disable if-then-else-fi"
|
||||||
|
default n
|
||||||
|
---help---
|
||||||
|
This can be set to 'y' to suppress support for if-then-else-fi
|
||||||
|
sequences in scripts. This would only be set on systems where
|
||||||
|
some minimal scripting is required but if-then-else-fi is not.
|
||||||
|
|
||||||
|
config NSH_DISABLE_LOOPS
|
||||||
|
bool "Disable loops"
|
||||||
|
default n
|
||||||
|
---help---
|
||||||
|
This can be set to 'y' to suppress support for while-do-done and
|
||||||
|
until-do-done sequences in scripts. This would only be set on
|
||||||
|
systems where some minimal scripting is required but looping
|
||||||
|
is not.
|
||||||
|
|
||||||
|
endif # !NSH_DISABLESCRIPT
|
||||||
|
|
||||||
config NSH_DISABLEBG
|
config NSH_DISABLEBG
|
||||||
bool "Disable background commands"
|
bool "Disable background commands"
|
||||||
default n
|
default n
|
||||||
|
@ -7,6 +7,7 @@ apps/nshlib
|
|||||||
- Console/NSH Front End
|
- Console/NSH Front End
|
||||||
- Command Overview
|
- Command Overview
|
||||||
- Conditional Command Execution
|
- Conditional Command Execution
|
||||||
|
- Looping
|
||||||
- Built-In Variables
|
- Built-In Variables
|
||||||
- Current Working Directory
|
- Current Working Directory
|
||||||
Environment Variables
|
Environment Variables
|
||||||
@ -121,6 +122,12 @@ Looping
|
|||||||
Execute <cmd-sequence> as long as <test-cmd> has a non-zero exit
|
Execute <cmd-sequence> as long as <test-cmd> has a non-zero exit
|
||||||
status.
|
status.
|
||||||
|
|
||||||
|
A break command is also supported. The break command is only valid
|
||||||
|
within the body of the a while or until loop, between the do and done
|
||||||
|
tokens. If the break command is executed within the body of a loop, the
|
||||||
|
loop will immediately terminate and execution will continue with the
|
||||||
|
next command immediately following the done token.
|
||||||
|
|
||||||
Built-In Variables
|
Built-In Variables
|
||||||
^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
@ -1094,6 +1101,20 @@ NSH-Specific Configuration Settings
|
|||||||
if-then[-else]-fi construct. This would only be set on systems
|
if-then[-else]-fi construct. This would only be set on systems
|
||||||
where a minimal footprint is a necessity and scripting is not.
|
where a minimal footprint is a necessity and scripting is not.
|
||||||
|
|
||||||
|
* CONFIG_NSH_DISABLE_ITEF
|
||||||
|
|
||||||
|
If scripting is enabled, then then this option can be selected to
|
||||||
|
suppress support for if-then-else-fi sequences in scripts. This would
|
||||||
|
only be set on systems where some minimal scripting is required but
|
||||||
|
if-then-else-fi is not.
|
||||||
|
|
||||||
|
* CONFIG_NSH_DISABLE_LOOPS
|
||||||
|
|
||||||
|
If scripting is enabled, then then this option can be selected
|
||||||
|
suppress support for while-do-done and until-do-done sequences in
|
||||||
|
scripts. This would only be set on systems where some minimal
|
||||||
|
scripting is required but looping is not.
|
||||||
|
|
||||||
* CONFIG_NSH_DISABLEBG
|
* CONFIG_NSH_DISABLEBG
|
||||||
This can be set to 'y' to suppress support for background
|
This can be set to 'y' to suppress support for background
|
||||||
commands. This setting disables the 'nice' command prefix and
|
commands. This setting disables the 'nice' command prefix and
|
||||||
|
21
nshlib/nsh.h
21
nshlib/nsh.h
@ -453,6 +453,8 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Public Types
|
* Public Types
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef CONFIG_NSH_DISABLE_ITEF
|
||||||
/* State when parsing and if-then-else sequence */
|
/* State when parsing and if-then-else sequence */
|
||||||
|
|
||||||
enum nsh_itef_e
|
enum nsh_itef_e
|
||||||
@ -472,7 +474,9 @@ struct nsh_itef_s
|
|||||||
uint8_t ie_unused : 4;
|
uint8_t ie_unused : 4;
|
||||||
uint8_t ie_state : 2; /* If-then-else state (see enum nsh_itef_e) */
|
uint8_t ie_state : 2; /* If-then-else state (see enum nsh_itef_e) */
|
||||||
};
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef CONFIG_NSH_DISABLE_LOOPS
|
||||||
/* State when parsing and while-do-done or until-do-done sequence */
|
/* State when parsing and while-do-done or until-do-done sequence */
|
||||||
|
|
||||||
enum nsh_lp_e
|
enum nsh_lp_e
|
||||||
@ -490,8 +494,12 @@ struct nsh_loop_s
|
|||||||
uint8_t lp_enable : 1; /* Loop command processing is enabled */
|
uint8_t lp_enable : 1; /* Loop command processing is enabled */
|
||||||
uint8_t lp_unused : 5;
|
uint8_t lp_unused : 5;
|
||||||
uint8_t lp_state : 2; /* Loop state (see enume nsh_lp_e) */
|
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 */
|
||||||
|
#endif
|
||||||
long lp_topoffs; /* Top of loop file offset */
|
long lp_topoffs; /* Top of loop file offset */
|
||||||
};
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
/* These structure provides the overall state of the parser */
|
/* These structure provides the overall state of the parser */
|
||||||
|
|
||||||
@ -510,19 +518,27 @@ struct nsh_parser_s
|
|||||||
|
|
||||||
#ifndef CONFIG_NSH_DISABLESCRIPT
|
#ifndef CONFIG_NSH_DISABLESCRIPT
|
||||||
FILE *np_stream; /* Stream of current script */
|
FILE *np_stream; /* Stream of current script */
|
||||||
|
#ifndef CONFIG_NSH_DISABLE_LOOPS
|
||||||
long np_foffs; /* File offset to the beginning of a line */
|
long np_foffs; /* File offset to the beginning of a line */
|
||||||
#ifndef NSH_DISABLE_SEMICOLON
|
#ifndef NSH_DISABLE_SEMICOLON
|
||||||
uint16_t np_loffs; /* Byte offset to the beginning of a command */
|
uint16_t np_loffs; /* Byte offset to the beginning of a command */
|
||||||
bool np_jump; /* "Jump" to the top of the loop */
|
bool np_jump; /* "Jump" to the top of the loop */
|
||||||
#endif
|
#endif
|
||||||
uint8_t np_iendx; /* Current index into np_iestate[] */
|
|
||||||
uint8_t np_lpndx; /* Current index into np_lpstate[] */
|
uint8_t np_lpndx; /* Current index into np_lpstate[] */
|
||||||
|
#endif
|
||||||
|
#ifndef CONFIG_NSH_DISABLE_ITEF
|
||||||
|
uint8_t np_iendx; /* Current index into np_iestate[] */
|
||||||
|
#endif
|
||||||
|
|
||||||
/* This is a stack of parser state information. */
|
/* This is a stack of parser state information. */
|
||||||
|
|
||||||
|
#ifndef CONFIG_NSH_DISABLE_ITEF
|
||||||
struct nsh_itef_s np_iestate[CONFIG_NSH_NESTDEPTH];
|
struct nsh_itef_s np_iestate[CONFIG_NSH_NESTDEPTH];
|
||||||
|
#endif
|
||||||
|
#ifndef CONFIG_NSH_DISABLE_LOOPS
|
||||||
struct nsh_loop_s np_lpstate[CONFIG_NSH_NESTDEPTH];
|
struct nsh_loop_s np_lpstate[CONFIG_NSH_NESTDEPTH];
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
struct nsh_vtbl_s; /* Defined in nsh_console.h */
|
struct nsh_vtbl_s; /* Defined in nsh_console.h */
|
||||||
@ -643,6 +659,9 @@ void nsh_usbtrace(void);
|
|||||||
|
|
||||||
/* Shell command handlers */
|
/* Shell command handlers */
|
||||||
|
|
||||||
|
#if !defined(CONFIG_NSH_DISABLESCRIPT) && !defined(CONFIG_NSH_DISABLE_LOOPS)
|
||||||
|
int cmd_break(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv);
|
||||||
|
#endif
|
||||||
#ifndef CONFIG_NSH_DISABLE_ECHO
|
#ifndef CONFIG_NSH_DISABLE_ECHO
|
||||||
int cmd_echo(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv);
|
int cmd_echo(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv);
|
||||||
#endif
|
#endif
|
||||||
|
@ -119,6 +119,10 @@ static const struct cmdmap_s g_cmdmap[] =
|
|||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if !defined(CONFIG_NSH_DISABLESCRIPT) && !defined(CONFIG_NSH_DISABLE_LOOPS)
|
||||||
|
{ "break", cmd_break, 1, 1, NULL },
|
||||||
|
#endif
|
||||||
|
|
||||||
#if CONFIG_NFILE_DESCRIPTORS > 0
|
#if CONFIG_NFILE_DESCRIPTORS > 0
|
||||||
# ifndef CONFIG_NSH_DISABLE_CAT
|
# ifndef CONFIG_NSH_DISABLE_CAT
|
||||||
{ "cat", cmd_cat, 2, CONFIG_NSH_MAXARGUMENTS, "<path> [<path> [<path> ...]]" },
|
{ "cat", cmd_cat, 2, CONFIG_NSH_MAXARGUMENTS, "<path> [<path> [<path> ...]]" },
|
||||||
@ -465,6 +469,7 @@ static inline void help_usage(FAR struct nsh_vtbl_s *vtbl)
|
|||||||
nsh_output(vtbl, " <cmd> [> <file>|>> <file>]\n\n");
|
nsh_output(vtbl, " <cmd> [> <file>|>> <file>]\n\n");
|
||||||
#endif
|
#endif
|
||||||
#ifndef CONFIG_NSH_DISABLESCRIPT
|
#ifndef CONFIG_NSH_DISABLESCRIPT
|
||||||
|
#ifndef CONFIG_NSH_DISABLE_ITEF
|
||||||
nsh_output(vtbl, "OR\n");
|
nsh_output(vtbl, "OR\n");
|
||||||
nsh_output(vtbl, " if <cmd>\n");
|
nsh_output(vtbl, " if <cmd>\n");
|
||||||
nsh_output(vtbl, " then\n");
|
nsh_output(vtbl, " then\n");
|
||||||
@ -472,6 +477,8 @@ static inline void help_usage(FAR struct nsh_vtbl_s *vtbl)
|
|||||||
nsh_output(vtbl, " else\n");
|
nsh_output(vtbl, " else\n");
|
||||||
nsh_output(vtbl, " [sequence of <cmd>]\n");
|
nsh_output(vtbl, " [sequence of <cmd>]\n");
|
||||||
nsh_output(vtbl, " fi\n\n");
|
nsh_output(vtbl, " fi\n\n");
|
||||||
|
#endif
|
||||||
|
#ifndef CONFIG_NSH_DISABLE_LOOPS
|
||||||
nsh_output(vtbl, "OR\n");
|
nsh_output(vtbl, "OR\n");
|
||||||
nsh_output(vtbl, " while <cmd>\n");
|
nsh_output(vtbl, " while <cmd>\n");
|
||||||
nsh_output(vtbl, " do\n");
|
nsh_output(vtbl, " do\n");
|
||||||
@ -483,6 +490,7 @@ static inline void help_usage(FAR struct nsh_vtbl_s *vtbl)
|
|||||||
nsh_output(vtbl, " [sequence of <cmd>]\n");
|
nsh_output(vtbl, " [sequence of <cmd>]\n");
|
||||||
nsh_output(vtbl, " done\n\n");
|
nsh_output(vtbl, " done\n\n");
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -160,14 +160,22 @@ static FAR char *nsh_argument(FAR struct nsh_vtbl_s *vtbl, char **saveptr,
|
|||||||
FAR NSH_MEMLIST_TYPE *memlist);
|
FAR NSH_MEMLIST_TYPE *memlist);
|
||||||
|
|
||||||
#ifndef CONFIG_NSH_DISABLESCRIPT
|
#ifndef CONFIG_NSH_DISABLESCRIPT
|
||||||
|
#ifndef CONFIG_NSH_DISABLE_LOOPS
|
||||||
static bool nsh_loop_enabled(FAR struct nsh_vtbl_s *vtbl);
|
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);
|
static bool nsh_itef_enabled(FAR struct nsh_vtbl_s *vtbl);
|
||||||
|
#endif
|
||||||
static bool nsh_cmdenabled(FAR struct nsh_vtbl_s *vtbl);
|
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,
|
static int nsh_loop(FAR struct nsh_vtbl_s *vtbl, FAR char **ppcmd,
|
||||||
FAR char **saveptr, FAR NSH_MEMLIST_TYPE *memlist);
|
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,
|
static int nsh_itef(FAR struct nsh_vtbl_s *vtbl, FAR char **ppcmd,
|
||||||
FAR char **saveptr, FAR NSH_MEMLIST_TYPE *memlist);
|
FAR char **saveptr, FAR NSH_MEMLIST_TYPE *memlist);
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef CONFIG_NSH_DISABLEBG
|
#ifndef CONFIG_NSH_DISABLEBG
|
||||||
static int nsh_nice(FAR struct nsh_vtbl_s *vtbl, FAR char **ppcmd,
|
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;
|
struct nsh_parser_s *np = &vtbl->np;
|
||||||
|
|
||||||
#ifndef CONFIG_NSH_DISABLESCRIPT
|
#ifndef CONFIG_NSH_DISABLESCRIPT
|
||||||
|
#ifndef CONFIG_NSH_DISABLE_LOOPS
|
||||||
/* Check if we are waiting for the condition associated with a while
|
/* Check if we are waiting for the condition associated with a while
|
||||||
* token.
|
* token.
|
||||||
*
|
*
|
||||||
@ -427,16 +436,20 @@ static int nsh_saveresult(FAR struct nsh_vtbl_s *vtbl, bool result)
|
|||||||
np->np_lpstate[np->np_lpndx].lp_enable = (result != OK);
|
np->np_lpstate[np->np_lpndx].lp_enable = (result != OK);
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef CONFIG_NSH_DISABLE_ITEF
|
||||||
/* Check if we are waiting for the condition associated with an if token */
|
/* 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_fail = false;
|
||||||
np->np_iestate[np->np_iendx].ie_ifcond = result;
|
np->np_iestate[np->np_iendx].ie_ifcond = result;
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
np->np_fail = result;
|
np->np_fail = result;
|
||||||
@ -1369,7 +1382,7 @@ static FAR char *nsh_argument(FAR struct nsh_vtbl_s *vtbl, FAR char **saveptr,
|
|||||||
* Name: nsh_loop_enabled
|
* 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)
|
static bool nsh_loop_enabled(FAR struct nsh_vtbl_s *vtbl)
|
||||||
{
|
{
|
||||||
FAR struct nsh_parser_s *np = &vtbl->np;
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
# define nsh_loop_enabled(vtbl) true
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: nsh_itef_enabled
|
* 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)
|
static bool nsh_itef_enabled(FAR struct nsh_vtbl_s *vtbl)
|
||||||
{
|
{
|
||||||
FAR struct nsh_parser_s *np = &vtbl->np;
|
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;
|
return ret;
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
# define nsh_itef_enabled(vtbl) true
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@ -1442,7 +1459,7 @@ static bool nsh_cmdenabled(FAR struct nsh_vtbl_s *vtbl)
|
|||||||
* Name: nsh_loop
|
* 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,
|
static int nsh_loop(FAR struct nsh_vtbl_s *vtbl, FAR char **ppcmd,
|
||||||
FAR char **saveptr, FAR NSH_MEMLIST_TYPE *memlist)
|
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 */
|
/* 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_WHILE ||
|
||||||
np->np_lpstate[np->np_lpndx].lp_state == NSH_LOOP_UNTIL ||
|
np->np_lpstate[np->np_lpndx].lp_state == NSH_LOOP_UNTIL ||
|
||||||
np->np_stream == NULL || np->np_foffs < 0)
|
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_lpndx++;
|
||||||
np->np_lpstate[np->np_lpndx].lp_state = state;
|
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_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;
|
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)
|
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);
|
*ppcmd = nsh_argument(vtbl, saveptr, memlist);
|
||||||
if (*ppcmd)
|
|
||||||
{
|
|
||||||
nsh_output(vtbl, g_fmtarginvalid, "do");
|
|
||||||
goto errout;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Verify that "do" is valid in this context */
|
/* Verify that "do" is valid in this context */
|
||||||
|
|
||||||
@ -1632,7 +1650,7 @@ errout:
|
|||||||
* Name: nsh_itef
|
* 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,
|
static int nsh_itef(FAR struct nsh_vtbl_s *vtbl, FAR char **ppcmd,
|
||||||
FAR char **saveptr, FAR NSH_MEMLIST_TYPE *memlist)
|
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);
|
cmd = nsh_argument(vtbl, &saveptr, &memlist);
|
||||||
|
|
||||||
#ifndef CONFIG_NSH_DISABLESCRIPT
|
#ifndef CONFIG_NSH_DISABLESCRIPT
|
||||||
|
#ifndef CONFIG_NSH_DISABLE_LOOPS
|
||||||
/* Handle while-do-done and until-do-done loops */
|
/* Handle while-do-done and until-do-done loops */
|
||||||
|
|
||||||
if (nsh_loop(vtbl, &cmd, &saveptr, &memlist) != 0)
|
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);
|
NSH_MEMLIST_FREE(&memlist);
|
||||||
return nsh_saveresult(vtbl, true);
|
return nsh_saveresult(vtbl, true);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef CONFIG_NSH_DISABLE_ITEF
|
||||||
/* Handle if-then-else-fi */
|
/* Handle if-then-else-fi */
|
||||||
|
|
||||||
if (nsh_itef(vtbl, &cmd, &saveptr, &memlist) != 0)
|
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);
|
NSH_MEMLIST_FREE(&memlist);
|
||||||
return nsh_saveresult(vtbl, true);
|
return nsh_saveresult(vtbl, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Handle nice */
|
/* Handle nice */
|
||||||
@ -2137,7 +2160,7 @@ int nsh_parse(FAR struct nsh_vtbl_s *vtbl, FAR char *cmdline)
|
|||||||
return nsh_parse_command(vtbl, cmdline);
|
return nsh_parse_command(vtbl, cmdline);
|
||||||
|
|
||||||
#else
|
#else
|
||||||
#ifndef CONFIG_NSH_DISABLESCRIPT
|
#if !defined(CONFIG_NSH_DISABLESCRIPT) && !defined(CONFIG_NSH_DISABLE_LOOPS)
|
||||||
FAR struct nsh_parser_s *np = &vtbl->np;
|
FAR struct nsh_parser_s *np = &vtbl->np;
|
||||||
#endif
|
#endif
|
||||||
FAR char *start = cmdline;
|
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.
|
* 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; )
|
for (np->np_jump = false; !np->np_jump; )
|
||||||
#else
|
#else
|
||||||
for (;;)
|
for (;;)
|
||||||
#endif
|
#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 */
|
/* Save the offset on the line to the start of the command */
|
||||||
|
|
||||||
np->np_loffs = (uint16_t)(working - cmdline);
|
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
|
||||||
#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
|
||||||
|
@ -129,10 +129,11 @@ int nsh_script(FAR struct nsh_vtbl_s *vtbl, FAR const char *cmd,
|
|||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
/* Get the next line of input from the file */
|
/* Flush any output generated by the previous line */
|
||||||
|
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
|
|
||||||
|
#ifndef CONFIG_NSH_DISABLE_LOOPS
|
||||||
/* Get the current file position. This is used to control
|
/* Get the current file position. This is used to control
|
||||||
* looping. If a loop begins in the next line, then this file
|
* looping. If a loop begins in the next line, then this file
|
||||||
* offset will be needed to locate the top of the loop in the
|
* offset will be needed to locate the top of the loop in the
|
||||||
@ -146,6 +147,7 @@ int nsh_script(FAR struct nsh_vtbl_s *vtbl, FAR const char *cmd,
|
|||||||
{
|
{
|
||||||
nsh_output(vtbl, g_fmtcmdfailed, "loop", "ftell", NSH_ERRNO);
|
nsh_output(vtbl, g_fmtcmdfailed, "loop", "ftell", NSH_ERRNO);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Now read the next line from the script file */
|
/* Now read the next line from the script file */
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user