<commit_before>// Copyright (C) 2019 Sajeer Ahamed <ahamedsajeer.15.15@cse.mrt.ac.lk>
// Copyright (C) 2019 Sebastian Dröge <sebastian@centricular.com>
//
// Licensed under the MIT license, see the LICENSE file or <http://opensource.org/licenses/MIT>

//! Extracts release for [GStreamer](https://gstreamer.freedesktop.org) plugin metadata
//!
//! See [`get_info`](fn.get_info.html) for details.
//!
//! This function is supposed to be used as follows in the `build.rs` of a crate that implements a
//! plugin:
//!
//! ```rust,ignore
//! extern crate gst_plugin_version_helper;
//!
//! gst_plugin_version_helper::get_info();
//! ```
//!
//! Inside `lib.rs` of the plugin, the information provided by `get_info` are usable as follows:
//!
//! ```rust,ignore
//! gst_plugin_define!(
//!     the_plugin_name,
//!     env!("CARGO_PKG_DESCRIPTION"),
//!     plugin_init,
//!     concat!(env!("CARGO_PKG_VERSION"), "-", env!("COMMIT_ID")),
//!     "The Plugin's License",
//!     env!("CARGO_PKG_NAME"),
//!     env!("CARGO_PKG_NAME"),
//!     env!("CARGO_PKG_REPOSITORY"),
//!     env!("BUILD_REL_DATE")
//! );
//! ```

mod git;

use std::{env, fs, path};

/// Extracts release for GStreamer plugin metadata
///
/// Release information is first tried to be extracted from a git repository at the same
/// place as the `Cargo.toml`, or one directory up to allow for Cargo workspaces. If no
/// git repository is found, the information is extract from a `release.txt` in the same
/// directory as the `Cargo.toml`.
///
/// - If extracted from a git repository, sets the `COMMIT_ID` environment variable to the short
///   commit id of the latest commit and the `BUILD_REL_DATE` environment variable to the date of the
///   commit.
///
/// - If extracted from a `release.txt`, `COMMIT_ID` will be set to the string `RELEASE` and the
///   `BUILD_REL_DATE` variable will be set to the release date extracted from `release.txt`.
///
/// - If neither is possible, `COMMIT_ID` is set to the string `UNKNOWN` and `BUILD_REL_DATE` to the
///   current date.
///
/// ## `release.txt`
///
/// `release.txt` is only parsed if no git repository was found and is assumed to be in the format
///
/// ```txt
/// version_number
/// release_date
/// ```
///
/// for example
///
/// ```txt
/// 1.16.0
/// 2019-04-19
/// ```
///
/// If the version number from `Cargo.toml` is not equivalent to the one in `release.txt`, this
/// function will panic.
pub fn get_info() {
    let mut commit_id = "UNKNOWN".into();
    let mut commit_date = chrono::Utc::now().format("%Y-%m-%d").to_string();

    let crate_dir =
        path::PathBuf::from(env::var("CARGO_MANIFEST_DIR").expect("CARGO_MANIFEST_DIR not set"));
    let mut repo_dir = crate_dir.clone();

    // First check for a git repository in the manifest directory and if there
    // is none try one directory up in case we're in a Cargo workspace
    let git_info = git::repo_hash(&repo_dir).or_else(move || {
        repo_dir.pop();
        git::repo_hash(&repo_dir)
    });

    let mut release_file = crate_dir.clone();
    release_file.push("release.txt");

    // If there is a git repository, extract the version information from there.
    // Otherwise use a 'release.txt' file as fallback, or report the current
    // date and an unknown revision.
    if let Some((id, date)) = git_info {
        commit_id = id;
        commit_date = date;
    } else if let Ok(release_file) = fs::File::open(release_file) {
        let mut cargo_toml = crate_dir;
        cargo_toml.push("Cargo.toml");

        if let Ok(cargo_toml) = fs::File::open(cargo_toml) {
            commit_date = read_release_date(cargo_toml, release_file);
            commit_id = "RELEASE".into();
        }
    }

    println!("cargo:rustc-env=COMMIT_ID={}", commit_id);
    println!("cargo:rustc-env=BUILD_REL_DATE={}", commit_date);
}

fn read_release_date(mut cargo_toml: fs::File, mut release_file: fs::File) -> String {
    use std::io::Read;

    let mut content = String::new();
    release_file
        .read_to_string(&mut content)
        .expect("Failed to read version file");

    let mut lines = content.lines();
    let version = lines.next().expect("Failed to read version number");
    let date = lines.next().expect("Failed to read release date");

    let mut cargo_toml_content = String::new();
    cargo_toml
        .read_to_string(&mut cargo_toml_content)
        .expect("Failed to read `Cargo.toml`");

    let cargo_toml = cargo_toml_content
        .parse::<toml::Value>()
        .expect("Failed to parse `Cargo.toml`");
    let package = cargo_toml["package"]
        .as_table()
        .expect("Failed to find 'package' section in `Cargo.toml`");
    let cargo_version = package["version"]
        .as_str()
        .expect("Failed to read version from `Cargo.toml`");

    if cargo_version != version {
        panic!(
            "Version from 'version.txt' `{}` different from 'Cargo.toml' `{}`",
            version, cargo_version
        );
    }

    date.into()
}
<commit_msg>version-helper: always assume we are in a release if not in git<commit_after>// Copyright (C) 2019 Sajeer Ahamed <ahamedsajeer.15.15@cse.mrt.ac.lk>
// Copyright (C) 2019 Sebastian Dröge <sebastian@centricular.com>
//
// Licensed under the MIT license, see the LICENSE file or <http://opensource.org/licenses/MIT>

//! Extracts release for [GStreamer](https://gstreamer.freedesktop.org) plugin metadata
//!
//! See [`get_info`](fn.get_info.html) for details.
//!
//! This function is supposed to be used as follows in the `build.rs` of a crate that implements a
//! plugin:
//!
//! ```rust,ignore
//! extern crate gst_plugin_version_helper;
//!
//! gst_plugin_version_helper::get_info();
//! ```
//!
//! Inside `lib.rs` of the plugin, the information provided by `get_info` are usable as follows:
//!
//! ```rust,ignore
//! gst_plugin_define!(
//!     the_plugin_name,
//!     env!("CARGO_PKG_DESCRIPTION"),
//!     plugin_init,
//!     concat!(env!("CARGO_PKG_VERSION"), "-", env!("COMMIT_ID")),
//!     "The Plugin's License",
//!     env!("CARGO_PKG_NAME"),
//!     env!("CARGO_PKG_NAME"),
//!     env!("CARGO_PKG_REPOSITORY"),
//!     env!("BUILD_REL_DATE")
//! );
//! ```

mod git;

use chrono::TimeZone;
use std::convert::TryInto;
use std::time::SystemTime;
use std::{env, fs, path};

/// Extracts release for GStreamer plugin metadata
///
/// Release information is first tried to be extracted from a git repository at the same
/// place as the `Cargo.toml`, or one directory up to allow for Cargo workspaces. If no
/// git repository is found, we assume this is a release.
///
/// - If extracted from a git repository, sets the `COMMIT_ID` environment variable to the short
///   commit id of the latest commit and the `BUILD_REL_DATE` environment variable to the date of the
///   commit.
///
/// - If not, `COMMIT_ID` will be set to the string `RELEASE` and the
///   `BUILD_REL_DATE` variable will be set to the mtime of `Cargo.toml`.
///
/// - If neither is possible, `COMMIT_ID` is set to the string `UNKNOWN` and `BUILD_REL_DATE` to the
///   current date.
///
pub fn get_info() {
    let crate_dir =
        path::PathBuf::from(env::var("CARGO_MANIFEST_DIR").expect("CARGO_MANIFEST_DIR not set"));
    let mut repo_dir = crate_dir.clone();

    // First check for a git repository in the manifest directory and if there
    // is none try one directory up in case we're in a Cargo workspace
    let git_info = git::repo_hash(&repo_dir).or_else(move || {
        repo_dir.pop();
        git::repo_hash(&repo_dir)
    });

    // If there is a git repository, extract the version information from there.
    // Otherwise assume this is a release and use Cargo.toml mtime as date.
    let (commit_id, commit_date) = git_info.unwrap_or_else(|| {
        let date = cargo_mtime_date(crate_dir).expect("Failed to get Cargo.toml mtime");
        ("RELEASE".into(), date)
    });

    println!("cargo:rustc-env=COMMIT_ID={}", commit_id);
    println!("cargo:rustc-env=BUILD_REL_DATE={}", commit_date);
}

fn cargo_mtime_date(crate_dir: path::PathBuf) -> Option<String> {
    let mut cargo_toml = crate_dir;
    cargo_toml.push("Cargo.toml");

    let metadata = fs::metadata(&cargo_toml).ok()?;
    let mtime = metadata.modified().ok()?;
    let unix_time = mtime.duration_since(SystemTime::UNIX_EPOCH).ok()?;
    let dt = chrono::Utc.timestamp(unix_time.as_secs().try_into().ok()?, 0);

    Some(dt.format("%Y-%m-%d").to_string())
}
<|endoftext|>


<commit_before>use super::point::Point;
use super::number::NumberOps;

#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone)]
pub struct Circle {
   pub center: Point,
   pub radius: i64,
}

impl Circle {
   #[inline]
   pub fn new(center: Point, radius: i64) -> Self {
      Circle {
         center: center,
         radius: radius,
      }
   }

   #[inline]
   pub fn y_tr(&self, x: i64) -> i64 { // top-right
      self.center.y + self.other_delta(x - self.center.x)
   }

   #[inline]
   pub fn x_tr(&self, y: i64) -> i64 { // top-right
      self.center.x + self.other_delta(y - self.center.y)
   }

   #[inline]
   pub fn y_br(&self, x: i64) -> i64 { // bottom-right
      self.center.y - self.other_delta(x - self.center.x)
   }

   #[inline]
   pub fn x_br(&self, y: i64) -> i64 { // bottom-right
      self.center.x + self.other_delta(self.center.y - y)
   }

   #[inline]
   pub fn y_tl(&self, x: i64) -> i64 { // top-left
      self.center.y + self.other_delta(self.center.x - x)
   }

   #[inline]
   pub fn x_tl(&self, y: i64) -> i64 { // top-left
      self.center.x - self.other_delta(y - self.center.y)
   }

   #[inline]
   pub fn y_bl(&self, x: i64) -> i64 { // bottom-left
      self.center.y - self.other_delta(self.center.x - x)
   }

   #[inline]
   pub fn x_bl(&self, y: i64) -> i64 { // bottom-left
      self.center.x - self.other_delta(self.center.y - y)
   }

   #[inline]
   fn other_delta(&self, other: i64) -> i64 {
      assert!(other > 0);
      assert!(other < self.radius);
      (self.radius.pow(2) - other.pow(2)).sqrt()
   }
}
<commit_msg>Tests for the circle intersection methods<commit_after>use super::point::Point;
use super::number::NumberOps;

#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone)]
pub struct Circle {
   pub center: Point,
   pub radius: i64,
}

impl Circle {
   #[inline]
   pub fn new(center: Point, radius: i64) -> Self {
      Circle {
         center: center,
         radius: radius,
      }
   }

   #[inline]
   pub fn y_tr(&self, x: i64) -> i64 { // top-right
      self.center.y + self.other_delta(x - self.center.x)
   }

   #[inline]
   pub fn x_tr(&self, y: i64) -> i64 { // top-right
      self.center.x + self.other_delta(y - self.center.y)
   }

   #[inline]
   pub fn y_br(&self, x: i64) -> i64 { // bottom-right
      self.center.y - self.other_delta(x - self.center.x)
   }

