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 (false)
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