octave-maintainers
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: quit() implementation


From: Jaroslav Hajek
Subject: Re: quit() implementation
Date: Tue, 26 May 2009 10:58:59 +0200

On Tue, May 26, 2009 at 10:22 AM, Michael Goffioul
<address@hidden> wrote:
> On Tue, May 26, 2009 at 8:23 AM, Jaroslav Hajek <address@hidden> wrote:
>> The drawback, however, is that probably few C++ apps will be ready for
>> this; so instead of unwanted (yet relatively clean) exits via system
>> exit() we will get unhandled exceptions resulting usually in abort()
>> (and, I believe, confused mails :). I believe that most embedding
>> applications simply don't want quit() at all, because it makes no good
>> sense. That's why I have made another change: when octave is run in
>> embedded mode (octave_main is called with the "embedded" flag), the
>> built-in function quit() is disabled by default (calling it results in
>> an error). This is controllable by the global flag quit_allowed in
>> toplev.h. After all, interrupts are allowed neither (by default) in
>> embedded mode, and quit() can be seen as a kind of interrupt.
>
> Does that mean that typing "quit" at octave prompt in an IDE
> (where the embedded flag is used) won't quit octave?

Yes. Because the 2) and 3) cases you describe below are currently
undistinguishable.

> Looking at the code, it seems you can overwrite that by changing
> quit_allowed after calling octave_main(), is that right?

Yes.

>> I think the current solution is definitely best than the previous
>> state (where you simply had no choice), and it seems a reasonable
>> compromise to me.
>> But maybe someone has a better idea how to do the whole thing, or a
>> good argument why I completely screwed things up with this.
>
> I think we should first ask ourselves what's the meaning of the "embedded"
> argument of octave_main(). I see 3 types of octave run:
> 1) in a normal shell, on the command-line, running the main loop
> 2) in an IDE (or anything else), but inside a virtual terminal,
> running the normal main loop
> 3) in another app, not running the main loop (like an embedded "engine")
>
> Does "embedded" cover 2) and 3)? Or just 3)?

Both, I think. Currently, the cases are undistinguishable, though. It
seems to me that considering 3) as the default causes less harm. In an
IDE, you may want to react specially to quit() anyway.

> Depending on the target, you may want to enable/disable quit(),
> the system exit() and the octave final cleanup.

Yes. Currently, I think the best strategy for an IDE is:
1 . call octave_main with embedded=true,
2. set quit_allowed = true,
3. possibly override octave_exit to raise an internal flag. If there's
no need to distinguish quit()
    from end-of-input, just set octave_exit = null.
4. call main_loop.
5. terminate

When quit() is called inside octave, main_loop will do a correct
terminate sequence except the
actual system call to exit() - user's octave_exit will be called
instead, if it is non-null.

The only minor drawback is that quit() will trigger an error during
the startup sequence (which I think is a bug anyway). This could be
avoided if octave_main gets another parameter, but will imply that
user needs to check for
the octave_exit call after octave_main. I'm not sure it's worth the
trouble, but it would be a minor and straightforward change.

> I think your latest proposal targets 3), but it's configurable and you can
> easily turn it into 2) (though I didn't test). So I think it should be fine.

Yes, exactly.

> However, speaking about this
> issue, I'd like to mention a problem I had with your previous change in
> OctaveDE, when John turned the embedded flag to true. I got a MSVC
> crash in "octave_restart()" (AKA yyrestart), because of invalid octave_in
> FILE*. The full stack is (from memory):
>
> isatty (or fileno, I'm not sure as MSVC was not verbose about it)
> octave_init_buffer
> octave_create_buffer
> octave_restart
> reset_parser
> main_loop
>
> Although it shouldn't crash (that's probably MSVC specific). it denotes
> a problem, and a difference in initialization when using the embedded flag.
> I tracked that down to those lines in octave_main:
>
>  if (! embedded)
>    switch_to_buffer (create_buffer (get_input_from_stdin ()));
>
> It seems those lines reset the parser in a correct state (after reading
> all initialization files). And when embedded is true, it leaves the parser in
> an invalid state (debugging revealed that fileno(octave_in) == -1 when
> reaching octave_init_buffer).
>
> Note that it's possible that the problem is in the flex version I'm using
> (2.5.33, I think; it's the default one in MSYS), and not in octave. But
> I wanted to mention that problem, and the fact that:
>
>    octave_main(..., false);
>
> is not 100% equivalent to
>
>    octave_main(..., true);
>    main_loop();
>
> Bye,
> Michael.
>

Yes. Another difference is that interrupt handlers are not installed.
And now there's one more: the initial status of quit_allowed. Maybe
rather than a single flag we could have an enum { NORMAL, IDE,
EMBEDDED }.

regards

-- 
RNDr. Jaroslav Hajek
computing expert & GNU Octave developer
Aeronautical Research and Test Institute (VZLU)
Prague, Czech Republic
url: www.highegg.matfyz.cz



reply via email to

[Prev in Thread] Current Thread [Next in Thread]