   #[inline]
   pub fn x_br(&self, y: i64) -> i64 { // bottom-right
      self.center.x + self.other_delta(self.center.y - y)
   }

   #[inline]
   pub fn y_tl(&self, x: i64) -> i64 { // top-left
      self.center.y + self.other_delta(self.center.x - x)
   }

   #[inline]
   pub fn x_tl(&self, y: i64) -> i64 { // top-left
      self.center.x - self.other_delta(y - self.center.y)
   }

   #[inline]
   pub fn y_bl(&self, x: i64) -> i64 { // bottom-left
      self.center.y - self.other_delta(self.center.x - x)
   }

   #[inline]
   pub fn x_bl(&self, y: i64) -> i64 { // bottom-left
      self.center.x - self.other_delta(self.center.y - y)
   }

   #[inline]
   fn other_delta(&self, delta: i64) -> i64 {
      assert!(delta > 0);
      assert!(delta < self.radius);
      (self.radius.pow(2) - delta.pow(2)).sqrt()
   }
}

#[cfg(test)]
mod tests {
   use super::super::point::Point;

   use super::*;

   #[test]
   fn test_y_tr() {
      let circle = Circle::new(Point::new(100_000, 100_000), 50_000);
      let y = circle.y_tr(120_000);
      assert_eq!(y, 145_826);
   }

   #[test]
   fn test_x_tr() {
      let circle = Circle::new(Point::new(100_000, 100_000), 50_000);
      let x = circle.x_tr(120_000);
      assert_eq!(x, 145_826);
   }

   #[test]
   fn test_y_br() {
      let circle = Circle::new(Point::new(100_000, 100_000), 50_000);
      let y = circle.y_br(120_000);
      assert_eq!(y, 54_174);
   }

   #[test]
   fn test_x_br() {
      let circle = Circle::new(Point::new(100_000, 100_000), 50_000);
      let x = circle.x_br(60_000);
      assert_eq!(x, 130_000);
   }

   #[test]
   fn test_y_tl() {
      let circle = Circle::new(Point::new(100_000, 100_000), 50_000);
      let y = circle.y_tl(60_000);
      assert_eq!(y, 130_000);
   }

   #[test]
   fn test_x_tl() {
      let circle = Circle::new(Point::new(100_000, 100_000), 50_000);
      let x = circle.x_tl(120_000);
      assert_eq!(x, 54_174);
   }

   #[test]
   fn test_y_bl() {
      let circle = Circle::new(Point::new(100_000, 100_000), 50_000);
      let y = circle.y_bl(60_000);
      assert_eq!(y, 70_000);
   }

   #[test]
   fn test_x_bl() {
      let circle = Circle::new(Point::new(100_000, 100_000), 50_000);
      let x = circle.x_bl(60_000);
      assert_eq!(x, 70_000);
   }
}
<|endoftext|>


<commit_before>/*
 * Copyright (c) Facebook, Inc. and its affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

use colored::*;
use common::Span;
use std::fmt::Write;

pub struct SourcePrinter;

const PRINT_WHITESPACE: bool = false;

impl SourcePrinter {
    pub fn new() -> Self {
        Self
    }

    pub fn write_span<W: Write>(
        &self,
        writer: &mut W,
        span: &Span,
        source: &str,
    ) -> std::fmt::Result {
        let start_char_index = span.start as usize;
        let end_char_index = span.end as usize;

        let start_byte_index =
            if let Some((byte_index, _)) = source.char_indices().nth(start_char_index) {
                byte_index
            } else {
                return write!(
                    writer,
                    "Internal error: Unable to print source, start index ({}) out of range.",
                    start_char_index
                );
            };
        let end_byte_index =
            if let Some((byte_index, _)) = source.char_indices().nth(end_char_index) {
                byte_index
            } else {
                return write!(
                    writer,
                    "Internal error: Unable to print source, end index ({}) out of range.",
                    end_char_index
                );
            };

        let mut line_end_byte_indices = Vec::new();
        for (byte_index, chr) in source.char_indices() {
            if chr == '\n' {
                line_end_byte_indices.push(byte_index + 1)
            }
        }
        if source.ends_with('\n') {
            line_end_byte_indices.pop();
        }

        let byte_index_to_line_index = |byte_index: usize| -> usize {
            line_end_byte_indices
                .binary_search(&byte_index)
                .unwrap_or_else(|x| x)
        };

        let line_index_to_byte_range = |line_index: usize| {
            let end = line_end_byte_indices
                .get(line_index)
                .cloned()
                .unwrap_or_else(|| source.len());
            let start = if line_index == 0 {
                0
            } else {
                line_end_byte_indices
                    .get(line_index - 1)
                    .cloned()
                    .unwrap_or_else(|| source.len())
            };
            start..end
        };

        const CONTEXT: usize = 1;

        let first_line_index = byte_index_to_line_index(start_char_index);
        let last_line_index = byte_index_to_line_index(end_char_index);

        let first_printed_line_index = first_line_index.saturating_sub(CONTEXT);
        let last_printed_line_index = (last_line_index + CONTEXT).min(line_end_byte_indices.len());

        let mut currently_hightlighted = false;
        for line_index in first_printed_line_index..=last_printed_line_index {
            write!(
                writer,
                "{}",
                format!(" {:>4} \u{2502} ", line_index + 1).bold()
            )
            .unwrap();
            let mut something_highlighted_on_line = false;
            let mut marker = String::new();
            for byte_index in line_index_to_byte_range(line_index) {
                if byte_index == end_byte_index {
                    currently_hightlighted = false
                } else if byte_index == start_byte_index {
                    currently_hightlighted = true;
                }

                let chr = match source
                    .char_indices()
                    .find(|(idx, _)| *idx == byte_index)
                    .map(|(_, chr)| chr)
                {
                    Some('\n') => {
                        if PRINT_WHITESPACE {
                            '␤'
                        } else {
                            continue;
                        }
                    }
                    Some('\r') => {
                        if PRINT_WHITESPACE {
                            '␍'
                        } else {
                            continue;
                        }
                    }
                    Some(c) => c,
                    None => continue,
                };

                if currently_hightlighted {
                    write!(writer, "{}", chr.to_string().red()).unwrap();
                    marker.push_str("^");
                    something_highlighted_on_line = true;
                } else {
                    write!(writer, "{}", chr).unwrap();
                    if !something_highlighted_on_line {
                        // TODO should push 2 spaces for emojis, unicode-width crate might help
                        marker.push(' ');
                    }
                }
            }
            writeln!(writer)?;
            if something_highlighted_on_line {
                writeln!(writer, "      \u{2502} {}", marker.red()).unwrap();
            }
        }

        Ok(())
    }
}
<commit_msg>fix out of bounds issue when printing to last character<commit_after>/*
 * Copyright (c) Facebook, Inc. and its affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

use colored::*;
use common::Span;
use std::fmt::Write;

pub struct SourcePrinter;

const PRINT_WHITESPACE: bool = false;

impl SourcePrinter {
    pub fn new() -> Self {
        Self
    }

    pub fn write_span<W: Write>(
        &self,
        writer: &mut W,
        span: &Span,
        source: &str,
    ) -> std::fmt::Result {
        let start_char_index = span.start as usize;
        let end_char_index = span.end as usize;

        let start_byte_index =
            if let Some((byte_index, _)) = source.char_indices().nth(start_char_index) {
                byte_index
            } else {
                return write!(
                    writer,
                    "Internal error: Unable to print source, start index ({}) out of range.",
                    start_char_index
                );
            };
        let end_byte_index = source
            .char_indices()
            .nth(end_char_index)
            .map_or_else(|| source.len(), |(byte_index, _)| byte_index);

        let mut line_end_byte_indices = Vec::new();
        for (byte_index, chr) in source.char_indices() {
            if chr == '\n' {
                line_end_byte_indices.push(byte_index + 1)
            }
        }
        if source.ends_with('\n') {
            line_end_byte_indices.pop();
        }

        let byte_index_to_line_index = |byte_index: usize| -> usize {
            line_end_byte_indices
                .binary_search(&byte_index)
                .unwrap_or_else(|x| x)
        };

        let line_index_to_byte_range = |line_index: usize| {
            let end = line_end_byte_indices
                .get(line_index)
                .cloned()
                .unwrap_or_else(|| source.len());
            let start = if line_index == 0 {
                0
            } else {
                line_end_byte_indices
                    .get(line_index - 1)
                    .cloned()
                    .unwrap_or_else(|| source.len())
            };
            start..end
        };

        const CONTEXT: usize = 1;

        let first_line_index = byte_index_to_line_index(start_char_index);
        let last_line_index = byte_index_to_line_index(end_char_index);

        let first_printed_line_index = first_line_index.saturating_sub(CONTEXT);
        let last_printed_line_index = (last_line_index + CONTEXT).min(line_end_byte_indices.len());

        let mut currently_hightlighted = false;
        for line_index in first_printed_line_index..=last_printed_line_index {
            write!(
                writer,
                "{}",
                format!(" {:>4} \u{2502} ", line_index + 1).bold()
            )
            .unwrap();
            let mut something_highlighted_on_line = false;
            let mut marker = String::new();
            for byte_index in line_index_to_byte_range(line_index) {
                if byte_index == end_byte_index {
                    currently_hightlighted = false
                } else if byte_index == start_byte_index {
                    currently_hightlighted = true;
                }

                let chr = match source
                    .char_indices()
                    .find(|(idx, _)| *idx == byte_index)
                    .map(|(_, chr)| chr)
                {
                    Some('\n') => {
                        if PRINT_WHITESPACE {
                            '␤'
                        } else {
                            continue;
                        }
                    }
                    Some('\r') => {
                        if PRINT_WHITESPACE {
                            '␍'
                        } else {
                            continue;
                        }
                    }
                    Some(c) => c,
                    None => continue,
                };

                if currently_hightlighted {
                    write!(writer, "{}", chr.to_string().red()).unwrap();
                    marker.push_str("^");
                    something_highlighted_on_line = true;
                } else {
                    write!(writer, "{}", chr).unwrap();
                    if !something_highlighted_on_line {
                        // TODO should push 2 spaces for emojis, unicode-width crate might help
                        marker.push(' ');
                    }
                }
            }
            writeln!(writer)?;
            if something_highlighted_on_line {
                writeln!(writer, "      \u{2502} {}", marker.red()).unwrap();
            }
        }

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


<commit_before>/*
 * Copyright (c) 2013, David Renshaw (dwrenshaw@gmail.com)
 *
 * See the LICENSE file in the capnproto-rust root directory.
 */

use std;

pub type BitCount0 = uint; // `BitCount` clashes with a standard trait
pub type BitCount8 = u8;
pub type BitCount16 = u16;
pub type BitCount32 = u32;
pub type BitCount64 = u64;

pub type ByteCount = uint;
pub type ByteCount8 = u8;
pub type ByteCount16 = u16;
pub type ByteCount32 = u32;
pub type ByteCount64 = u64;

pub type WordCount = uint;
pub type WordCount8 = u8;
pub type WordCount16 = u16;
pub type WordCount32 = u32;
pub type WordCount64 = u64;

pub type ElementCount = uint;
pub type ElementCount8 = u8;
pub type ElementCount16 = u16;
pub type ElementCount32 = u32;
pub type ElementCount64 = u64;

pub type WirePointerCount = uint;
pub type WirePointerCount8 = u8;
pub type WirePointerCount16 = u16;
pub type WirePointerCount32 = u32;
pub type WirePointerCount64 = u64;

pub struct Word {priv _x : u64}

pub static BITS_PER_BYTE : BitCount0 = 8;
pub static BITS_PER_WORD : BitCount0 = 64;
pub static BYTES_PER_WORD : ByteCount = 8;

