Commit 34cd0514 authored by Carl Worth's avatar Carl Worth

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)
parent 18906a87
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
......
......@@ -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
......
......@@ -27,6 +27,15 @@
#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;
......
......@@ -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
......
......@@ -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;
......
......@@ -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;
}
......@@ -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;
......
......@@ -452,6 +452,9 @@ FcInitLoadConfigAndFonts (void);
FcBool
FcInit (void);
void
FcFini (void);
int
FcGetVersion (void);
......
......@@ -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));
}
......
......@@ -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)
{
......
......@@ -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
*/
......
......@@ -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 */
......
......@@ -366,15 +366,43 @@ FcValueListEntCreate (FcValueList *h)
return e;
}
static void