<commit_before>use std::cmp::PartialEq;
use std::cmp::PartialOrd;
use std::fmt::Display;
use std::clone::Clone;
use std::ops::Range;

/// rules!("some string".to_string(), [min(5)])
pub fn min(min: usize) -> impl Fn(&String) -> ::ValidatorResult {
    move |s: &String| {
        if s.len() >= min {
            Ok(())
        } else {
            Err(::Invalid {
                msg: "Must not contain less characters than %1.".to_string(),
                args: vec![min.to_string()],
            })
        }
    }
}

/// rules!("some string".to_string(), [max(64)])
pub fn max(max: usize) -> impl Fn(&String) -> ::ValidatorResult {
    move |s: &String| {
        if s.len() <= max {
            Ok(())
        } else {
            Err(::Invalid {
                msg: "Must not contain more characters than %1.".to_string(),
                args: vec![max.to_string()],
            })
        }
    }
}

/// rules!("some string".to_string(), [length(5..64)])
pub fn length(range: Range<usize>) -> impl Fn(&String) -> ::ValidatorResult {
    move |s: &String| {
        match (min(range.start)(s), max(range.end)(s)) {
            (Err(_), Err(_)) => {
                Err(::Invalid {
                    msg: "Must not be less characters than %1 and not more than %2.".to_string(),
                    args: vec![range.start.to_string(), range.end.to_string()],
                })
            }
            (Err(e), _) => Err(e),
            (_, Err(e)) => Err(e),
            (_, _) => Ok(()),
        }
    }
}

/// rules!(25, [range(12..127)])
pub fn range<T: PartialOrd + Display + Clone>(range: Range<T>) -> impl Fn(&T) -> ::ValidatorResult {
    move |s: &T| {
        if *s >= range.start && *s <= range.end {
            Ok(())
        } else {
            Err(::Invalid {
                msg: "Must be in the range %1..%2.".to_string(),
                args: vec![range.start.to_string(), range.end.to_string()],
            })
        }
    }
}

/// rules!("test@test.test".to_string(), [contains("@"), contains(".")])
pub fn contains<'a>(needle: &'a str) -> impl Fn(&String) -> ::ValidatorResult {
    move |s: &String| {
        if s.contains(needle) {
            Ok(())
        } else {
            Err(::Invalid {
                msg: "Must contain %1.".to_string(),
                args: vec![needle.to_string()],
            })
        }
    }
}

/// rules!(25, [eq(25)])
pub fn eq<T>(value: T) -> impl Fn(&T) -> ::ValidatorResult
    where T: PartialEq + Display
{
    move |s: &T| {
        if *s == value {
            Ok(())
        } else {
            Err(::Invalid {
                msg: "Does not equal %1.".to_string(),
                args: vec![value.to_string()],
            })
        }
    }
}

/// rules!(25, [either(vec![15, 25, 35])])
pub fn either<T>(values: Vec<T>) -> impl Fn(&T) -> ::ValidatorResult
    where T: PartialEq + Display + Clone
{
    move |s: &T| {
        let x = values.iter().find(|x| *x == s);
        let r = x.is_some();
        if r == true {
            Ok(())
        } else {
            let list = values.iter()
                .cloned()
                .fold(String::new(), |acc, v| format!("{}, {}", acc, v));
            Err(::Invalid {
                msg: "Must be one of %1.".to_string(),
                args: vec![list.to_string()],
            })
        }
    }
}
<commit_msg>add tests for range and length<commit_after>use std::cmp::PartialEq;
use std::cmp::PartialOrd;
use std::fmt::Display;
use std::clone::Clone;
use std::ops::Range;

/// rules!("some string".to_string(), [min(5)])
pub fn min(min: usize) -> impl Fn(&String) -> ::ValidatorResult {
    move |s: &String| {
        if s.len() >= min {
            Ok(())
        } else {
            Err(::Invalid {
                msg: "Must not contain less characters than %1.".to_string(),
                args: vec![min.to_string()],
            })
        }
    }
}

/// rules!("some string".to_string(), [max(64)])
pub fn max(max: usize) -> impl Fn(&String) -> ::ValidatorResult {
    move |s: &String| {
        if s.len() <= max {
            Ok(())
        } else {
            Err(::Invalid {
                msg: "Must not contain more characters than %1.".to_string(),
                args: vec![max.to_string()],
            })
        }
    }
}

/// rules!("some string".to_string(), [length(5..64)])
pub fn length(range: Range<usize>) -> impl Fn(&String) -> ::ValidatorResult {
    move |s: &String| {
        match (min(range.start)(s), max(range.end)(s)) {
            (Err(_), Err(_)) => {
                Err(::Invalid {
                    msg: "Must not be less characters than %1 and not more than %2.".to_string(),
                    args: vec![range.start.to_string(), range.end.to_string()],
                })
            }
            (Err(e), _) => Err(e),
            (_, Err(e)) => Err(e),
            (_, _) => Ok(()),
        }
    }
}

/// rules!(25, [range(12..127)])
pub fn range<T: PartialOrd + Display + Clone>(range: Range<T>) -> impl Fn(&T) -> ::ValidatorResult {
    move |s: &T| {
        if *s >= range.start && *s <= range.end {
            Ok(())
        } else {
            Err(::Invalid {
                msg: "Must be in the range %1..%2.".to_string(),
                args: vec![range.start.to_string(), range.end.to_string()],
            })
        }
    }
}

/// rules!("test@test.test".to_string(), [contains("@"), contains(".")])
pub fn contains<'a>(needle: &'a str) -> impl Fn(&String) -> ::ValidatorResult {
    move |s: &String| {
        if s.contains(needle) {
            Ok(())
        } else {
            Err(::Invalid {
                msg: "Must contain %1.".to_string(),
                args: vec![needle.to_string()],
            })
        }
    }
}

/// rules!(25, [eq(25)])
pub fn eq<T>(value: T) -> impl Fn(&T) -> ::ValidatorResult
    where T: PartialEq + Display
{
    move |s: &T| {
        if *s == value {
            Ok(())
        } else {
            Err(::Invalid {
                msg: "Does not equal %1.".to_string(),
                args: vec![value.to_string()],
            })
        }
    }
}

/// rules!(25, [either(vec![15, 25, 35])])
pub fn either<T>(values: Vec<T>) -> impl Fn(&T) -> ::ValidatorResult
    where T: PartialEq + Display + Clone
{
    move |s: &T| {
        let x = values.iter().find(|x| *x == s);
        let r = x.is_some();
        if r == true {
            Ok(())
        } else {
            let list = values.iter()
                .cloned()
                .fold(String::new(), |acc, v| format!("{}, {}", acc, v));
            Err(::Invalid {
                msg: "Must be one of %1.".to_string(),
                args: vec![list.to_string()],
            })
        }
    }
}

#[cfg(test)]
mod tests {
    use validators::{length, range};

    #[test]
    fn test_length() {
        assert!(length(3..5)(&"12".to_string()).is_err());
        assert!(length(3..5)(&"123".to_string()).is_ok());
        assert!(length(3..5)(&"1234".to_string()).is_ok());
        assert!(length(3..5)(&"12345".to_string()).is_ok());
        assert!(length(3..5)(&"123456".to_string()).is_err());
    }

    #[test]
    fn test_range() {
        assert!(range(12..127)(&11).is_err());
        assert!(range(12..127)(&12).is_ok());
        assert!(range(12..127)(&50).is_ok());
        assert!(range(12..127)(&127).is_ok());
        assert!(range(12..127)(&128).is_err());
    }
}
<|endoftext|>


<commit_before>use rustc_index::vec::{Idx, IndexVec};
use std::mem;
use std::ptr;

pub trait IdFunctor: Sized {
    type Inner;

    fn map_id<F>(self, f: F) -> Self
    where
        F: FnMut(Self::Inner) -> Self::Inner;

    fn try_map_id<F, E>(self, f: F) -> Result<Self, E>
    where
        F: FnMut(Self::Inner) -> Result<Self::Inner, E>;
}

impl<T> IdFunctor for Box<T> {
    type Inner = T;

    #[inline]
    fn map_id<F>(self, mut f: F) -> Self
    where
        F: FnMut(Self::Inner) -> Self::Inner,
    {
        let raw = Box::into_raw(self);
        unsafe {
            // SAFETY: The raw pointer points to a valid value of type `T`.
            let value = ptr::read(raw);
            // SAFETY: Converts `Box<T>` to `Box<MaybeUninit<T>>` which is the
            // inverse of `Box::assume_init()` and should be safe.
            let mut raw: Box<mem::MaybeUninit<T>> = Box::from_raw(raw.cast());
            // SAFETY: Write the mapped value back into the `Box`.
            raw.write(f(value));
            // SAFETY: We just initialized `raw`.
            raw.assume_init()
        }
    }

    #[inline]
    fn try_map_id<F, E>(self, mut f: F) -> Result<Self, E>
    where
        F: FnMut(Self::Inner) -> Result<Self::Inner, E>,
    {
        let raw = Box::into_raw(self);
        Ok(unsafe {
            // SAFETY: The raw pointer points to a valid value of type `T`.
            let value = ptr::read(raw);
            // SAFETY: Converts `Box<T>` to `Box<MaybeUninit<T>>` which is the
            // inverse of `Box::assume_init()` and should be safe.
            let mut raw: Box<mem::MaybeUninit<T>> = Box::from_raw(raw.cast());
            // SAFETY: Write the mapped value back into the `Box`.
            ptr::write(raw.as_mut_ptr(), f(value)?);
            // SAFETY: We just initialized `raw`.
            raw.assume_init()
        })
    }
}

impl<T> IdFunctor for Vec<T> {
    type Inner = T;

    #[inline]
    fn map_id<F>(mut self, mut f: F) -> Self
    where
        F: FnMut(Self::Inner) -> Self::Inner,
    {
        // FIXME: We don't really care about panics here and leak
        // far more than we should, but that should be fine for now.
        let len = self.len();
        unsafe {
            self.set_len(0);
            let start = self.as_mut_ptr();
            for i in 0..len {
                let p = start.add(i);
                ptr::write(p, f(ptr::read(p)));
            }
            self.set_len(len);
        }
        self
    }

    #[inline]
    fn try_map_id<F, E>(mut self, mut f: F) -> Result<Self, E>
    where
        F: FnMut(Self::Inner) -> Result<Self::Inner, E>,
    {
        // FIXME: We don't really care about panics here and leak
        // far more than we should, but that should be fine for now.
        let len = self.len();
        let mut error = Ok(());
        unsafe {
            self.set_len(0);
            let start = self.as_mut_ptr();
            for i in 0..len {
                let p = start.add(i);
                match f(ptr::read(p)) {
                    Ok(value) => ptr::write(p, value),
                    Err(err) => {
                        error = Err(err);
                        break;
                    }
                }
            }
            // Even if we encountered an error, set the len back
            // so we don't leak memory.
            self.set_len(len);
        }
        error.map(|()| self)
    }
}

impl<T> IdFunctor for Box<[T]> {
    type Inner = T;

    #[inline]
    fn map_id<F>(self, f: F) -> Self
    where
        F: FnMut(Self::Inner) -> Self::Inner,
    {
        Vec::from(self).map_id(f).into()
    }

    #[inline]
    fn try_map_id<F, E>(self, f: F) -> Result<Self, E>
    where
        F: FnMut(Self::Inner) -> Result<Self::Inner, E>,
    {
        Vec::from(self).try_map_id(f).map(Into::into)
    }
}

