[PATCH] Rework Reporting Of Config Parse Errors To Use Callback

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This patch reworks the FcConfigMessage routine in fcxml.c to pass all
messages through a callback action. The idea is that it becomes easy to
add alternate versions of the FcConfigParseAndLoadxxx routines that pass
a caller-specified callback for capturing the messages, rather than
sending them direct to stderr.

Initially I had the callback details stored as fields in the
_FcConfigParse structure. Then I discovered that messages could be
reported in situations where such a structure did not exist. So I put
them in a separate _MessageCallback structure. So this structure has to
be passed as a separate arg to every FcConfigMessage call.

Let me know what you think.
diff --git a/fontconfig/fontconfig.h b/fontconfig/fontconfig.h
index 14a23be..b93b927 100644
--- a/fontconfig/fontconfig.h
+++ b/fontconfig/fontconfig.h
@@ -310,6 +310,8 @@ typedef struct _FcConfigFileInfoIter {
 
 typedef struct _FcAtomic FcAtomic;
 
+typedef void (*FcMessageCallback)(const char * msg, void * user_data);
+
 #if defined(__cplusplus) || defined(c_plusplus) /* for C++ V2.0 */
 #define _FCFUNCPROTOBEGIN extern "C" {	/* do not leave open across includes */
 #define _FCFUNCPROTOEND }
diff --git a/src/fcxml.c b/src/fcxml.c
index 2e5898e..e14a670 100644
--- a/src/fcxml.c
+++ b/src/fcxml.c
@@ -67,7 +67,9 @@ static FcBool
 _FcConfigParse (FcConfig	*config,
 		const FcChar8	*name,
 		FcBool		complain,
-		FcBool		load);
+		FcBool		load,
+		FcMessageCallback msg_callback,
+		void * msg_callback_data);
 
 void
 FcTestDestroy (FcTest *test)
@@ -360,7 +362,7 @@ typedef enum _FcElement {
     FcElementDescription,
     FcElementRemapDir,
     FcElementResetDirs,
-	
+
     FcElementRescan,
 
     FcElementPrefer,
@@ -568,9 +570,16 @@ typedef struct _FcVStack {
     } u;
 } FcVStack;
 
+struct _MessageCallback
+  {
+	FcMessageCallback callback;
+	void * callback_data;
+  };
+
 typedef struct _FcConfigParse {
     FcPStack	    *pstack;
     FcVStack	    *vstack;
+	struct _MessageCallback * messager;
     FcBool	    error;
     const FcChar8   *name;
     FcConfig	    *config;
@@ -587,8 +596,43 @@ typedef enum _FcConfigSeverity {
     FcSevereInfo, FcSevereWarning, FcSevereError
 } FcConfigSeverity;
 
+static void msg_to_stderr
+  (
+	const char * msg,
+	void * _
+  )
+  /* error action which outputs messages to stderr. */
+  {
+	fputs(msg, stderr);
+  } /*msg_to_stderr*/
+
+static void msg_line_va
+  (
+	struct _MessageCallback * messager,
+	const char * fmt,
+	va_list args
+  )
+  {
+	char msg[256]; /* big enough to avoid truncation? if not, make bigger. */
+	vsnprintf(msg, sizeof msg, fmt, args);
+	messager->callback(msg, messager->callback_data);
+  } /*msg_line_va*/
+
+static void msg_line
+  (
+	struct _MessageCallback * messager,
+	const char * fmt,
+	...
+  )
+  {
+    va_list	args;
+	va_start(args, fmt);
+	msg_line_va(messager, fmt, args);
+	va_end(args);
+  } /*msg_line*/
+
 static void
-FcConfigMessage (FcConfigParse *parse, FcConfigSeverity severe, const char *fmt, ...)
+FcConfigMessage (FcConfigParse *parse, struct _MessageCallback * messager, FcConfigSeverity severe, const char *fmt, ...)
 {
     const char	*s = "unknown";
     va_list	args;
@@ -601,20 +645,20 @@ FcConfigMessage (FcConfigParse *parse, FcConfigSeverity severe, const char *fmt,
     case FcSevereError: s = "error"; break;
     }
     if (parse)
-    {
-	if (parse->name)
-	    fprintf (stderr, "Fontconfig %s: \"%s\", line %d: ", s,
-		     parse->name, (int)XML_GetCurrentLineNumber (parse->parser));
-	else
-	    fprintf (stderr, "Fontconfig %s: line %d: ", s,
-		     (int)XML_GetCurrentLineNumber (parse->parser));
-	if (severe >= FcSevereError)
-	    parse->error = FcTrue;
-    }
+      {
+		if (parse->name)
+			msg_line (messager, "Fontconfig %s: \"%s\", line %d: ", s,
+				 parse->name, (int)XML_GetCurrentLineNumber (parse->parser));
+		else
+			msg_line (messager, "Fontconfig %s: line %d: ", s,
+				 (int)XML_GetCurrentLineNumber (parse->parser));
+		if (severe >= FcSevereError)
+			parse->error = FcTrue;
+      }
     else
-	fprintf (stderr, "Fontconfig %s: ", s);
-    vfprintf (stderr, fmt, args);
-    fprintf (stderr, "\n");
+		msg_line (messager, "Fontconfig %s: ", s);
+    msg_line_va (messager, fmt, args);
+    msg_line (messager, "\n");
     va_end (args);
 }
 
@@ -671,7 +715,7 @@ FcTypecheckValue (FcConfigParse *parse, FcType value, FcType type)
 	 * so don't warn in that case. */
 	if (value == FcTypeUnknown)
 	    return;
-	FcConfigMessage (parse, FcSevereWarning, "saw %s, expected %s",
+	FcConfigMessage (parse, parse->messager, FcSevereWarning, "saw %s, expected %s",
 			 FcTypeName (value), FcTypeName (type));
     }
 }
@@ -725,7 +769,7 @@ FcTypecheckExpr (FcConfigParse *parse, FcExpr *expr, FcType type)
 		FcTypecheckValue (parse, o->type, type);
 	}
         else
