<commit_before>#[allow(unused_imports, dead_code)]
mod test {
    use std::str;
    use std::io::{Cursor, Write};

    use regex::Regex;

    use clap::{App, Arg, SubCommand, ArgGroup};

    fn compare<S, S2>(l: S, r: S2) -> bool
        where S: AsRef<str>,
              S2: AsRef<str>
    {
        let re = Regex::new("\x1b[^m]*m").unwrap();
        // Strip out any mismatching \r character on windows that might sneak in on either side
        let left = re.replace_all(&l.as_ref().trim().replace("\r", "")[..], "");
        let right = re.replace_all(&r.as_ref().trim().replace("\r", "")[..], "");
        let b = left == right;
        if !b {
            println!("");
            println!("--> left");
            println!("{}", left);
            println!("--> right");
            println!("{}", right);
            println!("--")
        }
        b
    }

    pub fn compare_output(l: App, args: &str, right: &str, stderr: bool) -> bool {
        let mut buf = Cursor::new(Vec::with_capacity(50));
        let res = l.get_matches_from_safe(args.split(' ').collect::<Vec<_>>());
        let err = res.unwrap_err();
        err.write_to(&mut buf).unwrap();
        let content = buf.into_inner();
        let left = String::from_utf8(content).unwrap();
        assert_eq!(stderr, err.use_stderr());
        compare(left, right)
    }

    // Legacy tests from the pyhton script days

    pub fn complex_app() -> App<'static, 'static> {
        let args = "-o --option=[opt]... 'tests options'
                    [positional] 'tests positionals'";
        let opt3_vals = ["fast", "slow"];
        let pos3_vals = ["vi", "emacs"];
        App::new("clap-test")
            .version("v1.4.8")
            .about("tests clap library")
            .author("Kevin K. <kbknapp@gmail.com>")
            .args_from_usage(args)
            .arg(Arg::from_usage("-f --flag... 'tests flags'")
                .global(true))
            .args(&[
                Arg::from_usage("[flag2] -F 'tests flags with exclusions'").conflicts_with("flag").requires("long-option-2"),
                Arg::from_usage("--long-option-2 [option2] 'tests long options with exclusions'").conflicts_with("option").requires("positional2"),
                Arg::from_usage("[positional2] 'tests positionals with exclusions'"),
                Arg::from_usage("-O --Option [option3] 'specific vals'").possible_values(&opt3_vals),
                Arg::from_usage("[positional3]... 'tests specific values'").possible_values(&pos3_vals),
                Arg::from_usage("--multvals [one] [two] 'Tests mutliple values, not mult occs'"),
                Arg::from_usage("--multvalsmo... [one] [two] 'Tests mutliple values, and mult occs'"),
                Arg::from_usage("--minvals2 [minvals]... 'Tests 2 min vals'").min_values(2),
                Arg::from_usage("--maxvals3 [maxvals]... 'Tests 3 max vals'").max_values(3)
            ])
            .subcommand(SubCommand::with_name("subcmd")
                                    .about("tests subcommands")
                                    .version("0.1")
                                    .author("Kevin K. <kbknapp@gmail.com>")
                                    .arg_from_usage("-o --option [scoption]... 'tests options'")
                                    .arg_from_usage("[scpositional] 'tests positionals'"))
    }
}
<commit_msg>tests: fixes lifetime issue in a test<commit_after>#[allow(unused_imports, dead_code)]
mod test {
    use std::str;
    use std::io::{Cursor, Write};

    use regex::Regex;

    use clap::{App, Arg, SubCommand, ArgGroup};

    fn compare<S, S2>(l: S, r: S2) -> bool
        where S: AsRef<str>,
              S2: AsRef<str>
    {
        let re = Regex::new("\x1b[^m]*m").unwrap();
        // Strip out any mismatching \r character on windows that might sneak in on either side
        let ls = l.as_ref().trim().replace("\r", "");
        let rs = r.as_ref().trim().replace("\r", "");
        let left = re.replace_all(&*ls, "");
        let right = re.replace_all(&*rs, "");
        let b = left == right;
        if !b {
            println!("");
            println!("--> left");
            println!("{}", left);
            println!("--> right");
            println!("{}", right);
            println!("--")
        }
        b
    }

    pub fn compare_output(l: App, args: &str, right: &str, stderr: bool) -> bool {
        let mut buf = Cursor::new(Vec::with_capacity(50));
        let res = l.get_matches_from_safe(args.split(' ').collect::<Vec<_>>());
        let err = res.unwrap_err();
        err.write_to(&mut buf).unwrap();
        let content = buf.into_inner();
        let left = String::from_utf8(content).unwrap();
        assert_eq!(stderr, err.use_stderr());
        compare(left, right)
    }

    // Legacy tests from the pyhton script days

    pub fn complex_app() -> App<'static, 'static> {
        let args = "-o --option=[opt]... 'tests options'
                    [positional] 'tests positionals'";
        let opt3_vals = ["fast", "slow"];
        let pos3_vals = ["vi", "emacs"];
        App::new("clap-test")
            .version("v1.4.8")
            .about("tests clap library")
            .author("Kevin K. <kbknapp@gmail.com>")
            .args_from_usage(args)
            .arg(Arg::from_usage("-f --flag... 'tests flags'")
                .global(true))
            .args(&[
                Arg::from_usage("[flag2] -F 'tests flags with exclusions'").conflicts_with("flag").requires("long-option-2"),
                Arg::from_usage("--long-option-2 [option2] 'tests long options with exclusions'").conflicts_with("option").requires("positional2"),
                Arg::from_usage("[positional2] 'tests positionals with exclusions'"),
                Arg::from_usage("-O --Option [option3] 'specific vals'").possible_values(&opt3_vals),
                Arg::from_usage("[positional3]... 'tests specific values'").possible_values(&pos3_vals),
                Arg::from_usage("--multvals [one] [two] 'Tests mutliple values, not mult occs'"),
                Arg::from_usage("--multvalsmo... [one] [two] 'Tests mutliple values, and mult occs'"),
                Arg::from_usage("--minvals2 [minvals]... 'Tests 2 min vals'").min_values(2),
                Arg::from_usage("--maxvals3 [maxvals]... 'Tests 3 max vals'").max_values(3)
            ])
            .subcommand(SubCommand::with_name("subcmd")
                                    .about("tests subcommands")
                                    .version("0.1")
                                    .author("Kevin K. <kbknapp@gmail.com>")
                                    .arg_from_usage("-o --option [scoption]... 'tests options'")
                                    .arg_from_usage("[scpositional] 'tests positionals'"))
    }
}
<|endoftext|>


<commit_before>use cairo;
use cairo::Rectangle;
use markup5ever::{expanded_name, local_name, namespace_url, ns};

use crate::allowed_url::Href;
use crate::aspect_ratio::AspectRatio;
use crate::bbox::BoundingBox;
use crate::drawing_ctx::{ClipMode, DrawingCtx};
use crate::error::{NodeError, RenderingError};
use crate::float_eq_cairo::ApproxEqCairo;
use crate::length::*;
use crate::node::*;
use crate::parsers::{ParseError, ParseValue};
use crate::property_bag::PropertyBag;
use crate::rect::RectangleExt;
use crate::viewbox::ViewBox;

#[derive(Default)]
pub struct Image {
    x: Length<Horizontal>,
    y: Length<Vertical>,
    w: Length<Horizontal>,
    h: Length<Vertical>,
    aspect: AspectRatio,
    href: Option<Href>,
}

impl NodeTrait for Image {
    fn set_atts(&mut self, _: Option<&RsvgNode>, pbag: &PropertyBag<'_>) -> NodeResult {
        for (attr, value) in pbag.iter() {
            match attr.expanded() {
                expanded_name!(svg "x") => self.x = attr.parse(value)?,
                expanded_name!(svg "y") => self.y = attr.parse(value)?,
                expanded_name!(svg "width") => {
                    self.w = attr.parse_and_validate(value, Length::check_nonnegative)?
                }
                expanded_name!(svg "height") => {
                    self.h = attr.parse_and_validate(value, Length::check_nonnegative)?
                }
                expanded_name!(svg "preserveAspectRatio") => self.aspect = attr.parse(value)?,

                // "path" is used by some older Adobe Illustrator versions
                expanded_name!(xlink "href") | expanded_name!(svg "path") => {
                    let href = Href::parse(value).map_err(|_| {
                        NodeError::parse_error(attr, ParseError::new("could not parse href"))
                    })?;

                    self.href = Some(href);
                }

                _ => (),
            }
        }

        Ok(())
    }

    fn overflow_hidden(&self) -> bool {
        true
    }

