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
z_flag_handle_log_get(const struct shell * sh)224 static inline bool z_flag_handle_log_get(const struct shell *sh)
225 {
226 return sh->ctx->ctx.flags.handle_log == 1;
227 }
228
z_flag_handle_log_set(const struct shell * sh,bool val)229 static inline bool z_flag_handle_log_set(const struct shell *sh, bool val)
230 {
231 bool ret;
232
233 Z_SHELL_SET_FLAG_ATOMIC(sh, ctx, handle_log, val, ret);
234 return ret;
235 }
236
237 /* Function sends VT100 command to clear the screen from cursor position to
238 * end of the screen.
239 */
z_clear_eos(const struct shell * sh)240 static inline void z_clear_eos(const struct shell *sh)
241 {
242 Z_SHELL_VT100_CMD(sh, SHELL_VT100_CLEAREOS);
243 }
244
245 /* Function sends VT100 command to save cursor position. */
z_cursor_save(const struct shell * sh)246 static inline void z_cursor_save(const struct shell *sh)
247 {
248 Z_SHELL_VT100_CMD(sh, SHELL_VT100_SAVECURSOR);
249 }
250
251 /* Function sends VT100 command to restore saved cursor position. */
z_cursor_restore(const struct shell * sh)252 static inline void z_cursor_restore(const struct shell *sh)
253 {
254 Z_SHELL_VT100_CMD(sh, SHELL_VT100_RESTORECURSOR);
255 }
256
257 /* Function forcing new line - cannot be replaced with function
258 * cursor_down_move.
259 */
z_cursor_next_line_move(const struct shell * sh)260 static inline void z_cursor_next_line_move(const struct shell *sh)
261 {
262 z_shell_raw_fprintf(sh->fprintf_ctx, "\n");
263 }
264
265 void z_shell_op_cursor_vert_move(const struct shell *sh, int32_t delta);
266
267 void z_shell_op_cursor_horiz_move(const struct shell *sh, int32_t delta);
268
269 void z_shell_op_cond_next_line(const struct shell *sh);
270
271 /* Function will move cursor back to position == cmd_buff_pos. Example usage is
272 * when cursor needs to be moved back after printing some text. This function
273 * cannot be used to move cursor to new location by manual change of
274 * cmd_buff_pos.
275 */
276 void z_shell_op_cursor_position_synchronize(const struct shell *sh);
277
278 void z_shell_op_cursor_move(const struct shell *sh, int16_t val);
279
280 void z_shell_op_left_arrow(const struct shell *sh);
281
282 void z_shell_op_right_arrow(const struct shell *sh);
283
284 /* Moves cursor by defined number of words left (val negative) or right. */
285 void z_shell_op_cursor_word_move(const struct shell *sh, int16_t val);
286
287 /*
288 * Removes the "word" to the left of the cursor:
289 * - if there are spaces at the cursor position, remove all spaces to the left
290 * - remove the non-spaces (word) until a space is found or a beginning of
291 * buffer
292 */
293 void z_shell_op_word_remove(const struct shell *sh);
294
295 /* Function moves cursor to begin of command position, just after console
296 * name.
297 */
298 void z_shell_op_cursor_home_move(const struct shell *sh);
299
300 /* Function moves cursor to end of command. */
301 void z_shell_op_cursor_end_move(const struct shell *sh);
302
303 void z_shell_op_char_insert(const struct shell *sh, char data);
304
305 void z_shell_op_char_backspace(const struct shell *sh);
306
307 void z_shell_op_char_delete(const struct shell *sh);
308
309 void z_shell_op_delete_from_cursor(const struct shell *sh);
310
311 void z_shell_op_completion_insert(const struct shell *sh,
312 const char *compl,
313 uint16_t compl_len);
314
315 bool z_shell_cursor_in_empty_line(const struct shell *sh);
316
317 void z_shell_cmd_line_erase(const struct shell *sh);
318
319 /**
320 * @brief Print command buffer.
321 *
322 * @param sh Shell instance.
323 */
324 void z_shell_print_cmd(const struct shell *sh);
325
326 /**
327 * @brief Print prompt followed by command buffer.
328 *
329 * @param sh Shell instance.
330 */
331 void z_shell_print_prompt_and_cmd(const struct shell *sh);
332
333 /* Function sends data stream to the shell instance. Each time before the
334 * shell_write function is called, it must be ensured that IO buffer of fprintf
335 * is flushed to avoid synchronization issues.
336 * For that purpose, use function transport_buffer_flush(shell)
337 *
338 * This function can be only used by shell module, it shall not be called
339 * directly.
340 */
341 void z_shell_write(const struct shell *sh, const void *data, size_t length);
342
343 /**
344 * @internal @brief This function shall not be used directly, it is required by
345 * the fprintf module.
346 *
347 * @param[in] p_user_ctx Pointer to the context for the shell instance.
348 * @param[in] p_data Pointer to the data buffer.
349 * @param[in] len Data buffer size.
350 */
351 void z_shell_print_stream(const void *user_ctx, const char *data, size_t len);
352
353 /** @internal @brief Function for setting font color */
354 void z_shell_vt100_color_set(const struct shell *sh,
355 enum shell_vt100_color color);
356
z_shell_vt100_colors_store(const struct shell * sh,struct shell_vt100_colors * color)357 static inline void z_shell_vt100_colors_store(const struct shell *sh,
358 struct shell_vt100_colors *color)
359 {
360 memcpy(color, &sh->ctx->vt100_ctx.col, sizeof(*color));
361 }
362
363 void z_shell_vt100_colors_restore(const struct shell *sh,
364 const struct shell_vt100_colors *color);
365
366 /* This function can be called only within shell thread but not from command
367 * handlers.
368 */
369 void z_shell_fprintf(const struct shell *sh, enum shell_vt100_color color,
370 const char *fmt, ...);
371
372 void z_shell_vfprintf(const struct shell *sh, enum shell_vt100_color color,
373 const char *fmt, va_list args);
374
375 #ifdef __cplusplus
376 }
377 #endif
378
379 #endif /* SHELL_OPS_H__ */
380