f



How does the Tcl interpret handle results returned from C-created Tcl commands ?

I've ventured on creating a Tcl command trough a C routine. I've
followed the manual guidelines.
My C routine checks the validity of a selected option for the currently
displayed histogram.
Therefore it returns a Boolean value  that, according to the C <-> Tcl
communucation protocol, I have encoded as  TCL_ERROR (= FALSE) and
TCL_OK (TRUE).
WHenthis command is called in a Tcl proc, the interpreter is supposed
to perform two different actions according to the returned Boolean
value.
How can I fetch this returned Boolean result (TCL_ERROR/ TCL_OK) from
the Tcl proc that executes the C-created command ?
What if I wrote 1 (FALSE) or 0 (TRUE) in a string and have the C
routine return this 1-character string ? Would it be easier to get the
result of the teest from the caling TCL
proc ?

Please, find in the following the code  that implements (according to
my best resolution)  the
C-created command  and the callind Tcl proc.

Thank you,
Maura

*************************************************************************************************************
*                                                     C routine
                                                          *
*************************************************************************************************************
static int
check_hist_aint_option_cb( ClientData clientData,
                           Tcl_Interp *interp,
                           int argc, char *argv[] ) {
  int i;

  if ( hg.active_ <= 0 ){
     Tcl_SetResult( interp,
                    "Histogram not active !",
                    TCL_STATIC );
     return TCL_ERROR;
  }

  i = -1
  while ((++i < Length_of_AINT_histo_ID) && (hg.hid_ !=
AINT_histo_ID[i])) ;
  if (i >= Length_of_AINT_histo_ID) {
     Tcl_SetResult( interp,
                    "Renormalization option unavailable for the current
histogram !",
                    TCL_STATIC );
     return TCL_ERROR;
  }
  return TCL_OK;
}


*************************************************************************************************************
*                                                  Tcl calling proc
                                                        *
*************************************************************************************************************

proc change_RZ_hist_aint {} {

    global aint


    if (check_hist_aint_option) {
      puts "\n current AINT value: $aint"
      delete_hist_bar;
      draw_hist_bar;
    }
    else
      tk_messageBox -default ok -type ok -icon error -message "AINT
does not apply to the current histogram" 
}

0
5/25/2006 4:29:19 AM
comp.lang.tcl 23428 articles. 2 followers. Post Follow

6 Replies
1040 Views

Similar Articles

[PageSpeed] 28

When writing Tcl commands in C, you need to make a distinction between
the "status code" and the return value.  Ironically, you provide the
status code with the [return] command, and you provide the return value
with Tcl_SetObjResult, Tcl_AppendResult, or some other such command.

I can see where you're going with your code; if you want to go that
route, you should do something like this:

    if {[catch {check_hist_aint_option}]} {
        # deal with the error
    } else {
        # proceed as normal
    }

Another alternative is to return TCL_OK as the status code in either
case, and return true or false as the result.  Something like:

    if (can_do_histogram) {
        Tcl_SetObjResult(interp, Tcl_NewBooleanObj(1));
    } else {
        Tcl_SetObjResult(interp, Tcl_NewBooleanObj(0));
    }
    return TCL_OK;

Your Tcl code can then go like this:

    if {[check_hist_aint_option]} {
        # proceed with histogram
    } else {
        # give negative feedback
    }

Does that help?

0
aric.bills (466)
5/25/2006 5:27:15 AM
Sure. It does help.
I will try the first alternative. I haven't quite digested the use of
Tcl  "objects" as a communication tool with C.

Thank you so  much,
Maura

0
5/25/2006 8:40:47 AM
Dnia 24 May 2006 21:29:19 -0700, maura.monville@gmail.com skrobie:
> I've ventured on creating a Tcl command trough a C routine. I've
> followed the manual guidelines.
> My C routine checks the validity of a selected option for the currently
> displayed histogram.
> Therefore it returns a Boolean value  that, according to the C <-> Tcl
> communucation protocol, I have encoded as  TCL_ERROR (= FALSE) and
> TCL_OK (TRUE).
> WHenthis command is called in a Tcl proc, the interpreter is supposed
> to perform two different actions according to the returned Boolean
> value.
> How can I fetch this returned Boolean result (TCL_ERROR/ TCL_OK) from
> the Tcl proc that executes the C-created command ?
> What if I wrote 1 (FALSE) or 0 (TRUE) in a string and have the C
> routine return this 1-character string ? Would it be easier to get the
> result of the teest from the caling TCL
> proc ?

