X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fui%2Fgui%2Fpsppire-lex-reader.c;h=b34edf97b7ce430432e0f8af3a6755b6a6dc89c5;hb=588d9107cd4b6eee3a0c3ece3cf53868e22c52f4;hp=5afd10158beab236e749673e0573b4fd367e0e3c;hpb=5825b0b870739af3760c07138bed50e99db788ae;p=pspp diff --git a/src/ui/gui/psppire-lex-reader.c b/src/ui/gui/psppire-lex-reader.c index 5afd10158b..b34edf97b7 100644 --- a/src/ui/gui/psppire-lex-reader.c +++ b/src/ui/gui/psppire-lex-reader.c @@ -26,15 +26,24 @@ #include "libpspp/cast.h" +#include "gl/minmax.h" + static const struct lex_reader_class lex_gtk_text_buffer_reader_class ; struct lex_gtk_text_buffer_reader { struct lex_reader reader; + + /* The GtkTextBuffer from which we are reading. */ GtkTextBuffer *buffer; GtkTextIter start; GtkTextIter stop; + + /* Text pulled from part of the GtkTextBuffer. */ + gchar *part; + gsize part_len; /* Number of bytes in 'part'. */ + gsize part_ofs; /* Current offset into 'part'. */ }; static struct lex_gtk_text_buffer_reader * @@ -45,11 +54,15 @@ lex_gtk_text_buffer_reader_cast (struct lex_reader *r) struct lex_reader * -lex_reader_for_gtk_text_buffer (GtkTextBuffer *buffer, GtkTextIter start, GtkTextIter stop) +lex_reader_for_gtk_text_buffer (GtkTextBuffer *buffer, + GtkTextIter start, GtkTextIter stop, + enum segmenter_mode syntax_mode) { struct lex_gtk_text_buffer_reader *r = xmalloc (sizeof *r); lex_reader_init (&r->reader, &lex_gtk_text_buffer_reader_class); + r->reader.syntax = syntax_mode; + r->reader.line_number = gtk_text_iter_get_line (&start) + 1; r->buffer = buffer; g_object_ref (buffer); @@ -57,6 +70,10 @@ lex_reader_for_gtk_text_buffer (GtkTextBuffer *buffer, GtkTextIter start, GtkTex r->start = start; r->stop = stop; + r->part = NULL; + r->part_len = 0; + r->part_ofs = 0; + return &r->reader; } @@ -66,26 +83,38 @@ lex_gtk_text_buffer_read (struct lex_reader *r_, char *buf, size_t n, enum prompt_style prompt_style UNUSED) { struct lex_gtk_text_buffer_reader *r = lex_gtk_text_buffer_reader_cast (r_); - int n_chars = n; - char *s; + gsize chunk; + + if (r->part_ofs == r->part_len) + { + /* Read up to N characters into r->part. N characters might be more than + N bytes, but that's OK: we'll just buffer up some of those bytes for + the next read. */ + int n_chars = n; + + GtkTextIter iter = r->start ; + + int offset = gtk_text_iter_get_offset (&iter); + int end_offset = gtk_text_iter_get_offset (&r->stop); - GtkTextIter iter = r->start ; - - int offset = gtk_text_iter_get_offset (&iter); - int end_offset = gtk_text_iter_get_offset (&r->stop); + if (end_offset - offset < n) + n_chars = end_offset - offset; - if ( end_offset - offset < n) - n_chars = end_offset - offset; - - gtk_text_iter_set_offset (&iter, offset + n_chars); + gtk_text_iter_set_offset (&iter, offset + n_chars); - s = gtk_text_iter_get_text (&r->start, &iter); + g_free (r->part); + r->part = gtk_text_iter_get_text (&r->start, &iter); + r->part_len = strlen (r->part); + r->part_ofs = 0; - strcpy (buf, s); + r->start = iter; + } - r->start = iter; + chunk = MIN (r->part_len - r->part_ofs, n); + memcpy (buf, r->part + r->part_ofs, chunk); + r->part_ofs += chunk; - return strlen (s); + return chunk; } @@ -96,6 +125,8 @@ lex_gtk_text_buffer_close (struct lex_reader *r_) struct lex_gtk_text_buffer_reader *r = lex_gtk_text_buffer_reader_cast (r_); g_object_unref (r->buffer); + g_free (r->part); + g_free (r); }