/*
 * fontconfig/src/fcstr.c
 *
 * Copyright © 2000 Keith Packard
 *
 * Permission to use, copy, modify, distribute, and sell this software and its
 * documentation for any purpose is hereby granted without fee, provided that
 * the above copyright notice appear in all copies and that both that
 * copyright notice and this permission notice appear in supporting
 * documentation, and that the name of the author(s) not be used in
 * advertising or publicity pertaining to distribution of the software without
 * specific, written prior permission.  The authors make no
 * representations about the suitability of this software for any purpose.  It
 * is provided "as is" without express or implied warranty.
 *
 * THE AUTHOR(S) DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
 * EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY SPECIAL, INDIRECT OR
 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 * PERFORMANCE OF THIS SOFTWARE.
 */

#include "fcint.h"
#include <stdlib.h>
#include <ctype.h>
#include <string.h>


/* Objects MT-safe for readonly access. */

FcChar8 *
FcStrCopy (const FcChar8 *s)
{
    return FcStrdup (s);
}

static FcChar8 *
FcStrMakeTriple (const FcChar8 *s1, const FcChar8 *s2, const FcChar8 *s3)
{
    int	    s1l = s1 ? strlen ((char *) s1) : 0;
    int	    s2l = s2 ? strlen ((char *) s2) : 0;
    int     s3l = s3 ? strlen ((char *) s3) : 0;
    int	    l = s1l + 1 + s2l + 1 + s3l + 1;
    FcChar8 *s = malloc (l);

    if (!s)
	return 0;
    if (s1)
	memcpy (s, s1, s1l + 1);
    else
	s[0] = '\0';
    if (s2)
	memcpy (s + s1l + 1, s2, s2l + 1);
    else
	s[s1l + 1] = '\0';
    if (s3)
	memcpy (s + s1l + 1 + s2l + 1, s3, s3l + 1);
    else
	s[s1l + 1 + s2l + 1] = '\0';
    return s;
}

FcChar8 *
FcStrPlus (const FcChar8 *s1, const FcChar8 *s2)
{
    int	    s1l = strlen ((char *) s1);
    int	    s2l = strlen ((char *) s2);
    int	    l = s1l + s2l + 1;
    FcChar8 *s = malloc (l);

    if (!s)
	return 0;
    memcpy (s, s1, s1l);
    memcpy (s + s1l, s2, s2l + 1);
    return s;
}

void
FcStrFree (FcChar8 *s)
{
    free (s);
}


#include "../fc-case/fccase.h"

#define FcCaseFoldUpperCount(cf) \
    ((cf)->method == FC_CASE_FOLD_FULL ? 1 : (cf)->count)

typedef struct _FcCaseWalker {
    const FcChar8   *read;
    const FcChar8   *src;
    FcChar8	    utf8[FC_MAX_CASE_FOLD_CHARS + 1];
} FcCaseWalker;

static void
FcStrCaseWalkerInit (const FcChar8 *src, FcCaseWalker *w)
{
    w->src = src;
    w->read = 0;
}

static FcChar8
FcStrCaseWalkerLong (FcCaseWalker *w, FcChar8 r)
{
    FcChar32	ucs4;
    int		slen;
    int		len = strlen((char*)w->src);

    slen = FcUtf8ToUcs4 (w->src - 1, &ucs4, len + 1);
    if (slen <= 0)
	return r;
    if (FC_MIN_FOLD_CHAR <= ucs4 && ucs4 <= FC_MAX_FOLD_CHAR)
    {
	int min = 0;
	int max = FC_NUM_CASE_FOLD;

	while (min <= max)
	{
	    int		mid = (min + max) >> 1;
	    FcChar32    low = fcCaseFold[mid].upper;
	    FcChar32    high = low + FcCaseFoldUpperCount (&fcCaseFold[mid]);
	
	    if (high <= ucs4)
		min = mid + 1;
	    else if (ucs4 < low)
		max = mid - 1;
	    else
	    {
		const FcCaseFold    *fold = &fcCaseFold[mid];
		int		    dlen;
		
		switch (fold->method) {
		case  FC_CASE_FOLD_EVEN_ODD:
		    if ((ucs4 & 1) != (fold->upper & 1))
			return r;
		    /* fall through ... */
		default:
		    dlen = FcUcs4ToUtf8 (ucs4 + fold->offset, w->utf8);
		    break;
		case FC_CASE_FOLD_FULL:
		    dlen = fold->count;
		    memcpy (w->utf8, fcCaseFoldChars + fold->offset, dlen);
		    break;
		}
		
		/* consume rest of src utf-8 bytes */
		w->src += slen - 1;
		
		/* read from temp buffer */
		w->utf8[dlen] = '\0';
		w->read = w->utf8;
		return *w->read++;
	    }
	}
    }
    return r;
}

