Blob


1 #include "mk.h"
3 static int bquote(Biobuf*, Bufblock*);
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;
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 (shellt->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 }
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;
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 */
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, shellt, shellcmd);
91 return 1;
92 }
93 if(c == '\n')
94 break;
95 if(c == '\'' || c == '"' || c == '\\'){
96 insert(buf, c);
97 if(!shellt->escapetoken(bp, buf, 1, c))
98 return 0;
99 continue;
101 rinsert(buf, c);
103 SYNERR(line);
104 fprint(2, "missing closing %c after `\n", term);
105 return 0;
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)
116 int c, c2;
117 static int savec;
119 if(savec){
120 c = savec;
121 savec = 0;
122 return c;
125 for (;;) {
126 c = Bgetrune(bp);
127 if (c == '\\') {
128 c2 = Bgetrune(bp);
129 if(c2 == '\r'){
130 savec = c2;
131 c2 = Bgetrune(bp);
133 if (c2 == '\n') {
134 savec = 0;
135 mkinline++;
136 if (elide)
137 continue;
138 return ' ';
140 Bungetrune(bp);
142 if (c == '\n')
143 mkinline++;
144 return c;