-            FcConfigMessage (parse, FcSevereWarning,
+            FcConfigMessage (parse, parse->messager, FcSevereWarning,
                              "invalid constant used : %s",
                              expr->u.constant);
 	break;
@@ -787,7 +831,7 @@ FcTestCreate (FcConfigParse *parse,
     if (test)
     {
 	const FcObjectType	*o;
-	
+
 	test->kind = kind;
 	test->qual = qual;
 	test->object = FcObjectFromName ((const char *) field);
@@ -1127,7 +1171,7 @@ FcVStackElements (FcConfigParse *parse)
 }
 
 static FcChar8 **
-FcConfigSaveAttr (const XML_Char **attr, FcChar8 **buf, int size_bytes)
+FcConfigSaveAttr (FcConfigParse *parse, const XML_Char **attr, FcChar8 **buf, int size_bytes)
 {
     int		slen;
     int		i;
@@ -1149,7 +1193,7 @@ FcConfigSaveAttr (const XML_Char **attr, FcChar8 **buf, int size_bytes)
 	new = malloc (slen);
 	if (!new)
 	{
-	    FcConfigMessage (0, FcSevereError, "out of memory");
+	    FcConfigMessage (parse, parse->messager, FcSevereError, "out of memory");
 	    return 0;
 	}
     }
@@ -1180,7 +1224,7 @@ FcPStackPush (FcConfigParse *parse, FcElement element, const XML_Char **attr)
 
     new->prev = parse->pstack;
     new->element = element;
-    new->attr = FcConfigSaveAttr (attr, new->attr_buf_static, sizeof (new->attr_buf_static));
+    new->attr = FcConfigSaveAttr (parse, attr, new->attr_buf_static, sizeof (new->attr_buf_static));
     FcStrBufInit (&new->str, 0, 0);
     parse->pstack = new;
     return FcTrue;
@@ -1193,7 +1237,7 @@ FcPStackPop (FcConfigParse *parse)
 
     if (!parse->pstack)
     {
-	FcConfigMessage (parse, FcSevereError, "mismatching element");
+	FcConfigMessage (parse, parse->messager, FcSevereError, "mismatching element");
 	return FcFalse;
     }
 
@@ -1207,7 +1251,7 @@ FcPStackPop (FcConfigParse *parse)
 	{
 	    if (attrs[0][0])
 	    {
-		FcConfigMessage (parse, FcSevereError, "invalid attribute '%s'", attrs[0]);
+		FcConfigMessage (parse, parse->messager, FcSevereError, "invalid attribute '%s'", attrs[0]);
 	    }
 	    attrs += 2;
 	}
@@ -1230,15 +1274,19 @@ FcPStackPop (FcConfigParse *parse)
 
 static FcBool
 FcConfigParseInit (FcConfigParse	*parse,
+		   struct _MessageCallback * messager,
 		   const FcChar8	*name,
 		   FcConfig		*config,
 		   XML_Parser		parser,
-		   FcBool		enabled)
+		   FcBool		enabled,
+		   FcMessageCallback msg_callback,
+		   void * msg_callback_data)
 {
     parse->pstack = 0;
     parse->pstack_static_used = 0;
     parse->vstack = 0;
     parse->vstack_static_used = 0;
+	parse->messager = messager;
     parse->error = FcFalse;
     parse->name = name;
     parse->config = config;
@@ -1318,7 +1366,7 @@ _get_real_path_from_prefix(FcConfigParse *parse, const FcChar8 *path, const FcCh
     else
     {
 	if (!FcStrIsAbsoluteFilename (path) && path[0] != '~')
-	    FcConfigMessage (parse, FcSevereWarning, "Use of ambiguous path in <%s> element. please add prefix=\"cwd\" if current behavior is desired.", FcElementReverseMap (parse->pstack->element));
+	    FcConfigMessage (parse, parse->messager, FcSevereWarning, "Use of ambiguous path in <%s> element. please add prefix=\"cwd\" if current behavior is desired.", FcElementReverseMap (parse->pstack->element));
     }
 #else
     if (strcmp ((const char *) path, "CUSTOMFONTDIR") == 0)
@@ -1327,7 +1375,7 @@ _get_real_path_from_prefix(FcConfigParse *parse, const FcChar8 *path, const FcCh
 	path = buffer;
 	if (!GetModuleFileName (NULL, (LPCH) buffer, sizeof (buffer) - 20))
 	{
-	    FcConfigMessage (parse, FcSevereError, "GetModuleFileName failed");
+	    FcConfigMessage (parse, parse->messager, FcSevereError, "GetModuleFileName failed");
 	    return NULL;
 	}
 	/*
@@ -1346,7 +1394,7 @@ _get_real_path_from_prefix(FcConfigParse *parse, const FcChar8 *path, const FcCh
 	path = buffer;
 	if (!GetModuleFileName (NULL, (LPCH) buffer, sizeof (buffer) - 20))
 	{
-	    FcConfigMessage (parse, FcSevereError, "GetModuleFileName failed");
+	    FcConfigMessage (parse, parse->messager, FcSevereError, "GetModuleFileName failed");
 	    return NULL;
 	}
 	p = _mbsrchr (path, '\\');
@@ -1360,7 +1408,7 @@ _get_real_path_from_prefix(FcConfigParse *parse, const FcChar8 *path, const FcCh
 	rc = pGetSystemWindowsDirectory ((LPSTR) buffer, sizeof (buffer) - 20);
 	if (rc == 0 || rc > sizeof (buffer) - 20)
 	{
-	    FcConfigMessage (parse, FcSevereError, "GetSystemWindowsDirectory failed");
+	    FcConfigMessage (parse, parse->messager, FcSevereError, "GetSystemWindowsDirectory failed");
 	    return NULL;
 	}
 	if (path [strlen ((const char *) path) - 1] != '\\')
@@ -1372,7 +1420,7 @@ _get_real_path_from_prefix(FcConfigParse *parse, const FcChar8 *path, const FcCh
 	if (!prefix)
 	{
 	    if (!FcStrIsAbsoluteFilename (path) && path[0] != '~')
-		FcConfigMessage (parse, FcSevereWarning, "Use of ambiguous path in <%s> element. please add prefix=\"cwd\" if current behavior is desired.", FcElementReverseMap (parse->pstack->element));
+		FcConfigMessage (parse, parse->messager, FcSevereWarning, "Use of ambiguous path in <%s> element. please add prefix=\"cwd\" if current behavior is desired.", FcElementReverseMap (parse->pstack->element));
 	}
     }
 #endif
@@ -1396,11 +1444,11 @@ FcStartElement(void *userData, const XML_Char *name, const XML_Char **attr)
 
     element = FcElementMap (name);
     if (element == FcElementUnknown)
-	FcConfigMessage (parse, FcSevereWarning, "unknown element \"%s\"", name);
+	FcConfigMessage (parse, parse->messager, FcSevereWarning, "unknown element \"%s\"", name);
 
     if (!FcPStackPush (parse, element, attr))
     {
-	FcConfigMessage (parse, FcSevereError, "out of memory");
+	FcConfigMessage (parse, parse->messager, FcSevereError, "out of memory");
 	return;
     }
     return;
@@ -1414,7 +1462,7 @@ FcParseRescan (FcConfigParse *parse)
     {
 	FcVStack    *v = FcVStackFetch (parse, n);
 	if (v->tag != FcVStackInteger)
-	    FcConfigMessage (parse, FcSevereWarning, "non-integer rescan");
+	    FcConfigMessage (parse, parse->messager, FcSevereWarning, "non-integer rescan");
 	else
 	    parse->config->rescanInterval = v->u.integer;
     }
@@ -1431,13 +1479,13 @@ FcParseInt (FcConfigParse *parse)
     s = FcStrBufDoneStatic (&parse->pstack->str);
     if (!s)
     {
-	FcConfigMessage (parse, FcSevereError, "out of memory");
+	FcConfigMessage (parse, parse->messager, FcSevereError, "out of memory");
 	return;
     }
     end = 0;
     l = (int) strtol ((char *) s, (char **)&end, 0);
     if (end != s + strlen ((char *) s))
-	FcConfigMessage (parse, FcSevereError, "\"%s\": not a valid integer", s);
+	FcConfigMessage (parse, parse->messager, FcSevereError, "\"%s\": not a valid integer", s);
     else
 	FcVStackPushInteger (parse, l);
     FcStrBufDestroy (&parse->pstack->str);
@@ -1480,7 +1528,7 @@ FcStrtod (char *s, char **end)
     {
 	char	buf[128];
 	int	slen = strlen (s);
-	
+
 	if (slen + dlen > (int) sizeof (buf))
 	{
 	    if (end)
@@ -1523,13 +1571,13 @@ FcParseDouble (FcConfigParse *parse)
     s = FcStrBufDoneStatic (&parse->pstack->str);
     if (!s)
     {
-	FcConfigMessage (parse, FcSevereError, "out of memory");
+	FcConfigMessage (parse, parse->messager, FcSevereError, "out of memory");
 	return;
     }
     end = 0;
     d = FcStrtod ((char *) s, (char **)&end);
     if (end != s + strlen ((char *) s))
-	FcConfigMessage (parse, FcSevereError, "\"%s\": not a valid double", s);
+	FcConfigMessage (parse, parse->messager, FcSevereError, "\"%s\": not a valid double", s);
     else
 	FcVStackPushDouble (parse, d);
     FcStrBufDestroy (&parse->pstack->str);
@@ -1545,7 +1593,7 @@ FcParseString (FcConfigParse *parse, FcVStackTag tag)
     s = FcStrBufDone (&parse->pstack->str);
     if (!s)
     {
-	FcConfigMessage (parse, FcSevereError, "out of memory");
+	FcConfigMessage (parse, parse->messager, FcSevereError, "out of memory");
 	return;
     }
     if (!FcVStackPushString (parse, tag, s))
@@ -1573,7 +1621,7 @@ FcParseName (FcConfigParse *parse)
 	    kind = FcMatchDefault;
 	else
 	{
-	    FcConfigMessage (parse, FcSevereWarning, "invalid name target \"%s\"", kind_string);
+	    FcConfigMessage (parse, parse->messager, FcSevereWarning, "invalid name target \"%s\"", kind_string);
 	    return;
 	}
     }
@@ -1583,7 +1631,7 @@ FcParseName (FcConfigParse *parse)
     s = FcStrBufDone (&parse->pstack->str);
     if (!s)
     {
-	FcConfigMessage (parse, FcSevereError, "out of memory");
+	FcConfigMessage (parse, parse->messager, FcSevereError, "out of memory");
 	return;
     }
     object = FcObjectFromName ((const char *) s);
@@ -1605,11 +1653,11 @@ FcParseMatrix (FcConfigParse *parse)
 
     if (!m.yy || !m.yx || !m.xy || !m.xx)
     {
-	FcConfigMessage (parse, FcSevereWarning, "Missing values in matrix element");
+	FcConfigMessage (parse, parse->messager, FcSevereWarning, "Missing values in matrix element");
 	return;
     }
     if (FcPopExpr (parse))
-      FcConfigMessage (parse, FcSevereError, "wrong number of matrix elements");
+      FcConfigMessage (parse, parse->messager, FcSevereError, "wrong number of matrix elements");
     else
       FcVStackPushMatrix (parse, &m);
 }
@@ -1628,7 +1676,7 @@ FcParseRange (FcConfigParse *parse)
     {
 	if (count < 0)
 	{
-	    FcConfigMessage (parse, FcSevereError, "too many elements in range");
+	    FcConfigMessage (parse, parse->messager, FcSevereError, "too many elements in range");
 	    return;
 	}
 	switch ((int) vstack->tag) {
@@ -1645,7 +1693,7 @@ FcParseRange (FcConfigParse *parse)
 	    dflag = FcTrue;
 	    break;
 	default:
-	    FcConfigMessage (parse, FcSevereError, "invalid element in range");
+	    FcConfigMessage (parse, parse->messager, FcSevereError, "invalid element in range");
 	    if (dflag)
 		d[count] = 0.0L;
 	    else
@@ -1657,14 +1705,14 @@ FcParseRange (FcConfigParse *parse)
     }
     if (count >= 0)
     {
-	FcConfigMessage (parse, FcSevereError, "invalid range");
+	FcConfigMessage (parse, parse->messager, FcSevereError, "invalid range");
 	return;
     }
     if (dflag)
     {
 	if (d[0] > d[1])
 	{
-	    FcConfigMessage (parse, FcSevereError, "invalid range");
+	    FcConfigMessage (parse, parse->messager, FcSevereError, "invalid range");
 	    return;
 	}
 	r = FcRangeCreateDouble (d[0], d[1]);
@@ -1673,7 +1721,7 @@ FcParseRange (FcConfigParse *parse)
     {
 	if (n[0] > n[1])
 	{
-	    FcConfigMessage (parse, FcSevereError, "invalid range");
+	    FcConfigMessage (parse, parse->messager, FcSevereError, "invalid range");
 	    return;
 	}
 	r = FcRangeCreateInteger (n[0], n[1]);
@@ -1687,7 +1735,7 @@ FcConfigLexBool (FcConfigParse *parse, const FcChar8 *bool_)
     FcBool  result = FcFalse;
 
     if (!FcNameBool (bool_, &result))
-	FcConfigMessage (parse, FcSevereWarning, "\"%s\" is not known boolean",
+	FcConfigMessage (parse, parse->messager, FcSevereWarning, "\"%s\" is not known boolean",
 			 bool_);
     return result;
 }
@@ -1702,7 +1750,7 @@ FcParseBool (FcConfigParse *parse)
     s = FcStrBufDoneStatic (&parse->pstack->str);
     if (!s)
     {
-	FcConfigMessage (parse, FcSevereError, "out of memory");
+	FcConfigMessage (parse, parse->messager, FcSevereError, "out of memory");
 	return;
     }
     FcVStackPushBool (parse, FcConfigLexBool (parse, s));
@@ -1723,7 +1771,7 @@ FcParseCharSet (FcConfigParse *parse)
 	case FcVStackInteger:
 	    if (!FcCharSetAddChar (charset, vstack->u.integer))
 	    {
-		FcConfigMessage (parse, FcSevereWarning, "invalid character: 0x%04x", vstack->u.integer);
+		FcConfigMessage (parse, parse->messager, FcSevereWarning, "invalid character: 0x%04x", vstack->u.integer);
 	    }
 	    else
 		n++;
@@ -1738,7 +1786,7 @@ FcParseCharSet (FcConfigParse *parse)
 	      {
 		  if (!FcCharSetAddChar (charset, i))
 		  {
-		      FcConfigMessage (parse, FcSevereWarning, "invalid character: 0x%04x", i);
+		      FcConfigMessage (parse, parse->messager, FcSevereWarning, "invalid character: 0x%04x", i);
 		  }
 		  else
 		      n++;
@@ -1746,7 +1794,7 @@ FcParseCharSet (FcConfigParse *parse)
 	    }
 	    break;
 	default:
-		FcConfigMessage (parse, FcSevereError, "invalid element in charset");
+		FcConfigMessage (parse, parse->messager, FcSevereError, "invalid element in charset");
 		break;
 	}
 	FcVStackPopAndDestroy (parse);
@@ -1770,13 +1818,13 @@ FcParseLangSet (FcConfigParse *parse)
 	case FcVStackString:
 	    if (!FcLangSetAdd (langset, vstack->u.string))
 	    {
-		FcConfigMessage (parse, FcSevereWarning, "invalid langset: %s", vstack->u.string);
+		FcConfigMessage (parse, parse->messager, FcSevereWarning, "invalid langset: %s", vstack->u.string);
 	    }
 	    else
 		n++;
 	    break;
 	default:
-		FcConfigMessage (parse, FcSevereError, "invalid element in langset");
+		FcConfigMessage (parse, parse->messager, FcSevereError, "invalid element in langset");
 		break;
 	}
 	FcVStackPopAndDestroy (parse);
@@ -1806,7 +1854,7 @@ FcConfigLexBinding (FcConfigParse   *parse,
 	    binding = FcValueBindingSame;
 	else
 	{
-	    FcConfigMessage (parse, FcSevereWarning, "invalid binding \"%s\"", binding_string);
+	    FcConfigMessage (parse, parse->messager, FcSevereWarning, "invalid binding \"%s\"", binding_string);
 	    return FcFalse;
 	}
     }
@@ -1824,7 +1872,7 @@ FcParseFamilies (FcConfigParse *parse, FcVStackTag tag)
     {
 	if (vstack->tag != FcVStackFamily)
 	{
-	    FcConfigMessage (parse, FcSevereWarning, "non-family");
+	    FcConfigMessage (parse, parse->messager, FcSevereWarning, "non-family");
 	    FcVStackPopAndDestroy (parse);
 	    continue;
 	}
@@ -1836,7 +1884,7 @@ FcParseFamilies (FcConfigParse *parse, FcVStackTag tag)
 	    new = FcExprCreateOp (parse->config, left, FcOpComma, expr);
 	    if (!new)
 	    {
-		FcConfigMessage (parse, FcSevereError, "out of memory");
+		FcConfigMessage (parse, parse->messager, FcSevereError, "out of memory");
 		FcExprDestroy (left);
 		FcExprDestroy (expr);
 		break;
@@ -1850,7 +1898,7 @@ FcParseFamilies (FcConfigParse *parse, FcVStackTag tag)
     {
 	if (!FcVStackPushExpr (parse, tag, expr))
 	{
-	    FcConfigMessage (parse, FcSevereError, "out of memory");
+	    FcConfigMessage (parse, parse->messager, FcSevereError, "out of memory");
             FcExprDestroy (expr);
 	}
     }
@@ -1867,7 +1915,7 @@ FcParseFamily (FcConfigParse *parse)
     s = FcStrBufDoneStatic (&parse->pstack->str);
     if (!s)
     {
-	FcConfigMessage (parse, FcSevereError, "out of memory");
+	FcConfigMessage (parse, parse->messager, FcSevereError, "out of memory");
 	return;
     }
     expr = FcExprCreateString (parse->config, s);
@@ -1894,10 +1942,10 @@ FcParseAlias (FcConfigParse *parse)
 	case FcVStackFamily:
 	    if (family)
 	    {
-		FcConfigMessage (parse, FcSevereWarning, "Having multiple <family> in <alias> isn't supported and may not work as expected");
+		FcConfigMessage (parse, parse->messager, FcSevereWarning, "Having multiple <family> in <alias> isn't supported and may not work as expected");
 		new = FcExprCreateOp (parse->config, vstack->u.expr, FcOpComma, family);
 		if (!new)
-		    FcConfigMessage (parse, FcSevereError, "out of memory");
+		    FcConfigMessage (parse, parse->messager, FcSevereError, "out of memory");
 		else
 		    family = new;
 	    }
@@ -1939,14 +1987,14 @@ FcParseAlias (FcConfigParse *parse)
 	    vstack->tag = FcVStackNone;
 	    break;
 	default:
-	    FcConfigMessage (parse, FcSevereWarning, "bad alias");
+	    FcConfigMessage (parse, parse->messager, FcSevereWarning, "bad alias");
 	    break;
 	}
 	FcVStackPopAndDestroy (parse);
     }
     if (!family)
     {
-	FcConfigMessage (parse, FcSevereError, "missing family in alias");
+	FcConfigMessage (parse, parse->messager, FcSevereError, "missing family in alias");
 	if (prefer)
 	    FcExprDestroy (prefer);
 	if (accept)
@@ -2046,7 +2094,7 @@ FcParseDescription (FcConfigParse *parse)
     desc = FcStrBufDone (&parse->pstack->str);
     if (!desc)
     {
-	FcConfigMessage (parse, FcSevereError, "out of memory");
+	FcConfigMessage (parse, parse->messager, FcSevereError, "out of memory");
 	return;
     }
     FcRuleSetAddDescription (parse->ruleset, domain, desc);
@@ -2063,18 +2111,18 @@ FcParseRemapDir (FcConfigParse *parse)
     data = FcStrBufDoneStatic (&parse->pstack->str);
     if (!data)
     {
-	FcConfigMessage (parse, FcSevereError, "out of memory");
+	FcConfigMessage (parse, parse->messager, FcSevereError, "out of memory");
 	return;
     }
     if (data[0] == 0)
     {
-	FcConfigMessage (parse, FcSevereWarning, "empty font directory name for remap ignored");
+	FcConfigMessage (parse, parse->messager, FcSevereWarning, "empty font directory name for remap ignored");
 	return;
     }
     path = FcConfigGetAttribute (parse, "as-path");
     if (!path)
     {
-	FcConfigMessage (parse, FcSevereWarning, "Missing as-path in remap-dir");
+	FcConfigMessage (parse, parse->messager, FcSevereWarning, "Missing as-path in remap-dir");
 	return;
     }
     attr = FcConfigGetAttribute (parse, "prefix");
@@ -2087,7 +2135,7 @@ FcParseRemapDir (FcConfigParse *parse)
     else if (!parse->scanOnly && (!FcStrUsesHome (prefix) || FcConfigHome ()))
     {
 	if (!FcConfigAddFontDir (parse->config, prefix, path, salt))
-	    FcConfigMessage (parse, FcSevereError, "out of memory; cannot create remap data for %s as %s", prefix, path);
+	    FcConfigMessage (parse, parse->messager, FcSevereError, "out of memory; cannot create remap data for %s as %s", prefix, path);
     }
     FcStrBufDestroy (&parse->pstack->str);
 
@@ -2101,7 +2149,7 @@ FcParseResetDirs (FcConfigParse *parse)
     if (!parse->scanOnly)
     {
 	if (!FcConfigResetFontDirs (parse->config))
-	    FcConfigMessage (parse, FcSevereError, "Unable to reset fonts dirs");
+	    FcConfigMessage (parse, parse->messager, FcSevereError, "Unable to reset fonts dirs");
     }
 }
 
@@ -2191,7 +2239,7 @@ FcPopBinary (FcConfigParse *parse, FcOp op)
 	    new = FcExprCreateOp (parse->config, left, op, expr);
 	    if (!new)
 	    {
-		FcConfigMessage (parse, FcSevereError, "out of memory");
+		FcConfigMessage (parse, parse->messager, FcSevereError, "out of memory");
 		FcExprDestroy (left);
 		FcExprDestroy (expr);
 		return 0;
@@ -2228,7 +2276,7 @@ FcPopUnary (FcConfigParse *parse, FcOp op)
 	if (!new)
 	{
 	    FcExprDestroy (operand);
-	    FcConfigMessage (parse, FcSevereError, "out of memory");
+	    FcConfigMessage (parse, parse->messager, FcSevereError, "out of memory");
 	}
     }
     return new;
@@ -2251,12 +2299,12 @@ FcParseDir (FcConfigParse *parse)
     data = FcStrBufDoneStatic (&parse->pstack->str);
     if (!data)
     {
-	FcConfigMessage (parse, FcSevereError, "out of memory");
+	FcConfigMessage (parse, parse->messager, FcSevereError, "out of memory");
 	return;
     }
     if (data[0] == 0)
     {
-	FcConfigMessage (parse, FcSevereWarning, "empty font directory name ignored");
+	FcConfigMessage (parse, parse->messager, FcSevereWarning, "empty font directory name ignored");
 	return;
     }
     attr = FcConfigGetAttribute (parse, "prefix");
@@ -2269,7 +2317,7 @@ FcParseDir (FcConfigParse *parse)
     else if (!parse->scanOnly && (!FcStrUsesHome (prefix) || FcConfigHome ()))
     {
 	if (!FcConfigAddFontDir (parse->config, prefix, NULL, salt))
-	    FcConfigMessage (parse, FcSevereError, "out of memory; cannot add directory %s", prefix);
+	    FcConfigMessage (parse, parse->messager, FcSevereError, "out of memory; cannot add directory %s", prefix);
     }
     FcStrBufDestroy (&parse->pstack->str);
 
@@ -2296,7 +2344,7 @@ FcParseCacheDir (FcConfigParse *parse)
     data = FcStrBufDone (&parse->pstack->str);
     if (!data)
     {
-	FcConfigMessage (parse, FcSevereError, "out of memory");
+	FcConfigMessage (parse, parse->messager, FcSevereError, "out of memory");
 	data = prefix;
 	goto bail;
     }
@@ -2308,7 +2356,7 @@ FcParseCacheDir (FcConfigParse *parse)
 	p = realloc (prefix, plen + 1 + dlen + 1);
 	if (!p)
 	{
-	    FcConfigMessage (parse, FcSevereError, "out of memory");
+	    FcConfigMessage (parse, parse->messager, FcSevereError, "out of memory");
 	    FcStrFree (prefix);
 	    goto bail;
 	}
@@ -2328,7 +2376,7 @@ FcParseCacheDir (FcConfigParse *parse)
 	prefix = malloc (plen + 1 + dlen + 1);
 	if (!prefix)
 	{
-	    FcConfigMessage (parse, FcSevereError, "out of memory");
+	    FcConfigMessage (parse, parse->messager, FcSevereError, "out of memory");
 	    goto bail;
 	}
 	strcpy ((char *) prefix, (char *) fontconfig_instprefix);
@@ -2346,13 +2394,13 @@ FcParseCacheDir (FcConfigParse *parse)
 	data = malloc (1000);
 	if (!data)
 	{
-	    FcConfigMessage (parse, FcSevereError, "out of memory");
+	    FcConfigMessage (parse, parse->messager, FcSevereError, "out of memory");
 	    goto bail;
 	}
 	rc = GetTempPath (800, (LPSTR) data);
 	if (rc == 0 || rc > 800)
 	{
-	    FcConfigMessage (parse, FcSevereError, "GetTempPath failed");
+	    FcConfigMessage (parse, parse->messager, FcSevereError, "GetTempPath failed");
 	    goto bail;
 	}
 	if (data [strlen ((const char *) data) - 1] != '\\')
@@ -2366,7 +2414,7 @@ FcParseCacheDir (FcConfigParse *parse)
 
 	if (!(pSHGetFolderPathA && SUCCEEDED(pSHGetFolderPathA(NULL, /* CSIDL_LOCAL_APPDATA */ 28, NULL, 0, szFPath))))
 	{
-	    FcConfigMessage (parse, FcSevereError, "SHGetFolderPathA failed");
+	    FcConfigMessage (parse, parse->messager, FcSevereError, "SHGetFolderPathA failed");
 	    goto bail;
 	}
 	strncat(szFPath, "\\fontconfig\\cache", MAX_PATH - 1 - strlen(szFPath));
