summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAkira TAGOH <akira@tagoh.org>2015-06-11 17:30:04 +0900
committerAkira TAGOH <akira@tagoh.org>2017-07-07 15:52:15 +0900
commit12b7501bad3ed4d7819b00a27a9c021e7d120aa0 (patch)
tree018f685d7c071083e664cd5d7fcd3cfff7bf8600
parentee2000494c4c8367fe20593709a979d158687855 (diff)
Add FcConfigParseAndLoadFromMemory() to load a configuration from memory.
https://bugs.freedesktop.org/show_bug.cgi?id=78452
-rw-r--r--doc/fcconfig.fncs16
-rw-r--r--fontconfig/fontconfig.h5
-rw-r--r--src/fcxml.c206
3 files changed, 152 insertions, 75 deletions
diff --git a/doc/fcconfig.fncs b/doc/fcconfig.fncs
index a2ce5c8..59a2227 100644
--- a/doc/fcconfig.fncs
+++ b/doc/fcconfig.fncs
@@ -375,6 +375,22 @@ Returns FcFalse if some error occurred while loading the file, either a
parse error, semantic error or allocation failure. Otherwise returns FcTrue.
@@
+@RET@ FcBool
+@FUNC@ FcConfigParseAndLoadFromMemory
+@TYPE1@ FcConfig * @ARG1@ config
+@TYPE2@ const FcChar8 * @ARG2@ buffer
+@TYPE3@ FcBool% @ARG3@ complain
+@PURPOSE@ load a configuration from memory
+@DESC@
+Walks the configuration in 'memory' and constructs the internal representation
+in 'config'. Any includes files referenced from within 'memory' will be loaded
+and dparsed. If 'complain' is FcFalse, no warning will be displayed if
+'file' does not exist. Error and warning messages will be output to stderr.
+Returns FcFalse if fsome error occurred while loading the file, either a
+parse error, semantic error or allocation failure. Otherwise returns FcTrue.
+@SINCE@ 2.13.0
+@@
+
@RET@ const FcChar8 *
@FUNC@ FcConfigGetSysRoot
@TYPE1@ const FcConfig * @ARG1@ config
diff --git a/fontconfig/fontconfig.h b/fontconfig/fontconfig.h
index 9535c56..00ab409 100644
--- a/fontconfig/fontconfig.h
+++ b/fontconfig/fontconfig.h
@@ -1042,6 +1042,11 @@ FcStrListDone (FcStrList *list);
FcPublic FcBool
FcConfigParseAndLoad (FcConfig *config, const FcChar8 *file, FcBool complain);
+FcPublic FcBool
+FcConfigParseAndLoadFromMemory (FcConfig *config,
+ const FcChar8 *buffer,
+ FcBool complain);
+
_FCFUNCPROTOEND
#undef FC_ATTRIBUTE_SENTINEL
diff --git a/src/fcxml.c b/src/fcxml.c
index 031a7da..a7a41ce 100644
--- a/src/fcxml.c
+++ b/src/fcxml.c
@@ -3223,79 +3223,31 @@ pfnGetSystemWindowsDirectory pGetSystemWindowsDirectory = NULL;
pfnSHGetFolderPathA pSHGetFolderPathA = NULL;
#endif
-FcBool
-FcConfigParseAndLoad (FcConfig *config,
- const FcChar8 *name,
- FcBool complain)
+static FcBool
+FcConfigParseAndLoadFromMemoryInternal (FcConfig *config,
+ const FcChar8 *filename,
+ const FcChar8 *buffer,
+ FcBool complain)
{
XML_Parser p;
- FcChar8 *filename, *f;
- int fd;
- int len;
+ size_t len;
FcConfigParse parse;
FcBool error = FcTrue;
- const FcChar8 *sysroot = FcConfigGetSysRoot (config);
+ void *buf;
#ifdef ENABLE_LIBXML2
xmlSAXHandler sax;
- char buf[BUFSIZ];
#else
- void *buf;
-#endif
-
-#ifdef _WIN32
- if (!pGetSystemWindowsDirectory)
- {
- HMODULE hk32 = GetModuleHandleA("kernel32.dll");
- if (!(pGetSystemWindowsDirectory = (pfnGetSystemWindowsDirectory) GetProcAddress(hk32, "GetSystemWindowsDirectoryA")))
- pGetSystemWindowsDirectory = (pfnGetSystemWindowsDirectory) GetWindowsDirectory;
- }
- if (!pSHGetFolderPathA)
- {
- HMODULE hSh = LoadLibraryA("shfolder.dll");
- /* the check is done later, because there is no provided fallback */
- if (hSh)
- pSHGetFolderPathA = (pfnSHGetFolderPathA) GetProcAddress(hSh, "SHGetFolderPathA");
- }
+ const FcChar8 *s;
+ size_t buflen;
#endif
- f = FcConfigFilename (name);
- if (!f)
- goto bail0;
- if (sysroot)
- filename = FcStrBuildFilename (sysroot, f, NULL);
- else
- filename = FcStrdup (f);
- FcStrFree (f);
-
- if (FcStrSetMember (config->configFiles, filename))
- {
- FcStrFree (filename);
- return FcTrue;
- }
-
- if (!FcStrSetAdd (config->configFiles, filename))
- {
- FcStrFree (filename);
- goto bail0;
- }
-
- if (FcFileIsDir (filename))
- {
- FcBool ret = FcConfigParseAndLoadDir (config, name, filename, complain);
- FcStrFree (filename);
- return ret;
- }
-
+ if (!buffer)
+ return FcFalse;
+ len = strlen ((const char *) buffer);
if (FcDebug () & FC_DBG_CONFIG)
- printf ("\tLoading config file %s\n", filename);
-
- fd = FcOpen ((char *) filename, O_RDONLY);
- if (fd == -1) {
- FcStrFree (filename);
- goto bail0;
- }
+ printf ("\tLoading config file from %s\n", filename);
#ifdef ENABLE_LIBXML2
memset(&sax, 0, sizeof(sax));
@@ -3310,12 +3262,11 @@ FcConfigParseAndLoad (FcConfig *config,
#else
p = XML_ParserCreate ("UTF-8");
#endif
- FcStrFree (filename);
if (!p)
goto bail1;
- if (!FcConfigParseInit (&parse, name, config, p))
+ if (!FcConfigParseInit (&parse, filename, config, p))
goto bail2;
#ifndef ENABLE_LIBXML2
@@ -3328,43 +3279,148 @@ FcConfigParseAndLoad (FcConfig *config,
#endif /* ENABLE_LIBXML2 */
- do {
#ifndef ENABLE_LIBXML2
+ s = buffer;
+ do {
buf = XML_GetBuffer (p, BUFSIZ);
if (!buf)
{
FcConfigMessage (&parse, FcSevereError, "cannot get parse buffer");
goto bail3;
}
-#endif
- len = read (fd, buf, BUFSIZ);
- if (len < 0)
+ if (len > BUFSIZ)
{
- FcConfigMessage (&parse, FcSevereError, "failed reading config file");
- goto bail3;
+ buflen = BUFSIZ;
+ len -= BUFSIZ;
+ }
+ else
+ {
+ buflen = len;
+ len = 0;
}
+ memcpy (buf, s, buflen);
+ s = s + buflen;
+#endif
#ifdef ENABLE_LIBXML2
- if (xmlParseChunk (p, buf, len, len == 0))
+ if (xmlParseChunk (p, buffer, len, len == 0))
#else
- if (!XML_ParseBuffer (p, len, len == 0))
+ if (!XML_ParseBuffer (p, buflen, buflen == 0))
#endif
{
FcConfigMessage (&parse, FcSevereError, "%s",
XML_ErrorString (XML_GetErrorCode (p)));
goto bail3;
}
- } while (len != 0);
+#ifndef ENABLE_LIBXML2
+ } while (buflen != 0);
+#endif
error = parse.error;
bail3:
FcConfigCleanup (&parse);
bail2:
XML_ParserFree (p);
bail1:
+ if (error && complain)
+ {
+ FcConfigMessage (0, FcSevereError, "Cannot load config file from %s", filename);
+ return FcFalse;
+ }
+ return FcTrue;
+}
+
+FcBool
+FcConfigParseAndLoadFromMemory (FcConfig *config,
+ const FcChar8 *buffer,
+ FcBool complain)
+{
+ return FcConfigParseAndLoadFromMemoryInternal (config, (const FcChar8 *)"memory", buffer, complain);
+}
+
+FcBool
+FcConfigParseAndLoad (FcConfig *config,
+ const FcChar8 *name,
+ FcBool complain)
+{
+ FcChar8 *filename, *f;
+ int fd;
+ int len;
+ const FcChar8 *sysroot = FcConfigGetSysRoot (config);
+ FcStrBuf sbuf;
+ char buf[BUFSIZ];
+ FcBool ret = FcFalse;
+
+#ifdef _WIN32
+ if (!pGetSystemWindowsDirectory)
+ {
+ HMODULE hk32 = GetModuleHandleA("kernel32.dll");
+ if (!(pGetSystemWindowsDirectory = (pfnGetSystemWindowsDirectory) GetProcAddress(hk32, "GetSystemWindowsDirectoryA")))
+ pGetSystemWindowsDirectory = (pfnGetSystemWindowsDirectory) GetWindowsDirectory;
+ }
+ if (!pSHGetFolderPathA)
+ {
+ HMODULE hSh = LoadLibraryA("shfolder.dll");
+ /* the check is done later, because there is no provided fallback */
+ if (hSh)
+ pSHGetFolderPathA = (pfnSHGetFolderPathA) GetProcAddress(hSh, "SHGetFolderPathA");
+ }
+#endif
+
+ f = FcConfigFilename (name);
+ if (!f)
+ goto bail0;
+ if (sysroot)
+ filename = FcStrBuildFilename (sysroot, f, NULL);
+ else
+ filename = FcStrdup (f);
+ FcStrFree (f);
+
+ if (FcStrSetMember (config->configFiles, filename))
+ {
+ FcStrFree (filename);
+ return FcTrue;
+ }
+
+ if (!FcStrSetAdd (config->configFiles, filename))
+ {
+ FcStrFree (filename);
+ goto bail0;
+ }
+
+ if (FcFileIsDir (filename))
+ {
+ ret = FcConfigParseAndLoadDir (config, name, filename, complain);
+ FcStrFree (filename);
+ return ret;
+ }
+
+ FcStrBufInit (&sbuf, NULL, 0);
+
+ fd = FcOpen ((char *) filename, O_RDONLY);
+ if (fd == -1) {
+ FcStrFree (filename);
+ goto bail1;
+ }
+
+ do {
+ len = read (fd, buf, BUFSIZ);
+ if (len < 0)
+ {
+ FcConfigMessage (0, FcSevereError, "failed reading config file");
+ close (fd);
+ goto bail1;
+ }
+ FcStrBufData (&sbuf, (const FcChar8 *)buf, len);
+ } while (len != 0);
close (fd);
- fd = -1;
+
+ ret = FcConfigParseAndLoadFromMemoryInternal (config, filename, FcStrBufDoneStatic (&sbuf), complain);
+ complain = FcFalse; /* no need to reclaim here */
+bail1:
+ FcStrFree (filename);
+ FcStrBufDestroy (&sbuf);
bail0:
- if (error && complain)
+ if (!ret && complain)
{
if (name)
FcConfigMessage (0, FcSevereError, "Cannot load config file \"%s\"", name);
@@ -3372,7 +3428,7 @@ bail0:
FcConfigMessage (0, FcSevereError, "Cannot load default config file");
return FcFalse;
}
- return FcTrue;
+ return ret;
}
#define __fcxml__
#include "fcaliastail.h"