impl<I: Idx, T> IdFunctor for IndexVec<I, T> {
    type Inner = T;

    #[inline]
    fn map_id<F>(self, f: F) -> Self
    where
        F: FnMut(Self::Inner) -> Self::Inner,
    {
        IndexVec::from_raw(self.raw.map_id(f))
    }

    #[inline]
    fn try_map_id<F, E>(self, f: F) -> Result<Self, E>
    where
        F: FnMut(Self::Inner) -> Result<Self::Inner, E>,
    {
        self.raw.try_map_id(f).map(IndexVec::from_raw)
    }
}
<commit_msg>Avoid UB when short-circuiting try_map_id for Vec<commit_after>use rustc_index::vec::{Idx, IndexVec};
use std::mem;
use std::ptr;

pub trait IdFunctor: Sized {
    type Inner;

    fn map_id<F>(self, f: F) -> Self
    where
        F: FnMut(Self::Inner) -> Self::Inner;

    fn try_map_id<F, E>(self, f: F) -> Result<Self, E>
    where
        F: FnMut(Self::Inner) -> Result<Self::Inner, E>;
}

impl<T> IdFunctor for Box<T> {
    type Inner = T;

    #[inline]
    fn map_id<F>(self, mut f: F) -> Self
    where
        F: FnMut(Self::Inner) -> Self::Inner,
    {
        let raw = Box::into_raw(self);
        unsafe {
            // SAFETY: The raw pointer points to a valid value of type `T`.
            let value = ptr::read(raw);
            // SAFETY: Converts `Box<T>` to `Box<MaybeUninit<T>>` which is the
            // inverse of `Box::assume_init()` and should be safe.
            let mut raw: Box<mem::MaybeUninit<T>> = Box::from_raw(raw.cast());
            // SAFETY: Write the mapped value back into the `Box`.
            raw.write(f(value));
            // SAFETY: We just initialized `raw`.
            raw.assume_init()
        }
    }

    #[inline]
    fn try_map_id<F, E>(self, mut f: F) -> Result<Self, E>
    where
        F: FnMut(Self::Inner) -> Result<Self::Inner, E>,
    {
        let raw = Box::into_raw(self);
        Ok(unsafe {
            // SAFETY: The raw pointer points to a valid value of type `T`.
            let value = ptr::read(raw);
            // SAFETY: Converts `Box<T>` to `Box<MaybeUninit<T>>` which is the
            // inverse of `Box::assume_init()` and should be safe.
            let mut raw: Box<mem::MaybeUninit<T>> = Box::from_raw(raw.cast());
            // SAFETY: Write the mapped value back into the `Box`.
            ptr::write(raw.as_mut_ptr(), f(value)?);
            // SAFETY: We just initialized `raw`.
            raw.assume_init()
        })
    }
}

impl<T> IdFunctor for Vec<T> {
    type Inner = T;

    #[inline]
    fn map_id<F>(mut self, mut f: F) -> Self
    where
        F: FnMut(Self::Inner) -> Self::Inner,
    {
        // FIXME: We don't really care about panics here and leak
        // far more than we should, but that should be fine for now.
        let len = self.len();
        unsafe {
            self.set_len(0);
            let start = self.as_mut_ptr();
            for i in 0..len {
                let p = start.add(i);
                ptr::write(p, f(ptr::read(p)));
            }
            self.set_len(len);
        }
        self
    }

    #[inline]
    fn try_map_id<F, E>(mut self, mut f: F) -> Result<Self, E>
    where
        F: FnMut(Self::Inner) -> Result<Self::Inner, E>,
    {
        // FIXME: We don't really care about panics here and leak
        // far more than we should, but that should be fine for now.
        let len = self.len();
        unsafe {
            self.set_len(0);
            let start = self.as_mut_ptr();
            for i in 0..len {
                let p = start.add(i);
                match f(ptr::read(p)) {
                    Ok(value) => ptr::write(p, value),
                    Err(err) => {
                        // drop all other elements in self
                        // (current element was "moved" into the call to f)
                        for j in (0..i).chain(i + 1..len) {
                            let p = start.add(j);
                            ptr::drop_in_place(p);
                        }

                        // returning will drop self, releasing the allocation
                        // (len is 0 so elements will not be re-dropped)
                        return Err(err);
                    }
                }
            }
            // Even if we encountered an error, set the len back
            // so we don't leak memory.
            self.set_len(len);
        }
        Ok(self)
    }
}

impl<T> IdFunctor for Box<[T]> {
    type Inner = T;

    #[inline]
    fn map_id<F>(self, f: F) -> Self
    where
        F: FnMut(Self::Inner) -> Self::Inner,
    {
        Vec::from(self).map_id(f).into()
    }

    #[inline]
    fn try_map_id<F, E>(self, f: F) -> Result<Self, E>
    where
        F: FnMut(Self::Inner) -> Result<Self::Inner, E>,
    {
        Vec::from(self).try_map_id(f).map(Into::into)
    }
}

impl<I: Idx, T> IdFunctor for IndexVec<I, T> {
    type Inner = T;

    #[inline]
    fn map_id<F>(self, f: F) -> Self
    where
        F: FnMut(Self::Inner) -> Self::Inner,
    {
        IndexVec::from_raw(self.raw.map_id(f))
    }

    #[inline]
    fn try_map_id<F, E>(self, f: F) -> Result<Self, E>
    where
        F: FnMut(Self::Inner) -> Result<Self::Inner, E>,
    {
        self.raw.try_map_id(f).map(IndexVec::from_raw)
    }
}
<|endoftext|>


<commit_before>use config::Config;
use layout::{Layout, LayoutBox};
use xlib::Window;
use xlib_window_system::XlibWindowSystem;
use self::MoveOp::*;
use std::cmp;

pub struct WorkspaceConfig {
  pub tag: String,
  pub screen: uint,
  pub layout: LayoutBox
}

pub struct Workspace {
  managed: Vec<Window>,
  unmanaged: Vec<Window>,
  focused_window: Window,
  tag: String,
  screen: uint,
  visible: bool,
  layout: Box<Layout + 'static>
}

pub enum MoveOp {
  Up,
  Down,
  Swap
}

impl Workspace {
  pub fn add_window(&mut self, ws: &XlibWindowSystem, config: &Config, window: Window) {
    if !ws.is_transient_for(window) {
      self.managed.push(window);
    } else {
      self.unmanaged.push(window);
    }

    if self.visible {
      ws.map_window(window);
      self.redraw(ws, config);
    }
  }

  fn is_managed(&self, window: Window) -> bool {
    self.managed.iter().any(|&x| x == window)
  }

  fn is_unmanaged(&self, window: Window) -> bool {
    self.unmanaged.iter().any(|&x| x == window)
  }

  fn get_managed(&self, window: Window) -> uint {
    self.managed.iter().enumerate().filter(|&(_,&w)| w == window).map(|(i,_)| i).last().unwrap()
  }

  fn get_unmanaged(&self, window: Window) -> uint {
    self.unmanaged.iter().enumerate().filter(|&(_,&w)| w == window).map(|(i,_)| i).last().unwrap()
  }

  fn remove_managed(&mut self, ws: &XlibWindowSystem, config: &Config, window: Window) {
    let index = self.get_managed(window);

    self.focused_window = 0;
    ws.unmap_window(window);
    self.managed.remove(index);

    let new_focused_window = if !self.managed.is_empty() {
      self.managed[if index < self.managed.len() { index } else { index - 1}]
    } else {
      0
    };

    if self.visible {
      self.redraw(ws, config);
      self.focus_window(ws, config, new_focused_window);
    }
  }

  fn remove_unmanaged(&mut self, ws: &XlibWindowSystem, config: &Config, window: Window) {
    let index = self.get_unmanaged(window);

    self.focused_window = 0;
    ws.unmap_window(window);
    self.unmanaged.remove(index);

    let new_focused_window = if !self.unmanaged.is_empty() {
      self.unmanaged[if index < self.unmanaged.len() { index } else { index - 1}]
    } else {
      0
    };

    if self.visible {
      self.redraw(ws, config);
      self.focus_window(ws, config, new_focused_window);
    }
  }

  pub fn remove_window(&mut self, ws: &XlibWindowSystem, config: &Config, window: Window) -> bool {
    if self.is_managed(window) {
      self.remove_managed(ws, config, window);
    } else {
      if self.is_unmanaged(window) {
        self.remove_unmanaged(ws, config, window);
      } else {
        return false;
      }
    }

    return true;
  }

  pub fn focus_window(&mut self, ws: &XlibWindowSystem, config: &Config, window: Window) {
    if window == 0 {
      return;
    }

    self.unfocus_window(ws, config);
    self.focused_window = window;
    ws.focus_window(window, config.border_focus_color);
  }

  pub fn unfocus_window(&mut self, ws: &XlibWindowSystem, config: &Config) {
    if self.focused_window != 0 {
      ws.set_window_border_color(self.focused_window, config.border_color);
      self.focused_window = 0;
    }
  }

  pub fn move_focus(&mut self, ws: &XlibWindowSystem, config: &Config, op: MoveOp) {
    if self.focused_window == 0 || self.managed.len() < 2 {
      return;
    }

    let index = self.index_of(self.focused_window).unwrap();
    let new_focused_window = match op {
      Up => {
        if index == 0 {
          self.managed[self.managed.len() - 1]
        } else {
          self.managed[index - 1]
        }
      },
      Down => {
        self.managed[(index + 1) % self.managed.len()]
      },
      Swap => {
        self.managed[0]
      }
    };

    self.focus_window(ws, config, new_focused_window);
  }

  pub fn move_window(&mut self, ws: &XlibWindowSystem, config: &Config, op: MoveOp) {
    if self.focused_window == 0 || self.managed.len() < 2 {
      return;
    }

    let pos = self.index_of(self.focused_window).unwrap();
    let new_pos = match op {
      Up => {
        if pos == 0 {
          self.managed.len() - 1
        } else {
          pos - 1
        }
      },
      Down => {
        (pos + 1) % self.managed.len()
      },
      Swap => {
        let master = self.managed[0];
        self.managed.insert(pos, master);
        self.managed.remove(0);
        0
      }
    };

    self.managed.remove(pos);
    self.managed.insert(new_pos, self.focused_window);

    self.redraw(ws, config);
  }

  pub fn index_of(&self, window: Window) -> Option<uint> {
    self.managed.iter().enumerate().filter(|&(_,&w)| w == window).map(|(i,_)| i).last()
  }

  pub fn contains(&self, window: Window) -> bool {
    self.managed.iter().chain(self.unmanaged.iter()).any(|&w| w == window)
  }

  pub fn get_focused_window(&self) -> Window {
    self.focused_window
  }

  pub fn unfocus(&mut self, ws: &XlibWindowSystem, config: &Config) {
    ws.set_window_border_color(self.focused_window, config.border_color);
  }

  pub fn focus(&self, ws: &XlibWindowSystem, config: &Config) {
    if self.focused_window != 0 {
      ws.focus_window(self.focused_window, config.border_focus_color);
    }
  }

  pub fn hide(&mut self, ws: &XlibWindowSystem) {
    self.visible = false;

    for &w in self.managed.iter() {
      ws.unmap_window(w);
    }

    for &w in self.unmanaged.iter() {
      ws.unmap_window(w);
    }
  }

  pub fn show(&mut self, ws: &XlibWindowSystem, config: &Config) {
    self.visible = true;

    self.redraw(ws, config);
    for &w in self.managed.iter() {
      ws.map_window(w);
    }

    for &w in self.unmanaged.iter() {
      ws.map_window(w);
    }
  }

