#include "args.h"

#include "config.h"
/*
 * Copyright (c) 1986, 2014 by The Trustees of Columbia University in
 * the City of New York.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 *  + Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 *  + Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 *  + Neither the name of Columbia University nor the names of its
 *    contributors may be used to endorse or promote products derived
 *    from this software without specific prior written permission.
 */

#ifndef lint
static const char *rcsid = "$Header: /usr/local/src/mm/mm-0.94/mm/RCS/support.c,v 1.1 2005/05/28 22:27:54 beebe Exp $";
#endif

#include "mm.h"
#include "keytab.h"

/*
 * safe_strcat:
 * do a strcat, but malloc up the required space first.
 * possibly put a space in before the string, depending on context.
 * Note: returns dest if src is NULL.
 */


char *
#if HAVE_STDC
safe_strcat(char *dest, const char *src, int usespace)
#else /* K&R style */
safe_strcat(dest,src,usespace)
char *dest;
const char *src;
int usespace;
#endif /* HAVE_STDC */
{
    int space=FALSE;
    char c1,c2;


    if (src == NULL)
        return (dest);
    if (dest) {
	if (usespace) {
	    c1 = dest[strlen(dest)-1];
	    c2 = src[0];
	    if (isalnum(c1))
		space = TRUE;
	    if (c2 == '@' || c2 == '>' || c2 == ')')
		space = FALSE;
	    if (c1 == '>' || c1 == ')' || c1 == '\"')
		space = TRUE;
	}
	dest = (char*)realloc(dest,strlen(dest)+strlen(src)+1+(space?1:0));
	if (dest == nil) {
	    cmxprintf("?Out of memory");
	    ccmd_errnp(CMxOK);
	}
	if (space)
	    strcat(dest," ");
	strcat(dest,src);
    }
    else {
	dest = (char*)malloc(strlen(src)+1);
	if (dest == nil) {
	    cmxprintf("?Out of memory");
	    ccmd_errnp(CMxOK);
	}
	strcpy(dest,src);
    }
    return(dest);
}



void *
#if HAVE_STDC
safe_realloc(void *cp, int size)
#else /* K&R style */
safe_realloc(cp, size)
void *cp;
int size;
#endif /* HAVE_STDC */
{
    if (cp)
	return((void*)realloc(cp,size));
    else
	return((void*)malloc(size));
}


/*
 * safe_strcpy:
 * copy str into a newly malloc'ed buffer
 * Note: when str is NULL, returns NULL
 */

char *
#if HAVE_STDC
safe_strcpy(const char *str)
#else /* K&R style */
safe_strcpy(str)
const char *str;
#endif /* HAVE_STDC */
{
    char *x;

    if (str == NULL)
        return (NULL);
    x = (char*)malloc(strlen(str)+1);
    if (!x)
	panic ("Out of memory");
    strcpy(x,str);
    return(x);
}



#define min(x,y) (((x) < (y)) ? (x) : (y))


/*
 * safe_strncat:
 * Note: returns dest if src is NULL
 */

char *
#if HAVE_STDC
safe_strncat(char *dest, const char *src, int n)
#else /* K&R style */
safe_strncat(dest,src,n)
char *dest;
const char *src;
int n;
#endif /* HAVE_STDC */
{
    char *x;
    int srclen, destlen;

    if (src == NULL)
        return(dest);
    srclen = min((int)strlen(src),n);

    if (dest)
	destlen = (int)strlen(dest);
    else
	destlen = 0;

    if (dest)
	x = (char*)realloc(dest,srclen + destlen + 1);
    else
	x = (char*)malloc(srclen + 1);
    if (!x)
	panic ("Out of memory");
    strncat(x,src,srclen);
    return(x);
}

void *
#if HAVE_STDC
safe_free(void *str)
#else /* K&R style */
safe_free(str)
void *str;
#endif /* HAVE_STDC */
{
    if (str)
	free(str);
    return ((void *)NULL);
}
