Wrap a C Function with Variable Length Argument List

How to wrap a C function with variable length argument list?

I can see the “printf” example, using a flat tuple, and something like “
types”, together with some facilities written in C as indicated here:

http://xrats.illtyped.com/ats/ats029/prelude/CATS/printf.cats
http://xrats.illtyped.com/ats/ats029/prelude/SATS/printf.sats

I appreciate it a lot if someone could explain more details.

Thank you!

I am trying to do it in another way, but I got into another trouble.

What I am trying to do is to prepare a command in some function like

fun redis_command_prepare {ts: types} (fmt: printf_c (ts), args: ts):
string = let
val cmd = sprintf (fmt, args)
in
string_of_strptr (cmd)
end

But it gives me type mismatch error

mismatch of static terms (tyleq):
The needed term is: S2Evararg(S2Evar(ts(2611)))
The actual term is: S2Eapp(S2Ecst(va_list_types_viewt0ype);
S2Evar(ts(2611)))
exit(ATS): uncaught exception:
ATS_2d0_2e2_2e10_2src_2ats_error_2esats__FatalErrorException(1027)

I’ve discussed this with Alex, but we can’t figure it out. What do you
think?

But in this way, there’s no type checking at all.

Maybe it is better to implement redis_command_prepare in C and then give it
a type in ATS.
While it is possible to do it in ATS, it is quite involved and whatever
gain you may get is quite limited.

OK, I will try this one, and come back later.

Thanks a lot.

I have not made any progress on this issue. Also, stdarg.sats
is yet to be supported in ATS2.

Handling variadic functions like printf is planned to be addressed as an
issue of meta-programming.

For now, please call scanf and fprintf externally by using $extfcall. Scanf
will be difficult to handled
anyway.On Monday, May 12, 2014 8:13:32 PM UTC-4, Brandon Barker wrote:

Any updates on this topic? Primarily just curious about what the best way
to call multityped c-variadic functions is, as I’m about to do a lot of it
(e.g. scanf and fprintf - and am hoping the answer is not to create a
separate function for each).

I don’t see stdarg.sats anymore - any suggested examples?

On Tuesday, July 30, 2013 4:02:20 PM UTC-4, Steinway Wu wrote:

As I mentioned in our private talk, it’s really not easy to type check
the format string with all parameters, since they are not one-one mapping.
I will try something else.

As to the first limitation, could this be handled by using a full-fledged
tokenizer rather than a functional list only?

Brandon Barker
brandon…@gmail.comOn Mon, May 12, 2014 at 10:26 PM, gmhwxi gmh...@gmail.com wrote:

Thanks for the link.

The approach is largely based on the one by Olivier Danvy.
Its limitation is well-known (e.g., it does not support non-static format
strings).
Supporting something like printf (“%2.2d”, …) would be harder.

Also, supporting scanf would be much harder due to the need for
error-handling.
Actually, printf also needs error-handling; supporting it in Idris, I
think, can be a real
challenge.

On Monday, May 12, 2014 8:18:14 PM UTC-4, Chris Double wrote:

On Tue, May 13, 2014 at 12:13 PM, Brandon Barker brand...@gmail.com wrote:

Any updates on this topic? Primarily just curious about what the best
way to
call multityped c-variadic functions is, as I’m about to do a lot of it
(e.g. scanf and fprintf - and am hoping the answer is not to create a
separate function for each).
github githwxi

I create a separate function but it’s a bit of a pain. It’d be
wonderful if it was as easy as this Idris example:

https://www.youtube.com/watch?v=fVBck2Zngjo


http://www.bluishcoder.co.nz


You received this message because you are subscribed to the Google Groups
“ats-lang-users” group.
To unsubscribe from this group and stop receiving emails from it, send an
email to ats-lang-user...@googlegroups.com.
To post to this group, send email to ats-lan...@googlegroups.com.
To view this discussion on the web visit
https://groups.google.com/d/msgid/ats-lang-users/c30f0c75-bfc0-4e0f-934c-c12daffd5114%40googlegroups.comhttps://groups.google.com/d/msgid/ats-lang-users/c30f0c75-bfc0-4e0f-934c-c12daffd5114%40googlegroups.com?utm_medium=email&utm_source=footer
.

