Eine aufbereitete Darstellung der Quelle

 
     
 
 
Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 

Benutzer

Quelle  textiter.c

  Sprache: C
 

/* GTK - The GIMP Toolkit
 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library. If not, see <http://www.gnu.org/licenses/>.
 */


#include "config.h"
#include <stdio.h>
#include <string.h>

#include <gtk/gtk.h>

static void
test_empty_search (void)
{
  GtkTextBuffer *buffer;
  GtkTextIter it, s, e;
  gboolean res;

  buffer = gtk_text_buffer_new (NULL);
  gtk_text_buffer_set_text (buffer, "This is some foo text", -1);

  /* search from start forward */
  gtk_text_buffer_get_start_iter (buffer, &it);
  res = gtk_text_iter_forward_search (&it, ""0, &s, &e, NULL);
  g_assert_true (res);
  g_assert_cmpint (gtk_text_iter_get_offset (&s), ==, gtk_text_iter_get_offset (&e));
  g_assert_cmpint (gtk_text_iter_get_offset (&s), ==, 1);

  /* search from end backward */
  gtk_text_buffer_get_end_iter (buffer, &it);
  res = gtk_text_iter_backward_search (&it, ""0, &s, &e, NULL);
  g_assert_true (res);
  g_assert_cmpint (gtk_text_iter_get_offset (&s), ==, gtk_text_iter_get_offset (&e));
  g_assert_cmpint (gtk_text_iter_get_offset (&s), ==, 20);
}

static void
check_found_forward (const char *haystack,
                     const char *needle,
                     GtkTextSearchFlags flags,
                     int expected_start,
                     int expected_end,
                     const char *expected_string)
{
  GtkTextBuffer *buffer;
  GtkTextIter i, s, e;
  gboolean res;
  char *text;

  buffer = gtk_text_buffer_new (NULL);

  gtk_text_buffer_set_text (buffer, haystack, -1);

  /* TODO: add test with limit before, after and in the middle
     of expected start and end */


  /* search from start forward */
  gtk_text_buffer_get_start_iter (buffer, &i);
  res = gtk_text_iter_forward_search (&i, needle, flags, &s, &e, NULL);
  g_assert_true (res);
  g_assert_cmpint (expected_start, ==, gtk_text_iter_get_offset (&s));
  g_assert_cmpint (expected_end, ==, gtk_text_iter_get_offset (&e));
  text = gtk_text_iter_get_text (&s, &e);
  g_assert_cmpstr (expected_string, ==, text);
  g_free (text);

  g_object_unref (buffer);
}

static void
check_found_backward (const char *haystack,
                      const char *needle,
                      GtkTextSearchFlags flags,
                      int expected_start,
                      int expected_end,
                      const char *expected_string)
{
  GtkTextBuffer *buffer;
  GtkTextIter i, s, e;
  gboolean res;
  char *text;

  buffer = gtk_text_buffer_new (NULL);

  gtk_text_buffer_set_text (buffer, haystack, -1);

  /* search from end backward */
  gtk_text_buffer_get_end_iter (buffer, &i);
  res = gtk_text_iter_backward_search (&i, needle, flags, &s, &e, NULL);
  g_assert_true (res);
  g_assert_cmpint (expected_start, ==, gtk_text_iter_get_offset (&s));
  g_assert_cmpint (expected_end, ==, gtk_text_iter_get_offset (&e));
  text = gtk_text_iter_get_text (&s, &e);
  g_assert_cmpstr (expected_string, ==, text);
  g_free (text);

  g_object_unref (buffer);
}

static void
check_not_found (const char *haystack,
                 const char *needle,
                 GtkTextSearchFlags flags)
{
  GtkTextBuffer *buffer;
  GtkTextIter i, s, e;
  gboolean res;

  buffer = gtk_text_buffer_new (NULL);

  gtk_text_buffer_set_text (buffer, haystack, -1);

  /* search from start forward */
  gtk_text_buffer_get_start_iter (buffer, &i);
  res = gtk_text_iter_forward_search (&i, needle, flags, &s, &e, NULL);
  g_assert_false (res);

  /* search from end backward */
  gtk_text_buffer_get_end_iter (buffer, &i);
  res = gtk_text_iter_backward_search (&i, needle, flags, &s, &e, NULL);
  g_assert_false (res);

  g_object_unref (buffer);
}

