xref: /plan9-contrib/sys/src/cmd/mk/word.c (revision d3907fe5a68251e8b016f54f72acf8767ba044bb)
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