  pub fn redraw(&self, ws: &XlibWindowSystem, config: &Config) {
    for (i,rect) in self.layout.apply(ws.get_screen_infos()[self.screen], &self.managed).iter().enumerate() {
      ws.setup_window(rect.x, rect.y, rect.width, rect.height, config.border_width, config.border_color, self.managed[i]);
    }
    self.focus(ws, config);
  }
}

pub struct Workspaces {
  list: Vec<Workspace>,
  cur: uint
}

impl Workspaces {
  pub fn new(config: &mut Config, screens: uint) -> Workspaces{
    let mut workspaces = Workspaces{
      list: config.workspaces.iter_mut().map(|c| {
        Workspace {
          managed: Vec::new(),
          unmanaged: Vec::new(),
          focused_window: 0,
          tag: c.tag.clone(),
          screen: c.screen,
          visible: false,
          layout: (c.layout)()
        }
      }).collect(),
      cur: 0,
    };

    for screen in range(0u, screens) {
      if workspaces.list.iter().find(|ws| ws.screen == screen).is_none() {
        match workspaces.list.iter_mut().filter(|ws| ws.screen == 0).nth(1) {
          Some(ws) => {
            ws.screen = screen;
          },
          None => {}
        }
      }
    }

    for screen in range(0u, screens) {
      let ws = workspaces.list.iter_mut().find(|ws| ws.screen == screen).unwrap();
      ws.visible = true;
    }

    workspaces
  }

  pub fn get(&mut self, index: uint) -> &mut Workspace {
    if index < self.list.len() {
      self.list.get_mut(index).unwrap()
    } else {
      self.current()
    }
  }

  pub fn current(&mut self) -> &mut Workspace {
    self.list.get_mut(self.cur).unwrap()
  }

  pub fn switch_to(&mut self, ws: &XlibWindowSystem, config: &Config, index: uint) {
    if self.cur != index && index < self.list.len() {
      self.list[self.cur].hide(ws);

      if self.list[index].visible {
        self.switch_screens(index);
        self.list[self.cur].show(ws, config);
      }

      self.list[index].show(ws, config);
      self.list[index].focus(ws, config);
      self.cur = index;
    }
  }

  pub fn switch_to_screen(&mut self, ws: &XlibWindowSystem, config: &Config, screen: uint) {
    match self.list.iter().enumerate().filter(|&(_,ws)| ws.screen == screen && ws.visible).map(|(i,_)| i).last() {
      Some(index) => {
        self.list[self.cur].unfocus(ws, config);
        self.list[index].focus(ws, config);
        self.cur = index;
      },
      None => { }
    }
  }

  pub fn move_window_to(&mut self, ws: &XlibWindowSystem, config: &Config, index: uint) {
    let window = self.list[self.cur].get_focused_window();
    if window == 0 {
      return;
    }

    ws.unmap_window(window);
    self.remove_window(ws, config, window);
    self.list[index].add_window(ws, config, window);
  }

  pub fn move_window_to_screen(&mut self, ws: &XlibWindowSystem, config: &Config, screen: uint) {
    match self.list.iter().enumerate().find(|&(_,ws)| ws.screen == screen) {
      Some((index,_)) => {
        self.move_window_to(ws, config, index);
      },
      None => {}
    }
  }

  pub fn remove_window(&mut self, ws: &XlibWindowSystem, config: &Config, window: Window) {
    for workspace in self.list.iter_mut() {
      if workspace.remove_window(ws, config, window) {
        return;
      }
    }
  }

  pub fn rescreen(&mut self, ws: &XlibWindowSystem, config: &Config) {
    let new_screens = ws.get_screen_infos().len();

    // move and hide workspaces if their screens got removed
    for workspace in self.list.iter_mut().filter(|ws| ws.screen >= new_screens) {
      workspace.screen = 0;
      workspace.hide(ws);
    }

    // assign the first hidden workspace to the new screen
    let prev_screens = self.list.iter().fold(0, |acc, x| cmp::max(acc, x.screen));
    for screen in range(prev_screens, new_screens) {
      match self.list.iter_mut().find(|ws| !ws.visible) {
        Some(workspace) => {
          workspace.screen = screen;
          workspace.show(ws, config);
        },
        None => {
          break;
        }
      }
    }
  }

  pub fn contains(&self, window: Window) -> bool {
    self.list.iter().any(|ws| ws.contains(window))
  }

  fn switch_screens(&mut self, dest: uint) {
    let screen = self.list[self.cur].screen;
    self.list[self.cur].screen = self.list[dest].screen;
    self.list[dest].screen = screen;
  }
}<commit_msg>fixed focus behavior<commit_after>use config::Config;
use layout::{Layout, LayoutBox};
use xlib::Window;
use xlib_window_system::XlibWindowSystem;
use self::MoveOp::*;
use std::cmp;

pub struct WorkspaceConfig {
  pub tag: String,
  pub screen: uint,
  pub layout: LayoutBox
}

pub struct Workspace {
  managed: Vec<Window>,
  unmanaged: Vec<Window>,
  focused_window: Window,
  tag: String,
  screen: uint,
  visible: bool,
  layout: Box<Layout + 'static>
}

pub enum MoveOp {
  Up,
  Down,
  Swap
}

impl Workspace {
  pub fn add_window(&mut self, ws: &XlibWindowSystem, config: &Config, window: Window) {
    if !ws.is_transient_for(window) {
      self.managed.push(window);
    } else {
      self.unmanaged.push(window);
    }

    if self.visible {
      ws.map_window(window);
      self.redraw(ws, config);
    }
  }

  fn is_managed(&self, window: Window) -> bool {
    self.managed.iter().any(|&x| x == window)
  }

  fn is_unmanaged(&self, window: Window) -> bool {
    self.unmanaged.iter().any(|&x| x == window)
  }

  fn get_managed(&self, window: Window) -> uint {
    self.managed.iter().enumerate().filter(|&(_,&w)| w == window).map(|(i,_)| i).last().unwrap()
  }

  fn get_unmanaged(&self, window: Window) -> uint {
    self.unmanaged.iter().enumerate().filter(|&(_,&w)| w == window).map(|(i,_)| i).last().unwrap()
  }

  fn remove_managed(&mut self, ws: &XlibWindowSystem, config: &Config, window: Window) {
    let index = self.get_managed(window);

    self.focused_window = 0;
    ws.unmap_window(window);
    self.managed.remove(index);

    let new_focused_window = if !self.managed.is_empty() {
      self.managed[if index < self.managed.len() { index } else { index - 1}]
    } else {
      0
    };

    if self.visible {
      self.redraw(ws, config);
      self.focus_window(ws, config, new_focused_window);
    }
  }

  fn remove_unmanaged(&mut self, ws: &XlibWindowSystem, config: &Config, window: Window) {
    let index = self.get_unmanaged(window);

    self.focused_window = 0;
    ws.unmap_window(window);
    self.unmanaged.remove(index);

    let new_focused_window = if !self.unmanaged.is_empty() {
      self.unmanaged[if index < self.unmanaged.len() { index } else { index - 1}]
    } else {
      0
    };

    if self.visible {
      self.redraw(ws, config);
      self.focus_window(ws, config, new_focused_window);
    }
  }

  pub fn remove_window(&mut self, ws: &XlibWindowSystem, config: &Config, window: Window) -> bool {
    if self.is_managed(window) {
      self.remove_managed(ws, config, window);
    } else {
      if self.is_unmanaged(window) {
        self.remove_unmanaged(ws, config, window);
      } else {
        return false;
      }
    }

    return true;
  }

  pub fn focus_window(&mut self, ws: &XlibWindowSystem, config: &Config, window: Window) {
    if window == 0 {
      return;
    }

    self.unfocus_window(ws, config);
    self.focused_window = window;
    ws.focus_window(window, config.border_focus_color);
  }

  pub fn unfocus_window(&mut self, ws: &XlibWindowSystem, config: &Config) {
    if self.focused_window != 0 {
      ws.set_window_border_color(self.focused_window, config.border_color);
      self.focused_window = 0;
    }
  }

  pub fn move_focus(&mut self, ws: &XlibWindowSystem, config: &Config, op: MoveOp) {
    if self.focused_window == 0 || self.managed.len() < 2 {
      return;
    }

    let index = self.index_of(self.focused_window).unwrap();
    let new_focused_window = match op {
      Up => {
        if index == 0 {
          self.managed[self.managed.len() - 1]
        } else {
          self.managed[index - 1]
        }
      },
      Down => {
        self.managed[(index + 1) % self.managed.len()]
      },
      Swap => {
        self.managed[0]
      }
    };

    self.focus_window(ws, config, new_focused_window);
  }

  pub fn move_window(&mut self, ws: &XlibWindowSystem, config: &Config, op: MoveOp) {
    if self.focused_window == 0 || self.managed.len() < 2 {
      return;
    }

    let pos = self.index_of(self.focused_window).unwrap();
    let new_pos = match op {
      Up => {
        if pos == 0 {
          self.managed.len() - 1
        } else {
          pos - 1
        }
      },
      Down => {
        (pos + 1) % self.managed.len()
      },
      Swap => {
        let master = self.managed[0];
        self.managed.insert(pos, master);
        self.managed.remove(0);
        0
      }
    };

    self.managed.remove(pos);
    self.managed.insert(new_pos, self.focused_window);

    self.redraw(ws, config);
  }

  pub fn index_of(&self, window: Window) -> Option<uint> {
    self.managed.iter().enumerate().filter(|&(_,&w)| w == window).map(|(i,_)| i).last()
  }

  pub fn contains(&self, window: Window) -> bool {
    self.managed.iter().chain(self.unmanaged.iter()).any(|&w| w == window)
  }

  pub fn get_focused_window(&self) -> Window {
    self.focused_window
  }

  pub fn unfocus(&mut self, ws: &XlibWindowSystem, config: &Config) {
    ws.set_window_border_color(self.focused_window, config.border_color);
  }

  pub fn focus(&self, ws: &XlibWindowSystem, config: &Config) {
    if self.focused_window != 0 {
      ws.focus_window(self.focused_window, config.border_focus_color);
    }
  }

  pub fn hide(&mut self, ws: &XlibWindowSystem) {
    self.visible = false;

    for &w in self.managed.iter() {
      ws.unmap_window(w);
    }

    for &w in self.unmanaged.iter() {
      ws.unmap_window(w);
    }
  }

  pub fn show(&mut self, ws: &XlibWindowSystem, config: &Config) {
    self.visible = true;

    self.redraw(ws, config);
    for &w in self.managed.iter() {
      ws.map_window(w);
    }

    for &w in self.unmanaged.iter() {
      ws.map_window(w);
    }
  }

  pub fn redraw(&self, ws: &XlibWindowSystem, config: &Config) {
    for (i,rect) in self.layout.apply(ws.get_screen_infos()[self.screen], &self.managed).iter().enumerate() {
      ws.setup_window(rect.x, rect.y, rect.width, rect.height, config.border_width, config.border_color, self.managed[i]);
    }
    self.focus(ws, config);
  }
}

pub struct Workspaces {
  list: Vec<Workspace>,
  cur: uint
}

