<commit_before>// Copyright (c) 2016-2017 Chef Software Inc. and/or applicable contributors
//
// 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.

use std::path::{Path, PathBuf};

use hab_core::package::archive::PackageArchive;
use hab_core::config::ConfigFile;
use bldr_core::logger::Logger;

use super::workspace::Workspace;
use {PRODUCT, VERSION};
use config::Config;
use depot_client;
use error::{Error, Result};
use retry::retry;

/// Postprocessing config file name
const CONFIG_FILE: &'static str = "builder.toml";

pub const RETRIES: u64 = 5;
pub const RETRY_WAIT: u64 = 3000;

#[derive(Clone, Debug, Deserialize, PartialEq, Eq)]
pub struct Publish {
    pub enabled: bool,
    pub url: String,
    pub channel: String,
}

impl Publish {
    pub fn run(
        &mut self,
        archive: &mut PackageArchive,
        auth_token: &str,
        logger: &mut Logger,
    ) -> bool {
        if !self.enabled {
            return true;
        }
        debug!(
            "post process: publish (url: {}, channel: {})",
            self.url,
            self.channel
        );

        let client = depot_client::Client::new(&self.url, PRODUCT, VERSION, None).unwrap();

        match retry(RETRIES, RETRY_WAIT, || client.x_put_package(archive, auth_token), |res| res.is_ok()) {
            Ok(_) => (),
            Err(err) => {
                let msg = format!("post processing error uploading package after {} retries. ERR={:?}",
                RETRIES,
                err);
                error!("{}", msg);
                logger.log(&msg);
                return false;
            }
        }

        let ident = archive.ident().unwrap();

        match retry(RETRIES, RETRY_WAIT, || client.promote_package(&ident, &self.channel, auth_token), |res| res.is_ok()) {
            Ok(_) => (),
            Err(err) => {
                let msg = format!("post processing error promoting package after {} retries, ERR={:?}",
                RETRIES,
                err);
                error!("{}", msg);
                logger.log(&msg);
                return false;
            }
        }

        true
    }
}

#[derive(Default, Deserialize)]
#[serde(default)]
struct PublishBuilder {
    /// Whether publish is enabled
    enabled: Option<bool>,
    /// URL to Depot API
    url: Option<String>,
    /// Channel to publish to
    channel: Option<String>,
}

impl PublishBuilder {
    fn new(config_path: &Path) -> Result<Self> {
        let builder = if config_path.exists() {
            debug!(
                "using post processing config from {}",
                config_path.display()
            );
            PublishBuilder::from_file(config_path)?
        } else {
            debug!("no post processing config - using defaults");
            PublishBuilder::default()
        };
        Ok(builder)
    }

    fn build(self, config: &Config) -> Publish {
        Publish {
            enabled: self.enabled.unwrap_or(config.auto_publish),
            url: self.url.unwrap_or(config.depot_url.clone()),
            channel: self.channel.unwrap_or(config.depot_channel.clone()),
        }
    }
}

impl ConfigFile for PublishBuilder {
    type Error = Error;
}

pub struct PostProcessor {
    config_path: PathBuf,
}

impl PostProcessor {
    pub fn new(workspace: &Workspace) -> Self {
        let parent_path = Path::new(workspace.job.get_project().get_plan_path())
            .parent()
            .unwrap();
        let file_path = workspace.src().join(parent_path.join(CONFIG_FILE));
        PostProcessor { config_path: file_path }
    }

    pub fn run(
        &mut self,
        archive: &mut PackageArchive,
        config: &Config,
        logger: &mut Logger,
    ) -> bool {
        let mut publisher = match PublishBuilder::new(&self.config_path) {
            Ok(builder) => builder.build(config),
            Err(err) => {
                warn!("Failed to parse builder config, {}", err);
                return false;
            }
        };
        debug!("starting post processing");
        publisher.run(archive, &config.auth_token, logger)
    }
}

#[cfg(test)]
mod tests {
    use hab_core::config::ConfigFile;
    use super::*;
    use config::Config;

    #[test]
    fn test_publish_config_from_toml() {
        let toml = r#"
        enabled = false
        url = "https://willem.habitat.sh/v1/depot"
        channel = "unstable"
        "#;

        let config = Config::default();
        let cfg = PublishBuilder::from_raw(toml).unwrap().build(&config);
        assert_eq!("https://willem.habitat.sh/v1/depot", cfg.url);
        assert_eq!(false, cfg.enabled);
        assert_eq!("unstable", cfg.channel);
    }
}
<commit_msg>Update retry timeout for builder-worker<commit_after>// Copyright (c) 2016-2017 Chef Software Inc. and/or applicable contributors
//
// 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.

use std::path::{Path, PathBuf};

use hab_core::package::archive::PackageArchive;
use hab_core::config::ConfigFile;
use bldr_core::logger::Logger;

use super::workspace::Workspace;
use {PRODUCT, VERSION};
use config::Config;
use depot_client;
use error::{Error, Result};
use retry::retry;

/// Postprocessing config file name
const CONFIG_FILE: &'static str = "builder.toml";

pub const RETRIES: u64 = 10;
pub const RETRY_WAIT: u64 = 60000;

#[derive(Clone, Debug, Deserialize, PartialEq, Eq)]
pub struct Publish {
    pub enabled: bool,
    pub url: String,
    pub channel: String,
}

impl Publish {
    pub fn run(
        &mut self,
        archive: &mut PackageArchive,
        auth_token: &str,
        logger: &mut Logger,
    ) -> bool {
        if !self.enabled {
            return true;
        }
        debug!(
            "post process: publish (url: {}, channel: {})",
            self.url,
            self.channel
        );

        let client = depot_client::Client::new(&self.url, PRODUCT, VERSION, None).unwrap();

        match retry(RETRIES, RETRY_WAIT, || client.x_put_package(archive, auth_token), |res| res.is_ok()) {
            Ok(_) => (),
            Err(err) => {
                let msg = format!("post processing error uploading package after {} retries. ERR={:?}",
                RETRIES,
                err);
                error!("{}", msg);
                logger.log(&msg);
                return false;
            }
        }

        let ident = archive.ident().unwrap();

        match retry(RETRIES, RETRY_WAIT, || client.promote_package(&ident, &self.channel, auth_token), |res| res.is_ok()) {
            Ok(_) => (),
            Err(err) => {
                let msg = format!("post processing error promoting package after {} retries, ERR={:?}",
                RETRIES,
                err);
                error!("{}", msg);
                logger.log(&msg);
                return false;
            }
        }

        true
    }
}

#[derive(Default, Deserialize)]
#[serde(default)]
struct PublishBuilder {
    /// Whether publish is enabled
    enabled: Option<bool>,
    /// URL to Depot API
    url: Option<String>,
    /// Channel to publish to
    channel: Option<String>,
}

impl PublishBuilder {
    fn new(config_path: &Path) -> Result<Self> {
        let builder = if config_path.exists() {
            debug!(
                "using post processing config from {}",
                config_path.display()
            );
            PublishBuilder::from_file(config_path)?
        } else {
            debug!("no post processing config - using defaults");
            PublishBuilder::default()
        };
        Ok(builder)
    }

    fn build(self, config: &Config) -> Publish {
        Publish {
            enabled: self.enabled.unwrap_or(config.auto_publish),
            url: self.url.unwrap_or(config.depot_url.clone()),
            channel: self.channel.unwrap_or(config.depot_channel.clone()),
        }
    }
}

impl ConfigFile for PublishBuilder {
    type Error = Error;
}

pub struct PostProcessor {
    config_path: PathBuf,
}

impl PostProcessor {
    pub fn new(workspace: &Workspace) -> Self {
        let parent_path = Path::new(workspace.job.get_project().get_plan_path())
            .parent()
            .unwrap();
        let file_path = workspace.src().join(parent_path.join(CONFIG_FILE));
        PostProcessor { config_path: file_path }
    }

    pub fn run(
        &mut self,
        archive: &mut PackageArchive,
        config: &Config,
        logger: &mut Logger,
    ) -> bool {
        let mut publisher = match PublishBuilder::new(&self.config_path) {
            Ok(builder) => builder.build(config),
            Err(err) => {
                warn!("Failed to parse builder config, {}", err);
                return false;
            }
        };
        debug!("starting post processing");
        publisher.run(archive, &config.auth_token, logger)
    }
}

#[cfg(test)]
mod tests {
    use hab_core::config::ConfigFile;
    use super::*;
    use config::Config;

    #[test]
    fn test_publish_config_from_toml() {
        let toml = r#"
        enabled = false
        url = "https://willem.habitat.sh/v1/depot"
        channel = "unstable"
        "#;

        let config = Config::default();
        let cfg = PublishBuilder::from_raw(toml).unwrap().build(&config);
        assert_eq!("https://willem.habitat.sh/v1/depot", cfg.url);
        assert_eq!(false, cfg.enabled);
        assert_eq!("unstable", cfg.channel);
    }
}
<|endoftext|>


<commit_before>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at https://mozilla.org/MPL/2.0/. */

<%namespace name="helpers" file="/helpers.mako.rs" />
<% from data import ALL_SIDES, maybe_moz_logical_alias %>
<% data.new_style_struct("Padding", inherited=False) %>

// APPLIES_TO_PLACEHOLDER so we can set it in UA  stylesheets.  But we use a
// !important value there, so pages can't set it.
% for side in ALL_SIDES:
    <%
        spec = "https://drafts.csswg.org/css-box/#propdef-padding-%s" % side[0]
        if side[1]:
            spec = "https://drafts.csswg.org/css-logical-props/#propdef-padding-%s" % side[1]
    %>
    ${helpers.predefined_type(
        "padding-%s" % side[0],
        "NonNegativeLengthPercentage",
        "computed::NonNegativeLengthPercentage::zero()",
        alias=maybe_moz_logical_alias(product, side, "-moz-padding-%s"),
        animation_value_type="NonNegativeLengthPercentage",
        logical=side[1],
        logical_group="padding",
        spec=spec,
        flags="APPLIES_TO_FIRST_LETTER APPLIES_TO_PLACEHOLDER GETCS_NEEDS_LAYOUT_FLUSH",
        allow_quirks=not side[1],
        servo_restyle_damage="reflow rebuild_and_reflow_inline"
    )}
% endfor

% for side in ALL_SIDES:
    ${helpers.predefined_type(
        "scroll-padding-%s" % side[0],
        "NonNegativeLengthPercentageOrAuto",
        "computed::NonNegativeLengthPercentageOrAuto::auto()",
        products="gecko",
        gecko_pref="layout.css.scroll-snap-v1.enabled",
        logical=side[1],
        logical_group="scroll-padding",
        spec="https://drafts.csswg.org/css-scroll-snap-1/#propdef-scroll-padding-%s" % side[0],
        animation_value_type="ComputedValue",
    )}
% endfor
<commit_msg>style: Explicitly specify animation_value_type for scroll-padding.<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at https://mozilla.org/MPL/2.0/. */

<%namespace name="helpers" file="/helpers.mako.rs" />
<% from data import ALL_SIDES, maybe_moz_logical_alias %>
<% data.new_style_struct("Padding", inherited=False) %>

// APPLIES_TO_PLACEHOLDER so we can set it in UA  stylesheets.  But we use a
// !important value there, so pages can't set it.
% for side in ALL_SIDES:
    <%
        spec = "https://drafts.csswg.org/css-box/#propdef-padding-%s" % side[0]
        if side[1]:
            spec = "https://drafts.csswg.org/css-logical-props/#propdef-padding-%s" % side[1]
    %>
    ${helpers.predefined_type(
        "padding-%s" % side[0],
        "NonNegativeLengthPercentage",
        "computed::NonNegativeLengthPercentage::zero()",
        alias=maybe_moz_logical_alias(product, side, "-moz-padding-%s"),
        animation_value_type="NonNegativeLengthPercentage",
        logical=side[1],
        logical_group="padding",
        spec=spec,
        flags="APPLIES_TO_FIRST_LETTER APPLIES_TO_PLACEHOLDER GETCS_NEEDS_LAYOUT_FLUSH",
        allow_quirks=not side[1],
        servo_restyle_damage="reflow rebuild_and_reflow_inline"
    )}
