| /* |
| * Copyright (c) 2018 Oticon A/S |
| * |
| * SPDX-License-Identifier: Apache-2.0 |
| */ |
| |
| #include <stdbool.h> |
| #include <stdlib.h> |
| #include <string.h> |
| #include "cmdline_common.h" |
| #include <zephyr/types.h> |
| #include "hw_models_top.h" |
| #include "timer_model.h" |
| #include "cmdline.h" |
| #include <zephyr/toolchain.h> |
| #include <zephyr/arch/posix/posix_trace.h> |
| #include "native_tracing.h" |
| |
| static int s_argc, test_argc; |
| static char **s_argv, **test_argv; |
| |
| static struct args_struct_t *args_struct; |
| static int used_args; |
| static int args_aval; |
| #define ARGS_ALLOC_CHUNK_SIZE 20 |
| |
| void native_cleanup_cmd_line(void) |
| { |
| if (args_struct != NULL) { /* LCOV_EXCL_BR_LINE */ |
| free(args_struct); |
| args_struct = NULL; |
| } |
| } |
| |
| /** |
| * Add a set of command line options to the program. |
| * |
| * Each option to be added is described in one entry of the input <args> |
| * This input must be terminated with an entry containing ARG_TABLE_ENDMARKER. |
| */ |
| void native_add_command_line_opts(struct args_struct_t *args) |
| { |
| int count = 0; |
| |
| while (args[count].option != NULL) { |
| count++; |
| } |
| count++; /*for the end marker*/ |
| |
| if (used_args + count >= args_aval) { |
| int growby = count; |
| /* reallocs are expensive let's do them only in big chunks */ |
| if (growby < ARGS_ALLOC_CHUNK_SIZE) { |
| growby = ARGS_ALLOC_CHUNK_SIZE; |
| } |
| |
| struct args_struct_t *new_args_struct = realloc(args_struct, |
| (args_aval + growby)* |
| sizeof(struct args_struct_t)); |
| args_aval += growby; |
| /* LCOV_EXCL_START */ |
| if (new_args_struct == NULL) { |
| posix_print_error_and_exit("Could not allocate memory"); |
| } else { |
| args_struct = new_args_struct; |
| } |
| /* LCOV_EXCL_STOP */ |
| } |
| |
| memcpy(&args_struct[used_args], args, |
| count*sizeof(struct args_struct_t)); |
| |
| used_args += count - 1; |
| /* |
| * -1 as the end marker should be overwritten next time something |
| * is added |
| */ |
| } |
| |
| void native_add_testargs_option(void) |
| { |
| static struct args_struct_t testargs_options[] = { |
| /* |
| * Fields: |
| * manual, mandatory, switch, |
| * option_name, var_name ,type, |
| * destination, callback, |
| * description |
| */ |
| {true, false, false, |
| "testargs", "arg", 'l', |
| (void *)NULL, NULL, |
| "Any argument that follows will be ignored by the top level, " |
| "and made available for possible tests"}, |
| ARG_TABLE_ENDMARKER}; |
| |
| native_add_command_line_opts(testargs_options); |
| } |
| |
| static void print_invalid_opt_error(char *argv) |
| { |
| posix_print_error_and_exit("Incorrect option '%s'. Did you misspell it?" |
| " Is that feature supported in this build?" |
| "\n", |
| argv); |
| |
| } |
| |
| /** |
| * Handle possible command line arguments. |
| * |
| * We also store them for later use by possible test applications |
| */ |
| void native_handle_cmd_line(int argc, char *argv[]) |
| { |
| int i; |
| |
| native_add_tracing_options(); |
| native_add_testargs_option(); |
| |
| s_argv = argv; |
| s_argc = argc; |
| |
| cmd_args_set_defaults(args_struct); |
| |
| for (i = 1; i < argc; i++) { |
| |
| if ((cmd_is_option(argv[i], "testargs", 0))) { |
| test_argc = argc - i - 1; |
| test_argv = &argv[i+1]; |
| break; |
| } |
| |
| if (!cmd_parse_one_arg(argv[i], args_struct)) { |
| cmd_print_switches_help(args_struct); |
| print_invalid_opt_error(argv[i]); |
| } |
| } |
| } |
| |
| /** |
| * The application/test can use this function to inspect all the command line |
| * arguments |
| */ |
| void native_get_cmd_line_args(int *argc, char ***argv) |
| { |
| *argc = s_argc; |
| *argv = s_argv; |
| } |
| |
| /** |
| * The application/test can use this function to inspect the command line |
| * arguments received after --testargs |
| */ |
| void native_get_test_cmd_line_args(int *argc, char ***argv) |
| { |
| *argc = test_argc; |
| *argv = test_argv; |
| } |