static void
test_search_full_buffer (void)
{
  check_found_forward ("foo""foo"003"foo");
  check_found_backward ("foo""foo"003"foo");
  check_found_forward ("foo""foo", GTK_TEXT_SEARCH_CASE_INSENSITIVE, 03"foo");
  check_found_backward ("foo""foo", GTK_TEXT_SEARCH_CASE_INSENSITIVE, 03"foo");
  check_found_forward ("foo""Foo", GTK_TEXT_SEARCH_CASE_INSENSITIVE, 03"foo");
  check_found_backward ("foo""Foo", GTK_TEXT_SEARCH_CASE_INSENSITIVE, 03"foo");
}

static void
test_search (void)
{
  /* simple match */
  check_found_forward ("This is some foo text""foo"01316"foo");
  check_found_backward ("This is some foo text""foo"01316"foo");
  check_not_found ("This is some foo text""Foo"0);

  /* different matches for forward and backward */
  check_found_forward ("This is some foo foo text""foo"01316"foo");
  check_found_backward ("This is some foo foo text""foo"01720"foo");

  /* new lines in the haystack */
  check_found_forward ("This is some\nfoo text""foo"01316"foo");
  check_found_backward ("This is some\nfoo text""foo"01316"foo");
  check_found_forward ("This is some foo\nfoo text""foo"01316"foo");
  check_found_backward ("This is some foo\nfoo text""foo"01720"foo");
  check_not_found ("This is some\nfoo text""Foo"0);

  /* end of buffer */
  check_found_forward ("This is some\ntext foo""foo"01821"foo");
  check_found_backward ("This is some\ntext foo""foo"01821"foo");
  check_not_found ("This is some\ntext foo""Foo"0);

  /* multiple lines in the needle */
  check_found_forward ("This is some foo\nfoo text""foo\nfoo"01320"foo\nfoo");
  check_found_backward ("This is some foo\nfoo text""foo\nfoo"01320"foo\nfoo");
  check_not_found ("This is some foo\nfoo text""Foo\nfoo"0);

  /* check also that different composition of utf8 characters
     (e.g. accented letters) match */


  check_found_forward ("This is some \303\200 text""\303\200"01314"\303\200");
  check_found_forward ("This is some \303\200 text""some \303\200"0814"some \303\200");
  check_found_forward ("This is some \303\200 text""\303\200 text"01319"\303\200 text");
  check_found_forward ("This is some \303\200 text""some \303\200 text"0819"some \303\200 text");
  check_found_backward ("This is some \303\240 text""\303\240"01314"\303\240");
  check_found_backward ("This is some \303\240 text""some \303\240"0814"some \303\240");
  check_found_backward ("This is some \303\240 text""\303\240 text"01319"\303\240 text");
  check_found_backward ("This is some \303\240 text""some \303\240 text"0819"some \303\240 text");

  /* multi-byte characters outside the needle */
  check_found_forward ("\303\200 aa""aa"024"aa");
  check_found_forward ("aa \303\200""aa"002"aa");
  check_found_backward ("\303\200 aa""aa"024"aa");
  check_found_backward ("aa \303\200""aa"002"aa");
}

