]> git.wh0rd.org - fontconfig.git/commitdiff
Added new FcFini function for cleaning up all memory. Fixed a few memory
authorCarl Worth <cworth@cworth.org>
Fri, 15 Aug 2003 19:45:20 +0000 (19:45 +0000)
committerCarl Worth <cworth@cworth.org>
Fri, 15 Aug 2003 19:45:20 +0000 (19:45 +0000)
    leaks. fc-list now calls FcFini, (and is now leak-free according to
    valgrind)

15 files changed:
ChangeLog
doc/Makefile.am
doc/edit-sgml.c
doc/fcinit.fncs
fc-glyphname/fc-glyphname.c
fc-list/fc-list.c
fc-match/fc-match.c
fontconfig/fontconfig.h
src/fccfg.c
src/fccharset.c
src/fcinit.c
src/fcint.h
src/fcpat.c
src/fcxml.c
src/fontconfig.def.in

index 445421252319f42faea3f5e375ce22520a48098c..d265c74f622490caa3474437906f58d4269084a2 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,47 @@
+2003-08-15  Carl Worth  <cworth@isi.edu>
+
+       * src/fcxml.c (FcEditDestroy): Fix leak of FcEdit.
+       (FcPopExpr): Add comment about unhandled FcVStackGlob case.
+
+       * src/fcpat.c (FcValueListEntDestroy): New function to support
+       FcFini memory cleanup. Some statistics are not kept in
+       synch. here.
+       (FcValueListFreeze): Move hashTable outside this function so it
+       can be accessed by FcValueListThawAll.
+       (FcValueListThawAll): New function complements FcValueListFreeze.
+       (FcPatternBaseFreeze): Move hashTable outside this function so it
+       can be accessed by FcPatternBaseThawAll.
+       (FcPatternBaseThawAll): New function complements
+       FcPatternBaseFreeze.
+       (FcPatternThawAll): New function complements FcPatternFreeze.
+
+       * src/fcinit.c (FcFini): Add new FcFini to cleanup everything.
+
+       * src/fccharset.c (FcCharLeafEntCreate): Save pointers to all
+       allocated FcCharLeafEnt "blocks" so they can be freed later.
+       (FcCharSetFreezeLeaf): Move hashTable outside this function so it
+       can be accessed by FcCharSetThawAllLeaf.
+       (FcCharSetThawAllLeaf): New function complements FcCharSetFreezeLeaf.
+       (FcCharSetFreezeBase): Move hashTable outside this function so it
+       can be accessed by FcCharSetThawAll.
+       (FcCharSetThawAll): New function complements FcCharSetFreeze.
+
+       * src/fccfg.c (FcSubstDestroy): Fix leak of outer FcSubst.
+       (FcConfigDestroy): Fic leak of FcBlanks.
+
+       * fc-list/fc-list.c (main): Fix leak of FcObjectSet.
+       (main): Add call to FcFini when finished.
+
+       * fc-glyphname/fc-glyphname.c: Mark several local functions as
+       static. Add prototypes.
+
+       * doc/fcinit.fncs: Add documentation for FcFini function.
+
+       * doc/edit-sgml.c: Mark several local functions as static. Add
+       prototypes.
+
+       * doc/Makefile.am (DOC_MODULE): Fix "suspicious" lines.
+
 2003-06-15  Tor Lillqvist  <tml@iki.fi>
 
        * test/run-test.sh (FONTCONFIG_FILE): Remove CRs from the out file
index b98c13b21ee1660e3433e718ece13736c007f58f..7e1d70d346847c444ac0a915df7f463ef5cdbf12 100644 (file)
@@ -26,7 +26,7 @@ DOC_FUNCS_FNCS=\
        fcstring.fncs \
        fcstrset.fncs \
        fcvalue.fncs
-       
+
 DOC_FUNCS_SGML=\
        fcatomic.sgml \
        fcblanks.sgml \
