Blob
1 #include "mk.h"3 static int bquote(Biobuf*, Bufblock*);5 /*6 * Assemble a line skipping blank lines, comments, and eliding7 * escaped newlines8 */9 int10 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 (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 buffer66 */67 static int68 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 } else81 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);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 }108 /*109 * get next character stripping escaped newlines110 * the flag specifies whether escaped newlines are to be elided or111 * replaced with a blank.112 */113 int114 nextrune(Biobuf *bp, int elide)115 {116 int c, c2;117 static int savec;119 if(savec){120 c = savec;121 savec = 0;122 return c;123 }125 for (;;) {126 c = Bgetrune(bp);127 if (c == '\\') {128 c2 = Bgetrune(bp);129 if(c2 == '\r'){130 savec = c2;131 c2 = Bgetrune(bp);132 }133 if (c2 == '\n') {134 savec = 0;135 mkinline++;136 if (elide)137 continue;138 return ' ';139 }140 Bungetrune(bp);141 }142 if (c == '\n')143 mkinline++;144 return c;145 }146 return 0;147 }