Home | History | Annotate | Line # | Download | only in src
      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 #include "fcobjshash.h"
     28 
     29 #include <string.h>
     30 
     31 /* The 1000 is to leave some room for future added internal objects, such
     32  * that caches from newer fontconfig can still be used with older fontconfig
     33  * without getting confused. */
     34 static fc_atomic_int_t next_id = FC_MAX_BASE_OBJECT + FC_EXT_OBJ_INDEX;
     35 struct FcObjectOtherTypeInfo {
     36     struct FcObjectOtherTypeInfo *next;
     37     FcObjectType object;
     38     FcObject id;
     39 } *other_types;
     40 
     41 void
     42 FcObjectFini (void)
     43 {
     44     struct FcObjectOtherTypeInfo *ots, *ot;
     45 
     46 retry:
     47     ots = fc_atomic_ptr_get (&other_types);
     48     if (!ots)
     49 	return;
     50     if (!fc_atomic_ptr_cmpexch (&other_types, ots, NULL))
     51 	goto retry;
     52 
     53     while (ots)
     54     {
     55 	ot = ots->next;
     56 	if (ots->object.object)
     57 	    free (ots->object.object);
     58 	free (ots);
     59 	ots = ot;
     60     }
     61 }
     62 
     63 static FcObjectType *
     64 _FcObjectLookupOtherTypeByName (const char *str, FcObject *id)
     65 {
     66     struct FcObjectOtherTypeInfo *ots, *ot;
     67 
     68 retry:
     69     ots = fc_atomic_ptr_get (&other_types);
     70 
     71     for (ot = ots; ot; ot = ot->next)
     72 	if (0 == strcmp (ot->object.object, str))
     73 	    break;
     74 
     75     if (!ot)
     76     {
     77 	ot = malloc (sizeof (*ot));
     78 	if (!ot)
     79 	    return NULL;
     80 
     81 	ot->object.object = (char *) FcStrdup (str);
     82 	ot->object.type = FcTypeUnknown;
     83 	ot->id = fc_atomic_int_add (next_id, +1);
     84 	if (ot->id < (FC_MAX_BASE_OBJECT + FC_EXT_OBJ_INDEX))
     85 	{
     86 	    fprintf (stderr, "Fontconfig error: No object ID to assign\n");
     87 	    abort ();
     88 	}
     89 	ot->next = ots;
     90 
     91 	if (!fc_atomic_ptr_cmpexch (&other_types, ots, ot)) {
     92 	    if (ot->object.object)
     93 		free (ot->object.object);
     94 	    free (ot);
     95 	    goto retry;
     96 	}
     97     }
     98 
     99     if (id)
    100       *id = ot->id;
    101 
    102     return &ot->object;
    103 }
    104 
    105 FcObject
    106 FcObjectLookupBuiltinIdByName (const char *str)
    107 {
    108     const struct FcObjectTypeInfo *o = FcObjectTypeLookup (str, strlen (str));
    109 
    110     if (o)
    111 	return o->id;
    112 
    113     return 0;
    114 }
    115 
    116 FcObject
    117 FcObjectLookupIdByName (const char *str)
    118 {
    119     const struct FcObjectTypeInfo *o = FcObjectTypeLookup (str, strlen (str));
    120     FcObject id;
    121     if (o)
    122 	return o->id;
    123 
    124     if (_FcObjectLookupOtherTypeByName (str, &id))
    125 	return id;
    126 
    127     return 0;
    128 }
    129 
    130 const char *
    131 FcObjectLookupOtherNameById (FcObject id)
    132 {
    133     struct FcObjectOtherTypeInfo *ot;
    134 
    135     for (ot = fc_atomic_ptr_get (&other_types); ot; ot = ot->next)
    136 	if (ot->id == id)
    137 	    return ot->object.object;
    138 
    139     return NULL;
    140 }
    141 
    142 const FcObjectType *
    143 FcObjectLookupOtherTypeByName (const char *str)
    144 {
    145     return _FcObjectLookupOtherTypeByName (str, NULL);
    146 }
    147 
    148 FcPrivate const FcObjectType *
    149 FcObjectLookupOtherTypeById (FcObject id)
    150 {
    151     struct FcObjectOtherTypeInfo *ot;
    152 
    153     for (ot = fc_atomic_ptr_get (&other_types); ot; ot = ot->next)
    154 	if (ot->id == id)
    155 	    return &ot->object;
    156 
    157     return NULL;
    158 }
    159 
    160 
    161 #include "fcaliastail.h"
    162 #undef __fcobjs__
    163