#ifndef STRING_HANDLING_H
#define STRING_HANDLING_H

#include <stdint.h> /* SIZE_MAX */

#ifndef __has_attribute
#define __has_attribute(x) 0
#endif

#if defined(__OpenBSD__) && __has_attribute(bounded)
#define BOUNDED_STR(buf,len) __attribute__((__bounded__(__string__,buf,len)))
#define BOUNDED_WSTR(buf,len) __attribute__((__bounded__(__wcstring__,buf,len)))
#else
#define BOUNDED_STR(buf,len)
#define BOUNDED_WSTR(buf,len)
#endif

/*lint -sem(strColor, pure) */
/*lint -sem(strcasestr, r_null) */
/*lint -printf(3, sw_snprintf) */

__SWIRC_BEGIN_DECLS
extern const int STRINGS_MATCH;

char	*strToLower(char *);
char	*strToUpper(char *);
char	*sw_strdup(const char *);
char	*trim(char *);
const char *
	 strColor(short int color) NO_SIDE_EFFECT;
int	 strFeed(char *string, int count);
#if defined(HAVE_STRCASESTR) && HAVE_STRCASESTR == 0
char	*strcasestr(const char *, const char *);
#endif
errno_t	 sw_strcat(char *__restrict dest, const char *__restrict src, size_t)
	     BOUNDED_STR(1,3);
errno_t	 sw_strcpy(char *__restrict dest, const char *__restrict src, size_t)
	     BOUNDED_STR(1,3);
errno_t	 sw_wcscat(wchar_t *__restrict dest, const wchar_t *__restrict src,
	     size_t) BOUNDED_WSTR(1,3);
errno_t	 sw_wcscpy(wchar_t *__restrict dest, const wchar_t *__restrict src,
	     size_t) BOUNDED_WSTR(1,3);
size_t	 xstrnlen(const char *, size_t);
void	 squeeze(char *, const char *);
void	 sw_snprintf(char *, size_t, const char *, ...) PRINTFLIKE(3);
__SWIRC_END_DECLS

/* Inline function definitions
   =========================== */

#if (defined(HURD) || defined(LINUX)) && !defined(_GNU_SOURCE)
#define _GNU_SOURCE
#endif
#include <string.h>

#ifdef UNIX
#include <strings.h>
#endif

static SW_INLINE bool
strings_match(const char *s1, const char *s2)
{
	return (strcmp(s1, s2) == 0);
}

static SW_INLINE bool
strings_match_ignore_case(const char *s1, const char *s2)
{
#if defined(UNIX)
	return (strcasecmp(s1, s2) == 0);
#elif defined(WIN32)
	return (_stricmp(s1, s2) == 0);
#endif
}

#endif
