From a0f773b3181395d673b3ba34906c85bc53bc64fc Mon Sep 17 00:00:00 2001 From: Xiang Xiao Date: Sun, 31 Oct 2021 21:36:07 +0800 Subject: [PATCH] nshlib/nsh_session: Handle the command arguments in any order Signed-off-by: Xiang Xiao --- nshlib/nsh_session.c | 166 ++++++++++++++++++++++++------------------- 1 file changed, 94 insertions(+), 72 deletions(-) diff --git a/nshlib/nsh_session.c b/nshlib/nsh_session.c index e7cfff7cb..e0016061b 100644 --- a/nshlib/nsh_session.c +++ b/nshlib/nsh_session.c @@ -70,6 +70,7 @@ int nsh_session(FAR struct console_stdio_s *pstate, { FAR struct nsh_vtbl_s *vtbl; int ret = EXIT_FAILURE; + int i; DEBUGASSERT(pstate); vtbl = &pstate->cn_vtbl; @@ -113,91 +114,112 @@ int nsh_session(FAR struct console_stdio_s *pstate, #endif } - if (argc < 2) - { - /* Then enter the command line parsing loop */ + /* Process the command line option */ - for (; ; ) + for (i = 1; i < argc; i++) + { + if (strcmp(argv[i], "-h") == 0) { - /* For the case of debugging the USB console... - * dump collected USB trace data - */ - -#ifdef CONFIG_NSH_USBDEV_TRACE - nsh_usbtrace(); -#endif - - /* Get the next line of input. readline() returns EOF - * on end-of-file or any read failure. - */ - -#ifdef CONFIG_NSH_CLE - /* cle() normally returns the number of characters read, but will - * return a negated errno value on end of file or if an error - * occurs. Either will cause the session to terminate. - */ - - ret = cle(pstate->cn_line, g_nshprompt, CONFIG_NSH_LINELEN, - INSTREAM(pstate), OUTSTREAM(pstate)); - if (ret < 0) - { - fprintf(pstate->cn_errstream, g_fmtcmdfailed, "nsh_session", - "cle", NSH_ERRNO_OF(-ret)); - continue; - } -#else - /* Display the prompt string */ - - fputs(g_nshprompt, pstate->cn_outstream); - fflush(pstate->cn_outstream); - - /* readline() normally returns the number of characters read, but - * will return EOF on end of file or if an error occurs. EOF - * will cause the session to terminate. - */ - - ret = readline(pstate->cn_line, CONFIG_NSH_LINELEN, - INSTREAM(pstate), OUTSTREAM(pstate)); - if (ret == EOF) - { - /* NOTE: readline() does not set the errno variable, but - * perhaps we will be lucky and it will still be valid. - */ - - fprintf(pstate->cn_errstream, g_fmtcmdfailed, "nsh_session", - "readline", NSH_ERRNO); - ret = EXIT_SUCCESS; - break; - } -#endif - - /* Parse process the command */ - - nsh_parse(vtbl, pstate->cn_line); - fflush(pstate->cn_outstream); + nsh_output(vtbl, "Usage: %s [|-c ]\n", + argv[0]); + return EXIT_SUCCESS; } + else if (strcmp(argv[i], "-c") == 0) + { + /* Process the inline command */ + + if (i + 1 < argc) + { + return nsh_parse(vtbl, argv[i + 1]); + } + else + { + nsh_error(vtbl, g_fmtargrequired, argv[0]); + return EXIT_FAILURE; + } + } + else if (argv[i][0] != '-') + { + break; + } + + /* Unknown option */ + + nsh_error(vtbl, g_fmtsyntax, argv[0]); + return EXIT_FAILURE; } - else if (strcmp(argv[1], "-h") == 0) + + if (i < argc) { - ret = nsh_output(vtbl, "Usage: %s [|-c ]\n", - argv[0]); - } - else if (strcmp(argv[1], "-c") != 0) - { -#if defined(CONFIG_FILE_STREAM) && !defined(CONFIG_NSH_DISABLESCRIPT) +#ifndef CONFIG_NSH_DISABLESCRIPT /* Execute the shell script */ - ret = nsh_script(vtbl, argv[0], argv[1]); + return nsh_script(vtbl, argv[0], argv[i]); +#else + return EXIT_FAILURE; #endif } - else if (argc >= 3) + + /* Then enter the command line parsing loop */ + + for (; ; ) { + /* For the case of debugging the USB console... + * dump collected USB trace data + */ + +#ifdef CONFIG_NSH_USBDEV_TRACE + nsh_usbtrace(); +#endif + + /* Get the next line of input. readline() returns EOF + * on end-of-file or any read failure. + */ + +#ifdef CONFIG_NSH_CLE + /* cle() normally returns the number of characters read, but will + * return a negated errno value on end of file or if an error + * occurs. Either will cause the session to terminate. + */ + + ret = cle(pstate->cn_line, g_nshprompt, CONFIG_NSH_LINELEN, + INSTREAM(pstate), OUTSTREAM(pstate)); + if (ret < 0) + { + fprintf(pstate->cn_errstream, g_fmtcmdfailed, "nsh_session", + "cle", NSH_ERRNO_OF(-ret)); + continue; + } +#else + /* Display the prompt string */ + + fputs(g_nshprompt, pstate->cn_outstream); + fflush(pstate->cn_outstream); + + /* readline() normally returns the number of characters read, but + * will return EOF on end of file or if an error occurs. EOF + * will cause the session to terminate. + */ + + ret = readline(pstate->cn_line, CONFIG_NSH_LINELEN, + INSTREAM(pstate), OUTSTREAM(pstate)); + if (ret == EOF) + { + /* NOTE: readline() does not set the errno variable, but + * perhaps we will be lucky and it will still be valid. + */ + + fprintf(pstate->cn_errstream, g_fmtcmdfailed, "nsh_session", + "readline", NSH_ERRNO); + ret = EXIT_SUCCESS; + break; + } +#endif + /* Parse process the command */ - ret = nsh_parse(vtbl, argv[2]); -#ifdef CONFIG_FILE_STREAM + nsh_parse(vtbl, pstate->cn_line); fflush(pstate->cn_outstream); -#endif } return ret;