<commit_before>//! Parses ELF auxiliary vectors.
#![cfg_attr(any(target_arch = "arm", target_arch = "powerpc64"), allow(dead_code))]

/// Key to access the CPU Hardware capabilities bitfield.
pub(crate) const AT_HWCAP: usize = 25;
/// Key to access the CPU Hardware capabilities 2 bitfield.
pub(crate) const AT_HWCAP2: usize = 26;

/// Cache HWCAP bitfields of the ELF Auxiliary Vector.
///
/// If an entry cannot be read all the bits in the bitfield are set to zero.
/// This should be interpreted as all the features being disabled.
#[derive(Debug, Copy, Clone)]
pub(crate) struct AuxVec {
    pub hwcap: usize,
    pub hwcap2: usize,
}

/// ELF Auxiliary Vector
///
/// The auxiliary vector is a memory region in a running ELF program's stack
/// composed of (key: usize, value: usize) pairs.
///
/// The keys used in the aux vector are platform dependent. For FreeBSD, they are
/// defined in [sys/elf_common.h][elf_common_h]. The hardware capabilities of a given
/// CPU can be queried with the  `AT_HWCAP` and `AT_HWCAP2` keys.
///
/// Note that run-time feature detection is not invoked for features that can
/// be detected at compile-time.
///
/// [elf_common.h]: https://svnweb.freebsd.org/base/release/12.0.0/sys/sys/elf_common.h?revision=341707
pub(crate) fn auxv() -> Result<AuxVec, ()> {
    if let Ok(hwcap) = archauxv(AT_HWCAP) {
        if let Ok(hwcap2) = archauxv(AT_HWCAP2) {
            if hwcap != 0 && hwcap2 != 0 {
                return Ok(AuxVec { hwcap, hwcap2 });
            }
        }
    }
    Err(())
}

/// Tries to read the `key` from the auxiliary vector.
fn archauxv(key: usize) -> Result<usize, ()> {
    use mem;

    #[derive (Copy, Clone)]
    #[repr(C)]
    pub struct Elf_Auxinfo {
        pub a_type: usize,
        pub a_un: unnamed,
    }
    #[derive (Copy, Clone)]
    #[repr(C)]
    pub union unnamed {
        pub a_val: libc::c_long,
        pub a_ptr: *mut libc::c_void,
        pub a_fcn: Option<unsafe extern "C" fn() -> ()>,
    }

    let mut auxv: [Elf_Auxinfo; 27] =
        [Elf_Auxinfo{a_type: 0, a_un: unnamed{a_val: 0,},}; 27];

    let mut len: libc::c_uint = mem::size_of_val(&auxv) as libc::c_uint;

    unsafe {
        let mut mib = [libc::CTL_KERN, libc::KERN_PROC, libc::KERN_PROC_AUXV, libc::getpid()];

        let ret = libc::sysctl(mib.as_mut_ptr(),
                       mib.len() as u32,
                       &mut auxv as *mut _ as *mut _,
                       &mut len as *mut _ as *mut _,
                       0 as *mut libc::c_void,
                       0,
                );

        if ret != -1 {
            for i in 0..auxv.len() {
                if auxv[i].a_type == key {
                    return Ok(auxv[i].a_un.a_val as usize);
                }
            }
        }
    }
    return Ok(0);
}
<commit_msg>Fix build of auxvec.rs on FreeBSD/powerpc64<commit_after>//! Parses ELF auxiliary vectors.
#![cfg_attr(any(target_arch = "arm", target_arch = "powerpc64"), allow(dead_code))]

/// Key to access the CPU Hardware capabilities bitfield.
pub(crate) const AT_HWCAP: usize = 25;
/// Key to access the CPU Hardware capabilities 2 bitfield.
pub(crate) const AT_HWCAP2: usize = 26;

/// Cache HWCAP bitfields of the ELF Auxiliary Vector.
///
/// If an entry cannot be read all the bits in the bitfield are set to zero.
/// This should be interpreted as all the features being disabled.
#[derive(Debug, Copy, Clone)]
pub(crate) struct AuxVec {
    pub hwcap: usize,
    pub hwcap2: usize,
}

/// ELF Auxiliary Vector
///
/// The auxiliary vector is a memory region in a running ELF program's stack
/// composed of (key: usize, value: usize) pairs.
///
/// The keys used in the aux vector are platform dependent. For FreeBSD, they are
/// defined in [sys/elf_common.h][elf_common_h]. The hardware capabilities of a given
/// CPU can be queried with the  `AT_HWCAP` and `AT_HWCAP2` keys.
///
/// Note that run-time feature detection is not invoked for features that can
/// be detected at compile-time.
///
/// [elf_common.h]: https://svnweb.freebsd.org/base/release/12.0.0/sys/sys/elf_common.h?revision=341707
pub(crate) fn auxv() -> Result<AuxVec, ()> {
    if let Ok(hwcap) = archauxv(AT_HWCAP) {
        if let Ok(hwcap2) = archauxv(AT_HWCAP2) {
            if hwcap != 0 && hwcap2 != 0 {
                return Ok(AuxVec { hwcap, hwcap2 });
            }
        }
    }
    Err(())
}

/// Tries to read the `key` from the auxiliary vector.
fn archauxv(key: usize) -> Result<usize, ()> {
    use crate::mem;

    #[derive (Copy, Clone)]
    #[repr(C)]
    pub struct Elf_Auxinfo {
        pub a_type: usize,
        pub a_un: unnamed,
    }
    #[derive (Copy, Clone)]
    #[repr(C)]
    pub union unnamed {
        pub a_val: libc::c_long,
        pub a_ptr: *mut libc::c_void,
        pub a_fcn: Option<unsafe extern "C" fn() -> ()>,
    }

    let mut auxv: [Elf_Auxinfo; 27] =
        [Elf_Auxinfo{a_type: 0, a_un: unnamed{a_val: 0,},}; 27];

    let mut len: libc::c_uint = mem::size_of_val(&auxv) as libc::c_uint;

    unsafe {
        let mut mib = [libc::CTL_KERN, libc::KERN_PROC, libc::KERN_PROC_AUXV, libc::getpid()];

        let ret = libc::sysctl(mib.as_mut_ptr(),
                       mib.len() as u32,
                       &mut auxv as *mut _ as *mut _,
                       &mut len as *mut _ as *mut _,
                       0 as *mut libc::c_void,
                       0,
                );

        if ret != -1 {
            for i in 0..auxv.len() {
                if auxv[i].a_type == key {
                    return Ok(auxv[i].a_un.a_val as usize);
                }
            }
        }
    }
    return Ok(0);
}
<|endoftext|>


<commit_before>use crate::cpp_code_generator;
use crate::database::CppCheckerAddResult;
use crate::database::CppCheckerEnv;
use crate::database::CppFfiItem;
use crate::database::CppFfiItemKind;
use crate::processor::ProcessingStep;
use crate::processor::ProcessorData;
use log::debug;
use rayon::iter::IndexedParallelIterator;
use rayon::iter::IntoParallelIterator;
use rayon::iter::ParallelIterator;
use rayon::slice::ParallelSliceMut;
use ritual_common::cpp_lib_builder::{
    c2r_cmake_vars, BuildType, CppLibBuilder, CppLibBuilderOutput,
};
use ritual_common::errors::{bail, Result};
use ritual_common::file_utils::{create_dir_all, create_file, path_to_str, remove_dir_all};
use ritual_common::target::current_target;
use ritual_common::utils::MapIfOk;
use ritual_common::utils::ProgressBar;
use std::io::Write;
use std::iter;
use std::path::PathBuf;
use std::time::Instant;

fn check_snippets<'a>(
    data: &mut CppCheckerData,
    snippets: impl Iterator<Item = &'a Snippet>,
) -> Result<CppLibBuilderOutput> {
    {
        let mut file = create_file(&data.main_cpp_path)?;
        writeln!(file, "#include \"utils.h\"")?;
        writeln!(file)?;
        let mut main_content = Vec::new();
        for snippet in snippets {
            match snippet.context {
                SnippetContext::Main => {
                    main_content.push(&snippet.code);
                }
                SnippetContext::Global => {
                    writeln!(file, "{}", snippet.code)?;
                    writeln!(file)?;
                }
            }
        }

        writeln!(file, "int main() {{")?;
        for item in main_content {
            writeln!(file, "{{")?;
            writeln!(file, "{}", item)?;
            writeln!(file, "}}")?;
        }
        writeln!(file, "}}")?;
    }
    let instant = Instant::now();
    let result = data.builder.run();
    debug!("cpp builder time: {:?}", instant.elapsed());
    result
}

fn snippet_for_item(item: &CppFfiItem) -> Result<Snippet> {
    match &item.kind {
        CppFfiItemKind::Function(cpp_ffi_function) => Ok(Snippet::new_global(
            cpp_code_generator::function_implementation(cpp_ffi_function)?,
        )),
        CppFfiItemKind::QtSlotWrapper(_qt_slot_wrapper) => {
            bail!("qt slot wrappers are not supported yet");
        }
    }
}

struct CppCheckerData {
    main_cpp_path: PathBuf,
    builder: CppLibBuilder,
}

struct CppChecker<'b, 'a: 'b> {
    data: &'b mut ProcessorData<'a>,
}

#[derive(Debug, Clone, Copy)]
enum SnippetContext {
    Main,
    Global,
}

#[derive(Debug, Clone)]
struct Snippet {
    code: String,
    context: SnippetContext,
}

#[derive(Debug, Clone)]
struct SnippetWithIndexes {
    snippet: Snippet,
    ffi_item_index: usize,
    output: Option<CppLibBuilderOutput>,
}

impl Snippet {
    fn new_in_main<S: Into<String>>(code: S) -> Snippet {
        Snippet {
            code: code.into(),
            context: SnippetContext::Main,
        }
    }
    fn new_global<S: Into<String>>(code: S) -> Snippet {
        Snippet {
            code: code.into(),
            context: SnippetContext::Global,
        }
    }
}

struct PreliminaryTest {
    name: String,
    snippet: Snippet,
    expected: bool,
}

impl PreliminaryTest {
    fn new(name: &str, expected: bool, snippet: Snippet) -> Self {
        Self {
            name: name.into(),
            expected,
            snippet,
        }
    }
}

fn binary_check(
    snippets: &mut [SnippetWithIndexes],
    data: &mut CppCheckerData,
    progress_bar: &ProgressBar,
) -> Result<()> {
    if snippets.len() < 3 {
        for snippet in &mut *snippets {
            let output = check_snippets(data, iter::once(&snippet.snippet))?;
            snippet.output = Some(output);
            progress_bar.add(1);
        }
        return Ok(());
    }

    let output = check_snippets(data, snippets.iter().map(|s| &s.snippet))?;
    if let CppLibBuilderOutput::Success = output {
        for snippet in &mut *snippets {
            snippet.output = Some(output.clone());
        }
        progress_bar.add(snippets.len() as u64);
    } else {
        let split_point = snippets.len() / 2;
        let (left, right) = snippets.split_at_mut(split_point);
        binary_check(left, data, progress_bar)?;
        binary_check(right, data, progress_bar)?;
    }
    Ok(())
}

fn check_preliminary_test(data: &mut CppCheckerData, test: &PreliminaryTest) -> Result<()> {
    match check_snippets(data, iter::once(&test.snippet))? {
        CppLibBuilderOutput::Success => {
            if !test.expected {
                bail!("Nevative test ({}) succeeded", test.name);
            }
        }
        CppLibBuilderOutput::Fail(output) => {
            if test.expected {
                bail!("Positive test ({}) failed: {}", test.name, output.stderr);
            }
        }
    }
    Ok(())
}

