[gtksourceview/wip/chergert/snippets] more snippet parsing, use string chunks for infos
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtksourceview/wip/chergert/snippets] more snippet parsing, use string chunks for infos
- Date: Tue, 28 Jan 2020 19:53:58 +0000 (UTC)
commit 89b1a465adfb43e2ecdea460f2d826af62a6e538
Author: Christian Hergert <chergert redhat com>
Date: Tue Jan 28 11:45:26 2020 -0800
more snippet parsing, use string chunks for infos
This helps us avoid creating objects up-front, and keep all the string
data in contiguous memory (well to some degree).
gtksourceview/gtksourcesnippetbundle-private.h | 10 +++
gtksourceview/gtksourcesnippetbundle.c | 99 +++++++++++++++++++------
gtksourceview/gtksourcesnippetmanager-private.h | 3 +
gtksourceview/gtksourcesnippetmanager.c | 27 ++++++-
4 files changed, 115 insertions(+), 24 deletions(-)
---
diff --git a/gtksourceview/gtksourcesnippetbundle-private.h b/gtksourceview/gtksourcesnippetbundle-private.h
index 9d957fb0..0b1e0d75 100644
--- a/gtksourceview/gtksourcesnippetbundle-private.h
+++ b/gtksourceview/gtksourcesnippetbundle-private.h
@@ -26,6 +26,16 @@
G_BEGIN_DECLS
+typedef struct
+{
+ const gchar *group;
+ const gchar *name;
+ const gchar *trigger;
+ const gchar *language;
+ const gchar *description;
+ const gchar *text;
+} GtkSourceSnippetInfo;
+
#define GTK_SOURCE_TYPE_SNIPPET_BUNDLE (_gtk_source_snippet_bundle_get_type())
G_DECLARE_FINAL_TYPE (GtkSourceSnippetBundle, _gtk_source_snippet_bundle, GTK_SOURCE, SNIPPET_BUNDLE,
GObject)
diff --git a/gtksourceview/gtksourcesnippetbundle.c b/gtksourceview/gtksourcesnippetbundle.c
index 408f369a..24ac6e08 100644
--- a/gtksourceview/gtksourcesnippetbundle.c
+++ b/gtksourceview/gtksourcesnippetbundle.c
@@ -19,22 +19,26 @@
#include "config.h"
+#include "gtksourcesnippet.h"
#include "gtksourcesnippetbundle-private.h"
-#include "gtksourcesnippetmanager.h"
+#include "gtksourcesnippetmanager-private.h"
struct _GtkSourceSnippetBundle
{
GObject parent_instance;
+ GArray *infos;
};
typedef struct
{
+ GtkSourceSnippetManager *manager;
GtkSourceSnippetBundle *self;
gchar *group;
gchar *name;
gchar *description;
gchar *trigger;
gchar **languages;
+ GString *text;
} ParseState;
G_DEFINE_TYPE (GtkSourceSnippetBundle, _gtk_source_snippet_bundle, G_TYPE_OBJECT)
@@ -42,6 +46,10 @@ G_DEFINE_TYPE (GtkSourceSnippetBundle, _gtk_source_snippet_bundle, G_TYPE_OBJECT
static void
gtk_source_snippet_bundle_finalize (GObject *object)
{
+ GtkSourceSnippetBundle *self = (GtkSourceSnippetBundle *)object;
+
+ g_clear_pointer (&self->infos, g_array_unref);
+
G_OBJECT_CLASS (_gtk_source_snippet_bundle_parent_class)->finalize (object);
}
@@ -56,6 +64,23 @@ _gtk_source_snippet_bundle_class_init (GtkSourceSnippetBundleClass *klass)
static void
_gtk_source_snippet_bundle_init (GtkSourceSnippetBundle *self)
{
+ self->infos = g_array_new (FALSE, FALSE, sizeof (GtkSourceSnippetInfo));
+}
+
+static void
+gtk_source_snippet_bundle_add (GtkSourceSnippetBundle *self,
+ const GtkSourceSnippetInfo *info)
+{
+ g_assert (GTK_SOURCE_IS_SNIPPET_BUNDLE (self));
+ g_assert (info != NULL);
+
+ /* If there is no name, and no trigger, then there is no way to
+ * instantiate the snippet. Just ignore it.
+ */
+ if (info->name != NULL || info->trigger != NULL)
+ {
+ g_array_append_vals (self->infos, info, 1);
+ }
}
static void
@@ -66,14 +91,12 @@ text_and_cdata (GMarkupParseContext *context,
GError **error)
{
ParseState *state = user_data;
- gchar *copy;
g_assert (state != NULL);
g_assert (GTK_SOURCE_IS_SNIPPET_BUNDLE (state->self));
- copy = g_strndup (text, text_len);
- g_print ("%s", copy);
- g_free (copy);
+ g_string_truncate (state->text, 0);
+ g_string_append_len (state->text, text, text_len);
}
static const GMarkupParser text_parser = {
@@ -118,8 +141,8 @@ elements_start_element (GMarkupParseContext *context,
g_set_error (error,
G_MARKUP_ERROR,
G_MARKUP_ERROR_UNKNOWN_ELEMENT,
- "Element %s not supported",
- element_name);
+ "Element %s not supported",
+ element_name);
}
}
@@ -132,9 +155,31 @@ elements_end_element (GMarkupParseContext *context,
ParseState *state = user_data;
g_assert (state != NULL);
+ g_assert (GTK_SOURCE_IS_SNIPPET_MANAGER (state->manager));
g_assert (GTK_SOURCE_IS_SNIPPET_BUNDLE (state->self));
g_assert (element_name != NULL);
+ if (g_strcmp0 (element_name, "text") == 0 &&
+ state->languages != NULL &&
+ state->languages[0] != NULL)
+ {
+ GtkSourceSnippetInfo info;
+
+ info.group = _gtk_source_snippet_manager_intern (state->manager, state->group);
+ info.name = _gtk_source_snippet_manager_intern (state->manager, state->name);
+ info.description = _gtk_source_snippet_manager_intern (state->manager, state->description);
+ info.trigger = _gtk_source_snippet_manager_intern (state->manager, state->trigger);
+ info.text = _gtk_source_snippet_manager_intern (state->manager, state->text->str);
+
+ for (guint i = 0; state->languages[i]; i++)
+ {
+ info.language = _gtk_source_snippet_manager_intern (state->manager,
state->languages[i]);
+
+ gtk_source_snippet_bundle_add (state->self, &info);
+ }
+
+ }
+
g_clear_pointer (&state->languages, g_strfreev);
g_markup_parse_context_pop (context);
@@ -167,8 +212,8 @@ snippet_start_element (GMarkupParseContext *context,
g_set_error (error,
G_MARKUP_ERROR,
G_MARKUP_ERROR_UNKNOWN_ELEMENT,
- "Element %s not supported",
- element_name);
+ "Element %s not supported",
+ element_name);
return;
}
@@ -253,8 +298,8 @@ snippets_start_element (GMarkupParseContext *context,
g_set_error (error,
G_MARKUP_ERROR,
G_MARKUP_ERROR_UNKNOWN_ELEMENT,
- "Element %s not supported",
- element_name);
+ "Element %s not supported",
+ element_name);
return;
}
@@ -295,8 +340,9 @@ static const GMarkupParser snippets_parser = {
};
static gboolean
-gtk_source_snippet_bundle_parse (GtkSourceSnippetBundle *self,
- const gchar *path)
+gtk_source_snippet_bundle_parse (GtkSourceSnippetBundle *self,
+ GtkSourceSnippetManager *manager,
+ const gchar *path)
{
gchar *contents = NULL;
gsize length = 0;
@@ -308,7 +354,11 @@ gtk_source_snippet_bundle_parse (GtkSourceSnippetBundle *self,
if (g_file_get_contents (path, &contents, &length, NULL))
{
GMarkupParseContext *context;
- ParseState state = { .self = self };
+ ParseState state = {0};
+
+ state.self = self;
+ state.manager = manager;
+ state.text = g_string_new (NULL);
context = g_markup_parse_context_new (&snippets_parser,
(G_MARKUP_TREAT_CDATA_AS_TEXT |
@@ -322,9 +372,19 @@ gtk_source_snippet_bundle_parse (GtkSourceSnippetBundle *self,
g_clear_pointer (&state.name, g_free);
g_clear_pointer (&state.trigger, g_free);
g_clear_pointer (&state.group, g_free);
+ g_string_free (state.text, TRUE);
g_markup_parse_context_free (context);
g_free (contents);
+
+#if 0
+ for (guint i = 0; i < self->infos->len; i++)
+ {
+ GtkSourceSnippetInfo *info = &g_array_index (self->infos, GtkSourceSnippetInfo, i);
+ g_print ("group=%s name=%s language=%s trigger=%s\n",
+ info->group, info->name, info->language, info->trigger);
+ }
+#endif
}
return ret;
@@ -341,13 +401,10 @@ _gtk_source_snippet_bundle_new_from_file (const gchar *path,
self = g_object_new (GTK_SOURCE_TYPE_SNIPPET_BUNDLE, NULL);
- if (gtk_source_snippet_bundle_parse (self, path))
- {
- return g_steal_pointer (&self);
- }
- else
+ if (!gtk_source_snippet_bundle_parse (self, manager, path))
{
- g_object_unref (self);
- return NULL;
+ g_clear_object (&self);
}
+
+ return g_steal_pointer (&self);
}
diff --git a/gtksourceview/gtksourcesnippetmanager-private.h b/gtksourceview/gtksourcesnippetmanager-private.h
index 7a0f86d3..fd569639 100644
--- a/gtksourceview/gtksourcesnippetmanager-private.h
+++ b/gtksourceview/gtksourcesnippetmanager-private.h
@@ -25,5 +25,8 @@ G_BEGIN_DECLS
G_GNUC_INTERNAL
GtkSourceSnippetManager *_gtk_source_snippet_manager_peek_default (void);
+G_GNUC_INTERNAL
+const gchar *_gtk_source_snippet_manager_intern (GtkSourceSnippetManager *manager,
+ const gchar *str);
G_END_DECLS
diff --git a/gtksourceview/gtksourcesnippetmanager.c b/gtksourceview/gtksourcesnippetmanager.c
index b1e5c7d3..886ee37b 100644
--- a/gtksourceview/gtksourcesnippetmanager.c
+++ b/gtksourceview/gtksourcesnippetmanager.c
@@ -47,9 +47,10 @@
struct _GtkSourceSnippetManager
{
- GObject parent_instance;
- gchar **snippet_dirs;
- GPtrArray *bundles;
+ GObject parent_instance;
+ GStringChunk *strings;
+ gchar **snippet_dirs;
+ GPtrArray *bundles;
};
enum {
@@ -70,6 +71,7 @@ gtk_source_snippet_manager_finalize (GObject *object)
g_clear_pointer (&self->bundles, g_ptr_array_unref);
g_clear_pointer (&self->snippet_dirs, g_strfreev);
+ g_clear_pointer (&self->strings, g_string_chunk_free);
G_OBJECT_CLASS (gtk_source_snippet_manager_parent_class)->finalize (object);
}
@@ -179,6 +181,25 @@ _gtk_source_snippet_manager_peek_default (void)
return default_instance;
}
+const gchar *
+_gtk_source_snippet_manager_intern (GtkSourceSnippetManager *self,
+ const gchar *str)
+{
+ g_return_val_if_fail (GTK_SOURCE_IS_SNIPPET_MANAGER (self), NULL);
+
+ if (str == NULL)
+ {
+ return NULL;
+ }
+
+ if (self->strings == NULL)
+ {
+ self->strings = g_string_chunk_new (4096*2);
+ }
+
+ return g_string_chunk_insert_const (self->strings, str);
+}
+
/**
* gtk_source_snippet_manager_set_search_path:
* @self: a #GtkSourceSnippetManager
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]