summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apps/ChangeLog.txt6
-rw-r--r--apps/nshlib/Kconfig8
-rw-r--r--apps/nshlib/Makefile5
-rw-r--r--apps/nshlib/README.txt9
-rw-r--r--apps/nshlib/nsh.h21
-rw-r--r--apps/nshlib/nsh_command.c17
-rw-r--r--apps/nshlib/nsh_parse.c869
-rw-r--r--nuttx/Documentation/NuttShell.html14
-rw-r--r--nuttx/configs/freedom-kl25z/minnsh/defconfig1
-rw-r--r--nuttx/configs/sim/nsh/defconfig39
-rw-r--r--nuttx/libc/string/lib_strstr.c8
11 files changed, 250 insertions, 747 deletions
diff --git a/apps/ChangeLog.txt b/apps/ChangeLog.txt
index 4eeca46f8..a6adb5d6c 100644
--- a/apps/ChangeLog.txt
+++ b/apps/ChangeLog.txt
@@ -758,3 +758,9 @@
apps/nshlib/Kconfig: Refactor some configuration dependencies: NSH
features should debug on netutil selections; netutil selections
should depend on networking selections. (2014-1-9).
+ * apps/nshlib/nsh_command.c: Separate NSH command handling from NSH
+ line parsing. This re-partitioning simplifies the logic and will
+ enable some things to come (2014-1-10).
+ * apps/nshlib/nsh_parse.c: Will now support multiple commands on a
+ command line, each separated with a semi-colon (2014-1-10).
+
diff --git a/apps/nshlib/Kconfig b/apps/nshlib/Kconfig
index 09a0e5120..2a96b851b 100644
--- a/apps/nshlib/Kconfig
+++ b/apps/nshlib/Kconfig
@@ -269,6 +269,14 @@ config NSH_LINELEN
The maximum length of one command line and of one output line.
Default: 80
+config NSH_DISABLE_SEMICOLON
+ bool "Disable multiple commands per line"
+ default n
+ ---help---
+ By default, you can enter multiple NSH commands on a line with each
+ command separated by a semicolon. You can disable this feature to
+ save a little memory on FLASH challenged platforms.
+
config NSH_MAXARGUMENTS
int "Maximum number of command arguments"
default 6
diff --git a/apps/nshlib/Makefile b/apps/nshlib/Makefile
index 09b6f6122..c5eb5c53d 100644
--- a/apps/nshlib/Makefile
+++ b/apps/nshlib/Makefile
@@ -40,8 +40,9 @@ include $(APPDIR)/Make.defs
# NSH Library
ASRCS =
-CSRCS = nsh_init.c nsh_parse.c nsh_console.c nsh_script.c nsh_fscmds.c
-CSRCS += nsh_ddcmd.c nsh_proccmds.c nsh_mmcmds.c nsh_envcmds.c nsh_dbgcmds.c
+CSRCS = nsh_init.c nsh_parse.c nsh_console.c nsh_script.c
+CSRCS += nsh_command.c nsh_fscmds.c nsh_ddcmd.c nsh_proccmds.c nsh_mmcmds.c
+CSRCS += nsh_envcmds.c nsh_dbgcmds.c
ifeq ($(CONFIG_NFILE_STREAMS),0)
CSRCS += nsh_stdsession.c
diff --git a/apps/nshlib/README.txt b/apps/nshlib/README.txt
index dcc4ec711..683499c48 100644
--- a/apps/nshlib/README.txt
+++ b/apps/nshlib/README.txt
@@ -62,6 +62,9 @@ Command Overview
(more negative values) correspond to higher priorities. The
default niceness is 10.
+ Multiple commands per line. NSH will accept multiple commands per
+ command line with each command separated with the semi-colon character (;).
+
Conditional Command Execution
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -998,6 +1001,12 @@ NSH-Specific Configuration Settings
The maximum length of one command line and of one output line.
Default: 80
+ * CONFIG_NSH_DISABLE_SEMICOLON
+ By default, you can enter multiple NSH commands on a line with
+ each command separated by a semicolon. You can disable this
+ feature to save a little memory on FLASH challenged platforms.
+ Default: n
+
* CONFIG_NSH_NESTDEPTH
The maximum number of nested if-then[-else]-fi sequences that
are permissable. Default: 3
diff --git a/apps/nshlib/nsh.h b/apps/nshlib/nsh.h
index 1d89af3aa..fe85f34ce 100644
--- a/apps/nshlib/nsh.h
+++ b/apps/nshlib/nsh.h
@@ -340,6 +340,24 @@
# endif
#endif
+/* Argument list size
+ *
+ * argv[0]: The command name.
+ * argv[1]: The beginning of argument (up to CONFIG_NSH_MAXARGUMENTS)
+ * argv[argc-3]: Possibly '>' or '>>'
+ * argv[argc-2]: Possibly <file>
+ * argv[argc-1]: Possibly '&' (if pthreads are enabled)
+ * argv[argc]: NULL terminating pointer
+ *
+ * Maximum size is CONFIG_NSH_MAXARGUMENTS+5
+ */
+
+#ifndef CONFIG_NSH_DISABLEBG
+# define MAX_ARGV_ENTRIES (CONFIG_NSH_MAXARGUMENTS+5)
+#else
+# define MAX_ARGV_ENTRIES (CONFIG_NSH_MAXARGUMENTS+4)
+#endif
+
/* strerror() produces much nicer output but is, however, quite large and
* will only be used if CONFIG_NSH_STRERROR is defined. Note that the strerror
* interface must also have been enabled with CONFIG_LIBC_STRERROR.
@@ -487,6 +505,7 @@ extern const char g_loginfailure[];
extern const char g_nshprompt[];
extern const char g_nshsyntax[];
extern const char g_fmtargrequired[];
+extern const char g_fmtnomatching[];
extern const char g_fmtarginvalid[];
extern const char g_fmtargrange[];
extern const char g_fmtcmdnotfound[];
@@ -551,6 +570,8 @@ int nsh_parse(FAR struct nsh_vtbl_s *vtbl, char *cmdline);
/* Application interface */
+int nsh_command(FAR struct nsh_vtbl_s *vtbl, int argc, char *argv[]);
+
#ifdef CONFIG_NSH_BUILTIN_APPS
int nsh_builtin(FAR struct nsh_vtbl_s *vtbl, FAR const char *cmd,
FAR char **argv, FAR const char *redirfile, int oflags);
diff --git a/apps/nshlib/nsh_command.c b/apps/nshlib/nsh_command.c
index 4babd9200..7d914075f 100644
--- a/apps/nshlib/nsh_command.c
+++ b/apps/nshlib/nsh_command.c
@@ -39,22 +39,11 @@
#include <nuttx/config.h>
-#include <sys/stat.h>
-
-#include <stdint.h>
-#include <stdbool.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
#include <string.h>
-#include <sched.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <debug.h>
-
-#include <nuttx/version.h>
-#include <apps/nsh.h>
+#ifdef CONFIG_NSH_BUILTIN_APPS
+# include <nuttx/binfmt/builtin.h>
+#endif
#include "nsh.h"
#include "nsh_console.h"
diff --git a/apps/nshlib/nsh_parse.c b/apps/nshlib/nsh_parse.c
index 0b977b836..061aec65e 100644
--- a/apps/nshlib/nsh_parse.c
+++ b/apps/nshlib/nsh_parse.c
@@ -1,7 +1,7 @@
/****************************************************************************
* apps/nshlib/nsh_parse.c
*
- * Copyright (C) 2007-2013 Gregory Nutt. All rights reserved.
+ * Copyright (C) 2007-2013, 2014 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
@@ -39,29 +39,12 @@
#include <nuttx/config.h>
-#include <sys/stat.h>
-
-#include <stdint.h>
-#include <stdbool.h>
-#include <stdio.h>
#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <sched.h>
#include <fcntl.h>
+#include <string.h>
#include <errno.h>
#include <debug.h>
-#include <nuttx/version.h>
-
-#ifndef CONFIG_NSH_DISABLEBG
-# include <pthread.h>
-#endif
-
-#ifdef CONFIG_NSH_BUILTIN_APPS
-# include <nuttx/binfmt/builtin.h>
-#endif
-
#include <apps/nsh.h>
#include "nsh.h"
@@ -71,44 +54,11 @@
* Pre-processor Definitions
****************************************************************************/
-/* Argument list size
- *
- * argv[0]: The command name.
- * argv[1]: The beginning of argument (up to CONFIG_NSH_MAXARGUMENTS)
- * argv[argc-3]: Possibly '>' or '>>'
- * argv[argc-2]: Possibly <file>
- * argv[argc-1]: Possibly '&' (if pthreads are enabled)
- * argv[argc]: NULL terminating pointer
- *
- * Maximum size is CONFIG_NSH_MAXARGUMENTS+5
- */
-
-#ifndef CONFIG_NSH_DISABLEBG
-# define MAX_ARGV_ENTRIES (CONFIG_NSH_MAXARGUMENTS+5)
-#else
-# define MAX_ARGV_ENTRIES (CONFIG_NSH_MAXARGUMENTS+4)
-#endif
-
-/* Help command summary layout */
-
-#define MAX_CMDLEN 12
-#define CMDS_PER_LINE 6
-
-#define NUM_CMDS ((sizeof(g_cmdmap)/sizeof(struct cmdmap_s)) - 1)
-#define NUM_CMD_ROWS ((NUM_CMDS + (CMDS_PER_LINE-1)) / CMDS_PER_LINE)
-
/****************************************************************************
* Private Types
****************************************************************************/
-struct cmdmap_s
-{
- const char *cmd; /* Name of the command */
- cmd_t handler; /* Function that handles the command */
- uint8_t minargs; /* Minimum number of arguments (including command) */
- uint8_t maxargs; /* Maximum number of arguments (including command) */
- const char *usage; /* Usage instructions for 'help' command */
-};
+/* These structure describes the parsed command line */
#ifndef CONFIG_NSH_DISABLEBG
struct cmdarg_s
@@ -124,331 +74,17 @@ struct cmdarg_s
* Private Function Prototypes
****************************************************************************/
-#ifndef CONFIG_NSH_DISABLE_HELP
-static int cmd_help(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv);
-#endif
-
-#ifndef CONFIG_NSH_DISABLE_EXIT
-static int cmd_exit(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv);
-#endif
-static int cmd_unrecognized(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv);
-
/****************************************************************************
* Private Data
****************************************************************************/
-static const char g_delim[] = " \t\n";
-static const char g_redirect1[] = ">";
-static const char g_redirect2[] = ">>";
-static const char g_exitstatus[] = "$?";
-static const char g_success[] = "0";
-static const char g_failure[] = "1";
-
-static const struct cmdmap_s g_cmdmap[] =
-{
-#if !defined(CONFIG_NSH_DISABLESCRIPT) && !defined(CONFIG_NSH_DISABLE_TEST)
- { "[", cmd_lbracket, 4, CONFIG_NSH_MAXARGUMENTS, "<expression> ]" },
-#endif
-
-#ifndef CONFIG_NSH_DISABLE_HELP
- { "?", cmd_help, 1, 1, NULL },
-#endif
-
-#if defined(CONFIG_NET) && defined(CONFIG_NET_ROUTE) && !defined(CONFIG_NSH_DISABLE_ADDROUTE)
- { "addroute", cmd_addroute, 4, 4, "<target> <netmask> <router>" },
-#endif
-
-#if defined(CONFIG_NETUTILS_CODECS) && defined(CONFIG_CODECS_BASE64)
-# ifndef CONFIG_NSH_DISABLE_BASE64DEC
- { "base64dec", cmd_base64decode, 2, 4, "[-w] [-f] <string or filepath>" },
-# endif
-# ifndef CONFIG_NSH_DISABLE_BASE64ENC
- { "base64enc", cmd_base64encode, 2, 4, "[-w] [-f] <string or filepath>" },
-# endif
-#endif
-
-#if CONFIG_NFILE_DESCRIPTORS > 0
-# ifndef CONFIG_NSH_DISABLE_CAT
- { "cat", cmd_cat, 2, CONFIG_NSH_MAXARGUMENTS, "<path> [<path> [<path> ...]]" },
-# endif
-#ifndef CONFIG_DISABLE_ENVIRON
-# ifndef CONFIG_NSH_DISABLE_CD
- { "cd", cmd_cd, 1, 2, "[<dir-path>|-|~|..]" },
-# endif
-#endif
-# ifndef CONFIG_NSH_DISABLE_CP
- { "cp", cmd_cp, 3, 3, "<source-path> <dest-path>" },
-# endif
-# ifndef CONFIG_NSH_DISABLE_CMP
- { "cmp", cmd_cmp, 3, 3, "<path1> <path2>" },
-# endif
-#endif
-
-#if defined (CONFIG_RTC) && !defined(CONFIG_DISABLE_CLOCK) && !defined(CONFIG_NSH_DISABLE_DATE)
- { "date", cmd_date, 1, 3, "[-s \"MMM DD HH:MM:SS YYYY\"]" },
-#endif
-
-#if CONFIG_NFILE_DESCRIPTORS > 0 && !defined(CONFIG_NSH_DISABLE_DD)
- { "dd", cmd_dd, 3, 6, "if=<infile> of=<outfile> [bs=<sectsize>] [count=<sectors>] [skip=<sectors>]" },
-# endif
-
-#if defined(CONFIG_NET) && defined(CONFIG_NET_ROUTE) && !defined(CONFIG_NSH_DISABLE_DELROUTE)
- { "delroute", cmd_delroute, 3, 3, "<target> <netmask>" },
-#endif
-
-#if CONFIG_NFILE_DESCRIPTORS > 0 && !defined(CONFIG_DISABLE_MOUNTPOINT) && \
- defined(CONFIG_FS_READABLE) && !defined(CONFIG_NSH_DISABLE_DF)
-#ifdef CONFIG_NSH_CMDOPT_DF_H
- { "df", cmd_df, 1, 2, "[-h]" },
-#else
- { "df", cmd_df, 1, 1, NULL },
-#endif
-#endif
-
-#if CONFIG_NFILE_DESCRIPTORS > 0 && defined(CONFIG_SYSLOG) && \
- defined(CONFIG_RAMLOG_SYSLOG) && !defined(CONFIG_NSH_DISABLE_DMESG)
- { "dmesg", cmd_dmesg, 1, 1, NULL },
-#endif
-
-#ifndef CONFIG_NSH_DISABLE_ECHO
-# ifndef CONFIG_DISABLE_ENVIRON
- { "echo", cmd_echo, 0, CONFIG_NSH_MAXARGUMENTS, "[<string|$name> [<string|$name>...]]" },
-# else
- { "echo", cmd_echo, 0, CONFIG_NSH_MAXARGUMENTS, "[<string> [<string>...]]" },
-# endif
-#endif
-
-#ifndef CONFIG_NSH_DISABLE_EXEC
- { "exec", cmd_exec, 2, 3, "<hex-address>" },
-#endif
-#ifndef CONFIG_NSH_DISABLE_EXIT
- { "exit", cmd_exit, 1, 1, NULL },
-#endif
-
-#ifndef CONFIG_NSH_DISABLE_FREE
- { "free", cmd_free, 1, 1, NULL },
-#endif
-
-#if defined(CONFIG_NET_UDP) && CONFIG_NFILE_DESCRIPTORS > 0
-# ifndef CONFIG_NSH_DISABLE_GET
- { "get", cmd_get, 4, 7, "[-b|-n] [-f <local-path>] -h <ip-address> <remote-path>" },
-# endif
-#endif
-
-#ifndef CONFIG_NSH_DISABLE_HELP
-# ifdef CONFIG_NSH_HELP_TERSE
- { "help", cmd_help, 1, 2, "[<cmd>]" },
-#else
- { "help", cmd_help, 1, 3, "[-v] [<cmd>]" },
-# endif
-#endif
-
-#if CONFIG_NFILE_DESCRIPTORS > 0
-#ifndef CONFIG_NSH_DISABLE_HEXDUMP
-#ifndef CONFIG_NSH_CMDOPT_HEXDUMP
- { "hexdump", cmd_hexdump, 2, 2, "<file or device>" },
-#else
- { "hexdump", cmd_hexdump, 2, 4, "<file or device> [skip=<bytes>] [count=<bytes>]" },
-#endif
-#endif
-#endif
-
-#ifdef CONFIG_NET
-# ifndef CONFIG_NSH_DISABLE_IFCONFIG
- { "ifconfig", cmd_ifconfig, 1, 11, "[nic_name [<ip-address>|dhcp]] [dr|gw|gateway <dr-address>] [netmask <net-mask>] [dns <dns-address>] [hw <hw-mac>]" },
-# endif
-# ifndef CONFIG_NSH_DISABLE_IFUPDOWN
- { "ifdown", cmd_ifdown, 2, 2, "<nic_name>" },
- { "ifup", cmd_ifup, 2, 2, "<nic_name>" },
-# endif
-#endif
-
-#ifndef CONFIG_DISABLE_SIGNALS
-# ifndef CONFIG_NSH_DISABLE_KILL
- { "kill", cmd_kill, 3, 3, "-<signal> <pid>" },
-# endif
-#endif
-
-#if CONFIG_NFILE_DESCRIPTORS > 0 && !defined(CONFIG_DISABLE_MOUNTPOINT)
-# ifndef CONFIG_NSH_DISABLE_LOSETUP
- { "losetup", cmd_losetup, 3, 6, "[-d <dev-path>] | [[-o <offset>] [-r] <dev-path> <file-path>]" },
-# endif
-#endif
-
-#if CONFIG_NFILE_DESCRIPTORS > 0
-# ifndef CONFIG_NSH_DISABLE_LS
- { "ls", cmd_ls, 1, 5, "[-lRs] <dir-path>" },
-# endif
-#endif
-
-#ifndef CONFIG_NSH_DISABLE_MB
- { "mb", cmd_mb, 2, 3, "<hex-address>[=<hex-value>][ <hex-byte-count>]" },
-#endif
-
-#if defined(CONFIG_NETUTILS_CODECS) && defined(CONFIG_CODECS_HASH_MD5)
-# ifndef CONFIG_NSH_DISABLE_MD5
- { "md5", cmd_md5, 2, 3, "[-f] <string or filepath>" },
-# endif
-#endif
-
-#if !defined(CONFIG_DISABLE_MOUNTPOINT) && CONFIG_NFILE_DESCRIPTORS > 0 && defined(CONFIG_FS_WRITABLE)
-# ifndef CONFIG_NSH_DISABLE_MKDIR
- { "mkdir", cmd_mkdir, 2, 2, "<path>" },
-# endif
-#endif
-
-#if !defined(CONFIG_DISABLE_MOUNTPOINT) && CONFIG_NFILE_DESCRIPTORS > 0 && defined(CONFIG_FS_FAT)
-# ifndef CONFIG_NSH_DISABLE_MKFATFS
- { "mkfatfs", cmd_mkfatfs, 2, 4, "[-F <fatsize>] <block-driver>" },
-# endif
-#endif
-
-#if !defined(CONFIG_DISABLE_MOUNTPOINT) && CONFIG_NFILE_DESCRIPTORS > 0
-# ifndef CONFIG_NSH_DISABLE_MKFIFO
- { "mkfifo", cmd_mkfifo, 2, 2, "<path>" },
-# endif
-#endif
-
-#if !defined(CONFIG_DISABLE_MOUNTPOINT) && CONFIG_NFILE_DESCRIPTORS > 0 && defined(CONFIG_FS_WRITABLE)
-# ifndef CONFIG_NSH_DISABLE_MKRD
- { "mkrd", cmd_mkrd, 2, 6, "[-m <minor>] [-s <sector-size>] <nsectors>" },
-# endif
-#endif
-
-#if !defined(CONFIG_DISABLE_MOUNTPOINT) && CONFIG_NFILE_DESCRIPTORS > 0 && defined(CONFIG_FS_SMARTFS)
-# ifndef CONFIG_NSH_DISABLE_MKSMARTFS
-#ifdef CONFIG_SMARTFS_MULTI_ROOT_DIRS
- { "mksmartfs", cmd_mksmartfs, 2, 3, "<path> [<num-root-directories>]" },
-#else
- { "mksmartfs", cmd_mksmartfs, 2, 2, "<path>" },
-#endif
-# endif
-#endif
-
-#ifndef CONFIG_NSH_DISABLE_MH
- { "mh", cmd_mh, 2, 3, "<hex-address>[=<hex-value>][ <hex-byte-count>]" },
-#endif
-
-#if !defined(CONFIG_DISABLE_MOUNTPOINT) && CONFIG_NFILE_DESCRIPTORS > 0 && defined(CONFIG_FS_READABLE)
-# ifndef CONFIG_NSH_DISABLE_MOUNT
-# ifdef CONFIG_NUTTX_KERNEL
- { "mount", cmd_mount, 5, 5, "-t <fstype> [<block-device>] <mount-point>" },
-# else
- { "mount", cmd_mount, 1, 5, "[-t <fstype> [<block-device>] <mount-point>]" },
-# endif
-# endif
-#endif
-
-#if !defined(CONFIG_DISABLE_MOUNTPOINT) && CONFIG_NFILE_DESCRIPTORS > 0 && defined(CONFIG_FS_WRITABLE)
-# ifndef CONFIG_NSH_DISABLE_MV
- { "mv", cmd_mv, 3, 3, "<old-path> <new-path>" },
-# endif
-#endif
-
-#ifndef CONFIG_NSH_DISABLE_MW
- { "mw", cmd_mw, 2, 3, "<hex-address>[=<hex-value>][ <hex-byte-count>]" },
-#endif
-
-#if !defined(CONFIG_DISABLE_MOUNTPOINT) && CONFIG_NFILE_DESCRIPTORS > 0 && \
- defined(CONFIG_NET) && defined(CONFIG_NFS)
-# ifndef CONFIG_NSH_DISABLE_NFSMOUNT
- { "nfsmount", cmd_nfsmount, 4, 4, "<server-address> <mount-point> <remote-path>" },
-# endif
-#endif
-
-#if defined(CONFIG_NET) && defined(CONFIG_NET_ICMP) && defined(CONFIG_NET_ICMP_PING) && \
- !defined(CONFIG_DISABLE_CLOCK) && !defined(CONFIG_DISABLE_SIGNALS)
-# ifndef CONFIG_NSH_DISABLE_PING
- { "ping", cmd_ping, 2, 6, "[-c <count>] [-i <interval>] <ip-address>" },
-# endif
-#endif
-
-#ifndef CONFIG_NSH_DISABLE_PS
- { "ps", cmd_ps, 1, 1, NULL },
-#endif
-
-#if defined(CONFIG_NET_UDP) && CONFIG_NFILE_DESCRIPTORS > 0
-# ifndef CONFIG_NSH_DISABLE_PUT
- { "put", cmd_put, 4, 7, "[-b|-n] [-f <remote-path>] -h <ip-address> <local-path>" },
-# endif
-#endif
-
-#if CONFIG_NFILE_DESCRIPTORS > 0 && !defined(CONFIG_DISABLE_ENVIRON)
-# ifndef CONFIG_NSH_DISABLE_PWD
- { "pwd", cmd_pwd, 1, 1, NULL },
-# endif
-#endif
-
-#if !defined(CONFIG_DISABLE_MOUNTPOINT) && CONFIG_NFILE_DESCRIPTORS > 0 && defined(CONFIG_FS_WRITABLE)
-# ifndef CONFIG_NSH_DISABLE_RM
- { "rm", cmd_rm, 2, 2, "<file-path>" },
-# endif
-# ifndef CONFIG_NSH_DISABLE_RMDIR
- { "rmdir", cmd_rmdir, 2, 2, "<dir-path>" },
-# endif
-#endif
-
-#ifndef CONFIG_DISABLE_ENVIRON
-# ifndef CONFIG_NSH_DISABLE_SET
- { "set", cmd_set, 3, 3, "<name> <value>" },
-# endif
-#endif
-
-#if CONFIG_NFILE_DESCRIPTORS > 0 && CONFIG_NFILE_STREAMS > 0 && !defined(CONFIG_NSH_DISABLESCRIPT)
-# ifndef CONFIG_NSH_DISABLE_SH
- { "sh", cmd_sh, 2, 2, "<script-path>" },
-# endif
-#endif
-
-#ifndef CONFIG_DISABLE_SIGNALS
-# ifndef CONFIG_NSH_DISABLE_SLEEP
- { "sleep", cmd_sleep, 2, 2, "<sec>" },
-# endif
-#endif
-
-#if !defined(CONFIG_NSH_DISABLESCRIPT) && !defined(CONFIG_NSH_DISABLE_TEST)
- { "test", cmd_test, 3, CONFIG_NSH_MAXARGUMENTS, "<expression>" },
-#endif
-
-#if !defined(CONFIG_DISABLE_MOUNTPOINT) && CONFIG_NFILE_DESCRIPTORS > 0 && defined(CONFIG_FS_READABLE)
-# ifndef CONFIG_NSH_DISABLE_UMOUNT
- { "umount", cmd_umount, 2, 2, "<dir-path>" },
-# endif
-#endif
-
-#ifndef CONFIG_DISABLE_ENVIRON
-# ifndef CONFIG_NSH_DISABLE_UNSET
- { "unset", cmd_unset, 2, 2, "<name>" },
-# endif
-#endif
-
-#if defined(CONFIG_NETUTILS_CODECS) && defined(CONFIG_CODECS_URLCODE)
-# ifndef CONFIG_NSH_DISABLE_URLDECODE
- { "urldecode", cmd_urldecode, 2, 3, "[-f] <string or filepath>" },
-# endif
-# ifndef CONFIG_NSH_DISABLE_URLENCODE
- { "urlencode", cmd_urlencode, 2, 3, "[-f] <string or filepath>" },
-# endif
-#endif
-
-#ifndef CONFIG_DISABLE_SIGNALS
-# ifndef CONFIG_NSH_DISABLE_USLEEP
- { "usleep", cmd_usleep, 2, 2, "<usec>" },
-# endif
-#endif
-
-#if defined(CONFIG_NET_TCP) && CONFIG_NFILE_DESCRIPTORS > 0
-# ifndef CONFIG_NSH_DISABLE_WGET
- { "wget", cmd_wget, 2, 4, "[-o <local-path>] <url>" },
-# endif
-#endif
-
-#ifndef CONFIG_NSH_DISABLE_XD
- { "xd", cmd_xd, 3, 3, "<hex-address> <byte-count>" },
-#endif
-
- { NULL, NULL, 1, 1, NULL }
-};
+static const char g_token_separator[] = " \t\n";
+static const char g_line_separator[] = "\";\n";
+static const char g_redirect1[] = ">";
+static const char g_redirect2[] = ">>";
+static const char g_exitstatus[] = "$?";
+static const char g_success[] = "0";
+static const char g_failure[] = "1";
/****************************************************************************
* Public Data
@@ -483,6 +119,7 @@ const char g_nshprompt[] = "nsh> ";
const char g_nshsyntax[] = "nsh: %s: syntax error\n";
const char g_fmtargrequired[] = "nsh: %s: missing required argument(s)\n";
+const char g_fmtnomatching[] = "nsh: %s: no matching %s\n";
const char g_fmtarginvalid[] = "nsh: %s: argument invalid\n";
const char g_fmtargrange[] = "nsh: %s: value out of range\n";
const char g_fmtcmdnotfound[] = "nsh: %s: command not found\n";
@@ -506,328 +143,6 @@ const char g_fmtsignalrecvd[] = "nsh: %s: Interrupted by signal\n";
****************************************************************************/
/****************************************************************************
- * Name: help_cmdlist
- ****************************************************************************/
-
-#ifndef CONFIG_NSH_DISABLE_HELP
-static inline void help_cmdlist(FAR struct nsh_vtbl_s *vtbl)
-{
- int i;
- int j;
- int k;
-
- /* Print the command name in NUM_CMD_ROWS rows with CMDS_PER_LINE commands
- * on each line.
- */
-
- for (i = 0; i < NUM_CMD_ROWS; i++)
- {
- nsh_output(vtbl, " ");
- for (j = 0, k = i; j < CMDS_PER_LINE && k < NUM_CMDS; j++, k += NUM_CMD_ROWS)
- {
-#ifdef CONFIG_NOPRINTF_FIELDWIDTH
- nsh_output(vtbl, "%s\t", g_cmdmap[k].cmd);
-#else
- nsh_output(vtbl, "%-12s", g_cmdmap[k].cmd);
-#endif
- }
-
- nsh_output(vtbl, "\n");
- }
-}
-#endif
-
-/****************************************************************************
- * Name: help_usage
- ****************************************************************************/
-
-#if !defined(CONFIG_NSH_DISABLE_HELP) && !defined(CONFIG_NSH_HELP_TERSE)
-static inline void help_usage(FAR struct nsh_vtbl_s *vtbl)
-{
- nsh_output(vtbl, "NSH command forms:\n");
-#ifndef CONFIG_NSH_DISABLEBG
- nsh_output(vtbl, " [nice [-d <niceness>>]] <cmd> [> <file>|>> <file>] [&]\n");
-#else
- nsh_output(vtbl, " <cmd> [> <file>|>> <file>]\n");
-#endif
-#ifndef CONFIG_NSH_DISABLESCRIPT
- nsh_output(vtbl, "OR\n");
- nsh_output(vtbl, " if <cmd>\n");
- nsh_output(vtbl, " then\n");
- nsh_output(vtbl, " [sequence of <cmd>]\n");
- nsh_output(vtbl, " else\n");
- nsh_output(vtbl, " [sequence of <cmd>]\n");
- nsh_output(vtbl, " fi\n\n");
-#endif
-}
-#endif
-
-/****************************************************************************
- * Name: help_showcmd
- ****************************************************************************/
-
-#ifndef CONFIG_NSH_DISABLE_HELP
-static void help_showcmd(FAR struct nsh_vtbl_s *vtbl,
- FAR const struct cmdmap_s *cmdmap)
-{
- if (cmdmap->usage)
- {
- nsh_output(vtbl, " %s %s\n", cmdmap->cmd, cmdmap->usage);
- }
- else
- {
- nsh_output(vtbl, " %s\n", cmdmap->cmd);
- }
-}
-#endif
-
-/****************************************************************************
- * Name: help_cmd
- ****************************************************************************/
-
-#ifndef CONFIG_NSH_DISABLE_HELP
-static int help_cmd(FAR struct nsh_vtbl_s *vtbl, FAR const char *cmd)
-{
- FAR const struct cmdmap_s *cmdmap;
-
- /* Find the command in the command table */
-
- for (cmdmap = g_cmdmap; cmdmap->cmd; cmdmap++)
- {
- /* Is this the one we are looking for? */
-
- if (strcmp(cmdmap->cmd, cmd) == 0)
- {
- /* Yes... show it */
-
- nsh_output(vtbl, "%s usage:", cmd);
- help_showcmd(vtbl, cmdmap);
- return OK;
- }
- }
-
- nsh_output(vtbl, g_fmtcmdnotfound, cmd);
- return ERROR;
-}
-#endif
-
-/****************************************************************************
- * Name: help_allcmds
- ****************************************************************************/
-
-#if !defined(CONFIG_NSH_DISABLE_HELP) && !defined(CONFIG_NSH_HELP_TERSE)
-static inline void help_allcmds(FAR struct nsh_vtbl_s *vtbl)
-{
- FAR const struct cmdmap_s *cmdmap;
-
- /* Show all of the commands in the command table */
-
- for (cmdmap = g_cmdmap; cmdmap->cmd; cmdmap++)
- {
- help_showcmd(vtbl, cmdmap);
- }
-}
-#endif
-
-/****************************************************************************
- * Name: help_builtins
- ****************************************************************************/
-
-#ifndef CONFIG_NSH_DISABLE_HELP
-static inline void help_builtins(FAR struct nsh_vtbl_s *vtbl)
-{
-#ifdef CONFIG_NSH_BUILTIN_APPS
- FAR const char *name;
- int i;
-
- /* List the set of available built-in commands */
-
- nsh_output(vtbl, "\nBuiltin Apps:\n");
- for (i = 0; (name = builtin_getname(i)) != NULL; i++)
- {
- nsh_output(vtbl, " %s\n", name);
- }
-#endif
-}
-#endif
-
-/****************************************************************************
- * Name: cmd_help
- ****************************************************************************/
-
-#ifndef CONFIG_NSH_DISABLE_HELP
-static int cmd_help(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
-{
- FAR const char *cmd = NULL;
-#ifndef CONFIG_NSH_HELP_TERSE
- bool verbose = false;
- int i;
-#endif
-
- /* The command may be followed by a verbose option */
-
-#ifndef CONFIG_NSH_HELP_TERSE
- i = 1;
- if (argc > i)
- {
- if (strcmp(argv[i], "-v") == 0)
- {
- verbose = true;
- i++;
- }
- }
-
- /* The command line may end with a command name */
-
- if (argc > i)
- {
- cmd = argv[i];
- }
-
- /* Show the generic usage if verbose is requested */
-
- if (verbose)
- {
- help_usage(vtbl);
- }
-#else
- if (argc > 1)
- {
- cmd = argv[1];
- }
-#endif
-
- /* Are we showing help on a single command? */
-
- if (cmd)
- {
- /* Yes.. show the single command */
-
- help_cmd(vtbl, cmd);
- }
- else
- {
- /* In verbose mode, show detailed help for all commands */
-
-#ifndef CONFIG_NSH_HELP_TERSE
- if (verbose)
- {
- nsh_output(vtbl, "Where <cmd> is one of:\n");
- help_allcmds(vtbl);
- }
-
- /* Otherwise, just show the list of command names */
-
- else
-#endif
- {
- help_cmd(vtbl, "help");
- nsh_output(vtbl, "\n");
- help_cmdlist(vtbl);
- }
-
- /* And show the list of built-in applications */
-
- help_builtins(vtbl);
- }
-
- return OK;
-}
-#endif
-
-/****************************************************************************
- * Name: cmd_unrecognized
- ****************************************************************************/
-
-static int cmd_unrecognized(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
-{
- nsh_output(vtbl, g_fmtcmdnotfound, argv[0]);
- return ERROR;
-}
-
-/****************************************************************************
- * Name: cmd_exit
- ****************************************************************************/
-
-#ifndef CONFIG_NSH_DISABLE_EXIT
-static int cmd_exit(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
-{
- nsh_exit(vtbl, 0);
- return OK;
-}
-#endif
-
-/****************************************************************************
- * Name: nsh_execute
- *
- * Description:
- * Execute the command in argv[0]
- *
- * Returned Value:
- * -1 (ERRROR) if the command was unsuccessful
- * 0 (OK) if the command was successful
- *
- ****************************************************************************/
-
-static int nsh_execute(FAR struct nsh_vtbl_s *vtbl, int argc, char *argv[])
-{
- const struct cmdmap_s *cmdmap;
- const char *cmd;
- cmd_t handler = cmd_unrecognized;
- int ret;
-
- /* The form of argv is:
- *
- * argv[0]: The command name. This is argv[0] when the arguments
- * are, finally, received by the command vtblr
- * argv[1]: The beginning of argument (up to CONFIG_NSH_MAXARGUMENTS)
- * argv[argc]: NULL terminating pointer
- */
-
- cmd = argv[0];
-
- /* See if the command is one that we understand */
-
- for (cmdmap = g_cmdmap; cmdmap->cmd; cmdmap++)
- {
- if (strcmp(cmdmap->cmd, cmd) == 0)
- {
- /* Check if a valid number of arguments was provided. We
- * do this simple, imperfect checking here so that it does
- * not have to be performed in each command.
- */
-
- if (argc < cmdmap->minargs)
- {
- /* Fewer than the minimum number were provided */
-
- nsh_output(vtbl, g_fmtargrequired, cmd);
- return ERROR;
- }
- else if (argc > cmdmap->maxargs)
- {
- /* More than the maximum number were provided */
-
- nsh_output(vtbl, g_fmttoomanyargs, cmd);
- return ERROR;
- }
- else
- {
- /* A valid number of arguments were provided (this does
- * not mean they are right).
- */
-
- handler = cmdmap->handler;
- break;
- }
- }
- }
-
- ret = handler(vtbl, argc, argv);
- return ret;
-}
-
-/****************************************************************************
* Name: nsh_releaseargs
****************************************************************************/
@@ -877,7 +192,7 @@ static pthread_addr_t nsh_child(pthread_addr_t arg)
/* Execute the specified command on the child thread */
- ret = nsh_execute(carg->vtbl, carg->argc, carg->argv);
+ ret = nsh_command(carg->vtbl, carg->argc, carg->argv);
/* Released the cloned arguments */
@@ -909,6 +224,7 @@ static inline struct cmdarg_s *nsh_cloneargs(FAR struct nsh_vtbl_s *vtbl,
ret->argv[i] = strdup(argv[i]);
}
}
+
return ret;
}
#endif
@@ -917,7 +233,7 @@ static inline struct cmdarg_s *nsh_cloneargs(FAR struct nsh_vtbl_s *vtbl,
* Name: nsh_argument
****************************************************************************/
-char *nsh_argument(FAR struct nsh_vtbl_s *vtbl, char **saveptr)
+static char *nsh_argument(FAR struct nsh_vtbl_s *vtbl, char **saveptr)
{
char *pbegin = *saveptr;
char *pend = NULL;
@@ -929,11 +245,11 @@ char *nsh_argument(FAR struct nsh_vtbl_s *vtbl, char **saveptr)
/* Find the beginning of the next token */
for (;
- *pbegin && strchr(g_delim, *pbegin) != NULL;
+ *pbegin && strchr(g_token_separator, *pbegin) != NULL;
pbegin++);
- /* If we are at the end of the string with nothing
- * but delimiters found, then return NULL.
+ /* If we are at the end of the string with nothing but delimiters found,
+ * then return NULL, meaning that there are no further arguments on the line.
*/
if (!*pbegin)
@@ -986,9 +302,9 @@ char *nsh_argument(FAR struct nsh_vtbl_s *vtbl, char **saveptr)
}
else
{
- /* No, then any of the usual terminators will terminate the argument */
+ /* No, then any of the usual separators will terminate the argument */
- term = g_delim;
+ term = g_token_separator;
}
/* Find the end of the string */
@@ -1031,7 +347,9 @@ char *nsh_argument(FAR struct nsh_vtbl_s *vtbl, char **saveptr)
}
}
- /* Not a built-in? Return the value of the environment variable with this name */
+ /* Not a built-in? Return the value of the environment variable
+ * with this name
+ */
else
{
@@ -1081,6 +399,7 @@ static inline bool nsh_cmdenabled(FAR struct nsh_vtbl_s *vtbl)
break;
}
}
+
return ret;
}
#endif
@@ -1090,7 +409,8 @@ static inline bool nsh_cmdenabled(FAR struct nsh_vtbl_s *vtbl)
****************************************************************************/
#ifndef CONFIG_NSH_DISABLESCRIPT
-static inline int nsh_ifthenelse(FAR struct nsh_vtbl_s *vtbl, FAR char **ppcmd, FAR char **saveptr)
+static inline int nsh_ifthenelse(FAR struct nsh_vtbl_s *vtbl,
+ FAR char **ppcmd, FAR char **saveptr)
{
struct nsh_parser_s *np = &vtbl->np;
FAR char *cmd = *ppcmd;
@@ -1252,7 +572,8 @@ static inline int nsh_saveresult(FAR struct nsh_vtbl_s *vtbl, bool result)
****************************************************************************/
#ifndef CONFIG_NSH_DISABLEBG
-static inline int nsh_nice(FAR struct nsh_vtbl_s *vtbl, FAR char **ppcmd, FAR char **saveptr)
+static inline int nsh_nice(FAR struct nsh_vtbl_s *vtbl, FAR char **ppcmd,
+ FAR char **saveptr)
{
FAR char *cmd = *ppcmd;
@@ -1294,23 +615,20 @@ static inline int nsh_nice(FAR struct nsh_vtbl_s *vtbl, FAR char **ppcmd, FAR ch
*ppcmd = cmd;
}
}
+
return OK;
}
#endif
/****************************************************************************
- * Public Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Name: nsh_parse
+ * Name: nsh_parse_command
*
* Description:
- * This function parses and executes one NSH command.
+ * This function parses and executes one NSH command from the command line.
*
****************************************************************************/
-int nsh_parse(FAR struct nsh_vtbl_s *vtbl, char *cmdline)
+static int nsh_parse_command(FAR struct nsh_vtbl_s *vtbl, FAR char *cmdline)
{
FAR char *argv[MAX_ARGV_ENTRIES];
FAR char *saveptr;
@@ -1448,7 +766,7 @@ int nsh_parse(FAR struct nsh_vtbl_s *vtbl, char *cmdline)
* nsh_fileapp() returns:
*
* -1 (ERROR) if the application task corresponding to 'argv[0]' could not
- * be started (possibly because it doesn not exist).
+ * be started (possibly because it does not exist).
* 0 (OK) if the application task corresponding to 'argv[0]' was
* and successfully started. If CONFIG_SCHED_WAITPID is
* defined, this return value also indicates that the
@@ -1464,7 +782,7 @@ int nsh_parse(FAR struct nsh_vtbl_s *vtbl, char *cmdline)
ret = nsh_fileapp(vtbl, argv[0], argv, redirfile, oflags);
if (ret >= 0)
{
- /* nsh_fileapp() returned 0 or 1. This means that the builtin
+ /* nsh_fileapp() returned 0 or 1. This means that the built-in
* command was successfully started (although it may not have ran
* successfully). So certainly it is not an NSH command.
*/
@@ -1481,13 +799,14 @@ int nsh_parse(FAR struct nsh_vtbl_s *vtbl, char *cmdline)
return nsh_saveresult(vtbl, ret != OK);
}
- /* No, not a built in command (or, at least, we were unable to start a
- * builtin command of that name). Treat it like an NSH command.
+ /* No, not a file name command (or, at least, we were unable to start a
+ * program of that name). Maybe it is a built-in application or an NSH
+ * command.
*/
#endif
- /* Does this command correspond to a builtin command?
+ /* Does this command correspond to a built-in command?
* nsh_builtin() returns:
*
* -1 (ERROR) if the application task corresponding to 'argv[0]' could not
@@ -1511,7 +830,7 @@ int nsh_parse(FAR struct nsh_vtbl_s *vtbl, char *cmdline)
#endif
if (ret >= 0)
{
- /* nsh_builtin() returned 0 or 1. This means that the builtin
+ /* nsh_builtin() returned 0 or 1. This means that the built-in
* command was successfully started (although it may not have ran
* successfully). So certainly it is not an NSH command.
*/
@@ -1531,7 +850,7 @@ int nsh_parse(FAR struct nsh_vtbl_s *vtbl, char *cmdline)
}
/* No, not a built in command (or, at least, we were unable to start a
- * builtin command of that name). Treat it like an NSH command.
+ * built-in command of that name). Treat it like an NSH command.
*/
#endif
@@ -1678,13 +997,13 @@ int nsh_parse(FAR struct nsh_vtbl_s *vtbl, char *cmdline)
#endif
/* Then execute the command in "foreground" -- i.e., while the user waits
- * for the next prompt. nsh_execute will return:
+ * for the next prompt. nsh_command will return:
*
* -1 (ERRROR) if the command was unsuccessful
* 0 (OK) if the command was successful
*/
- ret = nsh_execute(vtbl, argc, argv);
+ ret = nsh_command(vtbl, argc, argv);
#if CONFIG_NFILE_STREAMS > 0
/* Restore the original output. Undirect will close the redirection
@@ -1726,3 +1045,109 @@ errout_with_redirect:
errout:
return nsh_saveresult(vtbl, true);
}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: nsh_parse
+ *
+ * Description:
+ * This function parses and executes the line of text received from the
+ * user. This may consist of one or more NSH commands. Multiple NSH
+ * commands are separated by semi-colons.
+ *
+ ****************************************************************************/
+
+int nsh_parse(FAR struct nsh_vtbl_s *vtbl, FAR char *cmdline)
+{
+#ifdef NSH_DISABLE_SEMICOLON
+ return nsh_parse_command(vtbl, cmdline);
+
+#else
+ FAR char *start = cmdline;
+ FAR char *working = cmdline;
+ FAR char *ptr;
+ size_t len;
+ int ret;
+
+ /* Loop until all of the commands on the command line have been processed */
+
+ for (;;)
+ {
+ /* A command may be terminated with a newline character, the end of the
+ * line, or a semicolon. NOTE that the set of delimiting characters
+ * includes the quotation mark. We need to handle quotation marks here
+ * because a semicolon or newline character within a quoted string must
+ * be ignored.
+ */
+
+ len = strcspn(working, g_line_separator);
+ ptr = working + len;
+
+ /* Check for the last command on the line. This means that the none
+ * of the delimiting characters was found or that the newline character
+ * was found. Anything after the newline character is ignored (there
+ * should not be anything.
+ */
+
+ if (*ptr == '\0' || *ptr == '\n')
+ {
+ /* Parse the last command on the line */
+
+ return nsh_parse_command(vtbl, start);
+ }
+
+ /* Check for a command terminated with ';'. There is probably another
+ * command on the command line after this one.
+ */
+
+ else if (*ptr == ';')
+ {
+ /* Terminate the line */
+
+ *ptr++ = '\0';
+
+ /* Parse this command */
+
+ ret = nsh_parse_command(vtbl, start);
+ if (ret != OK)
+ {
+ /* nsh_parse_command may return (1) -1 (ERROR) meaning that the
+ * command failed or we failed to start the command application
+ * or (2) 1 meaning that the application task was spawned
+ * successfully but returned failure exit status.
+ */
+
+ return ret;
+ }
+
+ /* Then set the start of the next command on the command line */
+
+ start = ptr;
+ working = ptr;
+ }
+
+ /* Check if we encountered a quoted string */
+
+ else /* if (*ptr == '"') */
+ {
+ /* Find the closing quotation mark */
+
+ FAR char *tmp = strchr(ptr, '"');
+ if (!tmp)
+ {
+ /* No closing quotation mark! */
+
+ nsh_output(vtbl, g_fmtnomatching, "[\"]", "[\"]");
+ return ERROR;
+ }
+
+ /* Otherwise, continue parsing after the closing quotation mark */
+
+ working = tmp++;
+ }
+ }
+#endif
+}
diff --git a/nuttx/Documentation/NuttShell.html b/nuttx/Documentation/NuttShell.html
index 63e216576..78b4a84b3 100644
--- a/nuttx/Documentation/NuttShell.html
+++ b/nuttx/Documentation/NuttShell.html
@@ -8,7 +8,7 @@
<tr align="center" bgcolor="#e4e4e4">
<td>
<h1><big><font color="#3c34ec"><i>NuttShell (NSH)</i></font></big></h1>
- <p>Last Updated: December 5, 2013</p>
+ <p>Last Updated: January 10, 2014</p>
</td>
</tr>
</table>
@@ -543,6 +543,11 @@ nsh&gt;
The default niceness is 10.
</p>
+<p>
+ <b>Multiple commands per line</b>.
+ NSH will accept multiple commands per command line with each command separated with the semi-colon character (;).
+</p>
+
<table width ="100%">
<tr bgcolor="#e4e4e4">
<td>
@@ -2650,6 +2655,13 @@ nsh>
Default: 80
</td>
</tr>
+ <tr>
+ <td valign="top"><b><code>CONFIG_NSH_DISABLE_SEMICOLON</code></b></td>
+ <td>
+ By default, you can enter multiple NSH commands on a line with each command separated by a semicolon.
+ You can disable this feature to save a little memory on FLASH challenged platforms.
+ Default: n
+ </td>
</tr>
<tr>
<td valign="top"><b><code>CONFIG_NSH_NESTDEPTH</code></b></td>
diff --git a/nuttx/configs/freedom-kl25z/minnsh/defconfig b/nuttx/configs/freedom-kl25z/minnsh/defconfig
index 4d8726cb9..14a1456c5 100644
--- a/nuttx/configs/freedom-kl25z/minnsh/defconfig
+++ b/nuttx/configs/freedom-kl25z/minnsh/defconfig
@@ -603,6 +603,7 @@ CONFIG_NSH_DISABLE_WGET=y
CONFIG_NSH_CODECS_BUFSIZE=128
CONFIG_NSH_FILEIOSIZE=64
CONFIG_NSH_LINELEN=80
+CONFIG_NSH_DISABLE_SEMICOLON=y
CONFIG_NSH_MAXARGUMENTS=6
CONFIG_NSH_NESTDEPTH=3
CONFIG_NSH_DISABLESCRIPT=y
diff --git a/nuttx/configs/sim/nsh/defconfig b/nuttx/configs/sim/nsh/defconfig
index 01c5342b0..b5d5789c4 100644
--- a/nuttx/configs/sim/nsh/defconfig
+++ b/nuttx/configs/sim/nsh/defconfig
@@ -40,7 +40,9 @@ CONFIG_HOST_LINUX=y
#
# CONFIG_DEBUG is not set
# CONFIG_ARCH_HAVE_STACKCHECK is not set
+# CONFIG_ARCH_HAVE_HEAPCHECK is not set
CONFIG_DEBUG_SYMBOLS=y
+CONFIG_DEBUG_NOOPT=y
#
# System Type
@@ -70,7 +72,7 @@ CONFIG_ARCH="sim"
# CONFIG_ARCH_NOINTC is not set
# CONFIG_ARCH_VECNOTIRQ is not set
# CONFIG_ARCH_DMA is not set
-# CONFIG_ARCH_IRQPRIO is not set
+# CONFIG_ARCH_HAVE_IRQPRIO is not set
# CONFIG_CUSTOM_STACK is not set
# CONFIG_ADDRENV is not set
# CONFIG_ARCH_HAVE_VFORK is not set
@@ -86,6 +88,12 @@ CONFIG_BOARD_LOOPSPERMSEC=0
# CONFIG_ARCH_CALIBRATION is not set
#
+# Interrupt options
+#
+# CONFIG_ARCH_HAVE_INTERRUPTSTACK is not set
+# CONFIG_ARCH_HAVE_HIPRI_INTERRUPT is not set
+
+#
# Boot options
#
CONFIG_BOOT_RUNFROMEXTSRAM=y
@@ -121,6 +129,7 @@ CONFIG_NSH_MMCSDMINOR=0
#
# CONFIG_BOARD_INITIALIZE is not set
CONFIG_MSEC_PER_TICK=10
+# CONFIG_SYSTEM_TIME64 is not set
CONFIG_RR_INTERVAL=0
# CONFIG_SCHED_INSTRUMENTATION is not set
CONFIG_TASK_NAME_SIZE=32
@@ -191,13 +200,17 @@ CONFIG_DEV_NULL=y
# CONFIG_LOOP is not set
# CONFIG_RAMDISK is not set
# CONFIG_CAN is not set
+# CONFIG_ARCH_HAVE_PWM_PULSECOUNT is not set
# CONFIG_PWM is not set
+# CONFIG_ARCH_HAVE_I2CRESET is not set
# CONFIG_I2C is not set
# CONFIG_SPI is not set
+# CONFIG_I2S is not set
# CONFIG_RTC is not set
# CONFIG_WATCHDOG is not set
# CONFIG_ANALOG is not set
# CONFIG_AUDIO_DEVICES is not set
+# CONFIG_VIDEO_DEVICES is not set
# CONFIG_BCH is not set
# CONFIG_INPUT is not set
# CONFIG_LCD is not set
@@ -207,6 +220,7 @@ CONFIG_DEV_NULL=y
# CONFIG_PM is not set
# CONFIG_POWER is not set
# CONFIG_SENSORS is not set
+# CONFIG_SERCOMM_CONSOLE is not set
CONFIG_SERIAL=y
# CONFIG_DEV_LOWCONSOLE is not set
# CONFIG_16550_UART is not set
@@ -233,6 +247,8 @@ CONFIG_SERIAL=y
#
# Networking Support
#
+# CONFIG_ARCH_HAVE_NET is not set
+# CONFIG_ARCH_HAVE_PHY is not set
# CONFIG_NET is not set
#
@@ -243,6 +259,8 @@ CONFIG_SERIAL=y
# File system configuration
#
# CONFIG_DISABLE_MOUNTPOINT is not set
+CONFIG_FS_READABLE=y
+CONFIG_FS_WRITABLE=y
# CONFIG_FS_RAMMAP is not set
CONFIG_FS_FAT=y
CONFIG_FAT_LCNAMES=y
@@ -254,6 +272,7 @@ CONFIG_FAT_MAXFNAME=32
CONFIG_FS_ROMFS=y
# CONFIG_FS_SMARTFS is not set
CONFIG_FS_BINFS=y
+# CONFIG_FS_PROCFS is not set
#
# System Logging
@@ -349,6 +368,7 @@ CONFIG_BUILTIN_PROXY_STACKSIZE=1024
#
# CONFIG_EXAMPLES_BUTTONS is not set
# CONFIG_EXAMPLES_CAN is not set
+# CONFIG_EXAMPLES_CONFIGDATA is not set
# CONFIG_EXAMPLES_DHCPD is not set
# CONFIG_EXAMPLES_ELF is not set
# CONFIG_EXAMPLES_FTPC is not set
@@ -416,14 +436,11 @@ CONFIG_EXAMPLES_NSH=y
# Networking Utilities
#
# CONFIG_NETUTILS_CODECS is not set
-# CONFIG_NETUTILS_DHCPC is not set
# CONFIG_NETUTILS_DHCPD is not set
# CONFIG_NETUTILS_FTPC is not set
# CONFIG_NETUTILS_FTPD is not set
# CONFIG_NETUTILS_JSON is not set
-# CONFIG_NETUTILS_RESOLV is not set
# CONFIG_NETUTILS_SMTP is not set
-# CONFIG_NETUTILS_TELNETD is not set
# CONFIG_NETUTILS_TFTPC is not set
# CONFIG_NETUTILS_THTTPD is not set
# CONFIG_NETUTILS_UIPLIB is not set
@@ -444,11 +461,13 @@ CONFIG_NSH_FILE_APPS=y
#
# Disable Individual commands
#
+# CONFIG_NSH_DISABLE_ADDROUTE is not set
# CONFIG_NSH_DISABLE_CAT is not set
# CONFIG_NSH_DISABLE_CD is not set
# CONFIG_NSH_DISABLE_CP is not set
# CONFIG_NSH_DISABLE_CMP is not set
# CONFIG_NSH_DISABLE_DD is not set
+# CONFIG_NSH_DISABLE_DELROUTE is not set
# CONFIG_NSH_DISABLE_ECHO is not set
# CONFIG_NSH_DISABLE_EXEC is not set
# CONFIG_NSH_DISABLE_EXIT is not set
@@ -490,8 +509,10 @@ CONFIG_NSH_FILE_APPS=y
#
# CONFIG_NSH_CMDOPT_DF_H is not set
CONFIG_NSH_CODECS_BUFSIZE=128
+# CONFIG_NSH_CMDOPT_HEXDUMP is not set
CONFIG_NSH_FILEIOSIZE=1024
CONFIG_NSH_LINELEN=80
+# CONFIG_NSH_DISABLE_SEMICOLON is not set
CONFIG_NSH_MAXARGUMENTS=6
CONFIG_NSH_NESTDEPTH=3
# CONFIG_NSH_DISABLESCRIPT is not set
@@ -520,6 +541,11 @@ CONFIG_NSH_CONSOLE=y
#
#
+# Platform-specific Support
+#
+# CONFIG_PLATFORM_CONFIGDATA is not set
+
+#
# System NSH Add-Ons
#
@@ -550,6 +576,11 @@ CONFIG_NSH_CONSOLE=y
#
#
+# NxPlayer media player library / command Line
+#
+# CONFIG_SYSTEM_NXPLAYER is not set
+
+#
# RAM test
#
# CONFIG_SYSTEM_RAMTEST is not set
diff --git a/nuttx/libc/string/lib_strstr.c b/nuttx/libc/string/lib_strstr.c
index 7a60a680d..0c695f7de 100644
--- a/nuttx/libc/string/lib_strstr.c
+++ b/nuttx/libc/string/lib_strstr.c
@@ -45,11 +45,11 @@
* Global Functions
****************************************************************************/
-char *strstr(const char *str, const char *substr)
+FAR char *strstr(FAR const char *str, FAR const char *substr)
{
- const char *candidate; /* Candidate in str with matching start character */
- char ch; /* First character of the substring */
- int len; /* The length of the substring */
+ FAR const char *candidate; /* Candidate in str with matching start character */
+ char ch; /* First character of the substring */
+ int len; /* The length of the substring */
/* Special case the empty substring */