pub static BITS_PER_POINTER : BitCount0 = 64;
pub static BYTES_PER_POINTER : ByteCount = 8;
pub static WORDS_PER_POINTER : WordCount = 1;

pub static POINTER_SIZE_IN_WORDS : WordCount = 1;

pub fn bytesPerElement<T>() -> ByteCount {
    std::mem::size_of::<T>()
}

pub fn bitsPerElement<T>() -> BitCount0 {
    8 * std::mem::size_of::<T>()
}

#[inline]
pub fn allocate_zeroed_words(size : WordCount) -> ~[Word] {

//    Do this, but faster:
//    return std::vec::from_elem(size, 0u8);

    let mut result : ~[Word] = std::vec::with_capacity(size);
    unsafe {
        std::vec::raw::set_len(&mut result, size);
        let p : *mut u8 = std::cast::transmute(result.unsafe_mut_ref(0));
        std::ptr::set_memory(p, 0, size);
    }
    return result;
}

<commit_msg>fix bug in allocate_zeroed_words. tests pass now<commit_after>/*
 * Copyright (c) 2013, David Renshaw (dwrenshaw@gmail.com)
 *
 * See the LICENSE file in the capnproto-rust root directory.
 */

use std;

pub type BitCount0 = uint; // `BitCount` clashes with a standard trait
pub type BitCount8 = u8;
pub type BitCount16 = u16;
pub type BitCount32 = u32;
pub type BitCount64 = u64;

pub type ByteCount = uint;
pub type ByteCount8 = u8;
pub type ByteCount16 = u16;
pub type ByteCount32 = u32;
pub type ByteCount64 = u64;

pub type WordCount = uint;
pub type WordCount8 = u8;
pub type WordCount16 = u16;
pub type WordCount32 = u32;
pub type WordCount64 = u64;

pub type ElementCount = uint;
pub type ElementCount8 = u8;
pub type ElementCount16 = u16;
pub type ElementCount32 = u32;
pub type ElementCount64 = u64;

pub type WirePointerCount = uint;
pub type WirePointerCount8 = u8;
pub type WirePointerCount16 = u16;
pub type WirePointerCount32 = u32;
pub type WirePointerCount64 = u64;

pub struct Word {priv _x : u64}

pub static BITS_PER_BYTE : BitCount0 = 8;
pub static BITS_PER_WORD : BitCount0 = 64;
pub static BYTES_PER_WORD : ByteCount = 8;

pub static BITS_PER_POINTER : BitCount0 = 64;
pub static BYTES_PER_POINTER : ByteCount = 8;
pub static WORDS_PER_POINTER : WordCount = 1;

pub static POINTER_SIZE_IN_WORDS : WordCount = 1;

pub fn bytesPerElement<T>() -> ByteCount {
    std::mem::size_of::<T>()
}

pub fn bitsPerElement<T>() -> BitCount0 {
    8 * std::mem::size_of::<T>()
}

#[inline]
pub fn allocate_zeroed_words(size : WordCount) -> ~[Word] {

//    Do this, but faster:
//    return std::vec::from_elem(size, 0u8);

    let mut result : ~[Word] = std::vec::with_capacity(size);
    unsafe {
        std::vec::raw::set_len(&mut result, size);
        let p : *mut u8 = std::cast::transmute(result.unsafe_mut_ref(0));
        std::ptr::set_memory(p, 0, size * BYTES_PER_WORD);
    }
    return result;
}

<|endoftext|>


<commit_before>use serde::Deserialize;
use std::collections::BTreeMap;
use std::path::Path;

use std::collections::BTreeSet as Set;
use std::fs;

/// A lookup table from TypeName to Entry.
pub type NodeTypeMap = BTreeMap<TypeName, Entry>;

#[derive(Debug)]
pub struct Entry {
    pub dbscheme_name: String,
    pub ql_class_name: String,
    pub kind: EntryKind,
}

#[derive(Debug)]
pub enum EntryKind {
    Union { members: Set<TypeName> },
    Table { name: String, fields: Vec<Field> },
    Token { kind_id: usize },
}

#[derive(Debug, Ord, PartialOrd, Eq, PartialEq)]
pub struct TypeName {
    pub kind: String,
    pub named: bool,
}

#[derive(Debug)]
pub enum FieldTypeInfo {
    /// The field has a single type.
    Single(TypeName),

    /// The field can take one of several types, so we also provide the name of
    /// the database union type that wraps them, and the corresponding QL class
    /// name.
    Multiple {
        types: Set<TypeName>,
        dbscheme_union: String,
        ql_class: String,
    },

    /// The field can be one of several tokens, so the db type will be an `int`
    /// with a `case @foo.kind` for each possiblity.
    ReservedWordInt(BTreeMap<String, (usize, String)>),
}

#[derive(Debug)]
pub struct Field {
    pub parent: TypeName,
    pub type_info: FieldTypeInfo,
    /// The name of the field or None for the anonymous 'children'
    /// entry from node_types.json
    pub name: Option<String>,
    /// The name of the predicate to get this field.
    pub getter_name: String,
    pub storage: Storage,
}

fn name_for_field_or_child(name: &Option<String>) -> String {
    match name {
        Some(name) => name.clone(),
        None => "child".to_owned(),
    }
}

#[derive(Debug)]
pub enum Storage {
    /// the field is stored as a column in the parent table
    Column { name: String },
    /// the field is stored in a link table, and may or may not have an
    /// associated index column
    Table { name: String, has_index: bool },
}

pub fn read_node_types(node_types_path: &Path) -> std::io::Result<NodeTypeMap> {
    let file = fs::File::open(node_types_path)?;
    let node_types = serde_json::from_reader(file)?;
    Ok(convert_nodes(&node_types))
}

pub fn read_node_types_str(node_types_json: &str) -> std::io::Result<NodeTypeMap> {
    let node_types = serde_json::from_str(node_types_json)?;
    Ok(convert_nodes(&node_types))
}

fn convert_type(node_type: &NodeType) -> TypeName {
    TypeName {
        kind: node_type.kind.to_string(),
        named: node_type.named,
    }
}

fn convert_types(node_types: &Vec<NodeType>) -> Set<TypeName> {
    let iter = node_types.iter().map(convert_type).collect();
    std::collections::BTreeSet::from(iter)
}

pub fn convert_nodes(nodes: &Vec<NodeInfo>) -> NodeTypeMap {
    let mut entries = NodeTypeMap::new();
    let mut token_kinds = Set::new();

    // First, find all the token kinds
    for node in nodes {
        if node.subtypes.is_none() {
            if node.fields.as_ref().map_or(0, |x| x.len()) == 0 && node.children.is_none() {
                let type_name = TypeName {
                    kind: node.kind.clone(),
                    named: node.named,
                };
                token_kinds.insert(type_name);
            }
        }
    }

    for node in nodes {
        let flattened_name = &node_type_name(&node.kind, node.named);
        let dbscheme_name = escape_name(&flattened_name);
        let ql_class_name = dbscheme_name_to_class_name(&dbscheme_name);
        if let Some(subtypes) = &node.subtypes {
            // It's a tree-sitter supertype node, for which we create a union
            // type.
            entries.insert(
                TypeName {
                    kind: node.kind.clone(),
                    named: node.named,
                },
                Entry {
                    dbscheme_name,
                    ql_class_name,
                    kind: EntryKind::Union {
                        members: convert_types(&subtypes),
                    },
                },
            );
        } else if node.fields.as_ref().map_or(0, |x| x.len()) == 0 && node.children.is_none() {
            // Token kind, handled above.
        } else {
            // It's a product type, defined by a table.
            let type_name = TypeName {
                kind: node.kind.clone(),
                named: node.named,
            };
            let table_name = escape_name(&(format!("{}_def", &flattened_name)));
            let mut fields = Vec::new();

            // If the type also has fields or children, then we create either
            // auxiliary tables or columns in the defining table for them.
            if let Some(node_fields) = &node.fields {
                for (field_name, field_info) in node_fields {
                    add_field(
                        &type_name,
                        Some(field_name.to_string()),
                        field_info,
                        &mut fields,
                        &token_kinds,
                    );
                }
            }
            if let Some(children) = &node.children {
                // Treat children as if they were a field called 'child'.
                add_field(&type_name, None, children, &mut fields, &token_kinds);
            }
            entries.insert(
                type_name,
                Entry {
                    dbscheme_name,
                    ql_class_name,
                    kind: EntryKind::Table {
                        name: table_name,
                        fields,
                    },
                },
            );
        }
    }
    let mut counter = 0;
    for type_name in token_kinds {
        let entry = if type_name.named {
            counter += 1;
            let unprefixed_name = node_type_name(&type_name.kind, true);
            Entry {
                dbscheme_name: escape_name(&format!("token_{}", &unprefixed_name)),
                ql_class_name: dbscheme_name_to_class_name(&escape_name(&unprefixed_name)),
                kind: EntryKind::Token { kind_id: counter },
            }
        } else {
            Entry {
                dbscheme_name: "reserved_word".to_owned(),
                ql_class_name: "ReservedWord".to_owned(),
                kind: EntryKind::Token { kind_id: 0 },
            }
        };
        entries.insert(type_name, entry);
    }
    entries
}

fn add_field(
    parent_type_name: &TypeName,
    field_name: Option<String>,
    field_info: &FieldInfo,
    fields: &mut Vec<Field>,
    token_kinds: &Set<TypeName>,
) {
    let parent_flattened_name = node_type_name(&parent_type_name.kind, parent_type_name.named);
    let storage = if !field_info.multiple && field_info.required {
        // This field must appear exactly once, so we add it as
        // a column to the main table for the node type.
        Storage::Column {
            name: escape_name(&name_for_field_or_child(&field_name)),
        }
    } else {
        // Put the field in an auxiliary table.
        let has_index = field_info.multiple;
        let field_table_name = escape_name(&format!(
            "{}_{}",
            parent_flattened_name,
            &name_for_field_or_child(&field_name)
        ));
        Storage::Table {
            has_index,
            name: field_table_name,
        }
    };
    let converted_types = convert_types(&field_info.types);
    let type_info = if field_info
        .types
        .iter()
        .all(|t| !t.named && token_kinds.contains(&convert_type(t)))
    {
        // All possible types for this field are reserved words. The db
        // representation will be an `int` with a `case @foo.field = ...` to
        // enumerate the possible values.
        let mut counter = 0;
        let mut field_token_ints: BTreeMap<String, (usize, String)> = BTreeMap::new();
        for t in converted_types {
            let dbscheme_variant_name =
                escape_name(&format!("{}_{}", parent_flattened_name, t.kind));
            field_token_ints.insert(t.kind.to_owned(), (counter, dbscheme_variant_name));
            counter += 1;
        }
        FieldTypeInfo::ReservedWordInt(field_token_ints)
    } else if field_info.types.len() == 1 {
        FieldTypeInfo::Single(converted_types.into_iter().next().unwrap())
    } else {
        // The dbscheme type for this field will be a union. In QL, it'll just be AstNode.
        FieldTypeInfo::Multiple {
            types: converted_types,
            dbscheme_union: format!(
                "{}_{}_type",
                &parent_flattened_name,
                &name_for_field_or_child(&field_name)
            ),
            ql_class: "AstNode".to_owned(),
        }
    };
    let getter_name = format!(
        "get{}",
        dbscheme_name_to_class_name(&escape_name(&name_for_field_or_child(&field_name)))
    );
    fields.push(Field {
        parent: TypeName {
            kind: parent_type_name.kind.to_string(),
            named: parent_type_name.named,
        },
        type_info,
        name: field_name,
        getter_name,
        storage,
    });
}
#[derive(Deserialize)]
pub struct NodeInfo {
    #[serde(rename = "type")]
    pub kind: String,
    pub named: bool,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub fields: Option<BTreeMap<String, FieldInfo>>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub children: Option<FieldInfo>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub subtypes: Option<Vec<NodeType>>,
}

