<commit_before>use crate::common::CodegenCx;
use crate::coverageinfo;
use crate::llvm;

use llvm::coverageinfo::CounterMappingRegion;
use rustc_codegen_ssa::coverageinfo::map::{Counter, CounterExpression};
use rustc_codegen_ssa::traits::{BaseTypeMethods, ConstMethods};
use rustc_data_structures::fx::FxIndexSet;
use rustc_llvm::RustString;
use rustc_middle::mir::coverage::CodeRegion;

use std::ffi::CString;

use tracing::debug;

/// Generates and exports the Coverage Map.
///
/// This Coverage Map complies with Coverage Mapping Format version 3 (zero-based encoded as 2),
/// as defined at [LLVM Code Coverage Mapping Format](https://github.com/rust-lang/llvm-project/blob/llvmorg-8.0.0/llvm/docs/CoverageMappingFormat.rst#llvm-code-coverage-mapping-format)
/// and published in Rust's current (July 2020) fork of LLVM. This version is supported by the
/// LLVM coverage tools (`llvm-profdata` and `llvm-cov`) bundled with Rust's fork of LLVM.
///
/// Consequently, Rust's bundled version of Clang also generates Coverage Maps compliant with
/// version 3. Clang's implementation of Coverage Map generation was referenced when implementing
/// this Rust version, and though the format documentation is very explicit and detailed, some
/// undocumented details in Clang's implementation (that may or may not be important) were also
/// replicated for Rust's Coverage Map.
pub fn finalize<'ll, 'tcx>(cx: &CodegenCx<'ll, 'tcx>) {
    if cx.coverage_context().is_none() {
        return;
    }
    let function_coverage_map = cx.coverage_context().unwrap().take_function_coverage_map();
    if function_coverage_map.is_empty() {
        // This module has no functions with coverage instrumentation
        return;
    }

    let mut mapgen = CoverageMapGenerator::new();

    // Encode coverage mappings and generate function records
    let mut function_records = Vec::<&'ll llvm::Value>::new();
    let coverage_mappings_buffer = llvm::build_byte_buffer(|coverage_mappings_buffer| {
        for (instance, function_coverage) in function_coverage_map.into_iter() {
            debug!("Generate coverage map for: {:?}", instance);

            let mangled_function_name = cx.tcx.symbol_name(instance).to_string();
            let function_source_hash = function_coverage.source_hash();
            let (expressions, counter_regions) =
                function_coverage.get_expressions_and_counter_regions();

            let old_len = coverage_mappings_buffer.len();
            mapgen.write_coverage_mappings(expressions, counter_regions, coverage_mappings_buffer);
            let mapping_data_size = coverage_mappings_buffer.len() - old_len;
            debug_assert!(
                mapping_data_size > 0,
                "Every `FunctionCoverage` should have at least one counter"
            );

            let function_record = mapgen.make_function_record(
                cx,
                mangled_function_name,
                function_source_hash,
                mapping_data_size,
            );
            function_records.push(function_record);
        }
    });

    // Encode all filenames referenced by counters/expressions in this module
    let filenames_buffer = llvm::build_byte_buffer(|filenames_buffer| {
        coverageinfo::write_filenames_section_to_buffer(&mapgen.filenames, filenames_buffer);
    });

    // Generate the LLVM IR representation of the coverage map and store it in a well-known global
    mapgen.save_generated_coverage_map(
        cx,
        function_records,
        filenames_buffer,
        coverage_mappings_buffer,
    );
}

struct CoverageMapGenerator {
    filenames: FxIndexSet<CString>,
}

impl CoverageMapGenerator {
    fn new() -> Self {
        Self { filenames: FxIndexSet::default() }
    }

    /// Using the `expressions` and `counter_regions` collected for the current function, generate
    /// the `mapping_regions` and `virtual_file_mapping`, and capture any new filenames. Then use
    /// LLVM APIs to encode the `virtual_file_mapping`, `expressions`, and `mapping_regions` into
    /// the given `coverage_mappings` byte buffer, compliant with the LLVM Coverage Mapping format.
    fn write_coverage_mappings(
        &mut self,
        expressions: Vec<CounterExpression>,
        counter_regions: impl Iterator<Item = (Counter, &'a CodeRegion)>,
        coverage_mappings_buffer: &RustString,
    ) {
        let mut counter_regions = counter_regions.collect::<Vec<_>>();
        if counter_regions.is_empty() {
            return;
        }

        let mut virtual_file_mapping = Vec::new();
        let mut mapping_regions = Vec::new();
        let mut current_file_name = None;
        let mut current_file_id = 0;

        // Convert the list of (Counter, CodeRegion) pairs to an array of `CounterMappingRegion`, sorted
        // by filename and position. Capture any new files to compute the `CounterMappingRegion`s
        // `file_id` (indexing files referenced by the current function), and construct the
        // function-specific `virtual_file_mapping` from `file_id` to its index in the module's
        // `filenames` array.
        counter_regions.sort_unstable_by_key(|(_counter, region)| *region);
        for (counter, region) in counter_regions {
            let CodeRegion { file_name, start_line, start_col, end_line, end_col } = *region;
            let same_file = current_file_name.as_ref().map_or(false, |p| *p == file_name);
            if !same_file {
                if current_file_name.is_some() {
                    current_file_id += 1;
                }
                current_file_name = Some(file_name);
                let c_filename = CString::new(file_name.to_string())
                    .expect("null error converting filename to C string");
                debug!("  file_id: {} = '{:?}'", current_file_id, c_filename);
                let (filenames_index, _) = self.filenames.insert_full(c_filename);
                virtual_file_mapping.push(filenames_index as u32);
            }
            debug!("Adding counter {:?} to map for {:?}", counter, region,);
            mapping_regions.push(CounterMappingRegion::code_region(
                counter,
                current_file_id,
                start_line,
                start_col,
                end_line,
                end_col,
            ));
        }

        // Encode and append the current function's coverage mapping data
        coverageinfo::write_mapping_to_buffer(
            virtual_file_mapping,
            expressions,
            mapping_regions,
            coverage_mappings_buffer,
        );
    }

    /// Generate and return the function record `Value`
    fn make_function_record(
        &mut self,
        cx: &CodegenCx<'ll, 'tcx>,
        mangled_function_name: String,
        function_source_hash: u64,
        mapping_data_size: usize,
    ) -> &'ll llvm::Value {
        let name_ref = coverageinfo::compute_hash(&mangled_function_name);
        let name_ref_val = cx.const_u64(name_ref);
        let mapping_data_size_val = cx.const_u32(mapping_data_size as u32);
        let func_hash_val = cx.const_u64(function_source_hash);
        cx.const_struct(
            &[name_ref_val, mapping_data_size_val, func_hash_val],
            /*packed=*/ true,
        )
    }

    /// Combine the filenames and coverage mappings buffers, construct coverage map header and the
    /// array of function records, and combine everything into the complete coverage map. Save the
    /// coverage map data into the LLVM IR as a static global using a specific, well-known section
    /// and name.
    fn save_generated_coverage_map(
        self,
        cx: &CodegenCx<'ll, 'tcx>,
        function_records: Vec<&'ll llvm::Value>,
        filenames_buffer: Vec<u8>,
        mut coverage_mappings_buffer: Vec<u8>,
    ) {
        // Concatenate the encoded filenames and encoded coverage mappings, and add additional zero
        // bytes as-needed to ensure 8-byte alignment.
        let mut coverage_size = coverage_mappings_buffer.len();
        let filenames_size = filenames_buffer.len();
        let remaining_bytes =
            (filenames_size + coverage_size) % coverageinfo::COVMAP_VAR_ALIGN_BYTES;
        if remaining_bytes > 0 {
            let pad = coverageinfo::COVMAP_VAR_ALIGN_BYTES - remaining_bytes;
            coverage_mappings_buffer.append(&mut [0].repeat(pad));
            coverage_size += pad;
        }
        let filenames_and_coverage_mappings = [filenames_buffer, coverage_mappings_buffer].concat();
        let filenames_and_coverage_mappings_val =
            cx.const_bytes(&filenames_and_coverage_mappings[..]);

        debug!(
            "cov map: n_records = {}, filenames_size = {}, coverage_size = {}, 0-based version = {}",
            function_records.len(),
            filenames_size,
            coverage_size,
            coverageinfo::mapping_version()
        );

        // Create the coverage data header
        let n_records_val = cx.const_u32(function_records.len() as u32);
        let filenames_size_val = cx.const_u32(filenames_size as u32);
        let coverage_size_val = cx.const_u32(coverage_size as u32);
        let version_val = cx.const_u32(coverageinfo::mapping_version());
        let cov_data_header_val = cx.const_struct(
            &[n_records_val, filenames_size_val, coverage_size_val, version_val],
            /*packed=*/ false,
        );

        // Create the function records array
        let name_ref_from_u64 = cx.type_i64();
        let mapping_data_size_from_u32 = cx.type_i32();
        let func_hash_from_u64 = cx.type_i64();
        let function_record_ty = cx.type_struct(
            &[name_ref_from_u64, mapping_data_size_from_u32, func_hash_from_u64],
            /*packed=*/ true,
        );
        let function_records_val = cx.const_array(function_record_ty, &function_records[..]);

        // Create the complete LLVM coverage data value to add to the LLVM IR
        let cov_data_val = cx.const_struct(
            &[cov_data_header_val, function_records_val, filenames_and_coverage_mappings_val],
            /*packed=*/ false,
        );

        // Save the coverage data value to LLVM IR
        coverageinfo::save_map_to_mod(cx, cov_data_val);
    }
}
<commit_msg>Update compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs<commit_after>use crate::common::CodegenCx;
use crate::coverageinfo;
use crate::llvm;

use llvm::coverageinfo::CounterMappingRegion;
use rustc_codegen_ssa::coverageinfo::map::{Counter, CounterExpression};
use rustc_codegen_ssa::traits::{BaseTypeMethods, ConstMethods};
use rustc_data_structures::fx::FxIndexSet;
use rustc_llvm::RustString;
use rustc_middle::mir::coverage::CodeRegion;

use std::ffi::CString;

use tracing::debug;

