#include <stdlib.h>
#if !defined(__linux__) /* for error */
#include <string.h>
#endif
#include <strings.h>
#include <sys/types.h>

#include <nllibc.h>

size_t strlen(const char *s)
{
  int len;
  for (len = 0; s[len]; len++)
    ;
  return len;
}

char *strcpy(char *dst, const char *src)
{
  int i;
  for (i = 0; src[i]; i++)
    dst[i] = src[i];
  dst[i] = '\0';
  return dst;
}

char *strncpy(char *dst, const char *src, size_t len)
{
  int i, over = 0;
  for (i = 0; i < len; i++) {
    if (over) {
      dst[i] = '\0';
    } else {
      dst[i] = src[i];
      if (src[i] == '\0')
	over = 1;
    }
  }
  return dst;
}

char *strcat(char *s, const char *append)
{
  strcpy(s + strlen(s), append);
  return s;
}

int strcmp(const char *s1, const char *s2)
{
  while (*s1 || *s2) {
    if ((*s1 < *s2) || (*s1 > *s2))
      return *s1 - *s2;
    s1++;
    s2++;
  }
  return 0;
}

int strncmp(const char *s1, const char *s2, size_t len)
{
  while (len-- > 0) {
    if ((*s1 < *s2) || (*s1 > *s2))
      return *s1 - *s2;
    s1++;
    s2++;
  }
  return 0;
}

char *strchr(const char *s, int c)
{
  while (1) {
    if (*s == c)
      break;
    if (*s == '\0') {
      s = NULL;
      break;
    }
    s++;
  }
  return (char *)s;
}

char *strrchr(const char *s, int c)
{
  const char *ss = s;
  s += strlen(s);
  while (1) {
    if (*s == c)
      break;
    if (s == ss) {
      s = NULL;
      break;
    }
    s--;
  }
  return (char *)s;
}

char *strdup(const char *str)
{
  char *s;
  s = malloc(strlen(str) + 1);
  if (s != NULL)
    strcpy(s, str);
  return s;
}

void *memset(void *dest, int c, size_t len)
{
  int i;
  char *s = dest;
  for (i = 0; i < len; i++)
    s[i] = c;
  return dest;
}

void *memcpy(void *dst, const void *src, size_t len)
{
  int i;
  char *d = dst;
  const char *s = src;
  for (i = 0; i < len; i++)
    d[i] = s[i];
  return dst;
}

void *memmove(void *dst, const void *src, size_t len)
{
  int i;
  char *d = dst;
  const char *s = src;
  if (d < s) {
    for (i = 0; i < len; i++)
      d[i] = s[i];
  } else {
    for (i = 0; i < len; i++)
      d[len - (i + 1)] = s[len - (i + 1)];
  }
  return dst;
}

int memcmp(const void *b1, const void *b2, size_t len)
{
  const char *s1 = b1, *s2 = b2;
  while (len-- > 0) {
    if ((*s1 < *s2) || (*s1 > *s2))
      return *s1 - *s2;
    s1++;
    s2++;
  }
  return 0;
}

void *memchr(const void *b, int c, size_t len)
{
  const unsigned char *s = b;
  while (len-- > 0) {
    if (*s == c)
      return (void *)s;
    s++;
  }
  return NULL;
}

int bcmp(const void *b1, const void *b2, size_t len)
{
  return memcmp(b1, b2, len);
}

void bcopy(const void *src, void *dst, size_t len)
{
  memcpy(dst, src, len);
}

void bzero(void *b, size_t len)
{
  memset(b, 0, len);
}
