Fix autoconf build process for fontconfig

This commit is contained in:
Keith Packard 2002-05-21 17:06:22 +00:00
parent 1ce2a1bbad
commit 179c39959c
18 changed files with 4381 additions and 335 deletions

68
config/Makedefs.in Normal file
View File

@ -0,0 +1,68 @@
#
# $XFree86$
#
# Copyright © 2002 Keith Packard, member of The XFree86 Project, Inc.
#
# Permission to use, copy, modify, distribute, and sell this software and its
# documentation for any purpose is hereby granted without fee, provided that
# the above copyright notice appear in all copies and that both that
# copyright notice and this permission notice appear in supporting
# documentation, and that the name of Keith Packard not be used in
# advertising or publicity pertaining to distribution of the software without
# specific, written prior permission. Keith Packard makes no
# representations about the suitability of this software for any purpose. It
# is provided "as is" without express or implied warranty.
#
# KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
# INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
# EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
# CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
# DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
# TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
#
SHELL = @SHELL@
srcdir=@srcdir@
prefix=@prefix@
exec_prefix=@exec_prefix@
libdir=@libdir@
bindir=@bindir@
datadir=@datadir@
includedir=@includedir@
sysconfdir=@sysconfdir@
CDEBUGFLAGS=@CFLAGS@
CPPFLAGS=@CPPFLAGS@
DEFS=@DEFS@
DSO_LDOPTS=@DSO_LDOPTS@
DSO_CFLAGS=@DSO_CFLAGS@
DSO_PIC_CFLAGS=@DSO_PIC_CFLAGS@
INCLUDES=-I$(TOPDIR) -I$(srcdir)
CFLAGS=$(CDEBUGFLAGS) $(INCLUDES) $(DEFS) $(CPPFLAGS)
INSTALL=@INSTALL@
INSTALL_PROGRAM=@INSTALL_PROGRAM@
INSTALL_SCRIPT=@INSTALL_SCRIPT@
INSTALL_DATA=@INSTALL_DATA@
MKSHLIB=@MKSHLIB@
LN_S=@LN_S@
# shared libraries
LIBDIR=$(libdir)
# programs
BINDIR=$(bindir)
# font configuration files
CONFDIR=$(sysconfdir)/fonts
LIBBASE=libfontconfig.so
LIBFILE=$(LIBBASE).@PACKAGE_MAJOR@.@PACKAGE_MINOR@
LIBMAJOR=$(LIBBASE).@PACKAGE_MAJOR@
LIBFONTCONFIG=-L$(SRCDIR) -lfontconfig
SRCDIR=$(TOPDIR)/src

1391
config/config.guess vendored Normal file

File diff suppressed because it is too large Load Diff

1355
config/config.sub vendored Normal file

File diff suppressed because it is too large Load Diff

240
config/install.sh Normal file
View File