impl CppChecker<'_, '_> {
    fn env(&self) -> CppCheckerEnv {
        CppCheckerEnv {
            target: current_target(),
            cpp_library_version: self.data.config.cpp_lib_version().map(|s| s.to_string()),
        }
    }
    fn create_instance(&self, id: &str) -> Result<CppCheckerData> {
        let root_path = self.data.workspace.tmp_path().join("cpp_checker").join(id);
        if root_path.exists() {
            remove_dir_all(&root_path)?;
        }
        let src_path = root_path.join("src");
        create_dir_all(&src_path)?;

        let mut cmake_file = create_file(src_path.join("CMakeLists.txt"))?;
        write!(
            cmake_file,
            "{}",
            include_str!("../templates/cpp_checker/CMakeLists.txt")
        )?;

        let mut utils_file = create_file(src_path.join("utils.h"))?;
        write!(
            utils_file,
            include_str!("../templates/cpp_checker/utils.h"),
            include_directives_code = self
                .data
                .config
                .include_directives()
                .map_if_ok(|d| -> Result<_> { Ok(format!("#include \"{}\"", path_to_str(d)?)) })?
                .join("\n")
        )?;

        let mut build_paths = self.data.config.cpp_build_paths().clone();
        build_paths.apply_env();
        let builder = CppLibBuilder {
            cmake_source_dir: src_path.clone(),
            build_dir: root_path.join("build"),
            install_dir: None,
            num_jobs: Some(1),
            build_type: BuildType::Debug,
            cmake_vars: c2r_cmake_vars(
                &self
                    .data
                    .config
                    .cpp_build_config()
                    .eval(&current_target())?,
                &build_paths,
                None,
            )?,
            capture_output: true,
            skip_cmake: false,
            skip_cmake_after_first_run: true,
        };

        Ok(CppCheckerData {
            builder,
            main_cpp_path: src_path.join("main.cpp"),
        })
    }
    fn run(&mut self) -> Result<()> {
        let env = self.env();
        if !self
            .data
            .current_database
            .environments
            .iter()
            .any(|e| e == &env)
        {
            self.data.current_database.environments.push(env.clone());
        }

        let mut snippets = Vec::new();
        for (ffi_item_index, ffi_item) in self.data.current_database.ffi_items.iter().enumerate() {
            if ffi_item.checks.items.iter().any(|check| check.env == env) {
                continue;
            }

            if let Ok(snippet) = snippet_for_item(ffi_item) {
                snippets.push(SnippetWithIndexes {
                    ffi_item_index,
                    snippet,
                    output: None,
                });
            }
        }

        if snippets.is_empty() {
            return Ok(());
        }

        self.run_tests()?;

        let progress_bar = ProgressBar::new(snippets.len() as u64, "Checking items");
        let num_threads = num_cpus::get();
        let div_ceil = |x, y| (x + y - 1) / y;
        let chunk_size = div_ceil(snippets.len(), num_threads);
        let num_chunks = div_ceil(snippets.len(), chunk_size);

        let instances =
            (0..num_chunks).map_if_ok(|index| self.create_instance(&format!("main_{}", index)))?;

        snippets
            .par_chunks_mut(chunk_size)
            .zip_eq(instances.into_par_iter())
            .map(|(chunk, mut instance)| {
                let progress_bar = progress_bar.clone();
                binary_check(chunk, &mut instance, &progress_bar)
            })
            .collect::<Result<_>>()?;

        for snippet in snippets {
            let ffi_item = &mut self.data.current_database.ffi_items[snippet.ffi_item_index];

            let error_data = match snippet.output.unwrap() {
                CppLibBuilderOutput::Success => None, // no error
                CppLibBuilderOutput::Fail(output) => {
                    Some(format!("build failed: {}", output.stderr))
                }
            };

            let r = ffi_item.checks.add(&env, error_data.clone());
            let change_text = match &r {
                CppCheckerAddResult::Added => "Added".to_string(),
                CppCheckerAddResult::Unchanged => "Unchanged".to_string(),
                CppCheckerAddResult::Changed { old } => {
                    format!("Changed! Old data for the same env: {:?}", old)
                }
            };

            debug!(
                "[cpp_checker_update] ffi_item = {:?}; snippet = {:?}; error = {:?}; {}",
                ffi_item, snippet.snippet.code, error_data, change_text
            );
        }
        Ok(())
    }

    fn run_tests(&mut self) -> Result<()> {
        let positive_tests = &[
            PreliminaryTest::new(
                "hello world",
                true,
                Snippet::new_in_main("std::cout << \"Hello world\\n\";"),
            ),
            PreliminaryTest::new(
                "correct assertion",
                true,
                Snippet::new_in_main("assert(2 + 2 == 4);"),
            ),
            PreliminaryTest::new(
                "type traits",
                true,
                Snippet::new_in_main(
                    "\
                     class C1 {}; \n\
                     enum E1 {};  \n\
                     assert(std::is_class<C1>::value); \n\
                     assert(!std::is_class<E1>::value); \n\
                     assert(!std::is_enum<C1>::value); \n\
                     assert(std::is_enum<E1>::value); \
                     assert(sizeof(C1) > 0);\
                     assert(sizeof(E1) > 0);\n\
                     ",
                ),
            ),
            PreliminaryTest::new(
                "incorrect assertion in fn",
                true,
                Snippet::new_global("int f1() { assert(2 + 2 == 5); return 1; }"),
            ),
        ];
        assert!(positive_tests.iter().all(|t| t.expected));

        let mut instance = self.create_instance("tests")?;
        let all_positive_output =
            check_snippets(&mut instance, positive_tests.iter().map(|t| &t.snippet))?;
        if all_positive_output != CppLibBuilderOutput::Success {
            for test in positive_tests {
                check_preliminary_test(&mut instance, test)?;
            }
        }

        let negative_tests = &[
            PreliminaryTest::new("syntax error", false, Snippet::new_in_main("}")),
            PreliminaryTest::new(
                "incorrect assertion",
                false,
                Snippet::new_in_main("assert(2 + 2 == 5);"),
            ),
            PreliminaryTest::new("status code 1", false, Snippet::new_in_main("return 1;")),
        ];
        assert!(negative_tests.iter().all(|t| !t.expected));

        for test in negative_tests {
            check_preliminary_test(&mut instance, test)?;
        }

        Ok(())
    }
}

fn run(data: &mut ProcessorData) -> Result<()> {
    let mut checker = CppChecker { data };

    checker.run()?;

    Ok(())
}

pub fn cpp_checker_step() -> ProcessingStep {
    ProcessingStep::new("cpp_checker", run)
}
<commit_msg>print DYLD_LIBRARY_PATH value<commit_after>use crate::cpp_code_generator;
use crate::database::CppCheckerAddResult;
use crate::database::CppCheckerEnv;
use crate::database::CppFfiItem;
use crate::database::CppFfiItemKind;
use crate::processor::ProcessingStep;
use crate::processor::ProcessorData;
use log::{debug, info};
use rayon::iter::IndexedParallelIterator;
use rayon::iter::IntoParallelIterator;
use rayon::iter::ParallelIterator;
use rayon::slice::ParallelSliceMut;
use ritual_common::cpp_lib_builder::{
    c2r_cmake_vars, BuildType, CppLibBuilder, CppLibBuilderOutput,
};
use ritual_common::errors::{bail, Result};
use ritual_common::file_utils::{create_dir_all, create_file, path_to_str, remove_dir_all};
use ritual_common::target::current_target;
use ritual_common::utils::MapIfOk;
use ritual_common::utils::ProgressBar;
use std::io::Write;
use std::iter;
use std::path::PathBuf;
use std::time::Instant;

fn check_snippets<'a>(
    data: &mut CppCheckerData,
    snippets: impl Iterator<Item = &'a Snippet>,
) -> Result<CppLibBuilderOutput> {
    {
        let mut file = create_file(&data.main_cpp_path)?;
        writeln!(file, "#include \"utils.h\"")?;
        writeln!(file)?;
        let mut main_content = Vec::new();
        for snippet in snippets {
            match snippet.context {
                SnippetContext::Main => {
                    main_content.push(&snippet.code);
                }
                SnippetContext::Global => {
                    writeln!(file, "{}", snippet.code)?;
                    writeln!(file)?;
                }
            }
        }

        writeln!(file, "int main() {{")?;
        for item in main_content {
            writeln!(file, "{{")?;
            writeln!(file, "{}", item)?;
            writeln!(file, "}}")?;
        }
        writeln!(file, "}}")?;
    }
    info!("env:");
    info!(
        "DYLD_LIBRARY_PATH = {:?}",
        std::env::var("DYLD_LIBRARY_PATH")
    );
    let instant = Instant::now();
    let result = data.builder.run();
    debug!("cpp builder time: {:?}", instant.elapsed());
    result
}

fn snippet_for_item(item: &CppFfiItem) -> Result<Snippet> {
    match &item.kind {
        CppFfiItemKind::Function(cpp_ffi_function) => Ok(Snippet::new_global(
            cpp_code_generator::function_implementation(cpp_ffi_function)?,
        )),
        CppFfiItemKind::QtSlotWrapper(_qt_slot_wrapper) => {
            bail!("qt slot wrappers are not supported yet");
        }
    }
}

struct CppCheckerData {
    main_cpp_path: PathBuf,
    builder: CppLibBuilder,
}

struct CppChecker<'b, 'a: 'b> {
    data: &'b mut ProcessorData<'a>,
}

#[derive(Debug, Clone, Copy)]
enum SnippetContext {
    Main,
    Global,
}

#[derive(Debug, Clone)]
struct Snippet {
    code: String,
    context: SnippetContext,
}

#[derive(Debug, Clone)]
struct SnippetWithIndexes {
    snippet: Snippet,
    ffi_item_index: usize,
    output: Option<CppLibBuilderOutput>,
}

impl Snippet {
    fn new_in_main<S: Into<String>>(code: S) -> Snippet {
        Snippet {
            code: code.into(),
            context: SnippetContext::Main,
        }
    }
    fn new_global<S: Into<String>>(code: S) -> Snippet {
        Snippet {
            code: code.into(),
            context: SnippetContext::Global,
        }
    }
}

struct PreliminaryTest {
    name: String,
    snippet: Snippet,
    expected: bool,
}

impl PreliminaryTest {
    fn new(name: &str, expected: bool, snippet: Snippet) -> Self {
        Self {
            name: name.into(),
            expected,
            snippet,
        }
    }
}

fn binary_check(
    snippets: &mut [SnippetWithIndexes],
    data: &mut CppCheckerData,
    progress_bar: &ProgressBar,
) -> Result<()> {
    if snippets.len() < 3 {
        for snippet in &mut *snippets {
            let output = check_snippets(data, iter::once(&snippet.snippet))?;
            snippet.output = Some(output);
            progress_bar.add(1);
        }
        return Ok(());
    }

    let output = check_snippets(data, snippets.iter().map(|s| &s.snippet))?;
    if let CppLibBuilderOutput::Success = output {
        for snippet in &mut *snippets {
            snippet.output = Some(output.clone());
        }
        progress_bar.add(snippets.len() as u64);
    } else {
        let split_point = snippets.len() / 2;
        let (left, right) = snippets.split_at_mut(split_point);
        binary_check(left, data, progress_bar)?;
        binary_check(right, data, progress_bar)?;
    }
    Ok(())
}

fn check_preliminary_test(data: &mut CppCheckerData, test: &PreliminaryTest) -> Result<()> {
    match check_snippets(data, iter::once(&test.snippet))? {
        CppLibBuilderOutput::Success => {
            if !test.expected {
                bail!("Nevative test ({}) succeeded", test.name);
            }
        }
        CppLibBuilderOutput::Fail(output) => {
            if test.expected {
                bail!("Positive test ({}) failed: {}", test.name, output.stderr);
            }
        }
    }
    Ok(())
}