impl Workspaces {
  pub fn new(config: &mut Config, screens: uint) -> Workspaces{
    let mut workspaces = Workspaces{
      list: config.workspaces.iter_mut().map(|c| {
        Workspace {
          managed: Vec::new(),
          unmanaged: Vec::new(),
          focused_window: 0,
          tag: c.tag.clone(),
          screen: c.screen,
          visible: false,
          layout: (c.layout)()
        }
      }).collect(),
      cur: 0,
    };

    for screen in range(0u, screens) {
      if workspaces.list.iter().find(|ws| ws.screen == screen).is_none() {
        match workspaces.list.iter_mut().filter(|ws| ws.screen == 0).nth(1) {
          Some(ws) => {
            ws.screen = screen;
          },
          None => {}
        }
      }
    }

    for screen in range(0u, screens) {
      let ws = workspaces.list.iter_mut().find(|ws| ws.screen == screen).unwrap();
      ws.visible = true;
    }

    workspaces
  }

  pub fn get(&mut self, index: uint) -> &mut Workspace {
    if index < self.list.len() {
      self.list.get_mut(index).unwrap()
    } else {
      self.current()
    }
  }

  pub fn current(&mut self) -> &mut Workspace {
    self.list.get_mut(self.cur).unwrap()
  }

  pub fn switch_to(&mut self, ws: &XlibWindowSystem, config: &Config, index: uint) {
    if self.cur != index && index < self.list.len() {
      if self.list[index].visible {
        self.switch_screens(index);
        self.list[self.cur].redraw(ws, config);
        self.list[self.cur].unfocus(ws, config);
      } else {
        self.list[self.cur].hide(ws);
      }

      self.list[index].show(ws, config);
      self.list[index].focus(ws, config);
      self.cur = index;
    }
  }

  pub fn switch_to_screen(&mut self, ws: &XlibWindowSystem, config: &Config, screen: uint) {
    match self.list.iter().enumerate().filter(|&(_,ws)| ws.screen == screen && ws.visible).map(|(i,_)| i).last() {
      Some(index) => {
        self.list[self.cur].unfocus(ws, config);
        self.list[index].focus(ws, config);
        self.cur = index;
      },
      None => { }
    }
  }

  pub fn move_window_to(&mut self, ws: &XlibWindowSystem, config: &Config, index: uint) {
    let window = self.list[self.cur].get_focused_window();
    if window == 0 {
      return;
    }

    ws.unmap_window(window);
    self.remove_window(ws, config, window);
    self.list[index].add_window(ws, config, window);
    self.list[index].unfocus(ws, config);
  }

  pub fn move_window_to_screen(&mut self, ws: &XlibWindowSystem, config: &Config, screen: uint) {
    match self.list.iter().enumerate().find(|&(_,ws)| ws.screen == screen) {
      Some((index,_)) => {
        self.move_window_to(ws, config, index);
      },
      None => {}
    }
  }

  pub fn remove_window(&mut self, ws: &XlibWindowSystem, config: &Config, window: Window) {
    for workspace in self.list.iter_mut() {
      if workspace.remove_window(ws, config, window) {
        return;
      }
    }
  }

  pub fn rescreen(&mut self, ws: &XlibWindowSystem, config: &Config) {
    let new_screens = ws.get_screen_infos().len();

    // move and hide workspaces if their screens got removed
    for workspace in self.list.iter_mut().filter(|ws| ws.screen >= new_screens) {
      workspace.screen = 0;
      workspace.hide(ws);
    }

    // assign the first hidden workspace to the new screen
    let prev_screens = self.list.iter().fold(0, |acc, x| cmp::max(acc, x.screen));
    for screen in range(prev_screens, new_screens) {
      match self.list.iter_mut().find(|ws| !ws.visible) {
        Some(workspace) => {
          workspace.screen = screen;
          workspace.show(ws, config);
        },
        None => {
          break;
        }
      }
    }
  }

  pub fn contains(&self, window: Window) -> bool {
    self.list.iter().any(|ws| ws.contains(window))
  }

  fn switch_screens(&mut self, dest: uint) {
    let screen = self.list[self.cur].screen;
    self.list[self.cur].screen = self.list[dest].screen;
    self.list[dest].screen = screen;
  }
}<|endoftext|>


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

use gfx_core::{Resources, TextureSlot, draw, tex};

struct Entry<R: Resources> {
    last_used: u16,
    bound: Option<(tex::Kind, R::Texture, Option<(R::Sampler, tex::SamplerInfo)>)>,
}

pub struct TextureCache<R: Resources> {
    count: u16,
    textures: Vec<Entry<R>>
}

fn age(now: u16, age: u16) -> u16 {
    use std::num::Wrapping;
    (Wrapping(now) - Wrapping(age)).0
}

impl<R> TextureCache<R> where R: Resources {
    /// Create a TextureCache with `x` slots
    pub fn new(slots: usize) -> TextureCache<R> {
        return TextureCache{
            count: 0,
            textures: (0..slots).map(|_| Entry {
                last_used: 0,
                bound: None
            }).collect()
        }
    }

    /// Returns the number of slots, If a draw call needs
    /// to bind more then this number of slots it will cause
    /// undefined behavior.
    pub fn number_of_slots(&self) -> usize {
        self.textures.len()
    }

    /// Bind a texture, this will look up the texture to see if
    /// it has been bound to a slot, if it has it will return that
    /// slot rather then sending a bind command, iff not it will
    /// release a free slot and bind the texture to it. If there is
    /// no free slots, and there is no bound texture we will throw
    /// away the oldest entries first to make room for the new ones
    pub fn bind_texture<C>(&mut self,
                           kind: tex::Kind,
                           tex: R::Texture,
                           samp: Option<(R::Sampler, tex::SamplerInfo)>,
                           cb: &mut C) -> TextureSlot
        where C: draw::CommandBuffer<R>
    {
        self.count += 1;
        let count = self.count;

        let bind = (kind, tex, samp);
        for (i, ent) in self.textures.iter_mut().enumerate() {
            if let Some(ref bound) = ent.bound {
                if bound.0 == bind.0 && bound.1 == bind.1 && bound.2 == bind.2 {
                    // Update the LRU with the current count
                    ent.last_used = count;
                    return i as TextureSlot;
                }
            }
        }

        // No texture was found that was bound to the texture slot
        let mut oldest = 0;
        for i in 0..self.textures.len() {
            if self.textures[i].bound.is_none() {
                oldest = i;
                break;
            }
            if age(count, self.textures[i].last_used) > age(count, self.textures[oldest].last_used) {
                oldest = i;
            }
        }

        cb.bind_texture(oldest as TextureSlot, bind.0, bind.1.clone(), bind.2.clone());

        self.textures[oldest].last_used = count;
        self.textures[oldest].bound = Some(bind);
        return oldest as TextureSlot;
    }

    /// Clear the texture cache
    pub fn clear(&mut self) {
        self.count = 0;
        for ent in self.textures.iter_mut() {
            ent.last_used = 0;
            ent.bound = None;
        }
    }
}

#[test]
fn test_age() {
    assert_eq!(age(100, 0), 100);
    assert_eq!(age(0, 0), 0);
    assert_eq!(age(0, 0xFFFF), 1);
    assert_eq!(age(0, 0xFFFE), 2);
}
<commit_msg>Removed the texture cache<commit_after><|endoftext|>


<commit_before>use std::result::Result;

use super::script::*;

///
/// Represents a parse error
///
pub struct ParseError {

}

///
/// Tool that parses our scripting language
///
pub struct ParseScriptTool {
}

impl ParseError {
    pub fn new() -> ParseError {
        ParseError { }
    }
}

///
/// Returns true if a token is considered syntax (gets returned from lookahead)
///
fn is_syntax(token: &ScriptToken) -> bool {
    match token.token {
        ScriptLexerToken::Whitespace    |
        ScriptLexerToken::Comment       => false,

        _                               => true
    }
}

///
/// Looks ahead to the next syntactically relevant lexer match (and returns the tokens after it)
///
fn lookahead<'a>(input: &'a [ScriptToken]) -> Option<(&'a ScriptToken, &'a [ScriptToken])> {
    let mut index   = 0;
    let len         = input.len();

    loop {
        if index >= len {
            return None;
        } else if is_syntax(&input[index]) {
            return Some((&input[index], &input[index+1..len]));
        }

        index += 1;
    }
}

///
/// Parses a statement
///
pub fn parse_statement<'a>(input: &'a [ScriptToken]) -> Result<(Script, &'a [ScriptToken]), ParseError> {
    if let Some((lookahead, remainder)) = lookahead(input) {
        match lookahead.token {
            // Newlines are ignored
            ScriptLexerToken::Newline       => parse_statement(remainder),

            ScriptLexerToken::Let           => parse_let(remainder),
            ScriptLexerToken::Var           => parse_var(remainder),
            ScriptLexerToken::Def           => parse_def(remainder),
            ScriptLexerToken::If            => parse_if(remainder),
            ScriptLexerToken::Using         => parse_using(remainder),
            ScriptLexerToken::While         => parse_while(remainder),
            ScriptLexerToken::Loop          => parse_loop(remainder),
            ScriptLexerToken::For           => parse_for(remainder),

            ScriptLexerToken::Identifier    => parse_command(input),

            // Unrecognised token
            _ => Err(ParseError::new())
        }
    } else {
        // EOF
        Err(ParseError::new())
    }
}

///
/// Parses a command
///
/// Syntax '<expression>', '<expression> <expression>'
///
pub fn parse_command<'a>(input: &'a [ScriptToken]) -> Result<(Script, &'a [ScriptToken]), ParseError> {
    unimplemented!();
}

pub fn parse_let<'a>(input: &'a [ScriptToken]) -> Result<(Script, &'a [ScriptToken]), ParseError> {
    unimplemented!()
}

pub fn parse_var<'a>(input: &'a [ScriptToken]) -> Result<(Script, &'a [ScriptToken]), ParseError> {
    unimplemented!()
}

pub fn parse_def<'a>(input: &'a [ScriptToken]) -> Result<(Script, &'a [ScriptToken]), ParseError> {
    unimplemented!()
}

pub fn parse_if<'a>(input: &'a [ScriptToken]) -> Result<(Script, &'a [ScriptToken]), ParseError> {
    unimplemented!()
}

pub fn parse_using<'a>(input: &'a [ScriptToken]) -> Result<(Script, &'a [ScriptToken]), ParseError> {
    unimplemented!()
}

pub fn parse_while<'a>(input: &'a [ScriptToken]) -> Result<(Script, &'a [ScriptToken]), ParseError> {
    unimplemented!()
}

pub fn parse_loop<'a>(input: &'a [ScriptToken]) -> Result<(Script, &'a [ScriptToken]), ParseError> {
    unimplemented!()
}

pub fn parse_for<'a>(input: &'a [ScriptToken]) -> Result<(Script, &'a [ScriptToken]), ParseError> {
    unimplemented!()
}

impl ParseScriptTool {
    ///
    /// Creates a new script parsing tool
    ///
    pub fn new() -> ParseScriptTool {
        ParseScriptTool { }
    }
}<commit_msg>Start work on expressions<commit_after>use std::result::Result;

use super::script::*;

///
/// Represents a parse error
///
pub struct ParseError {

}

///
/// Tool that parses our scripting language
///
pub struct ParseScriptTool {
}

impl ParseError {
    pub fn new() -> ParseError {
        ParseError { }
    }
}

///
/// Returns true if a token is considered syntax (gets returned from lookahead)
///
fn is_syntax(token: &ScriptToken) -> bool {
    match token.token {
        ScriptLexerToken::Whitespace    |
        ScriptLexerToken::Comment       => false,

        _                               => true
    }
}