    fn draw(
        &self,
        node: &RsvgNode,
        cascaded: &CascadedValues<'_>,
        draw_ctx: &mut DrawingCtx,
        clipping: bool,
    ) -> Result<BoundingBox, RenderingError> {
        let values = cascaded.get();
        let params = draw_ctx.get_view_params();

        let x = self.x.normalize(values, &params);
        let y = self.y.normalize(values, &params);
        let w = self.w.normalize(values, &params);
        let h = self.h.normalize(values, &params);

        if w.approx_eq_cairo(0.0) || h.approx_eq_cairo(0.0) {
            return Ok(draw_ctx.empty_bbox());
        }

        draw_ctx.with_discrete_layer(node, values, clipping, &mut |dc| {
            let surface = if let Some(Href::PlainUrl(ref url)) = self.href {
                dc.lookup_image(&url)?
            } else {
                return Ok(dc.empty_bbox());
            };

            let clip_mode = if !values.is_overflow() && self.aspect.is_slice() {
                Some(ClipMode::ClipToViewport)
            } else {
                None
            };

            let image_width = surface.width();
            let image_height = surface.height();
            if clipping || image_width == 0 || image_height == 0 {
                return Ok(dc.empty_bbox());
            }

            // The bounding box for <image> is decided by the values of x, y, w, h and not by
            // the final computed image bounds.
            let bbox = dc.empty_bbox().with_rect(Some(
                cairo::Rectangle {
                    x,
                    y,
                    width: w,
                    height: h,
                },
            ));

            dc.with_saved_cr(&mut |dc| {
                let cr = dc.get_cairo_context();

                let image_width = f64::from(image_width);
                let image_height = f64::from(image_height);

                if let Some(_params) = dc.push_new_viewport(
                    Some(ViewBox::new(0.0, 0.0, image_width, image_height)),
                    &Rectangle::new(x, y, w, h),
                    self.aspect,
                    clip_mode,
                ) {
                    // We need to set extend appropriately, so can't use cr.set_source_surface().
                    //
                    // If extend is left at its default value (None), then bilinear scaling uses
                    // transparency outside of the image producing incorrect results.
                    // For example, in svg1.1/filters-blend-01-b.svgthere's a completely
                    // opaque 100×1 image of a gradient scaled to 100×98 which ends up
                    // transparent almost everywhere without this fix (which it shouldn't).
                    let ptn = surface.to_cairo_pattern();
                    ptn.set_extend(cairo::Extend::Pad);
                    cr.set_source(&ptn);

                    // Clip is needed due to extend being set to pad.
                    cr.rectangle(0.0, 0.0, image_width, image_height);
                    cr.clip();

                    cr.paint();
                }

                Ok(bbox)
            })
        })
    }
}
<commit_msg>image: small cleanup<commit_after>use cairo;
use cairo::Rectangle;
use markup5ever::{expanded_name, local_name, namespace_url, ns};

use crate::allowed_url::Href;
use crate::aspect_ratio::AspectRatio;
use crate::bbox::BoundingBox;
use crate::drawing_ctx::{ClipMode, DrawingCtx};
use crate::error::{NodeError, RenderingError};
use crate::float_eq_cairo::ApproxEqCairo;
use crate::length::*;
use crate::node::*;
use crate::parsers::{ParseError, ParseValue};
use crate::property_bag::PropertyBag;
use crate::rect::RectangleExt;
use crate::viewbox::ViewBox;

#[derive(Default)]
pub struct Image {
    x: Length<Horizontal>,
    y: Length<Vertical>,
    w: Length<Horizontal>,
    h: Length<Vertical>,
    aspect: AspectRatio,
    href: Option<Href>,
}

impl NodeTrait for Image {
    fn set_atts(&mut self, _: Option<&RsvgNode>, pbag: &PropertyBag<'_>) -> NodeResult {
        for (attr, value) in pbag.iter() {
            match attr.expanded() {
                expanded_name!(svg "x") => self.x = attr.parse(value)?,
                expanded_name!(svg "y") => self.y = attr.parse(value)?,
                expanded_name!(svg "width") => {
                    self.w = attr.parse_and_validate(value, Length::check_nonnegative)?
                }
                expanded_name!(svg "height") => {
                    self.h = attr.parse_and_validate(value, Length::check_nonnegative)?
                }
                expanded_name!(svg "preserveAspectRatio") => self.aspect = attr.parse(value)?,

                // "path" is used by some older Adobe Illustrator versions
                expanded_name!(xlink "href") | expanded_name!(svg "path") => {
                    let href = Href::parse(value).map_err(|_| {
                        NodeError::parse_error(attr, ParseError::new("could not parse href"))
                    })?;

                    self.href = Some(href);
                }

                _ => (),
            }
        }

        Ok(())
    }

    fn overflow_hidden(&self) -> bool {
        true
    }

    fn draw(
        &self,
        node: &RsvgNode,
        cascaded: &CascadedValues<'_>,
        draw_ctx: &mut DrawingCtx,
        clipping: bool,
    ) -> Result<BoundingBox, RenderingError> {
        let values = cascaded.get();
        let params = draw_ctx.get_view_params();

        let x = self.x.normalize(values, &params);
        let y = self.y.normalize(values, &params);
        let w = self.w.normalize(values, &params);
        let h = self.h.normalize(values, &params);

        if w.approx_eq_cairo(0.0) || h.approx_eq_cairo(0.0) {
            return Ok(draw_ctx.empty_bbox());
        }

        draw_ctx.with_discrete_layer(node, values, clipping, &mut |dc| {
            let surface = if let Some(Href::PlainUrl(ref url)) = self.href {
                dc.lookup_image(&url)?
            } else {
                return Ok(dc.empty_bbox());
            };

            let clip_mode = if !values.is_overflow() && self.aspect.is_slice() {
                Some(ClipMode::ClipToViewport)
            } else {
                None
            };

            let image_width = surface.width();
            let image_height = surface.height();
            if clipping || image_width == 0 || image_height == 0 {
                return Ok(dc.empty_bbox());
            }

            // The bounding box for <image> is decided by the values of x, y, w, h and not by
            // the final computed image bounds.
            let bbox = dc.empty_bbox().with_rect(Some(cairo::Rectangle {
                x,
                y,
                width: w,
                height: h,
            }));

            dc.with_saved_cr(&mut |dc| {
                let cr = dc.get_cairo_context();

                let image_width = f64::from(image_width);
                let image_height = f64::from(image_height);

                if let Some(_params) = dc.push_new_viewport(
                    Some(ViewBox::new(0.0, 0.0, image_width, image_height)),
                    &Rectangle::new(x, y, w, h),
                    self.aspect,
                    clip_mode,
                ) {
                    // We need to set extend appropriately, so can't use cr.set_source_surface().
                    //
                    // If extend is left at its default value (None), then bilinear scaling uses
                    // transparency outside of the image producing incorrect results.
                    // For example, in svg1.1/filters-blend-01-b.svgthere's a completely
                    // opaque 100×1 image of a gradient scaled to 100×98 which ends up
                    // transparent almost everywhere without this fix (which it shouldn't).
                    let ptn = surface.to_cairo_pattern();
                    ptn.set_extend(cairo::Extend::Pad);
                    cr.set_source(&ptn);

                    // Clip is needed due to extend being set to pad.
                    cr.rectangle(0.0, 0.0, image_width, image_height);
                    cr.clip();

                    cr.paint();
                }

                Ok(bbox)
            })
        })
    }
}
<|endoftext|>


<commit_before>use kernel_micro::{include_file, MicroKernel};

/// A microkernel for Bash
///
/// The `kernel-bash.sh` script relies on `/dev/stdin`, `/dev/stdout`,
/// and `/dev/stderr` so this kernel is not available on Windows.
pub fn new() -> MicroKernel {
    MicroKernel::new(
        "bash-micro",
        &["bash"],
        &["linux", "macos", "windows"],
        &[],
        ("bash", "*"),
        &["{{script}}"],
        include_file!("bash-kernel.sh"),
        &[],
        "{{name}}=\"{{json}}\"",
        "echo ${{name}}",
    )
}

#[cfg(test)]
mod tests {
    use super::*;
    use kernel::{eyre::Result, stencila_schema::Node, KernelTrait};
    use test_utils::{assert_json_eq, serde_json::json};

    /// Tests of basic functionality
    /// This test is replicated in all the microkernels.
    /// Other test should be written for language specific quirks and regressions.
    #[tokio::test]
    async fn basics() -> Result<()> {
        let mut kernel = new();
        if !kernel.available().await {
            return Ok(());
        } else {
            kernel.start().await?;
        }

        // Assign a variable and output it
        let (outputs, messages) = kernel.exec("a=2\necho $a").await?;
        assert_json_eq!(messages, json!([]));
        assert_json_eq!(outputs, [2]);

        // Syntax error
        let (outputs, messages) = kernel.exec("if").await?;
        assert!(messages[0]
            .error_message
            .ends_with("syntax error: unexpected end of file\n"));
        assert_json_eq!(outputs, json!([]));

        // Runtime error
        let (outputs, messages) = kernel.exec("foo").await?;
        assert!(messages[0]
            .error_message
            .ends_with("foo: command not found\n"));
        assert_json_eq!(outputs, json!([]));

        // Set and get another variable
        kernel.set("b", Node::Integer(3)).await?;
        let b = kernel.get("b").await?;
        assert_json_eq!(b, 3);

        // Use both variables
        let (outputs, messages) = kernel.exec("echo $a$b").await?;
        assert_json_eq!(messages, json!([]));
        assert_json_eq!(outputs, [23]);

        Ok(())
    }
}
<commit_msg>test(Bash microkernel): Skip tests on windows<commit_after>use kernel_micro::{include_file, MicroKernel};

/// A microkernel for Bash
///
/// The `kernel-bash.sh` script relies on `/dev/stdin`, `/dev/stdout`,
/// and `/dev/stderr` so this kernel is not available on Windows.
pub fn new() -> MicroKernel {
    MicroKernel::new(
        "bash-micro",
        &["bash"],
        &["linux", "macos", "windows"],
        &[],
        ("bash", "*"),
        &["{{script}}"],
        include_file!("bash-kernel.sh"),
        &[],
        "{{name}}=\"{{json}}\"",
        "echo ${{name}}",
    )
}

#[cfg(test)]
mod tests {
    use super::*;
    use kernel::{eyre::Result, stencila_schema::Node, KernelTrait};
    use test_utils::{assert_json_eq, serde_json::json, skip_ci_os};

