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

📄 shell.c

📁 具有IDE功能的编辑器
💻 C
📖 第 1 页 / 共 3 页
字号:
/* shell.c - user defined shell commands    Copyright (C) 1996-2000 Paul Sheer   This program is free software; you can redistribute it and/or modify   it under the terms of the GNU General Public License as published by   the Free Software Foundation; either version 2 of the License, or   (at your option) any later version.   This program is distributed in the hope that it will be useful,   but WITHOUT ANY WARRANTY; without even the implied warranty of   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the   GNU General Public License for more details.   You should have received a copy of the GNU General Public License   along with this program; if not, write to the Free Software   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA   02111-1307, USA. */#include <config.h>#include <sys/types.h>#if HAVE_SYS_WAIT_H#include <sys/wait.h>#endif#ifndef WEXITSTATUS#define WEXITSTATUS(stat_val) ((unsigned)(stat_val) >> 8)#endif#ifndef WIFEXITED#define WIFEXITED(stat_val) (((stat_val) & 255) == 0)#endif#include <errno.h>#ifdef HAVE_SYS_ERRNO_H#include <sys/errno.h>#endif#include "editoptions.h"#include "shell.h"#include "pool.h"#include "mad.h"#define shell_error_dialog(h,t) CErrorDialog(e->widget->winid,20,20,h,"%s",t)#undef gettext_noop#define gettext_noop(x) xextern struct look *look;int save_options_section (const char *file, const char *section, const char *text);extern char *editor_options_file;extern char *init_font;extern Window main_window;/* Here are the default example shells */struct shell_cmd default_scripts[] ={    {	" Sed ",	"Sed...\tC-M-d",	'~',	XK_d,	Mod1Mask | ControlMask,	gettext_noop (" Enter sed arguments (see sed manpage) : "),	SHELL_OPTION_SAVE_BLOCK | SHELL_OPTION_REQUEST_ARGUMENTS |	SHELL_OPTION_DELETE_BLOCK | SHELL_OPTION_INSERT_STDOUT |	SHELL_OPTION_DISPLAY_ERROR_FILE | SHELL_OPTION_CHECK_ERROR_FILE,	0,	"#!/bin/sh\n" \	"cat %b | sed %a 2>%e\n"    },    {	gettext_noop (" Indent "),	gettext_noop ("'indent' C Formatter\tS-F9"),	'~',	XK_F9,	ShiftMask,	"",	SHELL_OPTION_SAVE_BLOCK | SHELL_OPTION_DELETE_BLOCK |	SHELL_OPTION_DISPLAY_ERROR_FILE | SHELL_OPTION_CHECK_ERROR_FILE |	SHELL_OPTION_INSERT_BLOCK_FILE,	0,	"#!/bin/sh\n" \	"indent -kr -pcs %b 2>%e\n"    },    {	gettext_noop (" Sort "),	gettext_noop ("Sort...\tM-t"),	'~',	XK_t,	Mod1Mask,	gettext_noop (" Enter sort options (see sort manpage) : "),	SHELL_OPTION_SAVE_BLOCK | SHELL_OPTION_REQUEST_ARGUMENTS |	SHELL_OPTION_DELETE_BLOCK | SHELL_OPTION_INSERT_STDOUT |	SHELL_OPTION_DISPLAY_ERROR_FILE | SHELL_OPTION_CHECK_ERROR_FILE,	0,	"#!/bin/sh\n" \	"sort %a %b 2>%e\n"    },    {	" Ispell ",	gettext_noop ("'ispell' Spell Check\tC-p"),	'~',	XK_p,	ControlMask,	"",	SHELL_OPTION_SAVE_BLOCK | SHELL_OPTION_DELETE_BLOCK |	SHELL_OPTION_INSERT_BLOCK_FILE,	0,	"#!/bin/sh\n" \	XTERM_CMD " -e ispell %b\n"    },    {	" Make ",	gettext_noop ("Run make in curr. dir\tM-F7"),	'~',	XK_F7,	Mod1Mask,	"",	SHELL_OPTION_DISPLAY_STDOUT_CONTINUOUS |	SHELL_OPTION_DISPLAY_STDERR_CONTINUOUS,	0,	"#!/bin/sh\n" \	"cd %d\n" \	"make\n" \	"echo Done\n"    },    {	" Latex ",	"Latex\tC-M-l",	'~',	XK_l,	Mod1Mask | ControlMask,	"",	SHELL_OPTION_DISPLAY_STDOUT_CONTINUOUS |	SHELL_OPTION_DISPLAY_STDERR_CONTINUOUS,	0,	"#!/bin/sh\n" \	"cd %p\n" \	"latex %f\n" \	"echo Done\n"    },    {	" Latex to PS ",	"Latex to PS\tC-M-p",	'~',	XK_p,	Mod1Mask | ControlMask,	"",	SHELL_OPTION_DISPLAY_STDOUT_CONTINUOUS |	SHELL_OPTION_DISPLAY_STDERR_CONTINUOUS,	0,	"#!/bin/sh\n" \	"cd %p\n" \	"latex %f\n" \	"dvips %n.dvi\n" \	"echo Done\n"    },    {	" Xdvi ",	"Xdvi\tC-M-d",	'~',	XK_d,	Mod1Mask | ControlMask,	"",	SHELL_OPTION_RUN_IN_BACKGROUND,	0,	"#!/bin/sh\n" \	"cd %p\n" \	"xdvi %n.dvi 2>%e\n"    },    {	" GhostView ",	"GhostView\tC-M-g",	'~',	XK_g,	Mod1Mask | ControlMask,	"",	SHELL_OPTION_RUN_IN_BACKGROUND,	0,	"#!/bin/sh\n" \	"cd %p\n" \	"ghostview %n.ps 2>%e\n"    },    {	gettext_noop (" Run Application "),	gettext_noop ("Run Application...\tC-M-a"),	'~',	XK_a,	Mod1Mask | ControlMask,	gettext_noop (" Enter command : "),	SHELL_OPTION_REQUEST_ARGUMENTS |	SHELL_OPTION_RUN_IN_BACKGROUND,	0,	"#!/bin/sh\n" \	"%a 2>%e\n"    },    {	gettext_noop (" Terminal Application "),	gettext_noop ("Run Terminal App...\tC-M-e"),	'~',	XK_e,	Mod1Mask | ControlMask,	gettext_noop (" Enter command : "),	SHELL_OPTION_REQUEST_ARGUMENTS |	SHELL_OPTION_RUN_IN_BACKGROUND,	0,	"#!/bin/sh\n" \	XTERM_CMD " -e %a\n"    },    {	" Translate ",	"Translate...\tC-M-t",	'~',	XK_t,	Mod1Mask | ControlMask,	gettext_noop (" Enter args for tr (See `man tr' for help): "),	SHELL_OPTION_SAVE_BLOCK | SHELL_OPTION_REQUEST_ARGUMENTS |	SHELL_OPTION_DELETE_BLOCK | SHELL_OPTION_INSERT_STDOUT |	SHELL_OPTION_DISPLAY_ERROR_FILE | SHELL_OPTION_CHECK_ERROR_FILE,	0,	"#!/bin/sh\n" \	"cat %b | tr %a 2>%e\n"    },    {	gettext_noop (" C Run "),	gettext_noop ("Run this file\tC-M-r"),	'~',	XK_r,	Mod1Mask | ControlMask,	"",	SHELL_OPTION_RUN_IN_BACKGROUND,	0,	"#!/bin/sh\n" \	XTERM_CMD " -e %p/%n\n"    },    {	gettext_noop (" C Compile "),	"Cc\tC-M-c",	'~',	XK_c,	Mod1Mask | ControlMask,	"",	SHELL_OPTION_DISPLAY_STDOUT_CONTINUOUS |	SHELL_OPTION_DISPLAY_STDERR_CONTINUOUS,	0,	"#!/bin/sh\n" \	"cd %p\n" \	"cc -g -Wall -o %n %f\n" \	"echo Done\n"    }};char *hme (char *text);char *substitute_strings (char *text, char *cmdline_options, char *editor_file, char *dnd_major_type, char *dnd_minor_type, char *dnd_data_file);/* {{{ dynamic display of shell output in a dialog box */#define MAX_RUNNING_SHELLS 32static struct running_shell {    pid_t shell_pid;    int shell_pipe;    POOL *shell_pool;    char *shell_name;    CWidget *w;    int killme;} running_shell[MAX_RUNNING_SHELLS];static void kill_process (pid_t p){    if (p)	kill (p, SIGTERM);}/* one of these must be non-zero */static int find_shell (pid_t p, char *name, CWidget * w){    int i;    for (i = 0; i < MAX_RUNNING_SHELLS; i++) {	if (p)	    if (running_shell[i].shell_pid == p)		return i;	if (name && running_shell[i].shell_name)	    if (*name)		if (!strcmp (name, running_shell[i].shell_name))		    return i;	if (w)	    if ((unsigned long) w == (unsigned long) running_shell[i].w)		return i;    }    return -1;}static int new_shell (char *name){    int i;    i = find_shell (0, name, 0);    if (i < 0) {	for (i = 0; i < MAX_RUNNING_SHELLS; i++)	    if (!running_shell[i].shell_name) {		memset (&running_shell[i], 0, sizeof (struct running_shell));		running_shell[i].shell_pipe = -1;		running_shell[i].shell_name = name;	/* FIXME: strdup() then free() later - static is ok for now */		return i;	    }    }    return -1;}void text_free (void *x){    if (x)	free (x);}static void shell_pool_update (int fd, fd_set * reading, fd_set * writing, fd_set * error, void *data);char *shell_free_pool (int i){    char *s = 0;    if (i < 0)	return 0;    if (running_shell[i].shell_pool)	s = (char *) pool_break (running_shell[i].shell_pool);    if (running_shell[i].shell_pipe >= 0) {	CRemoveWatch (running_shell[i].shell_pipe , shell_pool_update, WATCH_READING);	close (running_shell[i].shell_pipe);    }    memset (&running_shell[i], 0, sizeof (struct running_shell));    running_shell[i].shell_pipe = -1;    return s;}/* kills an executing shell whose output is being dynamically displayed */void set_to_kill (pid_t p){    int i;    i = find_shell (p, 0, 0);    if (i >= 0)	running_shell[i].killme = 1;}/* kills an executing shell whose output is being dynamically displayed */static int kill_shell (pid_t p, char *name, CWidget * w){    int i;    i = find_shell (p, name, w);    if (i < 0)	return -1;    kill_process (running_shell[i].shell_pid);    set_to_kill (running_shell[i].shell_pid);    return i;}static int restart_shell (pid_t p, char *name, CWidget * w){    int i;    i = find_shell (p, name, w);    if (i < 0)	return new_shell (name);    if (running_shell[i].shell_pipe >= 0) {	CRemoveWatch (running_shell[i].shell_pipe, shell_pool_update, WATCH_READING);	close (running_shell[i].shell_pipe);    }    kill_process (running_shell[i].shell_pid);    running_shell[i].shell_pid = 0;    running_shell[i].shell_pipe = -1;    running_shell[i].killme = 0;    if (running_shell[i].shell_pool) {	pool_break (running_shell[i].shell_pool);	running_shell[i].shell_pool = 0;    }    return i;}void goto_error (char *message, int raise_wm_window);/* if you double click on a line of gcc output, this will take you to the file */static int goto_file_callback (CWidget * w, XEvent * x, CEvent * c){    if (c->double_click || (c->command == CK_Enter && !c->handled)) {	int width;	char *q;	CPushFont ("editor", 0);	width = w->options & TEXTBOX_WRAP ? (w->width - TEXTBOX_BDR) / FONT_MEAN_WIDTH : 32000;	CPopFont ();	q = strline (w->text, strmovelines (w->text, w->current, w->cursor - w->firstline, width));	goto_error (q, 1);    }    return 0;}static char *nm (int i, char *a, char *b, char *c){    static char id[36];    sprintf (id, "%.3d%s", i, a);    if (b) {	strcat (id, ".");	strcat (id, b);	if (c) {	    strcat (id, ".");	    strcat (id, c);	}    }    return id;}/* if the dynamic output dialog's tick button is click, then terminate: */static int display_file_callback (CWidget * w, XEvent * x, CEvent * c){    shell_free_pool (kill_shell (0, 0, CIdent (nm (atoi (w->ident), "shelldisplaytext", "text", 0))));    CDestroyWidget (nm (atoi (w->ident), "shelldisplaytext", 0, 0));    return 1;}#if 0    fd_set reading;    struct timeval tv;    FD_ZERO (&reading);    for (i = 0; i < MAX_RUNNING_SHELLS; i++) {	if (running_shell[i].shell_pipe >= 0 && running_shell[i].shell_name) {	    FD_SET (running_shell[i].shell_pipe, &reading);	    if (n < (int) running_shell[i].shell_pipe)		n = running_shell[i].shell_pipe;	}    }    if (n < 0) {	CAddCallback ("AlarmCallback", 0);	return 0;    }    tv.tv_sec = 0;    tv.tv_usec = 0;#endif#define CHUNK 8192static void shell_pool_update (int fd, fd_set * reading, fd_set * writing, fd_set * error, void *data){    CWidget *w;    struct running_shell *r;    int i, count = 0, do_redraw = 0;    r = &running_shell[i = (int) data];    if (r->shell_pipe != fd) {	printf ("huh??\n");    }/* first check if we are still on the screen */    w = CIdent (nm (i, "shelldisplaytext", "text", 0));    if (!w) {	shell_free_pool (kill_shell (0, 0, w));	return;    }/* is the buffer initialised? : */    if (!r->shell_pool)	r->shell_pool = pool_init ();/* read a little */    for (;;) {	int c, j;	unsigned char *p;	if (pool_freespace (r->shell_pool) < CHUNK + 1) {	    pool_advance (r->shell_pool, CHUNK + 1);	    do_redraw = 1;	/* must redraw cause pool has changed */	}	while ((c = read (fd, pool_current (r->shell_pool), CHUNK)) == -1 && errno == EINTR);/* translate unreadables */	for (j = 0, p = (unsigned char *) pool_current (r->shell_pool); j < c; j++, p++) {	    if (*p == '\t')		*p = ' ';	    else if (*p == '\n')		*p = '\n';	    else if (!FONT_PER_CHAR(*p))		*p = '?';	}	if (c <= 0)	    break;	count += c;	pool_current (r->shell_pool) += c;	break;    }    pool_null (r->shell_pool);	/* adds a zero to the end *//* do we need to refresh? : */

⌨️ 快捷键说明

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