static void
test_search_caseless (void)
{
  GtkTextSearchFlags flags;

  flags = GTK_TEXT_SEARCH_CASE_INSENSITIVE;

  /* simple match */
  check_found_forward ("This is some foo text""foo", flags, 1316"foo");
  check_found_forward ("This is some foo text""Foo", flags, 1316"foo");
  check_found_forward ("This is some Foo text""foo", flags, 1316"Foo");
  check_found_backward ("This is some foo text""foo", flags, 1316"foo");
  check_found_backward ("This is some foo text""Foo", flags, 1316"foo");
  check_found_backward ("This is some Foo text""foo", flags, 1316"Foo");

  /* check also that different composition of utf8 characters
     (e.g. accented letters) match */


  /* different matches for forward and backward */
  check_found_forward ("This is some foo foo text""foo", flags, 1316"foo");
  check_found_forward ("This is some foo foo text""Foo", flags, 1316"foo");
  check_found_forward ("This is some Foo foo text""foo", flags, 1316"Foo");
  check_found_forward ("This is some \303\200 \303\240 text""\303\240", flags, 1314"\303\200");
  check_found_forward ("This is some \303\200 \303\240 text""\303\200", flags, 1314"\303\200");
  check_found_forward ("This is some \303\200 \303\240 text""a\314\200", flags, 1314"\303\200");
  check_found_backward ("This is some foo foo text""foo", flags, 1720"foo");
  check_found_backward ("This is some foo foo text""Foo", flags, 1720"foo");
  check_found_backward ("This is some foo Foo text""foo", flags, 1720"Foo");
  check_found_backward ("This is some \303\200 \303\240 text""\303\240", flags, 1516"\303\240");
  check_found_backward ("This is some \303\200 \303\240 text""\303\200", flags, 1516"\303\240");
  check_found_backward ("This is some \303\200 \303\240 text""a\314\200", flags, 1516"\303\240");

  /* new lines in the haystack */
  check_found_forward ("This is some\nfoo text""foo", flags, 1316"foo");
  check_found_forward ("This is some\nfoo text""Foo", flags, 1316"foo");
  check_found_forward ("This is some\nFoo text""foo", flags, 1316"Foo");
  check_found_forward ("This is some\n\303\200 text""\303\240", flags, 1314"\303\200");
  check_found_forward ("This is some\n\303\200 text""a\314\200", flags, 1314"\303\200");
  check_found_backward ("This is some\nfoo text""foo", flags, 1316"foo");
  check_found_backward ("This is some\nfoo text""Foo", flags, 1316"foo");
  check_found_backward ("This is some\nFoo text""foo", flags, 1316"Foo");
  check_found_backward ("This is some\n\303\200 text""\303\240", flags, 1314"\303\200");
  check_found_backward ("This is some\n\303\200 text""a\314\200", flags, 1314"\303\200");
  check_found_forward ("This is some foo\nfoo text""foo", flags, 1316"foo");
  check_found_forward ("This is some foo\nfoo text""Foo", flags, 1316"foo");
  check_found_forward ("This is some Foo\nfoo text""foo", flags, 1316"Foo");
  check_found_forward ("This is some \303\200\n\303\200 text""\303\240", flags, 1314"\303\200");
  check_found_forward ("This is some \303\200\n\303\200 text""a\314\200", flags, 1314"\303\200");
  check_found_backward ("This is some foo\nfoo text""foo", flags, 1720"foo");
  check_found_backward ("This is some foo\nfoo text""Foo", flags, 1720"foo");
  check_found_backward ("This is some foo\nFoo text""foo", flags, 1720"Foo");
  check_found_backward ("This is some \303\200\n\303\200 text""\303\240", flags, 1516"\303\200");
  check_found_backward ("This is some \303\200\n\303\200 text""a\314\200", flags, 1516"\303\200");

  /* end of buffer */
  check_found_forward ("This is some\ntext foo""foo", flags, 1821"foo");
  check_found_forward ("This is some\ntext foo""Foo", flags, 1821"foo");
  check_found_forward ("This is some\ntext Foo""foo", flags, 1821"Foo");
  check_found_forward ("This is some\ntext \303\200""\303\240", flags, 1819"\303\200");
  check_found_forward ("This is some\ntext \303\200""a\314\200", flags, 1819"\303\200");
  check_found_backward ("This is some\ntext foo""foo", flags, 1821"foo");
  check_found_backward ("This is some\ntext foo""Foo", flags, 1821"foo");
  check_found_backward ("This is some\ntext Foo""foo", flags, 1821"Foo");
  check_found_backward ("This is some\ntext \303\200""\303\240", flags, 1819"\303\200");
  check_found_backward ("This is some\ntext \303\200""a\314\200", flags, 1819"\303\200");

  /* multiple lines in the needle */
  check_found_forward ("This is some foo\nfoo text""foo\nfoo", flags, 1320"foo\nfoo");
  check_found_forward ("This is some foo\nfoo text""Foo\nFoo", flags, 1320"foo\nfoo");
  check_found_forward ("This is some Foo\nFoo text""foo\nfoo", flags, 1320"Foo\nFoo");
  check_found_forward ("This is some \303\200\n\303\200 text""\303\240\n\303\240", flags, 1316"\303\200\n\303\200");
  check_found_forward ("This is some \303\200\n\303\200 text""a\314\200\na\314\200", flags, 1316"\303\200\n\303\200");
  check_found_backward ("This is some foo\nfoo text""foo\nfoo", flags, 1320"foo\nfoo");
  check_found_backward ("This is some foo\nfoo text""Foo\nFoo", flags, 1320"foo\nfoo");
  check_found_backward ("This is some Foo\nFoo text""foo\nfoo", flags, 1320"Foo\nFoo");
  check_found_backward ("This is some \303\200\n\303\200 text""\303\240\n\303\240", flags, 1316"\303\200\n\303\200");
  check_found_backward ("This is some \303\200\n\303\200 text""a\314\200\na\314\200", flags, 1316"\303\200\n\303\200");

  /* multi-byte characters outside the needle */
  check_found_forward ("\303\200 aa""aa", flags, 24"aa");
  check_found_forward ("aa \303\200""aa", flags, 02"aa");
  check_found_backward ("\303\200 aa""aa", flags, 24"aa");
  check_found_backward ("aa \303\200""aa", flags, 02"aa");
}

