| 35 |
35 |
/******************************************************************************/
|
| 36 |
36 |
|
| 37 |
37 |
/**
|
|
38 |
* @brief The character the input buffer is initialized with.
|
|
39 |
*/
|
|
40 |
#define INBUF_INIT_CHAR '\x07'
|
|
41 |
|
|
42 |
/**
|
| 38 |
43 |
* @brief Event mask to be set on OS related events.
|
| 39 |
44 |
*/
|
| 40 |
|
#define AOS_SHELL_EVENTMASK_OS EVENT_MASK(0)
|
|
45 |
#define EVENTMASK_OS EVENT_MASK(0)
|
| 41 |
46 |
|
| 42 |
47 |
/**
|
| 43 |
48 |
* @brief Event mask to be set on a input event.
|
| 44 |
49 |
*/
|
| 45 |
|
#define AOS_SHELL_EVENTMASK_INPUT EVENT_MASK(1)
|
|
50 |
#define EVENTMASK_INPUT EVENT_MASK(1)
|
|
51 |
|
|
52 |
/**
|
|
53 |
* @brief String that defines the INSERT key as specified by VT100.
|
|
54 |
*/
|
|
55 |
#define KEYSTRING_INSERT "\x1B\x5B\x32\x7E"
|
|
56 |
|
|
57 |
/**
|
|
58 |
* @brief String that defines the DEL key as specified by VT100.
|
|
59 |
*/
|
|
60 |
#define KEYSTRING_DELETE "\x1B\x5B\x33\x7E"
|
|
61 |
|
|
62 |
/**
|
|
63 |
* @brief String that defines the HOME key as specified by VT100.
|
|
64 |
*/
|
|
65 |
#define KEYSTRING_HOME "\x1B\x5B\x48"
|
|
66 |
|
|
67 |
/**
|
|
68 |
* @brief String that defines the END key as specified by VT100.
|
|
69 |
*/
|
|
70 |
#define KEYSTRING_END "\x1B\x5B\x46"
|
|
71 |
|
|
72 |
/**
|
|
73 |
* @brief String that defines the PGUP key as specified by VT100.
|
|
74 |
*/
|
|
75 |
#define KEYSTRING_PAGEUP "\x1B\x5B\x35\x7E"
|
|
76 |
|
|
77 |
/**
|
|
78 |
* @brief String that defines the PGUP key as specified by VT100.
|
|
79 |
*/
|
|
80 |
#define KEYSTRING_PAGEDOWN "\x1B\x5B\x36\x7E"
|
|
81 |
|
|
82 |
/**
|
|
83 |
* @brief String that defines the 'arrow down' key as specified by VT100.
|
|
84 |
*/
|
|
85 |
#define KEYSTRING_ARROWUP "\x1B\x5B\x41"
|
|
86 |
|
|
87 |
/**
|
|
88 |
* @brief String that defines the 'arrow up' key as specified by VT100.
|
|
89 |
*/
|
|
90 |
#define KEYSTRING_ARROWDOWN "\x1B\x5B\x42"
|
|
91 |
|
|
92 |
/**
|
|
93 |
* @brief String that defines the 'arrow left' key as specified by VT100.
|
|
94 |
*/
|
|
95 |
#define KEYSTRING_ARROWLEFT "\x1B\x5B\x44"
|
|
96 |
|
|
97 |
/**
|
|
98 |
* @brief String that defines the 'arrow right' key as specified by VT100.
|
|
99 |
*/
|
|
100 |
#define KEYSTRING_ARROWRIGHT "\x1B\x5B\x43"
|
|
101 |
|
|
102 |
/**
|
|
103 |
* @brief String that defines the CRTL + 'arrow up' key combination as specified by VT100.
|
|
104 |
*/
|
|
105 |
#define KEYSTRING_CTRL_ARROWUP "\x1B\x5B\x31\x3B\x35\x41"
|
|
106 |
|
|
107 |
/**
|
|
108 |
* @brief String that defines the CRTL + 'arrow down' key combination as specified by VT100.
|
|
109 |
*/
|
|
110 |
#define KEYSTRING_CTRL_ARROWDOWN "\x1B\x5B\x31\x3B\x35\x42"
|
|
111 |
|
|
112 |
/**
|
|
113 |
* @brief String that defines the CRTL + 'arrow left' key combination as specified by VT100.
|
|
114 |
*/
|
|
115 |
#define KEYSTRING_CTRL_ARROWLEFT "\x1B\x5B\x31\x3B\x35\x44"
|
|
116 |
|
|
117 |
/**
|
|
118 |
* @brief String that defines the CRTL + 'arrow right' key combination as specified by VT100.
|
|
119 |
*/
|
|
120 |
#define KEYSTRING_CTRL_ARROWRIGHT "\x1B\x5B\x31\x3B\x35\x43"
|
| 46 |
121 |
|
| 47 |
122 |
/******************************************************************************/
|
| 48 |
123 |
/* EXPORTED VARIABLES */
|
| ... | ... | |
| 97 |
172 |
KEY_UNKNOWN, /**< any/unknow key */
|
| 98 |
173 |
KEY_AMBIGUOUS, /**< key is ambiguous */
|
| 99 |
174 |
KEY_TAB, /**< tabulator key */
|
| 100 |
|
KEY_ESCAPE, /**< escape key */
|
| 101 |
175 |
KEY_BACKSPACE, /**< backspace key */
|
| 102 |
176 |
KEY_INSERT, /**< insert key */
|
| 103 |
177 |
KEY_DELETE, /**< delete key */
|
|
178 |
KEY_ESCAPE, /**< escape key */
|
| 104 |
179 |
KEY_HOME, /**< home key */
|
| 105 |
180 |
KEY_END, /**< end key */
|
| 106 |
|
KEY_PAGE_UP, /**< page up key */
|
| 107 |
|
KEY_PAGE_DOWN, /**< page down key */
|
| 108 |
|
KEY_ARROW_UP, /**< arrow up key */
|
| 109 |
|
KEY_ARROW_DOWN, /**< arrow down key */
|
| 110 |
|
KEY_ARROW_LEFT, /**< arrow left key */
|
| 111 |
|
KEY_ARROW_RIGHT, /**< arrow right key */
|
| 112 |
|
KEY_CTRL_ARROW_UP, /**< CTRL + arrow up key */
|
| 113 |
|
KEY_CTRL_ARROW_DOWN, /**< CTRL + arrow down key */
|
| 114 |
|
KEY_CTRL_ARROW_LEFT, /**< CTRL + arrow left key */
|
| 115 |
|
KEY_CTRL_ARROW_RIGHT, /**< CTRL + arrow right key */
|
|
181 |
KEY_PAGEUP, /**< page up key */
|
|
182 |
KEY_PAGEDOWN, /**< page down key */
|
|
183 |
KEY_ARROWUP, /**< arrow up key */
|
|
184 |
KEY_ARROWDOWN, /**< arrow down key */
|
|
185 |
KEY_ARROWLEFT, /**< arrow left key */
|
|
186 |
KEY_ARROWRIGHT, /**< arrow right key */
|
|
187 |
KEY_CTRL_ARROWUP, /**< CTRL + arrow up key */
|
|
188 |
KEY_CTRL_ARROWDOWN, /**< CTRL + arrow down key */
|
|
189 |
KEY_CTRL_ARROWLEFT, /**< CTRL + arrow left key */
|
|
190 |
KEY_CTRL_ARROWRIGHT, /**< CTRL + arrow right key */
|
|
191 |
KEY_CTRL_C, /**< CTRL + C key */
|
| 116 |
192 |
} special_key_t;
|
| 117 |
193 |
|
| 118 |
194 |
/**
|
| ... | ... | |
| 124 |
200 |
CHAR_MATCH_CASE = 2, /**< Characters do match with case. */
|
| 125 |
201 |
} charmatch_t;
|
| 126 |
202 |
|
|
203 |
/**
|
|
204 |
* @brief Enumerator to encode shell actions.
|
|
205 |
*/
|
|
206 |
typedef enum aos_shellaction {
|
|
207 |
ACTION_NONE, /**< No action at all. */
|
|
208 |
ACTION_READCHAR, /**< Read a printable character. */
|
|
209 |
ACTION_AUTOCOMPLETE, /**< Automatically comlete input by using available command. */
|
|
210 |
ACTION_SUGGEST, /**< Suggest matching available commands. */
|
|
211 |
ACTION_EXECUTE, /**< Execute input. */
|
|
212 |
ACTION_DELETEBACKWARD, /**< Delete a single character backwards. */
|
|
213 |
ACTION_DELETEFORWARD, /**< Delete a single character forwards. */
|
|
214 |
ACTION_CLEAR, /**< Clear the input. */
|
|
215 |
ACTION_RECALLPREVIOUS, /**< Recall the previous (older) entry in the history. */
|
|
216 |
ACTION_RECALLNEXT, /**< Recall the next (more recent) entry in the history. */
|
|
217 |
ACTION_RECALLOLDEST, /**< Recall the oldest entry in the history. */
|
|
218 |
ACTION_RECALLCURRENT, /**< Recall the current input. */
|
|
219 |
ACTION_CURSORLEFT, /**< Move cursor one character to the left. */
|
|
220 |
ACTION_CURSORRIGHT, /**< Move cursor one character to the right. */
|
|
221 |
ACTION_CURSORWORDLEFT, /**< Move cursor one word to the left. */
|
|
222 |
ACTION_CURSORWORDRIGHT, /**< Move cursor one word to the right. */
|
|
223 |
ACTION_CURSOR2END, /**< Move cursor to the very right. */
|
|
224 |
ACTION_CURSOR2START, /**< Move cursor to the very left. */
|
|
225 |
ACTION_RESET, /**< Reset the current input. */
|
|
226 |
ACTION_INSERTTOGGLE, /**< Toggle insertion mode. */
|
|
227 |
ACTION_ESCSTART, /**< Start an escape sequence (special keys). */
|
|
228 |
ACTION_PRINTUNKNOWNSEQUENCE, /**< Print an unknown escape sequence. */
|
|
229 |
} action_t;
|
|
230 |
|
|
231 |
/**
|
|
232 |
* @brief Struct that holds most important runtime data for the shell.
|
|
233 |
* @details The structure is to be used by the shell thread main function as some kind of structured stack, which can be easily passed to other functions.
|
|
234 |
*/
|
|
235 |
typedef struct runtimedata {
|
|
236 |
/**
|
|
237 |
* @brief Data related to the current input.
|
|
238 |
*/
|
|
239 |
struct {
|
|
240 |
/**
|
|
241 |
* @brief Length of the input.
|
|
242 |
*/
|
|
243 |
size_t length;
|
|
244 |
|
|
245 |
/**
|
|
246 |
* @brief Current position of the cursor in the input line.
|
|
247 |
*/
|
|
248 |
size_t cursorpos;
|
|
249 |
|
|
250 |
/**
|
|
251 |
* @brief Buffer to store escape sequences, which describe special characters.
|
|
252 |
*/
|
|
253 |
char escseq[AOS_SHELL_ESCSEQUENCE_LENGTH];
|
|
254 |
} input;
|
|
255 |
|
|
256 |
/**
|
|
257 |
* @brief Data related to the entry or history buffer.
|
|
258 |
*/
|
|
259 |
struct {
|
|
260 |
/**
|
|
261 |
* @brief Current entry to be filled and executed.
|
|
262 |
*/
|
|
263 |
size_t current;
|
|
264 |
|
|
265 |
/**
|
|
266 |
* @brief Selected entry in the 'history' as preview.
|
|
267 |
* @details A value of 0 indicates, that the line is cleared as a preview.
|
|
268 |
* A value of 1 indicates, that the current entry is selected.
|
|
269 |
* A value of t>1 indicates, that the entry t-1 in the past is selected.
|
|
270 |
* The value must never be greater than the number of entries available, of course.
|
|
271 |
*/
|
|
272 |
size_t selected;
|
|
273 |
|
|
274 |
/**
|
|
275 |
* @brief Selected entry in the 'history' that has been edited by the user.
|
|
276 |
* A value of 0 indicates, that there was no modification by the user yet (i.e. charcters, deletions or autofill).
|
|
277 |
* A value of 1 indicates, that the current entry was edited.
|
|
278 |
* A value of t>1 indicated, that a history entry was recalled and then edited.
|
|
279 |
*/
|
|
280 |
size_t edited;
|
|
281 |
} buffer;
|
|
282 |
|
|
283 |
/**
|
|
284 |
* @brief The last action executed by the shell.
|
|
285 |
*/
|
|
286 |
action_t lastaction;
|
|
287 |
} runtimedata_t;
|
|
288 |
|
| 127 |
289 |
/******************************************************************************/
|
| 128 |
290 |
/* LOCAL VARIABLES */
|
| 129 |
291 |
/******************************************************************************/
|
| ... | ... | |
| 248 |
410 |
return MSG_OK;
|
| 249 |
411 |
}
|
| 250 |
412 |
|
|
413 |
/**
|
|
414 |
* @brief Implementation of the BaseSequentialStream write() method.
|
|
415 |
*/
|
| 251 |
416 |
static size_t _streamwrite(void *instance, const uint8_t *bp, size_t n)
|
| 252 |
417 |
{
|
| 253 |
418 |
aosDbgCheck(instance != NULL);
|
| ... | ... | |
| 267 |
432 |
return maxbytes;
|
| 268 |
433 |
}
|
| 269 |
434 |
|
|
435 |
/**
|
|
436 |
* @brief Implementation of the BaseSequentialStream read() method.
|
|
437 |
*/
|
| 270 |
438 |
static size_t _stremread(void *instance, uint8_t *bp, size_t n)
|
| 271 |
439 |
{
|
| 272 |
440 |
(void)instance;
|
| ... | ... | |
| 276 |
444 |
return 0;
|
| 277 |
445 |
}
|
| 278 |
446 |
|
|
447 |
/**
|
|
448 |
* @brief Implementation of the BaseSequentialStream put() method.
|
|
449 |
*/
|
| 279 |
450 |
static msg_t _streamput(void *instance, uint8_t b)
|
| 280 |
451 |
{
|
| 281 |
452 |
aosDbgCheck(instance != NULL);
|
| ... | ... | |
| 294 |
465 |
return ret;
|
| 295 |
466 |
}
|
| 296 |
467 |
|
|
468 |
/**
|
|
469 |
* @brief Implementation of the BaseSequentialStream get() method.
|
|
470 |
*/
|
| 297 |
471 |
static msg_t _streamget(void *instance)
|
| 298 |
472 |
{
|
| 299 |
473 |
(void)instance;
|
| ... | ... | |
| 302 |
476 |
}
|
| 303 |
477 |
|
| 304 |
478 |
/**
|
|
479 |
* @brief Retreive a pointer to the string buffer of a specified entry in the input buffer.
|
|
480 |
*
|
|
481 |
* @param[in] shell Pointer to a shell object.
|
|
482 |
* @param[in] entry Entry to be retrieved.
|
|
483 |
*
|
|
484 |
* @return Pointer to the entry in the input buffer.
|
|
485 |
*/
|
|
486 |
static inline char* _getAbsoluteEntry(const aos_shell_t* shell, size_t entry)
|
|
487 |
{
|
|
488 |
aosDbgCheck(shell != NULL);
|
|
489 |
aosDbgCheck(entry < shell->input.nentries);
|
|
490 |
|
|
491 |
return &(shell->input.buffer[entry * shell->input.linewidth * sizeof(char)]);
|
|
492 |
}
|
|
493 |
|
|
494 |
/**
|
|
495 |
* @brief Calculate absolute entry from history offset.
|
|
496 |
*
|
|
497 |
* @param[in] shell Pointer to a shell object.
|
|
498 |
* @param[in] rdata Pointer to a runtime data object.
|
|
499 |
* @param[in] offset Relative offset of the entry to be retreived.
|
|
500 |
*
|
|
501 |
* @return Absolute index of the historic entry.
|
|
502 |
*/
|
|
503 |
static inline size_t _historyOffset2EntryIndex(const aos_shell_t* shell, const runtimedata_t* rdata, size_t offset)
|
|
504 |
{
|
|
505 |
aosDbgCheck(shell != NULL);
|
|
506 |
aosDbgCheck(rdata != NULL);
|
|
507 |
aosDbgCheck(offset < shell->input.nentries);
|
|
508 |
|
|
509 |
return ((shell->input.nentries + rdata->buffer.current - offset) % shell->input.nentries);
|
|
510 |
}
|
|
511 |
|
|
512 |
/**
|
|
513 |
* @brief Retreive a pointer to the string buffer of a historic entry in the input buffer.
|
|
514 |
*
|
|
515 |
* @param[in] shell Pointer to a shell object.
|
|
516 |
* @param[in] rdata Pointer to a runtime data object.
|
|
517 |
* @param[in] offset Relative offset of the entry to be retreived.
|
|
518 |
*
|
|
519 |
* @return Pointer to the entry in the input buffer.
|
|
520 |
*/
|
|
521 |
static inline char* _getRelativeEntry(const aos_shell_t* shell, const runtimedata_t* rdata, size_t offset)
|
|
522 |
{
|
|
523 |
aosDbgCheck(shell != NULL);
|
|
524 |
aosDbgCheck(rdata != NULL);
|
|
525 |
aosDbgCheck(offset < shell->input.nentries);
|
|
526 |
|
|
527 |
return _getAbsoluteEntry(shell, _historyOffset2EntryIndex(shell, rdata, offset));
|
|
528 |
}
|
|
529 |
|
|
530 |
/**
|
|
531 |
* @brief Retreive a pointer to the current entry string in the input buffer.
|
|
532 |
*
|
|
533 |
* @param[in] shell Pointer to a shell object.
|
|
534 |
* @param[in] rdata Pointer to a runtime data object.
|
|
535 |
*
|
|
536 |
* @return Pointer to the string of the current entry in the input buffer.
|
|
537 |
*/
|
|
538 |
static inline char* _getCurrentEntry(const aos_shell_t* shell, const runtimedata_t* rdata)
|
|
539 |
{
|
|
540 |
aosDbgCheck(shell != NULL);
|
|
541 |
aosDbgCheck(rdata != NULL);
|
|
542 |
|
|
543 |
return _getAbsoluteEntry(shell, rdata->buffer.current);
|
|
544 |
}
|
|
545 |
|