microrl.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681
  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. printf(pThis->prompt_str);
  195. }
  196. //*****************************************************************************
  197. inline static void terminal_backspace (microrl_t * pThis)
  198. {
  199. pThis->print ("\033[D \033[D");
  200. }
  201. //*****************************************************************************
  202. inline static void terminal_newline (microrl_t * pThis)
  203. {
  204. pThis->print (ENDL);
  205. }
  206. #ifndef _USE_LIBC_STDIO
  207. //*****************************************************************************
  208. // convert 16 bit value to string
  209. // 0 value not supported!!! just make empty string
  210. // Returns pointer to a buffer tail
  211. static char *u16bit_to_str (unsigned int nmb, char * buf)
  212. {
  213. char tmp_str [6] = {0,};
  214. int i = 0, j;
  215. if (nmb <= 0xFFFF) {
  216. while (nmb > 0) {
  217. tmp_str[i++] = (nmb % 10) + '0';
  218. nmb /=10;
  219. }
  220. for (j = 0; j < i; ++j)
  221. *(buf++) = tmp_str [i-j-1];
  222. }
  223. *buf = '\0';
  224. return buf;
  225. }
  226. #endif
  227. //*****************************************************************************
  228. // set cursor at position from begin cmdline (after prompt) + offset
  229. static void terminal_move_cursor (microrl_t * pThis, int offset)
  230. {
  231. char str[16] = {0,};
  232. #ifdef _USE_LIBC_STDIO
  233. if (offset > 0) {
  234. snprintf (str, 16, "\033[%dC", offset);
  235. } else if (offset < 0) {
  236. snprintf (str, 16, "\033[%dD", -(offset));
  237. }
  238. #else
  239. char *endstr;
  240. strcpy (str, "\033[");
  241. if (offset > 0) {
  242. endstr = u16bit_to_str (offset, str+2);
  243. strcpy (endstr, "C");
  244. } else if (offset < 0) {
  245. endstr = u16bit_to_str (-(offset), str+2);
  246. strcpy (endstr, "D");
  247. } else
  248. return;
  249. #endif
  250. pThis->print (str);
  251. }
  252. //*****************************************************************************
  253. static void terminal_reset_cursor (microrl_t * pThis)
  254. {
  255. char str[16];
  256. #ifdef _USE_LIBC_STDIO
  257. snprintf (str, 16, "\033[%dD\033[%dC", \
  258. _COMMAND_LINE_LEN + _PROMPT_LEN + 2, _PROMPT_LEN);
  259. #else
  260. char *endstr;
  261. strcpy (str, "\033[");
  262. endstr = u16bit_to_str ( _COMMAND_LINE_LEN + _PROMPT_LEN + 2,str+2);
  263. strcpy (endstr, "D\033["); endstr += 3;
  264. endstr = u16bit_to_str (_PROMPT_LEN, endstr);
  265. strcpy (endstr, "C");
  266. #endif
  267. pThis->print (str);
  268. }
  269. //*****************************************************************************
  270. // print cmdline to screen, replace '\0' to wihitespace
  271. static void terminal_print_line (microrl_t * pThis, int pos, int cursor)
  272. {
  273. pThis->print ("\033[K"); // delete all from cursor to end
  274. char nch [] = {0,0};
  275. int i;
  276. for (i = pos; i < pThis->cmdlen; i++) {
  277. nch [0] = pThis->cmdline [i];
  278. if (nch[0] == '\0')
  279. nch[0] = ' ';
  280. pThis->print (nch);
  281. }
  282. terminal_reset_cursor (pThis);
  283. terminal_move_cursor (pThis, cursor);
  284. }
  285. //*****************************************************************************
  286. void microrl_init (microrl_t * pThis, void (*print) (const char *))
  287. {
  288. memset(pThis->cmdline, 0, _COMMAND_LINE_LEN);
  289. #ifdef _USE_HISTORY
  290. memset(pThis->ring_hist.ring_buf, 0, _RING_HISTORY_LEN);
  291. pThis->ring_hist.begin = 0;
  292. pThis->ring_hist.end = 0;
  293. pThis->ring_hist.cur = 0;
  294. #endif
  295. pThis->cmdlen =0;
  296. pThis->cursor = 0;
  297. pThis->execute = NULL;
  298. pThis->get_completion = NULL;
  299. #ifdef _USE_CTLR_C
  300. pThis->sigint = NULL;
  301. #endif
  302. pThis->prompt_str = prompt_default;
  303. pThis->print = print;
  304. #ifdef _ENABLE_INIT_PROMPT
  305. print_prompt (pThis);
  306. #endif
  307. }
  308. //*****************************************************************************
  309. void microrl_set_complete_callback (microrl_t * pThis, char ** (*get_completion)(int, const char* const*))
  310. {
  311. pThis->get_completion = get_completion;
  312. }
  313. //*****************************************************************************
  314. void microrl_set_execute_callback (microrl_t * pThis, int (*execute)(int, const char* const*))
  315. {
  316. pThis->execute = execute;
  317. }
  318. #ifdef _USE_CTLR_C
  319. //*****************************************************************************
  320. void microrl_set_sigint_callback (microrl_t * pThis, void (*sigintf)(void))
  321. {
  322. pThis->sigint = sigintf;
  323. }
  324. #endif
  325. #ifdef _USE_ESC_SEQ
  326. static void hist_search (microrl_t * pThis, int dir)
  327. {
  328. int len = hist_restore_line (&pThis->ring_hist, pThis->cmdline, dir);
  329. if (len >= 0) {
  330. pThis->cursor = pThis->cmdlen = len;
  331. terminal_reset_cursor (pThis);
  332. terminal_print_line (pThis, 0, pThis->cursor);
  333. }
  334. }
  335. //*****************************************************************************
  336. // handling escape sequences
  337. static int escape_process (microrl_t * pThis, char ch)
  338. {
  339. if (ch == '[') {
  340. pThis->escape_seq = _ESC_BRACKET;
  341. return 0;
  342. } else if (pThis->escape_seq == _ESC_BRACKET) {
  343. if (ch == 'A') {
  344. #ifdef _USE_HISTORY
  345. hist_search (pThis, _HIST_UP);
  346. #endif
  347. return 1;
  348. } else if (ch == 'B') {
  349. #ifdef _USE_HISTORY
  350. hist_search (pThis, _HIST_DOWN);
  351. #endif
  352. return 1;
  353. } else if (ch == 'C') {
  354. if (pThis->cursor < pThis->cmdlen) {
  355. terminal_move_cursor (pThis, 1);
  356. pThis->cursor++;
  357. }
  358. return 1;
  359. } else if (ch == 'D') {
  360. if (pThis->cursor > 0) {
  361. terminal_move_cursor (pThis, -1);
  362. pThis->cursor--;
  363. }
  364. return 1;
  365. } else if (ch == '7') {
  366. pThis->escape_seq = _ESC_HOME;
  367. return 0;
  368. } else if (ch == '8') {
  369. pThis->escape_seq = _ESC_END;
  370. return 0;
  371. }
  372. } else if (ch == '~') {
  373. if (pThis->escape_seq == _ESC_HOME) {
  374. terminal_reset_cursor (pThis);
  375. pThis->cursor = 0;
  376. return 1;
  377. } else if (pThis->escape_seq == _ESC_END) {
  378. terminal_move_cursor (pThis, pThis->cmdlen-pThis->cursor);
  379. pThis->cursor = pThis->cmdlen;
  380. return 1;
  381. }
  382. }
  383. /* unknown escape sequence, stop */
  384. return 1;
  385. }
  386. #endif
  387. //*****************************************************************************
  388. // insert len char of text at cursor position
  389. static int microrl_insert_text (microrl_t * pThis, char * text, int len)
  390. {
  391. int i;
  392. if (pThis->cmdlen + len < _COMMAND_LINE_LEN) {
  393. memmove (pThis->cmdline + pThis->cursor + len,
  394. pThis->cmdline + pThis->cursor,
  395. pThis->cmdlen - pThis->cursor);
  396. for (i = 0; i < len; i++) {
  397. pThis->cmdline [pThis->cursor + i] = text [i];
  398. if (pThis->cmdline [pThis->cursor + i] == ' ') {
  399. pThis->cmdline [pThis->cursor + i] = 0;
  400. }
  401. }
  402. pThis->cursor += len;
  403. pThis->cmdlen += len;
  404. pThis->cmdline [pThis->cmdlen] = '\0';
  405. return true;
  406. }
  407. return false;
  408. }
  409. //*****************************************************************************
  410. // remove one char at cursor
  411. static void microrl_backspace (microrl_t * pThis)
  412. {
  413. if (pThis->cursor > 0) {
  414. terminal_backspace (pThis);
  415. memmove (pThis->cmdline + pThis->cursor-1,
  416. pThis->cmdline + pThis->cursor,
  417. pThis->cmdlen-pThis->cursor+1);
  418. pThis->cursor--;
  419. pThis->cmdline [pThis->cmdlen] = '\0';
  420. pThis->cmdlen--;
  421. }
  422. }
  423. #ifdef _USE_COMPLETE
  424. //*****************************************************************************
  425. static int common_len (char ** arr)
  426. {
  427. int len = 0;
  428. int i = 1;
  429. while (1) {
  430. while (arr[i]!=NULL) {
  431. if ((arr[i][len] != arr[i-1][len]) ||
  432. (arr[i][len] == '\0') ||
  433. (arr[i-1][len]=='\0'))
  434. return len;
  435. len++;
  436. }
  437. i++;
  438. }
  439. return 0;
  440. }
  441. //*****************************************************************************
  442. static void microrl_get_complite (microrl_t * pThis)
  443. {
  444. char const * tkn_arr[_COMMAND_TOKEN_NMB];
  445. char ** compl_token;
  446. if (pThis->get_completion == NULL) // callback was not set
  447. return;
  448. int status = split (pThis, pThis->cursor, tkn_arr);
  449. if (pThis->cmdline[pThis->cursor-1] == '\0')
  450. tkn_arr[status++] = "";
  451. compl_token = pThis->get_completion (status, tkn_arr);
  452. if (compl_token[0] != NULL) {
  453. int i = 0;
  454. int len;
  455. if (compl_token[1] == NULL) {
  456. len = strlen (compl_token[0]);
  457. } else {
  458. len = common_len (compl_token);
  459. terminal_newline (pThis);
  460. while (compl_token [i] != NULL) {
  461. pThis->print (compl_token[i]);
  462. pThis->print (" ");
  463. i++;
  464. }
  465. terminal_newline (pThis);
  466. print_prompt (pThis);
  467. }
  468. if (len) {
  469. microrl_insert_text (pThis, compl_token[0] + strlen(tkn_arr[status-1]),
  470. len - strlen(tkn_arr[status-1]));
  471. if (compl_token[1] == NULL)
  472. microrl_insert_text (pThis, " ", 1);
  473. }
  474. terminal_reset_cursor (pThis);
  475. terminal_print_line (pThis, 0, pThis->cursor);
  476. }
  477. }
  478. #endif
  479. //*****************************************************************************
  480. void new_line_handler(microrl_t * pThis){
  481. char const * tkn_arr [_COMMAND_TOKEN_NMB];
  482. int status;
  483. terminal_newline (pThis);
  484. #ifdef _USE_HISTORY
  485. if (pThis->cmdlen > 0)
  486. hist_save_line (&pThis->ring_hist, pThis->cmdline, pThis->cmdlen);
  487. #endif
  488. status = split (pThis, pThis->cmdlen, tkn_arr);
  489. if (status == -1){
  490. // pThis->print ("ERROR: Max token amount exseed\n");
  491. pThis->print ("ERROR:too many tokens");
  492. pThis->print (ENDL);
  493. }
  494. if ((status > 0) && (pThis->execute != NULL))
  495. pThis->execute (status, tkn_arr);
  496. print_prompt (pThis);
  497. pThis->cmdlen = 0;
  498. pThis->cursor = 0;
  499. memset(pThis->cmdline, 0, _COMMAND_LINE_LEN);
  500. #ifdef _USE_HISTORY
  501. pThis->ring_hist.cur = 0;
  502. #endif
  503. }
  504. //*****************************************************************************
  505. void microrl_insert_char (microrl_t * pThis, int ch)
  506. {
  507. #ifdef _USE_ESC_SEQ
  508. if (pThis->escape) {
  509. if (escape_process(pThis, ch))
  510. pThis->escape = 0;
  511. } else {
  512. #endif
  513. switch (ch) {
  514. //-----------------------------------------------------
  515. #ifdef _ENDL_CR
  516. case KEY_CR:
  517. new_line_handler(pThis);
  518. break;
  519. case KEY_LF:
  520. break;
  521. #elif defined(_ENDL_CRLF)
  522. case KEY_CR:
  523. pThis->tmpch = KEY_CR;
  524. break;
  525. case KEY_LF:
  526. if (pThis->tmpch == KEY_CR)
  527. new_line_handler(pThis);
  528. break;
  529. #elif defined(_ENDL_LFCR)
  530. case KEY_LF:
  531. pThis->tmpch = KEY_LF;
  532. break;
  533. case KEY_CR:
  534. if (pThis->tmpch == KEY_LF)
  535. new_line_handler(pThis);
  536. break;
  537. #else
  538. case KEY_CR:
  539. break;
  540. case KEY_LF:
  541. new_line_handler(pThis);
  542. break;
  543. #endif
  544. //-----------------------------------------------------
  545. #ifdef _USE_COMPLETE
  546. case KEY_HT:
  547. microrl_get_complite (pThis);
  548. break;
  549. #endif
  550. //-----------------------------------------------------
  551. case KEY_ESC:
  552. #ifdef _USE_ESC_SEQ
  553. pThis->escape = 1;
  554. #endif
  555. break;
  556. //-----------------------------------------------------
  557. case KEY_NAK: // ^U
  558. while (pThis->cursor > 0) {
  559. microrl_backspace (pThis);
  560. }
  561. terminal_print_line (pThis, 0, pThis->cursor);
  562. break;
  563. //-----------------------------------------------------
  564. case KEY_VT: // ^K
  565. pThis->print ("\033[K");
  566. pThis->cmdlen = pThis->cursor;
  567. break;
  568. //-----------------------------------------------------
  569. case KEY_ENQ: // ^E
  570. terminal_move_cursor (pThis, pThis->cmdlen-pThis->cursor);
  571. pThis->cursor = pThis->cmdlen;
  572. break;
  573. //-----------------------------------------------------
  574. case KEY_SOH: // ^A
  575. terminal_reset_cursor (pThis);
  576. pThis->cursor = 0;
  577. break;
  578. //-----------------------------------------------------
  579. case KEY_ACK: // ^F
  580. if (pThis->cursor < pThis->cmdlen) {
  581. terminal_move_cursor (pThis, 1);
  582. pThis->cursor++;
  583. }
  584. break;
  585. //-----------------------------------------------------
  586. case KEY_STX: // ^B
  587. if (pThis->cursor) {
  588. terminal_move_cursor (pThis, -1);
  589. pThis->cursor--;
  590. }
  591. break;
  592. //-----------------------------------------------------
  593. case KEY_DLE: //^P
  594. #ifdef _USE_HISTORY
  595. hist_search (pThis, _HIST_UP);
  596. #endif
  597. break;
  598. //-----------------------------------------------------
  599. case KEY_SO: //^N
  600. #ifdef _USE_HISTORY
  601. hist_search (pThis, _HIST_DOWN);
  602. #endif
  603. break;
  604. //-----------------------------------------------------
  605. case KEY_DEL: // Backspace
  606. case KEY_BS: // ^U
  607. microrl_backspace (pThis);
  608. terminal_print_line (pThis, pThis->cursor, pThis->cursor);
  609. break;
  610. #ifdef _USE_CTLR_C
  611. case KEY_ETX:
  612. if (pThis->sigint != NULL)
  613. pThis->sigint();
  614. break;
  615. #endif
  616. //-----------------------------------------------------
  617. default:
  618. if (((ch == ' ') && (pThis->cmdlen == 0)) || IS_CONTROL_CHAR(ch))
  619. break;
  620. if (microrl_insert_text (pThis, (char*)&ch, 1))
  621. terminal_print_line (pThis, pThis->cursor-1, pThis->cursor);
  622. break;
  623. }
  624. #ifdef _USE_ESC_SEQ
  625. }
  626. #endif
  627. }