155682Smarkm/*
2233294Sstas * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska H��gskolan
355682Smarkm * (Royal Institute of Technology, Stockholm, Sweden).
455682Smarkm * All rights reserved.
5233294Sstas *
655682Smarkm * Redistribution and use in source and binary forms, with or without
755682Smarkm * modification, are permitted provided that the following conditions
855682Smarkm * are met:
9233294Sstas *
1055682Smarkm * 1. Redistributions of source code must retain the above copyright
1155682Smarkm *    notice, this list of conditions and the following disclaimer.
12233294Sstas *
1355682Smarkm * 2. Redistributions in binary form must reproduce the above copyright
1455682Smarkm *    notice, this list of conditions and the following disclaimer in the
1555682Smarkm *    documentation and/or other materials provided with the distribution.
16233294Sstas *
1755682Smarkm * 3. Neither the name of the Institute nor the names of its contributors
1855682Smarkm *    may be used to endorse or promote products derived from this software
1955682Smarkm *    without specific prior written permission.
20233294Sstas *
2155682Smarkm * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
2255682Smarkm * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2355682Smarkm * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2455682Smarkm * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
2555682Smarkm * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2655682Smarkm * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2755682Smarkm * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2855682Smarkm * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2955682Smarkm * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
3055682Smarkm * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3155682Smarkm * SUCH DAMAGE.
3255682Smarkm */
3355682Smarkm
3455682Smarkm#include <config.h>
35233294Sstas
3655682Smarkm#include "roken.h"
3755682Smarkm
38233294SstasROKEN_LIB_FUNCTION int ROKEN_LIB_CALL
3955682Smarkmroken_concat (char *s, size_t len, ...)
4055682Smarkm{
4155682Smarkm    int ret;
4255682Smarkm    va_list args;
4355682Smarkm
4455682Smarkm    va_start(args, len);
4555682Smarkm    ret = roken_vconcat (s, len, args);
4655682Smarkm    va_end(args);
4755682Smarkm    return ret;
4855682Smarkm}
4955682Smarkm
50233294SstasROKEN_LIB_FUNCTION int ROKEN_LIB_CALL
5155682Smarkmroken_vconcat (char *s, size_t len, va_list args)
5255682Smarkm{
5355682Smarkm    const char *a;
5455682Smarkm
5555682Smarkm    while ((a = va_arg(args, const char*))) {
5655682Smarkm	size_t n = strlen (a);
5755682Smarkm
5855682Smarkm	if (n >= len)
5955682Smarkm	    return -1;
6055682Smarkm	memcpy (s, a, n);
6155682Smarkm	s += n;
6255682Smarkm	len -= n;
6355682Smarkm    }
6455682Smarkm    *s = '\0';
6555682Smarkm    return 0;
6655682Smarkm}
6755682Smarkm
68233294SstasROKEN_LIB_FUNCTION size_t ROKEN_LIB_CALL
6955682Smarkmroken_vmconcat (char **s, size_t max_len, va_list args)
7055682Smarkm{
7155682Smarkm    const char *a;
7255682Smarkm    char *p, *q;
7355682Smarkm    size_t len = 0;
7455682Smarkm    *s = NULL;
7555682Smarkm    p = malloc(1);
7655682Smarkm    if(p == NULL)
7755682Smarkm	return 0;
7855682Smarkm    len = 1;
7955682Smarkm    while ((a = va_arg(args, const char*))) {
8055682Smarkm	size_t n = strlen (a);
81233294Sstas
8255682Smarkm	if(max_len && len + n > max_len){
8355682Smarkm	    free(p);
8455682Smarkm	    return 0;
8555682Smarkm	}
8655682Smarkm	q = realloc(p, len + n);
8755682Smarkm	if(q == NULL){
8855682Smarkm	    free(p);
8955682Smarkm	    return 0;
9055682Smarkm	}
9155682Smarkm	p = q;
9255682Smarkm	memcpy (p + len - 1, a, n);
9355682Smarkm	len += n;
9455682Smarkm    }
9555682Smarkm    p[len - 1] = '\0';
9655682Smarkm    *s = p;
9755682Smarkm    return len;
9855682Smarkm}
9955682Smarkm
100233294SstasROKEN_LIB_FUNCTION size_t ROKEN_LIB_CALL
10155682Smarkmroken_mconcat (char **s, size_t max_len, ...)
10255682Smarkm{
103233294Sstas    size_t ret;
10455682Smarkm    va_list args;
10555682Smarkm
10655682Smarkm    va_start(args, max_len);
10755682Smarkm    ret = roken_vmconcat (s, max_len, args);
10855682Smarkm    va_end(args);
10955682Smarkm    return ret;
11055682Smarkm}
111