% endfor

% for side in ALL_SIDES:
    ${helpers.predefined_type(
        "scroll-padding-%s" % side[0],
        "NonNegativeLengthPercentageOrAuto",
        "computed::NonNegativeLengthPercentageOrAuto::auto()",
        products="gecko",
        gecko_pref="layout.css.scroll-snap-v1.enabled",
        logical=side[1],
        logical_group="scroll-padding",
        spec="https://drafts.csswg.org/css-scroll-snap-1/#propdef-scroll-padding-%s" % side[0],
        animation_value_type="NonNegativeLengthPercentageOrAuto",
    )}
% endfor
<|endoftext|>


<commit_before>extern crate rustc_serialize;
extern crate libc;
#[macro_use] extern crate log;
extern crate env_logger;
extern crate regex;
extern crate shaman;
extern crate argparse;
extern crate quire;
#[macro_use] extern crate lithos;

use std::env;
use std::io::{stderr, Read, Write};
use std::io::Error as IoError;
use std::process::exit;
use std::path::{Path, PathBuf};
use std::path::Component;
use std::str::FromStr;
use std::ffi::{OsStr, OsString};
use std::fs::{File};
use std::fs::{copy, rename, metadata, read_link};
use std::os::unix::fs::symlink;
use std::os::unix::ffi::OsStrExt;
use std::default::Default;
use std::process::{Command, Stdio};

use shaman::digest::Digest;
use argparse::{ArgumentParser, Parse, ParseOption, StoreTrue};
use quire::parse_config;

use lithos::master_config::MasterConfig;
use lithos::tree_config::TreeConfig;
use lithos::signal;

fn hash_file(file: &Path) -> Result<String, IoError> {
    let mut hash = shaman::sha2::Sha256::new();
    // We assume that file is small enough so we don't care reading it
    // to memory
    let mut buf = Vec::with_capacity(1024);
    try!(try!(File::open(file)).read_to_end(&mut buf));
    hash.input(&buf);
    Ok(hash.result_str())
}

fn switch_config(master_cfg: &Path, tree_name: String, config_file: &Path,
    name_prefix: Option<String>)
    -> Result<(), String>
{
    match Command::new(env::current_exe().unwrap()
                       .parent().unwrap().join("lithos_check"))
        .stdin(Stdio::inherit())
        .stdout(Stdio::inherit())
        .stderr(Stdio::inherit())
        .arg("--config")
        .arg(&master_cfg)
        .arg("--tree")
        .arg(&tree_name)
        .arg("--alternate-config")
        .arg(&config_file)
        .output()
    {
        Ok(ref po) if po.status.code() == Some(0) => { }
        Ok(ref po) => {
            return Err(format!(
                "Configuration check failed with exit status: {}",
                po.status));
        }
        Err(e) => {
            return Err(format!("Can't check configuration: {}", e));
        }
    }
    info!("Checked. Proceeding");

    let master: MasterConfig = match parse_config(&master_cfg,
        &*MasterConfig::validator(), Default::default())
    {
        Ok(cfg) => cfg,
        Err(e) => {
            return Err(format!("Can't parse master config: {}", e));
        }
    };
    let tree_fn = master.config_dir.join(tree_name + ".yaml");
    let tree: TreeConfig = match parse_config(&tree_fn,
        &*TreeConfig::validator(), Default::default())
    {
        Ok(cfg) => cfg,
        Err(e) => {
            return Err(format!("Can't parse tree config: {}", e));
        }
    };

    let config_fn: OsString = if let Some(prefix) = name_prefix {
        let hash = try!(hash_file(&config_file)
            .map_err(|e| format!("Can't read file: {}", e)));
        OsString::from(prefix + &hash + ".yaml")
    } else {
        config_file.file_name().unwrap().to_owned()
    };
    let target_fn = tree.config_file.parent().unwrap()
                    .join(&config_fn);
    if target_fn == tree.config_file {
        return Err(format!("Target config file ({:?}) \
            is the current file ({:?}). You must have unique \
            name for each new configuration",
            target_fn, tree.config_file));
    }
    let lnk = try!(read_link(&tree.config_file)
       .map_err(|e| format!("Can't read link {:?}: {}", tree.config_file, e)));
    let mut cmp_iter = lnk.components();
    match (cmp_iter.next(), cmp_iter.next()) {
        (Some(Component::Normal(_)), None) => {},
        _ => return Err(format!("The path {:?} must be a symlink \
            which points to the file at the same level of hierarchy.",
            tree.config_file)),
    };
    if lnk.file_name() == target_fn.file_name() {
        warn!("Target config dir is the active one. Nothing to do.");
        return Ok(());
    }
    if metadata(&target_fn).is_ok() {
        warn!("Target file {:?} exists. \
            Probably already copied. Skipping copying step.",
            target_fn);
    } else {
        info!("Seems everything nice. Copying");
        try!(copy(&config_file, &target_fn)
            .map_err(|e| format!("Error copying: {}", e)));
    }
    info!("Ok files are there. Making symlink");
    let mut tmpname = OsStr::from_bytes(b".tmp.").to_owned();
    tmpname.push(tree.config_file.file_name().unwrap());
    let symlink_fn = tree.config_file.with_file_name(tmpname);
    try!(symlink(&Path::new(&config_fn), &symlink_fn)
        .map_err(|e| format!("Error symlinking dir: {}", e)));
    try!(rename(&symlink_fn, &tree.config_file)
        .map_err(|e| format!("Error replacing symlink: {}", e)));

    info!("Done. Sending SIGQUIT to lithos_tree");
    let pid_file = master.runtime_dir.join("master.pid");
    let mut buf = String::with_capacity(50);
    let read = File::open(&pid_file)
            .and_then(|mut f| f.read_to_string(&mut buf))
            .ok();
    match read.and_then(|_| FromStr::from_str(&buf).ok()) {
        Some(pid) if signal::is_process_alive(pid) => {
            signal::send_signal(pid, signal::SIGQUIT);
        }
        Some(pid) => {
            warn!("Process with pid {} is not running...", pid);
        }
        None => {
            warn!("Can't read pid file {}. Probably daemon is not running.",
                pid_file.display());
        }
    };

    return Ok(());
}

