+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
fcstring.fncs \
fcstrset.fncs \
fcvalue.fncs
-
+
DOC_FUNCS_SGML=\
fcatomic.sgml \
fcblanks.sgml \
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 \
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
#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 {
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);
return m;
}
-void *
+static void *
Reallocate (void *p, int size)
{
void *r = realloc (p, size);
return r;
}
-void
+static void
Dispose (void *p)
{
free (p);
}
-String *
+static String *
StringNew (void)
{
String *s;
return s;
}
-void
+static void
StringAdd (String *s, char c)
{
if (s->len == s->size)
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 ();
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;
#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));
return r;
}
-void
+static void
ReplaceDispose (Replace *r)
{
StringDispose (r->tag);
Dispose (r);
}
-void
+static void
Bail (char *format, char *arg)
{
fprintf (stderr, "fatal: ");
exit (1);
}
-Replace *
+static Replace *
ReplaceRead (FILE *f)
{
int c;
return r;
}
-typedef struct _replaceList {
- struct _replaceList *next;
- Replace *r;
-} ReplaceList;
-
-ReplaceList *
+static ReplaceList *
ReplaceListNew (Replace *r, ReplaceList *next)
{
ReplaceList *l = New (sizeof (ReplaceList));
return l;
}
-void
+static void
ReplaceListDispose (ReplaceList *l)
{
if (l)
}
}
-typedef struct {
- ReplaceList *head;
-} ReplaceSet;
-
-ReplaceSet *
+static ReplaceSet *
ReplaceSetNew (void)
{
ReplaceSet *s = New (sizeof (ReplaceSet));
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;
return 0;
}
-ReplaceSet *
+static ReplaceSet *
ReplaceSetRead (FILE *f)
{
ReplaceSet *s = ReplaceSetNew ();
return s;
}
-typedef struct _skipStack {
- struct _skipStack *prev;
- int skipping;
-} SkipStack;
-
-SkipStack *
+static SkipStack *
SkipStackPush (SkipStack *prev, int skipping)
{
SkipStack *ss = New (sizeof (SkipStack));
return ss;
}
-SkipStack *
+static SkipStack *
SkipStackPop (SkipStack *prev)
{
SkipStack *ss = prev->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));
return ls;
}
-LoopStack *
+static LoopStack *
LoopStackLoop (ReplaceSet *rs, LoopStack *ls, FILE *f)
{
String *s = StringMake (ls->tag->buf);
return ret;
}
-void
+static void
LineSkip (FILE *f)
{
int c;
ungetc (c, f);
}
-void
+static void
DoReplace (FILE *f, ReplaceSet *s)
{
int c;
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
#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)
{
FcGlyphName *ucs_to_name[MAX_GLYPHNAME*2];
int hash, rehash;
-int
+static int
rawindex (FcGlyphName *gn)
{
int i;
return -1;
}
-void
+static void
scan (FILE *f, char *filename)
{
char buf[MAX_NAMELEN];
return h;
}
-int
+static int
isprime (int i)
{
int l, t;
* Find a prime pair that leaves at least 25% of the hash table empty
*/
-void
+static void
find_hash (void)
{
int h;
rehash = h-2;
}
-FcChar32
+static FcChar32
FcHashGlyphName (const FcChar8 *name)
{
FcChar32 h = 0;
return h;
}
-void
+static void
insert (FcGlyphName *gn, FcGlyphName **table, FcChar32 h)
{
int i, r = 0;
table[i] = gn;
}
-void
+static void
dump (FcGlyphName **table, char *name)
{
int i;
if (!os)
os = FcObjectSetBuild (FC_FAMILY, FC_STYLE, (char *) 0);
fs = FcFontList (0, pat, os);
+ FcObjectSetDestroy (os);
if (pat)
FcPatternDestroy (pat);
}
FcFontSetDestroy (fs);
}
+
+ FcFini ();
+
return 0;
}
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
+#include <string.h>
#ifdef HAVE_CONFIG_H
#include <config.h>
#else
int verbose = 0;
int sort = 0;
int i;
- FcObjectSet *os = 0;
FcFontSet *fs;
FcPattern *pat;
FcResult result;
FcBool
FcInit (void);
+void
+FcFini (void);
+
int
FcGetVersion (void);
FcTestDestroy (s->test);
if (s->edit)
FcEditDestroy (s->edit);
+ free (s);
+ FcMemFree (FC_MEM_SUBST, sizeof (FcSubst));
s = n;
}
}
FcStrSetDestroy (config->acceptGlobs);
FcStrSetDestroy (config->rejectGlobs);
+ if (config->blanks)
+ FcBlanksDestroy (config->blanks);
+
if (config->cache)
FcStrFree (config->cache);
for (set = FcSetSystem; set <= FcSetApplication; set++)
if (config->fonts[set])
FcFontSetDestroy (config->fonts[set]);
+
free (config);
FcMemFree (FC_MEM_CONFIG, sizeof (FcConfig));
}
};
#define FC_CHAR_LEAF_BLOCK (4096 / sizeof (FcCharLeafEnt))
+static FcCharLeafEnt **FcCharLeafBlocks;
+static int FcCharLeafBlockCount;
static FcCharLeafEnt *
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));
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++;
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 {
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;
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)
{
return FcTrue;
}
+/*
+ * Free all library-allocated data structures.
+ */
+void
+FcFini (void)
+{
+ if (_fcConfig)
+ FcConfigDestroy (_fcConfig);
+
+ FcPatternThawAll ();
+ FcCharSetThawAll ();
+}
+
/*
* Reread the configuration and available font lists
*/
FcCharSet *
FcCharSetFreeze (FcCharSet *cs);
+void
+FcCharSetThawAll (void);
+
FcBool
FcNameUnparseCharSet (FcStrBuf *buf, const FcCharSet *c);
FcPattern *
FcPatternFreeze (FcPattern *p);
+void
+FcPatternThawAll (void);
+
/* fcrender.c */
/* fcmatrix.c */
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++;
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)
{
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;
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)
{
return n;
}
+void
+FcPatternThawAll (void)
+{
+ FcPatternBaseThawAll ();
+ FcValueListThawAll ();
+}
+
static int
FcPatternPosition (const FcPattern *p, const char *object)
{
FcStrFree ((FcChar8 *) e->field);
if (e->expr)
FcExprDestroy (e->expr);
+ free (e);
}
char *
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:
FcDirSave
FcDirScan
FcFileScan
+ FcFini
FcFontList
FcFontMatch
FcFontRenderPrepare