#[derive(Deserialize)]
pub struct NodeType {
    #[serde(rename = "type")]
    pub kind: String,
    pub named: bool,
}

#[derive(Deserialize)]
pub struct FieldInfo {
    pub multiple: bool,
    pub required: bool,
    pub types: Vec<NodeType>,
}

/// Given a tree-sitter node type's (kind, named) pair, returns a single string
/// representing the (unescaped) name we'll use to refer to corresponding QL
/// type.
fn node_type_name(kind: &str, named: bool) -> String {
    if named {
        kind.to_string()
    } else {
        format!("{}_unnamed", kind)
    }
}

const RESERVED_KEYWORDS: [&'static str; 14] = [
    "boolean", "case", "date", "float", "int", "key", "of", "order", "ref", "string", "subtype",
    "type", "unique", "varchar",
];

/// Returns a string that's a copy of `name` but suitably escaped to be a valid
/// QL identifier.
fn escape_name(name: &str) -> String {
    let mut result = String::new();

    // If there's a leading underscore, replace it with 'underscore_'.
    if let Some(c) = name.chars().next() {
        if c == '_' {
            result.push_str("underscore");
        }
    }
    for c in name.chars() {
        match c {
            '{' => result.push_str("lbrace"),
            '}' => result.push_str("rbrace"),
            '<' => result.push_str("langle"),
            '>' => result.push_str("rangle"),
            '[' => result.push_str("lbracket"),
            ']' => result.push_str("rbracket"),
            '(' => result.push_str("lparen"),
            ')' => result.push_str("rparen"),
            '|' => result.push_str("pipe"),
            '=' => result.push_str("equal"),
            '~' => result.push_str("tilde"),
            '?' => result.push_str("question"),
            '`' => result.push_str("backtick"),
            '^' => result.push_str("caret"),
            '!' => result.push_str("bang"),
            '#' => result.push_str("hash"),
            '%' => result.push_str("percent"),
            '&' => result.push_str("ampersand"),
            '.' => result.push_str("dot"),
            ',' => result.push_str("comma"),
            '/' => result.push_str("slash"),
            ':' => result.push_str("colon"),
            ';' => result.push_str("semicolon"),
            '"' => result.push_str("dquote"),
            '*' => result.push_str("star"),
            '+' => result.push_str("plus"),
            '-' => result.push_str("minus"),
            '@' => result.push_str("at"),
            _ if c.is_uppercase() => {
                result.push_str(&c.to_lowercase().to_string());
                result.push('_')
            }
            _ => result.push(c),
        }
    }

    for &keyword in &RESERVED_KEYWORDS {
        if result == keyword {
            result.push_str("__");
            break;
        }
    }

    result
}

/// Given a valid dbscheme name (i.e. in snake case), produces the equivalent QL
/// name (i.e. in CamelCase). For example, "foo_bar_baz" becomes "FooBarBaz".
fn dbscheme_name_to_class_name(dbscheme_name: &str) -> String {
    fn to_title_case(word: &str) -> String {
        let mut first = true;
        let mut result = String::new();
        for c in word.chars() {
            if first {
                first = false;
                result.push(c.to_ascii_uppercase());
            } else {
                result.push(c);
            }
        }
        result
    }
    dbscheme_name
        .split('_')
        .map(|word| to_title_case(word))
        .collect::<Vec<String>>()
        .join("")
}
<commit_msg>fix snake_casing of camelCased identifiers<commit_after>use serde::Deserialize;
use std::collections::BTreeMap;
use std::path::Path;

use std::collections::BTreeSet as Set;
use std::fs;

/// A lookup table from TypeName to Entry.
pub type NodeTypeMap = BTreeMap<TypeName, Entry>;

#[derive(Debug)]
pub struct Entry {
    pub dbscheme_name: String,
    pub ql_class_name: String,
    pub kind: EntryKind,
}

#[derive(Debug)]
pub enum EntryKind {
    Union { members: Set<TypeName> },
    Table { name: String, fields: Vec<Field> },
    Token { kind_id: usize },
}

#[derive(Debug, Ord, PartialOrd, Eq, PartialEq)]
pub struct TypeName {
    pub kind: String,
    pub named: bool,
}

#[derive(Debug)]
pub enum FieldTypeInfo {
    /// The field has a single type.
    Single(TypeName),

    /// The field can take one of several types, so we also provide the name of
    /// the database union type that wraps them, and the corresponding QL class
    /// name.
    Multiple {
        types: Set<TypeName>,
        dbscheme_union: String,
        ql_class: String,
    },

    /// The field can be one of several tokens, so the db type will be an `int`
    /// with a `case @foo.kind` for each possiblity.
    ReservedWordInt(BTreeMap<String, (usize, String)>),
}

#[derive(Debug)]
pub struct Field {
    pub parent: TypeName,
    pub type_info: FieldTypeInfo,
    /// The name of the field or None for the anonymous 'children'
    /// entry from node_types.json
    pub name: Option<String>,
    /// The name of the predicate to get this field.
    pub getter_name: String,
    pub storage: Storage,
}

fn name_for_field_or_child(name: &Option<String>) -> String {
    match name {
        Some(name) => name.clone(),
        None => "child".to_owned(),
    }
}

#[derive(Debug)]
pub enum Storage {
    /// the field is stored as a column in the parent table
    Column { name: String },
    /// the field is stored in a link table, and may or may not have an
    /// associated index column
    Table { name: String, has_index: bool },
}

pub fn read_node_types(node_types_path: &Path) -> std::io::Result<NodeTypeMap> {
    let file = fs::File::open(node_types_path)?;
    let node_types = serde_json::from_reader(file)?;
    Ok(convert_nodes(&node_types))
}

pub fn read_node_types_str(node_types_json: &str) -> std::io::Result<NodeTypeMap> {
    let node_types = serde_json::from_str(node_types_json)?;
    Ok(convert_nodes(&node_types))
}

fn convert_type(node_type: &NodeType) -> TypeName {
    TypeName {
        kind: node_type.kind.to_string(),
        named: node_type.named,
    }
}

fn convert_types(node_types: &Vec<NodeType>) -> Set<TypeName> {
    let iter = node_types.iter().map(convert_type).collect();
    std::collections::BTreeSet::from(iter)
}

pub fn convert_nodes(nodes: &Vec<NodeInfo>) -> NodeTypeMap {
    let mut entries = NodeTypeMap::new();
    let mut token_kinds = Set::new();

    // First, find all the token kinds
    for node in nodes {
        if node.subtypes.is_none() {
            if node.fields.as_ref().map_or(0, |x| x.len()) == 0 && node.children.is_none() {
                let type_name = TypeName {
                    kind: node.kind.clone(),
                    named: node.named,
                };
                token_kinds.insert(type_name);
            }
        }
    }

    for node in nodes {
        let flattened_name = &node_type_name(&node.kind, node.named);
        let dbscheme_name = escape_name(&flattened_name);
        let ql_class_name = dbscheme_name_to_class_name(&dbscheme_name);
        if let Some(subtypes) = &node.subtypes {
            // It's a tree-sitter supertype node, for which we create a union
            // type.
            entries.insert(
                TypeName {
                    kind: node.kind.clone(),
                    named: node.named,
                },
                Entry {
                    dbscheme_name,
                    ql_class_name,
                    kind: EntryKind::Union {
                        members: convert_types(&subtypes),
                    },
                },
            );
        } else if node.fields.as_ref().map_or(0, |x| x.len()) == 0 && node.children.is_none() {
            // Token kind, handled above.
        } else {
            // It's a product type, defined by a table.
            let type_name = TypeName {
                kind: node.kind.clone(),
                named: node.named,
            };
            let table_name = escape_name(&(format!("{}_def", &flattened_name)));
            let mut fields = Vec::new();

            // If the type also has fields or children, then we create either
            // auxiliary tables or columns in the defining table for them.
            if let Some(node_fields) = &node.fields {
                for (field_name, field_info) in node_fields {
                    add_field(
                        &type_name,
                        Some(field_name.to_string()),
                        field_info,
                        &mut fields,
                        &token_kinds,
                    );
                }
            }
            if let Some(children) = &node.children {
                // Treat children as if they were a field called 'child'.
                add_field(&type_name, None, children, &mut fields, &token_kinds);
            }
            entries.insert(
                type_name,
                Entry {
                    dbscheme_name,
                    ql_class_name,
                    kind: EntryKind::Table {
                        name: table_name,
                        fields,
                    },
                },
            );
        }
    }
    let mut counter = 0;
    for type_name in token_kinds {
        let entry = if type_name.named {
            counter += 1;
            let unprefixed_name = node_type_name(&type_name.kind, true);
            Entry {
                dbscheme_name: escape_name(&format!("token_{}", &unprefixed_name)),
                ql_class_name: dbscheme_name_to_class_name(&escape_name(&unprefixed_name)),
                kind: EntryKind::Token { kind_id: counter },
            }
        } else {
            Entry {
                dbscheme_name: "reserved_word".to_owned(),
                ql_class_name: "ReservedWord".to_owned(),
                kind: EntryKind::Token { kind_id: 0 },
            }
        };
        entries.insert(type_name, entry);
    }
    entries
}

fn add_field(
    parent_type_name: &TypeName,
    field_name: Option<String>,
    field_info: &FieldInfo,
    fields: &mut Vec<Field>,
    token_kinds: &Set<TypeName>,
) {
    let parent_flattened_name = node_type_name(&parent_type_name.kind, parent_type_name.named);
    let storage = if !field_info.multiple && field_info.required {
        // This field must appear exactly once, so we add it as
        // a column to the main table for the node type.
        Storage::Column {
            name: escape_name(&name_for_field_or_child(&field_name)),
        }
    } else {
        // Put the field in an auxiliary table.
        let has_index = field_info.multiple;
        let field_table_name = escape_name(&format!(
            "{}_{}",
            parent_flattened_name,
            &name_for_field_or_child(&field_name)
        ));
        Storage::Table {
            has_index,
            name: field_table_name,
        }
    };
    let converted_types = convert_types(&field_info.types);
    let type_info = if field_info
        .types
        .iter()
        .all(|t| !t.named && token_kinds.contains(&convert_type(t)))
    {
        // All possible types for this field are reserved words. The db
        // representation will be an `int` with a `case @foo.field = ...` to
        // enumerate the possible values.
        let mut counter = 0;
        let mut field_token_ints: BTreeMap<String, (usize, String)> = BTreeMap::new();
        for t in converted_types {
            let dbscheme_variant_name =
                escape_name(&format!("{}_{}", parent_flattened_name, t.kind));
            field_token_ints.insert(t.kind.to_owned(), (counter, dbscheme_variant_name));
            counter += 1;
        }
        FieldTypeInfo::ReservedWordInt(field_token_ints)
    } else if field_info.types.len() == 1 {
        FieldTypeInfo::Single(converted_types.into_iter().next().unwrap())
    } else {
        // The dbscheme type for this field will be a union. In QL, it'll just be AstNode.
        FieldTypeInfo::Multiple {
            types: converted_types,
            dbscheme_union: format!(
                "{}_{}_type",
                &parent_flattened_name,
                &name_for_field_or_child(&field_name)
            ),
            ql_class: "AstNode".to_owned(),
        }
    };
    let getter_name = format!(
        "get{}",
        dbscheme_name_to_class_name(&escape_name(&name_for_field_or_child(&field_name)))
    );
    fields.push(Field {
        parent: TypeName {
            kind: parent_type_name.kind.to_string(),
            named: parent_type_name.named,
        },
        type_info,
        name: field_name,
        getter_name,
        storage,
    });
}
#[derive(Deserialize)]
pub struct NodeInfo {
    #[serde(rename = "type")]
    pub kind: String,
    pub named: bool,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub fields: Option<BTreeMap<String, FieldInfo>>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub children: Option<FieldInfo>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub subtypes: Option<Vec<NodeType>>,
}

