Fix vendored files.

This commit is contained in:
Adam Ierymenko 2022-06-08 12:16:09 -04:00
parent d5ca4e5f52
commit ef36acb970
No known key found for this signature in database
GPG Key ID: C8877CF2D7A5D7F3
20 changed files with 2248 additions and 178 deletions

2
.gitignore vendored
View File

@ -107,7 +107,6 @@ windows/ZeroTierOne/Debug/
*.swp
*~.nib
DerivedData/
build/
*.pbxuser
*.mode1v3
*.mode2v3
@ -118,7 +117,6 @@ build/
!default.perspectivev3
*.xccheckout
xcuserdata/
ext/librethinkdbxx/build
.vscode
__pycache__
*~

4
zeroidc/Cargo.lock generated
View File

@ -1143,9 +1143,9 @@ checksum = "360dfd1d6d30e05fda32ace2c8c70e9c0a9da713275777f5a4dbb8a1893930c6"
[[package]]
name = "tracing"
version = "0.1.34"
version = "0.1.35"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5d0ecdcb44a79f0fe9844f0c4f33a342cbcbb5117de8001e6ba0dc2351327d09"
checksum = "a400e31aa60b9d44a52a8ee0343b5b18566b03a8321e0d321f695cf56e940160"
dependencies = [
"cfg-if",
"pin-project-lite",

View File

@ -0,0 +1,88 @@
pub fn get(openssl_version: Option<u64>, libressl_version: Option<u64>) -> Vec<&'static str> {
let mut cfgs = vec![];
if let Some(libressl_version) = libressl_version {
cfgs.push("libressl");
if libressl_version >= 0x2_05_01_00_0 {
cfgs.push("libressl251");
}
if libressl_version >= 0x2_05_02_00_0 {
cfgs.push("libressl252");
}
if libressl_version >= 0x2_06_01_00_0 {
cfgs.push("libressl261");
}
if libressl_version >= 0x2_07_00_00_0 {
cfgs.push("libressl270");
}
if libressl_version >= 0x2_07_01_00_0 {
cfgs.push("libressl271");
}
if libressl_version >= 0x2_07_03_00_0 {
cfgs.push("libressl273");
}
if libressl_version >= 0x2_08_00_00_0 {
cfgs.push("libressl280");
}
if libressl_version >= 0x2_08_01_00_0 {
cfgs.push("libressl281");
}
if libressl_version >= 0x2_09_01_00_0 {
cfgs.push("libressl291");
}
if libressl_version >= 0x3_02_01_00_0 {
cfgs.push("libressl321");
}
if libressl_version >= 0x3_03_02_00_0 {
cfgs.push("libressl332");
}
if libressl_version >= 0x3_04_00_00_0 {
cfgs.push("libressl340");
}
if libressl_version >= 0x3_05_00_00_0 {
cfgs.push("libressl350");
}
} else {
let openssl_version = openssl_version.unwrap();
if openssl_version >= 0x3_00_00_00_0 {
cfgs.push("ossl300");
}
if openssl_version >= 0x1_00_01_00_0 {
cfgs.push("ossl101");
}
if openssl_version >= 0x1_00_02_00_0 {
cfgs.push("ossl102");
}
if openssl_version >= 0x1_00_02_06_0 {
cfgs.push("ossl102f");
}
if openssl_version >= 0x1_00_02_08_0 {
cfgs.push("ossl102h");
}
if openssl_version >= 0x1_01_00_00_0 {
cfgs.push("ossl110");
}
if openssl_version >= 0x1_01_00_06_0 {
cfgs.push("ossl110f");
}
if openssl_version >= 0x1_01_00_07_0 {
cfgs.push("ossl110g");
}
if openssl_version >= 0x1_01_00_08_0 {
cfgs.push("ossl110h");
}
if openssl_version >= 0x1_01_01_00_0 {
cfgs.push("ossl111");
}
if openssl_version >= 0x1_01_01_02_0 {
cfgs.push("ossl111b");
}
if openssl_version >= 0x1_01_01_03_0 {
cfgs.push("ossl111c");
}
}
cfgs
}

View File

@ -0,0 +1,104 @@
#include <openssl/opensslv.h>
#include <openssl/opensslconf.h>
#define VERSION2(n, v) RUST_VERSION_##n##_##v
#define VERSION(n, v) VERSION2(n, v)
#define NEW_VERSION2(a, b, c) RUST_VERSION_NEW_OPENSSL_##a##_##b##_##c
#define NEW_VERSION(a, b, c) NEW_VERSION2(a, b, c)
#ifdef LIBRESSL_VERSION_NUMBER
VERSION(LIBRESSL, LIBRESSL_VERSION_NUMBER)
#elif defined OPENSSL_VERSION_MAJOR
NEW_VERSION(OPENSSL_VERSION_MAJOR, OPENSSL_VERSION_MINOR, OPENSSL_VERSION_PATCH)
#else
VERSION(OPENSSL, OPENSSL_VERSION_NUMBER)
#endif
#ifdef OPENSSL_NO_BF
RUST_CONF_OPENSSL_NO_BF
#endif
#ifdef OPENSSL_NO_BUF_FREELISTS
RUST_CONF_OPENSSL_NO_BUF_FREELISTS
#endif
#ifdef OPENSSL_NO_CHACHA
RUST_CONF_OPENSSL_NO_CHACHA
#endif
#ifdef OPENSSL_NO_CMS
RUST_CONF_OPENSSL_NO_CMS
#endif
#ifdef OPENSSL_NO_COMP
RUST_CONF_OPENSSL_NO_COMP
#endif
#ifdef OPENSSL_NO_EC
RUST_CONF_OPENSSL_NO_EC
#endif
#ifdef OPENSSL_NO_EC2M
RUST_CONF_OPENSSL_NO_EC2M
#endif
#ifdef OPENSSL_NO_ENGINE
RUST_CONF_OPENSSL_NO_ENGINE
#endif
#ifdef OPENSSL_NO_KRB5
RUST_CONF_OPENSSL_NO_KRB5
#endif
#ifdef OPENSSL_NO_NEXTPROTONEG
RUST_CONF_OPENSSL_NO_NEXTPROTONEG
#endif
#ifdef OPENSSL_NO_OCSP
RUST_CONF_OPENSSL_NO_OCSP
#endif
#ifdef OPENSSL_NO_PSK
RUST_CONF_OPENSSL_NO_PSK
#endif
#ifdef OPENSSL_NO_RFC3779
RUST_CONF_OPENSSL_NO_RFC3779
#endif
#ifdef OPENSSL_NO_RMD160
RUST_CONF_OPENSSL_NO_RMD160
#endif
#ifdef OPENSSL_NO_SHA
RUST_CONF_OPENSSL_NO_SHA
#endif
#ifdef OPENSSL_NO_SRP
RUST_CONF_OPENSSL_NO_SRP
#endif
#ifdef OPENSSL_NO_SSL3_METHOD
RUST_CONF_OPENSSL_NO_SSL3_METHOD
#endif
#ifdef OPENSSL_NO_TLSEXT
RUST_CONF_OPENSSL_NO_TLSEXT
#endif
#ifdef OPENSSL_NO_STDIO
RUST_CONF_OPENSSL_NO_STDIO
#endif
#ifdef OPENSSL_NO_SM3
RUST_CONF_OPENSSL_NO_SM3
#endif
#ifdef OPENSSL_NO_DEPRECATED_3_0
RUST_CONF_OPENSSL_NO_DEPRECATED_3_0
#endif
#ifdef OPENSSL_NO_SEED
RUST_CONF_OPENSSL_NO_SEED
#endif

View File

@ -0,0 +1,276 @@
use pkg_config;
use std::ffi::OsString;
use std::path::{Path, PathBuf};
use std::process::{self, Command};
use super::env;
pub fn get_openssl(target: &str) -> (Vec<PathBuf>, PathBuf) {
let lib_dir = env("OPENSSL_LIB_DIR").map(PathBuf::from);
let include_dir = env("OPENSSL_INCLUDE_DIR").map(PathBuf::from);
match (lib_dir, include_dir) {
(Some(lib_dir), Some(include_dir)) => (vec![lib_dir], include_dir),
(lib_dir, include_dir) => {
let openssl_dir = env("OPENSSL_DIR").unwrap_or_else(|| find_openssl_dir(target));
let openssl_dir = Path::new(&openssl_dir);
let lib_dir = lib_dir.map(|d| vec![d]).unwrap_or_else(|| {
let mut lib_dirs = vec![];
// OpenSSL 3.0 now puts it's libraries in lib64/ by default,
// check for both it and lib/.
if openssl_dir.join("lib64").exists() {
lib_dirs.push(openssl_dir.join("lib64"));
}
if openssl_dir.join("lib").exists() {
lib_dirs.push(openssl_dir.join("lib"));
}
lib_dirs
});
let include_dir = include_dir.unwrap_or_else(|| openssl_dir.join("include"));
(lib_dir, include_dir)
}
}
}
fn resolve_with_wellknown_homebrew_location(dir: &str) -> Option<PathBuf> {
let versions = ["openssl@3", "openssl@1.1"];
// Check up default aarch 64 Homebrew installation location first
// for quick resolution if possible.
// `pkg-config` on brew doesn't necessarily contain settings for openssl apparently.
for version in &versions {
let homebrew = Path::new(dir).join(format!("opt/{}", version));
if homebrew.exists() {
return Some(homebrew);
}
}
for version in &versions {
// Calling `brew --prefix <package>` command usually slow and
// takes seconds, and will be used only as a last resort.
let output = execute_command_and_get_output("brew", &["--prefix", version]);
if let Some(ref output) = output {
let homebrew = Path::new(&output);
if homebrew.exists() {
return Some(homebrew.to_path_buf());
}
}
}
None
}
fn resolve_with_wellknown_location(dir: &str) -> Option<PathBuf> {
let root_dir = Path::new(dir);
let include_openssl = root_dir.join("include/openssl");
if include_openssl.exists() {
Some(root_dir.to_path_buf())
} else {
None
}
}
fn find_openssl_dir(target: &str) -> OsString {
let host = env::var("HOST").unwrap();
if host == target && target.ends_with("-apple-darwin") {
let homebrew_dir = match target {
"aarch64-apple-darwin" => "/opt/homebrew",
_ => "/usr/local",
};
if let Some(dir) = resolve_with_wellknown_homebrew_location(homebrew_dir) {
return dir.into();
} else if let Some(dir) = resolve_with_wellknown_location("/opt/pkg") {
// pkgsrc
return dir.into();
} else if let Some(dir) = resolve_with_wellknown_location("/opt/local") {
// MacPorts
return dir.into();
}
}
try_pkg_config();
try_vcpkg();
// FreeBSD ships with OpenSSL but doesn't include a pkg-config file :(
if host == target && target.contains("freebsd") {
return OsString::from("/usr");
}
// DragonFly has libressl (or openssl) in ports, but this doesn't include a pkg-config file
if host == target && target.contains("dragonfly") {
return OsString::from("/usr/local");
}
let mut msg = format!(
"
Could not find directory of OpenSSL installation, and this `-sys` crate cannot
proceed without this knowledge. If OpenSSL is installed and this crate had
trouble finding it, you can set the `OPENSSL_DIR` environment variable for the
compilation process.
Make sure you also have the development packages of openssl installed.
For example, `libssl-dev` on Ubuntu or `openssl-devel` on Fedora.
If you're in a situation where you think the directory *should* be found
automatically, please open a bug at https://github.com/sfackler/rust-openssl
and include information about your system as well as this message.
$HOST = {}
$TARGET = {}
openssl-sys = {}
",
host,
target,
env!("CARGO_PKG_VERSION")
);
if host.contains("apple-darwin") && target.contains("apple-darwin") {
let system = Path::new("/usr/lib/libssl.0.9.8.dylib");
if system.exists() {
msg.push_str(
"
openssl-sys crate build failed: no supported version of OpenSSL found.
Ways to fix it:
- Use the `vendored` feature of openssl-sys crate to build OpenSSL from source.
- Use Homebrew to install the `openssl` package.
",
);
}
}
if host.contains("unknown-linux")
&& target.contains("unknown-linux-gnu")
&& Command::new("pkg-config").output().is_err()
{
msg.push_str(
"
It looks like you're compiling on Linux and also targeting Linux. Currently this
requires the `pkg-config` utility to find OpenSSL but unfortunately `pkg-config`
could not be found. If you have OpenSSL installed you can likely fix this by
installing `pkg-config`.
",
);
}
if host.contains("windows") && target.contains("windows-gnu") {
msg.push_str(
"
It looks like you're compiling for MinGW but you may not have either OpenSSL or
pkg-config installed. You can install these two dependencies with:
pacman -S openssl-devel pkg-config
and try building this crate again.
",
);
}
if host.contains("windows") && target.contains("windows-msvc") {
msg.push_str(
"
It looks like you're compiling for MSVC but we couldn't detect an OpenSSL
installation. If there isn't one installed then you can try the rust-openssl
README for more information about how to download precompiled binaries of
OpenSSL:
https://github.com/sfackler/rust-openssl#windows
",
);
}
panic!("{}", msg);
}
/// Attempt to find OpenSSL through pkg-config.
///
/// Note that if this succeeds then the function does not return as pkg-config
/// typically tells us all the information that we need.
fn try_pkg_config() {
let target = env::var("TARGET").unwrap();
let host = env::var("HOST").unwrap();
// If we're going to windows-gnu we can use pkg-config, but only so long as
// we're coming from a windows host.
//
// Otherwise if we're going to windows we probably can't use pkg-config.
if target.contains("windows-gnu") && host.contains("windows") {
env::set_var("PKG_CONFIG_ALLOW_CROSS", "1");
} else if target.contains("windows") {
return;
}
let lib = match pkg_config::Config::new()
.print_system_libs(false)
.find("openssl")
{
Ok(lib) => lib,
Err(e) => {
println!("run pkg_config fail: {:?}", e);
return;
}
};
super::postprocess(&lib.include_paths);
for include in lib.include_paths.iter() {
println!("cargo:include={}", include.display());
}
process::exit(0);
}
/// Attempt to find OpenSSL through vcpkg.
///
/// Note that if this succeeds then the function does not return as vcpkg
/// should emit all of the cargo metadata that we need.
#[cfg(target_env = "msvc")]
fn try_vcpkg() {
// vcpkg will not emit any metadata if it can not find libraries
// appropriate for the target triple with the desired linkage.
let lib = match vcpkg::Config::new()
.emit_includes(true)
.find_package("openssl")
{
Ok(lib) => lib,
Err(e) => {
println!("note: vcpkg did not find openssl: {}", e);
return;
}
};
super::postprocess(&lib.include_paths);
println!("cargo:rustc-link-lib=user32");
println!("cargo:rustc-link-lib=gdi32");
println!("cargo:rustc-link-lib=crypt32");
process::exit(0);
}
#[cfg(not(target_env = "msvc"))]
fn try_vcpkg() {}
fn execute_command_and_get_output(cmd: &str, args: &[&str]) -> Option<String> {
let out = Command::new(cmd).args(args).output();
if let Ok(ref r1) = out {
if r1.status.success() {
let r2 = String::from_utf8(r1.stdout.clone());
if let Ok(r3) = r2 {
return Some(r3.trim().to_string());
}
}
}
None
}

