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

📄 textsw_filter.c

📁 操作系统SunOS 4.1.3版本的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
		    goto Deal_With_Slop;		textsw_set_selection(VIEW_REP_TO_ABS(folio->first_view),				     (Es_index)int_buffer[2],				     (Es_index)int_buffer[3],				     EV_SEL_PRIMARY);		buffer += 4*sizeof(int);		break;	      default:		return(REPLY_ERROR);	    }	}	return(result);Deal_With_Slop:	ASSUME(buffer_last_plus_one-buffer < SLOP_SIZE);	if (buffer >= save_buffer)	    bcopy(buffer, buffer-SLOP_SIZE, buffer_last_plus_one-buffer);	folio->owed_by_filter = buffer-buffer_last_plus_one;	return(result);}pkg_private inttextsw_call_smart_filter(view, event, filter_argv)	register Textsw_view	 view;	Event			*event;	char			*filter_argv[];{/* *   A smart filter is expected to do more than just filter the current * selection.  As a result, it is passed more information; in particular: *	the entire input event that resulted in the filter invocation *	the position of the insertion point, and the first and last_plus_one *		positions of the line containing the insertion point, *	the first and last_plus_one positions of the selection, *	the line containing the insertion point, *	the selection */#define	FILTER_STARTED		0#define	HEADER_WRITTEN		1#define	INSERT_LINE_WRITTEN	2	extern Es_index		 ev_get_insert();	register Textsw_folio	 folio = FOLIO_FOR_VIEW(view);	int			 filter_input, filter_output,				 max_fds = GETDTABLESIZE(),				 result = 0;	Textsw_filter_attribute	 filter_attribute;	unsigned char		 buffer[PIPSIZ];	struct timeval		 tv;	Es_index		 insert, save_length;	Es_index		 insert_line_first, insert_line_last_plus_one;	unsigned		 state = FILTER_STARTED;	Ev_mark_object		 save_lpo_id;	int			 pid;	Textsw_selection_object	 selection;	Notify_func		 old_sigpipe = (Notify_func)0;	insert = ev_get_insert(folio->views);	ev_span(folio->views, insert, &insert_line_first,		&insert_line_last_plus_one, EI_SPAN_LINE);	if (insert_line_first == ES_CANNOT_SET) {	    insert_line_first = insert_line_last_plus_one = insert;	}	(void) textsw_filter_selection(folio, &selection);	if (selection.type & EV_SEL_PENDING_DELETE) {	    save_length = selection.last_plus_one - selection.first;	    save_lpo_id =		textsw_add_mark_internal(folio, selection.last_plus_one,					 TEXTSW_MARK_DEFAULTS);	}	pid = start_filter(filter_argv, &filter_input, &filter_output);	if (pid == FAIL) {	    result = 1;	    goto NoFilterReturn;	}	old_sigpipe =	    notify_set_signal_func((Notify_client)folio, textsw_sigpipe_func,				   SIGPIPE, NOTIFY_ASYNC);	(void) notify_set_wait3_func((Notify_client)folio,				     notify_default_wait3, pid);	    /* Note that there is no meaningful old_wait3_func */	tv.tv_sec = 1; tv.tv_usec = 0;		ev_set(0, folio->views, EV_CHAIN_DELAY_UPDATE, TRUE, 0);	/*	 * Give the filter the initial information	 */	for (;;) {	    register int		 nfds;	    fd_set			 exceptfds, readfds, writefds;	    int				 written;	    register struct timeval	*tv_to_use;	    FD_ZERO(&exceptfds); FD_ZERO(&readfds); FD_ZERO(&writefds);            FD_SET(filter_input, &writefds);	    tv_to_use = (timerisset(&tv)) ? &tv : 0;	    nfds = select(max_fds, &readfds, &writefds, &exceptfds, tv_to_use);	    switch (nfds) {	      case -1:	if (errno == EINTR)			    continue;		/* Probably itimer expired */			goto ErrorReturn;	      case 0:	/* Fall through */		      default:	timerclear(&tv);			break;	    }	    /* if (writefds & (1 << filter_input)) { */	    if (FD_ISSET(filter_input, &writefds)) {		int		to_write;		Es_index	next;		if (state == FILTER_STARTED) {		    filter_attribute = TEXTSW_FATTR_INPUT_EVENT;		    if ((write(filter_input, (char *)&filter_attribute,			       sizeof(filter_attribute)) == -1) ||			(write(filter_input, (char *)event,			       sizeof(*event)) == -1))			goto Write_Failed;		    if (folio->to_insert_next_free > folio->to_insert) {			filter_attribute = TEXTSW_FATTR_INPUT;			to_write = folio->to_insert_next_free-				   folio->to_insert;			if ((write(filter_input, (char *)&filter_attribute,				   sizeof(filter_attribute)) == -1) ||			    (write(filter_input, (char *)&to_write,				   sizeof(to_write)) == -1) ||			    (write(filter_input, folio->to_insert,				   to_write) == -1))			    goto Write_Failed;		    }		    filter_attribute = TEXTSW_FATTR_INSERTION_POINTS;		    if ((write(filter_input, (char *)&filter_attribute,			       sizeof(filter_attribute)) == -1) ||			(write(filter_input, (char *)&insert,			       sizeof(insert)) == -1) ||			(write(filter_input, (char *)&insert_line_first,			       sizeof(insert_line_first)) == -1) ||			(write(filter_input,			       (char *)&insert_line_last_plus_one,			       sizeof(insert_line_last_plus_one)) == -1))			goto Write_Failed;		    filter_attribute = TEXTSW_FATTR_SELECTION_ENDPOINTS;		    if ((write(filter_input, (char *)&filter_attribute,			       sizeof(filter_attribute)) == -1) ||			(write(filter_input, (char *)&selection.first,			       sizeof(selection.first)) == -1) ||			(write(filter_input, (char *)&selection.last_plus_one,			       sizeof(selection.last_plus_one)) == -1))			goto Write_Failed;		    if (insert_line_first < insert_line_last_plus_one) {			filter_attribute = TEXTSW_FATTR_INSERTION_LINE;			if (write(filter_input, (char *)&filter_attribute,			       sizeof(filter_attribute)) == -1)			goto Write_Failed;		    }		    state = HEADER_WRITTEN;		}		if (state == HEADER_WRITTEN) {		    if (insert_line_last_plus_one <= insert_line_first)			goto Done_Initial_Data;		    (void) es_set_position(folio->views->esh,					   insert_line_first);		    to_write = sizeof(buffer);		    if (to_write > insert_line_last_plus_one-insert_line_first)			to_write = insert_line_last_plus_one-insert_line_first;		    next = es_read(folio->views->esh, to_write, buffer,				   &to_write);		    if (READ_AT_EOF(insert_line_first, next, to_write)) {			goto Done_Initial_Data;		    } else {			ASSUME(to_write <= PIPSIZ);			written = write(filter_input, (char *)buffer,					to_write);			if (written == -1)			    goto Write_Failed;			insert_line_first = next;		    }		}	    }	    continue;Write_Failed:	    if (errno == EMSGSIZE) {		/* Give filter a chance to run */		tv.tv_sec = 0;		tv.tv_usec = 50000;	    } else goto ErrorReturn;	}Done_Initial_Data:	state = INSERT_LINE_WRITTEN;	switch (talk_to_filter(view, filter_input, filter_output,			       ES_INFINITY, ES_INFINITY,			       smarter_interpret_filter_reply)) {	  case 0:	    break;	  case 1:	    goto ErrorReturn;	}NormalReturn:	(void) close(filter_output);	if ((result == 0) && (selection.type & EV_SEL_PENDING_DELETE)) {	    Es_index		saved_lpo;	    saved_lpo = textsw_find_mark_internal(folio, save_lpo_id);	    if AN_ERROR(saved_lpo == ES_INFINITY) {	    } else {		(void) textsw_delete_span(view, saved_lpo-save_length,					  saved_lpo,					  TXTSW_DS_ADJUST|TXTSW_DS_SHELVE);	    }	}	if (old_sigpipe)	    (void) notify_set_signal_func((Notify_client)folio, old_sigpipe,					  SIGPIPE, NOTIFY_ASYNC);NoFilterReturn:        (void) close(filter_input); /* ECD fix */        (void) close(filter_output); /* ECD fix */	if (selection.type & EV_SEL_PENDING_DELETE)	    textsw_remove_mark_internal(folio, save_lpo_id);	folio->owed_by_filter = 0;	ev_set(0, folio->views, EV_CHAIN_DELAY_UPDATE, FALSE, 0);	ev_update_chain_display(folio->views);	return(result);ErrorReturn:	result = 3;	goto NormalReturn;}extern voidclose_nonstd_fds_on_exec(){	int	fd, max_fds = GETDTABLESIZE();	for (fd = STDERR+1; fd < max_fds; fd++)		(void) fcntl(fd, F_SETFD, 1);}static intstart_filter(filter_argv, filter_input, filter_output)	char	*filter_argv[];	int	*filter_input, *filter_output;{	int	 to_filter[2], from_filter[2], pid;	errno = 0;	if ((pipe(to_filter) != 0) || (pipe(from_filter) != 0))	    return(FAIL);	pid = vfork();	if (pid == 0) {		/* child */	    /*	     * Fiddle with the file descriptors, since the exec'd filter	     *   expects to read the data from stdin, and to write to stdout.	     */	    if ((dup2(to_filter[INPUT], STDIN) == -1) ||		(dup2(from_filter[OUTPUT], STDOUT) == -1))		    _exit(6);	    close_nonstd_fds_on_exec();	    (void) execvp(filter_argv[0], filter_argv);	    /*	     * Since we used vfork, the child is sharing the parent's address	     *   space.  The advantage is that we can let the parent know that	     *   the execvp failed simply by changing the (shared)	     *   execvp_failed.  The disadvantage is that we have to be very	     *   careful about how we terminate the (now unwanted) child.	     */	    execvp_failed = TRUE;	    _exit(7);	    }	/* parent */	if (execvp_failed || (pid < 0)) {	    execvp_failed = FALSE;	    return(FAIL);	}	if ((close(to_filter[INPUT]) == -1) ||	    (close(from_filter[OUTPUT]) == -1))	    return(FAIL);	/*	 * The pipes to the filter must be non-blocking so that caller can	 *   avoid deadly embrace while pushing the data through the filter.	 */	if (fcntl(to_filter[OUTPUT], F_SETFL, FNDELAY) == -1)	    return(FAIL);	if (fcntl(from_filter[INPUT], F_SETFL, FNDELAY) == -1)	    return(FAIL);	*filter_input = to_filter[OUTPUT];	*filter_output = from_filter[INPUT];	return(pid);}/* *	Parser of the .textswrc file at startup time */#include <sys/dir.h>#include "sunwindow/filter.h"#undef FOREVER#undef strdup#include "sunwindow/io_stream.h"extern STREAM		*file_input_stream();extern STREAM		*filter_comments_stream();pkg_private inttextsw_parse_rc(textsw)	Textsw_folio		 textsw;{	char			 *base_name = ".textswrc",				  file_name[MAXNAMLEN],				 *login_dir;	STREAM			 *rc_stream = NULL;	STREAM			 *rc_wo_comments_stream = NULL;	Key_map_handle		  current_key;	Key_map_handle		 *previous_key;	int			  i;	short unsigned		  type;	short			  event_code;	int			  result = 0;	struct filter_rec	**filters = NULL;	textsw->key_maps = NULL;	if ((login_dir = getlogindir()) == NULL)	    return(1);	(void) sprintf(file_name, "%s/%s", login_dir, base_name);	if ((rc_stream = file_input_stream(file_name, (FILE *)0)) == NULL) {	    result = 2;	    goto Done;	}	if ((rc_wo_comments_stream = filter_comments_stream(rc_stream))	    == NULL) {	    result = 3;	    goto Done;	}	if ((filters = parse_filter_table(rc_wo_comments_stream, base_name)) == NULL) {	    result = 4;	    goto Done;	}	previous_key = &textsw->key_maps;	for (i = 0; filters[i]; i++) {	    if ((event_code = event_code_for_filter_rec(filters[i])) == -1) {		continue;	    }	    if ((type = type_for_filter_rec(filters[i])) == TXTSW_KEY_NULL) {		continue;	    }	    *previous_key = current_key = NEW(Key_map_object);	    current_key->next = NULL;	    current_key->event_code = event_code;	    current_key->type = type;	    current_key->shifts = 0;	    current_key->maps_to = (caddr_t) filters[i]->call;	    filters[i]->call = NULL;	/* Transfer storage ownership. */	    previous_key = &(current_key->next);	}Done:	if (rc_stream != NULL)	    stream_close(rc_stream);	if (rc_wo_comments_stream != NULL)	    stream_close(rc_wo_comments_stream);	if (filters != NULL)	    free_filter_table(filters);	return(result);}static char	*type_groups[] = {	"FILTER", "SMART_FILTER", "MACRO", NULL};static short unsignedtype_for_filter_rec(rec)	struct filter_rec	*rec;{	int			 count;	count = match_in_table(rec->class, type_groups);	switch (count) {	  case -1:	    return(TXTSW_KEY_NULL);	  case TXTSW_KEY_FILTER:	  case TXTSW_KEY_SMART_FILTER:	  case TXTSW_KEY_MACRO:	    return(count);	  default:	    LINT_IGNORE(ASSUME(0));	    return(TXTSW_KEY_NULL);	}}static char	*key_groups[] = {	"KEY_LEFT", "KEY_TOP", "KEY_RIGHT", "KEY_BOTTOM",	"L", "T", "F", "R", "B", NULL};static intevent_code_for_filter_rec(rec)	struct filter_rec	*rec;{	int			 count;	count = match_in_table(rec->key_name, key_groups);	switch (count) {	  case -1:	    return(-1);	  case 0:	  case 4:	    return((rec->key_num < 0 || rec->key_num > 15)		    ? -1		    : KEY_LEFT(rec->key_num));	  case 1:	  case 5:	  case 6:	    return((rec->key_num < 0 || rec->key_num > 15)		    ? -1		    : KEY_TOP(rec->key_num));	  case 2:	  case 7:	    return((rec->key_num < 0 || rec->key_num > 15)		    ? -1		    : KEY_RIGHT(rec->key_num));	  case 3:	  case 8:	    return((rec->key_num < 0 || rec->key_num > 1)		    ? -1		    : KEY_BOTTOMLEFT + rec->key_num);	  default:	    LINT_IGNORE(ASSUME(0));	    return(-1);	}}

⌨️ 快捷键说明

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