#[derive(Deserialize)]
pub struct NodeType {
    #[serde(rename = "type")]
    pub kind: String,
    pub named: bool,
}

#[derive(Deserialize)]
pub struct FieldInfo {
    pub multiple: bool,
    pub required: bool,
    pub types: Vec<NodeType>,
}

/// Given a tree-sitter node type's (kind, named) pair, returns a single string
/// representing the (unescaped) name we'll use to refer to corresponding QL
/// type.
fn node_type_name(kind: &str, named: bool) -> String {
    if named {
        kind.to_string()
    } else {
        format!("{}_unnamed", kind)
    }
}

const RESERVED_KEYWORDS: [&'static str; 14] = [
    "boolean", "case", "date", "float", "int", "key", "of", "order", "ref", "string", "subtype",
    "type", "unique", "varchar",
];

/// Returns a string that's a copy of `name` but suitably escaped to be a valid
/// QL identifier.
fn escape_name(name: &str) -> String {
    let mut result = String::new();

    // If there's a leading underscore, replace it with 'underscore_'.
    if let Some(c) = name.chars().next() {
        if c == '_' {
            result.push_str("underscore");
        }
    }
    for c in name.chars() {
        match c {
            '{' => result.push_str("lbrace"),
            '}' => result.push_str("rbrace"),
            '<' => result.push_str("langle"),
            '>' => result.push_str("rangle"),
            '[' => result.push_str("lbracket"),
            ']' => result.push_str("rbracket"),
            '(' => result.push_str("lparen"),
            ')' => result.push_str("rparen"),
            '|' => result.push_str("pipe"),
            '=' => result.push_str("equal"),
            '~' => result.push_str("tilde"),
            '?' => result.push_str("question"),
            '`' => result.push_str("backtick"),
            '^' => result.push_str("caret"),
            '!' => result.push_str("bang"),
            '#' => result.push_str("hash"),
            '%' => result.push_str("percent"),
            '&' => result.push_str("ampersand"),
            '.' => result.push_str("dot"),
            ',' => result.push_str("comma"),
            '/' => result.push_str("slash"),
            ':' => result.push_str("colon"),
            ';' => result.push_str("semicolon"),
            '"' => result.push_str("dquote"),
            '*' => result.push_str("star"),
            '+' => result.push_str("plus"),
            '-' => result.push_str("minus"),
            '@' => result.push_str("at"),
            _ if c.is_uppercase() => {
                result.push('_');
                result.push_str(&c.to_lowercase().to_string())
            }
            _ => result.push(c),
        }
    }

    for &keyword in &RESERVED_KEYWORDS {
        if result == keyword {
            result.push_str("__");
            break;
        }
    }

    result
}

/// Given a valid dbscheme name (i.e. in snake case), produces the equivalent QL
/// name (i.e. in CamelCase). For example, "foo_bar_baz" becomes "FooBarBaz".
fn dbscheme_name_to_class_name(dbscheme_name: &str) -> String {
    fn to_title_case(word: &str) -> String {
        let mut first = true;
        let mut result = String::new();
        for c in word.chars() {
            if first {
                first = false;
                result.push(c.to_ascii_uppercase());
            } else {
                result.push(c);
            }
        }
        result
    }
    dbscheme_name
        .split('_')
        .map(|word| to_title_case(word))
        .collect::<Vec<String>>()
        .join("")
}
<|endoftext|>


<commit_before>//! Paths and Unix shells
//!
//! MacOS, Linux, FreeBSD, and many other OS model their design on Unix,
//! so handling them is relatively consistent. But only relatively.
//! POSIX postdates Unix by 20 years, and each "Unix-like" shell develops
//! unique quirks over time.
//!
//!
//! Windowing Managers, Desktop Environments, GUI Terminals, and PATHs
//!
//! Duplicating paths in PATH can cause performance issues when the OS searches
//! the same place multiple times. Traditionally, Unix configurations have
//! resolved this by setting up PATHs in the shell's login profile.
//!
//! This has its own issues. Login profiles are only intended to run once, but
//! changing the PATH is common enough that people may run it twice. Desktop
//! environments often choose to NOT start login shells in GUI terminals. Thus,
//! a trend has emerged to place PATH updates in other run-commands (rc) files,
//! leaving Rustup with few assumptions to build on for fulfilling its promise
//! to set up PATH appropriately.
//!
//! Rustup addresses this by:
//! 1) using a shell script that updates PATH if the path is not in PATH
//! 2) sourcing this script in any known and appropriate rc file

use super::*;
use crate::process;
use error_chain::bail;
use std::path::PathBuf;

pub type Shell = Box<dyn UnixShell>;

#[derive(Debug, PartialEq)]
pub struct ShellScript {
    content: &'static str,
    name: &'static str,
}

impl ShellScript {
    pub fn write(&self) -> Result<()> {
        let home = utils::cargo_home()?;
        let cargo_bin = format!("{}/bin", cargo_home_str()?);
        let env_name = home.join(self.name);
        let env_file = self.content.replace("{cargo_bin}", &cargo_bin);
        utils::write_file(self.name, &env_name, &env_file)?;
        Ok(())
    }
}

// TODO: Update into a bytestring.
pub fn cargo_home_str() -> Result<Cow<'static, str>> {
    let path = utils::cargo_home()?;

    let default_cargo_home = utils::home_dir()
        .unwrap_or_else(|| PathBuf::from("."))
        .join(".cargo");
    Ok(if default_cargo_home == path {
        "$HOME/.cargo".into()
    } else {
        match path.to_str() {
            Some(p) => p.to_owned().into(),
            None => bail!("Non-Unicode path!"),
        }
    })
}

// TODO: Tcsh (BSD)
// TODO?: Make a decision on Ion Shell, Power Shell, Nushell
// Cross-platform non-POSIX shells have not been assessed for integration yet
fn enumerate_shells() -> Vec<Shell> {
    vec![Box::new(Posix), Box::new(Bash), Box::new(Zsh)]
}

pub fn get_available_shells() -> impl Iterator<Item = Shell> {
    enumerate_shells().into_iter().filter(|sh| sh.does_exist())
}

pub trait UnixShell {
    // Detects if a shell "exists". Users have multiple shells, so an "eager"
    // heuristic should be used, assuming shells exist if any traces do.
    fn does_exist(&self) -> bool;

    // Gives all rcfiles of a given shell that rustup is concerned with.
    // Used primarily in checking rcfiles for cleanup.
    fn rcfiles(&self) -> Vec<PathBuf>;

    // Gives rcs that should be written to.
    fn update_rcs(&self) -> Vec<PathBuf>;

    // Writes the relevant env file.
    fn env_script(&self) -> ShellScript {
        ShellScript {
            name: "env.sh",
            content: include_str!("env.sh"),
        }
    }

    fn source_string(&self) -> Result<String> {
        Ok(format!(r#"source "{}/env.sh""#, cargo_home_str()?))
    }
}

struct Posix;
impl UnixShell for Posix {
    fn does_exist(&self) -> bool {
        true
    }

    fn rcfiles(&self) -> Vec<PathBuf> {
        match utils::home_dir() {
            Some(dir) => vec![dir.join(".profile")],
            _ => vec![],
        }
    }

    fn update_rcs(&self) -> Vec<PathBuf> {
        // Write to .profile even if it doesn't exist.
        self.rcfiles()
    }
}

struct Bash;

impl UnixShell for Bash {
    fn does_exist(&self) -> bool {
        self.update_rcs().len() > 0
    }

    fn rcfiles(&self) -> Vec<PathBuf> {
        [".bash_profile", ".bash_login", ".profile", ".bashrc"]
            .iter()
            .filter_map(|rc| utils::home_dir().map(|dir| dir.join(rc)))
            .collect()
    }

    fn update_rcs(&self) -> Vec<PathBuf> {
        self.rcfiles()
            .into_iter()
            .filter(|rc| rc.is_file())
            .collect()
    }
}

struct Zsh;

impl Zsh {
    fn zdotdir() -> Result<PathBuf> {
        use std::ffi::OsStr;
        use std::os::unix::ffi::OsStrExt;

        if matches!(process().var("SHELL"), Ok(sh) if sh.contains("zsh")) {
            match process().var("ZDOTDIR") {
                Ok(dir) if dir.len() > 0 => Ok(PathBuf::from(dir)),
                _ => bail!("Zsh setup failed."),
            }
        } else if utils::find_cmd(&["zsh"]) == Some("zsh") {
            match std::process::Command::new("zsh")
                .args(&["-c", "'echo $ZDOTDIR'"])
                .output()
            {
                Ok(io) if io.stdout.len() > 0 => Ok(PathBuf::from(OsStr::from_bytes(&io.stdout))),
                _ => bail!("Zsh setup failed."),
            }
        } else {
            bail!("What? Unpossible.")
        }
    }
}

impl UnixShell for Zsh {
    fn does_exist(&self) -> bool {
        // zsh has to either be the shell or be callable for zsh setup.
        matches!(process().var("SHELL"), Ok(sh) if sh.contains("zsh"))
            || matches!(utils::find_cmd(&["zsh"]), Some(sh) if sh.contains("zsh"))
    }

    fn rcfiles(&self) -> Vec<PathBuf> {
        [Zsh::zdotdir().ok(), utils::home_dir()]
            .iter()
            .filter_map(|dir| dir.as_ref().map(|p| p.join(".zshenv")))
            .collect()
    }

    fn update_rcs(&self) -> Vec<PathBuf> {
        // zsh can change $ZDOTDIR both _before_ AND _during_ reading .zshenv,
        // so we: write to $ZDOTDIR/.zshenv if-exists ($ZDOTDIR changes before)
        // OR write to $HOME/.zshenv if it exists (change-during)
        // if neither exist, we create it ourselves, but using the same logic,
        // because we must still respond to whether $ZDOTDIR is set or unset.
        // In any case we only write once.
        self.rcfiles()
            .into_iter()
            .filter(|env| env.is_file())
            .chain(self.rcfiles().into_iter())
            .take(1)
            .collect()
    }
}

pub fn legacy_paths() -> impl Iterator<Item = PathBuf> {
    let zprofiles = Zsh::zdotdir()
        .into_iter()
        .chain(utils::home_dir())
        .map(|d| d.join(".zprofile"));
    let profiles = [".bash_profile", ".profile"]
        .iter()
        .filter_map(|rc| utils::home_dir().map(|d| d.join(rc)));

    profiles.chain(zprofiles)
}
<commit_msg>Fix an incorrect comparison in impl Zsh<commit_after>//! Paths and Unix shells
//!
//! MacOS, Linux, FreeBSD, and many other OS model their design on Unix,
//! so handling them is relatively consistent. But only relatively.
//! POSIX postdates Unix by 20 years, and each "Unix-like" shell develops
//! unique quirks over time.
//!
//!
//! Windowing Managers, Desktop Environments, GUI Terminals, and PATHs
//!
//! Duplicating paths in PATH can cause performance issues when the OS searches
//! the same place multiple times. Traditionally, Unix configurations have
//! resolved this by setting up PATHs in the shell's login profile.
//!
//! This has its own issues. Login profiles are only intended to run once, but
//! changing the PATH is common enough that people may run it twice. Desktop
//! environments often choose to NOT start login shells in GUI terminals. Thus,
//! a trend has emerged to place PATH updates in other run-commands (rc) files,
//! leaving Rustup with few assumptions to build on for fulfilling its promise
//! to set up PATH appropriately.
//!
//! Rustup addresses this by:
//! 1) using a shell script that updates PATH if the path is not in PATH
//! 2) sourcing this script in any known and appropriate rc file

use super::*;
use crate::process;
use error_chain::bail;
use std::path::PathBuf;

pub type Shell = Box<dyn UnixShell>;

#[derive(Debug, PartialEq)]
pub struct ShellScript {
    content: &'static str,
    name: &'static str,
}

impl ShellScript {
    pub fn write(&self) -> Result<()> {
        let home = utils::cargo_home()?;
        let cargo_bin = format!("{}/bin", cargo_home_str()?);
        let env_name = home.join(self.name);
        let env_file = self.content.replace("{cargo_bin}", &cargo_bin);
        utils::write_file(self.name, &env_name, &env_file)?;
        Ok(())
    }
}

// TODO: Update into a bytestring.
pub fn cargo_home_str() -> Result<Cow<'static, str>> {
    let path = utils::cargo_home()?;

    let default_cargo_home = utils::home_dir()
        .unwrap_or_else(|| PathBuf::from("."))
        .join(".cargo");
    Ok(if default_cargo_home == path {
        "$HOME/.cargo".into()
    } else {
        match path.to_str() {
            Some(p) => p.to_owned().into(),
            None => bail!("Non-Unicode path!"),
        }
    })
}

// TODO: Tcsh (BSD)
// TODO?: Make a decision on Ion Shell, Power Shell, Nushell
// Cross-platform non-POSIX shells have not been assessed for integration yet
fn enumerate_shells() -> Vec<Shell> {
    vec![Box::new(Posix), Box::new(Bash), Box::new(Zsh)]
}

pub fn get_available_shells() -> impl Iterator<Item = Shell> {
    enumerate_shells().into_iter().filter(|sh| sh.does_exist())
}

pub trait UnixShell {
    // Detects if a shell "exists". Users have multiple shells, so an "eager"
    // heuristic should be used, assuming shells exist if any traces do.
    fn does_exist(&self) -> bool;