View File

@ -0,0 +1,16 @@
use openssl_src;
use std::path::PathBuf;
pub fn get_openssl(_target: &str) -> (Vec<PathBuf>, PathBuf) {
let artifacts = openssl_src::Build::new().build();
println!("cargo:vendored=1");
println!(
"cargo:root={}",
artifacts.lib_dir().parent().unwrap().display()
);
(
vec![artifacts.lib_dir().to_path_buf()],
artifacts.include_dir().to_path_buf(),
)
}

399
zeroidc/vendor/openssl-sys/build/main.rs vendored Normal file
View File

@ -0,0 +1,399 @@
#![allow(clippy::inconsistent_digit_grouping, clippy::unusual_byte_groupings)]
extern crate autocfg;
#[cfg(feature = "bindgen")]
extern crate bindgen;
extern crate cc;
#[cfg(feature = "vendored")]
extern crate openssl_src;
extern crate pkg_config;
#[cfg(target_env = "msvc")]
extern crate vcpkg;
use std::collections::HashSet;
use std::env;
use std::ffi::OsString;
use std::path::{Path, PathBuf};
mod cfgs;
mod find_normal;
#[cfg(feature = "vendored")]
mod find_vendored;
#[cfg(feature = "bindgen")]
mod run_bindgen;
#[derive(PartialEq)]
enum Version {
Openssl3xx,
Openssl11x,
Openssl10x,
Libressl,
}
fn env_inner(name: &str) -> Option<OsString> {
let var = env::var_os(name);
println!("cargo:rerun-if-env-changed={}", name);
match var {
Some(ref v) => println!("{} = {}", name, v.to_string_lossy()),
None => println!("{} unset", name),
}
var
}
fn env(name: &str) -> Option<OsString> {
let prefix = env::var("TARGET").unwrap().to_uppercase().replace('-', "_");
let prefixed = format!("{}_{}", prefix, name);
env_inner(&prefixed).or_else(|| env_inner(name))
}
fn find_openssl(target: &str) -> (Vec<PathBuf>, PathBuf) {
#[cfg(feature = "vendored")]
{
// vendor if the feature is present, unless
// OPENSSL_NO_VENDOR exists and isn't `0`
if env("OPENSSL_NO_VENDOR").map_or(true, |s| s == "0") {
return find_vendored::get_openssl(target);
}
}
find_normal::get_openssl(target)
}
fn main() {
check_rustc_versions();
let target = env::var("TARGET").unwrap();
let (lib_dirs, include_dir) = find_openssl(&target);
if !lib_dirs.iter().all(|p| Path::new(p).exists()) {
panic!("OpenSSL library directory does not exist: {:?}", lib_dirs);
}
if !Path::new(&include_dir).exists() {
panic!(
"OpenSSL include directory does not exist: {}",
include_dir.to_string_lossy()
);
}
for lib_dir in lib_dirs.iter() {
println!(
"cargo:rustc-link-search=native={}",
lib_dir.to_string_lossy()
);
}
println!("cargo:include={}", include_dir.to_string_lossy());
let version = postprocess(&[include_dir]);
let libs_env = env("OPENSSL_LIBS");
let libs = match libs_env.as_ref().and_then(|s| s.to_str()) {
Some(v) => {
if v.is_empty() {
vec![]
} else {
v.split(':').collect()
}
}
None => match version {
Version::Openssl10x if target.contains("windows") => vec!["ssleay32", "libeay32"],
Version::Openssl3xx | Version::Openssl11x if target.contains("windows-msvc") => {
vec!["libssl", "libcrypto"]
}
_ => vec!["ssl", "crypto"],
},
};
let kind = determine_mode(&lib_dirs, &libs);
for lib in libs.into_iter() {
println!("cargo:rustc-link-lib={}={}", kind, lib);
}
// https://github.com/openssl/openssl/pull/15086
if version == Version::Openssl3xx
&& kind == "static"
&& (env::var("CARGO_CFG_TARGET_OS").unwrap() == "linux"
|| env::var("CARGO_CFG_TARGET_OS").unwrap() == "android")
&& env::var("CARGO_CFG_TARGET_POINTER_WIDTH").unwrap() == "32"
{
println!("cargo:rustc-link-lib=dylib=atomic");
}
if kind == "static" && target.contains("windows") {
println!("cargo:rustc-link-lib=dylib=gdi32");
println!("cargo:rustc-link-lib=dylib=user32");
println!("cargo:rustc-link-lib=dylib=crypt32");
println!("cargo:rustc-link-lib=dylib=ws2_32");
println!("cargo:rustc-link-lib=dylib=advapi32");
}
}
fn check_rustc_versions() {
let cfg = autocfg::new();
if cfg.probe_rustc_version(1, 31) {
println!("cargo:rustc-cfg=const_fn");
}
}
#[allow(clippy::let_and_return)]
fn postprocess(include_dirs: &[PathBuf]) -> Version {
let version = validate_headers(include_dirs);
#[cfg(feature = "bindgen")]
run_bindgen::run(&include_dirs);
version
}
/// Validates the header files found in `include_dir` and then returns the
/// version string of OpenSSL.
#[allow(clippy::manual_strip)] // we need to support pre-1.45.0
fn validate_headers(include_dirs: &[PathBuf]) -> Version {
// This `*-sys` crate only works with OpenSSL 1.0.1, 1.0.2, 1.1.0, 1.1.1 and 3.0.0.
// To correctly expose the right API from this crate, take a look at
// `opensslv.h` to see what version OpenSSL claims to be.
//
// OpenSSL has a number of build-time configuration options which affect
// various structs and such. Since OpenSSL 1.1.0 this isn't really a problem
// as the library is much more FFI-friendly, but 1.0.{1,2} suffer this problem.
//
// To handle all this conditional compilation we slurp up the configuration
// file of OpenSSL, `opensslconf.h`, and then dump out everything it defines
// as our own #[cfg] directives. That way the `ossl10x.rs` bindings can
// account for compile differences and such.
println!("cargo:rerun-if-changed=build/expando.c");
let mut gcc = cc::Build::new();
for include_dir in include_dirs {
gcc.include(include_dir);
}
let expanded = match gcc.file("build/expando.c").try_expand() {
Ok(expanded) => expanded,
Err(e) => {
panic!(
"
Header expansion error:
{:?}
Failed to find OpenSSL development headers.
You can try fixing this setting the `OPENSSL_DIR` environment variable
pointing to your OpenSSL installation or installing OpenSSL headers package
specific to your distribution:
# On Ubuntu
sudo apt-get install libssl-dev
# On Arch Linux
sudo pacman -S openssl
# On Fedora
sudo dnf install openssl-devel
# On Alpine Linux
apk add openssl-dev
See rust-openssl README for more information:
https://github.com/sfackler/rust-openssl#linux
",
e
);
}
};
let expanded = String::from_utf8(expanded).unwrap();
let mut enabled = vec![];
let mut openssl_version = None;
let mut libressl_version = None;
for line in expanded.lines() {
let line = line.trim();
let openssl_prefix = "RUST_VERSION_OPENSSL_";
let new_openssl_prefix = "RUST_VERSION_NEW_OPENSSL_";
let libressl_prefix = "RUST_VERSION_LIBRESSL_";
let conf_prefix = "RUST_CONF_";
if line.starts_with(openssl_prefix) {
let version = &line[openssl_prefix.len()..];
openssl_version = Some(parse_version(version));
} else if line.starts_with(new_openssl_prefix) {
let version = &line[new_openssl_prefix.len()..];
openssl_version = Some(parse_new_version(version));
} else if line.starts_with(libressl_prefix) {
let version = &line[libressl_prefix.len()..];
libressl_version = Some(parse_version(version));
} else if line.starts_with(conf_prefix) {
enabled.push(&line[conf_prefix.len()..]);
}
}
for enabled in &enabled {
println!("cargo:rustc-cfg=osslconf=\"{}\"", enabled);
}
println!("cargo:conf={}", enabled.join(","));
for cfg in cfgs::get(openssl_version, libressl_version) {
println!("cargo:rustc-cfg={}", cfg);
}
if let Some(libressl_version) = libressl_version {
println!("cargo:libressl_version_number={:x}", libressl_version);
let major = (libressl_version >> 28) as u8;
let minor = (libressl_version >> 20) as u8;
let fix = (libressl_version >> 12) as u8;
let (major, minor, fix) = match (major, minor, fix) {
(2, 5, 0) => ('2', '5', '0'),
(2, 5, 1) => ('2', '5', '1'),
(2, 5, 2) => ('2', '5', '2'),
(2, 5, _) => ('2', '5', 'x'),
(2, 6, 0) => ('2', '6', '0'),
(2, 6, 1) => ('2', '6', '1'),
(2, 6, 2) => ('2', '6', '2'),
(2, 6, _) => ('2', '6', 'x'),
(2, 7, _) => ('2', '7', 'x'),
(2, 8, 0) => ('2', '8', '0'),
(2, 8, 1) => ('2', '8', '1'),
(2, 8, _) => ('2', '8', 'x'),
(2, 9, 0) => ('2', '9', '0'),
(2, 9, _) => ('2', '9', 'x'),
(3, 0, 0) => ('3', '0', '0'),
(3, 0, 1) => ('3', '0', '1'),
(3, 0, _) => ('3', '0', 'x'),
(3, 1, 0) => ('3', '1', '0'),
(3, 1, _) => ('3', '1', 'x'),
(3, 2, 0) => ('3', '2', '0'),
(3, 2, 1) => ('3', '2', '1'),
(3, 2, _) => ('3', '2', 'x'),
(3, 3, 0) => ('3', '3', '0'),
(3, 3, 1) => ('3', '3', '1'),
(3, 3, _) => ('3', '3', 'x'),
(3, 4, 0) => ('3', '4', '0'),
(3, 4, _) => ('3', '4', 'x'),
(3, 5, _) => ('3', '5', 'x'),
_ => version_error(),
};
println!("cargo:libressl=true");
println!("cargo:libressl_version={}{}{}", major, minor, fix);
println!("cargo:version=101");
Version::Libressl
} else {
let openssl_version = openssl_version.unwrap();
println!("cargo:version_number={:x}", openssl_version);
if openssl_version >= 0x4_00_00_00_0 {
version_error()
} else if openssl_version >= 0x3_00_00_00_0 {
Version::Openssl3xx
} else if openssl_version >= 0x1_01_01_00_0 {
println!("cargo:version=111");
Version::Openssl11x
} else if openssl_version >= 0x1_01_00_06_0 {
println!("cargo:version=110");
println!("cargo:patch=f");
Version::Openssl11x
} else if openssl_version >= 0x1_01_00_00_0 {
println!("cargo:version=110");
Version::Openssl11x
} else if openssl_version >= 0x1_00_02_00_0 {
println!("cargo:version=102");
Version::Openssl10x
} else if openssl_version >= 0x1_00_01_00_0 {
println!("cargo:version=101");
Version::Openssl10x
} else {
version_error()
}
}
}
fn version_error() -> ! {
panic!(
"
This crate is only compatible with OpenSSL (version 1.0.1 through 1.1.1, or 3.0.0), or LibreSSL 2.5
through 3.5, but a different version of OpenSSL was found. The build is now aborting
due to this version mismatch.
"
);
}
// parses a string that looks like "0x100020cfL"
#[allow(deprecated)] // trim_right_matches is now trim_end_matches
#[allow(clippy::match_like_matches_macro)] // matches macro requires rust 1.42.0
fn parse_version(version: &str) -> u64 {
// cut off the 0x prefix
assert!(version.starts_with("0x"));
let version = &version[2..];
// and the type specifier suffix
let version = version.trim_right_matches(|c: char| match c {
'0'..='9' | 'a'..='f' | 'A'..='F' => false,
_ => true,
});
u64::from_str_radix(version, 16).unwrap()
}
// parses a string that looks like 3_0_0
fn parse_new_version(version: &str) -> u64 {
println!("version: {}", version);
let mut it = version.split('_');
let major = it.next().unwrap().parse::<u64>().unwrap();
let minor = it.next().unwrap().parse::<u64>().unwrap();
let patch = it.next().unwrap().parse::<u64>().unwrap();
(major << 28) | (minor << 20) | (patch << 4)
}
/// Given a libdir for OpenSSL (where artifacts are located) as well as the name
/// of the libraries we're linking to, figure out whether we should link them
/// statically or dynamically.
fn determine_mode(libdirs: &[PathBuf], libs: &[&str]) -> &'static str {
// First see if a mode was explicitly requested
let kind = env("OPENSSL_STATIC");
match kind.as_ref().and_then(|s| s.to_str()) {
Some("0") => return "dylib",
Some(_) => return "static",
None => {}
}
// Next, see what files we actually have to link against, and see what our
// possibilities even are.
let mut files = HashSet::new();
for dir in libdirs {
for path in dir
.read_dir()
.unwrap()
.map(|e| e.unwrap())
.map(|e| e.file_name())
.filter_map(|e| e.into_string().ok())
{
files.insert(path);
}
}
let can_static = libs
.iter()
.all(|l| files.contains(&format!("lib{}.a", l)) || files.contains(&format!("{}.lib", l)));
let can_dylib = libs.iter().all(|l| {
files.contains(&format!("lib{}.so", l))
|| files.contains(&format!("{}.dll", l))
|| files.contains(&format!("lib{}.dylib", l))
});
match (can_static, can_dylib) {
(true, false) => return "static",
(false, true) => return "dylib",
(false, false) => {
panic!(
"OpenSSL libdir at `{:?}` does not contain the required files \
to either statically or dynamically link OpenSSL",
libdirs
);
}
(true, true) => {}
}
// Ok, we've got not explicit preference and can *either* link statically or
// link dynamically. In the interest of "security upgrades" and/or "best
// practices with security libs", let's link dynamically.
"dylib"
}

