]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/mk/lex.c
Import sources from 2011-03-30 iso image
[plan9front.git] / sys / src / cmd / mk / lex.c
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 }