]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/mk/rc.c
Import sources from 2011-03-30 iso image
[plan9front.git] / sys / src / cmd / mk / rc.c
1 #include        "mk.h"
2
3 char    *termchars = "'= \t";   /*used in parse.c to isolate assignment attribute*/
4 char    *shflags = "-I";        /* rc flag to force non-interactive mode */
5 int     IWS = '\1';             /* inter-word separator in env - not used in plan 9 */
6
7 /*
8  *      This file contains functions that depend on rc's syntax.  Most
9  *      of the routines extract strings observing rc's escape conventions
10  */
11
12
13 /*
14  *      skip a token in single quotes.
15  */
16 static char *
17 squote(char *cp)
18 {
19         Rune r;
20         int n;
21
22         while(*cp){
23                 n = chartorune(&r, cp);
24                 if(r == '\'') {
25                         n += chartorune(&r, cp+n);
26                         if(r != '\'')
27                                 return(cp);
28                 }
29                 cp += n;
30         }
31         SYNERR(-1);             /* should never occur */
32         fprint(2, "missing closing '\n");
33         return 0;
34 }
35
36 /*
37  *      search a string for characters in a pattern set
38  *      characters in quotes and variable generators are escaped
39  */
40 char *
41 charin(char *cp, char *pat)
42 {
43         Rune r;
44         int n, vargen;
45
46         vargen = 0;
47         while(*cp){
48                 n = chartorune(&r, cp);
49                 switch(r){
50                 case '\'':                      /* skip quoted string */
51                         cp = squote(cp+1);      /* n must = 1 */
52                         if(!cp)
53                                 return 0;
54                         break;
55                 case '$':
56                         if(*(cp+1) == '{')
57                                 vargen = 1;
58                         break;
59                 case '}':
60                         if(vargen)
61                                 vargen = 0;
62                         else if(utfrune(pat, r))
63                                 return cp;
64                         break;
65                 default:
66                         if(vargen == 0 && utfrune(pat, r))
67                                 return cp;
68                         break;
69                 }
70                 cp += n;
71         }
72         if(vargen){
73                 SYNERR(-1);
74                 fprint(2, "missing closing } in pattern generator\n");
75         }
76         return 0;
77 }
78
79 /*
80  *      extract an escaped token.  Possible escape chars are single-quote,
81  *      double-quote,and backslash.  Only the first is valid for rc. the
82  *      others are just inserted into the receiving buffer.
83  */
84 char*
85 expandquote(char *s, Rune r, Bufblock *b)
86 {
87         if (r != '\'') {
88                 rinsert(b, r);
89                 return s;
90         }
91
92         while(*s){
93                 s += chartorune(&r, s);
94                 if(r == '\'') {
95                         if(*s == '\'')
96                                 s++;
97                         else
98                                 return s;
99                 }
100                 rinsert(b, r);
101         }
102         return 0;
103 }
104
105 /*
106  *      Input an escaped token.  Possible escape chars are single-quote,
107  *      double-quote and backslash.  Only the first is a valid escape for
108  *      rc; the others are just inserted into the receiving buffer.
109  */
110 int
111 escapetoken(Biobuf *bp, Bufblock *buf, int preserve, int esc)
112 {
113         int c, line;
114
115         if(esc != '\'')
116                 return 1;
117
118         line = mkinline;
119         while((c = nextrune(bp, 0)) > 0){
120                 if(c == '\''){
121                         if(preserve)
122                                 rinsert(buf, c);
123                         c = Bgetrune(bp);
124                         if (c < 0)
125                                 break;
126                         if(c != '\''){
127                                 Bungetrune(bp);
128                                 return 1;
129                         }
130                 }
131                 rinsert(buf, c);
132         }
133         SYNERR(line); fprint(2, "missing closing %c\n", esc);
134         return 0;
135 }
136
137 /*
138  *      copy a single-quoted string; s points to char after opening quote
139  */
140 static char *
141 copysingle(char *s, Bufblock *buf)
142 {
143         Rune r;
144
145         while(*s){
146                 s += chartorune(&r, s);
147                 rinsert(buf, r);
148                 if(r == '\'')
149                         break;
150         }
151         return s;
152 }
153 /*
154  *      check for quoted strings.  backquotes are handled here; single quotes above.
155  *      s points to char after opening quote, q.
156  */
157 char *
158 copyq(char *s, Rune q, Bufblock *buf)
159 {
160         if(q == '\'')                           /* copy quoted string */
161                 return copysingle(s, buf);
162
163         if(q != '`')                            /* not quoted */
164                 return s;
165
166         while(*s){                              /* copy backquoted string */
167                 s += chartorune(&q, s);
168                 rinsert(buf, q);
169                 if(q == '}')
170                         break;
171                 if(q == '\'')
172                         s = copysingle(s, buf); /* copy quoted string */
173         }
174         return s;
175 }