///
/// Looks ahead to the next syntactically relevant lexer match (and returns the tokens after it)
///
fn lookahead<'a>(input: &'a [ScriptToken]) -> Option<(&'a ScriptToken, &'a [ScriptToken])> {
    let mut index   = 0;
    let len         = input.len();

    loop {
        if index >= len {
            return None;
        } else if is_syntax(&input[index]) {
            return Some((&input[index], &input[index+1..len]));
        }

        index += 1;
    }
}

///
/// Parses a statement
///
pub fn parse_statement<'a>(input: &'a [ScriptToken]) -> Result<(Script, &'a [ScriptToken]), ParseError> {
    if let Some((lookahead, remainder)) = lookahead(input) {
        match lookahead.token {
            // Newlines are ignored
            ScriptLexerToken::Newline       => parse_statement(remainder),

            ScriptLexerToken::Let           => parse_let(remainder),
            ScriptLexerToken::Var           => parse_var(remainder),
            ScriptLexerToken::Def           => parse_def(remainder),
            ScriptLexerToken::If            => parse_if(remainder),
            ScriptLexerToken::Using         => parse_using(remainder),
            ScriptLexerToken::While         => parse_while(remainder),
            ScriptLexerToken::Loop          => parse_loop(remainder),
            ScriptLexerToken::For           => parse_for(remainder),

            ScriptLexerToken::Identifier    => parse_command(input),

            // Unrecognised token
            _ => Err(ParseError::new())
        }
    } else {
        // EOF
        Err(ParseError::new())
    }
}

///
/// Parses a command
///
/// Syntax '<expression>', '<expression> <expression>'
///
pub fn parse_command<'a>(input: &'a [ScriptToken]) -> Result<(Script, &'a [ScriptToken]), ParseError> {
    unimplemented!();
}

///
/// Parses an Expression
///
pub fn parse_expression<'a>(input: &'a [ScriptToken]) -> Result<(Expression, &'a [ScriptToken]), ParseError> {
    if let Some((lookahead, remainder)) = lookahead(input) {
        let expr1 = match lookahead.token {
            ScriptLexerToken::Identifier    => Ok((Expression::Identifier(lookahead.clone()), remainder)),
            ScriptLexerToken::Number        |
            ScriptLexerToken::HexNumber     => Ok((Expression::Number(lookahead.clone()), remainder)),
            ScriptLexerToken::String        => Ok((Expression::String(lookahead.clone()), remainder)),

            _ => Err(ParseError::new())
        };

        expr1
    } else {
        // EOF
        Err(ParseError::new())
    }
}

pub fn parse_let<'a>(input: &'a [ScriptToken]) -> Result<(Script, &'a [ScriptToken]), ParseError> {
    unimplemented!()
}

pub fn parse_var<'a>(input: &'a [ScriptToken]) -> Result<(Script, &'a [ScriptToken]), ParseError> {
    unimplemented!()
}

pub fn parse_def<'a>(input: &'a [ScriptToken]) -> Result<(Script, &'a [ScriptToken]), ParseError> {
    unimplemented!()
}

pub fn parse_if<'a>(input: &'a [ScriptToken]) -> Result<(Script, &'a [ScriptToken]), ParseError> {
    unimplemented!()
}

pub fn parse_using<'a>(input: &'a [ScriptToken]) -> Result<(Script, &'a [ScriptToken]), ParseError> {
    unimplemented!()
}

pub fn parse_while<'a>(input: &'a [ScriptToken]) -> Result<(Script, &'a [ScriptToken]), ParseError> {
    unimplemented!()
}

pub fn parse_loop<'a>(input: &'a [ScriptToken]) -> Result<(Script, &'a [ScriptToken]), ParseError> {
    unimplemented!()
}

pub fn parse_for<'a>(input: &'a [ScriptToken]) -> Result<(Script, &'a [ScriptToken]), ParseError> {
    unimplemented!()
}

impl ParseScriptTool {
    ///
    /// Creates a new script parsing tool
    ///
    pub fn new() -> ParseScriptTool {
        ParseScriptTool { }
    }
}<|endoftext|>


<commit_before>// Copyright 2012-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.

use LinkerFlavor;
use target::{Target, TargetResult};

pub fn target() -> TargetResult {
    let mut base = super::linux_base::opts();
    base.cpu = "ppc64".to_string();
    base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m64".to_string());
    base.max_atomic_width = Some(64);

    // see #36994
    base.exe_allocation_crate = None;

    Ok(Target {
        llvm_target: "powerpc64-unknown-linux-gnu".to_string(),
        target_endian: "big".to_string(),
        target_pointer_width: "64".to_string(),
        data_layout: "E-m:e-i64:64-n32:64".to_string(),
        arch: "powerpc64".to_string(),
        target_os: "linux".to_string(),
        target_env: "gnu".to_string(),
        target_vendor: "unknown".to_string(),
        linker_flavor: LinkerFlavor::Gcc,
        options: base,
    })
}
<commit_msg>Make partial RELRO default on ppc64 due to segfault<commit_after>// Copyright 2012-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.

use LinkerFlavor;
use target::{Target, TargetResult, RelroLevel};

pub fn target() -> TargetResult {
    let mut base = super::linux_base::opts();
    base.cpu = "ppc64".to_string();
    base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m64".to_string());
    base.max_atomic_width = Some(64);

    // ld.so in at least RHEL6 on ppc64 has a bug related to BIND_NOW, so only enable partial RELRO
    // for now. https://github.com/rust-lang/rust/pull/43170#issuecomment-315411474
    base.relro_level = RelroLevel::Partial;

    // see #36994
    base.exe_allocation_crate = None;

    Ok(Target {
        llvm_target: "powerpc64-unknown-linux-gnu".to_string(),
        target_endian: "big".to_string(),
        target_pointer_width: "64".to_string(),
        data_layout: "E-m:e-i64:64-n32:64".to_string(),
        arch: "powerpc64".to_string(),
        target_os: "linux".to_string(),
        target_env: "gnu".to_string(),
        target_vendor: "unknown".to_string(),
        linker_flavor: LinkerFlavor::Gcc,
        options: base,
    })
}
<|endoftext|>


<commit_before>// Copyright (c) The Libra Core Contributors
// SPDX-License-Identifier: Apache-2.0

/// Builds the proto files needed for the network crate.
fn main() {
    let proto_files = [
        "src/proto/consensus.proto",
        "src/proto/network.proto",
        "src/proto/mempool.proto",
        "src/proto/state_synchronizer.proto",
        "src/proto/admission_control.proto",
    ];

    let proto_files_prost = ["src/proto/network.proto", "src/proto/mempool.proto"];

    let includes = ["../types/src/proto", "src/proto"];

    for file in &proto_files {
        println!("cargo:rerun-if-changed={}", file);
    }

    for file in &proto_files_prost {
        println!("cargo:rerun-if-changed={}", file);
    }

    protoc_rust::run(protoc_rust::Args {
        out_dir: "src/proto",
        input: &proto_files,
        includes: &includes,
        customize: protoc_rust::Customize {
            carllerche_bytes_for_bytes: Some(true),
            carllerche_bytes_for_string: Some(true),
            ..Default::default()
        },
    })
    .expect("protoc");

    prost_build::compile_protos(&proto_files_prost, &includes).unwrap();
}
<commit_msg>[network] stop generating mempool protos with rust-protobuf<commit_after>// Copyright (c) The Libra Core Contributors
// SPDX-License-Identifier: Apache-2.0

/// Builds the proto files needed for the network crate.
fn main() {
    let proto_files = [
        "src/proto/consensus.proto",
        "src/proto/network.proto",
        "src/proto/state_synchronizer.proto",
        "src/proto/admission_control.proto",
    ];

    let proto_files_prost = ["src/proto/network.proto", "src/proto/mempool.proto"];

    let includes = ["../types/src/proto", "src/proto"];

    for file in &proto_files {
        println!("cargo:rerun-if-changed={}", file);
    }

    for file in &proto_files_prost {
        println!("cargo:rerun-if-changed={}", file);
    }

    protoc_rust::run(protoc_rust::Args {
        out_dir: "src/proto",
        input: &proto_files,
        includes: &includes,
        customize: protoc_rust::Customize {
            carllerche_bytes_for_bytes: Some(true),
            carllerche_bytes_for_string: Some(true),
            ..Default::default()
        },
    })
    .expect("protoc");

    prost_build::compile_protos(&proto_files_prost, &includes).unwrap();
}
<|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 http://mozilla.org/MPL/2.0/. */

#![feature(borrow_state)]
#![feature(box_raw)]
#![feature(box_syntax)]
#![feature(convert)]
#![feature(core_intrinsics)]
#![feature(filling_drop)]
#![feature(iter_arith)]
#![feature(link_args)]
#![feature(plugin)]
#![feature(str_utf16)]
#![feature(unicode)]
#![feature(unsafe_no_drop_flag)]

#![allow(non_camel_case_types)]

#![plugin(plugins)]

#[macro_use]
extern crate log;

extern crate servo;
extern crate compositing;

extern crate azure;
extern crate euclid;
extern crate gfx;
extern crate gleam;
extern crate glutin_app;
extern crate js;
extern crate layers;
extern crate png;
extern crate rustc_unicode;
extern crate script;
extern crate script_traits;

extern crate net_traits;
extern crate msg;
extern crate util;
extern crate style;
extern crate stb_image;

extern crate libc;
extern crate url as std_url;

#[cfg(target_os="macos")]
#[link_args="-Xlinker -undefined -Xlinker dynamic_lookup"]
extern { }

#[cfg(target_os="macos")]
extern crate cgl;
#[cfg(target_os="macos")]
extern crate cocoa;
#[cfg(target_os="macos")]
extern crate core_foundation;
#[cfg(target_os="macos")]
extern crate core_graphics;
#[cfg(target_os="macos")]
extern crate core_text;
#[cfg(target_os="macos")]
#[macro_use]
extern crate objc;
#[cfg(target_os="linux")] extern crate x11;

// Must come first.
pub mod macros;

pub mod browser;
pub mod browser_host;
pub mod command_line;
pub mod cookie;
pub mod core;
pub mod drag_data;
pub mod eutil;
pub mod frame;
pub mod interfaces;
pub mod print_settings;
pub mod process_message;
pub mod render_handler;
pub mod request;
pub mod request_context;
pub mod response;
pub mod stream;
pub mod string;
pub mod string_list;
pub mod string_map;
pub mod string_multimap;
pub mod stubs;
pub mod switches;
pub mod task;
pub mod types;
pub mod urlrequest;
pub mod v8;
pub mod values;
pub mod window;
pub mod wrappers;
pub mod xml_reader;
pub mod zip_reader;
<commit_msg>Auto merge of #7728 - Ms2ger:box-raw, r=mbrubeck<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 http://mozilla.org/MPL/2.0/. */

#![feature(borrow_state)]
#![feature(box_syntax)]
#![feature(convert)]
#![feature(core_intrinsics)]
#![feature(filling_drop)]
#![feature(iter_arith)]
#![feature(link_args)]
#![feature(plugin)]
#![feature(str_utf16)]
#![feature(unicode)]
#![feature(unsafe_no_drop_flag)]

#![allow(non_camel_case_types)]

#![plugin(plugins)]

#[macro_use]
extern crate log;

extern crate servo;
extern crate compositing;

extern crate azure;
extern crate euclid;
extern crate gfx;
extern crate gleam;
extern crate glutin_app;
extern crate js;
extern crate layers;
extern crate png;
extern crate rustc_unicode;
extern crate script;
extern crate script_traits;