@@ -2375,18 +2423,18 @@ FcParseCacheDir (FcConfigParse *parse)
 	data = malloc(len);
 	if (!data)
 	{
-	    FcConfigMessage (parse, FcSevereError, "out of memory");
+	    FcConfigMessage (parse, parse->messager, FcSevereError, "out of memory");
 	    goto bail;
 	}
 	strncpy((char *) data, szFPath, len);
     }
 #endif
     if (strlen ((char *) data) == 0)
-	FcConfigMessage (parse, FcSevereWarning, "empty cache directory name ignored");
+	FcConfigMessage (parse, parse->messager, FcSevereWarning, "empty cache directory name ignored");
     else if (!parse->scanOnly && (!FcStrUsesHome (data) || FcConfigHome ()))
     {
 	if (!FcConfigAddCacheDir (parse->config, data))
-	    FcConfigMessage (parse, FcSevereError, "out of memory; cannot add cache directory %s", data);
+	    FcConfigMessage (parse, parse->messager, FcSevereError, "out of memory; cannot add cache directory %s", data);
     }
     FcStrBufDestroy (&parse->pstack->str);
 
@@ -2430,7 +2478,7 @@ FcParseInclude (FcConfigParse *parse)
     s = FcStrBufDoneStatic (&parse->pstack->str);
     if (!s)
     {
-	FcConfigMessage (parse, FcSevereError, "out of memory");
+	FcConfigMessage (parse, parse->messager, FcSevereError, "out of memory");
 	goto bail;
     }
     attr = FcConfigGetAttribute (parse, "ignore_missing");