static void
test_forward_to_tag_toggle (void)
{
  GtkTextBuffer *buffer;
  GtkTextTag *bold_tag;
  GtkTextTag *editable_tag;
  GtkTextIter iter;
  int offset;
  gboolean ret;

  buffer = gtk_text_buffer_new (NULL);

  bold_tag = gtk_text_buffer_create_tag (buffer, "bold",
                                         "weight", PANGO_WEIGHT_BOLD,
                                         NULL);

  editable_tag = gtk_text_buffer_create_tag (buffer, "not-editable",
                                             "editable"FALSE,
                                             NULL);

  gtk_text_buffer_get_start_iter (buffer, &iter);

  gtk_text_buffer_insert (buffer, &iter, "a", -1);
  gtk_text_buffer_insert_with_tags (buffer, &iter, "b", -1, bold_tag, NULL);
  gtk_text_buffer_insert_with_tags (buffer, &iter, "c", -1, editable_tag, NULL);

  /* Go to the first "on" toggle */
  gtk_text_buffer_get_start_iter (buffer, &iter);
  ret = gtk_text_iter_forward_to_tag_toggle (&iter, NULL);
  g_assert_true (ret);
  offset = gtk_text_iter_get_offset (&iter);
  g_assert_cmpint (offset, ==, 1);

  /* Go to the last "off" toggle for the bold tag */
  ret = gtk_text_iter_forward_to_tag_toggle (&iter, bold_tag);
  g_assert_true (ret);
  offset = gtk_text_iter_get_offset (&iter);
  g_assert_cmpint (offset, ==, 2);

  ret = gtk_text_iter_forward_to_tag_toggle (&iter, bold_tag);
  g_assert_false (ret);

  /* Go to the first "on" toggle for the editable tag */
  gtk_text_buffer_get_start_iter (buffer, &iter);
  ret = gtk_text_iter_forward_to_tag_toggle (&iter, editable_tag);
  g_assert_true (ret);
  offset = gtk_text_iter_get_offset (&iter);
  g_assert_cmpint (offset, ==, 2);

  /* Test with the end iter */
  gtk_text_buffer_get_end_iter (buffer, &iter);
  ret = gtk_text_iter_forward_to_tag_toggle (&iter, editable_tag);
  g_assert_false (ret);

  g_object_unref (buffer);
}

static void
check_forward_line_end (const char *buffer_text,
                        int          initial_offset,
                        int          result_offset,
                        gboolean     ret)
{
  GtkTextBuffer *buffer;
  GtkTextIter iter;

  buffer = gtk_text_buffer_new (NULL);
  gtk_text_buffer_set_text (buffer, buffer_text, -1);

  gtk_text_buffer_get_iter_at_offset (buffer, &iter, initial_offset);

  g_assert_cmpint (ret, ==, gtk_text_iter_forward_to_line_end (&iter));
  g_assert_cmpint (result_offset, ==, gtk_text_iter_get_offset (&iter));

  g_object_unref (buffer);
}

static void
test_forward_to_line_end (void)
{
  check_forward_line_end("a"01FALSE);
  check_forward_line_end("a\n"01TRUE);
  check_forward_line_end("a\r\n"01TRUE);
  check_forward_line_end("a\na\n"13TRUE);
  check_forward_line_end("a\na\n\n"13TRUE);
  check_forward_line_end("a\r\na\n"14TRUE);
  check_forward_line_end("a\r\na\r\n\r\n"14TRUE);
}

static void
check_word_boundaries (const char *buffer_text,
                       int          offset,
                       gboolean     starts_word,
                       gboolean     ends_word,
                       gboolean     inside_word)
{
  GtkTextBuffer *buffer;
  GtkTextIter iter;

  buffer = gtk_text_buffer_new (NULL);
  gtk_text_buffer_set_text (buffer, buffer_text, -1);

  gtk_text_buffer_get_iter_at_offset (buffer, &iter, offset);

  g_assert_cmpint (starts_word, ==, gtk_text_iter_starts_word (&iter));
  g_assert_cmpint (ends_word, ==, gtk_text_iter_ends_word (&iter));
  g_assert_cmpint (inside_word, ==, gtk_text_iter_inside_word (&iter));

  g_object_unref (buffer);
}

static void
check_forward_word_end (const char *buffer_text,
                        int          initial_offset,
                        int          result_offset,
                        gboolean     ret)
{
  GtkTextBuffer *buffer;
  GtkTextIter iter;

  buffer = gtk_text_buffer_new (NULL);
  gtk_text_buffer_set_text (buffer, buffer_text, -1);

  gtk_text_buffer_get_iter_at_offset (buffer, &iter, initial_offset);

  g_assert_cmpint (ret, ==, gtk_text_iter_forward_word_end (&iter));
  g_assert_cmpint (result_offset, ==, gtk_text_iter_get_offset (&iter));

  g_object_unref (buffer);
}

