Blame lib/common.c

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
 */