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

📄 textsw_extrasmenu.c

📁 操作系统SunOS 4.1.3版本的源码
💻 C
字号:
#ifndef lint#ifdef sccsstatic  char sccsid[] = "@(#)textsw_extrasmenu.c 1.1 92/07/30 SMI";#endif#endif/* * Copyright (c) 1987 by Sun Microsystems, Inc. *//***	Allow a user definable "Extras" menu in the textsw.  The search**	path to find the name of the file to initially look in is:**	/Text/Extras_menu_filename (defaults), EXTRASMENU (environment var),**	default ("/usr/lib/.text_extras_menu")****	Much of this code was borrowed from the suntools dynamic rootmenu code.*/#include	<suntool/primal.h>#include	<suntool/textsw_impl.h>#include	<errno.h>#include	<ctype.h>#include	<suntool/walkmenu.h>#include	<sunwindow/defaults.h>#include	<suntool/wmgr.h>#include	<suntool/icon.h>#include	<suntool/icon_load.h>#include	<sys/stat.h>#include	<strings.h>#include	<sunwindow/string_utils.h>#include	<sunwindow/sun.h>#include	"sunwindow/sv_malloc.h"#define	ERROR	-1#define	MAX_FILES	40#define MAXPATHLEN	1024#define	EXTRASMENU	"/usr/lib/.text_extras_menu"#define	MAXSTRLEN	256#define	MAXARGS		20struct stat_rec{    char             *name;	   /* Dynamically allocated menu file name */    time_t            mftime;      /* Modified file time */};static char		*textsw_savestr(), *textsw_save2str();extern char		*strcpy(), *index(), *getenv();void			expand_path();struct stat_rec		Extras_stat_array[MAX_FILES];int			Textsw_nextfile;static char		*Textsw_extras_menu_file;Menu_item		textsw_handle_extras_menuitem();static int		get_new_menu();static int		extras_menufile_changed();static int		free_stat_array();static int		walk_menufile();static int		walk_getmenu();pkg_private char	**string_to_argv();static int		free_argv();static Textsw		textsw; /* This should be a MENU_CLIENT_DATA in				 * walk_getmenu() when the pullright is 				 * created; however, it is already used.				 * When I have more time, I will come back and				 * fix this.				 */static Menu		Current_menu;static int		Nargs;intmake_new_menu(textsw, menu)     Textsw		textsw;    Menu		menu;{/*   *  Create new menu if there isn't one already, or *  if the current menu is not created with the textsw. *  This should be fixed, so the extras menu will only be created *  once for each textsw. */    return ((menu == NULL) ||             (textsw != (Textsw)LINT_CAST(menu_get(menu, MENU_CLIENT_DATA)))); }    Menutextsw_build_extras_menu(item, operation)	Menu_item	item;	Menu_generate	operation;{    textsw = (Textsw)LINT_CAST(menu_get(item, MENU_CLIENT_DATA));    	switch(operation)	{		case MENU_DISPLAY:			if(make_new_menu(textsw, Current_menu) || 			   extras_menufile_changed()) {			    get_new_menu(textsw, item);			}				break;		case MENU_DISPLAY_DONE:			break;		case MENU_NOTIFY:		        			if(make_new_menu(textsw, Current_menu) || 			   extras_menufile_changed()) {			    			    get_new_menu(textsw, item);			}				break;		case MENU_NOTIFY_DONE:			break;		default: 			break; 	}	return(Current_menu); }static intget_new_menu(textsw, item)    Textsw		textsw;	Menu_item	item;{	Menu	new_menu;						free_stat_array();		new_menu = menu_create(		MENU_LEFT_MARGIN,	6,		MENU_CLIENT_DATA,	textsw,		HELP_DATA,		"textsw:extrasmenu",		0);	if(walk_menufile(Textsw_extras_menu_file, new_menu) < 0)		menu_destroy(new_menu);	else	{		menu_destroy(Current_menu);		Current_menu = new_menu;	}}/***	Check to see if there is a valid extrasmenu file.  If the file**	exists then turn on the Extras item.  If the file does not **	exist and there isn't an Extras menu to display then gray out**	the Extras item.  Otherwise leave it alone.*/Menu_itemtextsw_toggle_extras_item(extras_item, operation)	Menu_item	extras_item;	Menu_generate	operation;{	char		full_file[MAXPATHLEN];	struct stat	statb;	switch(operation)	{		case MENU_DISPLAY:			if(Textsw_extras_menu_file == NULL)			{			    Textsw_extras_menu_file = defaults_get_string(			      "/Text/Extras_menu_filename", "", (int *)NULL);			    if((*Textsw_extras_menu_file == '\0')			      && ((Textsw_extras_menu_file = getenv("EXTRASMENU")) == NULL))				Textsw_extras_menu_file = EXTRASMENU;			}			expand_path(Textsw_extras_menu_file, full_file);			if(stat(full_file, &statb) < 0)			{				if(!Current_menu)					menu_set(extras_item, MENU_INACTIVE, TRUE, 0);			}			else				menu_set(extras_item, MENU_INACTIVE, FALSE, 0);			break;		case MENU_DISPLAY_DONE:		case MENU_NOTIFY:		case MENU_NOTIFY_DONE:			break;		default: 			break; 	}	return(extras_item);}static intextras_menufile_changed(){	int		i;	struct stat	statb;	if(Textsw_nextfile == 0) return(TRUE);	/* Whenever existing menu going up, stat menu files */	for(i = 0;i < Textsw_nextfile;i++)	{		if(stat(Extras_stat_array[i].name, &statb) < 0)		{			if(errno == ENOENT)				return(TRUE);			(void)fprintf(stderr, "textsw: ");			perror(Extras_stat_array[i].name);			return(ERROR);		}		if(statb.st_mtime > Extras_stat_array[i].mftime)			return(TRUE);	}	return(FALSE);}static intfree_stat_array(){   	int i = 0;    	while(i < Textsw_nextfile)	{		free(Extras_stat_array[i].name);	/* file name */		Extras_stat_array[i].name = NULL;		Extras_stat_array[i].mftime = 0;	/* mod time */		i++;	}	Textsw_nextfile = 0;}static intwalk_menufile(file, menu)	char 		*file;	Menu 		menu;{   	FILE		*mfd;	int		lineno = 1; /* Needed for recursion */	char		full_file[MAXPATHLEN];	struct stat 	statb;    expand_path(file, full_file);    if((mfd = fopen(full_file, "r")) == NULL) {	    (void)fprintf(stderr, "textsw: can't open extras menu file %s\n", full_file);	    return(ERROR);    }    if(Textsw_nextfile >= MAX_FILES - 1) {	    (void)fprintf(stderr, "textsw: max number of menu files is %ld\n", MAX_FILES);	    (void)fclose(mfd);	    return(ERROR);    }    if(stat(full_file, &statb) < 0) {	    (void)fprintf(stderr, "textsw: ");    	perror(full_file);	    (void)fclose(mfd);	    return(ERROR);    }        Extras_stat_array[Textsw_nextfile].mftime = statb.st_mtime;    Extras_stat_array[Textsw_nextfile].name = textsw_savestr(full_file);    Textsw_nextfile++;    if(walk_getmenu(menu, full_file, mfd, &lineno) < 0) {	    free(Extras_stat_array[--Textsw_nextfile].name);	    (void)fclose(mfd);	    return(ERROR);    }    else {	    (void)fclose(mfd);	    return(TRUE);    }}#ifndef IL_ERRORMSG_SIZE#define IL_ERRORMSG_SIZE	256#endifstatic intwalk_getmenu(m, file, mfd, lineno)	Menu 		m;	char 		*file;	FILE 		*mfd;	int 		*lineno;{      	char 		line[256], tag[32], prog[256], args[256];    	register char 	*p;    	Menu 		nm;    	Menu_item 	mi = (Menu_item) 0;    	char 		*nqformat, *qformat, *iformat, *format;    	char 		err[IL_ERRORMSG_SIZE], icon_file[MAXPATHLEN];    	struct pixrect *mpr;    nqformat = "%[^ \t\n]%*[ \t]%[^ \t\n]%*[ \t]%[^\n]\n";    qformat = "\"%[^\"]\"%*[ \t]%[^ \t\n]%*[ \t]%[^\n]\n";    iformat = "\<%[^\>]\>%*[ \t]%[^ \t\n]%*[ \t]%[^\n]\n";    for(; fgets(line, sizeof(line), mfd); (*lineno)++)  {        if (line[0] == '#') {            if (line[1] == '?') {                for (p = line + 2; isspace(*p); p++)                    ;                                     if (*p != '\0' && sscanf(p, "%[^\n]\n", args) > 0)                    menu_set((mi ? mi : m), HELP_DATA, textsw_savestr(args), 0);             }            continue;        }	for(p = line; isspace(*p); p++)	    ;	if(*p == '\0') continue;	args[0] = '\0';	format =  *p == '"' ? qformat : *p == '<' ? iformat : nqformat;		if(sscanf(p, format, tag, prog, args) < 2) {	    (void)fprintf(stderr, "textsw: format error in %s: line %d\n",		    file, *lineno);	    return(ERROR);	}	if(strcmp(prog, "END") == 0) return(TRUE);	if(format == iformat) {	    expand_path(tag, icon_file);	    if((mpr = icon_load_mpr(icon_file, err)) == NULL) {		(void)fprintf(stderr, "textsw: icon file format error: %s:\n", err);		return(ERROR);	    }	} else mpr = NULL;	if(strcmp(prog, "MENU") == 0)	{	    nm = menu_create(		MENU_LEFT_MARGIN,	6,		MENU_NOTIFY_PROC, menu_return_item,		HELP_DATA, "textsw:extrasmenu",		0);	    if(args[0] == '\0')	 {		    if(walk_getmenu(nm, file, mfd, lineno) < 0) {		        menu_destroy(nm);		        return(ERROR);		    }	    }	    else {	        if(walk_menufile(args, nm) < 0) {		        menu_destroy(nm);		        return(ERROR);		    }	    }	    if(mpr)		    mi = menu_create_item(MENU_IMAGE, mpr,				      MENU_PULLRIGHT, nm,				      MENU_RELEASE, 				      MENU_RELEASE_IMAGE, 				      0);	    else		    mi = menu_create_item(MENU_STRING, textsw_savestr(tag), 				      MENU_PULLRIGHT, nm,				      MENU_RELEASE, 				      MENU_RELEASE_IMAGE, 				      0);            (void)menu_set(mi, HELP_DATA, menu_get(nm, HELP_DATA), 0);	} else {	    if(mpr)		    mi = menu_create_item(MENU_IMAGE, mpr,				      MENU_CLIENT_DATA,				        textsw_save2str(prog, args),				      MENU_RELEASE, 				      MENU_RELEASE_IMAGE, 				      MENU_ACTION_PROC,	textsw_handle_extras_menuitem,				      0);	    else		    mi = menu_create_item(MENU_STRING, textsw_savestr(tag),				      MENU_CLIENT_DATA,				        textsw_save2str(prog, args),				      MENU_RELEASE, 				      MENU_RELEASE_IMAGE, 				      MENU_ACTION_PROC,	textsw_handle_extras_menuitem,				      0);	}	(void)menu_set(m, MENU_APPEND_ITEM, mi, 0);    }    return(TRUE);}/*ARGSUSED*/Menu_itemtextsw_handle_extras_menuitem(menu, item)	Menu		menu;	Menu_item	item;{	char			*prog, *args;	char			command_line[MAXPATHLEN];	char			**filter_argv;	pkg_private char	**string_to_argv();	register Textsw_view  	view = VIEW_ABS_TO_REP(textsw);	register Textsw_folio	folio = FOLIO_FOR_VIEW(view);	int			again_state;	prog = (char *)menu_get(item, MENU_CLIENT_DATA);	args = index(prog, '\0') + 1;	sprintf(command_line, "%s %s", prog, args);	filter_argv = string_to_argv(command_line);		textsw_flush_caches(view, TFC_STD);	folio->func_state |= TXTSW_FUNC_FILTER;	again_state = folio->func_state & TXTSW_FUNC_AGAIN;	textsw_record_extras(folio, command_line);	folio->func_state |= TXTSW_FUNC_AGAIN;		textsw_checkpoint_undo(VIEW_REP_TO_ABS(view),			       (caddr_t)TEXTSW_INFINITY-1);	if ( textsw_call_filter(view, filter_argv) == 1)                fprintf(stderr, "Cannot locate filter '%s'.\n", prog);		textsw_checkpoint_undo(VIEW_REP_TO_ABS(view),			       (caddr_t)TEXTSW_INFINITY-1);			       	folio->func_state &= ~TXTSW_FUNC_FILTER;	if (again_state == 0)	    folio->func_state &= ~TXTSW_FUNC_AGAIN;	free_argv(filter_argv);	return(item);}/***	string_to_argv - This function takes a char * that contains**			a program and it's arguments and returns**			a char ** argument vector for use with execvp****			For example "fmt -65" is turned into**			argv[0] = "fmt"**			argv[1] = "-65"**			argv[2] = NULL*/pkg_private char **string_to_argv(command_line)    char	*command_line;{    int		i, pos = 0;    char	**new_argv;    char	*arg_array[MAXARGS];    char	scratch[MAXSTRLEN];    int		use_shell = any_shell_meta(command_line);    Nargs = 0;    if (use_shell) {        /* put in their favorite shell and pass cmd as single string */        char *shell;	extern char *getenv();	if ((shell = getenv("SHELL")) == NULL)	    shell = "/bin/sh";	new_argv = (char **)sv_malloc((unsigned) 4  * sizeof (char *));	new_argv[0] = shell;	new_argv[1] = "-c";	new_argv[2] = strdup(command_line);	new_argv[3] = '\0';    } else {	/* Split command_line into it's individual arguments */	while(string_get_token(command_line, &pos, scratch, white_space) != NULL)	    arg_array[Nargs++] = strdup(scratch);	/*         * Allocate a new array of appropriate size (Nargs+1 for NULL string)         * This is so the caller will know where the array ends         */        new_argv = (char **)sv_malloc((unsigned) (Nargs + 1) *				     sizeof (char *));	/*	 * And WHATEVER you do, DON't forget to actually add that pesky zero.	 * This is Mick's first SunView bug-fix, and will probably be famous	 * someday for that reason.	 * Autographed copies available on request.	 */	new_argv[Nargs] = (char *) NULL;        /* Copy the strings from arg_array into it */        for (i = 0; i < Nargs; i++)    	    new_argv[i] = arg_array[i];    }    return(new_argv);}static intfree_argv(argv)	char	**argv;{	while(Nargs > 0)		free(argv[--Nargs]);	free(argv);}static char *textsw_savestr(s)	register char *s;{	register char *p;	p = sv_malloc((unsigned)(strlen(s) + 1));	(void)strcpy(p, s);	return(p);}static char *textsw_save2str(s, t)	register char *s, *t;{	register char *p;	p = sv_malloc((unsigned)(strlen(s) + strlen(t) + 1 + 1));	(void)strcpy(p, s);	(void)strcpy(index(p, '\0') + 1, t);	return(p);}/* * Are there any shell meta-characters in string s? */staticany_shell_meta(s)	register char *s;{	while (*s) {		if (index("~{[*?$`'\"\\", *s))			return (1);		s++;	}	return (0);}

⌨️ 快捷键说明

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