static FcChar8
FcStrCaseWalkerNextNonDelim (FcCaseWalker *w, const char *delims)
{
    FcChar8	r;

    if (FC_UNLIKELY (w->read != NULL))
    {
	if ((r = *w->read++))
	    return r;
	w->read = 0;
    }
    do
    {
	r = *w->src++;
    } while (r != 0 && delims && strchr (delims, r));

    if (FC_UNLIKELY ((r & 0xc0) == 0xc0))
	return FcStrCaseWalkerLong (w, r);
    if ('A' <= r && r <= 'Z')
        r = r - 'A' + 'a';
    return r;
}

static FcChar8
FcStrCaseWalkerNextNonBlank (FcCaseWalker *w)
{
    FcChar8	r;

    if (FC_UNLIKELY (w->read != NULL))
    {
	if ((r = *w->read++))
	    return r;
	w->read = 0;
    }
    do
    {
	r = *w->src++;
    } while (r == ' ');

    if (FC_UNLIKELY ((r & 0xc0) == 0xc0))
	return FcStrCaseWalkerLong (w, r);
    if ('A' <= r && r <= 'Z')
        r = r - 'A' + 'a';
    return r;
}

static FcChar8
FcStrCaseWalkerNext (FcCaseWalker *w)
{
    FcChar8	r;

    if (FC_UNLIKELY (w->read != NULL))
    {
	if ((r = *w->read++))
	    return r;
	w->read = 0;
    }

    r = *w->src++;

    if (FC_UNLIKELY ((r & 0xc0) == 0xc0))
	return FcStrCaseWalkerLong (w, r);
    if ('A' <= r && r <= 'Z')
        r = r - 'A' + 'a';
    return r;
}

FcChar8 *
FcStrDowncase (const FcChar8 *s)
{
    FcCaseWalker    w;
    int		    len = 0;
    FcChar8	    *dst, *d;

    FcStrCaseWalkerInit (s, &w);
    while (FcStrCaseWalkerNext (&w))
	len++;
    d = dst = malloc (len + 1);
    if (!d)
	return 0;
    FcStrCaseWalkerInit (s, &w);
    while ((*d++ = FcStrCaseWalkerNext (&w)));
    return dst;
}

int
FcStrCmpIgnoreCase (const FcChar8 *s1, const FcChar8 *s2)
{
    FcCaseWalker    w1, w2;
    FcChar8	    c1, c2;

    if (s1 == s2) return 0;

    FcStrCaseWalkerInit (s1, &w1);
    FcStrCaseWalkerInit (s2, &w2);

    for (;;)
    {
	c1 = FcStrCaseWalkerNext (&w1);
	c2 = FcStrCaseWalkerNext (&w2);
	if (!c1 || (c1 != c2))
	    break;
    }
    return (int) c1 - (int) c2;
}

int
FcStrCmpIgnoreBlanksAndCase (const FcChar8 *s1, const FcChar8 *s2)
{
    FcCaseWalker    w1, w2;
    FcChar8	    c1, c2;

    if (s1 == s2) return 0;

    FcStrCaseWalkerInit (s1, &w1);
    FcStrCaseWalkerInit (s2, &w2);

    for (;;)
    {
	c1 = FcStrCaseWalkerNextNonBlank (&w1);
	c2 = FcStrCaseWalkerNextNonBlank (&w2);
	if (!c1 || (c1 != c2))
	    break;
    }
    return (int) c1 - (int) c2;
}

int
FcStrCmp (const FcChar8 *s1, const FcChar8 *s2)
{
    FcChar8 c1, c2;

    if (s1 == s2)
	return 0;
    for (;;)
    {
	c1 = *s1++;
	c2 = *s2++;
	if (!c1 || c1 != c2)
	    break;
    }
    return (int) c1 - (int) c2;
}

/*
 * Return a hash value for a string
 */

FcChar32
FcStrHashIgnoreCase (const FcChar8 *s)
{
    FcChar32	    h = 0;
    FcCaseWalker    w;
    FcChar8	    c;

    FcStrCaseWalkerInit (s, &w);
    while ((c = FcStrCaseWalkerNext (&w)))
	h = ((h << 3) ^ (h >> 3)) ^ c;
    return h;
}

FcChar32
FcStrHashIgnoreBlanksAndCase (const FcChar8 *s)
{
    FcChar32	    h = 0;
    FcCaseWalker    w;
    FcChar8	    c;

    FcStrCaseWalkerInit (s, &w);
    while ((c = FcStrCaseWalkerNextNonBlank (&w)))
	h = ((h << 3) ^ (h >> 3)) ^ c;
    return h;
}

/*
 * Is the head of s1 equal to s2?
 */

static FcBool
FcStrIsAtIgnoreBlanksAndCase (const FcChar8 *s1, const FcChar8 *s2)
{
    FcCaseWalker    w1, w2;
    FcChar8	    c1, c2;

    FcStrCaseWalkerInit (s1, &w1);
    FcStrCaseWalkerInit (s2, &w2);

    for (;;)
    {
	c1 = FcStrCaseWalkerNextNonBlank (&w1);
	c2 = FcStrCaseWalkerNextNonBlank (&w2);
	if (!c1 || (c1 != c2))
	    break;
    }
    return c1 == c2 || !c2;
}

