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

📄 g.c

📁 早期freebsd实现
💻 C
字号:
/*- * Copyright (c) 1992, 1993 *	The Regents of the University of California.  All rights reserved. * * This code is derived from software contributed to Berkeley by * Rodney Ruddock of the University of Guelph. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software *    must display the following acknowledgement: *	This product includes software developed by the University of *	California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors *    may be used to endorse or promote products derived from this software *    without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */#ifndef lintstatic char sccsid[] = "@(#)g.c	8.1 (Berkeley) 5/31/93";#endif /* not lint */#include <sys/types.h>#include <limits.h>#include <regex.h>#include <setjmp.h>#include <stdio.h>#include <stdlib.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#ifdef DBI#include <db.h>#endif#include "ed.h"#include "extern.h"static int	find_line __P((LINE *));static void	w_cmd_l_file __P((FILE *, FILE *, int *));/* * Find a line that we noted matched the RE earlier in the current * buffer (it may have disappeared because of the commands in the * command list). */static intfind_line(dot)	LINE *dot;{	LINE *l_cl;	l_cl = top;	for (;;) {		if (l_cl == dot)			return (1);		if (l_cl == bottom)			return (0);		l_cl = l_cl->below;	}}/* * Write the command line to a STDIO tmp file. See g() below. * This allows us to use cmd_loop to run the command list because * we "trick" cmd_loop into reading a STDIO file instead of stdin. */static voidw_cmd_l_file(fp, inputt, errnum)	FILE *fp, *inputt;	int *errnum;{	int sl=0, jmp_flag, l_cnt=0;	if (jmp_flag = setjmp(ctrl_position3))		return;	for (;;) {		sigspecial3 = 1;		ss = getc(inputt);		sigspecial3 = 0;skip1:		if (ss == EOF)			goto skip2;		else if (ss == '\n') {			if (sl != '\\') {skip2:				if (l_cnt == 0)					fputc('p', fp);				else					fputc(sl, fp);				break;			}		}		else if ((ss == '\\') && (sl == '\\')) {			sigspecial3 = 1;			sl = getc(inputt);			sigspecial3 = 0;			if (sl == '\\') {				sigspecial3 = 1;				sl = getc(inputt);				sigspecial3 = 0;				if (sl == EOF)					goto skip2;				if (sl == '\n') {					fputc('\\', fp);					ss = sl;				}				else {					fputc('\\', fp);					fputc('\\', fp);					ss = sl;					sl = '\\';					goto skip1;				}			}			else {				fputc('\\', fp);				fputc('\\', fp);				if ((sl == '\n') || (sl == EOF))					goto skip2;				else					ss = sl;			}		}		else if (l_cnt)			fputc(sl, fp);		sl = ss;		l_cnt++;	}	fputc('\n', fp);	if (ss == EOF)		clearerr(inputt);}/* * The global function. All global commands (g, G, v, and V) are handled * in here. The lines to be affected by the command list are 1st noted * and then the command list is invoked for each line matching the RE. * Note the trick of how the command list is executed. Saves a lot of * code (and allows for \n's in substitutions). */voidg(inputt, errnum)	FILE *inputt;	int *errnum;{	static char *l_template_g;	char *l_patt;	static int l_template_flag = 0;	int l_re_success, l_flag_v = 0, l_err, l_num;	register l_gut_cnt, a;	register LINE **l_gut=gut;	FILE *l_fp;#ifdef POSIX	LINE *l_posix_cur;#endif	if (Start_default && End_default) {		Start = top;		End = bottom;	} else		if (Start_default)			Start = End;	if (Start == NULL) {		strcpy(help_msg, "buffer empty");		*errnum = -1;		return;	}	if (l_template_flag == 0) {		sigspecial++;		l_template_flag = 1;		l_template_g = calloc(FILENAME_LEN, sizeof(char));		sigspecial--;		if (sigint_flag && (!sigspecial))			SIGINT_ACTION;		if (l_template_g == NULL) {			*errnum = -1;			strcpy(help_msg, "out of memory error");			return;		}	}	/* set up the STDIO command list file */	memmove(l_template_g, "/tmp/_4.4bsd_ed_g_XXXXXX\0", 24);	mktemp(l_template_g);	if ((ss == 'v') || (ss == 'V'))		l_flag_v = 1;	if ((ss == 'G') || (ss == 'V')) {		/*		 * If it's an interactive global command we use stdin, not a		 * file.		 */		GV_flag = 1;		l_fp = stdin;	} else {		sigspecial++;		if ((l_fp = fopen(l_template_g, "w+")) == NULL) {			perror("ed: file I/O error, save buffer in ed.hup");			do_hup(); /* does not return */		}		sigspecial--;		if (sigint_flag && (!sigspecial))			goto point;	}	ss = getc(inputt);	/* Get the RE for the global command. */	l_patt = get_pattern(ss, inputt, errnum, 0);	/* Instead of: if ((*errnum == -1) && (ss == '\n'))... */	if (*errnum < -1)		return;	*errnum = 0;	if ((l_patt[1] == '\0') && (RE_flag == 0)) {		*errnum = -1;		ungetc(ss, inputt);		return;	} else		if (l_patt[1] || (RE_patt == NULL)) {			sigspecial++;			free(RE_patt);			RE_patt = l_patt;			sigspecial--;			if (sigint_flag && (!sigspecial))				goto point;		}	RE_sol = (RE_patt[1] == '^') ? 1 : 0;	if ((RE_patt[1]) &&	    (regfree(&RE_comp), l_err = regcomp(&RE_comp, &RE_patt[1], 0))) {		regerror(l_err, &RE_comp, help_msg, 128);		*errnum = -1;		RE_flag = 0;		ungetc(ss, inputt);		return;	}	RE_flag = 1;	if (GV_flag)		ss = getc(inputt);#ifdef POSIX	l_posix_cur = current;#endif	current = Start;	sigspecial++;	if ((l_num = line_number(bottom)) > gut_num) {		sigspecial++;		gut_num = l_num + 512;		free(l_gut);		gut = l_gut = malloc(sizeof(LINE **) * gut_num);		sigspecial--;		if (l_gut == NULL) {			*errnum = -1;			strcpy(help_msg, "out of memory error");#ifdef POSIX			current = l_posix_cur;#endif			ungetc('\n', inputt);			return;		}	}	l_gut_cnt = 0;	for (;;) {		/*		 * Find the lines in the buffer that the global command wants		 * to work with.		 */		get_line(current->handle, current->len);		if (sigint_flag && (!sigspecial))			goto point;		l_re_success =		    regexec(&RE_comp, text, (size_t) RE_SEC, RE_match, 0);		/* l_re_success=0 => success */		if ( (l_re_success == 0 && l_flag_v == 0) ||			(l_re_success && l_flag_v)) {				l_gut[l_gut_cnt++] = current;		}		if (End == current)			break;		current = current->below;	}	sigspecial--;	if (sigint_flag && (!sigspecial))		goto point;	if (l_gut_cnt == 0) {		strcpy(help_msg, "no matches found");#ifdef POSIX		current = l_posix_cur;#endif		return;	}	/* if non-interactive, get the command list */	if (GV_flag == 0) {		sigspecial++;		w_cmd_l_file(l_fp, inputt, errnum);		sigspecial--;		if (sigint_flag)			goto point;	}	if (g_flag == 0)		u_clr_stk();	sigspecial++;	for (a=0; a<l_gut_cnt; a++) {		/*		 * Execute the command list on the lines that still exist that		 * we indicated earlier that global wants to work with.		 */		if (sigint_flag)			goto point;		if (GV_flag == 0)			fseek(l_fp, (off_t)0, 0);		if (find_line(l_gut[a])) {			current = (l_gut[a]);			get_line(current->handle, current->len);			if (sigint_flag)				goto point;			if (GV_flag == 1)				printf("%s\n", text);			g_flag++;			explain_flag--;			sigspecial--;			cmd_loop(l_fp, errnum);			sigspecial++;			explain_flag++;			g_flag--;			if ((GV_flag == 1) && (*errnum < 0)) {				ungetc('\n', l_fp);				break;			}			*errnum = 0;		}	}point:	if (GV_flag == 0) {		fclose(l_fp);		unlink(l_template_g);	}	else		ungetc('\n', inputt);	GV_flag = 0;#ifdef POSIX	current = l_posix_cur;#endif	sigspecial--;	if (sigint_flag)		SIGINT_ACTION;}

⌨️ 快捷键说明

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