blob: 5f13de4aa8a2a632f48935be6265857beb153506 [file] [log] [blame]
/**
*Licensed to the Apache Software Foundation (ASF) under one
*or more contributor license agreements. See the NOTICE file
*distributed with this work for additional information
*regarding copyright ownership. The ASF licenses this file
*to you under the Apache License, Version 2.0 (the
*"License"); you may not use this file except in compliance
*with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
*Unless required by applicable law or agreed to in writing,
*software distributed under the License is distributed on an
*"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
*specific language governing permissions and limitations
*under the License.
*/
#include <CppUTest/TestHarness.h>
#include "CppUTest/CommandLineTestRunner.h"
extern "C" {
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "dyn_common.h"
#include "dyn_function.h"
static int g_count;
static void stdLog(void *handle, int level, const char *file, int line, const char *msg, ...) {
va_list ap;
const char *levels[5] = {"NIL", "ERROR", "WARNING", "INFO", "DEBUG"};
fprintf(stderr, "%s: FILE:%s, LINE:%i, MSG:",levels[level], file, line);
va_start(ap, msg);
vfprintf(stderr, msg, ap);
fprintf(stderr, "\n");
va_end(ap);
}
#define EXAMPLE1_DESCRIPTOR "example(III)I"
static void example1_binding(void *userData, void* args[], void *out) {
int32_t a = *((int32_t *)args[0]);
int32_t b = *((int32_t *)args[1]);
int32_t c = *((int32_t *)args[2]);
int32_t *ret = (int32_t *)out;
*ret = a + b + c;
g_count += 1;
}
#define EXAMPLE2_DESCRIPTOR "example(I{DDD val1 val2 val3}I)D"
struct example2_arg2 {
double val1;
double val2;
double val3;
};
void example2_binding(void *userData, void* args[], void *out) {
int32_t a = *((int32_t *)args[0]);
struct example2_arg2 b = *((struct example2_arg2 *)args[1]);
int32_t c = *((int32_t *)args[2]);
double *ret = (double *)out;
*ret = a + b.val1 + b.val2 + b.val3 + c;
g_count += 1;
}
#define EXAMPLE3_DESCRIPTOR "example(III){III sum max min}"
struct example3_ret {
int32_t sum;
int32_t max;
int32_t min;
};
static void example3_binding(void *userData, void* args[], void *out) {
int32_t a = *((int32_t *)args[0]);
int32_t b = *((int32_t *)args[1]);
int32_t c = *((int32_t *)args[2]);
struct example3_ret *result = (struct example3_ret *)calloc(1,sizeof(struct example3_ret));
result->sum = a + b + c;
result->min = a <= b ? a : b;
result->max = a >= b ? a : b;
result->min = result->min <= c ? result->min : c;
result->max = result->max >= c ? result->max : c;
struct example3_ret **ret = (struct example3_ret **)out;
(*ret) = result;
g_count += 1;
}
static void tests() {
dyn_function_type *dynFunction = NULL;
int rc = 0;
{
int32_t (*func)(int32_t a, int32_t b, int32_t c) = NULL;
rc = dynFunction_parseWithStr(EXAMPLE1_DESCRIPTOR, NULL, &dynFunction);
CHECK_EQUAL(0, rc);
rc = dynFunction_createClosure(dynFunction, example1_binding, NULL, (void(**)(void))&func);
CHECK_EQUAL(0, rc);
int32_t ret = func(2,3,4);
CHECK_EQUAL(1, g_count);
CHECK_EQUAL(9, ret);
dynFunction_destroy(dynFunction);
}
{
double (*func)(int32_t a, struct example2_arg2 b, int32_t c) = NULL;
double (*func2)(int32_t a, struct example2_arg2 b, int32_t c) = NULL;
dynFunction = NULL;
rc = dynFunction_parseWithStr(EXAMPLE2_DESCRIPTOR, NULL, &dynFunction);
CHECK_EQUAL(0, rc);
rc = dynFunction_createClosure(dynFunction, example2_binding, NULL, (void(**)(void))&func);
CHECK_EQUAL(0, rc);
rc = dynFunction_getFnPointer(dynFunction, (void(**)(void))&func2);
CHECK_EQUAL(0, rc);
CHECK(func == func2);
struct example2_arg2 b;
b.val1 = 1.0;
b.val2 = 1.5;
b.val3 = 2.0;
double ret = func(2,b,4);
CHECK_EQUAL(2, g_count);
CHECK_EQUAL(10.5, ret);
dynFunction_destroy(dynFunction);
}
{
struct example3_ret * (*func)(int32_t a, int32_t b, int32_t c) = NULL;
dynFunction = NULL;
rc = dynFunction_parseWithStr(EXAMPLE3_DESCRIPTOR, NULL, &dynFunction);
CHECK_EQUAL(0, rc);
rc = dynFunction_createClosure(dynFunction, example3_binding, NULL, (void(**)(void))&func);
CHECK_EQUAL(0, rc);
struct example3_ret *ret = func(2,8,4);
CHECK_EQUAL(3, g_count);
CHECK_EQUAL(14, ret->sum);
dynFunction_destroy(dynFunction);
free(ret);
}
}
}
TEST_GROUP(DynClosureTests) {
void setup() {
int lvl = 1;
dynFunction_logSetup(stdLog, NULL, lvl);
dynType_logSetup(stdLog, NULL, lvl);
dynCommon_logSetup(stdLog, NULL, lvl);
g_count = 0;
}
};
TEST(DynClosureTests, DynCLosureTest1) {
//TODO split up
tests();
}