impl CppChecker<'_, '_> {
    fn env(&self) -> CppCheckerEnv {
        CppCheckerEnv {
            target: current_target(),
            cpp_library_version: self.data.config.cpp_lib_version().map(|s| s.to_string()),
        }
    }
    fn create_instance(&self, id: &str) -> Result<CppCheckerData> {
        let root_path = self.data.workspace.tmp_path().join("cpp_checker").join(id);
        if root_path.exists() {
            remove_dir_all(&root_path)?;
        }
        let src_path = root_path.join("src");
        create_dir_all(&src_path)?;

        let mut cmake_file = create_file(src_path.join("CMakeLists.txt"))?;
        write!(
            cmake_file,
            "{}",
            include_str!("../templates/cpp_checker/CMakeLists.txt")
        )?;

        let mut utils_file = create_file(src_path.join("utils.h"))?;
        write!(
            utils_file,
            include_str!("../templates/cpp_checker/utils.h"),
            include_directives_code = self
                .data
                .config
                .include_directives()
                .map_if_ok(|d| -> Result<_> { Ok(format!("#include \"{}\"", path_to_str(d)?)) })?
                .join("\n")
        )?;

        let mut build_paths = self.data.config.cpp_build_paths().clone();
        build_paths.apply_env();
        let builder = CppLibBuilder {
            cmake_source_dir: src_path.clone(),
            build_dir: root_path.join("build"),
            install_dir: None,
            num_jobs: Some(1),
            build_type: BuildType::Debug,
            cmake_vars: c2r_cmake_vars(
                &self
                    .data
                    .config
                    .cpp_build_config()
                    .eval(&current_target())?,
                &build_paths,
                None,
            )?,
            capture_output: true,
            skip_cmake: false,
            skip_cmake_after_first_run: true,
        };

        Ok(CppCheckerData {
            builder,
            main_cpp_path: src_path.join("main.cpp"),
        })
    }
    fn run(&mut self) -> Result<()> {
        let env = self.env();
        if !self
            .data
            .current_database
            .environments
            .iter()
            .any(|e| e == &env)
        {
            self.data.current_database.environments.push(env.clone());
        }

        let mut snippets = Vec::new();
        for (ffi_item_index, ffi_item) in self.data.current_database.ffi_items.iter().enumerate() {
            if ffi_item.checks.items.iter().any(|check| check.env == env) {
                continue;
            }

            if let Ok(snippet) = snippet_for_item(ffi_item) {
                snippets.push(SnippetWithIndexes {
                    ffi_item_index,
                    snippet,
                    output: None,
                });
            }
        }

        if snippets.is_empty() {
            return Ok(());
        }

        self.run_tests()?;

        let progress_bar = ProgressBar::new(snippets.len() as u64, "Checking items");
        let num_threads = num_cpus::get();
        let div_ceil = |x, y| (x + y - 1) / y;
        let chunk_size = div_ceil(snippets.len(), num_threads);
        let num_chunks = div_ceil(snippets.len(), chunk_size);

        let instances =
            (0..num_chunks).map_if_ok(|index| self.create_instance(&format!("main_{}", index)))?;

        snippets
            .par_chunks_mut(chunk_size)
            .zip_eq(instances.into_par_iter())
            .map(|(chunk, mut instance)| {
                let progress_bar = progress_bar.clone();
                binary_check(chunk, &mut instance, &progress_bar)
            })
            .collect::<Result<_>>()?;

        for snippet in snippets {
            let ffi_item = &mut self.data.current_database.ffi_items[snippet.ffi_item_index];

            let error_data = match snippet.output.unwrap() {
                CppLibBuilderOutput::Success => None, // no error
                CppLibBuilderOutput::Fail(output) => {
                    Some(format!("build failed: {}", output.stderr))
                }
            };

            let r = ffi_item.checks.add(&env, error_data.clone());
            let change_text = match &r {
                CppCheckerAddResult::Added => "Added".to_string(),
                CppCheckerAddResult::Unchanged => "Unchanged".to_string(),
                CppCheckerAddResult::Changed { old } => {
                    format!("Changed! Old data for the same env: {:?}", old)
                }
            };

            debug!(
                "[cpp_checker_update] ffi_item = {:?}; snippet = {:?}; error = {:?}; {}",
                ffi_item, snippet.snippet.code, error_data, change_text
            );
        }
        Ok(())
    }

    fn run_tests(&mut self) -> Result<()> {
        let positive_tests = &[
            PreliminaryTest::new(
                "hello world",
                true,
                Snippet::new_in_main("std::cout << \"Hello world\\n\";"),
            ),
            PreliminaryTest::new(
                "correct assertion",
                true,
                Snippet::new_in_main("assert(2 + 2 == 4);"),
            ),
            PreliminaryTest::new(
                "type traits",
                true,
                Snippet::new_in_main(
                    "\
                     class C1 {}; \n\
                     enum E1 {};  \n\
                     assert(std::is_class<C1>::value); \n\
                     assert(!std::is_class<E1>::value); \n\
                     assert(!std::is_enum<C1>::value); \n\
                     assert(std::is_enum<E1>::value); \
                     assert(sizeof(C1) > 0);\
                     assert(sizeof(E1) > 0);\n\
                     ",
                ),
            ),
            PreliminaryTest::new(
                "incorrect assertion in fn",
                true,
                Snippet::new_global("int f1() { assert(2 + 2 == 5); return 1; }"),
            ),
        ];
        assert!(positive_tests.iter().all(|t| t.expected));

        let mut instance = self.create_instance("tests")?;
        let all_positive_output =
            check_snippets(&mut instance, positive_tests.iter().map(|t| &t.snippet))?;
        if all_positive_output != CppLibBuilderOutput::Success {
            for test in positive_tests {
                check_preliminary_test(&mut instance, test)?;
            }
        }

        let negative_tests = &[
            PreliminaryTest::new("syntax error", false, Snippet::new_in_main("}")),
            PreliminaryTest::new(
                "incorrect assertion",
                false,
                Snippet::new_in_main("assert(2 + 2 == 5);"),
            ),
            PreliminaryTest::new("status code 1", false, Snippet::new_in_main("return 1;")),
        ];
        assert!(negative_tests.iter().all(|t| !t.expected));

        for test in negative_tests {
            check_preliminary_test(&mut instance, test)?;
        }

        Ok(())
    }
}

fn run(data: &mut ProcessorData) -> Result<()> {
    let mut checker = CppChecker { data };

    checker.run()?;

    Ok(())
}

pub fn cpp_checker_step() -> ProcessingStep {
    ProcessingStep::new("cpp_checker", run)
}
<|endoftext|>


<commit_before>// Copyright 2014-2018 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution.
//
// 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.

extern crate clap;
extern crate clippy_dev;
extern crate regex;

use clap::{App, Arg, SubCommand};
use clippy_dev::*;

#[derive(PartialEq)]
enum UpdateMode {
    Check,
    Change
}

fn main() {
    let matches = App::new("Clippy developer tooling")
        .subcommand(
            SubCommand::with_name("update_lints")
                .about("Makes sure that:\n \
                       * the lint count in README.md is correct\n \
                       * the changelog contains markdown link references at the bottom\n \
                       * all lint groups include the correct lints\n \
                       * lint modules in `clippy_lints/*` are visible in `src/lib.rs` via `pub mod`\n \
                       * all lints are registered in the lint store")
                .arg(
                    Arg::with_name("print-only")
                        .long("print-only")
                        .help("Print a table of lints to STDOUT. This does not include deprecated and internal lints. (Does not modify any files)")
                )
                .arg(
                    Arg::with_name("check")
                        .long("check")
                        .help("Checks that util/dev update_lints has been run. Used on CI."),
                )
            )
            .get_matches();

    if let Some(matches) = matches.subcommand_matches("update_lints") {
        if matches.is_present("print-only") {
            print_lints();
        } else if matches.is_present("check") {
            update_lints(UpdateMode::Check);
        } else {
            update_lints(UpdateMode::Change);
        }
    }
}

fn print_lints() {
    let lint_list = gather_all();
    let usable_lints: Vec<Lint> = Lint::usable_lints(lint_list).collect();
    let lint_count = usable_lints.len();
    let grouped_by_lint_group = Lint::by_lint_group(&usable_lints);

    for (lint_group, mut lints) in grouped_by_lint_group {
        if lint_group == "Deprecated" { continue; }
        println!("\n## {}", lint_group);

        lints.sort_by_key(|l| l.name.clone());

        for lint in lints {
            println!("* [{}]({}#{}) ({})", lint.name, clippy_dev::DOCS_LINK.clone(), lint.name, lint.desc);
        }
    }

    println!("there are {} lints", lint_count);
}

fn update_lints(update_mode: UpdateMode) {
    let lint_list: Vec<Lint> = gather_all().collect();
    let usable_lints: Vec<Lint> = Lint::usable_lints(lint_list.clone().into_iter()).collect();
    let lint_count = usable_lints.len();

    let mut file_change = replace_region_in_file(
        "../README.md",
        r#"\[There are \d+ lints included in this crate!\]\(https://rust-lang-nursery.github.io/rust-clippy/master/index.html\)"#,
        "",
        true,
        update_mode == UpdateMode::Change,
        || {
            vec![
                format!("[There are {} lints included in this crate!](https://rust-lang-nursery.github.io/rust-clippy/master/index.html)", lint_count)
            ]
        }
    ).changed;

    file_change |= replace_region_in_file(
        "../CHANGELOG.md",
        "<!-- begin autogenerated links to lint list -->",
        "<!-- end autogenerated links to lint list -->",
        false,
        update_mode == UpdateMode::Change,
        || { gen_changelog_lint_list(lint_list.clone()) }
    ).changed;

    file_change |= replace_region_in_file(
        "../clippy_lints/src/lib.rs",
        "begin deprecated lints",
        "end deprecated lints",
        false,
        update_mode == UpdateMode::Change,
        || { gen_deprecated(&lint_list) }
    ).changed;

    file_change |= replace_region_in_file(
        "../clippy_lints/src/lib.rs",
        "begin lints modules",
        "end lints modules",
        false,
        update_mode == UpdateMode::Change,
        || { gen_modules_list(lint_list.clone()) }
    ).changed;

    // Generate lists of lints in the clippy::all lint group
    file_change |= replace_region_in_file(
        "../clippy_lints/src/lib.rs",
        r#"reg.register_lint_group\("clippy::all""#,
        r#"\]\);"#,
        false,
        update_mode == UpdateMode::Change,
        || {
            // clippy::all should only include the following lint groups:
            let all_group_lints = usable_lints.clone().into_iter().filter(|l| {
                l.group == "correctness" ||
                  l.group == "style" ||
                  l.group == "complexity" ||
                  l.group == "perf"
            }).collect();

            gen_lint_group_list(all_group_lints)
        }
    ).changed;

    // Generate the list of lints for all other lint groups
    for (lint_group, lints) in Lint::by_lint_group(&usable_lints) {
        file_change |= replace_region_in_file(
            "../clippy_lints/src/lib.rs",
            &format!("reg.register_lint_group\\(\"clippy::{}\"", lint_group),
            r#"\]\);"#,
            false,
            update_mode == UpdateMode::Change,
            || { gen_lint_group_list(lints.clone()) }
        ).changed;
    }

    if update_mode == UpdateMode::Check && file_change {
      println!("Not all lints defined properly. Please run `util/dev update_lints` to make sure all lints are defined properly.");
      std::process::exit(1);
    }
}
<commit_msg>Fix dogfood<commit_after>// Copyright 2014-2018 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution.
//
// 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.

extern crate clap;
extern crate clippy_dev;
extern crate regex;

use clap::{App, Arg, SubCommand};
use clippy_dev::*;

#[derive(PartialEq)]
enum UpdateMode {
    Check,
    Change
}

