#include <assert.h>
#include <ctype.h>
#include <rules.h>
#include <string.h>
#include <stddef.h>
#include <stdlib.h>

char *strdup(const char *s)
{
	if (!ENV_RAMSTAGE)
		dead_code();	/* This can't be used without malloc(). */

	size_t sz = strlen(s) + 1;
	char *d = malloc(sz);
	if (d)
		memcpy(d, s, sz);
	return d;
}

char *strconcat(const char *s1, const char *s2)
{
	if (!ENV_RAMSTAGE)
		dead_code();	/* This can't be used without malloc(). */

	size_t sz_1 = strlen(s1);
	size_t sz_2 = strlen(s2);
	char *d = malloc(sz_1 + sz_2 + 1);
	if (d) {
		memcpy(d, s1, sz_1);
		memcpy(d + sz_1, s2, sz_2 + 1);
	}
	return d;
}

size_t strnlen(const char *src, size_t max)
{
	size_t i = 0;
	while ((*src++) && (i < max))
		i++;
	return i;
}

size_t strlen(const char *src)
{
	size_t i = 0;
	while (*src++)
		i++;
	return i;
}

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

	return NULL;
}

char *strrchr(const char *s, int c)
{
	char *p = NULL;

	do {
		if (*s == c)
			p = (char *)s;
	} while (*s++);

	return p;
}

char *strncpy(char *to, const char *from, int count)
{
	char *ret = to;
	char data;

	while (count > 0) {
		count--;
		data = *from++;
		*to++  = data;
		if (data == '\0')
			break;
	}

	while (count > 0) {
		count--;
		*to++ = '\0';
	}
	return ret;
}

char *strcpy(char *dst, const char *src)
{
	char *ptr = dst;

	while (*src)
		*dst++ = *src++;
	*dst = '\0';

	return ptr;
}

int strcmp(const char *s1, const char *s2)
{
	int r;

	while ((r = (*s1 - *s2)) == 0 && *s1) {
		s1++;
		s2++;
	}
	return r;
}

int strncmp(const char *s1, const char *s2, int maxlen)
{
	int i;

	for (i = 0; i < maxlen; i++) {
		if ((s1[i] != s2[i]) || (s1[i] == '\0'))
			return s1[i] - s2[i];
	}

	return 0;
}

unsigned int skip_atoi(char **s)
{
	unsigned int i = 0;

	while (isdigit(**s))
		i = i*10 + *((*s)++) - '0';
	return i;
}

int strspn(const char *str, const char *spn)
{
	int ret = 0;

	while (*str != 0) {
		const char *p;
		for (p = spn; *str != *p; p++)
			if (*p == '\0')
				return ret;
		ret++;
		str++;
	}
	return ret;
}

int strcspn(const char *str, const char *spn)
{
	int ret = 0;

	while (*str != 0) {
		const char *p;
		for (p = spn; *p != '\0'; p++)
			if (*p == *str)
				return ret;
		ret++;
		str++;
	}
	return ret;
}

char *strstr(const char *haystack, const char *needle)
{
	size_t needle_len = strlen(needle);
	for (; *haystack; haystack++) {
		if (!strncmp(haystack, needle, needle_len))
			return (char *)haystack;
	}
	return NULL;
}

char *strtok_r(char *str, const char *delim, char **ptr)
{
	char *start;
	char *end;

	if (str == NULL)
		str = *ptr;
	start = str + strspn(str, delim);
	if (start[0] == '\0')
		return NULL;

	end = start + strcspn(start, delim);
	*ptr = end;
	if (end[0] != '\0')
		*(*ptr)++ = '\0';
	return start;
}

char *strtok(char *str, const char *delim)
{
	static char *strtok_ptr;

	return strtok_r(str, delim, &strtok_ptr);
}

long atol(const char *str)
{
	long ret = 0;
	long sign = 1;

	str += strspn(str, " \t\n\r\f\v");

	if (*str == '+') {
		sign = 1;
		str++;
	} else if (*str == '-') {
		sign = -1;
		str++;
	}

	while (isdigit(*str)) {
		ret *= 10;
		ret += *str++ - '0';
	}
	return ret * sign;
}
