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 Free Software Foundation, Inc.
8 Written by: 1994, 1995, 1998 Miguel de Icaza
9 1994, 1995 Janne Kukonlehto
14 2004 Roland Illig <roland.illig@gmx.de>
15 2005 Roland Illig <roland.illig@gmx.de>
16 2009 Slava Zanko <slavazanko@google.com>
17 2009 Andrew Borodin <aborodin@vmail.ru>
18 2009 Ilia Maslakov <il.smind@gmail.com>
20 This file is part of the Midnight Commander.
22 The Midnight Commander is free software; you can redistribute it
23 and/or modify it under the terms of the GNU General Public License as
24 published by the Free Software Foundation; either version 2 of the
25 License, or (at your option) any later version.
27 The Midnight Commander is distributed in the hope that it will be
28 useful, but WITHOUT ANY WARRANTY; without even the implied warranty
29 of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
30 General Public License for more details.
32 You should have received a copy of the GNU General Public License
33 along with this program; if not, write to the Free Software
34 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
40 #include "../src/global.h"
41 #include "../src/setup.h"
42 #include "../src/wtools.h"
43 #include "../src/tty/tty.h"
44 #include "../src/viewer/internal.h"
46 /*** global variables ****************************************************************************/
48 /*** file scope macro definitions ****************************************************************/
50 /*** file scope type declarations ****************************************************************/
52 /*** file scope variables ************************************************************************/
54 /*** file scope functions ************************************************************************/
57 /* --------------------------------------------------------------------------------------------- */
59 mcview_search_update_steps (mcview_t
* view
)
61 off_t filesize
= mcview_get_filesize (view
);
63 view
->update_steps
= 40000;
64 else /* viewing a data stream, not a file */
65 view
->update_steps
= filesize
/ 100;
67 /* Do not update the percent display but every 20 ks */
68 if (view
->update_steps
< 20000)
69 view
->update_steps
= 20000;
72 /* --------------------------------------------------------------------------------------------- */
75 mcview_find (mcview_t
* view
, gsize search_start
, gsize
* len
)
79 view
->search_numNeedSkipChar
= 0;
81 if (view
->search_backwards
) {
82 search_end
= mcview_get_filesize (view
);
83 while ((int) search_start
>= 0) {
84 if (search_end
> search_start
+ view
->search
->original_len
85 && mc_search_is_fixed_search_str (view
->search
))
86 search_end
= search_start
+ view
->search
->original_len
;
88 if (mc_search_run (view
->search
, (void *) view
, search_start
, search_end
, len
)
89 && view
->search
->normal_offset
== search_start
)
94 view
->search
->error_str
= g_strdup (_(" Search string not found "));
97 return mc_search_run (view
->search
, (void *) view
, search_start
, mcview_get_filesize (view
),
101 /* --------------------------------------------------------------------------------------------- */
103 /*** public functions ****************************************************************************/
105 /* --------------------------------------------------------------------------------------------- */
108 mcview_search_cmd_callback (const void *user_data
, gsize char_offset
)
111 mcview_t
*view
= (mcview_t
*) user_data
;
113 byte
= mcview_get_byte (view
, char_offset
);
115 return MC_SEARCH_CB_ABORT
;
116 /* view_read_continue (view, &view->search_onechar_info); *//* AB:FIXME */
118 if (view
->search_numNeedSkipChar
) {
119 view
->search_numNeedSkipChar
--;
120 if (view
->search_numNeedSkipChar
) {
123 return MC_SEARCH_CB_SKIP
;
126 if (view_read_test_nroff_back (view
, &view
->search_onechar_info
)) {
127 if (cmp (view
->search_onechar_info
.chi1
, "_") && (!cmp (view
->search_onechar_info
.cnxt
, "_")
128 || !cmp (view
->search_onechar_info
.chi2
,
131 view
->search_numNeedSkipChar
= 2;
133 view
->search_numNeedSkipChar
= 1;
135 return MC_SEARCH_CB_SKIP
;
137 if (byte
== '_' && *view
->search_onechar_info
.cnxt
== 0x8) {
138 view
->search_numNeedSkipChar
= 1;
139 return MC_SEARCH_CB_SKIP
;
146 /* --------------------------------------------------------------------------------------------- */
149 mcview_search_update_cmd_callback (const void *user_data
, gsize char_offset
)
151 mcview_t
*view
= (mcview_t
*) user_data
;
153 if (char_offset
>= view
->update_activate
) {
154 view
->update_activate
+= view
->update_steps
;
156 mcview_percent (view
, char_offset
);
159 if (tty_got_interrupt ())
160 return MC_SEARCH_CB_ABORT
;
162 /* may be in future return from this callback will change current position
163 * in searching block. Now this just constant return value.
168 /* --------------------------------------------------------------------------------------------- */
171 mcview_do_search (mcview_t
* view
)
174 gboolean isFound
= FALSE
;
181 d
= create_message (D_NORMAL
, _("Search"), _("Searching %s"), view
->last_search_string
);
185 /*for avoid infinite search loop we need to increase or decrease start offset of search */
187 if (view
->search_start
) {
188 search_start
= (view
->search_backwards
) ? -2 : 2;
189 search_start
= view
->search_start
+ search_start
+
190 mcview__get_nroff_real_len (view
, view
->search_start
, 2) * search_start
;
192 search_start
= view
->search_start
;
195 if (view
->search_backwards
&& (int) search_start
< 0)
198 /* Compute the percent steps */
199 mcview_search_update_steps (view
);
200 view
->update_activate
= 0;
202 tty_enable_interrupt_key ();
205 if (mcview_find (view
, search_start
, &match_len
)) {
206 view
->search_start
= view
->search
->normal_offset
+
207 mcview__get_nroff_real_len (view
,
208 view
->search
->start_buffer
,
209 view
->search
->normal_offset
-
210 view
->search
->start_buffer
);
213 view
->search_start
++;
215 view
->search_end
= view
->search_start
+ match_len
+
216 mcview__get_nroff_real_len (view
, view
->search_start
, match_len
+ 1);
218 if (view
->hex_mode
) {
219 view
->hex_cursor
= view
->search_start
;
220 view
->hexedit_lownibble
= FALSE
;
221 view
->dpy_start
= view
->search_start
- view
->search_start
% view
->bytes_per_line
;
222 view
->dpy_end
= view
->search_end
- view
->search_end
% view
->bytes_per_line
;
228 d
= create_message (D_NORMAL
, _("Search"), _("Seeking to search result"));
232 mcview_moveto_match (view
);
236 } while (mcview_may_still_grow (view
));
239 if (view
->search
->error_str
)
240 message (D_NORMAL
, _("Search"), "%s", view
->search
->error_str
);
244 mcview_update (view
);
247 tty_disable_interrupt_key ();
255 /* --------------------------------------------------------------------------------------------- */