fn main() {
    let matches = App::new("Clippy developer tooling")
        .subcommand(
            SubCommand::with_name("update_lints")
                .about("Makes sure that:\n \
                       * the lint count in README.md is correct\n \
                       * the changelog contains markdown link references at the bottom\n \
                       * all lint groups include the correct lints\n \
                       * lint modules in `clippy_lints/*` are visible in `src/lib.rs` via `pub mod`\n \
                       * all lints are registered in the lint store")
                .arg(
                    Arg::with_name("print-only")
                        .long("print-only")
                        .help("Print a table of lints to STDOUT. This does not include deprecated and internal lints. (Does not modify any files)")
                )
                .arg(
                    Arg::with_name("check")
                        .long("check")
                        .help("Checks that util/dev update_lints has been run. Used on CI."),
                )
            )
            .get_matches();

    if let Some(matches) = matches.subcommand_matches("update_lints") {
        if matches.is_present("print-only") {
            print_lints();
        } else if matches.is_present("check") {
            update_lints(&UpdateMode::Check);
        } else {
            update_lints(&UpdateMode::Change);
        }
    }
}

fn print_lints() {
    let lint_list = gather_all();
    let usable_lints: Vec<Lint> = Lint::usable_lints(lint_list).collect();
    let lint_count = usable_lints.len();
    let grouped_by_lint_group = Lint::by_lint_group(&usable_lints);

    for (lint_group, mut lints) in grouped_by_lint_group {
        if lint_group == "Deprecated" { continue; }
        println!("\n## {}", lint_group);

        lints.sort_by_key(|l| l.name.clone());

        for lint in lints {
            println!("* [{}]({}#{}) ({})", lint.name, clippy_dev::DOCS_LINK.clone(), lint.name, lint.desc);
        }
    }

    println!("there are {} lints", lint_count);
}

fn update_lints(update_mode: &UpdateMode) {
    let lint_list: Vec<Lint> = gather_all().collect();
    let usable_lints: Vec<Lint> = Lint::usable_lints(lint_list.clone().into_iter()).collect();
    let lint_count = usable_lints.len();

    let mut file_change = replace_region_in_file(
        "../README.md",
        r#"\[There are \d+ lints included in this crate!\]\(https://rust-lang-nursery.github.io/rust-clippy/master/index.html\)"#,
        "",
        true,
        update_mode == &UpdateMode::Change,
        || {
            vec![
                format!("[There are {} lints included in this crate!](https://rust-lang-nursery.github.io/rust-clippy/master/index.html)", lint_count)
            ]
        }
    ).changed;

    file_change |= replace_region_in_file(
        "../CHANGELOG.md",
        "<!-- begin autogenerated links to lint list -->",
        "<!-- end autogenerated links to lint list -->",
        false,
        update_mode == &UpdateMode::Change,
        || { gen_changelog_lint_list(lint_list.clone()) }
    ).changed;

    file_change |= replace_region_in_file(
        "../clippy_lints/src/lib.rs",
        "begin deprecated lints",
        "end deprecated lints",
        false,
        update_mode == &UpdateMode::Change,
        || { gen_deprecated(&lint_list) }
    ).changed;

    file_change |= replace_region_in_file(
        "../clippy_lints/src/lib.rs",
        "begin lints modules",
        "end lints modules",
        false,
        update_mode == &UpdateMode::Change,
        || { gen_modules_list(lint_list.clone()) }
    ).changed;

    // Generate lists of lints in the clippy::all lint group
    file_change |= replace_region_in_file(
        "../clippy_lints/src/lib.rs",
        r#"reg.register_lint_group\("clippy::all""#,
        r#"\]\);"#,
        false,
        update_mode == &UpdateMode::Change,
        || {
            // clippy::all should only include the following lint groups:
            let all_group_lints = usable_lints.clone().into_iter().filter(|l| {
                l.group == "correctness" ||
                  l.group == "style" ||
                  l.group == "complexity" ||
                  l.group == "perf"
            }).collect();

            gen_lint_group_list(all_group_lints)
        }
    ).changed;

    // Generate the list of lints for all other lint groups
    for (lint_group, lints) in Lint::by_lint_group(&usable_lints) {
        file_change |= replace_region_in_file(
            "../clippy_lints/src/lib.rs",
            &format!("reg.register_lint_group\\(\"clippy::{}\"", lint_group),
            r#"\]\);"#,
            false,
            update_mode == &UpdateMode::Change,
            || { gen_lint_group_list(lints.clone()) }
        ).changed;
    }

    if update_mode == &UpdateMode::Check && file_change {
      println!("Not all lints defined properly. Please run `util/dev update_lints` to make sure all lints are defined properly.");
      std::process::exit(1);
    }
}
<|endoftext|>


<commit_before>extern mod extra;
use extra::treemap::TreeMap;
use std::vec;
use std::iter::Zip;
use common::*;
use monomial::Monomial;
use polynomial::Polynomial;
use vector_monomial::VectorMonomial;

mod common;
mod monomial;
mod polynomial;
mod vector_monomial;

// An FENum identifies a finite element in the mesh.
#[deriving(Eq,TotalEq,Ord,TotalOrd,Clone)]
pub struct FENum(uint);

// An NBSideNum identifies a mesh side among all sides in the mesh.
#[deriving(Eq,TotalEq,Ord,TotalOrd,Clone)]
pub struct NBSideNum(uint);

// A SideFace identifies a side within the context of a single oriented shape
// or finite element.
#[deriving(Eq,TotalEq,Ord,TotalOrd,Clone)]
pub struct SideFace(u8);

// A Face locally identifies either the interior or a side in the
// context of a single oriented shape or finite element.
#[deriving(Eq,TotalEq,Ord,TotalOrd,Clone)]
pub enum Face {
  Interior,
  Side(SideFace)
}

// An identifier for the shape of a finite element together with the orientation
// of the shape (rotation will yield a different oriented shape). Many calculations
// on a finite element can be expressed in element-local coordinates and will only
// depend on the oriented shape of the element.
#[deriving(Eq,TotalEq,Ord,TotalOrd,Clone)]
pub struct OShape(u32);

#[deriving(Eq,TotalEq,Ord,TotalOrd,Clone)]
pub struct NBSideInclusions {
  nb_side_num: NBSideNum,

  fe1: FENum,
  sideface_in_fe1: SideFace,

  fe2: FENum,
  sideface_in_fe2: SideFace
}

pub trait Mesh<M> {

  fn num_fes(&self) -> uint;

  fn num_nb_sides(&self) -> uint;

  fn num_oriented_element_shapes(&self) -> uint;

  fn oriented_shape_for_fe(&self, fe: FENum) -> OShape;

  fn num_side_faces_for_fe(&self, fe: FENum) -> uint;

  fn num_side_faces_for_shape(&self, oshape: OShape) -> uint;

  // The dependent dim is, for a given side, the dimension j which is affine-
  // dependent on the other dimensions on the side. That is, the function
  // returns a j for which c_0,...,c_d exist such that
  //   x_j = c_0 + sum_{i=1..d} c_i x_i for all (x_1,...,x_d) in the side.
  // There may be more than one such coordinate number, in which case any
  // one of these may be returned depending on the mesh implementation.
  fn dependent_dim_for_oshape_side(&self, oshape: OShape, side_face: SideFace) -> Dim;

  // TODO: decide how to most efficiently fetch this structure.
  fn fe_inclusions_of_nb_side(&self, side_num: NBSideNum) -> NBSideInclusions;

  // Return non-boundary side number of the indicated fe relative side.
  fn nb_side_num_for_fe_side(&self, fe: FENum, side_face: SideFace) -> NBSideNum;

  fn is_boundary_side(&self, fe: FENum, side_face: SideFace) -> bool;

  fn num_boundary_sides(&self) -> uint;

  fn shape_diameter_inv(&self, oshape: OShape) -> R;

  fn max_fe_diameter(&self) -> R;

  fn fe_interior_origin(&self, fe: FENum) -> ~[R];

  fn num_non_boundary_sides_for_fe(&self, fe: FENum) -> uint;

  fn max_num_shape_sides(&self) -> uint;

  // integration functions

  fn intg_global_fn_on_fe_int(&self,
       g: &fn(&[R]) -> R,
       fe: FENum) -> R;

  fn intg_global_fn_x_facerel_mon_on_fe_int(&self,
       g: &fn(&[R]) -> R,
       mon: M,
       fe: FENum) -> R;

  fn intg_facerel_poly_on_oshape_int<P:Polynomial<M>>(&self,
       p: P,
       oshape: OShape) -> R;

  fn intg_facerel_poly_x_facerel_poly_on_oshape_int<P:Polynomial<M>>(&self,
       p1: P,
       p2: P,
       oshape: OShape) -> R;

  fn intg_facerel_poly_x_facerel_poly_on_oshape_side<P:Polynomial<M>>(&self,
       p1: P,
       p2: P,
       oshape: OShape,
       side_face: SideFace) -> R;

  fn intg_facerel_mon_x_facerel_mon_on_oshape_int(&self,
       mon1: M,
       mon2: M,
       oshape: OShape) -> R;

  fn intg_facerel_mon_x_facerel_mon_on_oshape_side(&self,
       mon1: M,
       mon2: M,
       oshape: OShape,
       side_face: SideFace) -> R;

  fn intg_facerel_mon_x_facerel_poly_on_oshape_int<P:Polynomial<M>>(&self,
       mon: M,
       p: P,
       oshape: OShape) -> R;

  fn intg_facerel_mon_x_facerel_poly_on_oshape_side<P:Polynomial<M>>(&self,
       mon: M,
       p: P,
       oshape: OShape,
       side_face: SideFace) -> R;

  fn intg_intrel_mon_x_siderel_mon_on_oshape_side(&self,
       int_mon: M,
       side_mon: M, oshape: OShape,
       side_face: SideFace) -> R;

  fn intg_siderel_mon_x_intrel_vmon_dot_normal_on_oshape_side(&self,
       mon: M,
       q: VectorMonomial<M>,
       oshape: OShape,
       side_face: SideFace) -> R;

  fn intg_siderel_poly_x_intrel_vmon_dot_normal_on_oshape_side<P:Polynomial<M>>(&self,
       p: P,
       q: VectorMonomial<M>,
       oshape: OShape,
       side_face: SideFace) -> R;

}

<commit_msg>Remove obsolete comment.<commit_after>extern mod extra;
use extra::treemap::TreeMap;
use std::vec;
use std::iter::Zip;
use common::*;
use monomial::Monomial;
use polynomial::Polynomial;
use vector_monomial::VectorMonomial;

mod common;
mod monomial;
mod polynomial;
mod vector_monomial;

// An FENum identifies a finite element in the mesh.
#[deriving(Eq,TotalEq,Ord,TotalOrd,Clone)]
pub struct FENum(uint);

// An NBSideNum identifies a mesh side among all sides in the mesh.
#[deriving(Eq,TotalEq,Ord,TotalOrd,Clone)]
pub struct NBSideNum(uint);

// A SideFace identifies a side within the context of a single oriented shape
// or finite element.
#[deriving(Eq,TotalEq,Ord,TotalOrd,Clone)]
pub struct SideFace(u8);

// A Face locally identifies either the interior or a side in the
// context of a single oriented shape or finite element.
#[deriving(Eq,TotalEq,Ord,TotalOrd,Clone)]
pub enum Face {
  Interior,
  Side(SideFace)
}

// An identifier for the shape of a finite element together with the orientation
// of the shape (rotation will yield a different oriented shape). Many calculations
// on a finite element can be expressed in element-local coordinates and will only
// depend on the oriented shape of the element.
#[deriving(Eq,TotalEq,Ord,TotalOrd,Clone)]
pub struct OShape(u32);

#[deriving(Eq,TotalEq,Ord,TotalOrd,Clone)]
pub struct NBSideInclusions {
  nb_side_num: NBSideNum,

