⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 view.c

📁 ReactOS是一些高手根据Windows XP的内核编写出的类XP。内核实现机理和API函数调用几乎相同。甚至可以兼容XP的程序。喜欢研究系统内核的人可以看一看。
💻 C
📖 第 1 页 / 共 5 页
字号:
	if (!s)
	    break;

	search_status = (*search) (view, text, s + 1, match_normal);
	if (search_status < 0)
	    break;

	if (search_status == 0)
	    continue;

	/* We found the string */

	if (!isatbeg && !view->search_start){

	    /* 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);
	}
	/* Record the position used to continue the search */
	if (view->direction == 1)
	    t = forward_line_start;
	else
	    t = reverse_line_start ? reverse_line_start + 3 : 0;
	view->search_start += t;

	if (t != beginning){
	    if (t > get_bottom_first (view, 0, 0))
		view->start_display = view->bottom_first;
	    else
		view->start_display = t;
	}

	free (s);
	break;
    }
    disable_interrupt_key ();
    if (verbose){
	dlg_run_done (d);
	destroy_dlg (d);
    }

    if (!s){
	message (0, _(" Search "), _(" Search string not found "));
	view->found_len = 0;
    }
}

/* Search buffer (it's size is len) in the complete buffer */
/* returns the position where the block was found or -1 if not found */
static long
block_search (WView *view, char *buffer, int len)
{
    int w = view->widget.cols - (view->have_frame * 2);
    char *d = buffer, b;
    long e;

    /* clear interrupt status */
    got_interrupt ();
    enable_interrupt_key ();
    e = view->found_len ? view->search_start + 1 : view->search_start;

    search_update_steps (view);
    update_activate = 0;

    for (; e < view->last_byte; e++){
	if (e >= update_activate){
	    update_activate += update_steps;
	    if (verbose){
		view_percent (view, e, w);
		mc_refresh ();
	    }
	    if (got_interrupt ())
		break;
	}
	b = get_byte (view, e);

	if (*d == b){
	    d++;
	} else {
	    e -= d - buffer;
	    d = buffer;
	}
	if (d - buffer == len){
	    disable_interrupt_key ();
	    return e - len;
	}
    }
    disable_interrupt_key ();
    return -1;
}

/* States of our funny recognizer */
enum {
    normal,
    inside_quotes,
    zero,
    hex1,
    hex2,
    oct1
};

/* This routine doesn't report all the user mistakes, it just ignores them */
static void
hex_search (WView *view, char *text)
{
    char buffer [120];		/* Where we hold the information */
    int  i, block_len;
    int  v = 0;
    long pos;			/* Where did we found the string */
    char *p;			/* Temporary */
    int  state = normal;	/* Initial state of the micro-scanner */

    /* First convert the string to a stream of bytes */
    for (i = block_len = 0; text [i] && block_len < sizeof (buffer); i++){
	switch (state){
	case inside_quotes:
	    if (text [i] == '"')
		state = normal;
	    else
		buffer [block_len++] = text [i];
	    break;

	case normal:
	    if (text [i] == '"'){
		state = inside_quotes;
		break;
	    }
	    if (text [i] == '0'){
		state = zero;
		break;
	    }
	    if (text [i] == 'x'){
		state = hex1;
		break;
	    }
	    break;

	case zero:
	    if (text [i] == 'x')
		state = hex1;
	    break;

	case hex1:
	    v = 0;
	    text [i] = toupper (text [i]);
	    if ((p = strchr (hex_char, text [i])) != 0){
		v = (p - hex_char) << 4;
		state = hex2;
	    }
	    break;

	case hex2:
	    text [i] = toupper (text [i]);
	    if ((p = strchr (hex_char, text [i])) != 0){
		v |= (p - hex_char);
		state = normal;
	    }
	    buffer [block_len++] = v;
	    break;
	}
    }
    /* Then start the search */
    pos = block_search (view, buffer, block_len);
    if (pos == -1){
	message (0, _(" Search "), _(" Search string not found "));
	view->found_len = 0;
	return;
    }

    view->search_start = pos + 1;
    view->found_len = block_len;
    /* Set the edit cursor to the search position, left nibble */
    view->edit_cursor = view->search_start;
    view->nib_shift = 0;

    /* Adjust the file offset */
    view->start_display = (pos & (~(view->bytes_per_line-1)));
    if (view->start_display > get_bottom_first (view, 0, 0))
    	view->start_display = view->bottom_first;
}