/// Generates and exports the Coverage Map.
///
/// This Coverage Map complies with Coverage Mapping Format version 3 (zero-based encoded as 2),
/// as defined at [LLVM Code Coverage Mapping Format](https://github.com/rust-lang/llvm-project/blob/llvmorg-8.0.0/llvm/docs/CoverageMappingFormat.rst#llvm-code-coverage-mapping-format)
/// and published in Rust's current (July 2020) fork of LLVM. This version is supported by the
/// LLVM coverage tools (`llvm-profdata` and `llvm-cov`) bundled with Rust's fork of LLVM.
///
/// Consequently, Rust's bundled version of Clang also generates Coverage Maps compliant with
/// version 3. Clang's implementation of Coverage Map generation was referenced when implementing
/// this Rust version, and though the format documentation is very explicit and detailed, some
/// undocumented details in Clang's implementation (that may or may not be important) were also
/// replicated for Rust's Coverage Map.
pub fn finalize<'ll, 'tcx>(cx: &CodegenCx<'ll, 'tcx>) {
    let function_coverage_map = match cx.coverage_context() {
        Some(ctx) => ctx.take_function_coverage_map(),
        None => return,
    };
    if function_coverage_map.is_empty() {
        // This module has no functions with coverage instrumentation
        return;
    }

    let mut mapgen = CoverageMapGenerator::new();

    // Encode coverage mappings and generate function records
    let mut function_records = Vec::<&'ll llvm::Value>::new();
    let coverage_mappings_buffer = llvm::build_byte_buffer(|coverage_mappings_buffer| {
        for (instance, function_coverage) in function_coverage_map.into_iter() {
            debug!("Generate coverage map for: {:?}", instance);

            let mangled_function_name = cx.tcx.symbol_name(instance).to_string();
            let function_source_hash = function_coverage.source_hash();
            let (expressions, counter_regions) =
                function_coverage.get_expressions_and_counter_regions();

            let old_len = coverage_mappings_buffer.len();
            mapgen.write_coverage_mappings(expressions, counter_regions, coverage_mappings_buffer);
            let mapping_data_size = coverage_mappings_buffer.len() - old_len;
            debug_assert!(
                mapping_data_size > 0,
                "Every `FunctionCoverage` should have at least one counter"
            );

            let function_record = mapgen.make_function_record(
                cx,
                mangled_function_name,
                function_source_hash,
                mapping_data_size,
            );
            function_records.push(function_record);
        }
    });

    // Encode all filenames referenced by counters/expressions in this module
    let filenames_buffer = llvm::build_byte_buffer(|filenames_buffer| {
        coverageinfo::write_filenames_section_to_buffer(&mapgen.filenames, filenames_buffer);
    });

    // Generate the LLVM IR representation of the coverage map and store it in a well-known global
    mapgen.save_generated_coverage_map(
        cx,
        function_records,
        filenames_buffer,
        coverage_mappings_buffer,
    );
}

struct CoverageMapGenerator {
    filenames: FxIndexSet<CString>,
}

impl CoverageMapGenerator {
    fn new() -> Self {
        Self { filenames: FxIndexSet::default() }
    }

    /// Using the `expressions` and `counter_regions` collected for the current function, generate
    /// the `mapping_regions` and `virtual_file_mapping`, and capture any new filenames. Then use
    /// LLVM APIs to encode the `virtual_file_mapping`, `expressions`, and `mapping_regions` into
    /// the given `coverage_mappings` byte buffer, compliant with the LLVM Coverage Mapping format.
    fn write_coverage_mappings(
        &mut self,
        expressions: Vec<CounterExpression>,
        counter_regions: impl Iterator<Item = (Counter, &'a CodeRegion)>,
        coverage_mappings_buffer: &RustString,
    ) {
        let mut counter_regions = counter_regions.collect::<Vec<_>>();
        if counter_regions.is_empty() {
            return;
        }

        let mut virtual_file_mapping = Vec::new();
        let mut mapping_regions = Vec::new();
        let mut current_file_name = None;
        let mut current_file_id = 0;

        // Convert the list of (Counter, CodeRegion) pairs to an array of `CounterMappingRegion`, sorted
        // by filename and position. Capture any new files to compute the `CounterMappingRegion`s
        // `file_id` (indexing files referenced by the current function), and construct the
        // function-specific `virtual_file_mapping` from `file_id` to its index in the module's
        // `filenames` array.
        counter_regions.sort_unstable_by_key(|(_counter, region)| *region);
        for (counter, region) in counter_regions {
            let CodeRegion { file_name, start_line, start_col, end_line, end_col } = *region;
            let same_file = current_file_name.as_ref().map_or(false, |p| *p == file_name);
            if !same_file {
                if current_file_name.is_some() {
                    current_file_id += 1;
                }
                current_file_name = Some(file_name);
                let c_filename = CString::new(file_name.to_string())
                    .expect("null error converting filename to C string");
                debug!("  file_id: {} = '{:?}'", current_file_id, c_filename);
                let (filenames_index, _) = self.filenames.insert_full(c_filename);
                virtual_file_mapping.push(filenames_index as u32);
            }
            debug!("Adding counter {:?} to map for {:?}", counter, region,);
            mapping_regions.push(CounterMappingRegion::code_region(
                counter,
                current_file_id,
                start_line,
                start_col,
                end_line,
                end_col,
            ));
        }

        // Encode and append the current function's coverage mapping data
        coverageinfo::write_mapping_to_buffer(
            virtual_file_mapping,
            expressions,
            mapping_regions,
            coverage_mappings_buffer,
        );
    }

    /// Generate and return the function record `Value`
    fn make_function_record(
        &mut self,
        cx: &CodegenCx<'ll, 'tcx>,
        mangled_function_name: String,
        function_source_hash: u64,
        mapping_data_size: usize,
    ) -> &'ll llvm::Value {
        let name_ref = coverageinfo::compute_hash(&mangled_function_name);
        let name_ref_val = cx.const_u64(name_ref);
        let mapping_data_size_val = cx.const_u32(mapping_data_size as u32);
        let func_hash_val = cx.const_u64(function_source_hash);
        cx.const_struct(
            &[name_ref_val, mapping_data_size_val, func_hash_val],
            /*packed=*/ true,
        )
    }

    /// Combine the filenames and coverage mappings buffers, construct coverage map header and the
    /// array of function records, and combine everything into the complete coverage map. Save the
    /// coverage map data into the LLVM IR as a static global using a specific, well-known section
    /// and name.
    fn save_generated_coverage_map(
        self,
        cx: &CodegenCx<'ll, 'tcx>,
        function_records: Vec<&'ll llvm::Value>,
        filenames_buffer: Vec<u8>,
        mut coverage_mappings_buffer: Vec<u8>,
    ) {
        // Concatenate the encoded filenames and encoded coverage mappings, and add additional zero
        // bytes as-needed to ensure 8-byte alignment.
        let mut coverage_size = coverage_mappings_buffer.len();
        let filenames_size = filenames_buffer.len();
        let remaining_bytes =
            (filenames_size + coverage_size) % coverageinfo::COVMAP_VAR_ALIGN_BYTES;
        if remaining_bytes > 0 {
            let pad = coverageinfo::COVMAP_VAR_ALIGN_BYTES - remaining_bytes;
            coverage_mappings_buffer.append(&mut [0].repeat(pad));
            coverage_size += pad;
        }
        let filenames_and_coverage_mappings = [filenames_buffer, coverage_mappings_buffer].concat();
        let filenames_and_coverage_mappings_val =
            cx.const_bytes(&filenames_and_coverage_mappings[..]);

        debug!(
            "cov map: n_records = {}, filenames_size = {}, coverage_size = {}, 0-based version = {}",
            function_records.len(),
            filenames_size,
            coverage_size,
            coverageinfo::mapping_version()
        );

        // Create the coverage data header
        let n_records_val = cx.const_u32(function_records.len() as u32);
        let filenames_size_val = cx.const_u32(filenames_size as u32);
        let coverage_size_val = cx.const_u32(coverage_size as u32);
        let version_val = cx.const_u32(coverageinfo::mapping_version());
        let cov_data_header_val = cx.const_struct(
            &[n_records_val, filenames_size_val, coverage_size_val, version_val],
            /*packed=*/ false,
        );

        // Create the function records array
        let name_ref_from_u64 = cx.type_i64();
        let mapping_data_size_from_u32 = cx.type_i32();
        let func_hash_from_u64 = cx.type_i64();
        let function_record_ty = cx.type_struct(
            &[name_ref_from_u64, mapping_data_size_from_u32, func_hash_from_u64],
            /*packed=*/ true,
        );
        let function_records_val = cx.const_array(function_record_ty, &function_records[..]);

        // Create the complete LLVM coverage data value to add to the LLVM IR
        let cov_data_val = cx.const_struct(
            &[cov_data_header_val, function_records_val, filenames_and_coverage_mappings_val],
            /*packed=*/ false,
        );

        // Save the coverage data value to LLVM IR
        coverageinfo::save_map_to_mod(cx, cov_data_val);
    }
}
<|endoftext|>


<commit_before>// run-pass

#![feature(const_mut_refs)]

struct Foo {
    x: usize
}

const fn bar(foo: &mut Foo) -> usize {
    let x = &mut foo.x;
    *x = 1;
    *x
}

fn main() {
    let _: [(); bar(&mut Foo { x: 0 })] = [(); 1];
}
<commit_msg>Extend test for const_mut_refs feature<commit_after>// run-pass

#![feature(const_mut_refs)]

struct Foo {
    x: usize
}

const fn foo() -> Foo {
    Foo { x: 0 }
}

impl Foo {
    const fn bar(&mut self) -> usize {
        self.x = 1;
        self.x
    }

}

const fn baz(foo: &mut Foo) -> usize {
    let x = &mut foo.x;
    *x = 2;
    *x
}

const fn bazz(foo: &mut Foo) -> usize {
    foo.x = 3;
    foo.x
}

fn main() {
    let _: [(); foo().bar()] = [(); 1];
    let _: [(); baz(&mut foo())] = [(); 2];
    let _: [(); bazz(&mut foo())] = [(); 3];
}
<|endoftext|>


<commit_before>// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

struct Foo(bool);
const NEW_FALSE: bool = false;
const STATIC_FOO: Foo = Foo(NEW_FALSE);

pub fn main() {
    match (Foo(false)) {
        STATIC_FOO => 3,
        _ => 11
    };
}
<commit_msg>Remove duplicate test case<commit_after><|endoftext|>


<commit_before>// run-pass
#![feature(existential_type)]

existential type A: Iterator;
fn def_a() -> A { 0..1 }
pub fn use_a() {
    def_a().map(|x| x);
}

fn main() {}
<commit_msg>Change to check-pass<commit_after>// check-pass
#![feature(existential_type)]

existential type A: Iterator;
fn def_a() -> A { 0..1 }
pub fn use_a() {
    def_a().map(|x| x);
}

fn main() {}
<|endoftext|>


<commit_before>// Rust on bare metal - Tested with Rust 1.0.0
// Uses Pure64 to get into a 64-bit SMP state
// rustc -O --crate-type lib -o kernel64.o --emit obj kernel64.rs
// ld -T app.ld -o kernel64.sys kernel64.o

#[no_mangle]
pub fn main() {
    clear_screen(Color::LightBlue);
    loop {
		// Loop forever
    }
}

#[derive(Copy,Clone)]
enum Color {
    Black       = 0,
    Blue        = 1,
    Green       = 2,
    Cyan        = 3,
    Red         = 4,
    Pink        = 5,
    Brown       = 6,
    LightGray   = 7,
    DarkGray    = 8,
    LightBlue   = 9,
    LightGreen  = 10,
    LightCyan   = 11,
    LightRed    = 12,
    LightPink   = 13,
    Yello       = 14,
    White       = 15,
}

fn clear_screen(background: Color) {
    for x in 0 .. 80*25 {
        unsafe {
            *((0xb8000 + x * 2) as *mut u16) = (background as u16) << 12;
        }
    }
}
<commit_msg>use pointer functionality instead of casting<commit_after>// Rust on bare metal - Tested with Rust 1.0.0
// Uses Pure64 to get into a 64-bit SMP state
// rustc -O --crate-type lib -o kernel64.o --emit obj kernel64.rs
// ld -T app.ld -o kernel64.sys kernel64.o

const BUF_VIDEO: *mut u16 = 0xb8000 as *mut u16;