extern crate net_traits;
extern crate msg;
extern crate util;
extern crate style;
extern crate stb_image;

extern crate libc;
extern crate url as std_url;

#[cfg(target_os="macos")]
#[link_args="-Xlinker -undefined -Xlinker dynamic_lookup"]
extern { }

#[cfg(target_os="macos")]
extern crate cgl;
#[cfg(target_os="macos")]
extern crate cocoa;
#[cfg(target_os="macos")]
extern crate core_foundation;
#[cfg(target_os="macos")]
extern crate core_graphics;
#[cfg(target_os="macos")]
extern crate core_text;
#[cfg(target_os="macos")]
#[macro_use]
extern crate objc;
#[cfg(target_os="linux")] extern crate x11;

// Must come first.
pub mod macros;

pub mod browser;
pub mod browser_host;
pub mod command_line;
pub mod cookie;
pub mod core;
pub mod drag_data;
pub mod eutil;
pub mod frame;
pub mod interfaces;
pub mod print_settings;
pub mod process_message;
pub mod render_handler;
pub mod request;
pub mod request_context;
pub mod response;
pub mod stream;
pub mod string;
pub mod string_list;
pub mod string_map;
pub mod string_multimap;
pub mod stubs;
pub mod switches;
pub mod task;
pub mod types;
pub mod urlrequest;
pub mod v8;
pub mod values;
pub mod window;
pub mod wrappers;
pub mod xml_reader;
pub mod zip_reader;
<|endoftext|>


<commit_before>//! Implements a command for uploading react-native projects.
use std::env;
use std::fs;
use std::path::{Path, PathBuf};
use std::process;

use clap::{App, Arg, ArgMatches};
use walkdir::WalkDir;
use serde_json;

use prelude::*;
use api::{Api, NewRelease};
use config::Config;
use xcode::InfoPlist;
use utils::{TempFile, propagate_exit_status};
use sourcemaputils::SourceMapProcessor;

#[derive(Serialize, Deserialize, Default, Debug)]
struct SourceMapReport {
    bundle_path: Option<PathBuf>,
    sourcemap_path: Option<PathBuf>,
}

pub fn make_app<'a, 'b: 'a>(app: App<'a, 'b>) -> App<'a, 'b> {
    app.about("uploads react-native projects from within an xcode build step")
        .arg(Arg::with_name("org")
            .value_name("ORG")
            .long("org")
            .short("o")
            .help("The organization slug"))
        .arg(Arg::with_name("project")
            .value_name("PROJECT")
            .long("project")
            .short("p")
            .help("The project slug"))
        .arg(Arg::with_name("verbose")
            .long("verbose")
            .short("verbose")
            .help("Enable verbose mode"))
        .arg(Arg::with_name("force")
             .long("force")
             .short("f")
             .help("Forces the script to run, even in Debug configuration"))
        .arg(Arg::with_name("build_script")
             .value_name("BUILD_SCRIPT")
             .index(1)
             .help("Optional path to the build script{n}{n}\
                    This is the path to the react-native-xcode.sh script you want \
                    to use.  By default the bundled build script is used.")
}

fn load_info_plist<P: AsRef<Path>>(path: P) -> Result<InfoPlist> {
    let fpl_fn = Some("info.plist".to_string());
    for dent_res in WalkDir::new(path.as_ref()) {
        let dent = dent_res?;
        if dent.file_name().to_str().map(|x| x.to_lowercase()) == fpl_fn {
            let md = dent.metadata()?;
            if md.is_file() {
                return Ok(InfoPlist::from_path(dent.path())?);
            }
        }
    }
    Err("Could not find info.plist".into())
}

fn find_node() -> String {
    if let Ok(path) = env::var("NODE_BINARY") {
        if path.len() > 0 {
            return path;
        }
    }
    "node".into()
}

pub fn execute<'a>(matches: &ArgMatches<'a>, config: &Config) -> Result<()> {
    let (org, project) = config.get_org_and_project(matches)?;
    let api = Api::new(config);
    let should_wrap = matches.is_present("force") || match env::var("CONFIGURATION") {
        Ok(config) => &config != "Debug",
        Err(_) => { return Err("Need to run this from Xcode".into()); }
    };
    let base = env::current_dir()?;
    let script = if let Some(path) = matches.value_of("build_script") {
        base.join(path)
    } else {
        base.join("../node_modules/react-native/packager/react-native-xcode.sh")
    }.canonicalize()?;

    info!("Using react-native build script at {}", base.display());

    // in case we are in debug mode we directly dispatch to the script
    // and exit out early.
    if !should_wrap {
        info!("Running in debug mode, skipping script wrapping.");
        let rv = process::Command::new(&script).spawn()?.wait()?;
        propagate_exit_status(rv);
        return Ok(());
    }

    info!("Parsing Info.plist");
    let plist = load_info_plist(&base)?;
    info!("Parse result from Info.plist: {:?}", &plist);
    let report_file = TempFile::new()?;
    let node = find_node();
    info!("Using node interpreter '{}'", &node);

    // this invokes via an indirection of sentry-cli our wrap_call() below.
    // What is happening behind the scenes is that we switch out NODE_BINARY
    // for ourselves which is what the react-native build script normally
    // invokes.  Because we export __SENTRY_RN_WRAP_XCODE_CALL=1, the main
    // sentry-cli script will invoke our wrap_call() function below.
    //
    // That will then attempt to figure out that a react-native bundle is
    // happening to the build script, parse out the arguments, add additional
    // arguments if needed and then report the parsed arguments to a temporary
    // JSON file we load back below.
    //
    // With that we we then have all the information we need to invoke the
    // upload process.
    let rv = process::Command::new(&script)
        .env("NODE_BINARY", env::current_exe()?.to_str().unwrap())
        .env("SENTRY_RN_REAL_NODE_BINARY", &node)
        .env("SENTRY_RN_SOURCEMAP_REPORT", report_file.path().to_str().unwrap())
        .env("__SENTRY_RN_WRAP_XCODE_CALL", "1")
        .spawn()?
        .wait()?;
    propagate_exit_status(rv);

    let mut f = fs::File::open(report_file.path())?;
    let report : SourceMapReport = serde_json::from_reader(&mut f)?;

    // if the report is complete, we can now upload sourcemaps
    if report.bundle_path.is_some() && report.sourcemap_path.is_some() {
        println!("Processing react-native sourcemaps for Sentry upload.");
        let bundle_path = report.bundle_path.unwrap();
        info!("  bundle path: {}", bundle_path.display());
        let sourcemap_path = report.sourcemap_path.unwrap();
        info!("  sourcemap path: {}", sourcemap_path.display());

        let mut processor = SourceMapProcessor::new(matches.is_present("verbose"));
        processor.add(&format!("~/{}", bundle_path.file_name()
                               .unwrap().to_string_lossy()), &bundle_path)?;
        processor.add(&format!("~/{}", sourcemap_path.file_name()
                               .unwrap().to_string_lossy()), &sourcemap_path)?;
        processor.rewrite(&vec![base.parent().unwrap().to_str().unwrap()])?;
        processor.add_sourcemap_references()?;

        let release = api.new_release(&org, &project, &NewRelease {
            version: plist.release_name(),
            ..Default::default()
        })?;
        println!("Uploading sourcemaps for release {}", release.version);
        processor.upload(&api, &org, &project, &release.version)?;
    }

    Ok(())
}

pub fn wrap_call() -> Result<()> {
    let mut args : Vec<_> = env::args().skip(1).collect();
    let mut bundle_path = None;
    let mut sourcemap_path = None;

    if args.len() > 1 && args[1] == "bundle" {
        let mut iter = args.iter().fuse();
        while let Some(item) = iter.next() {
            if item == "--sourcemap-output" {
                sourcemap_path = iter.next().map(|x| x.to_string());
            } else if item.starts_with("--sourcemap-output=") {
                sourcemap_path = Some(item[19..].to_string());
            } else if item == "--bundle-output" {
                bundle_path = iter.next().map(|x| x.to_string());
            } else if item.starts_with("--bundle-output=") {
                bundle_path = Some(item[16..].to_string());
            }
        }
    }

    let mut sourcemap_report = SourceMapReport::default();

    if sourcemap_path.is_none() && bundle_path.is_some() {
        let path = format!("{}.map", &bundle_path.as_ref().unwrap());
        sourcemap_report.sourcemap_path = Some(PathBuf::from(&path));
        args.push("--sourcemap-output".into());
        args.push(path);
    } else if let Some(path) = sourcemap_path {
        sourcemap_report.sourcemap_path = Some(PathBuf::from(path));
    }

    sourcemap_report.bundle_path = bundle_path.map(|x| PathBuf::from(x));

    let rv = process::Command::new(env::var("SENTRY_RN_REAL_NODE_BINARY").unwrap())
        .args(&args)
        .spawn()?
        .wait()?;
    propagate_exit_status(rv);

    let mut f = fs::File::create(env::var("SENTRY_RN_SOURCEMAP_REPORT").unwrap())?;
    serde_json::to_writer(&mut f, &sourcemap_report)?;

    Ok(())
}
<commit_msg>Fixed syntax error<commit_after>//! Implements a command for uploading react-native projects.
use std::env;
use std::fs;
use std::path::{Path, PathBuf};
use std::process;

use clap::{App, Arg, ArgMatches};
use walkdir::WalkDir;
use serde_json;

use prelude::*;
use api::{Api, NewRelease};
use config::Config;
use xcode::InfoPlist;
use utils::{TempFile, propagate_exit_status};
use sourcemaputils::SourceMapProcessor;

#[derive(Serialize, Deserialize, Default, Debug)]
struct SourceMapReport {
    bundle_path: Option<PathBuf>,
    sourcemap_path: Option<PathBuf>,
}

pub fn make_app<'a, 'b: 'a>(app: App<'a, 'b>) -> App<'a, 'b> {
    app.about("uploads react-native projects from within an xcode build step")
        .arg(Arg::with_name("org")
            .value_name("ORG")
            .long("org")
            .short("o")
            .help("The organization slug"))
        .arg(Arg::with_name("project")
            .value_name("PROJECT")
            .long("project")
            .short("p")
            .help("The project slug"))
        .arg(Arg::with_name("verbose")
            .long("verbose")
            .short("verbose")
            .help("Enable verbose mode"))
        .arg(Arg::with_name("force")
             .long("force")
             .short("f")
             .help("Forces the script to run, even in Debug configuration"))
        .arg(Arg::with_name("build_script")
             .value_name("BUILD_SCRIPT")
             .index(1)
             .help("Optional path to the build script{n}{n}\
                    This is the path to the react-native-xcode.sh script you want \
                    to use.  By default the bundled build script is used."))
}

fn load_info_plist<P: AsRef<Path>>(path: P) -> Result<InfoPlist> {
    let fpl_fn = Some("info.plist".to_string());
    for dent_res in WalkDir::new(path.as_ref()) {
        let dent = dent_res?;
        if dent.file_name().to_str().map(|x| x.to_lowercase()) == fpl_fn {
            let md = dent.metadata()?;
            if md.is_file() {
                return Ok(InfoPlist::from_path(dent.path())?);
            }
        }
    }
    Err("Could not find info.plist".into())
}

fn find_node() -> String {
    if let Ok(path) = env::var("NODE_BINARY") {
        if path.len() > 0 {
            return path;
        }
    }
    "node".into()
}