fn main() {
    if env::var("RUST_LOG").is_err() {
        env::set_var("RUST_LOG", "warn");
    }
    env_logger::init().unwrap();

    let mut master_config = PathBuf::from("/etc/lithos.yaml");
    let mut verbose = false;
    let mut name_prefix = None;
    let mut config_file = PathBuf::from("");
    let mut tree_name = "".to_string();
    {
        let mut ap = ArgumentParser::new();
        ap.set_description("Checks if lithos configuration is ok");
        ap.refer(&mut master_config)
          .add_option(&["--master"], Parse,
            "Name of the master configuration file (default /etc/lithos.yaml)")
          .metavar("FILE");
        ap.refer(&mut verbose)
          .add_option(&["-v", "--verbose"], StoreTrue,
            "Verbose configuration");
        ap.refer(&mut name_prefix)
          .add_option(&["--hashed-name"], ParseOption, "
            Do not use last component of FILE as a name, but create an unique
            name based on the PREFIX and hash of the contents.
            ")
          .metavar("PREFIX");
        ap.refer(&mut tree_name)
          .add_argument("tree", Parse,
            "Name of the tree which configuration will be switched for")
          .required()
          .metavar("NAME");
        ap.refer(&mut config_file)
          .add_argument("new_config", Parse, "
            Name of the configuration directory to switch to. It doesn't
            have to be a directory inside `config-dir`, and it will be copied
            there. However, if directory with the same name exists in the
            `config-dir` it's assumed that it's already copied and will not
            be updated. Be sure to use unique directory for each deployment.
            ")
          .metavar("FILE")
          .required();
        match ap.parse_args() {
            Ok(()) => {}
            Err(x) => {
                exit(x);
            }
        }
    }
    match switch_config(&master_config, tree_name, &config_file, name_prefix)
    {
        Ok(()) => {
            exit(0);
        }
        Err(e) => {
            write!(&mut stderr(), "Fatal error: {}\n", e).unwrap();
            exit(1);
        }
    }
}
<commit_msg>Shorten auto-generated file names in lithos_switch<commit_after>extern crate rustc_serialize;
extern crate libc;
#[macro_use] extern crate log;
extern crate env_logger;
extern crate regex;
extern crate shaman;
extern crate argparse;
extern crate quire;
#[macro_use] extern crate lithos;

use std::env;
use std::io::{stderr, Read, Write};
use std::io::Error as IoError;
use std::process::exit;
use std::path::{Path, PathBuf};
use std::path::Component;
use std::str::FromStr;
use std::ffi::{OsStr, OsString};
use std::fs::{File};
use std::fs::{copy, rename, metadata, read_link};
use std::os::unix::fs::symlink;
use std::os::unix::ffi::OsStrExt;
use std::default::Default;
use std::process::{Command, Stdio};

use shaman::digest::Digest;
use argparse::{ArgumentParser, Parse, ParseOption, StoreTrue};
use quire::parse_config;

use lithos::master_config::MasterConfig;
use lithos::tree_config::TreeConfig;
use lithos::signal;

fn hash_file(file: &Path) -> Result<String, IoError> {
    let mut hash = shaman::sha2::Sha256::new();
    // We assume that file is small enough so we don't care reading it
    // to memory
    let mut buf = Vec::with_capacity(1024);
    try!(try!(File::open(file)).read_to_end(&mut buf));
    hash.input(&buf);
    Ok(hash.result_str())
}

fn switch_config(master_cfg: &Path, tree_name: String, config_file: &Path,
    name_prefix: Option<String>)
    -> Result<(), String>
{
    match Command::new(env::current_exe().unwrap()
                       .parent().unwrap().join("lithos_check"))
        .stdin(Stdio::inherit())
        .stdout(Stdio::inherit())
        .stderr(Stdio::inherit())
        .arg("--config")
        .arg(&master_cfg)
        .arg("--tree")
        .arg(&tree_name)
        .arg("--alternate-config")
        .arg(&config_file)
        .output()
    {
        Ok(ref po) if po.status.code() == Some(0) => { }
        Ok(ref po) => {
            return Err(format!(
                "Configuration check failed with exit status: {}",
                po.status));
        }
        Err(e) => {
            return Err(format!("Can't check configuration: {}", e));
        }
    }
    info!("Checked. Proceeding");

    let master: MasterConfig = match parse_config(&master_cfg,
        &*MasterConfig::validator(), Default::default())
    {
        Ok(cfg) => cfg,
        Err(e) => {
            return Err(format!("Can't parse master config: {}", e));
        }
    };
    let tree_fn = master.config_dir.join(tree_name + ".yaml");
    let tree: TreeConfig = match parse_config(&tree_fn,
        &*TreeConfig::validator(), Default::default())
    {
        Ok(cfg) => cfg,
        Err(e) => {
            return Err(format!("Can't parse tree config: {}", e));
        }
    };

    let config_fn: OsString = if let Some(prefix) = name_prefix {
        let hash = try!(hash_file(&config_file)
            .map_err(|e| format!("Can't read file: {}", e)));
        OsString::from(prefix + &hash[..8] + ".yaml")
    } else {
        config_file.file_name().unwrap().to_owned()
    };
    let target_fn = tree.config_file.parent().unwrap()
                    .join(&config_fn);
    if target_fn == tree.config_file {
        return Err(format!("Target config file ({:?}) \
            is the current file ({:?}). You must have unique \
            name for each new configuration",
            target_fn, tree.config_file));
    }
    let lnk = try!(read_link(&tree.config_file)
       .map_err(|e| format!("Can't read link {:?}: {}", tree.config_file, e)));
    let mut cmp_iter = lnk.components();
    match (cmp_iter.next(), cmp_iter.next()) {
        (Some(Component::Normal(_)), None) => {},
        _ => return Err(format!("The path {:?} must be a symlink \
            which points to the file at the same level of hierarchy.",
            tree.config_file)),
    };
    debug!("Target filename {:?} ({:?} -> {:?})", target_fn,
        lnk.file_name(), target_fn.file_name());
    if lnk.file_name() == target_fn.file_name() {
        warn!("Target config dir is the active one. Nothing to do.");
        return Ok(());
    }
    if metadata(&target_fn).is_ok() {
        warn!("Target file {:?} exists. \
            Probably already copied. Skipping copying step.",
            target_fn);
    } else {
        info!("Seems everything nice. Copying");
        try!(copy(&config_file, &target_fn)
            .map_err(|e| format!("Error copying: {}", e)));
    }
    info!("Ok files are there. Making symlink");
    let mut tmpname = OsStr::from_bytes(b".tmp.").to_owned();
    tmpname.push(tree.config_file.file_name().unwrap());
    let symlink_fn = tree.config_file.with_file_name(tmpname);
    try!(symlink(&Path::new(&config_fn), &symlink_fn)
        .map_err(|e| format!("Error symlinking dir: {}", e)));
    try!(rename(&symlink_fn, &tree.config_file)
        .map_err(|e| format!("Error replacing symlink: {}", e)));

    info!("Done. Sending SIGQUIT to lithos_tree");
    let pid_file = master.runtime_dir.join("master.pid");
    let mut buf = String::with_capacity(50);
    let read = File::open(&pid_file)
            .and_then(|mut f| f.read_to_string(&mut buf))
            .ok();
    match read.and_then(|_| FromStr::from_str(&buf).ok()) {
        Some(pid) if signal::is_process_alive(pid) => {
            signal::send_signal(pid, signal::SIGQUIT);
        }
        Some(pid) => {
            warn!("Process with pid {} is not running...", pid);
        }
        None => {
            warn!("Can't read pid file {}. Probably daemon is not running.",
                pid_file.display());
        }
    };

    return Ok(());
}

fn main() {
    if env::var("RUST_LOG").is_err() {
        env::set_var("RUST_LOG", "warn");
    }
    env_logger::init().unwrap();

    let mut master_config = PathBuf::from("/etc/lithos.yaml");
    let mut verbose = false;
    let mut name_prefix = None;
    let mut config_file = PathBuf::from("");
    let mut tree_name = "".to_string();
    {
        let mut ap = ArgumentParser::new();
        ap.set_description("Checks if lithos configuration is ok");
        ap.refer(&mut master_config)
          .add_option(&["--master"], Parse,
            "Name of the master configuration file (default /etc/lithos.yaml)")
          .metavar("FILE");
        ap.refer(&mut verbose)
          .add_option(&["-v", "--verbose"], StoreTrue,
            "Verbose configuration");
        ap.refer(&mut name_prefix)
          .add_option(&["--hashed-name"], ParseOption, "
            Do not use last component of FILE as a name, but create an unique
            name based on the PREFIX and hash of the contents.
            ")
          .metavar("PREFIX");
        ap.refer(&mut tree_name)
          .add_argument("tree", Parse,
            "Name of the tree which configuration will be switched for")
          .required()
          .metavar("NAME");
        ap.refer(&mut config_file)
          .add_argument("new_config", Parse, "
            Name of the configuration directory to switch to. It doesn't
            have to be a directory inside `config-dir`, and it will be copied
            there. However, if directory with the same name exists in the
            `config-dir` it's assumed that it's already copied and will not
            be updated. Be sure to use unique directory for each deployment.
            ")
          .metavar("FILE")
          .required();
        match ap.parse_args() {
            Ok(()) => {}
            Err(x) => {
                exit(x);
            }
        }
    }
    match switch_config(&master_config, tree_name, &config_file, name_prefix)
    {
        Ok(()) => {
            exit(0);
        }
        Err(e) => {
            write!(&mut stderr(), "Fatal error: {}\n", e).unwrap();
            exit(1);
        }
    }
}
<|endoftext|>


<commit_before>use bitstream::byteread::*;

pub trait BitRead {
    fn consumed(&self) -> usize;
    fn available(&self) -> usize;
    fn can_refill(&self) -> bool;
    fn refill64(&mut self) -> ();
    fn get_val(&mut self, n:usize) -> u64;
    fn get_bit(&mut self) -> bool;
    fn peek_val(&mut self, n:usize) -> u64;
/*
    fn peek_bit1(size : u8) -> bool;

    fn get_bits32(size : u8) -> u32;

    fn get_bits64(size : u8) -> u64;

    fn peek_bits32(size : u8) -> u32;

    fn peek_bits64(size : u8) -> u64;

    fn skip_bits(size : u8) -> ();
*/
}

pub struct BitReadLE <'a> {
    buffer : &'a[u8], /// read buffer, 8-bytes padded
    index : usize,
    cache : u64,
    left : usize,
}

impl <'a> BitRead for BitReadLE<'a> {
    #[inline]
    fn consumed(&self) -> usize {
        self.index * 8 - self.left
    }

    #[inline]
    fn available(&self) -> usize {
        (self.buffer.len() - self.index) * 8 + self.left
    }

    #[inline]
    fn can_refill(&self) -> bool {
        self.index < self.buffer.len() - 8
    }

    #[inline]
    fn refill64(&mut self) -> () {
        if !self.can_refill() {
            return;
        }

        self.cache  = get_u64l(&self.buffer[self.index..]);
        self.index += 8;
        self.left   = 64;
    }

    #[inline]
    fn get_val(&mut self, n:usize) -> u64 {
        let ret = self.peek_val(n);

        self.cache = self.cache >> n;
        self.left -= n;

        return ret;
    }

    fn get_bit(&mut self) -> bool {
        if self.left <= 0 {
            self.refill64();
        }

        self.get_val(1) != 0
    }

    #[inline]
    fn peek_val(&mut self, n:usize) -> u64 {
        self.cache & ((1u64 << n) - 1)
    }
}

#[cfg(test)]
mod test {
    use super::*;

#[test]
    fn get_bit() {
        let buf = &[2, 0, 0, 0,
                    0, 0, 0, 0,
                    1, 0, 0, 0,
                    0, 0, 0, 0];

        let mut reader = BitReadLE {
            buffer : buf,
            index : 0,
            cache: 0,
            left: 0
        };

        assert!(!reader.get_bit());
        assert!(reader.get_bit());
    }
}
<commit_msg>bitstream: Implement get_bits_64<commit_after>use bitstream::byteread::*;

pub trait BitRead {
    fn consumed(&self) -> usize;
    fn available(&self) -> usize;
    fn can_refill(&self) -> bool;
    fn refill64(&mut self) -> ();
    fn get_val(&mut self, n:usize) -> u64;
    fn get_bit(&mut self) -> bool;
    fn peek_val(&mut self, n:usize) -> u64;
    fn get_bits_64(&mut self, n: usize) -> u64;
/*
    fn peek_bit1(size : u8) -> bool;

    fn get_bits32(size : u8) -> u32;

    fn peek_bits32(size : u8) -> u32;

    fn peek_bits64(size : u8) -> u64;

    fn skip_bits(size : u8) -> ();
*/
}

pub struct BitReadLE <'a> {
    buffer : &'a[u8], /// read buffer, 8-bytes padded
    index : usize,
    cache : u64,
    left : usize,
}

impl <'a> BitRead for BitReadLE<'a> {
    #[inline]
    fn consumed(&self) -> usize {
        self.index * 8 - self.left
    }

    #[inline]
    fn available(&self) -> usize {
        (self.buffer.len() - self.index) * 8 + self.left
    }

    #[inline]
    fn can_refill(&self) -> bool {
        self.index < self.buffer.len() - 8
    }

    #[inline]
    fn refill64(&mut self) -> () {
        if !self.can_refill() {
            return;
        }

        self.cache  = get_u64l(&self.buffer[self.index..]);
        self.index += 8;
        self.left   = 64;
    }

    #[inline]
    fn get_val(&mut self, n:usize) -> u64 {
        let ret = self.peek_val(n);

        self.cache = self.cache >> n;
        self.left -= n;

        return ret;
    }

    #[inline]
    fn peek_val(&mut self, n:usize) -> u64 {
        self.cache & ((1u64 << n) - 1)
    }

    #[inline]
    fn get_bit(&mut self) -> bool {
        if self.left <= 0 {
            self.refill64();
        }

        self.get_val(1) != 0
    }

    #[inline]
    fn get_bits_64(&mut self, n:usize) -> u64 {
        let mut left = 0;
        let mut ret = 0;

        if n == 0 {
            return 0;
        }

        if self.left < n {
            left = self.left;
            ret  = self.get_val(left);
            self.refill64();
        }

        self.get_val(n - left) << left | ret
    }
}

#[cfg(test)]
mod test {
    use super::*;

    const CHECKBOARD: [u8; 128] = [0b01010101; 128];

#[test]
    fn get_bit() {
        let mut reader = BitReadLE {
            buffer: &CHECKBOARD,
            index: 0,
            cache: 0,
            left: 0
        };

        assert!(reader.get_bit());
        assert!(!reader.get_bit());
    }

#[test]
    fn get_bits_64() {
        let mut reader = BitReadLE {
            buffer: &CHECKBOARD,
            index: 0,
            cache: 0,
            left: 0
        };

        assert!(reader.get_bits_64(1) == 1);
        assert!(reader.get_bits_64(2) == 2);
        assert!(reader.get_bits_64(4) == 10);
        assert!(reader.get_bits_64(1) == 0);
        assert!(reader.get_bits_64(8) == 85);
    }
}
<|endoftext|>


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

//! Implementation of the install aspects of the compiler.
//!
//! This module is responsible for installing the standard library,
//! compiler, and documentation.

use std::env;
use std::fs;
use std::path::{Path, PathBuf, Component};
use std::process::Command;

use Build;
use dist::{sanitize_sh, tmpdir};

/// Installs everything.
pub fn install(build: &Build, stage: u32, host: &str) {
    let prefix_default = PathBuf::from("/usr/local");
    let docdir_default = PathBuf::from("share/doc/rust");
    let mandir_default = PathBuf::from("share/man");
    let libdir_default = PathBuf::from("lib");
    let prefix = build.config.prefix.as_ref().unwrap_or(&prefix_default);
    let docdir = build.config.docdir.as_ref().unwrap_or(&docdir_default);
    let libdir = build.config.libdir.as_ref().unwrap_or(&libdir_default);
    let mandir = build.config.mandir.as_ref().unwrap_or(&mandir_default);

    let docdir = prefix.join(docdir);
    let libdir = prefix.join(libdir);
    let mandir = prefix.join(mandir);

    let destdir = env::var_os("DESTDIR").map(PathBuf::from);

    let prefix = add_destdir(&prefix, &destdir);
    let docdir = add_destdir(&docdir, &destdir);
    let libdir = add_destdir(&libdir, &destdir);
    let mandir = add_destdir(&mandir, &destdir);

    let empty_dir = build.out.join("tmp/empty_dir");
    t!(fs::create_dir_all(&empty_dir));
    if build.config.docs {
        install_sh(&build, "docs", "rust-docs", &build.rust_package_vers(),
                   stage, host, &prefix, &docdir, &libdir, &mandir, &empty_dir);
    }

    for target in build.config.target.iter() {
        install_sh(&build, "std", "rust-std", &build.rust_package_vers(),
                   stage, target, &prefix, &docdir, &libdir, &mandir, &empty_dir);
    }

    if build.config.extended {
        install_sh(&build, "cargo", "cargo", &build.cargo_package_vers(),
                   stage, host, &prefix, &docdir, &libdir, &mandir, &empty_dir);
        install_sh(&build, "rls", "rls", &build.rls_package_vers(),
                   stage, host, &prefix, &docdir, &libdir, &mandir, &empty_dir);
    }

    install_sh(&build, "rustc", "rustc", &build.rust_package_vers(),
               stage, host, &prefix, &docdir, &libdir, &mandir, &empty_dir);

    t!(fs::remove_dir_all(&empty_dir));
}

fn install_sh(build: &Build, package: &str, name: &str, version: &str, stage: u32, host: &str,
              prefix: &Path, docdir: &Path, libdir: &Path, mandir: &Path, empty_dir: &Path) {
    println!("Install {} stage{} ({})", package, stage, host);
    let package_name = format!("{}-{}-{}", name, version, host);

    let mut cmd = Command::new("sh");
    cmd.current_dir(empty_dir)
       .arg(sanitize_sh(&tmpdir(build).join(&package_name).join("install.sh")))
       .arg(format!("--prefix={}", sanitize_sh(prefix)))
       .arg(format!("--docdir={}", sanitize_sh(docdir)))
       .arg(format!("--libdir={}", sanitize_sh(libdir)))
       .arg(format!("--mandir={}", sanitize_sh(mandir)))
       .arg("--disable-ldconfig");
    build.run(&mut cmd);
}

fn add_destdir(path: &Path, destdir: &Option<PathBuf>) -> PathBuf {
    let mut ret = match *destdir {
        Some(ref dest) => dest.clone(),
        None => return path.to_path_buf(),
    };
    for part in path.components() {
        match part {
            Component::Normal(s) => ret.push(s),
            _ => {}
        }
    }
    return ret
}
<commit_msg>rustbuild: pass bindir to install_sh<commit_after>// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! Implementation of the install aspects of the compiler.
//!
//! This module is responsible for installing the standard library,
//! compiler, and documentation.

use std::env;
use std::fs;
use std::path::{Path, PathBuf, Component};
use std::process::Command;

use Build;
use dist::{sanitize_sh, tmpdir};

/// Installs everything.
pub fn install(build: &Build, stage: u32, host: &str) {
    let prefix_default = PathBuf::from("/usr/local");
    let docdir_default = PathBuf::from("share/doc/rust");
    let bindir_default = PathBuf::from("bin");
    let libdir_default = PathBuf::from("lib");
    let mandir_default = PathBuf::from("share/man");
    let prefix = build.config.prefix.as_ref().unwrap_or(&prefix_default);
    let docdir = build.config.docdir.as_ref().unwrap_or(&docdir_default);
    let bindir = build.config.bindir.as_ref().unwrap_or(&bindir_default);
    let libdir = build.config.libdir.as_ref().unwrap_or(&libdir_default);
    let mandir = build.config.mandir.as_ref().unwrap_or(&mandir_default);

    let docdir = prefix.join(docdir);
    let bindir = prefix.join(bindir);
    let libdir = prefix.join(libdir);
    let mandir = prefix.join(mandir);

    let destdir = env::var_os("DESTDIR").map(PathBuf::from);

    let prefix = add_destdir(&prefix, &destdir);
    let docdir = add_destdir(&docdir, &destdir);
    let bindir = add_destdir(&bindir, &destdir);
    let libdir = add_destdir(&libdir, &destdir);
    let mandir = add_destdir(&mandir, &destdir);

    let empty_dir = build.out.join("tmp/empty_dir");
    t!(fs::create_dir_all(&empty_dir));
    if build.config.docs {
        install_sh(&build, "docs", "rust-docs", &build.rust_package_vers(),
                   stage, host, &prefix, &docdir, &bindir, &libdir, &mandir, &empty_dir);
    }

    for target in build.config.target.iter() {
        install_sh(&build, "std", "rust-std", &build.rust_package_vers(),
                   stage, target, &prefix, &docdir, &bindir, &libdir, &mandir, &empty_dir);
    }

    if build.config.extended {
        install_sh(&build, "cargo", "cargo", &build.cargo_package_vers(),
                   stage, host, &prefix, &docdir, &bindir, &libdir, &mandir, &empty_dir);
        install_sh(&build, "rls", "rls", &build.rls_package_vers(),
                   stage, host, &prefix, &docdir, &bindir, &libdir, &mandir, &empty_dir);
    }

    install_sh(&build, "rustc", "rustc", &build.rust_package_vers(),
               stage, host, &prefix, &docdir, &bindir, &libdir, &mandir, &empty_dir);

    t!(fs::remove_dir_all(&empty_dir));
}

fn install_sh(build: &Build, package: &str, name: &str, version: &str, stage: u32, host: &str,
              prefix: &Path, docdir: &Path, bindir: &Path, libdir: &Path, mandir: &Path, empty_dir: &Path) {
    println!("Install {} stage{} ({})", package, stage, host);
    let package_name = format!("{}-{}-{}", name, version, host);

    let mut cmd = Command::new("sh");
    cmd.current_dir(empty_dir)
       .arg(sanitize_sh(&tmpdir(build).join(&package_name).join("install.sh")))
       .arg(format!("--prefix={}", sanitize_sh(prefix)))
       .arg(format!("--docdir={}", sanitize_sh(docdir)))
       .arg(format!("--bindir={}", sanitize_sh(bindir)))
       .arg(format!("--libdir={}", sanitize_sh(libdir)))
       .arg(format!("--mandir={}", sanitize_sh(mandir)))
       .arg("--disable-ldconfig");
    build.run(&mut cmd);
}

fn add_destdir(path: &Path, destdir: &Option<PathBuf>) -> PathBuf {
    let mut ret = match *destdir {
        Some(ref dest) => dest.clone(),
        None => return path.to_path_buf(),
    };
    for part in path.components() {
        match part {
            Component::Normal(s) => ret.push(s),
            _ => {}
        }
    }
    return ret
}
<|endoftext|>


<commit_before>//! An example control gallery: a port of the same `ui` example.

extern crate ui;

use ui::{BoxControl, Button, Checkbox, ColorButton, Combobox, DateTimePicker, Entry};
use ui::{FontButton, Group, InitOptions, Label, Menu, MenuItem, ProgressBar, RadioButtons};
use ui::{Separator, Slider, Spinbox, Tab, Window};

fn run() {
    let menu = Menu::new("File");
    menu.append_item("Open").on_clicked(Box::new(open_clicked));
    menu.append_item("Save").on_clicked(Box::new(save_clicked));

    let menu = Menu::new("Edit");
    menu.append_check_item("Checkable Item");
    menu.append_separator();
    let item = menu.append_item("Disabled Item");
    item.disable();
    menu.append_preferences_item();

    let menu = Menu::new("Help");
    menu.append_item("Help");
    menu.append_about_item();

    let mainwin = Window::new("ui Control Gallery", 640, 480, true);
    mainwin.set_margined(true);
    mainwin.on_closing(Box::new(|_| {
        ui::quit();
        false
    }));

    let vbox = BoxControl::new_vertical();
    vbox.set_padded(true);
    mainwin.set_child(vbox.clone().into());

    let hbox = BoxControl::new_horizontal();
    hbox.set_padded(true);
    vbox.append(hbox.clone().into(), true);

    let group = Group::new("Basic Controls");
    group.set_margined(true);
    hbox.append(group.clone().into(), false);

    let inner = BoxControl::new_vertical();
    inner.set_padded(true);
    group.set_child(inner.clone().into());

    inner.append(Button::new("Button").into(), false);
    inner.append(Checkbox::new("Checkbox").into(), false);
    let entry = Entry::new();
    entry.set_text("Entry");
    inner.append(entry.into(), false);
    inner.append(Label::new("Label").into(), false);
    inner.append(Separator::new_horizontal().into(), false);

    inner.append(DateTimePicker::new_date_picker().into(), false);
    inner.append(DateTimePicker::new_time_picker().into(), false);
    inner.append(DateTimePicker::new_date_time_picker().into(), false);

    inner.append(FontButton::new().into(), false);
    inner.append(ColorButton::new().into(), false);

    let inner2 = BoxControl::new_vertical();
    inner2.set_padded(true);
    hbox.append(inner2.clone().into(), true);

    let group = Group::new("Numbers");
    group.set_margined(true);
    inner2.append(group.clone().into(), false);

    let inner = BoxControl::new_vertical();
    inner.set_padded(true);
    group.set_child(inner.clone().into());

    let spinbox = Spinbox::new(0, 100);
    spinbox.on_changed(Box::new(|spinbox| update(spinbox.value())));
    inner.append(spinbox.into(), false);

    let slider = Slider::new(0, 100);
    slider.on_changed(Box::new(|slider| update(slider.value())));
    inner.append(slider.into(), false);

    let progress_bar = ProgressBar::new();
    inner.append(progress_bar.into(), false);

    let group = Group::new("Lists");
    group.set_margined(true);
    inner2.append(group.clone().into(), false);

    let inner = BoxControl::new_vertical();
    inner.set_padded(true);
    group.set_child(inner.clone().into());

    let cbox = Combobox::new();
    cbox.append("Combobox Item 1");
    cbox.append("Combobox Item 2");
    cbox.append("Combobox Item 3");
    inner.append(cbox.into(), false);

    let cbox = Combobox::new_editable();
    cbox.append("Editable Item 1");
    cbox.append("Editable Item 2");
    cbox.append("Editable Item 3");
    inner.append(cbox.into(), false);

    let rb = RadioButtons::new();
    rb.append("Radio Button 1");
    rb.append("Radio Button 2");
    rb.append("Radio Button 3");
    inner.append(rb.into(), true);

    let tab = Tab::new();
    tab.append("Page 1", BoxControl::new_horizontal().into());
    tab.append("Page 2", BoxControl::new_horizontal().into());
    tab.append("Page 3", BoxControl::new_horizontal().into());
    inner2.append(tab.into(), true);

    mainwin.show();
    ui::main();
}

pub fn main() {
    ui::init(InitOptions).unwrap();
    run();
    ui::uninit();
}

fn open_clicked(_: &MenuItem, mainwin: &Window) {
    match ui::open_file(mainwin) {
        Some(filename) => ui::msg_box(mainwin, "File selected", &*filename),
        None => ui::msg_box_error(mainwin, "No file selected", "Don't be alarmed!"),
    }
}

fn save_clicked(_: &MenuItem, mainwin: &Window) {
    match ui::open_file(mainwin) {
        Some(filename) => {
            ui::msg_box(mainwin, "File selected (don't worry, it's still there)", &*filename)
        }
        None => ui::msg_box_error(mainwin, "No file selected", "Don't be alarmed!"),
    }
}

fn update(_: i64) {
    // TODO(pcwalton)
}

<commit_msg>Updated example to compile with the new version<commit_after>//! An example control gallery: a port of the same `ui` example.

extern crate ui;

use ui::{BoxControl, Button, Checkbox, ColorButton, Combobox, EditableCombobox,
         DateTimePicker, Entry};
use ui::{FontButton, Group, InitOptions, Label, Menu, MenuItem, ProgressBar, RadioButtons};
use ui::{Separator, Slider, Spinbox, Tab, Window};

fn run() {
    let menu = Menu::new("File");
    menu.append_item("Open").on_clicked(Box::new(open_clicked));
    menu.append_item("Save").on_clicked(Box::new(save_clicked));

    let menu = Menu::new("Edit");
    menu.append_check_item("Checkable Item");
    menu.append_separator();
    let item = menu.append_item("Disabled Item");
    item.disable();
    menu.append_preferences_item();

    let menu = Menu::new("Help");
    menu.append_item("Help");
    menu.append_about_item();

    let mainwin = Window::new("ui Control Gallery", 640, 480, true);
    mainwin.set_margined(true);
    mainwin.on_closing(Box::new(|_| {
        ui::quit();
        false
    }));

    let vbox = BoxControl::new_vertical();
    vbox.set_padded(true);
    mainwin.set_child(vbox.clone().into());

    let hbox = BoxControl::new_horizontal();
    hbox.set_padded(true);
    vbox.append(hbox.clone().into(), true);

    let group = Group::new("Basic Controls");
    group.set_margined(true);
    hbox.append(group.clone().into(), false);

    let inner = BoxControl::new_vertical();
    inner.set_padded(true);
    group.set_child(inner.clone().into());

    inner.append(Button::new("Button").into(), false);
    inner.append(Checkbox::new("Checkbox").into(), false);
    let entry = Entry::new();
    entry.set_text("Entry");
    inner.append(entry.into(), false);
    inner.append(Label::new("Label").into(), false);
    inner.append(Separator::new_horizontal().into(), false);

    inner.append(DateTimePicker::new_date_picker().into(), false);
    inner.append(DateTimePicker::new_time_picker().into(), false);
    inner.append(DateTimePicker::new_date_time_picker().into(), false);

    inner.append(FontButton::new().into(), false);
    inner.append(ColorButton::new().into(), false);

    let inner2 = BoxControl::new_vertical();
    inner2.set_padded(true);
    hbox.append(inner2.clone().into(), true);

    let group = Group::new("Numbers");
    group.set_margined(true);
    inner2.append(group.clone().into(), false);

    let inner = BoxControl::new_vertical();
    inner.set_padded(true);
    group.set_child(inner.clone().into());

    let spinbox = Spinbox::new(0, 100);
    spinbox.on_changed(Box::new(|spinbox| update(spinbox.value())));
    inner.append(spinbox.into(), false);

    let slider = Slider::new(0, 100);
    slider.on_changed(Box::new(|slider| update(slider.value())));
    inner.append(slider.into(), false);

    let progress_bar = ProgressBar::new();
    inner.append(progress_bar.into(), false);

    let group = Group::new("Lists");
    group.set_margined(true);
    inner2.append(group.clone().into(), false);

    let inner = BoxControl::new_vertical();
    inner.set_padded(true);
    group.set_child(inner.clone().into());

    let cbox = Combobox::new();
    cbox.append("Combobox Item 1");
    cbox.append("Combobox Item 2");
    cbox.append("Combobox Item 3");
    inner.append(cbox.into(), false);

    let cbox = EditableCombobox::new();
    cbox.append("Editable Item 1");
    cbox.append("Editable Item 2");
    cbox.append("Editable Item 3");
    inner.append(cbox.into(), false);

    let rb = RadioButtons::new();
    rb.append("Radio Button 1");
    rb.append("Radio Button 2");
    rb.append("Radio Button 3");
    inner.append(rb.into(), true);

    let tab = Tab::new();
    tab.append("Page 1", BoxControl::new_horizontal().into());
    tab.append("Page 2", BoxControl::new_horizontal().into());
    tab.append("Page 3", BoxControl::new_horizontal().into());
    inner2.append(tab.into(), true);

    mainwin.show();
    ui::main();
}

pub fn main() {
    ui::init(InitOptions).unwrap();
    run();
    ui::uninit();
}

fn open_clicked(_: &MenuItem, mainwin: &Window) {
    match ui::open_file(mainwin) {
        Some(filename) => ui::msg_box(mainwin, "File selected", &*filename),
        None => ui::msg_box_error(mainwin, "No file selected", "Don't be alarmed!"),
    }
}

fn save_clicked(_: &MenuItem, mainwin: &Window) {
    match ui::save_file(mainwin) {
        Some(filename) => {
            ui::msg_box(mainwin, "File selected (don't worry, it's still there)", &*filename)
        }
        None => ui::msg_box_error(mainwin, "No file selected", "Don't be alarmed!"),
    }
}

fn update(_: i32) {
    // TODO(pcwalton)
}
<|endoftext|>


<commit_before>use cfg::DnfExpr;
use stdx::format_to;

use crate::{Diagnostic, DiagnosticsContext, Severity};

// Diagnostic: inactive-code
//
// This diagnostic is shown for code with inactive `#[cfg]` attributes.
pub(crate) fn inactive_code(
    ctx: &DiagnosticsContext<'_>,
    d: &hir::InactiveCode,
) -> Option<Diagnostic> {
    // If there's inactive code somewhere in a macro, don't propagate to the call-site.
    if d.node.file_id.is_macro() {
        return None;
    }

    let inactive = DnfExpr::new(d.cfg.clone()).why_inactive(&d.opts);
    let mut message = "code is inactive due to #[cfg] directives".to_string();

    if let Some(inactive) = inactive {
        format_to!(message, ": {}", inactive);
    }

    let res = Diagnostic::new(
        "inactive-code",
        message,
        ctx.sema.diagnostics_display_range(d.node.clone()).range,
    )
    .severity(Severity::WeakWarning)
    .with_unused(true);
    Some(res)
}

#[cfg(test)]
mod tests {
    use crate::{tests::check_diagnostics_with_config, DiagnosticsConfig};

    pub(crate) fn check(ra_fixture: &str) {
        let config = DiagnosticsConfig::default();
        check_diagnostics_with_config(config, ra_fixture)
    }

    #[test]
    fn cfg_diagnostics() {
        check(
            r#"
fn f() {
    // The three g̶e̶n̶d̶e̶r̶s̶ statements:

    #[cfg(a)] fn f() {}  // Item statement
  //^^^^^^^^^^^^^^^^^^^ weak: code is inactive due to #[cfg] directives: a is disabled
    #[cfg(a)] {}         // Expression statement
  //^^^^^^^^^^^^ weak: code is inactive due to #[cfg] directives: a is disabled
    #[cfg(a)] let x = 0; // let statement
  //^^^^^^^^^^^^^^^^^^^^ weak: code is inactive due to #[cfg] directives: a is disabled

    abc(#[cfg(a)] 0);
      //^^^^^^^^^^^ weak: code is inactive due to #[cfg] directives: a is disabled
    let x = Struct {
        #[cfg(a)] f: 0,
      //^^^^^^^^^^^^^^ weak: code is inactive due to #[cfg] directives: a is disabled
    };
    match () {
        () => (),
        #[cfg(a)] () => (),
      //^^^^^^^^^^^^^^^^^^^ weak: code is inactive due to #[cfg] directives: a is disabled
    }

    #[cfg(a)] 0          // Trailing expression of block
  //^^^^^^^^^^^ weak: code is inactive due to #[cfg] directives: a is disabled
}
        "#,
        );
    }

    #[test]
    fn inactive_item() {
        // Additional tests in `cfg` crate. This only tests disabled cfgs.

        check(
            r#"
    #[cfg(no)] pub fn f() {}
  //^^^^^^^^^^^^^^^^^^^^^^^^ weak: code is inactive due to #[cfg] directives: no is disabled

    #[cfg(no)] #[cfg(no2)] mod m;
  //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ weak: code is inactive due to #[cfg] directives: no and no2 are disabled

    #[cfg(all(not(a), b))] enum E {}
  //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ weak: code is inactive due to #[cfg] directives: b is disabled

    #[cfg(feature = "std")] use std;
  //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ weak: code is inactive due to #[cfg] directives: feature = "std" is disabled
"#,
        );
    }

    /// Tests that `cfg` attributes behind `cfg_attr` is handled properly.
    #[test]
    fn inactive_via_cfg_attr() {
        cov_mark::check!(cfg_attr_active);
        check(
            r#"
    #[cfg_attr(not(never), cfg(no))] fn f() {}
  //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ weak: code is inactive due to #[cfg] directives: no is disabled

    #[cfg_attr(not(never), cfg(not(no)))] fn f() {}

    #[cfg_attr(never, cfg(no))] fn g() {}

    #[cfg_attr(not(never), inline, cfg(no))] fn h() {}
  //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ weak: code is inactive due to #[cfg] directives: no is disabled
"#,
        );
    }
}
<commit_msg>fix: trailing ':' on empty inactive reasons<commit_after>use cfg::DnfExpr;
use stdx::format_to;

use crate::{Diagnostic, DiagnosticsContext, Severity};

// Diagnostic: inactive-code
//
// This diagnostic is shown for code with inactive `#[cfg]` attributes.
pub(crate) fn inactive_code(
    ctx: &DiagnosticsContext<'_>,
    d: &hir::InactiveCode,
) -> Option<Diagnostic> {
    // If there's inactive code somewhere in a macro, don't propagate to the call-site.
    if d.node.file_id.is_macro() {
        return None;
    }

    let inactive = DnfExpr::new(d.cfg.clone()).why_inactive(&d.opts);
    let mut message = "code is inactive due to #[cfg] directives".to_string();

    if let Some(inactive) = inactive {
        let inactive_reasons = inactive.to_string();

        if inactive_reasons.is_empty() {
            format_to!(message);
        } else {
            format_to!(message, ": {}", inactive);
        }
    }

    let res = Diagnostic::new(
        "inactive-code",
        message,
        ctx.sema.diagnostics_display_range(d.node.clone()).range,
    )
    .severity(Severity::WeakWarning)
    .with_unused(true);
    Some(res)
}

#[cfg(test)]
mod tests {
    use crate::{tests::check_diagnostics_with_config, DiagnosticsConfig};

    pub(crate) fn check(ra_fixture: &str) {
        let config = DiagnosticsConfig::default();
        check_diagnostics_with_config(config, ra_fixture)
    }

    #[test]
    fn cfg_diagnostics() {
        check(
            r#"
fn f() {
    // The three g̶e̶n̶d̶e̶r̶s̶ statements:

    #[cfg(a)] fn f() {}  // Item statement
  //^^^^^^^^^^^^^^^^^^^ weak: code is inactive due to #[cfg] directives: a is disabled
    #[cfg(a)] {}         // Expression statement
  //^^^^^^^^^^^^ weak: code is inactive due to #[cfg] directives: a is disabled
    #[cfg(a)] let x = 0; // let statement
  //^^^^^^^^^^^^^^^^^^^^ weak: code is inactive due to #[cfg] directives: a is disabled

    abc(#[cfg(a)] 0);
      //^^^^^^^^^^^ weak: code is inactive due to #[cfg] directives: a is disabled
    let x = Struct {
        #[cfg(a)] f: 0,
      //^^^^^^^^^^^^^^ weak: code is inactive due to #[cfg] directives: a is disabled
    };
    match () {
        () => (),
        #[cfg(a)] () => (),
      //^^^^^^^^^^^^^^^^^^^ weak: code is inactive due to #[cfg] directives: a is disabled
    }

    #[cfg(a)] 0          // Trailing expression of block
  //^^^^^^^^^^^ weak: code is inactive due to #[cfg] directives: a is disabled
}
        "#,
        );
    }

    #[test]
    fn inactive_item() {
        // Additional tests in `cfg` crate. This only tests disabled cfgs.

        check(
            r#"
    #[cfg(no)] pub fn f() {}
  //^^^^^^^^^^^^^^^^^^^^^^^^ weak: code is inactive due to #[cfg] directives: no is disabled

    #[cfg(no)] #[cfg(no2)] mod m;
  //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ weak: code is inactive due to #[cfg] directives: no and no2 are disabled

    #[cfg(all(not(a), b))] enum E {}
  //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ weak: code is inactive due to #[cfg] directives: b is disabled

    #[cfg(feature = "std")] use std;
  //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ weak: code is inactive due to #[cfg] directives: feature = "std" is disabled

    #[cfg(any())] pub fn f() {}
  //^^^^^^^^^^^^^^^^^^^^^^^^^^^ weak: code is inactive due to #[cfg] directives
"#,
        );
    }

    /// Tests that `cfg` attributes behind `cfg_attr` is handled properly.
    #[test]
    fn inactive_via_cfg_attr() {
        cov_mark::check!(cfg_attr_active);
        check(
            r#"
    #[cfg_attr(not(never), cfg(no))] fn f() {}
  //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ weak: code is inactive due to #[cfg] directives: no is disabled

    #[cfg_attr(not(never), cfg(not(no)))] fn f() {}

    #[cfg_attr(never, cfg(no))] fn g() {}

    #[cfg_attr(not(never), inline, cfg(no))] fn h() {}
  //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ weak: code is inactive due to #[cfg] directives: no is disabled
"#,
        );
    }
}
<|endoftext|>


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

use clean::*;

use super::Pass;
use core::DocContext;
use fold::DocFolder;

pub const COLLECT_TRAIT_IMPLS: Pass =
    Pass::early("collect-trait-impls", collect_trait_impls,
                "retrieves trait impls for items in the crate");

pub fn collect_trait_impls(krate: Crate, cx: &DocContext) -> Crate {
    let mut synth = SyntheticImplCollector::new(cx);
    let mut krate = synth.fold_crate(krate);

    if let Some(ref mut it) = krate.module {
        if let ModuleItem(Module { ref mut items, .. }) = it.inner {
            items.extend(synth.impls);

            for &cnum in cx.tcx.crates().iter() {
                for &did in cx.tcx.all_trait_implementations(cnum).iter() {
                    inline::build_impl(cx, did, items);
                }
            }

            // `tcx.crates()` doesn't include the local crate, and `tcx.all_trait_implementations`
            // doesn't work with it anyway, so pull them from the HIR map instead
            for &trait_did in cx.all_traits.iter() {
                for &impl_node in cx.tcx.hir.trait_impls(trait_did) {
                    let impl_did = cx.tcx.hir.local_def_id(impl_node);
                    inline::build_impl(cx, impl_did, items);
                }
            }

            // Also try to inline primitive impls from other crates.
            let lang_items = cx.tcx.lang_items();
            let primitive_impls = [
                lang_items.isize_impl(),
                lang_items.i8_impl(),
                lang_items.i16_impl(),
                lang_items.i32_impl(),
                lang_items.i64_impl(),
                lang_items.i128_impl(),
                lang_items.usize_impl(),
                lang_items.u8_impl(),
                lang_items.u16_impl(),
                lang_items.u32_impl(),
                lang_items.u64_impl(),
                lang_items.u128_impl(),
                lang_items.f32_impl(),
                lang_items.f64_impl(),
                lang_items.f32_runtime_impl(),
                lang_items.f64_runtime_impl(),
                lang_items.char_impl(),
                lang_items.str_impl(),
                lang_items.slice_impl(),
                lang_items.slice_u8_impl(),
                lang_items.str_alloc_impl(),
                lang_items.slice_alloc_impl(),
                lang_items.slice_u8_alloc_impl(),
                lang_items.const_ptr_impl(),
                lang_items.mut_ptr_impl(),
            ];

            for def_id in primitive_impls.iter().filter_map(|&def_id| def_id) {
                if !def_id.is_local() {
                    inline::build_impl(cx, def_id, items);

                    let auto_impls = get_auto_traits_with_def_id(cx, def_id);
                    let blanket_impls = get_blanket_impls_with_def_id(cx, def_id);
                    let mut renderinfo = cx.renderinfo.borrow_mut();

                    let new_impls: Vec<Item> = auto_impls.into_iter()
                        .chain(blanket_impls.into_iter())
                        .filter(|i| renderinfo.inlined.insert(i.def_id))
                        .collect();

                    items.extend(new_impls);
                }
            }
        } else {
            panic!("collect-trait-impls can't run");
        }
    } else {
        panic!("collect-trait-impls can't run");
    }

    krate
}

struct SyntheticImplCollector<'a, 'tcx: 'a, 'rcx: 'a, 'cstore: 'rcx> {
    cx: &'a DocContext<'a, 'tcx, 'rcx, 'cstore>,
    impls: Vec<Item>,
}

impl<'a, 'tcx, 'rcx, 'cstore> SyntheticImplCollector<'a, 'tcx, 'rcx, 'cstore> {
    fn new(cx: &'a DocContext<'a, 'tcx, 'rcx, 'cstore>) -> Self {
        SyntheticImplCollector {
            cx,
            impls: Vec::new(),
        }
    }
}

impl<'a, 'tcx, 'rcx, 'cstore> DocFolder for SyntheticImplCollector<'a, 'tcx, 'rcx, 'cstore> {
    fn fold_item(&mut self, i: Item) -> Option<Item> {
        if i.is_struct() || i.is_enum() || i.is_union() {
            if let (Some(node_id), Some(name)) =
                (self.cx.tcx.hir.as_local_node_id(i.def_id), i.name.clone())
            {
                self.impls.extend(get_auto_traits_with_node_id(self.cx, node_id, name.clone()));
                self.impls.extend(get_blanket_impls_with_node_id(self.cx, node_id, name));
            } else {
                self.impls.extend(get_auto_traits_with_def_id(self.cx, i.def_id));
                self.impls.extend(get_blanket_impls_with_def_id(self.cx, i.def_id));
            }
        }

        self.fold_item_recur(i)
    }
}
<commit_msg>filter collected trait impls against items in the crate<commit_after>// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use clean::*;

use rustc::util::nodemap::FxHashSet;
use rustc::hir::def_id::DefId;

use super::Pass;
use core::DocContext;
use fold::DocFolder;

pub const COLLECT_TRAIT_IMPLS: Pass =
    Pass::early("collect-trait-impls", collect_trait_impls,
                "retrieves trait impls for items in the crate");

pub fn collect_trait_impls(krate: Crate, cx: &DocContext) -> Crate {
    let mut synth = SyntheticImplCollector::new(cx);
    let mut krate = synth.fold_crate(krate);

    let prims: FxHashSet<PrimitiveType> =
        krate.primitives.iter().map(|p| p.1).collect();

    let crate_items = {
        let mut coll = ItemCollector::new();
        krate = coll.fold_crate(krate);
        coll.items
    };

    let mut new_items = Vec::new();

    for &cnum in cx.tcx.crates().iter() {
        for &did in cx.tcx.all_trait_implementations(cnum).iter() {
            inline::build_impl(cx, did, &mut new_items);
        }
    }

    // Also try to inline primitive impls from other crates.
    let lang_items = cx.tcx.lang_items();
    let primitive_impls = [
        lang_items.isize_impl(),
        lang_items.i8_impl(),
        lang_items.i16_impl(),
        lang_items.i32_impl(),
        lang_items.i64_impl(),
        lang_items.i128_impl(),
        lang_items.usize_impl(),
        lang_items.u8_impl(),
        lang_items.u16_impl(),
        lang_items.u32_impl(),
        lang_items.u64_impl(),
        lang_items.u128_impl(),
        lang_items.f32_impl(),
        lang_items.f64_impl(),
        lang_items.f32_runtime_impl(),
        lang_items.f64_runtime_impl(),
        lang_items.char_impl(),
        lang_items.str_impl(),
        lang_items.slice_impl(),
        lang_items.slice_u8_impl(),
        lang_items.str_alloc_impl(),
        lang_items.slice_alloc_impl(),
        lang_items.slice_u8_alloc_impl(),
        lang_items.const_ptr_impl(),
        lang_items.mut_ptr_impl(),
    ];

    for def_id in primitive_impls.iter().filter_map(|&def_id| def_id) {
        if !def_id.is_local() {
            inline::build_impl(cx, def_id, &mut new_items);

            let auto_impls = get_auto_traits_with_def_id(cx, def_id);
            let blanket_impls = get_blanket_impls_with_def_id(cx, def_id);
            let mut renderinfo = cx.renderinfo.borrow_mut();

            let new_impls: Vec<Item> = auto_impls.into_iter()
                .chain(blanket_impls.into_iter())
                .filter(|i| renderinfo.inlined.insert(i.def_id))
                .collect();

            new_items.extend(new_impls);
        }
    }

    let mut cleaner = BadImplStripper {
        prims,
        items: crate_items,
    };

    // scan through included items ahead of time to splice in Deref targets to the "valid" sets
    for it in &new_items {
        if let ImplItem(Impl { ref for_, ref trait_, ref items, .. }) = it.inner {
            if cleaner.keep_item(for_) && trait_.def_id() == cx.tcx.lang_items().deref_trait() {
                let target = items.iter().filter_map(|item| {
                    match item.inner {
                        TypedefItem(ref t, true) => Some(&t.type_),
                        _ => None,
                    }
                }).next().expect("Deref impl without Target type");

                if let Some(prim) = target.primitive_type() {
                    cleaner.prims.insert(prim);
                } else if let Some(did) = target.def_id() {
                    cleaner.items.insert(did);
                }
            }
        }
    }

    new_items.retain(|it| {
        if let ImplItem(Impl { ref for_, ref trait_, ref blanket_impl, .. }) = it.inner {
            cleaner.keep_item(for_) ||
                trait_.as_ref().map_or(false, |t| cleaner.keep_item(t)) ||
                blanket_impl.is_some()
        } else {
            true
        }
    });

    // `tcx.crates()` doesn't include the local crate, and `tcx.all_trait_implementations`
    // doesn't work with it anyway, so pull them from the HIR map instead
    for &trait_did in cx.all_traits.iter() {
        for &impl_node in cx.tcx.hir.trait_impls(trait_did) {
            let impl_did = cx.tcx.hir.local_def_id(impl_node);
            inline::build_impl(cx, impl_did, &mut new_items);
        }
    }

    if let Some(ref mut it) = krate.module {
        if let ModuleItem(Module { ref mut items, .. }) = it.inner {
            items.extend(synth.impls);
            items.extend(new_items);
        } else {
            panic!("collect-trait-impls can't run");
        }
    } else {
        panic!("collect-trait-impls can't run");
    }

    krate
}

struct SyntheticImplCollector<'a, 'tcx: 'a, 'rcx: 'a, 'cstore: 'rcx> {
    cx: &'a DocContext<'a, 'tcx, 'rcx, 'cstore>,
    impls: Vec<Item>,
}

impl<'a, 'tcx, 'rcx, 'cstore> SyntheticImplCollector<'a, 'tcx, 'rcx, 'cstore> {
    fn new(cx: &'a DocContext<'a, 'tcx, 'rcx, 'cstore>) -> Self {
        SyntheticImplCollector {
            cx,
            impls: Vec::new(),
        }
    }
}

impl<'a, 'tcx, 'rcx, 'cstore> DocFolder for SyntheticImplCollector<'a, 'tcx, 'rcx, 'cstore> {
    fn fold_item(&mut self, i: Item) -> Option<Item> {
        if i.is_struct() || i.is_enum() || i.is_union() {
            if let (Some(node_id), Some(name)) =
                (self.cx.tcx.hir.as_local_node_id(i.def_id), i.name.clone())
            {
                self.impls.extend(get_auto_traits_with_node_id(self.cx, node_id, name.clone()));
                self.impls.extend(get_blanket_impls_with_node_id(self.cx, node_id, name));
            } else {
                self.impls.extend(get_auto_traits_with_def_id(self.cx, i.def_id));
                self.impls.extend(get_blanket_impls_with_def_id(self.cx, i.def_id));
            }
        }

        self.fold_item_recur(i)
    }
}

#[derive(Default)]
struct ItemCollector {
    items: FxHashSet<DefId>,
}

impl ItemCollector {
    fn new() -> Self {
        Self::default()
    }
}

impl DocFolder for ItemCollector {
    fn fold_item(&mut self, i: Item) -> Option<Item> {
        self.items.insert(i.def_id);

        self.fold_item_recur(i)
    }
}

struct BadImplStripper {
    prims: FxHashSet<PrimitiveType>,
    items: FxHashSet<DefId>,
}

impl BadImplStripper {
    fn keep_item(&self, ty: &Type) -> bool {
        if let Generic(_) = ty {
            // keep impls made on generics
            true
        } else if let Some(prim) = ty.primitive_type() {
            self.prims.contains(&prim)
        } else if let Some(did) = ty.def_id() {
            self.items.contains(&did)
        } else {
            false
        }
    }
}
<|endoftext|>


<commit_before>
#[derive(Debug, Copy, Clone, Serialize, Deserialize)]
pub enum State {
    #[serde(rename = "merged")]
    Merged,
    #[serde(rename = "opened")]
    Opened,
    #[serde(rename = "closed")]
    Closed,
    #[serde(rename = "all")]
    All,
}

#[derive(Debug, Serialize, Deserialize)]
enum Status {
    #[serde(rename = "can_be_merged")]
    CanBeMerged,
    #[serde(rename = "cannot_be_merged")]
    CannotBeMerged,
    #[serde(rename = "unchecked")]
    Unchecked,
}

#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
pub enum ListingOrderBy {
    #[serde(rename = "created_at")]
    CreatedAt,
    #[serde(rename = "updated_at")]
    UpdatedAt,
}

#[derive(Default, Debug, Clone, Serialize, Deserialize)]
pub struct MergeRequestsListerInternal {
    /// Merge request's IID
    iid: Option<Vec<i64>>,
    /// State of the requests
    state: Option<State>,
    /// Return requests ordered by. Default is `ListingOrderBy::CreatedAt`.
    order_by: Option<ListingOrderBy>,
    /// Return requests sorted. Default is `ListingSort::Desc`.
    sort: Option<::ListingSort>,
}

#[derive(Debug, Serialize, Deserialize)]
pub struct MergeRequest {
    id: i64,
    iid: i64,
    project_id: i64,
    title: String,
    description: String,
    state: State,
    created_at: String,  // FIXME: Use chrono crate
    updated_at: String,  // FIXME: Use chrono crate
    target_branch: String,
    source_branch: String,
    upvotes: i64,
    downvotes: i64,
    author: ::User,
    assignee: Option<::User>,
    source_project_id: i64,
    target_project_id: i64,
    labels: Vec<String>,
    work_in_progress: bool,
    milestone: Option<::Milestone>,
    merge_when_build_succeeds: bool,
    merge_status: Status,
    sha: String,
    merge_commit_sha: Option<String>,
    subscribed: bool,
    user_notes_count: i64,
    should_remove_source_branch: Option<bool>,
    force_remove_source_branch: Option<bool>,
    web_url: String
}

pub type MergeRequests = Vec<MergeRequest>;
<commit_msg>Bug fix: Let `MergeRequest` struct use an `Option<>` for field `sha`<commit_after>
#[derive(Debug, Copy, Clone, Serialize, Deserialize)]
pub enum State {
    #[serde(rename = "merged")]
    Merged,
    #[serde(rename = "opened")]
    Opened,
    #[serde(rename = "closed")]
    Closed,
    #[serde(rename = "all")]
    All,
}

#[derive(Debug, Serialize, Deserialize)]
enum Status {
    #[serde(rename = "can_be_merged")]
    CanBeMerged,
    #[serde(rename = "cannot_be_merged")]
    CannotBeMerged,
    #[serde(rename = "unchecked")]
    Unchecked,
}

#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
pub enum ListingOrderBy {
    #[serde(rename = "created_at")]
    CreatedAt,
    #[serde(rename = "updated_at")]
    UpdatedAt,
}

#[derive(Default, Debug, Clone, Serialize, Deserialize)]
pub struct MergeRequestsListerInternal {
    /// Merge request's IID
    iid: Option<Vec<i64>>,
    /// State of the requests
    state: Option<State>,
    /// Return requests ordered by. Default is `ListingOrderBy::CreatedAt`.
    order_by: Option<ListingOrderBy>,
    /// Return requests sorted. Default is `ListingSort::Desc`.
    sort: Option<::ListingSort>,
}

#[derive(Debug, Serialize, Deserialize)]
pub struct MergeRequest {
    id: i64,
    iid: i64,
    project_id: i64,
    title: String,
    description: String,
    state: State,
    created_at: String,  // FIXME: Use chrono crate
    updated_at: String,  // FIXME: Use chrono crate
    target_branch: String,
    source_branch: String,
    upvotes: i64,
    downvotes: i64,
    author: ::User,
    assignee: Option<::User>,
    source_project_id: i64,
    target_project_id: i64,
    labels: Vec<String>,
    work_in_progress: bool,
    milestone: Option<::Milestone>,
    merge_when_build_succeeds: bool,
    merge_status: Status,
    sha: Option<String>,
    merge_commit_sha: Option<String>,
    subscribed: bool,
    user_notes_count: i64,
    should_remove_source_branch: Option<bool>,
    force_remove_source_branch: Option<bool>,
    web_url: String
}

pub type MergeRequests = Vec<MergeRequest>;
<|endoftext|>


<commit_before>use std::cmp;
use std::ops::Add;
use std::option::Option;
use pcre::{Match, Pcre};
use std::fmt;

#[derive(Debug)]
pub struct LexRule {
    priority: u32,
    ident: String,
    pub src: String,
    expr: Pcre
}

impl fmt::Display for LexRule {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{0} : {1} : {2}", self.priority, self.ident, self.src)
    }
}

impl LexRule {
    pub fn new(priority: u32, ident: String, expr: String) -> Result<LexRule, String> {
        let re = match Pcre::compile(&expr) {
            Ok(regex) => regex,
            Err(_) => return Err(String::from("Unable to compile regex ").add(&expr))
        };

        Ok(LexRule {
            priority: priority,
            ident: ident.clone(),
            src: expr.clone(),
            expr: re
        })
    }

    pub fn from_string(src:String) -> Result<LexRule, String> {
        //TODO Remove unwraps, handle those errors properly
        let mut buf_priority = String::new();
        let mut buf_ident = String::new();
        let mut buf_regex = String::new();

        let mut index = src.chars()
        .position(|c| c == ':')
        .unwrap();

        let (b_pr_str, mut rest_str) = src.split_at(index);
        rest_str = rest_str.split_at(1).1.trim(); // Split to remove colon (pos 0), trim
        buf_priority = buf_priority.add(b_pr_str.trim());

        index = rest_str.chars()
        .position(|c| c == ':')
        .unwrap();

        let (b_idt_str, mut b_reg_str) = rest_str.split_at(index);
        b_reg_str = b_reg_str.split_at(1).1.trim(); // Split to remove colon (pos 0), trim
        buf_ident = buf_ident.add(b_idt_str.trim());
        buf_regex = buf_regex.add(b_reg_str.trim());

        let priority:u32 = buf_priority.parse().unwrap();
        LexRule::new(priority, buf_ident.clone(), buf_regex.clone())
    }

    pub fn match_at<'a>(&'a mut self, src:&'a String, pos:usize) -> Option<Match> {
        self.expr.exec_from(&(**src), pos)
    }
}

