2 * $XFree86: xc/lib/fontconfig/src/fcstr.c,v 1.7 2002/07/13 05:43:25 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 (FcChar8 *src_orig,
132 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 (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 (FcChar8 *src_orig,
261 int len) /* in bytes */
263 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 (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)
345 FcStrBufInit (buf, 0, 0);
350 FcStrBufDone (FcStrBuf *buf)
354 ret = malloc (buf->len + 1);
357 memcpy (ret, buf->buf, buf->len);
358 ret[buf->len] = '\0';
360 FcStrBufDestroy (buf);
365 FcStrBufChar (FcStrBuf *buf, FcChar8 c)
367 if (buf->len == buf->size)
374 size = buf->size * 2;
375 new = realloc (buf->buf, size);
379 size = buf->size + 1024;
383 buf->allocated = FcTrue;
384 memcpy (new, buf->buf, buf->len);
389 buf->failed = FcTrue;
395 buf->buf[buf->len++] = c;
400 FcStrBufString (FcStrBuf *buf, const FcChar8 *s)
404 if (!FcStrBufChar (buf, c))
410 FcStrBufData (FcStrBuf *buf, const FcChar8 *s, int len)
413 if (!FcStrBufChar (buf, *s++))
419 FcStrCopyFilename (const FcChar8 *s)
425 FcChar8 *home = (FcChar8 *) getenv ("HOME");
426 int size = strlen ((char *) home) + strlen ((char *) s);
429 new = (FcChar8 *) malloc (size);
432 FcMemAlloc (FC_MEM_STRING, size);
433 strcpy ((char *) new, (char *) home);
434 strcat ((char *) new, (char *) s + 1);
438 int size = strlen ((char *) s) + 1;
439 new = (FcChar8 *) malloc (size);
442 FcMemAlloc (FC_MEM_STRING, size);
443 strcpy ((char *) new, (const char *) s);
449 FcStrDirname (const FcChar8 *file)
454 slash = (FcChar8 *) strrchr ((char *) file, '/');
456 return FcStrCopy ((FcChar8 *) ".");
457 dir = malloc ((slash - file) + 1);
460 FcMemAlloc (FC_MEM_STRING, (slash - file) + 1);
461 strncpy ((char *) dir, (const char *) file, slash - file);
462 dir[slash - file] = '\0';
467 FcStrBasename (const FcChar8 *file)
471 slash = (FcChar8 *) strrchr ((char *) file, '/');
473 return FcStrCopy (file);
474 return FcStrCopy (slash + 1);
478 FcStrSetCreate (void)
480 FcStrSet *set = malloc (sizeof (FcStrSet));
483 FcMemAlloc (FC_MEM_STRSET, sizeof (FcStrSet));
492 _FcStrSetAppend (FcStrSet *set, FcChar8 *s)
494 if (FcStrSetMember (set, s))
499 if (set->num == set->size)
501 FcChar8 **strs = malloc ((set->size + 2) * sizeof (FcChar8 *));
505 FcMemAlloc (FC_MEM_STRSET, (set->size + 2) * sizeof (FcChar8 *));
506 set->size = set->size + 1;
508 memcpy (strs, set->strs, set->num * sizeof (FcChar8 *));
513 set->strs[set->num++] = s;
514 set->strs[set->num] = 0;
519 FcStrSetMember (FcStrSet *set, const FcChar8 *s)
523 for (i = 0; i < set->num; i++)
524 if (!FcStrCmp (set->strs[i], s))
530 FcStrSetEqual (FcStrSet *sa, FcStrSet *sb)
533 if (sa->num != sb->num)
535 for (i = 0; i < sa->num; i++)
536 if (!FcStrSetMember (sb, sa->strs[i]))
542 FcStrSetAdd (FcStrSet *set, const FcChar8 *s)
544 FcChar8 *new = FcStrCopy (s);
547 if (!_FcStrSetAppend (set, new))
556 FcStrSetAddFilename (FcStrSet *set, const FcChar8 *s)
558 FcChar8 *new = FcStrCopyFilename (s);
561 if (!_FcStrSetAppend (set, new))
570 FcStrSetDel (FcStrSet *set, const FcChar8 *s)
574 for (i = 0; i < set->num; i++)
575 if (!FcStrCmp (set->strs[i], s))
577 FcStrFree (set->strs[i]);
579 * copy remaining string pointers and trailing
582 memmove (&set->strs[i], &set->strs[i+1],
583 (set->num - i) * sizeof (FcChar8 *));
591 FcStrSetDestroy (FcStrSet *set)
597 for (i = 0; i < set->num; i++)
598 FcStrFree (set->strs[i]);
599 FcMemFree (FC_MEM_STRSET, (set->size) * sizeof (FcChar8 *));
602 FcMemFree (FC_MEM_STRSET, sizeof (FcStrSet));
608 FcStrListCreate (FcStrSet *set)
612 list = malloc (sizeof (FcStrList));
615 FcMemAlloc (FC_MEM_STRLIST, sizeof (FcStrList));
623 FcStrListNext (FcStrList *list)
625 if (list->n >= list->set->num)
627 return list->set->strs[list->n++];
631 FcStrListDone (FcStrList *list)
633 FcStrSetDestroy (list->set);
634 FcMemFree (FC_MEM_STRLIST, sizeof (FcStrList));