    /// Tests of basic functionality
    /// This test is replicated in all the microkernels.
    /// Other test should be written for language specific quirks and regressions.
    #[tokio::test]
    async fn basics() -> Result<()> {
        if skip_ci_os("windows", "test currently failing on windows") {
            return Ok(());
        }

        let mut kernel = new();
        if !kernel.available().await {
            return Ok(());
        } else {
            kernel.start().await?;
        }

        // Assign a variable and output it
        let (outputs, messages) = kernel.exec("a=2\necho $a").await?;
        assert_json_eq!(messages, json!([]));
        assert_json_eq!(outputs, [2]);

        // Syntax error
        let (outputs, messages) = kernel.exec("if").await?;
        assert!(messages[0]
            .error_message
            .ends_with("syntax error: unexpected end of file\n"));
        assert_json_eq!(outputs, json!([]));

        // Runtime error
        let (outputs, messages) = kernel.exec("foo").await?;
        assert!(messages[0]
            .error_message
            .ends_with("foo: command not found\n"));
        assert_json_eq!(outputs, json!([]));

        // Set and get another variable
        kernel.set("b", Node::Integer(3)).await?;
        let b = kernel.get("b").await?;
        assert_json_eq!(b, 3);

        // Use both variables
        let (outputs, messages) = kernel.exec("echo $a$b").await?;
        assert_json_eq!(messages, json!([]));
        assert_json_eq!(outputs, [23]);

        Ok(())
    }
}
<|endoftext|>


<commit_before>// This entire module is Python 3.8+ and !Py_LIMITED_API only.

use crate::pyport::Py_ssize_t;
use libc::{c_char, c_int, c_ulong, wchar_t};

#[repr(C)]
#[derive(Copy, Clone)]
pub enum PyStatusType {
    _PyStatus_TYPE_OK = 0,
    _PyStatus_TYPE_ERROR = 1,
    _PyStatus_TYPE_EXIT = 2,
}

#[repr(C)]
#[derive(Copy, Clone)]
pub struct PyStatus {
    _type: PyStatusType,
    func: *const c_char,
    err_msg: *const c_char,
    exitcode: c_int,
}

#[cfg_attr(windows, link(name = "pythonXY"))]
extern "C" {
    pub fn PyStatus_Ok() -> PyStatus;
    pub fn PyStatus_Error(err_msg: *const c_char) -> PyStatus;
    pub fn PyStatus_NoMemory() -> PyStatus;
    pub fn PyStatus_Exit(exitcode: c_int) -> PyStatus;

    pub fn PyStatus_IsError(err: PyStatus) -> c_int;
    pub fn PyStatus_IsExit(err: PyStatus) -> c_int;
    pub fn PyStatus_Exception(err: PyStatus) -> c_int;
}

#[repr(C)]
#[derive(Copy, Clone)]
pub struct PyWideStringList {
    length: Py_ssize_t,
    items: *mut *mut wchar_t,
}

#[cfg_attr(windows, link(name = "pythonXY"))]
extern "C" {
    pub fn PyWideStringList_Append(list: *mut PyWideStringList, item: *const wchar_t) -> PyStatus;
    pub fn PyWideStringList_Insert(
        list: *mut PyWideStringList,
        index: Py_ssize_t,
        item: *const wchar_t,
    ) -> PyStatus;
}

#[repr(C)]
#[derive(Clone)]
pub struct PyPreConfig {
    _config_init: c_int,
    parse_argv: c_int,
    isolated: c_int,
    use_environment: c_int,
    configure_locale: c_int,
    coerce_c_locale: c_int,
    coerce_c_locale_warn: c_int,
    #[cfg(windows)]
    legacy_windows_fs_encoding: c_int,
    utf8_mode: c_int,
    dev_mode: c_int,
    allocator: c_int,
}

#[cfg_attr(windows, link(name = "pythonXY"))]
extern "C" {
    pub fn PyPreConfig_InitPythonConfig(config: *mut PyPreConfig) -> ();
    pub fn PyPreConfig_InitIsolatedConfig(config: *mut PyPreConfig) -> ();
}

#[repr(C)]
#[derive(Clone)]
pub struct PyConfig {
    _config_init: c_int,
    isolated: c_int,
    use_environment: c_int,
    dev_mode: c_int,
    install_signal_handlers: c_int,
    use_hash_seed: c_int,
    hash_seed: c_ulong,
    faulthandler: c_int,
    tracemalloc: c_int,
    import_time: c_int,
    show_ref_count: c_int,
    show_alloc_count: c_int,
    dump_refs: c_int,
    malloc_stats: c_int,
    filesystem_encoding: *mut wchar_t,
    filesystem_errors: *mut wchar_t,
    pycache_prefix: *mut wchar_t,
    parse_argv: c_int,
    argv: PyWideStringList,
    program_name: *mut wchar_t,
    xoptions: PyWideStringList,
    warnoptions: PyWideStringList,
    site_import: c_int,
    bytes_warning: c_int,
    inspect: c_int,
    interactive: c_int,
    optimization_level: c_int,
    parser_debug: c_int,
    write_bytecode: c_int,
    verbose: c_int,
    quiet: c_int,
    user_site_directory: c_int,
    configure_c_stdio: c_int,
    buffered_stdio: c_int,
    stdio_encoding: *mut wchar_t,
    stdio_errors: *mut wchar_t,
    #[cfg(windows)]
    legacy_windows_stdio: c_int,
    check_hash_pycs_mode: *mut wchar_t,
    pathconfig_warnings: c_int,
    pythonpath_env: *mut wchar_t,
    home: *mut wchar_t,
    module_search_paths_set: c_int,
    module_search_paths: PyWideStringList,
    executable: *mut wchar_t,
    base_executable: *mut wchar_t,
    prefix: *mut wchar_t,
    base_prefix: *mut wchar_t,
    exec_prefix: *mut wchar_t,
    base_exec_prefix: *mut wchar_t,
    skip_source_first_line: c_int,
    run_command: *mut wchar_t,
    run_module: *mut wchar_t,
    run_filename: *mut wchar_t,
    _install_importlib: c_int,
    _init_main: c_int,
}

#[cfg_attr(windows, link(name = "pythonXY"))]
extern "C" {
    pub fn PyConfig_InitPythonConfig(config: *mut PyConfig) -> ();
    pub fn PyConfig_InitIsolatedConfig(config: *mut PyConfig) -> ();
    pub fn PyConfig_Clear(config: *mut PyConfig) -> ();
    pub fn PyConfig_SetString(
        config: *mut PyConfig,
        config_str: *mut *mut wchar_t,
        value: *const wchar_t,
    ) -> PyStatus;
    pub fn PyConfig_SetBytesString(
        config: *mut PyConfig,
        config_str: *mut *mut wchar_t,
        value: *const c_char,
    ) -> PyStatus;
    pub fn PyConfig_Read(config: *mut PyConfig) -> PyStatus;
    pub fn PyConfig_SetBytesArgv(
        config: *mut PyConfig,
        argc: Py_ssize_t,
        argv: *const *mut c_char,
    ) -> PyStatus;
    pub fn PyConfig_SetArgv(
        config: *mut PyConfig,
        argc: Py_ssize_t,
        argv: *const *mut wchar_t,
    ) -> PyStatus;
    pub fn PyConfig_SetWideStringList(
        config: *mut PyConfig,
        list: *mut PyWideStringList,
        length: Py_ssize_t,
        items: *mut *mut wchar_t,
    ) -> PyStatus;
}
<commit_msg>Make fields of initialization config public and implement Default<commit_after>// This entire module is Python 3.8+ and !Py_LIMITED_API only.

use crate::pyport::Py_ssize_t;
use libc::{c_char, c_int, c_ulong, wchar_t};

#[repr(C)]
#[derive(Copy, Clone)]
pub enum PyStatusType {
    _PyStatus_TYPE_OK = 0,
    _PyStatus_TYPE_ERROR = 1,
    _PyStatus_TYPE_EXIT = 2,
}

#[repr(C)]
#[derive(Copy, Clone)]
pub struct PyStatus {
    pub _type: PyStatusType,
    pub func: *const c_char,
    pub err_msg: *const c_char,
    pub exitcode: c_int,
}

impl Default for PyStatus {
    fn default() -> Self {
        // zeroed() is UB for enums. So we are explicit about
        // what value it is set to. This probably isn't necessary
        // as we are dealing with a C-compat struct and 0 is a valid
        // enum value. But explicit is better than UB.
        let mut status: Self = unsafe { core::mem::zeroed() };
        status._type = PyStatusType::_PyStatus_TYPE_OK;

        status
    }
}

#[cfg_attr(windows, link(name = "pythonXY"))]
extern "C" {
    pub fn PyStatus_Ok() -> PyStatus;
    pub fn PyStatus_Error(err_msg: *const c_char) -> PyStatus;
    pub fn PyStatus_NoMemory() -> PyStatus;
    pub fn PyStatus_Exit(exitcode: c_int) -> PyStatus;

    pub fn PyStatus_IsError(err: PyStatus) -> c_int;
    pub fn PyStatus_IsExit(err: PyStatus) -> c_int;
    pub fn PyStatus_Exception(err: PyStatus) -> c_int;
}

#[repr(C)]
#[derive(Copy, Clone)]
pub struct PyWideStringList {
    pub length: Py_ssize_t,
    pub items: *mut *mut wchar_t,
}

#[cfg_attr(windows, link(name = "pythonXY"))]
extern "C" {
    pub fn PyWideStringList_Append(list: *mut PyWideStringList, item: *const wchar_t) -> PyStatus;
    pub fn PyWideStringList_Insert(
        list: *mut PyWideStringList,
        index: Py_ssize_t,
        item: *const wchar_t,
    ) -> PyStatus;
}

