Subversion Repositories planix.SVN

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
#include	"mk.h"
2
 
3
static	int	bquote(Biobuf*, Bufblock*);
4
 
5
/*
6
 *	Assemble a line skipping blank lines, comments, and eliding
7
 *	escaped newlines
8
 */
9
int
10
assline(Biobuf *bp, Bufblock *buf)
11
{
12
	int c;
13
	int lastc;
14
 
15
	buf->current=buf->start;
16
	while ((c = nextrune(bp, 1)) >= 0){
17
		switch(c)
18
		{
19
		case '\r':		/* consumes CRs for Win95 */
20
			continue;
21
		case '\n':
22
			if (buf->current != buf->start) {
23
				insert(buf, 0);
24
				return 1;
25
			}
26
			break;		/* skip empty lines */
27
		case '\\':
28
		case '\'':
29
		case '"':
30
			rinsert(buf, c);
31
			if (escapetoken(bp, buf, 1, c) == 0)
32
				Exit();
33
			break;
34
		case '`':
35
			if (bquote(bp, buf) == 0)
36
				Exit();
37
			break;
38
		case '#':
39
			lastc = '#';
40
			while ((c = Bgetc(bp)) != '\n') {
41
				if (c < 0)
42
					goto eof;
43
				if(c != '\r')
44
					lastc = c;
45
			}
46
			mkinline++;
47
			if (lastc == '\\')
48
				break;		/* propagate escaped newlines??*/
49
			if (buf->current != buf->start) {
50
				insert(buf, 0);
51
				return 1;
52
			}
53
			break;
54
		default:
55
			rinsert(buf, c);
56
			break;
57
		}
58
	}
59
eof:
60
	insert(buf, 0);
61
	return *buf->start != 0;
62
}
63
 
64
/*
65
 *	assemble a back-quoted shell command into a buffer
66
 */
67
static int
68
bquote(Biobuf *bp, Bufblock *buf)
69
{
70
	int c, line, term;
71
	int start;
72
 
73
	line = mkinline;
74
	while((c = Bgetrune(bp)) == ' ' || c == '\t')
75
			;
76
	if(c == '{'){
77
		term = '}';		/* rc style */
78
		while((c = Bgetrune(bp)) == ' ' || c == '\t')
79
			;
80
	} else
81
		term = '`';		/* sh style */
82
 
83
	start = buf->current-buf->start;
84
	for(;c > 0; c = nextrune(bp, 0)){
85
		if(c == term){
86
			insert(buf, '\n');
87
			insert(buf,0);
88
			buf->current = buf->start+start;
89
			execinit();
90
			execsh(0, buf->current, buf, envy);
91
			return 1;
92
		}
93
		if(c == '\n')
94
			break;
95
		if(c == '\'' || c == '"' || c == '\\'){
96
			insert(buf, c);
97
			if(!escapetoken(bp, buf, 1, c))
98
				return 0;
99
			continue;
100
		}
101
		rinsert(buf, c);
102
	}
103
	SYNERR(line);
104
	fprint(2, "missing closing %c after `\n", term);
105
	return 0;
106
}
107
 
108
/*
109
 *	get next character stripping escaped newlines
110
 *	the flag specifies whether escaped newlines are to be elided or
111
 *	replaced with a blank.
112
 */
113
int
114
nextrune(Biobuf *bp, int elide)
115
{
116
	int c;
117
 
118
	for (;;) {
119
		c = Bgetrune(bp);
120
		if (c == '\\') {
121
			if (Bgetrune(bp) == '\n') {
122
				mkinline++;
123
				if (elide)
124
					continue;
125
				return ' ';
126
			}
127
			Bungetrune(bp);
128
		}
129
		if (c == '\n')
130
			mkinline++;
131
		return c;
132
	}
133
}