impl cmp::Eq for LexRule {}

impl cmp::PartialEq for LexRule {
    fn eq (&self, other:&Self) -> bool{
        (self.priority, &self.ident) == (other.priority, &other.ident)
    }
}

impl cmp::Ord for LexRule {
    fn cmp (&self, other: &Self) -> cmp::Ordering {
        self.priority.cmp(&other.priority)
    }
}

impl cmp::PartialOrd for LexRule {
    fn partial_cmp (&self, other: &Self) -> Option<cmp::Ordering> {
        Some(self.priority.cmp(&other.priority))
    }
}
<commit_msg>Implemented Clone for LexRule<commit_after>use std::cmp;
use std::ops::Add;
use std::option::Option;
use pcre::{Match, Pcre};
use std::clone::Clone;
use std::fmt;

#[derive(Debug)]
pub struct LexRule {
    priority: u32,
    ident: String,
    pub src: String,
    expr: Pcre
}

impl fmt::Display for LexRule {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{0} : {1} : {2}", self.priority, self.ident, self.src)
    }
}

impl Clone for LexRule {
    fn clone(&self) -> Self {
        LexRule {
            priority: self.priority,
            ident: self.ident.clone(),
            src: self.src.clone(),
            expr: Pcre::compile(&self.src).unwrap()
        }
    }
    fn clone_from(&mut self, source: &Self) {
        self.priority = source.priority;
        self.ident = source.ident.clone();
        self.src = source.src.clone();
        self.expr = Pcre::compile(&source.src).unwrap()
    }
}

