Removed GError* member from ParserState; better error message when encountered an error in a referenced lang file; get error messages from xml parser

master
Yevgen Muntyan 2006-08-31 00:29:58 -05:00
parent d86c65ac43
commit f47ee58476
1 changed files with 93 additions and 83 deletions

View File

@ -89,8 +89,6 @@ struct _ParserState
gchar *opening_delimiter; gchar *opening_delimiter;
gchar *closing_delimiter; gchar *closing_delimiter;
GError **error;
}; };
typedef struct _ParserState ParserState; typedef struct _ParserState ParserState;
@ -565,6 +563,18 @@ add_ref (ParserState *parser_state,
parser_state->styles_mapping, parser_state->styles_mapping,
parser_state->loaded_lang_ids, parser_state->loaded_lang_ids,
&tmp_error); &tmp_error);
if (tmp_error)
{
GError *tmp_error2 = NULL;
g_set_error (&tmp_error2, PARSER_ERROR, tmp_error->code,
"In file '%s' referenced from '%s': %s",
imported_language->priv->lang_file_name,
parser_state->language->priv->lang_file_name,
tmp_error->message);
g_clear_error (&tmp_error);
tmp_error = tmp_error2;
}
} }
} }
ref_id = g_strdup (ref); ref_id = g_strdup (ref);
@ -675,8 +685,7 @@ handle_context_element (ParserState *parser_state,
GError *tmp_error = NULL; GError *tmp_error = NULL;
/* Return if an error is already set */ g_return_if_fail (error != NULL && *error == NULL);
g_return_if_fail (error == NULL || *error == NULL);
ref = xmlTextReaderGetAttribute (parser_state->reader, BAD_CAST "ref"); ref = xmlTextReaderGetAttribute (parser_state->reader, BAD_CAST "ref");
sub_pattern = xmlTextReaderGetAttribute (parser_state->reader, sub_pattern = xmlTextReaderGetAttribute (parser_state->reader,
@ -799,8 +808,7 @@ handle_language_element (ParserState *parser_state,
xmlChar *lang_id, *lang_version; xmlChar *lang_id, *lang_version;
xmlChar *expected_version = BAD_CAST "2.0"; xmlChar *expected_version = BAD_CAST "2.0";
/* Return if an error is already set */ g_return_if_fail (error != NULL && *error == NULL);
g_return_if_fail (error == NULL || *error == NULL);
lang_version = xmlTextReaderGetAttribute (parser_state->reader, BAD_CAST "version"); lang_version = xmlTextReaderGetAttribute (parser_state->reader, BAD_CAST "version");
@ -808,10 +816,11 @@ handle_language_element (ParserState *parser_state,
(xmlStrcmp (expected_version, lang_version) != 0)) (xmlStrcmp (expected_version, lang_version) != 0))
{ {
g_set_error (error, g_set_error (error,
PARSER_ERROR, PARSER_ERROR,
PARSER_ERROR_WRONG_VERSION, PARSER_ERROR_WRONG_VERSION,
"wrong language version '%s', expected '%s'", "wrong language version '%s', expected '%s'",
lang_version, (gchar *)expected_version); lang_version ? (gchar*) lang_version : "(none)",
(gchar*) expected_version);
} }
lang_id = xmlTextReaderGetAttribute (parser_state->reader, BAD_CAST "id"); lang_id = xmlTextReaderGetAttribute (parser_state->reader, BAD_CAST "id");
@ -827,14 +836,18 @@ handle_language_element (ParserState *parser_state,
static gboolean static gboolean
replace_by_id (const EggRegex *egg_regex, replace_by_id (const EggRegex *egg_regex,
const gchar *regex, const gchar *regex,
GString *expanded_regex, GString *expanded_regex,
gpointer data) gpointer user_data)
{ {
gchar *id, *subst, *escapes; gchar *id, *subst, *escapes;
gchar *tmp; gchar *tmp;
GError *tmp_error = NULL; GError *tmp_error = NULL;
ParserState *parser_state = data;
struct {
ParserState *parser_state;
GError *error;
} *data = user_data;
escapes = egg_regex_fetch (egg_regex, 1, regex); escapes = egg_regex_fetch (egg_regex, 1, regex);
tmp = egg_regex_fetch (egg_regex, 2, regex); tmp = egg_regex_fetch (egg_regex, 2, regex);
@ -844,17 +857,14 @@ replace_by_id (const EggRegex *egg_regex,
if (id_is_decorated (tmp, NULL)) if (id_is_decorated (tmp, NULL))
id = g_strdup (tmp); id = g_strdup (tmp);
else else
id = decorate_id (parser_state, tmp); id = decorate_id (data->parser_state, tmp);
g_free (tmp); g_free (tmp);
subst = g_hash_table_lookup (parser_state->defined_regexes, id); subst = g_hash_table_lookup (data->parser_state->defined_regexes, id);
if (subst == NULL) if (subst == NULL)
{
g_set_error (&tmp_error, g_set_error (&tmp_error,
PARSER_ERROR, PARSER_ERROR_WRONG_ID, PARSER_ERROR, PARSER_ERROR_WRONG_ID,
_ ("wrong id '%s' in regex '%s'"), id, regex); _("wrong id '%s' in regex '%s'"), id, regex);
}
if (tmp_error == NULL) if (tmp_error == NULL)
{ {
@ -867,7 +877,7 @@ replace_by_id (const EggRegex *egg_regex,
if (tmp_error != NULL) if (tmp_error != NULL)
{ {
g_propagate_error (parser_state->error, tmp_error); g_propagate_error (&data->error, tmp_error);
return TRUE; return TRUE;
} }
@ -977,20 +987,20 @@ expand_regex_vars (ParserState *parser_state, gchar *regex, gint len, GError **e
const gchar *re = "(?<!\\\\)(\\\\\\\\)*\\\\%\\{([^@]*?)\\}"; const gchar *re = "(?<!\\\\)(\\\\\\\\)*\\\\%\\{([^@]*?)\\}";
gchar *expanded_regex; gchar *expanded_regex;
EggRegex *egg_re; EggRegex *egg_re;
struct {
ParserState *parser_state;
GError *error;
} data = {parser_state, NULL};
if (regex == NULL) if (regex == NULL)
return NULL; return NULL;
egg_re = egg_regex_new (re, 0, 0, NULL); egg_re = egg_regex_new (re, 0, 0, NULL);
/* Use parser_state to pass the GError because we cannot pass
* it directly to the callback */
parser_state->error = error;
expanded_regex = egg_regex_replace_eval (egg_re, regex, len, 0, 0, expanded_regex = egg_regex_replace_eval (egg_re, regex, len, 0, 0,
replace_by_id, parser_state); replace_by_id, &data);
parser_state->error = NULL;
if (*error == NULL) if (data.error == NULL)
{ {
DEBUG (g_message ("expanded regex vars '%s' to '%s'", DEBUG (g_message ("expanded regex vars '%s' to '%s'",
regex, expanded_regex)); regex, expanded_regex));
@ -998,9 +1008,10 @@ expand_regex_vars (ParserState *parser_state, gchar *regex, gint len, GError **e
egg_regex_unref (egg_re); egg_regex_unref (egg_re);
if (*error != NULL) if (data.error != NULL)
{ {
g_free (expanded_regex); g_free (expanded_regex);
g_propagate_error (error, data.error);
return NULL; return NULL;
} }
@ -1194,8 +1205,7 @@ handle_define_regex_element (ParserState *parser_state,
int type; int type;
/* Return if an error is already set */ g_return_if_fail (error != NULL && *error == NULL);
g_return_if_fail (error == NULL || *error == NULL);
if (parser_state->engine == NULL) if (parser_state->engine == NULL)
return; return;
@ -1259,8 +1269,7 @@ handle_default_regex_options_element (ParserState *parser_state,
xmlChar *options; xmlChar *options;
int ret, type; int ret, type;
/* Return if an error is already set */ g_return_if_fail (error != NULL && *error == NULL);
g_return_if_fail (error == NULL || *error == NULL);
if (!parser_state->engine) if (!parser_state->engine)
return; return;
@ -1298,7 +1307,7 @@ map_style (ParserState *parser_state,
{ {
const gchar *mapped_style; const gchar *mapped_style;
g_return_if_fail (error == NULL || *error == NULL); g_return_if_fail (error != NULL && *error == NULL);
if (map_to != NULL) if (map_to != NULL)
mapped_style = g_hash_table_lookup (parser_state->styles_mapping, mapped_style = g_hash_table_lookup (parser_state->styles_mapping,
@ -1370,7 +1379,7 @@ parse_language_with_id (ParserState *parser_state,
GtkSourceLanguage *imported_language; GtkSourceLanguage *imported_language;
GError *tmp_error = NULL; GError *tmp_error = NULL;
g_return_if_fail (error == NULL || *error == NULL); g_return_if_fail (error != NULL && *error == NULL);
lm = _gtk_source_language_get_languages_manager (parser_state->language); lm = _gtk_source_language_get_languages_manager (parser_state->language);
imported_language = gtk_source_languages_manager_get_language_by_id (lm, lang_id); imported_language = gtk_source_languages_manager_get_language_by_id (lm, lang_id);
@ -1411,7 +1420,7 @@ parse_style (ParserState *parser_state,
gchar *lang_id = NULL; gchar *lang_id = NULL;
GError *tmp_error = NULL; GError *tmp_error = NULL;
g_return_if_fail (error == NULL || *error == NULL); g_return_if_fail (error != NULL && *error == NULL);
tmp = xmlTextReaderGetAttribute (parser_state->reader, tmp = xmlTextReaderGetAttribute (parser_state->reader,
BAD_CAST "id"); BAD_CAST "id");
@ -1485,8 +1494,7 @@ handle_keyword_char_class_element (ParserState *parser_state,
xmlChar *char_class; xmlChar *char_class;
int ret, type; int ret, type;
/* Return if an error is already set */ g_return_if_fail (error != NULL && *error == NULL);
g_return_if_fail (!error || !*error);
if (!parser_state->engine) if (!parser_state->engine)
return; return;
@ -1519,21 +1527,16 @@ handle_styles_element (ParserState *parser_state,
const xmlChar *tag_name; const xmlChar *tag_name;
GError *tmp_error = NULL; GError *tmp_error = NULL;
g_return_if_fail (error == NULL || *error == NULL); g_return_if_fail (error != NULL && *error == NULL);
while (TRUE) while (TRUE)
{ {
ret = xmlTextReaderRead (parser_state->reader); ret = xmlTextReaderRead (parser_state->reader);
if (!xmlTextReaderIsValid (parser_state->reader))
{ /* FIXME: is xmlTextReaderIsValid call needed here or
/* TODO: get the error message from the * error func will be called? */
* xml parser */ if (*error)
g_set_error (&tmp_error,
PARSER_ERROR,
PARSER_ERROR_INVALID_DOC,
"invalid language file");
break; break;
}
tag_name = xmlTextReaderConstName (parser_state->reader); tag_name = xmlTextReaderConstName (parser_state->reader);
type = xmlTextReaderNodeType (parser_state->reader); type = xmlTextReaderNodeType (parser_state->reader);
@ -1620,6 +1623,17 @@ element_end (ParserState *parser_state)
} }
} }
static void
text_reader_error_func (GError **error,
const gchar *msg,
xmlParserSeverities severity,
xmlTextReaderLocatorPtr locator)
{
/* FIXME: does someone know how to use libxml api? */
g_return_if_fail (error != NULL && *error == NULL);
g_set_error (error, PARSER_ERROR, PARSER_ERROR_INVALID_DOC, "%s", msg);
}
static gboolean static gboolean
file_parse (gchar *filename, file_parse (gchar *filename,
GtkSourceLanguage *language, GtkSourceLanguage *language,
@ -1634,6 +1648,8 @@ file_parse (gchar *filename,
int ret; int ret;
int fd; int fd;
GError *tmp_error = NULL; GError *tmp_error = NULL;
GtkSourceLanguagesManager *lm;
const gchar *rng_lang_schema;
g_return_val_if_fail (error == NULL || *error == NULL, FALSE); g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
@ -1653,51 +1669,44 @@ file_parse (gchar *filename,
PARSER_ERROR, PARSER_ERROR,
PARSER_ERROR_CANNOT_OPEN, PARSER_ERROR_CANNOT_OPEN,
"unable to open the file"); "unable to open the file");
goto error;
} }
if (tmp_error == NULL) lm = _gtk_source_language_get_languages_manager (language);
rng_lang_schema = _gtk_source_languages_manager_get_rng_file (lm);
if (!rng_lang_schema)
{ {
GtkSourceLanguagesManager *lm; g_set_error (&tmp_error,
const gchar *rng_lang_schema; PARSER_ERROR,
PARSER_ERROR_CANNOT_VALIDATE,
"could not find the RelaxNG schema file");
goto error;
}
lm = _gtk_source_language_get_languages_manager (language); if (xmlTextReaderRelaxNGValidate (reader, rng_lang_schema))
rng_lang_schema = _gtk_source_languages_manager_get_rng_file (lm); {
g_set_error (&tmp_error,
if (!rng_lang_schema) PARSER_ERROR,
{ PARSER_ERROR_CANNOT_VALIDATE,
g_set_error (&tmp_error, "unable to load the RelaxNG schema '%s'",
PARSER_ERROR, rng_lang_schema);
PARSER_ERROR_CANNOT_VALIDATE, goto error;
"could not find the RelaxNG schema file");
}
else if (xmlTextReaderRelaxNGValidate (reader, rng_lang_schema))
{
g_set_error (&tmp_error,
PARSER_ERROR,
PARSER_ERROR_CANNOT_VALIDATE,
"unable to load the RelaxNG schema '%s'",
rng_lang_schema);
}
} }
parser_state = parser_state_new (language, engine, parser_state = parser_state_new (language, engine,
defined_regexes, styles, defined_regexes, styles,
reader, loaded_lang_ids); reader, loaded_lang_ids);
xmlTextReaderSetErrorHandler (reader,
(xmlTextReaderErrorFunc) text_reader_error_func,
&tmp_error);
while (!tmp_error && (ret = xmlTextReaderRead (parser_state->reader)) == 1) while (!tmp_error && (ret = xmlTextReaderRead (parser_state->reader)) == 1)
{ {
int type; int type;
if (!xmlTextReaderIsValid (parser_state->reader)) /* FIXME: is xmlTextReaderIsValid call needed here or
{ * error func will be called? */
/* TODO: get the error message from the
* xml parser */
g_set_error (&tmp_error,
PARSER_ERROR,
PARSER_ERROR_INVALID_DOC,
"invalid language file");
}
if (tmp_error) if (tmp_error)
break; break;
@ -1717,12 +1726,13 @@ file_parse (gchar *filename,
parser_state_destroy (parser_state); parser_state_destroy (parser_state);
if (tmp_error) if (tmp_error)
{ goto error;
g_propagate_error (error, tmp_error);
return FALSE;
}
return TRUE; return TRUE;
error:
g_propagate_error (error, tmp_error);
return FALSE;
} }
static ParserState * static ParserState *