Skip to content

Commit

Permalink
Enhance checking in dynInterface.
Browse files Browse the repository at this point in the history
For any method, there must be exactly one handle argument, that is, the first one.
  • Loading branch information
PengZheng committed Jan 28, 2024
1 parent 4301a98 commit bfef295
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 21 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
:header
type=interface
name=calculator
version=1.0.0
:annotations
classname=org.example.Calculator
:types
StatsResult={DDD[D average min max input}
:methods
add(DD)D=add(#am=handle;P#am=handle;PDD#am=pre;*D)N
13 changes: 11 additions & 2 deletions libs/dfi/gtest/src/dyn_interface_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -178,12 +178,21 @@ extern "C" {
fclose(desc); desc=NULL;
celix_err_resetErrors();

/* Method with multiple handles */
desc = fopen("descriptors/invalids/methodWithMultipleHandles.descriptor", "r");
assert(desc != NULL);
status = dynInterface_parse(desc, &dynIntf);
ASSERT_NE(0, status);
EXPECT_STREQ("Parse Error. Handle argument is only allowed as the first argument for method add(DD)D (0)", celix_err_popLastError());
fclose(desc); desc=NULL;
celix_err_resetErrors();

/* Method with multiple PreOut arguments */
desc = fopen("descriptors/invalids/multiPreOutArgs.descriptor", "r");
assert(desc != NULL);
status = dynInterface_parse(desc, &dynIntf);
ASSERT_NE(0, status);
EXPECT_STREQ("Parse Error. Only one output argument is allowed for method multiPreOut(V)Di (0)", celix_err_popLastError());
EXPECT_STREQ("Parse Error. Output argument is only allowed as the last argument for method multiPreOut(V)Di (0)", celix_err_popLastError());
fclose(desc); desc=NULL;
celix_err_resetErrors();

Expand All @@ -192,7 +201,7 @@ extern "C" {
assert(desc != NULL);
status = dynInterface_parse(desc, &dynIntf);
ASSERT_NE(0, status);
EXPECT_STREQ("Parse Error. Only one output argument is allowed for method multiOut(V)Di (0)", celix_err_popLastError());
EXPECT_STREQ("Parse Error. Output argument is only allowed as the last argument for method multiOut(V)Di (0)", celix_err_popLastError());
fclose(desc); desc=NULL;
celix_err_resetErrors();

Expand Down
37 changes: 18 additions & 19 deletions libs/dfi/src/dyn_interface.c
Original file line number Diff line number Diff line change
Expand Up @@ -74,28 +74,27 @@ static int dynInterface_checkInterface(dyn_interface_type* intf) {
return ERROR;
}
const struct dyn_function_arguments_head* args = dynFunction_arguments(mEntry->dynFunc);
dyn_function_argument_type* argEntry = TAILQ_FIRST(args);
if (argEntry == NULL || argEntry->argumentMeta != DYN_FUNCTION_ARGUMENT_META__HANDLE) {
const dyn_function_argument_type* first = TAILQ_FIRST(args);
const dyn_function_argument_type* last = TAILQ_LAST(args, dyn_function_arguments_head);
if (first == NULL || first->argumentMeta != DYN_FUNCTION_ARGUMENT_META__HANDLE) {
celix_err_pushf("Parse Error. The first argument must be handle for method %s (%d)", mEntry->id, mEntry->index);
return ERROR;
}
size_t nbOfOutputArgs = 0;
for (argEntry = TAILQ_NEXT(argEntry, entries); argEntry != NULL; argEntry = TAILQ_NEXT(argEntry, entries)) {
if (argEntry->argumentMeta == DYN_FUNCTION_ARGUMENT_META__OUTPUT ||
argEntry->argumentMeta == DYN_FUNCTION_ARGUMENT_META__PRE_ALLOCATED_OUTPUT) {
nbOfOutputArgs += 1;
}
}
if (nbOfOutputArgs > 1) {
celix_err_pushf("Parse Error. Only one output argument is allowed for method %s (%d)", mEntry->id, mEntry->index);
return ERROR;
} else if (nbOfOutputArgs > 0) {
argEntry = TAILQ_LAST(args, dyn_function_arguments_head);
if (argEntry->argumentMeta != DYN_FUNCTION_ARGUMENT_META__OUTPUT &&
argEntry->argumentMeta != DYN_FUNCTION_ARGUMENT_META__PRE_ALLOCATED_OUTPUT) {
celix_err_pushf("Parse Error. Output argument is only allowed as the last argument for method %s (%d)",
mEntry->id, mEntry->index);
return ERROR;
const dyn_function_argument_type* argEntry = NULL;
TAILQ_FOREACH(argEntry, args, entries) {
if (argEntry->argumentMeta == DYN_FUNCTION_ARGUMENT_META__HANDLE) {
if (argEntry != first) {
celix_err_pushf("Parse Error. Handle argument is only allowed as the first argument for method %s (%d)",
mEntry->id, mEntry->index);
return ERROR;
}
} else if (argEntry->argumentMeta == DYN_FUNCTION_ARGUMENT_META__OUTPUT ||
argEntry->argumentMeta == DYN_FUNCTION_ARGUMENT_META__PRE_ALLOCATED_OUTPUT) {
if (argEntry != last) {
celix_err_pushf("Parse Error. Output argument is only allowed as the last argument for method %s (%d)",
mEntry->id, mEntry->index);
return ERROR;
}
}
}
}
Expand Down

0 comments on commit bfef295

Please sign in to comment.