You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by xi...@apache.org on 2021/04/03 06:07:41 UTC
[incubator-nuttx-apps] branch master updated: testing/ostest: Add a
test of the getopt() family of interfaces.
This is an automated email from the ASF dual-hosted git repository.
xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx-apps.git
The following commit(s) were added to refs/heads/master by this push:
new 99138f6 testing/ostest: Add a test of the getopt() family of interfaces.
99138f6 is described below
commit 99138f6b39fa9764c6c68a9a6511768f7e092461
Author: Gregory Nutt <gn...@nuttx.org>
AuthorDate: Thu Apr 1 14:17:07 2021 -0600
testing/ostest: Add a test of the getopt() family of interfaces.
This new test was used to verify the new implementations of getopt_long() and getopt_long_only() and to verify that there are no regressions to the existing getopts().
Only the OS test is affect by this change.
Verified with the getopt() modifications on a modified version of the sim:nsh configuration.
---
testing/ostest/Makefile | 2 +-
testing/ostest/getopt.c | 476 +++++++++++++++++++++++++++++++++++++++++++
testing/ostest/ostest.h | 4 +
testing/ostest/ostest_main.c | 8 +
4 files changed, 489 insertions(+), 1 deletion(-)
diff --git a/testing/ostest/Makefile b/testing/ostest/Makefile
index f0240cf..9767675 100644
--- a/testing/ostest/Makefile
+++ b/testing/ostest/Makefile
@@ -29,7 +29,7 @@ MODULE = $(CONFIG_TESTING_OSTEST)
# NuttX OS Test
-CSRCS = dev_null.c restart.c sigprocmask.c sighand.c signest.c
+CSRCS = getopt.c dev_null.c restart.c sigprocmask.c sighand.c signest.c
MAINSRC = ostest_main.c
ifeq ($(CONFIG_SIG_SIGSTOP_ACTION),y)
diff --git a/testing/ostest/getopt.c b/testing/ostest/getopt.c
new file mode 100644
index 0000000..96ae1f5
--- /dev/null
+++ b/testing/ostest/getopt.c
@@ -0,0 +1,476 @@
+/****************************************************************************
+ * apps/testing/ostest/getopt.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership. The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <stdio.h>
+#include <getopt.h>
+
+#include "ostest.h"
+
+/****************************************************************************
+ * Pre-processor DEFINTIONS
+ ****************************************************************************/
+
+#define SHORT_RESULT_A(n) \
+ { \
+ results[n].ret = 'a'; \
+ results[n].flag = 0; \
+ results[n].arg = NULL; \
+ }
+
+#define SHORT_RESULT_B(n) \
+ { \
+ results[n].ret = 'b'; \
+ results[n].flag = 0; \
+ results[n].arg = NULL; \
+ }
+
+#define SHORT_RESULT_C1(n) \
+ { \
+ results[n].ret = 'c'; \
+ results[n].flag = 0; \
+ results[n].arg = "Arg1"; \
+ }
+
+#define SHORT_RESULT_C2(n) \
+ { \
+ results[n].ret = 'c'; \
+ results[n].flag = 0; \
+ results[n].arg = NULL; \
+ }
+
+#define SHORT_RESULT_D(n) \
+ { \
+ results[n].ret = 'd'; \
+ results[n].flag = 0; \
+ results[n].arg = "Arg2"; \
+ }
+
+#define LONG_OPTION_A(n) \
+ { \
+ long_options[n].name = "OptionA"; \
+ long_options[n].has_arg = no_argument; \
+ long_options[n].flag = NULL; \
+ long_options[n].val = 'a'; \
+ }
+
+#define LONG_OPTION_B(n) \
+ { \
+ long_options[n].name = "OptionB"; \
+ long_options[n].has_arg = no_argument; \
+ long_options[n].flag = &g_flag; \
+ long_options[n].val = 'b'; \
+ }
+
+#define LONG_OPTION_C(n) \
+ { \
+ long_options[n].name = "OptionC"; \
+ long_options[n].has_arg = required_argument; \
+ long_options[n].flag = NULL; \
+ long_options[n].val = 'c'; \
+ }
+
+#define LONG_OPTION_D(n) \
+ { \
+ long_options[n].name = "OptionD"; \
+ long_options[n].has_arg = optional_argument; \
+ long_options[n].flag = &g_flag; \
+ long_options[n].val = 'd'; \
+ }
+
+#define LONG_OPTION_END(n) \
+ { \
+ long_options[n].name = NULL; \
+ long_options[n].has_arg = 0; \
+ long_options[n].flag = NULL; \
+ long_options[n].val = 0; \
+ }
+
+#define LONG_RESULT_A(n) \
+ { \
+ results[n].ret = 'a'; \
+ results[n].flag = 0; \
+ results[n].arg = NULL; \
+ }
+
+#define LONG_RESULT_B(n) \
+ { \
+ results[n].ret = OK; \
+ results[n].flag = 'b'; \
+ results[n].arg = NULL; \
+ }
+
+#define LONG_RESULT_C(n) \
+ { \
+ results[n].ret = 'c'; \
+ results[n].flag = 0; \
+ results[n].arg = "Arg1"; \
+ }
+
+#define LONG_RESULT_D1(n) \
+ { \
+ results[n].ret = OK; \
+ results[n].flag = 'd'; \
+ results[n].arg = "Arg2"; \
+ }
+
+#define LONG_RESULT_D2(n) \
+ { \
+ results[n].ret = OK; \
+ results[n].flag = 'd'; \
+ results[n].arg = NULL; \
+ }
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+struct result_s
+{
+ int ret;
+ int flag;
+ FAR char *arg;
+};
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+static int g_flag;
+static const char *g_optstring = "abc::d:";
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static int getopt_short_test(int argc, FAR char **argv,
+ FAR const char *optstring,
+ FAR const struct result_s *expected)
+{
+ int ndx;
+ int ret;
+
+ optarg = NULL;
+
+ for (ndx = 0;
+ (ret = getopt(argc, argv, g_optstring)) != ERROR;
+ ndx++)
+ {
+ if (optind < 1 || optind >= argc)
+ {
+ printf("ERROR: optind=%d\n", optind);
+ }
+
+ if (expected[ndx].ret != ret)
+ {
+ printf("ERROR: ret=%d (expected %d)\n",
+ ret, expected[ndx].ret);
+ }
+
+ if (expected[ndx].arg != optarg)
+ {
+ printf("ERROR: optarg=%s (expected %s)\n",
+ optarg == NULL ? "null" : optarg,
+ expected[ndx].arg == NULL ? "null" :
+ expected[ndx].arg);
+ }
+
+ optarg = NULL;
+ }
+
+ return OK;
+}
+
+static int getopt_long_test(int argc, FAR char **argv,
+ FAR const char *optstring,
+ FAR const struct option *longopts,
+ FAR int *longindex,
+ FAR const struct result_s *expected)
+{
+ int ndx;
+ int ret;
+
+ optarg = NULL;
+ g_flag = 0;
+
+ for (ndx = 0;
+ (ret = getopt_long(argc, argv, g_optstring, longopts,
+ longindex)) != ERROR;
+ ndx++)
+ {
+ if (optind < 1 || optind > 7)
+ {
+ printf("ERROR: optind=%d\n", optind);
+ }
+
+ if (expected[ndx].ret != ret)
+ {
+ printf("ERROR: ret=%d (expected %d)\n",
+ ret, expected[ndx].ret);
+ }
+
+ if (expected[ndx].flag != g_flag)
+ {
+ printf("ERROR: flag=%d (expected %d)\n",
+ expected[ndx].flag, g_flag);
+ }
+
+ if (expected[ndx].arg != optarg)
+ {
+ printf("ERROR: optarg=%s (expected %s)\n",
+ optarg == NULL ? "null" : optarg,
+ expected[ndx].arg == NULL ? "null" :
+ expected[ndx].arg);
+ }
+
+ optarg = NULL;
+ g_flag = 0;
+ }
+
+ return OK;
+}
+
+static int getopt_longonly_test(int argc, FAR char **argv,
+ FAR const char *optstring,
+ FAR const struct option *longopts,
+ FAR int *longindex,
+ FAR const struct result_s *expected)
+{
+ int ndx;
+ int ret;
+
+ optarg = NULL;
+ g_flag = 0;
+
+ for (ndx = 0;
+ (ret = getopt_long_only(argc, argv, g_optstring, longopts,
+ longindex)) != ERROR;
+ ndx++)
+ {
+ if (optind < 1 || optind > 7)
+ {
+ printf("ERROR: optind=%d\n", optind);
+ }
+
+ if (expected[ndx].ret != ret)
+ {
+ printf("ERROR: ret=%d (expected %d)\n",
+ ret, expected[ndx].ret);
+ }
+
+ if (expected[ndx].flag != g_flag)
+ {
+ printf("ERROR: flag=%d (expected %d)\n",
+ expected[ndx].flag, g_flag);
+ }
+
+ if (expected[ndx].arg != optarg)
+ {
+ printf("ERROR: optarg=%s (expected %s)\n",
+ optarg == NULL ? "null" : optarg,
+ expected[ndx].arg == NULL ? "null" :
+ expected[ndx].arg);
+ }
+
+ optarg = NULL;
+ g_flag = 0;
+ }
+
+ return OK;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+int getopt_test(void)
+{
+ struct option long_options[5];
+ struct result_s results[4];
+ FAR char *argv[9];
+
+ printf("getopt(): Simple test\n");
+
+ argv[0] = NULL;
+ argv[1] = "-a";
+ argv[2] = "-b";
+ argv[3] = "-c";
+ argv[4] = "Arg1";
+ argv[5] = "-d";
+ argv[6] = "Arg2";
+ argv[7] = "NoOption";
+ argv[8] = NULL;
+
+ SHORT_RESULT_A(0);
+ SHORT_RESULT_B(1);
+ SHORT_RESULT_C1(2);
+ SHORT_RESULT_D(3);
+
+ getopt_short_test(8, argv, g_optstring, results);
+
+ printf("getopt(): Missing optional argument\n");
+
+ argv[0] = NULL;
+ argv[1] = "-a";
+ argv[2] = "-b";
+ argv[3] = "-c";
+ argv[4] = "-d";
+ argv[5] = "Arg2";
+ argv[6] = "NoOption";
+ argv[7] = NULL;
+
+ SHORT_RESULT_A(0);
+ SHORT_RESULT_B(1);
+ SHORT_RESULT_C2(2);
+ SHORT_RESULT_D(3);
+
+ getopt_short_test(7, argv, g_optstring, results);
+
+ printf("getopt_long(): Simple test\n");
+
+ argv[0] = NULL;
+ argv[1] = "--OptionA";
+ argv[2] = "--OptionB";
+ argv[3] = "--OptionC";
+ argv[4] = "Arg1";
+ argv[5] = "--OptionD";
+ argv[6] = "Arg2";
+ argv[7] = "NoOption";
+ argv[8] = NULL;
+
+ LONG_OPTION_A(0);
+ LONG_OPTION_B(1);
+ LONG_OPTION_C(2);
+ LONG_OPTION_D(3);
+ LONG_OPTION_END(4)
+
+ LONG_RESULT_A(0);
+ LONG_RESULT_B(1);
+ LONG_RESULT_C(2);
+ LONG_RESULT_D1(3);
+
+ getopt_long_test(8, argv, g_optstring, long_options, NULL,
+ results);
+
+ printf("getopt_long(): No short options\n");
+
+ getopt_long_test(8, argv, NULL, long_options, NULL,
+ results);
+
+ printf("getopt_long(): Mixed long and short options\n");
+
+ argv[0] = NULL;
+ argv[1] = "--OptionA";
+ argv[2] = "-b";
+ argv[3] = "--OptionC";
+ argv[4] = "Arg1";
+ argv[5] = "-d";
+ argv[6] = "Arg2";
+ argv[7] = "NoOption";
+ argv[8] = NULL;
+
+ LONG_OPTION_A(0);
+ LONG_OPTION_C(1);
+ LONG_OPTION_END(2)
+
+ LONG_RESULT_A(0);
+ SHORT_RESULT_B(1);
+ LONG_RESULT_C(2);
+ SHORT_RESULT_D(3);
+
+ getopt_long_test(8, argv, g_optstring, long_options, NULL,
+ results);
+
+ printf("getopt_long(): Missing optional arguments\n");
+
+ argv[0] = NULL;
+ argv[1] = "--OptionA";
+ argv[2] = "--OptionB";
+ argv[3] = "-c";
+ argv[4] = "--OptionD";
+ argv[5] = NULL;
+
+ LONG_OPTION_A(0);
+ LONG_OPTION_B(1);
+ LONG_OPTION_D(2);
+ LONG_OPTION_END(3)
+
+ LONG_RESULT_A(0);
+ LONG_RESULT_B(1);
+ SHORT_RESULT_C2(2);
+ LONG_RESULT_D2(3);
+
+ getopt_long_test(6, argv, g_optstring, long_options, NULL,
+ results);
+
+ printf("getopt_long_only(): Mixed long and short options\n");
+
+ argv[0] = NULL;
+ argv[1] = "-a";
+ argv[2] = "--OptionB";
+ argv[3] = "-c";
+ argv[4] = "Arg1";
+ argv[5] = "--OptionD";
+ argv[6] = "Arg2";
+ argv[7] = "NoOption";
+ argv[8] = NULL;
+
+ LONG_OPTION_B(0);
+ LONG_OPTION_D(1);
+ LONG_OPTION_END(2)
+
+ SHORT_RESULT_A(0);
+ LONG_RESULT_B(1);
+ SHORT_RESULT_C1(2);
+ LONG_RESULT_D1(3);
+
+ getopt_longonly_test(8, argv, g_optstring, long_options, NULL,
+ results);
+
+ printf("getopt_long_only(): Single hyphen long options\n");
+
+ argv[0] = NULL;
+ argv[1] = "-OptionA";
+ argv[2] = "-b";
+ argv[3] = "--OptionC";
+ argv[4] = "Arg1";
+ argv[5] = "-d";
+ argv[6] = "Arg2";
+ argv[7] = "NoOption";
+ argv[8] = NULL;
+
+ LONG_OPTION_A(0);
+ LONG_OPTION_C(1);
+ LONG_OPTION_END(2)
+
+ LONG_RESULT_A(0);
+ SHORT_RESULT_B(1);
+ LONG_RESULT_C(2);
+ SHORT_RESULT_D(3);
+
+ getopt_longonly_test(8, argv, g_optstring, long_options, NULL,
+ results);
+ return OK;
+}
diff --git a/testing/ostest/ostest.h b/testing/ostest/ostest.h
index 136786c..33a18c8 100644
--- a/testing/ostest/ostest.h
+++ b/testing/ostest/ostest.h
@@ -92,6 +92,10 @@
* Public Function Prototypes
****************************************************************************/
+/* getopt.c *****************************************************************/
+
+int getopt_test(void);
+
/* setvbuf.c ****************************************************************/
#ifndef CONFIG_STDIO_DISABLE_BUFFERING
diff --git a/testing/ostest/ostest_main.c b/testing/ostest/ostest_main.c
index 61fcab0..3677052 100644
--- a/testing/ostest/ostest_main.c
+++ b/testing/ostest/ostest_main.c
@@ -246,6 +246,14 @@ static int user_main(int argc, char *argv[])
check_test_memory_usage();
+ /* Test additional getopt(), getopt_long(), and getopt_long_only()
+ * features.
+ */
+
+ printf("\nuser_main: getopt() test\n");
+ getopt_test();
+ check_test_memory_usage();
+
/* If retention of child status is enable, then suppress it for this task.
* This task may produce many, many children (especially if
* CONFIG_TESTING_OSTEST_LOOPS) and it does not harvest their exit status.