/*
 * Does s1 contain an instance of s2 (ignoring blanks and case)?
 */

const FcChar8 *
FcStrContainsIgnoreBlanksAndCase (const FcChar8 *s1, const FcChar8 *s2)
{
    while (*s1)
    {
	if (FcStrIsAtIgnoreBlanksAndCase (s1, s2))
	    return s1;
	s1++;
    }
    return 0;
}

static FcBool
FcCharIsPunct (const FcChar8 c)
{
    if (c < '0')
	return FcTrue;
    if (c <= '9')
	return FcFalse;
    if (c < 'A')
	return FcTrue;
    if (c <= 'Z')
	return FcFalse;
    if (c < 'a')
	return FcTrue;
    if (c <= 'z')
	return FcFalse;
    if (c <= '~')
	return FcTrue;
    return FcFalse;
}

/*
 * Is the head of s1 equal to s2?
 */

static FcBool
FcStrIsAtIgnoreCase (const FcChar8 *s1, const FcChar8 *s2)
{
    FcCaseWalker    w1, w2;
    FcChar8	    c1, c2;

    FcStrCaseWalkerInit (s1, &w1);
    FcStrCaseWalkerInit (s2, &w2);

    for (;;)
    {
	c1 = FcStrCaseWalkerNext (&w1);
	c2 = FcStrCaseWalkerNext (&w2);
	if (!c1 || (c1 != c2))
	    break;
    }
    return c1 == c2 || !c2;
}

/*
 * Does s1 contain an instance of s2 (ignoring blanks and case)?
 */

const FcChar8 *
FcStrContainsIgnoreCase (const FcChar8 *s1, const FcChar8 *s2)
{
    while (*s1)
    {
	if (FcStrIsAtIgnoreCase (s1, s2))
	    return s1;
	s1++;
    }
    return 0;
}

/*
 * Does s1 contain an instance of s2 on a word boundary (ignoring case)?
 */

const FcChar8 *
FcStrContainsWord (const FcChar8 *s1, const FcChar8 *s2)
{
    FcBool  wordStart = FcTrue;
    int	    s1len = strlen ((char *) s1);
    int	    s2len = strlen ((char *) s2);
	
    while (s1len >= s2len)
    {
	if (wordStart &&
	    FcStrIsAtIgnoreCase (s1, s2) &&
	    (s1len == s2len || FcCharIsPunct (s1[s2len])))
	{
	    return s1;
	}
	wordStart = FcFalse;
	if (FcCharIsPunct (*s1))
	    wordStart = FcTrue;
	s1++;
	s1len--;
    }
    return 0;
}

/*
 * returns the number of strings (ignoring delimiters and case) being matched
 */

int
FcStrMatchIgnoreCaseAndDelims (const FcChar8 *s1, const FcChar8 *s2, const FcChar8 *delims)
{
    FcCaseWalker    w1, w2;
    FcChar8	    c1, c2;

    if (s1 == s2) return 0;

    FcStrCaseWalkerInit (s1, &w1);
    FcStrCaseWalkerInit (s2, &w2);

    for (;;)
    {
	c1 = FcStrCaseWalkerNextNonDelim (&w1, (const char *)delims);
	c2 = FcStrCaseWalkerNextNonDelim (&w2, (const char *)delims);
	if (!c1 || (c1 != c2))
	    break;
    }
    return w1.src - s1 - 1;
}

FcBool
FcStrGlobMatch (const FcChar8 *glob,
		const FcChar8 *string)
{
    FcChar8	c;

    while ((c = *glob++))
    {
	switch (c) {
	case '*':
	    /* short circuit common case */
	    if (!*glob)
		return FcTrue;
	    /* short circuit another common case */
	    if (strchr ((char *) glob, '*') == 0)
	    {
		size_t l1, l2;

		l1 = strlen ((char *) string);
		l2 = strlen ((char *) glob);
		if (l1 < l2)
		    return FcFalse;
		string += (l1 - l2);
	    }
	    while (*string)
	    {
		if (FcStrGlobMatch (glob, string))
		    return FcTrue;
		string++;
	    }
	    return FcFalse;
	case '?':
	    if (*string++ == '\0')
		return FcFalse;
	    break;
	default:
	    if (*string++ != c)
		return FcFalse;
	    break;
	}
    }
    return *string == '\0';
}

const FcChar8 *
FcStrStrIgnoreCase (const FcChar8 *s1, const FcChar8 *s2)
{
    FcCaseWalker    w1, w2;
    FcChar8	    c1, c2;
    const FcChar8   *cur;

    if (!s1 || !s2)
	return 0;

    if (s1 == s2)
	return s1;

    FcStrCaseWalkerInit (s1, &w1);
    FcStrCaseWalkerInit (s2, &w2);

    c2 = FcStrCaseWalkerNext (&w2);

    for (;;)
    {
	cur = w1.src;
	c1 = FcStrCaseWalkerNext (&w1);
	if (!c1)
	    break;
	if (c1 == c2)
	{
	    FcCaseWalker    w1t = w1;
	    FcCaseWalker    w2t = w2;
	    FcChar8	    c1t, c2t;

	    for (;;)
	    {
		c1t = FcStrCaseWalkerNext (&w1t);
		c2t = FcStrCaseWalkerNext (&w2t);

		if (!c2t)
		    return cur;
		if (c2t != c1t)
		    break;
	    }
	}
    }
    return 0;
}