As I mentioned in our private talk, it’s really not easy to type check the
format string with all parameters, since they are not one-one mapping. I
will try something else.

Any updates on this topic? Primarily just curious about what the best way
to call multityped c-variadic functions is, as I’m about to do a lot of it
(e.g. scanf and fprintf - and am hoping the answer is not to create a
separate function for each).

I don’t see stdarg.sats anymore - any suggested examples?On Tuesday, July 30, 2013 4:02:20 PM UTC-4, Steinway Wu wrote:

As I mentioned in our private talk, it’s really not easy to type check the
format string with all parameters, since they are not one-one mapping. I
will try something else.

To do it in ATS is quite messy in ATS. I suggest not to do it. Instead, one
can call C functions by
declaring extern functions in ATS.

In ATS2, one can use $extfcall to call functions in C directly. Though it
is not type-safe, it is quite
convenient to do. E.g.,

val () = $extfcall (void, “printf”, “c = %c and i = %i”, ‘a’, 0)

Not any that I am aware of.On Monday, May 18, 2015 at 1:40:35 PM UTC-4, Steinway Wu wrote:

Is there any updates on this topic?

On Monday, July 29, 2013 at 2:26:25 PM UTC-4, Steinway Wu wrote:

How to wrap a C function with variable length argument list?

I can see the “printf” example, using a flat tuple, and something like "
types", together with some facilities written in C as indicated here:

http://xrats.illtyped.com/ats/ats029/prelude/CATS/printf.cats
http://xrats.illtyped.com/ats/ats029/prelude/SATS/printf.sats

I appreciate it a lot if someone could explain more details.

Thank you!

If it is just for a printf-like function, it is done as follows:

extern
fun fprintf{ts:types} (out: FILEref, fmt: printf_c (ts), args: ts)

For instance, the format string:

“c = %c and i = %i”

is given the type printf_c ((char, int)); so the typechecker makes sure
that the args following is of the type (char, int).

What is the example you are trying to handle?

To implement variadic functions, you need libc/SATS/stdarg.sats.

In this case, you need vsprintf. Take a look at vsprintf in
prelude/SATS/printf.sats

Well, the devil is always in the details.

Say you have parsed a format string like “%2.2f”. What do you do next?On Tuesday, May 13, 2014 9:15:21 AM UTC-4, Brandon Barker wrote:

To construct the fields of the format datatype, a parser could ignore
everything between the ‘%’ and the last encountered alphabetic character
in the word. This seems too obvious, so I’m probably missing something.

On 12 May 2014 22:47, “gmhwxi” <gmh...@gmail.com <javascript:>> wrote:

What do you mean by a full-fledged tokenizer?

On Monday, May 12, 2014 10:42:48 PM UTC-4, Brandon Barker wrote:

As to the first limitation, could this be handled by using a
full-fledged tokenizer rather than a functional list only?

Brandon Barker
brand...@gmail.com

On Mon, May 12, 2014 at 10:26 PM, gmhwxi gmh...@gmail.com wrote:

Thanks for the link.

The approach is largely based on the one by Olivier Danvy.
Its limitation is well-known (e.g., it does not support non-static
format strings).
Supporting something like printf (“%2.2d”, …) would be harder.

Also, supporting scanf would be much harder due to the need for
error-handling.
Actually, printf also needs error-handling; supporting it in Idris, I
think, can be a real
challenge.

On Monday, May 12, 2014 8:18:14 PM UTC-4, Chris Double wrote:

On Tue, May 13, 2014 at 12:13 PM, Brandon Barker brand...@gmail.com wrote:

Any updates on this topic? Primarily just curious about what the
best way to
call multityped c-variadic functions is, as I’m about to do a lot of
it
(e.g. scanf and fprintf - and am hoping the answer is not to create
a
separate function for each).
github githwxi

I create a separate function but it’s a bit of a pain. It’d be
wonderful if it was as easy as this Idris example:

