Troubleshooting development

My function now needs to return a result but either

return rebInteger(result);

where result is my resulting unsigned long value and

return rebVoid();

both make the console exit and not responsive.

What could cause this behaviour? Could it be I forgot to rebRelease a value that ought to be rebReleased?

Because this

    rebElide("print [{Returning the integer result.}", rebI(result), "{}]");

    rebElide("print {ok!}");

    return rebInteger(result);
}

Resulting in ending like

>> g-signal-connect-data button1 "clicked" get-handle :f null null 0
Returning the integer result. 52  
ok!
arnold@Ubuntu:/r3n-c/build$ 

where input typed will no longer appear on the terminal screen..

So indeed I removed a couple of my assignments that were meant to display information about the passed arguments and now the function at least is returning its correct value again:

>> g-signal-connect-data button1 "clicked" get-handle :f null null 0
Returning the integer result. 52 
ok!
== 52

So this does make a difference.

Now how can I check the value of user_data that I pass in this C function?

static void self_signal_connect_helper(GtkWidget *widget,
                                       gpointer  user_data){

I know it is not null from this test:

if (user_data){
    rebElide("print {user_data not null}");
}

Are you running a debug build?

e.g. if you say assert(false) in your code does it terminate the program?

If you are not running a debug build, then it can frequently crash without telling you what is wrong.

But if you are running a debug build and seeing something like this, that is uncommon. I'd want to reproduce it myself and look at it.

Do you mean how do you printf a pointer value (e.g. 0x14EBACD2) or how do you print what the data points to? Use %p in a printf.

Presumably "gpointer" is an alias for void* of some sort?

If you want to print what it points to you'd have to cast it to the type of information it is, and that depends on what type the pointer is.

gpointer is the pointer type of GTK. It is just a pointer but with the GTK guard to be the same across platforms.

While I had my code working, hence the printout I could show, in some way or the other I cannot reproduce it. (yeah sucks!) So that is the reason I ask, so I can see more of what the box is doing before breaking.

How to manipulate a C variable from inside the rebAPI?

Given a REBVAL *value how can I set the value of a C integer int c_value ?

You do not change values. You always make new ones.

So all you do is build and unpack values. You don't fiddle the value of a REBVAL* itself.

REBVAL *reb_value = rebValue("1020");
int c_value = rebUnboxInteger(reb_value);
rebRelease(reb_value);

Or

 REBVAL *reb_value = rebValue("1020");
 int c_value = rebUnboxInteger(rebR(reb_value));

rebR is not the same thing as rebRelease, it's something you use that signals a delayed release done by the extraction functions. You must use it as an argument like that, or it won't work.

And the smart thing about the API is that these functions are not one trick ponies, you can always add code.

 REBVAL *reb_value = rebValue("1020");
 int c_value = rebUnboxInteger("304 +", rebR(reb_value));
1 Like

I would like to use the type of input data to help me decide which C function I should call next.

REBVAL *mydata = ARG(data);

rebElide("switch type of ", mydata, "[",
    "text! [print {data type is text!}]",
    "action! [print {data type is action!}]",
    "block! [print {data type is block!}]",
    "handle! [print {data type is handle!}]",
    "integer! [print {data type is integer!}]",
    "]"); 

so instead of the print {data type is type!} there would be an assignment of some sort so I could proceed within the C code with a switch to go and call the appropriate C function that handles that type of data.

While your example is very clear(!!) I still do not see how to accomplish this.

You can produce an integer and then switch on the integer.

int which = rebUnboxInteger("switch type of ", mydata, "[",
    "text! [1]",
    "action! [2]",
    "block! [3]",
    "handle! [4]",
    "integer! [5]",
"] else [0]");

switch (which) {
    case 0:  // unknown
    case 1:  // text
    case 2:  // action
    ...
}

Though I find it can be clearer if you use a character instead.

 char which = rebUnboxChar("switch type of ", mydata, "[",
    "text! [#T]",
    "action! [#A]",
    "block! [#B]",
    "handle! [#H]",
    "integer! [#I]",
"] else [#]");

switch (which) {
    case '\0':  // unknown
    case 'T': // text
    case 'A':  // action
        ...
}

There are some more creative options possible with C++ lambdas but I haven't gotten into that yet.

1 Like

Brilliant!

I had no clue that was even possible within the rebUnboxXXX functions!

Thanks!

1 Like