1 /*
2 * Copyright (c) 2021 Nordic Semiconductor ASA
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6 #include <zephyr/kernel.h>
7 #include <zephyr/shell/shell.h>
8 #if CONFIG_SHELL_GETOPT
9 #include <zephyr/sys/iterable_sections.h>
10 #endif
11
12 #include "getopt.h"
13
14 /* Referring below variables is not thread safe. They reflects getopt state
15 * only when 1 thread is using getopt.
16 * When more threads are using getopt please call getopt_state_get to know
17 * getopt state for the current thread.
18 */
19 int opterr = 1; /* if error message should be printed */
20 int optind = 1; /* index into parent argv vector */
21 int optopt; /* character checked for validity */
22 int optreset; /* reset getopt */
23 char *optarg; /* argument associated with option */
24
25 /* Common state for all threads that did not have own getopt state. */
26 static struct getopt_state m_getopt_common_state = {
27 .opterr = 1,
28 .optind = 1,
29 .optopt = 0,
30 .optreset = 0,
31 .optarg = NULL,
32
33 .place = "", /* EMSG */
34
35 #if CONFIG_GETOPT_LONG
36 .nonopt_start = -1, /* first non option argument (for permute) */
37 .nonopt_end = -1, /* first option after non options (for permute) */
38 #endif
39 };
40
41 /* This function is not thread safe. All threads using getopt are calling
42 * this function.
43 */
z_getopt_global_state_update(struct getopt_state * state)44 void z_getopt_global_state_update(struct getopt_state *state)
45 {
46 opterr = state->opterr;
47 optind = state->optind;
48 optopt = state->optopt;
49 optreset = state->optreset;
50 optarg = state->optarg;
51 }
52
53 /* It is internal getopt API function, it shall not be called by the user. */
getopt_state_get(void)54 struct getopt_state *getopt_state_get(void)
55 {
56 #if CONFIG_SHELL_GETOPT
57 k_tid_t tid;
58
59 tid = k_current_get();
60 STRUCT_SECTION_FOREACH(shell, sh) {
61 if (tid == sh->ctx->tid) {
62 return &sh->ctx->getopt;
63 }
64 }
65 #endif
66 /* If not a shell thread return a common pointer */
67 return &m_getopt_common_state;
68 }
69