View File

@ -0,0 +1,129 @@
use bindgen::callbacks::{MacroParsingBehavior, ParseCallbacks};
use bindgen::RustTarget;
use std::env;
use std::path::PathBuf;
const INCLUDES: &str = "
#include <openssl/aes.h>
#include <openssl/asn1.h>
#include <openssl/bio.h>
#include <openssl/comp.h>
#include <openssl/conf.h>
#include <openssl/crypto.h>
#include <openssl/dh.h>
#include <openssl/dsa.h>
#include <openssl/ec.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/hmac.h>
#include <openssl/objects.h>
#include <openssl/ocsp.h>
#include <openssl/opensslv.h>
#include <openssl/pem.h>
#include <openssl/pkcs12.h>
#include <openssl/pkcs7.h>
#include <openssl/rand.h>
#include <openssl/rsa.h>
#include <openssl/safestack.h>
#include <openssl/sha.h>
#include <openssl/ssl.h>
#include <openssl/stack.h>
#include <openssl/x509.h>
#include <openssl/x509_vfy.h>
#include <openssl/x509v3.h>
// this must be included after ssl.h for libressl!
#include <openssl/srtp.h>
#if !defined(LIBRESSL_VERSION_NUMBER)
#include <openssl/cms.h>
#endif
#if !defined(LIBRESSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10100000
#include <openssl/kdf.h>
#endif
#if OPENSSL_VERSION_NUMBER >= 0x30000000
#include <openssl/provider.h>
#endif
";
pub fn run(include_dirs: &[PathBuf]) {
let out_dir = PathBuf::from(env::var_os("OUT_DIR").unwrap());
let mut builder = bindgen::builder()
.parse_callbacks(Box::new(OpensslCallbacks))
.rust_target(RustTarget::Stable_1_47)
.ctypes_prefix("::libc")
.raw_line("use libc::*;")
.raw_line("type evp_pkey_st = EVP_PKEY;")
.allowlist_file(".*/openssl/[^/]+\\.h")
.allowlist_recursively(false)
// libc is missing pthread_once_t on macOS
.blocklist_type("CRYPTO_ONCE")
.blocklist_function("CRYPTO_THREAD_run_once")
// we don't want to mess with va_list
.blocklist_function("BIO_vprintf")
.blocklist_function("BIO_vsnprintf")
.blocklist_function("ERR_vset_error")
.blocklist_function("ERR_add_error_vdata")
.blocklist_function("EVP_KDF_vctrl")
.blocklist_type("OSSL_FUNC_core_vset_error_fn")
.blocklist_type("OSSL_FUNC_BIO_vprintf_fn")
.blocklist_type("OSSL_FUNC_BIO_vsnprintf_fn")
// Maintain compatibility for existing enum definitions
.rustified_enum("point_conversion_form_t")
// Maintain compatibility for pre-union definitions
.blocklist_type("GENERAL_NAME")
.blocklist_type("GENERAL_NAME_st")
.blocklist_type("EVP_PKEY")
.blocklist_type("evp_pkey_st")
.layout_tests(false)
.header_contents("includes.h", INCLUDES);
for include_dir in include_dirs {
builder = builder
.clang_arg("-I")
.clang_arg(include_dir.display().to_string());
}
builder
.generate()
.unwrap()
.write_to_file(out_dir.join("bindgen.rs"))
.unwrap();
}
#[derive(Debug)]
struct OpensslCallbacks;
impl ParseCallbacks for OpensslCallbacks {
// for now we'll continue hand-writing constants
fn will_parse_macro(&self, _name: &str) -> MacroParsingBehavior {
MacroParsingBehavior::Ignore
}
fn item_name(&self, original_item_name: &str) -> Option<String> {
match original_item_name {
// Our original definitions of these are wrong, so rename to avoid breakage
"CRYPTO_EX_new"
| "CRYPTO_EX_dup"
| "CRYPTO_EX_free"
| "BIO_meth_set_write"
| "BIO_meth_set_read"
| "BIO_meth_set_puts"
| "BIO_meth_set_ctrl"
| "BIO_meth_set_create"
| "BIO_meth_set_destroy"
| "CRYPTO_set_locking_callback"
| "CRYPTO_set_id_callback"
| "SSL_CTX_set_tmp_dh_callback"
| "SSL_set_tmp_dh_callback"
| "SSL_CTX_set_tmp_ecdh_callback"
| "SSL_set_tmp_ecdh_callback"
| "SSL_CTX_callback_ctrl"
| "SSL_CTX_set_alpn_select_cb" => Some(format!("{}__fixed_rust", original_item_name)),
_ => None,
}
}
}

View File

