~ubuntu-branches/ubuntu/quantal/mc/quantal

« back to all changes in this revision

Viewing changes to .pc/2795.patch/src/viewer/search.c

  • Committer: Package Import Robot
  • Author(s): Dmitry Smirnov
  • Date: 2012-08-05 21:52:36 UTC
  • mfrom: (4.2.18 sid)
  • Revision ID: package-import@ubuntu.com-20120805215236-xwfu5p8qhavoz2vy
Tags: 3:4.8.3-5
2800.patch is corrected to avoid crash on entering archives.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
   Internal file viewer for the Midnight Commander
 
3
   Function for search data
 
4
 
 
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.
 
8
 
 
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
 
20
 
 
21
   This file is part of the Midnight Commander.
 
22
 
 
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.
 
27
 
 
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.
 
32
 
 
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/>.
 
35
 */
 
36
 
 
37
#include <config.h>
 
38
 
 
39
#include "lib/global.h"
 
40
#include "lib/tty/tty.h"
 
41
#include "lib/widget.h"
 
42
 
 
43
#include "src/setup.h"
 
44
 
 
45
#include "internal.h"
 
46
 
 
47
/*** global variables ****************************************************************************/
 
48
 
 
49
/*** file scope macro definitions ****************************************************************/
 
50
 
 
51
/*** file scope type declarations ****************************************************************/
 
52
 
 
53
/*** file scope variables ************************************************************************/
 
54
 
 
55
static int search_cb_char_curr_index = -1;
 
56
static char search_cb_char_buffer[6];
 
57
 
 
58
/*** file scope functions ************************************************************************/
 
59
/* --------------------------------------------------------------------------------------------- */
 
60
 
 
61
static void
 
62
mcview_search_update_steps (mcview_t * view)
 
63
{
 
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;
 
69
 
 
70
    /* Do not update the percent display but every 20 ks */
 
71
    if (view->update_steps < 20000)
 
72
        view->update_steps = 20000;
 
73
}
 
74
 
 
75
/* --------------------------------------------------------------------------------------------- */
 
76
 
 
77
static gboolean
 
78
mcview_find (mcview_t * view, gsize search_start, gsize * len)
 
79
{
 
80
    gsize search_end;
 
81
 
 
82
    view->search_numNeedSkipChar = 0;
 
83
    search_cb_char_curr_index = -1;
 
84
 
 
85
    if (mcview_search_options.backwards)
 
86
    {
 
87
        search_end = mcview_get_filesize (view);
 
88
        while ((int) search_start >= 0)
 
89
        {
 
90
            view->search_nroff_seq->index = search_start;
 
91
            mcview_nroff_seq_info (view->search_nroff_seq);
 
92
 
 
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;
 
96
 
 
97
            if (mc_search_run (view->search, (void *) view, search_start, search_end, len)
 
98
                && view->search->normal_offset == (off_t) search_start)
 
99
            {
 
100
                if (view->text_nroff_mode)
 
101
                    view->search->normal_offset++;
 
102
                return TRUE;
 
103
            }
 
104
 
 
105
            search_start--;
 
106
        }
 
107
        view->search->error_str = g_strdup (_("Search string not found"));
 
108
        return FALSE;
 
109
    }
 
110
    view->search_nroff_seq->index = search_start;
 
111
    mcview_nroff_seq_info (view->search_nroff_seq);
 
112
 
 
113
    return mc_search_run (view->search, (void *) view, search_start, mcview_get_filesize (view),
 
114
                          len);
 
115
}
 
116
 
 
117
/* --------------------------------------------------------------------------------------------- */
 
118
 
 
119
static void
 
120
mcview_search_show_result (mcview_t * view, Dlg_head ** d, size_t match_len)
 
121
{
 
122
    int nroff_len;
 
123
 
 
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;
 
129
 
 
130
    if (!view->hex_mode)
 
131
        view->search_start++;
 
132
 
 
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;
 
137
 
 
138
    if (view->hex_mode)
 
139
    {
 
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;
 
144
    }
 
145
 
 
146
    if (verbose)
 
147
    {
 
148
        dlg_run_done (*d);
 
149
        destroy_dlg (*d);
 
150
        *d = create_message (D_NORMAL, _("Search"), _("Seeking to search result"));
 
151
        tty_refresh ();
 
152
    }
 
153
    mcview_moveto_match (view);
 
154
 
 
155
}
 
156
 
 
157
/* --------------------------------------------------------------------------------------------- */
 
158
/*** public functions ****************************************************************************/
 
159
/* --------------------------------------------------------------------------------------------- */
 
160
 
 
161
int
 
162
mcview_search_cmd_callback (const void *user_data, gsize char_offset)
 
163
{
 
164
    int lc_byte;
 
165
    mcview_t *view = (mcview_t *) user_data;
 
166
 
 
167
    /*    view_read_continue (view, &view->search_onechar_info); *//* AB:FIXME */
 
168
    if (!view->text_nroff_mode)
 
169
    {
 
170
        if (!mcview_get_byte (view, char_offset, &lc_byte))
 
171
            return MC_SEARCH_CB_OK;
 
172
 
 
173
        return lc_byte;
 
174
    }
 
175
 
 
176
    if (view->search_numNeedSkipChar != 0)
 
177
    {
 
178
        view->search_numNeedSkipChar--;
 
179
        return MC_SEARCH_CB_SKIP;
 
180
    }
 
181
 
 
182
    if (search_cb_char_curr_index == -1
 
183
        || search_cb_char_curr_index >= view->search_nroff_seq->char_width)
 
184
    {
 
185
        if (search_cb_char_curr_index != -1)
 
186
            mcview_nroff_seq_next (view->search_nroff_seq);
 
187
 
 
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;
 
193
 
 
194
        if (view->search_nroff_seq->type != NROFF_TYPE_NONE)
 
195
        {
 
196
            switch (view->search_nroff_seq->type)
 
197
            {
 
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;
 
206
            }
 
207
        }
 
208
        return MC_SEARCH_CB_INVALID;
 
209
    }
 
210
 
 
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;
 
214
 
 
215
}
 
