read.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558
  1. /* $NetBSD: read.c,v 1.21 2002/03/18 16:00:57 christos Exp $ */
  2. /*-
  3. * Copyright (c) 1992, 1993
  4. * The Regents of the University of California. All rights reserved.
  5. *
  6. * This code is derived from software contributed to Berkeley by
  7. * Christos Zoulas of Cornell University.
  8. *
  9. * Redistribution and use in source and binary forms, with or without
  10. * modification, are permitted provided that the following conditions
  11. * are met:
  12. * 1. Redistributions of source code must retain the above copyright
  13. * notice, this list of conditions and the following disclaimer.
  14. * 2. Redistributions in binary form must reproduce the above copyright
  15. * notice, this list of conditions and the following disclaimer in the
  16. * documentation and/or other materials provided with the distribution.
  17. * 3. All advertising materials mentioning features or use of this software
  18. * must display the following acknowledgement:
  19. * This product includes software developed by the University of
  20. * California, Berkeley and its contributors.
  21. * 4. Neither the name of the University nor the names of its contributors
  22. * may be used to endorse or promote products derived from this software
  23. * without specific prior written permission.
  24. *
  25. * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  26. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  27. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  28. * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  29. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  30. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  31. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  32. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  33. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  34. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  35. * SUCH DAMAGE.
  36. */
  37. #include "config.h"
  38. #if !defined(lint) && !defined(SCCSID)
  39. #if 0
  40. static char sccsid[] = "@(#)read.c 8.1 (Berkeley) 6/4/93";
  41. #else
  42. __RCSID("$NetBSD: read.c,v 1.21 2002/03/18 16:00:57 christos Exp $");
  43. #endif
  44. #endif /* not lint && not SCCSID */
  45. /*
  46. * read.c: Clean this junk up! This is horrible code.
  47. * Terminal read functions
  48. */
  49. #include <errno.h>
  50. #include <unistd.h>
  51. #include <stdlib.h>
  52. #include "el.h"
  53. #define OKCMD -1
  54. private int read__fixio(int, int);
  55. private int read_preread(EditLine *);
  56. private int read_char(EditLine *, char *);
  57. private int read_getcmd(EditLine *, el_action_t *, char *);
  58. /* read_init():
  59. * Initialize the read stuff
  60. */
  61. protected int
  62. read_init(EditLine *el)
  63. {
  64. /* builtin read_char */
  65. el->el_read.read_char = read_char;
  66. return 0;
  67. }
  68. /* el_read_setfn():
  69. * Set the read char function to the one provided.
  70. * If it is set to EL_BUILTIN_GETCFN, then reset to the builtin one.
  71. */
  72. protected int
  73. el_read_setfn(EditLine *el, el_rfunc_t rc)
  74. {
  75. el->el_read.read_char = (rc == EL_BUILTIN_GETCFN) ? read_char : rc;
  76. return 0;
  77. }
  78. /* el_read_getfn():
  79. * return the current read char function, or EL_BUILTIN_GETCFN
  80. * if it is the default one
  81. */
  82. protected el_rfunc_t
  83. el_read_getfn(EditLine *el)
  84. {
  85. return (el->el_read.read_char == read_char) ?
  86. EL_BUILTIN_GETCFN : el->el_read.read_char;
  87. }
  88. #ifdef DEBUG_EDIT
  89. private void
  90. read_debug(EditLine *el)
  91. {
  92. if (el->el_line.cursor > el->el_line.lastchar)
  93. (void) fprintf(el->el_errfile, "cursor > lastchar\r\n");
  94. if (el->el_line.cursor < el->el_line.buffer)
  95. (void) fprintf(el->el_errfile, "cursor < buffer\r\n");
  96. if (el->el_line.cursor > el->el_line.limit)
  97. (void) fprintf(el->el_errfile, "cursor > limit\r\n");
  98. if (el->el_line.lastchar > el->el_line.limit)
  99. (void) fprintf(el->el_errfile, "lastchar > limit\r\n");
  100. if (el->el_line.limit != &el->el_line.buffer[EL_BUFSIZ - 2])
  101. (void) fprintf(el->el_errfile, "limit != &buffer[EL_BUFSIZ-2]\r\n");
  102. }
  103. #endif /* DEBUG_EDIT */
  104. /* read__fixio():
  105. * Try to recover from a read error
  106. */
  107. /* ARGSUSED */
  108. private int
  109. read__fixio(int fd, int e)
  110. {
  111. switch (e) {
  112. case -1: /* Make sure that the code is reachable */
  113. #ifdef EWOULDBLOCK
  114. case EWOULDBLOCK:
  115. #ifndef TRY_AGAIN
  116. #define TRY_AGAIN
  117. #endif
  118. #endif /* EWOULDBLOCK */
  119. #if defined(POSIX) && defined(EAGAIN)
  120. #if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN
  121. case EAGAIN:
  122. #ifndef TRY_AGAIN
  123. #define TRY_AGAIN
  124. #endif
  125. #endif /* EWOULDBLOCK && EWOULDBLOCK != EAGAIN */
  126. #endif /* POSIX && EAGAIN */
  127. e = 0;
  128. #ifdef TRY_AGAIN
  129. #if defined(F_SETFL) && defined(O_NDELAY)
  130. if ((e = fcntl(fd, F_GETFL, 0)) == -1)
  131. return (-1);
  132. if (fcntl(fd, F_SETFL, e & ~O_NDELAY) == -1)
  133. return (-1);
  134. else
  135. e = 1;
  136. #endif /* F_SETFL && O_NDELAY */
  137. #ifdef FIONBIO
  138. {
  139. int zero = 0;
  140. if (ioctl(fd, FIONBIO, (ioctl_t) & zero) == -1)
  141. return (-1);
  142. else
  143. e = 1;
  144. }
  145. #endif /* FIONBIO */
  146. #endif /* TRY_AGAIN */
  147. return (e ? 0 : -1);
  148. case EINTR:
  149. return (0);
  150. default:
  151. return (-1);
  152. }
  153. }
  154. /* read_preread():
  155. * Try to read the stuff in the input queue;
  156. */
  157. private int
  158. read_preread(EditLine *el)
  159. {
  160. int chrs = 0;
  161. if (el->el_chared.c_macro.nline) {
  162. el_free((ptr_t) el->el_chared.c_macro.nline);
  163. el->el_chared.c_macro.nline = NULL;
  164. }
  165. if (el->el_tty.t_mode == ED_IO)
  166. return (0);
  167. #ifdef FIONREAD
  168. (void) ioctl(el->el_infd, FIONREAD, (ioctl_t) & chrs);
  169. if (chrs > 0) {
  170. char buf[EL_BUFSIZ];
  171. chrs = read(el->el_infd, buf,
  172. (size_t) MIN(chrs, EL_BUFSIZ - 1));
  173. if (chrs > 0) {
  174. buf[chrs] = '\0';
  175. el->el_chared.c_macro.nline = strdup(buf);
  176. el_push(el, el->el_chared.c_macro.nline);
  177. }
  178. }
  179. #endif /* FIONREAD */
  180. return (chrs > 0);
  181. }
  182. /* el_push():
  183. * Push a macro
  184. */
  185. public void
  186. el_push(EditLine *el, char *str)
  187. {
  188. c_macro_t *ma = &el->el_chared.c_macro;
  189. if (str != NULL && ma->level + 1 < EL_MAXMACRO) {
  190. ma->level++;
  191. ma->macro[ma->level] = str;
  192. } else {
  193. term_beep(el);
  194. term__flush();
  195. }
  196. }
  197. /* read_getcmd():
  198. * Return next command from the input stream.
  199. */
  200. private int
  201. read_getcmd(EditLine *el, el_action_t *cmdnum, char *ch)
  202. {
  203. el_action_t cmd = ED_UNASSIGNED;
  204. int num;
  205. while (cmd == ED_UNASSIGNED || cmd == ED_SEQUENCE_LEAD_IN) {
  206. if ((num = el_getc(el, ch)) != 1) /* if EOF or error */
  207. return (num);
  208. #ifdef KANJI
  209. if ((*ch & 0200)) {
  210. el->el_state.metanext = 0;
  211. cmd = CcViMap[' '];
  212. break;
  213. } else
  214. #endif /* KANJI */
  215. if (el->el_state.metanext) {
  216. el->el_state.metanext = 0;
  217. *ch |= 0200;
  218. }
  219. cmd = el->el_map.current[(unsigned char) *ch];
  220. if (cmd == ED_SEQUENCE_LEAD_IN) {
  221. key_value_t val;
  222. switch (key_get(el, ch, &val)) {
  223. case XK_CMD:
  224. cmd = val.cmd;
  225. break;
  226. case XK_STR:
  227. el_push(el, val.str);
  228. break;
  229. #ifdef notyet
  230. case XK_EXE:
  231. /* XXX: In the future to run a user function */
  232. RunCommand(val.str);
  233. break;
  234. #endif
  235. default:
  236. EL_ABORT((el->el_errfile, "Bad XK_ type \n"));
  237. break;
  238. }
  239. }
  240. if (el->el_map.alt == NULL)
  241. el->el_map.current = el->el_map.key;
  242. }
  243. *cmdnum = cmd;
  244. return (OKCMD);
  245. }
  246. /* read_char():
  247. * Read a character from the tty.
  248. * XXX This routine is the default, but what you are actually looking for
  249. * is in main/asterisk.c, in ast_el_read_char(). XXX
  250. */
  251. private int
  252. read_char(EditLine *el, char *cp)
  253. {
  254. int num_read;
  255. int tried = 0;
  256. while ((num_read = read(el->el_infd, cp, 1)) == -1)
  257. if (!tried && read__fixio(el->el_infd, errno) == 0)
  258. tried = 1;
  259. else {
  260. *cp = '\0';
  261. return (-1);
  262. }
  263. return (num_read);
  264. }
  265. /* el_getc():
  266. * Read a character
  267. */
  268. public int
  269. el_getc(EditLine *el, char *cp)
  270. {
  271. int num_read;
  272. c_macro_t *ma = &el->el_chared.c_macro;
  273. term__flush();
  274. for (;;) {
  275. if (ma->level < 0) {
  276. if (!read_preread(el))
  277. break;
  278. }
  279. if (ma->level < 0)
  280. break;
  281. if (*ma->macro[ma->level] == 0) {
  282. ma->level--;
  283. continue;
  284. }
  285. *cp = *ma->macro[ma->level]++ & 0377;
  286. if (*ma->macro[ma->level] == 0) { /* Needed for QuoteMode
  287. * On */
  288. ma->level--;
  289. }
  290. return (1);
  291. }
  292. #ifdef DEBUG_READ
  293. (void) fprintf(el->el_errfile, "Turning raw mode on\n");
  294. #endif /* DEBUG_READ */
  295. if (tty_rawmode(el) < 0)/* make sure the tty is set up correctly */
  296. return (0);
  297. #ifdef DEBUG_READ
  298. (void) fprintf(el->el_errfile, "Reading a character\n");
  299. #endif /* DEBUG_READ */
  300. /* See main/asterisk.c: ast_el_read_char() */
  301. num_read = (*el->el_read.read_char)(el, cp);
  302. #ifdef DEBUG_READ
  303. (void) fprintf(el->el_errfile, "Got it %c\n", *cp);
  304. #endif /* DEBUG_READ */
  305. return (num_read);
  306. }
  307. public const char *
  308. el_gets(EditLine *el, int *nread)
  309. {
  310. int retval;
  311. el_action_t cmdnum = 0;
  312. int num; /* how many chars we have read at NL */
  313. char ch;
  314. #ifdef FIONREAD
  315. c_macro_t *ma = &el->el_chared.c_macro;
  316. #endif /* FIONREAD */
  317. if (el->el_flags & HANDLE_SIGNALS)
  318. sig_set(el);
  319. if (el->el_flags & NO_TTY) {
  320. char *cp = el->el_line.buffer;
  321. size_t idx;
  322. while ((*el->el_read.read_char)(el, cp) == 1) {
  323. /* make sure there is space for next character */
  324. if (cp + 1 >= el->el_line.limit) {
  325. idx = (cp - el->el_line.buffer);
  326. if (!ch_enlargebufs(el, 2))
  327. break;
  328. cp = &el->el_line.buffer[idx];
  329. }
  330. cp++;
  331. if (cp[-1] == '\r' || cp[-1] == '\n')
  332. break;
  333. }
  334. el->el_line.cursor = el->el_line.lastchar = cp;
  335. *cp = '\0';
  336. if (nread)
  337. *nread = el->el_line.cursor - el->el_line.buffer;
  338. return (el->el_line.buffer);
  339. }
  340. re_clear_display(el); /* reset the display stuff */
  341. ch_reset(el);
  342. #ifdef FIONREAD
  343. if (el->el_tty.t_mode == EX_IO && ma->level < 0) {
  344. long chrs = 0;
  345. (void) ioctl(el->el_infd, FIONREAD, (ioctl_t) & chrs);
  346. if (chrs == 0) {
  347. if (tty_rawmode(el) < 0) {
  348. if (nread)
  349. *nread = 0;
  350. return (NULL);
  351. }
  352. }
  353. }
  354. #endif /* FIONREAD */
  355. re_refresh(el); /* print the prompt */
  356. if (el->el_flags & EDIT_DISABLED) {
  357. char *cp = el->el_line.buffer;
  358. size_t idx;
  359. term__flush();
  360. while ((*el->el_read.read_char)(el, cp) == 1) {
  361. /* make sure there is space next character */
  362. if (cp + 1 >= el->el_line.limit) {
  363. idx = (cp - el->el_line.buffer);
  364. if (!ch_enlargebufs(el, 2))
  365. break;
  366. cp = &el->el_line.buffer[idx];
  367. }
  368. cp++;
  369. if (cp[-1] == '\r' || cp[-1] == '\n')
  370. break;
  371. }
  372. el->el_line.cursor = el->el_line.lastchar = cp;
  373. *cp = '\0';
  374. if (nread)
  375. *nread = el->el_line.cursor - el->el_line.buffer;
  376. return (el->el_line.buffer);
  377. }
  378. for (num = OKCMD; num == OKCMD;) { /* while still editing this
  379. * line */
  380. #ifdef DEBUG_EDIT
  381. read_debug(el);
  382. #endif /* DEBUG_EDIT */
  383. /* if EOF or error */
  384. if ((num = read_getcmd(el, &cmdnum, &ch)) != OKCMD) {
  385. #ifdef DEBUG_READ
  386. (void) fprintf(el->el_errfile,
  387. "Returning from el_gets %d\n", num);
  388. #endif /* DEBUG_READ */
  389. break;
  390. }
  391. if ((int) cmdnum >= el->el_map.nfunc) { /* BUG CHECK command */
  392. #ifdef DEBUG_EDIT
  393. (void) fprintf(el->el_errfile,
  394. "ERROR: illegal command from key 0%o\r\n", ch);
  395. #endif /* DEBUG_EDIT */
  396. continue; /* try again */
  397. }
  398. /* now do the real command */
  399. #ifdef DEBUG_READ
  400. {
  401. el_bindings_t *b;
  402. for (b = el->el_map.help; b->name; b++)
  403. if (b->func == cmdnum)
  404. break;
  405. if (b->name)
  406. (void) fprintf(el->el_errfile,
  407. "Executing %s\n", b->name);
  408. else
  409. (void) fprintf(el->el_errfile,
  410. "Error command = %d\n", cmdnum);
  411. }
  412. #endif /* DEBUG_READ */
  413. retval = (*el->el_map.func[cmdnum]) (el, ch);
  414. /* save the last command here */
  415. el->el_state.lastcmd = cmdnum;
  416. /* use any return value */
  417. switch (retval) {
  418. case CC_CURSOR:
  419. el->el_state.argument = 1;
  420. el->el_state.doingarg = 0;
  421. re_refresh_cursor(el);
  422. break;
  423. case CC_REDISPLAY:
  424. re_clear_lines(el);
  425. re_clear_display(el);
  426. /* FALLTHROUGH */
  427. case CC_REFRESH:
  428. el->el_state.argument = 1;
  429. el->el_state.doingarg = 0;
  430. re_refresh(el);
  431. break;
  432. case CC_REFRESH_BEEP:
  433. el->el_state.argument = 1;
  434. el->el_state.doingarg = 0;
  435. re_refresh(el);
  436. term_beep(el);
  437. break;
  438. case CC_NORM: /* normal char */
  439. el->el_state.argument = 1;
  440. el->el_state.doingarg = 0;
  441. break;
  442. case CC_ARGHACK: /* Suggested by Rich Salz */
  443. /* <rsalz@pineapple.bbn.com> */
  444. break; /* keep going... */
  445. case CC_EOF: /* end of file typed */
  446. num = 0;
  447. break;
  448. case CC_NEWLINE: /* normal end of line */
  449. num = el->el_line.lastchar - el->el_line.buffer;
  450. break;
  451. case CC_FATAL: /* fatal error, reset to known state */
  452. #ifdef DEBUG_READ
  453. (void) fprintf(el->el_errfile,
  454. "*** editor fatal ERROR ***\r\n\n");
  455. #endif /* DEBUG_READ */
  456. /* put (real) cursor in a known place */
  457. re_clear_display(el); /* reset the display stuff */
  458. ch_reset(el); /* reset the input pointers */
  459. re_refresh(el); /* print the prompt again */
  460. el->el_state.argument = 1;
  461. el->el_state.doingarg = 0;
  462. break;
  463. case CC_ERROR:
  464. default: /* functions we don't know about */
  465. #ifdef DEBUG_READ
  466. (void) fprintf(el->el_errfile,
  467. "*** editor ERROR ***\r\n\n");
  468. #endif /* DEBUG_READ */
  469. el->el_state.argument = 1;
  470. el->el_state.doingarg = 0;
  471. term_beep(el);
  472. term__flush();
  473. break;
  474. }
  475. }
  476. /* make sure the tty is set up correctly */
  477. (void) tty_cookedmode(el);
  478. term__flush(); /* flush any buffered output */
  479. if (el->el_flags & HANDLE_SIGNALS)
  480. sig_clr(el);
  481. if (nread)
  482. *nread = num;
  483. return (num ? el->el_line.buffer : NULL);
  484. }