    // Gives all rcfiles of a given shell that rustup is concerned with.
    // Used primarily in checking rcfiles for cleanup.
    fn rcfiles(&self) -> Vec<PathBuf>;

    // Gives rcs that should be written to.
    fn update_rcs(&self) -> Vec<PathBuf>;

    // Writes the relevant env file.
    fn env_script(&self) -> ShellScript {
        ShellScript {
            name: "env.sh",
            content: include_str!("env.sh"),
        }
    }

    fn source_string(&self) -> Result<String> {
        Ok(format!(r#"source "{}/env.sh""#, cargo_home_str()?))
    }
}

struct Posix;
impl UnixShell for Posix {
    fn does_exist(&self) -> bool {
        true
    }

    fn rcfiles(&self) -> Vec<PathBuf> {
        match utils::home_dir() {
            Some(dir) => vec![dir.join(".profile")],
            _ => vec![],
        }
    }

    fn update_rcs(&self) -> Vec<PathBuf> {
        // Write to .profile even if it doesn't exist.
        self.rcfiles()
    }
}

struct Bash;

impl UnixShell for Bash {
    fn does_exist(&self) -> bool {
        self.update_rcs().len() > 0
    }

    fn rcfiles(&self) -> Vec<PathBuf> {
        [".bash_profile", ".bash_login", ".bashrc"]
            .iter()
            .filter_map(|rc| utils::home_dir().map(|dir| dir.join(rc)))
            .collect()
    }

    fn update_rcs(&self) -> Vec<PathBuf> {
        self.rcfiles()
            .into_iter()
            .filter(|rc| rc.is_file())
            .collect()
    }
}

struct Zsh;

impl Zsh {
    fn zdotdir() -> Result<PathBuf> {
        use std::ffi::OsStr;
        use std::os::unix::ffi::OsStrExt;

        if matches!(process().var("SHELL"), Ok(sh) if sh.contains("zsh")) {
            match process().var("ZDOTDIR") {
                Ok(dir) if dir.len() > 0 => Ok(PathBuf::from(dir)),
                _ => bail!("Zsh setup failed."),
            }
        } else {
            match std::process::Command::new("zsh")
                .args(&["-c", "'echo $ZDOTDIR'"])
                .output()
            {
                Ok(io) if io.stdout.len() > 0 => Ok(PathBuf::from(OsStr::from_bytes(&io.stdout))),
                _ => bail!("Zsh setup failed."),
            }
        }
    }
}

impl UnixShell for Zsh {
    fn does_exist(&self) -> bool {
        // zsh has to either be the shell or be callable for zsh setup.
        matches!(process().var("SHELL"), Ok(sh) if sh.contains("zsh"))
            || matches!(utils::find_cmd(&["zsh"]), Some(sh) if sh.contains("zsh"))
    }

    fn rcfiles(&self) -> Vec<PathBuf> {
        [Zsh::zdotdir().ok(), utils::home_dir()]
            .iter()
            .filter_map(|dir| dir.as_ref().map(|p| p.join(".zshenv")))
            .collect()
    }

    fn update_rcs(&self) -> Vec<PathBuf> {
        // zsh can change $ZDOTDIR both _before_ AND _during_ reading .zshenv,
        // so we: write to $ZDOTDIR/.zshenv if-exists ($ZDOTDIR changes before)
        // OR write to $HOME/.zshenv if it exists (change-during)
        // if neither exist, we create it ourselves, but using the same logic,
        // because we must still respond to whether $ZDOTDIR is set or unset.
        // In any case we only write once.
        self.rcfiles()
            .into_iter()
            .filter(|env| env.is_file())
            .chain(self.rcfiles().into_iter())
            .take(1)
            .collect()
    }
}

pub fn legacy_paths() -> impl Iterator<Item = PathBuf> {
    let zprofiles = Zsh::zdotdir()
        .into_iter()
        .chain(utils::home_dir())
        .map(|d| d.join(".zprofile"));
    let profiles = [".bash_profile", ".profile"]
        .iter()
        .filter_map(|rc| utils::home_dir().map(|d| d.join(rc)));

    profiles.chain(zprofiles)
}
<|endoftext|>


<commit_before>use std::mem;

use runtime::{Class, Sel};

pub struct Encoding<T>(&'static str);

pub trait Encode {
	fn code() -> Encoding<Self>;
}

impl Encode for i8 {
	fn code() -> Encoding<i8> { Encoding("c") }
}

impl Encode for i16 {
	fn code() -> Encoding<i16> { Encoding("s") }
}

impl Encode for i32 {
	fn code() -> Encoding<i32> { Encoding("i") }
}

impl Encode for i64 {
	fn code() -> Encoding<i64> { Encoding("q") }
}

impl Encode for int {
	fn code() -> Encoding<int> {
		match mem::size_of::<int>() {
			1 => Encoding("c"),
			2 => Encoding("s"),
			4 => Encoding("i"),
			8 => Encoding("q"),
			_ => Encoding("?"),
		}
	}
}

impl Encode for u8 {
	fn code() -> Encoding<u8> { Encoding("C") }
}

impl Encode for u16 {
	fn code() -> Encoding<u16> { Encoding("S") }
}

impl Encode for u32 {
	fn code() -> Encoding<u32> { Encoding("I") }
}

impl Encode for u64 {
	fn code() -> Encoding<u64> { Encoding("Q") }
}

impl Encode for uint {
	fn code() -> Encoding<uint> {
		match mem::size_of::<uint>() {
			1 => Encoding("C"),
			2 => Encoding("S"),
			4 => Encoding("I"),
			8 => Encoding("Q"),
			_ => Encoding("?"),
		}
	}
}

impl Encode for f32 {
	fn code() -> Encoding<f32> { Encoding("f") }
}

impl Encode for f64 {
	fn code() -> Encoding<f64> { Encoding("d") }
}

impl Encode for bool {
	fn code() -> Encoding<bool> { Encoding("B") }
}

impl Encode for () {
	fn code() -> Encoding<()> { Encoding("v") }
}

impl Encode for Class {
	fn code() -> Encoding<Class> { Encoding("#") }
}

impl Encode for Sel {
	fn code() -> Encoding<Sel> { Encoding(":") }
}

pub fn encode<T: Encode>() -> &'static str {
	let Encoding(code): Encoding<T> = Encode::code();
	code
}

#[cfg(test)]
mod tests {
	use runtime::{Class, Sel};
	use super::encode;

	#[test]
	fn test_encode() {
		assert!(encode::<u32>() == "I");
		assert!(encode::<()>() == "v");
		assert!(encode::<Class>() == "#");
		assert!(encode::<Sel>() == ":");
	}
}
<commit_msg>Implemented Encode for objects.<commit_after>use std::mem;

use runtime::{Class, Message, Sel};

pub struct Encoding<T>(&'static str);

pub trait Encode {
	fn code() -> Encoding<Self>;
}

impl Encode for i8 {
	fn code() -> Encoding<i8> { Encoding("c") }
}

impl Encode for i16 {
	fn code() -> Encoding<i16> { Encoding("s") }
}

impl Encode for i32 {
	fn code() -> Encoding<i32> { Encoding("i") }
}

impl Encode for i64 {
	fn code() -> Encoding<i64> { Encoding("q") }
}

impl Encode for int {
	fn code() -> Encoding<int> {
		match mem::size_of::<int>() {
			1 => Encoding("c"),
			2 => Encoding("s"),
			4 => Encoding("i"),
			8 => Encoding("q"),
			_ => Encoding("?"),
		}
	}
}

impl Encode for u8 {
	fn code() -> Encoding<u8> { Encoding("C") }
}

impl Encode for u16 {
	fn code() -> Encoding<u16> { Encoding("S") }
}

impl Encode for u32 {
	fn code() -> Encoding<u32> { Encoding("I") }
}

impl Encode for u64 {
	fn code() -> Encoding<u64> { Encoding("Q") }
}

impl Encode for uint {
	fn code() -> Encoding<uint> {
		match mem::size_of::<uint>() {
			1 => Encoding("C"),
			2 => Encoding("S"),
			4 => Encoding("I"),
			8 => Encoding("Q"),
			_ => Encoding("?"),
		}
	}
}

impl Encode for f32 {
	fn code() -> Encoding<f32> { Encoding("f") }
}

impl Encode for f64 {
	fn code() -> Encoding<f64> { Encoding("d") }
}

impl Encode for bool {
	fn code() -> Encoding<bool> { Encoding("B") }
}

impl Encode for () {
	fn code() -> Encoding<()> { Encoding("v") }
}

impl<'a, T: Message> Encode for &'a T {
	fn code() -> Encoding<&'a T> { Encoding("@") }
}

impl<'a, T: Message> Encode for &'a mut T {
	fn code() -> Encoding<&'a mut T> { Encoding("@") }
}

impl<T: Message> Encode for *const T {
	fn code() -> Encoding<*const T> { Encoding("@") }
}

impl<T: Message> Encode for *mut T {
	fn code() -> Encoding<*mut T> { Encoding("@") }
}

impl Encode for Class {
	fn code() -> Encoding<Class> { Encoding("#") }
}

impl Encode for Sel {
	fn code() -> Encoding<Sel> { Encoding(":") }
}

pub fn encode<T: Encode>() -> &'static str {
	let Encoding(code): Encoding<T> = Encode::code();
	code
}

#[cfg(test)]
mod tests {
	use runtime::{Class, Object, Sel};
	use super::encode;

	#[test]
	fn test_encode() {
		assert!(encode::<u32>() == "I");
		assert!(encode::<()>() == "v");
		assert!(encode::<&Object>() == "@");
		assert!(encode::<*mut Object>() == "@");
		assert!(encode::<Class>() == "#");
		assert!(encode::<Sel>() == ":");
	}
}
<|endoftext|>


<commit_before>pub fn factors(n: u32) -> Vec<u32> {
    unimplemented!("This should calculate the prime factors of {}", n)
}
<commit_msg>prime-factors: replace u32 with u64 in stub<commit_after>pub fn factors(n: u64) -> Vec<u64> {
    unimplemented!("This should calculate the prime factors of {}", n)
}
<|endoftext|>


<commit_before>#![crate_type="dylib"]
#![feature(plugin_registrar)]

// basic syntax extension to calculate the factorial of 10
// at compile time for the compile-time calculation
// task (the task itself is in compile_time_calculation.rs)
extern crate syntax;
extern crate rustc;

use syntax::ast;
use syntax::codemap::Span;
use syntax::parse;
use syntax::parse::token;
use syntax::ast::TokenTree;
use syntax::ext::base::{ExtCtxt, MacResult, DummyResult, MacExpr};
use syntax::ext::build::AstBuilder;  // trait for expr_uint
use rustc::plugin::Registry;

use std::iter::range_inclusive;

fn exp_factorial(cx: &mut ExtCtxt, sp: Span, tts: &[TokenTree])
        -> Box<MacResult + 'static> {
    // extract the argument and ensure there is only one and it's a uint
    let mut parser = parse::new_parser_from_tts(cx.parse_sess(), cx.cfg(), tts.to_vec());

    // Try to parse a literal (doesn't need to be a number)
    let literal = if parser.token != token::EOF {
        parser.parse_lit()
    } else {
        // span_err shows a compile time error to the user
        cx.span_err(sp, "Unexpected end of file");
        return DummyResult::any(sp);
    };

    // Take the number of the literal (if it is a number)
    let n: u64 = match literal.node {
        ast::LitInt(x, _) => x,
         _              => {
            cx.span_err(sp, "Invalid literal (expected unsigned integer)");
            return DummyResult::any(sp);
        }
    };

    // calculating the factorial
    let result = range_inclusive(1u, n as uint).fold(1, |accum, elem| accum * elem);

    MacExpr::new(cx.expr_uint(sp, result))
}

// here's where we register the macro with the name of factorial_10
// so that it can be invoked a with every other macro with a ! at the end
#[plugin_registrar]
pub fn plugin_registrar(reg: &mut Registry) {
    reg.register_macro("factorial", exp_factorial);
}<commit_msg>Replaced syntax::parse::token::EOF with Eof<commit_after>#![crate_type="dylib"]
#![feature(plugin_registrar)]

// basic syntax extension to calculate the factorial of 10
// at compile time for the compile-time calculation
// task (the task itself is in compile_time_calculation.rs)
extern crate syntax;
extern crate rustc;

use syntax::ast;
use syntax::codemap::Span;
use syntax::parse;
use syntax::parse::token;
use syntax::ast::TokenTree;
use syntax::ext::base::{ExtCtxt, MacResult, DummyResult, MacExpr};
use syntax::ext::build::AstBuilder;  // trait for expr_uint
use rustc::plugin::Registry;

use std::iter::range_inclusive;

fn exp_factorial(cx: &mut ExtCtxt, sp: Span, tts: &[TokenTree])
        -> Box<MacResult + 'static> {
    // extract the argument and ensure there is only one and it's a uint
    let mut parser = parse::new_parser_from_tts(cx.parse_sess(), cx.cfg(), tts.to_vec());

