microrl.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680
  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. #include <string.h>
  8. #include <ctype.h>
  9. #include <stdlib.h>
  10. #include "microrl.h"
  11. #ifdef _USE_LIBC_STDIO
  12. #include <stdio.h>
  13. #endif
  14. //#define DBG(...) fprintf(stderr, "\033[33m");fprintf(stderr,__VA_ARGS__);fprintf(stderr,"\033[0m");
  15. char * prompt_default = _PROMPT_DEFAULT;
  16. #ifdef _USE_HISTORY
  17. #ifdef _HISTORY_DEBUG
  18. //*****************************************************************************
  19. // print buffer content on screen
  20. static void print_hist (ring_history_t * pThis)
  21. {
  22. printf ("\n");
  23. for (int i = 0; i < _RING_HISTORY_LEN; i++) {
  24. if (i == pThis->begin)
  25. printf ("b");
  26. else
  27. printf (" ");
  28. }
  29. printf ("\n");
  30. for (int i = 0; i < _RING_HISTORY_LEN; i++) {
  31. if (isalpha(pThis->ring_buf[i]))
  32. printf ("%c", pThis->ring_buf[i]);
  33. else
  34. printf ("%d", pThis->ring_buf[i]);
  35. }
  36. printf ("\n");
  37. for (int i = 0; i < _RING_HISTORY_LEN; i++) {
  38. if (i == pThis->end)
  39. printf ("e");
  40. else
  41. printf (" ");
  42. }
  43. printf ("\n");
  44. }
  45. #endif
  46. //*****************************************************************************
  47. // remove older message from ring buffer
  48. static void hist_erase_older (ring_history_t * pThis)
  49. {
  50. int new_pos = pThis->begin + pThis->ring_buf [pThis->begin] + 1;
  51. if (new_pos >= _RING_HISTORY_LEN)
  52. new_pos = new_pos - _RING_HISTORY_LEN;
  53. pThis->begin = new_pos;
  54. }
  55. //*****************************************************************************
  56. // check space for new line, remove older while not space
  57. static int hist_is_space_for_new (ring_history_t * pThis, int len)
  58. {
  59. if (pThis->ring_buf [pThis->begin] == 0)
  60. return true;
  61. if (pThis->end >= pThis->begin) {
  62. if (_RING_HISTORY_LEN - pThis->end + pThis->begin - 1 > len)
  63. return true;
  64. } else {
  65. if (pThis->begin - pThis->end - 1> len)
  66. return true;
  67. }
  68. return false;
  69. }
  70. //*****************************************************************************
  71. // put line to ring buffer
  72. static void hist_save_line (ring_history_t * pThis, char * line, int len)
  73. {
  74. if (len > _RING_HISTORY_LEN - 2)
  75. return;
  76. while (!hist_is_space_for_new (pThis, len)) {
  77. hist_erase_older (pThis);
  78. }
  79. // if it's first line
  80. if (pThis->ring_buf [pThis->begin] == 0)
  81. pThis->ring_buf [pThis->begin] = len;
  82. // store line
  83. if (len < _RING_HISTORY_LEN-pThis->end-1)
  84. memcpy (pThis->ring_buf + pThis->end + 1, line, len);
  85. else {
  86. int part_len = _RING_HISTORY_LEN-pThis->end-1;
  87. memcpy (pThis->ring_buf + pThis->end + 1, line, part_len);
  88. memcpy (pThis->ring_buf, line + part_len, len - part_len);
  89. }
  90. pThis->ring_buf [pThis->end] = len;
  91. pThis->end = pThis->end + len + 1;
  92. if (pThis->end >= _RING_HISTORY_LEN)
  93. pThis->end -= _RING_HISTORY_LEN;
  94. pThis->ring_buf [pThis->end] = 0;
  95. pThis->cur = 0;
  96. #ifdef _HISTORY_DEBUG
  97. print_hist (pThis);
  98. #endif
  99. }
  100. //*****************************************************************************
  101. // copy saved line to 'line' and return size of line
  102. static int hist_restore_line (ring_history_t * pThis, char * line, int dir)
  103. {
  104. int cnt = 0;
  105. // count history record
  106. int header = pThis->begin;
  107. while (pThis->ring_buf [header] != 0) {
  108. header += pThis->ring_buf [header] + 1;
  109. if (header >= _RING_HISTORY_LEN)
  110. header -= _RING_HISTORY_LEN;
  111. cnt++;
  112. }
  113. if (dir == _HIST_UP) {
  114. if (cnt >= pThis->cur) {
  115. int header = pThis->begin;
  116. int j = 0;
  117. // found record for 'pThis->cur' index
  118. while ((pThis->ring_buf [header] != 0) && (cnt - j -1 != pThis->cur)) {
  119. header += pThis->ring_buf [header] + 1;
  120. if (header >= _RING_HISTORY_LEN)
  121. header -= _RING_HISTORY_LEN;
  122. j++;
  123. }
  124. if (pThis->ring_buf[header]) {
  125. pThis->cur++;
  126. // obtain saved line
  127. if (pThis->ring_buf [header] + header < _RING_HISTORY_LEN) {
  128. memset (line, 0, _COMMAND_LINE_LEN);
  129. memcpy (line, pThis->ring_buf + header + 1, pThis->ring_buf[header]);
  130. } else {
  131. int part0 = _RING_HISTORY_LEN - header - 1;
  132. memset (line, 0, _COMMAND_LINE_LEN);
  133. memcpy (line, pThis->ring_buf + header + 1, part0);
  134. memcpy (line + part0, pThis->ring_buf, pThis->ring_buf[header] - part0);
  135. }
  136. return pThis->ring_buf[header];
  137. }
  138. }
  139. } else {
  140. if (pThis->cur > 0) {
  141. pThis->cur--;
  142. int header = pThis->begin;
  143. int j = 0;
  144. while ((pThis->ring_buf [header] != 0) && (cnt - j != pThis->cur)) {
  145. header += pThis->ring_buf [header] + 1;
  146. if (header >= _RING_HISTORY_LEN)
  147. header -= _RING_HISTORY_LEN;
  148. j++;
  149. }
  150. if (pThis->ring_buf [header] + header < _RING_HISTORY_LEN) {
  151. memcpy (line, pThis->ring_buf + header + 1, pThis->ring_buf[header]);
  152. } else {
  153. int part0 = _RING_HISTORY_LEN - header - 1;
  154. memcpy (line, pThis->ring_buf + header + 1, part0);
  155. memcpy (line + part0, pThis->ring_buf, pThis->ring_buf[header] - part0);
  156. }
  157. return pThis->ring_buf[header];
  158. } else {
  159. /* empty line */
  160. return 0;
  161. }
  162. }
  163. return -1;
  164. }
  165. #endif
  166. //*****************************************************************************
  167. // split cmdline to tkn array and return nmb of token
  168. static int split (microrl_t * pThis, int limit, char const ** tkn_arr)
  169. {
  170. int i = 0;
  171. int ind = 0;
  172. while (1) {
  173. // go to the first whitespace (zerro for us)
  174. while ((pThis->cmdline [ind] == '\0') && (ind < limit)) {
  175. ind++;
  176. }
  177. if (!(ind < limit)) return i;
  178. tkn_arr[i++] = pThis->cmdline + ind;
  179. if (i >= _COMMAND_TOKEN_NMB) {
  180. return -1;
  181. }
  182. // go to the first NOT whitespace (not zerro for us)
  183. while ((pThis->cmdline [ind] != '\0') && (ind < limit)) {
  184. ind++;
  185. }
  186. if (!(ind < limit)) return i;
  187. }
  188. return i;
  189. }
  190. //*****************************************************************************
  191. inline static void print_prompt (microrl_t * pThis)
  192. {
  193. pThis->print (pThis->prompt_str);
  194. }
  195. //*****************************************************************************
  196. inline static void terminal_backspace (microrl_t * pThis)
  197. {
  198. pThis->print ("\033[D \033[D");
  199. }
  200. //*****************************************************************************
  201. inline static void terminal_newline (microrl_t * pThis)
  202. {
  203. pThis->print (ENDL);
  204. }
  205. #ifndef _USE_LIBC_STDIO
  206. //*****************************************************************************
  207. // convert 16 bit value to string
  208. // 0 value not supported!!! just make empty string
  209. // Returns pointer to a buffer tail
  210. static char *u16bit_to_str (unsigned int nmb, char * buf)
  211. {
  212. char tmp_str [6] = {0,};
  213. int i = 0, j;
  214. if (nmb <= 0xFFFF) {
  215. while (nmb > 0) {
  216. tmp_str[i++] = (nmb % 10) + '0';
  217. nmb /=10;
  218. }
  219. for (j = 0; j < i; ++j)
  220. *(buf++) = tmp_str [i-j-1];
  221. }
  222. *buf = '\0';
  223. return buf;
  224. }
  225. #endif
  226. //*****************************************************************************
  227. // set cursor at position from begin cmdline (after prompt) + offset
  228. static void terminal_move_cursor (microrl_t * pThis, int offset)
  229. {
  230. char str[16] = {0,};
  231. #ifdef _USE_LIBC_STDIO
  232. if (offset > 0) {
  233. snprintf (str, 16, "\033[%dC", offset);
  234. } else if (offset < 0) {
  235. snprintf (str, 16, "\033[%dD", -(offset));
  236. }
  237. #else
  238. char *endstr;
  239. strcpy (str, "\033[");
  240. if (offset > 0) {
  241. endstr = u16bit_to_str (offset, str+2);
  242. strcpy (endstr, "C");
  243. } else if (offset < 0) {
  244. endstr = u16bit_to_str (-(offset), str+2);
  245. strcpy (endstr, "D");
  246. } else
  247. return;
  248. #endif
  249. pThis->print (str);
  250. }
  251. //*****************************************************************************
  252. static void terminal_reset_cursor (microrl_t * pThis)
  253. {
  254. char str[16];
  255. #ifdef _USE_LIBC_STDIO
  256. snprintf (str, 16, "\033[%dD\033[%dC", \
  257. _COMMAND_LINE_LEN + _PROMPT_LEN + 2, _PROMPT_LEN);
  258. #else
  259. char *endstr;
  260. strcpy (str, "\033[");
  261. endstr = u16bit_to_str ( _COMMAND_LINE_LEN + _PROMPT_LEN + 2,str+2);
  262. strcpy (endstr, "D\033["); endstr += 3;
  263. endstr = u16bit_to_str (_PROMPT_LEN, endstr);
  264. strcpy (endstr, "C");
  265. #endif
  266. pThis->print (str);
  267. }
  268. //*****************************************************************************
  269. // print cmdline to screen, replace '\0' to wihitespace
  270. static void terminal_print_line (microrl_t * pThis, int pos, int cursor)
  271. {
  272. pThis->print ("\033[K"); // delete all from cursor to end
  273. char nch [] = {0,0};
  274. int i;
  275. for (i = pos; i < pThis->cmdlen; i++) {
  276. nch [0] = pThis->cmdline [i];
  277. if (nch[0] == '\0')
  278. nch[0] = ' ';
  279. pThis->print (nch);
  280. }
  281. terminal_reset_cursor (pThis);
  282. terminal_move_cursor (pThis, cursor);
  283. }
  284. //*****************************************************************************
  285. void microrl_init (microrl_t * pThis, void (*print) (const char *))
  286. {
  287. memset(pThis->cmdline, 0, _COMMAND_LINE_LEN);
  288. #ifdef _USE_HISTORY
  289. memset(pThis->ring_hist.ring_buf, 0, _RING_HISTORY_LEN);
  290. pThis->ring_hist.begin = 0;
  291. pThis->ring_hist.end = 0;
  292. pThis->ring_hist.cur = 0;
  293. #endif
  294. pThis->cmdlen =0;
  295. pThis->cursor = 0;
  296. pThis->execute = NULL;
  297. pThis->get_completion = NULL;
  298. #ifdef _USE_CTLR_C
  299. pThis->sigint = NULL;
  300. #endif
  301. pThis->prompt_str = prompt_default;
  302. pThis->print = print;
  303. #ifdef _ENABLE_INIT_PROMPT
  304. print_prompt (pThis);
  305. #endif
  306. }
  307. //*****************************************************************************
  308. void microrl_set_complete_callback (microrl_t * pThis, char ** (*get_completion)(int, const char* const*))
  309. {
  310. pThis->get_completion = get_completion;
  311. }
  312. //*****************************************************************************
  313. void microrl_set_execute_callback (microrl_t * pThis, int (*execute)(int, const char* const*))
  314. {
  315. pThis->execute = execute;
  316. }
  317. #ifdef _USE_CTLR_C
  318. //*****************************************************************************
  319. void microrl_set_sigint_callback (microrl_t * pThis, void (*sigintf)(void))
  320. {
  321. pThis->sigint = sigintf;
  322. }
  323. #endif
  324. #ifdef _USE_ESC_SEQ
  325. static void hist_search (microrl_t * pThis, int dir)
  326. {
  327. int len = hist_restore_line (&pThis->ring_hist, pThis->cmdline, dir);
  328. if (len >= 0) {
  329. pThis->cursor = pThis->cmdlen = len;
  330. terminal_reset_cursor (pThis);
  331. terminal_print_line (pThis, 0, pThis->cursor);
  332. }
  333. }
  334. //*****************************************************************************
  335. // handling escape sequences
  336. static int escape_process (microrl_t * pThis, char ch)
  337. {
  338. if (ch == '[') {
  339. pThis->escape_seq = _ESC_BRACKET;
  340. return 0;
  341. } else if (pThis->escape_seq == _ESC_BRACKET) {
  342. if (ch == 'A') {
  343. #ifdef _USE_HISTORY
  344. hist_search (pThis, _HIST_UP);
  345. #endif
  346. return 1;
  347. } else if (ch == 'B') {
  348. #ifdef _USE_HISTORY
  349. hist_search (pThis, _HIST_DOWN);
  350. #endif
  351. return 1;
  352. } else if (ch == 'C') {
  353. if (pThis->cursor < pThis->cmdlen) {
  354. terminal_move_cursor (pThis, 1);
  355. pThis->cursor++;
  356. }
  357. return 1;
  358. } else if (ch == 'D') {
  359. if (pThis->cursor > 0) {
  360. terminal_move_cursor (pThis, -1);
  361. pThis->cursor--;
  362. }
  363. return 1;
  364. } else if (ch == '7') {
  365. pThis->escape_seq = _ESC_HOME;
  366. return 0;
  367. } else if (ch == '8') {
  368. pThis->escape_seq = _ESC_END;
  369. return 0;
  370. }
  371. } else if (ch == '~') {
  372. if (pThis->escape_seq == _ESC_HOME) {
  373. terminal_reset_cursor (pThis);
  374. pThis->cursor = 0;
  375. return 1;
  376. } else if (pThis->escape_seq == _ESC_END) {
  377. terminal_move_cursor (pThis, pThis->cmdlen-pThis->cursor);
  378. pThis->cursor = pThis->cmdlen;
  379. return 1;
  380. }
  381. }
  382. /* unknown escape sequence, stop */
  383. return 1;
  384. }
  385. #endif
  386. //*****************************************************************************
  387. // insert len char of text at cursor position
  388. static int microrl_insert_text (microrl_t * pThis, char * text, int len)
  389. {
  390. int i;
  391. if (pThis->cmdlen + len < _COMMAND_LINE_LEN) {
  392. memmove (pThis->cmdline + pThis->cursor + len,
  393. pThis->cmdline + pThis->cursor,
  394. pThis->cmdlen - pThis->cursor);
  395. for (i = 0; i < len; i++) {
  396. pThis->cmdline [pThis->cursor + i] = text [i];
  397. if (pThis->cmdline [pThis->cursor + i] == ' ') {
  398. pThis->cmdline [pThis->cursor + i] = 0;
  399. }
  400. }
  401. pThis->cursor += len;
  402. pThis->cmdlen += len;
  403. pThis->cmdline [pThis->cmdlen] = '\0';
  404. return true;
  405. }
  406. return false;
  407. }
  408. //*****************************************************************************
  409. // remove one char at cursor
  410. static void microrl_backspace (microrl_t * pThis)
  411. {
  412. if (pThis->cursor > 0) {
  413. terminal_backspace (pThis);
  414. memmove (pThis->cmdline + pThis->cursor-1,
  415. pThis->cmdline + pThis->cursor,
  416. pThis->cmdlen-pThis->cursor+1);
  417. pThis->cursor--;
  418. pThis->cmdline [pThis->cmdlen] = '\0';
  419. pThis->cmdlen--;
  420. }
  421. }
  422. #ifdef _USE_COMPLETE
  423. //*****************************************************************************
  424. static int common_len (char ** arr)
  425. {
  426. int len = 0;
  427. int i = 1;
  428. while (1) {
  429. while (arr[i]!=NULL) {
  430. if ((arr[i][len] != arr[i-1][len]) ||
  431. (arr[i][len] == '\0') ||
  432. (arr[i-1][len]=='\0'))
  433. return len;
  434. len++;
  435. }
  436. i++;
  437. }
  438. return 0;
  439. }
  440. //*****************************************************************************
  441. static void microrl_get_complite (microrl_t * pThis)
  442. {
  443. char const * tkn_arr[_COMMAND_TOKEN_NMB];
  444. char ** compl_token;
  445. if (pThis->get_completion == NULL) // callback was not set
  446. return;
  447. int status = split (pThis, pThis->cursor, tkn_arr);
  448. if (pThis->cmdline[pThis->cursor-1] == '\0')
  449. tkn_arr[status++] = "";
  450. compl_token = pThis->get_completion (status, tkn_arr);
  451. if (compl_token[0] != NULL) {
  452. int i = 0;
  453. int len;
  454. if (compl_token[1] == NULL) {
  455. len = strlen (compl_token[0]);
  456. } else {
  457. len = common_len (compl_token);
  458. terminal_newline (pThis);
  459. while (compl_token [i] != NULL) {
  460. pThis->print (compl_token[i]);
  461. pThis->print (" ");
  462. i++;
  463. }
  464. terminal_newline (pThis);
  465. print_prompt (pThis);
  466. }
  467. if (len) {
  468. microrl_insert_text (pThis, compl_token[0] + strlen(tkn_arr[status-1]),
  469. len - strlen(tkn_arr[status-1]));
  470. if (compl_token[1] == NULL)
  471. microrl_insert_text (pThis, " ", 1);
  472. }
  473. terminal_reset_cursor (pThis);
  474. terminal_print_line (pThis, 0, pThis->cursor);
  475. }
  476. }
  477. #endif
  478. //*****************************************************************************
  479. void new_line_handler(microrl_t * pThis){
  480. char const * tkn_arr [_COMMAND_TOKEN_NMB];
  481. int status;
  482. terminal_newline (pThis);
  483. #ifdef _USE_HISTORY
  484. if (pThis->cmdlen > 0)
  485. hist_save_line (&pThis->ring_hist, pThis->cmdline, pThis->cmdlen);
  486. #endif
  487. status = split (pThis, pThis->cmdlen, tkn_arr);
  488. if (status == -1){
  489. // pThis->print ("ERROR: Max token amount exseed\n");
  490. pThis->print ("ERROR:too many tokens");
  491. pThis->print (ENDL);
  492. }
  493. if ((status > 0) && (pThis->execute != NULL))
  494. pThis->execute (status, tkn_arr);
  495. print_prompt (pThis);
  496. pThis->cmdlen = 0;
  497. pThis->cursor = 0;
  498. memset(pThis->cmdline, 0, _COMMAND_LINE_LEN);
  499. #ifdef _USE_HISTORY
  500. pThis->ring_hist.cur = 0;
  501. #endif
  502. }
  503. //*****************************************************************************
  504. void microrl_insert_char (microrl_t * pThis, int ch)
  505. {
  506. #ifdef _USE_ESC_SEQ
  507. if (pThis->escape) {
  508. if (escape_process(pThis, ch))
  509. pThis->escape = 0;
  510. } else {
  511. #endif
  512. switch (ch) {
  513. //-----------------------------------------------------
  514. #ifdef _ENDL_CR
  515. case KEY_CR:
  516. new_line_handler(pThis);
  517. break;
  518. case KEY_LF:
  519. break;
  520. #elif defined(_ENDL_CRLF)
  521. case KEY_CR:
  522. pThis->tmpch = KEY_CR;
  523. break;
  524. case KEY_LF:
  525. if (pThis->tmpch == KEY_CR)
  526. new_line_handler(pThis);
  527. break;
  528. #elif defined(_ENDL_LFCR)
  529. case KEY_LF:
  530. pThis->tmpch = KEY_LF;
  531. break;
  532. case KEY_CR:
  533. if (pThis->tmpch == KEY_LF)
  534. new_line_handler(pThis);
  535. break;
  536. #else
  537. case KEY_CR:
  538. break;
  539. case KEY_LF:
  540. new_line_handler(pThis);
  541. break;
  542. #endif
  543. //-----------------------------------------------------
  544. #ifdef _USE_COMPLETE
  545. case KEY_HT:
  546. microrl_get_complite (pThis);
  547. break;
  548. #endif
  549. //-----------------------------------------------------
  550. case KEY_ESC:
  551. #ifdef _USE_ESC_SEQ
  552. pThis->escape = 1;
  553. #endif
  554. break;
  555. //-----------------------------------------------------
  556. case KEY_NAK: // ^U
  557. while (pThis->cursor > 0) {
  558. microrl_backspace (pThis);
  559. }
  560. terminal_print_line (pThis, 0, pThis->cursor);
  561. break;
  562. //-----------------------------------------------------
  563. case KEY_VT: // ^K
  564. pThis->print ("\033[K");
  565. pThis->cmdlen = pThis->cursor;
  566. break;
  567. //-----------------------------------------------------
  568. case KEY_ENQ: // ^E
  569. terminal_move_cursor (pThis, pThis->cmdlen-pThis->cursor);
  570. pThis->cursor = pThis->cmdlen;
  571. break;
  572. //-----------------------------------------------------
  573. case KEY_SOH: // ^A
  574. terminal_reset_cursor (pThis);
  575. pThis->cursor = 0;
  576. break;
  577. //-----------------------------------------------------
  578. case KEY_ACK: // ^F
  579. if (pThis->cursor < pThis->cmdlen) {
  580. terminal_move_cursor (pThis, 1);
  581. pThis->cursor++;
  582. }
  583. break;
  584. //-----------------------------------------------------
  585. case KEY_STX: // ^B
  586. if (pThis->cursor) {
  587. terminal_move_cursor (pThis, -1);
  588. pThis->cursor--;
  589. }
  590. break;
  591. //-----------------------------------------------------
  592. case KEY_DLE: //^P
  593. #ifdef _USE_HISTORY
  594. hist_search (pThis, _HIST_UP);
  595. #endif
  596. break;
  597. //-----------------------------------------------------
  598. case KEY_SO: //^N
  599. #ifdef _USE_HISTORY
  600. hist_search (pThis, _HIST_DOWN);
  601. #endif
  602. break;
  603. //-----------------------------------------------------
  604. case KEY_DEL: // Backspace
  605. case KEY_BS: // ^U
  606. microrl_backspace (pThis);
  607. terminal_print_line (pThis, pThis->cursor, pThis->cursor);
  608. break;
  609. #ifdef _USE_CTLR_C
  610. case KEY_ETX:
  611. if (pThis->sigint != NULL)
  612. pThis->sigint();
  613. break;
  614. #endif
  615. //-----------------------------------------------------
  616. default:
  617. if (((ch == ' ') && (pThis->cmdlen == 0)) || IS_CONTROL_CHAR(ch))
  618. break;
  619. if (microrl_insert_text (pThis, (char*)&ch, 1))
  620. terminal_print_line (pThis, pThis->cursor-1, pThis->cursor);
  621. break;
  622. }
  623. #ifdef _USE_ESC_SEQ
  624. }
  625. #endif
  626. }