static int regexp_view_search (WView *view, char *pattern, char *string, int match_type)
{
    static regex_t r;
    static char *old_pattern = NULL;
    static int old_type;
    regmatch_t pmatch[1];
    int i, flags = REG_ICASE;

    if (!old_pattern || strcmp (old_pattern, pattern) || old_type != match_type){
	if (old_pattern){
	    regfree (&r);
	    free (old_pattern);
	    old_pattern = 0;
	}
	for (i = 0; pattern[i] != 0; i++){
	    if (isupper ((unsigned char) pattern[i])){
		flags = 0;
		break;
	    }
	}
	flags |= REG_EXTENDED;
	if (regcomp (&r, pattern, flags)){
	    message (1, MSG_ERROR, _(" Invalid regular expression "));
	    return -1;
	}
	old_pattern = strdup (pattern);
	old_type = match_type;
    }
    if (regexec (&r, string, 1, pmatch, 0) != 0)
	return 0;
    view->found_len = pmatch[0].rm_eo - pmatch[0].rm_so;
    view->search_start = pmatch[0].rm_so;
    return 1;
}

static void do_regexp_search (void *xview, char *regexp)
{
    WView *view = (WView *) xview;

    view->search_exp = regexp;
    search (view, regexp, regexp_view_search);
    /* Had a refresh here */
    view->dirty++;
    view_update (view);
}

static void do_normal_search (void *xview, char *text)
{
    WView *view = (WView *) xview;

    view->search_exp = text;
    if (view->hex_mode)
	hex_search (view, text);
    else
	search (view, text, icase_search_p);
    /* Had a refresh here */
    view->dirty++;
    view_update (view);
}

/* }}} */
/* {{{ Mouse and keyboard handling */

/* Real view only */
static void help_cmd (void)
{
    char *hlpfile = concat_dir_and_file (mc_home, "mc.hlp");
    interactive_display (hlpfile, "[Internal File Viewer]");
    free (hlpfile);
    /*
    view_refresh (0);
    */
}

/* Both views */
void toggle_wrap_mode (WView *view)
{
    if (view->hex_mode) {
        if (view->growing_buffer != 0) {
            return;
        }
        get_bottom_first (view, 1, 1);
        if (view->hexedit_mode) {
            view->view_side = 1 - view->view_side;
        } else {
            view->hexedit_mode = 1 - view->hexedit_mode;
        }
        view_labels (view);
        view->dirty++;
        view_update (view);
		return;
    }
    view->wrap_mode = 1 - view->wrap_mode;
    get_bottom_first (view, 1, 1);
    if (view->wrap_mode)
	view->start_col = 0;
    else {
	if (have_fast_cpu){
	    if (view->bottom_first < view->start_display)
		view->search_start = view->start_display = view->bottom_first;
    	    view->found_len = 0;
	}
    }
    view_labels (view);
    view->dirty++;
    view_update (view);
}

/* Both views */
void
toggle_hex_mode (WView *view)
{
    view->hex_mode = 1 - view->hex_mode;

    if (view->hex_mode){
        /* Shift the line start to 0x____0 on entry, restore it for Ascii */
        view->start_save = view->start_display;
        view->start_display -= view->start_display % view->bytes_per_line;
        view->edit_cursor = view->start_display;
	view->widget.options |= W_WANT_CURSOR;
	view->widget.parent->raw = 1;
    } else {
        view->start_display = view->start_save;
	view->widget.parent->raw = 0;
	view->widget.options &= ~W_WANT_CURSOR;
    }
    altered_hex_mode = 1;
    get_bottom_first (view, 1, 1);
    view_labels (view);
    view->dirty++;
    view_update (view);
}

/* Both views */
void
toggle_hexedit_mode(WView *view)
{
    view->hexedit_mode = 1 - view->hexedit_mode;
}