@ -1 +1 @@
{"files":{"CHANGELOG.md":"1d82f1ac1540d9606314c56d1701d10fff72688b0bf458398846fa837a6b8209","Cargo.toml":"c924c5dd3ad8b58b4d65ec40f10a44b5352f89145c419d82dab9c647b5d363f3","LICENSE":"898b1ae9821e98daf8964c8d6c7f61641f5f5aa78ad500020771c0939ee0dea1","README.md":"39a30e68fd06cd90cdf232fb87cba82168797c9861739e9529fee68e72c26868","benches/global_subscriber.rs":"271213baed0e02054e506c1ec9c47b58696c78aaa46f0969a147f4c369f80e3d","benches/no_subscriber.rs":"495c9a91fb972ec61ced31ef8e19d2cca02ec8ffae4e98e3316e55f6a0074578","benches/subscriber.rs":"c609be119ed6e4d3fb79df77f15aa14effbd3e2f77c627a49229a50091d3ee6a","src/dispatcher.rs":"5732b1f228328cd41e77b04a27faf3b6054a8ed5cd5034a0dad8e1e694ca3889","src/field.rs":"55c7a2798b9ad0269e7c738c3f15a5d0281bf34ac3a6196a3f0b15801e5278bd","src/instrument.rs":"1fe4de5c13b5ba048e9872d78d1fa4e85655f9f2ed10f79b72b5da881c9b8b45","src/level_filters.rs":"baae8e797897bae9cdd9ec64b8e9a3d71156e9c03261be17b5b18acba034e154","src/lib.rs":"c794108f5f37b5dc1609498afad5ebbb25ad5f80bf9e362c032a63d327429937","src/macros.rs":"1bf35f17cbb50fb92f60e5e60190faf5eeba03c328f754631fff6df183509491","src/span.rs":"e7c16999e8702bf1ff82aaa6803c81ac5b77ab96b754cac6e686acfc6adc14f9","src/stdlib.rs":"248514a9bae6106e436358aee44c92abf8e7f79022895c4a25136ddef211d198","src/subscriber.rs":"ae879c373be7ee4935f7b02a345f92ccbeb7879d61c5d37e3cc1277b3d51ddb2","tests/enabled.rs":"1333339aace87ea9d701f2f76a1985820cc513a75013a7ed89669f7a2c635479","tests/event.rs":"c4ec3ac338475e9e61675551eb99df1d8a7cbefb05a0d60203994f5c1df7c784","tests/filter_caching_is_lexically_scoped.rs":"5487a37db5fbdf3d57020ab1f01185d928c45d967d99d723ffc434540459d8dc","tests/filters_are_not_reevaluated_for_the_same_span.rs":"251abbc000dddd298448958a1f0e5be71da527ac6c1a368d57837c83a5467329","tests/filters_are_reevaluated_for_different_call_sites.rs":"e0fdd8e930c043674702831b4d96f331e63aba824576bbac50b3f53bb0241cc7","tests/filters_dont_leak.rs":"d594266818a3461886da33bfcc76937d89a433ed6980226fc428706b216c093c","tests/future_send.rs":"3e9c9193219d12e342c18bbedb2f6ec940334202feb3cffba91601d6001b8575","tests/macro_imports.rs":"d5de857162185d4a2384f3cb644bfcf76c7f5c1a3b5f72bfa0d2620ac6e3873c","tests/macros.rs":"fa83397181d73d2cae09c16d9647a63d1e3bad0f2dbc5b3280f69f3d0180c488","tests/macros_incompatible_concat.rs":"5f3bcbb65e4ae39db1cfc2def62fc913c20bab0fb769c8f731504e2615585ee5","tests/macros_redefined_core.rs":"a6eac60522f71fe6c9a040b8b869d596f7eb9e907f5b49f4be4413a40c387676","tests/max_level_hint.rs":"9b366591d947ca0202fa0bdf797e1bb14534d3c896cf8b9674660cd2807c32ef","tests/multiple_max_level_hints.rs":"4d9ef0de9cccc787da8f5e3f6c233ac9db42a2a99cfe5e39997e1f4aa9df0c00","tests/no_subscriber.rs":"2f8f2ada5089d8e2e503394dfe8206598a11895907c53bf940b892f1e6afdd2f","tests/scoped_clobbers_default.rs":"806480a74c15e4d68bb7576050662b1e53ee765fd583d003f8b349f17ea63a4b","tests/span.rs":"f84ead5b1dad9b91e5cec9d8378ab932a942936374ba928fb381e67fab52cda0","tests/subscriber.rs":"1617c098f4fa6abed174fe062111444c7b67fa0f377d2b342176998e572480e3"},"package":"5d0ecdcb44a79f0fe9844f0c4f33a342cbcbb5117de8001e6ba0dc2351327d09"}
{"files":{"CHANGELOG.md":"7d5517e1ac705d5d8574915b59a37bbd0ba5aa6e663fc272b75e5792eca572a9","Cargo.toml":"f6290faffd0bf079845dbd6c3c1ddb6c728bcf7225e3b56a4ba5a9478dc72a8b","LICENSE":"898b1ae9821e98daf8964c8d6c7f61641f5f5aa78ad500020771c0939ee0dea1","README.md":"a83e1a8287e3eca752383ae849872707dddfbd07b918806cc7c027a0824872c6","benches/global_subscriber.rs":"271213baed0e02054e506c1ec9c47b58696c78aaa46f0969a147f4c369f80e3d","benches/no_subscriber.rs":"495c9a91fb972ec61ced31ef8e19d2cca02ec8ffae4e98e3316e55f6a0074578","benches/subscriber.rs":"c609be119ed6e4d3fb79df77f15aa14effbd3e2f77c627a49229a50091d3ee6a","src/dispatcher.rs":"a8158e1901c50dc83d2f15b1773e6b9e31985d9af65e460be52dbf8be6874cd2","src/field.rs":"55c7a2798b9ad0269e7c738c3f15a5d0281bf34ac3a6196a3f0b15801e5278bd","src/instrument.rs":"1fe4de5c13b5ba048e9872d78d1fa4e85655f9f2ed10f79b72b5da881c9b8b45","src/level_filters.rs":"baae8e797897bae9cdd9ec64b8e9a3d71156e9c03261be17b5b18acba034e154","src/lib.rs":"a8ab6b578f93b5fb833942fc59642e67caca8d343670d64fb52d47d5507a67e4","src/macros.rs":"f1a83930cea322f1f2000548d91800c22a9e28d2daf3f178c7c7c3ac8da5a02d","src/span.rs":"96b6c86be09c97b15b2ab5c607013abc5b388c2870eb648bee2cfc07837fa6e9","src/stdlib.rs":"248514a9bae6106e436358aee44c92abf8e7f79022895c4a25136ddef211d198","src/subscriber.rs":"ae879c373be7ee4935f7b02a345f92ccbeb7879d61c5d37e3cc1277b3d51ddb2","tests/enabled.rs":"1333339aace87ea9d701f2f76a1985820cc513a75013a7ed89669f7a2c635479","tests/event.rs":"c4ec3ac338475e9e61675551eb99df1d8a7cbefb05a0d60203994f5c1df7c784","tests/filter_caching_is_lexically_scoped.rs":"5487a37db5fbdf3d57020ab1f01185d928c45d967d99d723ffc434540459d8dc","tests/filters_are_not_reevaluated_for_the_same_span.rs":"251abbc000dddd298448958a1f0e5be71da527ac6c1a368d57837c83a5467329","tests/filters_are_reevaluated_for_different_call_sites.rs":"e0fdd8e930c043674702831b4d96f331e63aba824576bbac50b3f53bb0241cc7","tests/filters_dont_leak.rs":"d594266818a3461886da33bfcc76937d89a433ed6980226fc428706b216c093c","tests/future_send.rs":"3e9c9193219d12e342c18bbedb2f6ec940334202feb3cffba91601d6001b8575","tests/macro_imports.rs":"d5de857162185d4a2384f3cb644bfcf76c7f5c1a3b5f72bfa0d2620ac6e3873c","tests/macros.rs":"fa83397181d73d2cae09c16d9647a63d1e3bad0f2dbc5b3280f69f3d0180c488","tests/macros_incompatible_concat.rs":"5f3bcbb65e4ae39db1cfc2def62fc913c20bab0fb769c8f731504e2615585ee5","tests/macros_redefined_core.rs":"a6eac60522f71fe6c9a040b8b869d596f7eb9e907f5b49f4be4413a40c387676","tests/max_level_hint.rs":"9b366591d947ca0202fa0bdf797e1bb14534d3c896cf8b9674660cd2807c32ef","tests/multiple_max_level_hints.rs":"4d9ef0de9cccc787da8f5e3f6c233ac9db42a2a99cfe5e39997e1f4aa9df0c00","tests/no_subscriber.rs":"2f8f2ada5089d8e2e503394dfe8206598a11895907c53bf940b892f1e6afdd2f","tests/register_callsite_deadlock.rs":"c0b3142543e7a10065c7583a8ee0b6bc978ea4f3979599651101c5a28966e7c8","tests/scoped_clobbers_default.rs":"806480a74c15e4d68bb7576050662b1e53ee765fd583d003f8b349f17ea63a4b","tests/span.rs":"f84ead5b1dad9b91e5cec9d8378ab932a942936374ba928fb381e67fab52cda0","tests/subscriber.rs":"1617c098f4fa6abed174fe062111444c7b67fa0f377d2b342176998e572480e3"},"package":"a400e31aa60b9d44a52a8ee0343b5b18566b03a8321e0d321f695cf56e940160"}

View File

