Mercurial > octave
changeset 21083:8c9755d29d2a
Fix overflowing feedback buffers (bug #46417).
* gl2ps-renderer.h (glps_renderer::draw_axes): handle errors, warnings
and overflows after gl2psEndViewport.
* gl2ps-renderer.h (glps_renderer::buffer_overflow): new bool attribute.
* gl2ps-renderer.cc (glps_renderer::draw): make use of buffer_overflow to
detect overflows and increase buffer size by a factor of 2 instead of a
fixed amount of 1Mb.
* gl2ps-renderer.cc (glps_renderer::draw): pass a temporary file to gl2ps and
copy its content to the actual pipe/file stream after successfull run
* gl2ps-renderer.cc (glps_renderer::draw): remove error checking after
gl2psEndPage
* bootstrap.conf: add gnulib "ftruncate", necessary to discard content of
the temporary file
author | Pantxo Diribarne <pantxo.diribarne@gmail.com> |
---|---|
date | Sun, 03 Jan 2016 10:01:31 +0100 |
parents | 4484384a2959 |
children | 83ce7b8fb91c |
files | bootstrap.conf libinterp/corefcn/gl2ps-renderer.cc libinterp/corefcn/gl2ps-renderer.h |
diffstat | 3 files changed, 40 insertions(+), 22 deletions(-) [+] |
line wrap: on
line diff
--- a/bootstrap.conf Sat Jan 16 15:33:45 2016 -0800 +++ b/bootstrap.conf Sun Jan 03 10:01:31 2016 +0100 @@ -47,6 +47,7 @@ frexpf fseek ftell + ftruncate getcwd gethostname getopt-gnu
--- a/libinterp/corefcn/gl2ps-renderer.cc Sat Jan 16 15:33:45 2016 -0800 +++ b/libinterp/corefcn/gl2ps-renderer.cc Sun Jan 03 10:01:31 2016 +0100 @@ -38,6 +38,7 @@ #include "gl2ps.h" #include "sysdep.h" +#include "unistd.h" void glps_renderer::draw (const graphics_object& go, const std::string& print_cmd) @@ -80,11 +81,22 @@ if (term.find ("is2D") != std::string::npos) gl2ps_sort = GL2PS_SIMPLE_SORT; - GLint state = GL2PS_OVERFLOW; - GLint buffsize = 0; + // Use a temporary file in case an overflow happens + FILE* tmpf = gnulib::tmpfile (); + + if (! tmpf) + error ("glps_renderer::draw: couldn't open temporary file for printing"); - while (state == GL2PS_OVERFLOW) + GLint buffsize = 2*1024*1024; + buffer_overflow = true; + + while (buffer_overflow) { + buffer_overflow = false; + buffsize *= 2; + gnulib::fseek (tmpf, 0, SEEK_SET); + gnulib::ftruncate (fileno (tmpf), 0); + // For LaTeX output the fltk print process uses 2 drawnow() commands. // The first one is for the pdf/ps/eps graph to be included. The // print_cmd is saved as old_print_cmd. Then the second drawnow() @@ -111,8 +123,6 @@ else include_graph = "foobar-inc"; - buffsize += 1024*1024; - // GL2PS_SILENT was removed to allow gl2ps printing errors on stderr GLint ret = gl2psBeginPage ("glps_renderer figure", "Octave", 0, gl2ps_term, gl2ps_sort, @@ -123,31 +133,33 @@ | GL2PS_NO_PS3_SHADING | GL2PS_USE_CURRENT_VIEWPORT), GL_RGBA, 0, 0, 0, 0, 0, - buffsize, fp, include_graph.c_str ()); + buffsize, tmpf, include_graph.c_str ()); if (ret == GL2PS_ERROR) { old_print_cmd.clear (); error ("gl2ps-renderer::draw: gl2psBeginPage returned GL2PS_ERROR"); } - old_print_cmd = print_cmd; - opengl_renderer::draw (go); - // Without glFinish () there may be primitives missing in the - // gl2ps output. - glFinish (); + if (! buffer_overflow) + old_print_cmd = print_cmd; - state = gl2psEndPage (); + // Don't check return value of gl2psEndPage, it is not meaningful. + // Errors and warnings are checked after gl2psEndViewport in + // glps_renderer::draw_axes instead. + gl2psEndPage (); + } - if (state == GL2PS_ERROR) - { - old_print_cmd.clear (); - error ("gl2ps-renderer::draw: gl2psEndPage returned GL2PS_ERROR"); - } - - // Don't check state for GL2PS_UNINITIALIZED (should never happen) - // GL2PS_OVERFLOW (see while loop) or GL2PS_SUCCESS + // Copy temporary file to pipe + gnulib::fseek (tmpf, 0, SEEK_SET); + char str[256]; + int nread = 1; + while (! feof (tmpf) && nread) + { + nread = gnulib::fread (str, 1, 256, tmpf); + if (nread) + gnulib::fwrite (str, 1, nread, fp); } } else
--- a/libinterp/corefcn/gl2ps-renderer.h Sat Jan 16 15:33:45 2016 -0800 +++ b/libinterp/corefcn/gl2ps-renderer.h Sun Jan 03 10:01:31 2016 +0100 @@ -37,7 +37,7 @@ public: glps_renderer (FILE *_fp, const std::string& _term) : opengl_renderer () , fp (_fp), term (_term), fontsize (), - fontname () { } + fontname (), buffer_overflow (false) { } ~glps_renderer (void) { } @@ -66,7 +66,11 @@ // Finalize viewport GLint state = gl2psEndViewport (); if (state == GL2PS_NO_FEEDBACK) - warning ("gl2ps-renderer::draw: empty feedback buffer and/or nothing else to print"); + warning ("glps_renderer::draw_axes: empty feedback buffer and/or nothing else to print"); + else if (state == GL2PS_ERROR) + error ("glps_renderer::draw_axes: gl2psEndPage returned GL2PS_ERROR"); + + buffer_overflow |= (state == GL2PS_OVERFLOW); } void draw_text (const text::properties& props); @@ -115,6 +119,7 @@ caseless_str term; double fontsize; std::string fontname; + bool buffer_overflow; }; #endif