]> git.wh0rd.org Git - fontconfig.git/blob - src/fcstr.c
Fix autoconf build process for fontconfig
[fontconfig.git] / src / fcstr.c
1 /*
2  * $XFree86: xc/lib/fontconfig/src/fcstr.c,v 1.3 2002/02/18 22:29:28 keithp Exp $
3  *
4  * Copyright © 2000 Keith Packard, member of The XFree86 Project, Inc.
5  *
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.
15  *
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.
23  */
24
25 #include <stdlib.h>
26 #include <ctype.h>
27 #include <string.h>
28 #include "fcint.h"
29
30 FcChar8 *
31 FcStrCopy (const FcChar8 *s)
32 {
33     FcChar8     *r;
34
35     if (!s)
36         return 0;
37     r = (FcChar8 *) malloc (strlen ((char *) s) + 1);
38     if (!r)
39         return 0;
40     FcMemAlloc (FC_MEM_STRING, strlen ((char *) s) + 1);
41     strcpy ((char *) r, (char *) s);
42     return r;
43 }
44
45 FcChar8 *
46 FcStrPlus (const FcChar8 *s1, const FcChar8 *s2)
47 {
48     int     l = strlen ((char *)s1) + strlen ((char *) s2) + 1;
49     FcChar8 *s = malloc (l);
50
51     if (!s)
52         return 0;
53     FcMemAlloc (FC_MEM_STRING, l);
54     strcpy ((char *) s, (char *) s1);
55     strcat ((char *) s, (char *) s2);
56     return s;
57 }
58
59 void
60 FcStrFree (FcChar8 *s)
61 {
62     FcMemFree (FC_MEM_STRING, strlen ((char *) s) + 1);
63     free (s);
64 }
65
66 int
67 FcStrCmpIgnoreCase (const FcChar8 *s1, const FcChar8 *s2)
68 {
69     FcChar8 c1, c2;
70     
71     for (;;) 
72     {
73         c1 = *s1++;
74         c2 = *s2++;
75         if (!c1 || !c2)
76             break;
77         c1 = FcToLower (c1);
78         c2 = FcToLower (c2);
79         if (c1 != c2)
80             break;
81     }
82     return (int) c2 - (int) c1;
83 }
84
85 int
86 FcStrCmp (const FcChar8 *s1, const FcChar8 *s2)
87 {
88     FcChar8 c1, c2;
89     
90     if (s1 == s2)
91         return 0;
92     for (;;) 
93     {
94         c1 = *s1++;
95         c2 = *s2++;
96         if (!c1 || !c2)
97             break;
98         if (c1 != c2)
99             break;
100     }
101     return (int) c2 - (int) c1;
102 }
103
104 int
105 FcUtf8ToUcs4 (FcChar8   *src_orig,
106               FcChar32  *dst,
107               int       len)
108 {
109     FcChar8     *src = src_orig;
110     FcChar8     s;
111     int         extra;
112     FcChar32    result;
113
114     if (len == 0)
115         return 0;
116     
117     s = *src++;
118     len--;
119     
120     if (!(s & 0x80))
121     {
122         result = s;
123         extra = 0;
124     } 
125     else if (!(s & 0x40))
126     {
127         return -1;
128     }
129     else if (!(s & 0x20))
130     {
131         result = s & 0x1f;
132         extra = 1;
133     }
134     else if (!(s & 0x10))
135     {
136         result = s & 0xf;
137         extra = 2;
138     }
139     else if (!(s & 0x08))
140     {
141         result = s & 0x07;
142         extra = 3;
143     }
144     else if (!(s & 0x04))
145     {
146         result = s & 0x03;
147         extra = 4;
148     }
149     else if ( ! (s & 0x02))
150     {
151         result = s & 0x01;
152         extra = 5;
153     }
154     else
155     {
156         return -1;
157     }
158     if (extra > len)
159         return -1;
160     
161     while (extra--)
162     {
163         result <<= 6;
164         s = *src++;
165         
166         if ((s & 0xc0) != 0x80)
167             return -1;
168         
169         result |= s & 0x3f;
170     }
171     *dst = result;
172     return src - src_orig;
173 }
174
175 FcBool
176 FcUtf8Len (FcChar8      *string,
177             int         len,
178             int         *nchar,
179             int         *wchar)
180 {
181     int         n;
182     int         clen;
183     FcChar32    c;
184     FcChar32    max;
185     
186     n = 0;
187     max = 0;
188     while (len)
189     {
190         clen = FcUtf8ToUcs4 (string, &c, len);
191         if (clen <= 0)  /* malformed UTF8 string */
192             return FcFalse;
193         if (c > max)
194             max = c;
195         string += clen;
196         len -= clen;
197         n++;
198     }
199     *nchar = n;
200     if (max >= 0x10000)
201         *wchar = 4;
202     else if (max > 0x100)
203         *wchar = 2;
204     else
205         *wchar = 1;
206     return FcTrue;
207 }
208
209 void
210 FcStrBufInit (FcStrBuf *buf, FcChar8 *init, int size)
211 {
212     buf->buf = init;
213     buf->allocated = FcFalse;
214     buf->failed = FcFalse;
215     buf->len = 0;
216     buf->size = size;
217 }
218
219 void
220 FcStrBufDestroy (FcStrBuf *buf)
221 {
222     if (buf->allocated)
223     {
224         free (buf->buf);
225         FcStrBufInit (buf, 0, 0);
226     }
227 }
228
229 FcChar8 *
230 FcStrBufDone (FcStrBuf *buf)
231 {
232     FcChar8 *ret;
233
234     ret = malloc (buf->len + 1);
235     if (ret)
236     {
237         memcpy (ret, buf->buf, buf->len);
238         ret[buf->len] = '\0';
239     }
240     FcStrBufDestroy (buf);
241     return ret;
242 }
243
244 FcBool
245 FcStrBufChar (FcStrBuf *buf, FcChar8 c)
246 {
247     if (buf->len == buf->size)
248     {
249         FcChar8     *new;
250         int         size;
251
252         if (buf->allocated)
253         {
254             size = buf->size * 2;
255             new = realloc (buf->buf, size);
256         }
257         else
258         {
259             size = buf->size + 1024;
260             new = malloc (size);
261             if (new)
262             {
263                 buf->allocated = FcTrue;
264                 memcpy (new, buf->buf, buf->len);
265             }
266         }
267         if (!new)
268         {
269             buf->failed = FcTrue;
270             return FcFalse;
271         }
272         buf->size = size;
273         buf->buf = new;
274     }
275     buf->buf[buf->len++] = c;
276     return FcTrue;
277 }
278
279 FcBool
280 FcStrBufString (FcStrBuf *buf, const FcChar8 *s)
281 {
282     FcChar8 c;
283     while ((c = *s++))
284         if (!FcStrBufChar (buf, c))
285             return FcFalse;
286     return FcTrue;
287 }
288
289 FcBool
290 FcStrBufData (FcStrBuf *buf, const FcChar8 *s, int len)
291 {
292     while (len-- > 0)
293         if (!FcStrBufChar (buf, *s++))
294             return FcFalse;
295     return FcTrue;
296 }
297
298 FcChar8 *
299 FcStrCopyFilename (const FcChar8 *s)
300 {
301     FcChar8 *new;
302     
303     if (*s == '~')
304     {
305         FcChar8 *home = (FcChar8 *) getenv ("HOME");
306         int     size = strlen ((char *) home) + strlen ((char *) s);
307         if (!home)
308             return 0;
309         new = (FcChar8 *) malloc (size);
310         if (!new)
311             return 0;
312         FcMemAlloc (FC_MEM_STRING, size);
313         strcpy ((char *) new, (char *) home);
314         strcat ((char *) new, (char *) s + 1);
315     }
316     else
317     {
318         int     size = strlen ((char *) s) + 1;
319         new = (FcChar8 *) malloc (size);
320         if (!new)
321             return 0;
322         FcMemAlloc (FC_MEM_STRING, size);
323         strcpy ((char *) new, (const char *) s);
324     }
325     return new;
326 }
327
328 FcChar8 *
329 FcStrDirname (const FcChar8 *file)
330 {
331     FcChar8 *slash;
332     FcChar8 *dir;
333
334     slash = (FcChar8 *) strrchr ((char *) file, '/');
335     if (!slash)
336         return FcStrCopy ((FcChar8 *) ".");
337     dir = malloc ((slash - file) + 1);
338     if (!dir)
339         return 0;
340     FcMemAlloc (FC_MEM_STRING, (slash - file) + 1);
341     strncpy ((char *) dir, (const char *) file, slash - file);
342     dir[slash - file] = '\0';
343     return dir;
344 }
345
346 FcChar8 *
347 FcStrBasename (const FcChar8 *file)
348 {
349     FcChar8 *slash;
350
351     slash = (FcChar8 *) strrchr ((char *) file, '/');
352     if (!slash)
353         return FcStrCopy (file);
354     return FcStrCopy (slash + 1);
355 }
356
357 FcStrSet *
358 FcStrSetCreate (void)
359 {
360     FcStrSet    *set = malloc (sizeof (FcStrSet));
361     if (!set)
362         return 0;
363     FcMemAlloc (FC_MEM_STRSET, sizeof (FcStrSet));
364     set->ref = 1;
365     set->num = 0;
366     set->size = 0;
367     set->strs = 0;
368     return set;
369 }
370
371 static FcBool
372 _FcStrSetAppend (FcStrSet *set, FcChar8 *s)
373 {
374     if (FcStrSetMember (set, s))
375     {
376         FcStrFree (s);
377         return FcTrue;
378     }
379     if (set->num == set->size)
380     {
381         FcChar8 **strs = malloc ((set->size + 2) * sizeof (FcChar8 *));
382
383         if (!strs)
384             return FcFalse;
385         FcMemAlloc (FC_MEM_STRSET, (set->size + 2) * sizeof (FcChar8 *));
386         set->size = set->size + 1;
387         if (set->num)
388             memcpy (strs, set->strs, set->num * sizeof (FcChar8 *));
389         if (set->strs)
390             free (set->strs);
391         set->strs = strs;
392     }
393     set->strs[set->num++] = s;
394     set->strs[set->num] = 0;
395     return FcTrue;
396 }
397
398 FcBool
399 FcStrSetMember (FcStrSet *set, const FcChar8 *s)
400 {
401     int i;
402
403     for (i = 0; i < set->num; i++)
404         if (!FcStrCmp (set->strs[i], s))
405             return FcTrue;
406     return FcFalse;
407 }
408
409 FcBool
410 FcStrSetAdd (FcStrSet *set, const FcChar8 *s)
411 {
412     FcChar8 *new = FcStrCopy (s);
413     if (!new)
414         return FcFalse;
415     if (!_FcStrSetAppend (set, new))
416     {
417         FcStrFree (new);
418         return FcFalse;
419     }
420     return FcTrue;
421 }
422
423 FcBool
424 FcStrSetAddFilename (FcStrSet *set, const FcChar8 *s)
425 {
426     FcChar8 *new = FcStrCopyFilename (s);
427     if (!new)
428         return FcFalse;
429     if (!_FcStrSetAppend (set, new))
430     {
431         FcStrFree (new);
432         return FcFalse;
433     }
434     return FcTrue;
435 }
436
437 FcBool
438 FcStrSetDel (FcStrSet *set, const FcChar8 *s)
439 {
440     int i;
441
442     for (i = 0; i < set->num; i++)
443         if (!FcStrCmp (set->strs[i], s))
444         {
445             FcStrFree (set->strs[i]);
446             /*
447              * copy remaining string pointers and trailing
448              * NULL
449              */
450             memmove (&set->strs[i], &set->strs[i+1], 
451                      (set->num - i) * sizeof (FcChar8 *));
452             set->num--;
453             return FcTrue;
454         }
455     return FcFalse;
456 }
457
458 void
459 FcStrSetDestroy (FcStrSet *set)
460 {
461     if (--set->ref == 0)
462     {
463         int     i;
464     
465         for (i = 0; i < set->num; i++)
466             FcStrFree (set->strs[i]);
467         FcMemFree (FC_MEM_STRSET, (set->size) * sizeof (FcChar8 *));
468         if (set->strs)
469             free (set->strs);
470         FcMemFree (FC_MEM_STRSET, sizeof (FcStrSet));
471         free (set);
472     }
473 }
474
475 FcStrList *
476 FcStrListCreate (FcStrSet *set)
477 {
478     FcStrList   *list;
479
480     list = malloc (sizeof (FcStrList));
481     if (!list)
482         return 0;
483     FcMemAlloc (FC_MEM_STRLIST, sizeof (FcStrList));
484     list->set = set;
485     set->ref++;
486     list->n = 0;
487     return list;
488 }
489
490 FcChar8 *
491 FcStrListNext (FcStrList *list)
492 {
493     if (list->n >= list->set->num)
494         return 0;
495     return list->set->strs[list->n++];
496 }
497
498 void
499 FcStrListDone (FcStrList *list)
500 {
501     FcStrSetDestroy (list->set);
502     FcMemFree (FC_MEM_STRLIST, sizeof (FcStrList));
503     free (list);
504 }