pub fn execute<'a>(matches: &ArgMatches<'a>, config: &Config) -> Result<()> {
    let (org, project) = config.get_org_and_project(matches)?;
    let api = Api::new(config);
    let should_wrap = matches.is_present("force") || match env::var("CONFIGURATION") {
        Ok(config) => &config != "Debug",
        Err(_) => { return Err("Need to run this from Xcode".into()); }
    };
    let base = env::current_dir()?;
    let script = if let Some(path) = matches.value_of("build_script") {
        base.join(path)
    } else {
        base.join("../node_modules/react-native/packager/react-native-xcode.sh")
    }.canonicalize()?;

    info!("Using react-native build script at {}", base.display());

    // in case we are in debug mode we directly dispatch to the script
    // and exit out early.
    if !should_wrap {
        info!("Running in debug mode, skipping script wrapping.");
        let rv = process::Command::new(&script).spawn()?.wait()?;
        propagate_exit_status(rv);
        return Ok(());
    }

    info!("Parsing Info.plist");
    let plist = load_info_plist(&base)?;
    info!("Parse result from Info.plist: {:?}", &plist);
    let report_file = TempFile::new()?;
    let node = find_node();
    info!("Using node interpreter '{}'", &node);

    // this invokes via an indirection of sentry-cli our wrap_call() below.
    // What is happening behind the scenes is that we switch out NODE_BINARY
    // for ourselves which is what the react-native build script normally
    // invokes.  Because we export __SENTRY_RN_WRAP_XCODE_CALL=1, the main
    // sentry-cli script will invoke our wrap_call() function below.
    //
    // That will then attempt to figure out that a react-native bundle is
    // happening to the build script, parse out the arguments, add additional
    // arguments if needed and then report the parsed arguments to a temporary
    // JSON file we load back below.
    //
    // With that we we then have all the information we need to invoke the
    // upload process.
    let rv = process::Command::new(&script)
        .env("NODE_BINARY", env::current_exe()?.to_str().unwrap())
        .env("SENTRY_RN_REAL_NODE_BINARY", &node)
        .env("SENTRY_RN_SOURCEMAP_REPORT", report_file.path().to_str().unwrap())
        .env("__SENTRY_RN_WRAP_XCODE_CALL", "1")
        .spawn()?
        .wait()?;
    propagate_exit_status(rv);

    let mut f = fs::File::open(report_file.path())?;
    let report : SourceMapReport = serde_json::from_reader(&mut f)?;

    // if the report is complete, we can now upload sourcemaps
    if report.bundle_path.is_some() && report.sourcemap_path.is_some() {
        println!("Processing react-native sourcemaps for Sentry upload.");
        let bundle_path = report.bundle_path.unwrap();
        info!("  bundle path: {}", bundle_path.display());
        let sourcemap_path = report.sourcemap_path.unwrap();
        info!("  sourcemap path: {}", sourcemap_path.display());

        let mut processor = SourceMapProcessor::new(matches.is_present("verbose"));
        processor.add(&format!("~/{}", bundle_path.file_name()
                               .unwrap().to_string_lossy()), &bundle_path)?;
        processor.add(&format!("~/{}", sourcemap_path.file_name()
                               .unwrap().to_string_lossy()), &sourcemap_path)?;
        processor.rewrite(&vec![base.parent().unwrap().to_str().unwrap()])?;
        processor.add_sourcemap_references()?;

        let release = api.new_release(&org, &project, &NewRelease {
            version: plist.release_name(),
            ..Default::default()
        })?;
        println!("Uploading sourcemaps for release {}", release.version);
        processor.upload(&api, &org, &project, &release.version)?;
    }

    Ok(())
}

pub fn wrap_call() -> Result<()> {
    let mut args : Vec<_> = env::args().skip(1).collect();
    let mut bundle_path = None;
    let mut sourcemap_path = None;

    if args.len() > 1 && args[1] == "bundle" {
        let mut iter = args.iter().fuse();
        while let Some(item) = iter.next() {
            if item == "--sourcemap-output" {
                sourcemap_path = iter.next().map(|x| x.to_string());
            } else if item.starts_with("--sourcemap-output=") {
                sourcemap_path = Some(item[19..].to_string());
            } else if item == "--bundle-output" {
                bundle_path = iter.next().map(|x| x.to_string());
            } else if item.starts_with("--bundle-output=") {
                bundle_path = Some(item[16..].to_string());
            }
        }
    }

    let mut sourcemap_report = SourceMapReport::default();

    if sourcemap_path.is_none() && bundle_path.is_some() {
        let path = format!("{}.map", &bundle_path.as_ref().unwrap());
        sourcemap_report.sourcemap_path = Some(PathBuf::from(&path));
        args.push("--sourcemap-output".into());
        args.push(path);
    } else if let Some(path) = sourcemap_path {
        sourcemap_report.sourcemap_path = Some(PathBuf::from(path));
    }

    sourcemap_report.bundle_path = bundle_path.map(|x| PathBuf::from(x));

    let rv = process::Command::new(env::var("SENTRY_RN_REAL_NODE_BINARY").unwrap())
        .args(&args)
        .spawn()?
        .wait()?;
    propagate_exit_status(rv);

    let mut f = fs::File::create(env::var("SENTRY_RN_SOURCEMAP_REPORT").unwrap())?;
    serde_json::to_writer(&mut f, &sourcemap_report)?;

    Ok(())
}
<|endoftext|>


<commit_before>use std::io;
use std::cell::RefCell;
use std::rc::Rc;

use Error;

use anymap::AnyMap;
use futures::Future;
use core::net::TcpStream;
use core::reactor::Handle;
use proto::BindClient;
use tokio::{Service, NewService};
use c3po::{ConnFuture, Conn, Pool, Config};

use connections::{Client, ClientConnector, Configure};

#[derive(Clone)]
pub struct Environment {
    pools: Rc<AnyMap>,
}

impl Environment {
    pub fn conn<C: NewService>(&self) -> ConnFuture<Conn<C>, Error> {
        if let Some(pool) = self.pools.get::<Pool<C>>() {
            pool.connection()
        } else {
            panic!()
        }
    }

    pub fn client<C, K>(&self) -> ConnFuture<Conn<ClientConnector<C, K>>, Error>
    where
        C: Client,
        C::Protocol: BindClient<K, TcpStream, BindClient = C::Connection>,
        C::Connection: Service<Request  = <C::Protocol as BindClient<K, TcpStream>>::ServiceRequest,
                               Response = <C::Protocol as BindClient<K, TcpStream>>::ServiceResponse,
                               Error    = <C::Protocol as BindClient<K, TcpStream>>::ServiceError>,
        K: 'static,
    {
        if let Some(pool) = self.pools.get::<Pool<ClientConnector<C, K>>>() {
            pool.connection()
        } else {
            panic!()
        }
    }
}

#[derive(Clone)]
pub struct EnvBuilder {
    pools: Rc<RefCell<AnyMap>>,
}

impl EnvBuilder {
    pub fn new() -> EnvBuilder {
        EnvBuilder {
            pools: Rc::new(RefCell::new(AnyMap::new())),
        }
    }

    pub fn new_pool<C>(self, handle: Handle, cfg: Config, client_cfg: C::Config)
        -> Box<Future<Item = (), Error = io::Error>>
    where C: NewService + Configure + 'static
    {
        let client = C::new(&handle, client_cfg);
        Box::new(Pool::new(client, handle, cfg).map(move |pool| {
            self.pools.borrow_mut().insert(pool);
        }))
    }

    pub fn build(self) -> Environment {
        Environment {
            pools: Rc::new(Rc::try_unwrap(self.pools).unwrap().into_inner()),
        }
    }
}
<commit_msg>handle some panics.<commit_after>use std::io;
use std::cell::RefCell;
use std::rc::Rc;

use Error;

use anymap::AnyMap;
use futures::{Future, future};
use core::net::TcpStream;
use core::reactor::Handle;
use proto::BindClient;
use tokio::{Service, NewService};
use c3po::{ConnFuture, Conn, Pool, Config};

use connections::{Client, ClientConnector, Configure};

#[derive(Clone)]
pub struct Environment {
    pools: Rc<AnyMap>,
}

impl Environment {
    pub fn conn<C: NewService>(&self) -> ConnFuture<Conn<C>, Error> {
        if let Some(pool) = self.pools.get::<Pool<C>>() {
            pool.connection()
        } else {
            future::Either::A(future::err(Error))
        }
    }

    pub fn client<C, K>(&self) -> ConnFuture<Conn<ClientConnector<C, K>>, Error>
    where
        C: Client,
        C::Protocol: BindClient<K, TcpStream, BindClient = C::Connection>,
        C::Connection: Service<Request  = <C::Protocol as BindClient<K, TcpStream>>::ServiceRequest,
                               Response = <C::Protocol as BindClient<K, TcpStream>>::ServiceResponse,
                               Error    = <C::Protocol as BindClient<K, TcpStream>>::ServiceError>,
        K: 'static,
    {
        if let Some(pool) = self.pools.get::<Pool<ClientConnector<C, K>>>() {
            pool.connection()
        } else {
            future::Either::A(future::err(Error))
        }
    }
}

#[derive(Clone)]
pub struct EnvBuilder {
    pools: Rc<RefCell<AnyMap>>,
}

impl EnvBuilder {
    pub fn new() -> EnvBuilder {
        EnvBuilder {
            pools: Rc::new(RefCell::new(AnyMap::new())),
        }
    }

    pub fn new_pool<C>(self, handle: Handle, cfg: Config, client_cfg: C::Config)
        -> Box<Future<Item = (), Error = io::Error>>
    where C: NewService + Configure + 'static
    {
        let client = C::new(&handle, client_cfg);
        Box::new(Pool::new(client, handle, cfg).map(move |pool| {
            self.pools.borrow_mut().insert(pool);
        }))
    }

