|
Packit |
a7d494 |
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8; coding: utf-8 -*-
|
|
Packit |
a7d494 |
* gtksourcelanguage-parser-ver1.c
|
|
Packit |
a7d494 |
* Language specification parser for 1.0 version .lang files
|
|
Packit |
a7d494 |
* This file is part of GtkSourceView
|
|
Packit |
a7d494 |
*
|
|
Packit |
a7d494 |
* Copyright (C) 2003 - Paolo Maggi <paolo.maggi@polito.it>
|
|
Packit |
a7d494 |
*
|
|
Packit |
a7d494 |
* GtkSourceView is free software; you can redistribute it and/or
|
|
Packit |
a7d494 |
* modify it under the terms of the GNU Lesser General Public
|
|
Packit |
a7d494 |
* License as published by the Free Software Foundation; either
|
|
Packit |
a7d494 |
* version 2.1 of the License, or (at your option) any later version.
|
|
Packit |
a7d494 |
*
|
|
Packit |
a7d494 |
* GtkSourceView is distributed in the hope that it will be useful,
|
|
Packit |
a7d494 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit |
a7d494 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Packit |
a7d494 |
* Lesser General Public License for more details.
|
|
Packit |
a7d494 |
*
|
|
Packit |
a7d494 |
* You should have received a copy of the GNU Lesser General Public
|
|
Packit |
a7d494 |
* License along with this library; if not, write to the Free Software
|
|
Packit |
a7d494 |
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
Packit |
a7d494 |
*/
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
#ifdef HAVE_CONFIG_H
|
|
Packit |
a7d494 |
#include <config.h>
|
|
Packit |
a7d494 |
#endif
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
#include <string.h>
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
#include <libxml/parser.h>
|
|
Packit |
a7d494 |
#include "gtksourceview-i18n.h"
|
|
Packit |
a7d494 |
#include "gtksourcebuffer.h"
|
|
Packit |
a7d494 |
#include "gtksourcelanguage.h"
|
|
Packit |
a7d494 |
#include "gtksourcelanguage-private.h"
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
static gchar *
|
|
Packit |
a7d494 |
fix_pattern (const gchar *pattern,
|
|
Packit |
a7d494 |
gboolean *end_at_line_end)
|
|
Packit |
a7d494 |
{
|
|
Packit |
a7d494 |
char *slash;
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
if (pattern == NULL)
|
|
Packit |
a7d494 |
return NULL;
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
slash = strchr (pattern, '/');
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
if (slash != NULL)
|
|
Packit |
a7d494 |
{
|
|
Packit |
a7d494 |
GString *str;
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
str = g_string_new_len (pattern, slash - pattern);
|
|
Packit |
a7d494 |
g_string_append (str, "\\/");
|
|
Packit |
a7d494 |
pattern = slash + 1;
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
while ((slash = strchr (pattern, '/')) != NULL)
|
|
Packit |
a7d494 |
{
|
|
Packit |
a7d494 |
g_string_append_len (str, pattern, slash - pattern);
|
|
Packit |
a7d494 |
g_string_append (str, "\\/");
|
|
Packit |
a7d494 |
pattern = slash + 1;
|
|
Packit |
a7d494 |
}
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
if (g_str_has_suffix (pattern, "\\n"))
|
|
Packit |
a7d494 |
g_string_append_len (str, pattern, strlen(pattern) - 2);
|
|
Packit |
a7d494 |
else
|
|
Packit |
a7d494 |
g_string_append (str, pattern);
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
return g_string_free (str, FALSE);
|
|
Packit |
a7d494 |
}
|
|
Packit |
a7d494 |
else if (g_str_has_suffix (pattern, "\\n"))
|
|
Packit |
a7d494 |
{
|
|
Packit |
a7d494 |
if (end_at_line_end)
|
|
Packit |
a7d494 |
*end_at_line_end = TRUE;
|
|
Packit |
a7d494 |
return g_strndup (pattern, strlen (pattern) - 2);
|
|
Packit |
a7d494 |
}
|
|
Packit |
a7d494 |
else
|
|
Packit |
a7d494 |
{
|
|
Packit |
a7d494 |
return g_strdup (pattern);
|
|
Packit |
a7d494 |
}
|
|
Packit |
a7d494 |
}
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
static gboolean
|
|
Packit |
a7d494 |
ctx_data_add_simple_pattern (GtkSourceContextData *ctx_data,
|
|
Packit |
a7d494 |
GtkSourceLanguage *language,
|
|
Packit |
a7d494 |
const gchar *id,
|
|
Packit |
a7d494 |
const gchar *style,
|
|
Packit |
a7d494 |
const gchar *pattern)
|
|
Packit |
a7d494 |
{
|
|
Packit |
a7d494 |
gboolean result;
|
|
Packit |
a7d494 |
gchar *real_id, *root_id, *fixed;
|
|
Packit |
a7d494 |
GError *error = NULL;
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
g_return_val_if_fail (id != NULL, FALSE);
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
root_id = g_strdup_printf ("%s:%s", language->priv->id, language->priv->id);
|
|
Packit |
a7d494 |
real_id = g_strdup_printf ("%s:%s", language->priv->id, id);
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
fixed = fix_pattern (pattern, NULL);
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
result = _gtk_source_context_data_define_context (ctx_data, real_id,
|
|
Packit |
a7d494 |
root_id,
|
|
Packit |
a7d494 |
fixed, NULL, NULL,
|
|
Packit |
a7d494 |
style, NULL,
|
|
Packit |
a7d494 |
GTK_SOURCE_CONTEXT_EXTEND_PARENT |
|
|
Packit |
a7d494 |
GTK_SOURCE_CONTEXT_END_AT_LINE_END,
|
|
Packit |
a7d494 |
&error);
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
if (error != NULL)
|
|
Packit |
a7d494 |
{
|
|
Packit |
a7d494 |
g_warning ("%s", error->message);
|
|
Packit |
a7d494 |
g_error_free (error);
|
|
Packit |
a7d494 |
}
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
g_free (fixed);
|
|
Packit |
a7d494 |
g_free (real_id);
|
|
Packit |
a7d494 |
g_free (root_id);
|
|
Packit |
a7d494 |
return result;
|
|
Packit |
a7d494 |
}
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
static gboolean
|
|
Packit |
a7d494 |
ctx_data_add_syntax_pattern (GtkSourceContextData *ctx_data,
|
|
Packit |
a7d494 |
GtkSourceLanguage *language,
|
|
Packit |
a7d494 |
const gchar *id,
|
|
Packit |
a7d494 |
const gchar *style,
|
|
Packit |
a7d494 |
const gchar *pattern_start,
|
|
Packit |
a7d494 |
const gchar *pattern_end,
|
|
Packit |
a7d494 |
gboolean end_at_line_end)
|
|
Packit |
a7d494 |
{
|
|
Packit |
a7d494 |
gboolean result;
|
|
Packit |
a7d494 |
gchar *real_id, *root_id;
|
|
Packit |
a7d494 |
gchar *fixed_start, *fixed_end;
|
|
Packit |
a7d494 |
GError *error = NULL;
|
|
Packit |
a7d494 |
GtkSourceContextFlags flags = GTK_SOURCE_CONTEXT_EXTEND_PARENT;
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
g_return_val_if_fail (id != NULL, FALSE);
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
root_id = g_strdup_printf ("%s:%s", language->priv->id, language->priv->id);
|
|
Packit |
a7d494 |
real_id = g_strdup_printf ("%s:%s", language->priv->id, id);
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
fixed_start = fix_pattern (pattern_start, &end_at_line_end);
|
|
Packit |
a7d494 |
fixed_end = fix_pattern (pattern_end, &end_at_line_end);
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
if (end_at_line_end)
|
|
Packit |
a7d494 |
flags |= GTK_SOURCE_CONTEXT_END_AT_LINE_END;
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
result = _gtk_source_context_data_define_context (ctx_data, real_id, root_id,
|
|
Packit |
a7d494 |
NULL,
|
|
Packit |
a7d494 |
pattern_start,
|
|
Packit |
a7d494 |
pattern_end,
|
|
Packit |
a7d494 |
style,
|
|
Packit |
a7d494 |
NULL,
|
|
Packit |
a7d494 |
flags,
|
|
Packit |
a7d494 |
&error);
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
if (error != NULL)
|
|
Packit |
a7d494 |
{
|
|
Packit |
a7d494 |
g_warning ("%s", error->message);
|
|
Packit |
a7d494 |
g_error_free (error);
|
|
Packit |
a7d494 |
}
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
g_free (real_id);
|
|
Packit |
a7d494 |
g_free (root_id);
|
|
Packit |
a7d494 |
g_free (fixed_start);
|
|
Packit |
a7d494 |
g_free (fixed_end);
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
return result;
|
|
Packit |
a7d494 |
}
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
static gchar *
|
|
Packit |
a7d494 |
build_keyword_list (const GSList *keywords,
|
|
Packit |
a7d494 |
gboolean case_sensitive,
|
|
Packit |
a7d494 |
gboolean match_empty_string_at_beginning,
|
|
Packit |
a7d494 |
gboolean match_empty_string_at_end,
|
|
Packit |
a7d494 |
const gchar *beginning_regex,
|
|
Packit |
a7d494 |
const gchar *end_regex)
|
|
Packit |
a7d494 |
{
|
|
Packit |
a7d494 |
GString *str;
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
g_return_val_if_fail (keywords != NULL, NULL);
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
str = g_string_new ("");
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
if (keywords != NULL)
|
|
Packit |
a7d494 |
{
|
|
Packit |
a7d494 |
if (match_empty_string_at_beginning)
|
|
Packit |
a7d494 |
g_string_append (str, "\\b");
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
if (beginning_regex != NULL)
|
|
Packit |
a7d494 |
g_string_append (str, beginning_regex);
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
if (case_sensitive)
|
|
Packit |
a7d494 |
g_string_append (str, "(?:");
|
|
Packit |
a7d494 |
else
|
|
Packit |
a7d494 |
g_string_append (str, "(?i:");
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
/* TODO Make sure pcre can handle big lists, and split lists if necessary.
|
|
Packit |
a7d494 |
* See #110991 */
|
|
Packit |
a7d494 |
while (keywords != NULL)
|
|
Packit |
a7d494 |
{
|
|
Packit |
a7d494 |
g_string_append (str, (gchar*) keywords->data);
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
keywords = g_slist_next (keywords);
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
if (keywords != NULL)
|
|
Packit |
a7d494 |
g_string_append (str, "|");
|
|
Packit |
a7d494 |
}
|
|
Packit |
a7d494 |
g_string_append (str, ")");
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
if (end_regex != NULL)
|
|
Packit |
a7d494 |
g_string_append (str, end_regex);
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
if (match_empty_string_at_end)
|
|
Packit |
a7d494 |
g_string_append (str, "\\b");
|
|
Packit |
a7d494 |
}
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
return g_string_free (str, FALSE);
|
|
Packit |
a7d494 |
}
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
static void
|
|
Packit |
a7d494 |
parseLineComment (xmlNodePtr cur,
|
|
Packit |
a7d494 |
gchar *id,
|
|
Packit |
a7d494 |
xmlChar *style,
|
|
Packit |
a7d494 |
GtkSourceContextData *ctx_data,
|
|
Packit |
a7d494 |
GtkSourceLanguage *language)
|
|
Packit |
a7d494 |
{
|
|
Packit |
a7d494 |
xmlNodePtr child;
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
child = cur->xmlChildrenNode;
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
if ((child != NULL) && !xmlStrcmp (child->name, (const xmlChar *)"start-regex"))
|
|
Packit |
a7d494 |
{
|
|
Packit |
a7d494 |
xmlChar *start_regex;
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
start_regex = xmlNodeListGetString (child->doc, child->xmlChildrenNode, 1);
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
ctx_data_add_syntax_pattern (ctx_data, language, id,
|
|
Packit |
a7d494 |
(gchar*) style,
|
|
Packit |
a7d494 |
(gchar*) start_regex,
|
|
Packit |
a7d494 |
NULL, TRUE);
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
xmlFree (start_regex);
|
|
Packit |
a7d494 |
}
|
|
Packit |
a7d494 |
else
|
|
Packit |
a7d494 |
{
|
|
Packit |
a7d494 |
g_warning ("Missing start-regex in tag 'line-comment' (%s, line %ld)",
|
|
Packit |
a7d494 |
child->doc->name, xmlGetLineNo (child));
|
|
Packit |
a7d494 |
}
|
|
Packit |
a7d494 |
}
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
static void
|
|
Packit |
a7d494 |
parseBlockComment (xmlNodePtr cur,
|
|
Packit |
a7d494 |
gchar *id,
|
|
Packit |
a7d494 |
xmlChar *style,
|
|
Packit |
a7d494 |
GtkSourceContextData *ctx_data,
|
|
Packit |
a7d494 |
GtkSourceLanguage *language)
|
|
Packit |
a7d494 |
{
|
|
Packit |
a7d494 |
xmlChar *start_regex = NULL;
|
|
Packit |
a7d494 |
xmlChar *end_regex = NULL;
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
xmlNodePtr child;
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
child = cur->xmlChildrenNode;
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
while (child != NULL)
|
|
Packit |
a7d494 |
{
|
|
Packit |
a7d494 |
if (!xmlStrcmp (child->name, (const xmlChar *)"start-regex"))
|
|
Packit |
a7d494 |
{
|
|
Packit |
a7d494 |
start_regex = xmlNodeListGetString (child->doc, child->xmlChildrenNode, 1);
|
|
Packit |
a7d494 |
}
|
|
Packit |
a7d494 |
else
|
|
Packit |
a7d494 |
if (!xmlStrcmp (child->name, (const xmlChar *)"end-regex"))
|
|
Packit |
a7d494 |
{
|
|
Packit |
a7d494 |
end_regex = xmlNodeListGetString (child->doc, child->xmlChildrenNode, 1);
|
|
Packit |
a7d494 |
}
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
child = child->next;
|
|
Packit |
a7d494 |
}
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
if (start_regex == NULL)
|
|
Packit |
a7d494 |
{
|
|
Packit |
a7d494 |
g_warning ("Missing start-regex in tag 'block-comment' (%s, line %ld)",
|
|
Packit |
a7d494 |
child->doc->name, xmlGetLineNo (cur));
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
return;
|
|
Packit |
a7d494 |
}
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
if (end_regex == NULL)
|
|
Packit |
a7d494 |
{
|
|
Packit |
a7d494 |
xmlFree (start_regex);
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
g_warning ("Missing end-regex in tag 'block-comment' (%s, line %ld)",
|
|
Packit |
a7d494 |
child->doc->name, xmlGetLineNo (cur));
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
return;
|
|
Packit |
a7d494 |
}
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
ctx_data_add_syntax_pattern (ctx_data, language, id,
|
|
Packit |
a7d494 |
(gchar*) style,
|
|
Packit |
a7d494 |
(gchar*) start_regex,
|
|
Packit |
a7d494 |
(gchar*) end_regex,
|
|
Packit |
a7d494 |
FALSE);
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
xmlFree (start_regex);
|
|
Packit |
a7d494 |
xmlFree (end_regex);
|
|
Packit |
a7d494 |
}
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
static void
|
|
Packit |
a7d494 |
parseString (xmlNodePtr cur,
|
|
Packit |
a7d494 |
gchar *id,
|
|
Packit |
a7d494 |
xmlChar *style,
|
|
Packit |
a7d494 |
GtkSourceContextData *ctx_data,
|
|
Packit |
a7d494 |
GtkSourceLanguage *language)
|
|
Packit |
a7d494 |
{
|
|
Packit |
a7d494 |
xmlChar *start_regex = NULL;
|
|
Packit |
a7d494 |
xmlChar *end_regex = NULL;
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
xmlChar *prop = NULL;
|
|
Packit |
a7d494 |
gboolean end_at_line_end = TRUE;
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
xmlNodePtr child;
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
prop = xmlGetProp (cur, BAD_CAST "end-at-line-end");
|
|
Packit |
a7d494 |
if (prop != NULL)
|
|
Packit |
a7d494 |
{
|
|
Packit |
a7d494 |
if (!xmlStrcasecmp (prop, (const xmlChar *)"TRUE") ||
|
|
Packit |
a7d494 |
!xmlStrcmp (prop, (const xmlChar *)"1"))
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
end_at_line_end = TRUE;
|
|
Packit |
a7d494 |
else
|
|
Packit |
a7d494 |
end_at_line_end = FALSE;
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
xmlFree (prop);
|
|
Packit |
a7d494 |
}
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
child = cur->xmlChildrenNode;
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
while (child != NULL)
|
|
Packit |
a7d494 |
{
|
|
Packit |
a7d494 |
if (!xmlStrcmp (child->name, (const xmlChar *)"start-regex"))
|
|
Packit |
a7d494 |
{
|
|
Packit |
a7d494 |
start_regex = xmlNodeListGetString (child->doc, child->xmlChildrenNode, 1);
|
|
Packit |
a7d494 |
}
|
|
Packit |
a7d494 |
else
|
|
Packit |
a7d494 |
if (!xmlStrcmp (child->name, (const xmlChar *)"end-regex"))
|
|
Packit |
a7d494 |
{
|
|
Packit |
a7d494 |
end_regex = xmlNodeListGetString (child->doc, child->xmlChildrenNode, 1);
|
|
Packit |
a7d494 |
}
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
child = child->next;
|
|
Packit |
a7d494 |
}
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
if (start_regex == NULL)
|
|
Packit |
a7d494 |
{
|
|
Packit |
a7d494 |
g_warning ("Missing start-regex in tag 'string' (%s, line %ld)",
|
|
Packit |
a7d494 |
child->doc->name, xmlGetLineNo (cur));
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
return;
|
|
Packit |
a7d494 |
}
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
if (end_regex == NULL)
|
|
Packit |
a7d494 |
{
|
|
Packit |
a7d494 |
xmlFree (start_regex);
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
g_warning ("Missing end-regex in tag 'string' (%s, line %ld)",
|
|
Packit |
a7d494 |
child->doc->name, xmlGetLineNo (cur));
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
return;
|
|
Packit |
a7d494 |
}
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
ctx_data_add_syntax_pattern (ctx_data, language, id,
|
|
Packit |
a7d494 |
(gchar*) style,
|
|
Packit |
a7d494 |
(gchar*) start_regex,
|
|
Packit |
a7d494 |
(gchar*) end_regex,
|
|
Packit |
a7d494 |
end_at_line_end);
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
xmlFree (start_regex);
|
|
Packit |
a7d494 |
xmlFree (end_regex);
|
|
Packit |
a7d494 |
}
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
static void
|
|
Packit |
a7d494 |
parseKeywordList (xmlNodePtr cur,
|
|
Packit |
a7d494 |
gchar *id,
|
|
Packit |
a7d494 |
xmlChar *style,
|
|
Packit |
a7d494 |
GtkSourceContextData *ctx_data,
|
|
Packit |
a7d494 |
GtkSourceLanguage *language)
|
|
Packit |
a7d494 |
{
|
|
Packit |
a7d494 |
gboolean case_sensitive = TRUE;
|
|
Packit |
a7d494 |
gboolean match_empty_string_at_beginning = TRUE;
|
|
Packit |
a7d494 |
gboolean match_empty_string_at_end = TRUE;
|
|
Packit |
a7d494 |
gchar *beginning_regex = NULL;
|
|
Packit |
a7d494 |
gchar *end_regex = NULL;
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
GSList *list = NULL;
|
|
Packit |
a7d494 |
gchar *regex;
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
xmlChar *prop;
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
xmlNodePtr child;
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
prop = xmlGetProp (cur, BAD_CAST "case-sensitive");
|
|
Packit |
a7d494 |
if (prop != NULL)
|
|
Packit |
a7d494 |
{
|
|
Packit |
a7d494 |
if (!xmlStrcasecmp (prop, (const xmlChar *)"TRUE") ||
|
|
Packit |
a7d494 |
!xmlStrcmp (prop, (const xmlChar *)"1"))
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
case_sensitive = TRUE;
|
|
Packit |
a7d494 |
else
|
|
Packit |
a7d494 |
case_sensitive = FALSE;
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
xmlFree (prop);
|
|
Packit |
a7d494 |
}
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
prop = xmlGetProp (cur, BAD_CAST "match-empty-string-at-beginning");
|
|
Packit |
a7d494 |
if (prop != NULL)
|
|
Packit |
a7d494 |
{
|
|
Packit |
a7d494 |
if (!xmlStrcasecmp (prop, (const xmlChar *)"TRUE") ||
|
|
Packit |
a7d494 |
!xmlStrcmp (prop, (const xmlChar *)"1"))
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
match_empty_string_at_beginning = TRUE;
|
|
Packit |
a7d494 |
else
|
|
Packit |
a7d494 |
match_empty_string_at_beginning = FALSE;
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
xmlFree (prop);
|
|
Packit |
a7d494 |
}
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
prop = xmlGetProp (cur, BAD_CAST "match-empty-string-at-end");
|
|
Packit |
a7d494 |
if (prop != NULL)
|
|
Packit |
a7d494 |
{
|
|
Packit |
a7d494 |
if (!xmlStrcasecmp (prop, (const xmlChar *)"TRUE") ||
|
|
Packit |
a7d494 |
!xmlStrcmp (prop, (const xmlChar *)"1"))
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
match_empty_string_at_end = TRUE;
|
|
Packit |
a7d494 |
else
|
|
Packit |
a7d494 |
match_empty_string_at_end = FALSE;
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
xmlFree (prop);
|
|
Packit |
a7d494 |
}
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
prop = xmlGetProp (cur, BAD_CAST "beginning-regex");
|
|
Packit |
a7d494 |
if (prop != NULL)
|
|
Packit |
a7d494 |
{
|
|
Packit |
a7d494 |
beginning_regex = g_strdup ((gchar *)prop);
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
xmlFree (prop);
|
|
Packit |
a7d494 |
}
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
prop = xmlGetProp (cur, BAD_CAST "end-regex");
|
|
Packit |
a7d494 |
if (prop != NULL)
|
|
Packit |
a7d494 |
{
|
|
Packit |
a7d494 |
end_regex = g_strdup ((gchar *)prop);
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
xmlFree (prop);
|
|
Packit |
a7d494 |
}
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
child = cur->xmlChildrenNode;
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
while (child != NULL)
|
|
Packit |
a7d494 |
{
|
|
Packit |
a7d494 |
if (!xmlStrcmp (child->name, BAD_CAST "keyword"))
|
|
Packit |
a7d494 |
{
|
|
Packit |
a7d494 |
xmlChar *keyword;
|
|
Packit |
a7d494 |
keyword = xmlNodeListGetString (child->doc, child->xmlChildrenNode, 1);
|
|
Packit |
a7d494 |
list = g_slist_prepend (list, keyword);
|
|
Packit |
a7d494 |
}
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
child = child->next;
|
|
Packit |
a7d494 |
}
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
list = g_slist_reverse (list);
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
if (list == NULL)
|
|
Packit |
a7d494 |
{
|
|
Packit |
a7d494 |
g_warning ("No keywords in tag 'keyword-list' (%s, line %ld)",
|
|
Packit |
a7d494 |
child->doc->name, xmlGetLineNo (cur));
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
g_free (beginning_regex),
|
|
Packit |
a7d494 |
g_free (end_regex);
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
return;
|
|
Packit |
a7d494 |
}
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
regex = build_keyword_list (list,
|
|
Packit |
a7d494 |
case_sensitive,
|
|
Packit |
a7d494 |
match_empty_string_at_beginning,
|
|
Packit |
a7d494 |
match_empty_string_at_end,
|
|
Packit |
a7d494 |
beginning_regex,
|
|
Packit |
a7d494 |
end_regex);
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
g_free (beginning_regex),
|
|
Packit |
a7d494 |
g_free (end_regex);
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
g_slist_free_full (list, (GDestroyNotify)xmlFree);
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
ctx_data_add_simple_pattern (ctx_data, language, id, (gchar*) style, regex);
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
g_free (regex);
|
|
Packit |
a7d494 |
}
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
static void
|
|
Packit |
a7d494 |
parsePatternItem (xmlNodePtr cur,
|
|
Packit |
a7d494 |
gchar *id,
|
|
Packit |
a7d494 |
xmlChar *style,
|
|
Packit |
a7d494 |
GtkSourceContextData *ctx_data,
|
|
Packit |
a7d494 |
GtkSourceLanguage *language)
|
|
Packit |
a7d494 |
{
|
|
Packit |
a7d494 |
xmlNodePtr child;
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
child = cur->xmlChildrenNode;
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
if ((child != NULL) && !xmlStrcmp (child->name, (const xmlChar *)"regex"))
|
|
Packit |
a7d494 |
{
|
|
Packit |
a7d494 |
xmlChar *regex;
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
regex = xmlNodeListGetString (child->doc, child->xmlChildrenNode, 1);
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
ctx_data_add_simple_pattern (ctx_data, language, id,
|
|
Packit |
a7d494 |
(gchar*) style,
|
|
Packit |
a7d494 |
(gchar*) regex);
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
xmlFree (regex);
|
|
Packit |
a7d494 |
}
|
|
Packit |
a7d494 |
else
|
|
Packit |
a7d494 |
{
|
|
Packit |
a7d494 |
g_warning ("Missing regex in tag 'pattern-item' (%s, line %ld)",
|
|
Packit |
a7d494 |
child->doc->name, xmlGetLineNo (child));
|
|
Packit |
a7d494 |
}
|
|
Packit |
a7d494 |
}
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
static void
|
|
Packit |
a7d494 |
parseSyntaxItem (xmlNodePtr cur,
|
|
Packit |
a7d494 |
const gchar *id,
|
|
Packit |
a7d494 |
xmlChar *style,
|
|
Packit |
a7d494 |
GtkSourceContextData *ctx_data,
|
|
Packit |
a7d494 |
GtkSourceLanguage *language)
|
|
Packit |
a7d494 |
{
|
|
Packit |
a7d494 |
xmlChar *start_regex = NULL;
|
|
Packit |
a7d494 |
xmlChar *end_regex = NULL;
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
xmlNodePtr child;
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
child = cur->xmlChildrenNode;
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
while (child != NULL)
|
|
Packit |
a7d494 |
{
|
|
Packit |
a7d494 |
if (!xmlStrcmp (child->name, (const xmlChar *)"start-regex"))
|
|
Packit |
a7d494 |
{
|
|
Packit |
a7d494 |
start_regex = xmlNodeListGetString (child->doc, child->xmlChildrenNode, 1);
|
|
Packit |
a7d494 |
}
|
|
Packit |
a7d494 |
else
|
|
Packit |
a7d494 |
if (!xmlStrcmp (child->name, (const xmlChar *)"end-regex"))
|
|
Packit |
a7d494 |
{
|
|
Packit |
a7d494 |
end_regex = xmlNodeListGetString (child->doc, child->xmlChildrenNode, 1);
|
|
Packit |
a7d494 |
}
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
child = child->next;
|
|
Packit |
a7d494 |
}
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
if (start_regex == NULL)
|
|
Packit |
a7d494 |
{
|
|
Packit |
a7d494 |
g_warning ("Missing start-regex in tag 'syntax-item' (%s, line %ld)",
|
|
Packit |
a7d494 |
child->doc->name, xmlGetLineNo (cur));
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
return;
|
|
Packit |
a7d494 |
}
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
if (end_regex == NULL)
|
|
Packit |
a7d494 |
{
|
|
Packit |
a7d494 |
xmlFree (start_regex);
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
g_warning ("Missing end-regex in tag 'syntax-item' (%s, line %ld)",
|
|
Packit |
a7d494 |
child->doc->name, xmlGetLineNo (cur));
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
return;
|
|
Packit |
a7d494 |
}
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
ctx_data_add_syntax_pattern (ctx_data, language, id,
|
|
Packit |
a7d494 |
(gchar*) style,
|
|
Packit |
a7d494 |
(gchar*) start_regex,
|
|
Packit |
a7d494 |
(gchar*) end_regex,
|
|
Packit |
a7d494 |
FALSE);
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
xmlFree (start_regex);
|
|
Packit |
a7d494 |
xmlFree (end_regex);
|
|
Packit |
a7d494 |
}
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
static void
|
|
Packit |
a7d494 |
parseTag (GtkSourceLanguage *language,
|
|
Packit |
a7d494 |
xmlNodePtr cur,
|
|
Packit |
a7d494 |
GtkSourceContextData *ctx_data)
|
|
Packit |
a7d494 |
{
|
|
Packit |
a7d494 |
xmlChar *name;
|
|
Packit |
a7d494 |
xmlChar *style;
|
|
Packit |
a7d494 |
xmlChar *id;
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
name = xmlGetProp (cur, BAD_CAST "_name");
|
|
Packit |
a7d494 |
if (name == NULL)
|
|
Packit |
a7d494 |
{
|
|
Packit |
a7d494 |
name = xmlGetProp (cur, BAD_CAST "name");
|
|
Packit |
a7d494 |
id = xmlStrdup (name);
|
|
Packit |
a7d494 |
}
|
|
Packit |
a7d494 |
else
|
|
Packit |
a7d494 |
{
|
|
Packit |
a7d494 |
gchar *tmp1 = _gtk_source_language_translate_string (language, (gchar*) name);
|
|
Packit |
a7d494 |
xmlChar *tmp2 = xmlStrdup (BAD_CAST tmp1);
|
|
Packit |
a7d494 |
id = name;
|
|
Packit |
a7d494 |
name = tmp2;
|
|
Packit |
a7d494 |
g_free (tmp1);
|
|
Packit |
a7d494 |
}
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
if (name == NULL)
|
|
Packit |
a7d494 |
{
|
|
Packit |
a7d494 |
return;
|
|
Packit |
a7d494 |
}
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
style = xmlGetProp (cur, BAD_CAST "style");
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
if (!xmlStrcmp (cur->name, (const xmlChar*) "line-comment"))
|
|
Packit |
a7d494 |
{
|
|
Packit |
a7d494 |
parseLineComment (cur, (gchar*) id, style, ctx_data, language);
|
|
Packit |
a7d494 |
}
|
|
Packit |
a7d494 |
else if (!xmlStrcmp (cur->name, (const xmlChar*) "block-comment"))
|
|
Packit |
a7d494 |
{
|
|
Packit |
a7d494 |
parseBlockComment (cur, (gchar*) id, style, ctx_data, language);
|
|
Packit |
a7d494 |
}
|
|
Packit |
a7d494 |
else if (!xmlStrcmp (cur->name, (const xmlChar*) "string"))
|
|
Packit |
a7d494 |
{
|
|
Packit |
a7d494 |
parseString (cur, (gchar*) id, style, ctx_data, language);
|
|
Packit |
a7d494 |
}
|
|
Packit |
a7d494 |
else if (!xmlStrcmp (cur->name, (const xmlChar*) "keyword-list"))
|
|
Packit |
a7d494 |
{
|
|
Packit |
a7d494 |
parseKeywordList (cur, (gchar*) id, style, ctx_data, language);
|
|
Packit |
a7d494 |
}
|
|
Packit |
a7d494 |
else if (!xmlStrcmp (cur->name, (const xmlChar*) "pattern-item"))
|
|
Packit |
a7d494 |
{
|
|
Packit |
a7d494 |
parsePatternItem (cur, (gchar*) id, style, ctx_data, language);
|
|
Packit |
a7d494 |
}
|
|
Packit |
a7d494 |
else if (!xmlStrcmp (cur->name, (const xmlChar*) "syntax-item"))
|
|
Packit |
a7d494 |
{
|
|
Packit |
a7d494 |
parseSyntaxItem (cur, (gchar*) id, style, ctx_data, language);
|
|
Packit |
a7d494 |
}
|
|
Packit |
a7d494 |
else
|
|
Packit |
a7d494 |
{
|
|
Packit |
a7d494 |
g_print ("Unknown tag: %s\n", cur->name);
|
|
Packit |
a7d494 |
}
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
xmlFree (name);
|
|
Packit |
a7d494 |
xmlFree (style);
|
|
Packit |
a7d494 |
xmlFree (id);
|
|
Packit |
a7d494 |
}
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
static gboolean
|
|
Packit |
a7d494 |
define_root_context (GtkSourceContextData *ctx_data,
|
|
Packit |
a7d494 |
GtkSourceLanguage *language)
|
|
Packit |
a7d494 |
{
|
|
Packit |
a7d494 |
gboolean result;
|
|
Packit |
a7d494 |
gchar *id;
|
|
Packit |
a7d494 |
GError *error = NULL;
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
g_return_val_if_fail (language->priv->id != NULL, FALSE);
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
id = g_strdup_printf ("%s:%s", language->priv->id, language->priv->id);
|
|
Packit |
a7d494 |
result = _gtk_source_context_data_define_context (ctx_data, id,
|
|
Packit |
a7d494 |
NULL, NULL, NULL, NULL,
|
|
Packit |
a7d494 |
NULL, NULL,
|
|
Packit |
a7d494 |
GTK_SOURCE_CONTEXT_EXTEND_PARENT,
|
|
Packit |
a7d494 |
&error);
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
if (error != NULL)
|
|
Packit |
a7d494 |
{
|
|
Packit |
a7d494 |
g_warning ("%s", error->message);
|
|
Packit |
a7d494 |
g_error_free (error);
|
|
Packit |
a7d494 |
}
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
g_free (id);
|
|
Packit |
a7d494 |
return result;
|
|
Packit |
a7d494 |
}
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
gboolean
|
|
Packit |
a7d494 |
_gtk_source_language_file_parse_version1 (GtkSourceLanguage *language,
|
|
Packit |
a7d494 |
GtkSourceContextData *ctx_data)
|
|
Packit |
a7d494 |
{
|
|
Packit |
a7d494 |
xmlDocPtr doc;
|
|
Packit |
a7d494 |
xmlNodePtr cur;
|
|
Packit |
a7d494 |
GMappedFile *mf;
|
|
Packit |
a7d494 |
gunichar esc_char = 0;
|
|
Packit |
a7d494 |
xmlChar *lang_version = NULL;
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
xmlKeepBlanksDefault (0);
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
mf = g_mapped_file_new (language->priv->lang_file_name, FALSE, NULL);
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
if (mf == NULL)
|
|
Packit |
a7d494 |
{
|
|
Packit |
a7d494 |
doc = NULL;
|
|
Packit |
a7d494 |
}
|
|
Packit |
a7d494 |
else
|
|
Packit |
a7d494 |
{
|
|
Packit |
a7d494 |
doc = xmlParseMemory (g_mapped_file_get_contents (mf),
|
|
Packit |
a7d494 |
g_mapped_file_get_length (mf));
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
g_mapped_file_unref (mf);
|
|
Packit |
a7d494 |
}
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
if (doc == NULL)
|
|
Packit |
a7d494 |
{
|
|
Packit |
a7d494 |
g_warning ("Impossible to parse file '%s'",
|
|
Packit |
a7d494 |
language->priv->lang_file_name);
|
|
Packit |
a7d494 |
return FALSE;
|
|
Packit |
a7d494 |
}
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
cur = xmlDocGetRootElement (doc);
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
if (cur == NULL)
|
|
Packit |
a7d494 |
{
|
|
Packit |
a7d494 |
g_warning ("The lang file '%s' is empty",
|
|
Packit |
a7d494 |
language->priv->lang_file_name);
|
|
Packit |
a7d494 |
goto error;
|
|
Packit |
a7d494 |
}
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
if (xmlStrcmp (cur->name, (const xmlChar *) "language") != 0)
|
|
Packit |
a7d494 |
{
|
|
Packit |
a7d494 |
g_warning ("File '%s' is of the wrong type",
|
|
Packit |
a7d494 |
language->priv->lang_file_name);
|
|
Packit |
a7d494 |
goto error;
|
|
Packit |
a7d494 |
}
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
lang_version = xmlGetProp (cur, BAD_CAST "version");
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
if (lang_version == NULL || strcmp ("1.0", (char*) lang_version) != 0)
|
|
Packit |
a7d494 |
{
|
|
Packit |
a7d494 |
if (lang_version != NULL)
|
|
Packit |
a7d494 |
g_warning ("Wrong language version '%s' in file '%s', expected '%s'",
|
|
Packit |
a7d494 |
(char*) lang_version, language->priv->lang_file_name, "1.0");
|
|
Packit |
a7d494 |
else
|
|
Packit |
a7d494 |
g_warning ("Language version missing in file '%s'",
|
|
Packit |
a7d494 |
language->priv->lang_file_name);
|
|
Packit |
a7d494 |
goto error;
|
|
Packit |
a7d494 |
}
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
if (!define_root_context (ctx_data, language))
|
|
Packit |
a7d494 |
{
|
|
Packit |
a7d494 |
g_warning ("Could not create root context for file '%s'",
|
|
Packit |
a7d494 |
language->priv->lang_file_name);
|
|
Packit |
a7d494 |
goto error;
|
|
Packit |
a7d494 |
}
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
/* FIXME: check that the language name, version, etc. are the
|
|
Packit |
a7d494 |
* right ones - Paolo */
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
cur = xmlDocGetRootElement (doc);
|
|
Packit |
a7d494 |
cur = cur->xmlChildrenNode;
|
|
Packit |
a7d494 |
g_return_val_if_fail (cur != NULL, FALSE);
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
while (cur != NULL)
|
|
Packit |
a7d494 |
{
|
|
Packit |
a7d494 |
if (!xmlStrcmp (cur->name, (const xmlChar *)"escape-char"))
|
|
Packit |
a7d494 |
{
|
|
Packit |
a7d494 |
xmlChar *escape;
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
escape = xmlNodeListGetString (doc, cur->xmlChildrenNode, 1);
|
|
Packit |
a7d494 |
esc_char = g_utf8_get_char_validated ((gchar*) escape, -1);
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
if (esc_char == (gunichar) -1 || esc_char == (gunichar) -2)
|
|
Packit |
a7d494 |
{
|
|
Packit |
a7d494 |
g_warning ("Invalid (non UTF8) escape character in file '%s'",
|
|
Packit |
a7d494 |
language->priv->lang_file_name);
|
|
Packit |
a7d494 |
esc_char = 0;
|
|
Packit |
a7d494 |
}
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
xmlFree (escape);
|
|
Packit |
a7d494 |
}
|
|
Packit |
a7d494 |
else
|
|
Packit |
a7d494 |
{
|
|
Packit |
a7d494 |
parseTag (language, cur, ctx_data);
|
|
Packit |
a7d494 |
}
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
cur = cur->next;
|
|
Packit |
a7d494 |
}
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
if (esc_char != 0)
|
|
Packit |
a7d494 |
_gtk_source_context_data_set_escape_char (ctx_data, esc_char);
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
_gtk_source_context_data_finish_parse (ctx_data, NULL, NULL);
|
|
Packit |
a7d494 |
_gtk_source_language_define_language_styles (language);
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
xmlFreeDoc (doc);
|
|
Packit |
a7d494 |
xmlFree (lang_version);
|
|
Packit |
a7d494 |
return TRUE;
|
|
Packit |
a7d494 |
|
|
Packit |
a7d494 |
error:
|
|
Packit |
a7d494 |
if (doc)
|
|
Packit |
a7d494 |
xmlFreeDoc (doc);
|
|
Packit |
a7d494 |
xmlFree (lang_version);
|
|
Packit |
a7d494 |
return FALSE;
|
|
Packit |
a7d494 |
}
|
|
Packit |
a7d494 |
|