2 * $XFree86: xc/lib/fontconfig/src/fcstr.c,v 1.10 2002/08/31 22:17:32 keithp Exp $
4 * Copyright © 2000 Keith Packard, member of The XFree86 Project, Inc.
6 * Permission to use, copy, modify, distribute, and sell this software and its
7 * documentation for any purpose is hereby granted without fee, provided that
8 * the above copyright notice appear in all copies and that both that
9 * copyright notice and this permission notice appear in supporting
10 * documentation, and that the name of Keith Packard not be used in
11 * advertising or publicity pertaining to distribution of the software without
12 * specific, written prior permission. Keith Packard makes no
13 * representations about the suitability of this software for any purpose. It
14 * is provided "as is" without express or implied warranty.
16 * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
17 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
18 * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
19 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
20 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
21 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
22 * PERFORMANCE OF THIS SOFTWARE.
31 FcStrCopy (const FcChar8 *s)
37 r = (FcChar8 *) malloc (strlen ((char *) s) + 1);
40 FcMemAlloc (FC_MEM_STRING, strlen ((char *) s) + 1);
41 strcpy ((char *) r, (char *) s);
46 FcStrPlus (const FcChar8 *s1, const FcChar8 *s2)
48 int l = strlen ((char *)s1) + strlen ((char *) s2) + 1;
49 FcChar8 *s = malloc (l);
53 FcMemAlloc (FC_MEM_STRING, l);
54 strcpy ((char *) s, (char *) s1);
55 strcat ((char *) s, (char *) s2);
60 FcStrFree (FcChar8 *s)
62 FcMemFree (FC_MEM_STRING, strlen ((char *) s) + 1);
67 FcStrCmpIgnoreCase (const FcChar8 *s1, const FcChar8 *s2)
82 return (int) c1 - (int) c2;
86 FcStrCmpIgnoreBlanksAndCase (const FcChar8 *s1, const FcChar8 *s2)
105 return (int) c1 - (int) c2;
109 FcStrCmp (const FcChar8 *s1, const FcChar8 *s2)
124 return (int) c1 - (int) c2;
128 FcUtf8ToUcs4 (const FcChar8 *src_orig,
132 const FcChar8 *src = src_orig;
148 else if (!(s & 0x40))
152 else if (!(s & 0x20))
157 else if (!(s & 0x10))
162 else if (!(s & 0x08))
167 else if (!(s & 0x04))
172 else if ( ! (s & 0x02))
189 if ((s & 0xc0) != 0x80)
195 return src - src_orig;
199 FcUtf8Len (const FcChar8 *string,
213 clen = FcUtf8ToUcs4 (string, &c, len);
214 if (clen <= 0) /* malformed UTF8 string */
225 else if (max > 0x100)
233 FcUcs4ToUtf8 (FcChar32 ucs4,
234 FcChar8 dest[FC_UTF8_MAX_LEN])
239 if (ucs4 < 0x80) { *d++= ucs4; bits= -6; }
240 else if (ucs4 < 0x800) { *d++= ((ucs4 >> 6) & 0x1F) | 0xC0; bits= 0; }
241 else if (ucs4 < 0x10000) { *d++= ((ucs4 >> 12) & 0x0F) | 0xE0; bits= 6; }
242 else if (ucs4 < 0x200000) { *d++= ((ucs4 >> 18) & 0x07) | 0xF0; bits= 12; }
243 else if (ucs4 < 0x4000000) { *d++= ((ucs4 >> 24) & 0x03) | 0xF8; bits= 18; }
244 else if (ucs4 < 0x80000000) { *d++= ((ucs4 >> 30) & 0x01) | 0xFC; bits= 24; }
247 for ( ; bits >= 0; bits-= 6) {
248 *d++= ((ucs4 >> bits) & 0x3F) | 0x80;
253 #define GetUtf16(src,endian) \
254 ((FcChar16) ((src)[endian == FcEndianBig ? 0 : 1] << 8) | \
255 (FcChar16) ((src)[endian == FcEndianBig ? 1 : 0]))
258 FcUtf16ToUcs4 (const FcChar8 *src_orig,
261 int len) /* in bytes */
263 const FcChar8 *src = src_orig;
270 a = GetUtf16 (src, endian); src += 2; len -= 2;
273 * Check for surrogate
275 if ((a & 0xfc00) == 0xd800)
279 b = GetUtf16 (src, endian); src += 2; len -= 2;
281 * Check for invalid surrogate sequence
283 if ((b & 0xfc00) != 0xdc00)
285 result = ((((FcChar32) a & 0x3ff) << 10) |
286 ((FcChar32) b & 0x3ff)) + 0x10000;
291 return src - src_orig;
295 FcUtf16Len (const FcChar8 *string,
297 int len, /* in bytes */
310 clen = FcUtf16ToUcs4 (string, endian, &c, len);
311 if (clen <= 0) /* malformed UTF8 string */
322 else if (max > 0x100)
330 FcStrBufInit (FcStrBuf *buf, FcChar8 *init, int size)
333 buf->allocated = FcFalse;
334 buf->failed = FcFalse;
340 FcStrBufDestroy (FcStrBuf *buf)
344 FcMemFree (FC_MEM_STRBUF, buf->size);
346 FcStrBufInit (buf, 0, 0);
351 FcStrBufDone (FcStrBuf *buf)
355 ret = malloc (buf->len + 1);
358 FcMemAlloc (FC_MEM_STRING, buf->len + 1);
359 memcpy (ret, buf->buf, buf->len);
360 ret[buf->len] = '\0';
362 FcStrBufDestroy (buf);
367 FcStrBufChar (FcStrBuf *buf, FcChar8 c)
369 if (buf->len == buf->size)
376 size = buf->size * 2;
377 new = realloc (buf->buf, size);
381 size = buf->size + 1024;
385 buf->allocated = FcTrue;
386 memcpy (new, buf->buf, buf->len);
391 buf->failed = FcTrue;
395 FcMemFree (FC_MEM_STRBUF, buf->size);
396 FcMemAlloc (FC_MEM_STRBUF, size);
400 buf->buf[buf->len++] = c;
405 FcStrBufString (FcStrBuf *buf, const FcChar8 *s)
409 if (!FcStrBufChar (buf, c))
415 FcStrBufData (FcStrBuf *buf, const FcChar8 *s, int len)
418 if (!FcStrBufChar (buf, *s++))
424 FcStrCopyFilename (const FcChar8 *s)
430 FcChar8 *home = (FcChar8 *) getenv ("HOME");
434 size = strlen ((char *) home) + strlen ((char *) s);
435 new = (FcChar8 *) malloc (size);
438 FcMemAlloc (FC_MEM_STRING, size);
439 strcpy ((char *) new, (char *) home);
440 strcat ((char *) new, (char *) s + 1);
444 int size = strlen ((char *) s) + 1;
445 new = (FcChar8 *) malloc (size);
448 FcMemAlloc (FC_MEM_STRING, size);
449 strcpy ((char *) new, (const char *) s);
455 FcStrDirname (const FcChar8 *file)
460 slash = (FcChar8 *) strrchr ((char *) file, '/');
462 return FcStrCopy ((FcChar8 *) ".");
463 dir = malloc ((slash - file) + 1);
466 FcMemAlloc (FC_MEM_STRING, (slash - file) + 1);
467 strncpy ((char *) dir, (const char *) file, slash - file);
468 dir[slash - file] = '\0';
473 FcStrBasename (const FcChar8 *file)
477 slash = (FcChar8 *) strrchr ((char *) file, '/');
479 return FcStrCopy (file);
480 return FcStrCopy (slash + 1);
484 FcStrSetCreate (void)
486 FcStrSet *set = malloc (sizeof (FcStrSet));
489 FcMemAlloc (FC_MEM_STRSET, sizeof (FcStrSet));
498 _FcStrSetAppend (FcStrSet *set, FcChar8 *s)
500 if (FcStrSetMember (set, s))
505 if (set->num == set->size)
507 FcChar8 **strs = malloc ((set->size + 2) * sizeof (FcChar8 *));
511 FcMemAlloc (FC_MEM_STRSET, (set->size + 2) * sizeof (FcChar8 *));
512 set->size = set->size + 1;
514 memcpy (strs, set->strs, set->num * sizeof (FcChar8 *));
519 set->strs[set->num++] = s;
520 set->strs[set->num] = 0;
525 FcStrSetMember (FcStrSet *set, const FcChar8 *s)
529 for (i = 0; i < set->num; i++)
530 if (!FcStrCmp (set->strs[i], s))
536 FcStrSetEqual (FcStrSet *sa, FcStrSet *sb)
539 if (sa->num != sb->num)
541 for (i = 0; i < sa->num; i++)
542 if (!FcStrSetMember (sb, sa->strs[i]))
548 FcStrSetAdd (FcStrSet *set, const FcChar8 *s)
550 FcChar8 *new = FcStrCopy (s);
553 if (!_FcStrSetAppend (set, new))
562 FcStrSetAddFilename (FcStrSet *set, const FcChar8 *s)
564 FcChar8 *new = FcStrCopyFilename (s);
567 if (!_FcStrSetAppend (set, new))
576 FcStrSetDel (FcStrSet *set, const FcChar8 *s)
580 for (i = 0; i < set->num; i++)
581 if (!FcStrCmp (set->strs[i], s))
583 FcStrFree (set->strs[i]);
585 * copy remaining string pointers and trailing
588 memmove (&set->strs[i], &set->strs[i+1],
589 (set->num - i) * sizeof (FcChar8 *));
597 FcStrSetDestroy (FcStrSet *set)
603 for (i = 0; i < set->num; i++)
604 FcStrFree (set->strs[i]);
605 FcMemFree (FC_MEM_STRSET, (set->size) * sizeof (FcChar8 *));
608 FcMemFree (FC_MEM_STRSET, sizeof (FcStrSet));
614 FcStrListCreate (FcStrSet *set)
618 list = malloc (sizeof (FcStrList));
621 FcMemAlloc (FC_MEM_STRLIST, sizeof (FcStrList));
629 FcStrListNext (FcStrList *list)
631 if (list->n >= list->set->num)
633 return list->set->strs[list->n++];
637 FcStrListDone (FcStrList *list)
639 FcStrSetDestroy (list->set);
640 FcMemFree (FC_MEM_STRLIST, sizeof (FcStrList));