@@ -2460,7 +2508,7 @@ FcParseInclude (FcConfigParse *parse)
 	p = realloc (prefix, plen + 1 + dlen + 1);
 	if (!p)
 	{
-	    FcConfigMessage (parse, FcSevereError, "out of memory");
+	    FcConfigMessage (parse, parse->messager, FcSevereError, "out of memory");
 	    goto bail;
 	}
 	prefix = p;
@@ -2527,7 +2575,7 @@ FcParseInclude (FcConfigParse *parse)
 	}
     }
     FcRuleSetDestroy (ruleset);
-    if (!_FcConfigParse (parse->config, s, !ignore_missing, !parse->scanOnly))
+    if (!_FcConfigParse (parse->config, s, !ignore_missing, !parse->scanOnly, parse->messager->callback, parse->messager->callback_data))
 	parse->error = FcTrue;
 #ifndef _WIN32
     else
@@ -2554,7 +2602,7 @@ FcParseInclude (FcConfigParse *parse)
 		{
 		    if (!warn_confd)
 		    {
-			FcConfigMessage (parse, FcSevereWarning, "reading configurations from %s is deprecated. please move it to %s manually", s, userdir);
+			FcConfigMessage (parse, parse->messager, FcSevereWarning, "reading configurations from %s is deprecated. please move it to %s manually", s, userdir);
 			warn_confd = FcTrue;
 		    }
 		}
