|
Packit |
57a33d |
/*
|
|
Packit |
57a33d |
memory and string operations and some more common stuff
|
|
Packit |
57a33d |
|
|
Packit |
57a33d |
Copyright (C) 2000-2002 David Necas (Yeti) <yeti@physics.muni.cz>
|
|
Packit |
57a33d |
|
|
Packit |
57a33d |
This program is free software; you can redistribute it and/or modify it
|
|
Packit |
57a33d |
under the terms of version 2 of the GNU General Public License as published
|
|
Packit |
57a33d |
by the Free Software Foundation.
|
|
Packit |
57a33d |
|
|
Packit |
57a33d |
This program is distributed in the hope that it will be useful, but WITHOUT
|
|
Packit |
57a33d |
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
Packit |
57a33d |
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
|
Packit |
57a33d |
more details.
|
|
Packit |
57a33d |
|
|
Packit |
57a33d |
You should have received a copy of the GNU General Public License along
|
|
Packit |
57a33d |
with this program; if not, write to the Free Software Foundation, Inc.,
|
|
Packit |
57a33d |
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
|
|
Packit |
57a33d |
*/
|
|
Packit |
57a33d |
#ifdef HAVE_CONFIG_H
|
|
Packit |
57a33d |
# include "config.h"
|
|
Packit |
57a33d |
#endif /* HAVE_CONFIG_H */
|
|
Packit |
57a33d |
|
|
Packit |
57a33d |
#include <stdarg.h>
|
|
Packit |
57a33d |
|
|
Packit |
57a33d |
#include "enca.h"
|
|
Packit |
57a33d |
#include "internal.h"
|
|
Packit |
57a33d |
|
|
Packit |
57a33d |
/**
|
|
Packit |
57a33d |
* enca_malloc:
|
|
Packit |
57a33d |
* @size: The number of bytes to allocate.
|
|
Packit |
57a33d |
*
|
|
Packit |
57a33d |
* Allocates memory, always successfully (when fails, aborts program).
|
|
Packit |
57a33d |
*
|
|
Packit |
57a33d |
* Returns: Pointer to the newly allocated memory.
|
|
Packit |
57a33d |
**/
|
|
Packit |
57a33d |
void*
|
|
Packit |
57a33d |
enca_malloc(size_t size)
|
|
Packit |
57a33d |
{
|
|
Packit |
57a33d |
void *ptr;
|
|
Packit |
57a33d |
|
|
Packit |
57a33d |
if (size == 0)
|
|
Packit |
57a33d |
size = 1;
|
|
Packit |
57a33d |
ptr = malloc(size);
|
|
Packit |
57a33d |
assert(ptr != NULL);
|
|
Packit |
57a33d |
|
|
Packit |
57a33d |
return ptr;
|
|
Packit |
57a33d |
}
|
|
Packit |
57a33d |
|
|
Packit |
57a33d |
/**
|
|
Packit |
57a33d |
* enca_realloc:
|
|
Packit |
57a33d |
* @ptr: Pointer to block of previously allocated memory.
|
|
Packit |
57a33d |
* @size: The number of bytes to resize the block.
|
|
Packit |
57a33d |
*
|
|
Packit |
57a33d |
* Reallocates memory, always successfully (when fails, aborts program).
|
|
Packit |
57a33d |
*
|
|
Packit |
57a33d |
* Returns: Pointer to the newly allocated memory, #NULL when @size is zero.
|
|
Packit |
57a33d |
**/
|
|
Packit |
57a33d |
void*
|
|
Packit |
57a33d |
enca_realloc(void *ptr, size_t size)
|
|
Packit |
57a33d |
{
|
|
Packit |
57a33d |
if (size == 0) {
|
|
Packit |
57a33d |
free(ptr);
|
|
Packit |
57a33d |
return NULL;
|
|
Packit |
57a33d |
}
|
|
Packit |
57a33d |
|
|
Packit |
57a33d |
ptr = realloc(ptr, size);
|
|
Packit |
57a33d |
assert(ptr != NULL);
|
|
Packit |
57a33d |
|
|
Packit |
57a33d |
return ptr;
|
|
Packit |
57a33d |
}
|
|
Packit |
57a33d |
|
|
Packit |
57a33d |
/**
|
|
Packit |
57a33d |
* enca_strdup:
|
|
Packit |
57a33d |
* @s: A string.
|
|
Packit |
57a33d |
*
|
|
Packit |
57a33d |
* Duplicates string.
|
|
Packit |
57a33d |
*
|
|
Packit |
57a33d |
* Will be defined as strdup() when system provides it.
|
|
Packit |
57a33d |
*
|
|
Packit |
57a33d |
* Returns: The newly allocated string copy.
|
|
Packit |
57a33d |
**/
|
|
Packit |
57a33d |
char*
|
|
Packit |
57a33d |
enca_strdup(const char *s) {
|
|
Packit |
57a33d |
if (s == NULL)
|
|
Packit |
57a33d |
return NULL;
|
|
Packit |
57a33d |
else
|
|
Packit |
57a33d |
return strcpy(enca_malloc(strlen(s) + 1), s);
|
|
Packit |
57a33d |
}
|
|
Packit |
57a33d |
|
|
Packit |
57a33d |
#ifndef HAVE_STRSTR
|
|
Packit |
57a33d |
/**
|
|
Packit |
57a33d |
* enca_strstr:
|
|
Packit |
57a33d |
* @haystack: A string where to search.
|
|
Packit |
57a33d |
* @needle: A string to find.
|
|
Packit |
57a33d |
*
|
|
Packit |
57a33d |
* Finds occurence of a substring in a string.
|
|
Packit |
57a33d |
*
|
|
Packit |
57a33d |
* Will be defined as strstr() when system provides it.
|
|
Packit |
57a33d |
*
|
|
Packit |
57a33d |
* Returns: Pointer to the first occurence of @needle in @haystack; #NULL if
|
|
Packit |
57a33d |
* not found.
|
|
Packit |
57a33d |
**/
|
|
Packit |
57a33d |
const char*
|
|
Packit |
57a33d |
enca_strstr(const char *haystack,
|
|
Packit |
57a33d |
const char *needle)
|
|
Packit |
57a33d |
{
|
|
Packit |
57a33d |
char c;
|
|
Packit |
57a33d |
size_t n;
|
|
Packit |
57a33d |
|
|
Packit |
57a33d |
/* handle singularities */
|
|
Packit |
57a33d |
if (needle == NULL)
|
|
Packit |
57a33d |
return haystack;
|
|
Packit |
57a33d |
if ((n = strlen(needle)) == 0)
|
|
Packit |
57a33d |
return haystack;
|
|
Packit |
57a33d |
|
|
Packit |
57a33d |
/* search */
|
|
Packit |
57a33d |
c = needle[0];
|
|
Packit |
57a33d |
while ((haystack = strchr(haystack, c)) != NULL) {
|
|
Packit |
57a33d |
if (strncmp(haystack, needle, n) == 0)
|
|
Packit |
57a33d |
return haystack;
|
|
Packit |
57a33d |
}
|
|
Packit |
57a33d |
|
|
Packit |
57a33d |
return NULL;
|
|
Packit |
57a33d |
}
|
|
Packit |
57a33d |
#endif
|
|
Packit |
57a33d |
|
|
Packit |
57a33d |
#ifndef HAVE_STPCPY
|
|
Packit |
57a33d |
/**
|
|
Packit |
57a33d |
* enca_stpcpy:
|
|
Packit |
57a33d |
* @dest: A string.
|
|
Packit |
57a33d |
* @src: A string to append.
|
|
Packit |
57a33d |
*
|
|
Packit |
57a33d |
* Appends a string to the end of another strings, returning pointer to
|
|
Packit |
57a33d |
* the terminating zero byte.
|
|
Packit |
57a33d |
*
|
|
Packit |
57a33d |
* Will be defined as stpcpy() when system provides it.
|
|
Packit |
57a33d |
*
|
|
Packit |
57a33d |
* Caller is responisble for providing @dest long enough to hold the result.
|
|
Packit |
57a33d |
*
|
|
Packit |
57a33d |
* Returns: Pointer to the terminating zero byte of resulting string.
|
|
Packit |
57a33d |
**/
|
|
Packit |
57a33d |
char*
|
|
Packit |
57a33d |
enca_stpcpy(char *dest,
|
|
Packit |
57a33d |
const char *src)
|
|
Packit |
57a33d |
{
|
|
Packit |
57a33d |
const char *p = src;
|
|
Packit |
57a33d |
|
|
Packit |
57a33d |
if (src == NULL)
|
|
Packit |
57a33d |
return dest;
|
|
Packit |
57a33d |
|
|
Packit |
57a33d |
while (*p != '\0')
|
|
Packit |
57a33d |
*dest++ = *p++;
|
|
Packit |
57a33d |
|
|
Packit |
57a33d |
*dest = '\0';
|
|
Packit |
57a33d |
return dest;
|
|
Packit |
57a33d |
}
|
|
Packit |
57a33d |
#endif
|
|
Packit |
57a33d |
|
|
Packit |
57a33d |
/**
|
|
Packit |
57a33d |
* enca_strconcat:
|
|
Packit |
57a33d |
* @str: A string.
|
|
Packit |
57a33d |
* @...: A #NULL-terminated list of string to append.
|
|
Packit |
57a33d |
*
|
|
Packit |
57a33d |
* Concatenates arbitrary (but at least one) number of strings.
|
|
Packit |
57a33d |
*
|
|
Packit |
57a33d |
* Returns: All the strings concatenated together.
|
|
Packit |
57a33d |
**/
|
|
Packit |
57a33d |
char*
|
|
Packit |
57a33d |
enca_strconcat(const char *str,
|
|
Packit |
57a33d |
...)
|
|
Packit |
57a33d |
{
|
|
Packit |
57a33d |
va_list ap;
|
|
Packit |
57a33d |
char *result = NULL;
|
|
Packit |
57a33d |
size_t n;
|
|
Packit |
57a33d |
const char *s;
|
|
Packit |
57a33d |
char *r;
|
|
Packit |
57a33d |
|
|
Packit |
57a33d |
/* compute size of resulting string */
|
|
Packit |
57a33d |
n = 1;
|
|
Packit |
57a33d |
va_start(ap, str);
|
|
Packit |
57a33d |
for (s = str; s != NULL; s = va_arg(ap, const char*))
|
|
Packit |
57a33d |
n += strlen(s);
|
|
Packit |
57a33d |
va_end(ap);
|
|
Packit |
57a33d |
|
|
Packit |
57a33d |
/* and construct it using the smart stpcpy() function */
|
|
Packit |
57a33d |
r = result = (char*)enca_malloc(n);
|
|
Packit |
57a33d |
va_start(ap, str);
|
|
Packit |
57a33d |
for (s = str; s != NULL; s = va_arg(ap, const char*))
|
|
Packit |
57a33d |
r = enca_stpcpy(r, s);
|
|
Packit |
57a33d |
va_end(ap);
|
|
Packit |
57a33d |
|
|
Packit |
57a33d |
return result;
|
|
Packit |
57a33d |
}
|
|
Packit |
57a33d |
|
|
Packit |
57a33d |
/**
|
|
Packit |
57a33d |
* enca_strappend:
|
|
Packit |
57a33d |
* @str: A string.
|
|
Packit |
57a33d |
* @...: A #NULL-terminated list of string to append.
|
|
Packit |
57a33d |
*
|
|
Packit |
57a33d |
* Appends arbitrary number of strings to a string.
|
|
Packit |
57a33d |
*
|
|
Packit |
57a33d |
* The string @str is destroyed (reallocated), the others are kept.
|
|
Packit |
57a33d |
*
|
|
Packit |
57a33d |
* Returns: All the strings concatenated together.
|
|
Packit |
57a33d |
**/
|
|
Packit |
57a33d |
char*
|
|
Packit |
57a33d |
enca_strappend(char *str,
|
|
Packit |
57a33d |
...)
|
|
Packit |
57a33d |
{
|
|
Packit |
57a33d |
va_list ap;
|
|
Packit |
57a33d |
size_t n, n1;
|
|
Packit |
57a33d |
const char *s;
|
|
Packit |
57a33d |
char *r;
|
|
Packit |
57a33d |
|
|
Packit |
57a33d |
/* compute size of resulting string */
|
|
Packit |
57a33d |
n1 = strlen(str);
|
|
Packit |
57a33d |
n = 1 + n1;
|
|
Packit |
57a33d |
va_start(ap, str);
|
|
Packit |
57a33d |
for (s = va_arg(ap, const char*); s != NULL; s = va_arg(ap, const char*))
|
|
Packit |
57a33d |
n += strlen(s);
|
|
Packit |
57a33d |
va_end(ap);
|
|
Packit |
57a33d |
|
|
Packit |
57a33d |
/* and construct it using the smart stpcpy() function */
|
|
Packit |
57a33d |
str = (char*)enca_realloc(str, n);
|
|
Packit |
57a33d |
r = str + n1;
|
|
Packit |
57a33d |
va_start(ap, str);
|
|
Packit |
57a33d |
for (s = va_arg(ap, const char*); s != NULL; s = va_arg(ap, const char*))
|
|
Packit |
57a33d |
r = enca_stpcpy(r, s);
|
|
Packit |
57a33d |
va_end(ap);
|
|
Packit |
57a33d |
|
|
Packit |
57a33d |
return str;
|
|
Packit |
57a33d |
}
|
|
Packit |
57a33d |
|
|
Packit |
57a33d |
/* vim: ts=2
|
|
Packit |
57a33d |
*/
|