static void
check_backward_word_start (const char *buffer_text,
                           int          initial_offset,
                           int          result_offset,
                           gboolean     ret)
{
  GtkTextBuffer *buffer;
  GtkTextIter iter;

  buffer = gtk_text_buffer_new (NULL);
  gtk_text_buffer_set_text (buffer, buffer_text, -1);

  gtk_text_buffer_get_iter_at_offset (buffer, &iter, initial_offset);

  g_assert_cmpint (ret, ==, gtk_text_iter_backward_word_start (&iter));
  g_assert_cmpint (result_offset, ==, gtk_text_iter_get_offset (&iter));

  g_object_unref (buffer);
}

static void
test_word_boundaries (void)
{
  /* Test with trivial content. The word boundaries are anyway determined by
   * Pango and can change in the future for corner cases.
   */


  check_word_boundaries ("ab "0TRUEFALSETRUE);
  check_word_boundaries ("ab "1FALSEFALSETRUE);
  check_word_boundaries ("ab "2FALSETRUEFALSE);
  check_word_boundaries ("ab "3FALSEFALSEFALSE);
  check_word_boundaries (""0FALSEFALSEFALSE);

  check_forward_word_end ("ab "02TRUE);
  check_forward_word_end ("ab "12TRUE);
  check_forward_word_end ("ab "22FALSE);
  check_forward_word_end ("ab "33FALSE);
  check_forward_word_end ("ab"02FALSE);
  check_forward_word_end ("ab\n"22FALSE);

  check_backward_word_start (" ab"31TRUE);
  check_backward_word_start (" ab"21TRUE);
  check_backward_word_start (" ab"11FALSE);
  check_backward_word_start (" ab"00FALSE);
  check_backward_word_start ("ab"20TRUE);
}

static void
check_forward_visible_word_end (GtkTextBuffer *buffer,
                                int            initial_offset,
                                int            result_offset,
                                gboolean       ret)
{
  GtkTextIter iter;

  gtk_text_buffer_get_iter_at_offset (buffer, &iter, initial_offset);

  g_assert_cmpint (ret, ==, gtk_text_iter_forward_visible_word_end (&iter));
  g_assert_cmpint (result_offset, ==, gtk_text_iter_get_offset (&iter));
}

static void
check_backward_visible_word_start (GtkTextBuffer *buffer,
                                   int            initial_offset,
                                   int            result_offset,
                                   gboolean       ret)
{
  GtkTextIter iter;

  gtk_text_buffer_get_iter_at_offset (buffer, &iter, initial_offset);

  g_assert_cmpint (ret, ==, gtk_text_iter_backward_visible_word_start (&iter));
  g_assert_cmpint (result_offset, ==, gtk_text_iter_get_offset (&iter));
}

static void
test_visible_word_boundaries (void)
{
  /* Test with trivial content. The word boundaries are anyway determined by
   * Pango and can change in the future for corner cases.
   */


  GtkTextBuffer *buffer;
  GtkTextTag *invisible_tag;
  GtkTextIter iter;

  buffer = gtk_text_buffer_new (NULL);

  invisible_tag = gtk_text_buffer_create_tag (buffer, NULL,
                                              "invisible"TRUE,
                                              NULL);

  /* Buffer contents: " a b c " with " b " invisible */
  gtk_text_buffer_get_start_iter (buffer, &iter);
  gtk_text_buffer_insert (buffer, &iter, " a", -1);
  gtk_text_buffer_insert_with_tags (buffer, &iter, " b ", -1, invisible_tag, NULL);
  gtk_text_buffer_insert (buffer, &iter, "c ", -1);

  check_forward_visible_word_end (buffer, 06TRUE);
  check_forward_visible_word_end (buffer, 16TRUE);
  check_forward_visible_word_end (buffer, 26TRUE);
  check_forward_visible_word_end (buffer, 36TRUE);
  check_forward_visible_word_end (buffer, 46TRUE);
  check_forward_visible_word_end (buffer, 56TRUE);
  check_forward_visible_word_end (buffer, 66FALSE);
  check_forward_visible_word_end (buffer, 77FALSE);

  check_backward_visible_word_start (buffer, 75TRUE); /* FIXME result_offset should be 1 */
  check_backward_visible_word_start (buffer, 65TRUE); /* FIXME result_offset should be 1 */
  check_backward_visible_word_start (buffer, 51TRUE);
  check_backward_visible_word_start (buffer, 41TRUE);
  check_backward_visible_word_start (buffer, 31TRUE);
  check_backward_visible_word_start (buffer, 21TRUE);
  check_backward_visible_word_start (buffer, 11FALSE);
  check_backward_visible_word_start (buffer, 00FALSE);

  gtk_text_buffer_set_text (buffer, "ab", -1);
  check_forward_visible_word_end (buffer, 02FALSE);

  /* Buffer contents: "b c " with "b" invisible */
  gtk_text_buffer_set_text (buffer, "", -1);
  gtk_text_buffer_get_start_iter (buffer, &iter);
  gtk_text_buffer_insert_with_tags (buffer, &iter, "b", -1, invisible_tag, NULL);
  gtk_text_buffer_insert (buffer, &iter, " c ", -1);

  check_forward_visible_word_end (buffer, 01TRUE); /* FIXME result_offset should be 3 */

  g_object_unref (buffer);
}

