Ticket #2760: The password for session ftp remains in input history
[midnight-commander.git] / src / viewer / search.c
blobd9c40cb881bf8244924b8299da2d84ac42395980
1 /*
2 Internal file viewer for the Midnight Commander
3 Function for search data
5 Copyright (C) 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002, 2003,
6 2004, 2005, 2006, 2007, 2009, 2011
7 The Free Software Foundation, Inc.
9 Written by:
10 Miguel de Icaza, 1994, 1995, 1998
11 Janne Kukonlehto, 1994, 1995
12 Jakub Jelinek, 1995
13 Joseph M. Hinkle, 1996
14 Norbert Warmuth, 1997
15 Pavel Machek, 1998
16 Roland Illig <roland.illig@gmx.de>, 2004, 2005
17 Slava Zanko <slavazanko@google.com>, 2009
18 Andrew Borodin <aborodin@vmail.ru>, 2009
19 Ilia Maslakov <il.smind@gmail.com>, 2009
21 This file is part of the Midnight Commander.
23 The Midnight Commander is free software: you can redistribute it
24 and/or modify it under the terms of the GNU General Public License as
25 published by the Free Software Foundation, either version 3 of the License,
26 or (at your option) any later version.
28 The Midnight Commander is distributed in the hope that it will be useful,
29 but WITHOUT ANY WARRANTY; without even the implied warranty of
30 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
31 GNU General Public License for more details.
33 You should have received a copy of the GNU General Public License
34 along with this program. If not, see <http://www.gnu.org/licenses/>.
37 #include <config.h>
39 #include "lib/global.h"
40 #include "lib/tty/tty.h"
41 #include "lib/widget.h"
43 #include "src/setup.h"
45 #include "internal.h"
47 /*** global variables ****************************************************************************/
49 /*** file scope macro definitions ****************************************************************/
51 /*** file scope type declarations ****************************************************************/
53 /*** file scope variables ************************************************************************/
55 static int search_cb_char_curr_index = -1;
56 static char search_cb_char_buffer[6];
58 /*** file scope functions ************************************************************************/
59 /* --------------------------------------------------------------------------------------------- */
61 static void
62 mcview_search_update_steps (mcview_t * view)
64 off_t filesize = mcview_get_filesize (view);
65 if (filesize != 0)
66 view->update_steps = 40000;
67 else /* viewing a data stream, not a file */
68 view->update_steps = filesize / 100;
70 /* Do not update the percent display but every 20 ks */
71 if (view->update_steps < 20000)
72 view->update_steps = 20000;
75 /* --------------------------------------------------------------------------------------------- */
77 static gboolean
78 mcview_find (mcview_t * view, gsize search_start, gsize * len)
80 gsize search_end;
82 view->search_numNeedSkipChar = 0;
83 search_cb_char_curr_index = -1;
85 if (mcview_search_options.backwards)
87 search_end = mcview_get_filesize (view);
88 while ((int) search_start >= 0)
90 view->search_nroff_seq->index = search_start;
91 mcview_nroff_seq_info (view->search_nroff_seq);
93 if (search_end > search_start + view->search->original_len
94 && mc_search_is_fixed_search_str (view->search))
95 search_end = search_start + view->search->original_len;
97 if (mc_search_run (view->search, (void *) view, search_start, search_end, len)
98 && view->search->normal_offset == (off_t) search_start)
100 if (view->text_nroff_mode)
101 view->search->normal_offset++;
102 return TRUE;
105 search_start--;
107 view->search->error_str = g_strdup (_("Search string not found"));
108 return FALSE;
110 view->search_nroff_seq->index = search_start;
111 mcview_nroff_seq_info (view->search_nroff_seq);
113 return mc_search_run (view->search, (void *) view, search_start, mcview_get_filesize (view),
114 len);
117 /* --------------------------------------------------------------------------------------------- */
119 static void
120 mcview_search_show_result (mcview_t * view, Dlg_head ** d, size_t match_len)
122 int nroff_len;
124 nroff_len =
125 view->text_nroff_mode
126 ? mcview__get_nroff_real_len (view, view->search->start_buffer,
127 view->search->normal_offset - view->search->start_buffer) : 0;
128 view->search_start = view->search->normal_offset + nroff_len;
130 if (!view->hex_mode)
131 view->search_start++;
133 nroff_len =
134 view->text_nroff_mode ? mcview__get_nroff_real_len (view, view->search_start - 1,
135 match_len) : 0;
136 view->search_end = view->search_start + match_len + nroff_len;
138 if (view->hex_mode)
140 view->hex_cursor = view->search_start;
141 view->hexedit_lownibble = FALSE;
142 view->dpy_start = view->search_start - view->search_start % view->bytes_per_line;
143 view->dpy_end = view->search_end - view->search_end % view->bytes_per_line;
146 if (verbose)
148 dlg_run_done (*d);
149 destroy_dlg (*d);
150 *d = create_message (D_NORMAL, _("Search"), _("Seeking to search result"));
151 tty_refresh ();
153 mcview_moveto_match (view);
157 /* --------------------------------------------------------------------------------------------- */
158 /*** public functions ****************************************************************************/
159 /* --------------------------------------------------------------------------------------------- */
162 mcview_search_cmd_callback (const void *user_data, gsize char_offset)
164 int lc_byte;
165 mcview_t *view = (mcview_t *) user_data;
167 /* view_read_continue (view, &view->search_onechar_info); *//* AB:FIXME */
168 if (!view->text_nroff_mode)
170 if (!mcview_get_byte (view, char_offset, &lc_byte))
171 return MC_SEARCH_CB_OK;
173 return lc_byte;
176 if (view->search_numNeedSkipChar != 0)
178 view->search_numNeedSkipChar--;
179 return MC_SEARCH_CB_SKIP;
182 if (search_cb_char_curr_index == -1
183 || search_cb_char_curr_index >= view->search_nroff_seq->char_width)
185 if (search_cb_char_curr_index != -1)
186 mcview_nroff_seq_next (view->search_nroff_seq);
188 search_cb_char_curr_index = 0;
189 if (view->search_nroff_seq->char_width > 1)
190 g_unichar_to_utf8 (view->search_nroff_seq->current_char, search_cb_char_buffer);
191 else
192 search_cb_char_buffer[0] = (char) view->search_nroff_seq->current_char;
194 if (view->search_nroff_seq->type != NROFF_TYPE_NONE)
196 switch (view->search_nroff_seq->type)
198 case NROFF_TYPE_BOLD:
199 view->search_numNeedSkipChar = 1 + view->search_nroff_seq->char_width; /* real char width and 0x8 */
200 break;
201 case NROFF_TYPE_UNDERLINE:
202 view->search_numNeedSkipChar = 2; /* underline symbol and ox8 */
203 break;
204 default:
205 break;
208 return MC_SEARCH_CB_INVALID;
211 lc_byte = search_cb_char_buffer[search_cb_char_curr_index];
212 search_cb_char_curr_index++;
213 return (lc_byte != -1) ? (unsigned char) lc_byte : MC_SEARCH_CB_INVALID;
217 /* --------------------------------------------------------------------------------------------- */
220 mcview_search_update_cmd_callback (const void *user_data, gsize char_offset)
222 mcview_t *view = (mcview_t *) user_data;
224 if (char_offset >= (gsize) view->update_activate)
226 view->update_activate += view->update_steps;
227 if (verbose)
229 mcview_percent (view, char_offset);
230 tty_refresh ();
232 if (tty_got_interrupt ())
233 return MC_SEARCH_CB_ABORT;
235 /* may be in future return from this callback will change current position
236 * in searching block. Now this just constant return value.
238 return MC_SEARCH_CB_OK;
241 /* --------------------------------------------------------------------------------------------- */
243 void
244 mcview_do_search (mcview_t * view)
246 off_t search_start = 0;
247 gboolean isFound = FALSE;
248 gboolean need_search_again = TRUE;
250 Dlg_head *d = NULL;
252 size_t match_len;
254 if (verbose)
256 d = create_message (D_NORMAL, _("Search"), _("Searching %s"), view->last_search_string);
257 tty_refresh ();
260 /*for avoid infinite search loop we need to increase or decrease start offset of search */
262 if (view->search_start != 0)
264 if (!view->text_nroff_mode)
265 search_start = view->search_start + (mcview_search_options.backwards ? -2 : 0);
266 else
268 if (mcview_search_options.backwards)
270 mcview_nroff_t *nroff;
271 nroff = mcview_nroff_seq_new_num (view, view->search_start);
272 if (mcview_nroff_seq_prev (nroff) != -1)
273 search_start =
274 -(mcview__get_nroff_real_len (view, nroff->index - 1, 2) +
275 nroff->char_width + 1);
276 else
277 search_start = -2;
279 mcview_nroff_seq_free (&nroff);
281 else
283 search_start = mcview__get_nroff_real_len (view, view->search_start + 1, 2);
285 search_start += view->search_start;
289 if (mcview_search_options.backwards && (int) search_start < 0)
290 search_start = 0;
292 /* Compute the percent steps */
293 mcview_search_update_steps (view);
294 view->update_activate = 0;
296 tty_enable_interrupt_key ();
300 off_t growbufsize;
302 if (view->growbuf_in_use)
303 growbufsize = mcview_growbuf_filesize (view);
304 else
305 growbufsize = view->search->original_len;
307 if (mcview_find (view, search_start, &match_len))
309 mcview_search_show_result (view, &d, match_len);
310 need_search_again = FALSE;
311 isFound = TRUE;
312 break;
315 if (view->search->error_str == NULL)
316 break;
318 search_start = growbufsize - view->search->original_len;
319 if (search_start <= 0)
321 search_start = 0;
322 break;
325 while (mcview_may_still_grow (view));
327 if (view->search_start != 0 && !isFound && need_search_again
328 && !mcview_search_options.backwards)
330 int result;
332 mcview_update (view);
334 result =
335 query_dialog (_("Search done"), _("Continue from beginning?"), D_NORMAL, 2, _("&Yes"),
336 _("&No"));
338 if (result != 0)
339 isFound = TRUE;
340 else
341 search_start = 0;
344 if (!isFound && view->search->error_str != NULL && mcview_find (view, search_start, &match_len))
346 mcview_search_show_result (view, &d, match_len);
347 isFound = TRUE;
350 tty_disable_interrupt_key ();
352 if (verbose)
354 dlg_run_done (d);
355 destroy_dlg (d);
358 if (!isFound && view->search->error_str != NULL)
359 message (D_NORMAL, _("Search"), "%s", view->search->error_str);
361 view->dirty++;
362 mcview_update (view);
365 /* --------------------------------------------------------------------------------------------- */