PageRenderTime 136ms CodeModel.GetById 23ms RepoModel.GetById 1ms app.codeStats 1ms

/Falcon-0.9.6.8/clt/falcon/editline/src/readline.c

#
C | 2217 lines | 2174 code | 9 blank | 34 comment | 1 complexity | 5db44299c92d38cb61eb1fecc0c37305 MD5 | raw file
Possible License(s): BSD-3-Clause, MPL-2.0-no-copyleft-exception, GPL-2.0
  1. /* $NetBSD: readline.c,v 1.85 2009/09/07 21:24:33 christos Exp $ */
  2. /*-
  3. * Copyright (c) 1997 The NetBSD Foundation, Inc.
  4. * All rights reserved.
  5. *
  6. * This code is derived from software contributed to The NetBSD Foundation
  7. * by Jaromir Dolecek.
  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. *
  18. * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
  19. * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
  20. * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  21. * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
  22. * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  23. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  24. * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  25. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  26. * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  27. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  28. * POSSIBILITY OF SUCH DAMAGE.
  29. */
  30. #include <config.h>
  31. #if !defined(lint) && !defined(SCCSID)
  32. __RCSID("$NetBSD: readline.c,v 1.85 2009/09/07 21:24:33 christos Exp $");
  33. #endif /* not lint && not SCCSID */
  34. #include <sys/types.h>
  35. #include <sys/stat.h>
  36. #include <stdio.h>
  37. #include <dirent.h>
  38. #include <string.h>
  39. #include <pwd.h>
  40. #include <ctype.h>
  41. #include <stdlib.h>
  42. #include <unistd.h>
  43. #include <limits.h>
  44. #include <errno.h>
  45. #include <fcntl.h>
  46. #include <setjmp.h>
  47. #include <vis.h>
  48. #include "editline/readline.h"
  49. #include "el.h"
  50. #include "fcns.h" /* for EL_NUM_FCNS */
  51. #include "histedit.h"
  52. #include "filecomplete.h"
  53. #if !defined(SIZE_T_MAX)
  54. # define SIZE_T_MAX (size_t)(-1)
  55. #endif
  56. void rl_prep_terminal(int);
  57. void rl_deprep_terminal(void);
  58. /* for rl_complete() */
  59. #define TAB '\r'
  60. /* see comment at the #ifdef for sense of this */
  61. /* #define GDB_411_HACK */
  62. /* readline compatibility stuff - look at readline sources/documentation */
  63. /* to see what these variables mean */
  64. const char *rl_library_version = "EditLine wrapper";
  65. int rl_readline_version = RL_READLINE_VERSION;
  66. static char empty[] = { '\0' };
  67. static char expand_chars[] = { ' ', '\t', '\n', '=', '(', '\0' };
  68. static char break_chars[] = { ' ', '\t', '\n', '"', '\\', '\'', '`', '@', '$',
  69. '>', '<', '=', ';', '|', '&', '{', '(', '\0' };
  70. char *rl_readline_name = empty;
  71. FILE *rl_instream = NULL;
  72. FILE *rl_outstream = NULL;
  73. int rl_point = 0;
  74. int rl_end = 0;
  75. char *rl_line_buffer = NULL;
  76. VCPFunction *rl_linefunc = NULL;
  77. int rl_done = 0;
  78. VFunction *rl_event_hook = NULL;
  79. KEYMAP_ENTRY_ARRAY emacs_standard_keymap,
  80. emacs_meta_keymap,
  81. emacs_ctlx_keymap;
  82. int history_base = 1; /* probably never subject to change */
  83. int history_length = 0;
  84. int max_input_history = 0;
  85. char history_expansion_char = '!';
  86. char history_subst_char = '^';
  87. char *history_no_expand_chars = expand_chars;
  88. Function *history_inhibit_expansion_function = NULL;
  89. char *history_arg_extract(int start, int end, const char *str);
  90. int rl_inhibit_completion = 0;
  91. int rl_attempted_completion_over = 0;
  92. char *rl_basic_word_break_characters = break_chars;
  93. char *rl_completer_word_break_characters = NULL;
  94. char *rl_completer_quote_characters = NULL;
  95. Function *rl_completion_entry_function = NULL;
  96. CPPFunction *rl_attempted_completion_function = NULL;
  97. Function *rl_pre_input_hook = NULL;
  98. Function *rl_startup1_hook = NULL;
  99. int (*rl_getc_function)(FILE *) = NULL;
  100. char *rl_terminal_name = NULL;
  101. int rl_already_prompted = 0;
  102. int rl_filename_completion_desired = 0;
  103. int rl_ignore_completion_duplicates = 0;
  104. int rl_catch_signals = 1;
  105. int readline_echoing_p = 1;
  106. int _rl_print_completions_horizontally = 0;
  107. VFunction *rl_redisplay_function = NULL;
  108. Function *rl_startup_hook = NULL;
  109. VFunction *rl_completion_display_matches_hook = NULL;
  110. VFunction *rl_prep_term_function = (VFunction *)rl_prep_terminal;
  111. VFunction *rl_deprep_term_function = (VFunction *)rl_deprep_terminal;
  112. KEYMAP_ENTRY_ARRAY emacs_meta_keymap;
  113. /*
  114. * The current prompt string.
  115. */
  116. char *rl_prompt = NULL;
  117. /*
  118. * This is set to character indicating type of completion being done by
  119. * rl_complete_internal(); this is available for application completion
  120. * functions.
  121. */
  122. int rl_completion_type = 0;
  123. /*
  124. * If more than this number of items results from query for possible
  125. * completions, we ask user if they are sure to really display the list.
  126. */
  127. int rl_completion_query_items = 100;
  128. /*
  129. * List of characters which are word break characters, but should be left
  130. * in the parsed text when it is passed to the completion function.
  131. * Shell uses this to help determine what kind of completing to do.
  132. */
  133. char *rl_special_prefixes = NULL;
  134. /*
  135. * This is the character appended to the completed words if at the end of
  136. * the line. Default is ' ' (a space).
  137. */
  138. int rl_completion_append_character = ' ';
  139. /* stuff below is used internally by libedit for readline emulation */
  140. static History *h = NULL;
  141. static EditLine *e = NULL;
  142. static Function *map[256];
  143. static jmp_buf topbuf;
  144. /* internal functions */
  145. static unsigned char _el_rl_complete(EditLine *, int);
  146. static unsigned char _el_rl_tstp(EditLine *, int);
  147. static char *_get_prompt(EditLine *);
  148. static int _getc_function(EditLine *, char *);
  149. static HIST_ENTRY *_move_history(int);
  150. static int _history_expand_command(const char *, size_t, size_t,
  151. char **);
  152. static char *_rl_compat_sub(const char *, const char *,
  153. const char *, int);
  154. static int _rl_event_read_char(EditLine *, char *);
  155. static void _rl_update_pos(void);
  156. /* ARGSUSED */
  157. static char *
  158. _get_prompt(EditLine *el __attribute__((__unused__)))
  159. {
  160. rl_already_prompted = 1;
  161. return (rl_prompt);
  162. }
  163. /*
  164. * generic function for moving around history
  165. */
  166. static HIST_ENTRY *
  167. _move_history(int op)
  168. {
  169. HistEvent ev;
  170. static HIST_ENTRY rl_he;
  171. if (history(h, &ev, op) != 0)
  172. return (HIST_ENTRY *) NULL;
  173. rl_he.line = ev.str;
  174. rl_he.data = (histdata_t) &(ev.num);
  175. return (&rl_he);
  176. }
  177. /*
  178. * read one key from user defined input function
  179. */
  180. static int
  181. /*ARGSUSED*/
  182. _getc_function(EditLine *el, char *c)
  183. {
  184. int i;
  185. i = (*rl_getc_function)(NULL);
  186. if (i == -1)
  187. return 0;
  188. *c = i;
  189. return 1;
  190. }
  191. static const char _dothistory[] = "/.history";
  192. static const char *
  193. _default_history_file(void)
  194. {
  195. struct passwd *p;
  196. static char path[PATH_MAX];
  197. if (*path)
  198. return path;
  199. if ((p = getpwuid(getuid())) == NULL)
  200. return NULL;
  201. strlcpy(path, p->pw_dir, PATH_MAX);
  202. strlcat(path, _dothistory, PATH_MAX);
  203. return path;
  204. }
  205. /*
  206. * READLINE compatibility stuff
  207. */
  208. /*
  209. * Set the prompt
  210. */
  211. int
  212. rl_set_prompt(const char *prompt)
  213. {
  214. char *p;
  215. if (!prompt)
  216. prompt = "";
  217. if (rl_prompt != NULL && strcmp(rl_prompt, prompt) == 0)
  218. return 0;
  219. if (rl_prompt)
  220. free(rl_prompt);
  221. rl_prompt = strdup(prompt);
  222. if (rl_prompt == NULL)
  223. return -1;
  224. while ((p = strchr(rl_prompt, RL_PROMPT_END_IGNORE)) != NULL)
  225. *p = RL_PROMPT_START_IGNORE;
  226. return 0;
  227. }
  228. /*
  229. * initialize rl compat stuff
  230. */
  231. int
  232. rl_initialize(void)
  233. {
  234. HistEvent ev;
  235. const LineInfo *li;
  236. int editmode = 1;
  237. struct termios t;
  238. if (e != NULL)
  239. el_end(e);
  240. if (h != NULL)
  241. history_end(h);
  242. if (!rl_instream)
  243. rl_instream = stdin;
  244. if (!rl_outstream)
  245. rl_outstream = stdout;
  246. /*
  247. * See if we don't really want to run the editor
  248. */
  249. if (tcgetattr(fileno(rl_instream), &t) != -1 && (t.c_lflag & ECHO) == 0)
  250. editmode = 0;
  251. e = el_init(rl_readline_name, rl_instream, rl_outstream, stderr);
  252. if (!editmode)
  253. el_set(e, EL_EDITMODE, 0);
  254. h = history_init();
  255. if (!e || !h)
  256. return (-1);
  257. history(h, &ev, H_SETSIZE, INT_MAX); /* unlimited */
  258. history_length = 0;
  259. max_input_history = INT_MAX;
  260. el_set(e, EL_HIST, history, h);
  261. /* setup getc function if valid */
  262. if (rl_getc_function)
  263. el_set(e, EL_GETCFN, _getc_function);
  264. /* for proper prompt printing in readline() */
  265. if (rl_set_prompt("") == -1) {
  266. history_end(h);
  267. el_end(e);
  268. return -1;
  269. }
  270. el_set(e, EL_PROMPT, _get_prompt, RL_PROMPT_START_IGNORE);
  271. el_set(e, EL_SIGNAL, rl_catch_signals);
  272. /* set default mode to "emacs"-style and read setting afterwards */
  273. /* so this can be overriden */
  274. el_set(e, EL_EDITOR, "emacs");
  275. if (rl_terminal_name != NULL)
  276. el_set(e, EL_TERMINAL, rl_terminal_name);
  277. else
  278. el_get(e, EL_TERMINAL, &rl_terminal_name);
  279. /*
  280. * Word completion - this has to go AFTER rebinding keys
  281. * to emacs-style.
  282. */
  283. el_set(e, EL_ADDFN, "rl_complete",
  284. "ReadLine compatible completion function",
  285. _el_rl_complete);
  286. el_set(e, EL_BIND, "^I", "rl_complete", NULL);
  287. /*
  288. * Send TSTP when ^Z is pressed.
  289. */
  290. el_set(e, EL_ADDFN, "rl_tstp",
  291. "ReadLine compatible suspend function",
  292. _el_rl_tstp);
  293. el_set(e, EL_BIND, "^Z", "rl_tstp", NULL);
  294. /* read settings from configuration file */
  295. el_source(e, NULL);
  296. /*
  297. * Unfortunately, some applications really do use rl_point
  298. * and rl_line_buffer directly.
  299. */
  300. li = el_line(e);
  301. /* a cheesy way to get rid of const cast. */
  302. rl_line_buffer = memchr(li->buffer, *li->buffer, 1);
  303. _rl_update_pos();
  304. if (rl_startup_hook)
  305. (*rl_startup_hook)(NULL, 0);
  306. return (0);
  307. }
  308. /*
  309. * read one line from input stream and return it, chomping
  310. * trailing newline (if there is any)
  311. */
  312. char *
  313. readline(const char *p)
  314. {
  315. HistEvent ev;
  316. const char * volatile prompt = p;
  317. int count;
  318. const char *ret;
  319. char *buf;
  320. static int used_event_hook;
  321. if (e == NULL || h == NULL)
  322. rl_initialize();
  323. rl_done = 0;
  324. (void)setjmp(topbuf);
  325. /* update prompt accordingly to what has been passed */
  326. if (rl_set_prompt(prompt) == -1)
  327. return NULL;
  328. if (rl_pre_input_hook)
  329. (*rl_pre_input_hook)(NULL, 0);
  330. if (rl_event_hook && !(e->el_flags&NO_TTY)) {
  331. el_set(e, EL_GETCFN, _rl_event_read_char);
  332. used_event_hook = 1;
  333. }
  334. if (!rl_event_hook && used_event_hook) {
  335. el_set(e, EL_GETCFN, EL_BUILTIN_GETCFN);
  336. used_event_hook = 0;
  337. }
  338. rl_already_prompted = 0;
  339. /* get one line from input stream */
  340. ret = el_gets(e, &count);
  341. if (ret && count > 0) {
  342. int lastidx;
  343. buf = strdup(ret);
  344. if (buf == NULL)
  345. return NULL;
  346. lastidx = count - 1;
  347. if (buf[lastidx] == '\n')
  348. buf[lastidx] = '\0';
  349. } else
  350. buf = NULL;
  351. history(h, &ev, H_GETSIZE);
  352. history_length = ev.num;
  353. return buf;
  354. }
  355. /*
  356. * history functions
  357. */
  358. /*
  359. * is normally called before application starts to use
  360. * history expansion functions
  361. */
  362. void
  363. using_history(void)
  364. {
  365. if (h == NULL || e == NULL)
  366. rl_initialize();
  367. }
  368. /*
  369. * substitute ``what'' with ``with'', returning resulting string; if
  370. * globally == 1, substitutes all occurrences of what, otherwise only the
  371. * first one
  372. */
  373. static char *
  374. _rl_compat_sub(const char *str, const char *what, const char *with,
  375. int globally)
  376. {
  377. const char *s;
  378. char *r, *result;
  379. size_t len, with_len, what_len;
  380. len = strlen(str);
  381. with_len = strlen(with);
  382. what_len = strlen(what);
  383. /* calculate length we need for result */
  384. s = str;
  385. while (*s) {
  386. if (*s == *what && !strncmp(s, what, what_len)) {
  387. len += with_len - what_len;
  388. if (!globally)
  389. break;
  390. s += what_len;
  391. } else
  392. s++;
  393. }
  394. r = result = malloc(len + 1);
  395. if (result == NULL)
  396. return NULL;
  397. s = str;
  398. while (*s) {
  399. if (*s == *what && !strncmp(s, what, what_len)) {
  400. (void)strncpy(r, with, with_len);
  401. r += with_len;
  402. s += what_len;
  403. if (!globally) {
  404. (void)strcpy(r, s);
  405. return(result);
  406. }
  407. } else
  408. *r++ = *s++;
  409. }
  410. *r = '\0';
  411. return(result);
  412. }
  413. static char *last_search_pat; /* last !?pat[?] search pattern */
  414. static char *last_search_match; /* last !?pat[?] that matched */
  415. const char *
  416. get_history_event(const char *cmd, int *cindex, int qchar)
  417. {
  418. int idx, sign, sub, num, begin, ret;
  419. size_t len;
  420. char *pat;
  421. const char *rptr;
  422. HistEvent ev;
  423. idx = *cindex;
  424. if (cmd[idx++] != history_expansion_char)
  425. return(NULL);
  426. /* find out which event to take */
  427. if (cmd[idx] == history_expansion_char || cmd[idx] == '\0') {
  428. if (history(h, &ev, H_FIRST) != 0)
  429. return(NULL);
  430. *cindex = cmd[idx]? (idx + 1):idx;
  431. return(ev.str);
  432. }
  433. sign = 0;
  434. if (cmd[idx] == '-') {
  435. sign = 1;
  436. idx++;
  437. }
  438. if ('0' <= cmd[idx] && cmd[idx] <= '9') {
  439. HIST_ENTRY *rl_he;
  440. num = 0;
  441. while (cmd[idx] && '0' <= cmd[idx] && cmd[idx] <= '9') {
  442. num = num * 10 + cmd[idx] - '0';
  443. idx++;
  444. }
  445. if (sign)
  446. num = history_length - num + 1;
  447. if (!(rl_he = history_get(num)))
  448. return(NULL);
  449. *cindex = idx;
  450. return(rl_he->line);
  451. }
  452. sub = 0;
  453. if (cmd[idx] == '?') {
  454. sub = 1;
  455. idx++;
  456. }
  457. begin = idx;
  458. while (cmd[idx]) {
  459. if (cmd[idx] == '\n')
  460. break;
  461. if (sub && cmd[idx] == '?')
  462. break;
  463. if (!sub && (cmd[idx] == ':' || cmd[idx] == ' '
  464. || cmd[idx] == '\t' || cmd[idx] == qchar))
  465. break;
  466. idx++;
  467. }
  468. len = idx - begin;
  469. if (sub && cmd[idx] == '?')
  470. idx++;
  471. if (sub && len == 0 && last_search_pat && *last_search_pat)
  472. pat = last_search_pat;
  473. else if (len == 0)
  474. return(NULL);
  475. else {
  476. if ((pat = malloc(len + 1)) == NULL)
  477. return NULL;
  478. (void)strncpy(pat, cmd + begin, len);
  479. pat[len] = '\0';
  480. }
  481. if (history(h, &ev, H_CURR) != 0) {
  482. if (pat != last_search_pat)
  483. free(pat);
  484. return (NULL);
  485. }
  486. num = ev.num;
  487. if (sub) {
  488. if (pat != last_search_pat) {
  489. if (last_search_pat)
  490. free(last_search_pat);
  491. last_search_pat = pat;
  492. }
  493. ret = history_search(pat, -1);
  494. } else
  495. ret = history_search_prefix(pat, -1);
  496. if (ret == -1) {
  497. /* restore to end of list on failed search */
  498. history(h, &ev, H_FIRST);
  499. (void)fprintf(rl_outstream, "%s: Event not found\n", pat);
  500. if (pat != last_search_pat)
  501. free(pat);
  502. return(NULL);
  503. }
  504. if (sub && len) {
  505. if (last_search_match && last_search_match != pat)
  506. free(last_search_match);
  507. last_search_match = pat;
  508. }
  509. if (pat != last_search_pat)
  510. free(pat);
  511. if (history(h, &ev, H_CURR) != 0)
  512. return(NULL);
  513. *cindex = idx;
  514. rptr = ev.str;
  515. /* roll back to original position */
  516. (void)history(h, &ev, H_SET, num);
  517. return rptr;
  518. }
  519. /*
  520. * the real function doing history expansion - takes as argument command
  521. * to do and data upon which the command should be executed
  522. * does expansion the way I've understood readline documentation
  523. *
  524. * returns 0 if data was not modified, 1 if it was and 2 if the string
  525. * should be only printed and not executed; in case of error,
  526. * returns -1 and *result points to NULL
  527. * it's callers responsibility to free() string returned in *result
  528. */
  529. static int
  530. _history_expand_command(const char *command, size_t offs, size_t cmdlen,
  531. char **result)
  532. {
  533. char *tmp, *search = NULL, *aptr;
  534. const char *ptr, *cmd;
  535. static char *from = NULL, *to = NULL;
  536. int start, end, idx, has_mods = 0;
  537. int p_on = 0, g_on = 0;
  538. *result = NULL;
  539. aptr = NULL;
  540. ptr = NULL;
  541. /* First get event specifier */
  542. idx = 0;
  543. if (strchr(":^*$", command[offs + 1])) {
  544. char str[4];
  545. /*
  546. * "!:" is shorthand for "!!:".
  547. * "!^", "!*" and "!$" are shorthand for
  548. * "!!:^", "!!:*" and "!!:$" respectively.
  549. */
  550. str[0] = str[1] = '!';
  551. str[2] = '0';
  552. ptr = get_history_event(str, &idx, 0);
  553. idx = (command[offs + 1] == ':')? 1:0;
  554. has_mods = 1;
  555. } else {
  556. if (command[offs + 1] == '#') {
  557. /* use command so far */
  558. if ((aptr = malloc(offs + 1)) == NULL)
  559. return -1;
  560. (void)strncpy(aptr, command, offs);
  561. aptr[offs] = '\0';
  562. idx = 1;
  563. } else {
  564. int qchar;
  565. qchar = (offs > 0 && command[offs - 1] == '"')? '"':0;
  566. ptr = get_history_event(command + offs, &idx, qchar);
  567. }
  568. has_mods = command[offs + idx] == ':';
  569. }
  570. if (ptr == NULL && aptr == NULL)
  571. return(-1);
  572. if (!has_mods) {
  573. *result = strdup(aptr ? aptr : ptr);
  574. if (aptr)
  575. free(aptr);
  576. if (*result == NULL)
  577. return -1;
  578. return(1);
  579. }
  580. cmd = command + offs + idx + 1;
  581. /* Now parse any word designators */
  582. if (*cmd == '%') /* last word matched by ?pat? */
  583. tmp = strdup(last_search_match? last_search_match:"");
  584. else if (strchr("^*$-0123456789", *cmd)) {
  585. start = end = -1;
  586. if (*cmd == '^')
  587. start = end = 1, cmd++;
  588. else if (*cmd == '$')
  589. start = -1, cmd++;
  590. else if (*cmd == '*')
  591. start = 1, cmd++;
  592. else if (*cmd == '-' || isdigit((unsigned char) *cmd)) {
  593. start = 0;
  594. while (*cmd && '0' <= *cmd && *cmd <= '9')
  595. start = start * 10 + *cmd++ - '0';
  596. if (*cmd == '-') {
  597. if (isdigit((unsigned char) cmd[1])) {
  598. cmd++;
  599. end = 0;
  600. while (*cmd && '0' <= *cmd && *cmd <= '9')
  601. end = end * 10 + *cmd++ - '0';
  602. } else if (cmd[1] == '$') {
  603. cmd += 2;
  604. end = -1;
  605. } else {
  606. cmd++;
  607. end = -2;
  608. }
  609. } else if (*cmd == '*')
  610. end = -1, cmd++;
  611. else
  612. end = start;
  613. }
  614. tmp = history_arg_extract(start, end, aptr? aptr:ptr);
  615. if (tmp == NULL) {
  616. (void)fprintf(rl_outstream, "%s: Bad word specifier",
  617. command + offs + idx);
  618. if (aptr)
  619. free(aptr);
  620. return(-1);
  621. }
  622. } else
  623. tmp = strdup(aptr? aptr:ptr);
  624. if (aptr)
  625. free(aptr);
  626. if (*cmd == '\0' || ((size_t)(cmd - (command + offs)) >= cmdlen)) {
  627. *result = tmp;
  628. return(1);
  629. }
  630. for (; *cmd; cmd++) {
  631. if (*cmd == ':')
  632. continue;
  633. else if (*cmd == 'h') { /* remove trailing path */
  634. if ((aptr = strrchr(tmp, '/')) != NULL)
  635. *aptr = '\0';
  636. } else if (*cmd == 't') { /* remove leading path */
  637. if ((aptr = strrchr(tmp, '/')) != NULL) {
  638. aptr = strdup(aptr + 1);
  639. free(tmp);
  640. tmp = aptr;
  641. }
  642. } else if (*cmd == 'r') { /* remove trailing suffix */
  643. if ((aptr = strrchr(tmp, '.')) != NULL)
  644. *aptr = '\0';
  645. } else if (*cmd == 'e') { /* remove all but suffix */
  646. if ((aptr = strrchr(tmp, '.')) != NULL) {
  647. aptr = strdup(aptr);
  648. free(tmp);
  649. tmp = aptr;
  650. }
  651. } else if (*cmd == 'p') /* print only */
  652. p_on = 1;
  653. else if (*cmd == 'g')
  654. g_on = 2;
  655. else if (*cmd == 's' || *cmd == '&') {
  656. char *what, *with, delim;
  657. size_t len, from_len;
  658. size_t size;
  659. if (*cmd == '&' && (from == NULL || to == NULL))
  660. continue;
  661. else if (*cmd == 's') {
  662. delim = *(++cmd), cmd++;
  663. size = 16;
  664. what = realloc(from, size);
  665. if (what == NULL) {
  666. free(from);
  667. free(tmp);
  668. return 0;
  669. }
  670. len = 0;
  671. for (; *cmd && *cmd != delim; cmd++) {
  672. if (*cmd == '\\' && cmd[1] == delim)
  673. cmd++;
  674. if (len >= size) {
  675. char *nwhat;
  676. nwhat = realloc(what,
  677. (size <<= 1));
  678. if (nwhat == NULL) {
  679. free(what);
  680. free(tmp);
  681. return 0;
  682. }
  683. what = nwhat;
  684. }
  685. what[len++] = *cmd;
  686. }
  687. what[len] = '\0';
  688. from = what;
  689. if (*what == '\0') {
  690. free(what);
  691. if (search) {
  692. from = strdup(search);
  693. if (from == NULL) {
  694. free(tmp);
  695. return 0;
  696. }
  697. } else {
  698. from = NULL;
  699. free(tmp);
  700. return (-1);
  701. }
  702. }
  703. cmd++; /* shift after delim */
  704. if (!*cmd)
  705. continue;
  706. size = 16;
  707. with = realloc(to, size);
  708. if (with == NULL) {
  709. free(to);
  710. free(tmp);
  711. return -1;
  712. }
  713. len = 0;
  714. from_len = strlen(from);
  715. for (; *cmd && *cmd != delim; cmd++) {
  716. if (len + from_len + 1 >= size) {
  717. char *nwith;
  718. size += from_len + 1;
  719. nwith = realloc(with, size);
  720. if (nwith == NULL) {
  721. free(with);
  722. free(tmp);
  723. return -1;
  724. }
  725. with = nwith;
  726. }
  727. if (*cmd == '&') {
  728. /* safe */
  729. (void)strcpy(&with[len], from);
  730. len += from_len;
  731. continue;
  732. }
  733. if (*cmd == '\\'
  734. && (*(cmd + 1) == delim
  735. || *(cmd + 1) == '&'))
  736. cmd++;
  737. with[len++] = *cmd;
  738. }
  739. with[len] = '\0';
  740. to = with;
  741. }
  742. aptr = _rl_compat_sub(tmp, from, to, g_on);
  743. if (aptr) {
  744. free(tmp);
  745. tmp = aptr;
  746. }
  747. g_on = 0;
  748. }
  749. }
  750. *result = tmp;
  751. return (p_on? 2:1);
  752. }
  753. /*
  754. * csh-style history expansion
  755. */
  756. int
  757. history_expand(char *str, char **output)
  758. {
  759. int ret = 0;
  760. size_t idx, i, size;
  761. char *tmp, *result;
  762. if (h == NULL || e == NULL)
  763. rl_initialize();
  764. if (history_expansion_char == 0) {
  765. *output = strdup(str);
  766. return(0);
  767. }
  768. *output = NULL;
  769. if (str[0] == history_subst_char) {
  770. /* ^foo^foo2^ is equivalent to !!:s^foo^foo2^ */
  771. *output = malloc(strlen(str) + 4 + 1);
  772. if (*output == NULL)
  773. return 0;
  774. (*output)[0] = (*output)[1] = history_expansion_char;
  775. (*output)[2] = ':';
  776. (*output)[3] = 's';
  777. (void)strcpy((*output) + 4, str);
  778. str = *output;
  779. } else {
  780. *output = strdup(str);
  781. if (*output == NULL)
  782. return 0;
  783. }
  784. #define ADD_STRING(what, len, fr) \
  785. { \
  786. if (idx + len + 1 > size) { \
  787. char *nresult = realloc(result, (size += len + 1));\
  788. if (nresult == NULL) { \
  789. free(*output); \
  790. if (/*CONSTCOND*/fr) \
  791. free(tmp); \
  792. return 0; \
  793. } \
  794. result = nresult; \
  795. } \
  796. (void)strncpy(&result[idx], what, len); \
  797. idx += len; \
  798. result[idx] = '\0'; \
  799. }
  800. result = NULL;
  801. size = idx = 0;
  802. tmp = NULL;
  803. for (i = 0; str[i];) {
  804. int qchar, loop_again;
  805. size_t len, start, j;
  806. qchar = 0;
  807. loop_again = 1;
  808. start = j = i;
  809. loop:
  810. for (; str[j]; j++) {
  811. if (str[j] == '\\' &&
  812. str[j + 1] == history_expansion_char) {
  813. (void)strcpy(&str[j], &str[j + 1]);
  814. continue;
  815. }
  816. if (!loop_again) {
  817. if (isspace((unsigned char) str[j])
  818. || str[j] == qchar)
  819. break;
  820. }
  821. if (str[j] == history_expansion_char
  822. && !strchr(history_no_expand_chars, str[j + 1])
  823. && (!history_inhibit_expansion_function ||
  824. (*history_inhibit_expansion_function)(str,
  825. (int)j) == 0))
  826. break;
  827. }
  828. if (str[j] && loop_again) {
  829. i = j;
  830. qchar = (j > 0 && str[j - 1] == '"' )? '"':0;
  831. j++;
  832. if (str[j] == history_expansion_char)
  833. j++;
  834. loop_again = 0;
  835. goto loop;
  836. }
  837. len = i - start;
  838. ADD_STRING(&str[start], len, 0);
  839. if (str[i] == '\0' || str[i] != history_expansion_char) {
  840. len = j - i;
  841. ADD_STRING(&str[i], len, 0);
  842. if (start == 0)
  843. ret = 0;
  844. else
  845. ret = 1;
  846. break;
  847. }
  848. ret = _history_expand_command (str, i, (j - i), &tmp);
  849. if (ret > 0 && tmp) {
  850. len = strlen(tmp);
  851. ADD_STRING(tmp, len, 1);
  852. }
  853. if (tmp) {
  854. free(tmp);
  855. tmp = NULL;
  856. }
  857. i = j;
  858. }
  859. /* ret is 2 for "print only" option */
  860. if (ret == 2) {
  861. add_history(result);
  862. #ifdef GDB_411_HACK
  863. /* gdb 4.11 has been shipped with readline, where */
  864. /* history_expand() returned -1 when the line */
  865. /* should not be executed; in readline 2.1+ */
  866. /* it should return 2 in such a case */
  867. ret = -1;
  868. #endif
  869. }
  870. free(*output);
  871. *output = result;
  872. return (ret);
  873. }
  874. /*
  875. * Return a string consisting of arguments of "str" from "start" to "end".
  876. */
  877. char *
  878. history_arg_extract(int start, int end, const char *str)
  879. {
  880. size_t i, len, max;
  881. char **arr, *result = NULL;
  882. arr = history_tokenize(str);
  883. if (!arr)
  884. return NULL;
  885. if (arr && *arr == NULL)
  886. goto out;
  887. for (max = 0; arr[max]; max++)
  888. continue;
  889. max--;
  890. if (start == '$')
  891. start = (int)max;
  892. if (end == '$')
  893. end = (int)max;
  894. if (end < 0)
  895. end = (int)max + end + 1;
  896. if (start < 0)
  897. start = end;
  898. if (start < 0 || end < 0 || (size_t)start > max ||
  899. (size_t)end > max || start > end)
  900. goto out;
  901. for (i = start, len = 0; i <= (size_t)end; i++)
  902. len += strlen(arr[i]) + 1;
  903. len++;
  904. result = malloc(len);
  905. if (result == NULL)
  906. goto out;
  907. for (i = start, len = 0; i <= (size_t)end; i++) {
  908. (void)strcpy(result + len, arr[i]);
  909. len += strlen(arr[i]);
  910. if (i < (size_t)end)
  911. result[len++] = ' ';
  912. }
  913. result[len] = '\0';
  914. out:
  915. for (i = 0; arr[i]; i++)
  916. free(arr[i]);
  917. free(arr);
  918. return result;
  919. }
  920. /*
  921. * Parse the string into individual tokens,
  922. * similar to how shell would do it.
  923. */
  924. char **
  925. history_tokenize(const char *str)
  926. {
  927. int size = 1, idx = 0, i, start;
  928. size_t len;
  929. char **result = NULL, *temp, delim = '\0';
  930. for (i = 0; str[i];) {
  931. while (isspace((unsigned char) str[i]))
  932. i++;
  933. start = i;
  934. for (; str[i];) {
  935. if (str[i] == '\\') {
  936. if (str[i+1] != '\0')
  937. i++;
  938. } else if (str[i] == delim)
  939. delim = '\0';
  940. else if (!delim &&
  941. (isspace((unsigned char) str[i]) ||
  942. strchr("()<>;&|$", str[i])))
  943. break;
  944. else if (!delim && strchr("'`\"", str[i]))
  945. delim = str[i];
  946. if (str[i])
  947. i++;
  948. }
  949. if (idx + 2 >= size) {
  950. char **nresult;
  951. size <<= 1;
  952. nresult = realloc(result, size * sizeof(char *));
  953. if (nresult == NULL) {
  954. free(result);
  955. return NULL;
  956. }
  957. result = nresult;
  958. }
  959. len = i - start;
  960. temp = malloc(len + 1);
  961. if (temp == NULL) {
  962. for (i = 0; i < idx; i++)
  963. free(result[i]);
  964. free(result);
  965. return NULL;
  966. }
  967. (void)strncpy(temp, &str[start], len);
  968. temp[len] = '\0';
  969. result[idx++] = temp;
  970. result[idx] = NULL;
  971. if (str[i])
  972. i++;
  973. }
  974. return (result);
  975. }
  976. /*
  977. * limit size of history record to ``max'' events
  978. */
  979. void
  980. stifle_history(int max)
  981. {
  982. HistEvent ev;
  983. if (h == NULL || e == NULL)
  984. rl_initialize();
  985. if (history(h, &ev, H_SETSIZE, max) == 0)
  986. max_input_history = max;
  987. }
  988. /*
  989. * "unlimit" size of history - set the limit to maximum allowed int value
  990. */
  991. int
  992. unstifle_history(void)
  993. {
  994. HistEvent ev;
  995. int omax;
  996. history(h, &ev, H_SETSIZE, INT_MAX);
  997. omax = max_input_history;
  998. max_input_history = INT_MAX;
  999. return (omax); /* some value _must_ be returned */
  1000. }
  1001. int
  1002. history_is_stifled(void)
  1003. {
  1004. /* cannot return true answer */
  1005. return (max_input_history != INT_MAX);
  1006. }
  1007. static const char _history_tmp_template[] = "/tmp/.historyXXXXXX";
  1008. int
  1009. history_truncate_file (const char *filename, int nlines)
  1010. {
  1011. int ret = 0;
  1012. FILE *fp, *tp;
  1013. char template[sizeof(_history_tmp_template)];
  1014. char buf[4096];
  1015. int fd;
  1016. char *cp;
  1017. off_t off;
  1018. int count = 0;
  1019. ssize_t left = 0;
  1020. if (filename == NULL && (filename = _default_history_file()) == NULL)
  1021. return errno;
  1022. if ((fp = fopen(filename, "r+")) == NULL)
  1023. return errno;
  1024. strcpy(template, _history_tmp_template);
  1025. if ((fd = mkstemp(template)) == -1) {
  1026. ret = errno;
  1027. goto out1;
  1028. }
  1029. if ((tp = fdopen(fd, "r+")) == NULL) {
  1030. close(fd);
  1031. ret = errno;
  1032. goto out2;
  1033. }
  1034. for(;;) {
  1035. if (fread(buf, sizeof(buf), 1, fp) != 1) {
  1036. if (ferror(fp)) {
  1037. ret = errno;
  1038. break;
  1039. }
  1040. if (fseeko(fp, (off_t)sizeof(buf) * count, SEEK_SET) ==
  1041. (off_t)-1) {
  1042. ret = errno;
  1043. break;
  1044. }
  1045. left = fread(buf, 1, sizeof(buf), fp);
  1046. if (ferror(fp)) {
  1047. ret = errno;
  1048. break;
  1049. }
  1050. if (left == 0) {
  1051. count--;
  1052. left = sizeof(buf);
  1053. } else if (fwrite(buf, (size_t)left, 1, tp) != 1) {
  1054. ret = errno;
  1055. break;
  1056. }
  1057. fflush(tp);
  1058. break;
  1059. }
  1060. if (fwrite(buf, sizeof(buf), 1, tp) != 1) {
  1061. ret = errno;
  1062. break;
  1063. }
  1064. count++;
  1065. }
  1066. if (ret)
  1067. goto out3;
  1068. cp = buf + left - 1;
  1069. if(*cp != '\n')
  1070. cp++;
  1071. for(;;) {
  1072. while (--cp >= buf) {
  1073. if (*cp == '\n') {
  1074. if (--nlines == 0) {
  1075. if (++cp >= buf + sizeof(buf)) {
  1076. count++;
  1077. cp = buf;
  1078. }
  1079. break;
  1080. }
  1081. }
  1082. }
  1083. if (nlines <= 0 || count == 0)
  1084. break;
  1085. count--;
  1086. if (fseeko(tp, (off_t)sizeof(buf) * count, SEEK_SET) < 0) {
  1087. ret = errno;
  1088. break;
  1089. }
  1090. if (fread(buf, sizeof(buf), 1, tp) != 1) {
  1091. if (ferror(tp)) {
  1092. ret = errno;
  1093. break;
  1094. }
  1095. ret = EAGAIN;
  1096. break;
  1097. }
  1098. cp = buf + sizeof(buf);
  1099. }
  1100. if (ret || nlines > 0)
  1101. goto out3;
  1102. if (fseeko(fp, 0, SEEK_SET) == (off_t)-1) {
  1103. ret = errno;
  1104. goto out3;
  1105. }
  1106. if (fseeko(tp, (off_t)sizeof(buf) * count + (cp - buf), SEEK_SET) ==
  1107. (off_t)-1) {
  1108. ret = errno;
  1109. goto out3;
  1110. }
  1111. for(;;) {
  1112. if ((left = fread(buf, 1, sizeof(buf), tp)) == 0) {
  1113. if (ferror(fp))
  1114. ret = errno;
  1115. break;
  1116. }
  1117. if (fwrite(buf, (size_t)left, 1, fp) != 1) {
  1118. ret = errno;
  1119. break;
  1120. }
  1121. }
  1122. fflush(fp);
  1123. if((off = ftello(fp)) > 0)
  1124. (void)ftruncate(fileno(fp), off);
  1125. out3:
  1126. fclose(tp);
  1127. out2:
  1128. unlink(template);
  1129. out1:
  1130. fclose(fp);
  1131. return ret;
  1132. }
  1133. /*
  1134. * read history from a file given
  1135. */
  1136. int
  1137. read_history(const char *filename)
  1138. {
  1139. HistEvent ev;
  1140. if (h == NULL || e == NULL)
  1141. rl_initialize();
  1142. if (filename == NULL && (filename = _default_history_file()) == NULL)
  1143. return errno;
  1144. return (history(h, &ev, H_LOAD, filename) == -1 ? (errno ? errno : EINVAL) : 0);
  1145. }
  1146. /*
  1147. * write history to a file given
  1148. */
  1149. int
  1150. write_history(const char *filename)
  1151. {
  1152. HistEvent ev;
  1153. if (h == NULL || e == NULL)
  1154. rl_initialize();
  1155. if (filename == NULL && (filename = _default_history_file()) == NULL)
  1156. return errno;
  1157. return (history(h, &ev, H_SAVE, filename) == -1 ? (errno ? errno : EINVAL) : 0);
  1158. }
  1159. /*
  1160. * returns history ``num''th event
  1161. *
  1162. * returned pointer points to static variable
  1163. */
  1164. HIST_ENTRY *
  1165. history_get(int num)
  1166. {
  1167. static HIST_ENTRY she;
  1168. HistEvent ev;
  1169. int curr_num;
  1170. if (h == NULL || e == NULL)
  1171. rl_initialize();
  1172. /* save current position */
  1173. if (history(h, &ev, H_CURR) != 0)
  1174. return (NULL);
  1175. curr_num = ev.num;
  1176. /* start from the oldest */
  1177. if (history(h, &ev, H_LAST) != 0)
  1178. return (NULL); /* error */
  1179. /* look forwards for event matching specified offset */
  1180. if (history(h, &ev, H_NEXT_EVDATA, num, &she.data))
  1181. return (NULL);
  1182. she.line = ev.str;
  1183. /* restore pointer to where it was */
  1184. (void)history(h, &ev, H_SET, curr_num);
  1185. return (&she);
  1186. }
  1187. /*
  1188. * add the line to history table
  1189. */
  1190. int
  1191. add_history(const char *line)
  1192. {
  1193. HistEvent ev;
  1194. if (h == NULL || e == NULL)
  1195. rl_initialize();
  1196. (void)history(h, &ev, H_ENTER, line);
  1197. if (history(h, &ev, H_GETSIZE) == 0)
  1198. history_length = ev.num;
  1199. return (!(history_length > 0)); /* return 0 if all is okay */
  1200. }
  1201. /*
  1202. * remove the specified entry from the history list and return it.
  1203. */
  1204. HIST_ENTRY *
  1205. remove_history(int num)
  1206. {
  1207. HIST_ENTRY *he;
  1208. HistEvent ev;
  1209. if (h == NULL || e == NULL)
  1210. rl_initialize();
  1211. if ((he = malloc(sizeof(*he))) == NULL)
  1212. return NULL;
  1213. if (history(h, &ev, H_DELDATA, num, &he->data) != 0) {
  1214. free(he);
  1215. return NULL;
  1216. }
  1217. he->line = ev.str;
  1218. if (history(h, &ev, H_GETSIZE) == 0)
  1219. history_length = ev.num;
  1220. return he;
  1221. }
  1222. /*
  1223. * replace the line and data of the num-th entry
  1224. */
  1225. HIST_ENTRY *
  1226. replace_history_entry(int num, const char *line, histdata_t data)
  1227. {
  1228. HIST_ENTRY *he;
  1229. HistEvent ev;
  1230. int curr_num;
  1231. if (h == NULL || e == NULL)
  1232. rl_initialize();
  1233. /* save current position */
  1234. if (history(h, &ev, H_CURR) != 0)
  1235. return NULL;
  1236. curr_num = ev.num;
  1237. /* start from the oldest */
  1238. if (history(h, &ev, H_LAST) != 0)
  1239. return NULL; /* error */
  1240. if ((he = malloc(sizeof(*he))) == NULL)
  1241. return NULL;
  1242. /* look forwards for event matching specified offset */
  1243. if (history(h, &ev, H_NEXT_EVDATA, num, &he->data))
  1244. goto out;
  1245. he->line = strdup(ev.str);
  1246. if (he->line == NULL)
  1247. goto out;
  1248. if (history(h, &ev, H_REPLACE, line, data))
  1249. goto out;
  1250. /* restore pointer to where it was */
  1251. if (history(h, &ev, H_SET, curr_num))
  1252. goto out;
  1253. return he;
  1254. out:
  1255. free(he);
  1256. return NULL;
  1257. }
  1258. /*
  1259. * clear the history list - delete all entries
  1260. */
  1261. void
  1262. clear_history(void)
  1263. {
  1264. HistEvent ev;
  1265. history(h, &ev, H_CLEAR);
  1266. history_length = 0;
  1267. }
  1268. /*
  1269. * returns offset of the current history event
  1270. */
  1271. int
  1272. where_history(void)
  1273. {
  1274. HistEvent ev;
  1275. int curr_num, off;
  1276. if (history(h, &ev, H_CURR) != 0)
  1277. return (0);
  1278. curr_num = ev.num;
  1279. history(h, &ev, H_FIRST);
  1280. off = 1;
  1281. while (ev.num != curr_num && history(h, &ev, H_NEXT) == 0)
  1282. off++;
  1283. return (off);
  1284. }
  1285. /*
  1286. * returns current history event or NULL if there is no such event
  1287. */
  1288. HIST_ENTRY *
  1289. current_history(void)
  1290. {
  1291. return (_move_history(H_CURR));
  1292. }
  1293. /*
  1294. * returns total number of bytes history events' data are using
  1295. */
  1296. int
  1297. history_total_bytes(void)
  1298. {
  1299. HistEvent ev;
  1300. int curr_num;
  1301. size_t size;
  1302. if (history(h, &ev, H_CURR) != 0)
  1303. return (-1);
  1304. curr_num = ev.num;
  1305. history(h, &ev, H_FIRST);
  1306. size = 0;
  1307. do
  1308. size += strlen(ev.str);
  1309. while (history(h, &ev, H_NEXT) == 0);
  1310. /* get to the same position as before */
  1311. history(h, &ev, H_PREV_EVENT, curr_num);
  1312. return (int)(size);
  1313. }
  1314. /*
  1315. * sets the position in the history list to ``pos''
  1316. */
  1317. int
  1318. history_set_pos(int pos)
  1319. {
  1320. HistEvent ev;
  1321. int curr_num;
  1322. if (pos >= history_length || pos < 0)
  1323. return (-1);
  1324. history(h, &ev, H_CURR);
  1325. curr_num = ev.num;
  1326. /*
  1327. * use H_DELDATA to set to nth history (without delete) by passing
  1328. * (void **)-1
  1329. */
  1330. if (history(h, &ev, H_DELDATA, pos, (void **)-1)) {
  1331. history(h, &ev, H_SET, curr_num);
  1332. return(-1);
  1333. }
  1334. return (0);
  1335. }
  1336. /*
  1337. * returns previous event in history and shifts pointer accordingly
  1338. */
  1339. HIST_ENTRY *
  1340. previous_history(void)
  1341. {
  1342. return (_move_history(H_PREV));
  1343. }
  1344. /*
  1345. * returns next event in history and shifts pointer accordingly
  1346. */
  1347. HIST_ENTRY *
  1348. next_history(void)
  1349. {
  1350. return (_move_history(H_NEXT));
  1351. }
  1352. /*
  1353. * searches for first history event containing the str
  1354. */
  1355. int
  1356. history_search(const char *str, int direction)
  1357. {
  1358. HistEvent ev;
  1359. const char *strp;
  1360. int curr_num;
  1361. if (history(h, &ev, H_CURR) != 0)
  1362. return (-1);
  1363. curr_num = ev.num;
  1364. for (;;) {
  1365. if ((strp = strstr(ev.str, str)) != NULL)
  1366. return (int) (strp - ev.str);
  1367. if (history(h, &ev, direction < 0 ? H_NEXT:H_PREV) != 0)
  1368. break;
  1369. }
  1370. history(h, &ev, H_SET, curr_num);
  1371. return (-1);
  1372. }
  1373. /*
  1374. * searches for first history event beginning with str
  1375. */
  1376. int
  1377. history_search_prefix(const char *str, int direction)
  1378. {
  1379. HistEvent ev;
  1380. return (history(h, &ev, direction < 0? H_PREV_STR:H_NEXT_STR, str));
  1381. }
  1382. /*
  1383. * search for event in history containing str, starting at offset
  1384. * abs(pos); continue backward, if pos<0, forward otherwise
  1385. */
  1386. /* ARGSUSED */
  1387. int
  1388. history_search_pos(const char *str,
  1389. int direction __attribute__((__unused__)), int pos)
  1390. {
  1391. HistEvent ev;
  1392. int curr_num, off;
  1393. off = (pos > 0) ? pos : -pos;
  1394. pos = (pos > 0) ? 1 : -1;
  1395. if (history(h, &ev, H_CURR) != 0)
  1396. return (-1);
  1397. curr_num = ev.num;
  1398. if (history_set_pos(off) != 0 || history(h, &ev, H_CURR) != 0)
  1399. return (-1);
  1400. for (;;) {
  1401. if (strstr(ev.str, str))
  1402. return (off);
  1403. if (history(h, &ev, (pos < 0) ? H_PREV : H_NEXT) != 0)
  1404. break;
  1405. }
  1406. /* set "current" pointer back to previous state */
  1407. history(h, &ev, (pos < 0) ? H_NEXT_EVENT : H_PREV_EVENT, curr_num);
  1408. return (-1);
  1409. }
  1410. /********************************/
  1411. /* completion functions */
  1412. char *
  1413. tilde_expand(char *name)
  1414. {
  1415. return fn_tilde_expand(name);
  1416. }
  1417. char *
  1418. filename_completion_function(const char *name, int state)
  1419. {
  1420. return fn_filename_completion_function(name, state);
  1421. }
  1422. /*
  1423. * a completion generator for usernames; returns _first_ username
  1424. * which starts with supplied text
  1425. * text contains a partial username preceded by random character
  1426. * (usually '~'); state is ignored
  1427. * it's callers responsibility to free returned value
  1428. */
  1429. char *
  1430. username_completion_function(const char *text, int state)
  1431. {
  1432. struct passwd *pwd;
  1433. if (text[0] == '\0')
  1434. return (NULL);
  1435. if (*text == '~')
  1436. text++;
  1437. if (state == 0)
  1438. setpwent();
  1439. while ((pwd = getpwent())
  1440. && pwd != NULL && text[0] == pwd->pw_name[0]
  1441. && strcmp(text, pwd->pw_name) == 0);
  1442. if (pwd == NULL) {
  1443. endpwent();
  1444. return NULL;
  1445. }
  1446. return strdup(pwd->pw_name);
  1447. }
  1448. /*
  1449. * el-compatible wrapper to send TSTP on ^Z
  1450. */
  1451. /* ARGSUSED */
  1452. static unsigned char
  1453. _el_rl_tstp(EditLine *el __attribute__((__unused__)), int ch __attribute__((__unused__)))
  1454. {
  1455. (void)kill(0, SIGTSTP);
  1456. return CC_NORM;
  1457. }
  1458. /*
  1459. * Display list of strings in columnar format on readline's output stream.
  1460. * 'matches' is list of strings, 'len' is number of strings in 'matches',
  1461. * 'max' is maximum length of string in 'matches'.
  1462. */
  1463. void
  1464. rl_display_match_list(char **matches, int len, int max)
  1465. {
  1466. fn_display_match_list(e, matches, (size_t)len, (size_t)max);
  1467. }
  1468. static const char *
  1469. /*ARGSUSED*/
  1470. _rl_completion_append_character_function(const char *dummy
  1471. __attribute__((__unused__)))
  1472. {
  1473. static char buf[2];
  1474. buf[0] = rl_completion_append_character;
  1475. buf[1] = '\0';
  1476. return buf;
  1477. }
  1478. /*
  1479. * complete word at current point
  1480. */
  1481. /* ARGSUSED */
  1482. int
  1483. rl_complete(int ignore __attribute__((__unused__)), int invoking_key)
  1484. {
  1485. if (h == NULL || e == NULL)
  1486. rl_initialize();
  1487. if (rl_inhibit_completion) {
  1488. char arr[2];
  1489. arr[0] = (char)invoking_key;
  1490. arr[1] = '\0';
  1491. el_insertstr(e, arr);
  1492. return (CC_REFRESH);
  1493. }
  1494. /* Just look at how many global variables modify this operation! */
  1495. return fn_complete(e,
  1496. (CPFunction *)rl_completion_entry_function,
  1497. rl_attempted_completion_function,
  1498. rl_basic_word_break_characters, rl_special_prefixes,
  1499. _rl_completion_append_character_function,
  1500. (size_t)rl_completion_query_items,
  1501. &rl_completion_type, &rl_attempted_completion_over,
  1502. &rl_point, &rl_end);
  1503. }
  1504. /* ARGSUSED */
  1505. static unsigned char
  1506. _el_rl_complete(EditLine *el __attribute__((__unused__)), int ch)
  1507. {
  1508. return (unsigned char)rl_complete(0, ch);
  1509. }
  1510. /*
  1511. * misc other functions
  1512. */
  1513. /*
  1514. * bind key c to readline-type function func
  1515. */
  1516. int
  1517. rl_bind_key(int c, rl_command_func_t *func)
  1518. {
  1519. int retval = -1;
  1520. if (h == NULL || e == NULL)
  1521. rl_initialize();
  1522. if (func == rl_insert) {
  1523. /* XXX notice there is no range checking of ``c'' */
  1524. e->el_map.key[c] = ED_INSERT;
  1525. retval = 0;
  1526. }
  1527. return (retval);
  1528. }
  1529. /*
  1530. * read one key from input - handles chars pushed back
  1531. * to input stream also
  1532. */
  1533. int
  1534. rl_read_key(void)
  1535. {
  1536. char fooarr[2 * sizeof(int)];
  1537. if (e == NULL || h == NULL)
  1538. rl_initialize();
  1539. return (el_getc(e, fooarr));
  1540. }
  1541. /*
  1542. * reset the terminal
  1543. */
  1544. /* ARGSUSED */
  1545. void
  1546. rl_reset_terminal(const char *p __attribute__((__unused__)))
  1547. {
  1548. if (h == NULL || e == NULL)
  1549. rl_initialize();
  1550. el_reset(e);
  1551. }
  1552. /*
  1553. * insert character ``c'' back into input stream, ``count'' times
  1554. */
  1555. int
  1556. rl_insert(int count, int c)
  1557. {
  1558. char arr[2];
  1559. if (h == NULL || e == NULL)
  1560. rl_initialize();
  1561. /* XXX - int -> char conversion can lose on multichars */
  1562. arr[0] = c;
  1563. arr[1] = '\0';
  1564. for (; count > 0; count--)
  1565. el_push(e, arr);
  1566. return (0);
  1567. }
  1568. int
  1569. rl_insert_text(const char *text)
  1570. {
  1571. if (!text || *text == 0)
  1572. return (0);
  1573. if (h == NULL || e == NULL)
  1574. rl_initialize();
  1575. if (el_insertstr(e, text) < 0)
  1576. return (0);
  1577. return (int)strlen(text);
  1578. }
  1579. /*ARGSUSED*/
  1580. int
  1581. rl_newline(int count, int c)
  1582. {
  1583. /*
  1584. * Readline-4.0 appears to ignore the args.
  1585. */
  1586. return rl_insert(1, '\n');
  1587. }
  1588. /*ARGSUSED*/
  1589. static unsigned char
  1590. rl_bind_wrapper(EditLine *el, unsigned char c)
  1591. {
  1592. if (map[c] == NULL)
  1593. return CC_ERROR;
  1594. _rl_update_pos();
  1595. (*map[c])(NULL, c);
  1596. /* If rl_done was set by the above call, deal with it here */
  1597. if (rl_done)
  1598. return CC_EOF;
  1599. return CC_NORM;
  1600. }
  1601. int
  1602. rl_add_defun(const char *name, Function *fun, int c)
  1603. {
  1604. char dest[8];
  1605. if ((size_t)c >= sizeof(map) / sizeof(map[0]) || c < 0)
  1606. return -1;
  1607. map[(unsigned char)c] = fun;
  1608. el_set(e, EL_ADDFN, name, name, rl_bind_wrapper);
  1609. vis(dest, c, VIS_WHITE|VIS_NOSLASH, 0);
  1610. el_set(e, EL_BIND, dest, name);
  1611. return 0;
  1612. }
  1613. void
  1614. rl_callback_read_char()
  1615. {
  1616. int count = 0, done = 0;
  1617. const char *buf = el_gets(e, &count);
  1618. char *wbuf;
  1619. if (buf == NULL || count-- <= 0)
  1620. return;
  1621. if (count == 0 && buf[0] == e->el_tty.t_c[TS_IO][C_EOF])
  1622. done = 1;
  1623. if (buf[count] == '\n' || buf[count] == '\r')
  1624. done = 2;
  1625. if (done && rl_linefunc != NULL) {
  1626. el_set(e, EL_UNBUFFERED, 0);
  1627. if (done == 2) {
  1628. if ((wbuf = strdup(buf)) != NULL)
  1629. wbuf[count] = '\0';
  1630. } else
  1631. wbuf = NULL;
  1632. (*(void (*)(const char *))rl_linefunc)(wbuf);
  1633. //el_set(e, EL_UNBUFFERED, 1);
  1634. }
  1635. }
  1636. void
  1637. rl_callback_handler_install(const char *prompt, VCPFunction *linefunc)
  1638. {
  1639. if (e == NULL) {
  1640. rl_initialize();
  1641. }
  1642. (void)rl_set_prompt(prompt);
  1643. rl_linefunc = linefunc;
  1644. el_set(e, EL_UNBUFFERED, 1);
  1645. }
  1646. void
  1647. rl_callback_handler_remove(void)
  1648. {
  1649. el_set(e, EL_UNBUFFERED, 0);
  1650. rl_linefunc = NULL;
  1651. }
  1652. void
  1653. rl_redisplay(void)
  1654. {
  1655. char a[2];
  1656. a[0] = e->el_tty.t_c[TS_IO][C_REPRINT];
  1657. a[1] = '\0';
  1658. el_push(e, a);
  1659. }
  1660. int
  1661. rl_get_previous_history(int count, int key)
  1662. {
  1663. char a[2];
  1664. a[0] = key;
  1665. a[1] = '\0';
  1666. while (count--)
  1667. el_push(e, a);
  1668. return 0;
  1669. }
  1670. void
  1671. /*ARGSUSED*/
  1672. rl_prep_terminal(int meta_flag)
  1673. {
  1674. el_set(e, EL_PREP_TERM, 1);
  1675. }
  1676. void
  1677. rl_deprep_terminal(void)
  1678. {
  1679. el_set(e, EL_PREP_TERM, 0);
  1680. }
  1681. int
  1682. rl_read_init_file(const char *s)
  1683. {
  1684. return(el_source(e, s));
  1685. }
  1686. int
  1687. rl_parse_and_bind(const char *line)
  1688. {
  1689. const char **argv;
  1690. int argc;
  1691. Tokenizer *tok;
  1692. tok = tok_init(NULL);
  1693. tok_str(tok, line, &argc, &argv);
  1694. argc = el_parse(e, argc, argv);
  1695. tok_end(tok);
  1696. return (argc ? 1 : 0);
  1697. }
  1698. int
  1699. rl_variable_bind(const char *var, const char *value)
  1700. {
  1701. /*
  1702. * The proper return value is undocument, but this is what the
  1703. * readline source seems to do.
  1704. */
  1705. return ((el_set(e, EL_BIND, "", var, value) == -1) ? 1 : 0);
  1706. }
  1707. void
  1708. rl_stuff_char(int c)
  1709. {
  1710. char buf[2];
  1711. buf[0] = c;
  1712. buf[1] = '\0';
  1713. el_insertstr(e, buf);
  1714. }
  1715. static int
  1716. _rl_event_read_char(EditLine *el, char *cp)
  1717. {
  1718. int n;
  1719. ssize_t num_read = 0;
  1720. *cp = '\0';
  1721. while (rl_event_hook) {
  1722. (*rl_event_hook)();
  1723. #if defined(FIONREAD)
  1724. if (ioctl(el->el_infd, FIONREAD, &n) < 0)
  1725. return(-1);
  1726. if (n)
  1727. num_read = read(el->el_infd, cp, 1);
  1728. else
  1729. num_read = 0;
  1730. #elif defined(F_SETFL) && defined(O_NDELAY)
  1731. if ((n = fcntl(el->el_infd, F_GETFL, 0)) < 0)
  1732. return(-1);
  1733. if (fcntl(el->el_infd, F_SETFL, n|O_NDELAY) < 0)
  1734. return(-1);
  1735. num_read = read(el->el_infd, cp, 1);
  1736. if (fcntl(el->el_infd, F_SETFL, n))
  1737. return(-1);
  1738. #else
  1739. /* not non-blocking, but what you gonna do? */
  1740. num_read = read(el->el_infd, cp, 1);
  1741. return(-1);
  1742. #endif
  1743. if (num_read < 0 && errno == EAGAIN)
  1744. continue;
  1745. if (num_read == 0)
  1746. continue;
  1747. break;
  1748. }
  1749. if (!rl_event_hook)
  1750. el_set(el, EL_GETCFN, EL_BUILTIN_GETCFN);
  1751. return (int)num_read;
  1752. }
  1753. static void
  1754. _rl_update_pos(void)
  1755. {
  1756. const LineInfo *li = el_line(e);
  1757. rl_point = (int)(li->cursor - li->buffer);
  1758. rl_end = (int)(li->lastchar - li->buffer);
  1759. }
  1760. void
  1761. rl_get_screen_size(int *rows, int *cols)
  1762. {
  1763. if (rows)
  1764. el_get(e, EL_GETTC, "li", rows);
  1765. if (cols)
  1766. el_get(e, EL_GETTC, "co", cols);
  1767. }
  1768. void
  1769. rl_set_screen_size(int rows, int cols)
  1770. {
  1771. char buf[64];
  1772. (void)snprintf(buf, sizeof(buf), "%d", rows);
  1773. el_set(e, EL_SETTC, "li", buf);
  1774. (void)snprintf(buf, sizeof(buf), "%d", cols);
  1775. el_set(e, EL_SETTC, "co", buf);
  1776. }
  1777. char **
  1778. rl_completion_matches(const char *str, rl_compentry_func_t *fun)
  1779. {
  1780. size_t len, max, i, j, min;
  1781. char **list, *match, *a, *b;
  1782. len = 1;
  1783. max = 10;
  1784. if ((list = malloc(max * sizeof(*list))) == NULL)
  1785. return NULL;
  1786. while ((match = (*fun)(str, (int)(len - 1))) != NULL) {
  1787. list[len++] = match;
  1788. if (len == max) {
  1789. char **nl;
  1790. max += 10;
  1791. if ((nl = realloc(list, max * sizeof(*nl))) == NULL)
  1792. goto out;
  1793. list = nl;
  1794. }
  1795. }
  1796. if (len == 1)
  1797. goto out;
  1798. list[len] = NULL;
  1799. if (len == 2) {
  1800. if ((list[0] = strdup(list[1])) == NULL)
  1801. goto out;
  1802. return list;
  1803. }
  1804. qsort(&list[1], len - 1, sizeof(*list),
  1805. (int (*)(const void *, const void *)) strcmp);
  1806. min = SIZE_T_MAX;
  1807. for (i = 1, a = list[i]; i < len - 1; i++, a = b) {
  1808. b = list[i + 1];
  1809. for (j = 0; a[j] && a[j] == b[j]; j++)
  1810. continue;
  1811. if (min > j)
  1812. min = j;
  1813. }
  1814. if (min == 0 && *str) {
  1815. if ((list[0] = strdup(str)) == NULL)
  1816. goto out;
  1817. } else {
  1818. if ((list[0] = malloc(min + 1)) == NULL)
  1819. goto out;
  1820. (void)memcpy(list[0], list[1], min);
  1821. list[0][min] = '\0';
  1822. }
  1823. return list;
  1824. out:
  1825. free(list);
  1826. return NULL;
  1827. }
  1828. char *
  1829. rl_filename_completion_function (const char *text, int state)
  1830. {
  1831. return fn_filename_completion_function(text, state);
  1832. }
  1833. void
  1834. rl_forced_update_display(void)
  1835. {
  1836. el_set(e, EL_REFRESH);
  1837. }
  1838. int
  1839. _rl_abort_internal(void)
  1840. {
  1841. el_beep(e);
  1842. longjmp(topbuf, 1);
  1843. /*NOTREACHED*/
  1844. }
  1845. int
  1846. _rl_qsort_string_compare(char **s1, char **s2)
  1847. {
  1848. return strcoll(*s1, *s2);
  1849. }
  1850. HISTORY_STATE *
  1851. history_get_history_state(void)
  1852. {
  1853. HISTORY_STATE *hs;
  1854. if ((hs = malloc(sizeof(HISTORY_STATE))) == NULL)
  1855. return (NULL);
  1856. hs->length = history_length;
  1857. return (hs);
  1858. }
  1859. int
  1860. /*ARGSUSED*/
  1861. rl_kill_text(int from, int to)
  1862. {
  1863. return 0;
  1864. }
  1865. Keymap
  1866. rl_make_bare_keymap(void)
  1867. {
  1868. return NULL;
  1869. }
  1870. Keymap
  1871. rl_get_keymap(void)
  1872. {
  1873. return NULL;
  1874. }
  1875. void
  1876. /*ARGSUSED*/
  1877. rl_set_keymap(Keymap k)
  1878. {
  1879. }
  1880. int
  1881. /*ARGSUSED*/
  1882. rl_generic_bind(int type, const char * keyseq, const char * data, Keymap k)
  1883. {
  1884. return 0;
  1885. }
  1886. int
  1887. /*ARGSUSED*/
  1888. rl_bind_key_in_map(int key, rl_command_func_t *fun, Keymap k)
  1889. {
  1890. return 0;
  1891. }
  1892. /* unsupported, but needed by python */
  1893. void
  1894. rl_cleanup_after_signal(void)
  1895. {
  1896. }