/* Both views */
void
goto_line (WView *view)
{
    char *line, prompt [100];
    int i, oldline = 1;
    int saved_wrap_mode = view->wrap_mode;

    view->wrap_mode = 0;
    for (i = view->first; i < view->start_display; i++)
	if (get_byte (view, i) == '\n')
	    oldline ++;
    sprintf (prompt, _(" The current line number is %d.\n"
		       " Enter the new line number:"), oldline);
    line = input_dialog (_(" Goto line "), prompt, "");
    if (line){
	if (*line){
	    move_to_top (view);
	    view_move_forward (view, atoi (line) - 1);
	}
	free (line);
    }
    view->dirty++;
    view->wrap_mode = saved_wrap_mode;
    view_update (view);
}

/* Both views */
void
regexp_search (WView *view, int direction)
{
    char *regexp = "";
    static char *old = 0;

    /* This is really an F6 key handler */
    if (view->hex_mode){
        /* Save it without a confirmation prompt */
        save_edit_changes(view);
	return;
    }

    regexp = old ? old : regexp;
    regexp = input_dialog (_(" Search "), _(" Enter regexp:"), regexp);
    if ((!regexp) || (!*regexp)){
	return;
    }
    if (old)
	free (old);
    old = regexp;
#if 0
    /* Mhm, do we really need to load all the file in the core? */
    if (view->bytes_read < view->last_byte)
	get_byte (view, view->last_byte-1);/* Get the whole file in to memory */
#endif
    view->direction = direction;
    do_regexp_search (view, regexp);

    view->last_search = do_regexp_search;
}

void
regexp_search_cmd (WView *view)
{
    regexp_search (view, 1);
}

/* Both views */
void
normal_search (WView *view, int direction)
{
    static char *old;
    char *exp = "";

    exp = old ? old : exp;
    exp = input_dialog (_(" Search "), _(" Enter search string:"), exp);
    if ((!exp) || (!*exp)){
	return;
    }
    if (old)
	free (old);
    old = exp;

    view->direction = direction;
    do_normal_search (view, exp);
    view->last_search = do_normal_search;
}

void
normal_search_cmd (WView *view)
{
    normal_search (view, 1);
}

void
change_viewer (WView *view)
{
    char *s;
    char *t;


    if (*view->filename) {
        altered_magic_flag = 1;
        view->viewer_magic_flag = !view->viewer_magic_flag;
    	s = strdup (view->filename);
        if (view->command)
  	    t = strdup (view->command);
        else
            t = 0;

        view_done (view);
    	view_init (view, t, s, 0);
    	free (s);
    	if (t)
            free (t);
        view_labels (view);
        view->dirty++;
        view_update (view);
    }
}

void
change_nroff (WView *view)
{
    view->viewer_nroff_flag = !view->viewer_nroff_flag;
    altered_nroff_flag = 1;
    view_labels (view);
    view->dirty++;
    view_update (view);
}

/* Real view only */
static void
view_quit_cmd (WView *view)
{
    if (view_ok_to_quit (view))
	dlg_stop (view->widget.parent);
}

/* Both views */
void
view_labels (WView *view)
{
    Dlg_head *h = view->widget.parent;

    define_label (h, (Widget *) view, 1, _("Help"), help_cmd);

    my_define (h, 10, _("Quit"), view_quit_cmd, view);
    my_define (h, 4, view->hex_mode ? _("Ascii"): _("Hex"), toggle_hex_mode, view);
    my_define (h, 5, _("Line"), goto_line, view);
    my_define (h, 6, view->hex_mode ? _("Save") : _("RxSrch"), regexp_search_cmd, view);

    my_define (h, 2, view->hex_mode ? view->hexedit_mode ?
                     view->view_side == view_side_left ? _("EdText") : _("EdHex") :
                     view->growing_buffer ? "" : _("Edit") :
                     view->wrap_mode ? _("UnWrap") : _("Wrap"),
                     toggle_wrap_mode, view);

    my_define (h, 7, view->hex_mode ? _("HxSrch") : _("Search"),
	       normal_search_cmd, view);

    my_define (h, 8, view->viewer_magic_flag ? _("Raw") : _("Parse"),
	       change_viewer, view);

    if (!view->have_frame){
	my_define (h, 9, view->viewer_nroff_flag ? _("Unform") : _("Format"),
		   change_nroff, view);
	my_define (h, 3, _("Quit"), view_quit_cmd, view);
    }

    redraw_labels (h, (Widget *) view);
}

/* Both views */
static int
check_left_right_keys (WView *view, int c)
{
    if (c == KEY_LEFT)
	move_left (view);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -