/[gentoo-alt]/trunk/toolchain-prefix-wrapper/utils/stringutil.c
Gentoo

Contents of /trunk/toolchain-prefix-wrapper/utils/stringutil.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1591 - (show annotations) (download) (as text)
Fri Nov 2 10:58:02 2007 UTC (6 years, 10 months ago) by haubi
File MIME type: text/x-csrc
File size: 12327 byte(s)
initial import of toolchain-prefix-wrapper

1 /*
2 * Copyright 2007 Gentoo Foundation
3 * Distributed under the terms of the GNU General Public License v2
4 * Author: Michael Haubenwallner <haubi@gentoo.org>
5 */
6
7 #include "stringutil.h"
8
9 #include <string.h>
10 #include <stdlib.h>
11
12 typedef struct _Content {
13 int referenceCount;
14 int length;
15 int reserved;
16 char *buffer;
17 } Content;
18
19 static Content* ContentDestroy(Content* content)
20 {
21 if (content == NULL) {
22 return NULL;
23 }
24 if (content->buffer) {
25 free((void*)content->buffer);
26 }
27 content->buffer = NULL;
28 content->length = 0;
29 content->reserved = 0;
30 free(content);
31 return NULL;
32 }
33
34 static Content* ContentUnref(Content* content)
35 {
36 if (content == NULL) {
37 return NULL;
38 }
39 -- content->referenceCount;
40 if (content->referenceCount > 0) {
41 return NULL;
42 }
43 return ContentDestroy(content);
44 }
45
46 static Content* ContentRef(Content* content)
47 {
48 if (content != NULL) {
49 ++ content->referenceCount;
50 }
51 return content;
52 }
53
54 static Content* ContentCreate(int reserve)
55 {
56 Content* content = (Content*)malloc(sizeof(Content));
57 if (content == NULL) {
58 return NULL;
59 }
60 content->referenceCount = 0;
61 content->length = 0;
62 content->reserved = 0;
63 content->buffer = NULL;
64
65 content->reserved = reserve + 1;
66 content->buffer = (char*)malloc(content->reserved * sizeof(char));
67
68 if (content->buffer == NULL) {
69 content = ContentDestroy(content);
70 }
71
72 return content;
73 }
74
75 static int ContentAppend(Content* content, char const *text, int length)
76 {
77 if (content == NULL) return -1;
78 if (text == NULL) return 0;
79 if (length < 0) length = strlen(text);
80 if (length == 0) return 0;
81 if (content->length + length >= content->reserved) return -1;
82 memmove(content->buffer + content->length, text, length * sizeof(char));
83 content->length += length;
84 content->buffer[content->length] = '\0';
85 return 0;
86 }
87
88 static Content* ContentCreateVaConcat(Content *orig, char const *text, int length, va_list ap)
89 {
90 Content* content = NULL;
91 int concatLength;
92 char const * arg;
93 int argLength;
94 int err;
95 va_list aptmp;
96
97 do {
98 err = 1;
99
100 concatLength = 0;
101
102 if (orig && orig->buffer) {
103 concatLength += orig->length;
104 }
105
106 if (text) {
107 if (length < 0) {
108 length = strlen(text);
109 }
110 concatLength += length;
111 }
112
113 aptmp = ap;
114 do {
115 arg = va_arg(aptmp, char*);
116 if (arg == NULL) {
117 break;
118 }
119 argLength = va_arg(aptmp, int);
120 if (argLength < 0) {
121 argLength = strlen(arg);
122 }
123 concatLength += argLength;
124 } while(1);
125
126 content = ContentCreate(concatLength);
127 if (content == NULL) break;
128
129 if (orig && orig->buffer) {
130 if (ContentAppend(content, orig->buffer, orig->length) < 0) break;
131 }
132
133 /* length checked above already */
134 if (text) {
135 if (ContentAppend(content, text, length) < 0) break;
136 }
137
138 aptmp = ap;
139 do {
140 arg = va_arg(aptmp, char*);
141 if (arg == NULL) {
142 break;
143 }
144 argLength = va_arg(aptmp, int);
145 if (argLength < 0) {
146 argLength = strlen(arg);
147 }
148
149 if (ContentAppend(content, arg, argLength) < 0) break;
150 } while(1);
151
152 err = 0;
153 } while(0);
154
155 if (err && content) content = ContentDestroy(content);
156
157 return content;
158 }
159
160 static char * ContentExtractBuffer(Content* content)
161 {
162 char *ret = NULL;
163 if (content == NULL) {
164 return NULL;
165 }
166 ret = content->buffer;
167 content->buffer = NULL;
168 content->length = 0;
169 return ret;
170 }
171
172 static int ContentGetLength(Content const * content)
173 {
174 if (content == NULL) {
175 return -1;
176 }
177 return content->length;
178 }
179
180 static char const* ContentGetBuffer(Content const * content)
181 {
182 if (content == NULL) {
183 return NULL;
184 }
185 return content->buffer;
186 }
187
188 /*
189 * String with CopyOnWrite semantics
190 */
191
192 struct _String {
193 Content* content;
194 };
195
196 int StringGetLength(String *string)
197 {
198 if (string == NULL) {
199 return -1;
200 }
201 return ContentGetLength(string->content);
202 }
203
204 char const* StringGetBuffer(String *string)
205 {
206 if (string == NULL) {
207 return NULL;
208 }
209 return ContentGetBuffer(string->content);
210 }
211
212 String* StringDestroy(String *string)
213 {
214 if (string == NULL) {
215 return NULL;
216 }
217
218 string->content = ContentUnref(string->content);
219 free(string);
220 return NULL;
221 }
222
223 static String* StringCreate(Content* content)
224 {
225 String *string = (String*)malloc(sizeof(String));
226 if (string == NULL) return NULL;
227 if (content) string->content = ContentRef(content);
228 return string;
229 }
230
231 String* StringCreateVaConcat(char const *text, int length, va_list ap)
232 {
233 Content *content = NULL;
234 String *string = NULL;
235 int err;
236
237 do {
238 err = 1;
239
240 Content *content = ContentCreateVaConcat(NULL, text, length, ap);
241 if (content == NULL) break;
242
243 string = StringCreate(content);
244 if (string == NULL) break;
245
246 /* do not destroy content, is stored in string */
247 content = NULL;
248
249 err = 0;
250 } while(0);
251
252 if (err && string) string = StringDestroy(string);
253 if (content) content = ContentDestroy(content);
254
255 return string;
256 }
257
258 String* StringCreateConcat(char const *text, int length, ...)
259 {
260 String* string;
261
262 va_list ap;
263 va_start(ap, length);
264 string = StringCreateVaConcat(text, length, ap);
265 va_end(ap);
266
267 return string;
268 }
269
270 String* StringDup(String* origin)
271 {
272 if (origin == NULL) {
273 return StringCreateConcat(NULL, 0, NULL);
274 }
275
276 return StringCreate(origin->content);
277 }
278
279 void StringCopy(String* target, String* source)
280 {
281 ContentUnref(target->content);
282 target->content = ContentRef(source->content);
283 return;
284 }
285
286 int StringAppendVaConcat(String *string, char const *text, int length, va_list ap)
287 {
288 Content *newContent;
289 if (string == NULL) {
290 return 0;
291 }
292 newContent = ContentCreateVaConcat(string->content, text, length, ap);
293 if (newContent == NULL) {
294 return -1;
295 }
296
297 ContentUnref(string->content);
298 string->content = ContentRef(newContent);
299
300 return 0;
301 }
302
303 int StringAppendConcat(String *string, char const *text, int length, ...)
304 {
305 int ret;
306 va_list ap;
307
308 va_start(ap, length);
309 ret = StringAppendVaConcat(string, text, length, ap);
310 va_end(ap);
311
312 return 0;
313 }
314
315 int StringIsEqual(String *string, int at, char const *start, int length)
316 {
317 int rv = 0;
318 char const *buffer = NULL;
319 int buflen = 0;
320 if (string == NULL) {
321 if (start == NULL) {
322 return 1;
323 }
324 return 0;
325 }
326 buffer = ContentGetBuffer(string->content);
327 buflen = ContentGetLength(string->content);
328 if (buffer == NULL || at > buflen) {
329 buflen = 0;
330 buffer = "";
331 }
332 if (at <= buflen) {
333 buffer += at;
334 }
335 if (start == NULL) {
336 start = "";
337 length = 0;
338 }
339 if (length < 0) {
340 return strcmp(buffer, start) ? 0 : 1;
341 }
342
343 if (rv == 0) rv = length - buflen;
344 if (rv == 0) rv = strncmp(buffer, start, length);
345 return rv ? 0 : 1;
346 }
347
348 static char* StringExtractBuffer(String *string)
349 {
350 if (string == NULL) {
351 return NULL;
352 }
353 return ContentExtractBuffer(string->content);
354 }
355
356 /*
357 * StringList
358 */
359
360 struct _StringList {
361 int size;
362 int alloced;
363 String **list;
364 };
365
366 int StringListGetSize(StringList *list)
367 {
368 if (list == NULL) {
369 return -1;
370 }
371 return list->size;
372 }
373
374 String *StringListGetString(StringList *list, int index)
375 {
376 if (list == NULL || list->size <= index || index < 0) {
377 return NULL;
378 }
379 return list->list[index];
380 }
381
382 StringList *StringListDestroy(StringList *list)
383 {
384 if (list == NULL) {
385 return NULL;
386 }
387
388 while(list->size > 0) {
389 list->size --;
390 list->list[list->size] = StringDestroy(list->list[list->size]);
391 }
392 if (list->list != NULL) {
393 free(list->list);
394 list->list = NULL;
395 }
396 list->alloced = 0;
397
398 free(list);
399 return NULL;
400 }
401
402 int StringListAppendString(StringList *list, String *string)
403 {
404 if (string == NULL) {
405 return 0;
406 }
407 if (list->size == list->alloced) {
408 /* always have trailing NULL string in list */
409 String **tmp = (String**)realloc(list->list, (list->alloced + 5) * sizeof(char*));
410 if (tmp == NULL) {
411 return -1;
412 }
413 list->list = tmp;
414 list->alloced += 5;
415 }
416 list->list[list->size] = StringDup(string);
417 if (list->list[list->size] == NULL) {
418 return -1;
419 }
420 ++ list->size;
421 return 0;
422 }
423
424 int StringListAppendListModify(StringList *list, StringList *input, int start, int count
425 , char const *front, int frontLength
426 , char const *back, int backLength
427 )
428 {
429 if (list == NULL || input == NULL || start >= StringListGetSize(input)) {
430 return 0;
431 }
432
433 if (front && frontLength < 0) frontLength = strlen(front);
434 if (back && backLength < 0) backLength = strlen(back);
435
436 if (count > 0 && start + count > StringListGetSize(input)) {
437 count = StringListGetSize(input) - start;
438 }
439
440 if (count < 0) {
441 count = StringListGetSize(input) - start;
442 }
443
444 while(--count >= 0) {
445 if (front || back) {
446 if (StringListAppendConcat(list
447 , front ? front : "", front ? frontLength : 0
448 , StringGetBuffer(input->list[start]), StringGetLength(input->list[start])
449 , back ? back : "", back ? backLength : 0
450 , NULL) < 0) break;
451 start++;
452 } else {
453 if (StringListAppendString(list, input->list[start++]) < 0) break;
454 }
455 }
456 if (count >= 0) {
457 return -1;
458 }
459 return 0;
460 }
461
462 int StringListAppendList(StringList *list, StringList *input, int start, int count)
463 {
464 return StringListAppendListModify(list, input, start, count, NULL, 0, NULL, 0);
465 }
466
467 StringList *StringListCreate(StringList *input, int start, int count)
468 {
469 StringList *list = (StringList*)malloc(sizeof(StringList));
470 if (list == NULL) {
471 return NULL;
472 }
473 list->size = 0;
474 list->alloced = 0;
475 list->list = NULL;
476
477 if (StringListAppendList(list, input, start, count) < 0) {
478 list = StringListDestroy(list);
479 }
480 return list;
481 }
482
483 char **StringListToArgv(StringList *list)
484 {
485 char **argv;
486 if (list == NULL) {
487 return NULL;
488 }
489 argv = (char**)malloc((list->size + 1) * sizeof(char*));
490 if (argv == NULL) {
491 return NULL;
492 }
493
494 argv[list->size] = NULL;
495 while(list->size > 0) {
496 list->size --;
497 argv[list->size] = StringExtractBuffer(list->list[list->size]);
498 list->list[list->size] = StringDestroy(list->list[list->size]);
499 }
500
501 return argv;
502 }
503
504 int StringListAppendVaConcat(StringList* list, char const *text, int length, va_list ap)
505 {
506 int rv;
507 String *tmp = StringCreateVaConcat(text, length, ap);
508 if (tmp == NULL) {
509 return -1;
510 }
511
512 rv = StringListAppendString(list, tmp);
513
514 tmp = StringDestroy(tmp);
515
516 return rv;
517 }
518
519 int StringListAppendConcat(StringList* list, char const *text, int length, ...)
520 {
521 int ret;
522 va_list ap;
523 va_start(ap, length);
524 ret = StringListAppendVaConcat(list, text, length, ap);
525 va_end(ap);
526 return ret;
527 }
528
529 int StringListAppendArgv(StringList* list, int argc, char **argv)
530 {
531 String *tmp = NULL;
532 if (argc < 0) {
533 argc = 0;
534 while(*argv != NULL) ++argc;
535 }
536 while (--argc >= 0) {
537 if (StringListAppendConcat(list, *(argv++), -1, NULL) < 0) break;
538 }
539 if (tmp != NULL) {
540 tmp = StringDestroy(tmp);
541 }
542 if (argc >= 0) {
543 return -1;
544 }
545 return 0;
546 }
547
548 StringList* StringListFromArgv(int argc, char *argv[])
549 {
550 StringList *list = NULL;
551 list = StringListCreate(NULL, 0, 0);
552 if (list == NULL) {
553 return NULL;
554 }
555 if (StringListAppendArgv(list, argc, argv) < 0) {
556 list = StringListDestroy(list);
557 }
558
559 return list;
560 }
561
562 int StringListContains(StringList* list, char const *text, int length)
563 {
564 int i;
565 for(i = 0; i < list->size; i++) {
566 if (StringIsEqual(list->list[i], 0, text, length)) {
567 return 1;
568 }
569 }
570 return 0;
571 }
572
573 String* StringListJoin(StringList* list
574 , char const *start, int startLength
575 , char const *sep, int sepLength
576 , char const *end, int endLength)
577 {
578 Content *content = NULL;
579 String *result = NULL;
580 int i, err;
581 int length = 0;
582
583 if (start && startLength < 0) startLength += strlen(start);
584 if (sep && sepLength < 0) sepLength += strlen(sep);
585 if (end && endLength < 0) endLength += strlen(end);
586
587 if (start) length += startLength;
588
589 for(i = 0; i < list->size; i++) {
590 if (i > 0 && sep) length += sepLength;
591 length += StringGetLength(list->list[i]);
592 }
593
594 if (end) length += endLength;
595
596 do {
597 err = 1;
598
599 content = ContentCreate(length);
600 if (content == NULL) break;
601
602 if (start) if (ContentAppend(content, start, startLength) < 0) break;
603
604 for(i = 0; i < list->size; i++) {
605 if (i > 0 && sep) ContentAppend(content, sep, sepLength);
606 if (ContentAppend(content,
607 StringGetBuffer(list->list[i]), StringGetLength(list->list[i])
608 )) break;
609 }
610 if (i < list->size) break;
611
612 if (end) if (ContentAppend(content, end, endLength) < 0) break;
613
614 result = StringCreate(content);
615 if (result == NULL) break;
616
617 /* do not destroy content, is stored in string */
618 content = NULL;
619
620 err = 0;
621 } while(0);
622
623 if (err && result) result = StringDestroy(result);
624
625 if (content) content = ContentUnref(content);
626
627 return result;
628 }

Properties

Name Value
svn:executable

  ViewVC Help
Powered by ViewVC 1.1.20