#[repr(C)]
#[derive(Clone)]
pub struct PyPreConfig {
    pub _config_init: c_int,
    pub parse_argv: c_int,
    pub isolated: c_int,
    pub use_environment: c_int,
    pub configure_locale: c_int,
    pub coerce_c_locale: c_int,
    pub coerce_c_locale_warn: c_int,
    #[cfg(windows)]
    pub legacy_windows_fs_encoding: c_int,
    pub utf8_mode: c_int,
    pub dev_mode: c_int,
    pub allocator: c_int,
}

impl Default for PyPreConfig {
    fn default() -> Self {
        unsafe { core::mem::zeroed() }
    }
}

#[cfg_attr(windows, link(name = "pythonXY"))]
extern "C" {
    pub fn PyPreConfig_InitPythonConfig(config: *mut PyPreConfig) -> ();
    pub fn PyPreConfig_InitIsolatedConfig(config: *mut PyPreConfig) -> ();
}

#[repr(C)]
#[derive(Clone)]
pub struct PyConfig {
    pub _config_init: c_int,
    pub isolated: c_int,
    pub use_environment: c_int,
    pub dev_mode: c_int,
    pub install_signal_handlers: c_int,
    pub use_hash_seed: c_int,
    pub hash_seed: c_ulong,
    pub faulthandler: c_int,
    pub tracemalloc: c_int,
    pub import_time: c_int,
    pub show_ref_count: c_int,
    pub show_alloc_count: c_int,
    pub dump_refs: c_int,
    pub malloc_stats: c_int,
    pub filesystem_encoding: *mut wchar_t,
    pub filesystem_errors: *mut wchar_t,
    pub pycache_prefix: *mut wchar_t,
    pub parse_argv: c_int,
    pub argv: PyWideStringList,
    pub program_name: *mut wchar_t,
    pub xoptions: PyWideStringList,
    pub warnoptions: PyWideStringList,
    pub site_import: c_int,
    pub bytes_warning: c_int,
    pub inspect: c_int,
    pub interactive: c_int,
    pub optimization_level: c_int,
    pub parser_debug: c_int,
    pub write_bytecode: c_int,
    pub verbose: c_int,
    pub quiet: c_int,
    pub user_site_directory: c_int,
    pub configure_c_stdio: c_int,
    pub buffered_stdio: c_int,
    pub stdio_encoding: *mut wchar_t,
    pub stdio_errors: *mut wchar_t,
    #[cfg(windows)]
    pub legacy_windows_stdio: c_int,
    pub check_hash_pycs_mode: *mut wchar_t,
    pub pathconfig_warnings: c_int,
    pub pythonpath_env: *mut wchar_t,
    pub home: *mut wchar_t,
    pub module_search_paths_set: c_int,
    pub module_search_paths: PyWideStringList,
    pub executable: *mut wchar_t,
    pub base_executable: *mut wchar_t,
    pub prefix: *mut wchar_t,
    pub base_prefix: *mut wchar_t,
    pub exec_prefix: *mut wchar_t,
    pub base_exec_prefix: *mut wchar_t,
    pub skip_source_first_line: c_int,
    pub run_command: *mut wchar_t,
    pub run_module: *mut wchar_t,
    pub run_filename: *mut wchar_t,
    pub _install_importlib: c_int,
    pub _init_main: c_int,
}

impl Default for PyConfig {
    fn default() -> Self {
        unsafe { core::mem::zeroed() }
    }
}

#[cfg_attr(windows, link(name = "pythonXY"))]
extern "C" {
    pub fn PyConfig_InitPythonConfig(config: *mut PyConfig) -> ();
    pub fn PyConfig_InitIsolatedConfig(config: *mut PyConfig) -> ();
    pub fn PyConfig_Clear(config: *mut PyConfig) -> ();
    pub fn PyConfig_SetString(
        config: *mut PyConfig,
        config_str: *mut *mut wchar_t,
        value: *const wchar_t,
    ) -> PyStatus;
    pub fn PyConfig_SetBytesString(
        config: *mut PyConfig,
        config_str: *mut *mut wchar_t,
        value: *const c_char,
    ) -> PyStatus;
    pub fn PyConfig_Read(config: *mut PyConfig) -> PyStatus;
    pub fn PyConfig_SetBytesArgv(
        config: *mut PyConfig,
        argc: Py_ssize_t,
        argv: *const *mut c_char,
    ) -> PyStatus;
    pub fn PyConfig_SetArgv(
        config: *mut PyConfig,
        argc: Py_ssize_t,
        argv: *const *mut wchar_t,
    ) -> PyStatus;
    pub fn PyConfig_SetWideStringList(
        config: *mut PyConfig,
        list: *mut PyWideStringList,
        length: Py_ssize_t,
        items: *mut *mut wchar_t,
    ) -> PyStatus;
}
<|endoftext|>


<commit_before>//! Render to a window created by Glutin, using Glium's OpenGL functions

use ppu::{SCREEN_WIDTH, SCREEN_HEIGHT};

use glium::{DisplayBuild, Surface, Rect};
use glium::backend::glutin_backend::GlutinFacade;
use glium::index::{NoIndices, PrimitiveType};
use glium::glutin::WindowBuilder;
use glium::program::Program;
use glium::texture::{ClientFormat, RawImage2d, Texture2d};
use glium::vertex::VertexBuffer;

use std::process;
use std::borrow::Cow;

#[derive(Copy, Clone)]
struct Vertex {
    position: [f32; 2],
}

impl Vertex {
    fn new(x: f32, y: f32) -> Self { Vertex { position: [x, y] } }
}

implement_vertex!(Vertex, position);

const VERTEX_SHADER_SRC: &'static str = r#"
    #version 140

    in vec2 position;
    out vec2 tex_coords;

    void main() {
        gl_Position = vec4(position, 0.0, 1.0);
        tex_coords = (position + vec2(1,1)) * vec2(0.5, -0.5);
    }
"#;

const FRAGMENT_SHADER_SRC: &'static str = r#"
    #version 140

    in vec2 tex_coords;
    out vec4 color;

    uniform sampler2D tex;

    void main() {
        color = texture(tex, tex_coords);
    }
"#;

pub struct GliumRenderer {
    display: GlutinFacade,
    vbuf: VertexBuffer<Vertex>,
    program: Program,
    texture: Texture2d,
}

impl Default for GliumRenderer {
    fn default() -> Self {
        let display = WindowBuilder::new()
            .with_dimensions(SCREEN_WIDTH as u32 * 3, SCREEN_HEIGHT as u32 * 3)
            .with_title("sneeze".to_owned())
            .build_glium().unwrap();
        let shape = [
            Vertex::new(-1.0, 1.0),
            Vertex::new(1.0, 1.0),
            Vertex::new(-1.0, -1.0),
            Vertex::new(1.0, -1.0),
        ];

        GliumRenderer {
            vbuf: VertexBuffer::new(&display, &shape).unwrap(),
            program: Program::from_source(&display, VERTEX_SHADER_SRC, FRAGMENT_SHADER_SRC, None)
                .unwrap(),
            texture: Texture2d::empty(&display, SCREEN_WIDTH as u32, SCREEN_HEIGHT as u32)
                .unwrap(),
            display: display,
        }
    }
}

impl GliumRenderer {
    fn handle_events(&mut self) {
        use glium::glutin::Event::*;

        for ev in self.display.poll_events() {
            match ev {
                Closed => {
                    info!("quit event -> exiting");
                    process::exit(0);
                }
                _ => ()
            }
        }
    }
}

impl super::Renderer for GliumRenderer {
    fn render(&mut self, frame_data: &[u8]) {
        // upload new texture data
        self.texture.write(Rect {
            left: 0,
            bottom: 0,
            width: SCREEN_WIDTH as u32,
            height: SCREEN_HEIGHT as u32,
        }, RawImage2d {
            data: Cow::Borrowed(frame_data),
            width: SCREEN_WIDTH as u32,
            height: SCREEN_HEIGHT as u32,
            format: ClientFormat::U8U8U8,
        });

        let mut target = self.display.draw();
        target.draw(
            &self.vbuf,
            &NoIndices(PrimitiveType::TriangleStrip),
            &self.program,
            &uniform! {
                tex: &self.texture,
            },
            &Default::default()).unwrap();
        target.finish().unwrap();

        self.handle_events();
    }
}
<commit_msg>glium: Don't use linear filtering<commit_after>//! Render to a window created by Glutin, using Glium's OpenGL functions

use ppu::{SCREEN_WIDTH, SCREEN_HEIGHT};

use glium::{DisplayBuild, Surface, Rect};
use glium::backend::glutin_backend::GlutinFacade;
use glium::index::{NoIndices, PrimitiveType};
use glium::glutin::WindowBuilder;
use glium::program::Program;
use glium::texture::{ClientFormat, RawImage2d, Texture2d};
use glium::uniforms::MagnifySamplerFilter;
use glium::vertex::VertexBuffer;

use std::process;
use std::borrow::Cow;

#[derive(Copy, Clone)]
struct Vertex {
    position: [f32; 2],
}

impl Vertex {
    fn new(x: f32, y: f32) -> Self { Vertex { position: [x, y] } }
}

implement_vertex!(Vertex, position);

const VERTEX_SHADER_SRC: &'static str = r#"
    #version 140

    in vec2 position;
    out vec2 tex_coords;

    void main() {
        tex_coords = vec2((position.x + 1) * 0.5, 1 - (position.y + 1) * 0.5);
        gl_Position = vec4(position, 0.0, 1.0);
    }
"#;