@@ -2572,7 +2620,7 @@ FcParseInclude (FcConfigParse *parse)
 		{
 		    if (!warn_conf)
 		    {
-			FcConfigMessage (parse, FcSevereWarning, "reading configurations from %s is deprecated. please move it to %s manually", s, userconf);
+			FcConfigMessage (parse, parse->messager, FcSevereWarning, "reading configurations from %s is deprecated. please move it to %s manually", s, userconf);
 			warn_conf = FcTrue;
 		    }
 		}
@@ -2654,7 +2702,7 @@ FcParseTest (FcConfigParse *parse)
 	    kind = FcMatchDefault;
 	else
 	{
-	    FcConfigMessage (parse, FcSevereWarning, "invalid test target \"%s\"", kind_string);
+	    FcConfigMessage (parse, parse->messager, FcSevereWarning, "invalid test target \"%s\"", kind_string);
 	    return;
 	}
     }
@@ -2673,14 +2721,14 @@ FcParseTest (FcConfigParse *parse)
 	    qual = FcQualNotFirst;
 	else
 	{
-	    FcConfigMessage (parse, FcSevereWarning, "invalid test qual \"%s\"", qual_string);
+	    FcConfigMessage (parse, parse->messager, FcSevereWarning, "invalid test qual \"%s\"", qual_string);
 	    return;
 	}
     }
     name = FcConfigGetAttribute (parse, "name");
     if (!name)
     {
-	FcConfigMessage (parse, FcSevereWarning, "missing test name");
+	FcConfigMessage (parse, parse->messager, FcSevereWarning, "missing test name");
 	return;
     }
     compare_string = FcConfigGetAttribute (parse, "compare");