impl LexRule {
    pub fn new(priority: u32, ident: String, expr: String) -> Result<LexRule, String> {
        let re = match Pcre::compile(&expr) {
            Ok(regex) => regex,
            Err(_) => return Err(String::from("Unable to compile regex ").add(&expr))
        };

        Ok(LexRule {
            priority: priority,
            ident: ident.clone(),
            src: expr.clone(),
            expr: re
        })
    }

    pub fn from_string(src:String) -> Result<LexRule, String> {
        //TODO Remove unwraps, handle those errors properly
        let mut buf_priority = String::new();
        let mut buf_ident = String::new();
        let mut buf_regex = String::new();

        let mut index = src.chars()
        .position(|c| c == ':')
        .unwrap();

        let (b_pr_str, mut rest_str) = src.split_at(index);
        rest_str = rest_str.split_at(1).1.trim(); // Split to remove colon (pos 0), trim
        buf_priority = buf_priority.add(b_pr_str.trim());

        index = rest_str.chars()
        .position(|c| c == ':')
        .unwrap();

        let (b_idt_str, mut b_reg_str) = rest_str.split_at(index);
        b_reg_str = b_reg_str.split_at(1).1.trim(); // Split to remove colon (pos 0), trim
        buf_ident = buf_ident.add(b_idt_str.trim());
        buf_regex = buf_regex.add(b_reg_str.trim());

        let priority:u32 = buf_priority.parse().unwrap();
        LexRule::new(priority, buf_ident.clone(), buf_regex.clone())
    }

