text.c 37 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703
  1. /* text.c -- text handling commands for readline. */
  2. /* Copyright (C) 1987-2010 Free Software Foundation, Inc.
  3. This file is part of the GNU Readline Library (Readline), a library
  4. for reading lines of text with interactive input and history editing.
  5. Readline is free software: you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation, either version 3 of the License, or
  8. (at your option) any later version.
  9. Readline is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with Readline. If not, see <http://www.gnu.org/licenses/>.
  15. */
  16. #define READLINE_LIBRARY
  17. #if defined (HAVE_CONFIG_H)
  18. # include <config.h>
  19. #endif
  20. #if defined (HAVE_UNISTD_H)
  21. # include <unistd.h>
  22. #endif /* HAVE_UNISTD_H */
  23. #if defined (HAVE_STDLIB_H)
  24. # include <stdlib.h>
  25. #else
  26. # include "ansi_stdlib.h"
  27. #endif /* HAVE_STDLIB_H */
  28. #if defined (HAVE_LOCALE_H)
  29. # include <locale.h>
  30. #endif
  31. #include <stdio.h>
  32. /* System-specific feature definitions and include files. */
  33. #include "rldefs.h"
  34. #include "rlmbutil.h"
  35. #if defined (__EMX__)
  36. # define INCL_DOSPROCESS
  37. # include <os2.h>
  38. #endif /* __EMX__ */
  39. /* Some standard library routines. */
  40. #include "readline.h"
  41. #include "history.h"
  42. #include "rlprivate.h"
  43. #include "rlshell.h"
  44. #include "xmalloc.h"
  45. /* Forward declarations. */
  46. static int rl_change_case PARAMS((int, int));
  47. static int _rl_char_search PARAMS((int, int, int));
  48. #if defined (READLINE_CALLBACKS)
  49. static int _rl_insert_next_callback PARAMS((_rl_callback_generic_arg *));
  50. static int _rl_char_search_callback PARAMS((_rl_callback_generic_arg *));
  51. #endif
  52. /* The largest chunk of text that can be inserted in one call to
  53. rl_insert_text. Text blocks larger than this are divided. */
  54. #define TEXT_COUNT_MAX 1024
  55. /* **************************************************************** */
  56. /* */
  57. /* Insert and Delete */
  58. /* */
  59. /* **************************************************************** */
  60. /* Insert a string of text into the line at point. This is the only
  61. way that you should do insertion. _rl_insert_char () calls this
  62. function. Returns the number of characters inserted. */
  63. int
  64. rl_insert_text (string)
  65. const char *string;
  66. {
  67. register int i, l;
  68. l = (string && *string) ? strlen (string) : 0;
  69. if (l == 0)
  70. return 0;
  71. if (rl_end + l >= rl_line_buffer_len)
  72. rl_extend_line_buffer (rl_end + l);
  73. for (i = rl_end; i >= rl_point; i--)
  74. rl_line_buffer[i + l] = rl_line_buffer[i];
  75. strncpy (rl_line_buffer + rl_point, string, l);
  76. /* Remember how to undo this if we aren't undoing something. */
  77. if (_rl_doing_an_undo == 0)
  78. {
  79. /* If possible and desirable, concatenate the undos. */
  80. if ((l == 1) &&
  81. rl_undo_list &&
  82. (rl_undo_list->what == UNDO_INSERT) &&
  83. (rl_undo_list->end == rl_point) &&
  84. (rl_undo_list->end - rl_undo_list->start < 20))
  85. rl_undo_list->end++;
  86. else
  87. rl_add_undo (UNDO_INSERT, rl_point, rl_point + l, (char *)NULL);
  88. }
  89. rl_point += l;
  90. rl_end += l;
  91. rl_line_buffer[rl_end] = '\0';
  92. return l;
  93. }
  94. /* Delete the string between FROM and TO. FROM is inclusive, TO is not.
  95. Returns the number of characters deleted. */
  96. int
  97. rl_delete_text (from, to)
  98. int from, to;
  99. {
  100. register char *text;
  101. register int diff, i;
  102. /* Fix it if the caller is confused. */
  103. if (from > to)
  104. SWAP (from, to);
  105. /* fix boundaries */
  106. if (to > rl_end)
  107. {
  108. to = rl_end;
  109. if (from > to)
  110. from = to;
  111. }
  112. if (from < 0)
  113. from = 0;
  114. text = rl_copy_text (from, to);
  115. /* Some versions of strncpy() can't handle overlapping arguments. */
  116. diff = to - from;
  117. for (i = from; i < rl_end - diff; i++)
  118. rl_line_buffer[i] = rl_line_buffer[i + diff];
  119. /* Remember how to undo this delete. */
  120. if (_rl_doing_an_undo == 0)
  121. rl_add_undo (UNDO_DELETE, from, to, text);
  122. else
  123. xfree (text);
  124. rl_end -= diff;
  125. rl_line_buffer[rl_end] = '\0';
  126. return (diff);
  127. }
  128. /* Fix up point so that it is within the line boundaries after killing
  129. text. If FIX_MARK_TOO is non-zero, the mark is forced within line
  130. boundaries also. */
  131. #define _RL_FIX_POINT(x) \
  132. do { \
  133. if (x > rl_end) \
  134. x = rl_end; \
  135. else if (x < 0) \
  136. x = 0; \
  137. } while (0)
  138. void
  139. _rl_fix_point (fix_mark_too)
  140. int fix_mark_too;
  141. {
  142. _RL_FIX_POINT (rl_point);
  143. if (fix_mark_too)
  144. _RL_FIX_POINT (rl_mark);
  145. }
  146. #undef _RL_FIX_POINT
  147. /* Replace the contents of the line buffer between START and END with
  148. TEXT. The operation is undoable. To replace the entire line in an
  149. undoable mode, use _rl_replace_text(text, 0, rl_end); */
  150. int
  151. _rl_replace_text (text, start, end)
  152. const char *text;
  153. int start, end;
  154. {
  155. int n;
  156. n = 0;
  157. rl_begin_undo_group ();
  158. if (start <= end)
  159. rl_delete_text (start, end + 1);
  160. rl_point = start;
  161. if (*text)
  162. n = rl_insert_text (text);
  163. rl_end_undo_group ();
  164. return n;
  165. }
  166. /* Replace the current line buffer contents with TEXT. If CLEAR_UNDO is
  167. non-zero, we free the current undo list. */
  168. void
  169. rl_replace_line (text, clear_undo)
  170. const char *text;
  171. int clear_undo;
  172. {
  173. int len;
  174. len = strlen (text);
  175. if (len >= rl_line_buffer_len)
  176. rl_extend_line_buffer (len);
  177. strcpy (rl_line_buffer, text);
  178. rl_end = len;
  179. if (clear_undo)
  180. rl_free_undo_list ();
  181. _rl_fix_point (1);
  182. }
  183. /* **************************************************************** */
  184. /* */
  185. /* Readline character functions */
  186. /* */
  187. /* **************************************************************** */
  188. /* This is not a gap editor, just a stupid line input routine. No hair
  189. is involved in writing any of the functions, and none should be. */
  190. /* Note that:
  191. rl_end is the place in the string that we would place '\0';
  192. i.e., it is always safe to place '\0' there.
  193. rl_point is the place in the string where the cursor is. Sometimes
  194. this is the same as rl_end.
  195. Any command that is called interactively receives two arguments.
  196. The first is a count: the numeric arg pased to this command.
  197. The second is the key which invoked this command.
  198. */
  199. /* **************************************************************** */
  200. /* */
  201. /* Movement Commands */
  202. /* */
  203. /* **************************************************************** */
  204. /* Note that if you `optimize' the display for these functions, you cannot
  205. use said functions in other functions which do not do optimizing display.
  206. I.e., you will have to update the data base for rl_redisplay, and you
  207. might as well let rl_redisplay do that job. */
  208. /* Move forward COUNT bytes. */
  209. int
  210. rl_forward_byte (count, key)
  211. int count, key;
  212. {
  213. if (count < 0)
  214. return (rl_backward_byte (-count, key));
  215. if (count > 0)
  216. {
  217. int end, lend;
  218. end = rl_point + count;
  219. #if defined (VI_MODE)
  220. lend = rl_end > 0 ? rl_end - (VI_COMMAND_MODE()) : rl_end;
  221. #else
  222. lend = rl_end;
  223. #endif
  224. if (end > lend)
  225. {
  226. rl_point = lend;
  227. rl_ding ();
  228. }
  229. else
  230. rl_point = end;
  231. }
  232. if (rl_end < 0)
  233. rl_end = 0;
  234. return 0;
  235. }
  236. int
  237. _rl_forward_char_internal (count)
  238. int count;
  239. {
  240. int point;
  241. #if defined (HANDLE_MULTIBYTE)
  242. point = _rl_find_next_mbchar (rl_line_buffer, rl_point, count, MB_FIND_NONZERO);
  243. #if defined (VI_MODE)
  244. if (point >= rl_end && VI_COMMAND_MODE())
  245. point = _rl_find_prev_mbchar (rl_line_buffer, rl_end, MB_FIND_NONZERO);
  246. #endif
  247. if (rl_end < 0)
  248. rl_end = 0;
  249. #else
  250. point = rl_point + count;
  251. if (point > rl_end)
  252. point = rl_end;
  253. #endif
  254. return (point);
  255. }
  256. #if defined (HANDLE_MULTIBYTE)
  257. /* Move forward COUNT characters. */
  258. int
  259. rl_forward_char (count, key)
  260. int count, key;
  261. {
  262. int point;
  263. if (MB_CUR_MAX == 1 || rl_byte_oriented)
  264. return (rl_forward_byte (count, key));
  265. if (count < 0)
  266. return (rl_backward_char (-count, key));
  267. if (count > 0)
  268. {
  269. if (rl_point == rl_end && EMACS_MODE())
  270. {
  271. rl_ding ();
  272. return 0;
  273. }
  274. point = _rl_forward_char_internal (count);
  275. if (rl_point == point)
  276. rl_ding ();
  277. rl_point = point;
  278. }
  279. return 0;
  280. }
  281. #else /* !HANDLE_MULTIBYTE */
  282. int
  283. rl_forward_char (count, key)
  284. int count, key;
  285. {
  286. return (rl_forward_byte (count, key));
  287. }
  288. #endif /* !HANDLE_MULTIBYTE */
  289. /* Backwards compatibility. */
  290. int
  291. rl_forward (count, key)
  292. int count, key;
  293. {
  294. return (rl_forward_char (count, key));
  295. }
  296. /* Move backward COUNT bytes. */
  297. int
  298. rl_backward_byte (count, key)
  299. int count, key;
  300. {
  301. if (count < 0)
  302. return (rl_forward_byte (-count, key));
  303. if (count > 0)
  304. {
  305. if (rl_point < count)
  306. {
  307. rl_point = 0;
  308. rl_ding ();
  309. }
  310. else
  311. rl_point -= count;
  312. }
  313. if (rl_point < 0)
  314. rl_point = 0;
  315. return 0;
  316. }
  317. #if defined (HANDLE_MULTIBYTE)
  318. /* Move backward COUNT characters. */
  319. int
  320. rl_backward_char (count, key)
  321. int count, key;
  322. {
  323. int point;
  324. if (MB_CUR_MAX == 1 || rl_byte_oriented)
  325. return (rl_backward_byte (count, key));
  326. if (count < 0)
  327. return (rl_forward_char (-count, key));
  328. if (count > 0)
  329. {
  330. point = rl_point;
  331. while (count > 0 && point > 0)
  332. {
  333. point = _rl_find_prev_mbchar (rl_line_buffer, point, MB_FIND_NONZERO);
  334. count--;
  335. }
  336. if (count > 0)
  337. {
  338. rl_point = 0;
  339. rl_ding ();
  340. }
  341. else
  342. rl_point = point;
  343. }
  344. return 0;
  345. }
  346. #else
  347. int
  348. rl_backward_char (count, key)
  349. int count, key;
  350. {
  351. return (rl_backward_byte (count, key));
  352. }
  353. #endif
  354. /* Backwards compatibility. */
  355. int
  356. rl_backward (count, key)
  357. int count, key;
  358. {
  359. return (rl_backward_char (count, key));
  360. }
  361. /* Move to the beginning of the line. */
  362. int
  363. rl_beg_of_line (count, key)
  364. int count, key;
  365. {
  366. rl_point = 0;
  367. return 0;
  368. }
  369. /* Move to the end of the line. */
  370. int
  371. rl_end_of_line (count, key)
  372. int count, key;
  373. {
  374. rl_point = rl_end;
  375. return 0;
  376. }
  377. /* Move forward a word. We do what Emacs does. Handles multibyte chars. */
  378. int
  379. rl_forward_word (count, key)
  380. int count, key;
  381. {
  382. int c;
  383. if (count < 0)
  384. return (rl_backward_word (-count, key));
  385. while (count)
  386. {
  387. if (rl_point == rl_end)
  388. return 0;
  389. /* If we are not in a word, move forward until we are in one.
  390. Then, move forward until we hit a non-alphabetic character. */
  391. c = _rl_char_value (rl_line_buffer, rl_point);
  392. if (_rl_walphabetic (c) == 0)
  393. {
  394. rl_point = MB_NEXTCHAR (rl_line_buffer, rl_point, 1, MB_FIND_NONZERO);
  395. while (rl_point < rl_end)
  396. {
  397. c = _rl_char_value (rl_line_buffer, rl_point);
  398. if (_rl_walphabetic (c))
  399. break;
  400. rl_point = MB_NEXTCHAR (rl_line_buffer, rl_point, 1, MB_FIND_NONZERO);
  401. }
  402. }
  403. if (rl_point == rl_end)
  404. return 0;
  405. rl_point = MB_NEXTCHAR (rl_line_buffer, rl_point, 1, MB_FIND_NONZERO);
  406. while (rl_point < rl_end)
  407. {
  408. c = _rl_char_value (rl_line_buffer, rl_point);
  409. if (_rl_walphabetic (c) == 0)
  410. break;
  411. rl_point = MB_NEXTCHAR (rl_line_buffer, rl_point, 1, MB_FIND_NONZERO);
  412. }
  413. --count;
  414. }
  415. return 0;
  416. }
  417. /* Move backward a word. We do what Emacs does. Handles multibyte chars. */
  418. int
  419. rl_backward_word (count, key)
  420. int count, key;
  421. {
  422. int c, p;
  423. if (count < 0)
  424. return (rl_forward_word (-count, key));
  425. while (count)
  426. {
  427. if (rl_point == 0)
  428. return 0;
  429. /* Like rl_forward_word (), except that we look at the characters
  430. just before point. */
  431. p = MB_PREVCHAR (rl_line_buffer, rl_point, MB_FIND_NONZERO);
  432. c = _rl_char_value (rl_line_buffer, p);
  433. if (_rl_walphabetic (c) == 0)
  434. {
  435. rl_point = p;
  436. while (rl_point > 0)
  437. {
  438. p = MB_PREVCHAR (rl_line_buffer, rl_point, MB_FIND_NONZERO);
  439. c = _rl_char_value (rl_line_buffer, p);
  440. if (_rl_walphabetic (c))
  441. break;
  442. rl_point = p;
  443. }
  444. }
  445. while (rl_point)
  446. {
  447. p = MB_PREVCHAR (rl_line_buffer, rl_point, MB_FIND_NONZERO);
  448. c = _rl_char_value (rl_line_buffer, p);
  449. if (_rl_walphabetic (c) == 0)
  450. break;
  451. else
  452. rl_point = p;
  453. }
  454. --count;
  455. }
  456. return 0;
  457. }
  458. /* Clear the current line. Numeric argument to C-l does this. */
  459. int
  460. rl_refresh_line (ignore1, ignore2)
  461. int ignore1, ignore2;
  462. {
  463. int curr_line;
  464. curr_line = _rl_current_display_line ();
  465. _rl_move_vert (curr_line);
  466. _rl_move_cursor_relative (0, rl_line_buffer); /* XXX is this right */
  467. _rl_clear_to_eol (0); /* arg of 0 means to not use spaces */
  468. rl_forced_update_display ();
  469. rl_display_fixed = 1;
  470. return 0;
  471. }
  472. /* C-l typed to a line without quoting clears the screen, and then reprints
  473. the prompt and the current input line. Given a numeric arg, redraw only
  474. the current line. */
  475. int
  476. rl_clear_screen (count, key)
  477. int count, key;
  478. {
  479. if (rl_explicit_arg)
  480. {
  481. rl_refresh_line (count, key);
  482. return 0;
  483. }
  484. _rl_clear_screen (); /* calls termcap function to clear screen */
  485. rl_forced_update_display ();
  486. rl_display_fixed = 1;
  487. return 0;
  488. }
  489. int
  490. rl_skip_csi_sequence (count, key)
  491. int count, key;
  492. {
  493. int ch;
  494. RL_SETSTATE (RL_STATE_MOREINPUT);
  495. do
  496. ch = rl_read_key ();
  497. while (ch >= 0x20 && ch < 0x40);
  498. RL_UNSETSTATE (RL_STATE_MOREINPUT);
  499. return 0;
  500. }
  501. int
  502. rl_arrow_keys (count, c)
  503. int count, c;
  504. {
  505. int ch;
  506. RL_SETSTATE(RL_STATE_MOREINPUT);
  507. ch = rl_read_key ();
  508. RL_UNSETSTATE(RL_STATE_MOREINPUT);
  509. switch (_rl_to_upper (ch))
  510. {
  511. case 'A':
  512. rl_get_previous_history (count, ch);
  513. break;
  514. case 'B':
  515. rl_get_next_history (count, ch);
  516. break;
  517. case 'C':
  518. if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
  519. rl_forward_char (count, ch);
  520. else
  521. rl_forward_byte (count, ch);
  522. break;
  523. case 'D':
  524. if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
  525. rl_backward_char (count, ch);
  526. else
  527. rl_backward_byte (count, ch);
  528. break;
  529. default:
  530. rl_ding ();
  531. }
  532. return 0;
  533. }
  534. /* **************************************************************** */
  535. /* */
  536. /* Text commands */
  537. /* */
  538. /* **************************************************************** */
  539. #ifdef HANDLE_MULTIBYTE
  540. static char pending_bytes[MB_LEN_MAX];
  541. static int pending_bytes_length = 0;
  542. static mbstate_t ps = {0};
  543. #endif
  544. /* Insert the character C at the current location, moving point forward.
  545. If C introduces a multibyte sequence, we read the whole sequence and
  546. then insert the multibyte char into the line buffer. */
  547. int
  548. _rl_insert_char (count, c)
  549. int count, c;
  550. {
  551. register int i;
  552. char *string;
  553. #ifdef HANDLE_MULTIBYTE
  554. int string_size;
  555. char incoming[MB_LEN_MAX + 1];
  556. int incoming_length = 0;
  557. mbstate_t ps_back;
  558. static int stored_count = 0;
  559. #endif
  560. if (count <= 0)
  561. return 0;
  562. #if defined (HANDLE_MULTIBYTE)
  563. if (MB_CUR_MAX == 1 || rl_byte_oriented)
  564. {
  565. incoming[0] = c;
  566. incoming[1] = '\0';
  567. incoming_length = 1;
  568. }
  569. else
  570. {
  571. wchar_t wc;
  572. size_t ret;
  573. if (stored_count <= 0)
  574. stored_count = count;
  575. else
  576. count = stored_count;
  577. ps_back = ps;
  578. pending_bytes[pending_bytes_length++] = c;
  579. ret = mbrtowc (&wc, pending_bytes, pending_bytes_length, &ps);
  580. if (ret == (size_t)-2)
  581. {
  582. /* Bytes too short to compose character, try to wait for next byte.
  583. Restore the state of the byte sequence, because in this case the
  584. effect of mbstate is undefined. */
  585. ps = ps_back;
  586. return 1;
  587. }
  588. else if (ret == (size_t)-1)
  589. {
  590. /* Invalid byte sequence for the current locale. Treat first byte
  591. as a single character. */
  592. incoming[0] = pending_bytes[0];
  593. incoming[1] = '\0';
  594. incoming_length = 1;
  595. pending_bytes_length--;
  596. memmove (pending_bytes, pending_bytes + 1, pending_bytes_length);
  597. /* Clear the state of the byte sequence, because in this case the
  598. effect of mbstate is undefined. */
  599. memset (&ps, 0, sizeof (mbstate_t));
  600. }
  601. else if (ret == (size_t)0)
  602. {
  603. incoming[0] = '\0';
  604. incoming_length = 0;
  605. pending_bytes_length--;
  606. /* Clear the state of the byte sequence, because in this case the
  607. effect of mbstate is undefined. */
  608. memset (&ps, 0, sizeof (mbstate_t));
  609. }
  610. else
  611. {
  612. /* We successfully read a single multibyte character. */
  613. memcpy (incoming, pending_bytes, pending_bytes_length);
  614. incoming[pending_bytes_length] = '\0';
  615. incoming_length = pending_bytes_length;
  616. pending_bytes_length = 0;
  617. }
  618. }
  619. #endif /* HANDLE_MULTIBYTE */
  620. /* If we can optimize, then do it. But don't let people crash
  621. readline because of extra large arguments. */
  622. if (count > 1 && count <= TEXT_COUNT_MAX)
  623. {
  624. #if defined (HANDLE_MULTIBYTE)
  625. string_size = count * incoming_length;
  626. string = (char *)xmalloc (1 + string_size);
  627. i = 0;
  628. while (i < string_size)
  629. {
  630. strncpy (string + i, incoming, incoming_length);
  631. i += incoming_length;
  632. }
  633. incoming_length = 0;
  634. stored_count = 0;
  635. #else /* !HANDLE_MULTIBYTE */
  636. string = (char *)xmalloc (1 + count);
  637. for (i = 0; i < count; i++)
  638. string[i] = c;
  639. #endif /* !HANDLE_MULTIBYTE */
  640. string[i] = '\0';
  641. rl_insert_text (string);
  642. xfree (string);
  643. return 0;
  644. }
  645. if (count > TEXT_COUNT_MAX)
  646. {
  647. int decreaser;
  648. #if defined (HANDLE_MULTIBYTE)
  649. string_size = incoming_length * TEXT_COUNT_MAX;
  650. string = (char *)xmalloc (1 + string_size);
  651. i = 0;
  652. while (i < string_size)
  653. {
  654. strncpy (string + i, incoming, incoming_length);
  655. i += incoming_length;
  656. }
  657. while (count)
  658. {
  659. decreaser = (count > TEXT_COUNT_MAX) ? TEXT_COUNT_MAX : count;
  660. string[decreaser*incoming_length] = '\0';
  661. rl_insert_text (string);
  662. count -= decreaser;
  663. }
  664. xfree (string);
  665. incoming_length = 0;
  666. stored_count = 0;
  667. #else /* !HANDLE_MULTIBYTE */
  668. char str[TEXT_COUNT_MAX+1];
  669. for (i = 0; i < TEXT_COUNT_MAX; i++)
  670. str[i] = c;
  671. while (count)
  672. {
  673. decreaser = (count > TEXT_COUNT_MAX ? TEXT_COUNT_MAX : count);
  674. str[decreaser] = '\0';
  675. rl_insert_text (str);
  676. count -= decreaser;
  677. }
  678. #endif /* !HANDLE_MULTIBYTE */
  679. return 0;
  680. }
  681. if (MB_CUR_MAX == 1 || rl_byte_oriented)
  682. {
  683. /* We are inserting a single character.
  684. If there is pending input, then make a string of all of the
  685. pending characters that are bound to rl_insert, and insert
  686. them all. Don't do this if we're current reading input from
  687. a macro. */
  688. if ((RL_ISSTATE (RL_STATE_MACROINPUT) == 0) && _rl_any_typein ())
  689. _rl_insert_typein (c);
  690. else
  691. {
  692. /* Inserting a single character. */
  693. char str[2];
  694. str[1] = '\0';
  695. str[0] = c;
  696. rl_insert_text (str);
  697. }
  698. }
  699. #if defined (HANDLE_MULTIBYTE)
  700. else
  701. {
  702. rl_insert_text (incoming);
  703. stored_count = 0;
  704. }
  705. #endif
  706. return 0;
  707. }
  708. /* Overwrite the character at point (or next COUNT characters) with C.
  709. If C introduces a multibyte character sequence, read the entire sequence
  710. before starting the overwrite loop. */
  711. int
  712. _rl_overwrite_char (count, c)
  713. int count, c;
  714. {
  715. int i;
  716. #if defined (HANDLE_MULTIBYTE)
  717. char mbkey[MB_LEN_MAX];
  718. int k;
  719. /* Read an entire multibyte character sequence to insert COUNT times. */
  720. if (count > 0 && MB_CUR_MAX > 1 && rl_byte_oriented == 0)
  721. k = _rl_read_mbstring (c, mbkey, MB_LEN_MAX);
  722. #endif
  723. rl_begin_undo_group ();
  724. for (i = 0; i < count; i++)
  725. {
  726. #if defined (HANDLE_MULTIBYTE)
  727. if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
  728. rl_insert_text (mbkey);
  729. else
  730. #endif
  731. _rl_insert_char (1, c);
  732. if (rl_point < rl_end)
  733. rl_delete (1, c);
  734. }
  735. rl_end_undo_group ();
  736. return 0;
  737. }
  738. int
  739. rl_insert (count, c)
  740. int count, c;
  741. {
  742. return (rl_insert_mode == RL_IM_INSERT ? _rl_insert_char (count, c)
  743. : _rl_overwrite_char (count, c));
  744. }
  745. /* Insert the next typed character verbatim. */
  746. static int
  747. _rl_insert_next (count)
  748. int count;
  749. {
  750. int c;
  751. RL_SETSTATE(RL_STATE_MOREINPUT);
  752. c = rl_read_key ();
  753. RL_UNSETSTATE(RL_STATE_MOREINPUT);
  754. if (c < 0)
  755. return -1;
  756. #if defined (HANDLE_SIGNALS)
  757. if (RL_ISSTATE (RL_STATE_CALLBACK) == 0)
  758. _rl_restore_tty_signals ();
  759. #endif
  760. return (_rl_insert_char (count, c));
  761. }
  762. #if defined (READLINE_CALLBACKS)
  763. static int
  764. _rl_insert_next_callback (data)
  765. _rl_callback_generic_arg *data;
  766. {
  767. int count;
  768. count = data->count;
  769. /* Deregister function, let rl_callback_read_char deallocate data */
  770. _rl_callback_func = 0;
  771. _rl_want_redisplay = 1;
  772. return _rl_insert_next (count);
  773. }
  774. #endif
  775. int
  776. rl_quoted_insert (count, key)
  777. int count, key;
  778. {
  779. /* Let's see...should the callback interface futz with signal handling? */
  780. #if defined (HANDLE_SIGNALS)
  781. if (RL_ISSTATE (RL_STATE_CALLBACK) == 0)
  782. _rl_disable_tty_signals ();
  783. #endif
  784. #if defined (READLINE_CALLBACKS)
  785. if (RL_ISSTATE (RL_STATE_CALLBACK))
  786. {
  787. _rl_callback_data = _rl_callback_data_alloc (count);
  788. _rl_callback_func = _rl_insert_next_callback;
  789. return (0);
  790. }
  791. #endif
  792. return _rl_insert_next (count);
  793. }
  794. /* Insert a tab character. */
  795. int
  796. rl_tab_insert (count, key)
  797. int count, key;
  798. {
  799. return (_rl_insert_char (count, '\t'));
  800. }
  801. /* What to do when a NEWLINE is pressed. We accept the whole line.
  802. KEY is the key that invoked this command. I guess it could have
  803. meaning in the future. */
  804. int
  805. rl_newline (count, key)
  806. int count, key;
  807. {
  808. rl_done = 1;
  809. if (_rl_history_preserve_point)
  810. _rl_history_saved_point = (rl_point == rl_end) ? -1 : rl_point;
  811. RL_SETSTATE(RL_STATE_DONE);
  812. #if defined (VI_MODE)
  813. if (rl_editing_mode == vi_mode)
  814. {
  815. _rl_vi_done_inserting ();
  816. if (_rl_vi_textmod_command (_rl_vi_last_command) == 0) /* XXX */
  817. _rl_vi_reset_last ();
  818. }
  819. #endif /* VI_MODE */
  820. /* If we've been asked to erase empty lines, suppress the final update,
  821. since _rl_update_final calls rl_crlf(). */
  822. if (rl_erase_empty_line && rl_point == 0 && rl_end == 0)
  823. return 0;
  824. if (_rl_echoing_p)
  825. _rl_update_final ();
  826. return 0;
  827. }
  828. /* What to do for some uppercase characters, like meta characters,
  829. and some characters appearing in emacs_ctlx_keymap. This function
  830. is just a stub, you bind keys to it and the code in _rl_dispatch ()
  831. is special cased. */
  832. int
  833. rl_do_lowercase_version (ignore1, ignore2)
  834. int ignore1, ignore2;
  835. {
  836. return 0;
  837. }
  838. /* This is different from what vi does, so the code's not shared. Emacs
  839. rubout in overwrite mode has one oddity: it replaces a control
  840. character that's displayed as two characters (^X) with two spaces. */
  841. int
  842. _rl_overwrite_rubout (count, key)
  843. int count, key;
  844. {
  845. int opoint;
  846. int i, l;
  847. if (rl_point == 0)
  848. {
  849. rl_ding ();
  850. return 1;
  851. }
  852. opoint = rl_point;
  853. /* L == number of spaces to insert */
  854. for (i = l = 0; i < count; i++)
  855. {
  856. rl_backward_char (1, key);
  857. l += rl_character_len (rl_line_buffer[rl_point], rl_point); /* not exactly right */
  858. }
  859. rl_begin_undo_group ();
  860. if (count > 1 || rl_explicit_arg)
  861. rl_kill_text (opoint, rl_point);
  862. else
  863. rl_delete_text (opoint, rl_point);
  864. /* Emacs puts point at the beginning of the sequence of spaces. */
  865. if (rl_point < rl_end)
  866. {
  867. opoint = rl_point;
  868. _rl_insert_char (l, ' ');
  869. rl_point = opoint;
  870. }
  871. rl_end_undo_group ();
  872. return 0;
  873. }
  874. /* Rubout the character behind point. */
  875. int
  876. rl_rubout (count, key)
  877. int count, key;
  878. {
  879. if (count < 0)
  880. return (rl_delete (-count, key));
  881. if (!rl_point)
  882. {
  883. rl_ding ();
  884. return -1;
  885. }
  886. if (rl_insert_mode == RL_IM_OVERWRITE)
  887. return (_rl_overwrite_rubout (count, key));
  888. return (_rl_rubout_char (count, key));
  889. }
  890. int
  891. _rl_rubout_char (count, key)
  892. int count, key;
  893. {
  894. int orig_point;
  895. unsigned char c;
  896. /* Duplicated code because this is called from other parts of the library. */
  897. if (count < 0)
  898. return (rl_delete (-count, key));
  899. if (rl_point == 0)
  900. {
  901. rl_ding ();
  902. return -1;
  903. }
  904. orig_point = rl_point;
  905. if (count > 1 || rl_explicit_arg)
  906. {
  907. rl_backward_char (count, key);
  908. rl_kill_text (orig_point, rl_point);
  909. }
  910. else if (MB_CUR_MAX == 1 || rl_byte_oriented)
  911. {
  912. c = rl_line_buffer[--rl_point];
  913. rl_delete_text (rl_point, orig_point);
  914. /* The erase-at-end-of-line hack is of questionable merit now. */
  915. if (rl_point == rl_end && ISPRINT (c) && _rl_last_c_pos)
  916. {
  917. int l;
  918. l = rl_character_len (c, rl_point);
  919. _rl_erase_at_end_of_line (l);
  920. }
  921. }
  922. else
  923. {
  924. rl_point = _rl_find_prev_mbchar (rl_line_buffer, rl_point, MB_FIND_NONZERO);
  925. rl_delete_text (rl_point, orig_point);
  926. }
  927. return 0;
  928. }
  929. /* Delete the character under the cursor. Given a numeric argument,
  930. kill that many characters instead. */
  931. int
  932. rl_delete (count, key)
  933. int count, key;
  934. {
  935. int xpoint;
  936. if (count < 0)
  937. return (_rl_rubout_char (-count, key));
  938. if (rl_point == rl_end)
  939. {
  940. rl_ding ();
  941. return -1;
  942. }
  943. if (count > 1 || rl_explicit_arg)
  944. {
  945. xpoint = rl_point;
  946. if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
  947. rl_forward_char (count, key);
  948. else
  949. rl_forward_byte (count, key);
  950. rl_kill_text (xpoint, rl_point);
  951. rl_point = xpoint;
  952. }
  953. else
  954. {
  955. xpoint = MB_NEXTCHAR (rl_line_buffer, rl_point, 1, MB_FIND_NONZERO);
  956. rl_delete_text (rl_point, xpoint);
  957. }
  958. return 0;
  959. }
  960. /* Delete the character under the cursor, unless the insertion
  961. point is at the end of the line, in which case the character
  962. behind the cursor is deleted. COUNT is obeyed and may be used
  963. to delete forward or backward that many characters. */
  964. int
  965. rl_rubout_or_delete (count, key)
  966. int count, key;
  967. {
  968. if (rl_end != 0 && rl_point == rl_end)
  969. return (_rl_rubout_char (count, key));
  970. else
  971. return (rl_delete (count, key));
  972. }
  973. /* Delete all spaces and tabs around point. */
  974. int
  975. rl_delete_horizontal_space (count, ignore)
  976. int count, ignore;
  977. {
  978. int start;
  979. while (rl_point && whitespace (rl_line_buffer[rl_point - 1]))
  980. rl_point--;
  981. start = rl_point;
  982. while (rl_point < rl_end && whitespace (rl_line_buffer[rl_point]))
  983. rl_point++;
  984. if (start != rl_point)
  985. {
  986. rl_delete_text (start, rl_point);
  987. rl_point = start;
  988. }
  989. if (rl_point < 0)
  990. rl_point = 0;
  991. return 0;
  992. }
  993. /* Like the tcsh editing function delete-char-or-list. The eof character
  994. is caught before this is invoked, so this really does the same thing as
  995. delete-char-or-list-or-eof, as long as it's bound to the eof character. */
  996. int
  997. rl_delete_or_show_completions (count, key)
  998. int count, key;
  999. {
  1000. if (rl_end != 0 && rl_point == rl_end)
  1001. return (rl_possible_completions (count, key));
  1002. else
  1003. return (rl_delete (count, key));
  1004. }
  1005. #ifndef RL_COMMENT_BEGIN_DEFAULT
  1006. #define RL_COMMENT_BEGIN_DEFAULT "#"
  1007. #endif
  1008. /* Turn the current line into a comment in shell history.
  1009. A K*rn shell style function. */
  1010. int
  1011. rl_insert_comment (count, key)
  1012. int count, key;
  1013. {
  1014. char *rl_comment_text;
  1015. int rl_comment_len;
  1016. rl_beg_of_line (1, key);
  1017. rl_comment_text = _rl_comment_begin ? _rl_comment_begin : RL_COMMENT_BEGIN_DEFAULT;
  1018. if (rl_explicit_arg == 0)
  1019. rl_insert_text (rl_comment_text);
  1020. else
  1021. {
  1022. rl_comment_len = strlen (rl_comment_text);
  1023. if (STREQN (rl_comment_text, rl_line_buffer, rl_comment_len))
  1024. rl_delete_text (rl_point, rl_point + rl_comment_len);
  1025. else
  1026. rl_insert_text (rl_comment_text);
  1027. }
  1028. (*rl_redisplay_function) ();
  1029. rl_newline (1, '\n');
  1030. return (0);
  1031. }
  1032. /* **************************************************************** */
  1033. /* */
  1034. /* Changing Case */
  1035. /* */
  1036. /* **************************************************************** */
  1037. /* The three kinds of things that we know how to do. */
  1038. #define UpCase 1
  1039. #define DownCase 2
  1040. #define CapCase 3
  1041. /* Uppercase the word at point. */
  1042. int
  1043. rl_upcase_word (count, key)
  1044. int count, key;
  1045. {
  1046. return (rl_change_case (count, UpCase));
  1047. }
  1048. /* Lowercase the word at point. */
  1049. int
  1050. rl_downcase_word (count, key)
  1051. int count, key;
  1052. {
  1053. return (rl_change_case (count, DownCase));
  1054. }
  1055. /* Upcase the first letter, downcase the rest. */
  1056. int
  1057. rl_capitalize_word (count, key)
  1058. int count, key;
  1059. {
  1060. return (rl_change_case (count, CapCase));
  1061. }
  1062. /* The meaty function.
  1063. Change the case of COUNT words, performing OP on them.
  1064. OP is one of UpCase, DownCase, or CapCase.
  1065. If a negative argument is given, leave point where it started,
  1066. otherwise, leave it where it moves to. */
  1067. static int
  1068. rl_change_case (count, op)
  1069. int count, op;
  1070. {
  1071. int start, next, end;
  1072. int inword, c, nc, nop;
  1073. #if defined (HANDLE_MULTIBYTE)
  1074. wchar_t wc, nwc;
  1075. char mb[MB_LEN_MAX+1];
  1076. int mlen;
  1077. size_t m;
  1078. mbstate_t mps;
  1079. #endif
  1080. start = rl_point;
  1081. rl_forward_word (count, 0);
  1082. end = rl_point;
  1083. if (op != UpCase && op != DownCase && op != CapCase)
  1084. {
  1085. rl_ding ();
  1086. return -1;
  1087. }
  1088. if (count < 0)
  1089. SWAP (start, end);
  1090. #if defined (HANDLE_MULTIBYTE)
  1091. memset (&mps, 0, sizeof (mbstate_t));
  1092. #endif
  1093. /* We are going to modify some text, so let's prepare to undo it. */
  1094. rl_modifying (start, end);
  1095. inword = 0;
  1096. while (start < end)
  1097. {
  1098. c = _rl_char_value (rl_line_buffer, start);
  1099. /* This assumes that the upper and lower case versions are the same width. */
  1100. next = MB_NEXTCHAR (rl_line_buffer, start, 1, MB_FIND_NONZERO);
  1101. if (_rl_walphabetic (c) == 0)
  1102. {
  1103. inword = 0;
  1104. start = next;
  1105. continue;
  1106. }
  1107. if (op == CapCase)
  1108. {
  1109. nop = inword ? DownCase : UpCase;
  1110. inword = 1;
  1111. }
  1112. else
  1113. nop = op;
  1114. if (MB_CUR_MAX == 1 || rl_byte_oriented || isascii (c))
  1115. {
  1116. nc = (nop == UpCase) ? _rl_to_upper (c) : _rl_to_lower (c);
  1117. rl_line_buffer[start] = nc;
  1118. }
  1119. #if defined (HANDLE_MULTIBYTE)
  1120. else
  1121. {
  1122. m = mbrtowc (&wc, rl_line_buffer + start, end - start, &mps);
  1123. if (MB_INVALIDCH (m))
  1124. wc = (wchar_t)rl_line_buffer[start];
  1125. else if (MB_NULLWCH (m))
  1126. wc = L'\0';
  1127. nwc = (nop == UpCase) ? _rl_to_wupper (wc) : _rl_to_wlower (wc);
  1128. if (nwc != wc) /* just skip unchanged characters */
  1129. {
  1130. mlen = wcrtomb (mb, nwc, &mps);
  1131. if (mlen > 0)
  1132. mb[mlen] = '\0';
  1133. /* Assume the same width */
  1134. strncpy (rl_line_buffer + start, mb, mlen);
  1135. }
  1136. }
  1137. #endif
  1138. start = next;
  1139. }
  1140. rl_point = end;
  1141. return 0;
  1142. }
  1143. /* **************************************************************** */
  1144. /* */
  1145. /* Transposition */
  1146. /* */
  1147. /* **************************************************************** */
  1148. /* Transpose the words at point. If point is at the end of the line,
  1149. transpose the two words before point. */
  1150. int
  1151. rl_transpose_words (count, key)
  1152. int count, key;
  1153. {
  1154. char *word1, *word2;
  1155. int w1_beg, w1_end, w2_beg, w2_end;
  1156. int orig_point = rl_point;
  1157. if (!count)
  1158. return 0;
  1159. /* Find the two words. */
  1160. rl_forward_word (count, key);
  1161. w2_end = rl_point;
  1162. rl_backward_word (1, key);
  1163. w2_beg = rl_point;
  1164. rl_backward_word (count, key);
  1165. w1_beg = rl_point;
  1166. rl_forward_word (1, key);
  1167. w1_end = rl_point;
  1168. /* Do some check to make sure that there really are two words. */
  1169. if ((w1_beg == w2_beg) || (w2_beg < w1_end))
  1170. {
  1171. rl_ding ();
  1172. rl_point = orig_point;
  1173. return -1;
  1174. }
  1175. /* Get the text of the words. */
  1176. word1 = rl_copy_text (w1_beg, w1_end);
  1177. word2 = rl_copy_text (w2_beg, w2_end);
  1178. /* We are about to do many insertions and deletions. Remember them
  1179. as one operation. */
  1180. rl_begin_undo_group ();
  1181. /* Do the stuff at word2 first, so that we don't have to worry
  1182. about word1 moving. */
  1183. rl_point = w2_beg;
  1184. rl_delete_text (w2_beg, w2_end);
  1185. rl_insert_text (word1);
  1186. rl_point = w1_beg;
  1187. rl_delete_text (w1_beg, w1_end);
  1188. rl_insert_text (word2);
  1189. /* This is exactly correct since the text before this point has not
  1190. changed in length. */
  1191. rl_point = w2_end;
  1192. /* I think that does it. */
  1193. rl_end_undo_group ();
  1194. xfree (word1);
  1195. xfree (word2);
  1196. return 0;
  1197. }
  1198. /* Transpose the characters at point. If point is at the end of the line,
  1199. then transpose the characters before point. */
  1200. int
  1201. rl_transpose_chars (count, key)
  1202. int count, key;
  1203. {
  1204. #if defined (HANDLE_MULTIBYTE)
  1205. char *dummy;
  1206. int i;
  1207. #else
  1208. char dummy[2];
  1209. #endif
  1210. int char_length, prev_point;
  1211. if (count == 0)
  1212. return 0;
  1213. if (!rl_point || rl_end < 2)
  1214. {
  1215. rl_ding ();
  1216. return -1;
  1217. }
  1218. rl_begin_undo_group ();
  1219. if (rl_point == rl_end)
  1220. {
  1221. rl_point = MB_PREVCHAR (rl_line_buffer, rl_point, MB_FIND_NONZERO);
  1222. count = 1;
  1223. }
  1224. prev_point = rl_point;
  1225. rl_point = MB_PREVCHAR (rl_line_buffer, rl_point, MB_FIND_NONZERO);
  1226. #if defined (HANDLE_MULTIBYTE)
  1227. char_length = prev_point - rl_point;
  1228. dummy = (char *)xmalloc (char_length + 1);
  1229. for (i = 0; i < char_length; i++)
  1230. dummy[i] = rl_line_buffer[rl_point + i];
  1231. dummy[i] = '\0';
  1232. #else
  1233. dummy[0] = rl_line_buffer[rl_point];
  1234. dummy[char_length = 1] = '\0';
  1235. #endif
  1236. rl_delete_text (rl_point, rl_point + char_length);
  1237. rl_point = _rl_find_next_mbchar (rl_line_buffer, rl_point, count, MB_FIND_NONZERO);
  1238. _rl_fix_point (0);
  1239. rl_insert_text (dummy);
  1240. rl_end_undo_group ();
  1241. #if defined (HANDLE_MULTIBYTE)
  1242. xfree (dummy);
  1243. #endif
  1244. return 0;
  1245. }
  1246. /* **************************************************************** */
  1247. /* */
  1248. /* Character Searching */
  1249. /* */
  1250. /* **************************************************************** */
  1251. int
  1252. #if defined (HANDLE_MULTIBYTE)
  1253. _rl_char_search_internal (count, dir, smbchar, len)
  1254. int count, dir;
  1255. char *smbchar;
  1256. int len;
  1257. #else
  1258. _rl_char_search_internal (count, dir, schar)
  1259. int count, dir, schar;
  1260. #endif
  1261. {
  1262. int pos, inc;
  1263. #if defined (HANDLE_MULTIBYTE)
  1264. int prepos;
  1265. #endif
  1266. if (dir == 0)
  1267. return -1;
  1268. pos = rl_point;
  1269. inc = (dir < 0) ? -1 : 1;
  1270. while (count)
  1271. {
  1272. if ((dir < 0 && pos <= 0) || (dir > 0 && pos >= rl_end))
  1273. {
  1274. rl_ding ();
  1275. return -1;
  1276. }
  1277. #if defined (HANDLE_MULTIBYTE)
  1278. pos = (inc > 0) ? _rl_find_next_mbchar (rl_line_buffer, pos, 1, MB_FIND_ANY)
  1279. : _rl_find_prev_mbchar (rl_line_buffer, pos, MB_FIND_ANY);
  1280. #else
  1281. pos += inc;
  1282. #endif
  1283. do
  1284. {
  1285. #if defined (HANDLE_MULTIBYTE)
  1286. if (_rl_is_mbchar_matched (rl_line_buffer, pos, rl_end, smbchar, len))
  1287. #else
  1288. if (rl_line_buffer[pos] == schar)
  1289. #endif
  1290. {
  1291. count--;
  1292. if (dir < 0)
  1293. rl_point = (dir == BTO) ? _rl_find_next_mbchar (rl_line_buffer, pos, 1, MB_FIND_ANY)
  1294. : pos;
  1295. else
  1296. rl_point = (dir == FTO) ? _rl_find_prev_mbchar (rl_line_buffer, pos, MB_FIND_ANY)
  1297. : pos;
  1298. break;
  1299. }
  1300. #if defined (HANDLE_MULTIBYTE)
  1301. prepos = pos;
  1302. #endif
  1303. }
  1304. #if defined (HANDLE_MULTIBYTE)
  1305. while ((dir < 0) ? (pos = _rl_find_prev_mbchar (rl_line_buffer, pos, MB_FIND_ANY)) != prepos
  1306. : (pos = _rl_find_next_mbchar (rl_line_buffer, pos, 1, MB_FIND_ANY)) != prepos);
  1307. #else
  1308. while ((dir < 0) ? pos-- : ++pos < rl_end);
  1309. #endif
  1310. }
  1311. return (0);
  1312. }
  1313. /* Search COUNT times for a character read from the current input stream.
  1314. FDIR is the direction to search if COUNT is non-negative; otherwise
  1315. the search goes in BDIR. So much is dependent on HANDLE_MULTIBYTE
  1316. that there are two separate versions of this function. */
  1317. #if defined (HANDLE_MULTIBYTE)
  1318. static int
  1319. _rl_char_search (count, fdir, bdir)
  1320. int count, fdir, bdir;
  1321. {
  1322. char mbchar[MB_LEN_MAX];
  1323. int mb_len;
  1324. mb_len = _rl_read_mbchar (mbchar, MB_LEN_MAX);
  1325. if (mb_len <= 0)
  1326. return -1;
  1327. if (count < 0)
  1328. return (_rl_char_search_internal (-count, bdir, mbchar, mb_len));
  1329. else
  1330. return (_rl_char_search_internal (count, fdir, mbchar, mb_len));
  1331. }
  1332. #else /* !HANDLE_MULTIBYTE */
  1333. static int
  1334. _rl_char_search (count, fdir, bdir)
  1335. int count, fdir, bdir;
  1336. {
  1337. int c;
  1338. RL_SETSTATE(RL_STATE_MOREINPUT);
  1339. c = rl_read_key ();
  1340. RL_UNSETSTATE(RL_STATE_MOREINPUT);
  1341. if (c < 0)
  1342. return -1;
  1343. if (count < 0)
  1344. return (_rl_char_search_internal (-count, bdir, c));
  1345. else
  1346. return (_rl_char_search_internal (count, fdir, c));
  1347. }
  1348. #endif /* !HANDLE_MULTIBYTE */
  1349. #if defined (READLINE_CALLBACKS)
  1350. static int
  1351. _rl_char_search_callback (data)
  1352. _rl_callback_generic_arg *data;
  1353. {
  1354. _rl_callback_func = 0;
  1355. _rl_want_redisplay = 1;
  1356. return (_rl_char_search (data->count, data->i1, data->i2));
  1357. }
  1358. #endif
  1359. int
  1360. rl_char_search (count, key)
  1361. int count, key;
  1362. {
  1363. #if defined (READLINE_CALLBACKS)
  1364. if (RL_ISSTATE (RL_STATE_CALLBACK))
  1365. {
  1366. _rl_callback_data = _rl_callback_data_alloc (count);
  1367. _rl_callback_data->i1 = FFIND;
  1368. _rl_callback_data->i2 = BFIND;
  1369. _rl_callback_func = _rl_char_search_callback;
  1370. return (0);
  1371. }
  1372. #endif
  1373. return (_rl_char_search (count, FFIND, BFIND));
  1374. }
  1375. int
  1376. rl_backward_char_search (count, key)
  1377. int count, key;
  1378. {
  1379. #if defined (READLINE_CALLBACKS)
  1380. if (RL_ISSTATE (RL_STATE_CALLBACK))
  1381. {
  1382. _rl_callback_data = _rl_callback_data_alloc (count);
  1383. _rl_callback_data->i1 = BFIND;
  1384. _rl_callback_data->i2 = FFIND;
  1385. _rl_callback_func = _rl_char_search_callback;
  1386. return (0);
  1387. }
  1388. #endif
  1389. return (_rl_char_search (count, BFIND, FFIND));
  1390. }
  1391. /* **************************************************************** */
  1392. /* */
  1393. /* The Mark and the Region. */
  1394. /* */
  1395. /* **************************************************************** */
  1396. /* Set the mark at POSITION. */
  1397. int
  1398. _rl_set_mark_at_pos (position)
  1399. int position;
  1400. {
  1401. if (position > rl_end)
  1402. return -1;
  1403. rl_mark = position;
  1404. return 0;
  1405. }
  1406. /* A bindable command to set the mark. */
  1407. int
  1408. rl_set_mark (count, key)
  1409. int count, key;
  1410. {
  1411. return (_rl_set_mark_at_pos (rl_explicit_arg ? count : rl_point));
  1412. }
  1413. /* Exchange the position of mark and point. */
  1414. int
  1415. rl_exchange_point_and_mark (count, key)
  1416. int count, key;
  1417. {
  1418. if (rl_mark > rl_end)
  1419. rl_mark = -1;
  1420. if (rl_mark == -1)
  1421. {
  1422. rl_ding ();
  1423. return -1;
  1424. }
  1425. else
  1426. SWAP (rl_point, rl_mark);
  1427. return 0;
  1428. }