#[no_mangle]
pub fn main() {
    clear_screen(Color::LightBlue);
    loop {
        // Loop forever
    }
}

#[derive(Copy,Clone)]
enum Color {
    Black       = 0,
    Blue        = 1,
    Green       = 2,
    Cyan        = 3,
    Red         = 4,
    Pink        = 5,
    Brown       = 6,
    LightGray   = 7,
    DarkGray    = 8,
    LightBlue   = 9,
    LightGreen  = 10,
    LightCyan   = 11,
    LightRed    = 12,
    LightPink   = 13,
    Yello       = 14,
    White       = 15,
}

fn clear_screen(background: Color) {
    for x in 0 .. 80*25 {
        unsafe {
            std::ptr::write(BUF_VIDEO.offset(x),(background as u16) << 12);
        }
    }
}
<|endoftext|>


<commit_before>use crate::utils::{match_def_path, paths, snippet, span_lint_and_sugg};
use if_chain::if_chain;
use rustc_errors::Applicability;
use rustc_hir::{Expr, ExprKind};
use rustc_lint::{LateContext, LateLintPass};
use rustc_session::{declare_lint_pass, declare_tool_lint};

declare_clippy_lint! {
    /// **What it does:** Checks usage of `std::fs::create_dir` and suggest using `std::fs::create_dir_all` instead.
    ///
    /// **Why is this bad?** Sometimes `std::fs::crate_dir` is mistakenly chosen over `std::fs::create_dir_all`.
    ///
    /// **Known problems:** None.
    ///
    /// **Example:**
    ///
    /// ```rust
    /// std::fs::create_dir("foo");
    /// ```
    /// Use instead:
    /// ```rust
    /// std::fs::create_dir_all("foo");
    /// ```
    pub CREATE_DIR,
    restriction,
    "calling `std::fs::create_dir` instead of `std::fs::create_dir_all`"
}

declare_lint_pass!(CreateDir => [CREATE_DIR]);

impl LateLintPass<'_> for CreateDir {
    fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) {
        if_chain! {
            if let ExprKind::Call(ref func, ref args) = expr.kind;
            if let ExprKind::Path(ref path) = func.kind;
            if let Some(def_id) = cx.qpath_res(path, func.hir_id).opt_def_id();
            if match_def_path(cx, def_id, &paths::STD_FS_CREATE_DIR);
            then {
                span_lint_and_sugg(
                    cx,
                    CREATE_DIR,
                    expr.span,
                    "calling `std::fs::create_dir` where there may be a better way",
                    "consider calling `std::fs::create_dir_all` instead",
                    format!("create_dir_all({})", snippet(cx, args[0].span, "..")),
                    Applicability::MaybeIncorrect,
                )
            }
        }
    }
}
<commit_msg>Typo: std::fs::crate_dir -> std::fs::create_dir<commit_after>use crate::utils::{match_def_path, paths, snippet, span_lint_and_sugg};
use if_chain::if_chain;
use rustc_errors::Applicability;
use rustc_hir::{Expr, ExprKind};
use rustc_lint::{LateContext, LateLintPass};
use rustc_session::{declare_lint_pass, declare_tool_lint};

declare_clippy_lint! {
    /// **What it does:** Checks usage of `std::fs::create_dir` and suggest using `std::fs::create_dir_all` instead.
    ///
    /// **Why is this bad?** Sometimes `std::fs::create_dir` is mistakenly chosen over `std::fs::create_dir_all`.
    ///
    /// **Known problems:** None.
    ///
    /// **Example:**
    ///
    /// ```rust
    /// std::fs::create_dir("foo");
    /// ```
    /// Use instead:
    /// ```rust
    /// std::fs::create_dir_all("foo");
    /// ```
    pub CREATE_DIR,
    restriction,
    "calling `std::fs::create_dir` instead of `std::fs::create_dir_all`"
}

declare_lint_pass!(CreateDir => [CREATE_DIR]);

impl LateLintPass<'_> for CreateDir {
    fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) {
        if_chain! {
            if let ExprKind::Call(ref func, ref args) = expr.kind;
            if let ExprKind::Path(ref path) = func.kind;
            if let Some(def_id) = cx.qpath_res(path, func.hir_id).opt_def_id();
            if match_def_path(cx, def_id, &paths::STD_FS_CREATE_DIR);
            then {
                span_lint_and_sugg(
                    cx,
                    CREATE_DIR,
                    expr.span,
                    "calling `std::fs::create_dir` where there may be a better way",
                    "consider calling `std::fs::create_dir_all` instead",
                    format!("create_dir_all({})", snippet(cx, args[0].span, "..")),
                    Applicability::MaybeIncorrect,
                )
            }
        }
    }
}
<|endoftext|>


<commit_before>// Copyright (C) 2018, Cloudflare, Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright notice,
//       this list of conditions and the following disclaimer.
//
//     * Redistributions in binary form must reproduce the above copyright
//       notice, this list of conditions and the following disclaimer in the
//       documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

use std::io::BufRead;

use regex::Regex;

use protobuf::Message;

fn main() {
    let mut args = std::env::args();
    args.next();

    let log_file = args.next().unwrap();
    let trace_file = args.next().unwrap();

    let inp = std::fs::File::open(log_file).unwrap();
    let mut out = std::fs::File::create(trace_file).unwrap();

    let mut trace = quic_trace::Trace::new();

    trace.set_protocol_version(b"AAAA".to_vec());

    // Log prefix.
    let prefix_re = Regex::new(r"^\[(.*) TRACE quiche.*\]").unwrap();

    // Packet events.
    let pkt_re = Regex::new(
        r"(rx|tx) pkt (Initial|Handshake|Application) .* len=(\d+) pn=(\d+)",
    )
    .unwrap();
    let lost_re = Regex::new(r"packet (\d+) lost on epoch (\d)").unwrap();

    let rec_re =
        Regex::new(r"timer=(.*) crypto=(.*) inflight=(.*) cwnd=(.*) latest_rtt=(.*) srtt=(.*) min_rtt=(.*) rttvar=(.*) probes=(\d+)").unwrap();

    // Frame events.
    let stream_frm_re = Regex::new(
        r"(rx|tx) frm STREAM id=(\d+) off=(\d+) len=(\d+) fin=(true|false)",
    )
    .unwrap();
    let ack_frm_re =
        Regex::new(r"(rx|tx) frm ACK delay=(.*) blocks=\[(.*)\]").unwrap();
    let close_frm_re = Regex::new(
        r"(rx|tx) frm (APPLICATION|CONNECTION)_CLOSE err=(\d+) reason=",
    )
    .unwrap();

    let mut start_time = None;

    let mut events = Vec::new();

    let mut event: Option<quic_trace::Event> = None;

    let file = std::io::BufReader::new(&inp);
    for (_, line) in file.lines().enumerate() {
        let l = line.unwrap();

        let time = match prefix_re.captures(&l) {
            Some(caps) => {
                let s = caps.get(1).unwrap().as_str();
                humantime::parse_rfc3339(s).unwrap()
            },

            None => continue,
        };

        if start_time.is_none() {
            start_time = Some(time);
        }

        if let Some(caps) = pkt_re.captures(&l) {
            // Flush previous event.
            if event.is_some() {
                events.push(event.unwrap());
            }

            let mut ev = quic_trace::Event::new();

            let time_us = time.duration_since(start_time.unwrap()).unwrap();
            ev.set_time_us(time_us.as_micros() as u64);

            let ty = match caps.get(1).unwrap().as_str() {
                "rx" => quic_trace::EventType::PACKET_RECEIVED,
                "tx" => quic_trace::EventType::PACKET_SENT,
                _ => unreachable!(),
            };
            ev.set_event_type(ty);

            let ty = caps.get(2).unwrap().as_str();
            ev.set_encryption_level(str_to_enc_level(ty));

            let len = caps.get(3).unwrap().as_str();
            ev.set_packet_size(len.parse::<u64>().unwrap());

            let pn = caps.get(4).unwrap().as_str();
            ev.set_packet_number(pn.parse::<u64>().unwrap());

            event = Some(ev);
            continue;
        }

        if let Some(caps) = lost_re.captures(&l) {
            let mut ev = quic_trace::Event::new();

            let time_us = time.duration_since(start_time.unwrap()).unwrap();
            ev.set_time_us(time_us.as_micros() as u64);

            ev.set_event_type(quic_trace::EventType::PACKET_LOST);

            let pn = caps.get(1).unwrap().as_str();
            ev.set_packet_number(pn.parse::<u64>().unwrap());

            let ty = caps.get(2).unwrap().as_str().parse::<u64>().unwrap();
            ev.set_encryption_level(int_to_enc_level(ty));

            events.push(ev);
            continue;
        }

        if let Some(caps) = rec_re.captures(&l) {
            if event.is_none() {
                unreachable!();
            }

            let mut state = quic_trace::TransportState::new();

            let inflight = caps.get(3).unwrap().as_str();
            state.set_in_flight_bytes(inflight.parse::<u64>().unwrap());

            let cwnd = caps.get(4).unwrap().as_str();
            state.set_cwnd_bytes(cwnd.parse::<u64>().unwrap());

            let latest_rtt = caps.get(5).unwrap().as_str();
            let latest_rtt = str_to_duration(latest_rtt);
            state.set_last_rtt_us(latest_rtt.as_micros() as u64);

            let srtt = caps.get(6).unwrap().as_str();
            let srtt = if srtt == "None" {
                std::time::Duration::from_micros(0)
            } else {
                let srtt = &srtt[5..srtt.len() - 1];
                str_to_duration(srtt)
            };
            state.set_smoothed_rtt_us(srtt.as_micros() as u64);

            let min_rtt = caps.get(7).unwrap().as_str();
            let min_rtt = str_to_duration(min_rtt);
            state.set_smoothed_rtt_us(min_rtt.as_micros() as u64);

            event.as_mut().unwrap().set_transport_state(state);
            continue;
        }

        if let Some(caps) = stream_frm_re.captures(&l) {
            let mut frame = quic_trace::Frame::new();
            frame.set_frame_type(quic_trace::FrameType::STREAM);

            let mut info = quic_trace::StreamFrameInfo::new();

            let id = caps.get(2).unwrap().as_str();
            info.set_stream_id(id.parse::<u64>().unwrap());

            let off = caps.get(3).unwrap().as_str();
            info.set_offset(off.parse::<u64>().unwrap());

            let len = caps.get(4).unwrap().as_str();
            info.set_length(len.parse::<u64>().unwrap());

            let fin = caps.get(5).unwrap().as_str();
            match fin {
                "true" => info.set_fin(true),
                "false" => info.set_fin(false),
                _ => unreachable!(),
            }

            frame.set_stream_frame_info(info);

            event.as_mut().unwrap().mut_frames().push(frame);
            continue;
        }

        if let Some(caps) = ack_frm_re.captures(&l) {
            let mut frame = quic_trace::Frame::new();
            frame.set_frame_type(quic_trace::FrameType::ACK);

            let mut info = quic_trace::AckInfo::new();

            let delay = caps.get(2).unwrap().as_str();
            let delay = delay.parse::<u64>().unwrap() * 2_u64.pow(3_u32);
            info.set_ack_delay_us(delay);

            let mut blocks = Vec::new();

            let ranges = caps.get(3).unwrap().as_str();
            for r in ranges.split(", ") {
                let mut block = quic_trace::AckBlock::new();

                let mut parts = r.split("..");
                block.set_first_packet(
                    parts.next().unwrap().parse::<u64>().unwrap(),
                );
                block.set_last_packet(
                    parts.next().unwrap().parse::<u64>().unwrap(),
                );

                blocks.push(block);
            }

            info.set_acked_packets(protobuf::RepeatedField::from_vec(blocks));

            frame.set_ack_info(info);

            event.as_mut().unwrap().mut_frames().push(frame);
            continue;
        }

        if let Some(caps) = close_frm_re.captures(&l) {
            let mut frame = quic_trace::Frame::new();
            frame.set_frame_type(quic_trace::FrameType::CONNECTION_CLOSE);

            let mut info = quic_trace::CloseInfo::new();

            let err = caps.get(3).unwrap().as_str();
            info.set_error_code(u32::from_str_radix(err, 16).unwrap());

            frame.set_close_info(info);

            event.as_mut().unwrap().mut_frames().push(frame);
            continue;
        }
    }

    println!("Generated {} events", events.len());

    trace.set_events(protobuf::RepeatedField::from_vec(events));

    let mut cos = protobuf::CodedOutputStream::new(&mut out);
    trace.write_to(&mut cos).unwrap();
    cos.flush().unwrap();
}