const FcChar8 *
FcStrStr (const FcChar8 *s1, const FcChar8 *s2)
{
    FcChar8 c1, c2;
    const FcChar8 * p = s1;
    const FcChar8 * b = s2;

    if (!s1 || !s2)
	return 0;

    if (s1 == s2)
	return s1;

again:
    c2 = *s2++;

    if (!c2)
	return 0;

    for (;;)
    {
	p = s1;
	c1 = *s1++;
	if (!c1 || c1 == c2)
	    break;
    }

    if (c1 != c2)
	return 0;

    for (;;)
    {
	c1 = *s1;
	c2 = *s2;
	if (c1 && c2 && c1 != c2)
	{
	    s1 = p + 1;
	    s2 = b;
	    goto again;
	}
	if (!c2)
	    return p;
	if (!c1)
	    return 0;
	++ s1;
	++ s2;
    }
    /* never reached. */
}

int
FcUtf8ToUcs4 (const FcChar8 *src_orig,
	      FcChar32	    *dst,
	      int	    len)
{
    const FcChar8   *src = src_orig;
    FcChar8	    s;
    int		    extra;
    FcChar32	    result;

    if (len == 0)
	return 0;

    s = *src++;
    len--;

    if (!(s & 0x80))
    {
	result = s;
	extra = 0;
    }
    else if (!(s & 0x40))
    {
	return -1;
    }
    else if (!(s & 0x20))
    {
	result = s & 0x1f;
	extra = 1;
    }
    else if (!(s & 0x10))
    {
	result = s & 0xf;
	extra = 2;
    }
    else if (!(s & 0x08))
    {
	result = s & 0x07;
	extra = 3;
    }
    else if (!(s & 0x04))
    {
	result = s & 0x03;
	extra = 4;
    }
    else if ( ! (s & 0x02))
    {
	result = s & 0x01;
	extra = 5;
    }
    else
    {
	return -1;
    }
    if (extra > len)
	return -1;

    while (extra--)
    {
	result <<= 6;
	s = *src++;
	
	if ((s & 0xc0) != 0x80)
	    return -1;
	
	result |= s & 0x3f;
    }
    *dst = result;
    return src - src_orig;
}

FcBool
FcUtf8Len (const FcChar8    *string,
	   int		    len,
	   int		    *nchar,
	   int		    *wchar)
{
    int		n;
    int		clen;
    FcChar32	c;
    FcChar32	max;

    n = 0;
    max = 0;
    while (len)
    {
	clen = FcUtf8ToUcs4 (string, &c, len);
	if (clen <= 0)	/* malformed UTF8 string */
	    return FcFalse;
	if (c > max)
	    max = c;
	string += clen;
	len -= clen;
	n++;
    }
    *nchar = n;
    if (max >= 0x10000)
	*wchar = 4;
    else if (max > 0x100)
	*wchar = 2;
    else
	*wchar = 1;
    return FcTrue;
}

int
FcUcs4ToUtf8 (FcChar32	ucs4,
	      FcChar8	dest[FC_UTF8_MAX_LEN])
{
    int	bits;
    FcChar8 *d = dest;

    if      (ucs4 <       0x80) {  *d++=  ucs4;                         bits= -6; }
    else if (ucs4 <      0x800) {  *d++= ((ucs4 >>  6) & 0x1F) | 0xC0;  bits=  0; }
    else if (ucs4 <    0x10000) {  *d++= ((ucs4 >> 12) & 0x0F) | 0xE0;  bits=  6; }
    else if (ucs4 <   0x200000) {  *d++= ((ucs4 >> 18) & 0x07) | 0xF0;  bits= 12; }
    else if (ucs4 <  0x4000000) {  *d++= ((ucs4 >> 24) & 0x03) | 0xF8;  bits= 18; }
    else if (ucs4 < 0x80000000) {  *d++= ((ucs4 >> 30) & 0x01) | 0xFC;  bits= 24; }
    else return 0;

    for ( ; bits >= 0; bits-= 6) {
	*d++= ((ucs4 >> bits) & 0x3F) | 0x80;
    }
    return d - dest;
}

#define GetUtf16(src,endian) \
    ((FcChar16) ((src)[endian == FcEndianBig ? 0 : 1] << 8) | \
     (FcChar16) ((src)[endian == FcEndianBig ? 1 : 0]))