@@ -60,7 +60,7 @@ FcConfigGetConfigDirs.3 FcConfigGetConfigFiles.3 FcConfigGetCurrent.3 \
 FcConfigGetFontDirs.3 FcConfigGetFonts.3 FcConfigGetRescanInverval.3 \
 FcConfigParseAndLoad.3 FcConfigSetCurrent.3 FcConfigSetRescanInverval.3 \
 FcConfigSubstitute.3 FcConfigSubstituteWithPat.3 FcConfigUptoDate.3 \
-FcDefaultSubstitute.3 FcDirCacheValid.3 FcDirSave.3 FcDirScan.3 FcFileScan.3 \
+FcDefaultSubstitute.3 FcDirCacheValid.3 FcDirSave.3 FcDirScan.3 FcFini.3 FcFileScan.3 \
 FcFontList.3 FcFontMatch.3 FcFontRenderPrepare.3 FcFontSetAdd.3 \
 FcFontSetCreate.3 FcFontSetDestroy.3 FcFontSort.3 FcFreeTypeCharIndex.3 \
 FcFreeTypeCharSet.3 FcFreeTypeQuery.3 FcGetVersion.3 FcInit.3 \
@@ -89,8 +89,8 @@ DOC_FILES=$(TXT) $(HTML_FILES)
 DOC_DIRS=$(HTML_DIRS)
 LOCAL_DOCS=$(man_MANS) $(DOC_FILES) $(DOC_DIRS)
 
-EXTRA_DIST = $(LOCAL_DOCS) $(SGML) $(DOC_FUNCS_FNCS) $(FNCS_TMPL)
-       
+EXTRA_DIST=$(LOCAL_DOCS) $(SGML) $(DOC_FUNCS_FNCS) $(FNCS_TMPL)
+
 SUFFIXES=.fncs .sgml .txt .html
 
 if USEDOCBOOK
index 407dd2c240cbb28dd6e4580261019b5ea884f648..2375140f80fdbea25fe93724331dbc9f0f32b5a6 100644 (file)
 #include <string.h>
 #include <ctype.h>
 
