Paparazzi UAS  v6.0_unstable-40-gc34df8a-dirty
Paparazzi is a free software Unmanned Aircraft System.
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
microrl.c
Go to the documentation of this file.
1 /*
2  Author: Samoylov Eugene aka Helius (ghelius@gmail.com)
3  BUGS and TODO:
4  -- add echo_off feature
5  -- rewrite history for use more than 256 byte buffer
6 */
7 
8 #include <string.h>
9 #include <ctype.h>
10 #include <stdlib.h>
11 #include "microrl.h"
12 #ifdef _USE_LIBC_STDIO
13 #include <stdio.h>
14 #endif
15 
16 //#define DEBUG_MRL
17 #ifdef DEBUG_MRL
18 #include "ch.h"
19 #include "printf.h"
20 #include "hal.h"
21 
22 
23 #endif // DEBUG_MRL
24 
25 
26 //#define DBG(...) fprintf(stderr, "\033[33m");fprintf(stderr,__VA_ARGS__);fprintf(stderr,"\033[0m");
27 
29 
30 #ifdef __GNUC__
31 #pragma GCC diagnostic push
32 #pragma GCC diagnostic ignored "-Wstrict-overflow"
33 #endif
34 
35 
36 #ifdef _USE_HISTORY
37 
38 #ifdef _HISTORY_DEBUG
39 //*****************************************************************************
40 // print buffer content on screen
41 static void print_hist (ring_history_t * pThis)
42 {
43  printf ("\n");
44  for (int i = 0; i < _RING_HISTORY_LEN; i++) {
45  if (i == pThis->begin)
46  printf ("b");
47  else
48  printf (" ");
49  }
50  printf ("\n");
51  for (int i = 0; i < _RING_HISTORY_LEN; i++) {
52  if (isalpha(pThis->ring_buf[i]))
53  printf ("%c", pThis->ring_buf[i]);
54  else
55  printf ("%d", pThis->ring_buf[i]);
56  }
57  printf ("\n");
58  for (int i = 0; i < _RING_HISTORY_LEN; i++) {
59  if (i == pThis->end)
60  printf ("e");
61  else
62  printf (" ");
63  }
64  printf ("\n");
65 }
66 #endif
67 
68 //*****************************************************************************
69 // remove older message from ring buffer
70 static void hist_erase_older (ring_history_t * pThis)
71 {
72  int new_pos = pThis->begin + pThis->ring_buf [pThis->begin] + 1;
73  if (new_pos >= _RING_HISTORY_LEN)
74  new_pos = new_pos - _RING_HISTORY_LEN;
75 
76  pThis->begin = new_pos;
77 }
78 
79 //*****************************************************************************
80 // check space for new line, remove older while not space
81 static int hist_is_space_for_new (ring_history_t * pThis, int len)
82 {
83  if (pThis->ring_buf [pThis->begin] == 0)
84  return true;
85  if (pThis->end >= pThis->begin) {
86  if (_RING_HISTORY_LEN - pThis->end + pThis->begin - 1 > len)
87  return true;
88  } else {
89  if (pThis->begin - pThis->end - 1> len)
90  return true;
91  }
92  return false;
93 }
94 
95 //*****************************************************************************
96 // put line to ring buffer
97 static void hist_save_line (ring_history_t * pThis, char * line, int len)
98 {
99  if (len > _RING_HISTORY_LEN - 2)
100  return;
101  while (!hist_is_space_for_new (pThis, len)) {
102  hist_erase_older (pThis);
103  }
104  // if it's first line
105  if (pThis->ring_buf [pThis->begin] == 0)
106  pThis->ring_buf [pThis->begin] = len;
107 
108  // store line
109  if (len < _RING_HISTORY_LEN-pThis->end-1)
110  memmove (pThis->ring_buf + pThis->end + 1, line, len);
111  else {
112  int part_len = _RING_HISTORY_LEN-pThis->end-1;
113  memmove (pThis->ring_buf + pThis->end + 1, line, part_len);
114  memmove (pThis->ring_buf, line + part_len, len - part_len);
115  }
116  pThis->ring_buf [pThis->end] = len;
117  pThis->end = pThis->end + len + 1;
118  if (pThis->end >= _RING_HISTORY_LEN)
119  pThis->end -= _RING_HISTORY_LEN;
120  pThis->ring_buf [pThis->end] = 0;
121  pThis->cur = 0;
122 #ifdef _HISTORY_DEBUG
123  print_hist (pThis);
124 #endif
125 }
126 
127 //*****************************************************************************
128 // copy saved line to 'line' and return size of line
129 
130 
131 static int hist_restore_line (ring_history_t * pThis, char * line, int dir)
132 {
133  int cnt = 0;
134  // count history record
135  int header = pThis->begin;
136  while (pThis->ring_buf [header] != 0) {
137  header += pThis->ring_buf [header] + 1;
138  if (header >= _RING_HISTORY_LEN)
139  header -= _RING_HISTORY_LEN;
140  cnt++;
141  }
142 
143  if (dir == _HIST_UP) {
144  if (cnt >= pThis->cur) {
145  int lheader = pThis->begin;
146  int j = 0;
147  // found record for 'pThis->cur' index
148  while ((pThis->ring_buf [lheader] != 0) && (cnt - j -1 != pThis->cur)) {
149  lheader += pThis->ring_buf [lheader] + 1;
150  if (lheader >= _RING_HISTORY_LEN)
151  lheader -= _RING_HISTORY_LEN;
152  j++;
153  }
154  if (pThis->ring_buf[lheader]) {
155  pThis->cur++;
156  // obtain saved line
157  if ((pThis->ring_buf [lheader] + lheader + 1) < _RING_HISTORY_LEN) {
158  // fix from coverity scan
159  /*
160  CID 60358 (#1 of 2): Out-of-bounds read (OVERRUN)30.
161  overrun-local: Overrunning array of 256 bytes at byte offset 256
162  by dereferencing pointer &pThis->ring_buf[lheader] + 1
163  */
164  memmove (line, pThis->ring_buf + lheader + 1, pThis->ring_buf[lheader]);
165  } else {
166  int part0 = _RING_HISTORY_LEN - lheader - 1;
167  memmove (line, pThis->ring_buf + lheader + 1, part0);
168  memmove (line + part0, pThis->ring_buf, pThis->ring_buf[lheader] - part0);
169  }
170  return pThis->ring_buf[lheader];
171  }
172  }
173  } else {
174  if (pThis->cur > 0) {
175  pThis->cur--;
176  int lheader = pThis->begin;
177  int j = 0;
178 
179  while ((pThis->ring_buf [lheader] != 0) && (cnt - j != pThis->cur)) {
180  lheader += pThis->ring_buf [lheader] + 1;
181  if (lheader >= _RING_HISTORY_LEN)
182  lheader -= _RING_HISTORY_LEN;
183  j++;
184  }
185  if ((pThis->ring_buf [lheader] + lheader +1) < _RING_HISTORY_LEN) {
186  memmove (line, pThis->ring_buf + lheader + 1, pThis->ring_buf[lheader]);
187  } else {
188  int part0 = _RING_HISTORY_LEN - lheader - 1;
189  memmove (line, pThis->ring_buf + lheader + 1, part0);
190  memmove (line + part0, pThis->ring_buf, pThis->ring_buf[lheader] - part0);
191  }
192  return pThis->ring_buf[lheader];
193  }
194  }
195  return 0;
196 }
197 
198 
199 #endif
200 
201 
202 //*****************************************************************************
203 // split cmdline to tkn array and return nmb of token
204 static int split (microrl_t * pThis, int limit)
205 {
206  int i = 0;
207  int ind = 0;
208  while (1) {
209  // go to the first whitespace (zerro for us)
210  while ((pThis->cmdline [ind] == '\0') && (ind < limit)) {
211  ind++;
212  }
213  if (!(ind < limit)) return i;
214  pThis->tkn_arr[i++] = pThis->cmdline + ind;
215  if (i >= _COMMAND_TOKEN_NMB) {
216  return -1;
217  }
218  // go to the first NOT whitespace (not zerro for us)
219  while ((pThis->cmdline [ind] != '\0') && (ind < limit)) {
220  ind++;
221  }
222  if (!(ind < limit)) return i;
223  }
224  return i;
225 }
226 
227 
228 //*****************************************************************************
229 inline static void print_prompt (microrl_t * pThis)
230 {
231  pThis->print (pThis->prompt_str);
232 }
233 
234 //*****************************************************************************
235 inline static void terminal_backspace (microrl_t * pThis)
236 {
237  pThis->print ("\033[D \033[D");
238 }
239 
240 //*****************************************************************************
241 inline static void terminal_newline (microrl_t * pThis)
242 {
243  pThis->print (ENDL);
244 }
245 
246 #ifndef _USE_LIBC_STDIO
247 //*****************************************************************************
248 // convert 16 bit value to string
249 // 0 value not supported!!! just make empty string
250 static void u16bit_to_str (unsigned int nmb, char * buf)
251 {
252  char tmp_str [6] = {0,};
253  int i = 0;
254  if (nmb <= 0xFFFF) {
255  while (nmb > 0) {
256  tmp_str[i++] = (nmb % 10) + '0';
257  nmb /=10;
258  }
259  for (int j = 0; j < i; ++j)
260  *(buf++) = tmp_str [i-j-1];
261  }
262  *buf = '\0';
263 }
264 #endif
265 
266 
267 //*****************************************************************************
268 // set cursor at position from begin cmdline (after prompt) + offset
269 static void terminal_move_cursor (microrl_t * pThis, int offset)
270 {
271  char str[16] = {0,};
272 #ifdef _USE_LIBC_STDIO
273  if (offset > 0) {
274  snprintf (str, 16, "\033[%dC", offset);
275  } else if (offset < 0) {
276  snprintf (str, 16, "\033[%dD", -(offset));
277  }
278 #else
279  strcpy (str, "\033[");
280  if (offset > 0) {
281  u16bit_to_str (offset, str+2);
282  strcat (str, "C");
283  } else if (offset < 0) {
284  u16bit_to_str (-(offset), str+2);
285  strcat (str, "D");
286  } else
287  return;
288 #endif
289  pThis->print (str);
290 }
291 
292 //*****************************************************************************
293 static void terminal_reset_cursor (microrl_t * pThis)
294 {
295  char str[16];
296 #ifdef _USE_LIBC_STDIO
297  snprintf (str, 16, "\033[%dD\033[%dC", \
299 
300 #else
301  strcpy (str, "\033[");
303  strcat (str, "D\033[");
304  u16bit_to_str (_PROMPT_LEN, str+strlen(str));
305  strcat (str, "C");
306 #endif
307  pThis->print (str);
308 }
309 
310 //*****************************************************************************
311 // print cmdline to screen, replace '\0' to wihitespace
312 static void terminal_print_line (microrl_t * pThis, int pos, int cursor)
313 {
314  pThis->print ("\033[K"); // delete all from cursor to end
315 
316  char nch [] = {0,0};
317  for (int i = pos; i < pThis->cmdlen; i++) {
318  nch [0] = pThis->cmdline [i];
319  if (nch[0] == '\0')
320  nch[0] = ' ';
321  pThis->print (nch);
322  }
323 
324  terminal_reset_cursor (pThis);
325  terminal_move_cursor (pThis, cursor);
326 }
327 
328 //*****************************************************************************
329 void microrl_init (microrl_t * pThis, void (*print) (const char *))
330 {
331  memset(pThis->cmdline, 0, _COMMAND_LINE_LEN);
332 #ifdef _USE_HISTORY
333  memset(pThis->ring_hist.ring_buf, 0, _RING_HISTORY_LEN);
334  pThis->ring_hist.begin = 0;
335  pThis->ring_hist.end = 0;
336  pThis->ring_hist.cur = 0;
337 #endif
338  pThis->cmdlen =0;
339  pThis->cursor = 0;
340  pThis->execute = NULL;
341  pThis->get_completion = NULL;
342 #ifdef _USE_CTLR_C
343  pThis->sigint = NULL;
344 #endif
345  pThis->prompt_str = prompt_default;
346  pThis->print = print;
347 #ifdef _ENABLE_INIT_PROMPT
348  print_prompt (pThis);
349 #endif
350 }
351 
352 //*****************************************************************************
354  const char ** (*get_completion)(int, const char* const*))
355 {
356  pThis->get_completion = get_completion;
357 }
358 
359 //*****************************************************************************
360 void microrl_set_execute_callback (microrl_t * pThis, void (*execute)(int, const char* const*))
361 {
362  pThis->execute = execute;
363 }
364 #ifdef _USE_CTLR_C
365 //*****************************************************************************
366 void microrl_set_sigint_callback (microrl_t * pThis, void (*sigintf)(void))
367 {
368  pThis->sigint = sigintf;
369 }
370 #endif
371 
372 #ifdef _USE_ESC_SEQ
373 static void hist_search (microrl_t * pThis, int dir)
374 {
375  int len = hist_restore_line (&pThis->ring_hist, pThis->cmdline, dir);
376  if (len) {
377  pThis->cursor = pThis->cmdlen = len;
378  terminal_reset_cursor (pThis);
379  terminal_print_line (pThis, 0, pThis->cursor);
380  }
381 }
382 
383 //*****************************************************************************
384 // handling escape sequences
385 static int escape_process (microrl_t * pThis, char ch)
386 {
387  static int seq = 0;
388 
389  if (ch == '[') {
390  seq = _ESC_BRACKET;
391  } else if (seq == _ESC_BRACKET) {
392  if (ch == 'A') {
393 #ifdef _USE_HISTORY
394  hist_search (pThis, _HIST_UP);
395 #endif
396  return 1;
397  } else if (ch == 'B') {
398 #ifdef _USE_HISTORY
399  hist_search (pThis, _HIST_DOWN);
400 #endif
401  return 1;
402  } else if (ch == 'C') {
403  if (pThis->cursor < pThis->cmdlen) {
404  terminal_move_cursor (pThis, 1);
405  pThis->cursor++;
406  }
407  return 1;
408  } else if (ch == 'D') {
409  if (pThis->cursor > 0) {
410  terminal_move_cursor (pThis, -1);
411  pThis->cursor--;
412  }
413  return 1;
414  } else if (ch == '7') {
415  seq = _ESC_HOME;
416  return 0;
417  } else if (ch == '8') {
418  seq = _ESC_END;
419  return 0;
420  }
421  } else if (ch == '~') {
422  if (seq == _ESC_HOME) {
423  terminal_reset_cursor (pThis);
424  pThis->cursor = 0;
425  return 1;
426  } else if (seq == _ESC_END) {
427  terminal_move_cursor (pThis, pThis->cmdlen-pThis->cursor);
428  pThis->cursor = pThis->cmdlen;
429  return 1;
430  }
431 
432  }
433  return 0;
434 }
435 #endif
436 
437 //*****************************************************************************
438 // insert len char of text at cursor position
439 static int microrl_insert_text (microrl_t * pThis, const char * text, int len)
440 {
441 #pragma GCC diagnostic push
442 #pragma GCC diagnostic ignored "-Wstrict-overflow"
443  if (pThis->cmdlen + len < _COMMAND_LINE_LEN) {
444 #pragma GCC diagnostic pop
445  if (pThis->cmdlen != pThis->cursor) {
446  memmove (pThis->cmdline + pThis->cursor + len,
447  pThis->cmdline + pThis->cursor,
448  pThis->cmdlen - pThis->cursor);
449  }
450 
451  for (int i = 0; i < len; i++) {
452  pThis->cmdline [pThis->cursor + i] = text [i];
453  if (pThis->cmdline [pThis->cursor + i] == ' ') {
454  pThis->cmdline [pThis->cursor + i] = 0;
455  }
456  }
457  pThis->cursor += len;
458  pThis->cmdlen += len;
459  pThis->cmdline [pThis->cmdlen] = '\0';
460  return true;
461  }
462  return false;
463 }
464 
465 //*****************************************************************************
466 // remove one char at cursor
467 static void microrl_backspace (microrl_t * pThis)
468 {
469  if (pThis->cursor > 0) {
470  terminal_backspace (pThis);
471  if ((pThis->cmdlen-pThis->cursor+1) != 0) {
472  memmove (pThis->cmdline + pThis->cursor-1,
473  pThis->cmdline + pThis->cursor,
474  pThis->cmdlen-pThis->cursor+1);
475  }
476  pThis->cursor--;
477  pThis->cmdline [pThis->cmdlen] = '\0';
478  pThis->cmdlen--;
479  }
480 }
481 
482 
483 #ifdef _USE_COMPLETE
484 
485 //*****************************************************************************
486 static int common_len (const char ** arr)
487 {
488  int len = 0;
489  int i = 1;
490  while (1) {
491  while (arr[i]!=NULL) {
492  if ((arr[i][len] != arr[i-1][len]) ||
493  (arr[i][len] == '\0') ||
494  (arr[i-1][len]=='\0'))
495  return len;
496  len++;
497  }
498  i++;
499  }
500  return 0;
501 }
502 
503 //*****************************************************************************
504 static void microrl_get_complite (microrl_t * pThis)
505 {
506  const char ** compl_token;
507 
508  if (pThis->get_completion == NULL) // callback was not set
509  return;
510 
511  int status = split (pThis, pThis->cursor);
512  if (pThis->cmdline[pThis->cursor-1] == '\0')
513  pThis->tkn_arr[status++] = "";
514  compl_token = pThis->get_completion (status, pThis->tkn_arr);
515  if (compl_token[0] != NULL) {
516  int i = 0;
517  int len;
518 
519  if (compl_token[1] == NULL) {
520  len = strlen (compl_token[0]);
521  } else {
522  len = common_len (compl_token);
523  terminal_newline (pThis);
524  while (compl_token [i] != NULL) {
525  pThis->print (compl_token[i]);
526  pThis->print (" ");
527  i++;
528  }
529  terminal_newline (pThis);
530  print_prompt (pThis);
531  }
532 
533  if (len) {
534  microrl_insert_text (pThis, compl_token[0] + strlen(pThis->tkn_arr[status-1]),
535  len - strlen(pThis->tkn_arr[status-1]));
536  if (compl_token[1] == NULL)
537  microrl_insert_text (pThis, " ", 1);
538  }
539  terminal_reset_cursor (pThis);
540  terminal_print_line (pThis, 0, pThis->cursor);
541  }
542 }
543 #endif
544 
545 //*****************************************************************************
547  int status;
548 
549  terminal_newline (pThis);
550 #ifdef _USE_HISTORY
551  if (pThis->cmdlen > 0)
552  hist_save_line (&pThis->ring_hist, pThis->cmdline, pThis->cmdlen);
553 #endif
554  status = split (pThis, pThis->cmdlen);
555  if (status == -1){
556  // pThis->print ("ERROR: Max token amount exseed\n");
557  pThis->print ("ERROR:too many tokens");
558  pThis->print (ENDL);
559  }
560  if ((status > 0) && (pThis->execute != NULL))
561  pThis->execute (status, pThis->tkn_arr);
562  print_prompt (pThis);
563  pThis->cmdlen = 0;
564  pThis->cursor = 0;
565  memset(pThis->cmdline, 0, _COMMAND_LINE_LEN);
566 #ifdef _USE_HISTORY
567  pThis->ring_hist.cur = 0;
568 #endif
569 }
570 
571 //*****************************************************************************
572 #if (defined(_ENDL_CRLF) || defined(_ENDL_LFCR))
573 static int tmpch = 0;
574 #endif
575 
576 void microrl_insert_char (microrl_t * pThis, int ch)
577 {
578 
579 #ifdef _USE_ESC_SEQ
580  static int escape = false;
581 
582  if (escape) {
583  if (escape_process(pThis, ch))
584  escape = 0;
585  } else {
586 #endif
587  switch (ch) {
588  //-----------------------------------------------------
589 #ifdef _ENDL_CR
590  case KEY_CR:
591  new_line_handler(pThis);
592  break;
593  case KEY_LF:
594  break;
595 #elif defined(_ENDL_CRLF)
596  case KEY_CR:
597  tmpch = KEY_CR;
598  break;
599  case KEY_LF:
600  if (tmpch == KEY_CR)
601  new_line_handler(pThis);
602  break;
603 #elif defined(_ENDL_LFCR)
604  case KEY_LF:
605  tmpch = KEY_LF;
606  break;
607  case KEY_CR:
608  if (tmpch == KEY_LF)
609  new_line_handler(pThis);
610  break;
611 #else
612  case KEY_CR:
613  break;
614  case KEY_LF:
615  new_line_handler(pThis);
616  break;
617 #endif
618  //-----------------------------------------------------
619 #ifdef _USE_COMPLETE
620  case KEY_HT:
621  microrl_get_complite (pThis);
622  break;
623 #endif
624  //-----------------------------------------------------
625  case KEY_ESC:
626 #ifdef _USE_ESC_SEQ
627  escape = 1;
628 #endif
629  break;
630  //-----------------------------------------------------
631  case KEY_NAK: // ^U
632  while (pThis->cursor > 0) {
633  microrl_backspace (pThis);
634  }
635  terminal_print_line (pThis, 0, pThis->cursor);
636  break;
637  //-----------------------------------------------------
638  case KEY_VT: // ^K
639  pThis->print ("\033[K");
640  pThis->cmdlen = pThis->cursor;
641  break;
642  //-----------------------------------------------------
643  case KEY_ENQ: // ^E
644  terminal_move_cursor (pThis, pThis->cmdlen-pThis->cursor);
645  pThis->cursor = pThis->cmdlen;
646  break;
647  //-----------------------------------------------------
648  case KEY_SOH: // ^A
649  terminal_reset_cursor (pThis);
650  pThis->cursor = 0;
651  break;
652  //-----------------------------------------------------
653  case KEY_ACK: // ^F
654  if (pThis->cursor < pThis->cmdlen) {
655  terminal_move_cursor (pThis, 1);
656  pThis->cursor++;
657  }
658  break;
659  //-----------------------------------------------------
660  case KEY_STX: // ^B
661  if (pThis->cursor) {
662  terminal_move_cursor (pThis, -1);
663  pThis->cursor--;
664  }
665  break;
666  //-----------------------------------------------------
667  case KEY_DLE: //^P
668 #ifdef _USE_HISTORY
669  hist_search (pThis, _HIST_UP);
670 #endif
671  break;
672  //-----------------------------------------------------
673  case KEY_SO: //^N
674 #ifdef _USE_HISTORY
675  hist_search (pThis, _HIST_DOWN);
676 #endif
677  break;
678  //-----------------------------------------------------
679  case KEY_DEL: // Backspace
680  case KEY_BS: // ^U
681  microrl_backspace (pThis);
682  terminal_print_line (pThis, pThis->cursor, pThis->cursor);
683  break;
684 #ifdef _USE_CTLR_C
685  case KEY_ETX:
686  if (pThis->sigint != NULL)
687  pThis->sigint();
688  break;
689 #endif
690  //-----------------------------------------------------
691  default:
692  if ((ch == ' ') && (pThis->cmdlen == 0))
693  break;
694  if (microrl_insert_text (pThis, (char*)&ch, 1))
695  terminal_print_line (pThis, pThis->cursor-1, pThis->cursor);
696 
697  break;
698  }
699 #ifdef _USE_ESC_SEQ
700  }
701 #endif
702 }
703 
static int escape_process(microrl_t *pThis, char ch)
Definition: microrl.c:385
#define KEY_NAK
^U Negative acknowledge
Definition: microrl.h:31
int cmdlen
Definition: microrl.h:71
#define KEY_STX
^B Start of text, maintenance mode on HP console
Definition: microrl.h:12
static void hist_erase_older(ring_history_t *pThis)
Definition: microrl.c:70
void microrl_insert_char(microrl_t *pThis, int ch)
Definition: microrl.c:576
static void terminal_print_line(microrl_t *pThis, int pos, int cursor)
Definition: microrl.c:312
static void microrl_get_complite(microrl_t *pThis)
Definition: microrl.c:504
Mini printf-like functionality.
#define _PROMPT_LEN
Definition: microrlConfig.h:34
ring_history_t ring_hist
Definition: microrl.h:67
#define ENDL
Definition: microrlConfig.h:84
static void terminal_backspace(microrl_t *pThis)
Definition: microrl.c:235
static int seq
Definition: nps_ivy.c:33
#define KEY_ETX
^C End of text
Definition: microrl.h:13
void new_line_handler(microrl_t *pThis)
Definition: microrl.c:546
#define _HIST_DOWN
Definition: microrl.h:47
static void terminal_move_cursor(microrl_t *pThis, int offset)
Definition: microrl.c:269
char * prompt_default
Definition: microrl.c:28
static void microrl_backspace(microrl_t *pThis)
Definition: microrl.c:467
static int microrl_insert_text(microrl_t *pThis, const char *text, int len)
Definition: microrl.c:439
#define _HIST_UP
Definition: microrl.h:46
static void terminal_newline(microrl_t *pThis)
Definition: microrl.c:241
#define KEY_SOH
^A Start of heading, = console interrupt
Definition: microrl.h:11
#define KEY_DEL
Delete (not a real control character...)
Definition: microrl.h:43
int cursor
Definition: microrl.h:72
#define KEY_ACK
^F Acknowledge, clears ENQ logon hand
Definition: microrl.h:16
#define KEY_BS
^H Backspace, works on HP terminals/computers
Definition: microrl.h:18
#define _COMMAND_TOKEN_NMB
Definition: microrlConfig.h:24
#define _RING_HISTORY_LEN
Definition: microrlConfig.h:53
#define _ESC_BRACKET
Definition: microrl.h:49
#define KEY_DLE
^P Data link escape
Definition: microrl.h:26
static int hist_is_space_for_new(ring_history_t *pThis, int len)
Definition: microrl.c:81
#define KEY_ENQ
^E Enquiry, goes with ACK; old HP flow control
Definition: microrl.h:15
static int hist_restore_line(ring_history_t *pThis, char *line, int dir)
Definition: microrl.c:131
#define KEY_CR
^M Carriage Return
Definition: microrl.h:23
static const float offset[]
static void hist_save_line(ring_history_t *pThis, char *line, int len)
Definition: microrl.c:97
uint8_t status
static void hist_search(microrl_t *pThis, int dir)
Definition: microrl.c:373
static const float dir[]
char ring_buf[_RING_HISTORY_LEN]
Definition: microrl.h:57
void microrl_set_complete_callback(microrl_t *pThis, const char **(*get_completion)(int, const char *const *))
Definition: microrl.c:353
char cmdline[_COMMAND_LINE_LEN]
Definition: microrl.h:70
static void terminal_reset_cursor(microrl_t *pThis)
Definition: microrl.c:293
#define KEY_VT
^K Vertical tab
Definition: microrl.h:21
static void print_prompt(microrl_t *pThis)
Definition: microrl.c:229
const char **(* get_completion)(int argc, const char *const *argv)
Definition: microrl.h:75
#define _COMMAND_LINE_LEN
Definition: microrlConfig.h:16
#define _ESC_HOME
Definition: microrl.h:50
void microrl_set_execute_callback(microrl_t *pThis, void(*execute)(int, const char *const *))
Definition: microrl.c:360
void(* execute)(int argc, const char *const *argv)
Definition: microrl.h:74
#define KEY_HT
^I Horizontal tab, move to next tab stop
Definition: microrl.h:19
#define _PROMPT_DEFAUTL
Definition: microrlConfig.h:29
char const * tkn_arr[_COMMAND_TOKEN_NMB]
Definition: microrl.h:73
#define _ESC_END
Definition: microrl.h:51
void(* sigint)(void)
Definition: microrl.h:78
static int common_len(const char **arr)
Definition: microrl.c:486
char * prompt_str
Definition: microrl.h:69
#define KEY_SO
^N Shift Out, alternate character set
Definition: microrl.h:24
static void u16bit_to_str(unsigned int nmb, char *buf)
Definition: microrl.c:250
#define KEY_LF
^J Line Feed
Definition: microrl.h:20
void microrl_init(microrl_t *pThis, void(*print)(const char *))
Definition: microrl.c:329
#define KEY_ESC
^[ Escape, next character is not echoed
Definition: microrl.h:37
static int split(microrl_t *pThis, int limit)
Definition: microrl.c:204
void microrl_set_sigint_callback(microrl_t *pThis, void(*sigintf)(void))
Definition: microrl.c:366
void(* print)(const char *)
Definition: microrl.h:76