Mercurial > hg > octave-nkf
diff src/utils.cc @ 4302:ebc2d8e4968b
[project @ 2003-01-22 22:02:23 by jwe]
author | jwe |
---|---|
date | Wed, 22 Jan 2003 22:02:23 +0000 |
parents | 4e2d2516da22 |
children | 1e7f4405e037 |
line wrap: on
line diff
--- a/src/utils.cc +++ b/src/utils.cc @@ -44,6 +44,8 @@ #include <setjmp.h> +#include "quit.h" + #include "dir-ops.h" #include "file-ops.h" #include "file-stat.h" @@ -858,7 +860,13 @@ std::streambuf *sb = os.rdbuf (); if (sb) - retval = sb->vform (fmt, args); + { + BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; + + retval = sb->vform (fmt, args); + + END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; + } #else @@ -876,6 +884,115 @@ return retval; } +/* XXX FIXME XXX -- we really need a configure test for this. */ + +#if defined __GNUC__ && __GNUC__ >= 3 +#define HAVE_C99_VSNPRINTF 1 +#endif + +// We manage storage. User should not free it, and its contents are +// only valid until next call to vsnprintf. + +// Interrupts might happen if someone makes a call with something that +// will require a very large buffer. If we are interrupted in that +// case, we should make the buffer size smaller for the next call. + +#define BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE_FOR_VSNPRINTF \ + BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE_1; \ + delete [] buf; \ + buf = 0; \ + size = initial_size; \ + octave_throw_interrupt_exception (); \ + BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE_2 + +char * +octave_vsnprintf (const char *fmt, va_list args) +{ + static const size_t initial_size = 100; + + static size_t size = initial_size; + + static char *buf = 0; + + size_t nchars; + + if (! buf) + buf = new char [size]; + + if (! buf) + return 0; + +#if defined (HAVE_C99_VSNPRINTF) + + BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE_FOR_VSNPRINTF; + + nchars = octave_raw_vsnprintf (buf, size, fmt, args); + + END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; + + if (nchars >= size) + { + size = nchars + 1; + + delete [] buf; + + buf = new char [size]; + + if (buf) + { + BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE_FOR_VSNPRINTF; + + vsnprintf (buf, size, fmt, args); + + END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; + } + } + +#else + + while (1) + { + BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE_FOR_VSNPRINTF; + + nchars = octave_raw_vsnprintf (buf, size, fmt, args); + + END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; + + if (nchars > -1) + return buf; + else + { + delete [] buf; + + size *= 2; + + buf = new char [size]; + + if (! buf) + return 0; + } + } + +#endif + + return buf; +} + +char * +octave_snprintf (const char *fmt, ...) +{ + char *retval = 0; + + va_list args; + va_start (args, fmt); + + retval = octave_vsnprintf (fmt, args); + + va_end (args); + + return retval; +} + void octave_sleep (double seconds) {