    pub fn match_at<'a>(&'a mut self, src:&'a String, pos:usize) -> Option<Match> {
        self.expr.exec_from(&(**src), pos)
    }
}

impl cmp::Eq for LexRule {}

impl cmp::PartialEq for LexRule {
    fn eq (&self, other:&Self) -> bool{
        (self.priority, &self.ident) == (other.priority, &other.ident)
    }
}

impl cmp::Ord for LexRule {
    fn cmp (&self, other: &Self) -> cmp::Ordering {
        self.priority.cmp(&other.priority)
    }
}

impl cmp::PartialOrd for LexRule {
    fn partial_cmp (&self, other: &Self) -> Option<cmp::Ordering> {
        Some(self.priority.cmp(&other.priority))
    }
}
<|endoftext|>


<commit_before>use core::fail::{abort, out_of_memory};
use core::ptr::offset;
use core::ptr::{set_memory, copy_memory};
use core::i32::ctlz32;

use kernel::ptr::mut_offset;

enum Node {
    UNUSED = 0,
    USED = 1,
    SPLIT = 2,
    FULL = 3
}

pub trait Allocator {
    unsafe fn alloc(&mut self, size: uint) -> (*mut u8, uint);
    unsafe fn zero_alloc(&mut self, size: uint) -> (*mut u8, uint);
    unsafe fn realloc(&mut self, ptr: *mut u8, size: uint) -> (*mut u8, uint);
    unsafe fn free(&mut self, ptr: *mut u8);
}

