13e12c5d1SDavid du Colombier #include "mk.h"
23e12c5d1SDavid du Colombier
33e12c5d1SDavid du Colombier static int bquote(Biobuf*, Bufblock*);
43e12c5d1SDavid du Colombier
53e12c5d1SDavid du Colombier /*
63e12c5d1SDavid du Colombier * Assemble a line skipping blank lines, comments, and eliding
73e12c5d1SDavid du Colombier * escaped newlines
83e12c5d1SDavid du Colombier */
93e12c5d1SDavid du Colombier int
assline(Biobuf * bp,Bufblock * buf)103e12c5d1SDavid du Colombier assline(Biobuf *bp, Bufblock *buf)
113e12c5d1SDavid du Colombier {
123e12c5d1SDavid du Colombier int c;
133e12c5d1SDavid du Colombier int lastc;
143e12c5d1SDavid du Colombier
153e12c5d1SDavid du Colombier buf->current=buf->start;
163e12c5d1SDavid du Colombier while ((c = nextrune(bp, 1)) >= 0){
17219b2ee8SDavid du Colombier switch(c)
18219b2ee8SDavid du Colombier {
19*7dd7cddfSDavid du Colombier case '\r': /* consumes CRs for Win95 */
20*7dd7cddfSDavid du Colombier continue;
213e12c5d1SDavid du Colombier case '\n':
223e12c5d1SDavid du Colombier if (buf->current != buf->start) {
233e12c5d1SDavid du Colombier insert(buf, 0);
243e12c5d1SDavid du Colombier return 1;
253e12c5d1SDavid du Colombier }
263e12c5d1SDavid du Colombier break; /* skip empty lines */
27*7dd7cddfSDavid du Colombier case '\\':
283e12c5d1SDavid du Colombier case '\'':
29*7dd7cddfSDavid du Colombier case '"':
303e12c5d1SDavid du Colombier rinsert(buf, c);
31*7dd7cddfSDavid du Colombier if (escapetoken(bp, buf, 1, c) == 0)
323e12c5d1SDavid du Colombier Exit();
333e12c5d1SDavid du Colombier break;
343e12c5d1SDavid du Colombier case '`':
35*7dd7cddfSDavid du Colombier if (bquote(bp, buf) == 0)
363e12c5d1SDavid du Colombier Exit();
373e12c5d1SDavid du Colombier break;
383e12c5d1SDavid du Colombier case '#':
393e12c5d1SDavid du Colombier lastc = '#';
403e12c5d1SDavid du Colombier while ((c = Bgetc(bp)) != '\n') {
413e12c5d1SDavid du Colombier if (c < 0)
423e12c5d1SDavid du Colombier goto eof;
43*7dd7cddfSDavid du Colombier if(c != '\r')
443e12c5d1SDavid du Colombier lastc = c;
453e12c5d1SDavid du Colombier }
46*7dd7cddfSDavid du Colombier mkinline++;
473e12c5d1SDavid du Colombier if (lastc == '\\')
483e12c5d1SDavid du Colombier break; /* propagate escaped newlines??*/
493e12c5d1SDavid du Colombier if (buf->current != buf->start) {
503e12c5d1SDavid du Colombier insert(buf, 0);
513e12c5d1SDavid du Colombier return 1;
523e12c5d1SDavid du Colombier }
533e12c5d1SDavid du Colombier break;
543e12c5d1SDavid du Colombier default:
553e12c5d1SDavid du Colombier rinsert(buf, c);
563e12c5d1SDavid du Colombier break;
573e12c5d1SDavid du Colombier }
583e12c5d1SDavid du Colombier }
593e12c5d1SDavid du Colombier eof:
603e12c5d1SDavid du Colombier insert(buf, 0);
613e12c5d1SDavid du Colombier return *buf->start != 0;
623e12c5d1SDavid du Colombier }
633e12c5d1SDavid du Colombier
643e12c5d1SDavid du Colombier /*
65*7dd7cddfSDavid du Colombier * assemble a back-quoted shell command into a buffer
663e12c5d1SDavid du Colombier */
673e12c5d1SDavid du Colombier static int
bquote(Biobuf * bp,Bufblock * buf)683e12c5d1SDavid du Colombier bquote(Biobuf *bp, Bufblock *buf)
693e12c5d1SDavid du Colombier {
70*7dd7cddfSDavid du Colombier int c, line, term;
713e12c5d1SDavid du Colombier int start;
723e12c5d1SDavid du Colombier
73*7dd7cddfSDavid du Colombier line = mkinline;
74219b2ee8SDavid du Colombier while((c = Bgetrune(bp)) == ' ' || c == '\t')
75219b2ee8SDavid du Colombier ;
76*7dd7cddfSDavid du Colombier if(c == '{'){
77*7dd7cddfSDavid du Colombier term = '}'; /* rc style */
78*7dd7cddfSDavid du Colombier while((c = Bgetrune(bp)) == ' ' || c == '\t')
79*7dd7cddfSDavid du Colombier ;
80*7dd7cddfSDavid du Colombier } else
81*7dd7cddfSDavid du Colombier term = '`'; /* sh style */
82*7dd7cddfSDavid du Colombier
833e12c5d1SDavid du Colombier start = buf->current-buf->start;
84*7dd7cddfSDavid du Colombier for(;c > 0; c = nextrune(bp, 0)){
85*7dd7cddfSDavid du Colombier if(c == term){
863e12c5d1SDavid du Colombier insert(buf, '\n');
873e12c5d1SDavid du Colombier insert(buf,0);
883e12c5d1SDavid du Colombier buf->current = buf->start+start;
893e12c5d1SDavid du Colombier execinit();
90*7dd7cddfSDavid du Colombier execsh(0, buf->current, buf, envy);
913e12c5d1SDavid du Colombier return 1;
92*7dd7cddfSDavid du Colombier }
93*7dd7cddfSDavid du Colombier if(c == '\n')
94*7dd7cddfSDavid du Colombier break;
95*7dd7cddfSDavid du Colombier if(c == '\'' || c == '"' || c == '\\'){
963e12c5d1SDavid du Colombier insert(buf, c);
97*7dd7cddfSDavid du Colombier if(!escapetoken(bp, buf, 1, c))
983e12c5d1SDavid du Colombier return 0;
993e12c5d1SDavid du Colombier continue;
1003e12c5d1SDavid du Colombier }
1013e12c5d1SDavid du Colombier rinsert(buf, c);
1023e12c5d1SDavid du Colombier }
1033e12c5d1SDavid du Colombier SYNERR(line);
104*7dd7cddfSDavid du Colombier fprint(2, "missing closing %c after `\n", term);
1053e12c5d1SDavid du Colombier return 0;
1063e12c5d1SDavid du Colombier }
1073e12c5d1SDavid du Colombier
1083e12c5d1SDavid du Colombier /*
1093e12c5d1SDavid du Colombier * get next character stripping escaped newlines
1103e12c5d1SDavid du Colombier * the flag specifies whether escaped newlines are to be elided or
1113e12c5d1SDavid du Colombier * replaced with a blank.
1123e12c5d1SDavid du Colombier */
113*7dd7cddfSDavid du Colombier int
nextrune(Biobuf * bp,int elide)1143e12c5d1SDavid du Colombier nextrune(Biobuf *bp, int elide)
1153e12c5d1SDavid du Colombier {
1163e12c5d1SDavid du Colombier int c;
1173e12c5d1SDavid du Colombier
1183e12c5d1SDavid du Colombier for (;;) {
1193e12c5d1SDavid du Colombier c = Bgetrune(bp);
1203e12c5d1SDavid du Colombier if (c == '\\') {
1213e12c5d1SDavid du Colombier if (Bgetrune(bp) == '\n') {
122*7dd7cddfSDavid du Colombier mkinline++;
1233e12c5d1SDavid du Colombier if (elide)
1243e12c5d1SDavid du Colombier continue;
1253e12c5d1SDavid du Colombier return ' ';
1263e12c5d1SDavid du Colombier }
1273e12c5d1SDavid du Colombier Bungetrune(bp);
1283e12c5d1SDavid du Colombier }
1293e12c5d1SDavid du Colombier if (c == '\n')
130*7dd7cddfSDavid du Colombier mkinline++;
1313e12c5d1SDavid du Colombier return c;
1323e12c5d1SDavid du Colombier }
1333e12c5d1SDavid du Colombier }
134