Coverage Report

Created: 2025-07-07 10:01

/work/workdir/UnpackedTarball/fontconfig/src/fcobjs.c
Line
Count
Source (jump to first uncovered line)
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
27
static unsigned int
28
FcObjectTypeHash (register const char *str, register FC_GPERF_SIZE_T len);
29
30
static const struct FcObjectTypeInfo *
31
FcObjectTypeLookup (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. */
40
static fc_atomic_int_t next_id = FC_MAX_BASE_OBJECT + FC_EXT_OBJ_INDEX;
41
struct FcObjectOtherTypeInfo {
42
    struct FcObjectOtherTypeInfo *next;
43
    FcObjectType                  object;
44
    FcObject                      id;
45
} *other_types;
46
static FcRef obj_ref = { .count = 0 };
47
48
void
49
FcObjectInit (void)
50
106
{
51
106
    FcRefInc (&obj_ref);
52
106
}
53
54
void
55
FcObjectFini (void)
56
0
{
57
0
    struct FcObjectOtherTypeInfo *ots, *ot;
58
59
0
retry:
60
0
    if (obj_ref.count < 1)
61
0
  fprintf (stderr, "Fontconfig warning: too many caller of FcObjectFini()\n");
62
0
    if (obj_ref.count >= 1 && FcRefDec (&obj_ref) != 1)
63
0
  return;
64
0
    ots = fc_atomic_ptr_get (&other_types);
65
0
    if (!ots)
66
0
  return;
67
0
    if (!fc_atomic_ptr_cmpexch (&other_types, ots, NULL)) {
68
0
  FcRefInc (&obj_ref);
69
0
  goto retry;
70
0
    }
71
72
0
    while (ots) {
73
0
  ot = ots->next;
74
0
  if (ots->object.object)
75
0
      free (ots->object.object);
76
0
  free (ots);
77
0
  ots = ot;
78
0
    }
79
0
}
80
81
static FcObjectType *
82
_FcObjectLookupOtherTypeByName (const char *str, FcObject *id)
83
802
{
84
802
    struct FcObjectOtherTypeInfo *ots, *ot;
85
802
    static FcBool                 warn = FcFalse;
86
87
802
retry:
88
802
    ots = fc_atomic_ptr_get (&other_types);
89
802
    if (obj_ref.count < 1) {
90
0
  if (!warn) {
91
0
      fprintf (stderr, "Fontconfig warning: using without calling FcInit()\n");
92
0
      warn = FcTrue;
93
0
  }
94
0
  FcObjectInit();
95
0
    }
96
97
802
    for (ot = ots; ot; ot = ot->next)
98
800
  if (0 == strcmp (ot->object.object, str))
99
800
      break;
100
101
802
    if (!ot) {
102
2
  ot = malloc (sizeof (*ot));
103
2
  if (!ot)
104
0
      return NULL;
105
106
2
  ot->object.object = (char *)FcStrdup (str);
107
2
  ot->object.type = FcTypeUnknown;
108
2
  ot->id = fc_atomic_int_add (next_id, +1);
109
2
  if (ot->id < (FC_MAX_BASE_OBJECT + FC_EXT_OBJ_INDEX)) {
110
0
      fprintf (stderr, "Fontconfig error: No object ID to assign\n");
111
0
      abort();
112
0
  }
113
2
  ot->next = ots;
114
115
2
  if (!fc_atomic_ptr_cmpexch (&other_types, ots, ot)) {
116
0
      if (ot->object.object)
117
0
    free (ot->object.object);
118
0
      free (ot);
119
0
      goto retry;
120
0
  }
121
2
    }
122
123
802
    if (id)
124
802
  *id = ot->id;
125
126
802
    return &ot->object;
127
802
}
128
129
FcObject
130
FcObjectLookupBuiltinIdByName (const char *str)
131
0
{
132
0
    const struct FcObjectTypeInfo *o = FcObjectTypeLookup (str, strlen (str));
133
134
0
    if (o)
135
0
  return o->id;
136
137
0
    return 0;
138
0
}
139
140
FcObject
141
FcObjectLookupIdByName (const char *str)
142
71.9k
{
143
71.9k
    const struct FcObjectTypeInfo *o = FcObjectTypeLookup (str, strlen (str));
144
71.9k
    FcObject                       id;
145
71.9k
    if (o)
146
71.1k
  return o->id;
147
148
802
    if (_FcObjectLookupOtherTypeByName (str, &id))
149
802
  return id;
150
151
0
    return 0;
152
802
}
153
154
const char *
155
FcObjectLookupOtherNameById (FcObject id)
156
0
{
157
0
    struct FcObjectOtherTypeInfo *ot;
158
159
0
    for (ot = fc_atomic_ptr_get (&other_types); ot; ot = ot->next)
160
0
  if (ot->id == id)
161
0
      return ot->object.object;
162
163
0
    return NULL;
164
0
}
165
166
const FcObjectType *
167
FcObjectLookupOtherTypeByName (const char *str)
168
0
{
169
0
    return _FcObjectLookupOtherTypeByName (str, NULL);
170
0
}
171
172
FcPrivate const FcObjectType *
173
FcObjectLookupOtherTypeById (FcObject id)
174
0
{
175
0
    struct FcObjectOtherTypeInfo *ot;
176
177
0
    for (ot = fc_atomic_ptr_get (&other_types); ot; ot = ot->next)
178
0
  if (ot->id == id)
179
0
      return &ot->object;
180
181
0
    return NULL;
182
0
}
183
184
#include "fcaliastail.h"
185
#undef __fcobjs__