[gnome-builder] patternspec: add search match helper
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-builder] patternspec: add search match helper
- Date: Sun, 29 Mar 2015 08:02:44 +0000 (UTC)
commit 871613147be417d645b00ed671eb5c2f583fc029
Author: Christian Hergert <christian hergert me>
Date: Sun Mar 29 00:56:17 2015 -0700
patternspec: add search match helper
This simple pattern matcher allows for multiple words in the input
string. It will use simple word boundaries in the haystack (space or
underline).
"gtk widg" would match "gtk_widget_show".
libide/Makefile.am | 2 +
libide/ide-pattern-spec.c | 159 +++++++++++++++++++++++++++++++++++++++++++++
libide/ide-pattern-spec.h | 41 ++++++++++++
libide/ide.h | 1 +
4 files changed, 203 insertions(+), 0 deletions(-)
---
diff --git a/libide/Makefile.am b/libide/Makefile.am
index aec1cbf..bddd37c 100644
--- a/libide/Makefile.am
+++ b/libide/Makefile.am
@@ -109,6 +109,8 @@ libide_1_0_la_public_sources = \
libide/ide-log.h \
libide/ide-object.c \
libide/ide-object.h \
+ libide/ide-pattern-spec.c \
+ libide/ide-pattern-spec.h \
libide/ide-process.c \
libide/ide-process.h \
libide/ide-progress.c \
diff --git a/libide/ide-pattern-spec.c b/libide/ide-pattern-spec.c
new file mode 100644
index 0000000..4507842
--- /dev/null
+++ b/libide/ide-pattern-spec.c
@@ -0,0 +1,159 @@
+/* ide-pattern-spec.c
+ *
+ * Copyright (C) 2015 Christian Hergert <christian hergert me>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#define G_LOG_DOMAIN "ide-pattern-spec"
+
+#include <string.h>
+
+#include "ide-pattern-spec.h"
+
+G_DEFINE_BOXED_TYPE (IdePatternSpec, ide_pattern_spec,
+ ide_pattern_spec_ref, ide_pattern_spec_unref)
+
+/**
+ * SECTION:ide-pattern-spec:
+ *
+ * This works similar to GPatternSpec except the query syntax is different.
+ * It tries to mtach word boundaries, but with matching partial words up
+ * to those boundaries. For example, "gtk widg" would match "gtk_widget_show".
+ * Word boundaries include '_' and ' '. If any character is uppercase, then
+ * case sensitivity is used.
+ */
+
+struct _IdePatternSpec
+{
+ volatile gint ref_count;
+ gchar *needle;
+ gchar **parts;
+ guint case_sensitive : 1;
+};
+
+IdePatternSpec *
+ide_pattern_spec_new (const gchar *needle)
+{
+ IdePatternSpec *self;
+ const gchar *tmp;
+
+ g_return_val_if_fail (needle, NULL);
+
+ self = g_new0 (IdePatternSpec, 1);
+ self->ref_count = 1;
+ self->needle = g_strdup (needle);
+ self->parts = g_strsplit (needle, " ", 0);
+ self->case_sensitive = FALSE;
+
+ for (tmp = needle; tmp; tmp = g_utf8_next_char (tmp))
+ {
+ if (g_unichar_isupper (g_utf8_get_char (tmp)))
+ {
+ self->case_sensitive = TRUE;
+ break;
+ }
+ }
+
+ return self;
+}
+
+static void
+ide_pattern_spec_free (IdePatternSpec *self)
+{
+ g_strfreev (self->parts);
+ g_free (self->needle);
+ g_free (self);
+}
+
+static inline gboolean
+is_word_break (gunichar ch)
+{
+ return (ch == ' ' || ch == '_');
+}
+
+static const gchar *
+next_word_start (const gchar *haystack)
+{
+ for (; *haystack; haystack = g_utf8_next_char (haystack))
+ {
+ gunichar ch = g_utf8_get_char (haystack);
+
+ if (is_word_break (ch))
+ break;
+ }
+
+ for (; *haystack; haystack = g_utf8_next_char (haystack))
+ {
+ gunichar ch = g_utf8_get_char (haystack);
+
+ if (is_word_break (ch))
+ continue;
+
+ break;
+ }
+
+ g_return_val_if_fail (*haystack == '\0' || !is_word_break (*haystack), NULL);
+
+ return haystack;
+}
+
+gboolean
+ide_pattern_spec_match (IdePatternSpec *self,
+ const gchar *haystack)
+{
+ gsize i;
+
+ g_return_val_if_fail (self, FALSE);
+ g_return_val_if_fail (haystack, FALSE);
+
+ for (i = 0; (haystack != NULL) && self->parts [i]; i++)
+ {
+ if (self->parts [i][0] == '\0')
+ continue;
+
+ if (self->case_sensitive)
+ haystack = strstr (haystack, self->parts [i]);
+ else
+ haystack = strcasestr (haystack, self->parts [i]);
+
+ if (haystack == NULL)
+ return FALSE;
+
+ haystack = next_word_start (haystack + strlen (self->parts [i]));
+ }
+
+ return TRUE;
+}
+
+IdePatternSpec *
+ide_pattern_spec_ref (IdePatternSpec *self)
+{
+ g_return_val_if_fail (self, NULL);
+ g_return_val_if_fail (self->ref_count > 0, NULL);
+
+ g_atomic_int_inc (&self->ref_count);
+
+ return self;
+}
+
+void
+ide_pattern_spec_unref (IdePatternSpec *self)
+{
+ g_return_if_fail (self);
+ g_return_if_fail (self->ref_count > 0);
+
+ if (g_atomic_int_dec_and_test (&self->ref_count))
+ ide_pattern_spec_free (self);
+}
diff --git a/libide/ide-pattern-spec.h b/libide/ide-pattern-spec.h
new file mode 100644
index 0000000..66ddda0
--- /dev/null
+++ b/libide/ide-pattern-spec.h
@@ -0,0 +1,41 @@
+/* ide-pattern-spec.h
+ *
+ * Copyright (C) 2015 Christian Hergert <christian hergert me>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef IDE_MATCH_PATTERN_H
+#define IDE_MATCH_PATTERN_H
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+typedef struct _IdePatternSpec IdePatternSpec;
+
+#define IDE_TYPE_PATTERN_SPEC (ide_pattern_spec_get_type())
+
+GType ide_pattern_spec_get_type (void);
+IdePatternSpec *ide_pattern_spec_new (const gchar *keywords);
+IdePatternSpec *ide_pattern_spec_ref (IdePatternSpec *self);
+void ide_pattern_spec_unref (IdePatternSpec *self);
+gboolean ide_pattern_spec_match (IdePatternSpec *self,
+ const gchar *haystack);
+
+G_DEFINE_AUTOPTR_CLEANUP_FUNC (IdePatternSpec, ide_pattern_spec_unref)
+
+G_END_DECLS
+
+#endif /* IDE_MATCH_PATTERN_H */
diff --git a/libide/ide.h b/libide/ide.h
index ab3c64f..26c4957 100644
--- a/libide/ide.h
+++ b/libide/ide.h
@@ -54,6 +54,7 @@ G_BEGIN_DECLS
#include "ide-language.h"
#include "ide-log.h"
#include "ide-object.h"
+#include "ide-pattern-spec.h"
#include "ide-process.h"
#include "ide-progress.h"
#include "ide-project.h"
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]