The Tcl_SetResult sets the value that is returned by the command from the Tcl
side.

And the returned value by the C function that implements the command sets the
command's "status code", that is, it is something like "exceptions" in other
languages. The interpretation of this code depends on what is calling it. If
the returned value is TCL_OK, nothing happens. If the returned value is
TCL_ERROR then the "error" (or "1") status code is returned, which causes
abnormal execution termination. This can be next caught by the [catch]
command, which will set the result to the given variable name and return the
status code (in numerical convention, that is, 1 for TCL_ERROR).

You seemed also to use the [if] command incorrectly, so this is how you could
implement it:

if { [catch {check_hist_aint_option} result] != 0 } {
	puts "\n current AINT value: $aint"
	delete_hist_bar
	draw_hist_bar
} else {
	tk_messageBox ... -message "AINT does not apply to the current
histogram: $result"
}


-- 
//  _    ___         Michal "Sektor" Malecki <sektor(whirl)kis.p.lodz.pl>
\\ L_ |/ `|  /^\ ,()                         <ethourhs(O)gmail.com>
// \_ |\  \/ \_/ /\ C++ bez cholesterolu: http://www.intercon.pl/~sektor/cbx
"I am allergic to Java because programming in Java reminds me casting spells"
0
ethouris1 (65)
5/25/2006 8:54:27 AM
In article <1148531359.044694.114430@j33g2000cwa.googlegroups.com>,
maura.monville@gmail.com <maura.monville@gmail.com> wrote:
>I've ventured on creating a Tcl command trough a C routine. I've
>followed the manual guidelines.
			.
			.
			.
>static int
>check_hist_aint_option_cb( ClientData clientData,
>                           Tcl_Interp *interp,
>                           int argc, char *argv[] ) {
>  int i;
>
>  if ( hg.active_ <= 0 ){
>     Tcl_SetResult( interp,
>                    "Histogram not active !",
>                    TCL_STATIC );
>     return TCL_ERROR;
>  }
>
>  i = -1
>  while ((++i < Length_of_AINT_histo_ID) && (hg.hid_ !=
>AINT_histo_ID[i])) ;
>  if (i >= Length_of_AINT_histo_ID) {
>     Tcl_SetResult( interp,
>                    "Renormalization option unavailable for the current
>histogram !",
>                    TCL_STATIC );
>     return TCL_ERROR;
>  }
>  return TCL_OK;
>}
>
>
>*************************************************************************************************************
>*                                                  Tcl calling proc
>                                                        *
>*************************************************************************************************************
>
>proc change_RZ_hist_aint {} {
>
>    global aint
>
>
>    if (check_hist_aint_option) {
>      puts "\n current AINT value: $aint"
>      delete_hist_bar;
>      draw_hist_bar;
>    }
>    else
>      tk_messageBox -default ok -type ok -icon error -message "AINT
>does not apply to the current histogram" 
>}
>

Others have already helped with the direct questions you raised.
I think it important to add that you might be most satisfied in
the long term to concentrate on doing as much as possible in Tcl;
if I understand you correctly, there's no *functional* need to
resort to C as this example does.

If your aim is to learn the C interface, rather than achieve
particular algorithms, then, of course, we'll help you learn the
C interface.
0
claird (2363)
5/25/2006 1:12:20 PM
* "maura.monville@gmail.com" <maura.monville@gmail.com>
Whenever you write TCL code such as
    if {[some_c_routine]} { ... }
you implicitly assume that the routine returns TCL_OK, and the
interpreter result of calling the C routine is some boolean value.

If your C-code returns TCL_ERROR, the 'if' will not run at all, but
TCL will abort execution the proc containing that code.

So if you need the C code simply to determine yes/no, you would do it
like this:

    static int
    check_hist_aint_option_cb( ... ) {
      // default result is false
      int result = 0;
      // check our data structures
      if ( hg.active_ > 0 ) {
        for (int i = 0; i < Length_of_AINT_histo_ID; ++i) {
           if (hg.hid_ == AINT_histo_ID[i]) {
              // found something, result is true
              result = 1;
              break;
           }
        }
      }
      // set the result of calling this routine from TCL
      Tcl_SetObjResult(interp, Tcl_NewBooleanObj(result));
      // tell TCL we have performed our task succesfully
      return TCL_OK;
    }


| My C routine checks the validity of a selected option for the
| currently displayed histogram.  Therefore it returns a Boolean value
| that, according to the C <-> Tcl communucation protocol, I have
| encoded as TCL_ERROR (= FALSE) and TCL_OK (TRUE).

Returning TCL_ERROR or TCL_OK are meant as a means for TCL to find out
whether or not the C code has performed it's task successfully.
Returning TCL_ERROR or TCL_OK is *not* the result you will see in the
TCL code.

R'
0
ralfixx (1283)
5/25/2006 1:53:12 PM
In article <k2ngk3-fio.ln1@lairds.us>, I advised:
>In article <1148531359.044694.114430@j33g2000cwa.googlegroups.com>,
>maura.monville@gmail.com <maura.monville@gmail.com> wrote:
>>I've ventured on creating a Tcl command trough a C routine. I've
>>followed the manual guidelines.
>			.
>			.
>			.
>Others have already helped with the direct questions you raised.
>I think it important to add that you might be most satisfied in
>the long term to concentrate on doing as much as possible in Tcl;
>if I understand you correctly, there's no *functional* need to
>resort to C as this example does.
>
>If your aim is to learn the C interface, rather than achieve
>particular algorithms, then, of course, we'll help you learn the
>C interface.

I'm going to repeat myself.

Maura, I'm posting this as a follow-up in comp.lang.tcl, and
sending you a copy to your personal e-mail address.

You wrote me in personal e-mail
     "I feel much more comfortable with C and C++ and
     the traditional debuggers that apply to compiled
     code.

     Moreover, if I need to use a math function like
     log10, cos, exp, etc ... I could not find any of
     these features in the Tcl library ...."

I think you're making a mistake.

I understand that you're looking for the quickest, most certain
way to achieve results in a situation where your project lead is
accustomed to ... treating software development as unskilled,
mismnaged, fungible labor.  I understand that you have considerable
experience working with C and related languages and the debuggers
common in their use.  Tcl puzzles you, and you've been assigned a
base of source code which apparently was generated by a confused
mis-automation.

It's easy to sympathize with your decision to do as much work as
possible in C, rather than Tcl.

I can assure you that I, and several other contributors here, have
even more experience living through very similar situations.  I
have repeatedly been on teams that were more comfortable in C than
Tcl--several times, *I* was one of the programmers who felt that
way.  From everything I know, you're better off learning the 
relatively modest amount of Tcl you need to know to achieve the
results you're after.

I particularly emphasize:  I've seen the experiment where someone
says, "I know how to do this in C, so I'll just write a little 
C-Tcl interface, and that'll be quicker."  I've seen multiple
trials of that experiment.  They really don't work out that way.
By the time the person knows Tcl well enough to communicate cor-
rectly with the C side, he or she can typically write in pure Tcl.
There's no gain.  (Note to other readers:  there definitely are
cases where *teams* can divide labor so that one person concentrates
on C.  That is not Maura's situation.)

Finally, I'll transcribe a tclsh session that might interest you:
  % expr exp(1)
  2.71828182846
  % expr log(100.01)
  4.60527018099
  % expr log10(100.01)
  2.00004342728
  % expr cos(3.14)
  -0.999998731728

I summarize, again:  I strongly suspect you'll find the most 
ultimate satisfaction in learning enough of Tcl to code pure-Tcl
solutions to your tasks--or perhaps just to receive fragments
that others of us write.
0
claird (2363)
5/26/2006 2:24:21 PM
Reply: