Removed GError* member from ParserState; better error message when encountered an error in a referenced lang file; get error messages from xml parser
parent
d86c65ac43
commit
f47ee58476
|
@ -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 *
|
||||||
|
|
Loading…
Reference in New Issue