- Subject: Re: [slang-users] Is there a better way for two-type argument?
- From: "John E. Davis" <jed@xxxxxxxxxxx>
- Date: Thu, 28 Jan 2021 00:01:03 -0500
Sebastian Gniazdowski <sgniazdowski@xxxxxxxxx> wrote:
> I'm utilizing ARRAY_2_VOIDP annotation to detect the actual type of an
> argument and fill the remaining 2 (being the alternate type vars). The arg
> map is below. I wonder if there is a better solution to allow passing
> either string or integer to a SLang function?
I have to admit that I am not that knowledgable about slirp; I have
always hand wrapped libraries.
With that said, are you trying to create a wrapper that calls one C
function if a string was passed, and a different C function if an
integer was passed? If so, then it seems to me that you should let
slirp wrap these two function separately, and then create a slang
function that would call the appropriate one based upon what was
passed to it. For example, suppse that your foo.h header file
contains the two function declarations:
extern void func_with_string_arg (char *str);
extern void func_with_int_arg (int v);
slirp will create a module "foo" that wraps these functions. You
would create a file (foo.sl) that loads the foo module:
% foo.sl: loads the foo module and adds additional functions
import ("foo");
define func_with_string_or_int_arg (arg)
{
if (typeof (arg) == String_Type)
return func_with_int_arg (arg);
else
return func_with_int_arg (arg);
}
Users of this module would load it using
require ("foo");
A number of the modules distributed with the library take this
approach. See, e.g., rand.sl or csv.sl in the slang distribution.
I think that this approach is a lot easier and less error prone than
trying to create a complicated argmap.
Finally, If I were going to manually wrap these functions as a single
one, I would do it this way:
static func_with_string_or_int_arg (void)
{
int v;
char *str = NULL;
switch (SLang_peek_at_stack ())
{
case SLANG_STRING_TYPE:
case SLANG_BSTRING_TYPE:
if (0 == SLang_pop_slstring (&str))
{
func_with_string_arg (str);
SLang_free_slstring (str);
}
return;
default:
if (0 == SLang_pop_int (&v))
{
func_with_int_arg (v);
return;
}
}
}
I apologize for not being able to provide a direct answer to your
question.
Thanks,
--John
> % Allow a function (action()) to be called with either string or an integer
> as its first
> % argument and drop the last two. String is an action name (like
> "EditFile"), while integer is the CK_ enum code.
> #argmap(in, which=1, proxy=SLang_Array_Type) (void *ARRAY_2_VOIDP, char
> *action_name, long action_code)
> {
> /* Called with string argument? */
> if (proxy->data_type == SLANG_STRING_TYPE) {
> $2 = *((char**)proxy->data);
> $3 = -1;
> } else {
> /* It's certain that no string will be passed. */
> $2 = NULL;
> /* Called with a long argument? */
> if (proxy->data_type == SLANG_LONG_TYPE)
> $3 = *((long*)proxy->data);
> /* Called with an integer argument? */
> else if (proxy->data_type == SLANG_INT_TYPE)
> $3 = *((int*)proxy->data);
> /* Unknown type passed as argument – signal/mark the error with
> a special value. */
> else
> $3 = 0xbadc0de;
> }
> /*
> * The first parameter is only a placeholder of the void *
> arbitrary type argument
> * on S-Lang side, it's unused on C side.
> */
> $1 = 0;
> }
> #end
>
> --
> Sebastian Gniazdowski
_______________________________________________
For list information, visit <http://jedsoft.org/slang/mailinglists.html>.
[2021 date index]
[2021 thread index]
[Thread Prev] [Thread Next]
[Date Prev] [Date Next]