int
FcUtf16ToUcs4 (const FcChar8	*src_orig,
	       FcEndian		endian,
	       FcChar32		*dst,
	       int		len)	/* in bytes */
{
    const FcChar8   *src = src_orig;
    FcChar16	    a, b;
    FcChar32	    result;

    if (len < 2)
	return 0;

    a = GetUtf16 (src, endian); src += 2; len -= 2;

    /*
     * Check for surrogate
     */
    if ((a & 0xfc00) == 0xd800)
    {
	if (len < 2)
	    return 0;
	b = GetUtf16 (src, endian); src += 2; len -= 2;
	/*
	 * Check for invalid surrogate sequence
	 */
	if ((b & 0xfc00) != 0xdc00)
	    return 0;
	result = ((((FcChar32) a & 0x3ff) << 10) |
		  ((FcChar32) b & 0x3ff)) + 0x10000;
    }
    else
	result = a;
    *dst = result;
    return src - src_orig;
}

FcBool
FcUtf16Len (const FcChar8   *string,
	    FcEndian	    endian,
	    int		    len,	/* in bytes */
	    int		    *nchar,
	    int		    *wchar)
{
    int		n;
    int		clen;
    FcChar32	c;
    FcChar32	max;

    n = 0;
    max = 0;
    while (len)
    {
	clen = FcUtf16ToUcs4 (string, endian, &c, len);
	if (clen <= 0)	/* malformed UTF8 string */
	    return FcFalse;
	if (c > max)
	    max = c;
	string += clen;
	len -= clen;
	n++;
    }
    *nchar = n;
    if (max >= 0x10000)
	*wchar = 4;
    else if (max > 0x100)
	*wchar = 2;
    else
	*wchar = 1;
    return FcTrue;
}

void
FcStrBufInit (FcStrBuf *buf, FcChar8 *init, int size)
{
    if (init)
    {
	buf->buf = init;
	buf->size = size;
    } else
    {
	buf->buf = buf->buf_static;
	buf->size = sizeof (buf->buf_static);
    }
    buf->allocated = FcFalse;
    buf->failed = FcFalse;
    buf->len = 0;
}

void
FcStrBufDestroy (FcStrBuf *buf)
{
    if (buf->allocated)
    {
	free (buf->buf);
	FcStrBufInit (buf, 0, 0);
    }
}

FcChar8 *
FcStrBufDone (FcStrBuf *buf)
{
    FcChar8 *ret;

    if (buf->failed)
	ret = NULL;
    else
	ret = malloc (buf->len + 1);
    if (ret)
    {
	memcpy (ret, buf->buf, buf->len);
	ret[buf->len] = '\0';
    }
    FcStrBufDestroy (buf);
    return ret;
}

FcChar8 *
FcStrBufDoneStatic (FcStrBuf *buf)
{
    FcStrBufChar (buf, '\0');

    if (buf->failed)
	return NULL;

    return buf->buf;
}

FcBool
FcStrBufChar (FcStrBuf *buf, FcChar8 c)
{
    if (buf->len == buf->size)
    {
	FcChar8	    *new;
	int	    size;

	if (buf->failed)
	    return FcFalse;

	if (buf->allocated)
	{
	    size = buf->size * 2;
	    new = realloc (buf->buf, size);
	}
	else
	{
	    size = buf->size + 64;
	    new = malloc (size);
	    if (new)
	    {
		buf->allocated = FcTrue;
		memcpy (new, buf->buf, buf->len);
	    }
	}
	if (!new)
	{
	    buf->failed = FcTrue;
	    return FcFalse;
	}
	buf->size = size;
	buf->buf = new;
    }
    buf->buf[buf->len++] = c;
    return FcTrue;
}

FcBool
FcStrBufString (FcStrBuf *buf, const FcChar8 *s)
{
    FcChar8 c;
    while ((c = *s++))
	if (!FcStrBufChar (buf, c))
	    return FcFalse;
    return FcTrue;
}

FcBool
FcStrBufData (FcStrBuf *buf, const FcChar8 *s, int len)
{
    while (len-- > 0)
	if (!FcStrBufChar (buf, *s++))
	    return FcFalse;
    return FcTrue;
}

FcBool
FcStrUsesHome (const FcChar8 *s)
{
    return *s == '~';
}

FcBool
FcStrIsAbsoluteFilename (const FcChar8 *s)
{
#ifdef _WIN32
    if (*s == '\\' ||
	(isalpha (*s) && s[1] == ':' && (s[2] == '/' || s[2] == '\\')))
	return FcTrue;
#endif
    return *s == '/';
}

FcChar8 *
FcStrBuildFilename (const FcChar8 *path,
		    ...)
{
    va_list ap;
    FcStrSet *sset;
    FcStrList *list;
    FcChar8 *s, *ret = NULL, *p;
    size_t len = 0;

    if (!path)
	return NULL;

    sset = FcStrSetCreateEx (FCSS_ALLOW_DUPLICATES | FCSS_GROW_BY_64);
    if (!sset)
	return NULL;

    if (!FcStrSetAdd (sset, path))
	goto bail0;

    va_start (ap, path);
    while (1)
    {
	s = (FcChar8 *)va_arg (ap, FcChar8 *);
	if (!s)
	    break;
	if (!FcStrSetAdd (sset, s))
	    goto bail1;
    }
    list = FcStrListCreate (sset);
    while ((s = FcStrListNext (list)))
    {
	len += strlen ((const char *)s) + 1;
    }
    list->n = 0;
    ret = malloc (sizeof (FcChar8) * (len + 1));
    if (!ret)
	goto bail2;
    p = ret;
    while ((s = FcStrListNext (list)))
    {
	if (p != ret)
	{
	    p[0] = FC_DIR_SEPARATOR;
	    p++;
	}
	len = strlen ((const char *)s);
	memcpy (p, s, len);
	p += len;
    }
    *p = 0;

bail2:
    FcStrListDone (list);
bail1:
    va_end (ap);
bail0:
    FcStrSetDestroy (sset);

    return ret;
}

