xref: /inferno-os/utils/rcsh/word.c (revision 4eb166cf184c1f102fb79e31b1465ea3e2021c39)
1 #include "rc.h"
2 
3 Word *
4 newword(char *wd, Word *next)
5 {
6 	Word *p=new(Word);
7 	p->word=strdup(wd);
8 	p->next=next;
9 	return p;
10 }
11 
12 void
13 pushword(char *wd)
14 {
15 	if(runq->argv==0)
16 		panic("pushword but no argv!", 0);
17 	runq->argv->words=newword(wd, runq->argv->words);
18 }
19 
20 void
21 popword(void)
22 {
23 	Word *p;
24 
25 	if(runq->argv==0)
26 		panic("popword but no argv!", 0);
27 	p=runq->argv->words;
28 	if(p==0)
29 		panic("popword but no word!", 0);
30 	runq->argv->words=p->next;
31 	free(p->word);
32 	free(p);
33 }
34 
35 void
36 freewords(Word *w)
37 {
38 	Word *nw;
39 	while(w){
40 		free(w->word);
41 		nw=w->next;
42 		free(w);
43 		w=nw;
44 	}
45 }
46 
47 void
48 freelist(Word *w)
49 {
50 	Word *nw;
51 	while(w){
52 		nw=w->next;
53 		free(w->word);
54 		free(w);
55 		w=nw;
56 	}
57 }
58 
59 void
60 pushlist(void)
61 {
62 	List *p=new(List);
63 	p->next=runq->argv;
64 	p->words=0;
65 	runq->argv=p;
66 }
67 
68 void
69 poplist(void)
70 {
71 	List *p=runq->argv;
72 	if(p==0)
73 		panic("poplist but no argv", 0);
74 	freelist(p->words);
75 	runq->argv=p->next;
76 	free(p);
77 }
78 
79 int
80 count(Word *w)
81 {
82 	int n;
83 	for(n=0;w;n++)
84 		w=w->next;
85 	return n;
86 }
87 
88 /*
89  * copy arglist a, adding the copy to the front of tail
90  */
91 Word *
92 copywords(Word *a, Word *tail)
93 {
94 	Word *v=0, **end;
95 	for(end=&v;a;a=a->next,end=&(*end)->next)
96 		*end=newword(a->word, 0);
97 	*end=tail;
98 	return v;
99 }
100 
101 char *
102 list2str(Word *words)
103 {
104 	char *value, *s, *t;
105 	int len=0;
106 	Word *ap;
107 
108 	for(ap=words;ap;ap=ap->next)
109 		len+=1+strlen(ap->word);
110 	value=malloc(len+1);
111 	s=value;
112 	for(ap=words;ap;ap=ap->next){
113 		for(t=ap->word;*t;) *s++=*t++;
114 		*s++=' ';
115 	}
116 	if(s==value)
117 		*s='\0';
118 	else
119 		s[-1]='\0';
120 	return value;
121 }
122 
123 Word *
124 subwords(Word *val, int len, Word *sub, Word *a)
125 {
126 	int n;
127 	char *s;
128 
129 	if(!sub) return a;
130 	a=subwords(val, len, sub->next, a);
131 	s=sub->word;
132 	deglob(s);
133 	n=0;
134 	while('0'<=*s && *s<='9') n=n*10+ *s++ -'0';
135 	if(n<1 || len<n) return a;
136 	for(;n!=1;--n) val=val->next;
137 	return newword(val->word, a);
138 }
139 
140 
141 void
142 pushredir(int type, int from, int to)
143 {
144 	Redir *rp=new(Redir);
145 	rp->type=type;
146 	rp->from=from;
147 	rp->to=to;
148 	rp->next=runq->redir;
149 	runq->redir=rp;
150 }
151 
152 void
153 turfredir(void)
154 {
155 	while(runq->redir!=runq->startredir)
156 		Xpopredir();
157 }
158 
159 Word*
160 conclist(Word *lp, Word *rp, Word *tail)
161 {
162 	char *buf;
163 	Word *v;
164 	if(lp->next || rp->next)
165 		tail=conclist(lp->next==0?lp:lp->next, rp->next==0?rp:rp->next,
166 			tail);
167 	buf=malloc(strlen(lp->word)+strlen(rp->word)+1);
168 	strcpy(buf, lp->word);
169 	strcat(buf, rp->word);
170 	v=newword(buf, tail);
171 	free(buf);
172 	return v;
173 }
174