diff options
Diffstat (limited to 'src/Fl_Terminal.cxx')
| -rw-r--r-- | src/Fl_Terminal.cxx | 37 |
1 files changed, 27 insertions, 10 deletions
diff --git a/src/Fl_Terminal.cxx b/src/Fl_Terminal.cxx index fea9f4121..150cb6641 100644 --- a/src/Fl_Terminal.cxx +++ b/src/Fl_Terminal.cxx @@ -29,7 +29,6 @@ #include <string.h> // strlen #include <stdarg.h> // vprintf, va_list #include <assert.h> -#include <string> #include <FL/Fl.H> #include <FL/Fl_Terminal.H> @@ -3988,28 +3987,46 @@ int Fl_Terminal::handle(int e) { \return A string allocated with strdup(3) which must be free'd, text is UTF-8. */ const char* Fl_Terminal::text(bool lines_below_cursor) const { - std::string lines; // lines of text we'll return + // Dynamic buffer for lines of text we'll return + int buf_alloc = 4096; + int buf_len = 0; + char *lines = (char*)malloc(buf_alloc); + if (!lines) return 0; + lines[0] = '\0'; + // See how many display rows we need to include int disprows = lines_below_cursor ? disp_rows() - 1 // all display lines : cursor_row(); // only lines up to cursor // Start at top of 'in use' history, and walk to end of display int srow = hist_use_srow(); // start row of text to return int erow = srow + hist_use() + disprows; // end row of text to return - for (int row=srow; row<=erow; row++) { // walk rows + int row; + for (row=srow; row<=erow; row++) { // walk rows const Utf8Char *u8c = u8c_ring_row(row); // start of row int trim = 0; - for (int col=0; col<ring_cols(); col++,u8c++) { // walk cols in row + int col; + for (col=0; col<ring_cols(); col++,u8c++) { // walk cols in row const char *s = u8c->text_utf8(); // first byte of char - for (int i=0; i<u8c->length(); i++) lines += *s++; // append all bytes in multibyte char + int charlen = u8c->length(); + // Ensure buffer has space + if (buf_len + charlen + 2 > buf_alloc) { + buf_alloc *= 2; + char *newbuf = (char*)realloc(lines, buf_alloc); + if (!newbuf) { free(lines); return 0; } + lines = newbuf; + } + int i; + for (i=0; i<charlen; i++) lines[buf_len++] = *s++; // append all bytes in multibyte char // Count any trailing whitespace to trim - if (u8c->length()==1 && s[-1]==' ') trim++; // trailing whitespace? trim - else trim = 0; // non-whitespace? don't trim + if (charlen==1 && s[-1]==' ') trim++; // trailing whitespace? trim + else trim = 0; // non-whitespace? don't trim } // trim trailing whitespace from each line, if any - if (trim) lines.resize(lines.size() - trim); - lines += "\n"; + if (trim) buf_len -= trim; + lines[buf_len++] = '\n'; } - return fl_strdup(lines.c_str()); + lines[buf_len] = '\0'; + return lines; // caller must free() } /** |