fn str_to_enc_level(ty: &str) -> quic_trace::EncryptionLevel {
    match ty {
        "Initial" => quic_trace::EncryptionLevel::ENCRYPTION_INITIAL,
        "Handshake" => quic_trace::EncryptionLevel::ENCRYPTION_HANDSHAKE,
        "Application" => quic_trace::EncryptionLevel::ENCRYPTION_1RTT,
        _ => unreachable!(),
    }
}

fn int_to_enc_level(ty: u64) -> quic_trace::EncryptionLevel {
    match ty {
        0 => quic_trace::EncryptionLevel::ENCRYPTION_INITIAL,
        1 => quic_trace::EncryptionLevel::ENCRYPTION_HANDSHAKE,
        2 => quic_trace::EncryptionLevel::ENCRYPTION_1RTT,
        _ => unreachable!(),
    }
}

fn str_to_duration(d: &str) -> std::time::Duration {
    if let Ok(d) = humantime::parse_duration(d) {
        return d;
    }

    // humantime doesn't support parsing float duration, so do it manually.
    let end = d.chars().position(|c| !c.is_numeric() && c != '.').unwrap();
    let num = (&d[..end]).parse::<f64>().unwrap();
    let unit = &d[end..];

    let num = match unit {
        "s" => num,
        "ms" => num / 1_000_f64,
        "us" => num / 1_000_000_f64,
        "µs" => num / 1_000_000_f64,
        "ns" => num / 1_000_000_000_f64,
        _ => unreachable!(),
    };

    std::time::Duration::from_secs_f64(num)
}

mod quic_trace;
<commit_msg>quic-trace-log: fix unnecessary_unwrap clippy warning<commit_after>// Copyright (C) 2018, Cloudflare, Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright notice,
//       this list of conditions and the following disclaimer.
//
//     * Redistributions in binary form must reproduce the above copyright
//       notice, this list of conditions and the following disclaimer in the
//       documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

use std::io::BufRead;

use regex::Regex;

use protobuf::Message;

fn main() {
    let mut args = std::env::args();
    args.next();

    let log_file = args.next().unwrap();
    let trace_file = args.next().unwrap();

    let inp = std::fs::File::open(log_file).unwrap();
    let mut out = std::fs::File::create(trace_file).unwrap();

    let mut trace = quic_trace::Trace::new();

    trace.set_protocol_version(b"AAAA".to_vec());

    // Log prefix.
    let prefix_re = Regex::new(r"^\[(.*) TRACE quiche.*\]").unwrap();

    // Packet events.
    let pkt_re = Regex::new(
        r"(rx|tx) pkt (Initial|Handshake|Application) .* len=(\d+) pn=(\d+)",
    )
    .unwrap();
    let lost_re = Regex::new(r"packet (\d+) lost on epoch (\d)").unwrap();

    let rec_re =
        Regex::new(r"timer=(.*) crypto=(.*) inflight=(.*) cwnd=(.*) latest_rtt=(.*) srtt=(.*) min_rtt=(.*) rttvar=(.*) probes=(\d+)").unwrap();

    // Frame events.
    let stream_frm_re = Regex::new(
        r"(rx|tx) frm STREAM id=(\d+) off=(\d+) len=(\d+) fin=(true|false)",
    )
    .unwrap();
    let ack_frm_re =
        Regex::new(r"(rx|tx) frm ACK delay=(.*) blocks=\[(.*)\]").unwrap();
    let close_frm_re = Regex::new(
        r"(rx|tx) frm (APPLICATION|CONNECTION)_CLOSE err=(\d+) reason=",
    )
    .unwrap();

    let mut start_time = None;

    let mut events = Vec::new();

    let mut event: Option<quic_trace::Event> = None;

    let file = std::io::BufReader::new(&inp);
    for (_, line) in file.lines().enumerate() {
        let l = line.unwrap();

        let time = match prefix_re.captures(&l) {
            Some(caps) => {
                let s = caps.get(1).unwrap().as_str();
                humantime::parse_rfc3339(s).unwrap()
            },

            None => continue,
        };

        if start_time.is_none() {
            start_time = Some(time);
        }

        if let Some(caps) = pkt_re.captures(&l) {
            // Flush previous event.
            if let Some(event) = event {
                events.push(event);
            }

            let mut ev = quic_trace::Event::new();

            let time_us = time.duration_since(start_time.unwrap()).unwrap();
            ev.set_time_us(time_us.as_micros() as u64);

            let ty = match caps.get(1).unwrap().as_str() {
                "rx" => quic_trace::EventType::PACKET_RECEIVED,
                "tx" => quic_trace::EventType::PACKET_SENT,
                _ => unreachable!(),
            };
            ev.set_event_type(ty);

            let ty = caps.get(2).unwrap().as_str();
            ev.set_encryption_level(str_to_enc_level(ty));

            let len = caps.get(3).unwrap().as_str();
            ev.set_packet_size(len.parse::<u64>().unwrap());

            let pn = caps.get(4).unwrap().as_str();
            ev.set_packet_number(pn.parse::<u64>().unwrap());

            event = Some(ev);
            continue;
        }

        if let Some(caps) = lost_re.captures(&l) {
            let mut ev = quic_trace::Event::new();

            let time_us = time.duration_since(start_time.unwrap()).unwrap();
            ev.set_time_us(time_us.as_micros() as u64);

            ev.set_event_type(quic_trace::EventType::PACKET_LOST);

            let pn = caps.get(1).unwrap().as_str();
            ev.set_packet_number(pn.parse::<u64>().unwrap());

            let ty = caps.get(2).unwrap().as_str().parse::<u64>().unwrap();
            ev.set_encryption_level(int_to_enc_level(ty));

            events.push(ev);
            continue;
        }

        if let Some(caps) = rec_re.captures(&l) {
            if event.is_none() {
                unreachable!();
            }

            let mut state = quic_trace::TransportState::new();

            let inflight = caps.get(3).unwrap().as_str();
            state.set_in_flight_bytes(inflight.parse::<u64>().unwrap());

            let cwnd = caps.get(4).unwrap().as_str();
            state.set_cwnd_bytes(cwnd.parse::<u64>().unwrap());

            let latest_rtt = caps.get(5).unwrap().as_str();
            let latest_rtt = str_to_duration(latest_rtt);
            state.set_last_rtt_us(latest_rtt.as_micros() as u64);

            let srtt = caps.get(6).unwrap().as_str();
            let srtt = if srtt == "None" {
                std::time::Duration::from_micros(0)
            } else {
                let srtt = &srtt[5..srtt.len() - 1];
                str_to_duration(srtt)
            };
            state.set_smoothed_rtt_us(srtt.as_micros() as u64);

            let min_rtt = caps.get(7).unwrap().as_str();
            let min_rtt = str_to_duration(min_rtt);
            state.set_smoothed_rtt_us(min_rtt.as_micros() as u64);

            event.as_mut().unwrap().set_transport_state(state);
            continue;
        }

        if let Some(caps) = stream_frm_re.captures(&l) {
            let mut frame = quic_trace::Frame::new();
            frame.set_frame_type(quic_trace::FrameType::STREAM);

            let mut info = quic_trace::StreamFrameInfo::new();

            let id = caps.get(2).unwrap().as_str();
            info.set_stream_id(id.parse::<u64>().unwrap());

            let off = caps.get(3).unwrap().as_str();
            info.set_offset(off.parse::<u64>().unwrap());

            let len = caps.get(4).unwrap().as_str();
            info.set_length(len.parse::<u64>().unwrap());

            let fin = caps.get(5).unwrap().as_str();
            match fin {
                "true" => info.set_fin(true),
                "false" => info.set_fin(false),
                _ => unreachable!(),
            }

            frame.set_stream_frame_info(info);

            event.as_mut().unwrap().mut_frames().push(frame);
            continue;
        }

        if let Some(caps) = ack_frm_re.captures(&l) {
            let mut frame = quic_trace::Frame::new();
            frame.set_frame_type(quic_trace::FrameType::ACK);

            let mut info = quic_trace::AckInfo::new();

            let delay = caps.get(2).unwrap().as_str();
            let delay = delay.parse::<u64>().unwrap() * 2_u64.pow(3_u32);
            info.set_ack_delay_us(delay);

            let mut blocks = Vec::new();

            let ranges = caps.get(3).unwrap().as_str();
            for r in ranges.split(", ") {
                let mut block = quic_trace::AckBlock::new();

                let mut parts = r.split("..");
                block.set_first_packet(
                    parts.next().unwrap().parse::<u64>().unwrap(),
                );
                block.set_last_packet(
                    parts.next().unwrap().parse::<u64>().unwrap(),
                );

                blocks.push(block);
            }

            info.set_acked_packets(protobuf::RepeatedField::from_vec(blocks));

            frame.set_ack_info(info);

            event.as_mut().unwrap().mut_frames().push(frame);
            continue;
        }

        if let Some(caps) = close_frm_re.captures(&l) {
            let mut frame = quic_trace::Frame::new();
            frame.set_frame_type(quic_trace::FrameType::CONNECTION_CLOSE);

            let mut info = quic_trace::CloseInfo::new();

            let err = caps.get(3).unwrap().as_str();
            info.set_error_code(u32::from_str_radix(err, 16).unwrap());

            frame.set_close_info(info);

            event.as_mut().unwrap().mut_frames().push(frame);
            continue;
        }
    }

    println!("Generated {} events", events.len());

    trace.set_events(protobuf::RepeatedField::from_vec(events));

    let mut cos = protobuf::CodedOutputStream::new(&mut out);
    trace.write_to(&mut cos).unwrap();
    cos.flush().unwrap();
}

fn str_to_enc_level(ty: &str) -> quic_trace::EncryptionLevel {
    match ty {
        "Initial" => quic_trace::EncryptionLevel::ENCRYPTION_INITIAL,
        "Handshake" => quic_trace::EncryptionLevel::ENCRYPTION_HANDSHAKE,
        "Application" => quic_trace::EncryptionLevel::ENCRYPTION_1RTT,
        _ => unreachable!(),
    }
}

