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