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)
85 return (int) c1 - (int) c2;
89 FcStrCmpIgnoreBlanksAndCase (const FcChar8 *s1, const FcChar8 *s2)
108 return (int) c1 - (int) c2;
112 FcStrCmp (const FcChar8 *s1, const FcChar8 *s2)
127 return (int) c1 - (int) c2;
131 FcUtf8ToUcs4 (const FcChar8 *src_orig,
135 const FcChar8 *src = src_orig;
151 else if (!(s & 0x40))
155 else if (!(s & 0x20))
160 else if (!(s & 0x10))
165 else if (!(s & 0x08))
170 else if (!(s & 0x04))
175 else if ( ! (s & 0x02))
192 if ((s & 0xc0) != 0x80)
198 return src - src_orig;
202 FcUtf8Len (const FcChar8 *string,
216 clen = FcUtf8ToUcs4 (string, &c, len);
217 if (clen <= 0) /* malformed UTF8 string */
228 else if (max > 0x100)
236 FcUcs4ToUtf8 (FcChar32 ucs4,
237 FcChar8 dest[FC_UTF8_MAX_LEN])
242 if (ucs4 < 0x80) { *d++= ucs4; bits= -6; }
243 else if (ucs4 < 0x800) { *d++= ((ucs4 >> 6) & 0x1F) | 0xC0; bits= 0; }
244 else if (ucs4 < 0x10000) { *d++= ((ucs4 >> 12) & 0x0F) | 0xE0; bits= 6; }
245 else if (ucs4 < 0x200000) { *d++= ((ucs4 >> 18) & 0x07) | 0xF0; bits= 12; }
246 else if (ucs4 < 0x4000000) { *d++= ((ucs4 >> 24) & 0x03) | 0xF8; bits= 18; }
247 else if (ucs4 < 0x80000000) { *d++= ((ucs4 >> 30) & 0x01) | 0xFC; bits= 24; }
250 for ( ; bits >= 0; bits-= 6) {
251 *d++= ((ucs4 >> bits) & 0x3F) | 0x80;
256 #define GetUtf16(src,endian) \
257 ((FcChar16) ((src)[endian == FcEndianBig ? 0 : 1] << 8) | \
258 (FcChar16) ((src)[endian == FcEndianBig ? 1 : 0]))
261 FcUtf16ToUcs4 (const FcChar8 *src_orig,
264 int len) /* in bytes */
266 const FcChar8 *src = src_orig;
273 a = GetUtf16 (src, endian); src += 2; len -= 2;
276 * Check for surrogate
278 if ((a & 0xfc00) == 0xd800)
282 b = GetUtf16 (src, endian); src += 2; len -= 2;
284 * Check for invalid surrogate sequence
286 if ((b & 0xfc00) != 0xdc00)
288 result = ((((FcChar32) a & 0x3ff) << 10) |
289 ((FcChar32) b & 0x3ff)) + 0x10000;
294 return src - src_orig;
298 FcUtf16Len (const FcChar8 *string,
300 int len, /* in bytes */
313 clen = FcUtf16ToUcs4 (string, endian, &c, len);
314 if (clen <= 0) /* malformed UTF8 string */
325 else if (max > 0x100)
333 FcStrBufInit (FcStrBuf *buf, FcChar8 *init, int size)
336 buf->allocated = FcFalse;
337 buf->failed = FcFalse;
343 FcStrBufDestroy (FcStrBuf *buf)
347 FcMemFree (FC_MEM_STRBUF, buf->size);
349 FcStrBufInit (buf, 0, 0);
354 FcStrBufDone (FcStrBuf *buf)
358 ret = malloc (buf->len + 1);
361 FcMemAlloc (FC_MEM_STRING, buf->len + 1);
362 memcpy (ret, buf->buf, buf->len);
363 ret[buf->len] = '\0';
365 FcStrBufDestroy (buf);
370 FcStrBufChar (FcStrBuf *buf, FcChar8 c)
372 if (buf->len == buf->size)
379 size = buf->size * 2;
380 new = realloc (buf->buf, size);
384 size = buf->size + 1024;
388 buf->allocated = FcTrue;
389 memcpy (new, buf->buf, buf->len);
394 buf->failed = FcTrue;
398 FcMemFree (FC_MEM_STRBUF, buf->size);
399 FcMemAlloc (FC_MEM_STRBUF, size);
403 buf->buf[buf->len++] = c;
408 FcStrBufString (FcStrBuf *buf, const FcChar8 *s)
412 if (!FcStrBufChar (buf, c))
418 FcStrBufData (FcStrBuf *buf, const FcChar8 *s, int len)
421 if (!FcStrBufChar (buf, *s++))
427 FcStrCopyFilename (const FcChar8 *s)
433 FcChar8 *home = (FcChar8 *) getenv ("HOME");
437 size = strlen ((char *) home) + strlen ((char *) s);
438 new = (FcChar8 *) malloc (size);
441 FcMemAlloc (FC_MEM_STRING, size);
442 strcpy ((char *) new, (char *) home);
443 strcat ((char *) new, (char *) s + 1);
447 int size = strlen ((char *) s) + 1;
448 new = (FcChar8 *) malloc (size);
451 FcMemAlloc (FC_MEM_STRING, size);
452 strcpy ((char *) new, (const char *) s);
458 FcStrDirname (const FcChar8 *file)
463 slash = (FcChar8 *) strrchr ((char *) file, '/');
465 return FcStrCopy ((FcChar8 *) ".");
466 dir = malloc ((slash - file) + 1);
469 FcMemAlloc (FC_MEM_STRING, (slash - file) + 1);
470 strncpy ((char *) dir, (const char *) file, slash - file);
471 dir[slash - file] = '\0';
476 FcStrBasename (const FcChar8 *file)
480 slash = (FcChar8 *) strrchr ((char *) file, '/');
482 return FcStrCopy (file);
483 return FcStrCopy (slash + 1);
487 FcStrSetCreate (void)
489 FcStrSet *set = malloc (sizeof (FcStrSet));
492 FcMemAlloc (FC_MEM_STRSET, sizeof (FcStrSet));
501 _FcStrSetAppend (FcStrSet *set, FcChar8 *s)
503 if (FcStrSetMember (set, s))
508 if (set->num == set->size)
510 FcChar8 **strs = malloc ((set->size + 2) * sizeof (FcChar8 *));
514 FcMemAlloc (FC_MEM_STRSET, (set->size + 2) * sizeof (FcChar8 *));
515 set->size = set->size + 1;
517 memcpy (strs, set->strs, set->num * sizeof (FcChar8 *));
522 set->strs[set->num++] = s;
523 set->strs[set->num] = 0;
528 FcStrSetMember (FcStrSet *set, const FcChar8 *s)
532 for (i = 0; i < set->num; i++)
533 if (!FcStrCmp (set->strs[i], s))
539 FcStrSetEqual (FcStrSet *sa, FcStrSet *sb)
542 if (sa->num != sb->num)
544 for (i = 0; i < sa->num; i++)
545 if (!FcStrSetMember (sb, sa->strs[i]))
551 FcStrSetAdd (FcStrSet *set, const FcChar8 *s)
553 FcChar8 *new = FcStrCopy (s);
556 if (!_FcStrSetAppend (set, new))
565 FcStrSetAddFilename (FcStrSet *set, const FcChar8 *s)
567 FcChar8 *new = FcStrCopyFilename (s);
570 if (!_FcStrSetAppend (set, new))
579 FcStrSetDel (FcStrSet *set, const FcChar8 *s)
583 for (i = 0; i < set->num; i++)
584 if (!FcStrCmp (set->strs[i], s))
586 FcStrFree (set->strs[i]);
588 * copy remaining string pointers and trailing
591 memmove (&set->strs[i], &set->strs[i+1],
592 (set->num - i) * sizeof (FcChar8 *));
600 FcStrSetDestroy (FcStrSet *set)
606 for (i = 0; i < set->num; i++)
607 FcStrFree (set->strs[i]);
608 FcMemFree (FC_MEM_STRSET, (set->size) * sizeof (FcChar8 *));
611 FcMemFree (FC_MEM_STRSET, sizeof (FcStrSet));
617 FcStrListCreate (FcStrSet *set)
621 list = malloc (sizeof (FcStrList));
624 FcMemAlloc (FC_MEM_STRLIST, sizeof (FcStrList));
632 FcStrListNext (FcStrList *list)
634 if (list->n >= list->set->num)
636 return list->set->strs[list->n++];
640 FcStrListDone (FcStrList *list)
642 FcStrSetDestroy (list->set);
643 FcMemFree (FC_MEM_STRLIST, sizeof (FcStrList));