https://www.youtube.com/watch?v=fVBck2Zngjo


http://www.bluishcoder.co.nz


You received this message because you are subscribed to the Google
Groups “ats-lang-users” group.
To unsubscribe from this group and stop receiving emails from it, send
an email to ats-lang...@googlegroups.com.
To post to this group, send email to ats-l...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/
msgid/ats-lang-users/c30f0c75-bfc0-4e0f-934c-c12daffd5114%
40googlegroups.comhttps://groups.google.com/d/msgid/ats-lang-users/c30f0c75-bfc0-4e0f-934c-c12daffd5114%40googlegroups.com?utm_medium=email&utm_source=footer
.


You received this message because you are subscribed to the Google Groups
“ats-lang-users” group.
To unsubscribe from this group and stop receiving emails from it, send an
email to ats-lang...@googlegroups.com <javascript:>.
To post to this group, send email to ats-l...@googlegroups.com<javascript:>
.
To view this discussion on the web visit
https://groups.google.com/d/msgid/ats-lang-users/97b2287c-6958-4570-aacc-d37e7486e9c5%40googlegroups.comhttps://groups.google.com/d/msgid/ats-lang-users/97b2287c-6958-4570-aacc-d37e7486e9c5%40googlegroups.com?utm_medium=email&utm_source=footer
.

OK…But I can’t do it this way, because I still need to ensure type safety
for the first argument. Any alternatives?

Hi, I come up with a working solution.

It seems that for most C libraries with variadic functions, they will
provide two kinds of functions together.

  1. redisCommand (redisContext *ctx, char *fmt, …) //this is the … form
  2. redisvCommand (redisContext *ctx, char *fmt, va_list args) //this is
    the va_list form

And we can use the second form.

In ATS, we write this

fun ats_redis_command {ts: types} (ctx: !redis_ctx_ptr, fmt: string, args:
ts): redis_reply_ptr = “mac#ats_redis_command_handler”

And embedded the following handler C code in ATS

#include <stdarg.h>
redisReply *ats_redis_command_handler (redisContext *ctx, char *fmt, …) {
va_list args;
va_start (args, fmt);
redisReply *reply = redisvCommand (ctx, fmt, args);
va_end (args);
return reply;
}

And it works.

To construct the fields of the format datatype, a parser could ignore
everything between the ‘%’ and the last encountered alphabetic character
in the word. This seems too obvious, so I’m probably missing something.On 12 May 2014 22:47, “gmhwxi” gmh...@gmail.com wrote:

What do you mean by a full-fledged tokenizer?

On Monday, May 12, 2014 10:42:48 PM UTC-4, Brandon Barker wrote:

As to the first limitation, could this be handled by using a full-fledged
tokenizer rather than a functional list only?

Brandon Barker
brand...@gmail.com

On Mon, May 12, 2014 at 10:26 PM, gmhwxi gmh...@gmail.com wrote:

Thanks for the link.

The approach is largely based on the one by Olivier Danvy.
Its limitation is well-known (e.g., it does not support non-static
format strings).
Supporting something like printf (“%2.2d”, …) would be harder.

Also, supporting scanf would be much harder due to the need for
error-handling.
Actually, printf also needs error-handling; supporting it in Idris, I
think, can be a real
challenge.

On Monday, May 12, 2014 8:18:14 PM UTC-4, Chris Double wrote:

On Tue, May 13, 2014 at 12:13 PM, Brandon Barker brand...@gmail.com wrote:

Any updates on this topic? Primarily just curious about what the best
way to
call multityped c-variadic functions is, as I’m about to do a lot of
it
(e.g. scanf and fprintf - and am hoping the answer is not to create a
separate function for each).
github githwxi

I create a separate function but it’s a bit of a pain. It’d be
wonderful if it was as easy as this Idris example:

https://www.youtube.com/watch?v=fVBck2Zngjo


http://www.bluishcoder.co.nz


