Line data Source code
1 : /* 2 : * Copyright (c) 2005 Kungliga Tekniska Högskolan 3 : * (Royal Institute of Technology, Stockholm, Sweden). 4 : * All rights reserved. 5 : * 6 : * Redistribution and use in source and binary forms, with or without 7 : * modification, are permitted provided that the following conditions 8 : * are met: 9 : * 10 : * 1. Redistributions of source code must retain the above copyright 11 : * notice, this list of conditions and the following disclaimer. 12 : * 13 : * 2. Redistributions in binary form must reproduce the above copyright 14 : * notice, this list of conditions and the following disclaimer in the 15 : * documentation and/or other materials provided with the distribution. 16 : * 17 : * 3. Neither the name of the Institute nor the names of its contributors 18 : * may be used to endorse or promote products derived from this software 19 : * without specific prior written permission. 20 : * 21 : * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 22 : * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 : * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 : * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 25 : * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 : * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 : * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 : * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 : * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 : * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 : * SUCH DAMAGE. 32 : */ 33 : 34 : #include <config.h> 35 : 36 : #include <stdarg.h> 37 : #include <stdlib.h> 38 : #include "roken.h" 39 : 40 : struct rk_strpool { 41 : char *str; 42 : size_t len; /* strlen() of str */ 43 : size_t sz; /* Allocated size */ 44 : }; 45 : 46 : /* 47 : * 48 : */ 49 : 50 : ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL 51 0 : rk_strpoolfree(struct rk_strpool *p) 52 : { 53 0 : if (p && p->str) { 54 0 : free(p->str); 55 0 : p->str = NULL; 56 : } 57 0 : free(p); 58 0 : } 59 : 60 : /* 61 : * 62 : */ 63 : 64 : ROKEN_LIB_FUNCTION struct rk_strpool * ROKEN_LIB_CALL 65 2109418 : rk_strpoolprintf(struct rk_strpool *p, const char *fmt, ...) 66 : { 67 82172 : va_list ap; 68 82172 : char *str; 69 82172 : int len; 70 : 71 2109418 : va_start(ap, fmt); 72 2109418 : len = vasprintf(&str, fmt, ap); 73 2109418 : va_end(ap); 74 2109418 : if (str == NULL) 75 0 : return rk_strpoolfree(p), NULL; 76 : 77 2109418 : if (p == NULL) { 78 225614 : if ((p = malloc(sizeof(*p))) == NULL) 79 0 : return free(str), NULL; 80 225614 : p->str = str; 81 225614 : p->len = p->sz = len; 82 225614 : return p; 83 : } /* else grow the buffer and append `str', but don't grow too fast */ 84 : 85 1883804 : if (len + p->len + 1 > p->sz) { 86 615397 : size_t sz = p->len + len + 9 + (p->sz >> 2); 87 23706 : char *str2; 88 : 89 615397 : if ((str2 = realloc(p->str, sz)) == NULL) 90 0 : return rk_strpoolfree(p), NULL; 91 615397 : p->str = str2; 92 615397 : p->sz = sz; 93 : } 94 1883804 : memcpy(p->str + p->len, str, len + 1); 95 1883804 : p->len += len; 96 1883804 : free(str); 97 1883804 : return p; 98 : } 99 : 100 : /* 101 : * 102 : */ 103 : 104 : ROKEN_LIB_FUNCTION char * ROKEN_LIB_CALL 105 225614 : rk_strpoolcollect(struct rk_strpool *p) 106 : { 107 8196 : char *str; 108 225614 : if (p == NULL) 109 0 : return strdup(""); 110 225614 : str = p->str; 111 225614 : p->str = NULL; 112 225614 : free(p); 113 225614 : return str; 114 : }