+
+
+
+
+
+
\ No newline at end of file
diff --git a/rust_crates/registry/src/github.com-1ecc6299db9ec823/dlopen-0.1.7/.travis.yml b/rust_crates/registry/src/github.com-1ecc6299db9ec823/dlopen-0.1.7/.travis.yml
new file mode 100644
index 0000000000..2f846ba6ed
--- /dev/null
+++ b/rust_crates/registry/src/github.com-1ecc6299db9ec823/dlopen-0.1.7/.travis.yml
@@ -0,0 +1,44 @@
+language: rust
+sudo: required
+cache: cargo
+rust:
+ - 1.24.0
+ - stable
+ - nightly
+ - beta
+os:
+ - linux
+ - osx
+env:
+ - ARCH=x86_64
+ - ARCH=i686
+
+matrix:
+ allow_failures:
+ - rust: nightly
+
+addons:
+ apt:
+ packages:
+ - libcurl4-openssl-dev
+ - libelf-dev
+ - libdw-dev
+ - cmake
+ - gcc
+ - binutils-dev
+ - libiberty-dev
+
+after_success: |
+ wget https://github.com/SimonKagstrom/kcov/archive/master.tar.gz &&
+ tar xzf master.tar.gz &&
+ cd kcov-master &&
+ mkdir build &&
+ cd build &&
+ cmake .. &&
+ make &&
+ make install DESTDIR=../../kcov-build &&
+ cd ../.. &&
+ rm -rf kcov-master &&
+ for file in target/debug/dlopen-*[^\.d]; do mkdir -p "target/cov/$(basename $file)"; ./kcov-build/usr/local/bin/kcov --exclude-pattern=/.cargo,/usr/lib --verify "target/cov/$(basename $file)" "$file"; done &&
+ bash <(curl -s https://codecov.io/bash) &&
+ echo "Uploaded code coverage"
\ No newline at end of file
diff --git a/rust_crates/registry/src/github.com-1ecc6299db9ec823/dlopen-0.1.7/Cargo.toml b/rust_crates/registry/src/github.com-1ecc6299db9ec823/dlopen-0.1.7/Cargo.toml
new file mode 100644
index 0000000000..bfb7afa825
--- /dev/null
+++ b/rust_crates/registry/src/github.com-1ecc6299db9ec823/dlopen-0.1.7/Cargo.toml
@@ -0,0 +1,78 @@
+# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
+#
+# When uploading crates to the registry Cargo will automatically
+# "normalize" Cargo.toml files for maximal compatibility
+# with all versions of Cargo and also rewrite `path` dependencies
+# to registry (e.g., crates.io) dependencies
+#
+# If you believe there's an error in this file please file an
+# issue against the rust-lang/cargo repository. If you're
+# editing this file be aware that the upstream Cargo.toml
+# will likely look very different (and much more reasonable)
+
+[package]
+name = "dlopen"
+version = "0.1.7"
+authors = ["Szymon Wieloch "]
+description = "Library for opening and operating on dynamic link libraries (also known as shared objects or shared libraries)."
+keywords = ["dlopen", "dll", "so", "dylib", "shared"]
+license = "MIT"
+repository = "https://github.com/szymonwieloch/rust-dlopen"
+
+[[example]]
+name = "raw"
+crate-type = ["bin"]
+
+[[example]]
+name = "symbor"
+crate-type = ["bin"]
+
+[[example]]
+name = "symbor_api"
+crate-type = ["bin"]
+
+[[example]]
+name = "wrapper_api"
+crate-type = ["bin"]
+
+[[example]]
+name = "wrapper_multi_api"
+crate-type = ["bin"]
+[dependencies.dlopen_derive]
+version = "0.1.4"
+
+[dependencies.lazy_static]
+version = "1.2.0"
+[dev-dependencies.const-cstr]
+version = "0.1"
+
+[dev-dependencies.example_dylib]
+version = "0.1.0"
+
+[dev-dependencies.libc]
+version = "0.2.29"
+
+[dev-dependencies.regex]
+version = "0.2"
+[target."cfg(unix)".dependencies.libc]
+version = "0.2.29"
+[target."cfg(windows)".dependencies.kernel32-sys]
+version = "0.2"
+
+[target."cfg(windows)".dependencies.winapi]
+version = "0.2"
+[badges.appveyor]
+branch = "master"
+repository = "szymonwieloch/rust-dlopen"
+
+[badges.codecov]
+branch = "master"
+repository = "szymonwieloch/rust-dlopen"
+service = "github"
+
+[badges.is-it-maintained-open-issues]
+repository = "szymonwieloch/rust-dlopen"
+
+[badges.travis-ci]
+branch = "master"
+repository = "szymonwieloch/rust-dlopen"
diff --git a/rust_crates/registry/src/github.com-1ecc6299db9ec823/dlopen-0.1.7/Cargo.toml.orig b/rust_crates/registry/src/github.com-1ecc6299db9ec823/dlopen-0.1.7/Cargo.toml.orig
new file mode 100644
index 0000000000..d64ad736d5
--- /dev/null
+++ b/rust_crates/registry/src/github.com-1ecc6299db9ec823/dlopen-0.1.7/Cargo.toml.orig
@@ -0,0 +1,70 @@
+[package]
+name = "dlopen"
+version = "0.1.7"
+authors = ["Szymon Wieloch "]
+description = "Library for opening and operating on dynamic link libraries (also known as shared objects or shared libraries)."
+keywords = [
+ #common functions
+ "dlopen", "dll", "so", "dylib", "shared"]
+license = "MIT"
+repository = "https://github.com/szymonwieloch/rust-dlopen"
+
+[dependencies]
+lazy_static = "1.2.0"
+
+[dependencies.dlopen_derive]
+path = "rust-dlopen-derive"
+version = "0.1.4"
+
+[target.'cfg(windows)'.dependencies]
+winapi = "0.2"
+kernel32-sys = "0.2"
+
+[target.'cfg(unix)'.dependencies]
+libc = "0.2.29"
+
+
+[dev-dependencies.example_dylib]
+path = "rust-example-dylib"
+version = "0.1.0"
+
+[dev-dependencies]
+const-cstr = "0.1"
+libc = "0.2.29"
+regex = "0.2"
+
+[badges.travis-ci]
+repository = "szymonwieloch/rust-dlopen"
+branch = "master"
+
+[badges.appveyor]
+repository = "szymonwieloch/rust-dlopen"
+branch = "master"
+
+[badges.is-it-maintained-open-issues]
+repository = "szymonwieloch/rust-dlopen"
+
+[badges.codecov]
+repository = "szymonwieloch/rust-dlopen"
+branch = "master"
+service = "github"
+
+[[example]]
+name = "raw"
+crate-type = ["bin"]
+
+[[example]]
+name = "symbor"
+crate-type = ["bin"]
+
+[[example]]
+name = "symbor_api"
+crate-type = ["bin"]
+
+[[example]]
+name = "wrapper_api"
+crate-type = ["bin"]
+
+[[example]]
+name = "wrapper_multi_api"
+crate-type = ["bin"]
diff --git a/rust_crates/registry/src/github.com-1ecc6299db9ec823/dlopen-0.1.7/LICENSE b/rust_crates/registry/src/github.com-1ecc6299db9ec823/dlopen-0.1.7/LICENSE
new file mode 100644
index 0000000000..06d65cd3bb
--- /dev/null
+++ b/rust_crates/registry/src/github.com-1ecc6299db9ec823/dlopen-0.1.7/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2017 Szymon Wieloch
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/rust_crates/registry/src/github.com-1ecc6299db9ec823/dlopen-0.1.7/README.md b/rust_crates/registry/src/github.com-1ecc6299db9ec823/dlopen-0.1.7/README.md
new file mode 100644
index 0000000000..ad6e7ddeb7
--- /dev/null
+++ b/rust_crates/registry/src/github.com-1ecc6299db9ec823/dlopen-0.1.7/README.md
@@ -0,0 +1,76 @@
+# rust-dlopen
+
+[![Travis CI][tcii]][tci] [![Appveyor CI][acii]][aci] [![Crates CI][ccii]][cci] [![Codedov CI][vcii]][vci]
+
+[tcii]: https://travis-ci.org/szymonwieloch/rust-dlopen.svg?branch=master
+[tci]: https://travis-ci.org/szymonwieloch/rust-dlopen
+[acii]: https://ci.appveyor.com/api/projects/status/github/szymonwieloch/rust-dlopen?svg=true
+[aci]: https://ci.appveyor.com/project/szymonwieloch/rust-dlopen
+[ccii]: https://img.shields.io/crates/v/dlopen.svg
+[cci]: https://crates.io/crates/dlopen
+[vcii]: https://codecov.io/api/gh/szymonwieloch/rust-dlopen/branch/master/graph/badge.svg
+[vci]: https://codecov.io/gh/szymonwieloch/rust-dlopen
+
+# Overview
+
+This library is my effort to make use of dynamic link libraries in Rust simple.
+Previously existing solutions were either unsafe, provided huge overhead of required writing too much code to achieve simple things.
+I hope that this library will help you to quickly get what you need and avoid errors.
+
+# Features
+
+## Main features
+
+* Supports majority of platforms and is platform independent.
+* Is consistent with Rust error handling mechanism and makes making mistakes much more difficult.
+* Is very lightweight. It mostly uses zero cost wrappers to create safer abstractions over platform API.
+* Is thread safe.
+* Is object-oriented programming friendly.
+* Has a low-level API that provides full flexibility of using libraries.
+* Has two high-level APIs that protect against dangling symbols - each in its own way.
+* High level APIs support automatic loading of symbols into structures. You only need to define a
+ structure that represents an API. The rest happens automatically and requires only minimal amount of code.
+* Automatic loading of symbols helps you to follow the DRY paradigm.
+
+## Compare with other libraries
+
+|Feature | dlopen | [libloading](https://github.com/nagisa/rust_libloading) | [sharedlib](https://github.com/Tyleo/sharedlib) |
+|------------------------------------|------------|---------------------------------------------------------|-------------------------------------------------|
+| Basic functionality | Yes | Yes | Yes |
+| Multiplatform | Yes | Yes | Yes |
+|Dangling symbol prevention | Yes | Yes | Yes |
+| Thread safety | Yes | **Potential problem with SetErrorMode() on older Windows platforms** | **No support for SetErrorMode (library may block the application on Windows)**|
+| Loading of symbols into structures | Yes | **No** | **No**
+| Overhead | Minimal | Minimal | **Some overhead** |
+| Low-level, unsafe API | Yes | Yes | Yes |
+| Object-oriented friendly | Yes | **No** | Yes |
+
+## Safety
+
+Please note that while Rust aims at being 100% safe language, it does not yet provide mechanisms that would allow me to create a 100% safe library, so I had to settle on 99%.
+Also the nature of dynamic link libraries requires casting obtained pointers into types that are defined on the application side. And this cannot be safe.
+Having said that I still think that this library provides the best approach and greatest safety possible in Rust.
+
+# Usage:
+
+Cargo.toml:
+
+```toml
+[dependencies]
+dlopen = "0.1"
+```
+
+# Documentation
+
+[Cargo documentation](https://docs.rs/dlopen)
+
+# License
+This code is licensed under [MIT](./LICENSE) license.
+
+# Changelog
+
+[GitHub changelog](https://github.com/szymonwieloch/rust-dlopen/releases)
+
+# Acknowledgement
+
+Special thanks to [Simonas Kazlauskas](https://github.com/nagisa) whose [libloading](https://github.com/nagisa/rust_libloading) became code base for my project.
diff --git a/rust_crates/registry/src/github.com-1ecc6299db9ec823/dlopen-0.1.7/appveyor.yml b/rust_crates/registry/src/github.com-1ecc6299db9ec823/dlopen-0.1.7/appveyor.yml
new file mode 100644
index 0000000000..92342f956c
--- /dev/null
+++ b/rust_crates/registry/src/github.com-1ecc6299db9ec823/dlopen-0.1.7/appveyor.yml
@@ -0,0 +1,19 @@
+environment:
+ matrix:
+ - TARGET: nightly-x86_64-pc-windows-msvc
+ - TARGET: nightly-i686-pc-windows-msvc
+ - TARGET: nightly-x86_64-pc-windows-gnu
+ - TARGET: nightly-i686-pc-windows-gnu
+ - TARGET: 1.24.0-x86_64-pc-windows-msvc
+ - TARGET: 1.24.0-i686-pc-windows-msvc
+ - TARGET: 1.24.0-x86_64-pc-windows-gnu
+ - TARGET: 1.24.0-i686-pc-windows-gnu
+install:
+ - ps: Start-FileDownload "https://static.rust-lang.org/dist/rust-${env:TARGET}.exe" -FileName "rust.exe"
+ - ps: .\rust.exe /VERYSILENT /NORESTART /DIR="C:\rust" | Out-Null
+ - ps: $env:PATH="$env:PATH;C:\rust\bin"
+ - rustc -vV
+ - cargo -vV
+build: off
+test_script:
+ - cargo test
\ No newline at end of file
diff --git a/rust_crates/registry/src/github.com-1ecc6299db9ec823/dlopen-0.1.7/examples/README.md b/rust_crates/registry/src/github.com-1ecc6299db9ec823/dlopen-0.1.7/examples/README.md
new file mode 100644
index 0000000000..61a4462601
--- /dev/null
+++ b/rust_crates/registry/src/github.com-1ecc6299db9ec823/dlopen-0.1.7/examples/README.md
@@ -0,0 +1,14 @@
+# rust-dlopen examples
+
+Files in directory perform very similar operations
+but they use different APIs. You can compare these
+approaches and choose the API that suits your needs.
+Operations include calling both Rust and C functions,
+access to constant and mutable static data,
+modifying mutable data and operations on common data types.
+
+All examples use an example library that gets built
+together with this project. It covers most types
+of exported symbols, therefor it allows you to check
+if the library actually obtains correctly all kinds
+of symbols.
diff --git a/rust_crates/registry/src/github.com-1ecc6299db9ec823/dlopen-0.1.7/examples/commons/mod.rs b/rust_crates/registry/src/github.com-1ecc6299db9ec823/dlopen-0.1.7/examples/commons/mod.rs
new file mode 100644
index 0000000000..6b26ea7ecf
--- /dev/null
+++ b/rust_crates/registry/src/github.com-1ecc6299db9ec823/dlopen-0.1.7/examples/commons/mod.rs
@@ -0,0 +1,38 @@
+extern crate dlopen;
+extern crate libc;
+extern crate regex;
+use dlopen::utils::{PLATFORM_FILE_EXTENSION, PLATFORM_FILE_PREFIX};
+use std::env;
+use std::path::PathBuf;
+use libc::c_int;
+
+//Rust when building dependencies adds some weird numbers to file names
+// find the file using this pattern:
+//const FILE_PATTERN: &str = concat!(PLATFORM_FILE_PREFIX, "example.*\\.", PLATFORM_FILE_EXTENSION);
+
+
+pub fn example_lib_path() -> PathBuf {
+ let file_pattern = format!(
+ r"{}example.*\.{}",
+ PLATFORM_FILE_PREFIX,
+ PLATFORM_FILE_EXTENSION
+ );
+ let file_regex = regex::Regex::new(file_pattern.as_ref()).unwrap();
+ //build path to the example library that covers most cases
+ let mut lib_path = PathBuf::from(env::var_os("CARGO_MANIFEST_DIR").unwrap());
+ lib_path.extend(["target", "debug", "deps"].iter());
+ let entry = lib_path.read_dir().unwrap().find(|e| match e {
+ &Ok(ref entry) => file_regex.is_match(entry.file_name().to_str().unwrap()),
+ &Err(ref err) => panic!("Could not read cargo debug directory: {}", err),
+ });
+ lib_path.push(entry.unwrap().unwrap().file_name());
+ println!("Library path: {}", lib_path.to_str().unwrap());
+ lib_path
+}
+
+#[allow(dead_code)] //not all examples use this and this generates warnings
+#[repr(C)]
+pub struct SomeData {
+ pub first: c_int,
+ pub second: c_int,
+}
diff --git a/rust_crates/registry/src/github.com-1ecc6299db9ec823/dlopen-0.1.7/examples/raw.rs b/rust_crates/registry/src/github.com-1ecc6299db9ec823/dlopen-0.1.7/examples/raw.rs
new file mode 100644
index 0000000000..7ea75c11db
--- /dev/null
+++ b/rust_crates/registry/src/github.com-1ecc6299db9ec823/dlopen-0.1.7/examples/raw.rs
@@ -0,0 +1,72 @@
+#[macro_use]
+extern crate const_cstr;
+extern crate dlopen;
+extern crate libc;
+
+mod commons;
+
+use commons::{example_lib_path, SomeData};
+use dlopen::raw::Library;
+use libc::{c_char, c_int};
+use std::ffi::CStr;
+
+fn main() {
+ let lib_path = example_lib_path();
+ let lib = Library::open(lib_path).expect("Could not open library");
+
+ //get several symbols and play around
+ let rust_fun_print_something: fn() =
+ unsafe { lib.symbol_cstr(const_cstr!("rust_fun_print_something").as_cstr()) }.unwrap();
+ rust_fun_print_something();
+
+ let rust_fun_add_one: fn(i32) -> i32 =
+ unsafe { lib.symbol_cstr(const_cstr!("rust_fun_add_one").as_cstr()) }.unwrap();
+ println!(" 5+1={}", rust_fun_add_one(5));
+
+ let c_fun_print_something_else: unsafe extern "C" fn() =
+ unsafe { lib.symbol_cstr(const_cstr!("c_fun_print_something_else").as_cstr()) }.unwrap();
+ unsafe { c_fun_print_something_else() };
+
+ let c_fun_add_two: unsafe extern "C" fn(c_int) -> c_int =
+ unsafe { lib.symbol_cstr(const_cstr!("c_fun_add_two").as_cstr()) }.unwrap();
+ println!("2+2={}", unsafe { c_fun_add_two(2) });
+
+ let rust_i32: &i32 = unsafe { lib.symbol_cstr(const_cstr!("rust_i32").as_cstr()) }.unwrap();
+ println!("const rust i32 value: {}", rust_i32);
+
+ let rust_i32_mut: &mut i32 =
+ unsafe { lib.symbol_cstr(const_cstr!("rust_i32_mut").as_cstr()) }.unwrap();
+ println!("mutable rust i32 value: {}", rust_i32_mut);
+
+ *rust_i32_mut = 55;
+ //for a change use pointer to obtain its value
+ let rust_i32_ptr: *const i32 =
+ unsafe { lib.symbol_cstr(const_cstr!("rust_i32_mut").as_cstr()) }.unwrap();
+ println!("after change: {}", unsafe { *rust_i32_ptr });
+
+ //the same with C
+ let c_int: &c_int = unsafe { lib.symbol_cstr(const_cstr!("c_int").as_cstr()) }.unwrap();
+ println!("c_int={}", c_int);
+
+ //now static c struct
+
+ let c_struct: &SomeData =
+ unsafe { lib.symbol_cstr(const_cstr!("c_struct").as_cstr()) }.unwrap();
+ println!(
+ "c struct first: {}, second:{}",
+ c_struct.first,
+ c_struct.second
+ );
+
+ //let's play with strings
+
+ let rust_str: &&str = unsafe { lib.symbol_cstr(const_cstr!("rust_str").as_cstr()) }.unwrap();
+ println!("Rust says: {}", *rust_str);
+
+ let c_const_char_ptr: *const c_char =
+ unsafe { lib.symbol_cstr(const_cstr!("c_const_char_ptr").as_cstr()) }.unwrap();
+ let converted = unsafe { CStr::from_ptr(c_const_char_ptr) }
+ .to_str()
+ .unwrap();
+ println!("And now C says: {}", converted);
+}
diff --git a/rust_crates/registry/src/github.com-1ecc6299db9ec823/dlopen-0.1.7/examples/symbor.rs b/rust_crates/registry/src/github.com-1ecc6299db9ec823/dlopen-0.1.7/examples/symbor.rs
new file mode 100644
index 0000000000..43189940e0
--- /dev/null
+++ b/rust_crates/registry/src/github.com-1ecc6299db9ec823/dlopen-0.1.7/examples/symbor.rs
@@ -0,0 +1,80 @@
+#[macro_use]
+extern crate const_cstr;
+extern crate dlopen;
+extern crate libc;
+
+mod commons;
+
+use commons::{example_lib_path, SomeData};
+use dlopen::symbor::Library;
+use libc::{c_char, c_int};
+use std::ffi::CStr;
+
+
+fn main() {
+ let lib_path = example_lib_path();
+ let lib = Library::open(lib_path).expect("Could not open library");
+
+ let rust_fun_print_something = unsafe {
+ lib.symbol_cstr::(const_cstr!("rust_fun_print_something").as_cstr())
+ }.unwrap();
+ rust_fun_print_something();
+
+ let rust_fun_add_one = unsafe {
+ lib.symbol_cstr:: i32>(const_cstr!("rust_fun_add_one").as_cstr())
+ }.unwrap();
+ println!(" 5+1={}", rust_fun_add_one(5));
+
+ let c_fun_print_something_else = unsafe {
+ lib.symbol_cstr::(
+ const_cstr!("c_fun_print_something_else").as_cstr(),
+ )
+ }.unwrap();
+ unsafe { c_fun_print_something_else() };
+
+ let c_fun_add_two = unsafe {
+ lib.symbol_cstr:: c_int>(
+ const_cstr!("c_fun_add_two").as_cstr(),
+ )
+ }.unwrap();
+ println!("2+2={}", unsafe { c_fun_add_two(2) });
+
+ let rust_i32: &i32 = unsafe { lib.reference_cstr(const_cstr!("rust_i32").as_cstr()) }.unwrap();
+ println!("const rust i32 value: {}", rust_i32);
+
+ let rust_i32_mut: &mut i32 =
+ unsafe { lib.reference_mut_cstr(const_cstr!("rust_i32_mut").as_cstr()) }.unwrap();
+ println!("mutable rust i32 value: {}", rust_i32_mut);
+
+ *rust_i32_mut = 55;
+
+ //for a change use pointer to obtain its value
+ let rust_i32_ptr =
+ unsafe { lib.symbol_cstr::<*const i32>(const_cstr!("rust_i32_mut").as_cstr()) }.unwrap();
+ println!("after change: {}", unsafe { **rust_i32_ptr });
+
+ //the same with C
+ let c_int: &c_int = unsafe { lib.reference_cstr(const_cstr!("c_int").as_cstr()) }.unwrap();
+ println!("c_int={}", c_int);
+
+ //now static c struct
+ let c_struct: &SomeData =
+ unsafe { lib.reference_cstr(const_cstr!("c_struct").as_cstr()) }.unwrap();
+ println!(
+ "c struct first: {}, second:{}",
+ c_struct.first,
+ c_struct.second
+ );
+
+ //let's play with strings
+ let rust_str: &&str = unsafe { lib.reference_cstr(const_cstr!("rust_str").as_cstr()) }.unwrap();
+ println!("Rust says: {}", *rust_str);
+
+ let c_const_char_ptr = unsafe {
+ lib.symbol_cstr::<*const c_char>(const_cstr!("c_const_char_ptr").as_cstr())
+ }.unwrap();
+ let converted = unsafe { CStr::from_ptr(*c_const_char_ptr) }
+ .to_str()
+ .unwrap();
+ println!("And now C says: {}", converted);
+}
diff --git a/rust_crates/registry/src/github.com-1ecc6299db9ec823/dlopen-0.1.7/examples/symbor_api.rs b/rust_crates/registry/src/github.com-1ecc6299db9ec823/dlopen-0.1.7/examples/symbor_api.rs
new file mode 100644
index 0000000000..b69d8c8260
--- /dev/null
+++ b/rust_crates/registry/src/github.com-1ecc6299db9ec823/dlopen-0.1.7/examples/symbor_api.rs
@@ -0,0 +1,67 @@
+extern crate dlopen;
+#[macro_use]
+extern crate dlopen_derive;
+extern crate libc;
+
+mod commons;
+use commons::{example_lib_path, SomeData};
+use dlopen::symbor::{Library, PtrOrNull, Ref, RefMut, SymBorApi, Symbol};
+use libc::{c_char, c_int};
+use std::ffi::CStr;
+
+
+#[derive(SymBorApi)]
+struct Api<'a> {
+ pub rust_fun_print_something: Symbol<'a, fn()>,
+ pub rust_fun_add_one: Symbol<'a, fn(i32) -> i32>,
+ pub c_fun_print_something_else: Symbol<'a, unsafe extern "C" fn()>,
+ pub c_fun_add_two: Symbol<'a, unsafe extern "C" fn(c_int) -> c_int>,
+ pub rust_i32: Ref<'a, i32>,
+ pub rust_i32_mut: RefMut<'a, i32>,
+ #[dlopen_name = "rust_i32_mut"] pub rust_i32_ptr: Symbol<'a, *const i32>,
+ pub c_int: Ref<'a, c_int>,
+ pub c_struct: Ref<'a, SomeData>,
+ pub rust_str: Ref<'a, &'static str>,
+ pub c_const_char_ptr: PtrOrNull<'a, c_char>,
+}
+
+fn main() {
+ let lib_path = example_lib_path();
+ let lib = Library::open(lib_path).expect("Could not open library");
+ let mut api = unsafe { Api::load(&lib) }.expect("Could not load the API");
+
+ (api.rust_fun_print_something)();
+
+ println!(" 5+1={}", (api.rust_fun_add_one)(5));
+
+ unsafe { (api.c_fun_print_something_else)() };
+
+ println!("2+2={}", unsafe { (api.c_fun_add_two)(2) });
+
+ println!("const rust i32 value: {}", *api.rust_i32);
+
+ println!("mutable rust i32 value: {}", *api.rust_i32_mut);
+
+ *api.rust_i32_mut = 55;
+
+ //for a change use pointer to obtain its value
+ println!("after change: {}", unsafe { **api.rust_i32_ptr });
+
+ //the same with C
+ println!("c_int={}", *api.c_int);
+
+ //now static c struct
+ println!(
+ "c struct first: {}, second:{}",
+ api.c_struct.first,
+ api.c_struct.second
+ );
+
+ //let's play with strings
+ println!("Rust says: {}", *api.rust_str);
+
+ let converted = unsafe { CStr::from_ptr(*api.c_const_char_ptr) }
+ .to_str()
+ .unwrap();
+ println!("And now C says: {}", converted);
+}
diff --git a/rust_crates/registry/src/github.com-1ecc6299db9ec823/dlopen-0.1.7/examples/wrapper_api.rs b/rust_crates/registry/src/github.com-1ecc6299db9ec823/dlopen-0.1.7/examples/wrapper_api.rs
new file mode 100644
index 0000000000..e84e4e9c4c
--- /dev/null
+++ b/rust_crates/registry/src/github.com-1ecc6299db9ec823/dlopen-0.1.7/examples/wrapper_api.rs
@@ -0,0 +1,65 @@
+extern crate dlopen;
+#[macro_use]
+extern crate dlopen_derive;
+extern crate libc;
+use dlopen::wrapper::{Container, WrapperApi};
+use libc::{c_char, c_int};
+use std::ffi::CStr;
+
+mod commons;
+use commons::{example_lib_path, SomeData};
+
+#[derive(WrapperApi)]
+struct Api<'a> {
+ rust_fun_print_something: fn(),
+ rust_fun_add_one: fn(arg: i32) -> i32,
+ c_fun_print_something_else: unsafe extern "C" fn(),
+ c_fun_add_two: unsafe extern "C" fn(arg: c_int) -> c_int,
+ rust_i32: &'a i32,
+ rust_i32_mut: &'a mut i32,
+ #[dlopen_name = "rust_i32_mut"] rust_i32_ptr: *const i32,
+ c_int: &'a c_int,
+ c_struct: &'a SomeData,
+ rust_str: &'a &'static str,
+ c_const_char_ptr: *const c_char,
+}
+
+//those methods won't be generated
+impl<'a> Api<'a> {
+ fn rust_i32_ptr(&self) -> *const i32 {
+ self.rust_i32_ptr
+ }
+
+ fn c_const_str(&self) -> &CStr {
+ unsafe { CStr::from_ptr(self.c_const_char_ptr) }
+ }
+}
+
+fn main() {
+ let lib_path = example_lib_path();
+ let mut cont: Container =
+ unsafe { Container::load(lib_path) }.expect("Could not open library or load symbols");
+
+ cont.rust_fun_print_something();
+ println!(" 5+1={}", cont.rust_fun_add_one(5));
+ unsafe { cont.c_fun_print_something_else() };
+ println!("2+2={}", unsafe { cont.c_fun_add_two(2) });
+ println!("const rust i32 value: {}", *cont.rust_i32());
+ println!("mutable rust i32 value: {}", *cont.rust_i32_mut());
+ *cont.rust_i32_mut_mut() = 55;
+ println!("after change: {}", unsafe { *cont.rust_i32_ptr() });
+ //the same with C
+ println!("c_int={}", *cont.c_int());
+ //now static c struct
+
+ println!(
+ "c struct first: {}, second:{}",
+ cont.c_struct().first,
+ cont.c_struct().second
+ );
+ //let's play with strings
+
+ println!("Rust says: {}", *cont.rust_str());
+ let converted = cont.c_const_str().to_str().unwrap();
+ println!("And now C says: {}", converted);
+}
diff --git a/rust_crates/registry/src/github.com-1ecc6299db9ec823/dlopen-0.1.7/examples/wrapper_multi_api.rs b/rust_crates/registry/src/github.com-1ecc6299db9ec823/dlopen-0.1.7/examples/wrapper_multi_api.rs
new file mode 100644
index 0000000000..5b3ac47c0d
--- /dev/null
+++ b/rust_crates/registry/src/github.com-1ecc6299db9ec823/dlopen-0.1.7/examples/wrapper_multi_api.rs
@@ -0,0 +1,72 @@
+extern crate dlopen;
+#[macro_use]
+extern crate dlopen_derive;
+extern crate libc;
+mod commons;
+use commons::example_lib_path;
+use libc::c_int;
+use dlopen::wrapper::{Container, WrapperApi, WrapperMultiApi};
+
+
+//Define 3 APIs:
+
+#[derive(WrapperApi)]
+struct Working1<'a> {
+ rust_fun_print_something: fn(),
+ c_fun_add_two: unsafe extern "C" fn(arg: c_int) -> c_int,
+ rust_i32_mut: &'a mut i32,
+}
+
+#[derive(WrapperApi)]
+struct Working2<'a> {
+ rust_fun_add_one: fn(arg: i32) -> i32,
+ c_fun_print_something_else: extern "C" fn(),
+ rust_i32: &'a i32,
+}
+
+//this one wont' work in the example
+#[derive(WrapperApi)]
+struct NotWorking<'a> {
+ some_rust_fun: fn(arg: i32) -> i32,
+ some_c_fun: extern "C" fn(),
+ some_rust_num: &'a u32,
+}
+
+//Now define a multi wrapper that wraps sub APIs into one bigger API.
+//This example assumes that the first API is obligatory and the other two are optional.
+
+#[derive(WrapperMultiApi)]
+struct Api<'a> {
+ pub obligatory: Working1<'a>,
+ pub optional1: Option>,
+ pub optional2: Option>,
+}
+
+fn main() {
+ let lib_path = example_lib_path();
+ let api: Container = unsafe { Container::load(lib_path) }.expect("Could not open library");
+ //use obligatory API:
+ api.obligatory.rust_fun_print_something();
+ println!("4+2={}", unsafe { api.obligatory.c_fun_add_two(4) });
+ println!("static i32={}", api.obligatory.rust_i32_mut());
+
+ match api.optional1 {
+ Some(ref opt) => {
+ println!("First optional API loaded!");
+ println!("3+1={}", opt.rust_fun_add_one(3));
+ opt.c_fun_print_something_else();
+ println!("static value is {}", opt.rust_i32())
+ }
+ None => println!("Could not load the first optional API"),
+ }
+
+ match api.optional2 {
+ Some(ref opt) => {
+ opt.some_c_fun();
+ println!("Second optional API loaded");
+ println!("result of some function: {}", opt.some_rust_fun(3));
+ println!("static value is {}", opt.some_rust_num());
+ }
+ None => println!("Could not load the second optional API"),
+ }
+}
diff --git a/rust_crates/registry/src/github.com-1ecc6299db9ec823/dlopen-0.1.7/index-1.html b/rust_crates/registry/src/github.com-1ecc6299db9ec823/dlopen-0.1.7/index-1.html
new file mode 100644
index 0000000000..794fec435a
--- /dev/null
+++ b/rust_crates/registry/src/github.com-1ecc6299db9ec823/dlopen-0.1.7/index-1.html
@@ -0,0 +1,39 @@
+Unknown
+
rust-dlopen changelog
+
0.1.0
+
+
Initial version. Three complete APIs, tested
+
+
0.1.1
+
+
Removed warning during compilation in some rare cases
+
Fixed code formatting using rustfmt
+
+
0.1.2
+
+
Fixed synchronization issues on Windows
+
+
0.1.3
+
+
Updated documentation - it is easier for users to understand the value of the library.
+
+
0.1.4
+
+
Added badges showing the library quality.
+
Fixed collision of the "Result" name.
+ Other possible sources of collisions removed too.
+
Fixed small typos in error messages.
+
+
0.1.5
+
+
Fixed possible name collision in generated code- big thanks to kzys for finding it!
+
+
0.1.6
+
+
Fixed typo in "which" (docs)
+
Fixed build that stopped working for rust 1.18.0
+
Added code coverage (codedov.io), added badge
+
Fixed tests on certain MAC OS platforms - added recursive search
+ for a built test library.
+
+
\ No newline at end of file
diff --git a/rust_crates/registry/src/github.com-1ecc6299db9ec823/dlopen-0.1.7/rust-dlopen.iml b/rust_crates/registry/src/github.com-1ecc6299db9ec823/dlopen-0.1.7/rust-dlopen.iml
new file mode 100644
index 0000000000..7fe828a3a7
--- /dev/null
+++ b/rust_crates/registry/src/github.com-1ecc6299db9ec823/dlopen-0.1.7/rust-dlopen.iml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/rust_crates/registry/src/github.com-1ecc6299db9ec823/dlopen-0.1.7/src/err.rs b/rust_crates/registry/src/github.com-1ecc6299db9ec823/dlopen-0.1.7/src/err.rs
new file mode 100644
index 0000000000..0f83e3a388
--- /dev/null
+++ b/rust_crates/registry/src/github.com-1ecc6299db9ec823/dlopen-0.1.7/src/err.rs
@@ -0,0 +1,62 @@
+use std::error::Error as ErrorTrait;
+use std::fmt::{Display, Formatter, Result as FmtResult};
+use std::convert::From;
+use std::ffi::NulError;
+use std::io::Error as IoError;
+
+///This is a library-specific error that is returned by all calls to all APIs.
+#[derive(Debug)]
+pub enum Error {
+ ///Provided string could not be coverted into `std::ffi::CString` because it contained null
+ /// character.
+ NullCharacter(NulError),
+ ///The library could not be opened.
+ OpeningLibraryError(IoError),
+ ///The symbol could not be obtained.
+ SymbolGettingError(IoError),
+ ///Value of the symbol was null.
+ NullSymbol,
+}
+
+impl ErrorTrait for Error {
+ fn description(&self) -> &str {
+ match self {
+ &Error::NullCharacter(_) => "String had a null character",
+ &Error::OpeningLibraryError(_) => "Could not open library",
+ &Error::SymbolGettingError(_) => "Could not obtain symbol from the library",
+ &Error::NullSymbol => "The symbol is NULL",
+ }
+ }
+
+ fn cause(&self) -> Option<&ErrorTrait> {
+ match self {
+ &Error::NullCharacter(ref val) => Some(val),
+ &Error::OpeningLibraryError(_) | &Error::SymbolGettingError(_) | &Error::NullSymbol => {
+ None
+ }
+ }
+ }
+}
+
+impl Display for Error {
+ fn fmt(&self, f: &mut Formatter) -> FmtResult {
+ f.write_str(self.description())?;
+ match self {
+ &Error::OpeningLibraryError(ref msg) => {
+ f.write_str(": ")?;
+ msg.fmt(f)
+ }
+ &Error::SymbolGettingError(ref msg) => {
+ f.write_str(": ")?;
+ msg.fmt(f)
+ }
+ &Error::NullSymbol | &Error::NullCharacter(_) => Ok(()),
+ }
+ }
+}
+
+impl From for Error {
+ fn from(val: NulError) -> Error {
+ Error::NullCharacter(val)
+ }
+}
diff --git a/rust_crates/registry/src/github.com-1ecc6299db9ec823/dlopen-0.1.7/src/lib.rs b/rust_crates/registry/src/github.com-1ecc6299db9ec823/dlopen-0.1.7/src/lib.rs
new file mode 100644
index 0000000000..711b0a7b8e
--- /dev/null
+++ b/rust_crates/registry/src/github.com-1ecc6299db9ec823/dlopen-0.1.7/src/lib.rs
@@ -0,0 +1,113 @@
+/*!
+
+Library for opening and working with dynamic link libraries (also known as shared object).
+
+# Overview
+
+This library is an effort to make use of dynamic link libraries in Rust simple.
+Previously existing solutions were either unsafe, provided huge overhead of required writing too much code to achieve simple things.
+I hope that this library will help you to quickly get what you need and avoid errors.
+
+# Features
+
+## Main features
+
+* Supports majority of platforms and is platform independent.
+* Is consistent with Rust error handling mechanism and makes making mistakes much more difficult.
+* Is very lightweight. It mostly uses zero cost wrappers to create safer abstractions over platform API.
+* Is thread safe.
+* Is object-oriented programming friendly.
+* Has a low-level API that provides full flexibility of using libraries.
+* Has two high-level APIs that protect against dangling symbols - each in its own way.
+* High level APIs support automatic loading of symbols into structures. You only need to define a
+ structure that represents an API. The rest happens automatically and requires only minimal amount of code.
+* Automatic loading of symbols helps you to follow the DRY paradigm.
+
+## Compare with other libraries
+
+|Feature | dlopen | [libloading](https://github.com/nagisa/rust_libloading) | [sharedlib](https://github.com/Tyleo/sharedlib) |
+|------------------------------------|------------|---------------------------------------------------------|-------------------------------------------------|
+| Basic functionality | Yes | Yes | Yes |
+| Multiplatform | Yes | Yes | Yes |
+|Dangling symbol prevention | Yes | Yes | Yes |
+| Thread safety | Yes | **Potential problem with SetErrorMode() on older Windows platforms** | **No support for SetErrorMode (library may block the application on Windows)**|
+| Loading of symbols into structures | Yes | **No** | **No**
+| Overhead | Minimal | Minimal | **Some overhead** |
+| Low-level, unsafe API | Yes | Yes | Yes |
+| Object-oriented friendly | Yes | **No** | Yes |
+| Load from the program itself | Yes | **No** | **No** |
+
+## Safety
+
+Please note that while Rust aims at being 100% safe language, it does not yet provide mechanisms that would allow me to create a 100% safe library, so I had to settle on 99%.
+Also the nature of dynamic link libraries requires casting obtained pointers into types that are defined on the application side. And this cannot be safe.
+Having said that I still think that this library provides the best approach and greatest safety possible in Rust.
+
+# Usage:
+
+Cargo.toml:
+
+```toml
+[dependencies]
+dlopen = "0.1"
+```
+
+# Documentation
+
+[Cargo documentation](https://docs.rs/dlopen)
+
+[Examples](../examples)
+
+[Changelog](https://github.com/szymonwieloch/rust-dlopen/releases)
+
+# License
+This code is licensed under [MIT](../LICENSE) license.
+
+# Acknowledgement
+
+Special thanks to [Simonas Kazlauskas](https://github.com/nagisa) whose [libloading](https://github.com/nagisa/rust_libloading) became code base for my project.
+
+# Comparison of APIs:
+
+* [**raw**](./raw/index.html) - a low-level API. It is mainly intended to give you full flexibility
+ if you decide to create you own custom solution for handling dynamic link libraries.
+ For typical operations you probably should use one of high-level APIs.
+
+* [**symbor**](./symbor/index.html) - a high-level API. It prevents dangling symbols by creating
+ zero cost structural wrappers around symbols obtained from the library. These wrappers use
+ Rust borrowing mechanism to make sure that the library will never get released before obtained
+ symbols.
+
+* [**wrapper**](./wrapper/index.html) - a high-level API. It prevents dangling symbols by creating
+ zero cost functional wrappers around symbols obtained from the library. These wrappers prevent
+ accidental copying of raw symbols from library API. Dangling symbols are prevented by keeping
+ library and its API in one structure - this makes sure that symbols and library are released
+ together.
+
+Additionally both high-level APIs provide a way to automatically load symbols into a structure using
+Rust reflection mechanism. Decision which API should be used is a matter of taste - please check
+documentation of both of them and use the one that you prefer.
+At the moment none seems to have any reasonable advantage over the other.
+
+*/
+
+
+#[cfg(windows)]
+extern crate kernel32;
+#[macro_use]
+extern crate lazy_static;
+#[cfg(any(unix, test))]
+extern crate libc;
+#[cfg(windows)]
+extern crate winapi;
+
+#[cfg(test)]
+#[macro_use]
+extern crate const_cstr;
+
+pub mod raw;
+pub mod symbor;
+pub mod utils;
+pub mod wrapper;
+mod err;
+pub use err::Error;
diff --git a/rust_crates/registry/src/github.com-1ecc6299db9ec823/dlopen-0.1.7/src/raw/common.rs b/rust_crates/registry/src/github.com-1ecc6299db9ec823/dlopen-0.1.7/src/raw/common.rs
new file mode 100644
index 0000000000..92dcd26d62
--- /dev/null
+++ b/rust_crates/registry/src/github.com-1ecc6299db9ec823/dlopen-0.1.7/src/raw/common.rs
@@ -0,0 +1,141 @@
+use super::super::err::Error;
+use std::ffi::{CStr, CString, OsStr};
+
+//choose the right platform implementation here
+#[cfg(unix)]
+use super::unix::{close_lib, get_sym, open_self, open_lib, Handle};
+#[cfg(windows)]
+use super::windows::{close_lib, get_sym, open_self, open_lib, Handle};
+
+use std::mem::{size_of, transmute_copy};
+
+/**
+ Main interface for opening and working with a dynamic link library.
+
+ **Note:** Several methods have their "*_cstr" equivalents. This is because all native OS
+ interfaces actually use C-strings. If you pass
+ [`CStr`](https://doc.rust-lang.org/std/ffi/struct.CStr.html)
+ as an argument, Library doesn't need to perform additional conversion from Rust string to
+ C-string.. This makes `*_cstr" functions slightly more optimal than their normal equivalents.
+ It is recommended that you use
+ [const-cstr](https://github.com/abonander/const-cstr) crate to create statically allocated
+ C-strings.
+
+ **Note:** The handle to the library gets released when the library object gets dropped.
+ Unless your application opened the library multiple times, this is the moment when symbols
+ obtained from the library become dangling symbols.
+*/
+#[derive(Debug)]
+pub struct Library {
+ handle: Handle,
+}
+
+impl Library {
+ /**
+ Open a dynamic library.
+
+ **Note:** different platforms search for libraries in different directories.
+ Therefore this function cannot be 100% platform independent.
+ However it seems that all platforms support the full path and
+ searching in default os directories if you provide only the file name.
+ Please refer to your operating system guide for precise information about the directories
+ where the operating system searches for dynamic link libraries.
+
+ #Example
+
+ ```no_run
+ extern crate dlopen;
+ use dlopen::raw::Library;
+
+ fn main() {
+ //use full path
+ let lib = Library::open("/lib/i386-linux-gnu/libm.so.6").unwrap();
+ //use only file name
+ let lib = Library::open("libm.so.6").unwrap();
+ }
+ ```
+ */
+ pub fn open(name: S) -> Result
+ where
+ S: AsRef,
+ {
+ Ok(Self {
+ handle: unsafe { open_lib(name.as_ref()) }?,
+ })
+ }
+ /**
+ Open the main program itself as a library.
+
+ This allows a shared library to load symbols of the program it was loaded
+ into.
+ */
+ pub fn open_self() -> Result {
+ Ok(Self {
+ handle: unsafe { open_self() }?,
+ })
+ }
+ /**
+ Obtain symbol from opened library.
+
+ **Note:** the `T` template type needs to have a size of a pointer.
+ Because Rust does not support static casts at the moment, the size of the type
+ is checked in runtime and causes panic if it doesn't match.
+
+ **Note:** It is legal for a library to export null symbols.
+ However this is something that almost nobody expects.
+ Therefore allowing it here would bring many problems, especially if user obtains references
+ or functions.
+ This method checks the address value and returns `Error::NullSymbol` error if the value is null.
+ If your code does require obtaining symbols with null value, please do something like this:
+
+ #Example
+
+ ```no_run
+ extern crate dlopen;
+ use dlopen::raw::Library;
+ use dlopen::Error;
+ use std::ptr::null;
+ fn main(){
+ let lib = Library::open("libyourlib.so").unwrap();
+ let ptr_or_null: * const i32 = match unsafe{ lib.symbol("symbolname") } {
+ Ok(val) => val,
+ Err(err) => match err {
+ Error::NullSymbol => null(),
+ _ => panic!("Could not obtain the symbol")
+ }
+ };
+ //do something with the symbol
+ }
+ ```
+ */
+ pub unsafe fn symbol(&self, name: &str) -> Result {
+ let cname = CString::new(name)?;
+ self.symbol_cstr(cname.as_ref())
+ }
+ ///Equivalent of the `symbol` method but takes `CStr` as a argument.
+ pub unsafe fn symbol_cstr(&self, name: &CStr) -> Result {
+ //TODO: convert it to some kind of static assertion (not yet supported in Rust)
+ //this comparison should be calculated by compiler at compilation time - zero cost
+ if size_of::() != size_of::<*mut ()>() {
+ panic!(
+ "The type passed to dlopen::Library::symbol() function has a different size than a \
+ pointer - cannot transmute"
+ );
+ }
+ let raw = get_sym(self.handle, name)?;
+ if raw.is_null() {
+ return Err(Error::NullSymbol);
+ } else {
+ Ok(transmute_copy(&raw))
+ }
+ }
+}
+
+impl Drop for Library {
+ fn drop(&mut self) {
+ self.handle = close_lib(self.handle);
+ }
+}
+
+unsafe impl Sync for Library {}
+unsafe impl Send for Library {}
diff --git a/rust_crates/registry/src/github.com-1ecc6299db9ec823/dlopen-0.1.7/src/raw/mod.rs b/rust_crates/registry/src/github.com-1ecc6299db9ec823/dlopen-0.1.7/src/raw/mod.rs
new file mode 100644
index 0000000000..21b3666b7a
--- /dev/null
+++ b/rust_crates/registry/src/github.com-1ecc6299db9ec823/dlopen-0.1.7/src/raw/mod.rs
@@ -0,0 +1,37 @@
+/*!
+Low-level API for opening and getting raw symbols from dynamic link libraries.
+
+As a low-level API it returns raw pointers, references and functions from loaded libraries.
+This means that this API does not provide any protection against problems with dangling symbols.
+You may consider using other APIs to achieve better safety.
+However this API is the most flexible one and you may find is useful when creating your custom
+approach to loading dynamic link libraries.
+
+# Example
+```no_run
+extern crate dlopen;
+use dlopen::raw::Library;
+fn main(){
+ let lib = Library::open("libexample.so").unwrap();
+ let fun_add_one: unsafe extern "C" fn(i32)->i32 = unsafe{lib.symbol("add_one")}.unwrap();
+ println!("1+1= {}", unsafe{fun_add_one(1)});
+
+ drop(lib);
+ //warning! fun_add_one is now a dangling symbol and use of it may crash your application.
+}
+```
+*/
+
+
+
+//!
+
+mod common;
+#[cfg(unix)]
+mod unix;
+#[cfg(windows)]
+mod windows;
+#[cfg(test)]
+mod tests;
+
+pub use self::common::Library;
diff --git a/rust_crates/registry/src/github.com-1ecc6299db9ec823/dlopen-0.1.7/src/raw/tests.rs b/rust_crates/registry/src/github.com-1ecc6299db9ec823/dlopen-0.1.7/src/raw/tests.rs
new file mode 100644
index 0000000000..e82688297b
--- /dev/null
+++ b/rust_crates/registry/src/github.com-1ecc6299db9ec823/dlopen-0.1.7/src/raw/tests.rs
@@ -0,0 +1,59 @@
+use super::super::err::Error;
+#[cfg(unix)]
+use super::unix::{close_lib, get_sym, open_lib};
+#[cfg(windows)]
+use super::windows::{close_lib, get_sym, open_lib};
+
+#[cfg(windows)]
+const EXISTING_LIB: &str = "kernel32.dll";
+#[cfg(all(unix, not(any(target_os = "macos", target_os = "ios"))))]
+const EXISTING_LIB: &str = "libm.so.6";
+#[cfg(any(target_os = "macos", target_os = "ios"))]
+const EXISTING_LIB: &str = "libm.dylib";
+const NOT_EXISTING_LIB: &str = "notexisting.ext";
+#[cfg(windows)]
+const_cstr! {EXISTING_SYM = "GetLastError";}
+#[cfg(unix)]
+const_cstr! {EXISTING_SYM = "cos";}
+const_cstr! {NOT_EXISTING_SYM = "notexisting";}
+
+
+//This is an example of opening and closing a library
+//It's going to work only on Windows but this is what it is supposed to do
+#[test]
+fn load_get_close() {
+ unsafe {
+ let handle = open_lib(EXISTING_LIB.as_ref()).expect("Could not open library");
+ let sym = get_sym(handle, &EXISTING_SYM.as_cstr()).expect("Could not get symbol");
+ assert!(!sym.is_null());
+ assert!(close_lib(handle).is_null());
+ }
+}
+
+#[test]
+fn open_err() {
+ unsafe {
+ match open_lib(NOT_EXISTING_LIB.as_ref()) {
+ Ok(_) => panic!("Library should not get opened"),
+ Err(err) => match err {
+ Error::OpeningLibraryError(_) => (),
+ _ => panic!("Invalid error kind"),
+ },
+ }
+ }
+}
+
+#[test]
+fn get_err() {
+ unsafe {
+ let handle = open_lib(EXISTING_LIB.as_ref()).expect("Could not open library");
+ match get_sym(handle, NOT_EXISTING_SYM.as_cstr()) {
+ Ok(_) => panic!("Should not get the symbol"),
+ Err(err) => match err {
+ Error::SymbolGettingError(_) => (),
+ _ => panic!("Invalid error kind"),
+ },
+ }
+ assert!(close_lib(handle).is_null());
+ }
+}
diff --git a/rust_crates/registry/src/github.com-1ecc6299db9ec823/dlopen-0.1.7/src/raw/unix.rs b/rust_crates/registry/src/github.com-1ecc6299db9ec823/dlopen-0.1.7/src/raw/unix.rs
new file mode 100644
index 0000000000..7e23db4499
--- /dev/null
+++ b/rust_crates/registry/src/github.com-1ecc6299db9ec823/dlopen-0.1.7/src/raw/unix.rs
@@ -0,0 +1,85 @@
+use super::super::err::Error;
+use std::ffi::{CStr, OsStr};
+use libc::{c_int, c_void, dlclose, dlerror, dlopen, dlsym, RTLD_LAZY, RTLD_LOCAL};
+use std::ptr::{null, null_mut};
+use std::os::unix::ffi::OsStrExt;
+use std::io::{Error as IoError, ErrorKind};
+
+const DEFAULT_FLAGS: c_int = RTLD_LOCAL | RTLD_LAZY;
+
+use std::sync::Mutex;
+
+// calls to dlerror are not thread unsafe. Therefore we need to guard each call with a mutex
+
+lazy_static! {
+ static ref DLERROR_MUTEX: Mutex<()> = Mutex::new(());
+}
+
+pub type Handle = *mut c_void;
+
+#[inline]
+pub unsafe fn get_sym(handle: Handle, name: &CStr) -> Result<*mut (), Error> {
+ let _lock = DLERROR_MUTEX.lock();
+ //clear the dlerror in order to be able to distinguish between NULL pointer and error
+ let _ = dlerror();
+ let symbol = dlsym(handle, name.as_ptr());
+ //This can be either error or just the library has a NULl pointer - legal
+ if symbol.is_null() {
+ let msg = dlerror();
+ if !msg.is_null() {
+ return Err(Error::SymbolGettingError(IoError::new(
+ ErrorKind::Other,
+ CStr::from_ptr(msg).to_string_lossy().to_string(),
+ )));
+ }
+ }
+ Ok(symbol as *mut ())
+}
+
+#[inline]
+pub unsafe fn open_self() -> Result {
+ let _lock = DLERROR_MUTEX.lock();
+ let handle = dlopen(null(), DEFAULT_FLAGS);
+ if handle.is_null() {
+ Err(Error::OpeningLibraryError(IoError::new(
+ ErrorKind::Other,
+ CStr::from_ptr(dlerror()).to_string_lossy().to_string(),
+ )))
+ } else {
+ Ok(handle)
+ }
+}
+
+#[inline]
+pub unsafe fn open_lib(name: &OsStr) -> Result {
+ let mut v: Vec = Vec::new();
+ //as_bytes i a unix-specific extension
+ let cstr = if name.len() > 0 && name.as_bytes()[name.len() - 1] == 0 {
+ //don't need to convert
+ CStr::from_bytes_with_nul_unchecked(name.as_bytes())
+ } else {
+ //need to convert
+ v.extend_from_slice(name.as_bytes());
+ v.push(0);
+ CStr::from_bytes_with_nul_unchecked(v.as_slice())
+ };
+ let _lock = DLERROR_MUTEX.lock();
+ let handle = dlopen(cstr.as_ptr(), DEFAULT_FLAGS);
+ if handle.is_null() {
+ Err(Error::OpeningLibraryError(IoError::new(
+ ErrorKind::Other,
+ CStr::from_ptr(dlerror()).to_string_lossy().to_string(),
+ )))
+ } else {
+ Ok(handle)
+ }
+}
+
+#[inline]
+pub fn close_lib(handle: Handle) -> Handle {
+ let result = unsafe { dlclose(handle) };
+ if result != 0 {
+ panic!("Call to dlclose() failed");
+ }
+ null_mut()
+}
diff --git a/rust_crates/registry/src/github.com-1ecc6299db9ec823/dlopen-0.1.7/src/raw/windows.rs b/rust_crates/registry/src/github.com-1ecc6299db9ec823/dlopen-0.1.7/src/raw/windows.rs
new file mode 100644
index 0000000000..f710b3f2c7
--- /dev/null
+++ b/rust_crates/registry/src/github.com-1ecc6299db9ec823/dlopen-0.1.7/src/raw/windows.rs
@@ -0,0 +1,163 @@
+use winapi;
+use kernel32;
+use std::os::windows::ffi::OsStrExt;
+use std::sync::atomic::{AtomicBool, Ordering, ATOMIC_BOOL_INIT};
+use std::io::{Error as IoError, ErrorKind};
+use super::super::err::Error;
+use std::ptr::{null, null_mut};
+use std::ffi::{CStr, OsStr};
+use std::sync::Mutex;
+
+static USE_ERRORMODE: AtomicBool = ATOMIC_BOOL_INIT;
+
+struct SetErrorModeData {
+ pub count: u32,
+ pub previous: winapi::DWORD,
+}
+
+lazy_static! {
+ static ref SET_ERR_MODE_DATA: Mutex = Mutex::new( SetErrorModeData{
+ count: 0,
+ previous: 0
+ });
+}
+
+
+pub type Handle = winapi::HMODULE;
+
+/*
+Windows has an ugly feature: by default not finding the given library opens a window
+and passes control to the user.
+To fix this wee need to change thread/process error mode for the moment when the function is called
+and then revert it to the previous value.
+
+Since Windows 7 the SetThreadErrorMode function is supported. It sets error mode for the given
+thread. Older systems require calling SetErrorMode. This function sets error mode for the whole
+process.
+
+https://msdn.microsoft.com/pl-pl/library/windows/desktop/dd553630(v=vs.85).aspx
+*/
+
+const ERROR_MODE: winapi::DWORD = 1; //app handles everything
+
+enum ErrorModeGuard {
+ ThreadPreviousValue(winapi::DWORD),
+ DoNothing,
+ Process,
+}
+
+impl ErrorModeGuard {
+ fn new() -> Result {
+ if !USE_ERRORMODE.load(Ordering::Acquire) {
+ let mut previous: winapi::DWORD = 0;
+ if unsafe { kernel32::SetThreadErrorMode(ERROR_MODE, &mut previous) } == 0 {
+ //error. On some systems SetThreadErrorMode may not be implemented
+ let error = unsafe { kernel32::GetLastError() };
+ if error == winapi::ERROR_CALL_NOT_IMPLEMENTED {
+ USE_ERRORMODE.store(true, Ordering::Release);
+ } else {
+ //this is an actual error
+ //SetErrorMode never fails. Shouldn't we use it now?
+ return Err(IoError::from_raw_os_error(error as i32));
+ }
+ } else {
+ return Ok(if previous == ERROR_MODE {
+ ErrorModeGuard::DoNothing
+ } else {
+ ErrorModeGuard::ThreadPreviousValue(previous)
+ });
+ }
+ }
+ //several threads may be opening libraries at the same time.
+ //we need to make sure that only the first one sets the erro mode
+ //and only the last reverts it to the original value
+
+ //poisoning should never happen
+ let mut lock = SET_ERR_MODE_DATA.lock().expect("Mutex got poisoned");
+ if lock.count == 0 {
+ lock.previous = unsafe { kernel32::SetErrorMode(ERROR_MODE) };
+ if lock.previous == ERROR_MODE {
+ return Ok(ErrorModeGuard::DoNothing);
+ }
+ }
+ lock.count += 1;
+ Ok(ErrorModeGuard::Process)
+ }
+}
+
+impl Drop for ErrorModeGuard {
+ fn drop(&mut self) {
+ match self {
+ &mut ErrorModeGuard::DoNothing => (),
+ &mut ErrorModeGuard::Process => {
+ //poisoning should never happen
+ let mut lock = SET_ERR_MODE_DATA.lock().expect("Mutex got poisoned");
+ lock.count -= 1;
+ if lock.count == 0 {
+ unsafe { kernel32::SetErrorMode(lock.previous) };
+ }
+ }
+ &mut ErrorModeGuard::ThreadPreviousValue(previous) => unsafe {
+ kernel32::SetThreadErrorMode(previous, null_mut());
+ },
+ }
+ }
+}
+
+unsafe fn get_win_error() -> IoError {
+ let error = kernel32::GetLastError();
+ if error == 0 {
+ IoError::new(
+ ErrorKind::Other,
+ "Could not obtain information about the error",
+ )
+ } else {
+ IoError::from_raw_os_error(error as i32)
+ }
+}
+
+#[inline]
+pub unsafe fn get_sym(handle: Handle, name: &CStr) -> Result<*mut (), Error> {
+ let symbol = kernel32::GetProcAddress(handle, name.as_ptr());
+ if symbol.is_null() {
+ Err(Error::SymbolGettingError(get_win_error()))
+ } else {
+ Ok(symbol as *mut ())
+ }
+}
+
+#[inline]
+pub unsafe fn open_self() -> Result {
+ let mut handle: Handle = null_mut();
+ if kernel32::GetModuleHandleExW(0, null(), &mut handle) == 0 {
+ Err(Error::OpeningLibraryError(get_win_error()))
+ } else {
+ Ok(handle)
+ }
+}
+
+#[inline]
+pub unsafe fn open_lib(name: &OsStr) -> Result {
+ let wide_name: Vec = name.encode_wide().chain(Some(0)).collect();
+ let _guard = match ErrorModeGuard::new() {
+ Ok(val) => val,
+ Err(err) => return Err(Error::OpeningLibraryError(err)),
+ };
+ let handle = kernel32::LoadLibraryW(wide_name.as_ptr());
+ if handle.is_null() {
+ Err(Error::OpeningLibraryError(get_win_error()))
+ } else {
+ Ok(handle)
+ }
+}
+
+#[inline]
+pub fn close_lib(handle: Handle) -> Handle {
+ if unsafe { kernel32::FreeLibrary(handle) } == 0 {
+ //this should not happen
+ panic!("FreeLibrary() failed, the error is {}", unsafe {
+ get_win_error()
+ });
+ }
+ null_mut()
+}
diff --git a/rust_crates/registry/src/github.com-1ecc6299db9ec823/dlopen-0.1.7/src/symbor/api.rs b/rust_crates/registry/src/github.com-1ecc6299db9ec823/dlopen-0.1.7/src/symbor/api.rs
new file mode 100644
index 0000000000..84672b6883
--- /dev/null
+++ b/rust_crates/registry/src/github.com-1ecc6299db9ec823/dlopen-0.1.7/src/symbor/api.rs
@@ -0,0 +1,74 @@
+use super::library::Library;
+use super::super::err::Error;
+/**
+Trait for automatic loading of symbols from library.
+
+This trait is intended to be used together with the `derive` macro.
+To use it you need to define a structure, create several fields that
+implement the `FromRawResult` trait and then simply use the automatically
+generated `load(&Library)` function to load all symbols from previously opened library.
+
+```no_run
+#[macro_use]
+extern crate dlopen_derive;
+extern crate dlopen;
+extern crate libc;
+use dlopen::symbor::{Library, Symbol, SymBorApi, PtrOrNull, RefMut, PtrOrNullMut};
+use libc::{c_double, c_char};
+
+#[derive(SymBorApi)]
+struct Example<'a> {
+ pub simple_fun: Symbol<'a, unsafe extern "C" fn()>,
+ pub complex_fun: Symbol<'a, unsafe extern "C" fn(c_double)->c_double>,
+ pub optional_fun: Option>,
+ pub nullable_ptr: PtrOrNullMut<'a, c_char>,
+ pub mut_ref_i32: Symbol<'a, &'a mut i32>,
+ #[dlopen_name="mut_ref_i32"]
+ pub the_same_mut_ref_i32: RefMut<'a, i32>,
+ pub not_nullable_ptr: Symbol<'a, * mut c_double>
+}
+
+fn main(){
+ let lib = Library::open("example.dll").expect("Could not open library");
+ let mut api = unsafe{Example::load(&lib)}.expect("Could not load symbols");
+ unsafe{(api.simple_fun)()};
+ let _ = unsafe{(api.complex_fun)(1.0)};
+ match api.optional_fun {
+ Some(fun) => unsafe {fun()},
+ None => println!("Optional function could not be loaded"),
+ };
+ if api.nullable_ptr.is_null(){
+ println!("Library has a null symbol");
+ }
+ //while Symbol is good for everything, RefMut requires one less dereference to use
+ **api.mut_ref_i32 =34;
+ *api.the_same_mut_ref_i32 =35;
+ unsafe{**api.not_nullable_ptr = 55.0};
+ unsafe{**api.nullable_ptr = 0};
+}
+```
+
+Please notice several supported features:
+
+* By default `SymBorApi` uses the field name to obtain a symbol from the library.
+ You can override the symbol name using the `dlopen_name` attribute.
+* All kind of objects from the `symbor` module implement the Deref or DerefMut trait.
+ This means that you can use them as if you would use primitive types that they wrap.
+* You can obtain optional symbols. This is very useful when you are dealing with
+ different versions of libraries and the new versions support more functions.
+ If it is not possible to obtain the given symbol, the option is set to `None',
+ otherwise it contains the obtained symbol.
+* Both `Symbol` and `Ref` or `RefMut` can be used to obtain references to statically
+ allocated objects. But `Ref` and `RefMut` are just easier to use - they require
+ less dereferences to access the final value.
+ Actually they behave like a normal reference does, it just that they implement the
+ `FromRawResult` interface that allows them to be used inside structures that implement
+ the `SymBorApi` trait.
+
+*/
+pub trait SymBorApi<'a>
+where
+ Self: Sized,
+{
+ unsafe fn load(lib: &'a Library) -> Result;
+}
diff --git a/rust_crates/registry/src/github.com-1ecc6299db9ec823/dlopen-0.1.7/src/symbor/container.rs b/rust_crates/registry/src/github.com-1ecc6299db9ec823/dlopen-0.1.7/src/symbor/container.rs
new file mode 100644
index 0000000000..d902631a97
--- /dev/null
+++ b/rust_crates/registry/src/github.com-1ecc6299db9ec823/dlopen-0.1.7/src/symbor/container.rs
@@ -0,0 +1,97 @@
+use super::api::SymBorApi;
+use super::Library;
+use std::mem::transmute;
+use std::ops::{Deref, DerefMut};
+use std::ffi::OsStr;
+use super::super::Error;
+
+/**
+Container for both dynamic link library handle and its API.
+
+This structure solves an important issue: object oriented programming where the given
+structure has two objects and one of the objects has a reference to the second one.
+Normally you can't put `Library` and a structure that implements `SymBorApi` into one structure.
+This structure allows you to do it.
+
+#Example
+
+```no_run
+#[macro_use]
+extern crate dlopen_derive;
+extern crate dlopen;
+use dlopen::symbor::{Library, Symbol, Ref, PtrOrNull, SymBorApi, Container};
+
+ #[derive(SymBorApi)]
+ struct ExampleApi<'a> {
+ pub fun: Symbol<'a, unsafe extern "C" fn(i32) -> i32>,
+ pub glob_i32: Ref<'a, i32>,
+ pub maybe_c_str: PtrOrNull<'a, u8>,
+ }
+
+fn main(){
+ let cont: Container = unsafe{Container::load("libexample.so")}
+ .expect("Could not load library or symbols");
+ println!("fun(4)={}", unsafe{(cont.fun)(4)});
+ println!("glob_i32={}", *cont.glob_i32);
+ println!("The pointer is null={}", cont.maybe_c_str.is_null());
+}
+```
+*/
+pub struct Container
+where
+ T: SymBorApi<'static>,
+{
+ #[allow(dead_code)] lib: Library,
+ api: T,
+}
+
+impl Container
+where
+ T: SymBorApi<'static>,
+{
+ ///Open dynamic link library and load symbols.
+ pub unsafe fn load(name: S) -> Result
+ where
+ S: AsRef,
+ {
+ let lib = Library::open(name)?;
+ //this is cheating of course
+ //but it is safe because Library and api is placed in the same structure
+ //and therefore it is released at the same time.
+ let static_ref: &'static Library = transmute(&lib);
+ let api = T::load(static_ref)?;
+ Ok(Self { api: api, lib: lib })
+ }
+ ///Load all symbols from the program itself.
+ ///
+ /// This allows a shared library to load symbols of the program it was
+ /// loaded into.
+ pub unsafe fn load_self() -> Result {
+ let lib = Library::open_self()?;
+ //this is cheating of course
+ //but it is safe because Library and api is placed in the same structure
+ //and therefore it is released at the same time.
+ let static_ref: &'static Library = transmute(&lib);
+ let api = T::load(static_ref)?;
+ Ok(Self { api: api, lib: lib })
+ }
+}
+
+impl Deref for Container
+where
+ T: SymBorApi<'static>,
+{
+ type Target = T;
+ fn deref(&self) -> &T {
+ &self.api
+ }
+}
+
+impl DerefMut for Container
+where
+ T: SymBorApi<'static>,
+{
+ fn deref_mut(&mut self) -> &mut T {
+ &mut self.api
+ }
+}
diff --git a/rust_crates/registry/src/github.com-1ecc6299db9ec823/dlopen-0.1.7/src/symbor/from_raw.rs b/rust_crates/registry/src/github.com-1ecc6299db9ec823/dlopen-0.1.7/src/symbor/from_raw.rs
new file mode 100644
index 0000000000..8fc94de627
--- /dev/null
+++ b/rust_crates/registry/src/github.com-1ecc6299db9ec823/dlopen-0.1.7/src/symbor/from_raw.rs
@@ -0,0 +1,21 @@
+use super::ptr_or_null::PtrOrNull;
+use super::super::err::Error;
+pub type RawResult<'a> = Result, Error>;
+
+///Allows conversion of raw symbol result into the given symbol.
+///
+///This trait needs to be implemented by all members of structures that implement
+/// the `SymBorApi` trait. It is used to covert raw result obtained from library
+/// into the given object accessible to the user.
+///
+/// **Note:** `Option where T: FromRawResult` also implements `FromRawResult`.
+/// This allows you to use options in structures implementing `SymBorApi`. If
+/// the symbol is found, the variable contains `Some(symbol)`, otherwise `None`.
+///
+/// **Note:** You probably won't need to use it directly.
+pub trait FromRawResult
+where
+ Self: Sized,
+{
+ unsafe fn from_raw_result(raw: RawResult) -> Result;
+}
diff --git a/rust_crates/registry/src/github.com-1ecc6299db9ec823/dlopen-0.1.7/src/symbor/library.rs b/rust_crates/registry/src/github.com-1ecc6299db9ec823/dlopen-0.1.7/src/symbor/library.rs
new file mode 100644
index 0000000000..f2e704c21c
--- /dev/null
+++ b/rust_crates/registry/src/github.com-1ecc6299db9ec823/dlopen-0.1.7/src/symbor/library.rs
@@ -0,0 +1,150 @@
+use std::ffi::CStr;
+use super::symbol::Symbol;
+use super::ptr_or_null::PtrOrNull;
+use super::ptr_or_null_mut::PtrOrNullMut;
+use super::super::raw::Library as RawLib;
+use std::ffi::{CString, OsStr};
+use std::ptr::{null, null_mut};
+
+use super::super::err::Error;
+
+/**
+Safe wrapper around dynamic link library handle.
+
+Methods of `Library` return only types that make the library borrowed. Therefore the problem with
+dangling symbols is prevented.
+
+**Note:**: It is recommended that you use certain methods in certain situations:
+
+* `symbol()` - for obtaining functions and pointers (but only if you can't use references
+ instead of pointers and you do not accept null value of a pointer).
+* `reference()` and `reference_mut()` - for obtaining access to
+ statically allocated objects - either constant or mutable.
+* `ptr_or_null()` and `ptr_or_null_mut()` - for obtaining pointers if you accept null values of
+pointers (in 99% of cases you should rather use previously mentioned methods).
+
+#Example
+
+```no_run
+extern crate dlopen;
+use dlopen::symbor::Library;
+
+fn main(){
+ let lib = Library::open("libexample.dylib").unwrap();
+ let fun = unsafe{lib.symbol::("function")}.unwrap();
+ unsafe{fun()};
+ let glob_val: &mut u32 = unsafe{lib.reference_mut("glob_val")}.unwrap();
+ *glob_val = 42;
+ let ptr_or_null = unsafe{lib.ptr_or_null::<()>("void_ptr")}.unwrap();
+ println!("Pointer is null: {}", ptr_or_null.is_null());
+}
+```
+*/
+pub struct Library {
+ lib: RawLib,
+}
+
+impl Library {
+ ///Open dynamic link library using provided file name or path.
+ pub fn open(name: S) -> Result
+ where
+ S: AsRef,
+ {
+ Ok(Library {
+ lib: RawLib::open(name)?,
+ })
+ }
+
+ /// Open the program itself as library.
+ ///
+ /// This allows a shared library to load symbols of the program it was
+ /// loaded into.
+ pub fn open_self() -> Result {
+ Ok(Library {
+ lib: RawLib::open_self()?,
+ })
+ }
+
+ /// Obtain a symbol from library.
+ ///
+ /// This method is the most general one and allows obtaining basically everything assuming
+ /// that the value of the given symbol cannot be null (use `ptr_or_null()` for this case).
+ /// However the `reference()` and `reference_mut()` methods return a native reference and they
+ /// are more programmer friendly when you try accessing statically allocated data in
+ /// the library.
+ pub unsafe fn symbol(&self, name: &str) -> Result, Error> {
+ Ok(Symbol::new(self.lib.symbol(name)?))
+ }
+
+ ///Equivalent of the `symbol()` method but takes `CStr` as a argument.
+ pub unsafe fn symbol_cstr(&self, name: &CStr) -> Result, Error> {
+ Ok(Symbol::new(self.lib.symbol_cstr(name)?))
+ }
+
+ ///Obtain a const pointer from library.
+ ///
+ /// **Note:** This method is only recommended for data
+ /// that can't be accessed as a reference and that can have a null pointer value
+ /// (so not in 99% of cases).
+ pub unsafe fn ptr_or_null(&self, name: &str) -> Result, Error> {
+ let cname = CString::new(name)?;
+ self.ptr_or_null_cstr(cname.as_ref())
+ }
+
+ ///Equivalent of the `pointer()` method but takes `CStr` as a argument.
+ pub unsafe fn ptr_or_null_cstr(&self, name: &CStr) -> Result, Error> {
+ let raw_ptr = match self.lib.symbol_cstr(name) {
+ Ok(val) => val,
+ Err(err) => match err {
+ Error::NullSymbol => null(),
+ _ => return Err(err),
+ },
+ };
+ Ok(PtrOrNull::new(raw_ptr))
+ }
+
+ ///Obtain a mutable pointer from library.
+ ///
+ /// **Note:** This method is only recommended for data
+ /// that can't be accessed as a reference and that can have a null pointer value
+ /// (so not in 99% of cases).
+ pub unsafe fn ptr_or_null_mut(&self, name: &str) -> Result, Error> {
+ let cname = CString::new(name)?;
+ self.ptr_or_null_mut_cstr(cname.as_ref())
+ }
+
+ ///Equivalent of the `pointer_mut()` method but takes `CStr` as a argument.
+ pub unsafe fn ptr_or_null_mut_cstr(&self, name: &CStr) -> Result, Error> {
+ let raw_ptr = match self.lib.symbol_cstr(name) {
+ Ok(val) => val,
+ Err(err) => match err {
+ Error::NullSymbol => null_mut(),
+ _ => return Err(err),
+ },
+ };
+ Ok(PtrOrNullMut::new(raw_ptr))
+ }
+
+ ///Obtain const reference to statically allocated data in the library.
+ pub unsafe fn reference(&self, name: &str) -> Result<&T, Error> {
+ self.lib.symbol(name)
+ }
+
+ ///Equivalent of the `reference()` method but takes `CStr` as a argument.
+ pub unsafe fn reference_cstr(&self, name: &CStr) -> Result<&T, Error> {
+ self.lib.symbol_cstr(name)
+ }
+
+ ///Obtain mutable reference to statically allocated data in the library.
+ pub unsafe fn reference_mut(&self, name: &str) -> Result<&mut T, Error> {
+ self.lib.symbol(name)
+ }
+
+ ///Equivalent of the `reference_mut()` method but takes `CStr` as a argument.
+ pub unsafe fn reference_mut_cstr(&self, name: &CStr) -> Result<&mut T, Error> {
+ self.lib.symbol_cstr(name)
+ }
+}
+
+unsafe impl Send for Library {}
+unsafe impl Sync for Library {}
diff --git a/rust_crates/registry/src/github.com-1ecc6299db9ec823/dlopen-0.1.7/src/symbor/mod.rs b/rust_crates/registry/src/github.com-1ecc6299db9ec823/dlopen-0.1.7/src/symbor/mod.rs
new file mode 100644
index 0000000000..7bc10f04fc
--- /dev/null
+++ b/rust_crates/registry/src/github.com-1ecc6299db9ec823/dlopen-0.1.7/src/symbor/mod.rs
@@ -0,0 +1,112 @@
+/*!
+High-level and safe API for opening and getting symbols from dynamic libraries.
+It is based on symbol borrowing mechanism and supports automatic loading of symbols into structures.
+
+This API uses Rust borrowing mechanism to prevent problems with dangling symbols
+that take place when the library gets closed but the symbols still exist and are used.
+
+#Example of a dangling symbol prevention
+```no_run
+extern crate dlopen;
+use dlopen::symbor::Library;
+fn main(){
+ let lib = Library::open("libexample.dylib").unwrap();
+ let fun = unsafe{lib.symbol::f64>("some_symbol_name")}.unwrap();
+ println!("fun(1.0) = {}", unsafe{fun(1.0)});
+
+ //this would not compile because fun is a symbol borrowed from lib
+ //drop(lib);
+}
+```
+**Note:** All kind of objects from the `symbor` module implement the Deref or DerefMut trait.
+This means that you can use them as if you would use primitive types that they wrap.
+
+It also allows automatic loading of symbols into a structure.
+This is especially handy if you have a huge API with multiple symbols:
+
+# Example of automatic symbol loading
+
+```no_run
+#[macro_use]
+extern crate dlopen_derive;
+extern crate dlopen;
+use dlopen::symbor::{Library, Symbol, Ref, PtrOrNull, SymBorApi};
+
+ #[derive(SymBorApi)]
+ struct ExampleApi<'a> {
+ pub fun: Symbol<'a, unsafe extern "C" fn(i32) -> i32>,
+ pub glob_i32: Ref<'a, i32>,
+ pub maybe_c_str: PtrOrNull<'a, u8>,
+ pub opt_fun: Option>
+ }
+
+fn main(){
+ let lib = Library::open("example.dll").expect("Could not open library");
+ let api = unsafe{ExampleApi::load(&lib)}.expect("Could not load symbols");
+ println!("fun(4)={}", unsafe{(api.fun)(4)});
+ println!("glob_i32={}", *api.glob_i32);
+ println!("The pointer is null={}", api.maybe_c_str.is_null());
+ match api.opt_fun {
+ Some(fun) => fun(),
+ None => println!("Optional function not found in the library")
+ }
+
+ //this would not compile:
+ //drop(lib);
+}
+```
+
+**Note:** You can obtain optional symbols (`Option>`).
+This is very useful when you are dealing with
+ different versions of libraries and the newer versions support more functions.
+ If it is not possible to obtain the given symbol, the option is set to `None',
+ otherwise it contains the obtained symbol.
+
+Unfortunately in Rust it is not possible to create an API for dynamic link libraries that would
+be 100% safe. This API aims to be 99% safe by providing zero cost wrappers around raw symbols.
+However it is possible to make a mistake if you dereference safe wrappers into raw symbols.
+
+#Example of a mistake - dangling symbol
+
+```no_run
+extern crate dlopen;
+use dlopen::symbor::Library;
+fn main(){
+ let raw_fun = {
+ let lib = Library::open("libexample.dylib").unwrap();
+ let safe_fun = unsafe{
+ lib.symbol::f64>("some_symbol_name")
+ }.unwrap();
+ *safe_fun
+ };
+
+ //raw_fun is now a dangling symbol
+}
+```
+
+Original idea for this solution comes from Simonas Kazlauskas and his crate
+[libloading](https://github.com/nagisa/rust_libloading).
+Many improvements were added to solve several issues.
+
+*/
+
+mod ptr_or_null;
+mod ptr_or_null_mut;
+mod symbol;
+mod from_raw;
+mod library;
+mod option;
+mod reference;
+mod reference_mut;
+mod api;
+mod container;
+
+pub use self::library::Library;
+pub use self::symbol::Symbol;
+pub use self::api::SymBorApi;
+pub use self::ptr_or_null::PtrOrNull;
+pub use self::ptr_or_null_mut::PtrOrNullMut;
+pub use self::reference::Ref;
+pub use self::reference_mut::RefMut;
+pub use self::from_raw::FromRawResult;
+pub use self::container::Container;
diff --git a/rust_crates/registry/src/github.com-1ecc6299db9ec823/dlopen-0.1.7/src/symbor/option.rs b/rust_crates/registry/src/github.com-1ecc6299db9ec823/dlopen-0.1.7/src/symbor/option.rs
new file mode 100644
index 0000000000..b45756a7b0
--- /dev/null
+++ b/rust_crates/registry/src/github.com-1ecc6299db9ec823/dlopen-0.1.7/src/symbor/option.rs
@@ -0,0 +1,14 @@
+use super::super::err::Error;
+use super::from_raw::{FromRawResult, RawResult};
+
+impl<'a, T> FromRawResult for Option
+where
+ T: FromRawResult,
+{
+ unsafe fn from_raw_result(raw_result: RawResult) -> Result
, Error> {
+ match T::from_raw_result(raw_result) {
+ Ok(val) => Ok(Some(val)),
+ Err(_) => Ok(None),
+ }
+ }
+}
diff --git a/rust_crates/registry/src/github.com-1ecc6299db9ec823/dlopen-0.1.7/src/symbor/ptr_or_null.rs b/rust_crates/registry/src/github.com-1ecc6299db9ec823/dlopen-0.1.7/src/symbor/ptr_or_null.rs
new file mode 100644
index 0000000000..0b434c7e38
--- /dev/null
+++ b/rust_crates/registry/src/github.com-1ecc6299db9ec823/dlopen-0.1.7/src/symbor/ptr_or_null.rs
@@ -0,0 +1,44 @@
+use std::marker::PhantomData;
+use std::ops::Deref;
+use super::from_raw::{FromRawResult, RawResult};
+use super::super::err::Error;
+
+///Safe wrapper around const pointer.
+///
+///It is recommended only for obtaining pointers that can have null value.
+#[derive(Debug, Clone, Copy)]
+pub struct PtrOrNull<'lib, T: 'lib> {
+ pointer: *const T,
+ pd: PhantomData<&'lib T>,
+}
+
+impl<'lib, T> PtrOrNull<'lib, T> {
+ pub fn new(pointer: *const T) -> PtrOrNull<'lib, T> {
+ PtrOrNull {
+ pointer: pointer,
+ pd: PhantomData,
+ }
+ }
+}
+
+impl<'lib, T> FromRawResult for PtrOrNull<'lib, T> {
+ unsafe fn from_raw_result(raw_result: RawResult) -> Result {
+ match raw_result {
+ Ok(ptr) => Ok(PtrOrNull {
+ pointer: *ptr as *const T,
+ pd: PhantomData,
+ }),
+ Err(err) => Err(err),
+ }
+ }
+}
+
+impl<'lib, T> Deref for PtrOrNull<'lib, T> {
+ type Target = *const T;
+ fn deref(&self) -> &*const T {
+ &self.pointer
+ }
+}
+
+unsafe impl<'lib, T: Send> Send for PtrOrNull<'lib, T> {}
+unsafe impl<'lib, T: Sync> Sync for PtrOrNull<'lib, T> {}
diff --git a/rust_crates/registry/src/github.com-1ecc6299db9ec823/dlopen-0.1.7/src/symbor/ptr_or_null_mut.rs b/rust_crates/registry/src/github.com-1ecc6299db9ec823/dlopen-0.1.7/src/symbor/ptr_or_null_mut.rs
new file mode 100644
index 0000000000..2e86eb9e41
--- /dev/null
+++ b/rust_crates/registry/src/github.com-1ecc6299db9ec823/dlopen-0.1.7/src/symbor/ptr_or_null_mut.rs
@@ -0,0 +1,44 @@
+use std::marker::PhantomData;
+use std::ops::Deref;
+use super::from_raw::{FromRawResult, RawResult};
+use super::super::err::Error;
+
+///Safe wrapper around mutable pointer.
+///
+///It is recommended only for obtaining pointers that can have null value.
+#[derive(Debug, Clone, Copy)]
+pub struct PtrOrNullMut<'lib, T: 'lib> {
+ pointer: *mut T,
+ pd: PhantomData<&'lib T>,
+}
+
+impl<'lib, T> PtrOrNullMut<'lib, T> {
+ pub fn new(pointer: *mut T) -> PtrOrNullMut<'lib, T> {
+ PtrOrNullMut {
+ pointer: pointer,
+ pd: PhantomData,
+ }
+ }
+}
+
+impl<'lib, T> FromRawResult for PtrOrNullMut<'lib, T> {
+ unsafe fn from_raw_result(raw_result: RawResult) -> Result {
+ match raw_result {
+ Ok(ptr) => Ok(PtrOrNullMut {
+ pointer: *ptr as *mut T,
+ pd: PhantomData,
+ }),
+ Err(err) => Err(err),
+ }
+ }
+}
+
+impl<'lib, T> Deref for PtrOrNullMut<'lib, T> {
+ type Target = *mut T;
+ fn deref(&self) -> &*mut T {
+ &self.pointer
+ }
+}
+
+unsafe impl<'lib, T: Send> Send for PtrOrNullMut<'lib, T> {}
+unsafe impl<'lib, T: Sync> Sync for PtrOrNullMut<'lib, T> {}
diff --git a/rust_crates/registry/src/github.com-1ecc6299db9ec823/dlopen-0.1.7/src/symbor/reference.rs b/rust_crates/registry/src/github.com-1ecc6299db9ec823/dlopen-0.1.7/src/symbor/reference.rs
new file mode 100644
index 0000000000..2b3f046b0b
--- /dev/null
+++ b/rust_crates/registry/src/github.com-1ecc6299db9ec823/dlopen-0.1.7/src/symbor/reference.rs
@@ -0,0 +1,46 @@
+use std::ops::Deref;
+use super::from_raw::{FromRawResult, RawResult};
+use super::super::err::Error;
+use std::mem::transmute;
+
+///Safe wrapper around cont reference.
+///
+/// This type is intended to be used only inside structures implementing `SymBorApi` trait.
+/// In other cases you can as well use normal Rust reference.
+#[derive(Debug, Clone, Copy)]
+pub struct Ref<'lib, T: 'lib> {
+ reference: &'lib T,
+}
+
+impl<'lib, T> Ref<'lib, T> {
+ pub fn new(reference: &'lib T) -> Ref<'lib, T> {
+ Ref {
+ reference: reference,
+ }
+ }
+}
+
+impl<'lib, T> FromRawResult for Ref<'lib, T> {
+ unsafe fn from_raw_result(raw_result: RawResult) -> Result {
+ match raw_result {
+ Ok(ptr) => if ptr.is_null() {
+ Err(Error::NullSymbol)
+ } else {
+ Ok(Ref {
+ reference: transmute(*ptr),
+ })
+ },
+ Err(err) => Err(err),
+ }
+ }
+}
+
+impl<'lib, T> Deref for Ref<'lib, T> {
+ type Target = T;
+ fn deref(&self) -> &T {
+ self.reference
+ }
+}
+
+unsafe impl<'lib, T: Send> Send for Ref<'lib, T> {}
+unsafe impl<'lib, T: Sync> Sync for Ref<'lib, T> {}
diff --git a/rust_crates/registry/src/github.com-1ecc6299db9ec823/dlopen-0.1.7/src/symbor/reference_mut.rs b/rust_crates/registry/src/github.com-1ecc6299db9ec823/dlopen-0.1.7/src/symbor/reference_mut.rs
new file mode 100644
index 0000000000..3ac087084e
--- /dev/null
+++ b/rust_crates/registry/src/github.com-1ecc6299db9ec823/dlopen-0.1.7/src/symbor/reference_mut.rs
@@ -0,0 +1,53 @@
+use std::ops::{Deref, DerefMut};
+use super::from_raw::{FromRawResult, RawResult};
+use super::super::err::Error;
+use std::mem::transmute;
+
+///Safe wrapper around mutable reference.
+///
+/// This type is intended to be used only inside structures implementing `SymBorApi` trait.
+/// In other cases you can as well use normal Rust reference.
+#[derive(Debug)]
+pub struct RefMut<'lib, T: 'lib> {
+ reference: &'lib mut T,
+}
+
+impl<'lib, T> RefMut<'lib, T> {
+ pub fn new(reference: &'lib mut T) -> RefMut<'lib, T> {
+ RefMut {
+ reference: reference,
+ }
+ }
+}
+
+impl<'lib, T> FromRawResult for RefMut<'lib, T> {
+ unsafe fn from_raw_result(raw_result: RawResult) -> Result {
+ match raw_result {
+ Ok(ptr) => if ptr.is_null() {
+ Err(Error::NullSymbol)
+ } else {
+ Ok(RefMut {
+ reference: transmute(*ptr),
+ })
+ },
+ Err(err) => Err(err),
+ }
+ }
+}
+
+impl<'lib, T> Deref for RefMut<'lib, T> {
+ type Target = T;
+ fn deref(&self) -> &T {
+ self.reference
+ }
+}
+
+impl<'lib, T> DerefMut for RefMut<'lib, T> {
+ //type Target = T;
+ fn deref_mut(&mut self) -> &mut T {
+ self.reference
+ }
+}
+
+unsafe impl<'lib, T: Send> Send for RefMut<'lib, T> {}
+unsafe impl<'lib, T: Sync> Sync for RefMut<'lib, T> {}
diff --git a/rust_crates/registry/src/github.com-1ecc6299db9ec823/dlopen-0.1.7/src/symbor/symbol.rs b/rust_crates/registry/src/github.com-1ecc6299db9ec823/dlopen-0.1.7/src/symbor/symbol.rs
new file mode 100644
index 0000000000..554b458adb
--- /dev/null
+++ b/rust_crates/registry/src/github.com-1ecc6299db9ec823/dlopen-0.1.7/src/symbor/symbol.rs
@@ -0,0 +1,59 @@
+use std::marker::PhantomData;
+use std::ops::{Deref, DerefMut};
+use std::mem::transmute_copy;
+use super::from_raw::{FromRawResult, RawResult};
+use super::super::err::Error;
+
+///Safe wrapper around a symbol obtained from `Library`.
+///
+/// This is the most generic type, valid for obtaining functions, references and pointers.
+/// It does not accept null value of the library symbol. Other types may provide
+/// more specialized functionality better for some use cases.
+#[derive(Debug, Clone, Copy)]
+pub struct Symbol<'lib, T: 'lib> {
+ symbol: T,
+ pd: PhantomData<&'lib T>,
+}
+
+impl<'lib, T> Symbol<'lib, T> {
+ pub fn new(symbol: T) -> Symbol<'lib, T> {
+ Symbol {
+ symbol: symbol,
+ pd: PhantomData,
+ }
+ }
+}
+
+impl<'lib, T> FromRawResult for Symbol<'lib, T> {
+ unsafe fn from_raw_result(raw_result: RawResult) -> Result {
+ match raw_result {
+ Ok(ptr) => if ptr.is_null() {
+ Err(Error::NullSymbol)
+ } else {
+ let raw: *const () = *ptr;
+ Ok(Symbol {
+ symbol: transmute_copy(&raw),
+ pd: PhantomData,
+ })
+ },
+ Err(err) => Err(err),
+ }
+ }
+}
+
+impl<'lib, T> Deref for Symbol<'lib, T> {
+ type Target = T;
+ fn deref(&self) -> &T {
+ return &self.symbol;
+ }
+}
+
+impl<'lib, T> DerefMut for Symbol<'lib, T> {
+ //type Target = T;
+ fn deref_mut(&mut self) -> &mut T {
+ return &mut self.symbol;
+ }
+}
+
+unsafe impl<'lib, T: Send> Send for Symbol<'lib, T> {}
+unsafe impl<'lib, T: Sync> Sync for Symbol<'lib, T> {}
diff --git a/rust_crates/registry/src/github.com-1ecc6299db9ec823/dlopen-0.1.7/src/utils.rs b/rust_crates/registry/src/github.com-1ecc6299db9ec823/dlopen-0.1.7/src/utils.rs
new file mode 100644
index 0000000000..31c1e63937
--- /dev/null
+++ b/rust_crates/registry/src/github.com-1ecc6299db9ec823/dlopen-0.1.7/src/utils.rs
@@ -0,0 +1,55 @@
+/*!
+Utilities for working with dynamic link libraries.
+*/
+
+
+use std::ffi::{OsStr, OsString};
+
+//library naming patterns
+/* Naming pattern goes as follows:
+Windows *.dll
+Apple lib*.dylib
+Unix lib*.so
+*/
+
+///This is a platform-specific file prefix.
+///
+/// In Unix-based systems the convention is to start the file name with "lib".
+/// Windows does not have such a convention.
+#[cfg(unix)]
+pub const PLATFORM_FILE_PREFIX: &str = "lib";
+///This is a platform-specific file prefix.
+///
+/// In Unix-based systems the convention is to start the file name with "lib".
+/// Windows does not have such a convention.
+#[cfg(windows)]
+pub const PLATFORM_FILE_PREFIX: &str = "";
+
+///Dynamic link library file extension specific to the platform.
+#[cfg(any(target_os = "macos", target_os = "ios"))]
+pub const PLATFORM_FILE_EXTENSION: &str = "dylib";
+///Dynamic link library file extension specific to the platform.
+#[cfg(all(unix, not(any(target_os = "macos", target_os = "ios"))))]
+pub const PLATFORM_FILE_EXTENSION: &str = "so";
+///Dynamic link library file extension specific to the platform.
+#[cfg(windows)]
+pub const PLATFORM_FILE_EXTENSION: &str = "dll";
+
+///Crates a platform-specific file name from provided core file name.
+///
+/// For example on Ubuntu it converts "example" argument into "libexample.so".
+pub fn platform_file_name(core_name: S) -> OsString
+where
+ S: AsRef,
+{
+ //here we operate on OStr and OsString and there are no formatting functions for them - sad
+ let mut result = OsString::new();
+ result.reserve_exact(
+ core_name.as_ref().len() + PLATFORM_FILE_EXTENSION.len() + PLATFORM_FILE_PREFIX.len() + 1,
+ );
+ result.push(PLATFORM_FILE_PREFIX);
+ result.push(core_name);
+ result.push(".");
+ result.push(PLATFORM_FILE_EXTENSION);
+ result
+}
diff --git a/rust_crates/registry/src/github.com-1ecc6299db9ec823/dlopen-0.1.7/src/wrapper/api.rs b/rust_crates/registry/src/github.com-1ecc6299db9ec823/dlopen-0.1.7/src/wrapper/api.rs
new file mode 100644
index 0000000000..1571036bce
--- /dev/null
+++ b/rust_crates/registry/src/github.com-1ecc6299db9ec823/dlopen-0.1.7/src/wrapper/api.rs
@@ -0,0 +1,88 @@
+use super::super::err::Error;
+use super::super::raw::Library;
+
+/**
+Trait for defining library API.
+
+This trait is intended to be used with `#[derive(WrapperApi)]` macro defined in the
+`dlopen_derive` crate. It forces several restrictions on types that implement it:
+
+* Only structures can implement this trait.
+* All fields need to be private.
+* Only functions, references and pointers are allowed.
+* You can't define a type using `type Fun =fn();` and use it in the structure. This is a limitation
+ of the Rust reflection mechanism. Only raw functions, references and pointers are allowed.
+* All arguments of functions need to be named.
+
+
+The `derive` macro not only generates implementation of `load()` function, but it also generates
+safe wrappers around the loaded symbols. These wrappers are named exactly like the field that
+they wrap. Wrappers of functions have the same arguments like original functions and wrappers of
+references are just simple accessors in the form of `(&self) -> &FieldType` or
+`_mut(&mut self) -> &mut FieldType`.
+Wrappers are not generated only for:
+
+* Pointers - there is no safe way of preventing dangling symbols if a user has a direct access to
+ pointers. The recommended approach here is to either use references instead of pointers or
+ to manually create safe wrappers. For example C `const char *` can be manually converted into
+ `& std::ffi::CStr`.
+* Variadic functions. Rust doesn't have any mechanism that allows creating safe wrappers around
+ them. You need to handle them manually.
+
+#Example
+
+```no_run
+#[macro_use]
+extern crate dlopen_derive;
+extern crate dlopen;
+extern crate libc;
+use dlopen::wrapper::{WrapperApi, Container};
+use libc::{c_char};
+use std::ffi::CStr;
+
+#[derive(WrapperApi)]
+struct Example<'a> {
+ #[dlopen_name="function"]
+ do_something: extern "C" fn(),
+ add_one: unsafe extern "C" fn (arg: i32) -> i32,
+ global_count: &'a mut u32,
+ c_string: * const c_char,
+ #[dlopen_allow_null]
+ maybe_null_ptr: * const (),
+}
+
+//wrapper for c_string won't be generated, implement it here
+impl<'a> Example<'a> {
+ pub fn c_string(&self) -> &CStr {
+ unsafe {CStr::from_ptr(self.c_string)}
+ }
+}
+
+fn main () {
+ let mut cont: Container = unsafe { Container::load("libexample.dylib")}.unwrap();
+ cont.do_something();
+ let _result = unsafe { cont.add_one(5) };
+ *cont.global_count_mut() += 1;
+ println!("C string: {}", cont.c_string().to_str().unwrap())
+}
+```
+
+**Note**: `WrapperApi` should only be used together with `Container` structure, never to create
+a standalone object. API and library handle need to be kept together to prevent dangling symbols.
+
+**Note:** By default obtained symbol name is the field name. You can change this by
+assigning the "dlopen_name" attribute to the given field.
+
+**Note:** By default `Error::NullSymbol` is returned if the loaded symbol name has a null value.
+While null is a valid value of a exported symbol, it is usually not expected by users of libraries.
+If in your scenario null is an acceptable value, you should assign
+"dlopen_allow_null" attribute to the given field. Of course this makes sense only if the field
+is of pointer type.
+*/
+pub trait WrapperApi
+where
+ Self: Sized,
+{
+ ///Load symbols from provided library.
+ unsafe fn load(lib: &Library) -> Result;
+}
diff --git a/rust_crates/registry/src/github.com-1ecc6299db9ec823/dlopen-0.1.7/src/wrapper/container.rs b/rust_crates/registry/src/github.com-1ecc6299db9ec823/dlopen-0.1.7/src/wrapper/container.rs
new file mode 100644
index 0000000000..fe625a1dba
--- /dev/null
+++ b/rust_crates/registry/src/github.com-1ecc6299db9ec823/dlopen-0.1.7/src/wrapper/container.rs
@@ -0,0 +1,100 @@
+use super::super::raw::Library;
+use super::super::Error;
+use std::ops::{Deref, DerefMut};
+use super::api::WrapperApi;
+use std::ffi::OsStr;
+
+/**
+Container for both a dynamic load library handle and its API.
+
+Keeping both library and its symbols together makes it safe to use it because symbols are released
+together with the library. `Container` also doesn't have any external lifetimes - this makes it
+easy to use `Container` inside structures.
+
+#Example
+
+```no_run
+#[macro_use]
+extern crate dlopen_derive;
+extern crate dlopen;
+extern crate libc;
+use dlopen::wrapper::{Container, WrapperApi};
+use libc::{c_char};
+use std::ffi::CStr;
+
+#[derive(WrapperApi)]
+struct Example<'a> {
+ do_something: extern "C" fn(),
+ add_one: unsafe extern "C" fn (arg: i32) -> i32,
+ global_count: &'a mut u32,
+ c_string: * const c_char
+}
+
+//wrapper for c_string won't be generated, implement it here
+impl<'a> Example<'a> {
+ pub fn c_string(&self) -> &CStr {
+ unsafe {CStr::from_ptr(self.c_string)}
+ }
+}
+
+fn main () {
+ let mut container: Container = unsafe { Container::load("libexample.dylib")}.unwrap();
+ container.do_something();
+ let _result = unsafe { container.add_one(5) };
+ *container.global_count_mut() += 1;
+ println!("C string: {}", container.c_string().to_str().unwrap())
+}
+```
+*/
+pub struct Container
+where
+ T: WrapperApi,
+{
+ #[allow(dead_code)]
+ //this is not dead code because destructor of Library deallocates the library
+ lib: Library,
+ api: T,
+}
+
+impl Container
+where
+ T: WrapperApi,
+{
+ ///Open the library using provided file name or path and load all symbols.
+ pub unsafe fn load(name: S) -> Result, Error>
+ where
+ S: AsRef,
+ {
+ let lib = Library::open(name)?;
+ let api = T::load(&lib)?;
+ Ok(Self { lib: lib, api: api })
+ }
+ ///Load all symbols from the program itself.
+ ///
+ /// This allows a shared library to load symbols of the program it was
+ /// loaded into.
+ pub unsafe fn load_self() -> Result, Error> {
+ let lib = Library::open_self()?;
+ let api = T::load(&lib)?;
+ Ok(Self { lib: lib, api: api })
+ }
+}
+
+impl Deref for Container
+where
+ T: WrapperApi,
+{
+ type Target = T;
+ fn deref(&self) -> &T {
+ &self.api
+ }
+}
+
+impl DerefMut for Container
+where
+ T: WrapperApi,
+{
+ fn deref_mut(&mut self) -> &mut T {
+ &mut self.api
+ }
+}
diff --git a/rust_crates/registry/src/github.com-1ecc6299db9ec823/dlopen-0.1.7/src/wrapper/mod.rs b/rust_crates/registry/src/github.com-1ecc6299db9ec823/dlopen-0.1.7/src/wrapper/mod.rs
new file mode 100644
index 0000000000..a8a47e471d
--- /dev/null
+++ b/rust_crates/registry/src/github.com-1ecc6299db9ec823/dlopen-0.1.7/src/wrapper/mod.rs
@@ -0,0 +1,88 @@
+/*!
+High-level and safe API for opening and getting symbols from dynamic link libraries.
+It is based on wrapping private symbols with public functions to prevent direct access
+and supports automatic loading of symbols into structures.
+
+This API solves the problem with dangling symbols by wrapping raw symbols with public functions.
+User of API does not have direct access to raw symbols and therefore symbols cannot be copied.
+Symbols and library handle are kept in one `Container` structure and therefore both the the library
+and symbols get released at the same time.
+
+#Example
+
+```no_run
+#[macro_use]
+extern crate dlopen_derive;
+extern crate dlopen;
+use dlopen::wrapper::{Container, WrapperApi};
+
+#[derive(WrapperApi)]
+struct Example<'a> {
+ do_something: extern "C" fn(),
+ add_one: unsafe extern "C" fn (arg: i32) -> i32,
+ global_count: &'a mut u32,
+}
+
+fn main () {
+let mut container: Container = unsafe { Container::load("libexample.dylib")}.unwrap();
+container.do_something();
+let _result = unsafe { container.add_one(5) };
+*container.global_count_mut() += 1;
+
+//symbols are released together with library handle
+//this prevents dangling symbols
+drop(container);
+}
+```
+
+Unfortunately in Rust it is not possible to create an API for dynamic link libraries that would
+be 100% safe. This API aims to be 99% safe by providing zero cost functional wrappers around
+raw symbols. However it is possible to make a mistake if you create API as a standalone object
+(not in container):
+
+#Example of a mistake - dangling symbol
+
+```no_run
+#[macro_use]
+extern crate dlopen_derive;
+extern crate dlopen;
+use dlopen::wrapper::{Container, WrapperApi};
+use dlopen::raw::Library;
+
+#[derive(WrapperApi)]
+struct Example<'a> {
+ do_something: extern "C" fn(),
+ add_one: unsafe extern "C" fn (arg: i32) -> i32,
+ global_count: &'a mut u32,
+}
+
+fn main () {
+let lib = Library::open("libexample.dylib").unwrap();
+let mut api = unsafe{Example::load(&lib)};
+drop(lib);
+
+//api has now dangling symbols
+
+}
+```
+
+To prevent this mistake don't use structures implementing `WrapperApi` directly, but rather use
+`Container` as in the first example.
+
+**Note:** This API has a broad support for optional symbols (this solves the issue with multiple
+versions of one dynamic link library that have different sets of symbols). Please refer to the
+documentation of
+[`OptionalContainer`](./struct.OptionalContainer.html)
+and
+[`WrapperMultiApi`](./trait.WrapperMultiApi.html).
+*/
+
+mod api;
+mod multi_api;
+mod container;
+mod optional;
+mod option;
+pub use self::api::WrapperApi;
+pub use self::multi_api::WrapperMultiApi;
+pub use self::container::Container;
+pub use self::optional::OptionalContainer;
diff --git a/rust_crates/registry/src/github.com-1ecc6299db9ec823/dlopen-0.1.7/src/wrapper/multi_api.rs b/rust_crates/registry/src/github.com-1ecc6299db9ec823/dlopen-0.1.7/src/wrapper/multi_api.rs
new file mode 100644
index 0000000000..883645946b
--- /dev/null
+++ b/rust_crates/registry/src/github.com-1ecc6299db9ec823/dlopen-0.1.7/src/wrapper/multi_api.rs
@@ -0,0 +1,72 @@
+use super::api::WrapperApi;
+
+/**
+Allows creation of complex, optional APIs.
+
+Real life dynamic link libraries often come in multiple versions. Sometimes additional functions
+are added for the specific operating system, sometimes the library gets extended and new versions
+export more symbols. Often the API can have multiple versions. This trait helps creating
+library APIs with multiple optional parts.
+
+`WrapperMultiApi` is intended to be used together with the derive macro. You should create a new
+structure where all fields implement the `WrapperApi` trait (this includes `Option` where
+`T` implements `WrapperApi`). The derive macro will generate required implementation.
+
+**Note**: `WrapperMultiApi` should only be used together with `Container` structure, never to create
+a standalone object. API and library handle need to be kept together to prevent dangling symbols.
+
+```no_run
+#[macro_use]
+extern crate dlopen_derive;
+extern crate dlopen;
+use dlopen::wrapper::{Container, WrapperApi, WrapperMultiApi};
+
+//Define 3 APIs:
+
+#[derive(WrapperApi)]
+struct Obligatory{
+ some_fun: unsafe extern "C" fn()
+}
+
+#[derive(WrapperApi)]
+struct Optional1<'a>{
+ static_val: &'a i32
+}
+
+#[derive(WrapperApi)]
+struct Optional2{
+ another_fun: unsafe extern "C" fn()
+}
+
+//Now define a multi wrapper that wraps sub APIs into one bigger API.
+//This example assumes that the first API is obligatory and the other two are optional.
+
+#[derive(WrapperMultiApi)]
+struct Api<'a>{
+ pub obligatory: Obligatory,
+ pub optional1: Option>,
+ pub optional2: Option
+}
+
+fn main(){
+ let mut container: Container = unsafe {
+ Container::load("libexample.so")
+ }.expect("Could not open library or load symbols");
+
+ //use obligatory API:
+ unsafe{container.obligatory.some_fun()};
+
+ //use first optional API:
+ if let Some(ref opt) = container.optional1{
+ let _val = *opt.static_val();
+ }
+
+ //use second optional API:
+ if let Some(ref opt) = container.optional2{
+ unsafe {opt.another_fun()};
+ }
+}
+```
+*/
+
+pub trait WrapperMultiApi: WrapperApi {}
diff --git a/rust_crates/registry/src/github.com-1ecc6299db9ec823/dlopen-0.1.7/src/wrapper/option.rs b/rust_crates/registry/src/github.com-1ecc6299db9ec823/dlopen-0.1.7/src/wrapper/option.rs
new file mode 100644
index 0000000000..7a9846afc1
--- /dev/null
+++ b/rust_crates/registry/src/github.com-1ecc6299db9ec823/dlopen-0.1.7/src/wrapper/option.rs
@@ -0,0 +1,15 @@
+use super::api::WrapperApi;
+use super::super::raw::Library;
+use super::super::Error;
+
+impl WrapperApi for Option
+where
+ T: WrapperApi,
+{
+ unsafe fn load(lib: &Library) -> Result {
+ match T::load(lib) {
+ Ok(val) => Ok(Some(val)),
+ Err(_) => Ok(None),
+ }
+ }
+}
diff --git a/rust_crates/registry/src/github.com-1ecc6299db9ec823/dlopen-0.1.7/src/wrapper/optional.rs b/rust_crates/registry/src/github.com-1ecc6299db9ec823/dlopen-0.1.7/src/wrapper/optional.rs
new file mode 100644
index 0000000000..a3a6dc16cb
--- /dev/null
+++ b/rust_crates/registry/src/github.com-1ecc6299db9ec823/dlopen-0.1.7/src/wrapper/optional.rs
@@ -0,0 +1,126 @@
+use super::super::raw::Library;
+use super::super::Error;
+use std::ops::{Deref, DerefMut};
+use super::api::WrapperApi;
+use std::ffi::OsStr;
+
+/**
+Container for a library handle and both obligatory and optional APIs inside one structure.
+
+A common problem with dynamic link libraries is that they often have different versions and some
+of those versions have broader API than others. This structure allows you to use two APIs at the
+same time - one obligatory and one optional. If symbols of the optional API are found in the
+library, the optional API gets loaded. Otherwise the `optional()` method will return `None`.
+
+#Example
+
+```no_run
+#[macro_use]
+extern crate dlopen_derive;
+extern crate dlopen;
+use dlopen::wrapper::{OptionalContainer, WrapperApi};
+
+#[derive(WrapperApi)]
+struct Obligatory<'a> {
+ do_something: extern "C" fn(),
+ global_count: &'a mut u32,
+}
+
+#[derive(WrapperApi)]
+struct Optional{
+ add_one: unsafe extern "C" fn (arg: i32) -> i32,
+ c_string: * const u8
+}
+
+fn main () {
+ let mut container: OptionalContainer = unsafe {
+ OptionalContainer::load("libexample.dylib")
+ }.unwrap();
+ container.do_something();
+ *container.global_count_mut() += 1;
+
+ match container.optional(){
+ &Some(ref opt) => {
+ let _result = unsafe { opt.add_one(5) };
+ println!("First byte of C string is {}", unsafe{*opt.c_string});
+ },
+ &None => println!("The optional API was not loaded!")
+ }
+}
+```
+
+**Note:** For more complex cases (multiple versions of API) you can use
+[`WrapperMultiApi`](./trait.WrapperMultiApi.html).
+*/
+pub struct OptionalContainer
+where
+ Api: WrapperApi,
+ Optional: WrapperApi,
+{
+ #[allow(dead_code)]
+ //this is not dead code because destructor of Library deallocates the library
+ lib: Library,
+ api: Api,
+ optional: Option,
+}
+
+impl OptionalContainer
+where
+ Api: WrapperApi,
+ Optional: WrapperApi,
+{
+ ///Opens the library using provided file name or path and loads all symbols (including optional
+ ///if it is possible).
+ pub unsafe fn load(name: S) -> Result, Error>
+ where
+ S: AsRef,
+ {
+ let lib = Library::open(name)?;
+ let api = Api::load(&lib)?;
+ let optional = Optional::load(&lib).ok();
+ Ok(Self { lib, api, optional })
+ }
+
+ ///Load all symbols (including optional if it is possible) from the
+ ///program itself.
+ ///
+ /// This allows a shared library to load symbols of the program it was
+ /// loaded into.
+ pub unsafe fn load_self() -> Result, Error> {
+ let lib = Library::open_self()?;
+ let api = Api::load(&lib)?;
+ let optional = Optional::load(&lib).ok();
+ Ok(Self { lib, api, optional })
+ }
+
+ ///Gives access to the optional API - constant version.
+ pub fn optional(&self) -> &Option {
+ return &self.optional;
+ }
+
+ ///Gives access to the optional API - constant version.
+ pub fn optional_mut(&mut self) -> &Option {
+ return &mut self.optional;
+ }
+}
+
+impl Deref for OptionalContainer
+where
+ Api: WrapperApi,
+ Optional: WrapperApi,
+{
+ type Target = Api;
+ fn deref(&self) -> &Api {
+ &self.api
+ }
+}
+
+impl DerefMut for OptionalContainer
+where
+ Api: WrapperApi,
+ Optional: WrapperApi,
+{
+ fn deref_mut(&mut self) -> &mut Api {
+ &mut self.api
+ }
+}
diff --git a/rust_crates/registry/src/github.com-1ecc6299db9ec823/dlopen-0.1.7/tests/commons/mod.rs b/rust_crates/registry/src/github.com-1ecc6299db9ec823/dlopen-0.1.7/tests/commons/mod.rs
new file mode 100644
index 0000000000..b338449bfc
--- /dev/null
+++ b/rust_crates/registry/src/github.com-1ecc6299db9ec823/dlopen-0.1.7/tests/commons/mod.rs
@@ -0,0 +1,68 @@
+extern crate dlopen;
+extern crate libc;
+extern crate regex;
+use dlopen::utils::{PLATFORM_FILE_EXTENSION, PLATFORM_FILE_PREFIX};
+use std::env;
+use std::path::{Path, PathBuf};
+use libc::c_int;
+use std::fs;
+
+
+
+pub fn example_lib_path() -> PathBuf {
+
+ //Rust when building dependencies adds some weird numbers to file names
+ // find the file using this pattern:
+ //const FILE_PATTERN: &str = concat!(PLATFORM_FILE_PREFIX, "example.*\\.", PLATFORM_FILE_EXTENSION);
+ let file_pattern = format!(
+ r"{}example.*\.{}",
+ PLATFORM_FILE_PREFIX,
+ PLATFORM_FILE_EXTENSION
+ );
+ let file_regex = regex::Regex::new(file_pattern.as_ref()).unwrap();
+
+ //find the directory with dependencies - there shold be our example library
+ let mut deps_dir = PathBuf::from(env::var_os("CARGO_MANIFEST_DIR").unwrap());
+ deps_dir.extend(["target", "debug", "deps"].iter());
+
+ //unfortunately rust has no strict pattern of naming dependencies in this directory
+ //this is partially platform dependent as there was a bug reported that while the code runs
+ //well on Linux, Windows, it stopped working on a new version of Mac.
+ //The only way to handle this correctly is by traversing the directory recursively and
+ // finding a match.
+
+
+
+ let lib_path = recursive_find(deps_dir.as_path(), &file_regex).expect(
+ "Could not find the example library");
+ println!("Library path: {}", lib_path.to_str().unwrap());
+ lib_path
+}
+
+fn recursive_find(path: &Path, file_regex: ®ex::Regex) -> Option {
+ if path.is_dir(){
+ match fs::read_dir(path) {
+ Result::Err(_) => None,
+ Result::Ok(dir) => {
+ for entry in dir.filter_map(Result::ok) {
+ if let Some(p) = recursive_find(&entry.path(), file_regex){
+ return Some(p);
+ }
+ }
+ None
+ }
+ }
+ } else {
+ if file_regex.is_match(path.file_name().unwrap().to_str().unwrap()){
+ Some(path.to_path_buf())
+ } else {
+ None
+ }
+ }
+}
+
+#[repr(C)]
+pub struct SomeData {
+ pub first: c_int,
+ pub second: c_int,
+}
diff --git a/rust_crates/registry/src/github.com-1ecc6299db9ec823/dlopen-0.1.7/tests/raw.rs b/rust_crates/registry/src/github.com-1ecc6299db9ec823/dlopen-0.1.7/tests/raw.rs
new file mode 100644
index 0000000000..988832078f
--- /dev/null
+++ b/rust_crates/registry/src/github.com-1ecc6299db9ec823/dlopen-0.1.7/tests/raw.rs
@@ -0,0 +1,59 @@
+#[macro_use]
+extern crate const_cstr;
+extern crate dlopen;
+extern crate libc;
+use dlopen::raw::Library;
+use libc::{c_char, c_int};
+use std::ffi::CStr;
+
+mod commons;
+use commons::{example_lib_path, SomeData};
+
+#[test]
+fn open_play_close_raw() {
+ let lib_path = example_lib_path();
+ let lib = Library::open(lib_path).expect("Could not open library");
+ let rust_fun_print_something: fn() =
+ unsafe { lib.symbol_cstr(const_cstr!("rust_fun_print_something").as_cstr()) }.unwrap();
+ rust_fun_print_something(); //should not crash
+ let rust_fun_add_one: fn(i32) -> i32 =
+ unsafe { lib.symbol_cstr(const_cstr!("rust_fun_add_one").as_cstr()) }.unwrap();
+ assert_eq!(rust_fun_add_one(5), 6);
+ let c_fun_print_something_else: unsafe extern "C" fn() =
+ unsafe { lib.symbol_cstr(const_cstr!("c_fun_print_something_else").as_cstr()) }.unwrap();
+ unsafe { c_fun_print_something_else() }; //should not crash
+ let c_fun_add_two: unsafe extern "C" fn(c_int) -> c_int =
+ unsafe { lib.symbol_cstr(const_cstr!("c_fun_add_two").as_cstr()) }.unwrap();
+ assert_eq!(unsafe { c_fun_add_two(2) }, 4);
+ let rust_i32: &i32 = unsafe { lib.symbol_cstr(const_cstr!("rust_i32").as_cstr()) }.unwrap();
+ assert_eq!(43, *rust_i32);
+ let rust_i32_mut: &mut i32 =
+ unsafe { lib.symbol_cstr(const_cstr!("rust_i32_mut").as_cstr()) }.unwrap();
+ assert_eq!(42, *rust_i32_mut);
+ *rust_i32_mut = 55; //should not crash
+ //for a change use pointer to obtain its value
+ let rust_i32_ptr: *const i32 =
+ unsafe { lib.symbol_cstr(const_cstr!("rust_i32_mut").as_cstr()) }.unwrap();
+ assert_eq!(55, unsafe { *rust_i32_ptr });
+ //the same with C
+ let c_int: &c_int = unsafe { lib.symbol_cstr(const_cstr!("c_int").as_cstr()) }.unwrap();
+ assert_eq!(45, *c_int);
+ //now static c struct
+
+ let c_struct: &SomeData =
+ unsafe { lib.symbol_cstr(const_cstr!("c_struct").as_cstr()) }.unwrap();
+ assert_eq!(1, c_struct.first);
+ assert_eq!(2, c_struct.second);
+ //let's play with strings
+
+ let rust_str: &&str = unsafe { lib.symbol_cstr(const_cstr!("rust_str").as_cstr()) }.unwrap();
+ assert_eq!("Hello!", *rust_str);
+ let c_const_char_ptr: *const c_char =
+ unsafe { lib.symbol_cstr(const_cstr!("c_const_char_ptr").as_cstr()) }.unwrap();
+ let converted = unsafe { CStr::from_ptr(c_const_char_ptr) }
+ .to_str()
+ .unwrap();
+ assert_eq!(converted, "Hi!");
+
+ ::std::mem::forget(lib);
+}
diff --git a/rust_crates/registry/src/github.com-1ecc6299db9ec823/dlopen-0.1.7/tests/symbor.rs b/rust_crates/registry/src/github.com-1ecc6299db9ec823/dlopen-0.1.7/tests/symbor.rs
new file mode 100644
index 0000000000..6191a3b180
--- /dev/null
+++ b/rust_crates/registry/src/github.com-1ecc6299db9ec823/dlopen-0.1.7/tests/symbor.rs
@@ -0,0 +1,67 @@
+#[macro_use]
+extern crate const_cstr;
+extern crate dlopen;
+extern crate libc;
+use dlopen::symbor::Library;
+use libc::{c_char, c_int};
+use std::ffi::CStr;
+
+mod commons;
+use commons::{example_lib_path, SomeData};
+
+#[test]
+fn open_play_close_symbor() {
+ let lib_path = example_lib_path();
+ let lib = Library::open(lib_path).expect("Could not open library");
+ let rust_fun_print_something = unsafe {
+ lib.symbol_cstr::(const_cstr!("rust_fun_print_something").as_cstr())
+ }.unwrap();
+ rust_fun_print_something(); //should not crash
+ let rust_fun_add_one = unsafe {
+ lib.symbol_cstr:: i32>(const_cstr!("rust_fun_add_one").as_cstr())
+ }.unwrap();
+ assert_eq!(rust_fun_add_one(5), 6);
+
+ let c_fun_print_something_else = unsafe {
+ lib.symbol_cstr::(
+ const_cstr!("c_fun_print_something_else").as_cstr(),
+ )
+ }.unwrap();
+ unsafe { c_fun_print_something_else() }; //should not crash
+ let c_fun_add_two = unsafe {
+ lib.symbol_cstr:: c_int>(
+ const_cstr!("c_fun_add_two").as_cstr(),
+ )
+ }.unwrap();
+ assert_eq!(unsafe { c_fun_add_two(2) }, 4);
+ let rust_i32: &i32 = unsafe { lib.reference_cstr(const_cstr!("rust_i32").as_cstr()) }.unwrap();
+ assert_eq!(43, *rust_i32);
+ let rust_i32_mut: &mut i32 =
+ unsafe { lib.reference_mut_cstr(const_cstr!("rust_i32_mut").as_cstr()) }.unwrap();
+ assert_eq!(42, *rust_i32_mut);
+ *rust_i32_mut = 55; //should not crash
+ //for a change use pointer to obtain its value
+ let rust_i32_ptr =
+ unsafe { lib.symbol_cstr::<*const i32>(const_cstr!("rust_i32_mut").as_cstr()) }.unwrap();
+ assert_eq!(55, unsafe { **rust_i32_ptr });
+ //the same with C
+ let c_int: &c_int = unsafe { lib.reference_cstr(const_cstr!("c_int").as_cstr()) }.unwrap();
+ assert_eq!(45, *c_int);
+ //now static c struct
+
+ let c_struct: &SomeData =
+ unsafe { lib.reference_cstr(const_cstr!("c_struct").as_cstr()) }.unwrap();
+ assert_eq!(1, c_struct.first);
+ assert_eq!(2, c_struct.second);
+ //let's play with strings
+
+ let rust_str: &&str = unsafe { lib.reference_cstr(const_cstr!("rust_str").as_cstr()) }.unwrap();
+ assert_eq!("Hello!", *rust_str);
+ let c_const_char_ptr = unsafe {
+ lib.symbol_cstr::<*const c_char>(const_cstr!("c_const_char_ptr").as_cstr())
+ }.unwrap();
+ let converted = unsafe { CStr::from_ptr(*c_const_char_ptr) }
+ .to_str()
+ .unwrap();
+ assert_eq!(converted, "Hi!");
+}
diff --git a/rust_crates/registry/src/github.com-1ecc6299db9ec823/dlopen-0.1.7/tests/symbor_api.rs b/rust_crates/registry/src/github.com-1ecc6299db9ec823/dlopen-0.1.7/tests/symbor_api.rs
new file mode 100644
index 0000000000..99a3eec1ec
--- /dev/null
+++ b/rust_crates/registry/src/github.com-1ecc6299db9ec823/dlopen-0.1.7/tests/symbor_api.rs
@@ -0,0 +1,53 @@
+extern crate dlopen;
+#[macro_use]
+extern crate dlopen_derive;
+extern crate libc;
+use dlopen::symbor::{Library, PtrOrNull, Ref, RefMut, SymBorApi, Symbol};
+use libc::{c_char, c_int};
+use std::ffi::CStr;
+
+mod commons;
+use commons::{example_lib_path, SomeData};
+
+#[derive(SymBorApi)]
+struct Api<'a> {
+ pub rust_fun_print_something: Symbol<'a, fn()>,
+ pub rust_fun_add_one: Symbol<'a, fn(i32) -> i32>,
+ pub c_fun_print_something_else: Symbol<'a, unsafe extern "C" fn()>,
+ pub c_fun_add_two: Symbol<'a, unsafe extern "C" fn(c_int) -> c_int>,
+ pub rust_i32: Ref<'a, i32>,
+ pub rust_i32_mut: RefMut<'a, i32>,
+ #[dlopen_name = "rust_i32_mut"] pub rust_i32_ptr: Symbol<'a, *const i32>,
+ pub c_int: Ref<'a, c_int>,
+ pub c_struct: Ref<'a, SomeData>,
+ pub rust_str: Ref<'a, &'static str>,
+ pub c_const_char_ptr: PtrOrNull<'a, c_char>,
+}
+
+#[test]
+fn open_play_close_symbor_api() {
+ let lib_path = example_lib_path();
+ let lib = Library::open(lib_path).expect("Could not open library");
+ let mut api = unsafe { Api::load(&lib) }.expect("Could not load symbols");
+ (api.rust_fun_print_something)(); //should not crash
+ assert_eq!((api.rust_fun_add_one)(5), 6);
+ unsafe { (api.c_fun_print_something_else)() }; //should not crash
+ assert_eq!(unsafe { (api.c_fun_add_two)(2) }, 4);
+ assert_eq!(43, *api.rust_i32);
+ assert_eq!(42, *api.rust_i32_mut);
+ *api.rust_i32_mut = 55; //should not crash
+ assert_eq!(55, unsafe { **api.rust_i32_ptr });
+ //the same with C
+ assert_eq!(45, *api.c_int);
+ //now static c struct
+
+ assert_eq!(1, api.c_struct.first);
+ assert_eq!(2, api.c_struct.second);
+ //let's play with strings
+
+ assert_eq!("Hello!", *api.rust_str);
+ let converted = unsafe { CStr::from_ptr(*api.c_const_char_ptr) }
+ .to_str()
+ .unwrap();
+ assert_eq!(converted, "Hi!");
+}
diff --git a/rust_crates/registry/src/github.com-1ecc6299db9ec823/dlopen-0.1.7/tests/wrapper_api.rs b/rust_crates/registry/src/github.com-1ecc6299db9ec823/dlopen-0.1.7/tests/wrapper_api.rs
new file mode 100644
index 0000000000..2a34849205
--- /dev/null
+++ b/rust_crates/registry/src/github.com-1ecc6299db9ec823/dlopen-0.1.7/tests/wrapper_api.rs
@@ -0,0 +1,63 @@
+extern crate dlopen;
+#[macro_use]
+extern crate dlopen_derive;
+extern crate libc;
+use dlopen::wrapper::{Container, WrapperApi};
+use libc::{c_char, c_int};
+use std::ffi::CStr;
+
+mod commons;
+use commons::{example_lib_path, SomeData};
+
+#[derive(WrapperApi)]
+struct Api<'a> {
+ rust_fun_print_something: fn(),
+ rust_fun_add_one: fn(arg: i32) -> i32,
+ c_fun_print_something_else: unsafe extern "C" fn(),
+ c_fun_add_two: unsafe extern "C" fn(arg: c_int) -> c_int,
+ rust_i32: &'a i32,
+ rust_i32_mut: &'a mut i32,
+ #[dlopen_name = "rust_i32_mut"] rust_i32_ptr: *const i32,
+ c_int: &'a c_int,
+ c_struct: &'a SomeData,
+ rust_str: &'a &'static str,
+ c_const_char_ptr: *const c_char,
+}
+
+//those methods won't be generated
+impl<'a> Api<'a> {
+ fn rust_i32_ptr(&self) -> *const i32 {
+ self.rust_i32_ptr
+ }
+
+ fn c_const_str(&self) -> &CStr {
+ unsafe { CStr::from_ptr(self.c_const_char_ptr) }
+ }
+}
+
+#[test]
+fn open_play_close_wrapper_api() {
+ let lib_path = example_lib_path();
+ let mut cont: Container =
+ unsafe { Container::load(lib_path) }.expect("Could not open library or load symbols");
+
+ cont.rust_fun_print_something(); //should not crash
+ assert_eq!(cont.rust_fun_add_one(5), 6);
+ unsafe { cont.c_fun_print_something_else() }; //should not crash
+ assert_eq!(unsafe { cont.c_fun_add_two(2) }, 4);
+ assert_eq!(43, *cont.rust_i32());
+ assert_eq!(42, *cont.rust_i32_mut_mut());
+ *cont.rust_i32_mut_mut() = 55; //should not crash
+ assert_eq!(55, unsafe { *cont.rust_i32_ptr() });
+ //the same with C
+ assert_eq!(45, *cont.c_int());
+ //now static c struct
+
+ assert_eq!(1, cont.c_struct().first);
+ assert_eq!(2, cont.c_struct().second);
+ //let's play with strings
+
+ assert_eq!("Hello!", *cont.rust_str());
+ let converted = cont.c_const_str().to_str().unwrap();
+ assert_eq!(converted, "Hi!");
+}
diff --git a/rust_crates/registry/src/github.com-1ecc6299db9ec823/dlopen_derive-0.1.4/.cargo-ok b/rust_crates/registry/src/github.com-1ecc6299db9ec823/dlopen_derive-0.1.4/.cargo-ok
new file mode 100644
index 0000000000..b5754e2037
--- /dev/null
+++ b/rust_crates/registry/src/github.com-1ecc6299db9ec823/dlopen_derive-0.1.4/.cargo-ok
@@ -0,0 +1 @@
+ok
\ No newline at end of file
diff --git a/rust_crates/registry/src/github.com-1ecc6299db9ec823/dlopen_derive-0.1.4/Cargo.toml b/rust_crates/registry/src/github.com-1ecc6299db9ec823/dlopen_derive-0.1.4/Cargo.toml
new file mode 100644
index 0000000000..42470bc2e0
--- /dev/null
+++ b/rust_crates/registry/src/github.com-1ecc6299db9ec823/dlopen_derive-0.1.4/Cargo.toml
@@ -0,0 +1,29 @@
+# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
+#
+# When uploading crates to the registry Cargo will automatically
+# "normalize" Cargo.toml files for maximal compatibility
+# with all versions of Cargo and also rewrite `path` dependencies
+# to registry (e.g., crates.io) dependencies
+#
+# If you believe there's an error in this file please file an
+# issue against the rust-lang/cargo repository. If you're
+# editing this file be aware that the upstream Cargo.toml
+# will likely look very different (and much more reasonable)
+
+[package]
+name = "dlopen_derive"
+version = "0.1.4"
+authors = ["Szymon Wieloch "]
+description = "Derive macros for the dlopen crate."
+license = "MIT"
+
+[lib]
+proc-macro = true
+[dependencies.libc]
+version = "0.2.29"
+
+[dependencies.quote]
+version = "0.6.12"
+
+[dependencies.syn]
+version = "0.15.34"
diff --git a/rust_crates/registry/src/github.com-1ecc6299db9ec823/dlopen_derive-0.1.4/Cargo.toml.orig b/rust_crates/registry/src/github.com-1ecc6299db9ec823/dlopen_derive-0.1.4/Cargo.toml.orig
new file mode 100644
index 0000000000..969ea82047
--- /dev/null
+++ b/rust_crates/registry/src/github.com-1ecc6299db9ec823/dlopen_derive-0.1.4/Cargo.toml.orig
@@ -0,0 +1,15 @@
+[package]
+name = "dlopen_derive"
+version = "0.1.4"
+authors = ["Szymon Wieloch "]
+description = "Derive macros for the dlopen crate."
+license = "MIT"
+
+[lib]
+proc-macro = true
+
+[dependencies]
+syn = "0.15.34"
+quote = "0.6.12"
+libc = "0.2.29"
+
diff --git a/rust_crates/registry/src/github.com-1ecc6299db9ec823/dlopen_derive-0.1.4/src/api.rs b/rust_crates/registry/src/github.com-1ecc6299db9ec823/dlopen_derive-0.1.4/src/api.rs
new file mode 100644
index 0000000000..cb87ef6d94
--- /dev/null
+++ b/rust_crates/registry/src/github.com-1ecc6299db9ec823/dlopen_derive-0.1.4/src/api.rs
@@ -0,0 +1,40 @@
+use syn::{Field, DeriveInput};
+use syn;
+use super::common::{get_fields, symbol_name};
+
+pub fn impl_library_api(ast: &DeriveInput) -> syn::export::TokenStream2 {
+ let name = &ast.ident;
+ let fields = get_fields(ast, "SymBorApi");
+
+ let tok_iter = fields.named.iter().map(field_to_tokens);
+ let q = quote! {
+ impl<'a> SymBorApi<'a> for #name<'a> {
+ unsafe fn load(lib: &'a ::dlopen::symbor::Library) -> ::std::result::Result<#name<'a>,::dlopen::Error> {
+ ::std::result::Result::Ok(#name {
+ #(#tok_iter),*
+ })
+ }
+ }
+ };
+
+ //panic!("{}", q.as_str());
+ q
+}
+
+
+fn field_to_tokens(field: &Field) -> syn::export::TokenStream2 {
+ let field_name = &field.ident;
+ let symbol_name = symbol_name(field);
+
+ //panic!("type_name = {}, {:?}", field_type_name, field);
+
+ quote! {
+ #field_name: {
+ let raw_result = lib.ptr_or_null_cstr::<()>(
+ ::std::ffi::CStr::from_bytes_with_nul_unchecked(concat!(#symbol_name, "\0").as_bytes())
+ );
+ ::dlopen::symbor::FromRawResult::from_raw_result(raw_result)?
+ }
+ }
+
+}
diff --git a/rust_crates/registry/src/github.com-1ecc6299db9ec823/dlopen_derive-0.1.4/src/common.rs b/rust_crates/registry/src/github.com-1ecc6299db9ec823/dlopen_derive-0.1.4/src/common.rs
new file mode 100644
index 0000000000..6963a09e94
--- /dev/null
+++ b/rust_crates/registry/src/github.com-1ecc6299db9ec823/dlopen_derive-0.1.4/src/common.rs
@@ -0,0 +1,54 @@
+use syn::{Field, DeriveInput, Data, Lit, Meta, Fields, FieldsNamed};
+
+pub fn symbol_name(field: &Field) -> String {
+ match find_str_attr_val(field, "dlopen_name") {
+ Some(val) => val,
+ None => //not found, so use field name
+ match field.ident {
+ Some(ref val) => val.to_string(),
+ None => panic!("All structure fields need to be identifiable")
+ }
+ }
+}
+
+pub fn find_str_attr_val<'a>(field: &'a Field, attr_name: &str) -> Option {
+ for attr in field.attrs.iter() {
+ match attr.parse_meta() {
+ Ok(Meta::NameValue(ref meta)) => {
+ if meta.ident == attr_name {
+ return match &meta.lit {
+ &Lit::Str(ref val, ..) => {
+ Some(val.value())
+ },
+ _ => panic!("{} attribute must be a string", attr_name)
+ }
+ }
+ },
+ _ => continue
+ }
+ }
+ None
+}
+
+pub fn has_marker_attr(field :&Field, attr_name: &str) -> bool {
+ for attr in field.attrs.iter() {
+ match attr.parse_meta() {
+ Ok(Meta::Word(ref val)) => if val == attr_name{
+ return true;
+ },
+ _ => continue
+ }
+ }
+ false
+}
+
+pub fn get_fields<'a>(ast: &'a DeriveInput, trait_name: &str) -> &'a FieldsNamed {
+ let vd = match ast.data {
+ Data::Enum(_) | Data::Union(_) => panic ! ("{} can be only implemented for structures", trait_name),
+ Data::Struct( ref val) => val
+ };
+ match &vd.fields {
+ & Fields::Named( ref f) => f,
+ & Fields::Unnamed(_) | &Fields::Unit => panic ! ("{} can be only implemented for structures", trait_name)
+ }
+}
\ No newline at end of file
diff --git a/rust_crates/registry/src/github.com-1ecc6299db9ec823/dlopen_derive-0.1.4/src/lib.rs b/rust_crates/registry/src/github.com-1ecc6299db9ec823/dlopen_derive-0.1.4/src/lib.rs
new file mode 100644
index 0000000000..f5233a3b66
--- /dev/null
+++ b/rust_crates/registry/src/github.com-1ecc6299db9ec823/dlopen_derive-0.1.4/src/lib.rs
@@ -0,0 +1,56 @@
+#![recursion_limit="128"]
+
+extern crate proc_macro;
+#[macro_use]
+extern crate syn;
+#[macro_use]
+extern crate quote;
+
+mod api;
+mod multi_api;
+mod wrapper;
+mod common;
+
+
+
+use proc_macro::TokenStream;
+use api::impl_library_api;
+use wrapper::impl_wrapper_api;
+use multi_api::impl_wrapper_multi_api;
+use syn::{DeriveInput};
+
+#[proc_macro_derive(WrapperApi, attributes(dlopen_name, dlopen_allow_null))]
+pub fn wrapper_api(input: TokenStream) -> TokenStream {
+ // Parse the string representation
+ let ast = parse_macro_input!(input as DeriveInput);
+
+ // Build the impl
+ let gen = impl_wrapper_api(&ast);
+
+ // Return the generated impl
+ TokenStream::from(gen)
+}
+
+#[proc_macro_derive(WrapperMultiApi)]
+pub fn wrapper_multi_api(input: TokenStream) -> TokenStream {
+ // Parse the string representation
+ let ast = parse_macro_input!(input as DeriveInput);
+
+ // Build the impl
+ let gen = impl_wrapper_multi_api(&ast);
+
+ // Return the generated impl
+ TokenStream::from(gen)
+}
+
+#[proc_macro_derive(SymBorApi, attributes(dlopen_name))]
+pub fn library_api(input: TokenStream) -> TokenStream {
+ // Parse the string representation
+ let ast = parse_macro_input!(input as DeriveInput);
+
+ // Build the impl
+ let gen = impl_library_api(&ast);
+
+ // Return the generated impl
+ TokenStream::from(gen)
+}
diff --git a/rust_crates/registry/src/github.com-1ecc6299db9ec823/dlopen_derive-0.1.4/src/multi_api.rs b/rust_crates/registry/src/github.com-1ecc6299db9ec823/dlopen_derive-0.1.4/src/multi_api.rs
new file mode 100644
index 0000000000..d7f97c8aa5
--- /dev/null
+++ b/rust_crates/registry/src/github.com-1ecc6299db9ec823/dlopen_derive-0.1.4/src/multi_api.rs
@@ -0,0 +1,40 @@
+use syn::{Field, DeriveInput};
+use syn;
+use super::common::{get_fields};
+
+const TRATIT_NAME: &str = "WrapperMultiApi";
+
+pub fn impl_wrapper_multi_api(ast: &DeriveInput) -> syn::export::TokenStream2 {
+ let name = &ast.ident;
+ let generics = &ast.generics;
+ let fields = get_fields(ast, TRATIT_NAME);
+
+ let tok_iter = fields.named.iter().map(field_to_tokens);
+ let q = quote! {
+ impl #generics WrapperMultiApi for #name #generics{}
+
+ impl #generics ::dlopen::wrapper::WrapperApi for # name #generics{
+ unsafe fn load(lib: & ::dlopen::raw::Library) -> ::std::result::Result {
+ ::std::result::Result::Ok(#name {
+ #(#tok_iter),*
+ })
+ }
+
+ }
+ };
+
+ //panic!("{}", q.as_str());
+ q
+}
+
+
+fn field_to_tokens(field: &Field) -> syn::export::TokenStream2 {
+ let field_name = &field.ident;
+
+ //panic!("type_name = {}, {:?}", field_type_name, field);
+
+ quote! {
+ #field_name: ::dlopen::wrapper::WrapperApi::load(&lib)?
+ }
+
+}
\ No newline at end of file
diff --git a/rust_crates/registry/src/github.com-1ecc6299db9ec823/dlopen_derive-0.1.4/src/wrapper.rs b/rust_crates/registry/src/github.com-1ecc6299db9ec823/dlopen_derive-0.1.4/src/wrapper.rs
new file mode 100644
index 0000000000..bf58c51398
--- /dev/null
+++ b/rust_crates/registry/src/github.com-1ecc6299db9ec823/dlopen_derive-0.1.4/src/wrapper.rs
@@ -0,0 +1,154 @@
+use syn::{Field, Type, DeriveInput, Visibility, BareFnArg, TypePtr};
+use syn;
+use super::common::{get_fields, symbol_name, has_marker_attr};
+const ALLOW_NULL: &str = "dlopen_allow_null";
+const TRAIT_NAME: &str = "WrapperApi";
+
+pub fn impl_wrapper_api(ast: &DeriveInput) -> syn::export::TokenStream2 {
+ let struct_name = &ast.ident;
+ let fields = get_fields(ast, TRAIT_NAME);
+ let generics = &ast.generics;
+ //make sure that all fields are private - panic otherwise
+ //make sure that all fields are identifiable - panic otherwise
+ for field in fields.named.iter(){
+ let _ = field.ident.as_ref().expect("All fields of structures deriving WrapperAPI need to be identificable");
+ match field.vis {
+ Visibility::Inherited => (),
+ _ => panic!("All fields of structures deriving {} need to be private and '{}' is not",
+ TRAIT_NAME, field.ident.as_ref().unwrap())
+ }
+ }
+
+ let field_iter = fields.named.iter().map(field_to_tokens);
+ let wrapper_iter = fields.named.iter().filter_map(field_to_wrapper);
+ let q = quote! {
+ impl #generics WrapperApi for #struct_name #generics {
+ unsafe fn load(lib: & ::dlopen::raw::Library ) -> ::std::result::Result {
+ Ok(Self{
+ #(#field_iter),*
+ })
+ }
+ }
+
+ #[allow(dead_code)]
+ impl #generics #struct_name #generics {
+ #(#wrapper_iter)*
+ }
+ };
+
+ //panic!("{}", q.as_str());
+ q
+}
+
+fn field_to_tokens(field: &Field) -> syn::export::TokenStream2 {
+ let allow_null = has_marker_attr(field, ALLOW_NULL);
+ match field.ty {
+ Type::BareFn(_) | Type::Reference(_) => {
+ if allow_null {
+ panic!("Only pointers can have the '{}' attribute assigned", ALLOW_NULL);
+ }
+ normal_field(field)
+ },
+ Type::Ptr(ref ptr) => if allow_null {
+ allow_null_field(field, ptr)
+ } else {
+ normal_field(field)
+ },
+ _ => panic!("Only bare functions, references an pointers are allowed in structures implementing WrapperApi trait")
+ }
+}
+
+
+fn normal_field(field: &Field) -> syn::export::TokenStream2 {
+ let field_name = &field.ident;
+ let symbol_name = symbol_name(field);
+ quote! {
+ #field_name : lib.symbol_cstr(
+ ::std::ffi::CStr::from_bytes_with_nul_unchecked(concat!(#symbol_name, "\0").as_bytes())
+ )?
+ }
+}
+
+
+fn allow_null_field(field: &Field, ptr: &TypePtr) -> syn::export::TokenStream2 {
+ let field_name = &field.ident;
+ let symbol_name = symbol_name(field);
+ let null_fun = match ptr.mutability {
+ Some(_) => quote!{null},
+ None => quote!{null_mut}
+ };
+ quote! {
+ #field_name : match lib.symbol_cstr(
+ ::std::ffi::CStr::from_bytes_with_nul_unchecked(concat!(#symbol_name, "\0").as_bytes())
+ ) {
+ ::std::result::Result::Ok(val) => val,
+ ::std::result::Result::Err(err) => match err {
+ ::dlopen::Error::NullSymbol => ::std::ptr:: #null_fun (),
+ _ => return ::std::result::Result::Err(err)
+ }
+ }
+ }
+}
+
+fn field_to_wrapper(field: &Field) -> Option {
+ let ident = &field.ident;
+ match &field.ty {
+ &Type::BareFn(ref fun) => {
+ if fun.variadic.is_some() {
+ None
+ } else {
+ let output = &fun.output;
+ let unsafety = &fun.unsafety;
+ let arg_iter = fun.inputs.iter().map(|a| fun_arg_to_tokens(a, &ident.as_ref().unwrap().to_string()));
+ let arg_names = fun.inputs.iter().map(|a| match a.name {
+ ::std::option::Option::Some((ref arg_name, _)) => arg_name,
+ ::std::option::Option::None => panic!("This should never happen")
+ });
+ Some(quote! {
+ pub #unsafety fn #ident (&self, #(#arg_iter),* ) #output {
+ (self.#ident)(#(#arg_names),*)
+ }
+ })
+ }
+ },
+ &Type::Reference(ref ref_ty) => {
+ let ty = &ref_ty.elem;
+ let mut_acc = match ref_ty.mutability {
+ Some(_token) => {
+ let mut_ident = &format!("{}_mut", ident.as_ref().unwrap().to_string());
+ let method_name = syn::Ident::new(&mut_ident, ident.as_ref().unwrap().span());
+ Some(quote!{
+ pub fn #method_name (&mut self) -> &mut #ty {
+ self.#ident
+ }
+ })
+ },
+ None => None,
+ };
+ //constant accessor
+ let const_acc = quote! {
+ pub fn #ident (&self) -> & #ty {
+ self.#ident
+ }
+ };
+
+ Some(quote! {
+ #const_acc
+ #mut_acc
+ })
+ },
+ &Type::Ptr(_) => None,
+ _ => panic!("Unknown field type, this should not happen!")
+ }
+}
+
+fn fun_arg_to_tokens(arg: &BareFnArg, function_name: &str) -> syn::export::TokenStream2 {
+ let arg_name = match arg.name {
+ Some(ref val) => &val.0,
+ None => panic!("Function {} has an unnamed argument.", function_name)
+ };
+ let ty = &arg.ty;
+ quote!{
+ #arg_name: #ty
+ }
+}
\ No newline at end of file