  fe1: FENum,
  sideface_in_fe1: SideFace,

  fe2: FENum,
  sideface_in_fe2: SideFace
}

pub trait Mesh<M> {

  fn num_fes(&self) -> uint;

  fn num_nb_sides(&self) -> uint;

  fn num_oriented_element_shapes(&self) -> uint;

  fn oriented_shape_for_fe(&self, fe: FENum) -> OShape;

  fn num_side_faces_for_fe(&self, fe: FENum) -> uint;

  fn num_side_faces_for_shape(&self, oshape: OShape) -> uint;

  // The dependent dim is, for a given side, the dimension j which is affine-
  // dependent on the other dimensions on the side. That is, the function
  // returns a j for which c_0,...,c_d exist such that
  //   x_j = c_0 + sum_{i=1..d} c_i x_i for all (x_1,...,x_d) in the side.
  // There may be more than one such coordinate number, in which case any
  // one of these may be returned depending on the mesh implementation.
  fn dependent_dim_for_oshape_side(&self, oshape: OShape, side_face: SideFace) -> Dim;

  fn fe_inclusions_of_nb_side(&self, side_num: NBSideNum) -> NBSideInclusions;

  // Return non-boundary side number of the indicated fe relative side.
  fn nb_side_num_for_fe_side(&self, fe: FENum, side_face: SideFace) -> NBSideNum;

  fn is_boundary_side(&self, fe: FENum, side_face: SideFace) -> bool;

  fn num_boundary_sides(&self) -> uint;

  fn shape_diameter_inv(&self, oshape: OShape) -> R;

  fn max_fe_diameter(&self) -> R;

  fn fe_interior_origin(&self, fe: FENum) -> ~[R];

  fn num_non_boundary_sides_for_fe(&self, fe: FENum) -> uint;

  fn max_num_shape_sides(&self) -> uint;

  // integration functions

  fn intg_global_fn_on_fe_int(&self,
       g: &fn(&[R]) -> R,
       fe: FENum) -> R;

  fn intg_global_fn_x_facerel_mon_on_fe_int(&self,
       g: &fn(&[R]) -> R,
       mon: M,
       fe: FENum) -> R;

  fn intg_facerel_poly_on_oshape_int<P:Polynomial<M>>(&self,
       p: P,
       oshape: OShape) -> R;

  fn intg_facerel_poly_x_facerel_poly_on_oshape_int<P:Polynomial<M>>(&self,
       p1: P,
       p2: P,
       oshape: OShape) -> R;

  fn intg_facerel_poly_x_facerel_poly_on_oshape_side<P:Polynomial<M>>(&self,
       p1: P,
       p2: P,
       oshape: OShape,
       side_face: SideFace) -> R;

  fn intg_facerel_mon_x_facerel_mon_on_oshape_int(&self,
       mon1: M,
       mon2: M,
       oshape: OShape) -> R;

  fn intg_facerel_mon_x_facerel_mon_on_oshape_side(&self,
       mon1: M,
       mon2: M,
       oshape: OShape,
       side_face: SideFace) -> R;

  fn intg_facerel_mon_x_facerel_poly_on_oshape_int<P:Polynomial<M>>(&self,
       mon: M,
       p: P,
       oshape: OShape) -> R;

  fn intg_facerel_mon_x_facerel_poly_on_oshape_side<P:Polynomial<M>>(&self,
       mon: M,
       p: P,
       oshape: OShape,
       side_face: SideFace) -> R;

  fn intg_intrel_mon_x_siderel_mon_on_oshape_side(&self,
       int_mon: M,
       side_mon: M, oshape: OShape,
       side_face: SideFace) -> R;

  fn intg_siderel_mon_x_intrel_vmon_dot_normal_on_oshape_side(&self,
       mon: M,
       q: VectorMonomial<M>,
       oshape: OShape,
       side_face: SideFace) -> R;

  fn intg_siderel_poly_x_intrel_vmon_dot_normal_on_oshape_side<P:Polynomial<M>>(&self,
       p: P,
       q: VectorMonomial<M>,
       oshape: OShape,
       side_face: SideFace) -> R;

}

<|endoftext|>


<commit_before>use extra::json;
use extra::serialize::Decodable;

fn maybe_extract_from_json_object<T: Decodable<json::Decoder>>(
        obj: &json::Object, id: &~str) -> Option<T> {
    let found = match obj.find(id) {
        Some(s) => s.clone(),
        None => return None,
    };
    let mut decoder = json::Decoder(found);
    Decodable::decode(&mut decoder)
}

fn extract_from_json_object<T: Decodable<json::Decoder>>(obj: &json::Object, id: &~str) -> T {
    maybe_extract_from_json_object(obj, id).unwrap_or_else(|| {
        fail!("Didn't find id `{}` or an incorrect type in `{}`", *id, json::Object(~obj.clone()).to_str());
    })
}

fn expect_json_object<'a>(json: &'a json::Json) -> &'a json::Object {
    match *json {
        json::Object(~ref obj) => obj,
        _ => fail!("Expected an object, got {:?}", json),
    }
}

pub static API_VERSION: int = 3;

pub static API_KEY: &'static str = "def2ba77d002afeec898674ede24fe10828ad8a5";

pub struct ApiKey(~str);

pub struct Response<T> {
    status: ~str,
    errors: Option<~str>,
    notices: Option<~str>,
    logged_in: bool,
    api_version: uint,
    contents: T,
}

impl <T> Response<T> {
    fn from_json(json: &json::Json, contents: T) -> Response<T> {
        let obj = expect_json_object(json);
        Response::from_json_obj(obj, contents)
    }

    fn from_json_obj(obj: &json::Object, contents: T) -> Response<T> {
        Response {
            status: extract_from_json_object(obj, &~"status"),
            errors: maybe_extract_from_json_object(obj, &~"errors"),
            notices: maybe_extract_from_json_object(obj, &~"notices"),
            logged_in: extract_from_json_object(obj, &~"logged_in"),
            api_version: extract_from_json_object(obj, &~"api_version"),
            contents: contents,
        }
    }
}

#[deriving(Decodable, Clone)]
pub struct CoverUrls {
    sq56: ~str,
    sq100: ~str,
    sq133: ~str,
    max133w: ~str,
    max200: ~str,
    sq250: ~str,
    sq500: ~str,
    max1024: ~str,
    original: ~str,
}

impl CoverUrls {
    pub fn from_json(json: json::Json) -> CoverUrls {
        let mut decoder = json::Decoder(json);
        Decodable::decode(&mut decoder)
    }
}

#[deriving(Decodable, Clone)]
pub struct Mix {
    id: uint,
    path: ~str,
    web_path: ~str,
    name: ~str,
    description: ~str,
    plays_count: uint,
    likes_count: uint,
    certification: Option<~str>,
    // TODO parse this...
    tag_list_cache: ~str,
    duration: uint,
    tracks_count: uint,
    nsfw: bool,
    liked_by_current_user: bool,
    cover_urls: CoverUrls,
    // TODO parse this...
    first_published_at: ~str,
    user_id: uint,
}

impl Mix {
    pub fn from_json(json: &json::Json) -> Mix {
        let obj = expect_json_object(json);
        Mix {
            id: extract_from_json_object(obj, &~"id"),
            path: extract_from_json_object(obj, &~"path"),
            web_path: extract_from_json_object(obj, &~"web_path"),
            name: extract_from_json_object(obj, &~"name"),
            description: extract_from_json_object(obj, &~"description"),
            plays_count: extract_from_json_object(obj, &~"plays_count"),
            likes_count: extract_from_json_object(obj, &~"likes_count"),
            certification: maybe_extract_from_json_object(obj, &~"certification"),
            tag_list_cache: maybe_extract_from_json_object(obj, &~"tags_list_cache").unwrap_or_default(),
            duration: extract_from_json_object(obj, &~"duration"),
            tracks_count: extract_from_json_object(obj, &~"tracks_count"),
            nsfw: maybe_extract_from_json_object(obj, &~"nsfw").unwrap_or_default(),
            liked_by_current_user: maybe_extract_from_json_object(obj, &~"liked_by_current_user").unwrap_or_default(),
            cover_urls: CoverUrls::from_json(obj.find(&~"cover_urls").unwrap().clone()),
            first_published_at: extract_from_json_object(obj, &~"first_published_at"),
            user_id: extract_from_json_object(obj, &~"user_id"),
        }
    }
}

#[deriving(Decodable)]
struct MixSet {
    mixes: ~[Mix],
    smart_id: ~str,
    smart_type: ~str,
    path: ~str,
    name: ~str,
    web_path: ~str,
}

impl MixSet {
    pub fn from_json(json: &json::Json) -> MixSet {
        let obj = expect_json_object(json);
        let mixes_list = match obj.find(&~"mixes") {
            Some(&json::List(ref list)) => list,
            _ => fail!("expected mixes list in mix set, got {:?}", obj)
        };
        let mixes = mixes_list.map(|json| { Mix::from_json(json) });
        MixSet {
            mixes: mixes,
            smart_id: extract_from_json_object(obj, &~"smart_id"),
            smart_type: extract_from_json_object(obj, &~"smart_type"),
            path: extract_from_json_object(obj, &~"path"),
            name: extract_from_json_object(obj, &~"name"),
            web_path: extract_from_json_object(obj, &~"web_path"),
        }
    }
}

pub fn parse_mix_set_response(json: &json::Json) -> Response<MixSet> {
    let obj = expect_json_object(json);
    let mix_set = MixSet::from_json(obj.find(&~"mix_set").unwrap());
    Response::from_json(json, mix_set)
}
<commit_msg>api: update for Json api changes<commit_after>use extra::json;
use extra::serialize::Decodable;

fn maybe_extract_from_json_object<T: Decodable<json::Decoder>>(
        obj: &json::Object, id: &~str) -> Option<T> {
    let found = match obj.find(id) {
        Some(s) => s.clone(),
        None => return None,
    };
    let mut decoder = json::Decoder::init(found);
    Decodable::decode(&mut decoder)
}

fn extract_from_json_object<T: Decodable<json::Decoder>>(obj: &json::Object, id: &~str) -> T {
    maybe_extract_from_json_object(obj, id).unwrap_or_else(|| {
        fail!("Didn't find id `{}` or an incorrect type in `{}`", *id, json::Object(~obj.clone()).to_str());
    })
}

fn expect_json_object<'a>(json: &'a json::Json) -> &'a json::Object {
    match *json {
        json::Object(~ref obj) => obj,
        _ => fail!("Expected an object, got {:?}", json),
    }
}

pub static API_VERSION: int = 3;

pub static API_KEY: &'static str = "def2ba77d002afeec898674ede24fe10828ad8a5";

pub struct ApiKey(~str);

pub struct Response<T> {
    status: ~str,
    errors: Option<~str>,
    notices: Option<~str>,
    logged_in: bool,
    api_version: uint,
    contents: T,
}

impl <T> Response<T> {
    fn from_json(json: &json::Json, contents: T) -> Response<T> {
        let obj = expect_json_object(json);
        Response::from_json_obj(obj, contents)
    }

    fn from_json_obj(obj: &json::Object, contents: T) -> Response<T> {
        Response {
            status: extract_from_json_object(obj, &~"status"),
            errors: maybe_extract_from_json_object(obj, &~"errors"),
            notices: maybe_extract_from_json_object(obj, &~"notices"),
            logged_in: extract_from_json_object(obj, &~"logged_in"),
            api_version: extract_from_json_object(obj, &~"api_version"),
            contents: contents,
        }
    }
}

#[deriving(Decodable, Clone)]
pub struct CoverUrls {
    sq56: ~str,
    sq100: ~str,
    sq133: ~str,
    max133w: ~str,
    max200: ~str,
    sq250: ~str,
    sq500: ~str,
    max1024: ~str,
    original: ~str,
}