+static void *
+New (int size);
+
+static void *
+Reallocate (void *p, int size);
+
+static void
+Dispose (void *p);
+
 typedef enum { False, True } Bool;
 
 typedef struct {
@@ -35,9 +44,107 @@ typedef struct {
     int            len;
 } String;
 
+static String *
+StringNew (void);
+
+static void
+StringAdd (String *s, char c);
+
+static void
+StringAddString (String *s, char *buf);
+
+static String *
+StringMake (char *buf);
+
+static void
+StringDel (String *s);
+
+static void
+StringPut (FILE *f, String *s);
+
+static void
+StringDispose (String *s);
+
+typedef struct {
+    String  *tag;
+    String  *text;
+} Replace;
+
+static Replace *
+ReplaceNew (void);
+
+static void
+ReplaceDispose (Replace *r);
+
+static void
+Bail (char *format, char *arg);
+
+static Replace *
+ReplaceRead (FILE *f);
+
+typedef struct _replaceList {
+    struct _replaceList        *next;
+    Replace            *r;
+} ReplaceList;
+
+static ReplaceList *
+ReplaceListNew (Replace *r, ReplaceList *next);
+
+static void
+ReplaceListDispose (ReplaceList *l);
+
+typedef struct {
+    ReplaceList        *head;
+} ReplaceSet;
+
+static ReplaceSet *
+ReplaceSetNew (void);
+
+static void
+ReplaceSetDispose (ReplaceSet *s);
+
+static void
+ReplaceSetAdd (ReplaceSet *s, Replace *r);
+
+static Replace *
+ReplaceSetFind (ReplaceSet *s, char *tag);
+
+static ReplaceSet *
+ReplaceSetRead (FILE *f);
+
+typedef struct _skipStack {
+    struct _skipStack  *prev;
+    int                        skipping;
+} SkipStack;
+
+static SkipStack *
+SkipStackPush (SkipStack *prev, int skipping);
+
+static SkipStack *
+SkipStackPop (SkipStack *prev);
+
+typedef struct _loopStack {
+    struct _loopStack  *prev;
+    String             *tag;
+    String             *extra;
+    long               pos;
+} LoopStack;
+
+static LoopStack *
+LoopStackPush (LoopStack *prev, FILE *f, char *tag);
+
+static LoopStack *
+LoopStackLoop (ReplaceSet *rs, LoopStack *ls, FILE *f);
+
+static void
+LineSkip (FILE *f);
+
+static void
+DoReplace (FILE *f, ReplaceSet *s);
+
 #define STRING_INIT 128
 
-void *
+static void *
 New (int size)
 {
     void    *m = malloc (size);
@@ -46,7 +153,7 @@ New (int size)
     return m;
 }
 
-void *
+static void *
 Reallocate (void *p, int size)
 {
     void    *r = realloc (p, size);
@@ -56,13 +163,13 @@ Reallocate (void *p, int size)
     return r;
 }
 
-void
+static void
 Dispose (void *p)
 {
     free (p);
 }
 
-String *
+static String *
 StringNew (void)
 {
     String  *s;
@@ -75,7 +182,7 @@ StringNew (void)
     return s;
 }
 
-void
+static void
 StringAdd (String *s, char c)
 {
     if (s->len == s->size)
@@ -84,14 +191,14 @@ StringAdd (String *s, char c)
     s->buf[s->len] = '\0';
 }
 
-void
+static void
 StringAddString (String *s, char *buf)
 {
     while (*buf)
        StringAdd (s, *buf++);
 }
 
-String *
+static String *
 StringMake (char *buf)
 {
     String  *s = StringNew ();
@@ -99,14 +206,14 @@ StringMake (char *buf)
     return s;
 }
 
-void
+static void
 StringDel (String *s)
 {
     if (s->len)
        s->buf[--s->len] = '\0';
 }
 
-void
+static void
 StringPut (FILE *f, String *s)
 {
     char    *b = s->buf;
@@ -117,19 +224,14 @@ StringPut (FILE *f, String *s)
 
 #define StringLast(s)  ((s)->len ? (s)->buf[(s)->len - 1] : '\0')
 
-void
+static void
 StringDispose (String *s)
 {
     Dispose (s->buf);
     Dispose (s);
 }
 
-typedef struct {
-    String  *tag;
-    String  *text;
-} Replace;
-
-Replace *
+static Replace *
 ReplaceNew (void)
 {
     Replace *r = New (sizeof (Replace));
@@ -138,7 +240,7 @@ ReplaceNew (void)
     return r;
 }
 
-void
+static void
 ReplaceDispose (Replace *r)
 {
     StringDispose (r->tag);
@@ -146,7 +248,7 @@ ReplaceDispose (Replace *r)
     Dispose (r);
 }
 
-void
+static void
 Bail (char *format, char *arg)
 {
     fprintf (stderr, "fatal: ");
@@ -155,7 +257,7 @@ Bail (char *format, char *arg)
     exit (1);
 }
 
-Replace *
+static Replace *
 ReplaceRead (FILE *f)
 {
     int            c;
@@ -195,12 +297,7 @@ ReplaceRead (FILE *f)
     return r;
 }
 
-typedef struct _replaceList {
-    struct _replaceList        *next;
-    Replace            *r;
-} ReplaceList;
-
-ReplaceList *
+static ReplaceList *
 ReplaceListNew (Replace *r, ReplaceList *next)
 {
     ReplaceList        *l = New (sizeof (ReplaceList));
@@ -209,7 +306,7 @@ ReplaceListNew (Replace *r, ReplaceList *next)
     return l;
 }
 
-void
+static void
 ReplaceListDispose (ReplaceList *l)
 {
     if (l)
@@ -220,11 +317,7 @@ ReplaceListDispose (ReplaceList *l)
     }
 }
 
-typedef struct {
-    ReplaceList        *head;
-} ReplaceSet;
-
-ReplaceSet *
+static ReplaceSet *
 ReplaceSetNew (void)
 {
     ReplaceSet *s = New (sizeof (ReplaceSet));
@@ -232,20 +325,20 @@ ReplaceSetNew (void)
     return s;
 }
 
-void
+static void
 ReplaceSetDispose (ReplaceSet *s)
 {
     ReplaceListDispose (s->head);
     Dispose (s);
 }
 
-void
+static void
 ReplaceSetAdd (ReplaceSet *s, Replace *r)
 {
     s->head = ReplaceListNew (r, s->head);
 }
 
-Replace *
+static Replace *
 ReplaceSetFind (ReplaceSet *s, char *tag)
 {
     ReplaceList        *l;
@@ -256,7 +349,7 @@ ReplaceSetFind (ReplaceSet *s, char *tag)
     return 0;
 }
 
-ReplaceSet *
+static ReplaceSet *
 ReplaceSetRead (FILE *f)
 {
     ReplaceSet *s = ReplaceSetNew ();
@@ -276,12 +369,7 @@ ReplaceSetRead (FILE *f)
     return s;
 }
 
-typedef struct _skipStack {
-    struct _skipStack  *prev;
-    int                        skipping;
-} SkipStack;
-
-SkipStack *
+static SkipStack *
 SkipStackPush (SkipStack *prev, int skipping)
 {
     SkipStack  *ss = New (sizeof (SkipStack));
@@ -290,7 +378,7 @@ SkipStackPush (SkipStack *prev, int skipping)
     return ss;
 }
 
-SkipStack *
+static SkipStack *
 SkipStackPop (SkipStack *prev)
 {
     SkipStack  *ss = prev->prev;
@@ -298,14 +386,7 @@ SkipStackPop (SkipStack *prev)
     return ss;
 }
 
-typedef struct _loopStack {
-    struct _loopStack  *prev;
-    String             *tag;
-    String             *extra;
-    long               pos;
-} LoopStack;
-
-LoopStack *
+static LoopStack *
 LoopStackPush (LoopStack *prev, FILE *f, char *tag)
 {
     LoopStack  *ls = New (sizeof (LoopStack));
@@ -316,7 +397,7 @@ LoopStackPush (LoopStack *prev, FILE *f, char *tag)
     return ls;
 }
 
-LoopStack *
+static LoopStack *
 LoopStackLoop (ReplaceSet *rs, LoopStack *ls, FILE *f)
 {
     String     *s = StringMake (ls->tag->buf);
@@ -339,7 +420,7 @@ LoopStackLoop (ReplaceSet *rs, LoopStack *ls, FILE *f)
     return ret;
 }
 
-void
+static void
 LineSkip (FILE *f)
 {
     int        c;
@@ -349,7 +430,7 @@ LineSkip (FILE *f)
     ungetc (c, f);
 }
 
-void
+static void
 DoReplace (FILE *f, ReplaceSet *s)
 {
     int                c;
index bdf83fd86cbdf89283a1bb441bcfde97103dcc8e..04a3195ed3b1df491467081be3a943ffa5dcd03c 100644 (file)
@@ -50,6 +50,17 @@ process succeeded or not.  If the default configuration has already
 been loaded, this routine does nothing and returns FcTrue.
 @@
 
+@RET@          void
+@FUNC@         FcFini
+@TYPE1@                void
+@PURPOSE@      finalize fonconfig library
+@DESC@
+Frees all data structures allocated by previous calls to fontconfig
+functions. Fontconfig returns to an uninitialized state, requiring a
+new call to one of the FcInit functions before any other fontconfig
+function may be called.
+@@
+
 @RET@           int       
 @FUNC@          FcGetVersion 
 @TYPE1@                void
index fb18feade9ce15bb70b066b178cc7602777a6e55..769f4beb4d2a4bc5acb7fc206347040a184e300e 100644 (file)
 
 #include "fcint.h"
 
+static int
+rawindex (FcGlyphName *gn);
+
+static void
+scan (FILE *f, char *filename);
+
+static int
+isprime (int i);
+
+static void
+find_hash (void);
+
+static FcChar32
+FcHashGlyphName (const FcChar8 *name);
+
+static void
+insert (FcGlyphName *gn, FcGlyphName **table, FcChar32 h);
+
+static void
+dump (FcGlyphName **table, char *name);
+
 static FcGlyphName *
 FcAllocGlyphName (FcChar32 ucs, FcChar8 *name)
 {
@@ -55,7 +76,7 @@ FcGlyphName *name_to_ucs[MAX_GLYPHNAME*2];
 FcGlyphName *ucs_to_name[MAX_GLYPHNAME*2];
 int        hash, rehash;
 
-int
+static int
 rawindex (FcGlyphName *gn)
 {
     int        i;
@@ -66,7 +87,7 @@ rawindex (FcGlyphName *gn)
     return -1;
 }
 
-void
+static void
 scan (FILE *f, char *filename)
 {
     char           buf[MAX_NAMELEN];
@@ -122,7 +143,7 @@ isqrt (int a)
     return h;
 }
 
-int
+static int
 isprime (int i)
 {
     int        l, t;
@@ -146,7 +167,7 @@ isprime (int i)
  * Find a prime pair that leaves at least 25% of the hash table empty
  */
 
-void
+static void
 find_hash (void)
 {
     int        h;
@@ -160,7 +181,7 @@ find_hash (void)
     rehash = h-2;
 }
 
-FcChar32
+static FcChar32
 FcHashGlyphName (const FcChar8 *name)
 {
     FcChar32   h = 0;
@@ -173,7 +194,7 @@ FcHashGlyphName (const FcChar8 *name)
     return h;
 }
 
-void
+static void
 insert (FcGlyphName *gn, FcGlyphName **table, FcChar32 h)
 {
     int                i, r = 0;
@@ -189,7 +210,7 @@ insert (FcGlyphName *gn, FcGlyphName **table, FcChar32 h)
     table[i] = gn;
 }
 
-void
+static void
 dump (FcGlyphName **table, char *name)
 {
     int        i;
index 997a6acceb0a97b31db068fa42e3edcf7606023a..0fa1a8dccaf6f790b09cafdb06d93b7fa4b132b0 100644 (file)
@@ -137,6 +137,7 @@ main (int argc, char **argv)
     if (!os)
        os = FcObjectSetBuild (FC_FAMILY, FC_STYLE, (char *) 0);
     fs = FcFontList (0, pat, os);
+    FcObjectSetDestroy (os);
     if (pat)
        FcPatternDestroy (pat);
 
@@ -157,5 +158,8 @@ main (int argc, char **argv)
        }
        FcFontSetDestroy (fs);
     }
+
+    FcFini ();
+
     return 0;
 }
index 498018b0f8d891786babe85b40ff29081e70dacc..635c883c17059d3ac2ec65d30fb06b556e965f7f 100644 (file)
@@ -26,6 +26,7 @@
 #include <stdio.h>
 #include <unistd.h>
 #include <stdlib.h>
+#include <string.h>
 #ifdef HAVE_CONFIG_H
 #include <config.h>
 #else
@@ -91,7 +92,6 @@ main (int argc, char **argv)
     int                verbose = 0;
     int                sort = 0;
     int                i;
-    FcObjectSet *os = 0;
     FcFontSet  *fs;
     FcPattern   *pat;
     FcResult   result;
index 045a36b8e7ec9cd654bee98986b96c5c6fae8128..3cd7967ddea0673e155d03715278d1ffb2fba7c9 100644 (file)
@@ -452,6 +452,9 @@ FcInitLoadConfigAndFonts (void);
 FcBool
 FcInit (void);
 
+void
+FcFini (void);
+
 int
 FcGetVersion (void);
 
index 7b5d693b4a54f97bcd8c87c4b58f94a9534f6e85..12cad846f057a9c008d74a22554109caecdec423 100644 (file)
@@ -160,6 +160,8 @@ FcSubstDestroy (FcSubst *s)
            FcTestDestroy (s->test);
        if (s->edit)
            FcEditDestroy (s->edit);
+       free (s);
+       FcMemFree (FC_MEM_SUBST, sizeof (FcSubst));
        s = n;
     }
 }