const FRAGMENT_SHADER_SRC: &'static str = r#"
    #version 140

    in vec2 tex_coords;
    out vec4 color;

    uniform sampler2D tex;

    void main() {
        color = texture(tex, tex_coords);
    }
"#;

pub struct GliumRenderer {
    display: GlutinFacade,
    vbuf: VertexBuffer<Vertex>,
    program: Program,
    texture: Texture2d,
}

impl Default for GliumRenderer {
    fn default() -> Self {
        let display = WindowBuilder::new()
            .with_dimensions(SCREEN_WIDTH as u32 * 3, SCREEN_HEIGHT as u32 * 3)
            .with_title("sneeze".to_owned())
            .build_glium().unwrap();
        let shape = [
            Vertex::new(-1.0, 1.0),
            Vertex::new(1.0, 1.0),
            Vertex::new(-1.0, -1.0),
            Vertex::new(1.0, -1.0),
        ];

        GliumRenderer {
            vbuf: VertexBuffer::new(&display, &shape).unwrap(),
            program: Program::from_source(&display, VERTEX_SHADER_SRC, FRAGMENT_SHADER_SRC, None)
                .unwrap(),
            texture: Texture2d::empty(&display, SCREEN_WIDTH as u32, SCREEN_HEIGHT as u32)
                .unwrap(),
            display: display,
        }
    }
}

impl GliumRenderer {
    fn handle_events(&mut self) {
        use glium::glutin::Event::*;

        for ev in self.display.poll_events() {
            match ev {
                Closed => {
                    info!("quit event -> exiting");
                    process::exit(0);
                }
                _ => ()
            }
        }
    }
}

impl super::Renderer for GliumRenderer {
    fn render(&mut self, frame_data: &[u8]) {
        // upload new texture data
        self.texture.write(Rect {
            left: 0,
            bottom: 0,
            width: SCREEN_WIDTH as u32,
            height: SCREEN_HEIGHT as u32,
        }, RawImage2d {
            data: Cow::Borrowed(frame_data),
            width: SCREEN_WIDTH as u32,
            height: SCREEN_HEIGHT as u32,
            format: ClientFormat::U8U8U8,
        });

        let mut target = self.display.draw();
        target.draw(
            &self.vbuf,
            &NoIndices(PrimitiveType::TriangleStrip),
            &self.program,
            &uniform! {
                tex: self.texture.sampled()
                    .magnify_filter(MagnifySamplerFilter::Nearest),
            },
            &Default::default()).unwrap();
        target.finish().unwrap();

        self.handle_events();
    }
}
<|endoftext|>


<commit_before>// Copyright 2014 The Gfx-rs Developers.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#![crate_name = "gfx_macros"]
#![comment = "Helper macros for gfx-rs"]
#![license = "ASL2"]
#![crate_type = "dylib"]

#![feature(macro_rules, plugin_registrar, quote)]

//! Macro extensions crate.
//! Implements `shaders!` macro as well as `#[shader_param]` and
//! `#[vertex_format]` attributes.

extern crate rustc;
extern crate syntax;

use syntax::{ast, attr, ext, codemap};
use syntax::ext::build::AstBuilder;
use syntax::parse::token;
use syntax::fold::Folder;
use syntax::ptr::P;

pub mod shader_param;
pub mod vertex_format;

/// Entry point for the plugin phase
#[plugin_registrar]
pub fn registrar(reg: &mut rustc::plugin::Registry) {
    use syntax::parse::token::intern;
    use syntax::ext::base;
    // Register the `#[shader_param]` attribute.
    reg.register_syntax_extension(intern("shader_param"),
        base::ItemDecorator(box shader_param::expand));
    // Register the `#[vertex_format]` attribute.
    reg.register_syntax_extension(intern("vertex_format"),
        base::ItemDecorator(box vertex_format::expand));
}

/// Scan through the field's attributes and extract the field vertex name. If
/// multiple names are found, use the first name and emit a warning.
fn find_name(cx: &mut ext::base::ExtCtxt, span: codemap::Span,
             attributes: &[ast::Attribute]) -> Option<token::InternedString> {
    attributes.iter().fold(None, |name, attribute| {
        match attribute.node.value.node {
            ast::MetaNameValue(ref attr_name, ref attr_value) => {
                match (attr_name.get(), &attr_value.node) {
                    ("name", &ast::LitStr(ref new_name, _)) => {
                        attr::mark_used(attribute);
                        name.map_or(Some(new_name.clone()), |name| {
                            cx.span_warn(span, format!(
                                "Extra field name detected: {} - \
                                ignoring in favour of: {}", new_name, name
                            ).as_slice());
                            None
                        })
                    }
                    _ => None,
                }
            }
            _ => name,
        }
    })
}

/// Marker string to base the unique identifier generated by `extern_crate_hack()` on
static EXTERN_CRATE_HACK: &'static str = "__gfx_extern_crate_hack";

/// Inserts a module with a unique identifier that reexports
/// The `gfx` crate, and returns that identifier
fn extern_crate_hack(context: &mut ext::base::ExtCtxt,
                     span: codemap::Span,
                     push: |P<ast::Item>|) -> ast::Ident {
    let extern_crate_hack = token::gensym_ident(EXTERN_CRATE_HACK);
    // mod $EXTERN_CRATE_HACK {
    //     extern crate gfx_ = "gfx";
    //     pub use gfx_ as gfx;
    // }
    let item = context.item_mod(
        span,
        span,
        extern_crate_hack,
        vec![],
        vec![
            ast::ViewItem {
                span: span,
                vis: ast::Inherited,
                attrs: vec![],
                node: ast::ViewItemExternCrate(
                    context.ident_of("gfx_"),
                    Some((
                        token::InternedString::new("gfx"),
                        ast::CookedStr
                    )),
                    ast::DUMMY_NODE_ID
                )
            },
            context.view_use_simple_(
                span,
                ast::Public,
                context.ident_of("gfx"),
                context.path(span, vec![
                    context.ident_of("self"),
                    context.ident_of("gfx_")
                ])
            )
        ],
        vec![]
    );
    push(item);
    extern_crate_hack
}

/// This Folder gets used to fixup all paths generated by the
/// deriving trait impl to point to the unique module
/// containing the `gfx` reexport.
struct ExternCrateHackFolder {
    path_root: ast::Ident
}

impl Folder for ExternCrateHackFolder {
    fn fold_path(&mut self, p: ast::Path) -> ast::Path {
        let p = syntax::fold::noop_fold_path(p, self);
        let needs_fix = p.segments.as_slice().get(0)
                         .map(|s| s.identifier.as_str() == EXTERN_CRATE_HACK)
                         .unwrap_or(false);
        let needs_fix_self = p.segments.as_slice().get(0)
                              .map(|s| s.identifier.as_str() == "self")
                              .unwrap_or(false) &&
                             p.segments.as_slice().get(1)
                              .map(|s| s.identifier.as_str() == EXTERN_CRATE_HACK)
                              .unwrap_or(false);

        if needs_fix {
            let mut p = p.clone();
            p.segments.get_mut(0).identifier = self.path_root;
            p.global = false;
            p
        } else if needs_fix_self {
            let mut p = p.clone();
            p.segments.get_mut(1).identifier = self.path_root;
            p.global = false;
            p
        } else {
            p
        }

    }
}

/// Simply applies the `ExternCrateHackFolder`
fn fixup_extern_crate_paths(item: P<ast::Item>, path_root: ast::Ident) -> P<ast::Item> {
    ExternCrateHackFolder {
        path_root: path_root
    }.fold_item(item).into_iter().next().unwrap()
}

// The `gfx` reexport module here does not need a unique name,
// as it gets inserted in a new block and thus doesn't conflict with
// any names outside its lexical scope.
#[macro_export]
macro_rules! shaders {
    (GLSL_120: $v:expr $($t:tt)*) => {
        {
            mod __gfx_extern_crate_hack {
                extern crate "gfx" as gfx_;
                pub use self::gfx_ as gfx;
            }
            __gfx_extern_crate_hack::gfx::ShaderSource {
                glsl_120: Some(__gfx_extern_crate_hack::gfx::StaticBytes($v)),
                ..shaders!($($t)*)
            }
        }
    };
    (GLSL_150: $v:expr $($t:tt)*) => {
        {
            mod __gfx_extern_crate_hack {
                extern crate "gfx" as gfx_;
                pub use self::gfx_ as gfx;
            }
            __gfx_extern_crate_hack::gfx::ShaderSource {
                glsl_150: Some(__gfx_extern_crate_hack::gfx::StaticBytes($v)),
                ..shaders!($($t)*)
            }
        }
    };
    () => {
        {
            mod __gfx_extern_crate_hack {
                extern crate "gfx" as gfx_;
                pub use self::gfx_ as gfx;
            }
            __gfx_extern_crate_hack::gfx::ShaderSource {
                glsl_120: None,
                glsl_150: None,
            }
        }
    }
}
<commit_msg>Updated base::ItemDeclorator to base::Decorator<commit_after>// Copyright 2014 The Gfx-rs Developers.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#![crate_name = "gfx_macros"]
#![comment = "Helper macros for gfx-rs"]
#![license = "ASL2"]
#![crate_type = "dylib"]

#![feature(macro_rules, plugin_registrar, quote)]

//! Macro extensions crate.
//! Implements `shaders!` macro as well as `#[shader_param]` and
//! `#[vertex_format]` attributes.

extern crate rustc;
extern crate syntax;

use syntax::{ast, attr, ext, codemap};
use syntax::ext::build::AstBuilder;
use syntax::parse::token;
use syntax::fold::Folder;
use syntax::ptr::P;

