13e12c5d1SDavid du Colombier #include "mk.h"
23e12c5d1SDavid du Colombier
37dd7cddfSDavid du Colombier static Word *nextword(char**);
43e12c5d1SDavid du Colombier
53e12c5d1SDavid du Colombier Word*
newword(char * s)63e12c5d1SDavid du Colombier newword(char *s)
73e12c5d1SDavid du Colombier {
87dd7cddfSDavid du Colombier Word *w;
93e12c5d1SDavid du Colombier
107dd7cddfSDavid du Colombier w = (Word *)Malloc(sizeof(Word));
113e12c5d1SDavid du Colombier w->s = strdup(s);
123e12c5d1SDavid du Colombier w->next = 0;
133e12c5d1SDavid du Colombier return(w);
143e12c5d1SDavid du Colombier }
153e12c5d1SDavid du Colombier
163e12c5d1SDavid du Colombier Word *
stow(char * s)173e12c5d1SDavid du Colombier stow(char *s)
183e12c5d1SDavid du Colombier {
197dd7cddfSDavid du Colombier Word *head, *w, *new;
203e12c5d1SDavid du Colombier
213e12c5d1SDavid du Colombier w = head = 0;
223e12c5d1SDavid du Colombier while(*s){
237dd7cddfSDavid du Colombier new = nextword(&s);
247dd7cddfSDavid du Colombier if(new == 0)
253e12c5d1SDavid du Colombier break;
267dd7cddfSDavid du Colombier if (w)
277dd7cddfSDavid du Colombier w->next = new;
287dd7cddfSDavid du Colombier else
297dd7cddfSDavid du Colombier head = w = new;
307dd7cddfSDavid du Colombier while(w->next)
313e12c5d1SDavid du Colombier w = w->next;
327dd7cddfSDavid du Colombier
333e12c5d1SDavid du Colombier }
343e12c5d1SDavid du Colombier if (!head)
353e12c5d1SDavid du Colombier head = newword("");
363e12c5d1SDavid du Colombier return(head);
373e12c5d1SDavid du Colombier }
383e12c5d1SDavid du Colombier
393e12c5d1SDavid du Colombier char *
wtos(Word * w,int sep)407dd7cddfSDavid du Colombier wtos(Word *w, int sep)
413e12c5d1SDavid du Colombier {
423e12c5d1SDavid du Colombier Bufblock *buf;
433e12c5d1SDavid du Colombier char *cp;
443e12c5d1SDavid du Colombier
453e12c5d1SDavid du Colombier buf = newbuf();
467dd7cddfSDavid du Colombier for(; w; w = w->next){
477dd7cddfSDavid du Colombier for(cp = w->s; *cp; cp++)
487dd7cddfSDavid du Colombier insert(buf, *cp);
497dd7cddfSDavid du Colombier if(w->next)
507dd7cddfSDavid du Colombier insert(buf, sep);
517dd7cddfSDavid du Colombier }
523e12c5d1SDavid du Colombier insert(buf, 0);
533e12c5d1SDavid du Colombier cp = strdup(buf->start);
543e12c5d1SDavid du Colombier freebuf(buf);
553e12c5d1SDavid du Colombier return(cp);
563e12c5d1SDavid du Colombier }
573e12c5d1SDavid du Colombier
587dd7cddfSDavid du Colombier Word*
wdup(Word * w)597dd7cddfSDavid du Colombier wdup(Word *w)
603e12c5d1SDavid du Colombier {
617dd7cddfSDavid du Colombier Word *v, *new, *base;
623e12c5d1SDavid du Colombier
637dd7cddfSDavid du Colombier v = base = 0;
647dd7cddfSDavid du Colombier while(w){
657dd7cddfSDavid du Colombier new = newword(w->s);
667dd7cddfSDavid du Colombier if(v)
677dd7cddfSDavid du Colombier v->next = new;
687dd7cddfSDavid du Colombier else
697dd7cddfSDavid du Colombier base = new;
707dd7cddfSDavid du Colombier v = new;
717dd7cddfSDavid du Colombier w = w->next;
723e12c5d1SDavid du Colombier }
737dd7cddfSDavid du Colombier return base;
743e12c5d1SDavid du Colombier }
753e12c5d1SDavid du Colombier
763e12c5d1SDavid du Colombier void
delword(Word * w)773e12c5d1SDavid du Colombier delword(Word *w)
783e12c5d1SDavid du Colombier {
797dd7cddfSDavid du Colombier Word *v;
807dd7cddfSDavid du Colombier
817dd7cddfSDavid du Colombier while(v = w){
827dd7cddfSDavid du Colombier w = w->next;
837dd7cddfSDavid du Colombier if(v->s)
847dd7cddfSDavid du Colombier free(v->s);
857dd7cddfSDavid du Colombier free(v);
867dd7cddfSDavid du Colombier }
877dd7cddfSDavid du Colombier }
887dd7cddfSDavid du Colombier
897dd7cddfSDavid du Colombier /*
907dd7cddfSDavid du Colombier * break out a word from a string handling quotes, executions,
917dd7cddfSDavid du Colombier * and variable expansions.
927dd7cddfSDavid du Colombier */
937dd7cddfSDavid du Colombier static Word*
nextword(char ** s)947dd7cddfSDavid du Colombier nextword(char **s)
957dd7cddfSDavid du Colombier {
967dd7cddfSDavid du Colombier Bufblock *b;
977dd7cddfSDavid du Colombier Word *head, *tail, *w;
987dd7cddfSDavid du Colombier Rune r;
997dd7cddfSDavid du Colombier char *cp;
100*d3907fe5SDavid du Colombier int empty;
1017dd7cddfSDavid du Colombier
1027dd7cddfSDavid du Colombier cp = *s;
1037dd7cddfSDavid du Colombier b = newbuf();
104*d3907fe5SDavid du Colombier restart:
1057dd7cddfSDavid du Colombier head = tail = 0;
1067dd7cddfSDavid du Colombier while(*cp == ' ' || *cp == '\t') /* leading white space */
1077dd7cddfSDavid du Colombier cp++;
108*d3907fe5SDavid du Colombier empty = 1;
1097dd7cddfSDavid du Colombier while(*cp){
1107dd7cddfSDavid du Colombier cp += chartorune(&r, cp);
1117dd7cddfSDavid du Colombier switch(r)
1127dd7cddfSDavid du Colombier {
1137dd7cddfSDavid du Colombier case ' ':
1147dd7cddfSDavid du Colombier case '\t':
1157dd7cddfSDavid du Colombier case '\n':
1167dd7cddfSDavid du Colombier goto out;
1177dd7cddfSDavid du Colombier case '\\':
1187dd7cddfSDavid du Colombier case '\'':
1197dd7cddfSDavid du Colombier case '"':
120*d3907fe5SDavid du Colombier empty = 0;
1217dd7cddfSDavid du Colombier cp = expandquote(cp, r, b);
1227dd7cddfSDavid du Colombier if(cp == 0){
1237dd7cddfSDavid du Colombier fprint(2, "missing closing quote: %s\n", *s);
1247dd7cddfSDavid du Colombier Exit();
1257dd7cddfSDavid du Colombier }
1267dd7cddfSDavid du Colombier break;
1277dd7cddfSDavid du Colombier case '$':
1287dd7cddfSDavid du Colombier w = varsub(&cp);
129*d3907fe5SDavid du Colombier if(w == 0){
130*d3907fe5SDavid du Colombier if(empty)
131*d3907fe5SDavid du Colombier goto restart;
1327dd7cddfSDavid du Colombier break;
133*d3907fe5SDavid du Colombier }
134*d3907fe5SDavid du Colombier empty = 0;
1357dd7cddfSDavid du Colombier if(b->current != b->start){
1367dd7cddfSDavid du Colombier bufcpy(b, w->s, strlen(w->s));
1377dd7cddfSDavid du Colombier insert(b, 0);
1383e12c5d1SDavid du Colombier free(w->s);
1397dd7cddfSDavid du Colombier w->s = strdup(b->start);
1407dd7cddfSDavid du Colombier b->current = b->start;
1417dd7cddfSDavid du Colombier }
1427dd7cddfSDavid du Colombier if(head){
1437dd7cddfSDavid du Colombier bufcpy(b, tail->s, strlen(tail->s));
1447dd7cddfSDavid du Colombier bufcpy(b, w->s, strlen(w->s));
1457dd7cddfSDavid du Colombier insert(b, 0);
1467dd7cddfSDavid du Colombier free(tail->s);
1477dd7cddfSDavid du Colombier tail->s = strdup(b->start);
1487dd7cddfSDavid du Colombier tail->next = w->next;
1497dd7cddfSDavid du Colombier free(w->s);
1507dd7cddfSDavid du Colombier free(w);
1517dd7cddfSDavid du Colombier b->current = b->start;
1527dd7cddfSDavid du Colombier } else
1537dd7cddfSDavid du Colombier tail = head = w;
1547dd7cddfSDavid du Colombier while(tail->next)
1557dd7cddfSDavid du Colombier tail = tail->next;
1567dd7cddfSDavid du Colombier break;
1577dd7cddfSDavid du Colombier default:
158*d3907fe5SDavid du Colombier empty = 0;
1597dd7cddfSDavid du Colombier rinsert(b, r);
1607dd7cddfSDavid du Colombier break;
1617dd7cddfSDavid du Colombier }
1627dd7cddfSDavid du Colombier }
1637dd7cddfSDavid du Colombier out:
1647dd7cddfSDavid du Colombier *s = cp;
1657dd7cddfSDavid du Colombier if(b->current != b->start){
1667dd7cddfSDavid du Colombier if(head){
1677dd7cddfSDavid du Colombier cp = b->current;
1687dd7cddfSDavid du Colombier bufcpy(b, tail->s, strlen(tail->s));
1697dd7cddfSDavid du Colombier bufcpy(b, b->start, cp-b->start);
1707dd7cddfSDavid du Colombier insert(b, 0);
1717dd7cddfSDavid du Colombier free(tail->s);
1727dd7cddfSDavid du Colombier tail->s = strdup(cp);
1737dd7cddfSDavid du Colombier } else {
1747dd7cddfSDavid du Colombier insert(b, 0);
1757dd7cddfSDavid du Colombier head = newword(b->start);
1767dd7cddfSDavid du Colombier }
1777dd7cddfSDavid du Colombier }
1787dd7cddfSDavid du Colombier freebuf(b);
1797dd7cddfSDavid du Colombier return head;
1803e12c5d1SDavid du Colombier }
1813e12c5d1SDavid du Colombier
1823e12c5d1SDavid du Colombier void
dumpw(char * s,Word * w)1833e12c5d1SDavid du Colombier dumpw(char *s, Word *w)
1843e12c5d1SDavid du Colombier {
1857dd7cddfSDavid du Colombier Bprint(&bout, "%s", s);
1863e12c5d1SDavid du Colombier for(; w; w = w->next)
1877dd7cddfSDavid du Colombier Bprint(&bout, " '%s'", w->s);
1887dd7cddfSDavid du Colombier Bputc(&bout, '\n');
1893e12c5d1SDavid du Colombier }
190