fn int_to_enc_level(ty: u64) -> quic_trace::EncryptionLevel {
    match ty {
        0 => quic_trace::EncryptionLevel::ENCRYPTION_INITIAL,
        1 => quic_trace::EncryptionLevel::ENCRYPTION_HANDSHAKE,
        2 => quic_trace::EncryptionLevel::ENCRYPTION_1RTT,
        _ => unreachable!(),
    }
}

fn str_to_duration(d: &str) -> std::time::Duration {
    if let Ok(d) = humantime::parse_duration(d) {
        return d;
    }

    // humantime doesn't support parsing float duration, so do it manually.
    let end = d.chars().position(|c| !c.is_numeric() && c != '.').unwrap();
    let num = (&d[..end]).parse::<f64>().unwrap();
    let unit = &d[end..];

    let num = match unit {
        "s" => num,
        "ms" => num / 1_000_f64,
        "us" => num / 1_000_000_f64,
        "µs" => num / 1_000_000_f64,
        "ns" => num / 1_000_000_000_f64,
        _ => unreachable!(),
    };

    std::time::Duration::from_secs_f64(num)
}

mod quic_trace;
<|endoftext|>


<commit_before>// Copyright (c) 2016 The vulkano developers
// Licensed under the Apache License, Version 2.0
// <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT
// license <LICENSE-MIT or http://opensource.org/licenses/MIT>,
// at your option. All files in the project carrying such
// notice may not be copied, modified, or distributed except
// according to those terms.

#[macro_export]
macro_rules! merge_pipelines {
    ($($pipeline:ident,)+) => {
        use $crate::descriptor_set::pipeline_layout::PipelineLayout;

        pub struct MergedPipelines {
            inner: UnsafePipelineLayout
        }

        impl MergedPipelines {
            pub fn new() -> Result<Arc<MergedPipelines>, > {

            }
        }

        unsafe impl trait PipelineLayout for MergedPipelines {
            #[inline]
            fn inner_pipeline_layout(&self) -> &UnsafePipelineLayout {
                &self.inner
            }
        }
    };
}
<commit_msg>Remove merge module<commit_after><|endoftext|>


<commit_before>#![feature(rustc_private)]

extern crate rustc_codegen_ssa;
extern crate rustc_errors;
extern crate rustc_middle;
#[macro_use]
extern crate rustc_data_structures;
extern crate rustc_driver;
extern crate rustc_hir;
extern crate rustc_session;
extern crate rustc_span;
extern crate rustc_symbol_mangling;
extern crate rustc_target;

use rustc_codegen_ssa::traits::CodegenBackend;
use rustc_data_structures::owning_ref::OwningRef;
use rustc_data_structures::sync::MetadataRef;
use rustc_errors::ErrorReported;
use rustc_middle::dep_graph::DepGraph;
use rustc_middle::middle::cstore::{EncodedMetadata, MetadataLoader, MetadataLoaderDyn};
use rustc_middle::ty::query::Providers;
use rustc_middle::ty::TyCtxt;
use rustc_session::config::OutputFilenames;
use rustc_session::Session;
use rustc_span::symbol::Symbol;
use rustc_target::spec::Target;
use std::any::Any;
use std::path::Path;
use std::sync::Arc;

pub struct NoLlvmMetadataLoader;

impl MetadataLoader for NoLlvmMetadataLoader {
    fn get_rlib_metadata(&self, _: &Target, filename: &Path) -> Result<MetadataRef, String> {
        let buf =
            std::fs::read(filename).map_err(|e| format!("metadata file open err: {:?}", e))?;
        let buf: OwningRef<Vec<u8>, [u8]> = OwningRef::new(buf);
        Ok(rustc_erase_owner!(buf.map_owner_box()))
    }

    fn get_dylib_metadata(&self, target: &Target, filename: &Path) -> Result<MetadataRef, String> {
        self.get_rlib_metadata(target, filename)
    }
}

struct TheBackend;

impl CodegenBackend for TheBackend {
    fn metadata_loader(&self) -> Box<MetadataLoaderDyn> {
        Box::new(NoLlvmMetadataLoader)
    }

    fn provide(&self, providers: &mut Providers) {
        rustc_symbol_mangling::provide(providers);

        providers.target_features_whitelist = |tcx, _cnum| {
            tcx.arena.alloc(Default::default()) // Just a dummy
        };
        providers.is_reachable_non_generic = |_tcx, _defid| true;
        providers.exported_symbols = |_tcx, _crate| Arc::new(Vec::new());
    }

    fn provide_extern(&self, providers: &mut Providers) {
        providers.is_reachable_non_generic = |_tcx, _defid| true;
    }

    fn codegen_crate<'a, 'tcx>(
        &self,
        tcx: TyCtxt<'tcx>,
        _metadata: EncodedMetadata,
        _need_metadata_module: bool,
    ) -> Box<dyn Any> {
        use rustc_hir::def_id::LOCAL_CRATE;

        Box::new(tcx.crate_name(LOCAL_CRATE) as Symbol)
    }

    fn join_codegen(
        &self,
        ongoing_codegen: Box<dyn Any>,
        _sess: &Session,
        _dep_graph: &DepGraph,
    ) -> Result<Box<dyn Any>, ErrorReported> {
        let crate_name = ongoing_codegen
            .downcast::<Symbol>()
            .expect("in join_codegen: ongoing_codegen is not a Symbol");
        Ok(crate_name)
    }

    fn link(
        &self,
        sess: &Session,
        codegen_results: Box<dyn Any>,
        outputs: &OutputFilenames,
    ) -> Result<(), ErrorReported> {
        use rustc_session::{config::CrateType, output::out_filename};
        use std::io::Write;
        let crate_name =
            codegen_results.downcast::<Symbol>().expect("in link: codegen_results is not a Symbol");
        for &crate_type in sess.opts.crate_types.iter() {
            if crate_type != CrateType::Rlib {
                sess.fatal(&format!("Crate type is {:?}", crate_type));
            }
            let output_name = out_filename(sess, crate_type, &outputs, &*crate_name.as_str());
            let mut out_file = ::std::fs::File::create(output_name).unwrap();
            write!(out_file, "This has been \"compiled\" successfully.").unwrap();
        }
        Ok(())
    }
}

/// This is the entrypoint for a hot plugged rustc_codegen_llvm
#[no_mangle]
pub fn __rustc_codegen_backend() -> Box<dyn CodegenBackend> {
    Box::new(TheBackend)
}
<commit_msg>Fix test.<commit_after>#![feature(rustc_private)]

extern crate rustc_codegen_ssa;
extern crate rustc_errors;
extern crate rustc_middle;
#[macro_use]
extern crate rustc_data_structures;
extern crate rustc_driver;
extern crate rustc_hir;
extern crate rustc_session;
extern crate rustc_span;
extern crate rustc_symbol_mangling;
extern crate rustc_target;

use rustc_codegen_ssa::traits::CodegenBackend;
use rustc_data_structures::owning_ref::OwningRef;
use rustc_data_structures::sync::MetadataRef;
use rustc_errors::ErrorReported;
use rustc_middle::dep_graph::DepGraph;
use rustc_middle::middle::cstore::{EncodedMetadata, MetadataLoader, MetadataLoaderDyn};
use rustc_middle::ty::query::Providers;
use rustc_middle::ty::TyCtxt;
use rustc_session::config::OutputFilenames;
use rustc_session::Session;
use rustc_span::symbol::Symbol;
use rustc_target::spec::Target;
use std::any::Any;
use std::path::Path;

pub struct NoLlvmMetadataLoader;

impl MetadataLoader for NoLlvmMetadataLoader {
    fn get_rlib_metadata(&self, _: &Target, filename: &Path) -> Result<MetadataRef, String> {
        let buf =
            std::fs::read(filename).map_err(|e| format!("metadata file open err: {:?}", e))?;
        let buf: OwningRef<Vec<u8>, [u8]> = OwningRef::new(buf);
        Ok(rustc_erase_owner!(buf.map_owner_box()))
    }

    fn get_dylib_metadata(&self, target: &Target, filename: &Path) -> Result<MetadataRef, String> {
        self.get_rlib_metadata(target, filename)
    }
}

struct TheBackend;

impl CodegenBackend for TheBackend {
    fn metadata_loader(&self) -> Box<MetadataLoaderDyn> {
        Box::new(NoLlvmMetadataLoader)
    }

    fn provide(&self, providers: &mut Providers) {
        rustc_symbol_mangling::provide(providers);

        providers.target_features_whitelist = |tcx, _cnum| {
            tcx.arena.alloc(Default::default()) // Just a dummy
        };
        providers.is_reachable_non_generic = |_tcx, _defid| true;
        providers.exported_symbols = |_tcx, _crate| &[];
    }

    fn provide_extern(&self, providers: &mut Providers) {
        providers.is_reachable_non_generic = |_tcx, _defid| true;
    }

    fn codegen_crate<'a, 'tcx>(
        &self,
        tcx: TyCtxt<'tcx>,
        _metadata: EncodedMetadata,
        _need_metadata_module: bool,
    ) -> Box<dyn Any> {
        use rustc_hir::def_id::LOCAL_CRATE;

        Box::new(tcx.crate_name(LOCAL_CRATE) as Symbol)
    }

    fn join_codegen(
        &self,
        ongoing_codegen: Box<dyn Any>,
        _sess: &Session,
        _dep_graph: &DepGraph,
    ) -> Result<Box<dyn Any>, ErrorReported> {
        let crate_name = ongoing_codegen
            .downcast::<Symbol>()
            .expect("in join_codegen: ongoing_codegen is not a Symbol");
        Ok(crate_name)
    }

    fn link(
        &self,
        sess: &Session,
        codegen_results: Box<dyn Any>,
        outputs: &OutputFilenames,
    ) -> Result<(), ErrorReported> {
        use rustc_session::{config::CrateType, output::out_filename};
        use std::io::Write;
        let crate_name =
            codegen_results.downcast::<Symbol>().expect("in link: codegen_results is not a Symbol");
        for &crate_type in sess.opts.crate_types.iter() {
            if crate_type != CrateType::Rlib {
                sess.fatal(&format!("Crate type is {:?}", crate_type));
            }
            let output_name = out_filename(sess, crate_type, &outputs, &*crate_name.as_str());
            let mut out_file = ::std::fs::File::create(output_name).unwrap();
            write!(out_file, "This has been \"compiled\" successfully.").unwrap();
        }
        Ok(())
    }
}

/// This is the entrypoint for a hot plugged rustc_codegen_llvm
#[no_mangle]
pub fn __rustc_codegen_backend() -> Box<dyn CodegenBackend> {
    Box::new(TheBackend)
}
<|endoftext|>


<commit_before>use cipher::block::{BlockFn, BlockCipher};
use cipher::block::feistel::Feistel;
use secret::Secret;
use truncate::Truncate;

use typenum::consts::U16;

struct SubKey {
    // The top 16 bits are 0
    key: Secret<u64>
}

struct DesRound {
    key: SubKey
}

impl BlockFn for DesRound {
    type Block = Secret<u32>;
    fn encrypt(&self, block: Secret<u32>) -> Secret<u32> {
        permute(substitute(expand(block) ^ self.key.key))
    }
}

pub struct Des {
    inner: Feistel<DesRound, U16>
}

