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