slang-users mailing list

[2021 Date Index] [2021 Thread Index] [Other years]
[Thread Prev] [Thread Next]      [Date Prev] [Date Next]

Re: [slang-users] Is there a better way for two-type argument?


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]