lua.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700
  1. /*
  2. ** $Id: lua.c,v 1.160.1.2 2007/12/28 15:32:23 roberto Exp $
  3. ** Lua stand-alone interpreter
  4. ** See Copyright Notice in lua.h
  5. */
  6. // #include "c_signal.h"
  7. #include "c_stdio.h"
  8. #include "c_stdlib.h"
  9. #include "c_string.h"
  10. #include "flash_fs.h"
  11. #include "user_version.h"
  12. #define lua_c
  13. #include "lua.h"
  14. #include "lauxlib.h"
  15. #include "lualib.h"
  16. #include "legc.h"
  17. #include "os_type.h"
  18. os_timer_t lua_timer;
  19. LOCAL os_timer_t readline_timer;
  20. lua_State *globalL = NULL;
  21. lua_Load gLoad;
  22. static const char *progname = LUA_PROGNAME;
  23. #ifdef DEVKIT_VERSION_0_9
  24. static int key_press_count = 0;
  25. int led_high_count = LED_HIGH_COUNT_DEFAULT;
  26. int led_low_count = LED_LOW_COUNT_DEFAULT;
  27. static int led_count = 0;
  28. #endif
  29. #if 0
  30. static void lstop (lua_State *L, lua_Debug *ar) {
  31. (void)ar; /* unused arg. */
  32. lua_sethook(L, NULL, 0, 0);
  33. luaL_error(L, "interrupted!");
  34. }
  35. static void laction (int i) {
  36. // signal(i, SIG_DFL);
  37. /* if another SIGINT happens before lstop,
  38. terminate process (default action) */
  39. lua_sethook(globalL, lstop, LUA_MASKCALL | LUA_MASKRET | LUA_MASKCOUNT, 1);
  40. }
  41. static void print_usage (void) {
  42. #if defined(LUA_USE_STDIO)
  43. c_fprintf(c_stderr,
  44. #else
  45. luai_writestringerror(
  46. #endif
  47. "usage: %s [options] [script [args]].\n"
  48. "Available options are:\n"
  49. " -e stat execute string " LUA_QL("stat") "\n"
  50. " -l name require library " LUA_QL("name") "\n"
  51. " -m limit set memory limit. (units are in Kbytes)\n"
  52. " -i enter interactive mode after executing " LUA_QL("script") "\n"
  53. " -v show version information\n"
  54. " -- stop handling options\n"
  55. " - execute stdin and stop handling options\n"
  56. ,
  57. progname);
  58. #if defined(LUA_USE_STDIO)
  59. c_fflush(c_stderr);
  60. #endif
  61. }
  62. #endif
  63. static void l_message (const char *pname, const char *msg) {
  64. #if defined(LUA_USE_STDIO)
  65. if (pname) c_fprintf(c_stderr, "%s: ", pname);
  66. c_fprintf(c_stderr, "%s\n", msg);
  67. c_fflush(c_stderr);
  68. #else
  69. if (pname) luai_writestringerror("%s: ", pname);
  70. luai_writestringerror("%s\n", msg);
  71. #endif
  72. }
  73. static int report (lua_State *L, int status) {
  74. if (status && !lua_isnil(L, -1)) {
  75. const char *msg = lua_tostring(L, -1);
  76. if (msg == NULL) msg = "(error object is not a string)";
  77. l_message(progname, msg);
  78. lua_pop(L, 1);
  79. }
  80. return status;
  81. }
  82. static int traceback (lua_State *L) {
  83. if (!lua_isstring(L, 1)) /* 'message' not a string? */
  84. return 1; /* keep it intact */
  85. lua_getfield(L, LUA_GLOBALSINDEX, "debug");
  86. if (!lua_istable(L, -1) && !lua_isrotable(L, -1)) {
  87. lua_pop(L, 1);
  88. return 1;
  89. }
  90. lua_getfield(L, -1, "traceback");
  91. if (!lua_isfunction(L, -1) && !lua_islightfunction(L, -1)) {
  92. lua_pop(L, 2);
  93. return 1;
  94. }
  95. lua_pushvalue(L, 1); /* pass error message */
  96. lua_pushinteger(L, 2); /* skip this function and traceback */
  97. lua_call(L, 2, 1); /* call debug.traceback */
  98. return 1;
  99. }
  100. static int docall (lua_State *L, int narg, int clear) {
  101. int status;
  102. int base = lua_gettop(L) - narg; /* function index */
  103. lua_pushcfunction(L, traceback); /* push traceback function */
  104. lua_insert(L, base); /* put it under chunk and args */
  105. // signal(SIGINT, laction);
  106. status = lua_pcall(L, narg, (clear ? 0 : LUA_MULTRET), base);
  107. // signal(SIGINT, SIG_DFL);
  108. lua_remove(L, base); /* remove traceback function */
  109. /* force a complete garbage collection in case of errors */
  110. if (status != 0) lua_gc(L, LUA_GCCOLLECT, 0);
  111. return status;
  112. }
  113. static void print_version (void) {
  114. // l_message(NULL, LUA_RELEASE " " LUA_COPYRIGHT);
  115. l_message(NULL, "\n" NODE_VERSION " " BUILD_DATE " powered by " LUA_RELEASE);
  116. }
  117. static int getargs (lua_State *L, char **argv, int n) {
  118. int narg;
  119. int i;
  120. int argc = 0;
  121. while (argv[argc]) argc++; /* count total number of arguments */
  122. narg = argc - (n + 1); /* number of arguments to the script */
  123. luaL_checkstack(L, narg + 3, "too many arguments to script");
  124. for (i=n+1; i < argc; i++)
  125. lua_pushstring(L, argv[i]);
  126. lua_createtable(L, narg, n + 1);
  127. for (i=0; i < argc; i++) {
  128. lua_pushstring(L, argv[i]);
  129. lua_rawseti(L, -2, i - n);
  130. }
  131. return narg;
  132. }
  133. #if 0
  134. static int dofile (lua_State *L, const char *name) {
  135. int status = luaL_loadfile(L, name) || docall(L, 0, 1);
  136. return report(L, status);
  137. }
  138. #else
  139. static int dofsfile (lua_State *L, const char *name) {
  140. int status = luaL_loadfsfile(L, name) || docall(L, 0, 1);
  141. return report(L, status);
  142. }
  143. #endif
  144. static int dostring (lua_State *L, const char *s, const char *name) {
  145. int status = luaL_loadbuffer(L, s, c_strlen(s), name) || docall(L, 0, 1);
  146. return report(L, status);
  147. }
  148. static int dolibrary (lua_State *L, const char *name) {
  149. lua_getglobal(L, "require");
  150. lua_pushstring(L, name);
  151. return report(L, docall(L, 1, 1));
  152. }
  153. static const char *get_prompt (lua_State *L, int firstline) {
  154. const char *p;
  155. lua_getfield(L, LUA_GLOBALSINDEX, firstline ? "_PROMPT" : "_PROMPT2");
  156. p = lua_tostring(L, -1);
  157. if (p == NULL) p = (firstline ? LUA_PROMPT : LUA_PROMPT2);
  158. lua_pop(L, 1); /* remove global */
  159. return p;
  160. }
  161. static int incomplete (lua_State *L, int status) {
  162. if (status == LUA_ERRSYNTAX) {
  163. size_t lmsg;
  164. const char *msg = lua_tolstring(L, -1, &lmsg);
  165. const char *tp = msg + lmsg - (sizeof(LUA_QL("<eof>")) - 1);
  166. if (c_strstr(msg, LUA_QL("<eof>")) == tp) {
  167. lua_pop(L, 1);
  168. return 1;
  169. }
  170. }
  171. return 0; /* else... */
  172. }
  173. #if 0
  174. static int pushline (lua_State *L, int firstline) {
  175. char buffer[LUA_MAXINPUT];
  176. char *b = buffer;
  177. size_t l;
  178. const char *prmt = get_prompt(L, firstline);
  179. if (lua_readline(L, b, prmt) == 0)
  180. return 0; /* no input */
  181. l = c_strlen(b);
  182. if (l > 0 && b[l-1] == '\n') /* line ends with newline? */
  183. b[l-1] = '\0'; /* remove it */
  184. if (firstline && b[0] == '=') /* first line starts with `=' ? */
  185. lua_pushfstring(L, "return %s", b+1); /* change it to `return' */
  186. else
  187. lua_pushstring(L, b);
  188. lua_freeline(L, b);
  189. return 1;
  190. }
  191. static int loadline (lua_State *L) {
  192. int status;
  193. lua_settop(L, 0);
  194. if (!pushline(L, 1))
  195. return -1; /* no input */
  196. for (;;) { /* repeat until gets a complete line */
  197. status = luaL_loadbuffer(L, lua_tostring(L, 1), lua_strlen(L, 1), "=stdin");
  198. if (!incomplete(L, status)) break; /* cannot try to add lines? */
  199. if (!pushline(L, 0)) /* no more input? */
  200. return -1;
  201. lua_pushliteral(L, "\n"); /* add a new line... */
  202. lua_insert(L, -2); /* ...between the two lines */
  203. lua_concat(L, 3); /* join them */
  204. }
  205. lua_saveline(L, 1);
  206. lua_remove(L, 1); /* remove line */
  207. return status;
  208. }
  209. static void dotty (lua_State *L) {
  210. int status;
  211. const char *oldprogname = progname;
  212. progname = NULL;
  213. while ((status = loadline(L)) != -1) {
  214. if (status == 0) status = docall(L, 0, 0);
  215. report(L, status);
  216. if (status == 0 && lua_gettop(L) > 0) { /* any result to print? */
  217. lua_getglobal(L, "print");
  218. lua_insert(L, 1);
  219. if (lua_pcall(L, lua_gettop(L)-1, 0, 0) != 0)
  220. l_message(progname, lua_pushfstring(L,
  221. "error calling " LUA_QL("print") " (%s)",
  222. lua_tostring(L, -1)));
  223. }
  224. }
  225. lua_settop(L, 0); /* clear stack */
  226. #if defined(LUA_USE_STDIO)
  227. c_fputs("\n", c_stdout);
  228. c_fflush(c_stdout);
  229. #else
  230. luai_writeline();
  231. #endif
  232. progname = oldprogname;
  233. }
  234. static int handle_script (lua_State *L, char **argv, int n) {
  235. int status;
  236. const char *fname;
  237. int narg = getargs(L, argv, n); /* collect arguments */
  238. lua_setglobal(L, "arg");
  239. fname = argv[n];
  240. if (c_strcmp(fname, "-") == 0 && c_strcmp(argv[n-1], "--") != 0)
  241. fname = NULL; /* stdin */
  242. status = luaL_loadfile(L, fname);
  243. lua_insert(L, -(narg+1));
  244. if (status == 0)
  245. status = docall(L, narg, 0);
  246. else
  247. lua_pop(L, narg);
  248. return report(L, status);
  249. }
  250. #endif
  251. /* check that argument has no extra characters at the end */
  252. #define notail(x) {if ((x)[2] != '\0') return -1;}
  253. static int collectargs (char **argv, int *pi, int *pv, int *pe) {
  254. int i;
  255. for (i = 1; argv[i] != NULL; i++) {
  256. if (argv[i][0] != '-') /* not an option? */
  257. return i;
  258. switch (argv[i][1]) { /* option */
  259. case '-':
  260. notail(argv[i]);
  261. return (argv[i+1] != NULL ? i+1 : 0);
  262. case '\0':
  263. return i;
  264. case 'i':
  265. notail(argv[i]);
  266. *pi = 1; /* go through */
  267. case 'v':
  268. notail(argv[i]);
  269. *pv = 1;
  270. break;
  271. case 'e':
  272. *pe = 1; /* go through */
  273. case 'm': /* go through */
  274. case 'l':
  275. if (argv[i][2] == '\0') {
  276. i++;
  277. if (argv[i] == NULL) return -1;
  278. }
  279. break;
  280. default: return -1; /* invalid option */
  281. }
  282. }
  283. return 0;
  284. }
  285. static int runargs (lua_State *L, char **argv, int n) {
  286. int i;
  287. for (i = 1; i < n; i++) {
  288. if (argv[i] == NULL) continue;
  289. lua_assert(argv[i][0] == '-');
  290. switch (argv[i][1]) { /* option */
  291. case 'e': {
  292. const char *chunk = argv[i] + 2;
  293. if (*chunk == '\0') chunk = argv[++i];
  294. lua_assert(chunk != NULL);
  295. if (dostring(L, chunk, "=(command line)") != 0)
  296. return 1;
  297. break;
  298. }
  299. case 'm': {
  300. const char *limit = argv[i] + 2;
  301. int memlimit=0;
  302. if (*limit == '\0') limit = argv[++i];
  303. lua_assert(limit != NULL);
  304. memlimit = c_atoi(limit);
  305. lua_gc(L, LUA_GCSETMEMLIMIT, memlimit);
  306. break;
  307. }
  308. case 'l': {
  309. const char *filename = argv[i] + 2;
  310. if (*filename == '\0') filename = argv[++i];
  311. lua_assert(filename != NULL);
  312. if (dolibrary(L, filename))
  313. return 1; /* stop if file fails */
  314. break;
  315. }
  316. default: break;
  317. }
  318. }
  319. return 0;
  320. }
  321. static int handle_luainit (lua_State *L) {
  322. const char *init = c_getenv(LUA_INIT);
  323. if (init == NULL) return 0; /* status OK */
  324. else if (init[0] == '@')
  325. #if 0
  326. return dofile(L, init+1);
  327. #else
  328. return dofsfile(L, init+1);
  329. #endif
  330. else
  331. return dostring(L, init, "=" LUA_INIT);
  332. }
  333. struct Smain {
  334. int argc;
  335. char **argv;
  336. int status;
  337. };
  338. static int pmain (lua_State *L) {
  339. struct Smain *s = (struct Smain *)lua_touserdata(L, 1);
  340. char **argv = s->argv;
  341. int script;
  342. int has_i = 0, has_v = 0, has_e = 0;
  343. globalL = L;
  344. if (argv[0] && argv[0][0]) progname = argv[0];
  345. lua_gc(L, LUA_GCSTOP, 0); /* stop collector during initialization */
  346. luaL_openlibs(L); /* open libraries */
  347. lua_gc(L, LUA_GCRESTART, 0);
  348. print_version();
  349. s->status = handle_luainit(L);
  350. #if 0
  351. if (s->status != 0) return 0;
  352. #endif
  353. script = collectargs(argv, &has_i, &has_v, &has_e);
  354. if (script < 0) { /* invalid args? */
  355. #if 0
  356. print_usage();
  357. #endif
  358. s->status = 1;
  359. return 0;
  360. }
  361. // if (has_v) print_version();
  362. s->status = runargs(L, argv, (script > 0) ? script : s->argc);
  363. if (s->status != 0) return 0;
  364. #if 0
  365. if (script)
  366. s->status = handle_script(L, argv, script);
  367. if (s->status != 0) return 0;
  368. if (has_i)
  369. dotty(L);
  370. else if (script == 0 && !has_e && !has_v) {
  371. if (lua_stdin_is_tty()) {
  372. print_version();
  373. dotty(L);
  374. }
  375. else dofile(L, NULL); /* executes stdin as a file */
  376. }
  377. #endif
  378. return 0;
  379. }
  380. void dojob(lua_Load *load);
  381. void readline(lua_Load *load);
  382. char line_buffer[LUA_MAXINPUT];
  383. #ifdef LUA_RPC
  384. int main (int argc, char **argv) {
  385. #else
  386. int lua_main (int argc, char **argv) {
  387. #endif
  388. int status;
  389. struct Smain s;
  390. lua_State *L = lua_open(); /* create state */
  391. if (L == NULL) {
  392. l_message(argv[0], "cannot create state: not enough memory");
  393. return EXIT_FAILURE;
  394. }
  395. s.argc = argc;
  396. s.argv = argv;
  397. status = lua_cpcall(L, &pmain, &s);
  398. report(L, status);
  399. gLoad.L = L;
  400. gLoad.firstline = 1;
  401. gLoad.done = 0;
  402. gLoad.line = line_buffer;
  403. gLoad.len = LUA_MAXINPUT;
  404. gLoad.line_position = 0;
  405. gLoad.prmt = get_prompt(L, 1);
  406. // dojob(&gLoad);
  407. os_timer_disarm(&lua_timer);
  408. os_timer_setfn(&lua_timer, (os_timer_func_t *)dojob, &gLoad);
  409. os_timer_arm(&lua_timer, READLINE_INTERVAL, 0); // no repeat
  410. NODE_DBG("Heap size::%d.\n",system_get_free_heap_size());
  411. legc_set_mode( L, EGC_ALWAYS, 4096 );
  412. // legc_set_mode( L, EGC_ON_MEM_LIMIT, 4096 );
  413. // lua_close(L);
  414. return (status || s.status) ? EXIT_FAILURE : EXIT_SUCCESS;
  415. }
  416. void donejob(lua_Load *load){
  417. lua_close(load->L);
  418. }
  419. #if 0
  420. int log_fd = -1;
  421. int noparse = 0;
  422. #endif
  423. void dojob(lua_Load *load){
  424. size_t l, rs;
  425. int status;
  426. char *b = load->line;
  427. lua_State *L = load->L;
  428. const char *oldprogname = progname;
  429. progname = NULL;
  430. do{
  431. if(load->done == 1){
  432. l = c_strlen(b);
  433. if (l > 0 && b[l-1] == '\n') /* line ends with newline? */
  434. b[l-1] = '\0'; /* remove it */
  435. if (load->firstline && b[0] == '=') /* first line starts with `=' ? */
  436. lua_pushfstring(L, "return %s", b+1); /* change it to `return' */
  437. else
  438. lua_pushstring(L, b);
  439. if(load->firstline != 1){
  440. lua_pushliteral(L, "\n"); /* add a new line... */
  441. lua_insert(L, -2); /* ...between the two lines */
  442. lua_concat(L, 3); /* join them */
  443. }
  444. status = luaL_loadbuffer(L, lua_tostring(L, 1), lua_strlen(L, 1), "=stdin");
  445. if (!incomplete(L, status)) { /* cannot try to add lines? */
  446. lua_remove(L, 1); /* remove line */
  447. if (status == 0) {
  448. status = docall(L, 0, 0);
  449. }
  450. report(L, status);
  451. if (status == 0 && lua_gettop(L) > 0) { /* any result to print? */
  452. lua_getglobal(L, "print");
  453. lua_insert(L, 1);
  454. if (lua_pcall(L, lua_gettop(L)-1, 0, 0) != 0)
  455. l_message(progname, lua_pushfstring(L,
  456. "error calling " LUA_QL("print") " (%s)",
  457. lua_tostring(L, -1)));
  458. }
  459. load->firstline = 1;
  460. load->prmt = get_prompt(L, 1);
  461. lua_settop(L, 0);
  462. /* force a complete garbage collection in case of errors */
  463. if (status != 0) lua_gc(L, LUA_GCCOLLECT, 0);
  464. } else {
  465. load->firstline = 0;
  466. load->prmt = get_prompt(L, 0);
  467. }
  468. }
  469. }while(0);
  470. progname = oldprogname;
  471. load->done = 0;
  472. load->line_position = 0;
  473. c_memset(load->line, 0, load->len);
  474. os_timer_disarm(&readline_timer);
  475. os_timer_setfn(&readline_timer, (os_timer_func_t *)readline, load);
  476. os_timer_arm(&readline_timer, READLINE_INTERVAL, 0); // no repeat
  477. c_puts(load->prmt);
  478. // NODE_DBG("dojob() is called with firstline.\n");
  479. }
  480. #ifdef DEVKIT_VERSION_0_9
  481. extern void key_long_press(void *arg);
  482. extern void key_short_press(void *arg);
  483. static bool key_short_pressed = false;
  484. static bool key_long_pressed = false;
  485. void update_key_led(){
  486. uint8_t temp = 1, level = 1;
  487. led_count++;
  488. if(led_count>led_low_count+led_high_count){
  489. led_count = 0; // reset led_count, the level still high
  490. } else if(led_count>led_low_count && led_count <=led_high_count+led_low_count){
  491. level = 1; // output high level
  492. } else if(led_count<=led_low_count){
  493. level = 0; // output low level
  494. }
  495. temp = platform_key_led(level);
  496. if(temp == 0){ // key is pressed
  497. key_press_count++;
  498. if(key_press_count>=KEY_LONG_COUNT){
  499. // key_long_press(NULL);
  500. key_long_pressed = true;
  501. key_short_pressed = false;
  502. // key_press_count = 0;
  503. } else if(key_press_count>=KEY_SHORT_COUNT){ // < KEY_LONG_COUNT
  504. // key_short_press(NULL);
  505. key_short_pressed = true;
  506. }
  507. }else{ // key is released
  508. key_press_count = 0;
  509. if(key_long_pressed){
  510. key_long_press(NULL);
  511. key_long_pressed = false;
  512. }
  513. if(key_short_pressed){
  514. key_short_press(NULL);
  515. key_short_pressed = false;
  516. }
  517. }
  518. }
  519. #endif
  520. #ifndef uart_putc
  521. #define uart_putc uart0_putc
  522. #endif
  523. extern bool uart_on_data_cb(const char *buf, size_t len);
  524. extern bool uart0_echo;
  525. extern bool run_input;
  526. extern uint16_t need_len;
  527. extern int16_t end_char;
  528. void readline(lua_Load *load){
  529. // NODE_DBG("readline() is called.\n");
  530. #ifdef DEVKIT_VERSION_0_9
  531. update_key_led();
  532. #endif
  533. char ch;
  534. while (uart_getc(&ch))
  535. {
  536. if(run_input)
  537. {
  538. /* handle CR key */
  539. if (ch == '\r')
  540. {
  541. char next;
  542. if (uart_getc(&next))
  543. ch = next;
  544. }
  545. /* backspace key */
  546. else if (ch == 0x7f || ch == 0x08)
  547. {
  548. if (load->line_position > 0)
  549. {
  550. if(uart0_echo) uart_putc(0x08);
  551. if(uart0_echo) uart_putc(' ');
  552. if(uart0_echo) uart_putc(0x08);
  553. load->line_position--;
  554. }
  555. load->line[load->line_position] = 0;
  556. continue;
  557. }
  558. /* EOT(ctrl+d) */
  559. // else if (ch == 0x04)
  560. // {
  561. // if (load->line_position == 0)
  562. // // No input which makes lua interpreter close
  563. // donejob(load);
  564. // else
  565. // continue;
  566. // }
  567. /* end of line */
  568. if (ch == '\r' || ch == '\n')
  569. {
  570. load->line[load->line_position] = 0;
  571. if(uart0_echo) uart_putc('\n');
  572. uart_on_data_cb(load->line, load->line_position);
  573. if (load->line_position == 0)
  574. {
  575. /* Get a empty line, then go to get a new line */
  576. c_puts(load->prmt);
  577. os_timer_disarm(&readline_timer);
  578. os_timer_setfn(&readline_timer, (os_timer_func_t *)readline, load);
  579. os_timer_arm(&readline_timer, READLINE_INTERVAL, 0); // no repeat
  580. } else {
  581. load->done = 1;
  582. os_timer_disarm(&lua_timer);
  583. os_timer_setfn(&lua_timer, (os_timer_func_t *)dojob, load);
  584. os_timer_arm(&lua_timer, READLINE_INTERVAL, 0); // no repeat
  585. }
  586. continue;
  587. }
  588. /* other control character or not an acsii character */
  589. // if (ch < 0x20 || ch >= 0x80)
  590. // {
  591. // continue;
  592. // }
  593. /* echo */
  594. if(uart0_echo) uart_putc(ch);
  595. /* it's a large line, discard it */
  596. if ( load->line_position + 1 >= load->len ){
  597. load->line_position = 0;
  598. }
  599. }
  600. load->line[load->line_position] = ch;
  601. load->line_position++;
  602. if(!run_input)
  603. {
  604. if( ((need_len!=0) && (load->line_position >= need_len)) || \
  605. (load->line_position >= load->len) || \
  606. ((end_char>=0) && ((unsigned char)ch==(unsigned char)end_char)) )
  607. {
  608. uart_on_data_cb(load->line, load->line_position);
  609. load->line_position = 0;
  610. }
  611. }
  612. ch = 0;
  613. }
  614. if( (load->line_position > 0) && (!run_input) && (need_len==0) && (end_char<0) )
  615. {
  616. uart_on_data_cb(load->line, load->line_position);
  617. load->line_position = 0;
  618. }
  619. // if there is no input from user, repeat readline()
  620. os_timer_disarm(&readline_timer);
  621. os_timer_setfn(&readline_timer, (os_timer_func_t *)readline, load);
  622. os_timer_arm(&readline_timer, READLINE_INTERVAL, 0); // no repeat
  623. }