    pub fn build(self) -> Environment {
        Environment {
            pools: Rc::new(Rc::try_unwrap(self.pools).unwrap().into_inner()),
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>chore: migrate rocket app into libs<commit_after><|endoftext|>


<commit_before>// Copyright 2016 TiKV Project Authors. Licensed under Apache-2.0.

use super::Result;
use tikv_util::escape;

/// `UNSPECIFIED_FSP` is the unspecified fractional seconds part.
pub const UNSPECIFIED_FSP: i8 = -1;
/// `MAX_FSP` is the maximum digit of fractional seconds part.
pub const MAX_FSP: i8 = 6;
/// `MIN_FSP` is the minimum digit of fractional seconds part.
pub const MIN_FSP: i8 = 0;
/// `DEFAULT_FSP` is the default digit of fractional seconds part.
/// `MySQL` use 0 as the default Fsp.
pub const DEFAULT_FSP: i8 = 0;

fn check_fsp(fsp: i8) -> Result<u8> {
    if fsp == UNSPECIFIED_FSP {
        return Ok(DEFAULT_FSP as u8);
    }
    if fsp > MAX_FSP || fsp < MIN_FSP {
        return Err(invalid_type!("Invalid fsp {}", fsp));
    }
    Ok(fsp as u8)
}

/// Parse string as if it's a fraction part of a number and keep
/// only `fsp` precision.
fn parse_frac(s: &[u8], fsp: u8) -> Result<u32> {
    if s.is_empty() {
        return Ok(0);
    }

    if s.iter().any(|&c| c < b'0' || c > b'9') {
        return Err(invalid_type!("{} contains invalid char", escape(s)));
    }
    let res = s
        .iter()
        .take(fsp as usize + 1)
        .fold(0, |l, r| l * 10 + u32::from(r - b'0'));
    if s.len() > fsp as usize {
        if res % 10 >= 5 {
            Ok(res / 10 + 1)
        } else {
            Ok(res / 10)
        }
    } else {
        Ok(res * 10u32.pow((fsp as usize - s.len()) as u32))
    }
}

pub mod charset;
pub mod decimal;
pub mod duration;
pub mod json;
pub mod time;

pub use self::decimal::{dec_encoded_len, Decimal, DecimalEncoder, Res, RoundMode};
pub use self::duration::{Duration, DurationEncoder};
pub use self::json::{parse_json_path_expr, Json, JsonEncoder, ModifyType, PathExpression};
pub use self::time::{Time, TimeEncoder, TimeType, Tz};

#[cfg(test)]
mod tests {
    #[test]
    fn test_parse_frac() {
        let cases = vec![
            ("1234567", 0, 0),
            ("1234567", 1, 1),
            ("0000567", 5, 6),
            ("1234567", 5, 12346),
            ("1234567", 6, 123457),
            ("9999999", 6, 1000000),
        ];

        for (s, fsp, exp) in cases {
            let res = super::parse_frac(s.as_bytes(), fsp).unwrap();
            assert_eq!(res, exp);
        }
    }
}
<commit_msg>coprocessor: add unit tests to coverage `parse_frac` all path (#4683)<commit_after>// Copyright 2016 TiKV Project Authors. Licensed under Apache-2.0.

use super::Result;
use tikv_util::escape;

/// `UNSPECIFIED_FSP` is the unspecified fractional seconds part.
pub const UNSPECIFIED_FSP: i8 = -1;
/// `MAX_FSP` is the maximum digit of fractional seconds part.
pub const MAX_FSP: i8 = 6;
/// `MIN_FSP` is the minimum digit of fractional seconds part.
pub const MIN_FSP: i8 = 0;
/// `DEFAULT_FSP` is the default digit of fractional seconds part.
/// `MySQL` use 0 as the default Fsp.
pub const DEFAULT_FSP: i8 = 0;

fn check_fsp(fsp: i8) -> Result<u8> {
    if fsp == UNSPECIFIED_FSP {
        return Ok(DEFAULT_FSP as u8);
    }
    if fsp > MAX_FSP || fsp < MIN_FSP {
        return Err(invalid_type!("Invalid fsp {}", fsp));
    }
    Ok(fsp as u8)
}

/// Parse string as if it's a fraction part of a number and keep
/// only `fsp` precision.
fn parse_frac(s: &[u8], fsp: u8) -> Result<u32> {
    if s.is_empty() {
        return Ok(0);
    }

    if s.iter().any(|&c| c < b'0' || c > b'9') {
        return Err(invalid_type!("{} contains invalid char", escape(s)));
    }
    let res = s
        .iter()
        .take(fsp as usize + 1)
        .fold(0, |l, r| l * 10 + u32::from(r - b'0'));
    if s.len() > fsp as usize {
        if res % 10 >= 5 {
            Ok(res / 10 + 1)
        } else {
            Ok(res / 10)
        }
    } else {
        Ok(res * 10u32.pow((fsp as usize - s.len()) as u32))
    }
}

pub mod charset;
pub mod decimal;
pub mod duration;
pub mod json;
pub mod time;

pub use self::decimal::{dec_encoded_len, Decimal, DecimalEncoder, Res, RoundMode};
pub use self::duration::{Duration, DurationEncoder};
pub use self::json::{parse_json_path_expr, Json, JsonEncoder, ModifyType, PathExpression};
pub use self::time::{Time, TimeEncoder, TimeType, Tz};

#[cfg(test)]
mod tests {
    #[test]
    fn test_parse_frac() {
        let cases: Vec<(&'static [u8], u8, u32)> = vec![
            (b"", 0, 0),
            (b"", 10, 0),
            (b"1234567", 0, 0),
            (b"1234567", 1, 1),
            (b"0000567", 5, 6),
            (b"1234567", 5, 12346),
            (b"1234567", 6, 123457),
            (b"9999999", 6, 1000000),
            (b"12", 5, 12000),
        ];

        for (s, fsp, exp) in cases {
            let res = super::parse_frac(s, fsp).unwrap();
            assert_eq!(res, exp);
        }

        assert!(
            super::parse_frac(b"00x", 6).is_err(),
            "00x should be invalid for `parse_frac`"
        );
    }
}
<|endoftext|>


<commit_before>// compile-flags: --test -Z unstable-options --test-builder true --runtool true

/// ```
/// This does not compile, but specifying a custom --test-builder should let this pass anyway
/// `true` does not generate an output file to run, so we also specify it as a runtool
/// ```
pub struct Foo;
<commit_msg>Simplify regression test<commit_after>// compile-flags: --test -Z unstable-options --test-builder true

/// ```no_run
/// This tests that `--test-builder` is accepted as a flag by rustdoc.
/// ```
pub struct Foo;
<|endoftext|>


<commit_before>// Copyright 2012 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.

// xfail-test
use sys::rustrt::size_of;
extern mod std;

pub fn main() {
    assert!((size_of::<u8>() == 1 as uint));
    assert!((size_of::<u32>() == 4 as uint));
    assert!((size_of::<char>() == 4 as uint));
    assert!((size_of::<i8>() == 1 as uint));
    assert!((size_of::<i32>() == 4 as uint));
    assert!((size_of::<{a: u8, b: i8}>() == 2 as uint));
    assert!((size_of::<{a: u8, b: i8, c: u8}>() == 3 as uint));
    // Alignment causes padding before the char and the u32.

    assert!(size_of::<{a: u8, b: i8, c: {u: char, v: u8}, d: u32}>() ==
                16 as uint);
    assert!((size_of::<int>() == size_of::<uint>()));
    assert!((size_of::<{a: int, b: ()}>() == size_of::<int>()));
    assert!((size_of::<{a: int, b: (), c: ()}>() == size_of::<int>()));
    assert!((size_of::<int>() == size_of::<{x: int}>()));
}
<commit_msg>fixed up syntax<commit_after>// Copyright 2012 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.

extern mod core;
use core::sys::size_of;

struct t {a: u8, b: i8}
struct u {a: u8, b: i8, c: u8}
struct v {a: u8, b: i8, c: v2, d: u32}
struct v2 {u: char, v: u8}
struct w {a: int, b: ()}
struct x {a: int, b: (), c: ()}
struct y {x: int}

pub fn main() {
    assert!((size_of::<u8>() == 1 as uint));
    assert!((size_of::<u32>() == 4 as uint));
    assert!((size_of::<char>() == 4 as uint));
    assert!((size_of::<i8>() == 1 as uint));
    assert!((size_of::<i32>() == 4 as uint));
    assert!((size_of::<t>() == 2 as uint));
    assert!((size_of::<u>() == 3 as uint));
    // Alignment causes padding before the char and the u32.

    assert!(size_of::<v>() ==
                16 as uint);
    assert!((size_of::<int>() == size_of::<uint>()));
    assert!((size_of::<w>() == size_of::<int>()));
    assert!((size_of::<x>() == size_of::<int>()));
    assert!((size_of::<int>() == size_of::<y>()));
}
<|endoftext|>


<commit_before>// check-pass

// compile-flags: -O

fn foo(_: &'static [&'static str]) {}
fn bar(_: &'static [&'static str; 3]) {}
fn baz_i32(_: &'static i32) {}
fn baz_u32(_: &'static u32) {}

fn main() {
    foo(&["a", "b", "c"]);
    bar(&["d", "e", "f"]);

    // make sure that these do not cause trouble despite overflowing
    baz_u32(&(0-1));
    baz_i32(&-i32::MIN);
}
<commit_msg>make sure that promoteds which fail to evaluate in dead const code behave correctly<commit_after>// check-pass

// compile-flags: -O

fn foo(_: &'static [&'static str]) {}
fn bar(_: &'static [&'static str; 3]) {}
const fn baz_i32(_: &'static i32) {}
const fn baz_u32(_: &'static u32) {}

const fn fail() -> i32 { 1/0 }
const C: i32 = {
    // Promoted that fails to evaluate in dead code -- this must work
    // (for backwards compatibility reasons).
    if false {
        baz_i32(&fail());
    }
    42
};

fn main() {
    foo(&["a", "b", "c"]);
    bar(&["d", "e", "f"]);
    assert_eq!(C, 42);

    // make sure that these do not cause trouble despite overflowing
    baz_u32(&(0-1));
    baz_i32(&-i32::MIN);
}
<|endoftext|>


<commit_before>//! Test the behavior of moving out of non-`Copy` union fields.
//! Avoid types that `Drop`, we want to focus on moving.
#![feature(untagged_unions)]

use std::cell::RefCell;

fn move_out<T>(x: T) {}

union U1 {
    f1_nocopy: RefCell<i32>,
    f2_nocopy: RefCell<i32>,
    f3_copy: i32,
}

union U2 {
    f1_nocopy: RefCell<i32>,
}
impl Drop for U2 {
    fn drop(&mut self) {}
}

fn test1(x: U1) {
    // Moving out of a nocopy field prevents accessing other nocopy field.
    unsafe {
        move_out(x.f1_nocopy);
        move_out(x.f2_nocopy); //~ ERROR use of moved value: `x`
    }
}

fn test2(x: U1) {
    // "Moving" out of copy field doesn't prevent later field accesses.
    unsafe {
        move_out(x.f3_copy);
        move_out(x.f2_nocopy); // no error
    }
}

fn test3(x: U1) {
    // Moving out of a nocopy field prevents accessing other copy field.
    unsafe {
        move_out(x.f2_nocopy);
        move_out(x.f3_copy); //~ ERROR use of moved value: `x`
    }
}

fn test4(x: U2) {
    // Cannot move out of union that implements `Drop`.
    unsafe {
        move_out(x.f1_nocopy); //~ ERROR cannot move out of type `U2`, which implements the `Drop` trait
    }
}

fn main() {}
<commit_msg>please tidy<commit_after>//! Test the behavior of moving out of non-`Copy` union fields.
//! Avoid types that `Drop`, we want to focus on moving.
#![feature(untagged_unions)]

use std::cell::RefCell;

fn move_out<T>(x: T) {}

union U1 {
    f1_nocopy: RefCell<i32>,
    f2_nocopy: RefCell<i32>,
    f3_copy: i32,
}

union U2 {
    f1_nocopy: RefCell<i32>,
}
impl Drop for U2 {
    fn drop(&mut self) {}
}

fn test1(x: U1) {
    // Moving out of a nocopy field prevents accessing other nocopy field.
    unsafe {
        move_out(x.f1_nocopy);
        move_out(x.f2_nocopy); //~ ERROR use of moved value: `x`
    }
}

fn test2(x: U1) {
    // "Moving" out of copy field doesn't prevent later field accesses.
    unsafe {
        move_out(x.f3_copy);
        move_out(x.f2_nocopy); // no error
    }
}

fn test3(x: U1) {
    // Moving out of a nocopy field prevents accessing other copy field.
    unsafe {
        move_out(x.f2_nocopy);
        move_out(x.f3_copy); //~ ERROR use of moved value: `x`
    }
}

fn test4(x: U2) {
    // Cannot move out of union that implements `Drop`.
    unsafe {
        move_out(x.f1_nocopy); //~ ERROR cannot move out of type `U2`, which implements the `Drop`
    }
}

fn main() {}
<|endoftext|>