static void
check_is_cursor_position (const char *buffer_text,
                          int          offset,
                          gboolean     ret)
{
  GtkTextBuffer *buffer;
  GtkTextIter iter;

  buffer = gtk_text_buffer_new (NULL);
  gtk_text_buffer_set_text (buffer, buffer_text, -1);

  gtk_text_buffer_get_iter_at_offset (buffer, &iter, offset);
  g_assert_cmpint (ret, ==, gtk_text_iter_is_cursor_position (&iter));

  g_object_unref (buffer);
}

static void
check_cursor_position (const char *buffer_text,
                       gboolean     forward,
                       int          initial_offset,
                       int          result_offset,
                       gboolean     ret)
{
  GtkTextBuffer *buffer;
  GtkTextIter iter;

  buffer = gtk_text_buffer_new (NULL);
  gtk_text_buffer_set_text (buffer, buffer_text, -1);

  gtk_text_buffer_get_iter_at_offset (buffer, &iter, initial_offset);

  if (forward)
    g_assert_cmpint (ret, ==, gtk_text_iter_forward_cursor_position (&iter));
  else
    g_assert_cmpint (ret, ==, gtk_text_iter_backward_cursor_position (&iter));

  g_assert_cmpint (result_offset, ==, gtk_text_iter_get_offset (&iter));

  g_object_unref (buffer);
}

static void
test_cursor_positions (void)
{
  check_is_cursor_position ("a\r\n"0TRUE);
  check_is_cursor_position ("a\r\n"1TRUE);
  check_is_cursor_position ("a\r\n"2FALSE);
  check_is_cursor_position ("a\r\n"3TRUE);
  check_is_cursor_position (""0TRUE);

  /* forward */
  check_cursor_position ("a\r\nb"TRUE01TRUE);
  check_cursor_position ("a\r\nb"TRUE13TRUE);
  check_cursor_position ("a\r\nb"TRUE23TRUE);
  check_cursor_position ("a\r\nb"TRUE34FALSE);
  check_cursor_position ("a\r\nb"TRUE44FALSE);
  check_cursor_position ("a\n"TRUE12FALSE);

  /* backward */
  check_cursor_position ("a\r\nb"FALSE43TRUE);
  check_cursor_position ("a\r\nb"FALSE31TRUE);
  check_cursor_position ("a\r\nb"FALSE21TRUE);
  check_cursor_position ("a\r\nb"FALSE10TRUE);
  check_cursor_position ("a\r\nb"FALSE00FALSE);
}

static void
check_visible_cursor_position (GtkTextBuffer *buffer,
                               gboolean       forward,
                               int            initial_offset,
                               int            result_offset,
                               gboolean       ret)
{
  GtkTextIter iter;

  gtk_text_buffer_get_iter_at_offset (buffer, &iter, initial_offset);

  if (forward)
    g_assert_cmpint (ret, ==, gtk_text_iter_forward_visible_cursor_position (&iter));
  else
    g_assert_cmpint (ret, ==, gtk_text_iter_backward_visible_cursor_position (&iter));

  g_assert_cmpint (result_offset, ==, gtk_text_iter_get_offset (&iter));
}

