read.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556
  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. */
  249. private int
  250. read_char(EditLine *el, char *cp)
  251. {
  252. int num_read;
  253. int tried = 0;
  254. while ((num_read = read(el->el_infd, cp, 1)) == -1)
  255. if (!tried && read__fixio(el->el_infd, errno) == 0)
  256. tried = 1;
  257. else {
  258. *cp = '\0';
  259. return (-1);
  260. }
  261. return (num_read);
  262. }
  263. /* el_getc():
  264. * Read a character
  265. */
  266. public int
  267. el_getc(EditLine *el, char *cp)
  268. {
  269. int num_read;
  270. c_macro_t *ma = &el->el_chared.c_macro;
  271. term__flush();
  272. for (;;) {
  273. if (ma->level < 0) {
  274. if (!read_preread(el))
  275. break;
  276. }
  277. if (ma->level < 0)
  278. break;
  279. if (*ma->macro[ma->level] == 0) {
  280. ma->level--;
  281. continue;
  282. }
  283. *cp = *ma->macro[ma->level]++ & 0377;
  284. if (*ma->macro[ma->level] == 0) { /* Needed for QuoteMode
  285. * On */
  286. ma->level--;
  287. }
  288. return (1);
  289. }
  290. #ifdef DEBUG_READ
  291. (void) fprintf(el->el_errfile, "Turning raw mode on\n");
  292. #endif /* DEBUG_READ */
  293. if (tty_rawmode(el) < 0)/* make sure the tty is set up correctly */
  294. return (0);
  295. #ifdef DEBUG_READ
  296. (void) fprintf(el->el_errfile, "Reading a character\n");
  297. #endif /* DEBUG_READ */
  298. num_read = (*el->el_read.read_char)(el, cp);
  299. #ifdef DEBUG_READ
  300. (void) fprintf(el->el_errfile, "Got it %c\n", *cp);
  301. #endif /* DEBUG_READ */
  302. return (num_read);
  303. }
  304. public const char *
  305. el_gets(EditLine *el, int *nread)
  306. {
  307. int retval;
  308. el_action_t cmdnum = 0;
  309. int num; /* how many chars we have read at NL */
  310. char ch;
  311. #ifdef FIONREAD
  312. c_macro_t *ma = &el->el_chared.c_macro;
  313. #endif /* FIONREAD */
  314. if (el->el_flags & HANDLE_SIGNALS)
  315. sig_set(el);
  316. if (el->el_flags & NO_TTY) {
  317. char *cp = el->el_line.buffer;
  318. size_t idx;
  319. while ((*el->el_read.read_char)(el, cp) == 1) {
  320. /* make sure there is space for next character */
  321. if (cp + 1 >= el->el_line.limit) {
  322. idx = (cp - el->el_line.buffer);
  323. if (!ch_enlargebufs(el, 2))
  324. break;
  325. cp = &el->el_line.buffer[idx];
  326. }
  327. cp++;
  328. if (cp[-1] == '\r' || cp[-1] == '\n')
  329. break;
  330. }
  331. el->el_line.cursor = el->el_line.lastchar = cp;
  332. *cp = '\0';
  333. if (nread)
  334. *nread = el->el_line.cursor - el->el_line.buffer;
  335. return (el->el_line.buffer);
  336. }
  337. re_clear_display(el); /* reset the display stuff */
  338. ch_reset(el);
  339. #ifdef FIONREAD
  340. if (el->el_tty.t_mode == EX_IO && ma->level < 0) {
  341. long chrs = 0;
  342. (void) ioctl(el->el_infd, FIONREAD, (ioctl_t) & chrs);
  343. if (chrs == 0) {
  344. if (tty_rawmode(el) < 0) {
  345. if (nread)
  346. *nread = 0;
  347. return (NULL);
  348. }
  349. }
  350. }
  351. #endif /* FIONREAD */
  352. re_refresh(el); /* print the prompt */
  353. if (el->el_flags & EDIT_DISABLED) {
  354. char *cp = el->el_line.buffer;
  355. size_t idx;
  356. term__flush();
  357. while ((*el->el_read.read_char)(el, cp) == 1) {
  358. /* make sure there is space next character */
  359. if (cp + 1 >= el->el_line.limit) {
  360. idx = (cp - el->el_line.buffer);
  361. if (!ch_enlargebufs(el, 2))
  362. break;
  363. cp = &el->el_line.buffer[idx];
  364. }
  365. cp++;
  366. if (cp[-1] == '\r' || cp[-1] == '\n')
  367. break;
  368. }
  369. el->el_line.cursor = el->el_line.lastchar = cp;
  370. *cp = '\0';
  371. if (nread)
  372. *nread = el->el_line.cursor - el->el_line.buffer;
  373. return (el->el_line.buffer);
  374. }
  375. for (num = OKCMD; num == OKCMD;) { /* while still editing this
  376. * line */
  377. #ifdef DEBUG_EDIT
  378. read_debug(el);
  379. #endif /* DEBUG_EDIT */
  380. /* if EOF or error */
  381. if ((num = read_getcmd(el, &cmdnum, &ch)) != OKCMD) {
  382. #ifdef DEBUG_READ
  383. (void) fprintf(el->el_errfile,
  384. "Returning from el_gets %d\n", num);
  385. #endif /* DEBUG_READ */
  386. break;
  387. }
  388. if ((int) cmdnum >= el->el_map.nfunc) { /* BUG CHECK command */
  389. #ifdef DEBUG_EDIT
  390. (void) fprintf(el->el_errfile,
  391. "ERROR: illegal command from key 0%o\r\n", ch);
  392. #endif /* DEBUG_EDIT */
  393. continue; /* try again */
  394. }
  395. /* now do the real command */
  396. #ifdef DEBUG_READ
  397. {
  398. el_bindings_t *b;
  399. for (b = el->el_map.help; b->name; b++)
  400. if (b->func == cmdnum)
  401. break;
  402. if (b->name)
  403. (void) fprintf(el->el_errfile,
  404. "Executing %s\n", b->name);
  405. else
  406. (void) fprintf(el->el_errfile,
  407. "Error command = %d\n", cmdnum);
  408. }
  409. #endif /* DEBUG_READ */
  410. retval = (*el->el_map.func[cmdnum]) (el, ch);
  411. /* save the last command here */
  412. el->el_state.lastcmd = cmdnum;
  413. /* use any return value */
  414. switch (retval) {
  415. case CC_CURSOR:
  416. el->el_state.argument = 1;
  417. el->el_state.doingarg = 0;
  418. re_refresh_cursor(el);
  419. break;
  420. case CC_REDISPLAY:
  421. re_clear_lines(el);
  422. re_clear_display(el);
  423. /* FALLTHROUGH */
  424. case CC_REFRESH:
  425. el->el_state.argument = 1;
  426. el->el_state.doingarg = 0;
  427. re_refresh(el);
  428. break;
  429. case CC_REFRESH_BEEP:
  430. el->el_state.argument = 1;
  431. el->el_state.doingarg = 0;
  432. re_refresh(el);
  433. term_beep(el);
  434. break;
  435. case CC_NORM: /* normal char */
  436. el->el_state.argument = 1;
  437. el->el_state.doingarg = 0;
  438. break;
  439. case CC_ARGHACK: /* Suggested by Rich Salz */
  440. /* <rsalz@pineapple.bbn.com> */
  441. break; /* keep going... */
  442. case CC_EOF: /* end of file typed */
  443. num = 0;
  444. break;
  445. case CC_NEWLINE: /* normal end of line */
  446. num = el->el_line.lastchar - el->el_line.buffer;
  447. break;
  448. case CC_FATAL: /* fatal error, reset to known state */
  449. #ifdef DEBUG_READ
  450. (void) fprintf(el->el_errfile,
  451. "*** editor fatal ERROR ***\r\n\n");
  452. #endif /* DEBUG_READ */
  453. /* put (real) cursor in a known place */
  454. re_clear_display(el); /* reset the display stuff */
  455. ch_reset(el); /* reset the input pointers */
  456. re_refresh(el); /* print the prompt again */
  457. el->el_state.argument = 1;
  458. el->el_state.doingarg = 0;
  459. break;
  460. case CC_ERROR:
  461. default: /* functions we don't know about */
  462. #ifdef DEBUG_READ
  463. (void) fprintf(el->el_errfile,
  464. "*** editor ERROR ***\r\n\n");
  465. #endif /* DEBUG_READ */
  466. el->el_state.argument = 1;
  467. el->el_state.doingarg = 0;
  468. term_beep(el);
  469. term__flush();
  470. break;
  471. }
  472. }
  473. /* make sure the tty is set up correctly */
  474. (void) tty_cookedmode(el);
  475. term__flush(); /* flush any buffered output */
  476. if (el->el_flags & HANDLE_SIGNALS)
  477. sig_clr(el);
  478. if (nread)
  479. *nread = num;
  480. return (num ? el->el_line.buffer : NULL);
  481. }