Skip to content
This repository was archived by the owner on Aug 31, 2021. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions docs/guides/LiveCode Builder Language Reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -436,6 +436,14 @@ statement blocks.
A foreign handler definition binds an identifier to a handler defined in
foreign code.

The last parameter in a foreign handler declaration may be '...' to indicate
that the handler is variadic. This allows binding to C functions such as
sprintf.

Note: No bridging of types will occur when passing a parameter in the non-fixed
section of a variadic argument list. You must ensure the arguments you pass there
are of the appropriate foreign type (e.g. CInt, CDouble).

There are a number of types defined in the foreign module which map to
the appropriate foreign type when used in foreign handler signatures.

Expand Down
11 changes: 11 additions & 0 deletions docs/lcb/notes/19991.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# LiveCode Builder Language

## Variadic foreign C functions

* It is now possible to bind to variadic C functions:
foreign handler printf(in pFormat as Pointer, ...) returns CInt binds to "<builtin>"
In this case, the '...' must be the last parameter, and there must be at
least one fixed parameter.

# [19991] Add support for variadic foreign C functions.

15 changes: 14 additions & 1 deletion libfoundation/include/foundation.h
Original file line number Diff line number Diff line change
Expand Up @@ -1776,6 +1776,14 @@ struct MCForeignTypeDescriptor
bool (*doimport)(void *contents, bool release, MCValueRef& r_value);
bool (*doexport)(MCValueRef value, bool release, void *contents);
bool (*describe)(void *contents, MCStringRef & r_desc);

/* The promotedtype typeinfo is the type to which this type must be promoted
* when passed through variadic parameters. The 'promote' method does the
* promotion. */
MCTypeInfoRef promotedtype;
/* Promote the value in contents as necessary. The slot ptr must be big enough
* to hold the promotedtype. */
void (*promote)(void *contents);
};

MC_DLLEXPORT bool MCForeignTypeInfoCreate(const MCForeignTypeDescriptor *descriptor, MCTypeInfoRef& r_typeinfo);
Expand Down Expand Up @@ -1866,6 +1874,7 @@ enum MCHandlerTypeFieldMode
kMCHandlerTypeFieldModeIn,
kMCHandlerTypeFieldModeOut,
kMCHandlerTypeFieldModeInOut,
kMCHandlerTypeFieldModeVariadic,
};

struct MCHandlerTypeFieldInfo
Expand All @@ -1890,12 +1899,16 @@ MC_DLLEXPORT bool MCForeignHandlerTypeInfoCreate(const MCHandlerTypeFieldInfo *f

// Returns true if the handler is of foreign type.
MC_DLLEXPORT bool MCHandlerTypeInfoIsForeign(MCTypeInfoRef typeinfo);

// Returns true if the handler is variadic.
MC_DLLEXPORT bool MCHandlerTypeInfoIsVariadic(MCTypeInfoRef typeinfo);

// Get the return type of the handler. A return-type of kMCNullTypeInfo means no
// value is returned.
MC_DLLEXPORT MCTypeInfoRef MCHandlerTypeInfoGetReturnType(MCTypeInfoRef typeinfo);

// Get the number of parameters the handler takes.
// Get the number of parameters the handler takes. If the handler is variadic,
// this returns the number of fixed parameters.
MC_DLLEXPORT uindex_t MCHandlerTypeInfoGetParameterCount(MCTypeInfoRef typeinfo);

// Return the mode of the index'th parameter.
Expand Down
Loading