@ -0,0 +1,240 @@
#! /bin/sh
#
# install - install a program, script, or datafile
# This comes from X11R5.
#
# Calling this script install-sh is preferred over install.sh, to prevent
# `make' implicit rules from creating a file called install from it
# when there is no Makefile.
#
# This script is compatible with the BSD install script, but was written
# from scratch.
#
# $XFree86$
#
# set DOITPROG to echo to test this script
# Don't use :- since 4.3BSD and earlier shells don't like it.
doit="${DOITPROG-}"
# put in absolute paths if you don't have them in your path; or use env. vars.
mvprog="${MVPROG-mv}"
cpprog="${CPPROG-cp}"
chmodprog="${CHMODPROG-chmod}"
chownprog="${CHOWNPROG-chown}"
chgrpprog="${CHGRPPROG-chgrp}"
stripprog="${STRIPPROG-strip}"
rmprog="${RMPROG-rm}"
mkdirprog="${MKDIRPROG-mkdir}"
tranformbasename=""
transform_arg=""
instcmd="$mvprog"
chmodcmd="$chmodprog 0755"
chowncmd=""
chgrpcmd=""
stripcmd=""
rmcmd="$rmprog -f"
mvcmd="$mvprog"
src=""
dst=""
dir_arg=""
while [ x"$1" != x ]; do
case $1 in
-c) instcmd="$cpprog"
shift
continue;;
-d) dir_arg=true
shift
continue;;
-m) chmodcmd="$chmodprog $2"
shift
shift
continue;;
-o) chowncmd="$chownprog $2"
shift
shift
continue;;
-g) chgrpcmd="$chgrpprog $2"
shift
shift
continue;;
-s) stripcmd="$stripprog"
shift
continue;;
-t=*) transformarg=`echo $1 | sed 's/-t=//'`
shift
continue;;
-b=*) transformbasename=`echo $1 | sed 's/-b=//'`
shift
continue;;
*) if [ x"$src" = x ]
then
src=$1
else
# this colon is to work around a 386BSD /bin/sh bug
:
dst=$1
fi
shift
continue;;
esac
done
if [ x"$src" = x ]
then
echo "install: no input file specified"
exit 1
else
true
fi
if [ x"$dir_arg" != x ]; then
dst=$src
src=""
if [ -d $dst ]; then
instcmd=:
else
instcmd=mkdir
fi
else
# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
# might cause directories to be created, which would be especially bad
# if $src (and thus $dsttmp) contains '*'.
if [ -f $src -o -d $src ]
then
true
else
echo "install: $src does not exist"
exit 1
fi
if [ x"$dst" = x ]
then
echo "install: no destination specified"
exit 1
else
true
fi
# If destination is a directory, append the input filename; if your system
# does not like double slashes in filenames, you may need to add some logic
if [ -d $dst ]
then
dst="$dst"/`basename $src`
else
true
fi
fi
## this sed command emulates the dirname command
dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
# Make sure that the destination directory exists.
# this part is taken from Noah Friedman's mkinstalldirs script
# Skip lots of stat calls in the usual case.
if [ ! -d "$dstdir" ]; then
defaultIFS='
'
IFS="${IFS-${defaultIFS}}"
oIFS="${IFS}"
# Some sh's can't handle IFS=/ for some reason.
IFS='%'
set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'`
IFS="${oIFS}"
pathcomp=''
while [ $# -ne 0 ] ; do
pathcomp="${pathcomp}${1}"
shift
if [ ! -d "${pathcomp}" ] ;
then
$mkdirprog "${pathcomp}"
else
true
fi
pathcomp="${pathcomp}/"
done
fi
if [ x"$dir_arg" != x ]
then
$doit $instcmd $dst &&
if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi &&
if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi &&
if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi &&
if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi
else
# If we're going to rename the final executable, determine the name now.
if [ x"$transformarg" = x ]
then
dstfile=`basename $dst`
else
dstfile=`basename $dst $transformbasename |
sed $transformarg`$transformbasename
fi
# don't allow the sed command to completely eliminate the filename
if [ x"$dstfile" = x ]
then
dstfile=`basename $dst`
else
true
fi
# Make a temp file name in the proper directory.
dsttmp=$dstdir/#inst.$$#
# Move or copy the file name to the temp name
$doit $instcmd $src $dsttmp &&
trap "rm -f ${dsttmp}" 0 &&
# and set any options; do chmod last to preserve setuid bits
# If any of these fail, we abort the whole thing. If we want to
# ignore errors from any of these, just make sure not to ignore
# errors from the above "$doit $instcmd $src $dsttmp" command.
if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi &&
if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi &&
if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi &&
if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi &&
# Now rename the file to the real destination.
$doit $rmcmd -f $dstdir/$dstfile &&
$doit $mvcmd $dsttmp $dstdir/$dstfile
fi &&
exit 0

View File

@ -1,3 +1,8 @@
#ifdef UseInstalled
/* building outside the tree, use private defines */
#include "../local.def"
#endif
INCLUDES=$(FREETYPE2INCLUDES) $(LIBXML2INCLUDES) -I.. INCLUDES=$(FREETYPE2INCLUDES) $(LIBXML2INCLUDES) -I..
LOCAL_LIBRARIES=FontconfigClientLibs LOCAL_LIBRARIES=FontconfigClientLibs
@ -11,5 +16,5 @@ LinkBuildBinary(ProgramTargetName(fc-cache))
install:: install::
if [ x$${DESTDIR} = x ]; then \ if [ x$${DESTDIR} = x ]; then \
FC_DEBUG=128 $(FCCACHE) -v ;\ $(FCCACHE) -v -f;\
fi fi

46
fc-cache/Makefile.in Normal file
View File

@ -0,0 +1,46 @@
#
# $XFree86$
#
# Copyright © 2002 Keith Packard, member of The XFree86 Project, Inc.
#
# Permission to use, copy, modify, distribute, and sell this software and its
# documentation for any purpose is hereby granted without fee, provided that
# the above copyright notice appear in all copies and that both that
# copyright notice and this permission notice appear in supporting
# documentation, and that the name of Keith Packard not be used in
# advertising or publicity pertaining to distribution of the software without
# specific, written prior permission. Keith Packard makes no
# representations about the suitability of this software for any purpose. It
# is provided "as is" without express or implied warranty.
#
# KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
# INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
# EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
# CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
# DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
# TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
#
TOPDIR=..
include $(TOPDIR)/config/Makedefs
SRCS=fc-cache.c
OBJS=fc-cache.o
PROG=fc-cache
all:: $(PROG)
install:: $(BINDIR)/$(PROG)
$(BINDIR)/$(PROG): $(PROG)
$(INSTALL_PROGRAM) $(PROG) $(BINDIR)
clean::
rm -f $(PROG) $(OBJS)
$(PROG): $(OBJS)
$(CC) $(CFLAGS) -o $@ $(OBJS) $(LIBFONTCONFIG)

View File

@ -46,6 +46,7 @@
#define _GNU_SOURCE #define _GNU_SOURCE
#include <getopt.h> #include <getopt.h>
const struct option longopts[] = { const struct option longopts[] = {
{"force", 0, 0, 'f'},
{"version", 0, 0, 'V'}, {"version", 0, 0, 'V'},
{"verbose", 0, 0, 'v'}, {"verbose", 0, 0, 'v'},
{"help", 0, 0, '?'}, {"help", 0, 0, '?'},
@ -61,41 +62,134 @@ extern int optind, opterr, optopt;
static void static void
usage (char *program) usage (char *program)
{ {
fprintf (stderr, "usage: %s [-vV?] [--verbose] [--version] [--help] [dirs]\n", fprintf (stderr, "usage: %s [-fvV?] [--force] [--verbose] [--version] [--help] [dirs]\n",
program); program);
fprintf (stderr, "Build font information caches in [dirs]\n" fprintf (stderr, "Build font information caches in [dirs]\n"
"(all directories in font configuration by default).\n"); "(all directories in font configuration by default).\n");
fprintf (stderr, "\n"); fprintf (stderr, "\n");
fprintf (stderr, " -v, --force scan directories with apparently valid caches\n");
fprintf (stderr, " -v, --verbose display status information while busy\n"); fprintf (stderr, " -v, --verbose display status information while busy\n");
fprintf (stderr, " -V, --version display font config version and exit\n"); fprintf (stderr, " -V, --version display font config version and exit\n");
fprintf (stderr, " -?, --help display this help and exit\n"); fprintf (stderr, " -?, --help display this help and exit\n");
exit (1); exit (1);
} }
static int
nsubdirs (FcStrSet *set)
{
FcStrList *list;
int n = 0;
list = FcStrListCreate (set);
if (!list)
return 0;
while (FcStrListNext (list))
n++;
FcStrListDone (list);
return n;
}
static int
scanDirs (FcStrList *list, char *program, FcBool force, FcBool verbose)
{
int ret = 0;
FcChar8 *dir;
FcFontSet *set;
FcStrSet *subdirs;
FcStrList *sublist;
/*
* Now scan all of the directories into separate databases
* and write out the results
*/
while ((dir = FcStrListNext (list)))
{
if (verbose)
{
printf ("%s: \"%s\": ", program, dir);
fflush (stdout);
}
set = FcFontSetCreate ();
if (!set)
{
fprintf (stderr, "Can't create font set\n");
ret++;
continue;
}
subdirs = FcStrSetCreate ();
if (!subdirs)
{
fprintf (stderr, "Can't create directory set\n");
ret++;
continue;
}
if (!FcDirScan (set, subdirs, 0, FcConfigGetBlanks (0), dir, force))
{
fprintf (stderr, "Can't scan \"%s\"\n", dir);
ret++;
continue;
}
if (!force && FcDirCacheValid (dir))
{
if (verbose)
printf ("skipping, %d fonts, %d dirs\n",
set->nfont, nsubdirs(subdirs));
}
else
{
if (verbose)
printf ("caching, %d fonts, %d dirs\n",
set->nfont, nsubdirs (subdirs));
if (!FcDirSave (set, subdirs, dir))
{
fprintf (stderr, "Can't save cache in \"%s\"\n", dir);
ret++;
}
}
FcFontSetDestroy (set);
sublist = FcStrListCreate (subdirs);
if (!sublist)
{
fprintf (stderr, "Can't create subdir list in \"%s\"\n", dir);
ret++;
continue;
}
ret += scanDirs (sublist, program, force, verbose);
FcStrSetDestroy (subdirs);
}
FcStrListDone (list);
return ret;
}
int int
main (int argc, char **argv) main (int argc, char **argv)
{ {
int ret = 0; FcStrSet *dirs;
FcFontSet *set; FcStrList *list;
FcChar8 **dirs; FcBool verbose = FcFalse;
int verbose = 0; FcBool force = FcFalse;
FcConfig *config;
int i; int i;
int ret;
#if HAVE_GETOPT_LONG || HAVE_GETOPT #if HAVE_GETOPT_LONG || HAVE_GETOPT
int c; int c;
#if HAVE_GETOPT_LONG #if HAVE_GETOPT_LONG
while ((c = getopt_long (argc, argv, "Vv?", longopts, NULL)) != -1) while ((c = getopt_long (argc, argv, "fVv?", longopts, NULL)) != -1)
#else #else
while ((c = getopt (argc, argv, "Vv?")) != -1) while ((c = getopt (argc, argv, "fVv?")) != -1)
#endif #endif
{ {
switch (c) { switch (c) {
case 'f':
force = FcTrue;
break;
case 'V': case 'V':
fprintf (stderr, "fontconfig version %d.%d.%d\n", fprintf (stderr, "fontconfig version %d.%d.%d\n",
FC_MAJOR, FC_MINOR, FC_REVISION); FC_MAJOR, FC_MINOR, FC_REVISION);
exit (0); exit (0);
case 'v': case 'v':
verbose = 1; verbose = FcTrue;
break; break;
default: default:
usage (argv[0]); usage (argv[0]);
@ -106,51 +200,36 @@ main (int argc, char **argv)
i = 1; i = 1;
#endif #endif
if (!FcInitConfig ()) config = FcInitLoadConfig ();
if (!config)
{ {
fprintf (stderr, "Can't init font config library\n"); fprintf (stderr, "%s: Can't init font config library\n", argv[0]);
return 1; return 1;
} }
if (argv[i]) if (argv[i])
dirs = (FcChar8 **) (argv+i);
else
dirs = FcConfigGetDirs (0);
/*
* Now scan all of the directories into separate databases
* and write out the results
*/
while (dirs && *dirs)
{ {
if (verbose) dirs = FcStrSetCreate ();
printf ("%s: Scanning directory \"%s\"\n", argv[0], *dirs); if (!dirs)
set = FcFontSetCreate ();
if (!set)
{ {
fprintf (stderr, "Out of memory in \"%s\"\n", *dirs); fprintf (stderr, "%s: Can't create list of directories\n",
ret++; argv[0]);
return 1;
} }
else while (argv[i])
{ {
if (!FcDirScan (set, 0, FcConfigGetBlanks (0), *dirs, FcTrue)) if (!FcStrSetAdd (dirs, (FcChar8 *) argv[i]))
{ {
fprintf (stderr, "Can't scan directory \"%s\"\n", *dirs); fprintf (stderr, "%s: Can't add directory\n", argv[0]);
ret++; return 1;
} }
else i++;
{
if (verbose)
printf ("%s: Saving %d font names for \"%s\"\n",
argv[0], set->nfont, *dirs);
if (!FcDirSave (set, *dirs))
{
fprintf (stderr, "Can't save cache in \"%s\"\n", *dirs);
ret++;
}
}
FcFontSetDestroy (set);
} }
++dirs; list = FcStrListCreate (dirs);
FcStrSetDestroy (dirs);
} }
else
list = FcConfigGetConfigDirs (config);
ret = scanDirs (list, argv[0], force, verbose);
if (verbose) if (verbose)
printf ("%s: %s\n", argv[0], ret ? "failed" : "succeeded"); printf ("%s: %s\n", argv[0], ret ? "failed" : "succeeded");
return ret; return ret;

46
fc-list/Makefile.in Normal file
View File

@ -0,0 +1,46 @@
#
# $XFree86$
#
# Copyright © 2002 Keith Packard, member of The XFree86 Project, Inc.
#
# Permission to use, copy, modify, distribute, and sell this software and its
# documentation for any purpose is hereby granted without fee, provided that
# the above copyright notice appear in all copies and that both that
# copyright notice and this permission notice appear in supporting
# documentation, and that the name of Keith Packard not be used in
# advertising or publicity pertaining to distribution of the software without
# specific, written prior permission. Keith Packard makes no
# representations about the suitability of this software for any purpose. It
# is provided "as is" without express or implied warranty.
#
# KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
# INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
# EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
# CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
# DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
# TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
#
TOPDIR=..
include $(TOPDIR)/config/Makedefs
SRCS=fc-list.c
OBJS=fc-list.o
PROG=fc-list
all:: $(PROG)
install:: $(BINDIR)/$(PROG)
$(BINDIR)/$(PROG): $(PROG)
$(INSTALL_PROGRAM) $(PROG) $(BINDIR)
clean::
rm -f $(PROG) $(OBJS)
$(PROG): $(OBJS)
$(CC) $(CFLAGS) -o $@ $(OBJS) $(LIBFONTCONFIG)

View File

@ -228,6 +228,10 @@ typedef struct _FcFileCache FcFileCache;
typedef struct _FcBlanks FcBlanks; typedef struct _FcBlanks FcBlanks;
typedef struct _FcStrList FcStrList;
typedef struct _FcStrSet FcStrSet;
_FCFUNCPROTOBEGIN _FCFUNCPROTOBEGIN
/* fcblanks.c */ /* fcblanks.c */
@ -259,13 +263,19 @@ FcConfigSetCurrent (FcConfig *config);
FcConfig * FcConfig *
FcConfigGetCurrent (void); FcConfigGetCurrent (void);
FcBool
FcConfigUptoDate (FcConfig *config);
FcBool FcBool
FcConfigBuildFonts (FcConfig *config); FcConfigBuildFonts (FcConfig *config);
FcChar8 ** FcStrList *
FcConfigGetDirs (FcConfig *config); FcConfigGetFontDirs (FcConfig *config);
FcChar8 ** FcStrList *
FcConfigGetConfigDirs (FcConfig *config);
FcStrList *
FcConfigGetConfigFiles (FcConfig *config); FcConfigGetConfigFiles (FcConfig *config);
FcChar8 * FcChar8 *
@ -274,6 +284,12 @@ FcConfigGetCache (FcConfig *config);
FcBlanks * FcBlanks *
FcConfigGetBlanks (FcConfig *config); FcConfigGetBlanks (FcConfig *config);
int
FcConfigGetRescanInverval (FcConfig *config);
FcBool
FcConfigSetRescanInverval (FcConfig *config, int rescanInterval);
FcFontSet * FcFontSet *
FcConfigGetFonts (FcConfig *config, FcConfigGetFonts (FcConfig *config,
FcSetName set); FcSetName set);
@ -351,6 +367,7 @@ FcDefaultSubstitute (FcPattern *pattern);
/* fcdir.c */ /* fcdir.c */
FcBool FcBool
FcFileScan (FcFontSet *set, FcFileScan (FcFontSet *set,
FcStrSet *dirs,
FcFileCache *cache, FcFileCache *cache,
FcBlanks *blanks, FcBlanks *blanks,
const FcChar8 *file, const FcChar8 *file,
@ -358,13 +375,17 @@ FcFileScan (FcFontSet *set,
FcBool FcBool
FcDirScan (FcFontSet *set, FcDirScan (FcFontSet *set,
FcStrSet *dirs,
FcFileCache *cache, FcFileCache *cache,
FcBlanks *blanks, FcBlanks *blanks,
const FcChar8 *dir, const FcChar8 *dir,
FcBool force); FcBool force);
FcBool FcBool
FcDirSave (FcFontSet *set, const FcChar8 *dir); FcDirSave (FcFontSet *set, FcStrSet *dirs, const FcChar8 *dir);
FcBool
FcDirCacheValid (const FcChar8 *dir);
/* fcfreetype.c */ /* fcfreetype.c */
FcPattern * FcPattern *
@ -382,15 +403,21 @@ FcBool
FcFontSetAdd (FcFontSet *s, FcPattern *font); FcFontSetAdd (FcFontSet *s, FcPattern *font);
/* fcinit.c */ /* fcinit.c */
FcBool FcConfig *
FcInitFonts (void); FcInitLoadConfig (void);
FcBool FcConfig *
FcInitConfig (void); FcInitLoadConfigAndFonts (void);
FcBool FcBool
FcInit (void); FcInit (void);
FcBool
FcInitReinitialize (void);
FcBool
FcInitBringUptoDate (void);
/* fclist.c */ /* fclist.c */
FcObjectSet * FcObjectSet *
FcObjectSetCreate (void); FcObjectSetCreate (void);
@ -592,11 +619,17 @@ FcPatternBuild (FcPattern *orig, ...);
FcChar8 * FcChar8 *
FcStrCopy (const FcChar8 *s); FcStrCopy (const FcChar8 *s);
FcChar8 *
FcStrCopyFilename (const FcChar8 *s);
#define FcToLower(c) (('A' <= (c) && (c) <= 'Z') ? (c) - 'A' + 'a' : (c)) #define FcToLower(c) (('A' <= (c) && (c) <= 'Z') ? (c) - 'A' + 'a' : (c))
int int
FcStrCmpIgnoreCase (const FcChar8 *s1, const FcChar8 *s2); FcStrCmpIgnoreCase (const FcChar8 *s1, const FcChar8 *s2);
int
FcStrCmp (const FcChar8 *s1, const FcChar8 *s2);
int int
FcUtf8ToUcs4 (FcChar8 *src_orig, FcUtf8ToUcs4 (FcChar8 *src_orig,
FcChar32 *dst, FcChar32 *dst,
@ -608,6 +641,39 @@ FcUtf8Len (FcChar8 *string,
int *nchar, int *nchar,
int *wchar); int *wchar);
FcChar8 *
FcStrDirname (const FcChar8 *file);
FcChar8 *
FcStrBasename (const FcChar8 *file);
FcStrSet *
FcStrSetCreate (void);
FcBool
FcStrSetMember (FcStrSet *set, const FcChar8 *s);
FcBool
FcStrSetAdd (FcStrSet *set, const FcChar8 *s);
FcBool
FcStrSetAddFilename (FcStrSet *set, const FcChar8 *s);
FcBool
FcStrSetDel (FcStrSet *set, const FcChar8 *s);
void
FcStrSetDestroy (FcStrSet *set);
FcStrList *
FcStrListCreate (FcStrSet *set);
FcChar8 *
FcStrListNext (FcStrList *list);
void
FcStrListDone (FcStrList *list);
/* fcxml.c */ /* fcxml.c */
FcBool FcBool
FcConfigParseAndLoad (FcConfig *config, const FcChar8 *file, FcBool complain); FcConfigParseAndLoad (FcConfig *config, const FcChar8 *file, FcBool complain);

105
src/Makefile.in Normal file
View File

@ -0,0 +1,105 @@
#
# $XFree86$
#
# Copyright © 2002 Keith Packard, member of The XFree86 Project, Inc.
#
# Permission to use, copy, modify, distribute, and sell this software and its
# documentation for any purpose is hereby granted without fee, provided that
# the above copyright notice appear in all copies and that both that
# copyright notice and this permission notice appear in supporting
# documentation, and that the name of Keith Packard not be used in
# advertising or publicity pertaining to distribution of the software without
# specific, written prior permission. Keith Packard makes no
# representations about the suitability of this software for any purpose. It
# is provided "as is" without express or implied warranty.
#
# KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
# INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
# EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
# CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
# DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
# TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
#
TOPDIR=..
include $(TOPDIR)/config/Makedefs
LIBS=@LIBS@
SRCS=fcatomic.c \
fcavl.c \
fcblanks.c \
fccache.c \
fccfg.c \
fccharset.c \
fcdbg.c \
fcdefault.c \
fcdir.c \
fcfreetype.c \
fcfs.c \
fcinit.c \
fclist.c \
fclock.c \
fcmatch.c \
fcmatrix.c \
fcname.c \
fcpat.c \
fcstr.c \
fcxml.c
OBJS=fcatomic.@OBJEXT@ \
fcavl.@OBJEXT@ \
fcblanks.@OBJEXT@ \
fccache.@OBJEXT@ \
fccfg.@OBJEXT@ \
fccharset.@OBJEXT@ \
fcdbg.@OBJEXT@ \
fcdefault.@OBJEXT@ \
fcdir.@OBJEXT@ \
fcfreetype.@OBJEXT@ \
fcfs.@OBJEXT@ \
fcinit.@OBJEXT@ \
fclist.@OBJEXT@ \
fclock.@OBJEXT@ \
fcmatch.@OBJEXT@ \
fcmatrix.@OBJEXT@ \
fcname.@OBJEXT@ \
fcpat.@OBJEXT@ \
fcstr.@OBJEXT@ \
fcxml.@OBJEXT@
.c.@OBJEXT@:
$(CC) $(CFLAGS) $(DSO_PIC_CFLAGS) -c $< -o $@
all:: $(LIBFILE) $(LIBMAJOR) $(LIBBASE)
install:: $(LIBDIR)/$(LIB) $(LIBDIR)/$(LIBMAJOR) $(LIBDIR)/$(LIBBASE)
$(LIBDIR)/$(LIBFILE): $(LIBFILE)
$(INSTALL_PROGRAM) $< $(LIBDIR)
$(LIBDIR)/$(LIBMAJOR): $(LIBDIR)/$(LIBFILE)
$(LN_S) $(LIBDIR)/$(LIBFILE) $(LIBDIR)/$(LIBMAJOR)
$(LIBDIR)/$(LIBBASE): $(LIBDIR)/$(LIBMAJOR)
$(LN_S) $(LIBDIR)/$(LIBMAJOR) $(LIBDIR)/$(LIBBASE)
clean::
rm -f $(LIBFILE) $(LIBMAJOR) $(LIBBASE) $(OBJS)
$(LIBFILE): $(OBJS)
rm -f $@
$(MKSHLIB) $(OBJS) $(LIBS)
$(LIBMAJOR): $(LIBFILE)
rm -f $@
$(LN_S) $(LIBFILE) $(LIBMAJOR)
$(LIBBASE): $(LIBMAJOR)
rm -f $@
$(LN_S) $(LIBMAJOR) $(LIBBASE)
$(OBJS): fcint.h $(TOPDIR)/fontconfig/fontconfig.h
$(OBJS): $(TOPDIR)/fontconfig/fcprivate.h $(TOPDIR)/config.h

View File

@ -487,15 +487,42 @@ bail0:
} }
FcBool FcBool
FcFileCacheReadDir (FcFontSet *set, const FcChar8 *cache_file) FcFileCacheValid (const FcChar8 *cache_file)
{
FcChar8 *dir = FcStrDirname (cache_file);
struct stat file_stat, dir_stat;
if (!dir)
return FcFalse;
if (stat ((char *) dir, &dir_stat) < 0)
{
FcStrFree (dir);
return FcFalse;
}
FcStrFree (dir);
if (stat ((char *) cache_file, &file_stat) < 0)
return FcFalse;
/*
* If the directory has been modified more recently than
* the cache file, the cache is not valid
*/
if (dir_stat.st_mtime - file_stat.st_mtime > 0)
return FcFalse;
return FcTrue;
}
FcBool
FcFileCacheReadDir (FcFontSet *set, FcStrSet *dirs, const FcChar8 *cache_file)
{ {
FcPattern *font; FcPattern *font;
FILE *f; FILE *f;
FcChar8 *path;
FcChar8 *base; FcChar8 *base;
FcChar8 file_buf[8192], *file;
int id; int id;
int dir_len;
int file_len;
FcChar8 file_buf[8192], *file;
FcChar8 name_buf[8192], *name; FcChar8 name_buf[8192], *name;
FcChar8 path_buf[8192], *path;
FcBool ret = FcFalse; FcBool ret = FcFalse;
if (FcDebug () & FC_DBG_CACHE) if (FcDebug () & FC_DBG_CACHE)
@ -513,39 +540,72 @@ FcFileCacheReadDir (FcFontSet *set, const FcChar8 *cache_file)
goto bail0; goto bail0;
} }
if (!FcFileCacheValid (cache_file))
{
if (FcDebug () & FC_DBG_CACHE)
{
printf (" cache file older than directory\n");
}
goto bail1;
}
base = (FcChar8 *) strrchr ((char *) cache_file, '/'); base = (FcChar8 *) strrchr ((char *) cache_file, '/');
if (!base) if (!base)
goto bail1; goto bail1;
base++; base++;
path = malloc (base - cache_file + 8192 + 1); dir_len = base - cache_file;
if (!path) if (dir_len < sizeof (path_buf))
goto bail1; strncpy ((char *) path_buf, (const char *) cache_file, dir_len);
memcpy (path, cache_file, base - cache_file);
base = path + (base - cache_file);
file = 0; file = 0;
name = 0; name = 0;
path = 0;
while ((file = FcFileCacheReadString (f, file_buf, sizeof (file_buf))) && while ((file = FcFileCacheReadString (f, file_buf, sizeof (file_buf))) &&
FcFileCacheReadInt (f, &id) && FcFileCacheReadInt (f, &id) &&
(name = FcFileCacheReadString (f, name_buf, sizeof (name_buf)))) (name = FcFileCacheReadString (f, name_buf, sizeof (name_buf))))
{ {
font = FcNameParse (name); file_len = strlen ((const char *) file);
if (font) if (dir_len + file_len + 1 > sizeof (path_buf))
{
path = malloc (dir_len + file_len + 1);
if (!path)
goto bail2;
strncpy ((char *) path, (const char *) cache_file, dir_len);
}
else
path = path_buf;
strcpy ((char *) path + dir_len, (const char *) file);
if (!FcStrCmp (name, FC_FONT_FILE_DIR))
{ {
strcpy ((char *) base, (const char *) file);
if (FcDebug () & FC_DBG_CACHEV) if (FcDebug () & FC_DBG_CACHEV)
{ {
printf (" dir cache file \"%s\"\n", file); printf (" dir cache dir \"%s\"\n", path);
} }
FcPatternAddString (font, FC_FILE, path); if (!FcStrSetAdd (dirs, path))
if (!FcFontSetAdd (set, font))
goto bail2; goto bail2;
} }
else
{
font = FcNameParse (name);
if (font)
{
if (FcDebug () & FC_DBG_CACHEV)
{
printf (" dir cache file \"%s\"\n", file);
}
FcPatternAddString (font, FC_FILE, path);
if (!FcFontSetAdd (set, font))
goto bail2;
}
}
if (path != path_buf)
free (path);
if (file != file_buf) if (file != file_buf)
free (file); free (file);
if (name != name_buf) if (name != name_buf)
free (name); free (name);
file = name = 0; path = file = name = 0;
} }
if (FcDebug () & FC_DBG_CACHE) if (FcDebug () & FC_DBG_CACHE)
{ {
@ -554,7 +614,8 @@ FcFileCacheReadDir (FcFontSet *set, const FcChar8 *cache_file)
ret = FcTrue; ret = FcTrue;
bail2: bail2:
free (path); if (path && path != path_buf)
free (path);
if (file && file != file_buf) if (file && file != file_buf)
free (file); free (file);
if (name && name != name_buf) if (name && name != name_buf)
@ -565,8 +626,24 @@ bail0:
return ret; return ret;
} }
/*
* return the path from the directory containing 'cache' to 'file'
*/
static const FcChar8 *
FcFileBaseName (const FcChar8 *cache, const FcChar8 *file)
{
const FcChar8 *cache_slash;
cache_slash = (const FcChar8 *) strrchr ((const char *) cache, '/');
if (cache_slash && !strncmp ((const char *) cache, (const char *) file,
(cache_slash + 1) - cache))
return file + ((cache_slash + 1) - cache);
return file;
}
FcBool FcBool
FcFileCacheWriteDir (FcFontSet *set, const FcChar8 *cache_file) FcFileCacheWriteDir (FcFontSet *set, FcStrSet *dirs, const FcChar8 *cache_file)
{ {
FcPattern *font; FcPattern *font;
FILE *f; FILE *f;
@ -575,6 +652,8 @@ FcFileCacheWriteDir (FcFontSet *set, const FcChar8 *cache_file)
int n; int n;
int id; int id;
FcBool ret; FcBool ret;
FcStrList *list;
FcChar8 *dir;
if (FcDebug () & FC_DBG_CACHE) if (FcDebug () & FC_DBG_CACHE)
printf ("FcFileCacheWriteDir cache_file \"%s\"\n", cache_file); printf ("FcFileCacheWriteDir cache_file \"%s\"\n", cache_file);
@ -586,38 +665,59 @@ FcFileCacheWriteDir (FcFontSet *set, const FcChar8 *cache_file)
printf (" can't create \"%s\"\n", cache_file); printf (" can't create \"%s\"\n", cache_file);
goto bail0; goto bail0;
} }
list = FcStrListCreate (dirs);
if (!list)
goto bail1;
while ((dir = FcStrListNext (list)))
{
base = FcFileBaseName (cache_file, dir);
if (!FcFileCacheWriteString (f, base))
goto bail2;
if (putc (' ', f) == EOF)
goto bail2;
if (!FcFileCacheWriteInt (f, 0))
goto bail2;
if (putc (' ', f) == EOF)
goto bail2;
if (!FcFileCacheWriteString (f, FC_FONT_FILE_DIR))
goto bail2;
if (putc ('\n', f) == EOF)
goto bail2;
}
for (n = 0; n < set->nfont; n++) for (n = 0; n < set->nfont; n++)
{ {
font = set->fonts[n]; font = set->fonts[n];
if (FcPatternGetString (font, FC_FILE, 0, (FcChar8 **) &file) != FcResultMatch) if (FcPatternGetString (font, FC_FILE, 0, (FcChar8 **) &file) != FcResultMatch)
goto bail1; goto bail2;
base = (FcChar8 *) strrchr ((char *) file, '/'); base = FcFileBaseName (cache_file, file);
if (base)
base = base + 1;
else
base = file;
if (FcPatternGetInteger (font, FC_INDEX, 0, &id) != FcResultMatch) if (FcPatternGetInteger (font, FC_INDEX, 0, &id) != FcResultMatch)
goto bail1; goto bail2;
if (FcDebug () & FC_DBG_CACHEV) if (FcDebug () & FC_DBG_CACHEV)
printf (" write file \"%s\"\n", base); printf (" write file \"%s\"\n", base);
if (!FcFileCacheWriteString (f, base)) if (!FcFileCacheWriteString (f, base))
goto bail1; goto bail2;
if (putc (' ', f) == EOF) if (putc (' ', f) == EOF)
goto bail1; goto bail2;
if (!FcFileCacheWriteInt (f, id)) if (!FcFileCacheWriteInt (f, id))
goto bail1; goto bail2;
if (putc (' ', f) == EOF) if (putc (' ', f) == EOF)
goto bail1; goto bail2;
name = FcNameUnparse (font); name = FcNameUnparse (font);
if (!name) if (!name)
goto bail1; goto bail2;
ret = FcFileCacheWriteString (f, name); ret = FcFileCacheWriteString (f, name);
free (name); free (name);
if (!ret) if (!ret)
goto bail1; goto bail2;
if (putc ('\n', f) == EOF) if (putc ('\n', f) == EOF)
goto bail1; goto bail2;
} }
FcStrListDone (list);
if (fclose (f) == EOF) if (fclose (f) == EOF)
goto bail0; goto bail0;
@ -625,6 +725,8 @@ FcFileCacheWriteDir (FcFontSet *set, const FcChar8 *cache_file)
printf (" cache written\n"); printf (" cache written\n");
return FcTrue; return FcTrue;
bail2:
FcStrListDone (list);
bail1: bail1:
fclose (f); fclose (f);
bail0: bail0:

View File

@ -1,5 +1,5 @@
/* /*
* $XFree86: xc/lib/fontconfig/src/fccfg.c,v 1.4 2002/02/24 01:23:35 keithp Exp $ * $XFree86: xc/lib/fontconfig/src/fccfg.c,v 1.5 2002/03/01 01:00:54 keithp Exp $
* *
* Copyright © 2000 Keith Packard, member of The XFree86 Project, Inc. * Copyright © 2000 Keith Packard, member of The XFree86 Project, Inc.
* *
@ -22,9 +22,6 @@
* PERFORMANCE OF THIS SOFTWARE. * PERFORMANCE OF THIS SOFTWARE.
*/ */
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "fcint.h" #include "fcint.h"
FcConfig *_fcConfig; FcConfig *_fcConfig;
@ -38,20 +35,23 @@ FcConfigCreate (void)
config = malloc (sizeof (FcConfig)); config = malloc (sizeof (FcConfig));
if (!config) if (!config)
goto bail0; goto bail0;
FcMemAlloc (FC_MEM_CONFIG, sizeof (FcConfig));
config->dirs = malloc (sizeof (char *)); config->configDirs = FcStrSetCreate ();
if (!config->dirs) if (!config->configDirs)
goto bail1; goto bail1;
config->dirs[0] = 0;
config->configFiles = malloc (sizeof (char *)); config->configFiles = FcStrSetCreate ();
if (!config->configFiles) if (!config->configFiles)
goto bail2; goto bail2;
config->configFiles[0] = 0;
config->fontDirs = FcStrSetCreate ();
if (!config->fontDirs)
goto bail3;
config->cache = 0; config->cache = 0;
if (!FcConfigSetCache (config, (FcChar8 *) ("~/" FC_USER_CACHE_FILE))) if (!FcConfigSetCache (config, (FcChar8 *) ("~/" FC_USER_CACHE_FILE)))
goto bail3; goto bail4;
config->blanks = 0; config->blanks = 0;
@ -60,19 +60,74 @@ FcConfigCreate (void)
config->maxObjects = 0; config->maxObjects = 0;
for (set = FcSetSystem; set <= FcSetApplication; set++) for (set = FcSetSystem; set <= FcSetApplication; set++)
config->fonts[set] = 0; config->fonts[set] = 0;
config->rescanTime = time(0);
config->rescanInterval = 30;
return config; return config;
bail4:
FcStrSetDestroy (config->fontDirs);
bail3: bail3:
free (config->configFiles); FcStrSetDestroy (config->configFiles);
bail2: bail2:
free (config->dirs); FcStrSetDestroy (config->configDirs);
bail1: bail1:
free (config); free (config);
FcMemFree (FC_MEM_CONFIG, sizeof (FcConfig));
bail0: bail0:
return 0; return 0;
} }
static time_t
FcConfigNewestFile (FcStrSet *files)
{
FcStrList *list = FcStrListCreate (files);
FcBool set = FcFalse;
time_t newest = 0;
FcChar8 *file;
struct stat statb;
if (list)
{
while ((file = FcStrListNext (list)))
{
if (stat ((char *) file, &statb) == 0)
{
if (!set)
newest = statb.st_mtime;
else if (statb.st_mtime - newest > 0)
newest = statb.st_mtime;
}
}
FcStrListDone (list);
}
return newest;
}
FcBool
FcConfigUptoDate (FcConfig *config)
{
time_t config_time;
time_t font_time;
time_t now = time(0);
if (!config)
{
config = FcConfigGetCurrent ();
if (!config)
return FcFalse;
}
config_time = FcConfigNewestFile (config->configFiles);
font_time = FcConfigNewestFile (config->configDirs);
if (config_time - config->rescanTime > 0 ||
font_time - config->rescanTime > 0)
{
return FcFalse;
}
config->rescanTime = now;
return FcTrue;
}
static void static void
FcSubstDestroy (FcSubst *s) FcSubstDestroy (FcSubst *s)
{ {
@ -87,51 +142,27 @@ FcSubstDestroy (FcSubst *s)
} }
} }
static void
FcConfigDestroyStrings (FcChar8 **strings)
{
FcChar8 **s;
for (s = strings; s && *s; s++)
free (*s);
if (strings)
free (strings);
}
static FcBool
FcConfigAddString (FcChar8 ***strings, FcChar8 *string)
{
int n;
FcChar8 **s;
n = 0;
for (s = *strings; s && *s; s++)
n++;
s = malloc ((n + 2) * sizeof (FcChar8 *));
if (!s)
return FcFalse;
s[n] = string;
s[n+1] = 0;
memcpy (s, *strings, n * sizeof (FcChar8 *));
free (*strings);
*strings = s;
return FcTrue;
}
void void
FcConfigDestroy (FcConfig *config) FcConfigDestroy (FcConfig *config)
{ {
FcSetName set; FcSetName set;
FcConfigDestroyStrings (config->dirs);
FcConfigDestroyStrings (config->configFiles);
free (config->cache); if (config == _fcConfig)
_fcConfig = 0;
FcStrSetDestroy (config->configDirs);
FcStrSetDestroy (config->fontDirs);
FcStrSetDestroy (config->configFiles);
FcStrFree (config->cache);
FcSubstDestroy (config->substPattern); FcSubstDestroy (config->substPattern);
FcSubstDestroy (config->substFont); FcSubstDestroy (config->substFont);
for (set = FcSetSystem; set <= FcSetApplication; set++) for (set = FcSetSystem; set <= FcSetApplication; set++)
if (config->fonts[set]) if (config->fonts[set])
FcFontSetDestroy (config->fonts[set]); FcFontSetDestroy (config->fonts[set]);
free (config);
FcMemFree (FC_MEM_CONFIG, sizeof (FcConfig));
} }
/* /*
@ -145,7 +176,8 @@ FcConfigBuildFonts (FcConfig *config)
{ {
FcFontSet *fonts; FcFontSet *fonts;
FcFileCache *cache; FcFileCache *cache;
FcChar8 **d; FcStrList *list;
FcChar8 *dir;
fonts = FcFontSetCreate (); fonts = FcFontSetCreate ();
if (!fonts) if (!fonts)
@ -157,13 +189,19 @@ FcConfigBuildFonts (FcConfig *config)
FcFileCacheLoad (cache, config->cache); FcFileCacheLoad (cache, config->cache);
for (d = config->dirs; d && *d; d++) list = FcConfigGetFontDirs (config);
if (!list)
goto bail1;
while ((dir = FcStrListNext (list)))
{ {
if (FcDebug () & FC_DBG_FONTSET) if (FcDebug () & FC_DBG_FONTSET)
printf ("scan dir %s\n", *d); printf ("scan dir %s\n", dir);
FcDirScan (fonts, cache, config->blanks, *d, FcFalse); FcDirScan (fonts, config->fontDirs, cache, config->blanks, dir, FcFalse);
} }
FcStrListDone (list);
if (FcDebug () & FC_DBG_FONTSET) if (FcDebug () & FC_DBG_FONTSET)
FcFontSetPrint (fonts); FcFontSetPrint (fonts);
@ -202,40 +240,14 @@ FcConfigGetCurrent (void)
} }
FcBool FcBool
FcConfigAddDir (FcConfig *config, FcConfigAddConfigDir (FcConfig *config,
const FcChar8 *d) const FcChar8 *d)
{ {
FcChar8 *dir; return FcStrSetAddFilename (config->configDirs, d);
FcChar8 *h;
if (*d == '~')
{
h = (FcChar8 *) getenv ("HOME");
if (!h)
return FcFalse;
dir = (FcChar8 *) malloc (strlen ((char *) h) + strlen ((char *) d));
if (!dir)
return FcFalse;
strcpy ((char *) dir, (char *) h);
strcat ((char *) dir, (char *) d+1);
}
else
{
dir = (FcChar8 *) malloc (strlen ((char *) d) + 1);
if (!dir)
return FcFalse;
strcpy ((char *) dir, (const char *) d);
}
if (!FcConfigAddString (&config->dirs, dir))
{
free (dir);
return FcFalse;
}
return FcTrue;
} }
FcChar8 ** FcStrList *
FcConfigGetDirs (FcConfig *config) FcConfigGetConfigDirs (FcConfig *config)
{ {
if (!config) if (!config)
{ {
@ -243,26 +255,52 @@ FcConfigGetDirs (FcConfig *config)
if (!config) if (!config)
return 0; return 0;
} }
return config->dirs; return FcStrListCreate (config->configDirs);
}
FcBool
FcConfigAddFontDir (FcConfig *config,
const FcChar8 *d)
{
return FcStrSetAddFilename (config->fontDirs, d);
}
FcBool
FcConfigAddDir (FcConfig *config,
const FcChar8 *d)
{
return (FcConfigAddConfigDir (config, d) &&
FcConfigAddFontDir (config, d));
}
FcStrList *
FcConfigGetFontDirs (FcConfig *config)
{
if (!config)
{
config = FcConfigGetCurrent ();
if (!config)
return 0;
}
return FcStrListCreate (config->fontDirs);
} }
FcBool FcBool
FcConfigAddConfigFile (FcConfig *config, FcConfigAddConfigFile (FcConfig *config,
const FcChar8 *f) const FcChar8 *f)
{ {
FcChar8 *file; FcBool ret;
file = FcConfigFilename (f); FcChar8 *file = FcConfigFilename (f);
if (!file) if (!file)
return FcFalse; return FcFalse;
if (!FcConfigAddString (&config->configFiles, file))
{ ret = FcStrSetAdd (config->configFiles, file);
free (file); FcStrFree (file);
return FcFalse; return ret;
}
return FcTrue;
} }
FcChar8 ** FcStrList *
FcConfigGetConfigFiles (FcConfig *config) FcConfigGetConfigFiles (FcConfig *config)
{ {
if (!config) if (!config)
@ -271,33 +309,19 @@ FcConfigGetConfigFiles (FcConfig *config)
if (!config) if (!config)
return 0; return 0;
} }
return config->configFiles; return FcStrListCreate (config->configFiles);
} }
FcBool FcBool
FcConfigSetCache (FcConfig *config, FcConfigSetCache (FcConfig *config,
const FcChar8 *c) const FcChar8 *c)
{ {
FcChar8 *new; FcChar8 *new = FcStrCopyFilename (c);
FcChar8 *h;
if (!new)
if (*c == '~') return FcFalse;
{
h = (FcChar8 *) getenv ("HOME");
if (!h)
return FcFalse;
new = (FcChar8 *) malloc (strlen ((char *) h) + strlen ((char *) c));
if (!new)
return FcFalse;
strcpy ((char *) new, (char *) h);
strcat ((char *) new, (char *) c+1);
}
else
{
new = FcStrCopy (c);
}
if (config->cache) if (config->cache)
free (config->cache); FcStrFree (config->cache);
config->cache = new; config->cache = new;
return FcTrue; return FcTrue;
} }
@ -337,6 +361,8 @@ FcConfigSetFonts (FcConfig *config,
config->fonts[set] = fonts; config->fonts[set] = fonts;
} }
FcBlanks * FcBlanks *
FcConfigGetBlanks (FcConfig *config) FcConfigGetBlanks (FcConfig *config)
{ {
@ -368,6 +394,31 @@ FcConfigAddBlank (FcConfig *config,
return FcTrue; return FcTrue;
} }
int
FcConfigGetRescanInverval (FcConfig *config)
{
if (!config)
{
config = FcConfigGetCurrent ();
if (!config)
return 0;
}
return config->rescanInterval;
}
FcBool
FcConfigSetRescanInverval (FcConfig *config, int rescanInterval)
{
if (!config)
{
config = FcConfigGetCurrent ();
if (!config)
return FcFalse;
}
config->rescanInterval = rescanInterval;
return FcTrue;
}
FcBool FcBool
FcConfigAddEdit (FcConfig *config, FcConfigAddEdit (FcConfig *config,
FcTest *test, FcTest *test,
@ -805,22 +856,37 @@ FcConfigMatchValueList (FcPattern *p,
FcTest *t, FcTest *t,
FcValueList *v) FcValueList *v)
{ {
FcValueList *ret = 0; FcValueList *ret = 0;
FcValue value = FcConfigEvaluate (p, t->expr); FcExpr *e = t->expr;
FcValue value;
for (; v; v = v->next) while (e)
{ {
if (FcConfigCompareValue (v->value, t->op, value)) if (e->op == FcOpComma)
{ {
if (!ret) value = FcConfigEvaluate (p, e->u.tree.left);
ret = v; e = e->u.tree.right;
} }
else else
{ {
if (t->qual == FcQualAll) value = FcConfigEvaluate (p, e);
e = 0;
}
for (; v; v = v->next)
{
if (FcConfigCompareValue (v->value, t->op, value))
{ {
ret = 0; if (!ret)
break; ret = v;
}
else
{
if (t->qual == FcQualAll)
{
ret = 0;
break;
}
} }
} }
} }
@ -1323,6 +1389,9 @@ FcConfigAppFontAddFile (FcConfig *config,
const FcChar8 *file) const FcChar8 *file)
{ {
FcFontSet *set; FcFontSet *set;
FcStrSet *subdirs;
FcStrList *sublist;
FcChar8 *subdir;
if (!config) if (!config)
{ {
@ -1331,15 +1400,36 @@ FcConfigAppFontAddFile (FcConfig *config,
return FcFalse; return FcFalse;
} }
subdirs = FcStrSetCreate ();
if (!subdirs)
return FcFalse;
set = FcConfigGetFonts (config, FcSetApplication); set = FcConfigGetFonts (config, FcSetApplication);
if (!set) if (!set)
{ {
set = FcFontSetCreate (); set = FcFontSetCreate ();
if (!set) if (!set)
{
FcStrSetDestroy (subdirs);
return FcFalse; return FcFalse;
}
FcConfigSetFonts (config, set, FcSetApplication); FcConfigSetFonts (config, set, FcSetApplication);
} }
return FcFileScan (set, 0, config->blanks, file, FcFalse);
if (!FcFileScan (set, subdirs, 0, config->blanks, file, FcFalse))
{
FcStrSetDestroy (subdirs);
return FcFalse;
}
if ((sublist = FcStrListCreate (subdirs)))
{
while ((subdir = FcStrListNext (sublist)))
{
FcConfigAppFontAddDir (config, subdir);
}
FcStrListDone (sublist);
}
return FcTrue;
} }
FcBool FcBool
@ -1347,6 +1437,9 @@ FcConfigAppFontAddDir (FcConfig *config,
const FcChar8 *dir) const FcChar8 *dir)
{ {
FcFontSet *set; FcFontSet *set;
FcStrSet *subdirs;
FcStrList *sublist;
FcChar8 *subdir;
if (!config) if (!config)
{ {
@ -1354,15 +1447,36 @@ FcConfigAppFontAddDir (FcConfig *config,
if (!config) if (!config)
return FcFalse; return FcFalse;
} }
subdirs = FcStrSetCreate ();
if (!subdirs)
return FcFalse;
set = FcConfigGetFonts (config, FcSetApplication); set = FcConfigGetFonts (config, FcSetApplication);
if (!set) if (!set)
{ {
set = FcFontSetCreate (); set = FcFontSetCreate ();
if (!set) if (!set)
{
FcStrSetDestroy (subdirs);
return FcFalse; return FcFalse;
}
FcConfigSetFonts (config, set, FcSetApplication); FcConfigSetFonts (config, set, FcSetApplication);
} }
return FcDirScan (set, 0, config->blanks, dir, FcFalse);
if (!FcDirScan (set, subdirs, 0, config->blanks, dir, FcFalse))
{
FcStrSetDestroy (subdirs);
return FcFalse;
}
if ((sublist = FcStrListCreate (subdirs)))
{
while ((subdir = FcStrListNext (sublist)))
{
FcConfigAppFontAddDir (config, subdir);
}
FcStrListDone (sublist);
}
return FcTrue;
} }
void void

View File

@ -22,16 +22,22 @@
* PERFORMANCE OF THIS SOFTWARE. * PERFORMANCE OF THIS SOFTWARE.
*/ */
#include <sys/types.h>
#include <dirent.h>
#include <stdlib.h>
#include <string.h>
#include "fcint.h" #include "fcint.h"
#include <dirent.h>
#define FC_INVALID_FONT_FILE "." static FcBool
FcFileIsDir (const FcChar8 *file)
{
struct stat statb;
if (stat ((const char *) file, &statb) != 0)
return FcFalse;
return S_ISDIR(statb.st_mode);
}
FcBool FcBool
FcFileScan (FcFontSet *set, FcFileScan (FcFontSet *set,
FcStrSet *dirs,
FcFileCache *cache, FcFileCache *cache,
FcBlanks *blanks, FcBlanks *blanks,
const FcChar8 *file, const FcChar8 *file,
@ -41,6 +47,7 @@ FcFileScan (FcFontSet *set,
FcChar8 *name; FcChar8 *name;
FcPattern *font; FcPattern *font;
FcBool ret = FcTrue; FcBool ret = FcTrue;
FcBool isDir;
int count; int count;
id = 0; id = 0;
@ -53,14 +60,19 @@ FcFileScan (FcFontSet *set,
if (name) if (name)
{ {
/* "." means the file doesn't contain a font */ /* "." means the file doesn't contain a font */
if (strcmp ((const char *) name, FC_INVALID_FONT_FILE) != 0) if (FcStrCmp (name, FC_FONT_FILE_INVALID) == 0)
font = 0;
else if (FcStrCmp (name, FC_FONT_FILE_DIR) == 0)
{
ret = FcStrSetAdd (dirs, file);
font = 0;
}
else
{ {
font = FcNameParse (name); font = FcNameParse (name);
if (font) if (font)
FcPatternAddString (font, FC_FILE, file); FcPatternAddString (font, FC_FILE, file);
} }
else
font = 0;
} }
else else
{ {
@ -72,6 +84,12 @@ FcFileScan (FcFontSet *set,
font = FcFreeTypeQuery (file, id, blanks, &count); font = FcFreeTypeQuery (file, id, blanks, &count);
if (FcDebug () & FC_DBG_SCAN) if (FcDebug () & FC_DBG_SCAN)
printf ("done\n"); printf ("done\n");
isDir = FcFalse;
if (!font && FcFileIsDir (file))
{
isDir = FcTrue;
ret = FcStrSetAdd (dirs, file);
}
if (!force && cache) if (!force && cache)
{ {
if (font) if (font)
@ -87,8 +105,17 @@ FcFileScan (FcFontSet *set,
} }
else else
{ {
/* negative cache files not containing fonts */ if (isDir)
FcFileCacheUpdate (cache, file, id, (FcChar8 *) FC_INVALID_FONT_FILE); {
FcFileCacheUpdate (cache, file, id, (FcChar8 *)
FC_FONT_FILE_DIR);
}
else
{
/* negative cache files not containing fonts */
FcFileCacheUpdate (cache, file, id, (FcChar8 *)
FC_FONT_FILE_INVALID);
}
} }
} }
} }
@ -106,8 +133,29 @@ FcFileScan (FcFontSet *set,
return ret; return ret;
} }
FcBool
FcDirCacheValid (const FcChar8 *dir)
{
FcChar8 *path;
FcBool ret;
path = (FcChar8 *) malloc (strlen ((const char *) dir) + 1 +
strlen ((const char *) FC_DIR_CACHE_FILE) + 1);
if (!path)
return FcFalse;
strcpy ((char *) path, (const char *) dir);
strcat ((char *) path, (const char *) "/");
strcat ((char *) path, (const char *) FC_DIR_CACHE_FILE);
ret = FcFileCacheValid (path);
free (path);
return ret;
}
#define FC_MAX_FILE_LEN 4096
FcBool FcBool
FcDirScan (FcFontSet *set, FcDirScan (FcFontSet *set,
FcStrSet *dirs,
FcFileCache *cache, FcFileCache *cache,
FcBlanks *blanks, FcBlanks *blanks,
const FcChar8 *dir, const FcChar8 *dir,
@ -119,7 +167,7 @@ FcDirScan (FcFontSet *set,
FcChar8 *base; FcChar8 *base;
FcBool ret = FcTrue; FcBool ret = FcTrue;
file = (FcChar8 *) malloc (strlen ((char *) dir) + 1 + 256 + 1); file = (FcChar8 *) malloc (strlen ((char *) dir) + 1 + FC_MAX_FILE_LEN + 1);
if (!file) if (!file)
return FcFalse; return FcFalse;
@ -130,7 +178,7 @@ FcDirScan (FcFontSet *set,
{ {
strcpy ((char *) base, FC_DIR_CACHE_FILE); strcpy ((char *) base, FC_DIR_CACHE_FILE);
if (FcFileCacheReadDir (set, file)) if (FcFileCacheReadDir (set, dirs, file))
{ {
free (file); free (file);
return FcTrue; return FcTrue;
@ -141,14 +189,17 @@ FcDirScan (FcFontSet *set,
if (!d) if (!d)
{ {
free (file); free (file);
/* Don't complain about missing directories */
if (errno == ENOENT)
return FcTrue;
return FcFalse; return FcFalse;
} }
while (ret && (e = readdir (d))) while (ret && (e = readdir (d)))
{ {
if (e->d_name[0] != '.') if (e->d_name[0] != '.' && strlen (e->d_name) < FC_MAX_FILE_LEN)
{ {
strcpy ((char *) base, (char *) e->d_name); strcpy ((char *) base, (char *) e->d_name);
ret = FcFileScan (set, cache, blanks, file, force); ret = FcFileScan (set, dirs, cache, blanks, file, force);
} }
} }
free (file); free (file);
@ -157,7 +208,7 @@ FcDirScan (FcFontSet *set,
} }
FcBool FcBool
FcDirSave (FcFontSet *set, const FcChar8 *dir) FcDirSave (FcFontSet *set, FcStrSet *dirs, const FcChar8 *dir)
{ {
FcChar8 *file; FcChar8 *file;
FcChar8 *base; FcChar8 *base;
@ -171,8 +222,7 @@ FcDirSave (FcFontSet *set, const FcChar8 *dir)
strcat ((char *) file, "/"); strcat ((char *) file, "/");
base = file + strlen ((char *) file); base = file + strlen ((char *) file);
strcpy ((char *) base, FC_DIR_CACHE_FILE); strcpy ((char *) base, FC_DIR_CACHE_FILE);
ret = FcFileCacheWriteDir (set, file); ret = FcFileCacheWriteDir (set, dirs, file);
free (file); free (file);
return ret; return ret;
} }

View File

@ -1,5 +1,5 @@
/* /*
* $XFree86: xc/lib/fontconfig/src/fcinit.c,v 1.2 2002/02/15 06:01:28 keithp Exp $ * $XFree86: xc/lib/fontconfig/src/fcinit.c,v 1.3 2002/02/19 08:33:23 keithp Exp $
* *
* Copyright © 2001 Keith Packard, member of The XFree86 Project, Inc. * Copyright © 2001 Keith Packard, member of The XFree86 Project, Inc.
* *
@ -25,22 +25,7 @@
#include <stdlib.h> #include <stdlib.h>
#include "fcint.h" #include "fcint.h"
FcBool static FcConfig *
FcInitFonts (void)
{
FcConfig *config;
config = FcConfigGetCurrent ();
if (!config)
return FcFalse;
if (FcConfigGetFonts (config, FcSetSystem))
return FcTrue;
return FcConfigBuildFonts (config);
}
static FcBool
FcInitFallbackConfig (void) FcInitFallbackConfig (void)
{ {
FcConfig *config; FcConfig *config;
@ -50,25 +35,21 @@ FcInitFallbackConfig (void)
goto bail0; goto bail0;
if (!FcConfigAddDir (config, (FcChar8 *) FC_FALLBACK_FONTS)) if (!FcConfigAddDir (config, (FcChar8 *) FC_FALLBACK_FONTS))
goto bail1; goto bail1;
FcConfigSetCurrent (config); return config;
return FcTrue;
bail1: bail1:
FcConfigDestroy (config); FcConfigDestroy (config);
bail0: bail0:
return FcFalse; return 0;
} }
/* /*
* Locate and parse the configuration file * Load the configuration files
*/ */
FcBool FcConfig *
FcInitConfig (void) FcInitLoadConfig (void)
{ {
FcConfig *config; FcConfig *config;
if (_fcConfig)
return FcTrue;
config = FcConfigCreate (); config = FcConfigCreate ();
if (!config) if (!config)
@ -79,15 +60,83 @@ FcInitConfig (void)
FcConfigDestroy (config); FcConfigDestroy (config);
return FcInitFallbackConfig (); return FcInitFallbackConfig ();
} }
return config;
}
/*
* Load the configuration files and scan for available fonts
*/
FcConfig *
FcInitLoadConfigAndFonts (void)
{
FcConfig *config = FcInitLoadConfig ();
if (!config)
return 0;
if (!FcConfigBuildFonts (config))
{
FcConfigDestroy (config);
return 0;
}
return config;
}
/*
* Initialize the default library configuration
*/
FcBool
FcInit (void)
{
FcConfig *config;
if (_fcConfig)
return FcTrue;
config = FcInitLoadConfigAndFonts ();
if (!config)
return FcTrue;
FcConfigSetCurrent (config);
return FcTrue;
}
/*
* Reread the configuration and available font lists
*/
FcBool
FcInitReinitialize (void)
{
FcConfig *config;
config = FcInitLoadConfigAndFonts ();
if (!config)
return FcFalse;
FcConfigSetCurrent (config); FcConfigSetCurrent (config);
return FcTrue; return FcTrue;
} }
FcBool FcBool
FcInit (void) FcInitBringUptoDate (void)
{ {
return FcInitConfig () && FcInitFonts (); FcConfig *config = FcConfigGetCurrent ();
time_t now;
/*
* rescanInterval == 0 disables automatic up to date
*/
if (config->rescanInterval == 0)
return FcTrue;
/*
* Check no more often than rescanInterval seconds
*/
now = time (0);
if (config->rescanTime + config->rescanInterval - now > 0)
return FcTrue;
/*
* If up to date, don't reload configuration
*/
if (FcConfigUptoDate (0))
return FcTrue;
return FcInitReinitialize ();
} }
static struct { static struct {

View File

@ -33,6 +33,7 @@
#include <unistd.h> #include <unistd.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <time.h>
#include <fontconfig/fontconfig.h> #include <fontconfig/fontconfig.h>
#include <fontconfig/fcprivate.h> #include <fontconfig/fcprivate.h>
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
@ -53,6 +54,9 @@ typedef struct _FcSymbolic {
#define FC_CONFIG_PATH "fonts.conf" #define FC_CONFIG_PATH "fonts.conf"
#endif #endif
#define FC_FONT_FILE_INVALID ((FcChar8 *) ".")
#define FC_FONT_FILE_DIR ((FcChar8 *) ".dir")
#define FC_DBG_MATCH 1 #define FC_DBG_MATCH 1
#define FC_DBG_MATCHV 2 #define FC_DBG_MATCHV 2
#define FC_DBG_EDIT 4 #define FC_DBG_EDIT 4
@ -77,6 +81,9 @@ typedef struct _FcSymbolic {
#define FC_MEM_STRING 11 #define FC_MEM_STRING 11
#define FC_MEM_LISTBUCK 12 #define FC_MEM_LISTBUCK 12
#define FC_MEM_NUM 13 #define FC_MEM_NUM 13
#define FC_MEM_STRSET 14
#define FC_MEM_STRLIST 15
#define FC_MEM_CONFIG 16
typedef struct _FcValueList { typedef struct _FcValueList {
struct _FcValueList *next; struct _FcValueList *next;
@ -173,6 +180,18 @@ struct _FcCharSet {
FcCharNode node; FcCharNode node;
}; };
struct _FcStrSet {
int ref; /* reference count */
int num;
int size;
FcChar8 **strs;
};
struct _FcStrList {
FcStrSet *set;
int n;
};
typedef struct _FcStrBuf { typedef struct _FcStrBuf {
FcChar8 *buf; FcChar8 *buf;
FcBool allocated; FcBool allocated;
@ -219,18 +238,24 @@ struct _FcConfig {
* cache file must be consulted before the directories are scanned, * cache file must be consulted before the directories are scanned,
* and those directives may occur in any order * and those directives may occur in any order
*/ */
FcChar8 **dirs; /* directories containing fonts */ FcStrSet *configDirs; /* directories to scan for fonts */
FcChar8 *cache; /* name of per-user cache file */ FcChar8 *cache; /* name of per-user cache file */
/* /*
* Set of allowed blank chars -- used to * Set of allowed blank chars -- used to
* trim fonts of bogus glyphs * trim fonts of bogus glyphs
*/ */
FcBlanks *blanks; FcBlanks *blanks;
/*
* List of directories containing fonts,
* built by recursively scanning the set
* of configured directories
*/
FcStrSet *fontDirs;
/* /*
* Names of all of the configuration files used * Names of all of the configuration files used
* to create this configuration * to create this configuration
*/ */
FcChar8 **configFiles; /* config files loaded */ FcStrSet *configFiles; /* config files loaded */
/* /*
* Substitution instructions for patterns and fonts; * Substitution instructions for patterns and fonts;
* maxObjects is used to allocate appropriate intermediate storage * maxObjects is used to allocate appropriate intermediate storage
@ -246,6 +271,14 @@ struct _FcConfig {
* match preferrentially * match preferrentially
*/ */
FcFontSet *fonts[FcSetApplication + 1]; FcFontSet *fonts[FcSetApplication + 1];
/*
* Fontconfig can periodically rescan the system configuration
* and font directories. This rescanning occurs when font
* listing requests are made, but no more often than rescanInterval
* seconds apart.
*/
time_t rescanTime; /* last time information was scanned */
int rescanInterval; /* interval between scans */
}; };
extern FcConfig *_fcConfig; extern FcConfig *_fcConfig;
@ -266,6 +299,9 @@ FcFileCacheFind (FcFileCache *cache,
void void
FcFileCacheDestroy (FcFileCache *cache); FcFileCacheDestroy (FcFileCache *cache);
FcBool
FcFileCacheValid (const FcChar8 *cache_file);
void void
FcFileCacheLoad (FcFileCache *cache, FcFileCacheLoad (FcFileCache *cache,
const FcChar8 *cache_file); const FcChar8 *cache_file);
@ -281,13 +317,21 @@ FcFileCacheSave (FcFileCache *cache,
const FcChar8 *cache_file); const FcChar8 *cache_file);
FcBool FcBool
FcFileCacheReadDir (FcFontSet *set, const FcChar8 *cache_file); FcFileCacheReadDir (FcFontSet *set, FcStrSet *dirs, const FcChar8 *cache_file);
FcBool FcBool
FcFileCacheWriteDir (FcFontSet *set, const FcChar8 *cache_file); FcFileCacheWriteDir (FcFontSet *set, FcStrSet *dirs, const FcChar8 *cache_file);
/* fccfg.c */ /* fccfg.c */
FcBool
FcConfigAddConfigDir (FcConfig *config,
const FcChar8 *d);
FcBool
FcConfigAddFontDir (FcConfig *config,
const FcChar8 *d);
FcBool FcBool
FcConfigAddDir (FcConfig *config, FcConfigAddDir (FcConfig *config,
const FcChar8 *d); const FcChar8 *d);

View File

@ -1,5 +1,5 @@
/* /*
* $XFree86: $ * $XFree86: xc/lib/fontconfig/src/fclist.c,v 1.2 2002/02/28 16:51:48 keithp Exp $
* *
* Copyright © 2000 Keith Packard, member of The XFree86 Project, Inc. * Copyright © 2000 Keith Packard, member of The XFree86 Project, Inc.
* *
@ -372,6 +372,9 @@ FcFontSetList (FcConfig *config,
if (!config) if (!config)
{ {
if (!FcInitBringUptoDate ())
goto bail0;
config = FcConfigGetCurrent (); config = FcConfigGetCurrent ();
if (!config) if (!config)
goto bail0; goto bail0;

View File

@ -1,5 +1,5 @@
/* /*
* $XFree86: xc/lib/fontconfig/src/fcstr.c,v 1.2 2002/02/15 06:01:28 keithp Exp $ * $XFree86: xc/lib/fontconfig/src/fcstr.c,v 1.3 2002/02/18 22:29:28 keithp Exp $
* *
* Copyright © 2000 Keith Packard, member of The XFree86 Project, Inc. * Copyright © 2000 Keith Packard, member of The XFree86 Project, Inc.
* *
@ -82,6 +82,25 @@ FcStrCmpIgnoreCase (const FcChar8 *s1, const FcChar8 *s2)
return (int) c2 - (int) c1; return (int) c2 - (int) c1;
} }
int
FcStrCmp (const FcChar8 *s1, const FcChar8 *s2)
{
FcChar8 c1, c2;
if (s1 == s2)
return 0;
for (;;)
{
c1 = *s1++;
c2 = *s2++;
if (!c1 || !c2)
break;
if (c1 != c2)
break;
}
return (int) c2 - (int) c1;
}
int int
FcUtf8ToUcs4 (FcChar8 *src_orig, FcUtf8ToUcs4 (FcChar8 *src_orig,
FcChar32 *dst, FcChar32 *dst,
@ -276,3 +295,210 @@ FcStrBufData (FcStrBuf *buf, const FcChar8 *s, int len)
return FcTrue; return FcTrue;
} }
FcChar8 *
FcStrCopyFilename (const FcChar8 *s)
{
FcChar8 *new;
if (*s == '~')
{
FcChar8 *home = (FcChar8 *) getenv ("HOME");
int size = strlen ((char *) home) + strlen ((char *) s);
if (!home)
return 0;
new = (FcChar8 *) malloc (size);
if (!new)
return 0;
FcMemAlloc (FC_MEM_STRING, size);
strcpy ((char *) new, (char *) home);
strcat ((char *) new, (char *) s + 1);
}
else
{
int size = strlen ((char *) s) + 1;
new = (FcChar8 *) malloc (size);
if (!new)
return 0;
FcMemAlloc (FC_MEM_STRING, size);
strcpy ((char *) new, (const char *) s);
}
return new;
}
FcChar8 *
FcStrDirname (const FcChar8 *file)
{
FcChar8 *slash;
FcChar8 *dir;
slash = (FcChar8 *) strrchr ((char *) file, '/');
if (!slash)
return FcStrCopy ((FcChar8 *) ".");
dir = malloc ((slash - file) + 1);
if (!dir)
return 0;
FcMemAlloc (FC_MEM_STRING, (slash - file) + 1);
strncpy ((char *) dir, (const char *) file, slash - file);
dir[slash - file] = '\0';
return dir;
}
FcChar8 *
FcStrBasename (const FcChar8 *file)
{
FcChar8 *slash;
slash = (FcChar8 *) strrchr ((char *) file, '/');
if (!slash)
return FcStrCopy (file);
return FcStrCopy (slash + 1);
}
FcStrSet *
FcStrSetCreate (void)
{
FcStrSet *set = malloc (sizeof (FcStrSet));
if (!set)
return 0;
FcMemAlloc (FC_MEM_STRSET, sizeof (FcStrSet));
set->ref = 1;
set->num = 0;
set->size = 0;
set->strs = 0;
return set;
}
static FcBool
_FcStrSetAppend (FcStrSet *set, FcChar8 *s)
{
if (FcStrSetMember (set, s))
{
FcStrFree (s);
return FcTrue;
}
if (set->num == set->size)
{
FcChar8 **strs = malloc ((set->size + 2) * sizeof (FcChar8 *));
if (!strs)
return FcFalse;
FcMemAlloc (FC_MEM_STRSET, (set->size + 2) * sizeof (FcChar8 *));
set->size = set->size + 1;
if (set->num)
memcpy (strs, set->strs, set->num * sizeof (FcChar8 *));
if (set->strs)
free (set->strs);
set->strs = strs;
}
set->strs[set->num++] = s;
set->strs[set->num] = 0;
return FcTrue;
}
FcBool
FcStrSetMember (FcStrSet *set, const FcChar8 *s)
{
int i;
for (i = 0; i < set->num; i++)
if (!FcStrCmp (set->strs[i], s))
return FcTrue;
return FcFalse;
}
FcBool
FcStrSetAdd (FcStrSet *set, const FcChar8 *s)
{
FcChar8 *new = FcStrCopy (s);
if (!new)
return FcFalse;
if (!_FcStrSetAppend (set, new))
{
FcStrFree (new);
return FcFalse;
}
return FcTrue;
}
FcBool
FcStrSetAddFilename (FcStrSet *set, const FcChar8 *s)
{
FcChar8 *new = FcStrCopyFilename (s);
if (!new)
return FcFalse;
if (!_FcStrSetAppend (set, new))
{
FcStrFree (new);
return FcFalse;
}
return FcTrue;
}
FcBool
FcStrSetDel (FcStrSet *set, const FcChar8 *s)
{
int i;
for (i = 0; i < set->num; i++)
if (!FcStrCmp (set->strs[i], s))
{
FcStrFree (set->strs[i]);
/*
* copy remaining string pointers and trailing
* NULL
*/
memmove (&set->strs[i], &set->strs[i+1],
(set->num - i) * sizeof (FcChar8 *));
set->num--;
return FcTrue;
}
return FcFalse;
}
void
FcStrSetDestroy (FcStrSet *set)
{
if (--set->ref == 0)
{
int i;
for (i = 0; i < set->num; i++)
FcStrFree (set->strs[i]);
FcMemFree (FC_MEM_STRSET, (set->size) * sizeof (FcChar8 *));
if (set->strs)
free (set->strs);
FcMemFree (FC_MEM_STRSET, sizeof (FcStrSet));
free (set);
}
}
FcStrList *
FcStrListCreate (FcStrSet *set)
{
FcStrList *list;
list = malloc (sizeof (FcStrList));
if (!list)
return 0;
FcMemAlloc (FC_MEM_STRLIST, sizeof (FcStrList));
list->set = set;
set->ref++;
list->n = 0;
return list;
}
FcChar8 *
FcStrListNext (FcStrList *list)
{
if (list->n >= list->set->num)
return 0;
return list->set->strs[list->n++];
}
void
FcStrListDone (FcStrList *list)
{
FcStrSetDestroy (list->set);
FcMemFree (FC_MEM_STRLIST, sizeof (FcStrList));
free (list);
}

View File

@ -1,5 +1,5 @@
/* /*
* $XFree86: xc/lib/fontconfig/src/fcxml.c,v 1.5 2002/02/22 18:54:07 keithp Exp $ * $XFree86: xc/lib/fontconfig/src/fcxml.c,v 1.6 2002/02/28 16:51:48 keithp Exp $
* *
* Copyright © 2002 Keith Packard, member of The XFree86 Project, Inc. * Copyright © 2002 Keith Packard, member of The XFree86 Project, Inc.
* *
@ -23,8 +23,12 @@
*/ */
#include <stdarg.h> #include <stdarg.h>
#include <expat.h>
#include "fcint.h" #include "fcint.h"
#if HAVE_XMLPARSE_H
#include <xmlparse.h>
#else
#include <expat.h>
#endif
FcTest * FcTest *
FcTestCreate (FcQual qual, const FcChar8 *field, FcOp compare, FcExpr *expr) FcTestCreate (FcQual qual, const FcChar8 *field, FcOp compare, FcExpr *expr)
@ -270,6 +274,7 @@ typedef enum _FcElement {
FcElementAlias, FcElementAlias,
FcElementBlank, FcElementBlank,
FcElementRescan,
FcElementPrefer, FcElementPrefer,
FcElementAccept, FcElementAccept,
@ -319,6 +324,7 @@ FcElementMap (const XML_Char *name)
{ "alias", FcElementAlias }, { "alias", FcElementAlias },
{ "blank", FcElementBlank }, { "blank", FcElementBlank },
{ "rescan", FcElementRescan },
{ "prefer", FcElementPrefer }, { "prefer", FcElementPrefer },
{ "accept", FcElementAccept }, { "accept", FcElementAccept },
@ -418,24 +424,36 @@ typedef struct _FcConfigParse {
XML_Parser parser; XML_Parser parser;
} FcConfigParse; } FcConfigParse;
typedef enum _FcConfigSeverity {
FcSevereInfo, FcSevereWarning, FcSevereError
} FcConfigSeverity;
static void static void
FcConfigError (FcConfigParse *parse, char *fmt, ...) FcConfigMessage (FcConfigParse *parse, FcConfigSeverity severe, char *fmt, ...)
{ {
char *s = "unknown";
va_list args; va_list args;
va_start (args, fmt); va_start (args, fmt);
switch (severe) {
case FcSevereInfo: s = "info"; break;
case FcSevereWarning: s = "warning"; break;
case FcSevereError: s = "error"; break;
}
if (parse) if (parse)
{ {
if (parse->name) if (parse->name)
fprintf (stderr, "Fontconfig error: \"%s\", line %d: ", fprintf (stderr, "Fontconfig %s: \"%s\", line %d: ", s,
parse->name, XML_GetCurrentLineNumber (parse->parser)); parse->name, XML_GetCurrentLineNumber (parse->parser));
else else
fprintf (stderr, "Fontconfig error: line %d: ", fprintf (stderr, "Fontconfig %s: line %d: ", s,
XML_GetCurrentLineNumber (parse->parser)); XML_GetCurrentLineNumber (parse->parser));
parse->error = FcTrue; if (severe >= FcSevereError)
parse->error = FcTrue;
} }
else else
fprintf (stderr, "Fontconfig error: "); fprintf (stderr, "Fontconfig %s: ", s);
vfprintf (stderr, fmt, args); vfprintf (stderr, fmt, args);
fprintf (stderr, "\n"); fprintf (stderr, "\n");
va_end (args); va_end (args);
@ -694,7 +712,7 @@ FcPStackPush (FcConfigParse *parse, FcElement element, const XML_Char **attr)
{ {
new->attr = FcConfigSaveAttr (attr); new->attr = FcConfigSaveAttr (attr);
if (!new->attr) if (!new->attr)
FcConfigError (parse, "out of memory"); FcConfigMessage (parse, FcSevereError, "out of memory");
} }
else else
new->attr = 0; new->attr = 0;
@ -710,7 +728,7 @@ FcPStackPop (FcConfigParse *parse)
if (!parse->pstack) if (!parse->pstack)
{ {
FcConfigError (parse, "mismatching element"); FcConfigMessage (parse, FcSevereError, "mismatching element");
return FcFalse; return FcFalse;
} }
FcVStackClear (parse); FcVStackClear (parse);
@ -767,14 +785,11 @@ FcStartElement(void *userData, const XML_Char *name, const XML_Char **attr)
element = FcElementMap (name); element = FcElementMap (name);
if (element == FcElementUnknown) if (element == FcElementUnknown)
{ FcConfigMessage (parse, FcSevereWarning, "unknown element \"%s\"", name);
FcConfigError (parse, "unknown element \"%s\"", name);
return;
}
if (!FcPStackPush (parse, element, attr)) if (!FcPStackPush (parse, element, attr))
{ {
FcConfigError (parse, "out of memory"); FcConfigMessage (parse, FcSevereError, "out of memory");
return; return;
} }
return; return;
@ -788,7 +803,7 @@ FcParseBlank (FcConfigParse *parse)
{ {
FcVStack *v = FcVStackFetch (parse, n); FcVStack *v = FcVStackFetch (parse, n);
if (v->tag != FcVStackInteger) if (v->tag != FcVStackInteger)
FcConfigError (parse, "non-integer blank"); FcConfigMessage (parse, FcSevereError, "non-integer blank");
else else
{ {
if (!parse->config->blanks) if (!parse->config->blanks)
@ -796,19 +811,33 @@ FcParseBlank (FcConfigParse *parse)
parse->config->blanks = FcBlanksCreate (); parse->config->blanks = FcBlanksCreate ();
if (!parse->config->blanks) if (!parse->config->blanks)
{ {
FcConfigError (parse, "out of memory"); FcConfigMessage (parse, FcSevereError, "out of memory");
break; break;
} }
} }
if (!FcBlanksAdd (parse->config->blanks, v->u.integer)) if (!FcBlanksAdd (parse->config->blanks, v->u.integer))
{ {
FcConfigError (parse, "out of memory"); FcConfigMessage (parse, FcSevereError, "out of memory");
break; break;
} }
} }
} }
} }
static void
FcParseRescan (FcConfigParse *parse)
{
int n = FcVStackElements (parse);
while (n-- > 0)
{
FcVStack *v = FcVStackFetch (parse, n);
if (v->tag != FcVStackInteger)
FcConfigMessage (parse, FcSevereWarning, "non-integer rescan");
else
parse->config->rescanInterval = v->u.integer;
}
}
static void static void
FcParseInt (FcConfigParse *parse) FcParseInt (FcConfigParse *parse)
{ {
@ -820,13 +849,13 @@ FcParseInt (FcConfigParse *parse)
s = FcStrBufDone (&parse->pstack->str); s = FcStrBufDone (&parse->pstack->str);
if (!s) if (!s)
{ {
FcConfigError (parse, "out of memory"); FcConfigMessage (parse, FcSevereError, "out of memory");
return; return;
} }
end = 0; end = 0;
l = (int) strtol ((char *) s, (char **)&end, 0); l = (int) strtol ((char *) s, (char **)&end, 0);
if (end != s + strlen ((char *) s)) if (end != s + strlen ((char *) s))
FcConfigError (parse, "\"%s\": not a valid integer", s); FcConfigMessage (parse, FcSevereError, "\"%s\": not a valid integer", s);
else else
FcVStackPushInteger (parse, l); FcVStackPushInteger (parse, l);
FcStrFree (s); FcStrFree (s);
@ -843,13 +872,13 @@ FcParseDouble (FcConfigParse *parse)
s = FcStrBufDone (&parse->pstack->str); s = FcStrBufDone (&parse->pstack->str);
if (!s) if (!s)
{ {
FcConfigError (parse, "out of memory"); FcConfigMessage (parse, FcSevereError, "out of memory");
return; return;
} }
end = 0; end = 0;
d = strtod ((char *) s, (char **)&end); d = strtod ((char *) s, (char **)&end);
if (end != s + strlen ((char *) s)) if (end != s + strlen ((char *) s))
FcConfigError (parse, "\"%s\": not a valid double", s); FcConfigMessage (parse, FcSevereError, "\"%s\": not a valid double", s);
else else
FcVStackPushDouble (parse, d); FcVStackPushDouble (parse, d);
FcStrFree (s); FcStrFree (s);
@ -865,7 +894,7 @@ FcParseString (FcConfigParse *parse, FcVStackTag tag)
s = FcStrBufDone (&parse->pstack->str); s = FcStrBufDone (&parse->pstack->str);
if (!s) if (!s)
{ {
FcConfigError (parse, "out of memory"); FcConfigMessage (parse, FcSevereError, "out of memory");
return; return;
} }
if (!FcVStackPushString (parse, tag, s)) if (!FcVStackPushString (parse, tag, s))
@ -881,23 +910,30 @@ FcParseMatrix (FcConfigParse *parse)
while ((vstack = FcVStackPop (parse))) while ((vstack = FcVStackPop (parse)))
{ {
if (vstack->tag != FcVStackDouble) double v;
FcConfigError (parse, "non-double matrix element"); switch (vstack->tag) {
else case FcVStackInteger:
{ v = vstack->u.integer;
double v = vstack->u._double; break;
switch (matrix_state) { case FcVStackDouble:
case m_xx: m.xx = v; break; v = vstack->u._double;
case m_xy: m.xy = v; break; break;
case m_yx: m.yx = v; break; default:
case m_yy: m.yy = v; break; FcConfigMessage (parse, FcSevereError, "non-double matrix element");
default: break; v = 1.0;
} break;
matrix_state--;
} }
switch (matrix_state) {
case m_xx: m.xx = v; break;
case m_xy: m.xy = v; break;
case m_yx: m.yx = v; break;
case m_yy: m.yy = v; break;
default: break;
}
matrix_state--;
} }
if (matrix_state != m_done) if (matrix_state != m_done)
FcConfigError (parse, "wrong number of matrix elements"); FcConfigMessage (parse, FcSevereError, "wrong number of matrix elements");
else else
FcVStackPushMatrix (parse, &m); FcVStackPushMatrix (parse, &m);
} }
@ -924,7 +960,7 @@ FcParseBool (FcConfigParse *parse)
s = FcStrBufDone (&parse->pstack->str); s = FcStrBufDone (&parse->pstack->str);
if (!s) if (!s)
{ {
FcConfigError (parse, "out of memory"); FcConfigMessage (parse, FcSevereError, "out of memory");
return; return;
} }
FcVStackPushBool (parse, FcConfigLexBool (s)); FcVStackPushBool (parse, FcConfigLexBool (s));
@ -941,8 +977,9 @@ FcParseFamilies (FcConfigParse *parse, FcVStackTag tag)
{ {
if (vstack->tag != FcVStackFamily) if (vstack->tag != FcVStackFamily)
{ {
FcConfigError (parse, "non-family"); FcConfigMessage (parse, FcSevereWarning, "non-family");
break; FcVStackDestroy (vstack);
continue;
} }
left = vstack->u.expr; left = vstack->u.expr;
vstack->tag = FcVStackNone; vstack->tag = FcVStackNone;
@ -952,7 +989,7 @@ FcParseFamilies (FcConfigParse *parse, FcVStackTag tag)
new = FcExprCreateOp (left, FcOpComma, expr); new = FcExprCreateOp (left, FcOpComma, expr);
if (!new) if (!new)
{ {
FcConfigError (parse, "out of memory"); FcConfigMessage (parse, FcSevereError, "out of memory");
FcExprDestroy (left); FcExprDestroy (left);
FcExprDestroy (expr); FcExprDestroy (expr);
break; break;
@ -966,7 +1003,7 @@ FcParseFamilies (FcConfigParse *parse, FcVStackTag tag)
{ {
if (!FcVStackPushExpr (parse, tag, expr)) if (!FcVStackPushExpr (parse, tag, expr))
{ {
FcConfigError (parse, "out of memory"); FcConfigMessage (parse, FcSevereError, "out of memory");
if (expr) if (expr)
FcExprDestroy (expr); FcExprDestroy (expr);
} }
@ -984,7 +1021,7 @@ FcParseFamily (FcConfigParse *parse)
s = FcStrBufDone (&parse->pstack->str); s = FcStrBufDone (&parse->pstack->str);
if (!s) if (!s)
{ {
FcConfigError (parse, "out of memory"); FcConfigMessage (parse, FcSevereError, "out of memory");
return; return;
} }
expr = FcExprCreateString (s); expr = FcExprCreateString (s);
@ -996,7 +1033,7 @@ FcParseFamily (FcConfigParse *parse)
static void static void
FcParseAlias (FcConfigParse *parse) FcParseAlias (FcConfigParse *parse)
{ {
FcExpr *family = 0, *accept = 0, *prefer = 0, *def = 0; FcExpr *family = 0, *accept = 0, *prefer = 0, *def = 0, *new = 0;
FcEdit *edit = 0, *next; FcEdit *edit = 0, *next;
FcVStack *vstack; FcVStack *vstack;
FcTest *test; FcTest *test;
@ -1006,9 +1043,20 @@ FcParseAlias (FcConfigParse *parse)
switch (vstack->tag) { switch (vstack->tag) {
case FcVStackFamily: case FcVStackFamily:
if (family) if (family)
FcExprDestroy (family); {
family = vstack->u.expr; new = FcExprCreateOp (vstack->u.expr, FcOpComma, family);
vstack->tag = FcVStackNone; if (!new)
FcConfigMessage (parse, FcSevereError, "out of memory");
else
family = new;
}
else
new = vstack->u.expr;
if (new)
{
family = new;
vstack->tag = FcVStackNone;
}
break; break;
case FcVStackPrefer: case FcVStackPrefer:
if (prefer) if (prefer)
@ -1029,14 +1077,20 @@ FcParseAlias (FcConfigParse *parse)
vstack->tag = FcVStackNone; vstack->tag = FcVStackNone;
break; break;
default: default:
FcConfigError (parse, "bad alias"); FcConfigMessage (parse, FcSevereWarning, "bad alias");
break; break;
} }
FcVStackDestroy (vstack); FcVStackDestroy (vstack);
} }
if (!family) if (!family)
{ {
FcConfigError (parse, "missing family in alias"); FcConfigMessage (parse, FcSevereError, "missing family in alias");
if (prefer)
FcExprDestroy (prefer);
if (accept)
FcExprDestroy (accept);
if (def)
FcExprDestroy (def);
return; return;
} }
if (prefer) if (prefer)
@ -1147,7 +1201,7 @@ FcPopExprs (FcConfigParse *parse, FcOp op)
new = FcExprCreateOp (left, op, expr); new = FcExprCreateOp (left, op, expr);
if (!new) if (!new)
{ {
FcConfigError (parse, "out of memory"); FcConfigMessage (parse, FcSevereError, "out of memory");
FcExprDestroy (left); FcExprDestroy (left);
FcExprDestroy (expr); FcExprDestroy (expr);
break; break;
@ -1178,7 +1232,7 @@ FcParseInclude (FcConfigParse *parse)
s = FcStrBufDone (&parse->pstack->str); s = FcStrBufDone (&parse->pstack->str);
if (!s) if (!s)
{ {
FcConfigError (parse, "out of memory"); FcConfigMessage (parse, FcSevereError, "out of memory");
return; return;
} }
i = FcConfigGetAttribute (parse, "ignore_missing"); i = FcConfigGetAttribute (parse, "ignore_missing");
@ -1245,15 +1299,15 @@ FcParseTest (FcConfigParse *parse)
qual = FcQualAll; qual = FcQualAll;
else else
{ {
FcConfigError (parse, "invalid test qual \"%s\"", qual_string); FcConfigMessage (parse, FcSevereWarning, "invalid test qual \"%s\"", qual_string);
return; qual = FcQualAny;
} }
} }
name = FcConfigGetAttribute (parse, "name"); name = FcConfigGetAttribute (parse, "name");
if (!name) if (!name)
{ {
FcConfigError (parse, "missing test name"); FcConfigMessage (parse, FcSevereWarning, "missing test name");
return; name = (FcChar8 *) FC_FAMILY;
} }
compare_string = FcConfigGetAttribute (parse, "compare"); compare_string = FcConfigGetAttribute (parse, "compare");
if (!compare_string) if (!compare_string)
@ -1263,20 +1317,20 @@ FcParseTest (FcConfigParse *parse)
compare = FcConfigLexCompare (compare_string); compare = FcConfigLexCompare (compare_string);
if (compare == FcOpInvalid) if (compare == FcOpInvalid)
{ {
FcConfigError (parse, "invalid test compare \"%s\"", compare_string); FcConfigMessage (parse, FcSevereWarning, "invalid test compare \"%s\"", compare_string);
return; compare = FcOpEqual;
} }
} }
expr = FcPopExpr (parse); expr = FcPopExprs (parse, FcOpComma);
if (!expr) if (!expr)
{ {
FcConfigError (parse, "missing test expression"); FcConfigMessage (parse, FcSevereWarning, "missing test expression");
return; return;
} }
test = FcTestCreate (qual, name, compare, expr); test = FcTestCreate (qual, name, compare, expr);
if (!test) if (!test)
{ {
FcConfigError (parse, "out of memory"); FcConfigMessage (parse, FcSevereError, "out of memory");
return; return;
} }
FcVStackPushTest (parse, test); FcVStackPushTest (parse, test);
@ -1311,8 +1365,8 @@ FcParseEdit (FcConfigParse *parse)
name = FcConfigGetAttribute (parse, "name"); name = FcConfigGetAttribute (parse, "name");
if (!name) if (!name)
{ {
FcConfigError (parse, "missing edit name"); FcConfigMessage (parse, FcSevereWarning, "missing edit name");
return; name = (FcChar8 *) FC_FAMILY;
} }
mode_string = FcConfigGetAttribute (parse, "mode"); mode_string = FcConfigGetAttribute (parse, "mode");
if (!mode_string) if (!mode_string)
@ -1322,15 +1376,15 @@ FcParseEdit (FcConfigParse *parse)
mode = FcConfigLexMode (mode_string); mode = FcConfigLexMode (mode_string);
if (mode == FcOpInvalid) if (mode == FcOpInvalid)
{ {
FcConfigError (parse, "invalid edit mode \"%s\"", mode_string); FcConfigMessage (parse, FcSevereWarning, "invalid edit mode \"%s\"", mode_string);
return; mode = FcOpAssign;
} }
} }
expr = FcPopExprs (parse, FcOpComma); expr = FcPopExprs (parse, FcOpComma);
edit = FcEditCreate ((char *) FcStrCopy (name), mode, expr); edit = FcEditCreate ((char *) FcStrCopy (name), mode, expr);
if (!edit) if (!edit)
{ {
FcConfigError (parse, "out of memory"); FcConfigMessage (parse, FcSevereError, "out of memory");
FcExprDestroy (expr); FcExprDestroy (expr);
return; return;
} }
@ -1358,8 +1412,8 @@ FcParseMatch (FcConfigParse *parse)
kind = FcMatchFont; kind = FcMatchFont;
else else
{ {
FcConfigError (parse, "invalid match target \"%s\"", kind_name); FcConfigMessage (parse, FcSevereWarning, "invalid match target \"%s\"", kind_name);
return; kind = FcMatchPattern;
} }
} }
while ((vstack = FcVStackPop (parse))) while ((vstack = FcVStackPop (parse)))
@ -1376,13 +1430,13 @@ FcParseMatch (FcConfigParse *parse)
vstack->tag = FcVStackNone; vstack->tag = FcVStackNone;
break; break;
default: default:
FcConfigError (parse, "invalid match element"); FcConfigMessage (parse, FcSevereWarning, "invalid match element");
break; break;
} }
FcVStackDestroy (vstack); FcVStackDestroy (vstack);
} }
if (!FcConfigAddEdit (parse->config, test, edit, kind)) if (!FcConfigAddEdit (parse->config, test, edit, kind))
FcConfigError (parse, "out of memory"); FcConfigMessage (parse, FcSevereError, "out of memory");
} }
static void static void
@ -1402,22 +1456,22 @@ FcEndElement(void *userData, const XML_Char *name)
data = FcStrBufDone (&parse->pstack->str); data = FcStrBufDone (&parse->pstack->str);
if (!data) if (!data)
{ {
FcConfigError (parse, "out of memory"); FcConfigMessage (parse, FcSevereError, "out of memory");
break; break;
} }
if (!FcConfigAddDir (parse->config, data)) if (!FcConfigAddDir (parse->config, data))
FcConfigError (parse, "out of memory"); FcConfigMessage (parse, FcSevereError, "out of memory");
free (data); free (data);
break; break;
case FcElementCache: case FcElementCache:
data = FcStrBufDone (&parse->pstack->str); data = FcStrBufDone (&parse->pstack->str);
if (!data) if (!data)
{ {
FcConfigError (parse, "out of memory"); FcConfigMessage (parse, FcSevereError, "out of memory");
break; break;
} }
if (!FcConfigSetCache (parse->config, data)) if (!FcConfigSetCache (parse->config, data))
FcConfigError (parse, "out of memory"); FcConfigMessage (parse, FcSevereError, "out of memory");
free (data); free (data);
break; break;
case FcElementInclude: case FcElementInclude:
@ -1435,6 +1489,9 @@ FcEndElement(void *userData, const XML_Char *name)
case FcElementBlank: case FcElementBlank:
FcParseBlank (parse); FcParseBlank (parse);
break; break;
case FcElementRescan:
FcParseRescan (parse);
break;
case FcElementPrefer: case FcElementPrefer:
FcParseFamilies (parse, FcVStackPrefer); FcParseFamilies (parse, FcVStackPrefer);
@ -1537,7 +1594,7 @@ FcCharacterData (void *userData, const XML_Char *s, int len)
if (!parse->pstack) if (!parse->pstack)
return; return;
if (!FcStrBufData (&parse->pstack->str, (FcChar8 *) s, len)) if (!FcStrBufData (&parse->pstack->str, (FcChar8 *) s, len))
FcConfigError (parse, "out of memory"); FcConfigMessage (parse, FcSevereError, "out of memory");
} }
static void static void
@ -1550,7 +1607,7 @@ FcStartDoctypeDecl (void *userData,
FcConfigParse *parse = userData; FcConfigParse *parse = userData;
if (strcmp ((char *) doctypeName, "fontconfig") != 0) if (strcmp ((char *) doctypeName, "fontconfig") != 0)
FcConfigError (parse, "invalid doctype \"%s\"", doctypeName); FcConfigMessage (parse, FcSevereError, "invalid doctype \"%s\"", doctypeName);
} }
static void static void
@ -1597,18 +1654,18 @@ FcConfigParseAndLoad (FcConfig *config,
buf = XML_GetBuffer (p, BUFSIZ); buf = XML_GetBuffer (p, BUFSIZ);
if (!buf) if (!buf)
{ {
FcConfigError (&parse, "cannot get parse buffer"); FcConfigMessage (&parse, FcSevereError, "cannot get parse buffer");
goto bail3; goto bail3;
} }
len = fread (buf, 1, BUFSIZ, f); len = fread (buf, 1, BUFSIZ, f);
if (len < 0) if (len < 0)
{ {
FcConfigError (&parse, "failed reading config file"); FcConfigMessage (&parse, FcSevereError, "failed reading config file");
goto bail3; goto bail3;
} }
if (!XML_ParseBuffer (p, len, len == 0)) if (!XML_ParseBuffer (p, len, len == 0))
{ {
FcConfigError (&parse, "%s", FcConfigMessage (&parse, FcSevereError, "%s",
XML_ErrorString (XML_GetErrorCode (p))); XML_ErrorString (XML_GetErrorCode (p)));
goto bail3; goto bail3;
} }
@ -1624,9 +1681,9 @@ bail0:
if (error && complain) if (error && complain)
{ {
if (name) if (name)
FcConfigError (0, "Cannot load config file \"%s\"", name); FcConfigMessage (0, FcSevereError, "Cannot load config file \"%s\"", name);
else else
FcConfigError (0, "Cannot load default config file"); FcConfigMessage (0, FcSevereError, "Cannot load default config file");
return FcFalse; return FcFalse;
} }
return FcTrue; return FcTrue;