pub mod shader_param;
pub mod vertex_format;

/// Entry point for the plugin phase
#[plugin_registrar]
pub fn registrar(reg: &mut rustc::plugin::Registry) {
    use syntax::parse::token::intern;
    use syntax::ext::base;
    // Register the `#[shader_param]` attribute.
    reg.register_syntax_extension(intern("shader_param"),
        base::Decorator(box shader_param::expand));
    // Register the `#[vertex_format]` attribute.
    reg.register_syntax_extension(intern("vertex_format"),
        base::Decorator(box vertex_format::expand));
}

/// Scan through the field's attributes and extract the field vertex name. If
/// multiple names are found, use the first name and emit a warning.
fn find_name(cx: &mut ext::base::ExtCtxt, span: codemap::Span,
             attributes: &[ast::Attribute]) -> Option<token::InternedString> {
    attributes.iter().fold(None, |name, attribute| {
        match attribute.node.value.node {
            ast::MetaNameValue(ref attr_name, ref attr_value) => {
                match (attr_name.get(), &attr_value.node) {
                    ("name", &ast::LitStr(ref new_name, _)) => {
                        attr::mark_used(attribute);
                        name.map_or(Some(new_name.clone()), |name| {
                            cx.span_warn(span, format!(
                                "Extra field name detected: {} - \
                                ignoring in favour of: {}", new_name, name
                            ).as_slice());
                            None
                        })
                    }
                    _ => None,
                }
            }
            _ => name,
        }
    })
}

/// Marker string to base the unique identifier generated by `extern_crate_hack()` on
static EXTERN_CRATE_HACK: &'static str = "__gfx_extern_crate_hack";

/// Inserts a module with a unique identifier that reexports
/// The `gfx` crate, and returns that identifier
fn extern_crate_hack(context: &mut ext::base::ExtCtxt,
                     span: codemap::Span,
                     push: |P<ast::Item>|) -> ast::Ident {
    let extern_crate_hack = token::gensym_ident(EXTERN_CRATE_HACK);
    // mod $EXTERN_CRATE_HACK {
    //     extern crate gfx_ = "gfx";
    //     pub use gfx_ as gfx;
    // }
    let item = context.item_mod(
        span,
        span,
        extern_crate_hack,
        vec![],
        vec![
            ast::ViewItem {
                span: span,
                vis: ast::Inherited,
                attrs: vec![],
                node: ast::ViewItemExternCrate(
                    context.ident_of("gfx_"),
                    Some((
                        token::InternedString::new("gfx"),
                        ast::CookedStr
                    )),
                    ast::DUMMY_NODE_ID
                )
            },
            context.view_use_simple_(
                span,
                ast::Public,
                context.ident_of("gfx"),
                context.path(span, vec![
                    context.ident_of("self"),
                    context.ident_of("gfx_")
                ])
            )
        ],
        vec![]
    );
    push(item);
    extern_crate_hack
}

/// This Folder gets used to fixup all paths generated by the
/// deriving trait impl to point to the unique module
/// containing the `gfx` reexport.
struct ExternCrateHackFolder {
    path_root: ast::Ident
}

impl Folder for ExternCrateHackFolder {
    fn fold_path(&mut self, p: ast::Path) -> ast::Path {
        let p = syntax::fold::noop_fold_path(p, self);
        let needs_fix = p.segments.as_slice().get(0)
                         .map(|s| s.identifier.as_str() == EXTERN_CRATE_HACK)
                         .unwrap_or(false);
        let needs_fix_self = p.segments.as_slice().get(0)
                              .map(|s| s.identifier.as_str() == "self")
                              .unwrap_or(false) &&
                             p.segments.as_slice().get(1)
                              .map(|s| s.identifier.as_str() == EXTERN_CRATE_HACK)
                              .unwrap_or(false);

        if needs_fix {
            let mut p = p.clone();
            p.segments.get_mut(0).identifier = self.path_root;
            p.global = false;
            p
        } else if needs_fix_self {
            let mut p = p.clone();
            p.segments.get_mut(1).identifier = self.path_root;
            p.global = false;
            p
        } else {
            p
        }

    }
}

/// Simply applies the `ExternCrateHackFolder`
fn fixup_extern_crate_paths(item: P<ast::Item>, path_root: ast::Ident) -> P<ast::Item> {
    ExternCrateHackFolder {
        path_root: path_root
    }.fold_item(item).into_iter().next().unwrap()
}

// The `gfx` reexport module here does not need a unique name,
// as it gets inserted in a new block and thus doesn't conflict with
// any names outside its lexical scope.
#[macro_export]
macro_rules! shaders {
    (GLSL_120: $v:expr $($t:tt)*) => {
        {
            mod __gfx_extern_crate_hack {
                extern crate "gfx" as gfx_;
                pub use self::gfx_ as gfx;
            }
            __gfx_extern_crate_hack::gfx::ShaderSource {
                glsl_120: Some(__gfx_extern_crate_hack::gfx::StaticBytes($v)),
                ..shaders!($($t)*)
            }
        }
    };
    (GLSL_150: $v:expr $($t:tt)*) => {
        {
            mod __gfx_extern_crate_hack {
                extern crate "gfx" as gfx_;
                pub use self::gfx_ as gfx;
            }
            __gfx_extern_crate_hack::gfx::ShaderSource {
                glsl_150: Some(__gfx_extern_crate_hack::gfx::StaticBytes($v)),
                ..shaders!($($t)*)
            }
        }
    };
    () => {
        {
            mod __gfx_extern_crate_hack {
                extern crate "gfx" as gfx_;
                pub use self::gfx_ as gfx;
            }
            __gfx_extern_crate_hack::gfx::ShaderSource {
                glsl_120: None,
                glsl_150: None,
            }
        }
    }
}
<|endoftext|>


<commit_before>//! Types to describe the properties of memory allocated for gfx resources.

use crate::Backend;
use crate::{buffer, image, queue};
use std::mem;
use std::ops::Range;

/// A trait for plain-old-data types.
///
/// A POD type does not have invalid bit patterns and can be safely
/// created from arbitrary bit pattern.
/// The `Pod` trait is implemented for standard integer and floating point numbers as well as
/// common arrays of them (for example `[f32; 2]`).
pub unsafe trait Pod: Copy {}

macro_rules! impl_pod {
    ( ty = $($ty:ty)* ) => { $( unsafe impl Pod for $ty {} )* };
    ( ar = $($tt:expr)* ) => { $( unsafe impl<T: Pod> Pod for [T; $tt] {} )* };
}

impl_pod! { ty = isize usize i8 u8 i16 u16 i32 u32 i64 u64 f32 f64 }
impl_pod! { ar =
    0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
}

unsafe impl<T: Pod, U: Pod> Pod for (T, U) {}

/// Cast a slice from one POD type to another.
pub fn cast_slice<A: Pod, B: Pod>(slice: &[A]) -> &[B] {
    use std::slice;

    let raw_len = mem::size_of::<A>().wrapping_mul(slice.len());
    let len = raw_len / mem::size_of::<B>();
    assert_eq!(raw_len, mem::size_of::<B>().wrapping_mul(len));
    unsafe { slice::from_raw_parts(slice.as_ptr() as *const B, len) }
}

bitflags!(
    /// Memory property flags.
    #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
    pub struct Properties: u16 {
        /// Device local memory on the GPU.
        const DEVICE_LOCAL   = 0x1;

        /// Host visible memory can be accessed by the CPU.
        ///
        /// Backends must provide at least one cpu visible memory.
        const CPU_VISIBLE   = 0x2;

        /// CPU-GPU coherent.
        ///
        /// Non-coherent memory requires explicit flushing.
        const COHERENT     = 0x4;

        /// Cached memory by the CPU
        const CPU_CACHED = 0x8;

        /// Memory that may be lazily allocated as needed on the GPU
        /// and *must not* be visible to the CPU.
        const LAZILY_ALLOCATED = 0x10;
    }
);

bitflags!(
    /// Barrier dependency flags.
    #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
    pub struct Dependencies: u32 {
        /// Specifies the memory dependency to be framebuffer-local.
        const BY_REGION    = 0x1;
        //const VIEW_LOCAL   = 0x2;
        //const DEVICE_GROUP = 0x4;
    }
);

// DOC TODO: Could be better, but I don't know how to do this without
// trying to explain the whole synchronization model.
/// A [memory barrier](https://www.khronos.org/registry/vulkan/specs/1.0/html/vkspec.html#synchronization-memory-barriers)
/// type for either buffers or images.
#[allow(missing_docs)]
#[derive(Clone, Debug)]
pub enum Barrier<'a, B: Backend> {
    /// Applies the given access flags to all buffers in the range.
    AllBuffers(Range<buffer::Access>),
    /// Applies the given access flags to all images in the range.
    AllImages(Range<image::Access>),
    /// A memory barrier that defines access to a buffer.
    Buffer {
        /// The access flags controlling the buffer.
        states: Range<buffer::State>,
        /// The buffer the barrier controls.
        target: &'a B::Buffer,
        /// The source and destination Queue family IDs, for a [queue family ownership transfer](https://www.khronos.org/registry/vulkan/specs/1.0/html/vkspec.html#synchronization-queue-transfers)
        /// Can be `None` to indicate no ownership transfer.
        families: Option<Range<queue::QueueFamilyId>>,
        /// Range of the buffer the barrier applies to.
        range: Range<Option<u64>>,
    },
    /// A memory barrier that defines access to (a subset of) an image.
    Image {
        /// The access flags controlling the image.
        states: Range<image::State>,
        /// The image the barrier controls.
        target: &'a B::Image,
        /// The source and destination Queue family IDs, for a [queue family ownership transfer](https://www.khronos.org/registry/vulkan/specs/1.0/html/vkspec.html#synchronization-queue-transfers)
        /// Can be `None` to indicate no ownership transfer.
        families: Option<Range<queue::QueueFamilyId>>,
        /// A `SubresourceRange` that defines which section of an image the barrier applies to.
        range: image::SubresourceRange,
    },
}