impl BlockFn for Des {
    type Block = Secret<u64>;
    fn encrypt(&self, block: Secret<u64>) -> Secret<u64> {
        final_permute(join_block(self.inner.encrypt(split_block(initial_permute(block)))))
    }
}

impl BlockCipher for Des {
    fn decrypt(&self, block: Secret<u64>) -> Secret<u64> {
        final_permute(join_block(self.inner.decrypt(split_block(initial_permute(block)))))
    }
}

fn split_block(block: Secret<u64>) -> (Secret<u32>, Secret<u32>) {
    (block.truncate(), (block >> 32).truncate())
}

fn join_block(parts: (Secret<u32>, Secret<u32>)) -> Secret<u64> {
    Secret::<u64>::from(parts.0) | (Secret::<u64>::from(parts.1) << 32)
}

fn run_permutation(perm: &[u8], val: Secret<u64>) -> Secret<u64> {
    let mut out = Secret::new(0);
    for (i, src) in perm.iter().enumerate() {
        out |= ((val >> (*src as usize - 1)) & 1) << i;
    }
    out
}

// See FIPS Publication 46-3, Appendix 1
const INITIAL_PERMUTATION: [u8; 64] = [
    58, 50, 42, 34, 26, 18, 10, 2,
    60, 52, 44, 36, 28, 20, 12, 4,
    62, 54, 46, 38, 30, 22, 14, 6,
    64, 56, 48, 40, 32, 24, 16, 8,
    57, 49, 41, 33, 25, 17, 9,  1,
    59, 51, 43, 35, 27, 19, 11, 3,
    61, 53, 45, 37, 29, 21, 13, 5,
    63, 55, 47, 39, 31, 23, 15, 7
];

// Inverse of final_permute
fn initial_permute(block: Secret<u64>) -> Secret<u64> {
    run_permutation(&INITIAL_PERMUTATION, block)
}

// See FIPS Publication 46-3, Appendix 1
const FINAL_PERMUTATION: [u8; 64] = [
    40, 8, 48, 16, 56, 24, 64, 32,
    39, 7, 47, 15, 55, 23, 63, 31,
    38, 6, 46, 14, 54, 22, 62, 30,
	37, 5, 45, 13, 53, 21, 61, 29,
	36, 4, 44, 12, 52, 20, 60, 28,
	35, 3, 43, 11, 51, 19, 59, 27,
	34, 2, 42, 10, 50, 18, 58, 26,
	33, 1, 41, 9,  49, 17, 57, 25
];

// Inverse of initial_permute
fn final_permute(block: Secret<u64>) -> Secret<u64> {
    run_permutation(&FINAL_PERMUTATION, block)
}

// See FIPS Publication 46-3, Appendix 1
const EXPANSION_PERMUTATION: [u8; 48] = [
	32, 1,  2,  3,  4,  5,
	4,  5,  6,  7,  8,  9,
	8,  9,  10, 11, 12, 13,
	12, 13, 14, 15, 16, 17,
	16, 17, 18, 19, 20, 21,
	20, 21, 22, 23, 24, 25,
	24, 25, 26, 27, 28, 29,
	28, 29, 30, 31, 32, 1
];

// Returns 48 bits
fn expand(half_block: Secret<u32>) -> Secret<u64> {
    run_permutation(&EXPANSION_PERMUTATION, Secret::<u64>::from(half_block))
}

// Takes 48 bits
fn substitute(block: Secret<u64>) -> Secret<u32> {
    unimplemented!()
}

// See FIPS Publication 46-3, Appendix 1
const ROUND_PERMUTATION: [u8; 32] = [
	16, 7,  20, 21, 29, 12, 28, 17,
	1,  15, 23, 26, 5,  18, 31, 10,
	2,  8,  24, 14, 32, 27, 3,  9,
	19, 13, 30, 6,  22, 11, 4,  25
];

fn permute(block: Secret<u32>) -> Secret<u32> {
    run_permutation(&ROUND_PERMUTATION, Secret::<u64>::from(block)).truncate()
}

#[cfg(test)]
mod tests {
    use super::{initial_permute, final_permute};

    use secret::Secret;

    #[test]
    fn initial_final_inverses() {
        for i in 0..64 {
            let val = 1 << i;
            assert_eq!(final_permute(initial_permute(Secret::new(val))).expose(), val);
            assert_eq!(initial_permute(final_permute(Secret::new(val))).expose(), val);
        }
    }
}
<commit_msg>Move tables for DES into a submodule<commit_after>use cipher::block::{BlockFn, BlockCipher};
use cipher::block::feistel::Feistel;
use secret::Secret;
use truncate::Truncate;

use typenum::consts::U16;

struct SubKey {
    // The top 16 bits are 0
    key: Secret<u64>
}

struct DesRound {
    key: SubKey
}

impl BlockFn for DesRound {
    type Block = Secret<u32>;
    fn encrypt(&self, block: Secret<u32>) -> Secret<u32> {
        permute(substitute(expand(block) ^ self.key.key))
    }
}

pub struct Des {
    inner: Feistel<DesRound, U16>
}

impl BlockFn for Des {
    type Block = Secret<u64>;
    fn encrypt(&self, block: Secret<u64>) -> Secret<u64> {
        final_permute(join_block(self.inner.encrypt(split_block(initial_permute(block)))))
    }
}

impl BlockCipher for Des {
    fn decrypt(&self, block: Secret<u64>) -> Secret<u64> {
        final_permute(join_block(self.inner.decrypt(split_block(initial_permute(block)))))
    }
}

fn split_block(block: Secret<u64>) -> (Secret<u32>, Secret<u32>) {
    (block.truncate(), (block >> 32).truncate())
}

fn join_block(parts: (Secret<u32>, Secret<u32>)) -> Secret<u64> {
    Secret::<u64>::from(parts.0) | (Secret::<u64>::from(parts.1) << 32)
}

fn run_permutation(perm: &[u8], val: Secret<u64>) -> Secret<u64> {
    let mut out = Secret::new(0);
    for (i, src) in perm.iter().enumerate() {
        out |= ((val >> (*src as usize - 1)) & 1) << i;
    }
    out
}

// Inverse of final_permute
fn initial_permute(block: Secret<u64>) -> Secret<u64> {
    run_permutation(&tables::INITIAL_PERMUTATION, block)
}

// Inverse of initial_permute
fn final_permute(block: Secret<u64>) -> Secret<u64> {
    run_permutation(&tables::FINAL_PERMUTATION, block)
}

// Returns 48 bits
fn expand(half_block: Secret<u32>) -> Secret<u64> {
    run_permutation(&tables::EXPANSION_PERMUTATION, Secret::<u64>::from(half_block))
}

// Takes 48 bits
fn substitute(block: Secret<u64>) -> Secret<u32> {
    unimplemented!()
}

fn permute(block: Secret<u32>) -> Secret<u32> {
    run_permutation(&tables::ROUND_PERMUTATION, Secret::<u64>::from(block)).truncate()
}

// See FIPS Publication 46-3, Appendix 1
mod tables {
    pub const INITIAL_PERMUTATION: [u8; 64] = [
	    58, 50, 42, 34, 26, 18, 10, 2,
	    60, 52, 44, 36, 28, 20, 12, 4,
	    62, 54, 46, 38, 30, 22, 14, 6,
	    64, 56, 48, 40, 32, 24, 16, 8,
	    57, 49, 41, 33, 25, 17, 9,  1,
	    59, 51, 43, 35, 27, 19, 11, 3,
        61, 53, 45, 37, 29, 21, 13, 5,
        63, 55, 47, 39, 31, 23, 15, 7
    ];

    pub const FINAL_PERMUTATION: [u8; 64] = [
       40, 8, 48, 16, 56, 24, 64, 32,
       39, 7, 47, 15, 55, 23, 63, 31,
       38, 6, 46, 14, 54, 22, 62, 30,
       37, 5, 45, 13, 53, 21, 61, 29,
       36, 4, 44, 12, 52, 20, 60, 28,
       35, 3, 43, 11, 51, 19, 59, 27,
       34, 2, 42, 10, 50, 18, 58, 26,
       33, 1, 41, 9,  49, 17, 57, 25
    ];

    pub const EXPANSION_PERMUTATION: [u8; 48] = [
        32, 1,  2,  3,  4,  5,
        4,  5,  6,  7,  8,  9,
        8,  9,  10, 11, 12, 13,
        12, 13, 14, 15, 16, 17,
        16, 17, 18, 19, 20, 21,
        20, 21, 22, 23, 24, 25,
        24, 25, 26, 27, 28, 29,
        28, 29, 30, 31, 32, 1
    ];

    pub const ROUND_PERMUTATION: [u8; 32] = [
        16, 7,  20, 21, 29, 12, 28, 17,
        1,  15, 23, 26, 5,  18, 31, 10,
        2,  8,  24, 14, 32, 27, 3,  9,
        19, 13, 30, 6,  22, 11, 4,  25
    ];
}

#[cfg(test)]
mod tests {
    use super::{initial_permute, final_permute};

    use secret::Secret;

    #[test]
    fn initial_final_inverses() {
        for i in 0..64 {
            let val = 1 << i;
            assert_eq!(final_permute(initial_permute(Secret::new(val))).expose(), val);
            assert_eq!(initial_permute(final_permute(Secret::new(val))).expose(), val);
        }
    }
}
<|endoftext|>


<commit_before>#![feature(core_intrinsics, rustc_attrs)]

use std::intrinsics::rustc_peek;

#[rustc_mir(rustc_peek_liveness, stop_after_dataflow)]
fn foo() {
    {
        let mut x: (i32, i32) = (42, 0);

        // Assignment to a projection does not cause `x` to become live
        unsafe { rustc_peek(x); } //~ ERROR bit not set
        x.1 = 42;

        x = (0, 42);

        // ...but a read from a projection does.
        unsafe { rustc_peek(x); }
        println!("{}", x.1);
    }

    {
        let mut x = 42;

        // Derefs are treated like a read of a local even if they are on the RHS of an assignment.
        let p = &mut x;
        unsafe { rustc_peek(&p); }
        *p = 24;
        unsafe { rustc_peek(&p); } //~ ERROR bit not set
    }
}

fn main() {}
<commit_msg>Fix comment.<commit_after>#![feature(core_intrinsics, rustc_attrs)]

use std::intrinsics::rustc_peek;

#[rustc_mir(rustc_peek_liveness, stop_after_dataflow)]
fn foo() {
    {
        let mut x: (i32, i32) = (42, 0);

        // Assignment to a projection does not cause `x` to become live
        unsafe { rustc_peek(x); } //~ ERROR bit not set
        x.1 = 42;

        x = (0, 42);

        // ...but a read from a projection does.
        unsafe { rustc_peek(x); }
        println!("{}", x.1);
    }

    {
        let mut x = 42;

        // Derefs are treated like a read of a local even if they are on the LHS of an assignment.
        let p = &mut x;
        unsafe { rustc_peek(&p); }
        *p = 24;
        unsafe { rustc_peek(&p); } //~ ERROR bit not set
    }
}

fn main() {}
<|endoftext|>


<commit_before>// Copyright (c) 2019 DDN. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.

