Subversion Repositories planix.SVN

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 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
}