FcChar8 *
FcStrCopyFilename (const FcChar8 *s)
{
    FcChar8 *new;

    if (*s == '~')
    {
	FcChar8	*home = FcConfigHome ();
	FcChar8	*full;
	int	size;
	if (!home)
	    return NULL;
	size = strlen ((char *) home) + strlen ((char *) s);
	full = (FcChar8 *) malloc (size + 1);
	if (!full)
	    return NULL;
	strcpy ((char *) full, (char *) home);
	strcat ((char *) full, (char *) s + 1);
	new = FcStrCanonFilename (full);
	free (full);
    }
    else
	new = FcStrCanonFilename (s);

    return new;
}

FcChar8 *
FcStrLastSlash (const FcChar8  *path)
{
    FcChar8	    *slash;

    slash = (FcChar8 *) strrchr ((const char *) path, '/');
#ifdef _WIN32
    {
        FcChar8     *backslash;

	backslash = (FcChar8 *) strrchr ((const char *) path, '\\');
	if (!slash || (backslash && backslash > slash))
	    slash = backslash;
    }
#endif

    return slash;
}

FcChar8 *
FcStrDirname (const FcChar8 *file)
{
    FcChar8 *slash;
    FcChar8 *dir;

    slash = FcStrLastSlash (file);
    if (!slash)
	return FcStrCopy ((FcChar8 *) ".");
    dir = malloc ((slash - file) + 1);
    if (!dir)
	return 0;
    strncpy ((char *) dir, (const char *) file, slash - file);
    dir[slash - file] = '\0';
    return dir;
}

FcChar8 *
FcStrBasename (const FcChar8 *file)
{
    FcChar8 *slash;

    slash = FcStrLastSlash (file);
    if (!slash)
	return FcStrCopy (file);
    return FcStrCopy (slash + 1);
}

static FcChar8 *
FcStrCanonAbsoluteFilename (const FcChar8 *s)
{
    FcChar8 *file;
    FcChar8 *f;
    const FcChar8 *slash;
    int size;

    size = strlen ((char *) s) + 1;
    file = malloc (size);
    if (!file)
	return NULL;
    slash = NULL;
    f = file;
#ifdef _WIN32
    if (*s == '/' && *(s+1) == '/') /* Network path, do not squash // */
	*f++ = *s++;
#endif
    for (;;) {
	if (*s == '/' || *s == '\0')
	{
	    if (slash)
	    {
		switch (s - slash) {
		case 1:
		    f -= 1;	/* squash // and trim final / from file */
		    break;
		case 2:
		    if (!strncmp ((char *) slash, "/.", 2))
		    {
			f -= 2;	/* trim /. from file */
		    }
		    break;
		case 3:
		    if (!strncmp ((char *) slash, "/..", 3))
		    {
			f -= 3;	/* trim /.. from file */
			while (f > file) {
			    if (*--f == '/')
				break;
			}
		    }
		    break;
		}
	    }
	    slash = s;
	}
	if (!(*f++ = *s++))
	    break;
    }
    return file;
}

#ifdef _WIN32
/*
 * Convert '\\' to '/' , remove double '/'
 */
static void
FcConvertDosPath (char *str)
{
  size_t len = strlen (str);
  char *p = str;
  char *dest = str;
  char *end = str + len;
  char last = 0;

  if (*p == '\\')
    {
      *p = '/';
      p++;
      dest++;
    }
  while (p < end)
    {
      if (*p == '\\')
	*p = '/';

      if (*p != '/'
	  || last != '/')
	{
	  *dest++ = *p;
	}

      last = *p;
      p++;
    }

  *dest = 0;
}
#endif

FcChar8 *
FcStrCanonFilename (const FcChar8 *s)
{
#ifdef _WIN32
    FcChar8 full[FC_MAX_FILE_LEN + 2];
    int size = GetFullPathName ((LPCSTR) s, sizeof (full) -1,
				(LPSTR) full, NULL);

    if (size == 0)
	perror ("GetFullPathName");

    FcConvertDosPath ((char *) full);
    return FcStrCanonAbsoluteFilename (full);
#else
    if (s[0] == '/')
	return FcStrCanonAbsoluteFilename (s);
    else
    {
	FcChar8	*full;
	FcChar8 *file;

	FcChar8	cwd[FC_MAX_FILE_LEN + 2];
	if (getcwd ((char *) cwd, FC_MAX_FILE_LEN) == NULL)
	    return NULL;
	full = FcStrBuildFilename (cwd, s, NULL);
	file = FcStrCanonAbsoluteFilename (full);
	FcStrFree (full);
	return file;
    }
#endif
}