impl<'a, B: Backend> Barrier<'a, B> {
    /// Create a barrier for the whole buffer between the given states.
    pub fn whole_buffer(target: &'a B::Buffer, states: Range<buffer::State>) -> Self {
        Barrier::Buffer {
            states,
            target,
            families: None,
            range: None..None,
        }
    }
}

/// Memory requirements for a certain resource (buffer/image).
#[derive(Clone, Copy, Debug)]
pub struct Requirements {
    /// Size in the memory.
    pub size: u64,
    /// Memory alignment.
    pub alignment: u64,
    /// Supported memory types.
    pub type_mask: u64,
}
<commit_msg>[hal] merge use<commit_after>//! Types to describe the properties of memory allocated for gfx resources.

use crate::{Backend, buffer, image, queue};
use std::{mem, ops::Range};

/// A trait for plain-old-data types.
///
/// A POD type does not have invalid bit patterns and can be safely
/// created from arbitrary bit pattern.
/// The `Pod` trait is implemented for standard integer and floating point numbers as well as
/// common arrays of them (for example `[f32; 2]`).
pub unsafe trait Pod: Copy {}

macro_rules! impl_pod {
    ( ty = $($ty:ty)* ) => { $( unsafe impl Pod for $ty {} )* };
    ( ar = $($tt:expr)* ) => { $( unsafe impl<T: Pod> Pod for [T; $tt] {} )* };
}

impl_pod! { ty = isize usize i8 u8 i16 u16 i32 u32 i64 u64 f32 f64 }
impl_pod! { ar =
    0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
}

unsafe impl<T: Pod, U: Pod> Pod for (T, U) {}

/// Cast a slice from one POD type to another.
pub fn cast_slice<A: Pod, B: Pod>(slice: &[A]) -> &[B] {
    use std::slice;

    let raw_len = mem::size_of::<A>().wrapping_mul(slice.len());
    let len = raw_len / mem::size_of::<B>();
    assert_eq!(raw_len, mem::size_of::<B>().wrapping_mul(len));
    unsafe { slice::from_raw_parts(slice.as_ptr() as *const B, len) }
}

bitflags!(
    /// Memory property flags.
    #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
    pub struct Properties: u16 {
        /// Device local memory on the GPU.
        const DEVICE_LOCAL   = 0x1;

        /// Host visible memory can be accessed by the CPU.
        ///
        /// Backends must provide at least one cpu visible memory.
        const CPU_VISIBLE   = 0x2;

        /// CPU-GPU coherent.
        ///
        /// Non-coherent memory requires explicit flushing.
        const COHERENT     = 0x4;

        /// Cached memory by the CPU
        const CPU_CACHED = 0x8;

        /// Memory that may be lazily allocated as needed on the GPU
        /// and *must not* be visible to the CPU.
        const LAZILY_ALLOCATED = 0x10;
    }
);

bitflags!(
    /// Barrier dependency flags.
    #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
    pub struct Dependencies: u32 {
        /// Specifies the memory dependency to be framebuffer-local.
        const BY_REGION    = 0x1;
        //const VIEW_LOCAL   = 0x2;
        //const DEVICE_GROUP = 0x4;
    }
);

// DOC TODO: Could be better, but I don't know how to do this without
// trying to explain the whole synchronization model.
/// A [memory barrier](https://www.khronos.org/registry/vulkan/specs/1.0/html/vkspec.html#synchronization-memory-barriers)
/// type for either buffers or images.
#[allow(missing_docs)]
#[derive(Clone, Debug)]
pub enum Barrier<'a, B: Backend> {
    /// Applies the given access flags to all buffers in the range.
    AllBuffers(Range<buffer::Access>),
    /// Applies the given access flags to all images in the range.
    AllImages(Range<image::Access>),
    /// A memory barrier that defines access to a buffer.
    Buffer {
        /// The access flags controlling the buffer.
        states: Range<buffer::State>,
        /// The buffer the barrier controls.
        target: &'a B::Buffer,
        /// The source and destination Queue family IDs, for a [queue family ownership transfer](https://www.khronos.org/registry/vulkan/specs/1.0/html/vkspec.html#synchronization-queue-transfers)
        /// Can be `None` to indicate no ownership transfer.
        families: Option<Range<queue::QueueFamilyId>>,
        /// Range of the buffer the barrier applies to.
        range: Range<Option<u64>>,
    },
    /// A memory barrier that defines access to (a subset of) an image.
    Image {
        /// The access flags controlling the image.
        states: Range<image::State>,
        /// The image the barrier controls.
        target: &'a B::Image,
        /// The source and destination Queue family IDs, for a [queue family ownership transfer](https://www.khronos.org/registry/vulkan/specs/1.0/html/vkspec.html#synchronization-queue-transfers)
        /// Can be `None` to indicate no ownership transfer.
        families: Option<Range<queue::QueueFamilyId>>,
        /// A `SubresourceRange` that defines which section of an image the barrier applies to.
        range: image::SubresourceRange,
    },
}

impl<'a, B: Backend> Barrier<'a, B> {
    /// Create a barrier for the whole buffer between the given states.
    pub fn whole_buffer(target: &'a B::Buffer, states: Range<buffer::State>) -> Self {
        Barrier::Buffer {
            states,
            target,
            families: None,
            range: None..None,
        }
    }
}

/// Memory requirements for a certain resource (buffer/image).
#[derive(Clone, Copy, Debug)]
pub struct Requirements {
    /// Size in the memory.
    pub size: u64,
    /// Memory alignment.
    pub alignment: u64,
    /// Supported memory types.
    pub type_mask: u64,
}
<|endoftext|>


<commit_before>
use errors::*;
use std::path::{Path, PathBuf};
use std::fs;
use std::process::Command;
use hyper;

pub mod raw;

pub use self::raw::{
	is_directory,
	is_file,
	path_exists,
	to_absolute,
	if_not_empty,
	random_string,
	prefix_arg,
};

pub fn ensure_dir_exists(name: &'static str, path: &Path, notify_handler: &NotifyHandler) -> Result<bool> {
	raw::ensure_dir_exists(path, |p| {
		notify_handler.call(CreatingDirectory(name, p))
	}).map_err(|e| Error::CreatingDirectory { name: name, path: PathBuf::from(path), error: e })
}

pub fn read_file(name: &'static str, path: &Path) -> Result<String> {
	raw::read_file(path)
		.map_err(|e| Error::ReadingFile { name: name, path: PathBuf::from(path), error: e })
}

pub fn write_file(name: &'static str, path: &Path, contents: &str) -> Result<()> {
	raw::write_file(path, contents)
		.map_err(|e| Error::WritingFile { name: name, path: PathBuf::from(path), error: e })
}

pub fn append_file(name: &'static str, path: &Path, line: &str) -> Result<()> {
	raw::append_file(path, line)
		.map_err(|e| Error::WritingFile { name: name, path: PathBuf::from(path), error: e })
}

pub fn rename_file(name: &'static str, src: &Path, dest: &Path) -> Result<()> {
	fs::rename(src, dest)
		.map_err(|e| Error::RenamingFile {
			name: name,
			src: PathBuf::from(src),
			dest: PathBuf::from(dest),
			error: e
		})
}

pub fn rename_dir(name: &'static str, src: &Path, dest: &Path) -> Result<()> {
	fs::rename(src, dest)
		.map_err(|e| Error::RenamingDirectory {
			name: name,
			src: PathBuf::from(src),
			dest: PathBuf::from(dest),
			error: e
		})
}

pub fn filter_file<F: FnMut(&str) -> bool>(name: &'static str, src: &Path, dest: &Path, filter: F) -> Result<usize> {
	raw::filter_file(src, dest, filter)
		.map_err(|e| Error::FilteringFile {
			name: name,
			src: PathBuf::from(src),
			dest: PathBuf::from(dest),
			error: e
		})
}

pub fn match_file<T, F: FnMut(&str) -> Option<T>>(name: &'static str, src: &Path, f: F) -> Result<Option<T>> {
	raw::match_file(src, f)
		.map_err(|e| Error::ReadingFile {
			name: name,
			path: PathBuf::from(src),
			error: e
		})
}

pub fn canonicalize_path(path: &Path, notify_handler: &NotifyHandler) -> PathBuf {
	fs::canonicalize(path)
		.unwrap_or_else(|_| {
			notify_handler.call(Notification::NoCanonicalPath(path));
			PathBuf::from(path)
		})
}

pub fn download_file(url: hyper::Url, path: &Path, notify_handler: &NotifyHandler) -> Result<()> {
	notify_handler.call(DownloadingFile(&url, path));
	raw::download_file(url.clone(), path)
		.map_err(|_| Error::DownloadingFile { url: url, path: PathBuf::from(path) })
}

pub fn cmd_status(name: &'static str, mut cmd: Command) -> Result<()> {
	cmd.status()
		.map_err(|e| Error::RunningCommand { name: name, error: e })
		.and_then(|s| {
			if s.success() {
				Ok(())
			} else {
				Err(Error::CommandStatus {
					name: name,
					status: s,
				})
			}
		})
}

pub fn assert_is_file(path: &Path) -> Result<()> {
	if !is_file(path) {
		Err(Error::NotAFile { path: PathBuf::from(path) })
	} else {
		Ok(())
	}
}

