1 /*
2 * Copyright (c) 2018 Nordic Semiconductor ASA
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6 #ifndef SHELL_OPS_H__
7 #define SHELL_OPS_H__
8
9 #include <stdbool.h>
10 #include <zephyr/shell/shell.h>
11 #include "shell_vt100.h"
12 #include "shell_utils.h"
13
14 #ifdef __cplusplus
15 extern "C" {
16 #endif
17
z_shell_raw_fprintf(const struct shell_fprintf * const ctx,const char * fmt,...)18 static inline void z_shell_raw_fprintf(const struct shell_fprintf *const ctx,
19 const char *fmt, ...)
20 {
21 va_list args;
22
23 va_start(args, fmt);
24 z_shell_fprintf_fmt(ctx, fmt, args);
25 va_end(args);
26 }
27
28 /* Macro to send VT100 command. */
29 #define Z_SHELL_VT100_CMD(_shell_, ...) \
30 do { \
31 if (!IS_ENABLED(CONFIG_SHELL_VT100_COMMANDS) || \
32 !z_flag_use_vt100_get(_shell_)) \
33 break; \
34 z_shell_raw_fprintf(_shell_->fprintf_ctx, __VA_ARGS__); \
35 } while (0)
36
37 #define Z_SHELL_SET_FLAG_ATOMIC(_shell_, _type_, _flag_, _val_, _ret_) \
38 do { \
39 union shell_backend_##_type_ _internal_; \
40 atomic_t *_dst_ = (atomic_t *)&(_shell_)->ctx->_type_.value; \
41 _internal_.value = 0U; \
42 _internal_.flags._flag_ = 1U; \
43 if (_val_) { \
44 _internal_.value = atomic_or(_dst_, \
45 _internal_.value); \
46 } else { \
47 _internal_.value = atomic_and(_dst_, \
48 ~_internal_.value); \
49 } \
50 _ret_ = (_internal_.flags._flag_ != 0); \
51 } while (0)
52
z_flag_insert_mode_get(const struct shell * sh)53 static inline bool z_flag_insert_mode_get(const struct shell *sh)
54 {
55 return sh->ctx->cfg.flags.insert_mode == 1;
56 }
57
z_flag_insert_mode_set(const struct shell * sh,bool val)58 static inline bool z_flag_insert_mode_set(const struct shell *sh, bool val)
59 {
60 bool ret;
61
62 Z_SHELL_SET_FLAG_ATOMIC(sh, cfg, insert_mode, val, ret);
63 return ret;
64 }
65
z_flag_use_colors_get(const struct shell * sh)66 static inline bool z_flag_use_colors_get(const struct shell *sh)
67 {
68 return sh->ctx->cfg.flags.use_colors == 1;
69 }
70
z_flag_use_colors_set(const struct shell * sh,bool val)71 static inline bool z_flag_use_colors_set(const struct shell *sh, bool val)
72 {
73 bool ret;
74
75 Z_SHELL_SET_FLAG_ATOMIC(sh, cfg, use_colors, val, ret);
76 return ret;
77 }
78
z_flag_use_vt100_get(const struct shell * sh)79 static inline bool z_flag_use_vt100_get(const struct shell *sh)
80 {
81 return sh->ctx->cfg.flags.use_vt100 == 1;
82 }
83
z_flag_use_vt100_set(const struct shell * sh,bool val)84 static inline bool z_flag_use_vt100_set(const struct shell *sh, bool val)
85 {
86 bool ret;
87
88 Z_SHELL_SET_FLAG_ATOMIC(sh, cfg, use_vt100, val, ret);
89 return ret;
90 }
91
z_flag_echo_get(const struct shell * sh)92 static inline bool z_flag_echo_get(const struct shell *sh)
93 {
94 return sh->ctx->cfg.flags.echo == 1;
95 }
96
z_flag_echo_set(const struct shell * sh,bool val)97 static inline bool z_flag_echo_set(const struct shell *sh, bool val)
98 {
99 bool ret;
100
101 Z_SHELL_SET_FLAG_ATOMIC(sh, cfg, echo, val, ret);
102 return ret;
103 }
104
z_flag_obscure_get(const struct shell * sh)105 static inline bool z_flag_obscure_get(const struct shell *sh)
106 {
107 return sh->ctx->cfg.flags.obscure == 1;
108 }
109
z_flag_obscure_set(const struct shell * sh,bool val)110 static inline bool z_flag_obscure_set(const struct shell *sh, bool val)
111 {
112 bool ret;
113
114 Z_SHELL_SET_FLAG_ATOMIC(sh, cfg, obscure, val, ret);
115 return ret;
116 }
117
z_flag_processing_get(const struct shell * sh)118 static inline bool z_flag_processing_get(const struct shell *sh)
119 {
120 return sh->ctx->ctx.flags.processing == 1;
121 }
122
z_flag_processing_set(const struct shell * sh,bool val)123 static inline bool z_flag_processing_set(const struct shell *sh, bool val)
124 {
125 bool ret;
126
127 Z_SHELL_SET_FLAG_ATOMIC(sh, ctx, processing, val, ret);
128 return ret;
129 }
130
z_flag_tx_rdy_get(const struct shell * sh)131 static inline bool z_flag_tx_rdy_get(const struct shell *sh)
132 {
133 return sh->ctx->ctx.flags.tx_rdy == 1;
134 }
135
z_flag_tx_rdy_set(const struct shell * sh,bool val)136 static inline bool z_flag_tx_rdy_set(const struct shell *sh, bool val)
137 {
138 bool ret;
139
140 Z_SHELL_SET_FLAG_ATOMIC(sh, ctx, tx_rdy, val, ret);
141 return ret;
142 }
143
z_flag_mode_delete_get(const struct shell * sh)144 static inline bool z_flag_mode_delete_get(const struct shell *sh)
145 {
146 return sh->ctx->cfg.flags.mode_delete == 1;
147 }
148
z_flag_mode_delete_set(const struct shell * sh,bool val)149 static inline bool z_flag_mode_delete_set(const struct shell *sh, bool val)
150 {
151 bool ret;
152
153 Z_SHELL_SET_FLAG_ATOMIC(sh, cfg, mode_delete, val, ret);
154 return ret;
155 }
156
z_flag_history_exit_get(const struct shell * sh)157 static inline bool z_flag_history_exit_get(const struct shell *sh)
158 {
159 return sh->ctx->ctx.flags.history_exit == 1;
160 }
161
z_flag_history_exit_set(const struct shell * sh,bool val)162 static inline bool z_flag_history_exit_set(const struct shell *sh, bool val)
163 {
164 bool ret;
165
166 Z_SHELL_SET_FLAG_ATOMIC(sh, ctx, history_exit, val, ret);
167 return ret;
168 }
169
z_flag_cmd_ctx_get(const struct shell * sh)170 static inline bool z_flag_cmd_ctx_get(const struct shell *sh)
171 {
172 return sh->ctx->ctx.flags.cmd_ctx == 1;
173 }
174
z_flag_cmd_ctx_set(const struct shell * sh,bool val)175 static inline bool z_flag_cmd_ctx_set(const struct shell *sh, bool val)
176 {
177 bool ret;
178
179 Z_SHELL_SET_FLAG_ATOMIC(sh, ctx, cmd_ctx, val, ret);
180 return ret;
181 }
182
z_flag_last_nl_get(const struct shell * sh)183 static inline uint8_t z_flag_last_nl_get(const struct shell *sh)
184 {
185 return sh->ctx->ctx.flags.last_nl;
186 }
187
z_shell_get_return_value(const struct shell * sh)188 static inline int z_shell_get_return_value(const struct shell *sh)
189 {
190 return sh->ctx->ret_val;
191 }
192
z_flag_last_nl_set(const struct shell * sh,uint8_t val)193 static inline void z_flag_last_nl_set(const struct shell *sh, uint8_t val)
194 {
195 sh->ctx->ctx.flags.last_nl = val;
196 }
197
z_flag_print_noinit_get(const struct shell * sh)198 static inline bool z_flag_print_noinit_get(const struct shell *sh)
199 {
200 return sh->ctx->ctx.flags.print_noinit == 1;
201 }
202
z_flag_print_noinit_set(const struct shell * sh,bool val)203 static inline bool z_flag_print_noinit_set(const struct shell *sh, bool val)
204 {
205 bool ret;
206
207 Z_SHELL_SET_FLAG_ATOMIC(sh, ctx, print_noinit, val, ret);
208 return ret;
209 }
210
z_flag_sync_mode_get(const struct shell * sh)211 static inline bool z_flag_sync_mode_get(const struct shell *sh)
212 {
213 return sh->ctx->ctx.flags.sync_mode == 1;
214 }
215
z_flag_sync_mode_set(const struct shell * sh,bool val)216 static inline bool z_flag_sync_mode_set(const struct shell *sh, bool val)
217 {
218 bool ret;
219
220 Z_SHELL_SET_FLAG_ATOMIC(sh, ctx, sync_mode, val, ret);
221 return ret;
222 }
223
224 /* Function sends VT100 command to clear the screen from cursor position to
225 * end of the screen.
226 */
z_clear_eos(const struct shell * sh)227 static inline void z_clear_eos(const struct shell *sh)
228 {
229 Z_SHELL_VT100_CMD(sh, SHELL_VT100_CLEAREOS);
230 }
231
232 /* Function sends VT100 command to save cursor position. */
z_cursor_save(const struct shell * sh)233 static inline void z_cursor_save(const struct shell *sh)
234 {
235 Z_SHELL_VT100_CMD(sh, SHELL_VT100_SAVECURSOR);
236 }
237
238 /* Function sends VT100 command to restore saved cursor position. */
z_cursor_restore(const struct shell * sh)239 static inline void z_cursor_restore(const struct shell *sh)
240 {
241 Z_SHELL_VT100_CMD(sh, SHELL_VT100_RESTORECURSOR);
242 }
243
244 /* Function forcing new line - cannot be replaced with function
245 * cursor_down_move.
246 */
z_cursor_next_line_move(const struct shell * sh)247 static inline void z_cursor_next_line_move(const struct shell *sh)
248 {
249 z_shell_raw_fprintf(sh->fprintf_ctx, "\n");
250 }
251
252 void z_shell_op_cursor_vert_move(const struct shell *sh, int32_t delta);
253
254 void z_shell_op_cursor_horiz_move(const struct shell *sh, int32_t delta);
255
256 void z_shell_op_cond_next_line(const struct shell *sh);
257
258 /* Function will move cursor back to position == cmd_buff_pos. Example usage is
259 * when cursor needs to be moved back after printing some text. This function
260 * cannot be used to move cursor to new location by manual change of
261 * cmd_buff_pos.
262 */
263 void z_shell_op_cursor_position_synchronize(const struct shell *sh);
264
265 void z_shell_op_cursor_move(const struct shell *sh, int16_t val);
266
267 void z_shell_op_left_arrow(const struct shell *sh);
268
269 void z_shell_op_right_arrow(const struct shell *sh);
270
271 /* Moves cursor by defined number of words left (val negative) or right. */
272 void z_shell_op_cursor_word_move(const struct shell *sh, int16_t val);
273
274 /*
275 * Removes the "word" to the left of the cursor:
276 * - if there are spaces at the cursor position, remove all spaces to the left
277 * - remove the non-spaces (word) until a space is found or a beginning of
278 * buffer
279 */
280 void z_shell_op_word_remove(const struct shell *sh);
281
282 /* Function moves cursor to begin of command position, just after console
283 * name.
284 */
285 void z_shell_op_cursor_home_move(const struct shell *sh);
286
287 /* Function moves cursor to end of command. */
288 void z_shell_op_cursor_end_move(const struct shell *sh);
289
290 void z_shell_op_char_insert(const struct shell *sh, char data);
291
292 void z_shell_op_char_backspace(const struct shell *sh);
293
294 void z_shell_op_char_delete(const struct shell *sh);
295
296 void z_shell_op_delete_from_cursor(const struct shell *sh);
297
298 void z_shell_op_completion_insert(const struct shell *sh,
299 const char *compl,
300 uint16_t compl_len);
301
302 bool z_shell_cursor_in_empty_line(const struct shell *sh);
303
304 void z_shell_cmd_line_erase(const struct shell *sh);
305
306 /**
307 * @brief Print command buffer.
308 *
309 * @param sh Shell instance.
310 */
311 void z_shell_print_cmd(const struct shell *sh);
312
313 /**
314 * @brief Print prompt followed by command buffer.
315 *
316 * @param sh Shell instance.
317 */
318 void z_shell_print_prompt_and_cmd(const struct shell *sh);
319
320 /* Function sends data stream to the shell instance. Each time before the
321 * shell_write function is called, it must be ensured that IO buffer of fprintf
322 * is flushed to avoid synchronization issues.
323 * For that purpose, use function transport_buffer_flush(shell)
324 *
325 * This function can be only used by shell module, it shall not be called
326 * directly.
327 */
328 void z_shell_write(const struct shell *sh, const void *data, size_t length);
329
330 /**
331 * @internal @brief This function shall not be used directly, it is required by
332 * the fprintf module.
333 *
334 * @param[in] p_user_ctx Pointer to the context for the shell instance.
335 * @param[in] p_data Pointer to the data buffer.
336 * @param[in] len Data buffer size.
337 */
338 void z_shell_print_stream(const void *user_ctx, const char *data, size_t len);
339
340 /** @internal @brief Function for setting font color */
341 void z_shell_vt100_color_set(const struct shell *sh,
342 enum shell_vt100_color color);
343
z_shell_vt100_colors_store(const struct shell * sh,struct shell_vt100_colors * color)344 static inline void z_shell_vt100_colors_store(const struct shell *sh,
345 struct shell_vt100_colors *color)
346 {
347 memcpy(color, &sh->ctx->vt100_ctx.col, sizeof(*color));
348 }
349
350 void z_shell_vt100_colors_restore(const struct shell *sh,
351 const struct shell_vt100_colors *color);
352
353 /* This function can be called only within shell thread but not from command
354 * handlers.
355 */
356 void z_shell_fprintf(const struct shell *sh, enum shell_vt100_color color,
357 const char *fmt, ...);
358
359 void z_shell_vfprintf(const struct shell *sh, enum shell_vt100_color color,
360 const char *fmt, va_list args);
361
362 #ifdef __cplusplus
363 }
364 #endif
365
366 #endif /* SHELL_OPS_H__ */
367