Skip to content

Commit cc81ac5

Browse files
committed
[[ LCB ]] Add varargs support to foreign handlers
This patch adds varargs support to foreign C handlers, allowing binding to a wider range of C functions. The syntax for vararg handlers is similar to that of C: ``` foreign handler myvarargs(in pFirst as Pointer, ...) returns CInt binds to ... ``` Using the token `...` to indicate the start of the variable parameter list. To implement vararg functions, a new parameter mode 'variadic' has been added which causes a handler to be treated as variadic if such a parameter with a mode is present. As C requires any int type with rank less than int to be promoted to int, and float to be promoted to double (when passed to a non-fixed parameter in a variadic function), a 'promotedtype' and 'promote' function have been added to foreign type descriptors to describe the appropriate relation.
1 parent fa8cdcf commit cc81ac5

File tree

23 files changed

+735
-126
lines changed

23 files changed

+735
-126
lines changed

docs/guides/LiveCode Builder Language Reference.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -436,6 +436,14 @@ statement blocks.
436436
A foreign handler definition binds an identifier to a handler defined in
437437
foreign code.
438438

439+
The last parameter in a foreign handler declaration may be '...' to indicate
440+
that the handler is variadic. This allows binding to C functions such as
441+
sprintf.
442+
443+
Note: No bridging of types will occur when passing a parameter in the non-fixed
444+
section of a variadic argument list. You must ensure the arguments you pass there
445+
are of the appropriate foreign type (e.g. CInt, CDouble).
446+
439447
There are a number of types defined in the foreign module which map to
440448
the appropriate foreign type when used in foreign handler signatures.
441449

docs/lcb/notes/19991.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# LiveCode Builder Language
2+
3+
## Variadic foreign C functions
4+
5+
* It is now possible to bind to variadic C functions:
6+
foreign handler printf(in pFormat as Pointer, ...) returns CInt binds to "<builtin>"
7+
In this case, the '...' must be the last parameter, and there must be at
8+
least one fixed parameter.
9+
10+
# [19991] Add support for variadic foreign C functions.
11+

libfoundation/include/foundation.h

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1776,6 +1776,14 @@ struct MCForeignTypeDescriptor
17761776
bool (*doimport)(void *contents, bool release, MCValueRef& r_value);
17771777
bool (*doexport)(MCValueRef value, bool release, void *contents);
17781778
bool (*describe)(void *contents, MCStringRef & r_desc);
1779+
1780+
/* The promotedtype typeinfo is the type to which this type must be promoted
1781+
* when passed through variadic parameters. The 'promote' method does the
1782+
* promotion. */
1783+
MCTypeInfoRef promotedtype;
1784+
/* Promote the value in contents as necessary. The slot ptr must be big enough
1785+
* to hold the promotedtype. */
1786+
void (*promote)(void *contents);
17791787
};
17801788

17811789
MC_DLLEXPORT bool MCForeignTypeInfoCreate(const MCForeignTypeDescriptor *descriptor, MCTypeInfoRef& r_typeinfo);
@@ -1866,6 +1874,7 @@ enum MCHandlerTypeFieldMode
18661874
kMCHandlerTypeFieldModeIn,
18671875
kMCHandlerTypeFieldModeOut,
18681876
kMCHandlerTypeFieldModeInOut,
1877+
kMCHandlerTypeFieldModeVariadic,
18691878
};
18701879

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

18911900
// Returns true if the handler is of foreign type.
18921901
MC_DLLEXPORT bool MCHandlerTypeInfoIsForeign(MCTypeInfoRef typeinfo);
1902+
1903+
// Returns true if the handler is variadic.
1904+
MC_DLLEXPORT bool MCHandlerTypeInfoIsVariadic(MCTypeInfoRef typeinfo);
18931905

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

1898-
// Get the number of parameters the handler takes.
1910+
// Get the number of parameters the handler takes. If the handler is variadic,
1911+
// this returns the number of fixed parameters.
18991912
MC_DLLEXPORT uindex_t MCHandlerTypeInfoGetParameterCount(MCTypeInfoRef typeinfo);
19001913

19011914
// Return the mode of the index'th parameter.

0 commit comments

Comments
 (0)