]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/mk/word.c
ip/ipconfig: format ipmask with %M instead of %I
[plan9front.git] / sys / src / cmd / mk / word.c
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 space */
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 = expandquote(cp, r, b);
122                         if(cp == 0){
123                                 fprint(2, "missing closing quote: %s\n", *s);
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 }