@@ -2691,7 +2739,7 @@ FcParseTest (FcConfigParse *parse)
 	compare = FcConfigLexCompare (compare_string);
 	if (compare == FcOpInvalid)
 	{
-	    FcConfigMessage (parse, FcSevereWarning, "invalid test compare \"%s\"", compare_string);
+	    FcConfigMessage (parse, parse->messager, FcSevereWarning, "invalid test compare \"%s\"", compare_string);
 	    return;
 	}
     }
@@ -2702,7 +2750,7 @@ FcParseTest (FcConfigParse *parse)
 
 	if (!FcNameBool (iblanks_string, &f))
 	{
-	    FcConfigMessage (parse,
+	    FcConfigMessage (parse, parse->messager,
 			     FcSevereWarning,
 			     "invalid test ignore-blanks \"%s\"", iblanks_string);
 	}
@@ -2712,17 +2760,17 @@ FcParseTest (FcConfigParse *parse)
     expr = FcPopBinary (parse, FcOpComma);
     if (!expr)
     {
-	FcConfigMessage (parse, FcSevereWarning, "missing test expression");
+	FcConfigMessage (parse, parse->messager, FcSevereWarning, "missing test expression");
 	return;
     }
     if (expr->op == FcOpComma)
     {
-	FcConfigMessage (parse, FcSevereWarning, "Having multiple values in <test> isn't supported and may not work as expected");
+	FcConfigMessage (parse, parse->messager, FcSevereWarning, "Having multiple values in <test> isn't supported and may not work as expected");
     }
     test = FcTestCreate (parse, kind, qual, name, FC_OP (compare, flags), expr);
     if (!test)
     {
-	FcConfigMessage (parse, FcSevereError, "out of memory");
+	FcConfigMessage (parse, parse->messager, FcSevereError, "out of memory");
 	return;
     }
     FcVStackPushTest (parse, test);
@@ -2760,7 +2808,7 @@ FcParseEdit (FcConfigParse *parse)
     name = FcConfigGetAttribute (parse, "name");
     if (!name)
     {
-	FcConfigMessage (parse, FcSevereWarning, "missing edit name");
+	FcConfigMessage (parse, parse->messager, FcSevereWarning, "missing edit name");
 	return;
     }
     mode_string = FcConfigGetAttribute (parse, "mode");
@@ -2771,7 +2819,7 @@ FcParseEdit (FcConfigParse *parse)
 	mode = FcConfigLexMode (mode_string);
 	if (mode == FcOpInvalid)
 	{
-	    FcConfigMessage (parse, FcSevereWarning, "invalid edit mode \"%s\"", mode_string);
+	    FcConfigMessage (parse, parse->messager, FcSevereWarning, "invalid edit mode \"%s\"", mode_string);
 	    return;
 	}
     }
@@ -2782,7 +2830,7 @@ FcParseEdit (FcConfigParse *parse)
     if ((mode == FcOpDelete || mode == FcOpDeleteAll) &&
 	expr != NULL)
     {
-	FcConfigMessage (parse, FcSevereWarning, "Expression doesn't take any effects for delete and delete_all");
+	FcConfigMessage (parse, parse->messager, FcSevereWarning, "Expression doesn't take any effects for delete and delete_all");
 	FcExprDestroy (expr);
 	expr = NULL;
     }
@@ -2790,7 +2838,7 @@ FcParseEdit (FcConfigParse *parse)
 			 mode, expr, binding);
     if (!edit)
     {
-	FcConfigMessage (parse, FcSevereError, "out of memory");
+	FcConfigMessage (parse, parse->messager, FcSevereError, "out of memory");
 	FcExprDestroy (expr);
 	return;
     }
@@ -2820,7 +2868,7 @@ FcParseMatch (FcConfigParse *parse)
 	    kind = FcMatchScan;
 	else
 	{
-	    FcConfigMessage (parse, FcSevereWarning, "invalid match target \"%s\"", kind_name);
+	    FcConfigMessage (parse, parse->messager, FcSevereWarning, "invalid match target \"%s\"", kind_name);
 	    return;
 	}
     }
@@ -2837,7 +2885,7 @@ FcParseMatch (FcConfigParse *parse)
 	case FcVStackEdit:
 	    if (kind == FcMatchScan && vstack->u.edit->object > FC_MAX_BASE_OBJECT)
 	    {
-		FcConfigMessage (parse, FcSevereError,
+		FcConfigMessage (parse, parse->messager, FcSevereError,
 				 "<match target=\"scan\"> cannot edit user-defined object \"%s\"",
 				 FcObjectName(vstack->u.edit->object));
 		if (rule)
@@ -2851,19 +2899,19 @@ FcParseMatch (FcConfigParse *parse)
 	    vstack->tag = FcVStackNone;
 	    break;
 	default:
-	    FcConfigMessage (parse, FcSevereWarning, "invalid match element");
+	    FcConfigMessage (parse, parse->messager, FcSevereWarning, "invalid match element");
 	    break;
 	}
 	FcVStackPopAndDestroy (parse);
     }
     if (!rule)
     {
-	FcConfigMessage (parse, FcSevereWarning, "No <test> nor <edit> elements in <match>");
+	FcConfigMessage (parse, parse->messager, FcSevereWarning, "No <test> nor <edit> elements in <match>");
 	return;
     }
     if ((n = FcRuleSetAdd (parse->ruleset, rule, kind)) == -1)
     {
-	FcConfigMessage (parse, FcSevereError, "out of memory");
+	FcConfigMessage (parse, parse->messager, FcSevereError, "out of memory");
 	FcRuleDestroy (rule);
     }
     else
