Convert test_functions
parent
af7b64b82d
commit
67e6e8a9bf
56
src/cpp.cpp
56
src/cpp.cpp
|
@ -676,6 +676,38 @@ void constructorArgs(QTextStream& cpp, const QString& prefix, const Object& o, c
|
|||
}
|
||||
}
|
||||
|
||||
void writeFunctionCDecl(QTextStream& cpp, const Function& f, const QString& lcname, const Object& o) {
|
||||
const QString lc(snakeCase(f.name));
|
||||
cpp << " ";
|
||||
if (f.type.isComplex()) {
|
||||
cpp << "void";
|
||||
} else {
|
||||
cpp << f.type.name;
|
||||
}
|
||||
const QString name = QString("%1_%2").arg(lcname, lc);
|
||||
cpp << QString(" %1(%3%2::Private*").arg(name, o.name, f.mut ? "" : "const ");
|
||||
// write all the input arguments, for QString and QByteArray, write
|
||||
// pointers to their content and the length
|
||||
for (auto a = f.args.begin(); a < f.args.end(); a++) {
|
||||
if (a->type.name == "QString") {
|
||||
cpp << ", const ushort*, int";
|
||||
} else if (a->type.name == "QByteArray") {
|
||||
cpp << ", const char*, int";
|
||||
} else {
|
||||
cpp << ", " << a->type.rustType;
|
||||
}
|
||||
}
|
||||
// If the return type is QString or QByteArray, append a pointer to the
|
||||
// variable that will be set to the argument list. Also add a setter
|
||||
// function.
|
||||
if (f.type.name == "QString") {
|
||||
cpp << ", QString*, qstring_set";
|
||||
} else if (f.type.name == "QByteArray") {
|
||||
cpp << ", QByteArray*, qbytearray_set";
|
||||
}
|
||||
cpp << ");\n";
|
||||
}
|
||||
|
||||
void writeObjectCDecl(QTextStream& cpp, const Object& o, const Configuration& conf) {
|
||||
const QString lcname(snakeCase(o.name));
|
||||
cpp << QString(" %1::Private* %2_new(").arg(o.name, lcname);
|
||||
|
@ -712,20 +744,7 @@ void writeObjectCDecl(QTextStream& cpp, const Object& o, const Configuration& co
|
|||
}
|
||||
|
||||
for (const Function& f: o.functions) {
|
||||
const QString lc(snakeCase(f.name));
|
||||
const QString name = QString("%1_%2").arg(lcname, lc);
|
||||
cpp << QString(" %1 %2(%4%3::Private*")
|
||||
.arg(f.type.cSetType, name, o.name, f.mut ? "" : "const ");
|
||||
if (f.args.size() > 0) {
|
||||
cpp << ", ";
|
||||
for (auto a = f.args.begin(); a < f.args.end(); a++) {
|
||||
cpp << QString("%2%3").arg(a->type.cSetType, a + 1 < f.args.end() ? ", " : "");
|
||||
}
|
||||
}
|
||||
if (f.type.name == "QString") {
|
||||
cpp << ", QString*, qstring_set";
|
||||
}
|
||||
cpp << ");" << endl;
|
||||
writeFunctionCDecl(cpp, f, lcname, o);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -883,10 +902,11 @@ void writeCppObject(QTextStream& cpp, const Object& o, const Configuration& conf
|
|||
cpp << QString(")%1\n{\n")
|
||||
.arg(f.mut ? "" : " const");
|
||||
QString argList;
|
||||
if (f.args.size() > 0) {
|
||||
argList.append(", ");
|
||||
for (auto a = f.args.begin(); a < f.args.end(); a++) {
|
||||
argList.append(QString("%2%3").arg(a->name, a + 1 < f.args.end() ? ", " : ""));
|
||||
for (auto a = f.args.begin(); a < f.args.end(); a++) {
|
||||
if (a->type.name == "QString") {
|
||||
argList.append(QString(", %2%3.utf16(), %2%3.size()").arg(a->name, a + 1 < f.args.end() ? ", " : ""));
|
||||
} else {
|
||||
argList.append(QString(", %2%3").arg(a->name, a + 1 < f.args.end() ? ", " : ""));
|
||||
}
|
||||
}
|
||||
if (f.type.name == "QString") {
|
||||
|
|
119
src/rust.cpp
119
src/rust.cpp
|
@ -146,6 +146,91 @@ void rConstructorArgs(QTextStream& r, const QString& name, const Object& o, cons
|
|||
r << ");\n";
|
||||
}
|
||||
|
||||
void writeFunction(QTextStream& r, const Function& f, const QString& lcname, const Object& o) {
|
||||
const QString lc(snakeCase(f.name));
|
||||
r << QString(R"(
|
||||
#[no_mangle]
|
||||
pub extern "C" fn %1_%2(ptr: *%3 %4)").arg(lcname, lc, f.mut ? "mut" : "const", o.name);
|
||||
// write all the input arguments, for QString and QByteArray, write
|
||||
// pointers to their content and the length which is int in Qt
|
||||
for (auto a = f.args.begin(); a < f.args.end(); a++) {
|
||||
r << ", ";
|
||||
if (a->type.name == "QString") {
|
||||
r << QString("%1_str: *const c_ushort, %1_len: c_int").arg(a->name);
|
||||
} else {
|
||||
r << a->name << ": " << a->type.rustType;
|
||||
}
|
||||
}
|
||||
// If the return type is QString or QByteArray, append a pointer to the
|
||||
// variable that will be set to the argument list. Also add a setter
|
||||
// function.
|
||||
if (f.type.name == "QString") {
|
||||
r << ", d: *mut QString, set: fn(*mut QString, str: *const c_char, len: c_int)) {\n";
|
||||
} else if (f.type.name == "QByteArray") {
|
||||
r << ", d: *mut QByteArray, set: fn(*mut QString, str: *const c_char, len: c_int)) {\n";
|
||||
} else {
|
||||
r << ") -> " << f.type.rustType << " {\n";
|
||||
}
|
||||
for (auto a = f.args.begin(); a < f.args.end(); a++) {
|
||||
if (a->type.name == "QString") {
|
||||
r << " let mut " << a->name << " = String::new();\n";
|
||||
r << QString(" set_string_from_utf16(&mut %1, %1_str, %1_len);\n").arg(a->name);
|
||||
} else if (a->type.name == "QByteArray") {
|
||||
}
|
||||
}
|
||||
if (f.mut) {
|
||||
r << " let o = unsafe { &mut *ptr };\n";
|
||||
} else {
|
||||
r << " let o = unsafe { &*ptr };\n";
|
||||
}
|
||||
r << " let r = o." << lc << "(";
|
||||
for (auto a = f.args.begin(); a < f.args.end(); a++) {
|
||||
if (a != f.args.begin()) {
|
||||
r << ", ";
|
||||
}
|
||||
r << a->name;
|
||||
}
|
||||
r << ");\n";
|
||||
if (f.type.isComplex()) {
|
||||
r << " let s: *const c_char = r.as_ptr() as (*const c_char);\n";
|
||||
r << " set(d, s, r.len() as i32);\n";
|
||||
} else if (f.type.rustType != "()") {
|
||||
r << " r\n";
|
||||
}
|
||||
r << "}\n";
|
||||
/*
|
||||
const QString type = a->type.name == "QString" ? "*const c_ushort, len: c_int" : a->type.rustType;
|
||||
const QString passAlong = a->type.name == "QString" ? QString("%1.convert()").arg(a->name) : a->name;
|
||||
argList.append(QString("%1: %2%3").arg(a->name, type, a + 1 < f.args.end() ? ", " : ""));
|
||||
noTypeArgs.append(QString("%1%3").arg(passAlong, a + 1 < f.args.end() ? ", " : ""));
|
||||
}
|
||||
QString argList;
|
||||
QString noTypeArgs;
|
||||
if (f.args.size() > 0) {
|
||||
argList.append(", ");
|
||||
}
|
||||
if (f.type.name == "QString") {
|
||||
r << QString(R"(
|
||||
#[no_mangle]
|
||||
pub extern "C" fn %1_%2(ptr: *%3 %4%6, d: *mut QString, set: fn(*mut QString, str: *const c_char, len: c_int)) {
|
||||
let o = unsafe { &%5*ptr };
|
||||
let data = o.%2(%7);
|
||||
let s: *const c_char = data.as_ptr() as (*const c_char);
|
||||
set(d, s, data.len() as c_int);
|
||||
}
|
||||
)").arg(lcname, lc, f.mut ? "mut" : "const", o.name, f.mut ? "mut " : "", argList, noTypeArgs);
|
||||
|
||||
} else {
|
||||
r << QString(R"(
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn %1_%2(ptr: *%3 %4%7) -> %5 {
|
||||
(&%6*ptr).%2(%8)
|
||||
}
|
||||
)").arg(lcname, lc, f.mut ? "mut" : "const", o.name, f.type.rustType, f.mut ? "mut " : "", argList, noTypeArgs);
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
void writeRustInterfaceObject(QTextStream& r, const Object& o, const Configuration& conf) {
|
||||
const QString lcname(snakeCase(o.name));
|
||||
r << QString(R"(
|
||||
|
@ -455,35 +540,7 @@ pub unsafe extern "C" fn %2_set(ptr: *mut %1, v: %4) {
|
|||
}
|
||||
}
|
||||
for (const Function& f: o.functions) {
|
||||
const QString lc(snakeCase(f.name));
|
||||
QString argList;
|
||||
QString noTypeArgs;
|
||||
if (f.args.size() > 0) {
|
||||
argList.append(", ");
|
||||
for (auto a = f.args.begin(); a < f.args.end(); a++) {
|
||||
const QString type = a->type.name == "QString" ? "QStringIn" : a->type.rustType;
|
||||
const QString passAlong = a->type.name == "QString" ? QString("%1.convert()").arg(a->name) : a->name;
|
||||
argList.append(QString("%1: %2%3").arg(a->name, type, a + 1 < f.args.end() ? ", " : ""));
|
||||
noTypeArgs.append(QString("%1%3").arg(passAlong, a + 1 < f.args.end() ? ", " : ""));
|
||||
}
|
||||
}
|
||||
if (f.type.isComplex()) {
|
||||
r << QString(R"(
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn %1_%2(ptr: *%3 %4%7, d: *mut c_void, set: fn(*mut c_void, %5)) {
|
||||
let data = (&%6*ptr).%2(%8);
|
||||
set(d, (&data).into());
|
||||
}
|
||||
)").arg(lcname, lc, f.mut ? "mut" : "const", o.name, f.type.name, f.mut ? "mut " : "", argList, noTypeArgs);
|
||||
|
||||
} else {
|
||||
r << QString(R"(
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn %1_%2(ptr: *%3 %4%7) -> %5 {
|
||||
(&%6*ptr).%2(%8)
|
||||
}
|
||||
)").arg(lcname, lc, f.mut ? "mut" : "const", o.name, f.type.rustType, f.mut ? "mut " : "", argList, noTypeArgs);
|
||||
}
|
||||
writeFunction(r, f, lcname, o);
|
||||
}
|
||||
if (o.type == ObjectType::List) {
|
||||
r << QString(R"(
|
||||
|
@ -867,10 +924,6 @@ void writeRustImplementationObject(QTextStream& r, const Object& o) {
|
|||
r << QString(" %1: %2,\n").arg(lc, rustTypeInit(p));
|
||||
}
|
||||
}
|
||||
if (o.type != ObjectType::Object) {
|
||||
r << QString(" list: vec![%1Item::default(); 10],\n")
|
||||
.arg(o.name);
|
||||
}
|
||||
r << QString(R"( }
|
||||
}
|
||||
fn emit(&self) -> &%1Emitter {
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
/* generated by rust_qt_binding_generator */
|
||||
#![allow(unknown_lints)]
|
||||
#![allow(mutex_atomic, needless_pass_by_value)]
|
||||
use libc::{c_int, c_void, uint8_t, uint16_t};
|
||||
use libc::{c_char, c_ushort, c_int, c_void, uint8_t, uint16_t};
|
||||
use std::slice;
|
||||
use std::char::decode_utf16;
|
||||
|
||||
use std::sync::{Arc, Mutex};
|
||||
use std::ptr::null;
|
||||
|
@ -10,42 +11,17 @@ use std::ptr::null;
|
|||
use implementation::*;
|
||||
|
||||
|
||||
#[repr(C)]
|
||||
pub struct QString {
|
||||
data: *const uint8_t,
|
||||
len: c_int,
|
||||
pub enum QString {}
|
||||
|
||||
fn set_string_from_utf16(s: &mut String, str: *const c_ushort, len: c_int) {
|
||||
let utf16 = unsafe { slice::from_raw_parts(str, len as usize) };
|
||||
let characters = decode_utf16(utf16.iter().cloned())
|
||||
.into_iter()
|
||||
.map(|r| r.unwrap());
|
||||
s.clear();
|
||||
s.extend(characters);
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct QStringIn {
|
||||
data: *const uint16_t,
|
||||
len: c_int,
|
||||
}
|
||||
|
||||
impl QStringIn {
|
||||
fn convert(&self) -> String {
|
||||
let data = unsafe { slice::from_raw_parts(self.data, self.len as usize) };
|
||||
String::from_utf16_lossy(data)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> From<&'a str> for QString {
|
||||
fn from(string: &'a str) -> QString {
|
||||
QString {
|
||||
len: string.len() as c_int,
|
||||
data: string.as_ptr(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> From<&'a String> for QString {
|
||||
fn from(string: &'a String) -> QString {
|
||||
QString {
|
||||
len: string.len() as c_int,
|
||||
data: string.as_ptr(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct PersonQObject {}
|
||||
|
||||
|
@ -98,32 +74,44 @@ pub unsafe extern "C" fn person_free(ptr: *mut Person) {
|
|||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn person_user_name_get(
|
||||
pub extern "C" fn person_user_name_get(
|
||||
ptr: *const Person,
|
||||
p: *mut c_void,
|
||||
set: fn(*mut c_void, QString),
|
||||
set: fn(*mut c_void, *const c_char, c_int),
|
||||
) {
|
||||
let data = (&*ptr).user_name();
|
||||
set(p, data.into());
|
||||
let o = unsafe { &*ptr };
|
||||
let v = o.user_name();
|
||||
let s: *const c_char = v.as_ptr() as (*const c_char);
|
||||
set(p, s, v.len() as c_int);
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn person_user_name_set(ptr: *mut Person, v: QStringIn) {
|
||||
(&mut *ptr).set_user_name(v.convert());
|
||||
pub extern "C" fn person_user_name_set(ptr: *mut Person, v: *const c_ushort, len: c_int) {
|
||||
let o = unsafe { &mut *ptr };
|
||||
let mut s = String::new();
|
||||
set_string_from_utf16(&mut s, v, len);
|
||||
o.set_user_name(s);
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn person_double_name(ptr: *mut Person) -> () {
|
||||
(&mut *ptr).double_name()
|
||||
pub extern "C" fn person_double_name(ptr: *mut Person) -> () {
|
||||
let o = unsafe { &mut *ptr };
|
||||
let r = o.double_name();
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn person_greet(ptr: *const Person, Name: QStringIn, d: *mut c_void, set: fn(*mut c_void, QString)) {
|
||||
let data = (&*ptr).greet(Name.convert());
|
||||
set(d, (&data).into());
|
||||
pub extern "C" fn person_greet(ptr: *const Person, Name_str: *const c_ushort, Name_len: c_int, d: *mut QString, set: fn(*mut QString, str: *const c_char, len: c_int)) {
|
||||
let mut Name = String::new();
|
||||
set_string_from_utf16(&mut Name, Name_str, Name_len);
|
||||
let o = unsafe { &*ptr };
|
||||
let r = o.greet(Name);
|
||||
let s: *const c_char = r.as_ptr() as (*const c_char);
|
||||
set(d, s, r.len() as i32);
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn person_vowels_in_name(ptr: *const Person) -> u8 {
|
||||
(&*ptr).vowels_in_name()
|
||||
pub extern "C" fn person_vowels_in_name(ptr: *const Person) -> u8 {
|
||||
let o = unsafe { &*ptr };
|
||||
let r = o.vowels_in_name();
|
||||
r
|
||||
}
|
||||
|
|
|
@ -44,6 +44,7 @@ void TestRustObject::testSimpleFunction()
|
|||
person.setUserName("Konqi");
|
||||
|
||||
// THEN
|
||||
QCOMPARE(person.userName(), QString("Konqi"));
|
||||
QCOMPARE((int)person.vowelsInName(), 2);
|
||||
}
|
||||
|
||||
|
|
|
@ -3,22 +3,9 @@
|
|||
|
||||
namespace {
|
||||
|
||||
struct qstring_t {
|
||||
private:
|
||||
const void* data;
|
||||
int len;
|
||||
public:
|
||||
qstring_t(const QString& v):
|
||||
data(static_cast<const void*>(v.utf16())),
|
||||
len(v.size()) {
|
||||
}
|
||||
operator QString() const {
|
||||
return QString::fromUtf8(static_cast<const char*>(data), len);
|
||||
}
|
||||
};
|
||||
typedef void (*qstring_set)(QString*, qstring_t*);
|
||||
void set_qstring(QString* v, qstring_t* val) {
|
||||
*v = *val;
|
||||
typedef void (*qstring_set)(QString* val, const char* utf8, int nbytes);
|
||||
void set_qstring(QString* val, const char* utf8, int nbytes) {
|
||||
*val = QString::fromUtf8(utf8, nbytes);
|
||||
}
|
||||
inline void personUserNameChanged(Person* o)
|
||||
{
|
||||
|
@ -29,9 +16,9 @@ extern "C" {
|
|||
Person::Private* person_new(Person*, void (*)(Person*));
|
||||
void person_free(Person::Private*);
|
||||
void person_user_name_get(const Person::Private*, QString*, qstring_set);
|
||||
void person_user_name_set(Person::Private*, qstring_t);
|
||||
void person_user_name_set(Person::Private*, const ushort *str, int len);
|
||||
void person_double_name(Person::Private*);
|
||||
qstring_t person_greet(const Person::Private*, qstring_t, QString*, qstring_set);
|
||||
void person_greet(const Person::Private*, const ushort*, int, QString*, qstring_set);
|
||||
quint8 person_vowels_in_name(const Person::Private*);
|
||||
};
|
||||
|
||||
|
@ -62,7 +49,7 @@ QString Person::userName() const
|
|||
return v;
|
||||
}
|
||||
void Person::setUserName(const QString& v) {
|
||||
person_user_name_set(m_d, v);
|
||||
person_user_name_set(m_d, reinterpret_cast<const ushort*>(v.data()), v.size());
|
||||
}
|
||||
void Person::doubleName()
|
||||
{
|
||||
|
@ -71,7 +58,7 @@ void Person::doubleName()
|
|||
QString Person::greet(const QString& Name) const
|
||||
{
|
||||
QString s;
|
||||
person_greet(m_d, Name, &s, set_qstring);
|
||||
person_greet(m_d, Name.utf16(), Name.size(), &s, set_qstring);
|
||||
return s;
|
||||
}
|
||||
quint8 Person::vowelsInName() const
|
||||
|
|
Loading…
Reference in New Issue