use crate::{
    api_utils::{get, get_all, get_one},
    display_utils::{generate_table, wrap_fut},
    error::ImlManagerCliError,
    ostpool::{ostpool_cli, OstPoolCommand},
};
use futures::future::{try_join, try_join_all};
use iml_wire_types::{ApiList, Filesystem, FlatQuery, Mgt, Ost};
use number_formatter::{format_bytes, format_number};
use prettytable::{Row, Table};
use structopt::StructOpt;

#[derive(Debug, StructOpt)]
pub enum FilesystemCommand {
    /// List all configured filesystems
    #[structopt(name = "list")]
    List,
    /// Show filesystem
    #[structopt(name = "show")]
    Show {
        #[structopt(name = "FSNAME")]
        fsname: String,
    },
    /// Ost Pools
    #[structopt(name = "pool")]
    Pool {
        #[structopt(subcommand)]
        command: OstPoolCommand,
    },
}

fn usage(
    free: Option<f64>,
    total: Option<f64>,
    formatter: fn(f64, Option<usize>) -> String,
) -> String {
    match (free, total) {
        (Some(free), Some(total)) => format!(
            "{} / {}",
            formatter(total - free, Some(0)),
            formatter(total, Some(0))
        ),
        (None, Some(total)) => format!("Calculating ... / {}", formatter(total, Some(0))),
        _ => "Calculating ...".to_string(),
    }
}