pub fn assert_is_directory(path: &Path) -> Result<()> {
	if !is_directory(path) {
		Err(Error::NotADirectory { path: PathBuf::from(path) })
	} else {
		Ok(())
	}
}

pub fn symlink_dir(src: &Path, dest: &Path, notify_handler: &NotifyHandler) -> Result<()> {
	notify_handler.call(LinkingDirectory(src, dest));
	raw::symlink_dir(src, dest)
		.ok_or_else(|| Error::LinkingDirectory(PathBuf::from(src), PathBuf::from(dest)))
}

pub fn copy_dir(src: &Path, dest: &Path, notify_handler: &NotifyHandler) -> Result<()> {
	notify_handler.call(CopyingDirectory(src, dest));
	raw::copy_dir(src, dest)
		.ok_or_else(|| Error::CopyingDirectory(PathBuf::from(src), PathBuf::from(dest)))
}

pub fn copy_file(src: &Path, dest: &Path) -> Result<()> {
	fs::copy(src, dest)
		.map_err(|_| Error::CopyingFile(PathBuf::from(src), PathBuf::from(dest)))
		.map(|_|())
}

pub fn remove_dir(name: &'static str, path: &Path, notify_handler: &NotifyHandler) -> Result<()> {
	notify_handler.call(RemovingDirectory(name, path));
	fs::remove_dir_all(path)
		.map_err(|e| Error::RemovingDirectory { name: name, path: PathBuf::from(path), error: e })
}

pub fn remove_file(name: &'static str, path: &Path) -> Result<()> {
	fs::remove_file(path)
		.map_err(|e| Error::RemovingFile { name: name, path: PathBuf::from(path), error: e })
}

pub fn read_dir(name: &'static str, path: &Path) -> Result<fs::ReadDir> {
	fs::read_dir(path)
		.map_err(|e| Error::ReadingDirectory { name: name, path: PathBuf::from(path), error: e })
}

pub fn open_browser(path: &Path) -> Result<()> {
	if let Ok(true) = raw::open_browser(path) {
		Ok(())
	} else {
		Err(Error::OpeningBrowser)
	}
}

pub fn set_permissions(path: &Path, perms: fs::Permissions) -> Result<()> {
	fs::set_permissions(path, perms).map_err(|_| Error::SettingPermissions(PathBuf::from(path)))
}

pub fn make_executable(path: &Path) -> Result<()> {
	#[cfg(windows)]
	fn inner(_: &Path) -> Result<()> {
		Ok(())
	}
	#[cfg(not(windows))]
	fn inner(path: &Path) -> Result<()> {
		use std::os::unix::fs::PermissionsExt;

		let metadata = try!(fs::metadata(path).map_err(|_| Error::SettingPermissions(PathBuf::from(path))));
		let mut perms = metadata.permissions();
		perms.set_mode(perms.mode()|0o111);

		set_permissions(path, perms)
	}

	inner(path)
}
<commit_msg>Fix borrowck error<commit_after>
use errors::*;
use std::path::{Path, PathBuf};
use std::fs;
use std::process::Command;
use hyper;

pub mod raw;

pub use self::raw::{
	is_directory,
	is_file,
	path_exists,
	to_absolute,
	if_not_empty,
	random_string,
	prefix_arg,
};

pub fn ensure_dir_exists(name: &'static str, path: &Path, notify_handler: &NotifyHandler) -> Result<bool> {
	raw::ensure_dir_exists(path, |p| {
		notify_handler.call(CreatingDirectory(name, p))
	}).map_err(|e| Error::CreatingDirectory { name: name, path: PathBuf::from(path), error: e })
}

pub fn read_file(name: &'static str, path: &Path) -> Result<String> {
	raw::read_file(path)
		.map_err(|e| Error::ReadingFile { name: name, path: PathBuf::from(path), error: e })
}

pub fn write_file(name: &'static str, path: &Path, contents: &str) -> Result<()> {
	raw::write_file(path, contents)
		.map_err(|e| Error::WritingFile { name: name, path: PathBuf::from(path), error: e })
}

pub fn append_file(name: &'static str, path: &Path, line: &str) -> Result<()> {
	raw::append_file(path, line)
		.map_err(|e| Error::WritingFile { name: name, path: PathBuf::from(path), error: e })
}

pub fn rename_file(name: &'static str, src: &Path, dest: &Path) -> Result<()> {
	fs::rename(src, dest)
		.map_err(|e| Error::RenamingFile {
			name: name,
			src: PathBuf::from(src),
			dest: PathBuf::from(dest),
			error: e
		})
}

pub fn rename_dir(name: &'static str, src: &Path, dest: &Path) -> Result<()> {
	fs::rename(src, dest)
		.map_err(|e| Error::RenamingDirectory {
			name: name,
			src: PathBuf::from(src),
			dest: PathBuf::from(dest),
			error: e
		})
}

pub fn filter_file<F: FnMut(&str) -> bool>(name: &'static str, src: &Path, dest: &Path, filter: F) -> Result<usize> {
	raw::filter_file(src, dest, filter)
		.map_err(|e| Error::FilteringFile {
			name: name,
			src: PathBuf::from(src),
			dest: PathBuf::from(dest),
			error: e
		})
}

pub fn match_file<T, F: FnMut(&str) -> Option<T>>(name: &'static str, src: &Path, f: F) -> Result<Option<T>> {
	raw::match_file(src, f)
		.map_err(|e| Error::ReadingFile {
			name: name,
			path: PathBuf::from(src),
			error: e
		})
}

pub fn canonicalize_path(path: &Path, notify_handler: &NotifyHandler) -> PathBuf {
	fs::canonicalize(path)
		.unwrap_or_else(|_| {
			notify_handler.call(Notification::NoCanonicalPath(path));
			PathBuf::from(path)
		})
}

pub fn download_file(url: hyper::Url, path: &Path, notify_handler: &NotifyHandler) -> Result<()> {
	notify_handler.call(DownloadingFile(&url, path));
	raw::download_file(url.clone(), path)
		.map_err(|_| Error::DownloadingFile { url: url, path: PathBuf::from(path) })
}

pub fn cmd_status(name: &'static str, mut cmd: Command) -> Result<()> {
	cmd.status()
		.map_err(|e| Error::RunningCommand { name: name, error: e })
		.and_then(|s| {
			if s.success() {
				Ok(())
			} else {
				Err(Error::CommandStatus {
					name: name,
					status: s,
				})
			}
		})
}

pub fn assert_is_file(path: &Path) -> Result<()> {
	if !is_file(path) {
		Err(Error::NotAFile { path: PathBuf::from(path) })
	} else {
		Ok(())
	}
}

pub fn assert_is_directory(path: &Path) -> Result<()> {
	if !is_directory(path) {
		Err(Error::NotADirectory { path: PathBuf::from(path) })
	} else {
		Ok(())
	}
}

pub fn symlink_dir(src: &Path, dest: &Path, notify_handler: &NotifyHandler) -> Result<()> {
	notify_handler.call(LinkingDirectory(src, dest));
	raw::symlink_dir(src, dest)
		.ok_or_else(|| Error::LinkingDirectory(PathBuf::from(src), PathBuf::from(dest)))
}

pub fn copy_dir(src: &Path, dest: &Path, notify_handler: &NotifyHandler) -> Result<()> {
	notify_handler.call(CopyingDirectory(src, dest));
	raw::copy_dir(src, dest)
		.ok_or_else(|| Error::CopyingDirectory(PathBuf::from(src), PathBuf::from(dest)))
}

pub fn copy_file(src: &Path, dest: &Path) -> Result<()> {
	fs::copy(src, dest)
		.map_err(|_| Error::CopyingFile(PathBuf::from(src), PathBuf::from(dest)))
		.map(|_|())
}

pub fn remove_dir(name: &'static str, path: &Path, notify_handler: &NotifyHandler) -> Result<()> {
	notify_handler.call(RemovingDirectory(name, path));
	fs::remove_dir_all(path)
		.map_err(|e| Error::RemovingDirectory { name: name, path: PathBuf::from(path), error: e })
}

pub fn remove_file(name: &'static str, path: &Path) -> Result<()> {
	fs::remove_file(path)
		.map_err(|e| Error::RemovingFile { name: name, path: PathBuf::from(path), error: e })
}

pub fn read_dir(name: &'static str, path: &Path) -> Result<fs::ReadDir> {
	fs::read_dir(path)
		.map_err(|e| Error::ReadingDirectory { name: name, path: PathBuf::from(path), error: e })
}

pub fn open_browser(path: &Path) -> Result<()> {
	if let Ok(true) = raw::open_browser(path) {
		Ok(())
	} else {
		Err(Error::OpeningBrowser)
	}
}

pub fn set_permissions(path: &Path, perms: fs::Permissions) -> Result<()> {
	fs::set_permissions(path, perms).map_err(|_| Error::SettingPermissions(PathBuf::from(path)))
}

pub fn make_executable(path: &Path) -> Result<()> {
	#[cfg(windows)]
	fn inner(_: &Path) -> Result<()> {
		Ok(())
	}
	#[cfg(not(windows))]
	fn inner(path: &Path) -> Result<()> {
		use std::os::unix::fs::PermissionsExt;

		let metadata = try!(fs::metadata(path).map_err(|_| Error::SettingPermissions(PathBuf::from(path))));
		let mut perms = metadata.permissions();
		let new_mode = perms.mode()|0o111;
		perms.set_mode(new_mode);

		set_permissions(path, perms)
	}

	inner(path)
}
<|endoftext|>