@@ -2884,7 +2932,7 @@ FcParseAcceptRejectFont (FcConfigParse *parse, FcElement element)
 						      vstack->u.string,
 						      element == FcElementAcceptfont))
 	    {
-		FcConfigMessage (parse, FcSevereError, "out of memory");
+		FcConfigMessage (parse, parse->messager, FcSevereError, "out of memory");
 	    }
 	    else
 	    {
@@ -2900,7 +2948,7 @@ FcParseAcceptRejectFont (FcConfigParse *parse, FcElement element)
 							  vstack->u.pattern,
 							  element == FcElementAcceptfont))
 	    {
-		FcConfigMessage (parse, FcSevereError, "out of memory");
+		FcConfigMessage (parse, parse->messager, FcSevereError, "out of memory");
 	    }
 	    else
 	    {
@@ -2910,7 +2958,7 @@ FcParseAcceptRejectFont (FcConfigParse *parse, FcElement element)
 	    }
 	    break;
 	default:
-	    FcConfigMessage (parse, FcSevereWarning, "bad font selector");
+	    FcConfigMessage (parse, parse->messager, FcSevereWarning, "bad font selector");
 	    break;
 	}
 	FcVStackPopAndDestroy (parse);
@@ -2967,7 +3015,7 @@ FcPopValue (FcConfigParse *parse)
 	    value.type = FcTypeRange;
 	break;
     default:
-	FcConfigMessage (parse, FcSevereWarning, "unknown pattern element %d",
+	FcConfigMessage (parse, parse->messager, FcSevereWarning, "unknown pattern element %d",
 			 vstack->tag);
 	break;
     }
@@ -2985,14 +3033,14 @@ FcParsePatelt (FcConfigParse *parse)
 
     if (!pattern)
     {
-	FcConfigMessage (parse, FcSevereError, "out of memory");
+	FcConfigMessage (parse, parse->messager, FcSevereError, "out of memory");
 	return;
     }
 
     name = (char *) FcConfigGetAttribute (parse, "name");
     if (!name)
     {
-	FcConfigMessage (parse, FcSevereWarning, "missing pattern element name");
+	FcConfigMessage (parse, parse->messager, FcSevereWarning, "missing pattern element name");
 	FcPatternDestroy (pattern);
 	return;
     }
@@ -3004,7 +3052,7 @@ FcParsePatelt (FcConfigParse *parse)
 	    break;
 	if (!FcPatternAdd (pattern, name, value, FcTrue))
 	{
-	    FcConfigMessage (parse, FcSevereError, "out of memory");
+	    FcConfigMessage (parse, parse->messager, FcSevereError, "out of memory");
             FcValueDestroy(value);
 	    break;
 	}
@@ -3022,23 +3070,23 @@ FcParsePattern (FcConfigParse *parse)
 
     if (!pattern)
     {
-	FcConfigMessage (parse, FcSevereError, "out of memory");
+	FcConfigMessage (parse, parse->messager, FcSevereError, "out of memory");
 	return;
     }
-	
+
     while ((vstack = FcVStackPeek (parse)))
     {
 	switch ((int) vstack->tag) {
 	case FcVStackPattern:
 	    if (!FcPatternAppend (pattern, vstack->u.pattern))
 	    {
-		FcConfigMessage (parse, FcSevereError, "out of memory");
+		FcConfigMessage (parse, parse->messager, FcSevereError, "out of memory");
 		FcPatternDestroy (pattern);
 		return;
 	    }
 	    break;
 	default:
-	    FcConfigMessage (parse, FcSevereWarning, "unknown pattern element");
+	    FcConfigMessage (parse, parse->messager, FcSevereWarning, "unknown pattern element");
 	    break;
 	}
 	FcVStackPopAndDestroy (parse);
@@ -3070,7 +3118,7 @@ FcEndElement(void *userData, const XML_Char *name FC_UNUSED)
 	data = FcStrBufDoneStatic (&parse->pstack->str);
 	if (!data)
 	{
-	    FcConfigMessage (parse, FcSevereError, "out of memory");
+	    FcConfigMessage (parse, parse->messager, FcSevereError, "out of memory");
 	    break;
 	}
 	/* discard this data; no longer used */
@@ -3100,7 +3148,7 @@ FcEndElement(void *userData, const XML_Char *name FC_UNUSED)
     case FcElementRescan:
 	FcParseRescan (parse);
 	break;
-	
+
     case FcElementPrefer:
 	FcParseFamilies (parse, FcVStackPrefer);
 	break;
@@ -3240,7 +3288,7 @@ FcCharacterData (void *userData, const XML_Char *s, int len)
     if (!parse->pstack)
 	return;
     if (!FcStrBufData (&parse->pstack->str, (FcChar8 *) s, len))
-	FcConfigMessage (parse, FcSevereError, "out of memory");
+	FcConfigMessage (parse, parse->messager, FcSevereError, "out of memory");
 }
 
 static void
@@ -3253,7 +3301,7 @@ FcStartDoctypeDecl (void	    *userData,
     FcConfigParse   *parse = userData;
 
     if (strcmp ((char *) doctypeName, "fontconfig") != 0)
-	FcConfigMessage (parse, FcSevereError, "invalid doctype \"%s\"", doctypeName);
+	FcConfigMessage (parse, parse->messager, FcSevereError, "invalid doctype \"%s\"", doctypeName);
 }
 
 #ifdef ENABLE_LIBXML2
