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