Branch data Line data Source code
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 <zephyr/sys/sys_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 sys_getopt_opterr = 1; /* if error message should be printed */
20 : : int sys_getopt_optind = 1; /* index into parent argv vector */
21 : : int sys_getopt_optopt; /* character checked for validity */
22 : : int sys_getopt_optreset; /* reset getopt */
23 : : char *sys_getopt_optarg; /* argument associated with option */
24 : :
25 : : /* Common state for all threads that did not have own getopt state. */
26 : : static struct sys_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 : : /* Shim function to update global variables in getopt_shim.c if user wants to
42 : : * still use the original non-posix compliant getopt. The shim will be deprecated
43 : : * and eventually removed in the future.
44 : : */
45 : : extern void z_getopt_global_state_update_shim(struct sys_getopt_state *state);
46 : :
47 : : /* This function is not thread safe. All threads using getopt are calling
48 : : * this function.
49 : : */
50 : 0 : void z_getopt_global_state_update(struct sys_getopt_state *state)
51 : : {
52 : 0 : sys_getopt_opterr = state->opterr;
53 : 0 : sys_getopt_optind = state->optind;
54 : 0 : sys_getopt_optopt = state->optopt;
55 : 0 : sys_getopt_optreset = state->optreset;
56 : 0 : sys_getopt_optarg = state->optarg;
57 : :
58 : 0 : if (!IS_ENABLED(CONFIG_NATIVE_LIBC) && IS_ENABLED(CONFIG_POSIX_C_LIB_EXT)) {
59 : : z_getopt_global_state_update_shim(state);
60 : : }
61 : 0 : }
62 : :
63 : : /* It is internal getopt API function, it shall not be called by the user. */
64 : 0 : struct sys_getopt_state *sys_getopt_state_get(void)
65 : : {
66 : : #if CONFIG_SHELL_GETOPT
67 : : k_tid_t tid;
68 : :
69 : : tid = k_current_get();
70 : : STRUCT_SECTION_FOREACH(shell, sh) {
71 : : if (tid == sh->ctx->tid) {
72 : : return &sh->ctx->getopt;
73 : : }
74 : : }
75 : : #endif
76 : : /* If not a shell thread return a common pointer */
77 : 0 : return &m_getopt_common_state;
78 : : }
|