fcobjs.c revision 953daeba
1/*
2 * fontconfig/src/fclist.c
3 *
4 * Copyright © 2000 Keith Packard
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 the author(s) not be used in
11 * advertising or publicity pertaining to distribution of the software without
12 * specific, written prior permission.  The authors make 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 * THE AUTHOR(S) DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
17 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
18 * EVENT SHALL THE AUTHOR(S) 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 "fcint.h"
26
27static unsigned int
28FcObjectTypeHash (register const char *str, register FC_GPERF_SIZE_T len);
29
30static const struct FcObjectTypeInfo *
31FcObjectTypeLookup (register const char *str, register FC_GPERF_SIZE_T len);
32
33#include "fcobjshash.h"
34
35#include <string.h>
36
37/* The 1000 is to leave some room for future added internal objects, such
38 * that caches from newer fontconfig can still be used with older fontconfig
39 * without getting confused. */
40static fc_atomic_int_t next_id = FC_MAX_BASE_OBJECT + FC_EXT_OBJ_INDEX;
41struct FcObjectOtherTypeInfo {
42    struct FcObjectOtherTypeInfo *next;
43    FcObjectType object;
44    FcObject id;
45} *other_types;
46
47void
48FcObjectFini (void)
49{
50    struct FcObjectOtherTypeInfo *ots, *ot;
51
52retry:
53    ots = fc_atomic_ptr_get (&other_types);
54    if (!ots)
55	return;
56    if (!fc_atomic_ptr_cmpexch (&other_types, ots, NULL))
57	goto retry;
58
59    while (ots)
60    {
61	ot = ots->next;
62	if (ots->object.object)
63	    free (ots->object.object);
64	free (ots);
65	ots = ot;
66    }
67}
68
69static FcObjectType *
70_FcObjectLookupOtherTypeByName (const char *str, FcObject *id)
71{
72    struct FcObjectOtherTypeInfo *ots, *ot;
73
74retry:
75    ots = fc_atomic_ptr_get (&other_types);
76
77    for (ot = ots; ot; ot = ot->next)
78	if (0 == strcmp (ot->object.object, str))
79	    break;
80
81    if (!ot)
82    {
83	ot = malloc (sizeof (*ot));
84	if (!ot)
85	    return NULL;
86
87	ot->object.object = (char *) FcStrdup (str);
88	ot->object.type = FcTypeUnknown;
89	ot->id = fc_atomic_int_add (next_id, +1);
90	if (ot->id < (FC_MAX_BASE_OBJECT + FC_EXT_OBJ_INDEX))
91	{
92	    fprintf (stderr, "Fontconfig error: No object ID to assign\n");
93	    abort ();
94	}
95	ot->next = ots;
96
97	if (!fc_atomic_ptr_cmpexch (&other_types, ots, ot)) {
98	    if (ot->object.object)
99		free (ot->object.object);
100	    free (ot);
101	    goto retry;
102	}
103    }
104
105    if (id)
106      *id = ot->id;
107
108    return &ot->object;
109}
110
111FcObject
112FcObjectLookupBuiltinIdByName (const char *str)
113{
114    const struct FcObjectTypeInfo *o = FcObjectTypeLookup (str, strlen (str));
115
116    if (o)
117	return o->id;
118
119    return 0;
120}
121
122FcObject
123FcObjectLookupIdByName (const char *str)
124{
125    const struct FcObjectTypeInfo *o = FcObjectTypeLookup (str, strlen (str));
126    FcObject id;
127    if (o)
128	return o->id;
129
130    if (_FcObjectLookupOtherTypeByName (str, &id))
131	return id;
132
133    return 0;
134}
135
136const char *
137FcObjectLookupOtherNameById (FcObject id)
138{
139    struct FcObjectOtherTypeInfo *ot;
140
141    for (ot = fc_atomic_ptr_get (&other_types); ot; ot = ot->next)
142	if (ot->id == id)
143	    return ot->object.object;
144
145    return NULL;
146}
147
148const FcObjectType *
149FcObjectLookupOtherTypeByName (const char *str)
150{
151    return _FcObjectLookupOtherTypeByName (str, NULL);
152}
153
154FcPrivate const FcObjectType *
155FcObjectLookupOtherTypeById (FcObject id)
156{
157    struct FcObjectOtherTypeInfo *ot;
158
159    for (ot = fc_atomic_ptr_get (&other_types); ot; ot = ot->next)
160	if (ot->id == id)
161	    return &ot->object;
162
163    return NULL;
164}
165
166
167#include "fcaliastail.h"
168#undef __fcobjs__
169