    // Try to parse a literal (doesn't need to be a number)
    let literal = if parser.token != token::Eof {
        parser.parse_lit()
    } else {
        // span_err shows a compile time error to the user
        cx.span_err(sp, "Unexpected end of file");
        return DummyResult::any(sp);
    };

    // Take the number of the literal (if it is a number)
    let n: u64 = match literal.node {
        ast::LitInt(x, _) => x,
         _              => {
            cx.span_err(sp, "Invalid literal (expected unsigned integer)");
            return DummyResult::any(sp);
        }
    };

    // calculating the factorial
    let result = range_inclusive(1u, n as uint).fold(1, |accum, elem| accum * elem);

    MacExpr::new(cx.expr_uint(sp, result))
}

// here's where we register the macro with the name of factorial_10
// so that it can be invoked a with every other macro with a ! at the end
#[plugin_registrar]
pub fn plugin_registrar(reg: &mut Registry) {
    reg.register_macro("factorial", exp_factorial);
}
<|endoftext|>


<commit_before>extern crate gcc;

fn main() {
    gcc::Config::new()
                .cpp(true)
                .flag("-std=c++11")
                .flag("-O3")
                .flag("-mssse3")
                .include("./cpp/SIMDCompressionAndIntersection/include")
                .object("cpp/SIMDCompressionAndIntersection/bitpacking.o")
                .object("cpp/SIMDCompressionAndIntersection/integratedbitpacking.o")
                .object("cpp/SIMDCompressionAndIntersection/simdbitpacking.o")
                .object("cpp/SIMDCompressionAndIntersection/usimdbitpacking.o")
                .object("cpp/SIMDCompressionAndIntersection/simdintegratedbitpacking.o")
                .object("cpp/SIMDCompressionAndIntersection/intersection.o")
                .object("cpp/SIMDCompressionAndIntersection/varintdecode.o")
                .object("cpp/SIMDCompressionAndIntersection/streamvbyte.o")
                .object("cpp/SIMDCompressionAndIntersection/simdpackedsearch.o")
                .object("cpp/SIMDCompressionAndIntersection/simdpackedselect.o")
                .object("cpp/SIMDCompressionAndIntersection/frameofreference.o")
                .object("cpp/SIMDCompressionAndIntersection/for.o")
                .file("cpp/encode.cpp")
                .compile("libsimdcompression.a");
    println!("cargo:rustc-flags=-l dylib=stdc++");
}
<commit_msg>Added make to the build command.<commit_after>extern crate gcc;

use std::process::Command;

fn main() {
    Command::new("make")
        .current_dir("cpp/SIMDCompressionAndIntersection")
        .output()
        .unwrap_or_else(|e| { panic!("Failed to make SIMDCompressionAndIntersection: {}", e) });
    gcc::Config::new()
                .cpp(true)
                .flag("-std=c++11")
                .flag("-O3")
                .flag("-mssse3")
                .include("./cpp/SIMDCompressionAndIntersection/include")
                .object("cpp/SIMDCompressionAndIntersection/bitpacking.o")
                .object("cpp/SIMDCompressionAndIntersection/integratedbitpacking.o")
                .object("cpp/SIMDCompressionAndIntersection/simdbitpacking.o")
                .object("cpp/SIMDCompressionAndIntersection/usimdbitpacking.o")
                .object("cpp/SIMDCompressionAndIntersection/simdintegratedbitpacking.o")
                .object("cpp/SIMDCompressionAndIntersection/intersection.o")
                .object("cpp/SIMDCompressionAndIntersection/varintdecode.o")
                .object("cpp/SIMDCompressionAndIntersection/streamvbyte.o")
                .object("cpp/SIMDCompressionAndIntersection/simdpackedsearch.o")
                .object("cpp/SIMDCompressionAndIntersection/simdpackedselect.o")
                .object("cpp/SIMDCompressionAndIntersection/frameofreference.o")
                .object("cpp/SIMDCompressionAndIntersection/for.o")
                .file("cpp/encode.cpp")
                .compile("libsimdcompression.a");
    println!("cargo:rustc-flags=-l dylib=stdc++");
}
<|endoftext|>


<commit_before>extern crate embed_resource;
#[cfg(not(any(target_os = "windows", target_os = "macos")))]
extern crate cc;

#[cfg(not(any(target_os = "windows", target_os = "macos")))]
use std::env;
#[cfg(not(any(target_os = "windows", target_os = "macos")))]
use std::io::Write;
#[cfg(not(any(target_os = "windows", target_os = "macos")))]
use std::path::Path;
#[cfg(not(any(target_os = "windows", target_os = "macos")))]
use std::fs::{self, File};

/// The last line of this, after running it through a preprocessor, will expand to the value of `BLKGETSIZE`
#[cfg(not(any(target_os = "windows", target_os = "macos")))]
static IOCTL_CHECK_SOURCE: &str = r#"
#include <sys/mount.h>

BLKGETSIZE
"#;

/// Replace `{}` with the `BLKGETSIZE` expression from `IOCTL_CHECK_SOURCE`
#[cfg(not(any(target_os = "windows", target_os = "macos")))]
static IOCTL_INCLUDE_SKELETON: &str = r#"
/// Return `device size / 512` (`long *` arg)
static BLKGETSIZE: c_ulong = {};
"#;

fn main() {
    embed_resources();
    get_ioctl_data();
}

fn embed_resources() {
    embed_resource::compile("http-manifest.rc");
}

#[cfg(any(target_os = "windows", target_os = "macos"))]
fn get_ioctl_data() {}

#[cfg(not(any(target_os = "windows", target_os = "macos")))]
fn get_ioctl_data() {
    let ioctl_dir = Path::new(&env::var("OUT_DIR").unwrap()).join("ioctl-data");
    fs::create_dir_all(&ioctl_dir).unwrap();

    let ioctl_source = ioctl_dir.join("ioctl.c");
    File::create(&ioctl_source).unwrap().write_all(IOCTL_CHECK_SOURCE.as_bytes()).unwrap();

    let ioctl_preprocessed = String::from_utf8(cc::Build::new().file(ioctl_source).expand()).unwrap();
    let blkgetsize_expr = ioctl_preprocessed.lines().next_back().unwrap().replace("U", " as c_ulong");

    let ioctl_include = ioctl_dir.join("ioctl.rs");
    File::create(&ioctl_include).unwrap().write_all(IOCTL_INCLUDE_SKELETON.replace("{}", &blkgetsize_expr).as_bytes()).unwrap();
}
<commit_msg>Change BLKGETSIZE to c_int on musl target<commit_after>extern crate embed_resource;
#[cfg(not(any(target_os = "windows", target_os = "macos")))]
extern crate cc;

#[cfg(not(any(target_os = "windows", target_os = "macos")))]
use std::env;
#[cfg(not(any(target_os = "windows", target_os = "macos")))]
use std::io::Write;
#[cfg(not(any(target_os = "windows", target_os = "macos")))]
use std::path::Path;
#[cfg(not(any(target_os = "windows", target_os = "macos")))]
use std::fs::{self, File};

/// The last line of this, after running it through a preprocessor, will expand to the value of `BLKGETSIZE`
#[cfg(not(any(target_os = "windows", target_os = "macos")))]
static IOCTL_CHECK_SOURCE: &str = r#"
#include <sys/mount.h>

BLKGETSIZE
"#;

/// Replace `{}` with the `BLKGETSIZE` expression from `IOCTL_CHECK_SOURCE`
#[cfg(not(any(target_os = "windows", target_os = "macos")))]
static IOCTL_INCLUDE_SKELETON: &str = r#"
/// Return `device size / 512` (`long *` arg)
static BLKGETSIZE: {type} = {expr} as {type};
"#;

#[cfg(all(not(any(target_os = "windows", target_os = "macos")), not(target_env = "musl")))]
static IOCTL_REQUEST_TYPE: &str = "libc::c_ulong";

#[cfg(all(not(any(target_os = "windows", target_os = "macos")), target_env = "musl"))]
static IOCTL_REQUEST_TYPE: &str = "libc::c_int";

fn main() {
    embed_resources();
    get_ioctl_data();
}

fn embed_resources() {
    embed_resource::compile("http-manifest.rc");
}

#[cfg(any(target_os = "windows", target_os = "macos"))]
fn get_ioctl_data() {}

#[cfg(not(any(target_os = "windows", target_os = "macos")))]
fn get_ioctl_data() {
    let ioctl_dir = Path::new(&env::var("OUT_DIR").unwrap()).join("ioctl-data");
    fs::create_dir_all(&ioctl_dir).unwrap();

    let ioctl_source = ioctl_dir.join("ioctl.c");
    File::create(&ioctl_source).unwrap().write_all(IOCTL_CHECK_SOURCE.as_bytes()).unwrap();

    let ioctl_preprocessed = String::from_utf8(cc::Build::new().file(ioctl_source).expand()).unwrap();
    let blkgetsize_expr = ioctl_preprocessed.lines().next_back().unwrap().replace("U", "");

    let ioctl_include = ioctl_dir.join("ioctl.rs");
    File::create(&ioctl_include)
        .unwrap()
        .write_all(IOCTL_INCLUDE_SKELETON.replace("{type}", IOCTL_REQUEST_TYPE).replace("{expr}", &blkgetsize_expr).as_bytes())
        .unwrap();
}
<|endoftext|>


<commit_before>// Compiles the `rsmpi` C shim library.
extern crate gcc;
// Generates the Rust header for the C API.
extern crate bindgen;
// Finds out information about the MPI library
extern crate build_probe_mpi;
// Inspect version of rustc compiler
extern crate rustc_version;

use std::env;
use std::path::Path;

fn main() {
    // Use `mpicc` wrapper rather than the system C compiler.
    env::set_var("CC", "mpicc");
    // Build the `rsmpi` C shim library.
    gcc::compile_library("librsmpi.a", &["src/ffi/rsmpi.c"]);

    // Try to find an MPI library
    let lib = match build_probe_mpi::probe() {
        Ok(lib) => lib,
        Err(errs) => {
            println!("Could not find MPI library for various reasons:\n");
            for (i, err) in errs.iter().enumerate() {
                println!("Reason #{}:\n{}\n", i, err);
            }
            panic!();
        }
    };

    // Let `rustc` know about the library search directories.
    for dir in &lib.lib_paths {
        println!("cargo:rustc-link-search=native={}", dir.display());
    }
    for lib in &lib.libs {
        println!("cargo:rustc-link-lib={}", lib);
    }

    let mut builder = bindgen::builder();
    // Let `bindgen` know about libraries and search directories.
    for lib in &lib.libs { builder = builder.link(lib.clone()); }
    for dir in &lib.lib_paths { builder = builder.clang_arg(format!("-L{}", dir.display())); }
    for dir in &lib.include_paths { builder = builder.clang_arg(format!("-I{}", dir.display())); }

    // Generate Rust bindings for the MPI C API.
    let bindings = builder
        .header("src/ffi/rsmpi.h")
        .emit_builtins()
        .no_unstable_rust()
        .hide_type("mpich_struct_mpi_long_double_int")
        .generate()
        .unwrap();

    // Write the bindings to disk.
    let out_dir = env::var("OUT_DIR").expect("cargo did not set OUT_DIR");
    let out_file = Path::new(&out_dir).join("functions_and_types.rs");
    bindings
        .write_to_file(out_file)
        .unwrap();

    // Access to extern statics has to be marked unsafe after 1.13.0
    if rustc_version::version_matches(">=1.13.0") {
        println!("cargo:rustc-cfg=extern_statics_are_unsafe");
    }
}
<commit_msg>build.rs: workaround for servo/rust-bindgen#550<commit_after>// Compiles the `rsmpi` C shim library.
extern crate gcc;
// Generates the Rust header for the C API.
extern crate bindgen;
// Finds out information about the MPI library
extern crate build_probe_mpi;
// Inspect version of rustc compiler
extern crate rustc_version;

use std::env;
use std::path::Path;

fn main() {
    // Use `mpicc` wrapper rather than the system C compiler.
    env::set_var("CC", "mpicc");
    // Build the `rsmpi` C shim library.
    gcc::compile_library("librsmpi.a", &["src/ffi/rsmpi.c"]);

    // Try to find an MPI library
    let lib = match build_probe_mpi::probe() {
        Ok(lib) => lib,
        Err(errs) => {
            println!("Could not find MPI library for various reasons:\n");
            for (i, err) in errs.iter().enumerate() {
                println!("Reason #{}:\n{}\n", i, err);
            }
            panic!();
        }
    };

    // Let `rustc` know about the library search directories.
    for dir in &lib.lib_paths {
        println!("cargo:rustc-link-search=native={}", dir.display());
    }
    for lib in &lib.libs {
        println!("cargo:rustc-link-lib={}", lib);
    }

    let mut builder = bindgen::builder();
    // Let `bindgen` know about libraries and search directories.
    for lib in &lib.libs { builder = builder.link(lib.clone()); }
    for dir in &lib.lib_paths { builder = builder.clang_arg(format!("-L{}", dir.display())); }
    for dir in &lib.include_paths { builder = builder.clang_arg(format!("-I{}", dir.display())); }

    // Generate Rust bindings for the MPI C API.
    let bindings = builder
        .header("src/ffi/rsmpi.h")
        .emit_builtins()
        .no_unstable_rust()
        .hide_type("mpich_struct_mpi_long_double_int")
        .hide_type("max_align_t") // https://github.com/servo/rust-bindgen/issues/550
        .generate()
        .unwrap();

    // Write the bindings to disk.
    let out_dir = env::var("OUT_DIR").expect("cargo did not set OUT_DIR");
    let out_file = Path::new(&out_dir).join("functions_and_types.rs");
    bindings
        .write_to_file(out_file)
        .unwrap();

    // Access to extern statics has to be marked unsafe after 1.13.0
    if rustc_version::version_matches(">=1.13.0") {
        println!("cargo:rustc-cfg=extern_statics_are_unsafe");
    }
}
<|endoftext|>


<commit_before>#![cfg(feature="arbitrary")]

extern crate "nalgebra" as na;
extern crate quickcheck;

use std::rand;
use quickcheck::{Arbitrary, StdGen};
use na::*;

macro_rules! trivial_arb_test(
    ($t: ty, $name: ident) => (
        #[test]
        fn $name() {
            let mut g = StdGen::new(rand::thread_rng(), 100);
            let _: $t = Arbitrary::arbitrary(&mut g);
        }
    )
);

trivial_arb_test!(Vec1<f64>, arb_vec1);
trivial_arb_test!(Vec2<f64>, arb_vec2);
trivial_arb_test!(Vec3<f64>, arb_vec3);
trivial_arb_test!(Vec4<f64>, arb_vec4);
trivial_arb_test!(Vec5<f64>, arb_vec5);
trivial_arb_test!(Vec6<f64>, arb_vec6);

trivial_arb_test!(Pnt1<f64>, arb_pnt1);
trivial_arb_test!(Pnt2<f64>, arb_pnt2);
trivial_arb_test!(Pnt3<f64>, arb_pnt3);
trivial_arb_test!(Pnt4<f64>, arb_pnt4);
trivial_arb_test!(Pnt5<f64>, arb_pnt5);
trivial_arb_test!(Pnt6<f64>, arb_pnt6);

trivial_arb_test!(Mat1<f64>, arb_mat1);
trivial_arb_test!(Mat2<f64>, arb_mat2);
trivial_arb_test!(Mat3<f64>, arb_mat3);
trivial_arb_test!(Mat4<f64>, arb_mat4);
trivial_arb_test!(Mat5<f64>, arb_mat5);
trivial_arb_test!(Mat6<f64>, arb_mat6);

trivial_arb_test!(DVec1<f64>, arb_dvec1);
trivial_arb_test!(DVec2<f64>, arb_dvec2);
trivial_arb_test!(DVec3<f64>, arb_dvec3);
trivial_arb_test!(DVec4<f64>, arb_dvec4);
trivial_arb_test!(DVec5<f64>, arb_dvec5);
trivial_arb_test!(DVec6<f64>, arb_dvec6);

trivial_arb_test!(DMat<f64>, arb_dmat);
trivial_arb_test!(DVec<f64>, arb_dvec);

trivial_arb_test!(Quat<f64>, arb_quat);
trivial_arb_test!(UnitQuat<f64>, arb_unit_quat);

trivial_arb_test!(Iso2<f64>, arb_iso2);
trivial_arb_test!(Iso3<f64>, arb_iso3);

trivial_arb_test!(Rot2<f64>, arb_rot2);
trivial_arb_test!(Rot3<f64>, arb_rot3);

trivial_arb_test!(Ortho3<f64>, arb_ortho3);
trivial_arb_test!(OrthoMat3<f64>, arb_ortho_mat3);
trivial_arb_test!(Persp3<f64>, arb_persp3);
trivial_arb_test!(PerspMat3<f64>, arb_persp_mat3);
<commit_msg>Fix dependency in arbitrary tests<commit_after>#![cfg(feature="arbitrary")]

extern crate "nalgebra" as na;
extern crate quickcheck;
extern crate rand;

use quickcheck::{Arbitrary, StdGen};
use na::*;

macro_rules! trivial_arb_test(
    ($t: ty, $name: ident) => (
        #[test]
        fn $name() {
            let mut g = StdGen::new(rand::thread_rng(), 100);
            let _: $t = Arbitrary::arbitrary(&mut g);
        }
    )
);

trivial_arb_test!(Vec1<f64>, arb_vec1);
trivial_arb_test!(Vec2<f64>, arb_vec2);
trivial_arb_test!(Vec3<f64>, arb_vec3);
trivial_arb_test!(Vec4<f64>, arb_vec4);
trivial_arb_test!(Vec5<f64>, arb_vec5);
trivial_arb_test!(Vec6<f64>, arb_vec6);

trivial_arb_test!(Pnt1<f64>, arb_pnt1);
trivial_arb_test!(Pnt2<f64>, arb_pnt2);
trivial_arb_test!(Pnt3<f64>, arb_pnt3);
trivial_arb_test!(Pnt4<f64>, arb_pnt4);
trivial_arb_test!(Pnt5<f64>, arb_pnt5);
trivial_arb_test!(Pnt6<f64>, arb_pnt6);

trivial_arb_test!(Mat1<f64>, arb_mat1);
trivial_arb_test!(Mat2<f64>, arb_mat2);
trivial_arb_test!(Mat3<f64>, arb_mat3);
trivial_arb_test!(Mat4<f64>, arb_mat4);
trivial_arb_test!(Mat5<f64>, arb_mat5);
trivial_arb_test!(Mat6<f64>, arb_mat6);

trivial_arb_test!(DVec1<f64>, arb_dvec1);
trivial_arb_test!(DVec2<f64>, arb_dvec2);
trivial_arb_test!(DVec3<f64>, arb_dvec3);
trivial_arb_test!(DVec4<f64>, arb_dvec4);
trivial_arb_test!(DVec5<f64>, arb_dvec5);
trivial_arb_test!(DVec6<f64>, arb_dvec6);

trivial_arb_test!(DMat<f64>, arb_dmat);
trivial_arb_test!(DVec<f64>, arb_dvec);

trivial_arb_test!(Quat<f64>, arb_quat);
trivial_arb_test!(UnitQuat<f64>, arb_unit_quat);

trivial_arb_test!(Iso2<f64>, arb_iso2);
trivial_arb_test!(Iso3<f64>, arb_iso3);

trivial_arb_test!(Rot2<f64>, arb_rot2);
trivial_arb_test!(Rot3<f64>, arb_rot3);

trivial_arb_test!(Ortho3<f64>, arb_ortho3);
trivial_arb_test!(OrthoMat3<f64>, arb_ortho_mat3);
trivial_arb_test!(Persp3<f64>, arb_persp3);
trivial_arb_test!(PerspMat3<f64>, arb_persp_mat3);
<|endoftext|>