FcStrSet *
FcStrSetCreate (void)
{
    return FcStrSetCreateEx (FCSS_DEFAULT);
}

FcStrSet *
FcStrSetCreateEx (unsigned int control)
{
    FcStrSet	*set = malloc (sizeof (FcStrSet));
    if (!set)
	return 0;
    FcRefInit (&set->ref, 1);
    set->num = 0;
    set->size = 0;
    set->strs = 0;
    set->control = control;
    return set;
}

static FcBool
_FcStrSetGrow (FcStrSet *set, int growElements)
{
    /* accommodate an additional NULL entry at the end of the array */
    FcChar8 **strs = malloc ((set->size + growElements + 1) * sizeof (FcChar8 *));
    if (!strs)
        return FcFalse;
    if (set->num)
        memcpy (strs, set->strs, set->num * sizeof (FcChar8 *));
    if (set->strs)
        free (set->strs);
    set->size = set->size + growElements;
    set->strs = strs;
    return FcTrue;
}

static FcBool
_FcStrSetInsert (FcStrSet *set, FcChar8 *s, int pos)
{
    if (!FcStrSetHasControlBit (set, FCSS_ALLOW_DUPLICATES))
    {
        if (FcStrSetMember (set, s))
        {
            FcStrFree (s);
            return FcTrue;
        }
    }
    if (set->num == set->size)
    {
        int growElements = FcStrSetHasControlBit (set, FCSS_GROW_BY_64) ? 64 : 1;
        if (!_FcStrSetGrow(set, growElements))
            return FcFalse;
    }
    if (pos >= set->num)
    {
	set->strs[set->num++] = s;
	set->strs[set->num] = 0;
    }
    else
    {
	int i;

	set->num++;
	set->strs[set->num] = 0;
	for (i = set->num - 1; i > pos; i--)
	    set->strs[i] = set->strs[i - 1];
	set->strs[pos] = s;
    }
    return FcTrue;
}

FcBool
FcStrSetMember (FcStrSet *set, const FcChar8 *s)
{
    int	i;

    for (i = 0; i < set->num; i++)
	if (!FcStrCmp (set->strs[i], s))
	    return FcTrue;
    return FcFalse;
}

static int
fc_strcmp_r (const FcChar8 *s1, const FcChar8 *s2, const FcChar8 **ret)
{
    FcChar8 c1, c2;

    if (s1 == s2)
    {
	if (ret)
	    *ret = NULL;
	return 0;
    }
    for (;;)
    {
	if (s1)
	    c1 = *s1++;
	else
	    c1 = 0;
	if (s2)
	    c2 = *s2++;
	else
	    c2 = 0;
	if (!c1 || c1 != c2)
	    break;
    }
    if (ret)
	*ret = s1;
    return (int) c1  - (int) c2;
}

FcBool
FcStrSetMemberAB (FcStrSet *set, const FcChar8 *a, FcChar8 *b, FcChar8 **ret)
{
    int i;
    const FcChar8 *s = NULL;

    for (i = 0; i < set->num; i++)
    {
	if (!fc_strcmp_r (set->strs[i], a, &s) && s)
	{
	    if (!fc_strcmp_r (s, b, NULL))
	    {
		if (ret)
		    *ret = set->strs[i];
		return FcTrue;
	    }
	}
    }
    if (ret)
	*ret = NULL;
    return FcFalse;
}

FcBool
FcStrSetEqual (FcStrSet *sa, FcStrSet *sb)
{
    int	i;
    if (sa->num != sb->num)
	return FcFalse;
    for (i = 0; i < sa->num; i++)
	if (!FcStrSetMember (sb, sa->strs[i]))
	    return FcFalse;
    return FcTrue;
}

FcBool
FcStrSetAdd (FcStrSet *set, const FcChar8 *s)
{
    FcChar8 *new = FcStrCopy (s);
    if (!new)
	return FcFalse;
    if (!_FcStrSetInsert (set, new, set->num))
    {
	FcStrFree (new);
	return FcFalse;
    }
    return FcTrue;
}

FcBool
FcStrSetInsert (FcStrSet *set, const FcChar8 *s, int pos)
{
    FcChar8 *new = FcStrCopy (s);
    if (!new)
	return FcFalse;
    if (!_FcStrSetInsert (set, new, pos))
    {
	FcStrFree (new);
	return FcFalse;
    }
    return FcTrue;
}

FcBool
FcStrSetAddTriple (FcStrSet *set, const FcChar8 *a, const FcChar8 *b, const FcChar8 *c)
{
    FcChar8 *new = FcStrMakeTriple (a, b, c);
    if (!new)
	return FcFalse;
    if (!_FcStrSetInsert (set, new, set->num))
    {
	FcStrFree (new);
	return FcFalse;
    }
    return FcTrue;
}

const FcChar8 *
FcStrTripleSecond (FcChar8 *str)
{
    FcChar8 *second = str + strlen((char *) str) + 1;

    if (*second == '\0')
	return 0;
    return second;
}

