static void parse_language_with_id (ParserState *parser_state, gchar *lang_id) { GtkSourceLanguageManager *lm; GtkSourceLanguage *imported_language; g_return_if_fail (parser_state->error == NULL); lm = _gtk_source_language_get_language_manager (parser_state->language); imported_language = gtk_source_language_manager_get_language (lm, lang_id); if (imported_language == NULL) { g_set_error (&parser_state->error, PARSER_ERROR, PARSER_ERROR_WRONG_ID, "unable to resolve language '%s'", lang_id); } else { file_parse (imported_language->priv->lang_file_name, parser_state->language, parser_state->ctx_data, parser_state->defined_regexes, parser_state->styles_mapping, parser_state->loaded_lang_ids, parser_state->replacements, &parser_state->error); } }
void _gtk_source_language_define_language_styles (GtkSourceLanguage *lang) { static const gchar *alias[][2] = { {"Base-N Integer", "def:base-n-integer"}, {"Character", "def:character"}, {"Comment", "def:comment"}, {"Function", "def:function"}, {"Decimal", "def:decimal"}, {"Floating Point", "def:floating-point"}, {"Keyword", "def:keyword"}, {"Preprocessor", "def:preprocessor"}, {"String", "def:string"}, {"Specials", "def:specials"}, {"Data Type", "def:type"}, {NULL, NULL}}; gint i = 0; GtkSourceLanguageManager *lm; GtkSourceLanguage *def_lang; while (alias[i][0] != NULL) { GtkSourceStyleInfo *info; info = _gtk_source_style_info_new (alias[i][0], alias[i][1]); g_hash_table_insert (lang->priv->styles, g_strdup (alias[i][0]), info); ++i; } /* We translate String to def:string, but def:string is mapped-to * def:constant in def.lang, so we got to take style mappings from def.lang */ lm = _gtk_source_language_get_language_manager (lang); def_lang = gtk_source_language_manager_get_language (lm, "def"); if (def_lang != NULL) { force_styles (def_lang); g_hash_table_foreach (def_lang->priv->styles, (GHFunc) copy_style_info, lang->priv->styles); } }
static gboolean add_ref (ParserState *parser_state, const gchar *ref, GtkSourceContextRefOptions options, const gchar *style, GError **error) { gboolean all = FALSE; gchar *ref_id; gchar *lang_id = NULL; GError *tmp_error = NULL; /* Return if an error is already set */ g_return_val_if_fail (error == NULL || *error == NULL, FALSE); if (id_is_decorated (ref, &lang_id)) { if (!lang_id_is_already_loaded (parser_state, lang_id)) { GtkSourceLanguageManager *lm; GtkSourceLanguage *imported_language; lm = _gtk_source_language_get_language_manager (parser_state->language); imported_language = gtk_source_language_manager_get_language (lm, lang_id); if (imported_language == NULL) { g_set_error (&tmp_error, PARSER_ERROR, PARSER_ERROR_WRONG_ID, "unable to resolve language '%s' in ref '%s'", lang_id, ref); } else { file_parse (imported_language->priv->lang_file_name, parser_state->language, parser_state->ctx_data, parser_state->defined_regexes, parser_state->styles_mapping, parser_state->loaded_lang_ids, parser_state->replacements, &tmp_error); if (tmp_error != NULL) { 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); } else { ref_id = decorate_id (parser_state, ref); } if (tmp_error == NULL && parser_state->ctx_data != NULL) { if (g_str_has_suffix (ref, ":*")) { all = TRUE; ref_id [strlen (ref_id) - 2] = '\0'; } if (all && (options & (GTK_SOURCE_CONTEXT_IGNORE_STYLE | GTK_SOURCE_CONTEXT_OVERRIDE_STYLE))) { g_set_error (&tmp_error, PARSER_ERROR, PARSER_ERROR_WRONG_STYLE, "style override used with wildcard context reference" " in language '%s' in ref '%s'", lang_id != NULL ? lang_id : parser_state->current_lang_id, ref); } } if (tmp_error == NULL && parser_state->ctx_data != NULL) { gchar *container_id; container_id = g_queue_peek_head (parser_state->curr_parents); /* If the document is validated container_id is never NULL */ g_assert (container_id); _gtk_source_context_data_add_ref (parser_state->ctx_data, container_id, ref_id, options, style, all, &tmp_error); DEBUG (g_message ("appended %s in %s", ref_id, container_id)); } g_free (lang_id); g_free (ref_id); if (tmp_error != NULL) { g_propagate_error (error, tmp_error); return FALSE; } return TRUE; }
static gboolean file_parse (gchar *filename, GtkSourceLanguage *language, GtkSourceContextData *ctx_data, GHashTable *defined_regexes, GHashTable *styles, GHashTable *loaded_lang_ids, GQueue *replacements, GError **error) { ParserState *parser_state; xmlTextReader *reader = NULL; int fd = -1; GError *tmp_error = NULL; GtkSourceLanguageManager *lm; const gchar *rng_lang_schema; g_return_val_if_fail (error == NULL || *error == NULL, FALSE); DEBUG (g_message ("loading file '%s'", filename)); /* * Use fd instead of filename so that it's utf8 safe on w32. */ fd = g_open (filename, O_RDONLY, 0); if (fd != -1) reader = xmlReaderForFd (fd, filename, NULL, 0); if (reader == NULL) { g_set_error (&tmp_error, PARSER_ERROR, PARSER_ERROR_CANNOT_OPEN, "unable to open the file"); goto error; } lm = _gtk_source_language_get_language_manager (language); rng_lang_schema = _gtk_source_language_manager_get_rng_file (lm); if (rng_lang_schema == NULL) { g_set_error (&tmp_error, PARSER_ERROR, PARSER_ERROR_CANNOT_VALIDATE, "could not find the RelaxNG schema file"); goto error; } 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); goto error; } parser_state = parser_state_new (language, ctx_data, defined_regexes, styles, replacements, reader, filename, loaded_lang_ids); xmlTextReaderSetStructuredErrorHandler (reader, (xmlStructuredErrorFunc) text_reader_structured_error_func, parser_state); while ((parser_state->error == NULL) && (1 == xmlTextReaderRead (parser_state->reader))) { int type; /* FIXME: does xmlTextReaderRead already do it? */ xmlTextReaderIsValid (parser_state->reader); if (parser_state->error != NULL) break; type = xmlTextReaderNodeType (parser_state->reader); switch (type) { case XML_READER_TYPE_ELEMENT: element_start (parser_state); break; case XML_READER_TYPE_END_ELEMENT: element_end (parser_state); break; } } if (parser_state->error != NULL) { g_propagate_error (&tmp_error, parser_state->error); parser_state->error = NULL; } parser_state_destroy (parser_state); if (tmp_error != NULL) goto error; close (fd); return TRUE; error: if (fd != -1) close (fd); g_propagate_error (error, tmp_error); return FALSE; }