AArch64: Fix LD crash on weak and undefined TLS symbols. (PR/24602).
[external/binutils.git] / readline / search.c
1 /* search.c - code for non-incremental searching in emacs and vi modes. */
2
3 /* Copyright (C) 1992-2017 Free Software Foundation, Inc.
4
5    This file is part of the GNU Readline Library (Readline), a library
6    for reading lines of text with interactive input and history editing.      
7
8    Readline is free software: you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation, either version 3 of the License, or
11    (at your option) any later version.
12
13    Readline is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17
18    You should have received a copy of the GNU General Public License
19    along with Readline.  If not, see <http://www.gnu.org/licenses/>.
20 */
21
22 #define READLINE_LIBRARY
23
24 #if defined (HAVE_CONFIG_H)
25 #  include <config.h>
26 #endif
27
28 #include <sys/types.h>
29 #include <stdio.h>
30
31 #if defined (HAVE_UNISTD_H)
32 #  include <unistd.h>
33 #endif
34
35 #if defined (HAVE_STDLIB_H)
36 #  include <stdlib.h>
37 #else
38 #  include "ansi_stdlib.h"
39 #endif
40
41 #include "rldefs.h"
42 #include "rlmbutil.h"
43
44 #include "readline.h"
45 #include "history.h"
46 #include "histlib.h"
47
48 #include "rlprivate.h"
49 #include "xmalloc.h"
50
51 #ifdef abs
52 #  undef abs
53 #endif
54 #define abs(x)          (((x) >= 0) ? (x) : -(x))
55
56 _rl_search_cxt *_rl_nscxt = 0;
57
58 extern HIST_ENTRY *_rl_saved_line_for_history;
59
60 /* Functions imported from the rest of the library. */
61 extern void _rl_free_history_entry PARAMS((HIST_ENTRY *));
62
63 static char *noninc_search_string = (char *) NULL;
64 static int noninc_history_pos;
65
66 static char *prev_line_found = (char *) NULL;
67
68 static int rl_history_search_len;
69 static int rl_history_search_pos;
70 static int rl_history_search_flags;
71
72 static char *history_search_string;
73 static int history_string_size;
74
75 static void make_history_line_current PARAMS((HIST_ENTRY *));
76 static int noninc_search_from_pos PARAMS((char *, int, int, int, int *));
77 static int noninc_dosearch PARAMS((char *, int, int));
78 static int noninc_search PARAMS((int, int));
79 static int rl_history_search_internal PARAMS((int, int));
80 static void rl_history_search_reinit PARAMS((int));
81
82 static _rl_search_cxt *_rl_nsearch_init PARAMS((int, int));
83 static void _rl_nsearch_abort PARAMS((_rl_search_cxt *));
84 static int _rl_nsearch_dispatch PARAMS((_rl_search_cxt *, int));
85
86 /* Make the data from the history entry ENTRY be the contents of the
87    current line.  This doesn't do anything with rl_point; the caller
88    must set it. */
89 static void
90 make_history_line_current (HIST_ENTRY *entry)
91 {
92   _rl_replace_text (entry->line, 0, rl_end);
93   _rl_fix_point (1);
94 #if defined (VI_MODE)
95   if (rl_editing_mode == vi_mode)
96     /* POSIX.2 says that the `U' command doesn't affect the copy of any
97        command lines to the edit line.  We're going to implement that by
98        making the undo list start after the matching line is copied to the
99        current editing buffer. */
100     rl_free_undo_list ();
101 #endif
102
103   if (_rl_saved_line_for_history)
104     _rl_free_history_entry (_rl_saved_line_for_history);
105   _rl_saved_line_for_history = (HIST_ENTRY *)NULL;
106 }
107
108 /* Search the history list for STRING starting at absolute history position
109    POS.  If STRING begins with `^', the search must match STRING at the
110    beginning of a history line, otherwise a full substring match is performed
111    for STRING.  DIR < 0 means to search backwards through the history list,
112    DIR >= 0 means to search forward. */
113 static int
114 noninc_search_from_pos (char *string, int pos, int dir, int flags, int *ncp)
115 {
116   int ret, old, sflags;
117   char *s;
118
119   if (pos < 0)
120     return -1;
121
122   old = where_history ();
123   if (history_set_pos (pos) == 0)
124     return -1;
125
126   RL_SETSTATE(RL_STATE_SEARCH);
127   /* These functions return the match offset in the line; history_offset gives
128      the matching line in the history list */
129   if (flags & SF_PATTERN)
130     {
131       s = string;
132       sflags = 0;               /* Non-anchored search */
133       if (*s == '^')
134         {
135           sflags |= ANCHORED_SEARCH;
136           s++;
137         }
138       ret = _hs_history_patsearch (s, dir, sflags);
139     }
140   else if (*string == '^')
141     ret = history_search_prefix (string + 1, dir);
142   else
143     ret = history_search (string, dir);
144   RL_UNSETSTATE(RL_STATE_SEARCH);
145
146   if (ncp)
147     *ncp = ret;         /* caller will catch -1 to indicate no-op */
148
149   if (ret != -1)
150     ret = where_history ();
151
152   history_set_pos (old);
153   return (ret);
154 }
155
156 /* Search for a line in the history containing STRING.  If DIR is < 0, the
157    search is backwards through previous entries, else through subsequent
158    entries.  Returns 1 if the search was successful, 0 otherwise. */
159 static int
160 noninc_dosearch (char *string, int dir, int flags)
161 {
162   int oldpos, pos;
163   HIST_ENTRY *entry;
164
165   if (string == 0 || *string == '\0' || noninc_history_pos < 0)
166     {
167       rl_ding ();
168       return 0;
169     }
170
171   pos = noninc_search_from_pos (string, noninc_history_pos + dir, dir, flags, (int *)0);
172   if (pos == -1)
173     {
174       /* Search failed, current history position unchanged. */
175       rl_maybe_unsave_line ();
176       rl_clear_message ();
177       rl_point = 0;
178       rl_ding ();
179       return 0;
180     }
181
182   noninc_history_pos = pos;
183
184   oldpos = where_history ();
185   history_set_pos (noninc_history_pos);
186   entry = current_history ();           /* will never be NULL after successful search */
187   
188 #if defined (VI_MODE)
189   if (rl_editing_mode != vi_mode)
190 #endif
191     history_set_pos (oldpos);
192
193   make_history_line_current (entry);
194
195   rl_point = 0;
196   rl_mark = rl_end;
197
198   rl_clear_message ();
199   return 1;
200 }
201
202 static _rl_search_cxt *
203 _rl_nsearch_init (int dir, int pchar)
204 {
205   _rl_search_cxt *cxt;
206   char *p;
207
208   cxt = _rl_scxt_alloc (RL_SEARCH_NSEARCH, 0);
209   if (dir < 0)
210     cxt->sflags |= SF_REVERSE;          /* not strictly needed */
211 #if defined (VI_MODE)
212   if (VI_COMMAND_MODE() && (pchar == '?' || pchar == '/'))
213     cxt->sflags |= SF_PATTERN;
214 #endif
215
216   cxt->direction = dir;
217   cxt->history_pos = cxt->save_line;
218
219   rl_maybe_save_line ();
220
221   /* Clear the undo list, since reading the search string should create its
222      own undo list, and the whole list will end up being freed when we
223      finish reading the search string. */
224   rl_undo_list = 0;
225
226   /* Use the line buffer to read the search string. */
227   rl_line_buffer[0] = 0;
228   rl_end = rl_point = 0;
229
230   p = _rl_make_prompt_for_search (pchar ? pchar : ':');
231   rl_message ("%s", p);
232   xfree (p);
233
234   RL_SETSTATE(RL_STATE_NSEARCH);
235
236   _rl_nscxt = cxt;
237
238   return cxt;
239 }
240
241 int
242 _rl_nsearch_cleanup (_rl_search_cxt *cxt, int r)
243 {
244   _rl_scxt_dispose (cxt, 0);
245   _rl_nscxt = 0;
246
247   RL_UNSETSTATE(RL_STATE_NSEARCH);
248
249   return (r != 1);
250 }
251
252 static void
253 _rl_nsearch_abort (_rl_search_cxt *cxt)
254 {
255   rl_maybe_unsave_line ();
256   rl_clear_message ();
257   rl_point = cxt->save_point;
258   rl_mark = cxt->save_mark;
259   rl_restore_prompt ();
260
261   RL_UNSETSTATE (RL_STATE_NSEARCH);
262 }
263
264 /* Process just-read character C according to search context CXT.  Return -1
265    if the caller should abort the search, 0 if we should break out of the
266    loop, and 1 if we should continue to read characters. */
267 static int
268 _rl_nsearch_dispatch (_rl_search_cxt *cxt, int c)
269 {
270   if (c < 0)
271     c = CTRL ('C');  
272
273   switch (c)
274     {
275     case CTRL('W'):
276       rl_unix_word_rubout (1, c);
277       break;
278
279     case CTRL('U'):
280       rl_unix_line_discard (1, c);
281       break;
282
283     case RETURN:
284     case NEWLINE:
285       return 0;
286
287     case CTRL('H'):
288     case RUBOUT:
289       if (rl_point == 0)
290         {
291           _rl_nsearch_abort (cxt);
292           return -1;
293         }
294       _rl_rubout_char (1, c);
295       break;
296
297     case CTRL('C'):
298     case CTRL('G'):
299       rl_ding ();
300       _rl_nsearch_abort (cxt);
301       return -1;
302
303     default:
304 #if defined (HANDLE_MULTIBYTE)
305       if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
306         rl_insert_text (cxt->mb);
307       else
308 #endif
309         _rl_insert_char (1, c);
310       break;
311     }
312
313   (*rl_redisplay_function) ();
314   return 1;
315 }
316
317 /* Perform one search according to CXT, using NONINC_SEARCH_STRING.  Return
318    -1 if the search should be aborted, any other value means to clean up
319    using _rl_nsearch_cleanup ().  Returns 1 if the search was successful,
320    0 otherwise. */
321 static int
322 _rl_nsearch_dosearch (_rl_search_cxt *cxt)
323 {
324   rl_mark = cxt->save_mark;
325
326   /* If rl_point == 0, we want to re-use the previous search string and
327      start from the saved history position.  If there's no previous search
328      string, punt. */
329   if (rl_point == 0)
330     {
331       if (noninc_search_string == 0)
332         {
333           rl_ding ();
334           rl_restore_prompt ();
335           RL_UNSETSTATE (RL_STATE_NSEARCH);
336           return -1;
337         }
338     }
339   else
340     {
341       /* We want to start the search from the current history position. */
342       noninc_history_pos = cxt->save_line;
343       FREE (noninc_search_string);
344       noninc_search_string = savestring (rl_line_buffer);
345
346       /* If we don't want the subsequent undo list generated by the search
347          matching a history line to include the contents of the search string,
348          we need to clear rl_line_buffer here.  For now, we just clear the
349          undo list generated by reading the search string.  (If the search
350          fails, the old undo list will be restored by rl_maybe_unsave_line.) */
351       rl_free_undo_list ();
352     }
353
354   rl_restore_prompt ();
355   return (noninc_dosearch (noninc_search_string, cxt->direction, cxt->sflags&SF_PATTERN));
356 }
357
358 /* Search non-interactively through the history list.  DIR < 0 means to
359    search backwards through the history of previous commands; otherwise
360    the search is for commands subsequent to the current position in the
361    history list.  PCHAR is the character to use for prompting when reading
362    the search string; if not specified (0), it defaults to `:'. */
363 static int
364 noninc_search (int dir, int pchar)
365 {
366   _rl_search_cxt *cxt;
367   int c, r;
368
369   cxt = _rl_nsearch_init (dir, pchar);
370
371   if (RL_ISSTATE (RL_STATE_CALLBACK))
372     return (0);
373
374   /* Read the search string. */
375   r = 0;
376   while (1)
377     {
378       c = _rl_search_getchar (cxt);
379
380       if (c < 0)
381         {
382           _rl_nsearch_abort (cxt);
383           return 1;
384         }
385           
386       if (c == 0)
387         break;
388
389       r = _rl_nsearch_dispatch (cxt, c);
390       if (r < 0)
391         return 1;
392       else if (r == 0)
393         break;        
394     }
395
396   r = _rl_nsearch_dosearch (cxt);
397   return ((r >= 0) ? _rl_nsearch_cleanup (cxt, r) : (r != 1));
398 }
399
400 /* Search forward through the history list for a string.  If the vi-mode
401    code calls this, KEY will be `?'. */
402 int
403 rl_noninc_forward_search (int count, int key)
404 {
405   return noninc_search (1, (key == '?') ? '?' : 0);
406 }
407
408 /* Reverse search the history list for a string.  If the vi-mode code
409    calls this, KEY will be `/'. */
410 int
411 rl_noninc_reverse_search (int count, int key)
412 {
413   return noninc_search (-1, (key == '/') ? '/' : 0);
414 }
415
416 /* Search forward through the history list for the last string searched
417    for.  If there is no saved search string, abort.  If the vi-mode code
418    calls this, KEY will be `N'. */
419 int
420 rl_noninc_forward_search_again (int count, int key)
421 {
422   int r;
423
424   if (!noninc_search_string)
425     {
426       rl_ding ();
427       return (1);
428     }
429 #if defined (VI_MODE)
430   if (VI_COMMAND_MODE() && key == 'N')
431     r = noninc_dosearch (noninc_search_string, 1, SF_PATTERN);
432   else
433 #endif
434     r = noninc_dosearch (noninc_search_string, 1, 0);
435   return (r != 1);
436 }
437
438 /* Reverse search in the history list for the last string searched
439    for.  If there is no saved search string, abort.  If the vi-mode code
440    calls this, KEY will be `n'. */
441 int
442 rl_noninc_reverse_search_again (int count, int key)
443 {
444   int r;
445
446   if (!noninc_search_string)
447     {
448       rl_ding ();
449       return (1);
450     }
451 #if defined (VI_MODE)
452   if (VI_COMMAND_MODE() && key == 'n')
453     r = noninc_dosearch (noninc_search_string, -1, SF_PATTERN);
454   else
455 #endif
456     r = noninc_dosearch (noninc_search_string, -1, 0);
457   return (r != 1);
458 }
459
460 #if defined (READLINE_CALLBACKS)
461 int
462 _rl_nsearch_callback (_rl_search_cxt *cxt)
463 {
464   int c, r;
465
466   c = _rl_search_getchar (cxt);
467   if (c <= 0)
468     {
469       if (c < 0)
470         _rl_nsearch_abort (cxt);
471       return 1;
472     }
473   r = _rl_nsearch_dispatch (cxt, c);
474   if (r != 0)
475     return 1;
476
477   r = _rl_nsearch_dosearch (cxt);
478   return ((r >= 0) ? _rl_nsearch_cleanup (cxt, r) : (r != 1));
479 }
480 #endif
481   
482 static int
483 rl_history_search_internal (int count, int dir)
484 {
485   HIST_ENTRY *temp;
486   int ret, oldpos, newcol;
487   char *t;
488
489   rl_maybe_save_line ();
490   temp = (HIST_ENTRY *)NULL;
491
492   /* Search COUNT times through the history for a line matching
493      history_search_string.  If history_search_string[0] == '^', the
494      line must match from the start; otherwise any substring can match.
495      When this loop finishes, TEMP, if non-null, is the history line to
496      copy into the line buffer. */
497   while (count)
498     {
499       RL_CHECK_SIGNALS ();
500       ret = noninc_search_from_pos (history_search_string, rl_history_search_pos + dir, dir, 0, &newcol);
501       if (ret == -1)
502         break;
503
504       /* Get the history entry we found. */
505       rl_history_search_pos = ret;
506       oldpos = where_history ();
507       history_set_pos (rl_history_search_pos);
508       temp = current_history ();        /* will never be NULL after successful search */
509       history_set_pos (oldpos);
510
511       /* Don't find multiple instances of the same line. */
512       if (prev_line_found && STREQ (prev_line_found, temp->line))
513         continue;
514       prev_line_found = temp->line;
515       count--;
516     }
517
518   /* If we didn't find anything at all, return. */
519   if (temp == 0)
520     {
521       rl_maybe_unsave_line ();
522       rl_ding ();
523       /* If you don't want the saved history line (last match) to show up
524          in the line buffer after the search fails, change the #if 0 to
525          #if 1 */
526 #if 0
527       if (rl_point > rl_history_search_len)
528         {
529           rl_point = rl_end = rl_history_search_len;
530           rl_line_buffer[rl_end] = '\0';
531           rl_mark = 0;
532         }
533 #else
534       rl_point = rl_history_search_len; /* rl_maybe_unsave_line changes it */
535       rl_mark = rl_end;
536 #endif
537       return 1;
538     }
539
540   /* Copy the line we found into the current line buffer. */
541   make_history_line_current (temp);
542
543   /* decide where to put rl_point -- need to change this for pattern search */
544   if (rl_history_search_flags & ANCHORED_SEARCH)
545     rl_point = rl_history_search_len;   /* easy case */
546   else
547     {
548 #if 0
549       t = strstr (rl_line_buffer, history_search_string);       /* XXX */
550       rl_point = t ? (int)(t - rl_line_buffer) + rl_history_search_len : rl_end;
551 #else
552       rl_point = (newcol >= 0) ? newcol : rl_end;
553 #endif
554     }
555   rl_mark = rl_end;
556
557   return 0;
558 }
559
560 static void
561 rl_history_search_reinit (int flags)
562 {
563   int sind;
564
565   rl_history_search_pos = where_history ();
566   rl_history_search_len = rl_point;
567   rl_history_search_flags = flags;
568
569   prev_line_found = (char *)NULL;
570   if (rl_point)
571     {
572       /* Allocate enough space for anchored and non-anchored searches */
573       if (rl_history_search_len >= history_string_size - 2)
574         {
575           history_string_size = rl_history_search_len + 2;
576           history_search_string = (char *)xrealloc (history_search_string, history_string_size);
577         }
578       sind = 0;
579       if (flags & ANCHORED_SEARCH)
580         history_search_string[sind++] = '^';
581       strncpy (history_search_string + sind, rl_line_buffer, rl_point);
582       history_search_string[rl_point + sind] = '\0';
583     }
584   _rl_free_saved_history_line ();
585 }
586
587 /* Search forward in the history for the string of characters
588    from the start of the line to rl_point.  This is a non-incremental
589    search.  The search is anchored to the beginning of the history line. */
590 int
591 rl_history_search_forward (int count, int ignore)
592 {
593   if (count == 0)
594     return (0);
595
596   if (rl_last_func != rl_history_search_forward &&
597       rl_last_func != rl_history_search_backward)
598     rl_history_search_reinit (ANCHORED_SEARCH);
599
600   if (rl_history_search_len == 0)
601     return (rl_get_next_history (count, ignore));
602   return (rl_history_search_internal (abs (count), (count > 0) ? 1 : -1));
603 }
604
605 /* Search backward through the history for the string of characters
606    from the start of the line to rl_point.  This is a non-incremental
607    search. */
608 int
609 rl_history_search_backward (int count, int ignore)
610 {
611   if (count == 0)
612     return (0);
613
614   if (rl_last_func != rl_history_search_forward &&
615       rl_last_func != rl_history_search_backward)
616     rl_history_search_reinit (ANCHORED_SEARCH);
617
618   if (rl_history_search_len == 0)
619     return (rl_get_previous_history (count, ignore));
620   return (rl_history_search_internal (abs (count), (count > 0) ? -1 : 1));
621 }
622
623 /* Search forward in the history for the string of characters
624    from the start of the line to rl_point.  This is a non-incremental
625    search.  The search succeeds if the search string is present anywhere
626    in the history line. */
627 int
628 rl_history_substr_search_forward (int count, int ignore)
629 {
630   if (count == 0)
631     return (0);
632
633   if (rl_last_func != rl_history_substr_search_forward &&
634       rl_last_func != rl_history_substr_search_backward)
635     rl_history_search_reinit (NON_ANCHORED_SEARCH);
636
637   if (rl_history_search_len == 0)
638     return (rl_get_next_history (count, ignore));
639   return (rl_history_search_internal (abs (count), (count > 0) ? 1 : -1));
640 }
641
642 /* Search backward through the history for the string of characters
643    from the start of the line to rl_point.  This is a non-incremental
644    search. */
645 int
646 rl_history_substr_search_backward (int count, int ignore)
647 {
648   if (count == 0)
649     return (0);
650
651   if (rl_last_func != rl_history_substr_search_forward &&
652       rl_last_func != rl_history_substr_search_backward)
653     rl_history_search_reinit (NON_ANCHORED_SEARCH);
654
655   if (rl_history_search_len == 0)
656     return (rl_get_previous_history (count, ignore));
657   return (rl_history_search_internal (abs (count), (count > 0) ? -1 : 1));
658 }