trait BitvTrait {
    fn get(&self, i: uint) -> Node;
    fn set(&self, i: uint, x: Node);
    fn to_bytes(&self) -> *mut u8;
    fn size(&self) -> uint;
}

static BITV_SIZE: uint = 0x10_000;
pub type BitvStorage = *mut [u32, ..BITV_SIZE / 4];

// vector of 2-bit
pub struct Bitv {
    storage: BitvStorage
}

impl BitvTrait for Bitv {
    #[inline]
    fn get(&self, i: uint) -> Node {
        let w = i / 16;
        let b = (i % 16) * 2;
        unsafe { [UNUSED, USED, SPLIT, FULL][((*self.storage)[w] as uint >> b) & 3] }
    }

    #[inline]
    fn set(&self, i: uint, x: Node) {
        let w = i / 16;
        let b = (i % 16) * 2;
        unsafe { (*self.storage)[w] = (((*self.storage)[w] & !(3 << b)) | (x as u32 << b)); }
    }

    #[inline]
    fn to_bytes(&self) -> *mut u8 {
        self.storage as *mut u8
    }

    #[inline]
    fn size(&self) -> uint {
        BITV_SIZE
    }
}

pub struct BuddyAlloc {
    base: *mut u8,
    order: uint,
    tree: Bitv
}

