readline.c 36 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670
  1. /* $NetBSD: readline.c,v 1.21 2002/03/18 16:20:36 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. * 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 NetBSD
  20. * Foundation, Inc. and its contributors.
  21. * 4. Neither the name of The NetBSD Foundation nor the names of its
  22. * contributors may be used to endorse or promote products derived
  23. * from this software without specific prior written permission.
  24. *
  25. * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
  26. * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
  27. * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  28. * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
  29. * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  30. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  31. * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  32. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  33. * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  34. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  35. * POSSIBILITY OF SUCH DAMAGE.
  36. */
  37. #include "config.h"
  38. #if !defined(lint) && !defined(SCCSID)
  39. __RCSID("$NetBSD: readline.c,v 1.21 2002/03/18 16:20:36 christos Exp $");
  40. #endif /* not lint && not SCCSID */
  41. #include <sys/types.h>
  42. #include <sys/stat.h>
  43. #include <stdio.h>
  44. #include <dirent.h>
  45. #include <string.h>
  46. #include <pwd.h>
  47. #include <ctype.h>
  48. #include <stdlib.h>
  49. #include <unistd.h>
  50. #include <limits.h>
  51. #ifdef SOLARIS
  52. #include <alloca.h>
  53. #endif
  54. #include "histedit.h"
  55. #include "readline/readline.h"
  56. #include "el.h"
  57. #include "fcns.h" /* for EL_NUM_FCNS */
  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. static char empty[] = { '\0' };
  66. static char expand_chars[] = { ' ', '\t', '\n', '=', '(', '\0' };
  67. static char break_chars[] = { ' ', '\t', '\n', '"', '\\', '\'', '`', '@', '$',
  68. '>', '<', '=', ';', '|', '&', '{', '(', '\0' };
  69. char *rl_readline_name = empty;
  70. FILE *rl_instream = NULL;
  71. FILE *rl_outstream = NULL;
  72. int rl_point = 0;
  73. int rl_end = 0;
  74. char *rl_line_buffer = NULL;
  75. int history_base = 1; /* probably never subject to change */
  76. int history_length = 0;
  77. int max_input_history = 0;
  78. char history_expansion_char = '!';
  79. char history_subst_char = '^';
  80. char *history_no_expand_chars = expand_chars;
  81. Function *history_inhibit_expansion_function = NULL;
  82. int rl_inhibit_completion = 0;
  83. int rl_attempted_completion_over = 0;
  84. char *rl_basic_word_break_characters = break_chars;
  85. char *rl_completer_word_break_characters = NULL;
  86. char *rl_completer_quote_characters = NULL;
  87. CPFunction *rl_completion_entry_function = NULL;
  88. CPPFunction *rl_attempted_completion_function = NULL;
  89. /*
  90. * This is set to character indicating type of completion being done by
  91. * rl_complete_internal(); this is available for application completion
  92. * functions.
  93. */
  94. int rl_completion_type = 0;
  95. /*
  96. * If more than this number of items results from query for possible
  97. * completions, we ask user if they are sure to really display the list.
  98. */
  99. int rl_completion_query_items = 100;
  100. /*
  101. * List of characters which are word break characters, but should be left
  102. * in the parsed text when it is passed to the completion function.
  103. * Shell uses this to help determine what kind of completing to do.
  104. */
  105. char *rl_special_prefixes = (char *)NULL;
  106. /*
  107. * This is the character appended to the completed words if at the end of
  108. * the line. Default is ' ' (a space).
  109. */
  110. int rl_completion_append_character = ' ';
  111. /* stuff below is used internally by libedit for readline emulation */
  112. /* if not zero, non-unique completions always show list of possible matches */
  113. static int _rl_complete_show_all = 0;
  114. static History *h = NULL;
  115. static EditLine *e = NULL;
  116. static int el_rl_complete_cmdnum = 0;
  117. /* internal functions */
  118. static unsigned char _el_rl_complete(EditLine *, int);
  119. static char *_get_prompt(EditLine *);
  120. static HIST_ENTRY *_move_history(int);
  121. static int _history_search_gen(const char *, int, int);
  122. static int _history_expand_command(const char *, size_t, char **);
  123. static char *_rl_compat_sub(const char *, const char *,
  124. const char *, int);
  125. static int rl_complete_internal(int);
  126. static int _rl_qsort_string_compare(const void *, const void *);
  127. /*
  128. * needed for prompt switching in readline()
  129. */
  130. static char *el_rl_prompt = NULL;
  131. /* ARGSUSED */
  132. static char *
  133. _get_prompt(EditLine *el)
  134. {
  135. return (el_rl_prompt);
  136. }
  137. /*
  138. * generic function for moving around history
  139. */
  140. static HIST_ENTRY *
  141. _move_history(int op)
  142. {
  143. HistEvent ev;
  144. static HIST_ENTRY rl_he;
  145. if (history(h, &ev, op) != 0)
  146. return (HIST_ENTRY *) NULL;
  147. rl_he.line = ev.str;
  148. rl_he.data = "";
  149. return (&rl_he);
  150. }
  151. /*
  152. * READLINE compatibility stuff
  153. */
  154. /*
  155. * initialize rl compat stuff
  156. */
  157. int
  158. rl_initialize(void)
  159. {
  160. HistEvent ev;
  161. const LineInfo *li;
  162. int i;
  163. int editmode = 1;
  164. struct termios t;
  165. if (e != NULL)
  166. el_end(e);
  167. if (h != NULL)
  168. history_end(h);
  169. if (!rl_instream)
  170. rl_instream = stdin;
  171. if (!rl_outstream)
  172. rl_outstream = stdout;
  173. /*
  174. * See if we don't really want to run the editor
  175. */
  176. if (tcgetattr(fileno(rl_instream), &t) != -1 && (t.c_lflag & ECHO) == 0)
  177. editmode = 0;
  178. e = el_init(rl_readline_name, rl_instream, rl_outstream, stderr);
  179. if (!editmode)
  180. el_set(e, EL_EDITMODE, 0);
  181. h = history_init();
  182. if (!e || !h)
  183. return (-1);
  184. history(h, &ev, H_SETSIZE, INT_MAX); /* unlimited */
  185. history_length = 0;
  186. max_input_history = INT_MAX;
  187. el_set(e, EL_HIST, history, h);
  188. /* for proper prompt printing in readline() */
  189. el_rl_prompt = strdup("");
  190. el_set(e, EL_PROMPT, _get_prompt);
  191. el_set(e, EL_SIGNAL, 1);
  192. /* set default mode to "emacs"-style and read setting afterwards */
  193. /* so this can be overriden */
  194. el_set(e, EL_EDITOR, "emacs");
  195. /*
  196. * Word completition - this has to go AFTER rebinding keys
  197. * to emacs-style.
  198. */
  199. el_set(e, EL_ADDFN, "rl_complete",
  200. "ReadLine compatible completition function",
  201. _el_rl_complete);
  202. el_set(e, EL_BIND, "^I", "rl_complete", NULL);
  203. /*
  204. * Find out where the rl_complete function was added; this is
  205. * used later to detect that lastcmd was also rl_complete.
  206. */
  207. for(i=EL_NUM_FCNS; i < e->el_map.nfunc; i++) {
  208. if (e->el_map.func[i] == _el_rl_complete) {
  209. el_rl_complete_cmdnum = i;
  210. break;
  211. }
  212. }
  213. /* read settings from configuration file */
  214. el_source(e, NULL);
  215. /*
  216. * Unfortunately, some applications really do use rl_point
  217. * and rl_line_buffer directly.
  218. */
  219. li = el_line(e);
  220. /* a cheesy way to get rid of const cast. */
  221. rl_line_buffer = memchr(li->buffer, *li->buffer, 1);
  222. rl_point = rl_end = 0;
  223. return (0);
  224. }
  225. /*
  226. * read one line from input stream and return it, chomping
  227. * trailing newline (if there is any)
  228. */
  229. char *
  230. readline(const char *prompt)
  231. {
  232. HistEvent ev;
  233. int count;
  234. const char *ret;
  235. char *buf;
  236. if (e == NULL || h == NULL)
  237. rl_initialize();
  238. /* update prompt accordingly to what has been passed */
  239. if (!prompt)
  240. prompt = "";
  241. if (strcmp(el_rl_prompt, prompt) != 0) {
  242. free(el_rl_prompt);
  243. el_rl_prompt = strdup(prompt);
  244. }
  245. /* get one line from input stream */
  246. ret = el_gets(e, &count);
  247. if (ret && count > 0) {
  248. int lastidx;
  249. buf = strdup(ret);
  250. lastidx = count - 1;
  251. if (buf[lastidx] == '\n')
  252. buf[lastidx] = '\0';
  253. } else
  254. buf = NULL;
  255. history(h, &ev, H_GETSIZE);
  256. history_length = ev.num;
  257. return buf;
  258. }
  259. /*
  260. * history functions
  261. */
  262. /*
  263. * is normally called before application starts to use
  264. * history expansion functions
  265. */
  266. void
  267. using_history(void)
  268. {
  269. if (h == NULL || e == NULL)
  270. rl_initialize();
  271. }
  272. /*
  273. * substitute ``what'' with ``with'', returning resulting string; if
  274. * globally == 1, substitutes all occurences of what, otherwise only the
  275. * first one
  276. */
  277. static char *
  278. _rl_compat_sub(const char *str, const char *what, const char *with,
  279. int globally)
  280. {
  281. char *result;
  282. const char *temp, *new;
  283. int len, with_len, what_len, add;
  284. size_t size, i;
  285. result = malloc((size = 16));
  286. temp = str;
  287. with_len = strlen(with);
  288. what_len = strlen(what);
  289. len = 0;
  290. do {
  291. new = strstr(temp, what);
  292. if (new) {
  293. i = new - temp;
  294. add = i + with_len;
  295. if (i + add + 1 >= size) {
  296. size += add + 1;
  297. result = realloc(result, size);
  298. }
  299. (void) strncpy(&result[len], temp, i);
  300. len += i;
  301. (void) strcpy(&result[len], with); /* safe */
  302. len += with_len;
  303. temp = new + what_len;
  304. } else {
  305. add = strlen(temp);
  306. if (len + add + 1 >= size) {
  307. size += add + 1;
  308. result = realloc(result, size);
  309. }
  310. (void) strcpy(&result[len], temp); /* safe */
  311. len += add;
  312. temp = NULL;
  313. }
  314. } while (temp && globally);
  315. result[len] = '\0';
  316. return (result);
  317. }
  318. /*
  319. * the real function doing history expansion - takes as argument command
  320. * to do and data upon which the command should be executed
  321. * does expansion the way I've understood readline documentation
  322. * word designator ``%'' isn't supported (yet ?)
  323. *
  324. * returns 0 if data was not modified, 1 if it was and 2 if the string
  325. * should be only printed and not executed; in case of error,
  326. * returns -1 and *result points to NULL
  327. * it's callers responsibility to free() string returned in *result
  328. */
  329. static int
  330. _history_expand_command(const char *command, size_t cmdlen, char **result)
  331. {
  332. char **arr, *tempcmd, *line, *search = NULL, *cmd;
  333. const char *event_data = NULL;
  334. static char *from = NULL, *to = NULL;
  335. int start = -1, end = -1, max, i, idx;
  336. int h_on = 0, t_on = 0, r_on = 0, e_on = 0, p_on = 0, g_on = 0;
  337. int event_num = 0, retval;
  338. size_t cmdsize;
  339. *result = NULL;
  340. cmd = alloca(cmdlen + 1);
  341. (void) strncpy(cmd, command, cmdlen);
  342. cmd[cmdlen] = 0;
  343. idx = 1;
  344. /* find out which event to take */
  345. if (cmd[idx] == history_expansion_char) {
  346. event_num = history_length;
  347. idx++;
  348. } else {
  349. int off, num;
  350. size_t len;
  351. off = idx;
  352. while (cmd[off] && !strchr(":^$*-%", cmd[off]))
  353. off++;
  354. num = atoi(&cmd[idx]);
  355. if (num != 0) {
  356. event_num = num;
  357. if (num < 0)
  358. event_num += history_length + 1;
  359. } else {
  360. int prefix = 1, curr_num;
  361. HistEvent ev;
  362. len = off - idx;
  363. if (cmd[idx] == '?') {
  364. idx++, len--;
  365. if (cmd[off - 1] == '?')
  366. len--;
  367. else if (cmd[off] != '\n' && cmd[off] != '\0')
  368. return (-1);
  369. prefix = 0;
  370. }
  371. search = alloca(len + 1);
  372. (void) strncpy(search, &cmd[idx], len);
  373. search[len] = '\0';
  374. if (history(h, &ev, H_CURR) != 0)
  375. return (-1);
  376. curr_num = ev.num;
  377. if (prefix)
  378. retval = history_search_prefix(search, -1);
  379. else
  380. retval = history_search(search, -1);
  381. if (retval == -1) {
  382. fprintf(rl_outstream, "%s: Event not found\n",
  383. search);
  384. return (-1);
  385. }
  386. if (history(h, &ev, H_CURR) != 0)
  387. return (-1);
  388. event_data = ev.str;
  389. /* roll back to original position */
  390. history(h, &ev, H_NEXT_EVENT, curr_num);
  391. }
  392. idx = off;
  393. }
  394. if (!event_data && event_num >= 0) {
  395. HIST_ENTRY *rl_he;
  396. rl_he = history_get(event_num);
  397. if (!rl_he)
  398. return (0);
  399. event_data = rl_he->line;
  400. } else
  401. return (-1);
  402. if (cmd[idx] != ':')
  403. return (-1);
  404. cmd += idx + 1;
  405. /* recognize cmd */
  406. if (*cmd == '^')
  407. start = end = 1, cmd++;
  408. else if (*cmd == '$')
  409. start = end = -1, cmd++;
  410. else if (*cmd == '*')
  411. start = 1, end = -1, cmd++;
  412. else if (isdigit((unsigned char) *cmd)) {
  413. const char *temp;
  414. int shifted = 0;
  415. start = atoi(cmd);
  416. temp = cmd;
  417. for (; isdigit((unsigned char) *cmd); cmd++);
  418. if (temp != cmd)
  419. shifted = 1;
  420. if (shifted && *cmd == '-') {
  421. if (!isdigit((unsigned char) *(cmd + 1)))
  422. end = -2;
  423. else {
  424. end = atoi(cmd + 1);
  425. for (; isdigit((unsigned char) *cmd); cmd++);
  426. }
  427. } else if (shifted && *cmd == '*')
  428. end = -1, cmd++;
  429. else if (shifted)
  430. end = start;
  431. }
  432. if (*cmd == ':')
  433. cmd++;
  434. line = strdup(event_data);
  435. for (; *cmd; cmd++) {
  436. if (*cmd == ':')
  437. continue;
  438. else if (*cmd == 'h')
  439. h_on = 1 | g_on, g_on = 0;
  440. else if (*cmd == 't')
  441. t_on = 1 | g_on, g_on = 0;
  442. else if (*cmd == 'r')
  443. r_on = 1 | g_on, g_on = 0;
  444. else if (*cmd == 'e')
  445. e_on = 1 | g_on, g_on = 0;
  446. else if (*cmd == 'p')
  447. p_on = 1 | g_on, g_on = 0;
  448. else if (*cmd == 'g')
  449. g_on = 2;
  450. else if (*cmd == 's' || *cmd == '&') {
  451. char *what, *with, delim;
  452. int len, from_len;
  453. size_t size;
  454. if (*cmd == '&' && (from == NULL || to == NULL))
  455. continue;
  456. else if (*cmd == 's') {
  457. delim = *(++cmd), cmd++;
  458. size = 16;
  459. what = realloc(from, size);
  460. len = 0;
  461. for (; *cmd && *cmd != delim; cmd++) {
  462. if (*cmd == '\\'
  463. && *(cmd + 1) == delim)
  464. cmd++;
  465. if (len >= size)
  466. what = realloc(what,
  467. (size <<= 1));
  468. what[len++] = *cmd;
  469. }
  470. what[len] = '\0';
  471. from = what;
  472. if (*what == '\0') {
  473. free(what);
  474. if (search)
  475. from = strdup(search);
  476. else {
  477. from = NULL;
  478. return (-1);
  479. }
  480. }
  481. cmd++; /* shift after delim */
  482. if (!*cmd)
  483. continue;
  484. size = 16;
  485. with = realloc(to, size);
  486. len = 0;
  487. from_len = strlen(from);
  488. for (; *cmd && *cmd != delim; cmd++) {
  489. if (len + from_len + 1 >= size) {
  490. size += from_len + 1;
  491. with = realloc(with, size);
  492. }
  493. if (*cmd == '&') {
  494. /* safe */
  495. (void) strcpy(&with[len], from);
  496. len += from_len;
  497. continue;
  498. }
  499. if (*cmd == '\\'
  500. && (*(cmd + 1) == delim
  501. || *(cmd + 1) == '&'))
  502. cmd++;
  503. with[len++] = *cmd;
  504. }
  505. with[len] = '\0';
  506. to = with;
  507. tempcmd = _rl_compat_sub(line, from, to,
  508. (g_on) ? 1 : 0);
  509. free(line);
  510. line = tempcmd;
  511. g_on = 0;
  512. }
  513. }
  514. }
  515. arr = history_tokenize(line);
  516. free(line); /* no more needed */
  517. if (arr && *arr == NULL)
  518. free(arr), arr = NULL;
  519. if (!arr)
  520. return (-1);
  521. /* find out max valid idx to array of array */
  522. max = 0;
  523. for (i = 0; arr[i]; i++)
  524. max++;
  525. max--;
  526. /* set boundaries to something relevant */
  527. if (start < 0)
  528. start = 1;
  529. if (end < 0)
  530. end = max - ((end < -1) ? 1 : 0);
  531. /* check boundaries ... */
  532. if (start > max || end > max || start > end)
  533. return (-1);
  534. for (i = 0; i <= max; i++) {
  535. char *temp;
  536. if (h_on && (i == 1 || h_on > 1) &&
  537. (temp = strrchr(arr[i], '/')))
  538. *(temp + 1) = '\0';
  539. if (t_on && (i == 1 || t_on > 1) &&
  540. (temp = strrchr(arr[i], '/')))
  541. (void) strcpy(arr[i], temp + 1);
  542. if (r_on && (i == 1 || r_on > 1) &&
  543. (temp = strrchr(arr[i], '.')))
  544. *temp = '\0';
  545. if (e_on && (i == 1 || e_on > 1) &&
  546. (temp = strrchr(arr[i], '.')))
  547. (void) strcpy(arr[i], temp);
  548. }
  549. cmdsize = 1, cmdlen = 0;
  550. tempcmd = malloc(cmdsize);
  551. for (i = start; start <= i && i <= end; i++) {
  552. int arr_len;
  553. arr_len = strlen(arr[i]);
  554. if (cmdlen + arr_len + 1 >= cmdsize) {
  555. cmdsize += arr_len + 1;
  556. tempcmd = realloc(tempcmd, cmdsize);
  557. }
  558. (void) strcpy(&tempcmd[cmdlen], arr[i]); /* safe */
  559. cmdlen += arr_len;
  560. tempcmd[cmdlen++] = ' '; /* add a space */
  561. }
  562. while (cmdlen > 0 && isspace((unsigned char) tempcmd[cmdlen - 1]))
  563. cmdlen--;
  564. tempcmd[cmdlen] = '\0';
  565. *result = tempcmd;
  566. for (i = 0; i <= max; i++)
  567. free(arr[i]);
  568. free(arr), arr = (char **) NULL;
  569. return (p_on) ? 2 : 1;
  570. }
  571. /*
  572. * csh-style history expansion
  573. */
  574. int
  575. history_expand(char *str, char **output)
  576. {
  577. int i, retval = 0, idx;
  578. size_t size;
  579. char *temp, *result;
  580. if (h == NULL || e == NULL)
  581. rl_initialize();
  582. *output = strdup(str); /* do it early */
  583. if (str[0] == history_subst_char) {
  584. /* ^foo^foo2^ is equivalent to !!:s^foo^foo2^ */
  585. temp = alloca(4 + strlen(str) + 1);
  586. temp[0] = temp[1] = history_expansion_char;
  587. temp[2] = ':';
  588. temp[3] = 's';
  589. (void) strcpy(temp + 4, str);
  590. str = temp;
  591. }
  592. #define ADD_STRING(what, len) \
  593. { \
  594. if (idx + len + 1 > size) \
  595. result = realloc(result, (size += len + 1)); \
  596. (void)strncpy(&result[idx], what, len); \
  597. idx += len; \
  598. result[idx] = '\0'; \
  599. }
  600. result = NULL;
  601. size = idx = 0;
  602. for (i = 0; str[i];) {
  603. int start, j, loop_again;
  604. size_t len;
  605. loop_again = 1;
  606. start = j = i;
  607. loop:
  608. for (; str[j]; j++) {
  609. if (str[j] == '\\' &&
  610. str[j + 1] == history_expansion_char) {
  611. (void) strcpy(&str[j], &str[j + 1]);
  612. continue;
  613. }
  614. if (!loop_again) {
  615. if (str[j] == '?') {
  616. while (str[j] && str[++j] != '?');
  617. if (str[j] == '?')
  618. j++;
  619. } else if (isspace((unsigned char) str[j]))
  620. break;
  621. }
  622. if (str[j] == history_expansion_char
  623. && !strchr(history_no_expand_chars, str[j + 1])
  624. && (!history_inhibit_expansion_function ||
  625. (*history_inhibit_expansion_function)(str, j) == 0))
  626. break;
  627. }
  628. if (str[j] && str[j + 1] != '#' && loop_again) {
  629. i = j;
  630. j++;
  631. if (str[j] == history_expansion_char)
  632. j++;
  633. loop_again = 0;
  634. goto loop;
  635. }
  636. len = i - start;
  637. temp = &str[start];
  638. ADD_STRING(temp, len);
  639. if (str[i] == '\0' || str[i] != history_expansion_char
  640. || str[i + 1] == '#') {
  641. len = j - i;
  642. temp = &str[i];
  643. ADD_STRING(temp, len);
  644. if (start == 0)
  645. retval = 0;
  646. else
  647. retval = 1;
  648. break;
  649. }
  650. retval = _history_expand_command(&str[i], (size_t) (j - i),
  651. &temp);
  652. if (retval != -1) {
  653. len = strlen(temp);
  654. ADD_STRING(temp, len);
  655. }
  656. i = j;
  657. } /* for(i ...) */
  658. if (retval == 2) {
  659. add_history(temp);
  660. #ifdef GDB_411_HACK
  661. /* gdb 4.11 has been shipped with readline, where */
  662. /* history_expand() returned -1 when the line */
  663. /* should not be executed; in readline 2.1+ */
  664. /* it should return 2 in such a case */
  665. retval = -1;
  666. #endif
  667. }
  668. free(*output);
  669. *output = result;
  670. return (retval);
  671. }
  672. /*
  673. * Parse the string into individual tokens, similarily to how shell would do it.
  674. */
  675. char **
  676. history_tokenize(const char *str)
  677. {
  678. int size = 1, result_idx = 0, i, start;
  679. size_t len;
  680. char **result = NULL, *temp, delim = '\0';
  681. for (i = 0; str[i]; i++) {
  682. while (isspace((unsigned char) str[i]))
  683. i++;
  684. start = i;
  685. for (; str[i]; i++) {
  686. if (str[i] == '\\') {
  687. if (str[i+1] != '\0')
  688. i++;
  689. } else if (str[i] == delim)
  690. delim = '\0';
  691. else if (!delim &&
  692. (isspace((unsigned char) str[i]) ||
  693. strchr("()<>;&|$", str[i])))
  694. break;
  695. else if (!delim && strchr("'`\"", str[i]))
  696. delim = str[i];
  697. }
  698. if (result_idx + 2 >= size) {
  699. size <<= 1;
  700. result = realloc(result, size * sizeof(char *));
  701. }
  702. len = i - start;
  703. temp = malloc(len + 1);
  704. (void) strncpy(temp, &str[start], len);
  705. temp[len] = '\0';
  706. result[result_idx++] = temp;
  707. result[result_idx] = NULL;
  708. }
  709. return (result);
  710. }
  711. /*
  712. * limit size of history record to ``max'' events
  713. */
  714. void
  715. stifle_history(int max)
  716. {
  717. HistEvent ev;
  718. if (h == NULL || e == NULL)
  719. rl_initialize();
  720. if (history(h, &ev, H_SETSIZE, max) == 0)
  721. max_input_history = max;
  722. }
  723. /*
  724. * "unlimit" size of history - set the limit to maximum allowed int value
  725. */
  726. int
  727. unstifle_history(void)
  728. {
  729. HistEvent ev;
  730. int omax;
  731. history(h, &ev, H_SETSIZE, INT_MAX);
  732. omax = max_input_history;
  733. max_input_history = INT_MAX;
  734. return (omax); /* some value _must_ be returned */
  735. }
  736. int
  737. history_is_stifled(void)
  738. {
  739. /* cannot return true answer */
  740. return (max_input_history != INT_MAX);
  741. }
  742. /*
  743. * read history from a file given
  744. */
  745. int
  746. read_history(const char *filename)
  747. {
  748. HistEvent ev;
  749. if (h == NULL || e == NULL)
  750. rl_initialize();
  751. return (history(h, &ev, H_LOAD, filename));
  752. }
  753. /*
  754. * write history to a file given
  755. */
  756. int
  757. write_history(const char *filename)
  758. {
  759. HistEvent ev;
  760. if (h == NULL || e == NULL)
  761. rl_initialize();
  762. return (history(h, &ev, H_SAVE, filename));
  763. }
  764. /*
  765. * returns history ``num''th event
  766. *
  767. * returned pointer points to static variable
  768. */
  769. HIST_ENTRY *
  770. history_get(int num)
  771. {
  772. static HIST_ENTRY she;
  773. HistEvent ev;
  774. int i = 1, curr_num;
  775. if (h == NULL || e == NULL)
  776. rl_initialize();
  777. /* rewind to beginning */
  778. if (history(h, &ev, H_CURR) != 0)
  779. return (NULL);
  780. curr_num = ev.num;
  781. if (history(h, &ev, H_LAST) != 0)
  782. return (NULL); /* error */
  783. while (i < num && history(h, &ev, H_PREV) == 0)
  784. i++;
  785. if (i != num)
  786. return (NULL); /* not so many entries */
  787. she.line = ev.str;
  788. she.data = NULL;
  789. /* rewind history to the same event it was before */
  790. (void) history(h, &ev, H_FIRST);
  791. (void) history(h, &ev, H_NEXT_EVENT, curr_num);
  792. return (&she);
  793. }
  794. /*
  795. * add the line to history table
  796. */
  797. int
  798. add_history(const char *line)
  799. {
  800. HistEvent ev;
  801. if (h == NULL || e == NULL)
  802. rl_initialize();
  803. (void) history(h, &ev, H_ENTER, line);
  804. if (history(h, &ev, H_GETSIZE) == 0)
  805. history_length = ev.num;
  806. return (!(history_length > 0)); /* return 0 if all is okay */
  807. }
  808. /*
  809. * clear the history list - delete all entries
  810. */
  811. void
  812. clear_history(void)
  813. {
  814. HistEvent ev;
  815. history(h, &ev, H_CLEAR);
  816. }
  817. /*
  818. * returns offset of the current history event
  819. */
  820. int
  821. where_history(void)
  822. {
  823. HistEvent ev;
  824. int curr_num, off;
  825. if (history(h, &ev, H_CURR) != 0)
  826. return (0);
  827. curr_num = ev.num;
  828. history(h, &ev, H_FIRST);
  829. off = 1;
  830. while (ev.num != curr_num && history(h, &ev, H_NEXT) == 0)
  831. off++;
  832. return (off);
  833. }
  834. /*
  835. * returns current history event or NULL if there is no such event
  836. */
  837. HIST_ENTRY *
  838. current_history(void)
  839. {
  840. return (_move_history(H_CURR));
  841. }
  842. /*
  843. * returns total number of bytes history events' data are using
  844. */
  845. int
  846. history_total_bytes(void)
  847. {
  848. HistEvent ev;
  849. int curr_num, size;
  850. if (history(h, &ev, H_CURR) != 0)
  851. return (-1);
  852. curr_num = ev.num;
  853. history(h, &ev, H_FIRST);
  854. size = 0;
  855. do
  856. size += strlen(ev.str);
  857. while (history(h, &ev, H_NEXT) == 0);
  858. /* get to the same position as before */
  859. history(h, &ev, H_PREV_EVENT, curr_num);
  860. return (size);
  861. }
  862. /*
  863. * sets the position in the history list to ``pos''
  864. */
  865. int
  866. history_set_pos(int pos)
  867. {
  868. HistEvent ev;
  869. int off, curr_num;
  870. if (pos > history_length || pos < 0)
  871. return (-1);
  872. history(h, &ev, H_CURR);
  873. curr_num = ev.num;
  874. history(h, &ev, H_FIRST);
  875. off = 0;
  876. while (off < pos && history(h, &ev, H_NEXT) == 0)
  877. off++;
  878. if (off != pos) { /* do a rollback in case of error */
  879. history(h, &ev, H_FIRST);
  880. history(h, &ev, H_NEXT_EVENT, curr_num);
  881. return (-1);
  882. }
  883. return (0);
  884. }
  885. /*
  886. * returns previous event in history and shifts pointer accordingly
  887. */
  888. HIST_ENTRY *
  889. previous_history(void)
  890. {
  891. return (_move_history(H_PREV));
  892. }
  893. /*
  894. * returns next event in history and shifts pointer accordingly
  895. */
  896. HIST_ENTRY *
  897. next_history(void)
  898. {
  899. return (_move_history(H_NEXT));
  900. }
  901. /*
  902. * generic history search function
  903. */
  904. static int
  905. _history_search_gen(const char *str, int direction, int pos)
  906. {
  907. HistEvent ev;
  908. const char *strp;
  909. int curr_num;
  910. if (history(h, &ev, H_CURR) != 0)
  911. return (-1);
  912. curr_num = ev.num;
  913. for (;;) {
  914. strp = strstr(ev.str, str);
  915. if (strp && (pos < 0 || &ev.str[pos] == strp))
  916. return (int) (strp - ev.str);
  917. if (history(h, &ev, direction < 0 ? H_PREV : H_NEXT) != 0)
  918. break;
  919. }
  920. history(h, &ev, direction < 0 ? H_NEXT_EVENT : H_PREV_EVENT, curr_num);
  921. return (-1);
  922. }
  923. /*
  924. * searches for first history event containing the str
  925. */
  926. int
  927. history_search(const char *str, int direction)
  928. {
  929. return (_history_search_gen(str, direction, -1));
  930. }
  931. /*
  932. * searches for first history event beginning with str
  933. */
  934. int
  935. history_search_prefix(const char *str, int direction)
  936. {
  937. return (_history_search_gen(str, direction, 0));
  938. }
  939. /*
  940. * search for event in history containing str, starting at offset
  941. * abs(pos); continue backward, if pos<0, forward otherwise
  942. */
  943. /* ARGSUSED */
  944. int
  945. history_search_pos(const char *str, int direction, int pos)
  946. {
  947. HistEvent ev;
  948. int curr_num, off;
  949. off = (pos > 0) ? pos : -pos;
  950. pos = (pos > 0) ? 1 : -1;
  951. if (history(h, &ev, H_CURR) != 0)
  952. return (-1);
  953. curr_num = ev.num;
  954. if (history_set_pos(off) != 0 || history(h, &ev, H_CURR) != 0)
  955. return (-1);
  956. for (;;) {
  957. if (strstr(ev.str, str))
  958. return (off);
  959. if (history(h, &ev, (pos < 0) ? H_PREV : H_NEXT) != 0)
  960. break;
  961. }
  962. /* set "current" pointer back to previous state */
  963. history(h, &ev, (pos < 0) ? H_NEXT_EVENT : H_PREV_EVENT, curr_num);
  964. return (-1);
  965. }
  966. /********************************/
  967. /* completition functions */
  968. /*
  969. * does tilde expansion of strings of type ``~user/foo''
  970. * if ``user'' isn't valid user name or ``txt'' doesn't start
  971. * w/ '~', returns pointer to strdup()ed copy of ``txt''
  972. *
  973. * it's callers's responsibility to free() returned string
  974. */
  975. char *
  976. tilde_expand(char *txt)
  977. {
  978. struct passwd *pass;
  979. char *temp;
  980. size_t len = 0;
  981. if (txt[0] != '~')
  982. return (strdup(txt));
  983. temp = strchr(txt + 1, '/');
  984. if (temp == NULL)
  985. temp = strdup(txt + 1);
  986. else {
  987. len = temp - txt + 1; /* text until string after slash */
  988. temp = malloc(len);
  989. (void) strncpy(temp, txt + 1, len - 2);
  990. temp[len - 2] = '\0';
  991. }
  992. pass = getpwnam(temp);
  993. free(temp); /* value no more needed */
  994. if (pass == NULL)
  995. return (strdup(txt));
  996. /* update pointer txt to point at string immedially following */
  997. /* first slash */
  998. txt += len;
  999. temp = malloc(strlen(pass->pw_dir) + 1 + strlen(txt) + 1);
  1000. (void) sprintf(temp, "%s/%s", pass->pw_dir, txt);
  1001. return (temp);
  1002. }
  1003. /*
  1004. * return first found file name starting by the ``text'' or NULL if no
  1005. * such file can be found
  1006. * value of ``state'' is ignored
  1007. *
  1008. * it's caller's responsibility to free returned string
  1009. */
  1010. char *
  1011. filename_completion_function(const char *text, int state)
  1012. {
  1013. static DIR *dir = NULL;
  1014. static char *filename = NULL, *dirname = NULL;
  1015. static size_t filename_len = 0;
  1016. struct dirent *entry;
  1017. char *temp;
  1018. size_t len;
  1019. if (state == 0 || dir == NULL) {
  1020. if (dir != NULL) {
  1021. closedir(dir);
  1022. dir = NULL;
  1023. }
  1024. temp = strrchr(text, '/');
  1025. if (temp) {
  1026. temp++;
  1027. filename = realloc(filename, strlen(temp) + 1);
  1028. (void) strcpy(filename, temp);
  1029. len = temp - text; /* including last slash */
  1030. dirname = realloc(dirname, len + 1);
  1031. (void) strncpy(dirname, text, len);
  1032. dirname[len] = '\0';
  1033. } else {
  1034. filename = strdup(text);
  1035. dirname = NULL;
  1036. }
  1037. /* support for ``~user'' syntax */
  1038. if (dirname && *dirname == '~') {
  1039. temp = tilde_expand(dirname);
  1040. dirname = realloc(dirname, strlen(temp) + 1);
  1041. (void) strcpy(dirname, temp); /* safe */
  1042. free(temp); /* no longer needed */
  1043. }
  1044. /* will be used in cycle */
  1045. filename_len = strlen(filename);
  1046. if (filename_len == 0)
  1047. return (NULL); /* no expansion possible */
  1048. dir = opendir(dirname ? dirname : ".");
  1049. if (!dir)
  1050. return (NULL); /* cannot open the directory */
  1051. }
  1052. /* find the match */
  1053. while ((entry = readdir(dir)) != NULL) {
  1054. /* otherwise, get first entry where first */
  1055. /* filename_len characters are equal */
  1056. if (entry->d_name[0] == filename[0]
  1057. #if defined(__SVR4) || defined(__linux__)
  1058. && strlen(entry->d_name) >= filename_len
  1059. #else
  1060. && entry->d_namlen >= filename_len
  1061. #endif
  1062. && strncmp(entry->d_name, filename,
  1063. filename_len) == 0)
  1064. break;
  1065. }
  1066. if (entry) { /* match found */
  1067. struct stat stbuf;
  1068. #if defined(__SVR4) || defined(__linux__)
  1069. len = strlen(entry->d_name) +
  1070. #else
  1071. len = entry->d_namlen +
  1072. #endif
  1073. ((dirname) ? strlen(dirname) : 0) + 1 + 1;
  1074. temp = malloc(len);
  1075. (void) sprintf(temp, "%s%s",
  1076. dirname ? dirname : "", entry->d_name); /* safe */
  1077. /* test, if it's directory */
  1078. if (stat(temp, &stbuf) == 0 && S_ISDIR(stbuf.st_mode))
  1079. strcat(temp, "/"); /* safe */
  1080. } else
  1081. temp = NULL;
  1082. return (temp);
  1083. }
  1084. /*
  1085. * a completion generator for usernames; returns _first_ username
  1086. * which starts with supplied text
  1087. * text contains a partial username preceded by random character
  1088. * (usually '~'); state is ignored
  1089. * it's callers responsibility to free returned value
  1090. */
  1091. char *
  1092. username_completion_function(const char *text, int state)
  1093. {
  1094. struct passwd *pwd;
  1095. if (text[0] == '\0')
  1096. return (NULL);
  1097. if (*text == '~')
  1098. text++;
  1099. if (state == 0)
  1100. setpwent();
  1101. while ((pwd = getpwent()) && text[0] == pwd->pw_name[0]
  1102. && strcmp(text, pwd->pw_name) == 0);
  1103. if (pwd == NULL) {
  1104. endpwent();
  1105. return (NULL);
  1106. }
  1107. return (strdup(pwd->pw_name));
  1108. }
  1109. /*
  1110. * el-compatible wrapper around rl_complete; needed for key binding
  1111. */
  1112. /* ARGSUSED */
  1113. static unsigned char
  1114. _el_rl_complete(EditLine *el, int ch)
  1115. {
  1116. return (unsigned char) rl_complete(0, ch);
  1117. }
  1118. /*
  1119. * returns list of completitions for text given
  1120. */
  1121. char **
  1122. completion_matches(const char *text, CPFunction *genfunc)
  1123. {
  1124. char **match_list = NULL, *retstr, *prevstr;
  1125. size_t match_list_len, max_equal, which, i;
  1126. int matches;
  1127. if (h == NULL || e == NULL)
  1128. rl_initialize();
  1129. matches = 0;
  1130. match_list_len = 1;
  1131. while ((retstr = (*genfunc) (text, matches)) != NULL) {
  1132. if (matches + 1 >= match_list_len) {
  1133. match_list_len <<= 1;
  1134. match_list = realloc(match_list,
  1135. match_list_len * sizeof(char *));
  1136. }
  1137. match_list[++matches] = retstr;
  1138. }
  1139. if (!match_list)
  1140. return (char **) NULL; /* nothing found */
  1141. /* find least denominator and insert it to match_list[0] */
  1142. which = 2;
  1143. prevstr = match_list[1];
  1144. max_equal = strlen(prevstr);
  1145. for (; which <= matches; which++) {
  1146. for (i = 0; i < max_equal &&
  1147. prevstr[i] == match_list[which][i]; i++)
  1148. continue;
  1149. max_equal = i;
  1150. }
  1151. retstr = malloc(max_equal + 1);
  1152. (void) strncpy(retstr, match_list[1], max_equal);
  1153. retstr[max_equal] = '\0';
  1154. match_list[0] = retstr;
  1155. /* add NULL as last pointer to the array */
  1156. if (matches + 1 >= match_list_len)
  1157. match_list = realloc(match_list,
  1158. (match_list_len + 1) * sizeof(char *));
  1159. match_list[matches + 1] = (char *) NULL;
  1160. return (match_list);
  1161. }
  1162. /*
  1163. * Sort function for qsort(). Just wrapper around strcasecmp().
  1164. */
  1165. static int
  1166. _rl_qsort_string_compare(i1, i2)
  1167. const void *i1, *i2;
  1168. {
  1169. /* LINTED const castaway */
  1170. const char *s1 = ((const char **)i1)[0];
  1171. /* LINTED const castaway */
  1172. const char *s2 = ((const char **)i2)[0];
  1173. return strcasecmp(s1, s2);
  1174. }
  1175. /*
  1176. * Display list of strings in columnar format on readline's output stream.
  1177. * 'matches' is list of strings, 'len' is number of strings in 'matches',
  1178. * 'max' is maximum length of string in 'matches'.
  1179. */
  1180. void
  1181. rl_display_match_list (matches, len, max)
  1182. char **matches;
  1183. int len, max;
  1184. {
  1185. int i, idx, limit, count;
  1186. int screenwidth = e->el_term.t_size.h;
  1187. /*
  1188. * Find out how many entries can be put on one line, count
  1189. * with two spaces between strings.
  1190. */
  1191. limit = screenwidth / (max + 2);
  1192. if (limit == 0)
  1193. limit = 1;
  1194. /* how many lines of output */
  1195. count = len / limit;
  1196. if (count * limit < len)
  1197. count++;
  1198. /* Sort the items if they are not already sorted. */
  1199. qsort(&matches[1], (size_t)(len - 1), sizeof(char *),
  1200. _rl_qsort_string_compare);
  1201. idx = 1;
  1202. for(; count > 0; count--) {
  1203. for(i=0; i < limit && matches[idx]; i++, idx++)
  1204. fprintf(e->el_outfile, "%-*s ", max, matches[idx]);
  1205. fprintf(e->el_outfile, "\n");
  1206. }
  1207. }
  1208. /*
  1209. * Complete the word at or before point, called by rl_complete()
  1210. * 'what_to_do' says what to do with the completion.
  1211. * `?' means list the possible completions.
  1212. * TAB means do standard completion.
  1213. * `*' means insert all of the possible completions.
  1214. * `!' means to do standard completion, and list all possible completions if
  1215. * there is more than one.
  1216. *
  1217. * Note: '*' support is not implemented
  1218. */
  1219. static int
  1220. rl_complete_internal(int what_to_do)
  1221. {
  1222. CPFunction *complet_func;
  1223. const LineInfo *li;
  1224. char *temp, **matches;
  1225. const char *ctemp;
  1226. size_t len;
  1227. rl_completion_type = what_to_do;
  1228. if (h == NULL || e == NULL)
  1229. rl_initialize();
  1230. complet_func = rl_completion_entry_function;
  1231. if (!complet_func)
  1232. complet_func = filename_completion_function;
  1233. /* We now look backwards for the start of a filename/variable word */
  1234. li = el_line(e);
  1235. ctemp = (const char *) li->cursor;
  1236. while (ctemp > li->buffer
  1237. && !strchr(rl_basic_word_break_characters, ctemp[-1])
  1238. && (!rl_special_prefixes
  1239. || !strchr(rl_special_prefixes, ctemp[-1]) ) )
  1240. ctemp--;
  1241. len = li->cursor - ctemp;
  1242. temp = alloca(len + 1);
  1243. (void) strncpy(temp, ctemp, len);
  1244. temp[len] = '\0';
  1245. /* these can be used by function called in completion_matches() */
  1246. /* or (*rl_attempted_completion_function)() */
  1247. rl_point = li->cursor - li->buffer;
  1248. rl_end = li->lastchar - li->buffer;
  1249. if (!rl_attempted_completion_function)
  1250. matches = completion_matches(temp, complet_func);
  1251. else {
  1252. int end = li->cursor - li->buffer;
  1253. matches = (*rl_attempted_completion_function) (temp, (int)
  1254. (end - len), end);
  1255. }
  1256. if (matches) {
  1257. int i, retval = CC_REFRESH;
  1258. int matches_num, maxlen, match_len, match_display=1;
  1259. /*
  1260. * Only replace the completed string with common part of
  1261. * possible matches if there is possible completion.
  1262. */
  1263. if (matches[0][0] != '\0') {
  1264. el_deletestr(e, (int) len);
  1265. el_insertstr(e, matches[0]);
  1266. }
  1267. if (what_to_do == '?')
  1268. goto display_matches;
  1269. if (matches[2] == NULL && strcmp(matches[0], matches[1]) == 0) {
  1270. /*
  1271. * We found exact match. Add a space after
  1272. * it, unless we do filename completition and the
  1273. * object is a directory.
  1274. */
  1275. size_t alen = strlen(matches[0]);
  1276. if ((complet_func != filename_completion_function
  1277. || (alen > 0 && (matches[0])[alen - 1] != '/'))
  1278. && rl_completion_append_character) {
  1279. char buf[2];
  1280. buf[0] = rl_completion_append_character;
  1281. buf[1] = '\0';
  1282. el_insertstr(e, buf);
  1283. }
  1284. } else if (what_to_do == '!') {
  1285. display_matches:
  1286. /*
  1287. * More than one match and requested to list possible
  1288. * matches.
  1289. */
  1290. for(i=1, maxlen=0; matches[i]; i++) {
  1291. match_len = strlen(matches[i]);
  1292. if (match_len > maxlen)
  1293. maxlen = match_len;
  1294. }
  1295. matches_num = i - 1;
  1296. /* newline to get on next line from command line */
  1297. fprintf(e->el_outfile, "\n");
  1298. /*
  1299. * If there are too many items, ask user for display
  1300. * confirmation.
  1301. */
  1302. if (matches_num > rl_completion_query_items) {
  1303. fprintf(e->el_outfile,
  1304. "Display all %d possibilities? (y or n) ",
  1305. matches_num);
  1306. fflush(e->el_outfile);
  1307. if (getc(stdin) != 'y')
  1308. match_display = 0;
  1309. fprintf(e->el_outfile, "\n");
  1310. }
  1311. if (match_display)
  1312. rl_display_match_list(matches, matches_num,
  1313. maxlen);
  1314. retval = CC_REDISPLAY;
  1315. } else if (matches[0][0]) {
  1316. /*
  1317. * There was some common match, but the name was
  1318. * not complete enough. Next tab will print possible
  1319. * completions.
  1320. */
  1321. el_beep(e);
  1322. } else {
  1323. /* lcd is not a valid object - further specification */
  1324. /* is needed */
  1325. el_beep(e);
  1326. retval = CC_NORM;
  1327. }
  1328. /* free elements of array and the array itself */
  1329. for (i = 0; matches[i]; i++)
  1330. free(matches[i]);
  1331. free(matches), matches = NULL;
  1332. return (retval);
  1333. }
  1334. return (CC_NORM);
  1335. }
  1336. /*
  1337. * complete word at current point
  1338. */
  1339. int
  1340. rl_complete(int ignore, int invoking_key)
  1341. {
  1342. if (h == NULL || e == NULL)
  1343. rl_initialize();
  1344. if (rl_inhibit_completion) {
  1345. rl_insert(ignore, invoking_key);
  1346. return (CC_REFRESH);
  1347. } else if (e->el_state.lastcmd == el_rl_complete_cmdnum)
  1348. return rl_complete_internal('?');
  1349. else if (_rl_complete_show_all)
  1350. return rl_complete_internal('!');
  1351. else
  1352. return (rl_complete_internal(TAB));
  1353. }
  1354. /*
  1355. * misc other functions
  1356. */
  1357. /*
  1358. * bind key c to readline-type function func
  1359. */
  1360. int
  1361. rl_bind_key(int c, int func(int, int))
  1362. {
  1363. int retval = -1;
  1364. if (h == NULL || e == NULL)
  1365. rl_initialize();
  1366. if (func == rl_insert) {
  1367. /* XXX notice there is no range checking of ``c'' */
  1368. e->el_map.key[c] = ED_INSERT;
  1369. retval = 0;
  1370. }
  1371. return (retval);
  1372. }
  1373. /*
  1374. * read one key from input - handles chars pushed back
  1375. * to input stream also
  1376. */
  1377. int
  1378. rl_read_key(void)
  1379. {
  1380. char fooarr[2 * sizeof(int)];
  1381. if (e == NULL || h == NULL)
  1382. rl_initialize();
  1383. return (el_getc(e, fooarr));
  1384. }
  1385. /*
  1386. * reset the terminal
  1387. */
  1388. /* ARGSUSED */
  1389. void
  1390. rl_reset_terminal(const char *p)
  1391. {
  1392. if (h == NULL || e == NULL)
  1393. rl_initialize();
  1394. el_reset(e);
  1395. }
  1396. /*
  1397. * insert character ``c'' back into input stream, ``count'' times
  1398. */
  1399. int
  1400. rl_insert(int count, int c)
  1401. {
  1402. char arr[2];
  1403. if (h == NULL || e == NULL)
  1404. rl_initialize();
  1405. /* XXX - int -> char conversion can lose on multichars */
  1406. arr[0] = c;
  1407. arr[1] = '\0';
  1408. for (; count > 0; count--)
  1409. el_push(e, arr);
  1410. return (0);
  1411. }