xref: /plan9-contrib/sys/src/cmd/mk/varsub.c (revision 219b2ee8daee37f4aad58d63f21287faa8e4ffdc)
1 #include	"mk.h"
2 
3 static void	varcopy(char*, Bufblock*);
4 
5 void
6 subsub(Word *val, char *ext, Bufblock *buf)
7 {
8 	char *s;
9 	char *a, *b, *c, *d;
10 	int na, nb, nc, nd;
11 
12 	/* prepare literals */
13 	a = ext;
14 	s = charin(a, "=%&");
15 	if (!s) {
16 		na = strlen(a);
17 		s = a+na;
18 	} else
19 		na = s-a;
20 	b = s;			/* s guaranteed to be on utf boundary */
21 	if(PERCENT(*s)) {
22 		b++;
23 		s = charin(b, "=");
24 		if (!s) {
25 			nb = strlen(b);
26 			s = b+nb;
27 		} else
28 			nb = s-b;
29 	} else
30 		nb = 0;
31 	c = s;
32 	if (*s) {
33 		c++;		/* skip '=' */
34 		s = charin(c, "&%");
35 		if (!s) {
36 			nc = strlen(c);
37 			s = c+nc;
38 		} else
39 			nc = s-c;
40 	} else
41 		nc = 0;
42 	d = s;
43 	if(PERCENT(*s))
44 		nd = strlen(d+1);
45 	else
46 		nd = 0;
47 
48 		/* break into words, do sub
49 		 * assume all separators are unique in utf
50 		 */
51 	for(; val; val = val->next){
52 		if (!val->s || !val->s[0])
53 			continue;
54 		s = val->s+strlen(val->s);
55 		/* substitute in val..s */
56 		if((memcmp(val->s, a, na) == 0) && (memcmp(s-nb, b, nb) == 0)){
57 			if (nc)
58 				bufcpy(buf, c, nc);
59 			if (PERCENT(*d))
60 				bufcpy(buf, val->s+na, s-nb-val->s+na);
61 			if (nd)
62 				bufcpy(buf, d+1, nd);
63 		} else
64 			bufcpy(buf, val->s, s-val->s);
65 		insert(buf, ' ');
66 	}
67 	return;
68 }
69 
70 void
71 varmatch(char *var, Bufblock *buf)
72 {
73 	Symtab *sym;
74 	Word *w;
75 
76 	sym = symlook(var, S_VAR, (char *)0);
77 	if (sym){
78 		w = (Word *) sym->value;
79 		while (w) {
80 			varcopy(w->s, buf);
81 			w = w->next;
82 			if (w && w->s && w->s[0])
83 				insert(buf, ' ');
84 		}
85 	}
86 }
87 
88 static void
89 varcopy(char *s, Bufblock *buf)
90 {
91 	Rune r;
92 
93 	if (!s)
94 		return;
95 	while (*s) {
96 		s += chartorune(&r, s);
97 			/* prevent further evaluation special chars*/
98 		if (QUOTE(r) || r == '=') {
99 			insert(buf, '\'');
100 			rinsert(buf, r);
101 			insert(buf, '\'');
102 		} else
103 			rinsert(buf, r);
104 	}
105 }
106