tword.c - plan9port - [fork] Plan 9 from user space | |
git clone git://src.adamsgaard.dk/plan9port | |
Log | |
Files | |
Refs | |
README | |
LICENSE | |
--- | |
tword.c (2715B) | |
--- | |
1 #include "mk.h" | |
2 | |
3 static Word *nextword(char**); | |
4 | |
5 Word* | |
6 newword(char *s) | |
7 { | |
8 Word *w; | |
9 | |
10 w = (Word *)Malloc(sizeof(Word)); | |
11 w->s = strdup(s); | |
12 w->next = 0; | |
13 return(w); | |
14 } | |
15 | |
16 Word * | |
17 stow(char *s) | |
18 { | |
19 Word *head, *w, *new; | |
20 | |
21 w = head = 0; | |
22 while(*s){ | |
23 new = nextword(&s); | |
24 if(new == 0) | |
25 break; | |
26 if (w) | |
27 w->next = new; | |
28 else | |
29 head = w = new; | |
30 while(w->next) | |
31 w = w->next; | |
32 | |
33 } | |
34 if (!head) | |
35 head = newword(""); | |
36 return(head); | |
37 } | |
38 | |
39 char * | |
40 wtos(Word *w, int sep) | |
41 { | |
42 Bufblock *buf; | |
43 char *cp; | |
44 | |
45 buf = newbuf(); | |
46 for(; w; w = w->next){ | |
47 for(cp = w->s; *cp; cp++) | |
48 insert(buf, *cp); | |
49 if(w->next) | |
50 insert(buf, sep); | |
51 } | |
52 insert(buf, 0); | |
53 cp = strdup(buf->start); | |
54 freebuf(buf); | |
55 return(cp); | |
56 } | |
57 | |
58 Word* | |
59 wdup(Word *w) | |
60 { | |
61 Word *v, *new, *base; | |
62 | |
63 v = base = 0; | |
64 while(w){ | |
65 new = newword(w->s); | |
66 if(v) | |
67 v->next = new; | |
68 else | |
69 base = new; | |
70 v = new; | |
71 w = w->next; | |
72 } | |
73 return base; | |
74 } | |
75 | |
76 void | |
77 delword(Word *w) | |
78 { | |
79 Word *v; | |
80 | |
81 while(v = w){ | |
82 w = w->next; | |
83 if(v->s) | |
84 free(v->s); | |
85 free(v); | |
86 } | |
87 } | |
88 | |
89 /* | |
90 * break out a word from a string handling quotes, executions, | |
91 * and variable expansions. | |
92 */ | |
93 static Word* | |
94 nextword(char **s) | |
95 { | |
96 Bufblock *b; | |
97 Word *head, *tail, *w; | |
98 Rune r; | |
99 char *cp; | |
100 int empty; | |
101 | |
102 cp = *s; | |
103 b = newbuf(); | |
104 restart: | |
105 head = tail = 0; | |
106 while(*cp == ' ' || *cp == '\t') /* leading white… | |
107 cp++; | |
108 empty = 1; | |
109 while(*cp){ | |
110 cp += chartorune(&r, cp); | |
111 switch(r) | |
112 { | |
113 case ' ': | |
114 case '\t': | |
115 case '\n': | |
116 goto out; | |
117 case '\\': | |
118 case '\'': | |
119 case '"': | |
120 empty = 0; | |
121 cp = shellt->expandquote(cp, r, b); | |
122 if(cp == 0){ | |
123 fprint(2, "missing closing quote: %s\n",… | |
124 Exit(); | |
125 } | |
126 break; | |
127 case '$': | |
128 w = varsub(&cp); | |
129 if(w == 0){ | |
130 if(empty) | |
131 goto restart; | |
132 break; | |
133 } | |
134 empty = 0; | |
135 if(b->current != b->start){ | |
136 bufcpy(b, w->s, strlen(w->s)); | |
137 insert(b, 0); | |
138 free(w->s); | |
139 w->s = strdup(b->start); | |
140 b->current = b->start; | |
141 } | |
142 if(head){ | |
143 bufcpy(b, tail->s, strlen(tail->s)); | |
144 bufcpy(b, w->s, strlen(w->s)); | |
145 insert(b, 0); | |
146 free(tail->s); | |
147 tail->s = strdup(b->start); | |
148 tail->next = w->next; | |
149 free(w->s); | |
150 free(w); | |
151 b->current = b->start; | |
152 } else | |
153 tail = head = w; | |
154 while(tail->next) | |
155 tail = tail->next; | |
156 break; | |
157 default: | |
158 empty = 0; | |
159 rinsert(b, r); | |
160 break; | |
161 } | |
162 } | |
163 out: | |
164 *s = cp; | |
165 if(b->current != b->start){ | |
166 if(head){ | |
167 cp = b->current; | |
168 bufcpy(b, tail->s, strlen(tail->s)); | |
169 bufcpy(b, b->start, cp-b->start); | |
170 insert(b, 0); | |
171 free(tail->s); | |
172 tail->s = strdup(cp); | |
173 } else { | |
174 insert(b, 0); | |
175 head = newword(b->start); | |
176 } | |
177 } | |
178 freebuf(b); | |
179 return head; | |
180 } | |
181 | |
182 void | |
183 dumpw(char *s, Word *w) | |
184 { | |
185 Bprint(&bout, "%s", s); | |
186 for(; w; w = w->next) | |
187 Bprint(&bout, " '%s'", w->s); | |
188 Bputc(&bout, '\n'); | |
189 } |