[devhelp] Start to implement DhSearchContext internal class
- From: Sébastien Wilmet <swilmet src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [devhelp] Start to implement DhSearchContext internal class
- Date: Thu, 18 Jan 2018 12:34:56 +0000 (UTC)
commit cf2b1d23c65fefda98f3a03e8cf330358f7b5ae4
Author: Sébastien Wilmet <swilmet gnome org>
Date: Thu Jan 18 10:55:53 2018 +0100
Start to implement DhSearchContext internal class
docs/reference/Makefile.am | 1 +
po/POTFILES.in | 1 +
src/Makefile.am | 2 +
src/dh-search-context.c | 196 ++++++++++++++++++++++++++++++++++++++++++++
src/dh-search-context.h | 45 ++++++++++
5 files changed, 245 insertions(+), 0 deletions(-)
---
diff --git a/docs/reference/Makefile.am b/docs/reference/Makefile.am
index 7854955..f17ba5d 100644
--- a/docs/reference/Makefile.am
+++ b/docs/reference/Makefile.am
@@ -52,6 +52,7 @@ IGNORE_HFILES = \
dh-error.h \
dh-parser.h \
dh-preferences.h \
+ dh-search-context.h \
dh-settings.h \
dh-util.h \
dh-window.h
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 63e98df..a987008 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -17,6 +17,7 @@ src/dh-link.c
src/dh-main.c
src/dh-parser.c
src/dh-preferences.ui
+src/dh-search-context.c
src/dh-sidebar.c
src/dh-util.c
src/dh-window.c
diff --git a/src/Makefile.am b/src/Makefile.am
index db4918b..2873a8b 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -38,6 +38,7 @@ libdevhelp_private_headers = \
dh-error.h \
dh-parser.h \
dh-preferences.h \
+ dh-search-context.h \
dh-settings.h \
dh-util.h \
$(NULL)
@@ -46,6 +47,7 @@ libdevhelp_private_c_files = \
dh-error.c \
dh-parser.c \
dh-preferences.c \
+ dh-search-context.c \
dh-settings.c \
dh-util.c \
$(NULL)
diff --git a/src/dh-search-context.c b/src/dh-search-context.c
new file mode 100644
index 0000000..03d5b36
--- /dev/null
+++ b/src/dh-search-context.c
@@ -0,0 +1,196 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2018 Sébastien Wilmet <swilmet gnome org>
+ *
+ * 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 2 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/>.
+ */
+
+#include "dh-search-context.h"
+#include <string.h>
+
+struct _DhSearchContext {
+ gchar *book_id;
+ gchar *page_id;
+ GStrv keywords;
+};
+
+/* Process the input search string and extract:
+ * - If "book:" prefix given, a book_id;
+ * - If "page:" prefix given, a page_id;
+ * - All remaining keywords.
+ *
+ * Returns TRUE if the extraction is successfull, FALSE if the @search_string is
+ * invalid.
+ */
+static gboolean
+process_search_string (DhSearchContext *search,
+ const gchar *search_string)
+{
+ gchar *processed = NULL;
+ GStrv tokens = NULL;
+ gint token_num;
+ gint keyword_num;
+ gboolean ret = TRUE;
+
+ g_assert (search->book_id == NULL);
+ g_assert (search->page_id == NULL);
+ g_assert (search->keywords == NULL);
+
+ /* First, remove all leading and trailing whitespaces in the search
+ * string.
+ */
+ processed = g_strdup (search_string);
+ g_strstrip (processed);
+
+ /* Also avoid words being separated by more than one whitespace, or
+ * g_strsplit() will give us empty strings.
+ */
+ {
+ gchar *aux;
+
+ aux = processed;
+ while ((aux = strchr (aux, ' ')) != NULL) {
+ g_strchug (++aux);
+ }
+ }
+
+ /* If after all this we get an empty string, nothing else to do. */
+ if (processed[0] == '\0') {
+ ret = FALSE;
+ goto out;
+ }
+
+ /* Split the input string into tokens */
+ tokens = g_strsplit (processed, " ", 0);
+
+ /* Allocate output keywords */
+ search->keywords = g_new0 (gchar *, g_strv_length (tokens) + 1);
+ keyword_num = 0;
+
+ for (token_num = 0; tokens[token_num] != NULL; token_num++) {
+ const gchar *cur_token = tokens[token_num];
+ const gchar *prefix;
+ gint prefix_len;
+
+ /* Book prefix? */
+ prefix = "book:";
+ if (g_str_has_prefix (cur_token, prefix)) {
+ prefix_len = strlen (prefix);
+
+ /* If keyword given but no content, skip it. */
+ if (cur_token[prefix_len] == '\0') {
+ continue;
+ }
+
+ /* We got a second request of book, don't allow this. */
+ if (search->book_id != NULL) {
+ ret = FALSE;
+ goto out;
+ }
+
+ search->book_id = g_strdup (cur_token + prefix_len);
+ continue;
+ }
+
+ /* Page prefix? */
+ prefix = "page:";
+ if (g_str_has_prefix (cur_token, prefix)) {
+ prefix_len = strlen (prefix);
+
+ /* If keyword given but no content, skip it. */
+ if (cur_token[prefix_len] == '\0') {
+ continue;
+ }
+
+ /* We got a second request of page, don't allow this. */
+ if (search->page_id != NULL) {
+ ret = FALSE;
+ goto out;
+ }
+
+ search->page_id = g_strdup (cur_token + prefix_len);
+ continue;
+ }
+
+ /* Then, a new keyword to look for. */
+ search->keywords[keyword_num] = g_strdup (cur_token);
+ keyword_num++;
+ }
+
+ if (keyword_num == 0) {
+ g_free (search->keywords);
+ search->keywords = NULL;
+ }
+
+out:
+ g_free (processed);
+ g_strfreev (tokens);
+ return ret;
+}
+
+/* Returns: (transfer full) (nullable): a new #DhSearchContext, or %NULL if
+ * @search_string is invalid.
+ */
+DhSearchContext *
+_dh_search_context_new (const gchar *search_string)
+{
+ DhSearchContext *search;
+
+ g_return_val_if_fail (search_string != NULL, NULL);
+
+ search = g_new0 (DhSearchContext, 1);
+
+ if (!process_search_string (search, search_string)) {
+ _dh_search_context_free (search);
+ return NULL;
+ }
+
+ return search;
+}
+
+void
+_dh_search_context_free (DhSearchContext *search)
+{
+ if (search == NULL)
+ return;
+
+ g_free (search->book_id);
+ g_free (search->page_id);
+ g_strfreev (search->keywords);
+ g_free (search);
+}
+
+const gchar *
+_dh_search_context_get_book_id (DhSearchContext *search)
+{
+ g_return_val_if_fail (search != NULL, NULL);
+
+ return search->book_id;
+}
+
+const gchar *
+_dh_search_context_get_page_id (DhSearchContext *search)
+{
+ g_return_val_if_fail (search != NULL, NULL);
+
+ return search->page_id;
+}
+
+GStrv
+_dh_search_context_get_keywords (DhSearchContext *search)
+{
+ g_return_val_if_fail (search != NULL, NULL);
+
+ return search->keywords;
+}
diff --git a/src/dh-search-context.h b/src/dh-search-context.h
new file mode 100644
index 0000000..14fc34f
--- /dev/null
+++ b/src/dh-search-context.h
@@ -0,0 +1,45 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2018 Sébastien Wilmet <swilmet gnome org>
+ *
+ * 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 2 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 DH_SEARCH_CONTEXT_H
+#define DH_SEARCH_CONTEXT_H
+
+#include <glib.h>
+
+G_BEGIN_DECLS
+
+typedef struct _DhSearchContext DhSearchContext;
+
+G_GNUC_INTERNAL
+DhSearchContext * _dh_search_context_new (const gchar *search_string);
+
+G_GNUC_INTERNAL
+void _dh_search_context_free (DhSearchContext *search);
+
+G_GNUC_INTERNAL
+const gchar * _dh_search_context_get_book_id (DhSearchContext *search);
+
+G_GNUC_INTERNAL
+const gchar * _dh_search_context_get_page_id (DhSearchContext *search);
+
+G_GNUC_INTERNAL
+GStrv _dh_search_context_get_keywords (DhSearchContext *search);
+
+G_END_DECLS
+
+#endif /* DH_SEARCH_CONTEXT_H */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]