doc/fcconfig.fncs | 16 +++ fontconfig/fontconfig.h | 5 + src/fcxml.c | 206 ++++++++++++++++++++++++++++++------------------ 3 files changed, 152 insertions(+), 75 deletions(-) New commits: commit 12b7501bad3ed4d7819b00a27a9c021e7d120aa0 Author: Akira TAGOH <akira@xxxxxxxxx> Date: Thu Jun 11 17:30:04 2015 +0900 Add FcConfigParseAndLoadFromMemory() to load a configuration from memory. https://bugs.freedesktop.org/show_bug.cgi?id=78452 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" _______________________________________________ Fontconfig mailing list Fontconfig@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/fontconfig