Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

[c-ffi] Add a new error-condition result type. #803

Merged
merged 3 commits into from

2 participants

@fracek
Owner

This helps writing better wrappers for C libraries where the
return value is used to signal if the function did error.

sources/dfmc/c-ffi/c-function-macro.dylan
@@ -158,10 +159,15 @@ define method parse-early-options
collecting (return-values, arg-fragments, parameters, parameter-names)
let result-fragment = #f;
let vname = result-spec.name;
+ // 1
@waywardmonkeys Owner

This can be removed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@waywardmonkeys

I think this would be a bit more clear if this was error-result instead of error-condition so that it matches with result, especially for the warning about multiple results (which I was very glad to see you'd included).

@waywardmonkeys

We'll also hold off on merging this until the documentation and release notes are updated!

fracek added some commits
@fracek fracek [c-ffi] Add a new error-condition result type.
This helps writing better wrappers for C libraries where the
return value is used to signal if the function did error.
b7fd60a
@fracek fracek [doc] Add documentation about error-result. a17dad9
@fracek fracek [doc] Update release notes with latest changes to C-ffi. 9a76cd1
@waywardmonkeys waywardmonkeys merged commit 56038ee into dylan-lang:master
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Jul 20, 2014
  1. @fracek

    [c-ffi] Add a new error-condition result type.

    fracek authored
    This helps writing better wrappers for C libraries where the
    return value is used to signal if the function did error.
  2. @fracek
Commits on Jul 22, 2014
  1. @fracek
This page is out of date. Refresh to see the latest.
View
5 documentation/library-reference/source/c-ffi/index.rst
@@ -2435,11 +2435,16 @@ Describing C functions to Dylan
A result-spec has the following syntax::
result [name :: c-type]
+ error-result [name :: c-type]
If no *result* is specified, the Dylan function does not return a
value for the C result, and the C function is expected to have a
return type of *void*.
+ *error-result* is used when it is necessary to call the *import-map*
+ function on the result and then discard it. This is often used when
+ mapping a return value to a Dylan error.
+
Each *function-option* is a keyword–value pair. The
*generic-function-method:* option may be either ``#t`` or ``#f``,
indicating whether to add a method to the generic function name or
View
5 documentation/release-notes/source/2014.1.rst
@@ -95,6 +95,11 @@ C-FFI
This must be used in conjunction with the Objective C / Dylan
bridge library.
+* A result of a ``C-function`` may now be flagged as an ``error-result`` which
+ means that the import function will be called, but the actual value will not
+ be returned. This is useful for wrapping C APIs which return error codes that
+ should signal conditions when an error occurs.
+
C Run-time
==========
View
32 sources/dfmc/c-ffi/c-function-macro.dylan
@@ -23,6 +23,7 @@ define class <C-ffi-result-descriptor> (<object>)
slot designator-name, init-keyword: designator-name:;
slot model-type;
constant slot void? :: <boolean>, init-keyword: void?:, init-value: #f;
+ constant slot error-result? :: <boolean>, init-keyword: error-result?:, init-value: #f;
end;
@@ -160,8 +161,12 @@ define method parse-early-options
let vname = result-spec.name;
let type = ~void?(result-spec) & result-spec.designator-name;
if (~void?(result-spec))
- collect-into(return-values, #{ ?vname :: import-type-for(?type) });
- result-fragment := #{ (result ?vname :: ?type) };
+ if (~error-result?(result-spec))
+ collect-into(return-values, #{ ?vname :: import-type-for(?type) });
+ result-fragment := #{ (result ?vname :: ?type) };
+ else
+ result-fragment := #{ (error-result ?vname :: ?type) };
+ end if;
else
result-fragment := #{ (result void) }
end if;
@@ -592,6 +597,11 @@ result-spec:
name: result-name,
designator-name: type,
key-options);
+ { (error-result ?result-name:name :: ?type:expression) }
+ => make(<c-ffi-result-descriptor>,
+ name: result-name,
+ designator-name: type,
+ error-result?: #t);
key-options:
{ } => #()
{ ?key:expression, ?value:expression, ... }
@@ -730,6 +740,17 @@ define method parse-c-function-spec (form-name, specs :: <sequence>, #key name-s
result-spec := make(<C-ffi-result-descriptor>,
designator-name: designator, name: name)
end if;
+ { error-result ?name:name :: ?designator:expression }
+ => if (result-spec)
+ note(<multiple-return-clauses>,
+ source-location: fragment-source-location(spec),
+ definition-name: form-name);
+ else
+ result-spec := make(<C-ffi-result-descriptor>,
+ designator-name: designator,
+ name: name,
+ error-result?: #t)
+ end if;
{ ?function-options:* }
=> parse-options!(options, function-options)
{ ?key:symbol ?key-value:expression }
@@ -1093,6 +1114,11 @@ result-spec:
name: result-name,
designator-name: type,
key-options);
+ { (error-result ?result-name:name :: ?type:expression) }
+ => make(<c-ffi-result-descriptor>,
+ name: result-name,
+ designator-name: type,
+ error-result?: #t);
key-options:
{ } => #()
{ ?key:expression, ?value:expression, ... }
@@ -1199,7 +1225,7 @@ define method expand-c-function-body
& (result-designator.^import-function
| #{ identity });
let return-values =
- if (result-designator)
+ if (result-designator & ~error-result?(result-desc))
pair( #{ ?result-name }, as(<list>, extra-return-values));
else
extra-return-values
Something went wrong with that request. Please try again.