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
extern crate cpp_to_rust; use cpp_to_rust::config::Config; use cpp_to_rust::errors::{Result, ChainErr}; use cpp_to_rust::log; use cpp_to_rust::utils::run_command; use cpp_to_rust::file_utils::PathBufWithAdded; mod fix_header_names; use std::path::PathBuf; use std::process::Command; use std::env; fn run_qmake_query(arg: &str) -> Result<PathBuf> { let result = try!(run_command(Command::new("qmake").arg("-query").arg(arg), true, true)); Ok(PathBuf::from(result.trim())) } pub trait QtConfig { fn setup_qt_library(&mut self) -> Result<()>; fn exclude_qlist_eq_based_methods<S: AsRef<str>, I: IntoIterator<Item=S>>(&mut self, types: I); fn exclude_qvector_eq_based_methods<S: AsRef<str>, I: IntoIterator<Item=S>>(&mut self, types: I); } impl QtConfig for Config { fn setup_qt_library(&mut self) -> Result<()> { let qt_lib_name = try!(env::var("CARGO_MANIFEST_LINKS") .chain_err(|| "no environment variable: CARGO_MANIFEST_LINKS")); if !qt_lib_name.starts_with("Qt5") { return Err(format!("Invalid library name (must start with \"Qt5\"): {}", qt_lib_name) .into()); } let folder_name = format!("Qt{}", &qt_lib_name[3..]); log::info("Detecting Qt directories..."); let qt_install_headers_path = try!(run_qmake_query("QT_INSTALL_HEADERS")); log::info(format!("QT_INSTALL_HEADERS = \"{}\"", qt_install_headers_path.display())); let qt_install_libs_path = try!(run_qmake_query("QT_INSTALL_LIBS")); log::info(format!("QT_INSTALL_LIBS = \"{}\"", qt_install_libs_path.display())); self.add_include_path(&qt_install_headers_path); let dir = qt_install_headers_path.with_added(&folder_name); let qt_this_lib_headers_dir = if dir.exists() { self.add_include_path(&dir); self.add_target_include_path(&dir); self.add_lib_path(&qt_install_libs_path); self.add_linked_lib(qt_lib_name); dir } else { let dir2 = qt_install_libs_path.with_added(format!("{}.framework/Headers", folder_name)); if dir2.exists() { self.add_include_path(&dir2); self.add_target_include_path(&dir2); self.add_framework_path(&qt_install_libs_path); self.add_linked_framework(folder_name.clone()); dir2 } else { return Err(format!("extra header dir not found (tried: {}, {})", dir.display(), dir2.display()) .into()); } }; self.add_include_directive(&folder_name); self.add_cpp_data_filter(Box::new(move |cpp_data| { fix_header_names::fix_header_names(cpp_data, &qt_this_lib_headers_dir) })); self.add_cpp_parser_blocked_name("qt_check_for_QGADGET_macro"); Ok(()) } fn exclude_qlist_eq_based_methods<S: AsRef<str>, I: IntoIterator<Item=S>>(&mut self, types: I) { let types: Vec<String> = types.into_iter().map(|x| x.as_ref().to_string()).collect(); self.add_cpp_ffi_generator_filter(Box::new(move |method| { if let Some(ref info) = method.class_membership { if info.class_type.name == "QList" { let args = try!(info.class_type.template_arguments.as_ref() .chain_err(|| "failed to get QList args")); let arg = try!(args.get(0).chain_err(|| "failed to get QList arg")); let arg_text = arg.to_cpp_pseudo_code(); if types.iter().any(|x| x == &arg_text) { match method.name.as_ref() { "operator==" | "operator!=" | "indexOf" | "lastIndexOf" | "contains" | "startsWith" | "endsWith" | "removeOne" | "removeAll" | "value" | "toVector" | "toSet" => return Ok(false), "count" => if method.arguments.len() == 1 { return Ok(false); }, _ => {} } } } } Ok(true) })); } fn exclude_qvector_eq_based_methods<S: AsRef<str>, I: IntoIterator<Item=S>>(&mut self, types: I) { let types: Vec<String> = types.into_iter().map(|x| x.as_ref().to_string()).collect(); self.add_cpp_ffi_generator_filter(Box::new(move |method| { if let Some(ref info) = method.class_membership { if info.class_type.name == "QVector" { let args = try!(info.class_type.template_arguments.as_ref() .chain_err(|| "failed to get QVector args")); let arg = try!(args.get(0).chain_err(|| "failed to get QVector arg")); let arg_text = arg.to_cpp_pseudo_code(); if types.iter().any(|x| x == &arg_text) { match method.name.as_ref() { "operator==" | "operator!=" | "indexOf" | "lastIndexOf" | "contains" | "startsWith" | "endsWith" | "removeOne" | "removeAll" | "toList" => return Ok(false), "count" => if method.arguments.len() == 1 { return Ok(false); }, _ => {} } } } } Ok(true) })); } }