static void
test_visible_cursor_positions (void)
{
  GtkTextBuffer *buffer;
  GtkTextTag *invisible_tag;
  GtkTextIter iter;

  buffer = gtk_text_buffer_new (NULL);

  invisible_tag = gtk_text_buffer_create_tag (buffer, NULL,
                                              "invisible"TRUE,
                                              NULL);

  /* Buffer contents: "abcd" with 'bc' invisible */
  gtk_text_buffer_get_start_iter (buffer, &iter);
  gtk_text_buffer_insert (buffer, &iter, "a", -1);
  gtk_text_buffer_insert_with_tags (buffer, &iter, "bc", -1, invisible_tag, NULL);
  gtk_text_buffer_insert (buffer, &iter, "d", -1);

  /* forward */
  check_visible_cursor_position (buffer, TRUE03TRUE);
  check_visible_cursor_position (buffer, TRUE13TRUE);
  check_visible_cursor_position (buffer, TRUE23TRUE);
  check_visible_cursor_position (buffer, TRUE34FALSE);
  check_visible_cursor_position (buffer, TRUE44FALSE);

  /* backward */
  check_visible_cursor_position (buffer, FALSE43TRUE);
  check_visible_cursor_position (buffer, FALSE30TRUE);
  check_visible_cursor_position (buffer, FALSE20TRUE);
  check_visible_cursor_position (buffer, FALSE10TRUE);
  check_visible_cursor_position (buffer, FALSE00FALSE);

  g_object_unref (buffer);
}

static void
check_sentence_boundaries (const char *buffer_text,
                           int          offset,
                           gboolean     starts_sentence,
                           gboolean     ends_sentence,
                           gboolean     inside_sentence)
{
  GtkTextBuffer *buffer;
  GtkTextIter iter;

  buffer = gtk_text_buffer_new (NULL);
  gtk_text_buffer_set_text (buffer, buffer_text, -1);

  gtk_text_buffer_get_iter_at_offset (buffer, &iter, offset);

  g_assert_cmpint (starts_sentence, ==, gtk_text_iter_starts_sentence (&iter));
  g_assert_cmpint (ends_sentence, ==, gtk_text_iter_ends_sentence (&iter));
  g_assert_cmpint (inside_sentence, ==, gtk_text_iter_inside_sentence (&iter));

  g_object_unref (buffer);
}

static void
check_forward_sentence_end (const char *buffer_text,
                            int          initial_offset,
                            int          result_offset,
                            gboolean     ret)
{
  GtkTextBuffer *buffer;
  GtkTextIter iter;

  buffer = gtk_text_buffer_new (NULL);
  gtk_text_buffer_set_text (buffer, buffer_text, -1);

  gtk_text_buffer_get_iter_at_offset (buffer, &iter, initial_offset);

  g_assert_cmpint (ret, ==, gtk_text_iter_forward_sentence_end (&iter));
  g_assert_cmpint (result_offset, ==, gtk_text_iter_get_offset (&iter));

  g_object_unref (buffer);
}

static void
check_backward_sentence_start (const char *buffer_text,
                               int          initial_offset,
                               int          result_offset,
                               gboolean     ret)
{
  GtkTextBuffer *buffer;
  GtkTextIter iter;

  buffer = gtk_text_buffer_new (NULL);
  gtk_text_buffer_set_text (buffer, buffer_text, -1);

  gtk_text_buffer_get_iter_at_offset (buffer, &iter, initial_offset);

  g_assert_cmpint (ret, ==, gtk_text_iter_backward_sentence_start (&iter));
  g_assert_cmpint (result_offset, ==, gtk_text_iter_get_offset (&iter));

  g_object_unref (buffer);
}

static void
test_sentence_boundaries (void)
{
  check_sentence_boundaries ("Hi. "0TRUEFALSETRUE);
  check_sentence_boundaries ("Hi. "1FALSEFALSETRUE);
  check_sentence_boundaries ("Hi. "2FALSEFALSETRUE);
  check_sentence_boundaries ("Hi. "3FALSETRUEFALSE);
  check_sentence_boundaries ("Hi. "4FALSEFALSEFALSE);
  check_sentence_boundaries (""0FALSEFALSEFALSE);

  check_forward_sentence_end ("Hi. "03TRUE);
  check_forward_sentence_end ("Hi. "13TRUE);
  check_forward_sentence_end ("Hi. "23TRUE);
  check_forward_sentence_end ("Hi. "33FALSE);
  check_forward_sentence_end ("Hi. "44FALSE);
  check_forward_sentence_end ("Hi."03FALSE);
  check_forward_sentence_end ("Hi.\n"33FALSE);

  check_backward_sentence_start (" Hi."41TRUE);
  check_backward_sentence_start (" Hi."31TRUE);
  check_backward_sentence_start (" Hi."21TRUE);
  check_backward_sentence_start (" Hi."11FALSE);
  check_backward_sentence_start (" Hi."00FALSE);
}

