Re: Checking user-entered expressions for validity

From: Tom Roberts <tjrob_at_fnal.gov>
Date: Mon, 15 Jan 2007 13:58:54 -0600


It's even worse than I thought. If the user enters an invalid expression like "(", then Cint never returns from ProcessLineSync(), and moreover, all the functions involved are marked busy and the entire application ceases to work at all. The kludge using a TTimer catches some invalid expressions, but by no means all of them, and only occasionally does the application continue to work after an invalid expression (depends in detail on the type of error).

Is Cint always this hostile? Is there some mode I can put it in that will just return an error code when there is an error?

Unless someone has a solution to these Cint woes, it looks like I'll need a rather serious kludge to make this application reasonably robust. I've thought of these -- comments?

  1. implement an expression syntax checker by myself. This is quite a bit of work, and seems redundant with Cint available....
  2. never call Cint from the mainline program. Instead, always setup a TThread to call it, and a TTimer to fire if the thread bombs. This must be doubly-indirect so no function of my class is busy if Cint bombs; so I write a known-good function-loader file, load and execute it to create the thread that loads and executes the actual function which contains the user's expressions.

Any help would be appreciated -- this is driving me crazy.... is there any hope of getting Cint to behave sensibly on an error?

Tom Roberts

Tom Roberts wrote:
> In my Root application the user can enter several arbitrary expressions
> using any C functions and operators, and the branch names of a selected
> TNtuple (all names are valid C identifiers). It then creates a function
> scan() that will scan the TNtuple using these expressions, writing it to
> the file ".scan.C", and does:
> Int_t err=TInterpreter::kNoError;
> gROOT->ProcessLineSync(".L .scan.C",&err);
> if(err != TInterpreter::kNoError) {
> new TGMsgBox(gClient->GetRoot(),window,"Error",
> "Invalid Expression(s)");
> return false;
> }
> scan(); // call the generated function
>
> This works fine as long as the expressions are valid. Unfortunately, if
> any expression is invalid, Cint prints an error message to stderr and
> never returns from ProcessLineSync(). To the user this is disconcerting,
> as no sensible error message is presented (the user probably won't watch
> stderr, which may not be visible in a graphical environment).
>
> How can I get Cint to return to the program when there is an error
> loading the file?
>
> Alternatively, how can I test the individual expressions for validity?
> -- all my attempts have failed, either Cint does not return an error for
> an invalid expression (!), or it does not return from ProcessLineSync(),
> or it goes crazy: When I tried this Cint got into a strange state that
> could not write any files or do anything useful:
> Int_t err=-99;
> char *str = "{\nfloat x,y;\n.p x+y;\n}\n";
> gROOT->ProcessLineSync(str,&err);
> Omitting the braces makes it merely not return when an invalid
> expression is given.
>
> Do I need to follow Rube Goldberg and:
> set a timer for 500 ms in the future
> call ProcessLineSync()
> clear the timer if it returns success
> ... display an error MsgBox if the timer fires
>
>
> Note this is always done in response to a GUI button push, and the fact
> that ProcessLineSync() does not return does not seem to bother the
> application.
>
> This is Root version 5.12/00.
>
>
> Tom Roberts
>
Received on Mon Jan 15 2007 - 20:59:22 CET

This archive was generated by hypermail 2.2.0 : Tue Jan 16 2007 - 05:50:00 CET