diff options
Diffstat (limited to 'contrib/syslinux-4.02/com32/menu/refstr.c')
-rw-r--r-- | contrib/syslinux-4.02/com32/menu/refstr.c | 105 |
1 files changed, 105 insertions, 0 deletions
diff --git a/contrib/syslinux-4.02/com32/menu/refstr.c b/contrib/syslinux-4.02/com32/menu/refstr.c new file mode 100644 index 0000000..97ab1ed --- /dev/null +++ b/contrib/syslinux-4.02/com32/menu/refstr.c @@ -0,0 +1,105 @@ +/* ----------------------------------------------------------------------- * + * + * Copyright 2008 H. Peter Anvin - All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston MA 02110-1301, USA; either version 2 of the License, or + * (at your option) any later version; incorporated herein by reference. + * + * ----------------------------------------------------------------------- */ + +/* + * refstr.c + * + * Simple reference-counted strings + */ + +#include <stdlib.h> +#include <string.h> +#include <stdio.h> +#include "refstr.h" + +/* Allocate space for a refstring of len bytes, plus final null */ +/* The final null is inserted in the string; the rest is uninitialized. */ +char *refstr_alloc(size_t len) +{ + char *r = malloc(sizeof(unsigned int) + len + 1); + if (!r) + return NULL; + *(unsigned int *)r = 1; + r += sizeof(unsigned int); + r[len] = '\0'; + return r; +} + +const char *refstrndup(const char *str, size_t len) +{ + char *r; + + if (!str) + return NULL; + + len = strnlen(str, len); + r = refstr_alloc(len); + if (r) + memcpy(r, str, len); + return r; +} + +const char *refstrdup(const char *str) +{ + char *r; + size_t len; + + if (!str) + return NULL; + + len = strlen(str); + r = refstr_alloc(len); + if (r) + memcpy(r, str, len); + return r; +} + +int vrsprintf(const char **bufp, const char *fmt, va_list ap) +{ + va_list ap1; + int len; + char *p; + + va_copy(ap1, ap); + len = vsnprintf(NULL, 0, fmt, ap1); + va_end(ap1); + + *bufp = p = refstr_alloc(len); + if (!p) + return -1; + + return vsnprintf(p, len + 1, fmt, ap); +} + +int rsprintf(const char **bufp, const char *fmt, ...) +{ + int rv; + va_list ap; + + va_start(ap, fmt); + rv = vrsprintf(bufp, fmt, ap); + va_end(ap); + + return rv; +} + +void refstr_put(const char *r) +{ + unsigned int *ref; + + if (r) { + ref = (unsigned int *)r - 1; + + if (!--*ref) + free(ref); + } +} |