#[macro_use]
extern crate lazy_static;
use bindgen::callbacks::{EnumVariantValue, IntKind, ParseCallbacks};
use std::collections::BTreeMap;
use std::env;
use std::fs::OpenOptions;
use std::io::Write;
use std::path::PathBuf;
use std::sync::{Arc, Mutex};
use std::fmt::Error;
#[derive(Debug)]
struct Enum {
name: String,
kind: IntKind,
variant: BTreeMap<i64, String>,
}
impl Enum {
fn new(name: String, kind: IntKind) -> Self {
Self {
name: name,
kind: kind,
variant: BTreeMap::new(),
}
}
}
lazy_static! {
static ref ENUMS: Arc<Mutex<BTreeMap<String, Enum>>> = Arc::new(Mutex::new(BTreeMap::new()));
}
#[derive(Debug)]
struct InkViewTypeChooser;
impl ParseCallbacks for InkViewTypeChooser {
fn int_macro(&self, name: &str, value: i64) -> Option<IntKind> {
let mutex = Arc::clone(&ENUMS);
let mut enum_map = mutex.lock().unwrap();
for (prefix, enum_kind) in &mut *enum_map {
if name.starts_with(prefix.as_str()) {
let mut variant_name = String::from(&name[prefix.len()..]);
if let Some(first) = variant_name.chars().next() {
if first.is_digit(10) {
variant_name.insert_str(0, &enum_kind.name.to_uppercase());
}
}
enum_kind.variant.insert(value, variant_name);
return Some(enum_kind.kind);
}
}
if value >= i32::MIN as i64 && value <= i32::MAX as i64 {
Some(IntKind::I32)
} else {
None
}
}
fn enum_variant_name(
&self,
enum_name: Option<&str>,
original_variant_name: &str,
_variant_value: EnumVariantValue,
) -> Option<String> {
match enum_name {
Some("PANEL_FLAGS") => Some(original_variant_name[6..].to_string()),
_ => None,
}
}
fn item_name(&self, original_item_name: &str) -> Option<String> {
match original_item_name {
"PANEL_FLAGS" => Some(String::from("PanelType")),
_ => None,
}
}
}
fn main() -> std::io::Result<()> {
println!("Codegen started");
if !cfg!(feature="sdk_v6") && !cfg!(feature="sdk_v4"){
return Ok(())
}
println!("argo:rustc-link-lib=inkview");
{
let mutex = Arc::clone(&ENUMS);
let mut enum_map = mutex.lock().unwrap();
enum_map.insert(
String::from("EVT_"),
Enum::new(String::from("Event"), IntKind::I32),
);
if cfg!(feature = "sdk_v6") {
enum_map.insert(
String::from("IV_KEY_"),
Enum::new(String::from("Key"), IntKind::I32),
);
} else if cfg!(feature = "sdk_v4") {
enum_map.insert(
String::from("KEY_"),
Enum::new(String::from("Key"), IntKind::I32),
);
} else {
}
enum_map.insert(
String::from("REQ_"),
Enum::new(String::from("Request"), IntKind::I32),
);
enum_map.insert(
String::from("ICON_"),
Enum::new(String::from("Icon"), IntKind::I32),
);
enum_map.insert(
String::from("DEF_"),
Enum::new(String::from("Button"), IntKind::I32),
);
enum_map.insert(String::from("DITHER_"), Enum::new(String::from("Dither"), IntKind::I32));
}
if !cfg!(feature="sdk_v6") && !cfg!(feature="sdk_v4"){
return Ok(())
}
let bindings = bindgen::Builder::default()
.header_contents(
"inkview.h",
"#include <inkview.h>"
)
.whitelist_var("[A-Z]+DIR[0-9]?")
.whitelist_var("[A-Z]+DATA[0-9]?")
.whitelist_var("[A-Z]+PATH[0-9]?")
.whitelist_var("[A-Z]+PROFILES?[0-9]?")
.whitelist_var("[A-Z]+FILE")
.whitelist_var("USER[A-Z]+")
.whitelist_var("SYSTEM[A-Z]+")
.whitelist_var("[A-Z][0-9A-Z_]*_APP(_PATH)?")
.whitelist_var("STATECLEANER")
.whitelist_var("[A-Z]+SCRIPT")
.whitelist_var("NETAGENT[A-Z]*")
.whitelist_var("[A-Z]+APP")
.whitelist_var("POCKETBOOKSIG")
.whitelist_var("LASTOPENBOOKS")
.whitelist_var("CURRENTBOOK_SAVE")
.whitelist_var("FAVORITES")
.whitelist_var("CURRENTBOOK")
.whitelist_var("BOOKSHELFSTATE")
.whitelist_var("BOOKSHELFSTATE_NV")
.whitelist_var("DICKEYBOARD")
.whitelist_var("URLHISTORY")
.whitelist_var("WEBCACHE[A-Z]*")
.whitelist_var("WIDGETS[A-Z]+")
.whitelist_var("SWUPDATESTATUS")
.whitelist_var("[A-Z]+FOLDER")
.whitelist_var("SOCIAL[A-Z_]+")
.whitelist_var("[A-Z][0-9A-Z_]*_DIRECTORY")
.whitelist_var("[A-Z][0-9A-Z_]*_FILE")
.whitelist_var("[A-Z][0-9A-Z_]*_CFG")
.whitelist_var("[A-Z][0-9A-Z_]*_PATH")
.whitelist_var("BROWSER_FOR_AUTH")
.whitelist_var("READER_[0-9A-Z_]+")
.whitelist_var("OBREEY_[0-9A-Z_]+")
.whitelist_var("PROFILE_[0-9A-Z_]+")
.whitelist_var("SYSTEMDEPTH")
.whitelist_var("MAXMSGSIZE")
.whitelist_type("AvrcpCommands")
.whitelist_function("IS[A-Z]+EVENT")
.whitelist_var("KEYMAPPING_KEY_[0-9A-Z_]+")
.whitelist_var("BLACK")
.whitelist_var("[DL]GRAY")
.whitelist_var("WHITE")
.whitelist_var("ITEM_[0-9A-Z_]+")
.whitelist_var("KBD_[0-9A-Z_]+")
.whitelist_var("NO_DISMISS")
.whitelist_var("WITH_SIZE")
.whitelist_var("PANELICON_[0-9A-Z_]+")
.whitelist_var("LIST(FLAG)?_[0-9A-Z_]+")
.whitelist_var("BMK_[0-9A-Z_]+")
.whitelist_var("CFG_[0-9A-Z_]+")
.whitelist_var("[A-Z]+TASKS?")
.whitelist_var("TASK_[0-9A-Z_]+")
.whitelist_var("RQL_[0-9A-Z_]+")
.whitelist_var("ALIGN_[A-Z]+")
.whitelist_var("VALIGN_[A-Z]+")
.whitelist_var("ROTATE")
.whitelist_var("HYPHENS")
.whitelist_var("DOTS")
.whitelist_var("RTLAUTO")
.whitelist_var("UNDERLINE")
.whitelist_var("STRETCH")
.whitelist_var("TILE")
.whitelist_var("TO_UPPER")
.whitelist_var("FR_[A-Z]+")
.whitelist_var("ARROW_[A-Z]+")
.whitelist_var("SYMBOL_[A-Z]+")
.whitelist_var("IMAGE_[A-Z]+")
.whitelist_var("ROTATE[0-9]+")
.whitelist_var("[XY]MIRROR")
.whitelist_var("A2DITHER")
.whitelist_var("DITHER_[A-Z]+")
.whitelist_var("QN_[A-Z]+")
.whitelist_type("PB_(TTS_)?STATE")
.whitelist_var("MP_[A-Z]+")
.whitelist_var("FTYPE_[A-Z]+")
.whitelist_var("OB_[A-Z]+")
.whitelist_var("NET_[0-9A-Z]+")
.whitelist_var("CONN_[0-9A-Z]+")
.whitelist_var("BLUETOOTH_[A-Z]+")
.whitelist_type("WIFI_SECURITY")
.whitelist_type("NET_STATE")
.whitelist_var("VN_[A-Z]+")
.whitelist_var("A2DP_[0-9A-Z_]+")
.whitelist_var("CF_[0-9A-Z_]+")
.whitelist_var("FONT_ACTIVATE_CODE")
.whitelist_function("TOUCHDRAGDEADZONE")
.whitelist_type("FONT_TYPE")
.whitelist_type("SideFlags")
.whitelist_type("PANEL_FLAGS")
.whitelist_function("iv_[0-9a-z_]+")
.whitelist_function("DEFAULTFONT[A-Z]*")
.whitelist_type("irect")
.whitelist_type("ibitmap")
.whitelist_type("control_panel")
.whitelist_type("TransparentHandle")
.whitelist_type("ihash(_item)?")
.whitelist_type("ifont[0-9a-z_]+")
.whitelist_type("FONT_MENU_FLAGS")
.whitelist_type("iuser_font")
.whitelist_type("imenu[0-9a-z_]+")
.whitelist_type("icanvas")
.whitelist_type("icontext_menu[0-9a-z_]+")
.whitelist_type("font_selector_properties")
.whitelist_type("iapp_caption")
.whitelist_type("itaskmgr")
.whitelist_type("ipager")
.whitelist_type("iselection")
.whitelist_type("iappstyle")
.whitelist_type("ievent")
.whitelist_type("iconfig(edit)?")
.whitelist_type("oldconfigedit")
.whitelist_type("tocentry")
.whitelist_type("itimer")
.whitelist_type("bookinfo")
.whitelist_type("iv_[0-9a-z_]+")
.whitelist_type("(sub)?taskinfo")
.whitelist_type("network_interface[a-z_]*")
.whitelist_type("bt_[0-9a-z_]+")
.whitelist_type("obex_[0-9a-z_]+")
.whitelist_type("audio_output[a-z_]*")
.whitelist_type("icolor_map")
.whitelist_type("APPLICATION_ATTRIBUTE")
.whitelist_function("(Open|Close)[A-Z][A-Za-z]*")
.whitelist_function("InkViewMain")
.whitelist_function("CloseApp")
.whitelist_function("InitInkview")
.whitelist_function("iRect")
.whitelist_function("Screen(Width|Height)")
.whitelist_function("[SG]et[A-Z][A-Za-z]*")
.whitelist_function("[SG]et(Global|GSensor)?Orientation")
.whitelist_var("GSENSOR_[A-Z]+")
.whitelist_function("[A-Z][a-z]+GSensor(Enabled)?")
.whitelist_type("estyle")
.whitelist_function("Clear[A-Z][A-Za-z]*")
.whitelist_function("ClearScreen")
.whitelist_function("([SG]et|Merge)Clip(Rect)?")
.whitelist_function("Draw[A-Z][A-Za-z]*")
.whitelist_function("Fill[A-Z][A-Za-z]*")
.whitelist_function("Invert[A-Z][A-Za-z]*")
.whitelist_function("ColorMap[A-Z][A-Za-z]*")
.whitelist_function("Dim[A-Z][A-Za-z]*")
.whitelist_function("DitherArea((Quick|Pattern)2Level)?")
.whitelist_function("QuickFloyd16Dither")
.whitelist_function("Stretch[A-Z][A-Za-z]*")
.whitelist_function("[SG]etCanvas")
.whitelist_function("Repaint")
.whitelist_function("CheckFramePointer")
.whitelist_function("(Get|Is)?Pager[A-Z][A-Za-z]*")
.whitelist_function("Transparent(Rect)?")
.whitelist_function("(Load|Save)[A-Z][A-Za-z]*")
.whitelist_function("(zLoad|New|Copy|Move|Tile|Mirror)Bitmap([A-Z][A-Za-z]*)?")
.whitelist_function("SetTransparentColor")
.whitelist_function("EnumFonts([A-Z][A-Za-z]*)?")
.whitelist_function("FreeFontsForSort")
.whitelist_function("(Open|Close|[SG]et)Font")
.whitelist_function("TextRectHeight(Ex)?")
.whitelist_function("PanelHeight")
.whitelist_function("(MinimalTextRect|Char|String|GetMultilineString)Width(Ext)?")
.whitelist_function("RegisterFontList")
.whitelist_function("SetTextStrength")
.whitelist_function("(Full|Soft|Partial|Dynamic|Exit|IsInA2|Fine|HQ|Schedule|WaitFor)Update([A-Z][A-Za-z0-9]*)?")
.whitelist_function("[SG]etEventHandler(Ex)?")
.whitelist_function("SendEvent(Ex)?")
.whitelist_function("(Flush|Is)AnyEvents")
.whitelist_function("GetCurrentEventExData")
.whitelist_function("ProcessEventLoop(Quick)?")
.whitelist_function("PrepareForLoop")
.whitelist_function("ClearOnExit")
.whitelist_function("(Set(Hard|Weak)|Query|Clear)Timer(Ex|ByName)?")
.whitelist_function("(Open|Update)Menu(Ex|3x3)?")
.whitelist_function("Message")
.whitelist_function("(Open|Set|Create|Close)ContextMenu")
.whitelist_function("GetMenuRect(Ex)?")
.whitelist_function("Open(Dummy)?List")
.whitelist_function("[SG]etListHeaderLevel")
.whitelist_function("EnumKeyboards")
.whitelist_function("BitmapStretchCopy")
.blacklist_item("O_[A-Z]+")
.blacklist_item("E(NOT|IS)DIR")
.blacklist_item("E[NM]FILE")
.blacklist_item("ENODATA")
.ctypes_prefix("c_types")
.default_enum_style(bindgen::EnumVariation::Rust{non_exhaustive: false})
.bitfield_enum("PanelType")
.generate_comments(true)
.layout_tests(false)
.parse_callbacks(Box::new(InkViewTypeChooser))
.prepend_enum_name(false)
.rustfmt_bindings(true)
.use_core()
.generate()
.expect("Unable to generate bindings");
println!("{}", env::var("OUT_DIR").unwrap());
let out_path = PathBuf::from(env::var("OUT_DIR").unwrap());
let file = OpenOptions::new()
.write(true)
.truncate(true)
.create(true)
.open(out_path.join("bindings.rs"))?;
let mut file_copy = file.try_clone()?;
bindings.write(Box::new(file))?;
{
let mutex = Arc::clone(&ENUMS);
let enum_map = mutex.lock().unwrap();
for (_prefix, enum_kind) in &*enum_map {
match enum_kind.kind {
IntKind::I32 => {
writeln!(file_copy, "#[repr(i32)]")?;
}
IntKind::U32 => {
writeln!(file_copy, "#[repr(u32)]")?;
}
_ => {}
}
writeln!(
file_copy,
"#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, FromPrimitive)]"
)?;
writeln!(file_copy, "pub enum {} {{", enum_kind.name)?;
for (variant_value, variant_name) in &enum_kind.variant {
writeln!(file_copy, " {} = {},", variant_name, variant_value)?;
}
writeln!(file_copy, "}}")?;
}
}
Ok(())
}