impl BuddyAlloc {
    pub fn new(base: *mut u8, order: uint, storage: Bitv) -> BuddyAlloc {
        unsafe { set_memory(storage.to_bytes(), 0, storage.size()); }

        BuddyAlloc { base: base, order: order, tree: storage }
    }

    #[inline]
    fn offset(&self, index: uint, level: uint) -> *mut u8 {
        unsafe {
            mut_offset(self.base, (index + 1 - (1 << (self.order - level))) as int << level)
        }
    }
}

impl Allocator for BuddyAlloc {
    fn alloc(&mut self, mut size: uint) -> (*mut u8, uint) {
        if size == 0 {
            size = 1;
        }
        // smallest power of 2 >= size
        let lg2_size = 32 - unsafe { ctlz32(size as i32 - 1) } as uint;

        let mut index = 0; // points to current tree node
        let mut level = self.order; // current height

        loop {
            match (self.tree.get(index), level == lg2_size) {
                (UNUSED, true) => {
                    // Found appropriate unused node
                    self.tree.set(index, USED); // use

                    let mut parent = index;
                    loop {
                        let buddy = parent - 1 + (parent & 1) * 2;
                        match self.tree.get(buddy) {
                            USED | FULL if parent > 0 => {
                                parent = (parent + 1) / 2 - 1;
                                self.tree.set(parent, FULL);
                            }
                            _ => break
                        }
                    }
                    return (
                        self.offset(index, level),
                        1 << lg2_size
                    );
                }
                (UNUSED, false) => {
                    // This large node is unused, split it!
                    self.tree.set(index, SPLIT);
                    self.tree.set(index*2 + 1, UNUSED);
                    self.tree.set(index*2 + 2, UNUSED);
                    index = index * 2 + 1; // left child
                    level -= 1;
                }
                (SPLIT, false) => {
                    // Traverse children
                    index = index * 2 + 1; // left child
                    level -= 1;
                }
                _ => loop {
                    // Go either right or back up
                    if index & 1 == 1 {
                        // right sibling
                        index += 1;
                        break;
                    }

                    // go up by one level
                    level += 1;

                    if index == 0 {
                        // out of memory -- back at tree's root after traversal
                        return (self.base, 0);
                    }

                    index = (index + 1) / 2 - 1; // parent
                }
            }
        }
    }

    fn zero_alloc(&mut self, s: uint) -> (*mut u8, uint) {
        let (ptr, size) = self.alloc(s);
        unsafe { set_memory(ptr, 0, size); }
        (ptr, size)
    }

    fn realloc(&mut self, src: *mut u8, size: uint) -> (*mut u8, uint) {
        self.free(src);
        let (ptr, sz) = self.alloc(size);
        unsafe { copy_memory(ptr, src as *u8, sz); }
        (ptr, sz)
    }

    fn free(&mut self, ptr: *mut u8) {
        let mut length = 1 << self.order;
        let mut left = 0;
        let mut index = 0;

        if ((ptr as uint) < self.base as uint) || (ptr as uint >= self.base as uint + length) {
            return;
        }
        let offset = ptr as uint - self.base as uint;

        loop {
            match self.tree.get(index) {
                UNUSED => return,
                USED => loop {
                    if index == 0 {
                        self.tree.set(0, UNUSED);
                        return;
                    }

                    let buddy = index - 1 + (index & 1) * 2;
                    match self.tree.get(buddy) {
                        UNUSED => {}
                        _ => {
                            self.tree.set(index, UNUSED);
                            loop {
                                let parent = (index + 1) / 2 - 1; // parent
                                match self.tree.get(parent) {
                                    FULL if index > 0 => {
                                        self.tree.set(parent, SPLIT);
                                    }
                                    _ => return
                                }
                                index = parent;
                            }
                        }
                    }
                    index = (index + 1) / 2 - 1; // parent
                },
                _ => {
                    length /= 2;
                    if offset < left + length {
                        index = index * 2 + 1; // left child
                    }
                    else {
                        left += length;
                        index = index * 2 + 2; // right child
                    }
                }
            }
        }
    }
}
<commit_msg>Buddy: optimize<commit_after>use core::mem::transmute;
use core::ptr::{set_memory, copy_memory, offset};
use core::i32::ctlz32;

use kernel::ptr::mut_offset;

#[repr(u8)]
enum Node {
    UNUSED = 0,
    USED = 1,
    SPLIT = 2,
    FULL = 3
}

pub trait Allocator {
    unsafe fn alloc(&mut self, size: uint) -> (*mut u8, uint);
    unsafe fn zero_alloc(&mut self, size: uint) -> (*mut u8, uint);
    unsafe fn realloc(&mut self, ptr: *mut u8, size: uint) -> (*mut u8, uint);
    unsafe fn free(&mut self, ptr: *mut u8);
}

trait BitvTrait {
    fn get(&self, i: uint) -> Node;
    fn set(&self, i: uint, x: Node);
    fn to_bytes(&self) -> *mut u8;
    fn size(&self) -> uint;
}

static BITV_SIZE: uint = 0x10_000;
pub type BitvStorage = *mut [u32, ..BITV_SIZE / 4];

// vector of 2-bit
pub struct Bitv {
    storage: BitvStorage
}

impl BitvTrait for Bitv {
    #[inline]
    fn get(&self, i: uint) -> Node {
        let w = i / 16;
        let b = (i % 16) * 2;
        unsafe { transmute(((*self.storage)[w] as uint >> b) as u8 & 3) }
    }

    #[inline]
    fn set(&self, i: uint, x: Node) {
        let w = i / 16;
        let b = (i % 16) * 2;
        unsafe { (*self.storage)[w] = (((*self.storage)[w] & !(3 << b)) | (x as u32 << b)); }
    }

    #[inline]
    fn to_bytes(&self) -> *mut u8 {
        self.storage as *mut u8
    }

    #[inline]
    fn size(&self) -> uint {
        BITV_SIZE
    }
}

pub struct BuddyAlloc {
    base: *mut u8,
    order: uint,
    tree: Bitv
}

impl BuddyAlloc {
    pub fn new(base: *mut u8, order: uint, storage: Bitv) -> BuddyAlloc {
        unsafe { set_memory(storage.to_bytes(), 0, storage.size()); }

        BuddyAlloc { base: base, order: order, tree: storage }
    }

    #[inline]
    fn offset(&self, index: uint, level: uint) -> *mut u8 {
        unsafe {
            mut_offset(self.base, (index + 1 - (1 << (self.order - level))) as int << level)
        }
    }
}

impl Allocator for BuddyAlloc {
    fn alloc(&mut self, mut size: uint) -> (*mut u8, uint) {
        if size == 0 {
            size = 1;
        }
        // smallest power of 2 >= size
        let lg2_size = 32 - unsafe { ctlz32(size as i32 - 1) } as uint;

        let mut index = 0; // points to current tree node
        let mut level = self.order; // current height

        loop {
            match (self.tree.get(index), level == lg2_size) {
                (UNUSED, true) => {
                    // Found appropriate unused node
                    self.tree.set(index, USED); // use

                    let mut parent = index;
                    loop {
                        let buddy = parent - 1 + (parent & 1) * 2;
                        match self.tree.get(buddy) {
                            USED | FULL if parent > 0 => {
                                parent = (parent + 1) / 2 - 1;
                                self.tree.set(parent, FULL);
                            }
                            _ => break
                        }
                    }
                    return (
                        self.offset(index, level),
                        1 << lg2_size
                    );
                }
                (UNUSED, false) => {
                    // This large node is unused, split it!
                    self.tree.set(index, SPLIT);
                    self.tree.set(index*2 + 1, UNUSED);
                    self.tree.set(index*2 + 2, UNUSED);
                    index = index * 2 + 1; // left child
                    level -= 1;
                }
                (SPLIT, false) => {
                    // Traverse children
                    index = index * 2 + 1; // left child
                    level -= 1;
                }
                _ => loop {
                    // Go either right or back up
                    if index & 1 == 1 {
                        // right sibling
                        index += 1;
                        break;
                    }

                    // go up by one level
                    level += 1;

                    if index == 0 {
                        // out of memory -- back at tree's root after traversal
                        return (self.base, 0);
                    }

                    index = (index + 1) / 2 - 1; // parent
                }
            }
        }
    }

    fn zero_alloc(&mut self, s: uint) -> (*mut u8, uint) {
        let (ptr, size) = self.alloc(s);
        unsafe { set_memory(ptr, 0, size); }
        (ptr, size)
    }

    fn realloc(&mut self, src: *mut u8, size: uint) -> (*mut u8, uint) {
        self.free(src);
        let (ptr, sz) = self.alloc(size);
        unsafe { copy_memory(ptr, src as *u8, sz); }
        (ptr, sz)
    }

    fn free(&mut self, ptr: *mut u8) {
        let mut length = 1 << self.order;
        let mut left = 0;
        let mut index = 0;

        if ((ptr as uint) < self.base as uint) || (ptr as uint >= self.base as uint + length) {
            return;
        }
        let offset = ptr as uint - self.base as uint;

        loop {
            match self.tree.get(index) {
                UNUSED => return,
                USED => loop {
                    if index == 0 {
                        self.tree.set(0, UNUSED);
                        return;
                    }

                    let buddy = index - 1 + (index & 1) * 2;
                    match self.tree.get(buddy) {
                        UNUSED => {}
                        _ => {
                            self.tree.set(index, UNUSED);
                            loop {
                                let parent = (index + 1) / 2 - 1; // parent
                                match self.tree.get(parent) {
                                    FULL if index > 0 => {
                                        self.tree.set(parent, SPLIT);
                                    }
                                    _ => return
                                }
                                index = parent;
                            }
                        }
                    }
                    index = (index + 1) / 2 - 1; // parent
                },
                _ => {
                    length /= 2;
                    if offset < left + length {
                        index = index * 2 + 1; // left child
                    }
                    else {
                        left += length;
                        index = index * 2 + 2; // right child
                    }
                }
            }
        }
    }
}
<|endoftext|>