]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/mk/lex.c
realemu: implement IDIV, mark 0xE0000 writeable, fix DIV overfow trap
[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, depth;
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         depth = 1;
84         start = buf->current-buf->start;
85         for(;c > 0; c = nextrune(bp, 0)){
86                 if(c == '{' && term == '}')
87                         depth++;
88                 if(c == term && --depth == 0){
89                         insert(buf, '\n');
90                         insert(buf,0);
91                         buf->current = buf->start+start;
92                         execinit();
93                         execsh(0, buf->current, buf, envy);
94                         return 1;
95                 }
96                 if(c == '\n')
97                         break;
98                 if(c == '\'' || c == '"' || c == '\\'){
99                         insert(buf, c);
100                         if(!escapetoken(bp, buf, 1, c))
101                                 return 0;
102                         continue;
103                 }
104                 rinsert(buf, c);
105         }
106         SYNERR(line);
107         fprint(2, "missing closing %c after `\n", term);
108         return 0;
109 }
110
111 /*
112  *      get next character stripping escaped newlines
113  *      the flag specifies whether escaped newlines are to be elided or
114  *      replaced with a blank.
115  */
116 int
117 nextrune(Biobuf *bp, int elide)
118 {
119         int c;
120
121         for (;;) {
122                 c = Bgetrune(bp);
123                 if (c == '\\') {
124                         if (Bgetrune(bp) == '\n') {
125                                 mkinline++;
126                                 if (elide)
127                                         continue;
128                                 return ' ';
129                         }
130                         Bungetrune(bp);
131                 }
132                 if (c == '\n')
133                         mkinline++;
134                 return c;
135         }
136 }