@ -1,3 +1,19 @@
# 0.1.35 (June 8, 2022)
This release reduces the overhead of callsite registration by using new
`tracing-core` APIs.
### Added
- Use `DefaultCallsite` to reduce callsite registration overhead ([#2083])
### Changed
- `tracing-core`: updated to [0.1.27][core-0.1.27]
[core-0.1.27]: https://github.com/tokio-rs/tracing/releases/tag/tracing-core-0.1.27
[#2088]: https://github.com/tokio-rs/tracing/pull/2083
# 0.1.34 (April 14, 2022)
This release includes bug fixes for the "log" support feature and for the use of

View File

@ -13,7 +13,7 @@
edition = "2018"
rust-version = "1.49.0"
name = "tracing"
version = "0.1.34"
version = "0.1.35"
authors = [
"Eliza Weisman <eliza@buoyant.io>",
"Tokio Contributors <team@tokio.rs>",
@ -74,7 +74,7 @@ version = "0.1.20"
optional = true
[dependencies.tracing-core]
version = "0.1.22"
version = "0.1.27"
default-features = false
[dev-dependencies.criterion]

View File

@ -16,9 +16,9 @@ Application-level tracing for Rust.
[Documentation][docs-url] | [Chat][discord-url]
[crates-badge]: https://img.shields.io/crates/v/tracing.svg
[crates-url]: https://crates.io/crates/tracing/0.1.34
[crates-url]: https://crates.io/crates/tracing/0.1.35
[docs-badge]: https://docs.rs/tracing/badge.svg
[docs-url]: https://docs.rs/tracing/0.1.34
[docs-url]: https://docs.rs/tracing/0.1.35
[docs-master-badge]: https://img.shields.io/badge/docs-master-blue
[docs-master-url]: https://tracing-rs.netlify.com/tracing
[mit-badge]: https://img.shields.io/badge/license-MIT-blue.svg
@ -250,7 +250,7 @@ my_future
is as long as the future's.
The second, and preferred, option is through the
[`#[instrument]`](https://docs.rs/tracing/0.1.34/tracing/attr.instrument.html)
[`#[instrument]`](https://docs.rs/tracing/0.1.35/tracing/attr.instrument.html)
attribute:
```rust
@ -297,7 +297,7 @@ span.in_scope(|| {
// Dropping the span will close it, indicating that it has ended.
```
The [`#[instrument]`](https://docs.rs/tracing/0.1.34/tracing/attr.instrument.html) attribute macro
The [`#[instrument]`](https://docs.rs/tracing/0.1.35/tracing/attr.instrument.html) attribute macro
can reduce some of this boilerplate:
```rust

View File

@ -123,10 +123,6 @@
//! instrumentation.
//!
//! [`Subscriber`]: crate::Subscriber
//! [`with_default`]: with_default
//! [`set_global_default`]: set_global_default
//! [`get_default`]: get_default
//! [`Dispatch`]: Dispatch
#[cfg(feature = "std")]
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
pub use tracing_core::dispatcher::set_default;

View File

@ -119,8 +119,6 @@
//! tracing = "0.1"
//! ```
//!
//! *Compiler support: [requires `rustc` 1.42+][msrv]*
//!
//! ## Recording Spans and Events
//!
//! Spans and events are recorded using macros.
@ -437,9 +435,9 @@
//! [target]: Metadata::target
//! [parent span]: span::Attributes::parent
//! [determined contextually]: span::Attributes::is_contextual
//! [`fmt::Debug`]: https://doc.rust-lang.org/std/fmt/trait.Debug.html
//! [`fmt::Display`]: https://doc.rust-lang.org/std/fmt/trait.Display.html
//! [fmt]: https://doc.rust-lang.org/std/fmt/#usage
//! [`fmt::Debug`]: std::fmt::Debug
//! [`fmt::Display`]: std::fmt::Display
//! [fmt]: std::fmt#usage
//! [`Empty`]: field::Empty
//!
//! ### Shorthand Macros
@ -466,7 +464,6 @@
//! [`info_span!`]: info_span!
//! [`warn_span!`]: warn_span!
//! [`error_span!`]: error_span!
//! [`Level`]: Level
//!
//! ### For `log` Users
//!
@ -812,7 +809,7 @@
//!
//! ```toml
//! [dependencies]
//! tracing = { version = "0.1.34", default-features = false }
//! tracing = { version = "0.1.35", default-features = false }
//! ```
//!
//! <pre class="ignore" style="white-space:normal;font:inherit;">
@ -895,7 +892,7 @@
//! [flags]: #crate-feature-flags
#![cfg_attr(not(feature = "std"), no_std)]
#![cfg_attr(docsrs, feature(doc_cfg), deny(rustdoc::broken_intra_doc_links))]
#![doc(html_root_url = "https://docs.rs/tracing/0.1.34")]
#![doc(html_root_url = "https://docs.rs/tracing/0.1.35")]
#![doc(
html_logo_url = "https://raw.githubusercontent.com/tokio-rs/tracing/master/assets/logo-type.png",
issue_tracker_base_url = "https://github.com/tokio-rs/tracing/issues/"
@ -968,13 +965,8 @@ pub mod subscriber;
#[doc(hidden)]
pub mod __macro_support {
pub use crate::callsite::Callsite;
use crate::stdlib::{
fmt,
sync::atomic::{AtomicUsize, Ordering},
};
use crate::{subscriber::Interest, Metadata};
pub use core::concat;
use tracing_core::Once;
/// Callsite implementation used by macro-generated code.
///
@ -984,138 +976,70 @@ pub mod __macro_support {
/// by the `tracing` macros, but it is not part of the stable versioned API.
/// Breaking changes to this module may occur in small-numbered versions
/// without warning.
pub struct MacroCallsite {
interest: AtomicUsize,
meta: &'static Metadata<'static>,
registration: Once,
pub use tracing_core::callsite::DefaultCallsite as MacroCallsite;
/// /!\ WARNING: This is *not* a stable API! /!\
/// This function, and all code contained in the `__macro_support` module, is
/// a *private* API of `tracing`. It is exposed publicly because it is used
/// by the `tracing` macros, but it is not part of the stable versioned API.
/// Breaking changes to this module may occur in small-numbered versions
/// without warning.
pub fn __is_enabled(meta: &Metadata<'static>, interest: Interest) -> bool {
interest.is_always() || crate::dispatcher::get_default(|default| default.enabled(meta))
}
impl MacroCallsite {
/// Returns a new `MacroCallsite` with the specified `Metadata`.
///
/// /!\ WARNING: This is *not* a stable API! /!\
/// This method, and all code contained in the `__macro_support` module, is
/// a *private* API of `tracing`. It is exposed publicly because it is used
/// by the `tracing` macros, but it is not part of the stable versioned API.
/// Breaking changes to this module may occur in small-numbered versions
/// without warning.
pub const fn new(meta: &'static Metadata<'static>) -> Self {
Self {
interest: AtomicUsize::new(0xDEAD),
meta,
registration: Once::new(),
}
}
/// Registers this callsite with the global callsite registry.
///
/// If the callsite is already registered, this does nothing.
///
/// /!\ WARNING: This is *not* a stable API! /!\
/// This method, and all code contained in the `__macro_support` module, is
/// a *private* API of `tracing`. It is exposed publicly because it is used
/// by the `tracing` macros, but it is not part of the stable versioned API.
/// Breaking changes to this module may occur in small-numbered versions
/// without warning.
#[inline(never)]
// This only happens once (or if the cached interest value was corrupted).
#[cold]
pub fn register(&'static self) -> Interest {
self.registration
.call_once(|| crate::callsite::register(self));
match self.interest.load(Ordering::Relaxed) {
0 => Interest::never(),
2 => Interest::always(),
_ => Interest::sometimes(),
}
}
/// Returns the callsite's cached Interest, or registers it for the
/// first time if it has not yet been registered.
///
/// /!\ WARNING: This is *not* a stable API! /!\
/// This method, and all code contained in the `__macro_support` module, is
/// a *private* API of `tracing`. It is exposed publicly because it is used
/// by the `tracing` macros, but it is not part of the stable versioned API.
/// Breaking changes to this module may occur in small-numbered versions
/// without warning.
#[inline]
pub fn interest(&'static self) -> Interest {
match self.interest.load(Ordering::Relaxed) {
0 => Interest::never(),
1 => Interest::sometimes(),
2 => Interest::always(),
_ => self.register(),
}
}
pub fn is_enabled(&self, interest: Interest) -> bool {
interest.is_always()
|| crate::dispatcher::get_default(|default| default.enabled(self.meta))
}
#[inline]
#[cfg(feature = "log")]
pub fn disabled_span(&self) -> crate::Span {
crate::Span::new_disabled(self.meta)
}
#[inline]
#[cfg(not(feature = "log"))]
pub fn disabled_span(&self) -> crate::Span {
crate::Span::none()
}
#[cfg(feature = "log")]
pub fn log(
&self,
logger: &'static dyn log::Log,
log_meta: log::Metadata<'_>,
values: &tracing_core::field::ValueSet<'_>,
) {
let meta = self.metadata();
logger.log(
&crate::log::Record::builder()
.file(meta.file())
.module_path(meta.module_path())
.line(meta.line())
.metadata(log_meta)
.args(format_args!(
"{}",
crate::log::LogValueSet {
values,
is_first: true
}
))
.build(),
);
}
/// /!\ WARNING: This is *not* a stable API! /!\
/// This function, and all code contained in the `__macro_support` module, is
/// a *private* API of `tracing`. It is exposed publicly because it is used
/// by the `tracing` macros, but it is not part of the stable versioned API.
/// Breaking changes to this module may occur in small-numbered versions
/// without warning.
#[inline]
#[cfg(feature = "log")]
pub fn __disabled_span(meta: &'static Metadata<'static>) -> crate::Span {
crate::Span::new_disabled(meta)
}
impl Callsite for MacroCallsite {
fn set_interest(&self, interest: Interest) {
let interest = match () {
_ if interest.is_never() => 0,
_ if interest.is_always() => 2,
_ => 1,
};
self.interest.store(interest, Ordering::SeqCst);
}
#[inline(always)]
fn metadata(&self) -> &Metadata<'static> {
self.meta
}
/// /!\ WARNING: This is *not* a stable API! /!\
/// This function, and all code contained in the `__macro_support` module, is
/// a *private* API of `tracing`. It is exposed publicly because it is used
/// by the `tracing` macros, but it is not part of the stable versioned API.
/// Breaking changes to this module may occur in small-numbered versions
/// without warning.
#[inline]
#[cfg(not(feature = "log"))]
pub fn __disabled_span(_: &'static Metadata<'static>) -> crate::Span {
crate::Span::none()
}
impl fmt::Debug for MacroCallsite {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("MacroCallsite")
.field("interest", &self.interest)
.field("meta", &self.meta)
.field("registration", &self.registration)
.finish()
}
/// /!\ WARNING: This is *not* a stable API! /!\
/// This function, and all code contained in the `__macro_support` module, is
/// a *private* API of `tracing`. It is exposed publicly because it is used
/// by the `tracing` macros, but it is not part of the stable versioned API.
/// Breaking changes to this module may occur in small-numbered versions
/// without warning.
#[cfg(feature = "log")]
pub fn __tracing_log(
meta: &Metadata<'static>,
logger: &'static dyn log::Log,
log_meta: log::Metadata<'_>,
values: &tracing_core::field::ValueSet<'_>,
) {
logger.log(
&crate::log::Record::builder()
.file(meta.file())
.module_path(meta.module_path())
.line(meta.line())
.metadata(log_meta)
.args(format_args!(
"{}",
crate::log::LogValueSet {
values,
is_first: true
}
))
.build(),
);
}
}

View File

@ -24,7 +24,7 @@ macro_rules! span {
(target: $target:expr, parent: $parent:expr, $lvl:expr, $name:expr, $($fields:tt)*) => {
{
use $crate::__macro_support::Callsite as _;
static CALLSITE: $crate::__macro_support::MacroCallsite = $crate::callsite2! {
static CALLSITE: $crate::callsite::DefaultCallsite = $crate::callsite2! {
name: $name,
kind: $crate::metadata::Kind::SPAN,
target: $target,
@ -34,7 +34,7 @@ macro_rules! span {
let mut interest = $crate::subscriber::Interest::never();
if $crate::level_enabled!($lvl)
&& { interest = CALLSITE.interest(); !interest.is_never() }
&& CALLSITE.is_enabled(interest)
&& $crate::__macro_support::__is_enabled(CALLSITE.metadata(), interest)
{
let meta = CALLSITE.metadata();
// span with explicit parent
@ -44,7 +44,7 @@ macro_rules! span {
&$crate::valueset!(meta.fields(), $($fields)*),
)
} else {
let span = CALLSITE.disabled_span();
let span = $crate::__macro_support::__disabled_span(CALLSITE.metadata());
$crate::if_log_enabled! { $lvl, {
span.record_all(&$crate::valueset!(CALLSITE.metadata().fields(), $($fields)*));
}};
@ -55,7 +55,7 @@ macro_rules! span {
(target: $target:expr, $lvl:expr, $name:expr, $($fields:tt)*) => {
{
use $crate::__macro_support::Callsite as _;
static CALLSITE: $crate::__macro_support::MacroCallsite = $crate::callsite2! {
static CALLSITE: $crate::callsite::DefaultCallsite = $crate::callsite2! {
name: $name,
kind: $crate::metadata::Kind::SPAN,
target: $target,
@ -65,7 +65,7 @@ macro_rules! span {
let mut interest = $crate::subscriber::Interest::never();
if $crate::level_enabled!($lvl)
&& { interest = CALLSITE.interest(); !interest.is_never() }
&& CALLSITE.is_enabled(interest)
&& $crate::__macro_support::__is_enabled(CALLSITE.metadata(), interest)
{
let meta = CALLSITE.metadata();
// span with contextual parent
@ -74,7 +74,7 @@ macro_rules! span {
&$crate::valueset!(meta.fields(), $($fields)*),
)
} else {
let span = CALLSITE.disabled_span();
let span = $crate::__macro_support::__disabled_span(CALLSITE.metadata());
$crate::if_log_enabled! { $lvl, {
span.record_all(&$crate::valueset!(CALLSITE.metadata().fields(), $($fields)*));
}};
@ -584,7 +584,7 @@ macro_rules! error_span {
macro_rules! event {
(target: $target:expr, parent: $parent:expr, $lvl:expr, { $($fields:tt)* } )=> ({
use $crate::__macro_support::Callsite as _;
static CALLSITE: $crate::__macro_support::MacroCallsite = $crate::callsite2! {
static CALLSITE: $crate::callsite::DefaultCallsite = $crate::callsite2! {
name: $crate::__macro_support::concat!(
"event ",
file!(),
@ -599,7 +599,7 @@ macro_rules! event {
let enabled = $crate::level_enabled!($lvl) && {
let interest = CALLSITE.interest();
!interest.is_never() && CALLSITE.is_enabled(interest)
!interest.is_never() && $crate::__macro_support::__is_enabled(CALLSITE.metadata(), interest)
};
if enabled {
(|value_set: $crate::field::ValueSet| {
@ -641,7 +641,7 @@ macro_rules! event {
);
(target: $target:expr, $lvl:expr, { $($fields:tt)* } )=> ({
use $crate::__macro_support::Callsite as _;
static CALLSITE: $crate::__macro_support::MacroCallsite = $crate::callsite2! {
static CALLSITE: $crate::callsite::DefaultCallsite = $crate::callsite2! {
name: $crate::__macro_support::concat!(
"event ",
file!(),
@ -655,7 +655,7 @@ macro_rules! event {
};
let enabled = $crate::level_enabled!($lvl) && {
let interest = CALLSITE.interest();
!interest.is_never() && CALLSITE.is_enabled(interest)
!interest.is_never() && $crate::__macro_support::__is_enabled(CALLSITE.metadata(), interest)
};
if enabled {
(|value_set: $crate::field::ValueSet| {
@ -832,6 +832,8 @@ macro_rules! event {
/// }
/// ```
///
/// [`enabled!`]: crate::enabled
/// [`span_enabled!`]: crate::span_enabled
#[macro_export]
macro_rules! event_enabled {
($($rest:tt)*)=> (
@ -864,6 +866,8 @@ macro_rules! event_enabled {
/// }
/// ```
///
/// [`enabled!`]: crate::enabled
/// [`span_enabled!`]: crate::span_enabled
#[macro_export]
macro_rules! span_enabled {
($($rest:tt)*)=> (
@ -959,13 +963,14 @@ macro_rules! span_enabled {
/// [`Metadata`]: crate::Metadata
/// [`is_event`]: crate::Metadata::is_event
/// [`is_span`]: crate::Metadata::is_span
///
/// [`enabled!`]: crate::enabled
/// [`span_enabled!`]: crate::span_enabled
#[macro_export]
macro_rules! enabled {
(kind: $kind:expr, target: $target:expr, $lvl:expr, { $($fields:tt)* } )=> ({
if $crate::level_enabled!($lvl) {
use $crate::__macro_support::Callsite as _;
static CALLSITE: $crate::__macro_support::MacroCallsite = $crate::callsite2! {
static CALLSITE: $crate::callsite::DefaultCallsite = $crate::callsite2! {
name: $crate::__macro_support::concat!(
"enabled ",
file!(),
@ -978,7 +983,7 @@ macro_rules! enabled {
fields: $($fields)*
};
let interest = CALLSITE.interest();
if !interest.is_never() && CALLSITE.is_enabled(interest) {
if !interest.is_never() && $crate::__macro_support::__is_enabled(CALLSITE.metadata(), interest) {
let meta = CALLSITE.metadata();
$crate::dispatcher::get_default(|current| current.enabled(meta))
} else {
@ -2096,7 +2101,6 @@ macro_rules! callsite {
level: $lvl:expr,
fields: $($fields:tt)*
) => {{
use $crate::__macro_support::MacroCallsite;
static META: $crate::Metadata<'static> = {
$crate::metadata! {
name: $name,
@ -2107,7 +2111,7 @@ macro_rules! callsite {
kind: $kind,
}
};
static CALLSITE: MacroCallsite = MacroCallsite::new(&META);
static CALLSITE: $crate::callsite::DefaultCallsite = $crate::callsite::DefaultCallsite::new(&META);
CALLSITE.register();
&CALLSITE
}};
@ -2147,7 +2151,6 @@ macro_rules! callsite2 {
level: $lvl:expr,
fields: $($fields:tt)*
) => {{
use $crate::__macro_support::MacroCallsite;
static META: $crate::Metadata<'static> = {
$crate::metadata! {
name: $name,
@ -2158,7 +2161,7 @@ macro_rules! callsite2 {
kind: $kind,
}
};
MacroCallsite::new(&META)
$crate::callsite::DefaultCallsite::new(&META)
}};
}
@ -2428,13 +2431,14 @@ macro_rules! __tracing_log {
use $crate::log;
let level = $crate::level_to_log!($level);
if level <= log::max_level() {
let meta = $callsite.metadata();
let log_meta = log::Metadata::builder()
.level(level)
.target(CALLSITE.metadata().target())
.target(meta.target())
.build();
let logger = log::logger();
if logger.enabled(&log_meta) {
$callsite.log(logger, log_meta, $value_set)
$crate::__macro_support::__tracing_log(meta, logger, log_meta, $value_set)
}
}
}}

View File

@ -718,8 +718,8 @@ impl Span {
/// ```
///
/// [syntax]: https://rust-lang.github.io/async-book/01_getting_started/04_async_await_primer.html
/// [`Span::in_scope`]: #method.in_scope
/// [instrument]: https://docs.rs/tracing/latest/tracing/trait.Instrument.html
/// [`Span::in_scope`]: Span::in_scope()
/// [instrument]: crate::Instrument
/// [attr]: macro@crate::instrument
///
/// # Examples
@ -1239,7 +1239,7 @@ impl Span {
///
/// See also [`is_none`].
///
/// [`is_none`]: #method.is_none
/// [`is_none`]: Span::is_none()
#[inline]
pub fn is_disabled(&self) -> bool {
self.inner.is_none()
@ -1253,8 +1253,8 @@ impl Span {
/// rather than constructed by `Span::none`, this method will return
/// `false`, while `is_disabled` will return `true`.
///
/// [`Span::none`]: #method.none
/// [`is_disabled`]: #method.is_disabled
/// [`Span::none`]: Span::none()
/// [`is_disabled`]: Span::is_disabled()
#[inline]
pub fn is_none(&self) -> bool {
self.is_disabled() && self.meta.is_none()

View File

@ -0,0 +1,47 @@
use std::{sync::mpsc, thread, time::Duration};
use tracing::{
metadata::Metadata,
span,
subscriber::{self, Interest, Subscriber},
Event,
};
#[test]
fn register_callsite_doesnt_deadlock() {
pub struct EvilSubscriber;
impl Subscriber for EvilSubscriber {
fn register_callsite(&self, meta: &'static Metadata<'static>) -> Interest {
tracing::info!(?meta, "registered a callsite");
Interest::always()
}
fn enabled(&self, _: &Metadata<'_>) -> bool {
true
}
fn new_span(&self, _: &span::Attributes<'_>) -> span::Id {
span::Id::from_u64(1)
}
fn record(&self, _: &span::Id, _: &span::Record<'_>) {}
fn record_follows_from(&self, _: &span::Id, _: &span::Id) {}
fn event(&self, _: &Event<'_>) {}
fn enter(&self, _: &span::Id) {}
fn exit(&self, _: &span::Id) {}
}
subscriber::set_global_default(EvilSubscriber).unwrap();
// spawn a thread, and assert it doesn't hang...
let (tx, didnt_hang) = mpsc::channel();
let th = thread::spawn(move || {
tracing::info!("hello world!");
tx.send(()).unwrap();
});
didnt_hang
// Note: 60 seconds is *way* more than enough, but let's be generous in
// case of e.g. slow CI machines.
.recv_timeout(Duration::from_secs(60))
.expect("the thread must not have hung!");
th.join().expect("thread should join successfully");
}

186
zeroidc/vendor/typenum/build/main.rs vendored Normal file
View File

@ -0,0 +1,186 @@
use std::env;
use std::fmt;
use std::fs::File;
use std::io::Write;
use std::path::Path;
mod op;
mod tests;
pub enum UIntCode {
Term,
Zero(Box<UIntCode>),
One(Box<UIntCode>),
}
pub enum IntCode {
Zero,
Pos(Box<UIntCode>),
Neg(Box<UIntCode>),
}
impl fmt::Display for UIntCode {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
UIntCode::Term => write!(f, "UTerm"),
UIntCode::Zero(ref inner) => write!(f, "UInt<{}, B0>", inner),
UIntCode::One(ref inner) => write!(f, "UInt<{}, B1>", inner),
}
}
}
impl fmt::Display for IntCode {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
IntCode::Zero => write!(f, "Z0"),
IntCode::Pos(ref inner) => write!(f, "PInt<{}>", inner),
IntCode::Neg(ref inner) => write!(f, "NInt<{}>", inner),
}
}
}
pub fn gen_uint(u: u64) -> UIntCode {
let mut result = UIntCode::Term;
let mut x = 1u64 << 63;
while x > u {
x >>= 1
}
while x > 0 {
result = if x & u > 0 {
UIntCode::One(Box::new(result))
} else {
UIntCode::Zero(Box::new(result))
};
x >>= 1;
}
result
}
pub fn gen_int(i: i64) -> IntCode {
use std::cmp::Ordering::{Equal, Greater, Less};
match i.cmp(&0) {
Greater => IntCode::Pos(Box::new(gen_uint(i as u64))),
Less => IntCode::Neg(Box::new(gen_uint(i.abs() as u64))),
Equal => IntCode::Zero,
}
}
#[cfg_attr(
feature = "no_std",
deprecated(
since = "1.3.0",
note = "the `no_std` flag is no longer necessary and will be removed in the future"
)
)]
pub fn no_std() {}
// fixme: get a warning when testing without this
#[allow(dead_code)]
fn main() {
let highest: u64 = 1024;
// Use hardcoded values to avoid issues with cross-compilation.
// See https://github.com/paholg/typenum/issues/162
let first2: u32 = 11; // (highest as f64).log(2.0).round() as u32 + 1;
let first10: u32 = 4; // (highest as f64).log(10.0) as u32 + 1;
let uints = (0..(highest + 1))
.chain((first2..64).map(|i| 2u64.pow(i)))
.chain((first10..20).map(|i| 10u64.pow(i)));
let out_dir = env::var("OUT_DIR").unwrap();
let dest = Path::new(&out_dir).join("consts.rs");
println!("cargo:rustc-env=TYPENUM_BUILD_CONSTS={}", dest.display());
let mut f = File::create(&dest).unwrap();
no_std();
// Header stuff here!
write!(
f,
"
/**
Type aliases for many constants.
This file is generated by typenum's build script.
For unsigned integers, the format is `U` followed by the number. We define aliases for
- Numbers 0 through {highest}
- Powers of 2 below `u64::MAX`
- Powers of 10 below `u64::MAX`
These alias definitions look like this:
```rust
use typenum::{{B0, B1, UInt, UTerm}};
# #[allow(dead_code)]
type U6 = UInt<UInt<UInt<UTerm, B1>, B1>, B0>;
```
For positive signed integers, the format is `P` followed by the number and for negative
signed integers it is `N` followed by the number. For the signed integer zero, we use
`Z0`. We define aliases for
- Numbers -{highest} through {highest}
- Powers of 2 between `i64::MIN` and `i64::MAX`
- Powers of 10 between `i64::MIN` and `i64::MAX`
These alias definitions look like this:
```rust
use typenum::{{B0, B1, UInt, UTerm, PInt, NInt}};
# #[allow(dead_code)]
type P6 = PInt<UInt<UInt<UInt<UTerm, B1>, B1>, B0>>;
# #[allow(dead_code)]
type N6 = NInt<UInt<UInt<UInt<UTerm, B1>, B1>, B0>>;
```
# Example
```rust
# #[allow(unused_imports)]
use typenum::{{U0, U1, U2, U3, U4, U5, U6}};
# #[allow(unused_imports)]
use typenum::{{N3, N2, N1, Z0, P1, P2, P3}};
# #[allow(unused_imports)]
use typenum::{{U774, N17, N10000, P1024, P4096}};
```
We also define the aliases `False` and `True` for `B0` and `B1`, respectively.
*/
#[allow(missing_docs)]
pub mod consts {{
use crate::uint::{{UInt, UTerm}};
use crate::int::{{PInt, NInt}};
pub use crate::bit::{{B0, B1}};
pub use crate::int::Z0;
pub type True = B1;
pub type False = B0;
",
highest = highest
)
.unwrap();
for u in uints {
writeln!(f, " pub type U{} = {};", u, gen_uint(u)).unwrap();
if u <= ::std::i64::MAX as u64 && u != 0 {
let i = u as i64;
writeln!(
f,
" pub type P{i} = PInt<U{i}>; pub type N{i} = NInt<U{i}>;",
i = i
)
.unwrap();
}
}
write!(f, "}}").unwrap();
tests::build_tests().unwrap();
op::write_op_macro().unwrap();
}

559
zeroidc/vendor/typenum/build/op.rs vendored Normal file
View File

@ -0,0 +1,559 @@
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
enum OpType {
Operator,
Function,
}
use self::OpType::*;
struct Op {
token: &'static str,
operator: &'static str,
example: (&'static str, &'static str),
precedence: u8,
n_args: u8,
op_type: OpType,
}
pub fn write_op_macro() -> ::std::io::Result<()> {
let out_dir = ::std::env::var("OUT_DIR").unwrap();
let dest = ::std::path::Path::new(&out_dir).join("op.rs");
println!("cargo:rustc-env=TYPENUM_BUILD_OP={}", dest.display());
let mut f = ::std::fs::File::create(&dest).unwrap();
// Operator precedence is taken from
// https://doc.rust-lang.org/reference.html#operator-precedence
//
// We choose 16 as the highest precedence (functions are set to 255 but it doesn't matter
// for them). We also only use operators that are left associative so we don't have to worry
// about that.
let ops = &[
Op {
token: "*",
operator: "Prod",
example: ("P2 * P3", "P6"),
precedence: 16,
n_args: 2,
op_type: Operator,
},
Op {
token: "/",
operator: "Quot",
example: ("P6 / P2", "P3"),
precedence: 16,
n_args: 2,
op_type: Operator,
},
Op {
token: "%",
operator: "Mod",
example: ("P5 % P3", "P2"),
precedence: 16,
n_args: 2,
op_type: Operator,
},
Op {
token: "+",
operator: "Sum",
example: ("P2 + P3", "P5"),
precedence: 15,
n_args: 2,
op_type: Operator,
},
Op {
token: "-",
operator: "Diff",
example: ("P2 - P3", "N1"),
precedence: 15,
n_args: 2,
op_type: Operator,
},
Op {
token: "<<",
operator: "Shleft",
example: ("U1 << U5", "U32"),
precedence: 14,
n_args: 2,
op_type: Operator,
},
Op {
token: ">>",
operator: "Shright",
example: ("U32 >> U5", "U1"),
precedence: 14,
n_args: 2,
op_type: Operator,
},
Op {
token: "&",
operator: "And",
example: ("U5 & U3", "U1"),
precedence: 13,
n_args: 2,
op_type: Operator,
},
Op {
token: "^",
operator: "Xor",
example: ("U5 ^ U3", "U6"),
precedence: 12,
n_args: 2,
op_type: Operator,
},
Op {
token: "|",
operator: "Or",
example: ("U5 | U3", "U7"),
precedence: 11,
n_args: 2,
op_type: Operator,
},
Op {
token: "==",
operator: "Eq",
example: ("P5 == P3 + P2", "True"),
precedence: 10,
n_args: 2,
op_type: Operator,
},
Op {
token: "!=",
operator: "NotEq",
example: ("P5 != P3 + P2", "False"),
precedence: 10,
n_args: 2,
op_type: Operator,
},
Op {
token: "<=",
operator: "LeEq",
example: ("P6 <= P3 + P2", "False"),
precedence: 10,
n_args: 2,
op_type: Operator,
},
Op {
token: ">=",
operator: "GrEq",
example: ("P6 >= P3 + P2", "True"),
precedence: 10,
n_args: 2,
op_type: Operator,
},
Op {
token: "<",
operator: "Le",
example: ("P4 < P3 + P2", "True"),
precedence: 10,
n_args: 2,
op_type: Operator,
},
Op {
token: ">",
operator: "Gr",
example: ("P5 < P3 + P2", "False"),
precedence: 10,
n_args: 2,
op_type: Operator,
},
Op {
token: "cmp",
operator: "Compare",
example: ("cmp(P2, P3)", "Less"),
precedence: !0,
n_args: 2,
op_type: Function,
},
Op {
token: "sqr",
operator: "Square",
example: ("sqr(P2)", "P4"),
precedence: !0,
n_args: 1,
op_type: Function,
},
Op {
token: "sqrt",
operator: "Sqrt",
example: ("sqrt(U9)", "U3"),
precedence: !0,
n_args: 1,
op_type: Function,
},
Op {
token: "abs",
operator: "AbsVal",
example: ("abs(N2)", "P2"),
precedence: !0,
n_args: 1,
op_type: Function,
},
Op {
token: "cube",
operator: "Cube",
example: ("cube(P2)", "P8"),
precedence: !0,
n_args: 1,
op_type: Function,
},
Op {
token: "pow",
operator: "Exp",
example: ("pow(P2, P3)", "P8"),
precedence: !0,
n_args: 2,
op_type: Function,
},
Op {
token: "min",
operator: "Minimum",
example: ("min(P2, P3)", "P2"),
precedence: !0,
n_args: 2,
op_type: Function,
},
Op {
token: "max",
operator: "Maximum",
example: ("max(P2, P3)", "P3"),
precedence: !0,
n_args: 2,
op_type: Function,
},
Op {
token: "log2",
operator: "Log2",
example: ("log2(U9)", "U3"),
precedence: !0,
n_args: 1,
op_type: Function,
},
Op {
token: "gcd",
operator: "Gcf",
example: ("gcd(U9, U21)", "U3"),
precedence: !0,
n_args: 2,
op_type: Function,
},
];
use std::io::Write;
write!(
f,
"
/**
Convenient type operations.
Any types representing values must be able to be expressed as `ident`s. That means they need to be
in scope.
For example, `P5` is okay, but `typenum::P5` is not.
You may combine operators arbitrarily, although doing so excessively may require raising the
recursion limit.
# Example
```rust
#![recursion_limit=\"128\"]
#[macro_use] extern crate typenum;
use typenum::consts::*;
fn main() {{
assert_type!(
op!(min((P1 - P2) * (N3 + N7), P5 * (P3 + P4)) == P10)
);
}}
```
Operators are evaluated based on the operator precedence outlined
[here](https://doc.rust-lang.org/reference.html#operator-precedence).
The full list of supported operators and functions is as follows:
{}
They all expand to type aliases defined in the `operator_aliases` module. Here is an expanded list,
including examples:
",
ops.iter()
.map(|op| format!("`{}`", op.token))
.collect::<Vec<_>>()
.join(", ")
)?;
//write!(f, "Token | Alias | Example\n ===|===|===\n")?;
for op in ops.iter() {
write!(
f,
"---\nOperator `{token}`. Expands to `{operator}`.
```rust
# #[macro_use] extern crate typenum;
# use typenum::*;
# fn main() {{
assert_type_eq!(op!({ex0}), {ex1});
# }}
```\n
",
token = op.token,
operator = op.operator,
ex0 = op.example.0,
ex1 = op.example.1
)?;
}
write!(
f,
"*/
#[macro_export(local_inner_macros)]
macro_rules! op {{
($($tail:tt)*) => ( __op_internal__!($($tail)*) );
}}
#[doc(hidden)]
#[macro_export(local_inner_macros)]
macro_rules! __op_internal__ {{
"
)?;
// We first us the shunting-yard algorithm to produce our tokens in Polish notation.
// See: https://en.wikipedia.org/wiki/Shunting-yard_algorithm
// Note: Due to macro asymmetry, "the top of the stack" refers to the first element, not the
// last
// -----------------------------------------------------------------------------------------
// Stage 1: There are tokens to be read:
// -------
// Case 1: Token is a function => Push it onto the stack:
for fun in ops.iter().filter(|f| f.op_type == Function) {
write!(
f,
"
(@stack[$($stack:ident,)*] @queue[$($queue:ident,)*] @tail: {f_token} $($tail:tt)*) => (
__op_internal__!(@stack[{f_op}, $($stack,)*] @queue[$($queue,)*] @tail: $($tail)*)
);",
f_token = fun.token,
f_op = fun.operator
)?;
}
// -------
// Case 2: Token is a comma => Until the top of the stack is a LParen,
// Pop operators from stack to queue
// Base case: Top of stack is LParen, ditch comma and continue
write!(
f,
"
(@stack[LParen, $($stack:ident,)*] @queue[$($queue:ident,)*] @tail: , $($tail:tt)*) => (
__op_internal__!(@stack[LParen, $($stack,)*] @queue[$($queue,)*] @tail: $($tail)*)
);"
)?;
// Recursive case: Not LParen, pop from stack to queue
write!(
f,
"
(@stack[$stack_top:ident, $($stack:ident,)*] @queue[$($queue:ident,)*] @tail: , $($tail:tt)*) => (
__op_internal__!(@stack[$($stack,)*] @queue[$stack_top, $($queue,)*] @tail: , $($tail)*)
);"
)?;
// -------
// Case 3: Token is an operator, o1:
for o1 in ops.iter().filter(|op| op.op_type == Operator) {
// If top of stack is operator o2 with o1.precedence <= o2.precedence,
// Then pop o2 off stack onto queue:
for o2 in ops
.iter()
.filter(|op| op.op_type == Operator)
.filter(|o2| o1.precedence <= o2.precedence)
{
write!(
f,
"
(@stack[{o2_op}, $($stack:ident,)*] @queue[$($queue:ident,)*] @tail: {o1_token} $($tail:tt)*) => (
__op_internal__!(@stack[$($stack,)*] @queue[{o2_op}, $($queue,)*] @tail: {o1_token} $($tail)*)
);",
o2_op = o2.operator,
o1_token = o1.token
)?;
}
// Base case: push o1 onto stack
write!(
f,
"
(@stack[$($stack:ident,)*] @queue[$($queue:ident,)*] @tail: {o1_token} $($tail:tt)*) => (
__op_internal__!(@stack[{o1_op}, $($stack,)*] @queue[$($queue,)*] @tail: $($tail)*)
);",
o1_op = o1.operator,
o1_token = o1.token
)?;
}
// -------
// Case 4: Token is "(": push it onto stack as "LParen". Also convert the ")" to "RParen" to
// appease the macro gods:
write!(
f,
"
(@stack[$($stack:ident,)*] @queue[$($queue:ident,)*] @tail: ( $($stuff:tt)* ) $($tail:tt)* )
=> (
__op_internal__!(@stack[LParen, $($stack,)*] @queue[$($queue,)*]
@tail: $($stuff)* RParen $($tail)*)
);"
)?;
// -------
// Case 5: Token is "RParen":
// 1. Pop from stack to queue until we see an "LParen",
// 2. Kill the "LParen",
// 3. If the top of the stack is a function, pop it onto the queue
// 2. Base case:
write!(
f,
"
(@stack[LParen, $($stack:ident,)*] @queue[$($queue:ident,)*] @tail: RParen $($tail:tt)*) => (
__op_internal__!(@rp3 @stack[$($stack,)*] @queue[$($queue,)*] @tail: $($tail)*)
);"
)?;
// 1. Recursive case:
write!(
f,
"
(@stack[$stack_top:ident, $($stack:ident,)*] @queue[$($queue:ident,)*] @tail: RParen $($tail:tt)*)
=> (
__op_internal__!(@stack[$($stack,)*] @queue[$stack_top, $($queue,)*] @tail: RParen $($tail)*)
);"
)?;
// 3. Check for function:
for fun in ops.iter().filter(|f| f.op_type == Function) {
write!(
f,
"
(@rp3 @stack[{fun_op}, $($stack:ident,)*] @queue[$($queue:ident,)*] @tail: $($tail:tt)*) => (
__op_internal__!(@stack[$($stack,)*] @queue[{fun_op}, $($queue,)*] @tail: $($tail)*)
);",
fun_op = fun.operator
)?;
}
// 3. If no function found:
write!(
f,
"
(@rp3 @stack[$($stack:ident,)*] @queue[$($queue:ident,)*] @tail: $($tail:tt)*) => (
__op_internal__!(@stack[$($stack,)*] @queue[$($queue,)*] @tail: $($tail)*)
);"
)?;
// -------
// Case 6: Token is a number: Push it onto the queue
write!(
f,
"
(@stack[$($stack:ident,)*] @queue[$($queue:ident,)*] @tail: $num:ident $($tail:tt)*) => (
__op_internal__!(@stack[$($stack,)*] @queue[$num, $($queue,)*] @tail: $($tail)*)
);"
)?;
// -------
// Case 7: Out of tokens:
// Base case: Stack empty: Start evaluating
write!(
f,
"
(@stack[] @queue[$($queue:ident,)*] @tail: ) => (
__op_internal__!(@reverse[] @input: $($queue,)*)
);"
)?;
// Recursive case: Pop stack to queue
write!(
f,
"
(@stack[$stack_top:ident, $($stack:ident,)*] @queue[$($queue:ident,)*] @tail:) => (
__op_internal__!(@stack[$($stack,)*] @queue[$stack_top, $($queue,)*] @tail: )
);"
)?;
// -----------------------------------------------------------------------------------------
// Stage 2: Reverse so we have RPN
write!(
f,
"
(@reverse[$($revved:ident,)*] @input: $head:ident, $($tail:ident,)* ) => (
__op_internal__!(@reverse[$head, $($revved,)*] @input: $($tail,)*)
);"
)?;
write!(
f,
"
(@reverse[$($revved:ident,)*] @input: ) => (
__op_internal__!(@eval @stack[] @input[$($revved,)*])
);"
)?;
// -----------------------------------------------------------------------------------------
// Stage 3: Evaluate in Reverse Polish Notation
// Operators / Operators with 2 args:
for op in ops.iter().filter(|op| op.n_args == 2) {
// Note: We have to switch $a and $b here, otherwise non-commutative functions are backwards
write!(
f,
"
(@eval @stack[$a:ty, $b:ty, $($stack:ty,)*] @input[{op}, $($tail:ident,)*]) => (
__op_internal__!(@eval @stack[$crate::{op}<$b, $a>, $($stack,)*] @input[$($tail,)*])
);",
op = op.operator
)?;
}
// Operators with 1 arg:
for op in ops.iter().filter(|op| op.n_args == 1) {
write!(
f,
"
(@eval @stack[$a:ty, $($stack:ty,)*] @input[{op}, $($tail:ident,)*]) => (
__op_internal__!(@eval @stack[$crate::{op}<$a>, $($stack,)*] @input[$($tail,)*])
);",
op = op.operator
)?;
}
// Wasn't a function or operator, so must be a value => push onto stack
write!(
f,
"
(@eval @stack[$($stack:ty,)*] @input[$head:ident, $($tail:ident,)*]) => (
__op_internal__!(@eval @stack[$head, $($stack,)*] @input[$($tail,)*])
);"
)?;
// No input left:
write!(
f,
"
(@eval @stack[$stack:ty,] @input[]) => (
$stack
);"
)?;
// -----------------------------------------------------------------------------------------
// Stage 0: Get it started
write!(
f,
"
($($tail:tt)* ) => (
__op_internal__!(@stack[] @queue[] @tail: $($tail)*)
);"
)?;
write!(
f,
"
}}"
)?;
Ok(())
}

328
zeroidc/vendor/typenum/build/tests.rs vendored Normal file
View File

@ -0,0 +1,328 @@
use std::{env, fmt, fs, io, path};
use super::{gen_int, gen_uint};
/// Computes the greatest common divisor of two integers.
fn gcdi(mut a: i64, mut b: i64) -> i64 {
a = a.abs();
b = b.abs();
while a != 0 {
let tmp = b % a;
b = a;
a = tmp;
}
b
}
fn gcdu(mut a: u64, mut b: u64) -> u64 {
while a != 0 {
let tmp = b % a;
b = a;
a = tmp;
}
b
}
fn sign(i: i64) -> char {
use std::cmp::Ordering::*;
match i.cmp(&0) {
Greater => 'P',
Less => 'N',
Equal => '_',
}
}
struct UIntTest {
a: u64,
op: &'static str,
b: Option<u64>,
r: u64,
}
impl fmt::Display for UIntTest {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self.b {
Some(b) => write!(
f,
"
#[test]
#[allow(non_snake_case)]
fn test_{a}_{op}_{b}() {{
type A = {gen_a};
type B = {gen_b};
type U{r} = {result};
#[allow(non_camel_case_types)]
type U{a}{op}U{b} = <<A as {op}<B>>::Output as Same<U{r}>>::Output;
assert_eq!(<U{a}{op}U{b} as Unsigned>::to_u64(), <U{r} as Unsigned>::to_u64());
}}",
gen_a = gen_uint(self.a),
gen_b = gen_uint(b),
r = self.r,
result = gen_uint(self.r),
a = self.a,
b = b,
op = self.op
),
None => write!(
f,
"
#[test]
#[allow(non_snake_case)]
fn test_{a}_{op}() {{
type A = {gen_a};
type U{r} = {result};
#[allow(non_camel_case_types)]
type {op}U{a} = <<A as {op}>::Output as Same<U{r}>>::Output;
assert_eq!(<{op}U{a} as Unsigned>::to_u64(), <U{r} as Unsigned>::to_u64());
}}",
gen_a = gen_uint(self.a),
r = self.r,
result = gen_uint(self.r),
a = self.a,
op = self.op
),
}
}
}
fn uint_binary_test(left: u64, operator: &'static str, right: u64, result: u64) -> UIntTest {
UIntTest {
a: left,
op: operator,
b: Option::Some(right),
r: result,
}
}
// fn uint_unary_test(op: &'static str, a: u64, result: u64) -> UIntTest {
// UIntTest { a: a, op: op, b: Option::None, r: result }
// }
struct IntBinaryTest {
a: i64,
op: &'static str,
b: i64,
r: i64,
}
impl fmt::Display for IntBinaryTest {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(
f,
"
#[test]
#[allow(non_snake_case)]
fn test_{sa}{a}_{op}_{sb}{b}() {{
type A = {gen_a};
type B = {gen_b};
type {sr}{r} = {result};
#[allow(non_camel_case_types)]
type {sa}{a}{op}{sb}{b} = <<A as {op}<B>>::Output as Same<{sr}{r}>>::Output;
assert_eq!(<{sa}{a}{op}{sb}{b} as Integer>::to_i64(), <{sr}{r} as Integer>::to_i64());
}}",
gen_a = gen_int(self.a),
gen_b = gen_int(self.b),
r = self.r.abs(),
sr = sign(self.r),
result = gen_int(self.r),
a = self.a.abs(),
b = self.b.abs(),
sa = sign(self.a),
sb = sign(self.b),
op = self.op
)
}
}
fn int_binary_test(left: i64, operator: &'static str, right: i64, result: i64) -> IntBinaryTest {
IntBinaryTest {
a: left,
op: operator,
b: right,
r: result,
}
}
struct IntUnaryTest {
op: &'static str,
a: i64,
r: i64,
}
impl fmt::Display for IntUnaryTest {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(
f,
"
#[test]
#[allow(non_snake_case)]
fn test_{sa}{a}_{op}() {{
type A = {gen_a};
type {sr}{r} = {result};
#[allow(non_camel_case_types)]
type {op}{sa}{a} = <<A as {op}>::Output as Same<{sr}{r}>>::Output;
assert_eq!(<{op}{sa}{a} as Integer>::to_i64(), <{sr}{r} as Integer>::to_i64());
}}",
gen_a = gen_int(self.a),
r = self.r.abs(),
sr = sign(self.r),
result = gen_int(self.r),
a = self.a.abs(),
sa = sign(self.a),
op = self.op
)
}
}
fn int_unary_test(operator: &'static str, num: i64, result: i64) -> IntUnaryTest {
IntUnaryTest {
op: operator,
a: num,
r: result,
}
}
fn uint_cmp_test(a: u64, b: u64) -> String {
format!(
"
#[test]
#[allow(non_snake_case)]
fn test_{a}_Cmp_{b}() {{
type A = {gen_a};
type B = {gen_b};
#[allow(non_camel_case_types)]
type U{a}CmpU{b} = <A as Cmp<B>>::Output;
assert_eq!(<U{a}CmpU{b} as Ord>::to_ordering(), Ordering::{result:?});
}}",
a = a,
b = b,
gen_a = gen_uint(a),
gen_b = gen_uint(b),
result = a.cmp(&b)
)
}
fn int_cmp_test(a: i64, b: i64) -> String {
format!(
"
#[test]
#[allow(non_snake_case)]
fn test_{sa}{a}_Cmp_{sb}{b}() {{
type A = {gen_a};
type B = {gen_b};
#[allow(non_camel_case_types)]
type {sa}{a}Cmp{sb}{b} = <A as Cmp<B>>::Output;
assert_eq!(<{sa}{a}Cmp{sb}{b} as Ord>::to_ordering(), Ordering::{result:?});
}}",
a = a.abs(),
b = b.abs(),
sa = sign(a),
sb = sign(b),
gen_a = gen_int(a),
gen_b = gen_int(b),
result = a.cmp(&b)
)
}
// Allow for rustc 1.22 compatibility.
#[allow(bare_trait_objects)]
pub fn build_tests() -> Result<(), Box<::std::error::Error>> {
// will test all permutations of number pairs up to this (and down to its opposite for ints)
let high: i64 = 5;
let uints = (0u64..high as u64 + 1).flat_map(|a| (a..a + 1).cycle().zip(0..high as u64 + 1));
let ints = (-high..high + 1).flat_map(|a| (a..a + 1).cycle().zip(-high..high + 1));
let out_dir = env::var("OUT_DIR")?;
let dest = path::Path::new(&out_dir).join("tests.rs");
let f = fs::File::create(&dest)?;
let mut writer = io::BufWriter::new(&f);
use std::io::Write;
writer.write_all(
b"
extern crate typenum;
use std::ops::*;
use std::cmp::Ordering;
use typenum::*;
",
)?;
use std::cmp;
// uint operators:
for (a, b) in uints {
write!(writer, "{}", uint_binary_test(a, "BitAnd", b, a & b))?;
write!(writer, "{}", uint_binary_test(a, "BitOr", b, a | b))?;
write!(writer, "{}", uint_binary_test(a, "BitXor", b, a ^ b))?;
write!(writer, "{}", uint_binary_test(a, "Shl", b, a << b))?;
write!(writer, "{}", uint_binary_test(a, "Shr", b, a >> b))?;
write!(writer, "{}", uint_binary_test(a, "Add", b, a + b))?;
write!(writer, "{}", uint_binary_test(a, "Min", b, cmp::min(a, b)))?;
write!(writer, "{}", uint_binary_test(a, "Max", b, cmp::max(a, b)))?;
write!(writer, "{}", uint_binary_test(a, "Gcd", b, gcdu(a, b)))?;
if a >= b {
write!(writer, "{}", uint_binary_test(a, "Sub", b, a - b))?;
}
write!(writer, "{}", uint_binary_test(a, "Mul", b, a * b))?;
if b != 0 {
write!(writer, "{}", uint_binary_test(a, "Div", b, a / b))?;
write!(writer, "{}", uint_binary_test(a, "Rem", b, a % b))?;
if a % b == 0 {
write!(writer, "{}", uint_binary_test(a, "PartialDiv", b, a / b))?;
}
}
write!(writer, "{}", uint_binary_test(a, "Pow", b, a.pow(b as u32)))?;
write!(writer, "{}", uint_cmp_test(a, b))?;
}
// int operators:
for (a, b) in ints {
write!(writer, "{}", int_binary_test(a, "Add", b, a + b))?;
write!(writer, "{}", int_binary_test(a, "Sub", b, a - b))?;
write!(writer, "{}", int_binary_test(a, "Mul", b, a * b))?;
write!(writer, "{}", int_binary_test(a, "Min", b, cmp::min(a, b)))?;
write!(writer, "{}", int_binary_test(a, "Max", b, cmp::max(a, b)))?;
write!(writer, "{}", int_binary_test(a, "Gcd", b, gcdi(a, b)))?;
if b != 0 {
write!(writer, "{}", int_binary_test(a, "Div", b, a / b))?;
write!(writer, "{}", int_binary_test(a, "Rem", b, a % b))?;
if a % b == 0 {
write!(writer, "{}", int_binary_test(a, "PartialDiv", b, a / b))?;
}
}
if b >= 0 || a.abs() == 1 {
let result = if b < 0 {
if a == 1 {
a
} else if a == -1 {
a.pow((-b) as u32)
} else {
unreachable!()
}
} else {
a.pow(b as u32)
};
write!(writer, "{}", int_binary_test(a, "Pow", b, result))?;
}
write!(writer, "{}", int_cmp_test(a, b))?;
}
// int unary operators:
for n in -high..high + 1 {
write!(writer, "{}", int_unary_test("Neg", n, -n))?;
write!(writer, "{}", int_unary_test("Abs", n, n.abs()))?;
}
writer.flush()?;
Ok(())
}