static void
test_backward_line (void)
{
  GtkTextBuffer *buffer;
  GtkTextIter iter, start, end;
  gboolean ret;
  int offset;

  buffer = gtk_text_buffer_new (NULL);
  gtk_text_buffer_get_start_iter (buffer, &iter);
  gtk_text_buffer_insert (buffer, &iter, "Hi line 1\nHi line 2", -1);

  /* Go to middle of first line */
  gtk_text_iter_backward_line (&iter);
  gtk_text_iter_set_line_offset (&iter, 4);

  /* Now insert some chars with gtk_text_buffer_insert_range() */
  gtk_text_buffer_get_end_iter (buffer, &end);
  start = end;
  gtk_text_iter_backward_cursor_positions (&start, 5);
  gtk_text_buffer_insert_range (buffer, &iter, &start, &end);

  /* Check we are still at the first line */
  g_assert_cmpint (gtk_text_iter_get_line (&iter), ==, 0);

  /* Now a call to gtk_text_iter_backward_line() should return TRUE
     and move &iter to start of the line, or return FALSE if &iter
     was already at start of the line, so in both cases &iter should
     be at the start of the line, so check that */

  ret = gtk_text_iter_backward_line (&iter);
  g_assert_true (ret);
  offset = gtk_text_iter_get_line_offset (&iter);
  g_assert_cmpint (offset, ==, 0);

  g_object_unref (buffer);
}

static void
test_invisible_text (void)
{
  GtkTextBuffer *buffer;
  GtkTextIter iter, end;
  GtkTextTag *tag;
  GtkTextTagTable *tags;
  char *text;

  buffer = gtk_text_buffer_new (NULL);

  tag = gtk_text_tag_new ("invisible");

  tags = gtk_text_buffer_get_tag_table (buffer);
  g_object_set (tag, "invisible"TRUE, NULL);
  gtk_text_tag_table_add (tags, tag);
  gtk_text_buffer_get_start_iter (buffer, &iter);
  gtk_text_buffer_insert (buffer, &iter, "one ", -1);
  gtk_text_buffer_insert_with_tags_by_name (buffer, &iter, "two three", -1"invisible", NULL);
  gtk_text_buffer_insert (buffer, &iter, " four", -1);

  gtk_text_buffer_get_start_iter (buffer, &iter);
  gtk_text_buffer_get_end_iter (buffer, &end);

  gtk_text_iter_forward_visible_word_end (&iter);

  text = gtk_text_buffer_get_text (buffer, &iter, &end, TRUE);
  g_assert_cmpstr (text, ==, " two three four");
  g_free (text);

  gtk_text_iter_forward_word_end (&iter);
  text = gtk_text_buffer_get_text (buffer, &iter, &end, TRUE);
  g_assert_cmpstr (text, ==, " three four");
  g_free (text);

  gtk_text_iter_forward_visible_word_end (&iter);
  text = gtk_text_buffer_get_text (buffer, &iter, &end, TRUE);
  g_assert_cmpstr (text, ==, " four");
  g_free (text);

  gtk_text_iter_forward_visible_word_end (&iter);
  g_assert_true (gtk_text_iter_equal (&iter, &end));

  g_object_unref (buffer);
}

int
main (int argc, char** argv)
{
  gtk_test_init (&argc, &argv);

  g_test_add_func ("/TextIter/Search Empty", test_empty_search);
  g_test_add_func ("/TextIter/Search Full Buffer", test_search_full_buffer);
  g_test_add_func ("/TextIter/Search", test_search);
  g_test_add_func ("/TextIter/Search Caseless", test_search_caseless);
  g_test_add_func ("/TextIter/Forward To Tag Toggle", test_forward_to_tag_toggle);
  g_test_add_func ("/TextIter/Forward To Line End", test_forward_to_line_end);
  g_test_add_func ("/TextIter/Word Boundaries", test_word_boundaries);
  g_test_add_func ("/TextIter/Visible Word Boundaries", test_visible_word_boundaries);
  g_test_add_func ("/TextIter/Cursor Positions", test_cursor_positions);
  g_test_add_func ("/TextIter/Visible Cursor Positions", test_visible_cursor_positions);
  g_test_add_func ("/TextIter/Sentence Boundaries", test_sentence_boundaries);
  g_test_add_func ("/TextIter/Backward line", test_backward_line);
  g_test_add_func ("/TextIter/Invisible text", test_invisible_text);

  return g_test_run();
}

Messung V0.5 in Prozent
C=100 H=92 G=95

¤ Dauer der Verarbeitung: 0.17 Sekunden  (vorverarbeitet am  2026-07-02) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Quellcodebibliothek
     Eigene Quellcodes
     Fremde Quellcodes
     Suchen

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik