Skip to content

Instantly share code, notes, and snippets.

@rust-play
Created August 4, 2019 19:58
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save rust-play/934334234ecdd436a3ff91a945d7fb93 to your computer and use it in GitHub Desktop.
Save rust-play/934334234ecdd436a3ff91a945d7fb93 to your computer and use it in GitHub Desktop.
Code shared from the Rust Playground
//! [dependencies]
//! fstrings = "0.1.4"
//! itertools = "0.8.0"
//! lazy_static = "1.3.0"
//! libc = "0.2.60"
//! libloading = "0.5.2"
#[macro_use] extern crate fstrings;
use ::std::{*,
convert::{
TryInto,
TryFrom,
},
ffi::{
CStr,
},
fmt::Write,
};
use ::libc::{
c_int as int,
};
use ::libloading::{
Library,
Symbol,
};
#[allow(bad_style)]
type char = u8;
/// TODO: implement utf-16 when needed
macro_rules! TEXT {(
$text:expr
) => (
concat!($text, "\0")
)}
#[derive(
Debug,
Default,
Clone, Copy,
)]
#[repr(C, packed(1))]
struct SynthForm {
form: [char; 30],
stem_length: int,
}
#[derive(
Debug,
Default,
Clone, Copy,
)]
#[repr(C, packed(1))]
struct SynthFormSet {
declination_type: int,
part_of_speech: [char; 3],
number_of_options: int,
parallel_forms: int,
form_code: [char; 30],
forms: [SynthForm; 5],
}
type SynthesizeFormsFunc =
unsafe
extern "stdcall"
fn (*const char, int, int, *mut SynthFormSet, int) -> int
;
fn synthesize (word: &'_ CStr)
{
let mut buffer = [SynthFormSet::default(); 300];
// use a static to avoid issues with the library being deallocated
::lazy_static::lazy_static!{
static ref DLL_INSTANCE: Library =
Library::new(TEXT!("fmsynth.dll"))
.expect("Failed to load the dynamic library `fmsynth.dll`")
;
static ref SYNTHESIZE_FORMS: Symbol<'static, SynthesizeFormsFunc> = unsafe {
DLL_INSTANCE
.get(b"SynthesizeForms\0")
.expect("Failed to dynamically load `SynthesizeForms`")
};
}
let count = usize::try_from(unsafe {
SYNTHESIZE_FORMS(
word.as_ptr() as *const char,
0,
0,
buffer.as_mut_ptr(),
buffer.len().try_into().expect("Overflow"),
)
}).expect("Overflow");
println!("Options found: {}", count);
// buffer[.. count]
// .iter()
// .for_each(|form| println_f!("{form:#?}"))
// ;
let mut string = String::new();
for &SynthFormSet {
declination_type,
part_of_speech,
number_of_options,
parallel_forms,
form_code,
forms,
} in &buffer[.. count]
{
use ::itertools::Itertools;
let part_of_speech = String::from_utf8_lossy(&part_of_speech);
let form_code = String::from_utf8_lossy(&form_code);
string.clear();
write_f!(string,
"{part_of_speech}, {declination_type}, {number_of_options}, {parallel_forms}, {form_code}, {forms}, ",
forms =
forms[.. parallel_forms as usize]
.iter()
.map(|&SynthForm { ref form, stem_length }| {
(String::from_utf8_lossy(form), stem_length)
})
.format_with(" ~ ", |(form, stem_length), write| write(
&format_args!("{} ({})", form, stem_length)
)),
).unwrap();
println_f!("{string}");
}
}
macro_rules! c_str {(
$str:literal
) => (
CStr::from_bytes_with_nul(concat!($str, "\0").as_bytes())
.unwrap()
)}
fn main ()
{
synthesize(c_str!("iga"));
synthesize(c_str!("hea"));
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment