1
1

* view.c: Fixed long existed bugs in internal viewer. When search is

doing in binary file it ignore skipped zero(es), so cursor is before
searched expression and next search find the same string. Also regexp
search could return wrong results for '^ ?' expressions.

(get_line_at): skipped: new parameter for number of skipped zero(es)

(search): new features of get_line_at used.
Этот коммит содержится в:
Andrew V. Samoilov 2000-11-20 17:25:43 +00:00
родитель 0b8fd41ca9
Коммит 540c532680

Просмотреть файл

@ -99,6 +99,7 @@ extern Hook *idle_hook;
/* Our callback */
static int view_callback (Dlg_head *h, WView *view, int msg, int par);
static int regexp_view_search (WView *view, char *pattern, char *string, int match_type);
/* If set, show a ruler */
int ruler = 0;
@ -650,10 +651,9 @@ view_update_bytes_per_line(WView *view)
cols = view->widget.cols - 2;
else
cols = view->widget.cols;
view->bottom_first = -1;
view->bytes_per_line = 2 * (cols - 8) / 9;
view->bytes_per_line &= 0xfffc;
view->bytes_per_line = ((2 * (cols - 8) / 9) & 0xfffc);
if (view->bytes_per_line == 0)
view->bytes_per_line++; /* To avoid division by 0 */
@ -741,16 +741,10 @@ view_status (WView *view, gboolean update_gui)
addstr (_(" [grow]"));
}
if (w > 26) {
if (view->hex_mode)
view_percent (view,
view->edit_cursor - view->first,
view->widget.cols - view->have_frame + 1,
update_gui);
else
view_percent (view,
view->start_display - view->first,
view->widget.cols - view->have_frame + 1,
update_gui);
view_percent (view,
view->hex_mode ? view->edit_cursor : view->start_display,
view->widget.cols - view->have_frame + 1,
update_gui);
}
}
attrset (SELECTED_COLOR);
@ -861,18 +855,15 @@ display (WView *view)
else
height -= 2;
}
/* Find the first displayable changed byte */
while (curr) {
if (curr->offset < from)
curr = curr->next;
else
break;
while (curr && (curr->offset < from)) {
curr = curr->next;
}
if (view->hex_mode){
char hex_buff[10]; /* A temporary buffer for sprintf and mvwaddstr */
int bytes; /* Number of bytes already printed on the line */
/* Start of text column */
int text_start = width - view->bytes_per_line - 1 + frame_shift;
@ -1383,73 +1374,74 @@ move_left (WView *view)
static int
icase_search_p (WView *view, char *text, char *data, int nothing)
{
int p = 0, lng;
char *q;
int lng;
p = (q = _icase_search (text, data, &lng)) != 0;
if (p) {
if ((q = _icase_search (text, data, &lng)) != 0) {
view->found_len = lng;
view->search_start = q - data - view->found_len;
view->search_start = q - data - lng;
return 1;
}
return p;
return 0;
}
static char *
grow_string_buffer (char *text, int *size)
{
char *new;
int old_size = *size;
/* The grow steps */
*size += 160;
new = g_malloc (*size);
if (text){
strncpy (new, text, old_size);
g_free (text);
} else {
new = g_realloc (text, *size);
if (!text){
*new = 0;
}
return new;
}
static char *
get_line_at (WView *view, unsigned long *p)
get_line_at (WView *view, unsigned long *p, unsigned long *skipped)
{
char *buffer = 0;
int buffer_size, usable_size;
int ch;
int ch = 0;
int direction;
unsigned long pos = *p;
long i;
long i = 0;
int prev;
direction = view->direction;
buffer_size = usable_size = 0;
i = ch = 0;
for (;pos >= 0 && (ch = get_byte (view, pos))!= -1; pos += direction, i++){
prev = (pos) ? ((prev = get_byte (view, pos - 1) == -1) ? 0 : prev) : 0;
*skipped = 0;
while ((ch = get_byte (view, pos)) != -1){
/* skip over all the possible zeros in the file */
if (ch == 0 && i == 0){
while (pos >= 0 && ((ch = get_byte (view, pos)) != -1) && ch == 0)
pos+= direction;
do {
pos += direction; i++;
} while ((ch = get_byte (view, pos)) == 0);
*skipped = i;
i = 0;
if (ch == -1)
break;
}
if (i == usable_size){
buffer = grow_string_buffer (buffer, &buffer_size);
usable_size = buffer_size - 2;
buffer [0] = ' '; /* This makes possible strcpy of buffer */
}
buffer [i+1] = ch;
if (ch == '\n' || !ch || ch == -1){
pos += direction; i++;
pos += direction; i++;
buffer [i] = ch;
if (ch == '\n' || !ch){
break;
}
}
if (buffer){
i--;
buffer [0] = ' ';
buffer [i+1] = 0;
buffer [0] = prev;
buffer [i] = 0;
/* If we are searching backwards, reverse the string */
if (view->direction < 0)
@ -1496,13 +1488,11 @@ search (WView *view, char *text, int (*search)(WView *, char *, char *, int))
char *s = NULL; /* The line we read from the view buffer */
long p, beginning;
int ch;
int isatbeg; /* Nonzero means we start search at beginning of some line */
int found_len, search_start;
Dlg_head *d = 0;
int search_status;
int abort;
#ifdef HAVE_GNOME
int abort;
GtkWidget *gd;
#endif
@ -1515,8 +1505,8 @@ search (WView *view, char *text, int (*search)(WView *, char *, char *, int))
/* Clear interrupt status */
got_interrupt ();
abort = 0;
#ifdef HAVE_GNOME
abort = 0;
gd = gnome_message_box_new (_("Searching for `%s'"),
GNOME_MESSAGE_BOX_INFO,
GNOME_STOCK_BUTTON_CANCEL,
@ -1529,23 +1519,22 @@ search (WView *view, char *text, int (*search)(WView *, char *, char *, int))
mc_refresh ();
}
#endif
ch = 0;
if (view->direction == 1){
p = view->found_len ? view->search_start + 1 : view->search_start;
} else {
p = (view->found_len ? view->search_start : view->last) - 1;
}
beginning = p;
isatbeg = view->found_len == 0;
found_len = view->found_len;
search_start = view->search_start;
if (view->direction == 1){
p = found_len ? search_start + 1 : search_start;
} else {
p = (found_len ? search_start : view->last) - 1;
}
beginning = p;
/* Compute the percent steps */
search_update_steps (view);
update_activate = 0;
for (; ; isatbeg = 1, g_free (s)){
for (; ; g_free (s)){
#ifdef PORT_HAS_FLUSH_EVENTS
static int count;
@ -1570,38 +1559,37 @@ search (WView *view, char *text, int (*search)(WView *, char *, char *, int))
}
forward_line_start = p;
disable_interrupt_key ();
s = get_line_at (view, &p);
s = get_line_at (view, &p, &t);
reverse_line_start = p;
enable_interrupt_key ();
if (!s)
break;
search_status = (*search) (view, text, s + 1, match_normal);
if (search_status < 0)
if (search_status < 0){
g_free (s);
break;
}
if (search_status == 0)
continue;
/* We found the string */
if (!isatbeg && !view->search_start){
if (*s && !view->search_start && (search == regexp_view_search) && (*text == '^')){
/* We do not want to match a
* ^ regexp when not at the real
* beginning of some line
*/
view->found_len = found_len;
view->search_start = search_start;
if ((*search) (view, text, s, match_normal) <= 0)
continue;
(*search) (view, text, s + 1, match_normal);
continue;
}
/* Record the position used to continue the search */
if (view->direction == 1)
t = forward_line_start;
t += forward_line_start;
else
t = reverse_line_start ? reverse_line_start + 3 : 0;
t += reverse_line_start ? reverse_line_start + 3 : 0;
view->search_start += t;
if (t != beginning){
@ -1610,7 +1598,7 @@ search (WView *view, char *text, int (*search)(WView *, char *, char *, int))
else
view->start_display = t;
}
g_free (s);
break;
}
@ -1966,7 +1954,11 @@ regexp_search (WView *view, int direction)
regexp = old ? old : regexp;
regexp = input_dialog (_(" Search "), _(" Enter regexp:"), regexp);
if ((!regexp) || (!*regexp)){
if ((!regexp)){
return;
}
if ((!*regexp)){
g_free (regexp);
return;
}
if (old)
@ -1998,7 +1990,11 @@ normal_search (WView *view, int direction)
exp = old ? old : exp;
exp = input_dialog (_(" Search "), _(" Enter search string:"), exp);
if ((!exp) || (!*exp)){
if ((!exp)){
return;
}
if ((!*exp)){
g_free (exp);
return;
}
if (old)