1 /* This code was written and is copyrighted 1994,1995,1996 by
2  *
3  *       Elmar Bartel
4  *       Institut fuer Informatik
5  *       Technische Universitaet Muenchen
6  *       bartel@informatik.tu-muenchen.de
7  *
8  * Permission to use, copy, modify and distribute this software
9  * and its documentation for any purpose, except making money, is
10  * herby granted, provided that the above copyright notice and
11  * this permission appears in all places, where this code is
12  * referenced or used literally.
13  */
14 
15 /* This file is a partial copy from files of other packages.
16  * Full information about these other packes can be obtained
17  * from the author:
18  *       		bartel@informatik.tu-muenchen.de
19  */
20 #include <string.h>
21 #if defined(FreeBSD)
22 #include <stdlib.h>
23 #else
24 #include <malloc.h>
25 #endif /*FreeBSD*/
26 #include "support.h"
27 
28 /* Pad the string to size from right with character pad.
29  * CAUTION: No check is done to ensure there is room for the
30  *          additional characters.
31  */
strrpad(char * s,char pad,int size)32 char *strrpad(char *s, char pad, int size) {
33     int i= strlen(s);
34     while (i<size) {
35     	s[i]= pad;
36 	i++;
37     }
38     s[i]= '\0';
39     return s;
40 }
LenStrLeng(LenStr * ls)41 int LenStrLeng(LenStr *ls) {
42     return ls->Leng;
43 }
LenStrApp(LenStr * ls,char ch)44 LenStr *LenStrApp(LenStr *ls, char ch) {
45     if (ls->Leng == ls->MaxLeng) {
46 	ls->MaxLeng+= (ls->MaxLeng >> 3) + 1;
47 	ls->s= rNew(ls->s, ls->MaxLeng+1, char);
48     }
49     ls->s[ls->Leng++]= ch;
50     ls->s[ls->Leng]= '\0';
51     return ls;
52 }
LenStrEnsureSpace(LenStr * ls,int n)53 LenStr *LenStrEnsureSpace(LenStr *ls, int n) {
54     if (ls->MaxLeng-ls->Leng < n) {
55     	char *ns= rNew(ls->s, n+1, char);
56 	if (ns == Nil(char))
57 	    return Nil(LenStr);
58 	else {
59 	    ls->s= ns;
60 	    return ls;
61 	}
62     }
63     else
64 	return ls;
65 }
LenStrPadRight(LenStr * ls,char c,int n)66 LenStr *LenStrPadRight(LenStr *ls, char c, int n) {
67     if (ls->Leng >= n)
68     	return ls;
69     ls= LenStrEnsureSpace(ls, n);
70     strrpad(ls->s, c, n);
71     ls->Leng= n;
72     return ls;
73 }
LenStrcpy(LenStr * dvs,char * s)74 LenStr *LenStrcpy(LenStr *dvs, char *s) {
75     int l= strlen(s);
76     if (l >= dvs->MaxLeng) {
77 	dvs->s= rNew(dvs->s, l+1, char);
78 	dvs->MaxLeng= l;
79     }
80     strcpy(dvs->s, s);
81     dvs->Leng= l;
82     return dvs;
83 }
LenStrString(LenStr * ls)84 char *LenStrString(LenStr *ls) {
85     return ls->s;
86 }
LenStrncat(LenStr * dls,char * s,int n)87 LenStr *LenStrncat(LenStr *dls, char *s, int n) {
88     int l= strlen(s);
89     if (l < n)
90     	n= l;
91     if (n+dls->Leng >= dls->MaxLeng) {
92 	dls->MaxLeng= (dls->Leng + l);
93 	dls->s= rNew(dls->s, dls->MaxLeng+1, char);
94     }
95     strncat(dls->s+dls->Leng, s, n);
96     dls->Leng+= n;
97     dls->s[dls->Leng]= '\0';
98     return dls;
99 }
LenStrMake(char * s)100 LenStr *LenStrMake(char *s) {
101     LenStr *vs= NewLenStr;
102     vs->MaxLeng= vs->Leng= strlen(s);
103     vs->s= (char *)malloc(vs->Leng+1);
104     strcpy(vs->s, s);
105     return vs;
106 }
LenStrcat(LenStr * dls,char * s)107 LenStr *LenStrcat(LenStr *dls, char *s) {
108     int l= strlen(s);
109     if (l+dls->Leng >= dls->MaxLeng) {
110 	dls->MaxLeng= (dls->Leng + l);
111 	dls->s= rNew(dls->s, dls->MaxLeng+1, char);
112     }
113     strcat(dls->s+dls->Leng, s);
114     dls->Leng+= l;
115     return dls;
116 }
LenStrCreate(int l)117 LenStr *LenStrCreate(int l) {
118     LenStr *vs= New(LenStr);
119     vs->Leng= 0;
120     vs->MaxLeng= l;
121     vs->s= (char *)malloc(l+1);
122     vs->s[0]= '\0';
123     return vs;
124 }
LenStrDestroy(LenStr * ls)125 void LenStrDestroy(LenStr *ls) {
126     if (ls->s)
127 	free(ls->s);
128     free(ls);
129     return;
130 }
131 
StrVecFromArgv(int argc,char * argv[])132 StrVec *StrVecFromArgv(int argc, char *argv[]) {
133     StrVec *sa= New(StrVec);
134     int i;
135 
136     if (sa == Nil(StrVec))
137     	return Nil(StrVec);
138     if ((sa->String=nNew(argc, char *)) == Nil(char*)) {
139     	free(sa);
140     	return Nil(StrVec);
141     }
142     sa->Leng= 0;
143     sa->MaxLeng= argc;
144     for (i= 0; i<argc; i++) {
145     	StrVec *nsa= StrVecAppend(sa, argv[i]);
146 	if (nsa == Nil(StrVec)) {
147 	    StrVecDestroy(sa);
148 	    return Nil(StrVec);
149 	}
150 	else
151 	    sa= nsa;
152     }
153     return sa;
154 }
StrVecExpand(StrVec * sv,int n)155 StrVec *StrVecExpand(StrVec *sv, int n) {
156     if (n > sv->MaxLeng) {
157 	char **ss;
158 	if (sv->String==Nil(char *))
159 	    ss= nNew(n, char*);
160 	else
161 	    ss= rNew(sv->String, n, char*);
162 	if (ss == Nil(char *))
163 	    return Nil(StrVec);
164 	sv->MaxLeng= n;
165 	sv->String= ss;
166     }
167     return sv;
168 }
StrVecAppend(StrVec * sa,char * s)169 StrVec *StrVecAppend(StrVec *sa, char *s) {
170     char *ns;
171     if (sa->Leng >= sa->MaxLeng) {
172     	StrVec *nsa;
173 	int nl= sa->MaxLeng;
174 	nl+= (nl>>3) + 4;
175     	if ((nsa=StrVecExpand(sa, nl)) == Nil(StrVec))
176 	    return Nil(StrVec);
177     }
178     if ((ns=strdup(s)) == Nil(char))
179     	return Nil(StrVec);
180     sa->String[sa->Leng++]= ns;
181     return sa;
182 }
StrVecToString(StrVec * sa,char Sep)183 char *StrVecToString(StrVec *sa, char Sep) {
184     int  i, StrLeng= 0;
185     char *str, *dstr;
186 
187     for (i=0; i< sa->Leng; i++) {
188         char *cp= sa->String[i];
189 	int l= 0;
190 	while (*cp) {
191 	    l++;
192 	    if (*cp == Sep) {
193 	    	l++;
194 		while (*cp && *cp==Sep)
195 		    cp++;
196 	    }
197 	    else
198 		cp++;
199 	}
200 	StrLeng+= l+1;
201     }
202     dstr= str= nNew(StrLeng+1, char);
203     if (dstr == Nil(char))
204     	return Nil(char);
205     for (i=0; i< sa->Leng; i++) {
206         char *cp= sa->String[i];
207 	if (i>0)
208 	    *dstr++= Sep;
209 	while (*cp) {
210 	    if (*cp == Sep)
211 	    	*dstr++= '\\';
212 	    *dstr++= *cp++;
213 	}
214     }
215     *dstr='\0';
216     return str;
217 }
StrVecJoin(StrVec * sv,StrVec * sv1)218 StrVec *StrVecJoin(StrVec *sv, StrVec *sv1) {
219     int i;
220     sv= StrVecExpand(sv, sv->Leng+sv1->Leng);
221 
222     if (sv == Nil(StrVec))
223     	return Nil(StrVec);
224 
225     for (i=0; i<sv1->Leng; i++) {
226     	char *sd= strdup(sv1->String[i]);
227 	if (sd != Nil(char))
228 	    sv->String[sv->Leng++]= sd;
229 	else {
230 	    while (--i>=0)
231 	    	free(sv->String[--sv->Leng]);
232 	    return Nil(StrVec);
233 	}
234     }
235     return sv;
236 }
StrVecCreate()237 StrVec *StrVecCreate() {
238     StrVec *sa= New(StrVec);
239 
240     if (sa == Nil(StrVec))
241 	return Nil(StrVec);
242     sa->Leng= 0;
243     sa->MaxLeng= 0;
244     sa->String= Nil(char*);
245     return sa;
246 }
StrVecFromString(char * s,char Sep)247 StrVec *StrVecFromString(char *s, char Sep) {
248     char *scp, *rcp, *ss;
249     StrVec *sa;
250 
251     if ((ss=strdup(s)) == Nil(char))
252     	return Nil(StrVec);
253     if ((sa=StrVecCreate()) == Nil(StrVec)) {
254     	free(ss);
255     	return Nil(StrVec);
256     }
257     rcp= ss;
258     while (*rcp) {
259     	StrVec *nsa;
260 	char *start;
261         while (*rcp == Sep)
262 	    rcp++;
263 	scp= start= rcp;
264 	while (*rcp) {
265 	    if (*rcp == '\\') {
266 	        *scp++= *++rcp;
267 		if (*rcp) rcp++;
268 		continue;
269 	    }
270 	    if (*rcp == Sep) {
271 		if (*rcp) rcp++;
272 	    	*scp= '\0';
273 		break;
274 	    }
275 	    *scp++= *rcp++;
276 	}
277 	if ((nsa=StrVecAppend(sa, start)) == Nil(StrVec)) {
278 	    free(ss);
279 	    StrVecDestroy(sa);
280 	    return Nil(StrVec);
281 	}
282 	else
283 	    sa= nsa;
284     }
285     free(ss);
286     return sa;
287 }
StrVecDestroy(StrVec * sa)288 void StrVecDestroy(StrVec *sa) {
289     int i;
290     for (i=0; i<sa->Leng; i++)
291     	free(sa->String[i]);
292     if (sa->Leng > 0)
293 	free(sa->String);
294     free(sa);
295     return;
296 }
297