1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140
|
/*
* GridTools
*
* Copyright (c) 2014-2019, ETH Zurich
* All rights reserved.
*
* Please, refer to the LICENSE file in the root directory.
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <cpp_bindgen/generator.hpp>
#include <cpp_bindgen/handle_impl.hpp>
#include <sstream>
#include <gtest/gtest.h>
namespace cpp_bindgen {
namespace {
BINDGEN_ADD_GENERATED_DECLARATION(void(), foo);
BINDGEN_ADD_GENERATED_DECLARATION(bindgen_handle *(int, double const *, bindgen_handle *), bar);
BINDGEN_ADD_GENERATED_DECLARATION(void(int *const *volatile *const *), baz);
BINDGEN_ADD_GENERATED_DECLARATION_WRAPPED(void(int, int (&)[1][2][3]), qux);
BINDGEN_ADD_GENERIC_DECLARATION(foo, bar);
BINDGEN_ADD_GENERIC_DECLARATION(foo, baz);
const char expected_c_interface[] = R"?(// This file is generated!
#pragma once
#include <cpp_bindgen/array_descriptor.h>
#include <cpp_bindgen/handle.h>
#ifdef __cplusplus
extern "C" {
#endif
bindgen_handle* bar(int, double*, bindgen_handle*);
void baz(int****);
void foo();
void qux(int, bindgen_fortran_array_descriptor*);
#ifdef __cplusplus
}
#endif
)?";
TEST(generator, c_interface) {
std::ostringstream strm;
generate_c_interface(strm);
EXPECT_EQ(strm.str(), expected_c_interface);
}
const char expected_fortran_interface[] = R"?(! This file is generated!
module my_module
use iso_c_binding
implicit none
interface
type(c_ptr) function bar(arg0, arg1, arg2) bind(c)
use iso_c_binding
integer(c_int), value :: arg0
real(c_double), dimension(*) :: arg1
type(c_ptr), value :: arg2
end function
subroutine baz(arg0) bind(c)
use iso_c_binding
type(c_ptr) :: arg0
end subroutine
subroutine foo() bind(c)
use iso_c_binding
end subroutine
subroutine qux_impl(arg0, arg1) bind(c, name="qux")
use iso_c_binding
use bindgen_array_descriptor
integer(c_int), value :: arg0
type(bindgen_fortran_array_descriptor) :: arg1
end subroutine
end interface
interface foo
procedure bar, baz
end interface
contains
subroutine qux(arg0, arg1)
use iso_c_binding
use bindgen_array_descriptor
integer(c_int), value, target :: arg0
integer(c_int), dimension(:,:,:), target :: arg1
type(bindgen_fortran_array_descriptor) :: descriptor1
descriptor1%rank = 3
descriptor1%type = 1
descriptor1%dims = reshape(shape(arg1), &
shape(descriptor1%dims), (/0/))
descriptor1%data = c_loc(arg1(lbound(arg1, 1),lbound(arg1, 2),lbound(arg1, 3)))
call qux_impl(arg0, descriptor1)
end subroutine
end
)?";
TEST(generator, fortran_interface) {
std::ostringstream strm;
generate_fortran_interface(strm, "my_module");
EXPECT_EQ(strm.str(), expected_fortran_interface);
}
TEST(generator, wrap_short_line) {
const std::string prefix = " ";
const std::string line = "short line, short line";
EXPECT_EQ(prefix + line + '\n', wrap_line(line, prefix));
}
TEST(generator, wrap_almost_full_line) {
const std::string prefix = " ";
const std::string line = std::string(64, 'x') + "," + std::string(63, 'x');
EXPECT_EQ(prefix + line + '\n', wrap_line(line, prefix));
}
TEST(generator, wrap_full_line) {
const std::string prefix = " ";
const std::string line = std::string(64, 'x') + "," + std::string(64, 'x');
EXPECT_EQ(prefix + std::string(64, 'x') + ", &" + '\n' + prefix + " " + std::string(64, 'x') + "\n",
wrap_line(line, prefix));
}
TEST(generator, wrap_multiple_lines) {
const std::string prefix = " ";
const std::string line = std::string(50, 'x') + "," + std::string(50, 'x') + "," + std::string(60, 'x') +
"," + std::string(61, 'x') + "," + std::string(60, 'x') + "," +
std::string(62, 'x') + "," + std::string(59, 'x') + "," + std::string(122, 'x');
const std::string line1 = prefix + std::string(50, 'x') + "," + std::string(50, 'x') + ", &" + '\n';
const std::string line2 = prefix + " " + std::string(60, 'x') + "," + std::string(61, 'x') + ", &" + '\n';
const std::string line3 = prefix + " " + std::string(60, 'x') + ", &" + '\n';
const std::string line4 = prefix + " " + std::string(62, 'x') + "," + std::string(59, 'x') + ", &" + '\n';
const std::string line5 = prefix + " " + std::string(122, 'x') + '\n';
EXPECT_EQ(line1 + line2 + line3 + line4 + line5, wrap_line(line, prefix));
}
} // namespace
} // namespace cpp_bindgen
|