impl CoverUrls {
    pub fn from_json(json: json::Json) -> CoverUrls {
        let mut decoder = json::Decoder::init(json);
        Decodable::decode(&mut decoder)
    }
}

#[deriving(Decodable, Clone)]
pub struct Mix {
    id: uint,
    path: ~str,
    web_path: ~str,
    name: ~str,
    description: ~str,
    plays_count: uint,
    likes_count: uint,
    certification: Option<~str>,
    // TODO parse this...
    tag_list_cache: ~str,
    duration: uint,
    tracks_count: uint,
    nsfw: bool,
    liked_by_current_user: bool,
    cover_urls: CoverUrls,
    // TODO parse this...
    first_published_at: ~str,
    user_id: uint,
}

impl Mix {
    pub fn from_json(json: &json::Json) -> Mix {
        let obj = expect_json_object(json);
        Mix {
            id: extract_from_json_object(obj, &~"id"),
            path: extract_from_json_object(obj, &~"path"),
            web_path: extract_from_json_object(obj, &~"web_path"),
            name: extract_from_json_object(obj, &~"name"),
            description: extract_from_json_object(obj, &~"description"),
            plays_count: extract_from_json_object(obj, &~"plays_count"),
            likes_count: extract_from_json_object(obj, &~"likes_count"),
            certification: maybe_extract_from_json_object(obj, &~"certification"),
            tag_list_cache: maybe_extract_from_json_object(obj, &~"tags_list_cache").unwrap_or_default(),
            duration: extract_from_json_object(obj, &~"duration"),
            tracks_count: extract_from_json_object(obj, &~"tracks_count"),
            nsfw: maybe_extract_from_json_object(obj, &~"nsfw").unwrap_or_default(),
            liked_by_current_user: maybe_extract_from_json_object(obj, &~"liked_by_current_user").unwrap_or_default(),
            cover_urls: CoverUrls::from_json(obj.find(&~"cover_urls").unwrap().clone()),
            first_published_at: extract_from_json_object(obj, &~"first_published_at"),
            user_id: extract_from_json_object(obj, &~"user_id"),
        }
    }
}

#[deriving(Decodable)]
struct MixSet {
    mixes: ~[Mix],
    smart_id: ~str,
    smart_type: ~str,
    path: ~str,
    name: ~str,
    web_path: ~str,
}

impl MixSet {
    pub fn from_json(json: &json::Json) -> MixSet {
        let obj = expect_json_object(json);
        let mixes_list = match obj.find(&~"mixes") {
            Some(&json::List(ref list)) => list,
            _ => fail!("expected mixes list in mix set, got {:?}", obj)
        };
        let mixes = mixes_list.map(|json| { Mix::from_json(json) });
        MixSet {
            mixes: mixes,
            smart_id: extract_from_json_object(obj, &~"smart_id"),
            smart_type: extract_from_json_object(obj, &~"smart_type"),
            path: extract_from_json_object(obj, &~"path"),
            name: extract_from_json_object(obj, &~"name"),
            web_path: extract_from_json_object(obj, &~"web_path"),
        }
    }
}

pub fn parse_mix_set_response(json: &json::Json) -> Response<MixSet> {
    let obj = expect_json_object(json);
    let mix_set = MixSet::from_json(obj.find(&~"mix_set").unwrap());
    Response::from_json(json, mix_set)
}
<|endoftext|>


<commit_before>use std::os::args;
use std::from_str::FromStr;

fn main() {
    let a : int = FromStr::from_str(args()[1]).unwrap();
    let b : int = FromStr::from_str(args()[2]).unwrap();

    let (g, u, v) = eea(a, b, 1, a, 0, b);
    println(fmt!("%d (a) * %d (u) + %d (b) * %d (v) = %d (gcd(a,b))", a, u, b, v, g));
}

fn eea(a : int, b : int, u : int, g : int, x : int, y : int) -> (int,int,int) {
    if y == 0 {
        return (g, u, (g - a * u)/b);
    }
    let q = g / y;
    let t = g % y;
    let s = u - q * x;
    eea(a, b, x, y, s, t)
}<commit_msg>make eea calculate positive u<commit_after>use std::os::args;
use std::from_str::FromStr;

fn main() {
    let a : int = FromStr::from_str(args()[1]).unwrap();
    let b : int = FromStr::from_str(args()[2]).unwrap();

    let (g, u, v) = eea(a, b, 1, a, 0, b);
    println(fmt!("%d (a) * %d (u) + %d (b) * %d (v) = %d (gcd(a,b))", a, u, b, v, g));
}

fn eea(a : int, b : int, u : int, g : int, x : int, y : int) -> (int,int,int) {
    if y == 0 {
        let mut ur = u;
        let mut vr = (g - a * u)/b;
        while ur < 0 {
            ur += b/g; vr -= a/g;
        }
        return (g, ur, vr);
    }
    let q = g / y;
    let t = g % y;
    let s = u - q * x;
    eea(a, b, x, y, s, t)
}<|endoftext|>


<commit_before>//! # The Redox OS Kernel, version 2
//!
//! The Redox OS Kernel is a hybrid kernel that supports X86 systems and
//! provides Unix-like syscalls for primarily Rust applications
//!
//! ## Syscalls
//! Syscalls in Redox are often handled by userspace `schemes`.
//! The essential syscalls in Redox are as follows:
//!
//! ### Open
//! `open(path: &str, flags: usize) -> Result<file_descriptor: usize>`
//!
//! Open a file, providing a path as a `&str` and flags, defined elsewhere.
//!
//! Returns a number, known as a file descriptor, that is passed to other syscalls
//!
//! ### Close
//! `close(file_descriptor: usize) -> Result<()>`
//!
//! Close a file descriptor, providing the file descriptor from `open`
//!
//! Returns an error, `EBADF`, if the file descriptor was not found.
//!
//! This potential error is often ignored by userspace
//!
//! ### Duplicate
//! `dup(file_descriptor: usize) -> Result<file_descriptor: usize>`
//!
//! Duplicate a file descriptor, providing the file descriptor from `open`
//!
//! Returns a new file descriptor, or an error
//!
//! ### Read
//! `read(file_descriptor: usize, buffer: &mut [u8]) -> Result<count: usize>`
//!
//! Read from a file descriptor, providing the file descriptor from `open` and a mutable buffer
//!
//! Returns the number of bytes actually read, or an error
//!
//! ### Write
//! `write(file_descriptor: usize, buffer: &[u8]) -> Result<count: usize>`
//!
//! Write to a file descriptor, providing the file descriptor from `open` and a const buffer
//!
//! Returns the number of bytes actually written, or an error
//!
//! ### Stat
//! `fstat(file_descriptor: usize, stat: &mut Stat) -> Result<()>`
//!
//! Get information from a file descriptor, providing the file descriptor from `open`
//! and a mutable Stat struct, defined elsewhere.
//!
//! Returns an error if the operation failed
//!
//! ### Path
//! `fpath(file_descriptor: usize, buffer: &mut [u8]) -> Result<count: usize>`
//!
//! Read the path of a file descriptor, providing the file descriptor from `open` and
//! a mutable buffer.
//!
//! Returns the number of bytes actually read, or an error
//!
//! The buffer should be 4096 bytes, to ensure that the entire path will fit.
//! An error will be returned, `ENOBUFS`, if the buffer is not long enough for the name.
//! In this case, it is recommended to add one page, 4096 bytes, to the buffer and retry.

#![feature(alloc)]
#![feature(collections)]
#![feature(const_fn)]
#![feature(question_mark)]
#![no_std]

use arch::interrupt;

/// Architecture specific items (test)
#[cfg(test)]
#[macro_use]
extern crate arch_test as arch;

/// Architecture specific items (x86_64)
#[cfg(all(not(test), target_arch = "x86_64"))]
#[macro_use]
extern crate arch_x86_64 as arch;

extern crate alloc;
#[macro_use]
extern crate collections;

#[macro_use]
extern crate bitflags;
#[macro_use]
extern crate lazy_static;
extern crate spin;

/// Context management
pub mod context;

/// Schemes, filesystem handlers
pub mod scheme;

/// Syscall handlers
pub mod syscall;

/// Tests
#[cfg(test)]
pub mod tests;

#[no_mangle]
pub extern fn kmain() {
    loop {
        unsafe { interrupt::enable_and_halt(); }
        print!("HALT\n");
    }
}
<commit_msg>Print out more useful information about AP and BSP, create kmain_ap<commit_after>//! # The Redox OS Kernel, version 2
//!
//! The Redox OS Kernel is a hybrid kernel that supports X86 systems and
//! provides Unix-like syscalls for primarily Rust applications
//!
//! ## Syscalls
//! Syscalls in Redox are often handled by userspace `schemes`.
//! The essential syscalls in Redox are as follows:
//!
//! ### Open
//! `open(path: &str, flags: usize) -> Result<file_descriptor: usize>`
//!
//! Open a file, providing a path as a `&str` and flags, defined elsewhere.
//!
//! Returns a number, known as a file descriptor, that is passed to other syscalls
//!
//! ### Close
//! `close(file_descriptor: usize) -> Result<()>`
//!
//! Close a file descriptor, providing the file descriptor from `open`
//!
//! Returns an error, `EBADF`, if the file descriptor was not found.
//!
//! This potential error is often ignored by userspace
//!
//! ### Duplicate
//! `dup(file_descriptor: usize) -> Result<file_descriptor: usize>`
//!
//! Duplicate a file descriptor, providing the file descriptor from `open`
//!
//! Returns a new file descriptor, or an error
//!
//! ### Read
//! `read(file_descriptor: usize, buffer: &mut [u8]) -> Result<count: usize>`
//!
//! Read from a file descriptor, providing the file descriptor from `open` and a mutable buffer
//!
//! Returns the number of bytes actually read, or an error
//!
//! ### Write
//! `write(file_descriptor: usize, buffer: &[u8]) -> Result<count: usize>`
//!
//! Write to a file descriptor, providing the file descriptor from `open` and a const buffer
//!
//! Returns the number of bytes actually written, or an error
//!
//! ### Stat
//! `fstat(file_descriptor: usize, stat: &mut Stat) -> Result<()>`
//!
//! Get information from a file descriptor, providing the file descriptor from `open`
//! and a mutable Stat struct, defined elsewhere.
//!
//! Returns an error if the operation failed
//!
//! ### Path
//! `fpath(file_descriptor: usize, buffer: &mut [u8]) -> Result<count: usize>`
//!
//! Read the path of a file descriptor, providing the file descriptor from `open` and
//! a mutable buffer.
//!
//! Returns the number of bytes actually read, or an error
//!
//! The buffer should be 4096 bytes, to ensure that the entire path will fit.
//! An error will be returned, `ENOBUFS`, if the buffer is not long enough for the name.
//! In this case, it is recommended to add one page, 4096 bytes, to the buffer and retry.

#![feature(alloc)]
#![feature(collections)]
#![feature(const_fn)]
#![feature(question_mark)]
#![no_std]

use arch::interrupt;

/// Architecture specific items (test)
#[cfg(test)]
#[macro_use]
extern crate arch_test as arch;

/// Architecture specific items (x86_64)
#[cfg(all(not(test), target_arch = "x86_64"))]
#[macro_use]
extern crate arch_x86_64 as arch;

extern crate alloc;
#[macro_use]
extern crate collections;

#[macro_use]
extern crate bitflags;
#[macro_use]
extern crate lazy_static;
extern crate spin;

/// Context management
pub mod context;

/// Schemes, filesystem handlers
pub mod scheme;

/// Syscall handlers
pub mod syscall;

/// Tests
#[cfg(test)]
pub mod tests;

#[no_mangle]
pub extern fn kmain() {
    loop {
        unsafe { interrupt::enable_and_halt(); }
        print!("INT BSP\n");
    }
}

