xref: /plan9/sys/src/cmd/mk/shprint.c (revision 219b2ee8daee37f4aad58d63f21287faa8e4ffdc)
1 #include	"mk.h"
2 
3 static char *vexpand(char*, Envy*, Bufblock*);
4 static char *shquote(char*, Rune, Bufblock*);
5 static char *shbquote(char*, Bufblock*);
6 
7 void
8 shprint(char *s, Envy *env, Bufblock *buf)
9 {
10 	int n;
11 	Rune r;
12 
13 	while(*s) {
14 		n = chartorune(&r, s);
15 		if (r == '$')
16 			s = vexpand(s, env, buf);
17 		else {
18 			rinsert(buf, r);
19 			s += n;
20 			if (QUOTE(r))		/* copy quoted string */
21 				s = shquote(s, r, buf);
22 			else if (r == '`')	/* copy backquoted string */
23 				s = shbquote(s, buf);
24 		}
25 	}
26 	insert(buf, 0);
27 }
28 /*
29  *	skip quoted string; s points to char after opening quote
30  */
31 static char *
32 shquote(char *s, Rune q, Bufblock *buf)
33 {
34 	Rune r;
35 
36 	while (*s) {
37 		s += chartorune(&r, s);
38 		rinsert(buf, r);
39 		if (r == q)
40 			break;
41 	}
42 	return s;
43 }
44 /*
45  *	skip backquoted string; s points to char after opening backquote
46  */
47 static char *
48 shbquote(char *s, Bufblock *buf)
49 {
50 	Rune r;
51 
52 	while (*s) {
53 		s += chartorune(&r, s);
54 		rinsert(buf, r);
55 		if (QUOTE(r))
56 			s = shquote(s, r, buf);	/* skip quoted string */
57 		else if (r == '}')
58 			break;
59 	}
60 	return s;
61 }
62 
63 static char *
64 mygetenv(char *name, Envy *env)
65 {
66 	if (!env)
67 		return 0;
68 	if (!symlook(name, S_WESET, 0))
69 		return 0;
70 	for(; env->name; env++){
71 		if (strcmp(env->name, name) == 0)
72 			return wtos(env->values);
73 	}
74 	return 0;
75 }
76 
77 static char *
78 vexpand(char *w, Envy *env, Bufblock *buf)
79 {
80 	char *s, carry, *p, *q;
81 
82 	assert("vexpand no $", *w == '$');
83 	p = w+1;	/* skip dollar sign */
84 	if(*p == '{') {
85 		p++;
86 		q = utfrune(p, '}');
87 		if (!q)
88 			q = strchr(p, 0);
89 	} else
90 		q = shname(p);
91 	carry = *q;
92 	*q = 0;
93 	s = mygetenv(p, env);
94 	*q = carry;
95 	if (carry == '}')
96 		q++;
97 	if (s) {
98 		bufcpy(buf, s, strlen(s));
99 		free(s);
100 	} else 		/* copy name intact*/
101 		bufcpy(buf, w, q-w);
102 	return(q);
103 }
104 
105 void
106 front(char *s)
107 {
108 	char *t, *q;
109 	int i, j;
110 	char *flds[512];
111 
112 	q = strdup(s);
113 	setfields(" \t\n");
114 	i = getfields(q, flds, 512);
115 	if(i > 5){
116 		flds[4] = flds[i-1];
117 		flds[3] = "...";
118 		i = 5;
119 	}
120 	t = s;
121 	for(j = 0; j < i; j++){
122 		for(s = flds[j]; *s; *t++ = *s++);
123 		*t++ = ' ';
124 	}
125 	*t = 0;
126 	free(q);
127 }
128