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;
101 cp = *s;
102 b = newbuf();
103 head = tail = 0;
104 while(*cp == ' ' || *cp == '\t') /* leading white space */
105 cp++;
106 while(*cp){
107 cp += chartorune(&r, cp);
108 switch(r)
110 case ' ':
111 case '\t':
112 case '\n':
113 goto out;
114 case '\\':
115 case '\'':
116 case '"':
117 cp = shellt->expandquote(cp, r, b);
118 if(cp == 0){
119 fprint(2, "missing closing quote: %s\n", *s);
120 Exit();
122 break;
123 case '$':
124 w = varsub(&cp);
125 if(w == 0)
126 break;
127 if(b->current != b->start){
128 bufcpy(b, w->s, strlen(w->s));
129 insert(b, 0);
130 free(w->s);
131 w->s = strdup(b->start);
132 b->current = b->start;
134 if(head){
135 bufcpy(b, tail->s, strlen(tail->s));
136 bufcpy(b, w->s, strlen(w->s));
137 insert(b, 0);
138 free(tail->s);
139 tail->s = strdup(b->start);
140 tail->next = w->next;
141 free(w->s);
142 free(w);
143 b->current = b->start;
144 } else
145 tail = head = w;
146 while(tail->next)
147 tail = tail->next;
148 break;
149 default:
150 rinsert(b, r);
151 break;
154 out:
155 *s = cp;
156 if(b->current != b->start){
157 if(head){
158 cp = b->current;
159 bufcpy(b, tail->s, strlen(tail->s));
160 bufcpy(b, b->start, cp-b->start);
161 insert(b, 0);
162 free(tail->s);
163 tail->s = strdup(cp);
164 } else {
165 insert(b, 0);
166 head = newword(b->start);
169 freebuf(b);
170 return head;
173 void
174 dumpw(char *s, Word *w)
176 Bprint(&bout, "%s", s);
177 for(; w; w = w->next)
178 Bprint(&bout, " '%s'", w->s);
179 Bputc(&bout, '\n');