xref: /plan9-contrib/sys/src/cmd/mk/word.c (revision 219b2ee8daee37f4aad58d63f21287faa8e4ffdc)
1 #include	"mk.h"
2 
3 static char *nextword(char*, char**, char**);
4 
5 Word *
6 newword(char *s)
7 {
8 	Word *w = (Word *)Malloc(sizeof(Word));
9 
10 	w->s = strdup(s);
11 	w->next = 0;
12 	return(w);
13 }
14 
15 Word *
16 stow(char *s)
17 {
18 	int save;
19 	char *start, *end;
20 	Word *head, *w;
21 
22 	w = head = 0;
23 	while(*s){
24 		s = nextword(s, &start, &end);
25 		if(*start == 0)
26 			break;
27 		save = *end;
28 		*end = 0;
29 		if (w) {
30 			w->next = newword(start);
31 			w = w->next;
32 		} else
33 			head = w = newword(start);
34 		*end = save;
35 	}
36 	if (!head)
37 		head = newword("");
38 	return(head);
39 }
40 
41 char *
42 wtos(Word *w)
43 {
44 	Bufblock *buf;
45 	char *cp;
46 
47 	buf = newbuf();
48 	wtobuf(w, buf);
49 	insert(buf, 0);
50 	cp = strdup(buf->start);
51 	freebuf(buf);
52 	return(cp);
53 }
54 
55 void
56 wtobuf(Word *w, Bufblock *buf)
57 {
58 	char *cp;
59 
60 	for(; w; w = w->next){
61 		for(cp = w->s; *cp; cp++)
62 			insert(buf, *cp);
63 		if(w->next)
64 			insert(buf, ' ');
65 	}
66 }
67 
68 void
69 delword(Word *w)
70 {
71 	free(w->s);
72 	free((char *)w);
73 }
74 
75 void
76 dumpw(char *s, Word *w)
77 {
78 	Bprint(&stdout, "%s", s);
79 	for(; w; w = w->next)
80 		Bprint(&stdout, " '%s'", w->s);
81 	Bputc(&stdout, '\n');
82 }
83 
84 static char *
85 nextword(char *s, char **start, char **end)
86 {
87 	char *to;
88 	Rune r, q;
89 	int n;
90 
91 	while (*s && SEP(*s))		/* skip leading white space */
92 		s++;
93 	to = *start = s;
94 	while (*s) {
95 		n = chartorune(&r, s);
96 		if (SEP(r)) {
97 			if (to != *start)	/* we have data */
98 				break;
99 			s += n;		/* null string - keep looking */
100 			while (*s && SEP(*s))
101 				s++;
102 			to = *start = s;
103 		} else if (QUOTE(r)) {
104 			q = r;
105 			s += n;		/* skip leading quote */
106 			while (*s) {
107 				n = chartorune(&r, s);
108 				if (r == q) {
109 					if (s[1] != '\'')
110 						break;
111 					s++;	/* embedded quote */
112 				}
113 				while (n--)
114 					*to++ = *s++;
115 			}
116 			if (!*s)		/* no trailing quote */
117 				break;
118 			s++;			/* skip trailing quote */
119 		} else  {
120 			while (n--)
121 				*to++ = *s++;
122 		}
123 	}
124 	*end = to;
125 	return s;
126 }
127