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