From 34cd0514a215d65af6822eba2c2f0cd04eb0065f Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Fri, 15 Aug 2003 19:45:20 +0000 Subject: [PATCH] Added new FcFini function for cleaning up all memory. Fixed a few memory leaks. fc-list now calls FcFini, (and is now leak-free according to valgrind) --- ChangeLog | 44 +++++++++ doc/Makefile.am | 8 +- doc/edit-sgml.c | 187 ++++++++++++++++++++++++++---------- doc/fcinit.fncs | 11 +++ fc-glyphname/fc-glyphname.c | 35 +++++-- fc-list/fc-list.c | 4 + fc-match/fc-match.c | 2 +- fontconfig/fontconfig.h | 3 + src/fccfg.c | 6 ++ src/fccharset.c | 64 +++++++++++- src/fcinit.c | 13 +++ src/fcint.h | 6 ++ src/fcpat.c | 84 +++++++++++++++- src/fcxml.c | 4 + src/fontconfig.def.in | 1 + 15 files changed, 398 insertions(+), 74 deletions(-) diff --git a/ChangeLog b/ChangeLog index 4454212..d265c74 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,47 @@ +2003-08-15 Carl Worth + + * 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 * test/run-test.sh (FONTCONFIG_FILE): Remove CRs from the out file diff --git a/doc/Makefile.am b/doc/Makefile.am index b98c13b..7e1d70d 100644 --- a/doc/Makefile.am +++ b/doc/Makefile.am @@ -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 diff --git a/doc/edit-sgml.c b/doc/edit-sgml.c index 407dd2c..2375140 100644 --- a/doc/edit-sgml.c +++ b/doc/edit-sgml.c @@ -27,6 +27,15 @@ #include #include +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; diff --git a/doc/fcinit.fncs b/doc/fcinit.fncs index bdf83fd..04a3195 100644 --- a/doc/fcinit.fncs +++ b/doc/fcinit.fncs @@ -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 diff --git a/fc-glyphname/fc-glyphname.c b/fc-glyphname/fc-glyphname.c index fb18fea..769f4be 100644 --- a/fc-glyphname/fc-glyphname.c +++ b/fc-glyphname/fc-glyphname.c @@ -24,6 +24,27 @@ #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; diff --git a/fc-list/fc-list.c b/fc-list/fc-list.c index 997a6ac..0fa1a8d 100644 --- a/fc-list/fc-list.c +++ b/fc-list/fc-list.c @@ -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; } diff --git a/fc-match/fc-match.c b/fc-match/fc-match.c index 498018b..635c883 100644 --- a/fc-match/fc-match.c +++ b/fc-match/fc-match.c @@ -26,6 +26,7 @@ #include #include #include +#include #ifdef HAVE_CONFIG_H #include #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; diff --git a/fontconfig/fontconfig.h b/fontconfig/fontconfig.h index 045a36b..3cd7967 100644 --- a/fontconfig/fontconfig.h +++ b/fontconfig/fontconfig.h @@ -452,6 +452,9 @@ FcInitLoadConfigAndFonts (void); FcBool FcInit (void); +void +FcFini (void); + int FcGetVersion (void); diff --git a/src/fccfg.c b/src/fccfg.c index 7b5d693..12cad84 100644 --- a/src/fccfg.c +++ b/src/fccfg.c @@ -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)); } diff --git a/src/fccharset.c b/src/fccharset.c index d87a720..a1c8f89 100644 --- a/src/fccharset.c +++ b/src/fccharset.c @@ -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) { diff --git a/src/fcinit.c b/src/fcinit.c index 404c2c6..8c596f9 100644 --- a/src/fcinit.c +++ b/src/fcinit.c @@ -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 */ diff --git a/src/fcint.h b/src/fcint.h index 926111e..036da9e 100644 --- a/src/fcint.h +++ b/src/fcint.h @@ -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 */ diff --git a/src/fcpat.c b/src/fcpat.c index eb1ebd4..ddc16f8 100644 --- a/src/fcpat.c +++ b/src/fcpat.c @@ -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) { diff --git a/src/fcxml.c b/src/fcxml.c index 65af503..e54f07e 100644 --- a/src/fcxml.c +++ b/src/fcxml.c @@ -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: diff --git a/src/fontconfig.def.in b/src/fontconfig.def.in index bbb07a6..1d78987 100755 --- a/src/fontconfig.def.in +++ b/src/fontconfig.def.in @@ -53,6 +53,7 @@ EXPORTS FcDirSave FcDirScan FcFileScan + FcFini FcFontList FcFontMatch FcFontRenderPrepare -- 2.39.2