File: globals.c

package info (click to toggle)
vile 9.2y-1
  • links: PTS
  • area: main
  • in suites: woody
  • size: 5,700 kB
  • ctags: 7,341
  • sloc: ansic: 78,427; lex: 4,726; perl: 2,922; cpp: 2,710; sh: 2,612; makefile: 715; awk: 212
file content (131 lines) | stat: -rw-r--r-- 3,240 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
/* ed/vi/ex style global commands, where first the file is scanned for
 *	matching lines, then for each such line, an action is performed.
 *	written for vile: Copyright (c) 1990-1999 by Paul Fox
 *
 * $Header: /usr/build/vile/vile/RCS/globals.c,v 1.46 2000/08/26 16:37:48 tom Exp $
 *
 */

#include	"estruct.h"
#include        "edef.h"
#include	"nefunc.h"

static	int	globber (CMD_ARGS, int g_or_v);

int
globals(int f, int n)
{
	return globber(f,n,'g');
}

int
vglobals(int f, int n)
{
	return globber(f,n,'v');
}

/* ARGSUSED */
static int
globber(int f GCC_UNUSED, int n GCC_UNUSED, int g_or_v)
{
	int c, s;
	register LINE *lp;
	register char *fnp;	/* ptr to the name of the cmd to exec */
	char	cmd[NLINE];
	const CMDFUNC *cfp;
	int foundone;
	int	status;
	WINDOW *wp, *sw_wp;
	L_NUM	before;
	int	save_report;

	c = kbd_delimiter();
	if ((status = readpattern("global pattern: ", searchpat,
				&gregexp, c, FALSE)) != TRUE) {
		mlforce("[No pattern.]");
		return status;
	}

	/* in some sense, it would be nice to search first, before
                making the user answer the next question, but the
                searching delay is too long, and unexpected in the
                middle of a command.  */

	fnp = kbd_engl("action to perform on each matching line: ", cmd);
	/* get the name of, and then the function to execute */
	if (!fnp) {
	        mlforce("[No function]");
		return FALSE;
	} else if ((cfp = engl2fnc(fnp)) == 0) {
	        return no_such_function(fnp);
	} else if ((cfp->c_flags & GLOBOK) == 0) {
	        mlforce("[Function not allowed]");
		return FALSE;
	}


	/* call the searcher, telling it to do line marking */
	s = fsearch(FALSE,0,TRUE,FALSE);
	if (s != TRUE)
		return s;

	calledbefore = FALSE;

	if (g_or_v == 'v') {  /* invert the sense of all the matches */
		for_each_line(lp, curbp)
			lflipmark(lp);
	}
	/* loop through the buffer -- we must clear the marks no matter what */
	s = TRUE;
	lp = lforw(buf_head(curbp));
	wp = sw_wp = curwp;
	/* loop until there are no marked lines in the buffer */
	foundone = FALSE;
	before = vl_line_count(curbp);
	save_report = global_g_val(GVAL_REPORT);
	for_ever {
		if (lp == win_head(wp)) {
			/* at the end -- only quit if we found no
				marks on the last pass through. otherwise,
				go through again */
			if (foundone)
				foundone = FALSE;
			else
				break;
			lsetnotmarked(lp); /* always unmark the header line */
		}
		if (lismarked(lp)) {
			foundone = TRUE;
			lsetnotmarked(lp);
			/* call the function, if there is one, and results
				have been ok so far */
			if (cfp && s) {
				if (!calledbefore && (cfp->c_flags & UNDO)) {
					if (b_val(wp->w_bufp,MDVIEW))
						return(rdonly());
					mayneedundo();
					set_global_g_val(GVAL_REPORT,0);
				}
				havemotion = &f_godotplus;
				wp->w_dot.l = lp;
				wp->w_dot.o = 0;
				s = call_cmdfunc(cfp, FALSE, 1);
				if (curwp != wp) {
				    /* function may have switched on us */
				    sw_wp = curwp;
				    (void)set_curwp(wp);
				}
				lp = wp->w_dot.l;
				havemotion = NULL;
				calledbefore = TRUE;
			}
		}
		lp = lforw(lp);
	}
	set_global_g_val(GVAL_REPORT,save_report);
	(void)line_report(before);
	/* if it tried to switch, do it now */
	(void)set_curwp(sw_wp);

	return s;
}