pub async fn filesystem_cli(command: FilesystemCommand) -> Result<(), ImlManagerCliError> {
    match command {
        FilesystemCommand::List => {
            let filesystems: ApiList<Filesystem> =
                wrap_fut("Fetching filesystems...", get_all()).await?;

            tracing::debug!("FSs: {:?}", filesystems);

            let table = generate_table(
                &[
                    "Name", "State", "Space", "Inodes", "Clients", "MDTs", "OSTs",
                ],
                filesystems.objects.into_iter().map(|f| {
                    vec![
                        f.label,
                        f.state,
                        usage(f.bytes_free, f.bytes_total, format_bytes),
                        usage(f.files_free, f.files_total, format_number),
                        format_number(f.client_count.unwrap_or(0.0), Some(0)),
                        f.mdts.len().to_string(),
                        f.osts.len().to_string(),
                    ]
                }),
            );

            table.printstd();
        }
        FilesystemCommand::Show { fsname } => {
            let fs: Filesystem =
                wrap_fut("Fetching filesystem...", get_one(vec![("name", &fsname)])).await?;

            tracing::debug!("FS: {:?}", fs);

            let (mgt, osts): (Mgt, Vec<Ost>) = try_join(
                wrap_fut("Fetching MGT...", get(&fs.mgt, Mgt::query())),
                try_join_all(fs.osts.into_iter().map(|o| async move {
                    wrap_fut("Fetching OST...", get(&o, Ost::query())).await
                })),
            )
            .await?;

            let mut table = Table::new();
            table.add_row(Row::from(&["Name".to_string(), fs.label]));
            table.add_row(Row::from(&[
                "Space".to_string(),
                usage(fs.bytes_free, fs.bytes_total, format_bytes),
            ]));
            table.add_row(Row::from(&[
                "Inodes".to_string(),
                usage(fs.files_free, fs.files_total, format_number),
            ]));
            table.add_row(Row::from(&["State".to_string(), fs.state]));
            table.add_row(Row::from(&[
                "Management Server".to_string(),
                mgt.active_host_name,
            ]));

            let mdtnames: Vec<String> = fs.mdts.into_iter().map(|m| m.name).collect();
            table.add_row(Row::from(&["MDTs".to_string(), mdtnames.join("\n")]));

            let ostnames: Vec<String> = osts.into_iter().map(|m| m.name).collect();
            table.add_row(Row::from(&["OSTs".to_string(), ostnames.join("\n")]));

            table.add_row(Row::from(&[
                "Clients".to_string(),
                format!("{:0}", fs.client_count.unwrap_or(0.0)),
            ]));
            table.add_row(Row::from(&["Mount Path".to_string(), fs.mount_path]));
            table.printstd();
        }
        FilesystemCommand::Pool { command } => ostpool_cli(command).await?,
    };

    Ok(())
}
<commit_msg>Add filesystem detect command (#1616)<commit_after>// Copyright (c) 2019 DDN. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.

use crate::{
    api_utils::{
        create_command, get, get_all, get_hosts, get_one, wait_for_cmds, SendCmd, SendJob,
    },
    display_utils::{generate_table, wrap_fut},
    error::ImlManagerCliError,
    ostpool::{ostpool_cli, OstPoolCommand},
};
use futures::future::{try_join, try_join_all};
use iml_wire_types::{ApiList, Filesystem, FlatQuery, Mgt, Ost};
use number_formatter::{format_bytes, format_number};
use prettytable::{Row, Table};
use std::collections::BTreeMap;
use structopt::StructOpt;

#[derive(Debug, StructOpt)]
pub enum FilesystemCommand {
    /// List all configured filesystems
    #[structopt(name = "list")]
    List,
    /// Show filesystem
    #[structopt(name = "show")]
    Show {
        #[structopt(name = "FSNAME")]
        fsname: String,
    },
    /// Ost Pools
    #[structopt(name = "pool")]
    Pool {
        #[structopt(subcommand)]
        command: OstPoolCommand,
    },
    /// Detect existing filesystem
    #[structopt(name = "detect")]
    Detect {
        #[structopt(short, long)]
        hosts: Option<String>,
    },
}

#[derive(serde::Serialize)]
pub struct HostList {
    hosts: Vec<String>,
}

fn usage(
    free: Option<f64>,
    total: Option<f64>,
    formatter: fn(f64, Option<usize>) -> String,
) -> String {
    match (free, total) {
        (Some(free), Some(total)) => format!(
            "{} / {}",
            formatter(total - free, Some(0)),
            formatter(total, Some(0))
        ),
        (None, Some(total)) => format!("Calculating ... / {}", formatter(total, Some(0))),
        _ => "Calculating ...".to_string(),
    }
}

async fn detect_filesystem(hosts: Option<String>) -> Result<(), ImlManagerCliError> {
    let hosts = if let Some(hl) = hosts {
        let hostlist = hostlist_parser::parse(&hl)?;
        tracing::debug!("Host Names: {:?}", hostlist);
        let all_hosts = get_hosts().await?;

        let hostmap: BTreeMap<&str, &str> = all_hosts
            .objects
            .iter()
            .map(|h| {
                vec![
                    (h.nodename.as_str(), h.resource_uri.as_str()),
                    (h.fqdn.as_str(), h.resource_uri.as_str()),
                ]
            })
            .flatten()
            .collect();

        hostlist
            .iter()
            .filter_map(|h| hostmap.get(h.as_str()))
            .map(|x| (*x).to_string())
            .collect()
    } else {
        vec![]
    };

    tracing::debug!("Host APIs: {:?}", hosts);

    let cmd = SendCmd {
        message: "Detecting filesystems".into(),
        jobs: vec![SendJob {
            class_name: "DetectTargetsJob".into(),
            args: HostList { hosts },
        }],
    };
    let cmd = wrap_fut("Detecting filesystems...", create_command(cmd)).await?;

    wait_for_cmds(vec![cmd]).await?;
    Ok(())
}

pub async fn filesystem_cli(command: FilesystemCommand) -> Result<(), ImlManagerCliError> {
    match command {
        FilesystemCommand::List => {
            let filesystems: ApiList<Filesystem> =
                wrap_fut("Fetching filesystems...", get_all()).await?;

            tracing::debug!("FSs: {:?}", filesystems);

            let table = generate_table(
                &[
                    "Name", "State", "Space", "Inodes", "Clients", "MDTs", "OSTs",
                ],
                filesystems.objects.into_iter().map(|f| {
                    vec![
                        f.label,
                        f.state,
                        usage(f.bytes_free, f.bytes_total, format_bytes),
                        usage(f.files_free, f.files_total, format_number),
                        format_number(f.client_count.unwrap_or(0.0), Some(0)),
                        f.mdts.len().to_string(),
                        f.osts.len().to_string(),
                    ]
                }),
            );

            table.printstd();
        }
        FilesystemCommand::Show { fsname } => {
            let fs: Filesystem =
                wrap_fut("Fetching filesystem...", get_one(vec![("name", &fsname)])).await?;

            tracing::debug!("FS: {:?}", fs);

            let (mgt, osts): (Mgt, Vec<Ost>) = try_join(
                wrap_fut("Fetching MGT...", get(&fs.mgt, Mgt::query())),
                try_join_all(fs.osts.into_iter().map(|o| async move {
                    wrap_fut("Fetching OST...", get(&o, Ost::query())).await
                })),
            )
            .await?;

            let mut table = Table::new();
            table.add_row(Row::from(&["Name".to_string(), fs.label]));
            table.add_row(Row::from(&[
                "Space".to_string(),
                usage(fs.bytes_free, fs.bytes_total, format_bytes),
            ]));
            table.add_row(Row::from(&[
                "Inodes".to_string(),
                usage(fs.files_free, fs.files_total, format_number),
            ]));
            table.add_row(Row::from(&["State".to_string(), fs.state]));
            table.add_row(Row::from(&[
                "Management Server".to_string(),
                mgt.active_host_name,
            ]));

            let mdtnames: Vec<String> = fs.mdts.into_iter().map(|m| m.name).collect();
            table.add_row(Row::from(&["MDTs".to_string(), mdtnames.join("\n")]));

            let ostnames: Vec<String> = osts.into_iter().map(|m| m.name).collect();
            table.add_row(Row::from(&["OSTs".to_string(), ostnames.join("\n")]));

            table.add_row(Row::from(&[
                "Clients".to_string(),
                format!("{:0}", fs.client_count.unwrap_or(0.0)),
            ]));
            table.add_row(Row::from(&["Mount Path".to_string(), fs.mount_path]));
            table.printstd();
        }
        FilesystemCommand::Pool { command } => ostpool_cli(command).await?,
        FilesystemCommand::Detect { hosts } => detect_filesystem(hosts).await?,
    };

    Ok(())
}
<|endoftext|>


<commit_before>use criterion::{criterion_group, criterion_main, Criterion};
use std::fs::File;
use std::io::{Cursor, Read};

use octobuild::vs::postprocess;

fn filter_preprocessed_benchmark(c: &mut Criterion) {
    c.bench_function("filter_preprocessed", |b| {
        let mut source = Vec::new();
        File::open("tests/filter_preprocessed.i")
            .unwrap()
            .read_to_end(&mut source)
            .unwrap();
        let marker = Some("c:\\bozaro\\github\\octobuild\\test_cl\\sample.h".to_string());

        b.iter(|| {
            let mut result = Vec::with_capacity(source.len());
            postprocess::filter_preprocessed(
                &mut Cursor::new(source.clone()),
                &mut result,
                &marker,
                false,
            )
            .unwrap();
            result
        })
    });
}

criterion_group!(benches, filter_preprocessed_benchmark);
criterion_main!(benches);
<commit_msg>More Clippy fixes<commit_after>use std::fs;
use std::io::Cursor;

use criterion::{criterion_group, criterion_main, Criterion};

use octobuild::vs::postprocess;

fn filter_preprocessed_benchmark(c: &mut Criterion) {
    c.bench_function("filter_preprocessed", |b| {
        let source = fs::read("tests/filter_preprocessed.i").unwrap();
        let marker = Some("c:\\bozaro\\github\\octobuild\\test_cl\\sample.h".to_string());

        b.iter(|| {
            let mut result = Vec::with_capacity(source.len());
            postprocess::filter_preprocessed(
                &mut Cursor::new(source.clone()),
                &mut result,
                &marker,
                false,
            )
            .unwrap();
            result
        })
    });
}

criterion_group!(benches, filter_preprocessed_benchmark);
criterion_main!(benches);
<|endoftext|>


<commit_before>// compile-pass

#![warn(unused_imports)] // Warning explanation here, it's OK

mod test {
    pub trait A {
        fn a();
    }

    impl A for () {
        fn a() { }
    }

    pub trait B {
        fn b(self);
    }

    impl B for () {
        fn b(self) { }
    }

    pub trait Unused {
    }
}

use test::Unused;   // This is really unused, so warning is OK
use test::A;        // This is used by the test2::func() through import of super::*
use test::B;        // This is used by the test2::func() through import of super::*

mod test2 {
    use super::*;
    pub fn func() {
        let _ = <()>::a();
        let _ = ().b();
        test3::inner_func();
    }
    mod test3 {
    use super::*;
    pub fn inner_func() {
        let _ = <()>::a();
        let _ = ().b();
    }
}

}

fn main() {
    test2::func();
}
<commit_msg>Fix misleading indentation<commit_after>// compile-pass

#![warn(unused_imports)] // Warning explanation here, it's OK

mod test {
    pub trait A {
        fn a();
    }

    impl A for () {
        fn a() { }
    }

    pub trait B {
        fn b(self);
    }

    impl B for () {
        fn b(self) { }
    }

    pub trait Unused {
    }
}

use test::Unused;   // This is really unused, so warning is OK
use test::A;        // This is used by the test2::func() through import of super::*
use test::B;        // This is used by the test2::func() through import of super::*

mod test2 {
    use super::*;
    pub fn func() {
        let _ = <()>::a();
        let _ = ().b();
        test3::inner_func();
    }
    mod test3 {
        use super::*;
        pub fn inner_func() {
            let _ = <()>::a();
            let _ = ().b();
        }
    }
}

fn main() {
    test2::func();
}
<|endoftext|>


<commit_before>/// Returns true if the find string can be found in the search string.
/// # Examples
///
/// ```
/// use substring::has_substring;
///
/// assert!(has_substring("abcdef", "def"));
/// assert!(!has_substring("abcdef", "xyz"));
/// ```
pub fn has_substring(search: &str, find: &str) -> bool {
    // The non-brute-force algorithms would be to implement in an interview
    // without reference so accept that this will be O(nm).
    if search.is_empty() {
        return find.is_empty();
    }

    let search_bytes = search.as_bytes();
    let find_bytes = find.as_bytes();
    let max_search_index = search_bytes.len() - find_bytes.len();

    for i in 0..(max_search_index + 1) {
        let mut found = true;
        for j in 0..find_bytes.len() {
            if search_bytes[i + j] != find_bytes[j] {
                found = false;
                break;
            }
        }
        if found {
            return true;
        }
    }
    false
}

#[test]
fn substring_at_end() {
    assert!(has_substring("abcdef", "def"));
}

#[test]
fn substring_at_beginning() {
    assert!(has_substring("abcdef", "abc"));
}

#[test]
fn substring_in_middle() {
    assert!(has_substring("abcdef", "cde"));
}

#[test]
fn substring_empty() {
    assert!(has_substring("abcdef", ""));
}

#[test]
fn search_string_empty() {
    assert!(!has_substring("", "abc"));
}

#[test]
fn search_string_and_substring_empty() {
    assert!(has_substring("", ""));
}

#[test]
fn search_string_has_repeating_pattern() {
    assert!(has_substring("aaaaaaaaaaaaaba", "aaab"));
}

#[test]
fn substring_not_found() {
    assert!(!has_substring("aaaaaaaaaaaaaba", "aaabb"));
}

#[test]
fn non_ascii() {
    assert!(has_substring(
        "Οἱ δὲ Φοίνιϰες οὗτοι οἱ σὺν Κάδμῳ ἀπιϰόμενοι..",
        "Φοίνιϰες"));
}
<commit_msg>Fix the grammar in a comment.<commit_after>/// Returns true if the find string can be found in the search string.
/// # Examples
///
/// ```
/// use substring::has_substring;
///
/// assert!(has_substring("abcdef", "def"));
/// assert!(!has_substring("abcdef", "xyz"));
/// ```
pub fn has_substring(search: &str, find: &str) -> bool {
    // The non-brute-force algorithms would be too difficult to implement in an
    // interview without reference so accept that this will be O(nm).
    if search.is_empty() {
        return find.is_empty();
    }

    let search_bytes = search.as_bytes();
    let find_bytes = find.as_bytes();
    let max_search_index = search_bytes.len() - find_bytes.len();

    for i in 0..(max_search_index + 1) {
        let mut found = true;
        for j in 0..find_bytes.len() {
            if search_bytes[i + j] != find_bytes[j] {
                found = false;
                break;
            }
        }
        if found {
            return true;
        }
    }
    false
}

#[test]
fn substring_at_end() {
    assert!(has_substring("abcdef", "def"));
}

#[test]
fn substring_at_beginning() {
    assert!(has_substring("abcdef", "abc"));
}

#[test]
fn substring_in_middle() {
    assert!(has_substring("abcdef", "cde"));
}

#[test]
fn substring_empty() {
    assert!(has_substring("abcdef", ""));
}

#[test]
fn search_string_empty() {
    assert!(!has_substring("", "abc"));
}

#[test]
fn search_string_and_substring_empty() {
    assert!(has_substring("", ""));
}

#[test]
fn search_string_has_repeating_pattern() {
    assert!(has_substring("aaaaaaaaaaaaaba", "aaab"));
}

#[test]
fn substring_not_found() {
    assert!(!has_substring("aaaaaaaaaaaaaba", "aaabb"));
}

#[test]
fn non_ascii() {
    assert!(has_substring(
        "Οἱ δὲ Φοίνιϰες οὗτοι οἱ σὺν Κάδμῳ ἀπιϰόμενοι..",
        "Φοίνιϰες"));
}
<|endoftext|>


<commit_before>use super::super::common::exit_validator;
use super::Error;
use types::*;

/// Peforms a validator registry update, if required.
///
/// Spec v0.5.1
pub fn update_registry_and_shuffling_data<T: EthSpec>(
    state: &mut BeaconState<T>,
    current_total_balance: u64,
    spec: &ChainSpec,
) -> Result<(), Error> {
    // First set previous shuffling data to current shuffling data.
    state.previous_shuffling_epoch = state.current_shuffling_epoch;
    state.previous_shuffling_start_shard = state.previous_shuffling_start_shard;
    state.previous_shuffling_seed = state.previous_shuffling_seed;

    let current_epoch = state.current_epoch();
    let next_epoch = current_epoch + 1;

    // Check we should update, and if so, update.
    if should_update_validator_registry(state, spec)? {
        update_validator_registry(state, current_total_balance, spec)?;

        // If we update the registry, update the shuffling data and shards as well.
        state.current_shuffling_epoch = next_epoch;
        state.current_shuffling_start_shard = {
            let active_validators =
                state.get_cached_active_validator_indices(RelativeEpoch::Current, spec)?;
            let epoch_committee_count = spec.get_epoch_committee_count(active_validators.len());

            (state.current_shuffling_start_shard + epoch_committee_count) % spec.shard_count
        };
        state.current_shuffling_seed = state.generate_seed(state.current_shuffling_epoch, spec)?;
    } else {
        // If processing at least on crosslink keeps failing, the reshuffle every power of two, but
        // don't update the current_shuffling_start_shard.
        let epochs_since_last_update = current_epoch - state.validator_registry_update_epoch;

        if epochs_since_last_update > 1 && epochs_since_last_update.is_power_of_two() {
            state.current_shuffling_epoch = next_epoch;
            state.current_shuffling_seed =
                state.generate_seed(state.current_shuffling_epoch, spec)?;
        }
    }

    Ok(())
}

/// Returns `true` if the validator registry should be updated during an epoch processing.
///
/// Spec v0.5.1
pub fn should_update_validator_registry<T: EthSpec>(
    state: &BeaconState<T>,
    spec: &ChainSpec,
) -> Result<bool, BeaconStateError> {
    if state.finalized_epoch <= state.validator_registry_update_epoch {
        return Ok(false);
    }

    let num_active_validators = state
        .get_cached_active_validator_indices(RelativeEpoch::Current, spec)?
        .len();
    let current_epoch_committee_count = spec.get_epoch_committee_count(num_active_validators);

    for shard in (0..current_epoch_committee_count)
        .map(|i| (state.current_shuffling_start_shard + i as u64) % spec.shard_count)
    {
        if state.latest_crosslinks[shard as usize].epoch <= state.validator_registry_update_epoch {
            return Ok(false);
        }
    }

    Ok(true)
}

/// Update validator registry, activating/exiting validators if possible.
///
/// Note: Utilizes the cache and will fail if the appropriate cache is not initialized.
///
/// Spec v0.5.1
pub fn update_validator_registry<T: EthSpec>(
    state: &mut BeaconState<T>,
    current_total_balance: u64,
    spec: &ChainSpec,
) -> Result<(), Error> {
    let current_epoch = state.current_epoch();

    let max_balance_churn = std::cmp::max(
        spec.max_deposit_amount,
        current_total_balance / (2 * spec.max_balance_churn_quotient),
    );

    // Activate validators within the allowable balance churn.
    let mut balance_churn = 0;
    for index in 0..state.validator_registry.len() {
        let not_activated =
            state.validator_registry[index].activation_epoch == spec.far_future_epoch;
        let has_enough_balance = state.validator_balances[index] >= spec.max_deposit_amount;

        if not_activated && has_enough_balance {
            // Check the balance churn would be within the allowance.
            balance_churn += state.get_effective_balance(index, spec)?;
            if balance_churn > max_balance_churn {
                break;
            }

            activate_validator(state, index, false, spec);
        }
    }

    // Exit validators within the allowable balance churn.
    let mut balance_churn = 0;
    for index in 0..state.validator_registry.len() {
        let not_exited = state.validator_registry[index].exit_epoch == spec.far_future_epoch;
        let has_initiated_exit = state.validator_registry[index].initiated_exit;

        if not_exited && has_initiated_exit {
            // Check the balance churn would be within the allowance.
            balance_churn += state.get_effective_balance(index, spec)?;
            if balance_churn > max_balance_churn {
                break;
            }

            exit_validator(state, index, spec)?;
        }
    }

    state.validator_registry_update_epoch = current_epoch;

    Ok(())
}

/// Activate the validator of the given ``index``.
///
/// Spec v0.5.1
pub fn activate_validator<T: EthSpec>(
    state: &mut BeaconState<T>,
    validator_index: usize,
    is_genesis: bool,
    spec: &ChainSpec,
) {
    let current_epoch = state.current_epoch();

    state.validator_registry[validator_index].activation_epoch = if is_genesis {
        spec.genesis_epoch
    } else {
        state.get_delayed_activation_exit_epoch(current_epoch, spec)
    }
}
<commit_msg>Remove `update_registry_and_shuffling_data`<commit_after><|endoftext|>