You received this message because you are subscribed to the Google
Groups “ats-lang-users” group.
To unsubscribe from this group and stop receiving emails from it, send
an email to ats-lang...@googlegroups.com.
To post to this group, send email to ats-l...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/
msgid/ats-lang-users/c30f0c75-bfc0-4e0f-934c-c12daffd5114%
40googlegroups.comhttps://groups.google.com/d/msgid/ats-lang-users/c30f0c75-bfc0-4e0f-934c-c12daffd5114%40googlegroups.com?utm_medium=email&utm_source=footer
.


You received this message because you are subscribed to the Google Groups
“ats-lang-users” group.
To unsubscribe from this group and stop receiving emails from it, send an
email to ats-lang-user...@googlegroups.com.
To post to this group, send email to ats-lan...@googlegroups.com.
To view this discussion on the web visit
https://groups.google.com/d/msgid/ats-lang-users/97b2287c-6958-4570-aacc-d37e7486e9c5%40googlegroups.comhttps://groups.google.com/d/msgid/ats-lang-users/97b2287c-6958-4570-aacc-d37e7486e9c5%40googlegroups.com?utm_medium=email&utm_source=footer
.

Try to introduce an abstract type

abstype format (ts:types) = string

fun redisCommand {ts: types} (ctx: !redis_ctx_ptr, fmt: format(ts), args:
ts)

This at least shifts the burden to the user for creating a value of the
type format(ts) for some ts. For instance,
one may do:

castfn format_unsafe {ts:types} (fmt: string): format(ts)

But it is possible that one has other ways to construct format-values.

Is there any updates on this topic?On Monday, July 29, 2013 at 2:26:25 PM UTC-4, Steinway Wu wrote:

How to wrap a C function with variable length argument list?

I can see the “printf” example, using a flat tuple, and something like "
types", together with some facilities written in C as indicated here:

http://xrats.illtyped.com/ats/ats029/prelude/CATS/printf.cats
http://xrats.illtyped.com/ats/ats029/prelude/SATS/printf.sats

I appreciate it a lot if someone could explain more details.

Thank you!

What do you mean by a full-fledged tokenizer?On Monday, May 12, 2014 10:42:48 PM UTC-4, Brandon Barker wrote:

As to the first limitation, could this be handled by using a full-fledged
tokenizer rather than a functional list only?

Brandon Barker
brand...@gmail.com <javascript:>

On Mon, May 12, 2014 at 10:26 PM, gmhwxi <gmh...@gmail.com <javascript:>>wrote:

Thanks for the link.

The approach is largely based on the one by Olivier Danvy.
Its limitation is well-known (e.g., it does not support non-static format
strings).
Supporting something like printf (“%2.2d”, …) would be harder.

Also, supporting scanf would be much harder due to the need for
error-handling.
Actually, printf also needs error-handling; supporting it in Idris, I
think, can be a real
challenge.

On Monday, May 12, 2014 8:18:14 PM UTC-4, Chris Double wrote:

On Tue, May 13, 2014 at 12:13 PM, Brandon Barker brand...@gmail.com wrote:

Any updates on this topic? Primarily just curious about what the best
way to
call multityped c-variadic functions is, as I’m about to do a lot of
it
(e.g. scanf and fprintf - and am hoping the answer is not to create a
separate function for each).
github githwxi

I create a separate function but it’s a bit of a pain. It’d be
wonderful if it was as easy as this Idris example:

https://www.youtube.com/watch?v=fVBck2Zngjo


http://www.bluishcoder.co.nz


You received this message because you are subscribed to the Google Groups
“ats-lang-users” group.
To unsubscribe from this group and stop receiving emails from it, send an
email to ats-lang...@googlegroups.com <javascript:>.
To post to this group, send email to ats-l...@googlegroups.com<javascript:>
.
To view this discussion on the web visit
https://groups.google.com/d/msgid/ats-lang-users/c30f0c75-bfc0-4e0f-934c-c12daffd5114%40googlegroups.comhttps://groups.google.com/d/msgid/ats-lang-users/c30f0c75-bfc0-4e0f-934c-c12daffd5114%40googlegroups.com?utm_medium=email&utm_source=footer
.