/* * This file is part of the UCB release of Plan 9. It is subject to the license * terms in the LICENSE file found in the top-level directory of this * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No * part of the UCB release of Plan 9, including this file, may be copied, * modified, propagated, or distributed except according to the terms contained * in the LICENSE file. */#include "mk.h"static int bquote(Biobuf*, Bufblock*);/* * Assemble a line skipping blank lines, comments, and eliding * escaped newlines */intassline(Biobuf *bp, Bufblock *buf){ int c; int lastc; buf->current=buf->start; while ((c = nextrune(bp, 1)) >= 0){ switch(c) { case '\r': /* consumes CRs for Win95 */ continue; case '\n': if (buf->current != buf->start) { insert(buf, 0); return 1; } break; /* skip empty lines */ case '\\': case '\'': case '"': rinsert(buf, c); if (escapetoken(bp, buf, 1, c) == 0) Exit(); break; case '`': if (bquote(bp, buf) == 0) Exit(); break; case '#': lastc = '#'; while ((c = Bgetc(bp)) != '\n') { if (c < 0) goto eof; if(c != '\r') lastc = c; } mkinline++; if (lastc == '\\') break; /* propagate escaped newlines??*/ if (buf->current != buf->start) { insert(buf, 0); return 1; } break; default: rinsert(buf, c); break; } }eof: insert(buf, 0); return *buf->start != 0;}/* * assemble a back-quoted shell command into a buffer */static intbquote(Biobuf *bp, Bufblock *buf){ int c, line, term; int start; line = mkinline; while((c = Bgetrune(bp)) == ' ' || c == '\t') ; if(c == '{'){ term = '}'; /* rc style */ while((c = Bgetrune(bp)) == ' ' || c == '\t') ; } else term = '`'; /* sh style */ start = buf->current-buf->start; for(;c > 0; c = nextrune(bp, 0)){ if(c == term){ insert(buf, '\n'); insert(buf,0); buf->current = buf->start+start; execinit(); execsh(0, buf->current, buf, envy); return 1; } if(c == '\n') break; if(c == '\'' || c == '"' || c == '\\'){ insert(buf, c); if(!escapetoken(bp, buf, 1, c)) return 0; continue; } rinsert(buf, c); } SYNERR(line); fprint(2, "missing closing %c after `\n", term); return 0;}/* * get next character stripping escaped newlines * the flag specifies whether escaped newlines are to be elided or * replaced with a blank. */intnextrune(Biobuf *bp, int elide){ int c; for (;;) { c = Bgetrune(bp); if (c == '\\') { if (Bgetrune(bp) == '\n') { mkinline++; if (elide) continue; return ' '; } Bungetrune(bp); } if (c == '\n') mkinline++; return c; }}
/*
* This file is part of the UCB release of Plan 9. It is subject to the license
* terms in the LICENSE file found in the top-level directory of this
* distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
* part of the UCB release of Plan 9, including this file, may be copied,
* modified, propagated, or distributed except according to the terms contained
* in the LICENSE file.
*/
#include "mk.h"
static int bquote(Biobuf*, Bufblock*);
/*
* Assemble a line skipping blank lines, comments, and eliding
* escaped newlines
*/
int
assline(Biobuf *bp, Bufblock *buf)
{
int c;
int lastc;
buf->current=buf->start;
while ((c = nextrune(bp, 1)) >= 0){
switch(c)
{
case '\r': /* consumes CRs for Win95 */
continue;
case '\n':
if (buf->current != buf->start) {
insert(buf, 0);
return 1;
}
break; /* skip empty lines */
case '\\':
case '\'':
case '"':
rinsert(buf, c);
if (escapetoken(bp, buf, 1, c) == 0)
Exit();
break;
case '`':
if (bquote(bp, buf) == 0)
Exit();
break;
case '#':
lastc = '#';
while ((c = Bgetc(bp)) != '\n') {
if (c < 0)
goto eof;
if(c != '\r')
lastc = c;
}
mkinline++;
if (lastc == '\\')
break; /* propagate escaped newlines??*/
if (buf->current != buf->start) {
insert(buf, 0);
return 1;
}
break;
default:
rinsert(buf, c);
break;
}
}
eof:
insert(buf, 0);
return *buf->start != 0;
}
/*
* assemble a back-quoted shell command into a buffer
*/
static int
bquote(Biobuf *bp, Bufblock *buf)
{
int c, line, term;
int start;
line = mkinline;
while((c = Bgetrune(bp)) == ' ' || c == '\t')
;
if(c == '{'){
term = '}'; /* rc style */
while((c = Bgetrune(bp)) == ' ' || c == '\t')
;
} else
term = '`'; /* sh style */
start = buf->current-buf->start;
for(;c > 0; c = nextrune(bp, 0)){
if(c == term){
insert(buf, '\n');
insert(buf,0);
buf->current = buf->start+start;
execinit();
execsh(0, buf->current, buf, envy);
return 1;
}
if(c == '\n')
break;
if(c == '\'' || c == '"' || c == '\\'){
insert(buf, c);
if(!escapetoken(bp, buf, 1, c))
return 0;
continue;
}
rinsert(buf, c);
}
SYNERR(line);
fprint(2, "missing closing %c after `\n", term);
return 0;
}
/*
* get next character stripping escaped newlines
* the flag specifies whether escaped newlines are to be elided or
* replaced with a blank.
*/
int
nextrune(Biobuf *bp, int elide)
{
int c;
for (;;) {
c = Bgetrune(bp);
if (c == '\\') {
if (Bgetrune(bp) == '\n') {
mkinline++;
if (elide)
continue;
return ' ';
}
Bungetrune(bp);
}
if (c == '\n')
mkinline++;
return c;
}
}