/*
elmo - ELectronic Mail Operator
Copyright (C) 2003 rzyjontko
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; version 2.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
----------------------------------------------------------------------
resizable strings
*/
/****************************************************************************
* IMPLEMENTATION HEADERS
****************************************************************************/
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#include "str.h"
#include "xmalloc.h"
/****************************************************************************
* IMPLEMENTATION PRIVATE DEFINITIONS / ENUMERATIONS / SIMPLE TYPEDEFS
****************************************************************************/
#define INITIAL_SIZE 64
#define PREAMBLE do { if (str == NULL) return; } while (0)
/****************************************************************************
* IMPLEMENTATION PRIVATE CLASS PROTOTYPES / EXTERNAL CLASS REFERENCES
****************************************************************************/
/****************************************************************************
* IMPLEMENTATION PRIVATE STRUCTURES / UTILITY CLASSES
****************************************************************************/
/****************************************************************************
* IMPLEMENTATION REQUIRED EXTERNAL REFERENCES (AVOID)
****************************************************************************/
/****************************************************************************
* IMPLEMENTATION PRIVATE DATA
****************************************************************************/
/****************************************************************************
* INTERFACE DATA
****************************************************************************/
/****************************************************************************
* IMPLEMENTATION PRIVATE FUNCTION PROTOTYPES
****************************************************************************/
/****************************************************************************
* IMPLEMENTATION PRIVATE FUNCTIONS
****************************************************************************/
/****************************************************************************
* INTERFACE FUNCTIONS
****************************************************************************/
str_t *
str_create_size (int size)
{
str_t *result = xmalloc (sizeof (str_t));
result->len = 0;
result->size = size;
result->str = xmalloc (size + 1);
*result->str = '\0';
return result;
}
str_t *
str_create (void)
{
return str_create_size (INITIAL_SIZE);
}
str_t *
str_dup (const char *str)
{
int len;
str_t *result;
if (str == NULL)
return NULL;
len = strlen (str);
result = str_create_size (len);
str_put_string_len (result, str, len);
return result;
}
str_t *
str_from_str (char *s, int len)
{
str_t *result = xmalloc (sizeof (str_t));
result->len = len;
result->size = len;
result->str = s;
return result;
}
void
str_destroy (str_t *str)
{
PREAMBLE;
if (str->str)
xfree (str->str);
xfree (str);
}
void
str_clear (str_t *str)
{
PREAMBLE;
str->len = 0;
*str->str = '\0';
}
char *
str_finished (str_t *str)
{
char *result;
if (str == NULL)
return NULL;
result = xrealloc (str->str, str->len + 1);
xfree (str);
return result;
}
void
str_put_nchar (str_t *str, int c, int n)
{
PREAMBLE;
if (str->len + n > str->size - 1){
str->size = (str->size + n) * 2;
str->str = xrealloc (str->str, str->size + 1);
}
memset (str->str + str->len, c, n);
str->str[str->len + n] = '\0';
str->len += n;
}
void
str_put_char (str_t *str, int c)
{
str_put_nchar (str, c, 1);
}
void
str_put_string_len (str_t *str, const char *s, int len)
{
PREAMBLE;
if (str->len + len > str->size - 1){
str->size = (str->size + len) * 2;
str->str = xrealloc (str->str, str->size + 1);
}
memcpy (str->str + str->len, s, len);
str->str[str->len + len] = '\0';
str->len += len;
}
void
str_put_string (str_t *str, const char *s)
{
int len;
if (s == NULL)
return;
len = strlen (s);
str_put_string_len (str, s, len);
}
int
str_vsprintf (str_t *str, const char *fmt, va_list ap)
{
int n;
int max_size;
va_list copy;
if (str == NULL || fmt == NULL)
return -1;
while (1){
max_size = str->size - str->len - 1;
#if (defined(__FreeBSD__) && __FreeBSD__ < 5)
copy = ap;
#else
va_copy (copy, ap);
#endif
n = vsnprintf (str->str + str->len, max_size, fmt, copy);
if (n > -1 && n < max_size){
str->len += n;
return n;
}
if (n > -1)
while (max_size < n + 1){
str->size *= 2;
max_size = str->size - str->len;
}
else {
str->size *= 2;
}
str->str = xrealloc (str->str, str->size + 1);
}
}
int
str_sprintf (str_t *str, const char *fmt, ...)
{
int ret;
va_list ap;
va_start (ap, fmt);
ret = str_vsprintf (str, fmt, ap);
va_end (ap);
return ret;
}
void
str_chop (str_t *str)
{
int len = str->len;
if (len == 0)
return;
str->str[len - 1] = '\0';
str->len--;
}
/****************************************************************************
* INTERFACE CLASS BODIES
****************************************************************************/
/****************************************************************************
*
* END MODULE str.c
*
****************************************************************************/
syntax highlighted by Code2HTML, v. 0.9.1