/*
 * libc string functions
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Library General Public License version 2.
 */

#include "libcflat.h"
#include "ctype.h"
#include "stdlib.h"
#include "linux/compiler.h"

size_t strlen(const char *buf)
{
	size_t len = 0;

	while (*buf++)
		++len;
	return len;
}

size_t strnlen(const char *buf, size_t maxlen)
{
	const char *sc;

	for (sc = buf; maxlen-- && *sc != '\0'; ++sc)
		/* nothing */ ;
	return sc - buf;
}

char *strcat(char *dest, const char *src)
{
	char *p = dest;

	while (*p)
		++p;
	while ((*p++ = *src++) != 0)
		;
	return dest;
}

char *strcpy(char *dest, const char *src)
{
	*dest = 0;
	return strcat(dest, src);
}

int strncmp(const char *a, const char *b, size_t n)
{
	for (; n--; ++a, ++b)
		if (*a != *b || *a == '\0')
			return *a - *b;

	return 0;
}

int strncasecmp(const char *a, const char *b, size_t n)
{
	for (; n--; ++a, ++b)
		if (tolower(*a) != tolower(*b) || *a == '\0')
			return tolower(*a) - tolower(*b);

	return 0;
}

int strcmp(const char *a, const char *b)
{
	return strncmp(a, b, SIZE_MAX);
}

int strcasecmp(const char *a, const char *b)
{
	return strncasecmp(a, b, SIZE_MAX);
}

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

char *strrchr(const char *s, int c)
{
	const char *last = NULL;
	do {
		if (*s == (char)c)
			last = s;
	} while (*s++);
	return (char *)last;
}

char *strchrnul(const char *s, int c)
{
	while (*s && *s != (char)c)
		s++;
	return (char *)s;
}

char *strstr(const char *s1, const char *s2)
{
	size_t l1, l2;

	l2 = strlen(s2);
	if (!l2)
		return (char *)s1;
	l1 = strlen(s1);
	while (l1 >= l2) {
		l1--;
		if (!memcmp(s1, s2, l2))
			return (char *)s1;
		s1++;
	}
	return NULL;
}

void *memset(void *s, int c, size_t n)
{
	size_t i;
	char *a = s;

	for (i = 0; i < n; ++i)
		a[i] = c;

	return s;
}

void *memcpy(void *dest, const void *src, size_t n)
{
	size_t i;
	char *a = dest;
	const char *b = src;

	for (i = 0; i < n; ++i)
		a[i] = b[i];

	return dest;
}

int memcmp(const void *s1, const void *s2, size_t n)
{
	const unsigned char *a = s1, *b = s2;
	int ret = 0;

	while (n--) {
		ret = *a - *b;
		if (ret)
			break;
		++a, ++b;
	}
	return ret;
}

void *memmove(void *dest, const void *src, size_t n)
{
	const unsigned char *s = src;
	unsigned char *d = dest;

	if (d <= s) {
		while (n--)
			*d++ = *s++;
	} else {
		d += n, s += n;
		while (n--)
			*--d = *--s;
	}
	return dest;
}

void *memchr(const void *s, int c, size_t n)
{
	const unsigned char *str = s, chr = (unsigned char)c;

	while (n--)
		if (*str++ == chr)
			return (void *)(str - 1);
	return NULL;
}

static unsigned long long __strtoll(const char *nptr, char **endptr,
				    int base, bool is_signed, bool is_longlong)
{
	unsigned long long ull = 0;
	const char *s = nptr;
	int neg, c;

	assert(base == 0 || (base >= 2 && base <= 36));

	while (isspace(*s))
		s++;

	if (*s == '-') {
		neg = 1;
		s++;
	} else {
		neg = 0;
		if (*s == '+')
			s++;
	}

	if (base == 0 || base == 16) {
		if (*s == '0') {
			s++;
			if (*s == 'x' || *s == 'X') {
				s++;
				base = 16;
			} else if (base == 0)
				base = 8;
		} else if (base == 0)
			base = 10;
	}

	while (*s) {
		if (*s >= '0' && *s < '0' + base && *s <= '9')
			c = *s - '0';
		else if (*s >= 'a' && *s < 'a' + base - 10)
			c = *s - 'a' + 10;
		else if (*s >= 'A' && *s < 'A' + base - 10)
			c = *s - 'A' + 10;
		else
			break;

		if (!is_longlong) {
			if (is_signed) {
				long sl = (long)ull;
				assert(!check_mul_overflow(sl, base));
				assert(!check_add_overflow(sl * base, c));
			} else {
				unsigned long ul = (unsigned long)ull;
				assert(!check_mul_overflow(ul, base));
				assert(!check_add_overflow(ul * base, c));
			}
		} else {
			if (is_signed) {
				long long sll = (long long)ull;
				assert(!check_mul_overflow(sll, base));
				assert(!check_add_overflow(sll * base, c));
			} else {
				assert(!check_mul_overflow(ull, base));
				assert(!check_add_overflow(ull * base, c));
			}
		}

		ull = ull * base + c;
		s++;
	}

	if (neg)
		ull = -ull;

	if (endptr)
		*endptr = (char *)s;

	return ull;
}

long int strtol(const char *nptr, char **endptr, int base)
{
	return __strtoll(nptr, endptr, base, true, false);
}

unsigned long int strtoul(const char *nptr, char **endptr, int base)
{
	return __strtoll(nptr, endptr, base, false, false);
}

long long int strtoll(const char *nptr, char **endptr, int base)
{
	return __strtoll(nptr, endptr, base, true, true);
}

unsigned long long int strtoull(const char *nptr, char **endptr, int base)
{
	return __strtoll(nptr, endptr, base, false, true);
}

long atol(const char *ptr)
{
	return strtol(ptr, NULL, 10);
}

extern char **environ;

char *getenv(const char *name)
{
	char **envp = environ, *delim;
	int len;

	while (*envp) {
		delim = strchr(*envp, '=');
		assert(delim);
		len = delim - *envp;
		if (memcmp(name, *envp, len) == 0 && !name[len])
			return delim + 1;
		++envp;
	}
	return NULL;
}

/* Very simple glob matching. Allows '*' at beginning and end of pattern. */
bool simple_glob(const char *text, const char *pattern)
{
	bool star_start = false;
	bool star_end = false;
	size_t n = strlen(pattern);
	char copy[n + 1];

	if (pattern[0] == '*') {
		pattern += 1;
		n -= 1;
		star_start = true;
	}

	strcpy(copy, pattern);

	if (n > 0 && pattern[n - 1] == '*') {
		n -= 1;
		copy[n] = '\0';
		star_end = true;
	}

	if (star_start && star_end)
		return strstr(text, copy);

	if (star_end)
		return strstr(text, copy) == text;

	if (star_start) {
		size_t text_len = strlen(text);
		const char *suffix;

		if (n > text_len)
			return false;
		suffix = text + text_len - n;
		return !strcmp(suffix, copy);
	}

	return !strcmp(text, copy);
}