216
 
 
217
/* --------------------------------------------------------------------------------------------- */
 
218
 
 
219
int
 
220
mcview_search_update_cmd_callback (const void *user_data, gsize char_offset)
 
221
{
 
222
    mcview_t *view = (mcview_t *) user_data;
 
223
 
 
224
    if (char_offset >= (gsize) view->update_activate)
 
225
    {
 
226
        view->update_activate += view->update_steps;
 
227
        if (verbose)
 
228
        {
 
229
            mcview_percent (view, char_offset);
 
230
            tty_refresh ();
 
231
        }
 
232
        if (tty_got_interrupt ())
 
233
            return MC_SEARCH_CB_ABORT;
 
234
    }
 
235
    /* may be in future return from this callback will change current position
 
236
     * in searching block. Now this just constant return value.
 
237
     */
 
238
    return MC_SEARCH_CB_OK;
 
239
}
 
240
 
 
241
/* --------------------------------------------------------------------------------------------- */
 
242
 
 
243
void
 
244
mcview_do_search (mcview_t * view)
 
245
{
 
246
    off_t search_start = 0;
 
247
    gboolean isFound = FALSE;
 
248
    gboolean need_search_again = TRUE;
 
249
 
 
250
    Dlg_head *d = NULL;
 
251
 
 
252
    size_t match_len;
 
253
 
 
254
    if (verbose)
 
255
    {
 
256
        d = create_message (D_NORMAL, _("Search"), _("Searching %s"), view->last_search_string);
 
257
        tty_refresh ();
 
258
    }
 
259
 
 
260
    /*for avoid infinite search loop we need to increase or decrease start offset of search */
 
261
 
 
262
    if (view->search_start != 0)
 
263
    {
 
264
        if (!view->text_nroff_mode)
 
265
            search_start = view->search_start + (mcview_search_options.backwards ? -2 : 0);
 
266
        else
 
267
        {
 
268
            if (mcview_search_options.backwards)
 
269
            {
 
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;
 
278
 
 
279
                mcview_nroff_seq_free (&nroff);
 
280
            }
 
281
            else
 
282
            {
 
283
                search_start = mcview__get_nroff_real_len (view, view->search_start + 1, 2);
 
284
            }
 
285
            search_start += view->search_start;
 
286
        }
 
287
    }
 
288
 
 
289
    if (mcview_search_options.backwards && (int) search_start < 0)
 
290
        search_start = 0;
 
291
 
 
292
    /* Compute the percent steps */
 
293
    mcview_search_update_steps (view);
 
294
    view->update_activate = 0;
 
295
 
 
296
    tty_enable_interrupt_key ();
 
297
 
 
298
    do
 
299
    {
 
300
        off_t growbufsize;
 
301
 
 
302
        if (view->growbuf_in_use)
 
303
            growbufsize = mcview_growbuf_filesize (view);
 
304
        else
 
305
            growbufsize = view->search->original_len;
 
306
 
 
307
        if (mcview_find (view, search_start, &match_len))
 
308
        {
 
309
            mcview_search_show_result (view, &d, match_len);
 
310
            need_search_again = FALSE;
 
311
            isFound = TRUE;
 
312
            break;
 
313
        }
 
314
 
 
315
        if (view->search->error_str == NULL)
 
316
            break;
 
317
 
 
318
        search_start = growbufsize - view->search->original_len;
 
319
        if (search_start <= 0)
 
320
        {
 
321
            search_start = 0;
 
322
            break;
 
323
        }
 
324
    }
 
325
    while (mcview_may_still_grow (view));
 
326
 
 
327
    if (view->search_start != 0 && !isFound && need_search_again
 
328
        && !mcview_search_options.backwards)
 
329
    {
 
330
        int result;
 
331
 
 
332
        mcview_update (view);
 
333
 
 
334
        result =
 
335
            query_dialog (_("Search done"), _("Continue from beginning?"), D_NORMAL, 2, _("&Yes"),
 
336
                          _("&No"));
 
337
 
 
338
        if (result != 0)
 
339
            isFound = TRUE;
 
340
        else
 
341
            search_start = 0;
 
342
    }
 
343
 
 
344
    if (!isFound && view->search->error_str != NULL && mcview_find (view, search_start, &match_len))
 
345
    {
 
346
        mcview_search_show_result (view, &d, match_len);
 
347
        isFound = TRUE;
 
348
    }
 
349
 
 
350
    tty_disable_interrupt_key ();
 
351
 
 
352
    if (verbose)
 
353
    {
 
354
        dlg_run_done (d);
 
355
        destroy_dlg (d);
 
356
    }
 
357
 
 
358
    if (!isFound && view->search->error_str != NULL)
 
359
        message (D_NORMAL, _("Search"), "%s", view->search->error_str);
 
360
 
 
361
    view->dirty++;
 
362
    mcview_update (view);
 
363
}
 
364
 
 
365
/* --------------------------------------------------------------------------------------------- */