@@ -178,6 +180,9 @@ FcConfigDestroy (FcConfig *config)
     FcStrSetDestroy (config->acceptGlobs);
     FcStrSetDestroy (config->rejectGlobs);
 
+    if (config->blanks)
+       FcBlanksDestroy (config->blanks);
+
     if (config->cache)
        FcStrFree (config->cache);
 
@@ -186,6 +191,7 @@ FcConfigDestroy (FcConfig *config)
     for (set = FcSetSystem; set <= FcSetApplication; set++)
        if (config->fonts[set])
            FcFontSetDestroy (config->fonts[set]);
+
     free (config);
     FcMemFree (FC_MEM_CONFIG, sizeof (FcConfig));
 }
index d87a720a5f4b31efd6bfd81efc503145377599f1..a1c8f890fbb480076ed26c44434e5341f1eb5f3d 100644 (file)
@@ -845,6 +845,8 @@ struct _FcCharLeafEnt {
 };
 
 #define FC_CHAR_LEAF_BLOCK     (4096 / sizeof (FcCharLeafEnt))
+static FcCharLeafEnt **FcCharLeafBlocks;
+static int FcCharLeafBlockCount;
 
 static FcCharLeafEnt *
 FcCharLeafEntCreate (void)
@@ -854,7 +856,14 @@ FcCharLeafEntCreate (void)
 
     if (!remain)
     {
-       block = malloc (FC_CHAR_LEAF_BLOCK * sizeof (FcCharLeafEnt));
+       FcCharLeafEnt **newBlocks;
+
+       FcCharLeafBlockCount++;
+       newBlocks = realloc (FcCharLeafBlocks, FcCharLeafBlockCount * sizeof (FcCharLeafEnt *));
+       if (!newBlocks)
+           return 0;
+       FcCharLeafBlocks = newBlocks;
+       block = FcCharLeafBlocks[FcCharLeafBlockCount-1] = malloc (FC_CHAR_LEAF_BLOCK * sizeof (FcCharLeafEnt));
        if (!block)
            return 0;
        FcMemAlloc (FC_MEM_CHARLEAF, FC_CHAR_LEAF_BLOCK * sizeof (FcCharLeafEnt));
@@ -880,12 +889,13 @@ FcCharLeafHash (FcCharLeaf *leaf)
 static int     FcCharLeafTotal;
 static int     FcCharLeafUsed;
 
+static FcCharLeafEnt   *FcCharLeafHashTable[FC_CHAR_LEAF_HASH_SIZE];
+
 static FcCharLeaf *
 FcCharSetFreezeLeaf (FcCharLeaf *leaf)
 {
-    static FcCharLeafEnt       *hashTable[FC_CHAR_LEAF_HASH_SIZE];
     FcChar32                   hash = FcCharLeafHash (leaf);
-    FcCharLeafEnt              **bucket = &hashTable[hash % FC_CHAR_LEAF_HASH_SIZE];
+    FcCharLeafEnt              **bucket = &FcCharLeafHashTable[hash % FC_CHAR_LEAF_HASH_SIZE];
     FcCharLeafEnt              *ent;
     
     FcCharLeafTotal++;
@@ -906,6 +916,25 @@ FcCharSetFreezeLeaf (FcCharLeaf *leaf)
     return &ent->leaf;
 }
 
+static void
+FcCharSetThawAllLeaf (void)
+{
+    int i;
+
+    for (i = 0; i < FC_CHAR_LEAF_HASH_SIZE; i++)
+       FcCharLeafHashTable[i] = 0;
+
+    FcCharLeafTotal = 0;
+    FcCharLeafUsed = 0;
+
+    for (i = 0; i < FcCharLeafBlockCount; i++)
+       free (FcCharLeafBlocks[i]);
+
+    free (FcCharLeafBlocks);
+    FcCharLeafBlocks = 0;
+    FcCharLeafBlockCount = 0;
+}
+
 typedef struct _FcCharSetEnt FcCharSetEnt;
 
 struct _FcCharSetEnt {
@@ -937,12 +966,13 @@ static int        FcCharSetTotal;
 static int     FcCharSetUsed;
 static int     FcCharSetTotalEnts, FcCharSetUsedEnts;
 
+static FcCharSetEnt    *FcCharSetHashTable[FC_CHAR_SET_HASH_SIZE];
+
 static FcCharSet *
 FcCharSetFreezeBase (FcCharSet *fcs)
 {
-    static FcCharSetEnt        *hashTable[FC_CHAR_SET_HASH_SIZE];
     FcChar32           hash = FcCharSetHash (fcs);
-    FcCharSetEnt       **bucket = &hashTable[hash % FC_CHAR_SET_HASH_SIZE];
+    FcCharSetEnt       **bucket = &FcCharSetHashTable[hash % FC_CHAR_SET_HASH_SIZE];
     FcCharSetEnt       *ent;
     int                        size;
 
@@ -992,6 +1022,30 @@ FcCharSetFreezeBase (FcCharSet *fcs)
     return &ent->set;
 }
 
+void
+FcCharSetThawAll (void)
+{
+    int i;
+    FcCharSetEnt       *ent, *next;
+
+    for (i = 0; i < FC_CHAR_SET_HASH_SIZE; i++)
+    {
+       for (ent = FcCharSetHashTable[i]; ent; ent = next)
+       {
+           next = ent->next;
+           free (ent);
+       }
+       FcCharSetHashTable[i] = 0;
+    }
+
+    FcCharSetTotal = 0;
+    FcCharSetTotalEnts = 0;
+    FcCharSetUsed = 0;
+    FcCharSetUsedEnts = 0;
+
+    FcCharSetThawAllLeaf ();
+}
+
 FcCharSet *
 FcCharSetFreeze (FcCharSet *fcs)
 {
index 404c2c6a4fd67a709b9582e7558fcaec88973e83..8c596f957204fb6e5107ec758d730c7ff564e813 100644 (file)
@@ -107,6 +107,19 @@ FcInit (void)
     return FcTrue;
 }
 
+/*
+ * Free all library-allocated data structures.
+ */
+void
+FcFini (void)
+{
+    if (_fcConfig)
+       FcConfigDestroy (_fcConfig);
+
+    FcPatternThawAll ();
+    FcCharSetThawAll ();
+}
+
 /*
  * Reread the configuration and available font lists
  */
index 926111e8fc08398f4cfb441b75a4ae401af4f3e9..036da9e74ae3f78b68ba67d879b316dbbf712da0 100644 (file)
@@ -469,6 +469,9 @@ FcConfigAcceptFilename (FcConfig    *config,
 FcCharSet *
 FcCharSetFreeze (FcCharSet *cs);
 
+void
+FcCharSetThawAll (void);
+
 FcBool
 FcNameUnparseCharSet (FcStrBuf *buf, const FcCharSet *c);
 
@@ -663,6 +666,9 @@ FcPatternAddWithBinding  (FcPattern     *p,
 FcPattern *
 FcPatternFreeze (FcPattern *p);
 
+void
+FcPatternThawAll (void);
+
 /* fcrender.c */
 
 /* fcmatrix.c */
index eb1ebd4ea2e89acb0dedc3b3c088fcf3a0eb020e..ddc16f835f4c4c8274f2d80681ccff7d2cf900af 100644 (file)
@@ -366,15 +366,43 @@ FcValueListEntCreate (FcValueList *h)
     return e;
 }
 
+static void
+FcValueListEntDestroy (FcValueListEnt *e)
+{
+    FcValueList        *l;
+
+    FcValueListFrozenCount[e->list->value.type]--;
+
+    /* XXX: We should perform these two operations with "size" as
+       computed in FcValueListEntCreate, but we don't have access to
+       that value here. Without this, the FcValueListFrozenBytes
+       values will be wrong as will the FcMemFree counts.
+
+       FcValueListFrozenBytes[e->list->value.type] -= size;
+       FcMemFree (FC_MEM_VALLIST, size);
+    */
+
+    for (l = e->list; l; l = l->next)
+    {
+       if (l->value.type != FcTypeString)
+           FcValueDestroy (l->value);
+    }
+    /* XXX: Are we being too chummy with the implementation here to
+       free(e) when it was actually the enclosing FcValueListAlign
+       that was allocated? */
+    free (e);
+}
+
 static int     FcValueListTotal;
 static int     FcValueListUsed;
 
+static FcValueListEnt   *FcValueListHashTable[FC_VALUE_LIST_HASH_SIZE];
+
 static FcValueList *
 FcValueListFreeze (FcValueList *l)
 {
-    static FcValueListEnt   *hashTable[FC_VALUE_LIST_HASH_SIZE];
     FcChar32               hash = FcValueListHash (l);
-    FcValueListEnt         **bucket = &hashTable[hash % FC_VALUE_LIST_HASH_SIZE];
+    FcValueListEnt         **bucket = &FcValueListHashTable[hash % FC_VALUE_LIST_HASH_SIZE];
     FcValueListEnt         *ent;
 
     FcValueListTotal++;
@@ -395,6 +423,26 @@ FcValueListFreeze (FcValueList *l)
     return ent->list;
 }
 
+static void
+FcValueListThawAll (void)
+{
+    int i;
+    FcValueListEnt     *ent, *next;
+
+    for (i = 0; i < FC_VALUE_LIST_HASH_SIZE; i++)
+    {
+       for (ent = FcValueListHashTable[i]; ent; ent = next)
+       {
+           next = ent->next;
+           FcValueListEntDestroy (ent);
+       }
+       FcValueListHashTable[i] = 0;
+    }
+
+    FcValueListTotal = 0;
+    FcValueListUsed = 0;
+}
+
 static FcChar32
 FcPatternBaseHash (FcPattern *b)
 {
@@ -417,12 +465,13 @@ struct _FcPatternEnt {
 static int     FcPatternTotal;
 static int     FcPatternUsed;
 
+static FcPatternEnt    *FcPatternHashTable[FC_VALUE_LIST_HASH_SIZE];
+
 static FcPattern *
 FcPatternBaseFreeze (FcPattern *b)
 {
-    static FcPatternEnt        *hashTable[FC_VALUE_LIST_HASH_SIZE];
     FcChar32           hash = FcPatternBaseHash (b);
-    FcPatternEnt       **bucket = &hashTable[hash % FC_VALUE_LIST_HASH_SIZE];
+    FcPatternEnt       **bucket = &FcPatternHashTable[hash % FC_VALUE_LIST_HASH_SIZE];
     FcPatternEnt       *ent;
     int                        i;
     char               *objects;
@@ -481,6 +530,26 @@ FcPatternBaseFreeze (FcPattern *b)
     return &ent->pattern;
 }
 
+static void
+FcPatternBaseThawAll (void)
+{
+    int i;
+    FcPatternEnt       *ent, *next;
+
+    for (i = 0; i < FC_VALUE_LIST_HASH_SIZE; i++)
+    {
+       for (ent = FcPatternHashTable[i]; ent; ent = next)
+       {
+           next = ent->next;
+           free (ent);
+       }
+       FcPatternHashTable[i] = 0;
+    }
+
+    FcPatternTotal = 0;
+    FcPatternUsed = 0;
+}
+
 FcPattern *
 FcPatternFreeze (FcPattern *p)
 {
@@ -526,6 +595,13 @@ bail:
     return n;
 }
 
+void
+FcPatternThawAll (void)
+{
+    FcPatternBaseThawAll ();
+    FcValueListThawAll ();
+}
+
 static int
 FcPatternPosition (const FcPattern *p, const char *object)
 {
index 65af5039b99f1ead14d8d4085e1e623122fa0ef8..e54f07e8d2ca031b37ee22fb42842728c00eb170 100644 (file)
@@ -292,6 +292,7 @@ FcEditDestroy (FcEdit *e)
     FcStrFree ((FcChar8 *) e->field);
     if (e->expr)
        FcExprDestroy (e->expr);
+    free (e);
 }
 
 char *
@@ -1288,6 +1289,9 @@ FcPopExpr (FcConfigParse *parse)
     case FcVStackConstant:
        expr = FcExprCreateConst (vstack->u.string);
        break;
+    case FcVStackGlob:
+       /* XXX: What's the correct action here? (CDW) */
+       break;
     case FcVStackPrefer:
     case FcVStackAccept:
     case FcVStackDefault:
index bbb07a6e38f84173754e1d6dd130d952b7d0b457..1d789875c1f24b5b849648cf125f67e9a1b444f7 100755 (executable)
@@ -53,6 +53,7 @@ EXPORTS
        FcDirSave
        FcDirScan
        FcFileScan
+       FcFini
        FcFontList
        FcFontMatch
        FcFontRenderPrepare