const FcChar8 *
FcStrTripleThird (FcChar8 *str)
{
    FcChar8 *second = str + strlen ((char *) str) + 1;
    FcChar8 *third = second + strlen ((char *) second) + 1;

    if (*third == '\0')
	return 0;
    return third;
}

FcBool
FcStrSetAddFilename (FcStrSet *set, const FcChar8 *s)
{
    FcChar8 *new = FcStrCopyFilename (s);
    if (!new)
	return FcFalse;
    if (!_FcStrSetInsert (set, new, set->num))
    {
	FcStrFree (new);
	return FcFalse;
    }
    return FcTrue;
}

FcBool
FcStrSetAddFilenamePairWithSalt (FcStrSet *set, const FcChar8 *a, const FcChar8 *b, const FcChar8 *salt)
{
    FcChar8 *new_a = NULL;
    FcChar8 *new_b = NULL;
    FcChar8 *rs = NULL;
    FcBool  ret;

    if (a)
    {
	new_a = FcStrCopyFilename (a);
	if (!new_a)
	    return FcFalse;
    }
    if (b)
    {
	new_b = FcStrCopyFilename(b);
	if (!new_b)
	{
	    if (new_a)
		FcStrFree(new_a);
	    return FcFalse;
	}
    }
    /* Override maps with new one if exists */
    if (FcStrSetMemberAB (set, new_a, new_b, &rs))
    {
	FcStrSetDel (set, rs);
    }
    ret = FcStrSetAddTriple (set, new_a, new_b, salt);
    if (new_a)
	FcStrFree (new_a);
    if (new_b)
	FcStrFree (new_b);
    return ret;
}

FcBool
FcStrSetAddLangs (FcStrSet *strs, const char *languages)
{
    const char *p = languages, *next;
    FcChar8 lang[128] = {0}, *normalized_lang;
    size_t len;
    FcBool ret = FcFalse;

    if (!languages)
	return FcFalse;

    while ((next = strchr (p, ':')))
    {
	len = next - p;
	len = FC_MIN (len, 127);
	strncpy ((char *) lang, p, len);
	lang[len] = 0;
	/* ignore an empty item */
	if (*lang)
	{
	    normalized_lang = FcLangNormalize ((const FcChar8 *) lang);
	    if (normalized_lang)
	    {
		FcStrSetAdd (strs, normalized_lang);
		FcStrFree (normalized_lang);
		ret = FcTrue;
	    }
	}
	p = next + 1;
    }
    if (*p)
    {
	normalized_lang = FcLangNormalize ((const FcChar8 *) p);
	if (normalized_lang)
	{
	    FcStrSetAdd (strs, normalized_lang);
	    FcStrFree (normalized_lang);
	    ret = FcTrue;
	}
    }

    return ret;
}

FcBool
FcStrSetDel (FcStrSet *set, const FcChar8 *s)
{
    int	i;

    for (i = 0; i < set->num; i++)
	if (!FcStrCmp (set->strs[i], s))
	{
	    FcStrFree (set->strs[i]);
	    /*
	     * copy remaining string pointers and trailing
	     * NULL
	     */
	    memmove (&set->strs[i], &set->strs[i+1],
		     (set->num - i) * sizeof (FcChar8 *));
	    set->num--;
	    return FcTrue;
	}
    return FcFalse;
}

FcBool
FcStrSetDeleteAll (FcStrSet *set)
{
    int i;

    if (FcRefIsConst (&set->ref))
	return FcFalse;

    for (i = set->num; i > 0; i--)
    {
	FcStrFree (set->strs[i - 1]);
	set->num--;
    }
    return FcTrue;
}

/* TODO Make public */
static FcStrSet *
FcStrSetReference (FcStrSet *set)
{
    if (FcRefIsConst (&set->ref))
	return set;

    FcRefInc (&set->ref);
    return set;
}

void
FcStrSetDestroy (FcStrSet *set)
{
    int	i;

    /* We rely on this in FcGetDefaultLangs for caching. */
    if (FcRefIsConst (&set->ref))
	return;

    if (FcRefDec (&set->ref) != 1)
	return;

    for (i = 0; i < set->num; i++)
	FcStrFree (set->strs[i]);
    if (set->strs)
	free (set->strs);
    free (set);
}

FcStrList *
FcStrListCreate (FcStrSet *set)
{
    FcStrList	*list;

    list = malloc (sizeof (FcStrList));
    if (!list)
	return 0;
    list->set = set;
    FcStrSetReference (set);
    list->n = 0;
    return list;
}

void
FcStrListFirst (FcStrList *list)
{
    list->n = 0;
}

FcChar8 *
FcStrListNext (FcStrList *list)
{
    if (list->n >= list->set->num)
	return 0;
    return list->set->strs[list->n++];
}

void
FcStrListDone (FcStrList *list)
{
    FcStrSetDestroy (list->set);
    free (list);
}

#define __fcstr__
#include "fcaliastail.h"
#undef __fcstr__