@@ -3298,8 +3346,11 @@ FcConfigParseAndLoadDir (FcConfig	*config,
 			 const FcChar8	*name,
 			 const FcChar8	*dir,
 			 FcBool		complain,
-			 FcBool		load)
+			 FcBool		load,
+			 FcMessageCallback msg_callback,
+			 void * msg_callback_data)
 {
+	struct _MessageCallback messager = {msg_callback, msg_callback_data};
     DIR		    *d;
     struct dirent   *e;
     FcBool	    ret = FcTrue;
@@ -3311,7 +3362,7 @@ FcConfigParseAndLoadDir (FcConfig	*config,
     if (!d)
     {
 	if (complain)
-	    FcConfigMessage (0, FcSevereError, "Cannot open config dir \"%s\"",
+	    FcConfigMessage (0, &messager, FcSevereError, "Cannot open config dir \"%s\"",
 			     name);
 	ret = FcFalse;
 	goto bail0;
@@ -3368,7 +3419,7 @@ FcConfigParseAndLoadDir (FcConfig	*config,
 	qsort (files->strs, files->num, sizeof (FcChar8 *),
 	       (int (*)(const void *, const void *)) FcSortCmpStr);
 	for (i = 0; ret && i < files->num; i++)
-	    ret = _FcConfigParse (config, files->strs[i], complain, load);
+	    ret = _FcConfigParse (config, files->strs[i], complain, load, msg_callback, msg_callback_data);
     }
 bail3:
     FcStrSetDestroy (files);
@@ -3390,9 +3441,11 @@ FcConfigParseAndLoadFromMemoryInternal (FcConfig       *config,
 					const FcChar8  *filename,
 					const FcChar8  *buffer,
 					FcBool         complain,
-					FcBool         load)
+					FcBool         load,
+					FcMessageCallback msg_callback,
+					void * msg_callback_data)
 {
-
+	struct _MessageCallback messager = {msg_callback, msg_callback_data};
     XML_Parser	    p;
     size_t	    len;
     FcConfigParse   parse;
@@ -3431,7 +3484,7 @@ FcConfigParseAndLoadFromMemoryInternal (FcConfig       *config,
     if (!p)
 	goto bail1;
 
-    if (!FcConfigParseInit (&parse, filename, config, p, load))
+    if (!FcConfigParseInit (&parse, &messager, filename, config, p, load, msg_callback, msg_callback_data))
 	goto bail2;
 
 #ifndef ENABLE_LIBXML2
@@ -3441,7 +3494,7 @@ FcConfigParseAndLoadFromMemoryInternal (FcConfig       *config,
     XML_SetDoctypeDeclHandler (p, FcStartDoctypeDecl, FcEndDoctypeDecl);
     XML_SetElementHandler (p, FcStartElement, FcEndElement);
     XML_SetCharacterDataHandler (p, FcCharacterData);
-	
+
 #endif /* ENABLE_LIBXML2 */
 
 #ifndef ENABLE_LIBXML2
@@ -3450,7 +3503,7 @@ FcConfigParseAndLoadFromMemoryInternal (FcConfig       *config,
 	buf = XML_GetBuffer (p, BUFSIZ);
 	if (!buf)
 	{
-	    FcConfigMessage (&parse, FcSevereError, "cannot get parse buffer");
+	    FcConfigMessage (&parse, &messager, FcSevereError, "cannot get parse buffer");
 	    goto bail3;
 	}
 	if (len > BUFSIZ)
@@ -3473,7 +3526,7 @@ FcConfigParseAndLoadFromMemoryInternal (FcConfig       *config,
 	if (!XML_ParseBuffer (p, buflen, buflen == 0))
 #endif
 	{
-	    FcConfigMessage (&parse, FcSevereError, "%s",
+	    FcConfigMessage (&parse, parse.messager, FcSevereError, "%s",
 			   XML_ErrorString (XML_GetErrorCode (p)));
 	    goto bail3;
 	}
@@ -3506,7 +3559,7 @@ bail2:
 bail1:
     if (error && complain)
     {
-	FcConfigMessage (0, FcSevereError, "Cannot %s config file from %s", load ? "load" : "scan", filename);
+	FcConfigMessage (0, &messager, FcSevereError, "Cannot %s config file from %s", load ? "load" : "scan", filename);
 	return FcFalse;
     }
     if (FcDebug () & FC_DBG_CONFIG)
@@ -3518,8 +3571,11 @@ static FcBool
 _FcConfigParse (FcConfig	*config,
 		const FcChar8	*name,
 		FcBool		complain,
-		FcBool		load)
+		FcBool		load,
+		FcMessageCallback msg_callback,
+		void * msg_callback_data)
 {
+	struct _MessageCallback messager = {msg_callback, msg_callback_data};
     FcChar8	    *filename = NULL, *realfilename = NULL;
     int		    fd;
     int		    len;
@@ -3566,7 +3622,7 @@ _FcConfigParse (FcConfig	*config,
 
     if (FcFileIsDir (realfilename))
     {
-	ret = FcConfigParseAndLoadDir (config, name, realfilename, complain, load);
+	ret = FcConfigParseAndLoadDir (config, name, realfilename, complain, load, msg_callback, msg_callback_data);
 	FcStrFree (filename);
 	FcStrFree (realfilename);
 	return ret;
@@ -3595,7 +3651,7 @@ _FcConfigParse (FcConfig	*config,
 #else
 	    ebuf[0] = 0;
 #endif
-	    FcConfigMessage (0, FcSevereError, "failed reading config file: %s: %s (errno %d)", realfilename, ebuf, errno_);
+	    FcConfigMessage (0, &messager, FcSevereError, "failed reading config file: %s: %s (errno %d)", realfilename, ebuf, errno_);
 	    close (fd);
 	    goto bail1;
 	}
@@ -3603,7 +3659,7 @@ _FcConfigParse (FcConfig	*config,
     } while (len != 0);
     close (fd);
 
-    ret = FcConfigParseAndLoadFromMemoryInternal (config, filename, FcStrBufDoneStatic (&sbuf), complain, load);
+    ret = FcConfigParseAndLoadFromMemoryInternal (config, filename, FcStrBufDoneStatic (&sbuf), complain, load, msg_callback, msg_callback_data);
     complain = FcFalse; /* no need to reclaim here */
 bail1:
     FcStrBufDestroy (&sbuf);
@@ -3615,9 +3671,9 @@ bail0:
     if (!ret && complain)
     {
 	if (name)
-	    FcConfigMessage (0, FcSevereError, "Cannot %s config file \"%s\"", load ? "load" : "scan", name);
+	    FcConfigMessage (0, &messager, FcSevereError, "Cannot %s config file \"%s\"", load ? "load" : "scan", name);
 	else
-	    FcConfigMessage (0, FcSevereError, "Cannot %s default config file", load ? "load" : "scan");
+	    FcConfigMessage (0, &messager, FcSevereError, "Cannot %s default config file", load ? "load" : "scan");
 	return FcFalse;
     }
     return FcTrue;
@@ -3628,7 +3684,7 @@ FcConfigParseOnly (FcConfig		*config,
 		   const FcChar8	*name,
 		   FcBool		complain)
 {
-    return _FcConfigParse (config, name, complain, FcFalse);
+    return _FcConfigParse (config, name, complain, FcFalse, msg_to_stderr, NULL);
 }
 
 FcBool
@@ -3636,7 +3692,7 @@ FcConfigParseAndLoad (FcConfig	    *config,
 		      const FcChar8 *name,
 		      FcBool	    complain)
 {
-    return _FcConfigParse (config, name, complain, FcTrue);
+    return _FcConfigParse (config, name, complain, FcTrue, msg_to_stderr, NULL);
 }
 
 FcBool
@@ -3644,7 +3700,7 @@ FcConfigParseAndLoadFromMemory (FcConfig       *config,
 				const FcChar8  *buffer,
 				FcBool         complain)
 {
-    return FcConfigParseAndLoadFromMemoryInternal (config, (const FcChar8 *)"memory", buffer, complain, FcTrue);
+    return FcConfigParseAndLoadFromMemoryInternal (config, (const FcChar8 *)"memory", buffer, complain, FcTrue, msg_to_stderr, NULL);
 }
 
 #define __fcxml__
_______________________________________________
Fontconfig mailing list
Fontconfig@xxxxxxxxxxxxxxxxxxxxx
https://lists.freedesktop.org/mailman/listinfo/fontconfig

[Index of Archives]     [Fedora Fonts]     [Fedora Users]     [Fedora Cloud]     [Kernel]     [Fedora Packaging]     [Fedora Desktop]     [PAM]     [Gimp Graphics Editor]     [Yosemite News]

  Powered by Linux