#[no_mangle]
pub extern fn kmain_ap() {
    loop {
        unsafe { interrupt::enable_and_halt() }
        print!("INT AP\n");
    }
}
<|endoftext|>


<commit_before>use syntax::ast::{Expr, Ident, Pat, Stmt, TokenTree};
use syntax::ext::base::ExtCtxt;
use syntax::ext::build::AstBuilder;
use syntax::parse::token;
use syntax::ptr::P;

use maud;

#[derive(Copy)]
pub enum Escape {
    PassThru,
    Escape,
}

pub struct Renderer<'cx, 's: 'cx> {
    pub cx: &'cx ExtCtxt<'s>,
    stmts: Vec<P<Stmt>>,
    w: Ident,
}

impl<'cx, 's> Renderer<'cx, 's> {
    /// Create a new `Renderer` using the given extension context.
    pub fn new(cx: &'cx ExtCtxt<'s>) -> Renderer<'cx, 's> {
        Renderer {
            cx: cx,
            stmts: vec![],
            w: Ident::new(token::intern("w")),
        }
    }

    /// Create a new `Renderer` under the same context as `self`.
    pub fn fork(&self) -> Renderer<'cx, 's> {
        Renderer {
            cx: self.cx,
            stmts: vec![],
            w: self.w,
        }
    }

    /// Reify the `Renderer` into a block of markup.
    pub fn into_expr(self) -> P<Expr> {
        let Renderer { cx, stmts, w } = self;
        quote_expr!(cx,
            ::maud::rt::make_markup(|$w: &mut ::std::fmt::Write| -> Result<(), ::std::fmt::Error> {
                $stmts
                Ok(())
            }))
    }

    /// Reify the `Renderer` into a raw list of statements.
    pub fn into_stmts(self) -> Vec<P<Stmt>> {
        let Renderer { stmts, .. } = self;
        stmts
    }

    /// Append the list of statements to the output.
    pub fn push_stmts(&mut self, mut stmts: Vec<P<Stmt>>) {
        self.stmts.append(&mut stmts);
    }

    /// Push an expression statement, also wrapping it with `try!`.
    fn push_try(&mut self, expr: P<Expr>) {
        let stmt = self.cx.stmt_expr(self.cx.expr_try(expr.span, expr));
        self.stmts.push(stmt);
    }

    /// Append a literal pre-escaped string.
    fn write(&mut self, s: &str) {
        let w = self.w;
        let expr = quote_expr!(self.cx, $w.write_str($s));
        self.push_try(expr);
    }

    /// Append a literal string, with the specified escaping method.
    pub fn string(&mut self, s: &str, escape: Escape) {
        let escaped;
        let s = match escape {
            Escape::PassThru => s,
            Escape::Escape => { escaped = maud::escape(s); &*escaped },
        };
        self.write(s);
    }

    /// Append the result of an expression, with the specified escaping method.
    pub fn splice(&mut self, expr: P<Expr>, escape: Escape) {
        let w = self.w;
        let expr = match escape {
            Escape::PassThru =>
                quote_expr!(self.cx, ::maud::rt::write_fmt($w, $expr)),
            Escape::Escape =>
                quote_expr!(self.cx,
                    ::maud::rt::write_fmt(
                        &mut ::maud::rt::Escaper { inner: $w },
                        $expr)),
        };
        self.push_try(expr);
    }

    pub fn element_open_start(&mut self, name: &str) {
        self.write("<");
        self.write(name);
    }

    pub fn attribute_start(&mut self, name: &str) {
        self.write(" ");
        self.write(name);
        self.write("=\"");
    }

    pub fn attribute_empty(&mut self, name: &str) {
        self.write(" ");
        self.write(name);
    }

    pub fn attribute_end(&mut self) {
        self.write("\"");
    }

    pub fn element_open_end(&mut self) {
        self.write(">");
    }

    pub fn element_close(&mut self, name: &str) {
        self.write("</");
        self.write(name);
        self.write(">");
    }

    /// Emit an `if` expression.
    ///
    /// The condition is a token tree (not an expression) so we don't
    /// need to special-case `if let`.
    pub fn emit_if(&mut self, if_cond: Vec<TokenTree>, if_body: Vec<P<Stmt>>,
                   else_body: Option<Vec<P<Stmt>>>) {
        let stmt = match else_body {
            None => quote_stmt!(self.cx, if $if_cond { $if_body }),
            Some(else_body) =>
                quote_stmt!(self.cx, if $if_cond { $if_body } else { $else_body }),
        };
        self.stmts.push(stmt);
    }

    pub fn emit_for(&mut self, pattern: P<Pat>, iterable: P<Expr>, body: Vec<P<Stmt>>) {
        let stmt = quote_stmt!(self.cx, for $pattern in $iterable { $body });
        self.stmts.push(stmt);
    }
}
<commit_msg>Epic rustup of doom<commit_after>use syntax::ast::{Expr, Ident, Pat, Stmt, TokenTree};
use syntax::ext::base::ExtCtxt;
use syntax::ext::build::AstBuilder;
use syntax::parse::token;
use syntax::ptr::P;

use maud;

#[derive(Copy)]
pub enum Escape {
    PassThru,
    Escape,
}

pub struct Renderer<'cx, 's: 'cx> {
    pub cx: &'cx ExtCtxt<'s>,
    stmts: Vec<P<Stmt>>,
    w: Ident,
}

impl<'cx, 's> Renderer<'cx, 's> {
    /// Create a new `Renderer` using the given extension context.
    pub fn new(cx: &'cx ExtCtxt<'s>) -> Renderer<'cx, 's> {
        Renderer {
            cx: cx,
            stmts: vec![],
            w: Ident::new(token::intern("w")),
        }
    }

    /// Create a new `Renderer` under the same context as `self`.
    pub fn fork(&self) -> Renderer<'cx, 's> {
        Renderer {
            cx: self.cx,
            stmts: vec![],
            w: self.w,
        }
    }

    /// Reify the `Renderer` into a block of markup.
    pub fn into_expr(self) -> P<Expr> {
        let Renderer { cx, stmts, w } = self;
        quote_expr!(cx,
            ::maud::rt::make_markup(|$w: &mut ::std::fmt::Write| -> Result<(), ::std::fmt::Error> {
                $stmts
                Ok(())
            }))
    }

    /// Reify the `Renderer` into a raw list of statements.
    pub fn into_stmts(self) -> Vec<P<Stmt>> {
        let Renderer { stmts, .. } = self;
        stmts
    }

    /// Append the list of statements to the output.
    pub fn push_stmts(&mut self, mut stmts: Vec<P<Stmt>>) {
        self.stmts.append(&mut stmts);
    }

    /// Push an expression statement, also wrapping it with `try!`.
    fn push_try(&mut self, expr: P<Expr>) {
        let stmt = self.cx.stmt_expr(self.cx.expr_try(expr.span, expr));
        self.stmts.push(stmt);
    }

    /// Append a literal pre-escaped string.
    fn write(&mut self, s: &str) {
        let w = self.w;
        let expr = quote_expr!(self.cx, $w.write_str($s));
        self.push_try(expr);
    }

    /// Append a literal string, with the specified escaping method.
    pub fn string(&mut self, s: &str, escape: Escape) {
        let escaped;
        let s = match escape {
            Escape::PassThru => s,
            Escape::Escape => { escaped = maud::escape(s); &*escaped },
        };
        self.write(s);
    }

    /// Append the result of an expression, with the specified escaping method.
    pub fn splice(&mut self, expr: P<Expr>, escape: Escape) {
        let w = self.w;
        let expr = match escape {
            Escape::PassThru =>
                quote_expr!(self.cx, ::maud::rt::write_fmt($w, $expr)),
            Escape::Escape =>
                quote_expr!(self.cx,
                    ::maud::rt::write_fmt(
                        &mut ::maud::rt::Escaper { inner: $w },
                        $expr)),
        };
        self.push_try(expr);
    }

    pub fn element_open_start(&mut self, name: &str) {
        self.write("<");
        self.write(name);
    }

    pub fn attribute_start(&mut self, name: &str) {
        self.write(" ");
        self.write(name);
        self.write("=\"");
    }

    pub fn attribute_empty(&mut self, name: &str) {
        self.write(" ");
        self.write(name);
    }

    pub fn attribute_end(&mut self) {
        self.write("\"");
    }

    pub fn element_open_end(&mut self) {
        self.write(">");
    }

    pub fn element_close(&mut self, name: &str) {
        self.write("</");
        self.write(name);
        self.write(">");
    }

    /// Emit an `if` expression.
    ///
    /// The condition is a token tree (not an expression) so we don't
    /// need to special-case `if let`.
    pub fn emit_if(&mut self, if_cond: Vec<TokenTree>, if_body: Vec<P<Stmt>>,
                   else_body: Option<Vec<P<Stmt>>>) {
        let stmt = match else_body {
            None => quote_stmt!(self.cx, if $if_cond { $if_body }),
            Some(else_body) =>
                quote_stmt!(self.cx, if $if_cond { $if_body } else { $else_body }),
        }.unwrap();
        self.stmts.push(stmt);
    }

    pub fn emit_for(&mut self, pattern: P<Pat>, iterable: P<Expr>, body: Vec<P<Stmt>>) {
        let stmt = quote_stmt!(self.cx, for $pattern in $iterable { $body }).unwrap();
        self.stmts.push(stmt);
    }
}
<|endoftext|>


<commit_before>use mio::{unix::EventedFd, Events, Poll, PollOpt, Ready, Token};

use libtiny_tui::{Colors, MsgTarget, TUIRet, TUI};
use term_input::{Event, Input};

fn main() {
    let mut tui = TUI::new(Colors::default());
    tui.new_server_tab("debug");
    tui.draw();

    let poll = Poll::new().unwrap();
    poll.register(
        &EventedFd(&libc::STDIN_FILENO),
        Token(libc::STDIN_FILENO as usize),
        Ready::readable(),
        PollOpt::level(),
    )
    .unwrap();

    let mut ev_buffer: Vec<Event> = Vec::new();
    let mut input = Input::new();
    let mut events = Events::with_capacity(10);
    'mainloop: loop {
        match poll.poll(&mut events, None) {
            Err(_) => {
                // usually SIGWINCH, which is caught by term_input
                tui.resize();
                tui.draw();
            }
            Ok(_) => {
                input.read_input_events(&mut ev_buffer);
                for ev in ev_buffer.drain(0..) {
                    match tui.handle_input_event(ev) {
                        TUIRet::Input { msg, .. } => {
                            tui.add_msg(
                                &msg.into_iter().collect::<String>(),
                                time::now(),
                                &MsgTarget::Server { serv_name: "debug" },
                            );
                        }
                        TUIRet::Abort => {
                            break 'mainloop;
                        }
                        _ => {}
                    }
                }
                tui.draw();
            }
        }
    }
}
<commit_msg>tui: Remove msg_area example<commit_after><|endoftext|>


<commit_before>extern crate rectangles;

use rectangles::count;

#[test]
fn test_zero_area_1() {
    let lines = vec![];
    assert_eq!(0, count(&lines))
}

#[test]
#[ignore]
fn test_zero_area_2() {
    let lines = vec![""];
    assert_eq!(0, count(&lines))
}

#[test]
#[ignore]
fn test_empty_area() {
    let lines = vec![" "];
    assert_eq!(0, count(&lines))
}

#[test]
#[ignore]
fn test_one_rectangle() {
    let lines = vec![
        "+-+",
        "| |",
        "+-+",
        ];
    assert_eq!(1, count(&lines))
}

#[test]
#[ignore]
fn test_two_rectangles_no_shared_parts() {
    let lines = vec![
        "  +-+",
        "  | |",
        "+-+-+",
        "| |  ",
        "+-+  "
        ];
    assert_eq!(2, count(&lines))
}

