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

📄 shell.c

📁 具有IDE功能的编辑器
💻 C
📖 第 1 页 / 共 3 页
字号:
    if (count || do_redraw) {/* we do a manual appending of the text for optimization purposes, instead of CRedrawTextbox */	w->text = (char *) pool_start (r->shell_pool);	CPushFont ("editor", 0);	w->numlines += strcountlines (w->text + w->textlength, 0, 2000000000, w->options & TEXTBOX_WRAP ? (w->width - TEXTBOX_BDR) / FONT_MEAN_WIDTH : 32000);	w->textlength = pool_length (r->shell_pool);/* only redraw if we crossed a newline */	if (strchr (w->text + w->textlength - count, '\n')) {	    CExpose (w->ident);	    if (w->winid != CGetFocus ())		if (w->numlines > w->firstline + (w->height / FONT_PIX_PER_LINE - 1))		    CSetTextboxPos (w, TEXT_SET_LINE, w->numlines - (w->height / FONT_PIX_PER_LINE - 1));	}	CPopFont ();    }    r->killme |= CChildExitted (r->shell_pid, 0);    if (!count && r->killme) {	pool_break (r->shell_pool);	r->shell_pool = 0;	CRemoveWatch (fd, shell_pool_update, WATCH_READING);	close (fd);	r->shell_pipe = -1;    }}/* draws a textbox dialog for showing the shells output */static void shell_display_output (char *text, const char *heading, int (*select_line_callback) (CWidget *, XEvent *, CEvent *), char *name){    int i;    if (!text)	text = "";    i = find_shell (0, name, 0);    if (i >= 0 && CIdent (nm (i, "shelldisplaytext", 0, 0))) {	/* exists ? */	CWidget *w;	w = CIdent (nm (i, "shelldisplaytext", "text", 0));	free (w->text);	w->text = 0;	CRedrawTextbox (nm (i, "shelldisplaytext", "text", 0), text, 0);	CRedrawText (nm (i, "shelldisplaytext", "header", 0), heading);	CFocus (CIdent (nm (i, "shelldisplaytext", "text", 0)));	CRaiseWMWindow (nm (i, "shelldisplaytext", 0, 0));    } else {	int x, y;	Window win;	CWidget *w;	win = CDrawMainWindow (nm (i, "shelldisplaytext", 0, 0), heading);	CGetHintPos (&x, &y);	CPushFont ("editor", 0);	running_shell[i].w = w = CDrawTextbox (nm (i, "shelldisplaytext", "text", 0), win, x, y, 80 * FONT_MEAN_WIDTH + 7, 25 * FONT_PIX_PER_LINE + 6, 0, 0, text, TEXTBOX_WRAP | TEXTBOX_NO_STRDUP);/* Toolhint */	CSetToolHint (nm (i, "shelldisplaytext", "text", 0), _ ("Double click on file:line type messages to goto the\nfile and line number.  Note that the file will not\nauto-load unless there is a full path in the message."));	w->position |= POSITION_HEIGHT | POSITION_WIDTH;	(CIdent (nm (i, "shelldisplaytext", "text", "vsc")))->position |= POSITION_HEIGHT | POSITION_RIGHT;	CGetHintPos (0, &y);	(CDrawPixmapButton (nm (i, "shelldisplaytext", "done", 0), win, 0, y, PIXMAP_BUTTON_TICK))->position = POSITION_BOTTOM | POSITION_CENTRE;/* Toolhint */	CSetToolHint (nm (i, "shelldisplaytext", "done", 0), _ ("Kill the running script"));	CCentre (nm (i, "shelldisplaytext", "done", 0));	CSetSizeHintPos (nm (i, "shelldisplaytext", 0, 0));	CSetWindowResizable (nm (i, "shelldisplaytext", 0, 0), FONT_MEAN_WIDTH * 15, FONT_PIX_PER_LINE * 15, 1600, 1200);	/* minimum and maximum sizes */	CPopFont ();	CMapDialog (nm (i, "shelldisplaytext", 0, 0));	CAddCallback (nm (i, "shelldisplaytext", "text", 0), select_line_callback);	CAddCallback (nm (i, "shelldisplaytext", "done", 0), display_file_callback);	CFocus (CIdent (nm (i, "shelldisplaytext", "done", 0)));    }}/* }}} dynamic display of shell output in a dialog box */static char *hme_i (char *h, int i){    static char s[MAX_PATH_LEN];    sprintf (s, "%s-%d", hme (h), i);    return s;}/* returns non-zero on error */int execute_background_display_output (char *title, char *s, char *name){    char *argv[] =    {0, 0};    pid_t p;    int i;    i = restart_shell (0, name, 0);    argv[0] = hme_i (SCRIPT_FILE, i);    savefile (argv[0], s, strlen (s), 0700);    if ((p = triple_pipe_open (0, &running_shell[i].shell_pipe, 0, 1, argv[0], argv)) < 0)	return 1;    running_shell[i].shell_pid = p;    if (!running_shell[i].shell_pool) {	running_shell[i].shell_pool = pool_init ();	pool_null (running_shell[i].shell_pool);    }    shell_display_output ((char *) pool_start (running_shell[i].shell_pool), title, goto_file_callback, name);    CAddWatch (running_shell[i].shell_pipe, shell_pool_update, WATCH_READING, (void *) i);    return 0;}/*   Executes the shell in the background. The "Insert File" options   will be ignored if this is called. */static int execute_background_shell (struct shell_cmd *s, char *script, char *name){    char *argv[] =    {0, 0};    pid_t p = 0;    int i;    i = restart_shell (0, name, 0);    argv[0] = hme_i (SCRIPT_FILE, i);    savefile (argv[0], script, strlen (script), 0700);    if (s->options & SHELL_OPTION_DISPLAY_STDOUT_CONTINUOUS) {	if ((p = triple_pipe_open (0, &running_shell[i].shell_pipe, 0,	   (s->options & SHELL_OPTION_DISPLAY_STDERR_CONTINUOUS) ? 1 : 0,				   hme_i (SCRIPT_FILE, i), argv)) < 0)	    return 0;    } else {	if (!(s->options & SHELL_OPTION_DISPLAY_STDERR_CONTINUOUS)) {	/* no output desired, just run in background */	    switch (fork ()) {	    case 0:{		    int nulldevice_wr, nulldevice_rd;		    nulldevice_wr = open ("/dev/null", O_WRONLY);		    nulldevice_rd = open ("/dev/null", O_RDONLY);		    close (0);		    dup (nulldevice_rd);		    close (1);		    dup (nulldevice_wr);		    close (2);		    dup (nulldevice_wr);		    set_signal_handlers_to_default ();		    execlp (argv[0], argv[0], 0);		    exit (0);	/* should never reach */		}	    case -1:		return 0;	    default:		return 1;	    }	}	if ((p = triple_pipe_open (0, 0, &running_shell[i].shell_pipe, 0, hme_i (SCRIPT_FILE, i), argv)) < 0)	    return 0;    }    running_shell[i].shell_pid = p;    if (!running_shell[i].shell_pool) {	running_shell[i].shell_pool = pool_init ();	pool_null (running_shell[i].shell_pool);    }    shell_display_output ((char *) pool_start (running_shell[i].shell_pool), catstrs (s->name, _ (" Output "), 0), goto_file_callback, name);    CAddWatch (running_shell[i].shell_pipe, shell_pool_update, WATCH_READING, (void *) i);    return 1;}char *read_pipe (int fd, int *len);/*   Returns shell_output on success, 0 on error. Result must be free'd.   Unlike the above routine, this blocks waiting for the shell to exit. */static char *execute_foreground_shell (struct shell_cmd *s, char *script){    pid_t p = 0;    char *argv[] =    {0, 0};    int shell_foreground_pipe = -1;    char *t;    argv[0] = hme (SCRIPT_FILE);    savefile (argv[0], script, strlen (script), 0700);    if (s->options & SHELL_OPTION_INSERT_STDOUT) {	if ((p = triple_pipe_open (0, &shell_foreground_pipe, 0, (s->options & SHELL_OPTION_INSERT_STDERR) ? 1 : 0, hme (SCRIPT_FILE), argv)) < 0)	    return 0;	t = read_pipe (shell_foreground_pipe, 0);    } else {	if ((p = triple_pipe_open (0, 0, &shell_foreground_pipe, 0, hme (SCRIPT_FILE), argv)) < 0)	    return 0;	t = read_pipe (shell_foreground_pipe, 0);	if (!(s->options & SHELL_OPTION_INSERT_STDERR)) {	    if (t)		free (t);	    t = (char *) strdup ("");	}    }    if (shell_foreground_pipe >= 0)	close (shell_foreground_pipe);    kill_process (p);    return t;}int edit_save_block (WEdit * edit, const char *filename, long start, long finish);/* This is called from the envokation dialog below */static int run_shell (WEdit * e, struct shell_cmd *s, char *cmdline_options, char *name){    struct stat st;    long start_mark, end_mark;    char *script;    char *output = 0;    int i;    i = find_shell (0, name, 0);    if (!(s->options & (SHELL_OPTION_DISPLAY_STDOUT_CONTINUOUS |			SHELL_OPTION_DISPLAY_STDERR_CONTINUOUS)))	/* --> these kill any running script automatically */	if (running_shell[i].shell_pid) {	    shell_error_dialog (_ (" Shell script "), _ (" A script is already running "));	    return -1;	}    if (s->options & SHELL_OPTION_SAVE_BLOCK) {	eval_marks (e, &start_mark, &end_mark);	edit_save_block (e, hme (BLOCK_FILE), start_mark, end_mark);    }    if (s->options & SHELL_OPTION_SAVE_EDITOR_FILE)	if (!edit_save_file (e, catstrs (e->dir, e->filename, 0)))	    if (!edit_save_as_cmd (e))		return -1;    script = substitute_strings (s->script,	  cmdline_options, catstrs (e->dir, e->filename, 0), "", "", "");    if ((s->options & (SHELL_OPTION_DISPLAY_STDOUT_CONTINUOUS |		       SHELL_OPTION_DISPLAY_STDERR_CONTINUOUS |		       SHELL_OPTION_RUN_IN_BACKGROUND))) {	if (!execute_background_shell (s, script, name)) {	    shell_error_dialog (_ (" Shell script "), get_sys_error (_ (" Error trying to pipe script. ")));	    return -1;	}	if (script)	    free (script);	return 0;    } else {	CHourGlass (main_window);	output = execute_foreground_shell (s, script);	CUnHourGlass (main_window);	if (!output) {	    shell_error_dialog (_ (" Shell script "), get_sys_error (_ (" Error trying to pipe script. ")));	    if (script)		free (script);	    return -1;	}    }    if (script)	free (script);    script = 0;    if (s->options & SHELL_OPTION_CHECK_ERROR_FILE) {	if (stat (hme (ERROR_FILE), &st) == 0) {	    if (st.st_size) {		char *error;		if (s->options & SHELL_OPTION_DISPLAY_ERROR_FILE) {		    error = loadfile (hme (ERROR_FILE), 0);		    if (error) {			CTextboxMessageDialog (main_window, 20, 20, 80, 20, catstrs (s->name, _ (" Error "), 0), error, 0);			free (error);		    }		}		return -1;	    }	}    }    if (s->options & SHELL_OPTION_DELETE_BLOCK)	if (edit_block_delete_cmd (e))	    return 1;    if (output)	if (*output)	    for (i = strlen (output) - 1; i >= 0; i--)		edit_insert_ahead (e, output[i]);    if (output)	free (output);    if (s->options & SHELL_OPTION_INSERT_TEMP_FILE)	if (!edit_insert_file (e, hme (TEMP_FILE)))	    shell_error_dialog (_ (" Shell script "), get_sys_error (_ (" Error trying to insert temp file. ")));    if (s->options & SHELL_OPTION_INSERT_BLOCK_FILE)	if (!edit_insert_file (e, hme (BLOCK_FILE)))	    shell_error_dialog (_ (" Shell script "), get_sys_error (_ (" Error trying to insert block file. ")));    if (s->options & SHELL_OPTION_INSERT_CLIP_FILE)	if (!edit_insert_file (e, hme (CLIP_FILE)))	    shell_error_dialog (_ (" Shell script "), get_sys_error (_ (" Error trying to insert clip file. ")));    if (s->options & SHELL_OPTION_DISPLAY_ERROR_FILE)	if (stat (hme (ERROR_FILE), &st) == 0)	    if (st.st_size) {	/* no error messages */		char *error;		error = loadfile (hme (ERROR_FILE), 0);		if (error) {		    CTextboxMessageDialog (main_window, 20, 20, 80, 25, s->name, error, 0);		    free (error);		}	    }    return 0;}int edit_execute_cmd (WEdit * edit, int command, int char_for_insertion);/*   Main entry point. Request args if option is set and calls run_shell.   Returns 0 on success, -1 on error and 1 on cancel. */static int run_shell_dialog (WEdit * e, struct shell_cmd *s){    char *cmdline_options;    int r;    long start_mark, end_mark;    if (!s)	return -1;    if (s->options & SHELL_OPTION_SAVE_BLOCK)	if (eval_marks (e, &start_mark, &end_mark)) {	    shell_error_dialog (_ (" Shell Script "), _ (" Script requires some text to be highlighted. "));	    return 1;	}    if (s->options & SHELL_OPTION_REQUEST_ARGUMENTS) {	char *p, *q;	p = (char *) strdup (s->name);	/* create a name for the input dialog by stripping spaces */	for (q = p; *q; q++)	    if (*q == ' ')		memmove (q, q + 1, strlen (q));	if (strlen (p) > 20)	    p[20] = 0;	cmdline_options = CInputDialog (p, 0, 0, 0, 40 * FONT_MEAN_WIDTH, s->last_options ? s->last_options : "", s->name, s->prompt);	free (p);	if (!cmdline_options)	    return 1;	if (s->last_options)	    free (s->last_options);	s->last_options = cmdline_options;    } else {	cmdline_options = "";    }    r = run_shell (e, s, cmdline_options, s->menu);    CRefreshEditor (e);    return r;}static struct shell_cmd *scripts[MAX_NUM_SCRIPTS] ={0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};/* loads from options file */void load_scripts (){    char *s = 0, *p, *q;    unsigned char *r;    int i = 0, n;    memset (&running_shell, 0, sizeof (running_shell));    s = get_options_section (editor_options_file, "[Shell Scripts]");    if (!s) {	goto load_default_scripts;    } else {	if (!*s)	    goto load_default_scripts;    }    p = q = s;    for (i = 0; i < MAX_NUM_SCRIPTS; i++) {	if (!*q || *q == '\n')	    break;	q = strchr (p, '\n');	if (!q)	    break;	*q++ = 0;	scripts[i] = CMalloc (sizeof (struct shell_cmd));	memset (scripts[i], 0, sizeof (struct shell_cmd));	strncpy (scripts[i]->name, p, 39);	p = q;	q = strchr (p, '\n');	*q++ = 0;	strncpy (scripts[i]->menu, p, 39);	p = q;	q = strchr (p, '\n');	*q++ = 0;	scripts[i]->menu_hot_key = *p;	p = q;	q = strchr (p, '\n');	*q++ = 0;	scripts[i]->key = (KeySym) atoi (p);	p = q;	q = strchr (p, '\n');	*q++ = 0;	scripts[i]->keyboard_state = atoi (p);	p = q;	q = strchr (p, '\n');	*q++ = 0;	strncpy (scripts[i]->prompt, p, 159);	p = q;	q = strchr (p, '\n');	*q++ = 0;	scripts[i]->options = atoi (p);	p = q;	q = strchr (p, '\n');	*q++ = 0;	scripts[i]->last_options = (char *) strdup (p);	p = q;	q = strchr (p, '\n');	*q++ = 0;	scripts[i]->script = (char *) strdup (p);	for (r = (unsigned char *) scripts[i]->script; *r; r++)	    if (*r == 129)		*r = '\n';	p = q;    }  load_default_scripts:    n = sizeof (default_scripts) / sizeof (struct shell_cmd);    if (i < n) {	for (; i < n; i++) {	    scripts[i] = CMalloc (sizeof (struct shell_cmd));	    memset (scripts[i], 0, sizeof (struct shell_cmd));	    memcpy (scripts[i], &default_scripts[i], sizeof (struct shell_cmd));	    scripts[i]->script = (char *) strdup (default_scripts[i].script);	}    }    if (s)	free (s);}/* saves to options file */static void save_scripts (void){    char *s, *p;    int i = 0, n;    p = s = CMalloc (65536);	/* make longer if overwrites */    while (scripts[i]) {	unsigned char *t, *r;	t = (unsigned char *) strdup (scripts[i]->script);	for (r = t; *r; r++)	    if (*r == '\n')		*r = 129;	/* replace newlines with 129 */	sprintf (p, "%s\n%s\n%c\n%d\n%d\n%s\n%d\n%s\n%s\n%n",		 scripts[i]->name ? scripts[i]->name : 0,		 scripts[i]->menu ? scripts[i]->menu : 0,	       scripts[i]->menu_hot_key ? scripts[i]->menu_hot_key : ' ',		 (int) scripts[i]->key,		 (int) scripts[i]->keyboard_state,		 scripts[i]->prompt ? scripts[i]->prompt : "",		 (int) scripts[i]->options,		 scripts[i]->last_options ? scripts[i]->last_options : "",		 t, &n);	free (t);	p += n;	i++;    }    *p++ = '\n';    *p = 0;    save_options_section (editor_options_file, "[Shell Scripts]", s);    free (s);}#define N_ITEMS 4extern CWidget *edit[];extern int current_edit;/* straight from the menu */static void script_menu_callback (unsigned long ignored)

⌨️ 快捷键说明

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