Blob


1 #include "mk.h"
3 static Word *nextword(char**);
5 Word*
6 newword(char *s)
7 {
8 Word *w;
10 w = (Word *)Malloc(sizeof(Word));
11 w->s = strdup(s);
12 w->next = 0;
13 return(w);
14 }
16 Word *
17 stow(char *s)
18 {
19 Word *head, *w, *new;
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;
33 }
34 if (!head)
35 head = newword("");
36 return(head);
37 }
39 char *
40 wtos(Word *w, int sep)
41 {
42 Bufblock *buf;
43 char *cp;
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 }
58 Word*
59 wdup(Word *w)
60 {
61 Word *v, *new, *base;
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 }
76 void
77 delword(Word *w)
78 {
79 Word *v;
81 while(v = w){
82 w = w->next;
83 if(v->s)
84 free(v->s);
85 free(v);
86 }
87 }
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;
102 cp = *s;
103 b = newbuf();
104 restart:
105 head = tail = 0;
106 while(*cp == ' ' || *cp == '\t') /* leading white space */
107 cp++;
108 empty = 1;
109 while(*cp){
110 cp += chartorune(&r, cp);
111 switch(r)
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", *s);
124 Exit();
126 break;
127 case '$':
128 w = varsub(&cp);
129 if(w == 0){
130 if(empty)
131 goto restart;
132 break;
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;
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;
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);
178 freebuf(b);
179 return head;
182 void
183 dumpw(char *s, Word *w)
185 Bprint(&bout, "%s", s);
186 for(; w; w = w->next)
187 Bprint(&bout, " '%s'", w->s);
188 Bputc(&bout, '\n');