#[test]
#[ignore]
fn test_five_rectangles_three_regions() {
    let lines = vec![
        "  +-+",
        "  | |",
        "+-+-+",
        "| | |",
        "+-+-+"
        ];
    assert_eq!(5, count(&lines))
}

#[test]
#[ignore]
fn rectangle_of_height_1() {
    let lines = vec![
        "+--+",
        "+--+"
        ];
    assert_eq!(1, count(&lines))
}

#[test]
#[ignore]
fn rectangle_of_width_1() {
    let lines = vec![
        "++",
        "||",
        "++"
        ];
    assert_eq!(1, count(&lines))
}

#[test]
#[ignore]
fn unit_equare() {
    let lines = vec![
        "++",
        "++"
        ];
    assert_eq!(1, count(&lines))
}

#[test]
#[ignore]
fn test_incomplete_rectangles() {
    let lines = vec![
        "  +-+",
        "    |",
        "+-+-+",
        "| | -",
        "+-+-+"
        ];
    assert_eq!(1, count(&lines))
}

#[test]
#[ignore]
fn test_complicated() {
    let lines = vec![
        "+------+----+",
        "|      |    |",
        "+---+--+    |",
        "|   |       |",
        "+---+-------+"
        ];
    assert_eq!(3, count(&lines))
}

#[test]
#[ignore]
fn test_not_so_complicated() {
    let lines = vec![
        "+------+----+",
        "|      |    |",
        "+------+    |",
        "|   |       |",
        "+---+-------+"
        ];
    assert_eq!(2, count(&lines))
}

#[test]
#[ignore]
fn test_large_input_with_many_rectangles() {
    let lines = vec![
        "+---+--+----+",
        "|   +--+----+",
        "+---+--+    |",
        "|   +--+----+",
        "+---+--+--+-+",
        "+---+--+--+-+",
        "+------+  | |",
        "          +-+"
        ];
    assert_eq!(60, count(&lines))
}
<commit_msg>rectangles: Use &[T] instead of &Vec<T> for input lines<commit_after>extern crate rectangles;

use rectangles::count;

#[test]
fn test_zero_area_1() {
    let lines = &[];
    assert_eq!(0, count(lines))
}

#[test]
#[ignore]
fn test_zero_area_2() {
    let lines = &[""];
    assert_eq!(0, count(lines))
}

#[test]
#[ignore]
fn test_empty_area() {
    let lines = &[" "];
    assert_eq!(0, count(lines))
}

#[test]
#[ignore]
fn test_one_rectangle() {
    let lines = &[
        "+-+",
        "| |",
        "+-+",
        ];
    assert_eq!(1, count(lines))
}

#[test]
#[ignore]
fn test_two_rectangles_no_shared_parts() {
    let lines = &[
        "  +-+",
        "  | |",
        "+-+-+",
        "| |  ",
        "+-+  "
        ];
    assert_eq!(2, count(lines))
}

#[test]
#[ignore]
fn test_five_rectangles_three_regions() {
    let lines = &[
        "  +-+",
        "  | |",
        "+-+-+",
        "| | |",
        "+-+-+"
        ];
    assert_eq!(5, count(lines))
}

#[test]
#[ignore]
fn rectangle_of_height_1() {
    let lines = &[
        "+--+",
        "+--+"
        ];
    assert_eq!(1, count(lines))
}

#[test]
#[ignore]
fn rectangle_of_width_1() {
    let lines = &[
        "++",
        "||",
        "++"
        ];
    assert_eq!(1, count(lines))
}

#[test]
#[ignore]
fn unit_equare() {
    let lines = &[
        "++",
        "++"
        ];
    assert_eq!(1, count(lines))
}

#[test]
#[ignore]
fn test_incomplete_rectangles() {
    let lines = &[
        "  +-+",
        "    |",
        "+-+-+",
        "| | -",
        "+-+-+"
        ];
    assert_eq!(1, count(lines))
}

#[test]
#[ignore]
fn test_complicated() {
    let lines = &[
        "+------+----+",
        "|      |    |",
        "+---+--+    |",
        "|   |       |",
        "+---+-------+"
        ];
    assert_eq!(3, count(lines))
}

#[test]
#[ignore]
fn test_not_so_complicated() {
    let lines = &[
        "+------+----+",
        "|      |    |",
        "+------+    |",
        "|   |       |",
        "+---+-------+"
        ];
    assert_eq!(2, count(lines))
}

#[test]
#[ignore]
fn test_large_input_with_many_rectangles() {
    let lines = &[
        "+---+--+----+",
        "|   +--+----+",
        "+---+--+    |",
        "|   +--+----+",
        "+---+--+--+-+",
        "+---+--+--+-+",
        "+------+  | |",
        "          +-+"
        ];
    assert_eq!(60, count(lines))
}
<|endoftext|>


<commit_before>use std::collections::HashSet;
use std::io::{File, fs};
use util;
use core::{Package,Manifest,SourceId};
use util::{CargoResult, human};
use util::important_paths::find_project_manifest_exact;

pub fn read_manifest(contents: &[u8], source_id: &SourceId)
    -> CargoResult<(Manifest, Vec<Path>)>
{
    util::toml::to_manifest(contents, source_id).map_err(human)
}

pub fn read_package(path: &Path, source_id: &SourceId)
    -> CargoResult<(Package, Vec<Path>)>
{
    log!(5, "read_package; path={}; source-id={}", path.display(), source_id);
    let mut file = try!(File::open(path));
    let data = try!(file.read_to_end());
    let (manifest, nested) = try!(read_manifest(data.as_slice(),
                                                      source_id));

    Ok((Package::new(manifest, path, source_id), nested))
}

pub fn read_packages(path: &Path,
                     source_id: &SourceId) -> CargoResult<Vec<Package>>
{
    let mut all_packages = Vec::new();
    let mut visited = HashSet::<Path>::new();

    log!(5, "looking for root package: {}, source_id={}", path.display(), source_id);
    try!(process_possible_package(path, &mut all_packages, source_id, &mut visited));

    try!(walk(path, true, |dir| {
        log!(5, "looking for child package: {}", dir.display());
        if dir.filename_str() == Some(".git") { return Ok(false); }
        if dir.join(".git").is_dir() { return Ok(false); }
        try!(process_possible_package(dir, &mut all_packages, source_id, &mut visited));
        Ok(true)
    }));

    if all_packages.is_empty() {
        Err(human(format!("Could not find Cargo.toml in `{}`", path.display())))
    } else {
        log!(5, "all packages: {}", all_packages);
        Ok(all_packages)
    }
}

fn walk(path: &Path, is_root: bool, callback: |&Path| -> CargoResult<bool>) -> CargoResult<()> {
    if path.is_dir() {
        if !is_root {
            let continues = try!(callback(path));
            if !continues { log!(5, "Found submodule at {}", path.display()); return Ok(()); }
        }

        for dir in try!(fs::readdir(path)).iter() {
            try!(walk(dir, false, |x| callback(x)))
        }
    }

    Ok(())
}

fn process_possible_package(dir: &Path,
                            all_packages: &mut Vec<Package>,
                            source_id: &SourceId,
                            visited: &mut HashSet<Path>) -> CargoResult<()> {

    if !has_manifest(dir) { return Ok(()); }

    let packages = try!(read_nested_packages(dir, source_id, visited));
    push_all(all_packages, packages);

    Ok(())
}

fn has_manifest(path: &Path) -> bool {
    find_project_manifest_exact(path, "Cargo.toml").is_ok()
}

fn read_nested_packages(path: &Path, source_id: &SourceId,
                 visited: &mut HashSet<Path>) -> CargoResult<Vec<Package>> {
    if !visited.insert(path.clone()) { return Ok(Vec::new()) }

    let manifest = try!(find_project_manifest_exact(path, "Cargo.toml"));

    let (pkg, nested) = try!(read_package(&manifest, source_id));
    let mut ret = vec![pkg];

    for p in nested.iter() {
        ret.push_all(try!(read_nested_packages(&path.join(p),
                                        source_id,
                                        visited)).as_slice());
    }

    Ok(ret)
}

fn push_all(set: &mut Vec<Package>, packages: Vec<Package>) {
    for package in packages.move_iter() {
        if set.contains(&package) { continue; }

        set.push(package)
    }
}
<commit_msg>Improvements based on the review<commit_after>use std::collections::HashSet;
use std::io::{File, fs};
use util;
use core::{Package,Manifest,SourceId};
use util::{CargoResult, human};
use util::important_paths::find_project_manifest_exact;

pub fn read_manifest(contents: &[u8], source_id: &SourceId)
    -> CargoResult<(Manifest, Vec<Path>)>
{
    util::toml::to_manifest(contents, source_id).map_err(human)
}

pub fn read_package(path: &Path, source_id: &SourceId)
    -> CargoResult<(Package, Vec<Path>)>
{
    log!(5, "read_package; path={}; source-id={}", path.display(), source_id);
    let mut file = try!(File::open(path));
    let data = try!(file.read_to_end());
    let (manifest, nested) = try!(read_manifest(data.as_slice(),
                                                      source_id));

    Ok((Package::new(manifest, path, source_id), nested))
}

pub fn read_packages(path: &Path,
                     source_id: &SourceId) -> CargoResult<Vec<Package>>
{
    let mut all_packages = Vec::new();
    let mut visited = HashSet::<Path>::new();

    log!(5, "looking for root package: {}, source_id={}", path.display(), source_id);
    try!(process_possible_package(path, &mut all_packages, source_id, &mut visited));

    try!(walk(path, true, |dir| {
        log!(5, "looking for child package: {}", dir.display());
        if dir.filename_str() == Some(".git") { return Ok(false); }
        if dir.join(".git").exists() { return Ok(false); }
        try!(process_possible_package(dir, &mut all_packages, source_id, &mut visited));
        Ok(true)
    }));

    if all_packages.is_empty() {
        Err(human(format!("Could not find Cargo.toml in `{}`", path.display())))
    } else {
        log!(5, "all packages: {}", all_packages);
        Ok(all_packages)
    }
}

fn walk(path: &Path, is_root: bool, callback: |&Path| -> CargoResult<bool>) -> CargoResult<()> {
    if path.is_dir() {
        if !is_root {
            let continues = try!(callback(path));
            if !continues { log!(5, "Found submodule at {}", path.display()); return Ok(()); }
        }

        for dir in try!(fs::readdir(path)).iter() {
            try!(walk(dir, false, |x| callback(x)))
        }
    }

    Ok(())
}

fn process_possible_package(dir: &Path,
                            all_packages: &mut Vec<Package>,
                            source_id: &SourceId,
                            visited: &mut HashSet<Path>) -> CargoResult<()> {

    if !has_manifest(dir) { return Ok(()); }

    let packages = try!(read_nested_packages(dir, source_id, visited));
    push_all(all_packages, packages);

    Ok(())
}

fn has_manifest(path: &Path) -> bool {
    find_project_manifest_exact(path, "Cargo.toml").is_ok()
}

fn read_nested_packages(path: &Path, source_id: &SourceId,
                 visited: &mut HashSet<Path>) -> CargoResult<Vec<Package>> {
    if !visited.insert(path.clone()) { return Ok(Vec::new()) }

    let manifest = try!(find_project_manifest_exact(path, "Cargo.toml"));

    let (pkg, nested) = try!(read_package(&manifest, source_id));
    let mut ret = vec![pkg];

    for p in nested.iter() {
        ret.push_all_move(try!(read_nested_packages(&path.join(p),
                                        source_id,
                                        visited)));
    }

    Ok(ret)
}

fn push_all(set: &mut Vec<Package>, packages: Vec<Package>) {
    for package in packages.move_iter() {
        if set.contains(&package) { continue; }

        set.push(package)
    }
}
<|endoftext|>