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

mod blocking;
mod client;
mod response;

pub use blocking::JsonRpcClient;
pub use client::{
    get_response_from_batch, process_batch_response, JsonRpcAsyncClient, JsonRpcBatch,
};
pub use libra_json_rpc_types::{errors, views};
pub use libra_types::{account_address::AccountAddress, transaction::SignedTransaction};
pub use response::{JsonRpcResponse, ResponseAsView};
<commit_msg>[small] Expose json rpc error enum<commit_after>// Copyright (c) The Libra Core Contributors
// SPDX-License-Identifier: Apache-2.0

mod blocking;
mod client;
mod response;

pub use blocking::JsonRpcClient;
pub use client::{
    get_response_from_batch, process_batch_response, JsonRpcAsyncClient, JsonRpcAsyncClientError,
    JsonRpcBatch,
};
pub use libra_json_rpc_types::{errors, views};
pub use libra_types::{account_address::AccountAddress, transaction::SignedTransaction};
pub use response::{JsonRpcResponse, ResponseAsView};
<|endoftext|>


<commit_before>use std::{iter, str::Lines};

use log::info;

use crate::*;

/// Trait for wrapping `std::process::Command::output()` with logging.
pub trait OutputInfo {
    fn output_info(&mut self) -> CVResult<(String, String)> {
        self.output_info_helper(|v| String::from(from_utf8(v).expect("not UTF-8")), false)
            .map(|(stdout, stderr, _)| (stdout, stderr))
    }

    fn latin1_output_info(&mut self) -> CVResult<(String, String)> {
        self.output_info_helper(utils::from_latin1, false)
            .map(|(stdout, stderr, _)| (stdout, stderr))
    }

    fn output_info_ignore_exit(&mut self) -> CVResult<(String, String, bool)> {
        self.output_info_helper(|v| String::from(from_utf8(v).expect("not UTF-8")), true)
    }

    fn latin1_output_info_ignore_exit(&mut self) -> CVResult<(String, String, bool)> {
        self.output_info_helper(utils::from_latin1, true)
    }

    fn output_info_helper(
        &mut self,
        trans: impl Fn(&[u8]) -> String,
        ignore_exit: bool,
    ) -> CVResult<(String, String, bool)>;
}

impl OutputInfo for Command {
    fn output_info_helper(
        &mut self,
        trans: impl Fn(&[u8]) -> String,
        ignore_exit: bool,
    ) -> CVResult<(String, String, bool)> {
        info_cmd(&self);

        let output = self.output()?;

        let stdout = trans(&output.stdout);
        info_lines("STDOUT: ", stdout.lines());

        let stderr = trans(&output.stderr);
        info_lines("STDERR: ", stderr.lines());

        if !ignore_exit && !output.status.success() {
            match output.status.code() {
                Some(code) => Err(format!(
                    "FAILED: '{}' terminated with exit code {}.",
                    self.get_program().to_string_lossy(),
                    code
                ))?,
                None => Err(format!(
                    "FAILED: '{}' terminated by a signal.",
                    self.get_program().to_string_lossy()
                ))?,
            }
        }

        Ok((stdout, stderr, output.status.success()))
    }
}

/// Log `cmd` nicely.
fn info_cmd(cmd: &Command) {
    info!(
        "Running '{}' in '{}' with command:\n{}",
        cmd.get_program().to_string_lossy(),
        cmd.get_current_dir()
            .unwrap_or(&PathBuf::from("."))
            .to_string_lossy(),
        iter::once(cmd.get_program())
            .chain(cmd.get_args())
            .map(|s| shell_escape::escape(s.to_string_lossy()))
            .collect::<Vec<_>>()
            .join(" ")
    );

    let envs = cmd.get_envs();
    if envs.len() > 0 {
        info!(
            "with environment variables:\n{}",
            envs.map(|(var, val)| match val {
                Some(val) => format!(
                    "{}={}",
                    var.to_string_lossy(),
                    shell_escape::escape(val.to_string_lossy())
                ),
                None => format!("{}=''", var.to_string_lossy()), // explicitly removed
            })
            .collect::<Vec<_>>()
            .join("\n")
        );
    }
}

/// Print each line of `Lines` using `info!`, prefixed with `prefix`.
pub fn info_lines(prefix: &str, lines: Lines) {
    for l in lines {
        info!("{}{}", prefix, l);
    }
}

/// Run `cargo clean`.
pub fn clean(opt: &Opt) {
    info_at!(&opt, 1, "Running `cargo clean`");
    Command::new("cargo")
        .arg("clean")
        .arg("--manifest-path")
        .arg(&opt.cargo_toml)
        .output_info_ignore_exit()
        .ok(); // Discarding the error on purpose.
}

/// Find the name of the crate.
pub fn get_meta_package_name(opt: &Opt) -> CVResult<String> {
    let name = MetadataCommand::new()
        .manifest_path(&opt.cargo_toml)
        .features(CargoOpt::SomeFeatures(opt.features.clone()))
        .exec()?
        .root_package()
        .ok_or("no root package")?
        .name
        .replace(
            |c| match c {
                // Allowed characters.
                'a'..='z' | 'A'..='Z' | '0'..='9' | '_' => false,
                // Anything else will be replaced with the '_' character.
                _ => true,
            },
            "_",
        );

    Ok(name)
}

/// Find the target directory.
pub fn get_meta_target_directory(opt: &Opt) -> CVResult<PathBuf> {
    // FIXME: add '--cfg=verify' to RUSTFLAGS?
    let dir = MetadataCommand::new()
        .manifest_path(&opt.cargo_toml)
        .features(CargoOpt::SomeFeatures(opt.features.clone()))
        .exec()?
        .target_directory;

    Ok(dir)
}

/// Get name of default_host.
/// This is passed to cargo using "--target=..." and will be the name of the
/// directory within the target directory.
pub fn get_default_host(crate_path: &Path) -> CVResult<String> {
    let mut cmd = Command::new("rustup");
    cmd.arg("show");

    if crate_path != PathBuf::from("") {
        cmd.current_dir(crate_path);
    }

    Ok(cmd
        .output_info()?
        .0
        .lines()
        .find_map(|l| l.strip_prefix("Default host:").and_then(|l| Some(l.trim())))
        .ok_or("Unable to determine default host")?
        .to_string())
}

/// Count how many functions in `f`s are present in `bcfile`.
pub fn count_symbols(opt: &Opt, bcfile: &Path, fs: &[&str]) -> CVResult<usize> {
    info_at!(
        &opt,
        4,
        "    Counting symbols {:?} in {}",
        fs,
        bcfile.to_string_lossy()
    );

    let mut cmd = Command::new("llvm-nm");
    cmd.arg("--defined-only").arg(bcfile);
    let (stdout, _) = cmd.output_info()?;

    let count = stdout
        .lines()
        .map(|l| l.split(" ").collect::<Vec<_>>())
        .filter(|l| l.len() == 3 && l[1] == "T" && fs.iter().any(|f| f == &l[2]))
        .count();

    info_at!(&opt, 4, "    Found {} functions", count);
    Ok(count)
}

/// Generate a list of tests in the crate by parsing the output of
/// `cargo test -- --list`
pub fn list_tests(opt: &Opt, target: &str) -> CVResult<Vec<String>> {
    let mut cmd = Command::new("cargo");
    cmd.arg("test").arg("--manifest-path").arg(&opt.cargo_toml);

    if !opt.features.is_empty() {
        cmd.arg("--features").arg(opt.features.join(","));
    }

    cmd.arg(format!("--target={}", target))
        .args(vec!["-v"; opt.verbose])
        .envs(get_build_envs(&opt)?)
        .args(&["--", "--list"]);
    // .arg("--exclude-should-panic")
    // .env("PATH", ...)

    lazy_static! {
        static ref TEST: Regex = Regex::new(r"(\S+):\s+test\s*$").unwrap();
    }

    // TODO: Python ignores bad exit codes
    let tests = cmd
        .output_info()?
        .0
        .lines()
        .filter_map(|l| {
            TEST.captures(l)
                .map(|caps| caps.get(1).unwrap().as_str().into())
        })
        .collect();

    Ok(tests)
}
<commit_msg>Cargo-verify: avoid doc tests problem<commit_after>use std::{iter, str::Lines};

use log::info;

use crate::*;

/// Trait for wrapping `std::process::Command::output()` with logging.
pub trait OutputInfo {
    fn output_info(&mut self) -> CVResult<(String, String)> {
        self.output_info_helper(|v| String::from(from_utf8(v).expect("not UTF-8")), false)
            .map(|(stdout, stderr, _)| (stdout, stderr))
    }

    fn latin1_output_info(&mut self) -> CVResult<(String, String)> {
        self.output_info_helper(utils::from_latin1, false)
            .map(|(stdout, stderr, _)| (stdout, stderr))
    }

    fn output_info_ignore_exit(&mut self) -> CVResult<(String, String, bool)> {
        self.output_info_helper(|v| String::from(from_utf8(v).expect("not UTF-8")), true)
    }

    fn latin1_output_info_ignore_exit(&mut self) -> CVResult<(String, String, bool)> {
        self.output_info_helper(utils::from_latin1, true)
    }

    fn output_info_helper(
        &mut self,
        trans: impl Fn(&[u8]) -> String,
        ignore_exit: bool,
    ) -> CVResult<(String, String, bool)>;
}

impl OutputInfo for Command {
    fn output_info_helper(
        &mut self,
        trans: impl Fn(&[u8]) -> String,
        ignore_exit: bool,
    ) -> CVResult<(String, String, bool)> {
        info_cmd(&self);

        let output = self.output()?;

        let stdout = trans(&output.stdout);
        info_lines("STDOUT: ", stdout.lines());

        let stderr = trans(&output.stderr);
        info_lines("STDERR: ", stderr.lines());

        if !ignore_exit && !output.status.success() {
            match output.status.code() {
                Some(code) => Err(format!(
                    "FAILED: '{}' terminated with exit code {}.",
                    self.get_program().to_string_lossy(),
                    code
                ))?,
                None => Err(format!(
                    "FAILED: '{}' terminated by a signal.",
                    self.get_program().to_string_lossy()
                ))?,
            }
        }

        Ok((stdout, stderr, output.status.success()))
    }
}

/// Log `cmd` nicely.
fn info_cmd(cmd: &Command) {
    info!(
        "Running '{}' in '{}' with command:\n{}",
        cmd.get_program().to_string_lossy(),
        cmd.get_current_dir()
            .unwrap_or(&PathBuf::from("."))
            .to_string_lossy(),
        iter::once(cmd.get_program())
            .chain(cmd.get_args())
            .map(|s| shell_escape::escape(s.to_string_lossy()))
            .collect::<Vec<_>>()
            .join(" ")
    );

    let envs = cmd.get_envs();
    if envs.len() > 0 {
        info!(
            "with environment variables:\n{}",
            envs.map(|(var, val)| match val {
                Some(val) => format!(
                    "{}={}",
                    var.to_string_lossy(),
                    shell_escape::escape(val.to_string_lossy())
                ),
                None => format!("{}=''", var.to_string_lossy()), // explicitly removed
            })
            .collect::<Vec<_>>()
            .join("\n")
        );
    }
}

/// Print each line of `Lines` using `info!`, prefixed with `prefix`.
pub fn info_lines(prefix: &str, lines: Lines) {
    for l in lines {
        info!("{}{}", prefix, l);
    }
}

/// Run `cargo clean`.
pub fn clean(opt: &Opt) {
    info_at!(&opt, 1, "Running `cargo clean`");
    Command::new("cargo")
        .arg("clean")
        .arg("--manifest-path")
        .arg(&opt.cargo_toml)
        .output_info_ignore_exit()
        .ok(); // Discarding the error on purpose.
}

/// Find the name of the crate.
pub fn get_meta_package_name(opt: &Opt) -> CVResult<String> {
    let name = MetadataCommand::new()
        .manifest_path(&opt.cargo_toml)
        .features(CargoOpt::SomeFeatures(opt.features.clone()))
        .exec()?
        .root_package()
        .ok_or("no root package")?
        .name
        .replace(
            |c| match c {
                // Allowed characters.
                'a'..='z' | 'A'..='Z' | '0'..='9' | '_' => false,
                // Anything else will be replaced with the '_' character.
                _ => true,
            },
            "_",
        );

    Ok(name)
}

/// Find the target directory.
pub fn get_meta_target_directory(opt: &Opt) -> CVResult<PathBuf> {
    // FIXME: add '--cfg=verify' to RUSTFLAGS?
    let dir = MetadataCommand::new()
        .manifest_path(&opt.cargo_toml)
        .features(CargoOpt::SomeFeatures(opt.features.clone()))
        .exec()?
        .target_directory;

    Ok(dir)
}

/// Get name of default_host.
/// This is passed to cargo using "--target=..." and will be the name of the
/// directory within the target directory.
pub fn get_default_host(crate_path: &Path) -> CVResult<String> {
    let mut cmd = Command::new("rustup");
    cmd.arg("show");

    if crate_path != PathBuf::from("") {
        cmd.current_dir(crate_path);
    }

    Ok(cmd
        .output_info()?
        .0
        .lines()
        .find_map(|l| l.strip_prefix("Default host:").and_then(|l| Some(l.trim())))
        .ok_or("Unable to determine default host")?
        .to_string())
}

/// Count how many functions in `f`s are present in `bcfile`.
pub fn count_symbols(opt: &Opt, bcfile: &Path, fs: &[&str]) -> CVResult<usize> {
    info_at!(
        &opt,
        4,
        "    Counting symbols {:?} in {}",
        fs,
        bcfile.to_string_lossy()
    );

    let mut cmd = Command::new("llvm-nm");
    cmd.arg("--defined-only").arg(bcfile);
    let (stdout, _) = cmd.output_info()?;

    let count = stdout
        .lines()
        .map(|l| l.split(" ").collect::<Vec<_>>())
        .filter(|l| l.len() == 3 && l[1] == "T" && fs.iter().any(|f| f == &l[2]))
        .count();

    info_at!(&opt, 4, "    Found {} functions", count);
    Ok(count)
}

/// Generate a list of tests in the crate by parsing the output of
/// `cargo test -- --list`
pub fn list_tests(opt: &Opt, target: &str) -> CVResult<Vec<String>> {
    let mut cmd = Command::new("cargo");
    cmd.arg("test").arg("--manifest-path").arg(&opt.cargo_toml);

    if !opt.features.is_empty() {
        cmd.arg("--features").arg(opt.features.join(","));
    }

    // Surprisingly, the effect of the following line is to prevent
    // consideration of doc tests from the list of tests.
    // We ignore doc tests because installing rustdoc to enable this
    // causes additional build problems and because we don't currently
    // expect doc tests to be based on property-based testing.
    cmd.arg("--all-targets");

    cmd.arg(format!("--target={}", target))
        .args(vec!["-v"; opt.verbose])
        .envs(get_build_envs(&opt)?)
        .args(&["--", "--list"]);
    // .arg("--exclude-should-panic")
    // .env("PATH", ...)

    lazy_static! {
        static ref TEST: Regex = Regex::new(r"(\S+):\s+test\s*$").unwrap();
    }

    // TODO: Python ignores bad exit codes
    let tests = cmd
        .output_info()?
        .0
        .lines()
        .filter_map(|l| {
            TEST.captures(l)
                .map(|caps| caps.get(1).unwrap().as_str().into())
        })
        .collect();

    Ok(tests)
}
<|endoftext|>


<commit_before>extern crate gooddata_fs;

use gooddata_fs::*;

fn connect() -> gd::GoodDataClient {
    let mut gd = gd::GoodDataClient::new(gooddata_fs::rest::url::SERVER.to_string(), None);
    gd.connect("tomas.korcak+gem_tester@gooddata.com", "jindrisska");
    gd
}

#[test]
fn it_creates_client() {
    let gd = gd::GoodDataClient::new(gooddata_fs::rest::url::SERVER.to_string(), None);
    assert_eq!(gd.projects.is_some(), false);
    assert_eq!(gd.user.is_some(), false);
    assert_eq!(gd.token_updated.is_some(), false);
}

#[test]
fn client_can_connect() {
    let gd = connect();

    assert_eq!(gd.projects.is_some(), false);
    assert_eq!(gd.user.is_some(), true);
    assert_eq!(gd.token_updated.is_some(), true);
}

#[test]
fn client_can_disconnect() {
    let mut gd = connect();
    gd.disconnect();

    assert_eq!(gd.projects.is_some(), false);
    assert_eq!(gd.user.is_some(), false);
    assert_eq!(gd.token_updated.is_some(), false);
}

#[test]
fn client_can_get_projects() {
    let mut gd = connect();
    gd.projects_fetch();

    assert_eq!(gd.projects.is_some(), true);
    assert_eq!(gd.user.is_some(), true);
    assert_eq!(gd.token_updated.is_some(), true);

    gd.disconnect();
}
<commit_msg>Fixing tests<commit_after>extern crate gooddata_fs;

use gooddata_fs::*;

fn connect() -> gd::GoodDataClient {
    // Create instance of GoodData HTTP Connector
    let connector = gooddata_fs::gd::Connector::new(gooddata_fs::rest::url::SERVER.to_string());
    // Create instance of GoodData REST API Client
    let mut gd = gooddata_fs::gd::GoodDataClient::new(connector, None);
    gd.connect("tomas.korcak+gem_tester@gooddata.com", "jindrisska");
    gd
}

#[test]
fn it_creates_connector() {
    // Create instance of GoodData HTTP Connector
    let connector = gooddata_fs::gd::Connector::new(gooddata_fs::rest::url::SERVER.to_string());
    assert_eq!(connector.token_updated.is_some(), false);
}

#[test]
fn it_creates_client() {
    // Create instance of GoodData HTTP Connector
    let connector = gooddata_fs::gd::Connector::new(gooddata_fs::rest::url::SERVER.to_string());
    // Create instance of GoodData REST API Client
    let gd = gd::GoodDataClient::new(connector, None);
    assert_eq!(gd.projects.is_some(), false);
    assert_eq!(gd.user.is_some(), false);
    assert_eq!(gd.token.is_some(), false);
}

#[test]
fn it_creates_client_with_token() {
    // Create instance of GoodData HTTP Connector
    let connector = gooddata_fs::gd::Connector::new(gooddata_fs::rest::url::SERVER.to_string());
    let token = Some("xxx".to_string());
    // Create instance of GoodData REST API Client
    let gd = gd::GoodDataClient::new(connector, token);
    assert_eq!(gd.token.is_some(), true);
    assert_eq!(gd.projects.is_some(), false);
    assert_eq!(gd.user.is_some(), false);
}

#[test]
fn client_can_connect() {
    let gd = connect();
    assert_eq!(gd.projects.is_some(), false);
    assert_eq!(gd.user.is_some(), true);

}

#[test]
fn client_can_disconnect() {
    let mut gd = connect();
    gd.disconnect();
    assert_eq!(gd.projects.is_some(), false);
    assert_eq!(gd.user.is_some(), false);
}

#[test]
fn client_can_get_projects() {
    let mut gd = connect();
    gd.projects_fetch();
    assert_eq!(gd.projects.is_some(), true);
    assert_eq!(gd.user.is_some(), true);
    gd.disconnect();
}
<|endoftext|>


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

#![no_std]
#![allow(unused_attributes)]
#![unstable(feature = "alloc_system",
            reason = "this library is unlikely to be stabilized in its current \
                      form or name",
            issue = "32838")]

#![feature(allocator_api)]
#![feature(core_intrinsics)]
#![feature(nll)]
#![feature(staged_api)]
#![feature(rustc_attrs)]
#![cfg_attr(
    all(target_arch = "wasm32", not(target_os = "emscripten")),
    feature(integer_atomics, stdsimd)
)]
#![cfg_attr(any(unix, target_os = "cloudabi", target_os = "redox"), feature(libc))]
#![rustc_alloc_kind = "lib"]

// The minimum alignment guaranteed by the architecture. This value is used to
// add fast paths for low alignment values.
#[cfg(all(any(target_arch = "x86",
              target_arch = "arm",
              target_arch = "mips",
              target_arch = "powerpc",
              target_arch = "powerpc64",
              target_arch = "asmjs",
              target_arch = "wasm32")))]
#[allow(dead_code)]
const MIN_ALIGN: usize = 8;
#[cfg(all(any(target_arch = "x86_64",
              target_arch = "aarch64",
              target_arch = "mips64",
              target_arch = "s390x",
              target_arch = "sparc64")))]
#[allow(dead_code)]
const MIN_ALIGN: usize = 16;

use core::alloc::{Alloc, GlobalAlloc, AllocErr, Layout};
use core::ptr::NonNull;

/// The default memory allocator provided by the operating system.
///
/// This is based on `malloc` on Unix platforms and `HeapAlloc` on Windows,
/// plus related functions.
///
/// This type can be used in a `static` item
/// with the `#[global_allocator]` attribute
/// to force the global allocator to be the system’s one.
/// (The default is jemalloc for executables, on some platforms.)
///
/// ```rust
/// use std::alloc::System;
///
/// #[global_allocator]
/// static A: System = System;
///
/// fn main() {
///     let a = Box::new(4); // Allocates from the system allocator.
///     println!("{}", a);
/// }
/// ```
///
/// It can also be used directly to allocate memory
/// independently of the standard library’s global allocator.
#[stable(feature = "alloc_system_type", since = "1.28.0")]
pub struct System;

#[unstable(feature = "allocator_api", issue = "32838")]
unsafe impl Alloc for System {
    #[inline]
    unsafe fn alloc(&mut self, layout: Layout) -> Result<NonNull<u8>, AllocErr> {
        NonNull::new(GlobalAlloc::alloc(self, layout)).ok_or(AllocErr)
    }

    #[inline]
    unsafe fn alloc_zeroed(&mut self, layout: Layout) -> Result<NonNull<u8>, AllocErr> {
        NonNull::new(GlobalAlloc::alloc_zeroed(self, layout)).ok_or(AllocErr)
    }

    #[inline]
    unsafe fn dealloc(&mut self, ptr: NonNull<u8>, layout: Layout) {
        GlobalAlloc::dealloc(self, ptr.as_ptr(), layout)
    }

    #[inline]
    unsafe fn realloc(&mut self,
                      ptr: NonNull<u8>,
                      layout: Layout,
                      new_size: usize) -> Result<NonNull<u8>, AllocErr> {
        NonNull::new(GlobalAlloc::realloc(self, ptr.as_ptr(), layout, new_size)).ok_or(AllocErr)
    }
}

#[cfg(any(windows, unix, target_os = "cloudabi", target_os = "redox"))]
mod realloc_fallback {
    use core::alloc::{GlobalAlloc, Layout};
    use core::cmp;
    use core::ptr;

    impl super::System {
        pub(crate) unsafe fn realloc_fallback(&self, ptr: *mut u8, old_layout: Layout,
                                              new_size: usize) -> *mut u8 {
            // Docs for GlobalAlloc::realloc require this to be valid:
            let new_layout = Layout::from_size_align_unchecked(new_size, old_layout.align());

            let new_ptr = GlobalAlloc::alloc(self, new_layout);
            if !new_ptr.is_null() {
                let size = cmp::min(old_layout.size(), new_size);
                ptr::copy_nonoverlapping(ptr, new_ptr, size);
                GlobalAlloc::dealloc(self, ptr, old_layout);
            }
            new_ptr
        }
    }
}

#[cfg(any(unix, target_os = "cloudabi", target_os = "redox"))]
mod platform {
    extern crate libc;

    use core::ptr;

    use MIN_ALIGN;
    use System;
    use core::alloc::{GlobalAlloc, Layout};

    #[stable(feature = "alloc_system_type", since = "1.28.0")]
    unsafe impl GlobalAlloc for System {
        #[inline]
        unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
            if layout.align() <= MIN_ALIGN && layout.align() <= layout.size() {
                libc::malloc(layout.size()) as *mut u8
            } else {
                #[cfg(target_os = "macos")]
                {
                    if layout.align() > (1 << 31) {
                        return ptr::null_mut()
                    }
                }
                aligned_malloc(&layout)
            }
        }

        #[inline]
        unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut u8 {
            if layout.align() <= MIN_ALIGN && layout.align() <= layout.size() {
                libc::calloc(layout.size(), 1) as *mut u8
            } else {
                let ptr = self.alloc(layout.clone());
                if !ptr.is_null() {
                    ptr::write_bytes(ptr, 0, layout.size());
                }
                ptr
            }
        }

        #[inline]
        unsafe fn dealloc(&self, ptr: *mut u8, _layout: Layout) {
            libc::free(ptr as *mut libc::c_void)
        }

        #[inline]
        unsafe fn realloc(&self, ptr: *mut u8, layout: Layout, new_size: usize) -> *mut u8 {
            if layout.align() <= MIN_ALIGN && layout.align() <= new_size {
                libc::realloc(ptr as *mut libc::c_void, new_size) as *mut u8
            } else {
                self.realloc_fallback(ptr, layout, new_size)
            }
        }
    }

    #[cfg(any(target_os = "android",
              target_os = "hermit",
              target_os = "redox",
              target_os = "solaris"))]
    #[inline]
    unsafe fn aligned_malloc(layout: &Layout) -> *mut u8 {
        // On android we currently target API level 9 which unfortunately
        // doesn't have the `posix_memalign` API used below. Instead we use
        // `memalign`, but this unfortunately has the property on some systems
        // where the memory returned cannot be deallocated by `free`!
        //
        // Upon closer inspection, however, this appears to work just fine with
        // Android, so for this platform we should be fine to call `memalign`
        // (which is present in API level 9). Some helpful references could
        // possibly be chromium using memalign [1], attempts at documenting that
        // memalign + free is ok [2] [3], or the current source of chromium
        // which still uses memalign on android [4].
        //
        // [1]: https://codereview.chromium.org/10796020/
        // [2]: https://code.google.com/p/android/issues/detail?id=35391
        // [3]: https://bugs.chromium.org/p/chromium/issues/detail?id=138579
        // [4]: https://chromium.googlesource.com/chromium/src/base/+/master/
        //                                       /memory/aligned_memory.cc
        libc::memalign(layout.align(), layout.size()) as *mut u8
    }

    #[cfg(not(any(target_os = "android",
                  target_os = "hermit",
                  target_os = "redox",
                  target_os = "solaris")))]
    #[inline]
    unsafe fn aligned_malloc(layout: &Layout) -> *mut u8 {
        let mut out = ptr::null_mut();
        let ret = libc::posix_memalign(&mut out, layout.align(), layout.size());
        if ret != 0 {
            ptr::null_mut()
        } else {
            out as *mut u8
        }
    }
}

#[cfg(windows)]
#[allow(nonstandard_style)]
mod platform {
    use MIN_ALIGN;
    use System;
    use core::alloc::{GlobalAlloc, Layout};

    type LPVOID = *mut u8;
    type HANDLE = LPVOID;
    type SIZE_T = usize;
    type DWORD = u32;
    type BOOL = i32;

    extern "system" {
        fn GetProcessHeap() -> HANDLE;
        fn HeapAlloc(hHeap: HANDLE, dwFlags: DWORD, dwBytes: SIZE_T) -> LPVOID;
        fn HeapReAlloc(hHeap: HANDLE, dwFlags: DWORD, lpMem: LPVOID, dwBytes: SIZE_T) -> LPVOID;
        fn HeapFree(hHeap: HANDLE, dwFlags: DWORD, lpMem: LPVOID) -> BOOL;
        fn GetLastError() -> DWORD;
    }

    #[repr(C)]
    struct Header(*mut u8);

    const HEAP_ZERO_MEMORY: DWORD = 0x00000008;

    unsafe fn get_header<'a>(ptr: *mut u8) -> &'a mut Header {
        &mut *(ptr as *mut Header).offset(-1)
    }

    unsafe fn align_ptr(ptr: *mut u8, align: usize) -> *mut u8 {
        let aligned = ptr.add(align - (ptr as usize & (align - 1)));
        *get_header(aligned) = Header(ptr);
        aligned
    }

    #[inline]
    unsafe fn allocate_with_flags(layout: Layout, flags: DWORD) -> *mut u8 {
        let ptr = if layout.align() <= MIN_ALIGN {
            HeapAlloc(GetProcessHeap(), flags, layout.size())
        } else {
            let size = layout.size() + layout.align();
            let ptr = HeapAlloc(GetProcessHeap(), flags, size);
            if ptr.is_null() {
                ptr
            } else {
                align_ptr(ptr, layout.align())
            }
        };
        ptr as *mut u8
    }

    #[stable(feature = "alloc_system_type", since = "1.28.0")]
    unsafe impl GlobalAlloc for System {
        #[inline]
        unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
            allocate_with_flags(layout, 0)
        }

        #[inline]
        unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut u8 {
            allocate_with_flags(layout, HEAP_ZERO_MEMORY)
        }

        #[inline]
        unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) {
            if layout.align() <= MIN_ALIGN {
                let err = HeapFree(GetProcessHeap(), 0, ptr as LPVOID);
                debug_assert!(err != 0, "Failed to free heap memory: {}",
                              GetLastError());
            } else {
                let header = get_header(ptr);
                let err = HeapFree(GetProcessHeap(), 0, header.0 as LPVOID);
                debug_assert!(err != 0, "Failed to free heap memory: {}",
                              GetLastError());
            }
        }

        #[inline]
        unsafe fn realloc(&self, ptr: *mut u8, layout: Layout, new_size: usize) -> *mut u8 {
            if layout.align() <= MIN_ALIGN {
                HeapReAlloc(GetProcessHeap(), 0, ptr as LPVOID, new_size) as *mut u8
            } else {
                self.realloc_fallback(ptr, layout, new_size)
            }
        }
    }
}

// This is an implementation of a global allocator on the wasm32 platform when
// emscripten is not in use. In that situation there's no actual runtime for us
// to lean on for allocation, so instead we provide our own!
//
// The wasm32 instruction set has two instructions for getting the current
// amount of memory and growing the amount of memory. These instructions are the
// foundation on which we're able to build an allocator, so we do so! Note that
// the instructions are also pretty "global" and this is the "global" allocator
// after all!
//
// The current allocator here is the `dlmalloc` crate which we've got included
// in the rust-lang/rust repository as a submodule. The crate is a port of
// dlmalloc.c from C to Rust and is basically just so we can have "pure Rust"
// for now which is currently technically required (can't link with C yet).
//
// The crate itself provides a global allocator which on wasm has no
// synchronization as there are no threads!
#[cfg(all(target_arch = "wasm32", not(target_os = "emscripten")))]
mod platform {
    extern crate dlmalloc;

    use core::alloc::{GlobalAlloc, Layout};
    use System;

    static mut DLMALLOC: dlmalloc::Dlmalloc = dlmalloc::DLMALLOC_INIT;

    #[stable(feature = "alloc_system_type", since = "1.28.0")]
    unsafe impl GlobalAlloc for System {
        #[inline]
        unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
            let _lock = lock::lock();
            DLMALLOC.malloc(layout.size(), layout.align())
        }

        #[inline]
        unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut u8 {
            let _lock = lock::lock();
            DLMALLOC.calloc(layout.size(), layout.align())
        }

        #[inline]
        unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) {
            let _lock = lock::lock();
            DLMALLOC.free(ptr, layout.size(), layout.align())
        }

        #[inline]
        unsafe fn realloc(&self, ptr: *mut u8, layout: Layout, new_size: usize) -> *mut u8 {
            let _lock = lock::lock();
            DLMALLOC.realloc(ptr, layout.size(), layout.align(), new_size)
        }
    }

    #[cfg(target_feature = "atomics")]
    mod lock {
        use core::arch::wasm32;
        use core::sync::atomic::{AtomicI32, Ordering::SeqCst};

        static LOCKED: AtomicI32 = AtomicI32::new(0);

        pub struct DropLock;

        pub fn lock() -> DropLock {
            loop {
                if LOCKED.swap(1, SeqCst) == 0 {
                    return DropLock
                }
                unsafe {
                    let r = wasm32::atomic::wait_i32(
                        &LOCKED as *const AtomicI32 as *mut i32,
                        1,  // expected value
                        -1, // timeout
                    );
                    debug_assert!(r == 0 || r == 1);
                }
            }
        }

        impl Drop for DropLock {
            fn drop(&mut self) {
                let r = LOCKED.swap(0, SeqCst);
                debug_assert_eq!(r, 1);
                unsafe {
                    wasm32::atomic::wake(
                        &LOCKED as *const AtomicI32 as *mut i32,
                        1, // only one thread
                    );
                }
            }
        }
    }

    #[cfg(not(target_feature = "atomics"))]
    mod lock {
        pub fn lock() {} // no atomics, no threads, that's easy!
    }
}
<commit_msg>wasm32: Inline a trivial function in libstd<commit_after>// Copyright 2015 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.

#![no_std]
#![allow(unused_attributes)]
#![unstable(feature = "alloc_system",
            reason = "this library is unlikely to be stabilized in its current \
                      form or name",
            issue = "32838")]

#![feature(allocator_api)]
#![feature(core_intrinsics)]
#![feature(nll)]
#![feature(staged_api)]
#![feature(rustc_attrs)]
#![cfg_attr(
    all(target_arch = "wasm32", not(target_os = "emscripten")),
    feature(integer_atomics, stdsimd)
)]
#![cfg_attr(any(unix, target_os = "cloudabi", target_os = "redox"), feature(libc))]
#![rustc_alloc_kind = "lib"]

// The minimum alignment guaranteed by the architecture. This value is used to
// add fast paths for low alignment values.
#[cfg(all(any(target_arch = "x86",
              target_arch = "arm",
              target_arch = "mips",
              target_arch = "powerpc",
              target_arch = "powerpc64",
              target_arch = "asmjs",
              target_arch = "wasm32")))]
#[allow(dead_code)]
const MIN_ALIGN: usize = 8;
#[cfg(all(any(target_arch = "x86_64",
              target_arch = "aarch64",
              target_arch = "mips64",
              target_arch = "s390x",
              target_arch = "sparc64")))]
#[allow(dead_code)]
const MIN_ALIGN: usize = 16;

use core::alloc::{Alloc, GlobalAlloc, AllocErr, Layout};
use core::ptr::NonNull;

/// The default memory allocator provided by the operating system.
///
/// This is based on `malloc` on Unix platforms and `HeapAlloc` on Windows,
/// plus related functions.
///
/// This type can be used in a `static` item
/// with the `#[global_allocator]` attribute
/// to force the global allocator to be the system’s one.
/// (The default is jemalloc for executables, on some platforms.)
///
/// ```rust
/// use std::alloc::System;
///
/// #[global_allocator]
/// static A: System = System;
///
/// fn main() {
///     let a = Box::new(4); // Allocates from the system allocator.
///     println!("{}", a);
/// }
/// ```
///
/// It can also be used directly to allocate memory
/// independently of the standard library’s global allocator.
#[stable(feature = "alloc_system_type", since = "1.28.0")]
pub struct System;

#[unstable(feature = "allocator_api", issue = "32838")]
unsafe impl Alloc for System {
    #[inline]
    unsafe fn alloc(&mut self, layout: Layout) -> Result<NonNull<u8>, AllocErr> {
        NonNull::new(GlobalAlloc::alloc(self, layout)).ok_or(AllocErr)
    }

    #[inline]
    unsafe fn alloc_zeroed(&mut self, layout: Layout) -> Result<NonNull<u8>, AllocErr> {
        NonNull::new(GlobalAlloc::alloc_zeroed(self, layout)).ok_or(AllocErr)
    }

    #[inline]
    unsafe fn dealloc(&mut self, ptr: NonNull<u8>, layout: Layout) {
        GlobalAlloc::dealloc(self, ptr.as_ptr(), layout)
    }

    #[inline]
    unsafe fn realloc(&mut self,
                      ptr: NonNull<u8>,
                      layout: Layout,
                      new_size: usize) -> Result<NonNull<u8>, AllocErr> {
        NonNull::new(GlobalAlloc::realloc(self, ptr.as_ptr(), layout, new_size)).ok_or(AllocErr)
    }
}

#[cfg(any(windows, unix, target_os = "cloudabi", target_os = "redox"))]
mod realloc_fallback {
    use core::alloc::{GlobalAlloc, Layout};
    use core::cmp;
    use core::ptr;

    impl super::System {
        pub(crate) unsafe fn realloc_fallback(&self, ptr: *mut u8, old_layout: Layout,
                                              new_size: usize) -> *mut u8 {
            // Docs for GlobalAlloc::realloc require this to be valid:
            let new_layout = Layout::from_size_align_unchecked(new_size, old_layout.align());

            let new_ptr = GlobalAlloc::alloc(self, new_layout);
            if !new_ptr.is_null() {
                let size = cmp::min(old_layout.size(), new_size);
                ptr::copy_nonoverlapping(ptr, new_ptr, size);
                GlobalAlloc::dealloc(self, ptr, old_layout);
            }
            new_ptr
        }
    }
}

#[cfg(any(unix, target_os = "cloudabi", target_os = "redox"))]
mod platform {
    extern crate libc;

    use core::ptr;

    use MIN_ALIGN;
    use System;
    use core::alloc::{GlobalAlloc, Layout};

    #[stable(feature = "alloc_system_type", since = "1.28.0")]
    unsafe impl GlobalAlloc for System {
        #[inline]
        unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
            if layout.align() <= MIN_ALIGN && layout.align() <= layout.size() {
                libc::malloc(layout.size()) as *mut u8
            } else {
                #[cfg(target_os = "macos")]
                {
                    if layout.align() > (1 << 31) {
                        return ptr::null_mut()
                    }
                }
                aligned_malloc(&layout)
            }
        }

        #[inline]
        unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut u8 {
            if layout.align() <= MIN_ALIGN && layout.align() <= layout.size() {
                libc::calloc(layout.size(), 1) as *mut u8
            } else {
                let ptr = self.alloc(layout.clone());
                if !ptr.is_null() {
                    ptr::write_bytes(ptr, 0, layout.size());
                }
                ptr
            }
        }

        #[inline]
        unsafe fn dealloc(&self, ptr: *mut u8, _layout: Layout) {
            libc::free(ptr as *mut libc::c_void)
        }

        #[inline]
        unsafe fn realloc(&self, ptr: *mut u8, layout: Layout, new_size: usize) -> *mut u8 {
            if layout.align() <= MIN_ALIGN && layout.align() <= new_size {
                libc::realloc(ptr as *mut libc::c_void, new_size) as *mut u8
            } else {
                self.realloc_fallback(ptr, layout, new_size)
            }
        }
    }

    #[cfg(any(target_os = "android",
              target_os = "hermit",
              target_os = "redox",
              target_os = "solaris"))]
    #[inline]
    unsafe fn aligned_malloc(layout: &Layout) -> *mut u8 {
        // On android we currently target API level 9 which unfortunately
        // doesn't have the `posix_memalign` API used below. Instead we use
        // `memalign`, but this unfortunately has the property on some systems
        // where the memory returned cannot be deallocated by `free`!
        //
        // Upon closer inspection, however, this appears to work just fine with
        // Android, so for this platform we should be fine to call `memalign`
        // (which is present in API level 9). Some helpful references could
        // possibly be chromium using memalign [1], attempts at documenting that
        // memalign + free is ok [2] [3], or the current source of chromium
        // which still uses memalign on android [4].
        //
        // [1]: https://codereview.chromium.org/10796020/
        // [2]: https://code.google.com/p/android/issues/detail?id=35391
        // [3]: https://bugs.chromium.org/p/chromium/issues/detail?id=138579
        // [4]: https://chromium.googlesource.com/chromium/src/base/+/master/
        //                                       /memory/aligned_memory.cc
        libc::memalign(layout.align(), layout.size()) as *mut u8
    }

    #[cfg(not(any(target_os = "android",
                  target_os = "hermit",
                  target_os = "redox",
                  target_os = "solaris")))]
    #[inline]
    unsafe fn aligned_malloc(layout: &Layout) -> *mut u8 {
        let mut out = ptr::null_mut();
        let ret = libc::posix_memalign(&mut out, layout.align(), layout.size());
        if ret != 0 {
            ptr::null_mut()
        } else {
            out as *mut u8
        }
    }
}

#[cfg(windows)]
#[allow(nonstandard_style)]
mod platform {
    use MIN_ALIGN;
    use System;
    use core::alloc::{GlobalAlloc, Layout};

    type LPVOID = *mut u8;
    type HANDLE = LPVOID;
    type SIZE_T = usize;
    type DWORD = u32;
    type BOOL = i32;

    extern "system" {
        fn GetProcessHeap() -> HANDLE;
        fn HeapAlloc(hHeap: HANDLE, dwFlags: DWORD, dwBytes: SIZE_T) -> LPVOID;
        fn HeapReAlloc(hHeap: HANDLE, dwFlags: DWORD, lpMem: LPVOID, dwBytes: SIZE_T) -> LPVOID;
        fn HeapFree(hHeap: HANDLE, dwFlags: DWORD, lpMem: LPVOID) -> BOOL;
        fn GetLastError() -> DWORD;
    }

    #[repr(C)]
    struct Header(*mut u8);

    const HEAP_ZERO_MEMORY: DWORD = 0x00000008;

    unsafe fn get_header<'a>(ptr: *mut u8) -> &'a mut Header {
        &mut *(ptr as *mut Header).offset(-1)
    }

    unsafe fn align_ptr(ptr: *mut u8, align: usize) -> *mut u8 {
        let aligned = ptr.add(align - (ptr as usize & (align - 1)));
        *get_header(aligned) = Header(ptr);
        aligned
    }

    #[inline]
    unsafe fn allocate_with_flags(layout: Layout, flags: DWORD) -> *mut u8 {
        let ptr = if layout.align() <= MIN_ALIGN {
            HeapAlloc(GetProcessHeap(), flags, layout.size())
        } else {
            let size = layout.size() + layout.align();
            let ptr = HeapAlloc(GetProcessHeap(), flags, size);
            if ptr.is_null() {
                ptr
            } else {
                align_ptr(ptr, layout.align())
            }
        };
        ptr as *mut u8
    }

    #[stable(feature = "alloc_system_type", since = "1.28.0")]
    unsafe impl GlobalAlloc for System {
        #[inline]
        unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
            allocate_with_flags(layout, 0)
        }

        #[inline]
        unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut u8 {
            allocate_with_flags(layout, HEAP_ZERO_MEMORY)
        }

        #[inline]
        unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) {
            if layout.align() <= MIN_ALIGN {
                let err = HeapFree(GetProcessHeap(), 0, ptr as LPVOID);
                debug_assert!(err != 0, "Failed to free heap memory: {}",
                              GetLastError());
            } else {
                let header = get_header(ptr);
                let err = HeapFree(GetProcessHeap(), 0, header.0 as LPVOID);
                debug_assert!(err != 0, "Failed to free heap memory: {}",
                              GetLastError());
            }
        }

        #[inline]
        unsafe fn realloc(&self, ptr: *mut u8, layout: Layout, new_size: usize) -> *mut u8 {
            if layout.align() <= MIN_ALIGN {
                HeapReAlloc(GetProcessHeap(), 0, ptr as LPVOID, new_size) as *mut u8
            } else {
                self.realloc_fallback(ptr, layout, new_size)
            }
        }
    }
}

// This is an implementation of a global allocator on the wasm32 platform when
// emscripten is not in use. In that situation there's no actual runtime for us
// to lean on for allocation, so instead we provide our own!
//
// The wasm32 instruction set has two instructions for getting the current
// amount of memory and growing the amount of memory. These instructions are the
// foundation on which we're able to build an allocator, so we do so! Note that
// the instructions are also pretty "global" and this is the "global" allocator
// after all!
//
// The current allocator here is the `dlmalloc` crate which we've got included
// in the rust-lang/rust repository as a submodule. The crate is a port of
// dlmalloc.c from C to Rust and is basically just so we can have "pure Rust"
// for now which is currently technically required (can't link with C yet).
//
// The crate itself provides a global allocator which on wasm has no
// synchronization as there are no threads!
#[cfg(all(target_arch = "wasm32", not(target_os = "emscripten")))]
mod platform {
    extern crate dlmalloc;

    use core::alloc::{GlobalAlloc, Layout};
    use System;

    static mut DLMALLOC: dlmalloc::Dlmalloc = dlmalloc::DLMALLOC_INIT;

    #[stable(feature = "alloc_system_type", since = "1.28.0")]
    unsafe impl GlobalAlloc for System {
        #[inline]
        unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
            let _lock = lock::lock();
            DLMALLOC.malloc(layout.size(), layout.align())
        }

        #[inline]
        unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut u8 {
            let _lock = lock::lock();
            DLMALLOC.calloc(layout.size(), layout.align())
        }

        #[inline]
        unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) {
            let _lock = lock::lock();
            DLMALLOC.free(ptr, layout.size(), layout.align())
        }

        #[inline]
        unsafe fn realloc(&self, ptr: *mut u8, layout: Layout, new_size: usize) -> *mut u8 {
            let _lock = lock::lock();
            DLMALLOC.realloc(ptr, layout.size(), layout.align(), new_size)
        }
    }

    #[cfg(target_feature = "atomics")]
    mod lock {
        use core::arch::wasm32;
        use core::sync::atomic::{AtomicI32, Ordering::SeqCst};

        static LOCKED: AtomicI32 = AtomicI32::new(0);

        pub struct DropLock;

        pub fn lock() -> DropLock {
            loop {
                if LOCKED.swap(1, SeqCst) == 0 {
                    return DropLock
                }
                unsafe {
                    let r = wasm32::atomic::wait_i32(
                        &LOCKED as *const AtomicI32 as *mut i32,
                        1,  // expected value
                        -1, // timeout
                    );
                    debug_assert!(r == 0 || r == 1);
                }
            }
        }

        impl Drop for DropLock {
            fn drop(&mut self) {
                let r = LOCKED.swap(0, SeqCst);
                debug_assert_eq!(r, 1);
                unsafe {
                    wasm32::atomic::wake(
                        &LOCKED as *const AtomicI32 as *mut i32,
                        1, // only one thread
                    );
                }
            }
        }
    }

    #[cfg(not(target_feature = "atomics"))]
    mod lock {
        #[inline]
        pub fn lock() {} // no atomics, no threads, that's easy!
    }
}
<|endoftext|>


<commit_before>//! `ra_vfs_glob` crate implements exclusion rules for vfs.
//!
//! By default, we include only `.rs` files, and skip some know offenders like
//! `/target` or `/node_modules` altogether.
//!
//! It's also possible to add custom exclusion globs.

use globset::{Glob, GlobSet, GlobSetBuilder};
use ra_vfs::{Filter, RelativePath};

const ALWAYS_IGNORED: &[&str] = &["target/**", "**/node_modules/**", "**/.git/**"];
const IGNORED_FOR_NON_MEMBERS: &[&str] = &["examples/**", "tests/**", "benches/**"];

pub struct RustPackageFilterBuilder {
    is_member: bool,
    exclude: GlobSetBuilder,
}

impl Default for RustPackageFilterBuilder {
    fn default() -> RustPackageFilterBuilder {
        RustPackageFilterBuilder { is_member: false, exclude: GlobSetBuilder::new() }
    }
}

impl RustPackageFilterBuilder {
    pub fn set_member(mut self, is_member: bool) -> RustPackageFilterBuilder {
        self.is_member = is_member;
        self
    }
    pub fn exclude(mut self, glob: &str) -> Result<RustPackageFilterBuilder, globset::Error> {
        self.exclude.add(Glob::new(glob)?);
        Ok(self)
    }
    pub fn into_vfs_filter(self) -> Box<dyn Filter> {
        let RustPackageFilterBuilder { is_member, mut exclude } = self;
        for &glob in ALWAYS_IGNORED {
            exclude.add(Glob::new(glob).unwrap());
        }
        if !is_member {
            for &glob in IGNORED_FOR_NON_MEMBERS {
                exclude.add(Glob::new(glob).unwrap());
            }
        }
        Box::new(RustPackageFilter { exclude: exclude.build().unwrap() })
    }
}

struct RustPackageFilter {
    exclude: GlobSet,
}

impl Filter for RustPackageFilter {
    fn include_dir(&self, dir_path: &RelativePath) -> bool {
        !self.exclude.is_match(dir_path.as_str())
    }

    fn include_file(&self, file_path: &RelativePath) -> bool {
        file_path.extension() == Some("rs")
    }
}

#[test]
fn test_globs() {
    let filter = RustPackageFilterBuilder::default().set_member(true).into_vfs_filter();

    assert!(filter.include_dir(RelativePath::new("src/tests")));
    assert!(filter.include_dir(RelativePath::new("src/target")));
    assert!(filter.include_dir(RelativePath::new("tests")));
    assert!(filter.include_dir(RelativePath::new("benches")));

    assert!(!filter.include_dir(RelativePath::new("target")));
    assert!(!filter.include_dir(RelativePath::new("src/foo/.git")));
    assert!(!filter.include_dir(RelativePath::new("foo/node_modules")));

    let filter = RustPackageFilterBuilder::default().set_member(false).into_vfs_filter();

    assert!(filter.include_dir(RelativePath::new("src/tests")));
    assert!(filter.include_dir(RelativePath::new("src/target")));

    assert!(!filter.include_dir(RelativePath::new("target")));
    assert!(!filter.include_dir(RelativePath::new("src/foo/.git")));
    assert!(!filter.include_dir(RelativePath::new("foo/node_modules")));
    assert!(!filter.include_dir(RelativePath::new("tests")));
    assert!(!filter.include_dir(RelativePath::new("benches")));

    let filter = RustPackageFilterBuilder::default()
        .set_member(true)
        .exclude("src/llvm-project/**")
        .unwrap()
        .into_vfs_filter();

    assert!(!filter.include_dir(RelativePath::new("src/llvm-project/clang")));
}
<commit_msg>push glob errors outwards<commit_after>//! `ra_vfs_glob` crate implements exclusion rules for vfs.
//!
//! By default, we include only `.rs` files, and skip some know offenders like
//! `/target` or `/node_modules` altogether.
//!
//! It's also possible to add custom exclusion globs.

use globset::{GlobSet, GlobSetBuilder};
use ra_vfs::{Filter, RelativePath};

pub use globset::{Glob, GlobBuilder};

const ALWAYS_IGNORED: &[&str] = &["target/**", "**/node_modules/**", "**/.git/**"];
const IGNORED_FOR_NON_MEMBERS: &[&str] = &["examples/**", "tests/**", "benches/**"];

pub struct RustPackageFilterBuilder {
    is_member: bool,
    exclude: GlobSetBuilder,
}

impl Default for RustPackageFilterBuilder {
    fn default() -> RustPackageFilterBuilder {
        RustPackageFilterBuilder { is_member: false, exclude: GlobSetBuilder::new() }
    }
}

impl RustPackageFilterBuilder {
    pub fn set_member(mut self, is_member: bool) -> RustPackageFilterBuilder {
        self.is_member = is_member;
        self
    }
    pub fn exclude(mut self, glob: Glob) -> RustPackageFilterBuilder {
        self.exclude.add(glob);
        self
    }
    pub fn into_vfs_filter(self) -> Box<dyn Filter> {
        let RustPackageFilterBuilder { is_member, mut exclude } = self;
        for &glob in ALWAYS_IGNORED {
            exclude.add(Glob::new(glob).unwrap());
        }
        if !is_member {
            for &glob in IGNORED_FOR_NON_MEMBERS {
                exclude.add(Glob::new(glob).unwrap());
            }
        }
        Box::new(RustPackageFilter { exclude: exclude.build().unwrap() })
    }
}

struct RustPackageFilter {
    exclude: GlobSet,
}

impl Filter for RustPackageFilter {
    fn include_dir(&self, dir_path: &RelativePath) -> bool {
        !self.exclude.is_match(dir_path.as_str())
    }

    fn include_file(&self, file_path: &RelativePath) -> bool {
        file_path.extension() == Some("rs")
    }
}

#[test]
fn test_globs() {
    let filter = RustPackageFilterBuilder::default().set_member(true).into_vfs_filter();

    assert!(filter.include_dir(RelativePath::new("src/tests")));
    assert!(filter.include_dir(RelativePath::new("src/target")));
    assert!(filter.include_dir(RelativePath::new("tests")));
    assert!(filter.include_dir(RelativePath::new("benches")));

    assert!(!filter.include_dir(RelativePath::new("target")));
    assert!(!filter.include_dir(RelativePath::new("src/foo/.git")));
    assert!(!filter.include_dir(RelativePath::new("foo/node_modules")));

    let filter = RustPackageFilterBuilder::default().set_member(false).into_vfs_filter();

    assert!(filter.include_dir(RelativePath::new("src/tests")));
    assert!(filter.include_dir(RelativePath::new("src/target")));

    assert!(!filter.include_dir(RelativePath::new("target")));
    assert!(!filter.include_dir(RelativePath::new("src/foo/.git")));
    assert!(!filter.include_dir(RelativePath::new("foo/node_modules")));
    assert!(!filter.include_dir(RelativePath::new("tests")));
    assert!(!filter.include_dir(RelativePath::new("benches")));

    let filter = RustPackageFilterBuilder::default()
        .set_member(true)
        .exclude(Glob::new("src/llvm-project/**").unwrap())
        .into_vfs_filter();

    assert!(!filter.include_dir(RelativePath::new("src/llvm-project/clang")));
}
<|endoftext|>


<commit_before>// Copyright (c) 2015, The Radare Project. All rights reserved.
// See the COPYING file at the top-level directory of this distribution.
// Licensed under the BSD 3-Clause License:
// <http://opensource.org/licenses/BSD-3-Clause>
// This file may not be copied, modified, or distributed
// except according to those terms.

//! Implements a pass that goes over the ssa and checks if the ssa is still
//! valid.
//!
//! This is only for verification and to catch potential mistakes.
#![allow(unused_variables)]
use petgraph::graph::{NodeIndex};

use super::cfg_traits::{CFG};
use super::ssa_traits::{SSA, SSAMod, ValueType};
use super::ssastorage::{EdgeData};
use super::ssastorage::NodeData;
use super::ssa_traits::NodeData as TNodeData;
use super::error::SSAErr;

use super::ssastorage::SSAStorage;
use middle::ir::{MArity, MOpcode};
use std::result;
use std::fmt::Debug;

pub type VResult<T> = result::Result<(), SSAErr<T>>;

pub trait Verify: SSA {
	fn verify_block(&self, i: &Self::ActionRef) -> VResult<Self>;
	fn verify_expr(&self, i: &Self::ValueRef) -> VResult<Self>;
}

pub trait VerifiedAdd: SSAMod {
	fn verified_add_op(&mut self, block: Self::ActionRef, opc: MOpcode, vt:
					   ValueType, args: &[Self::ValueRef],
					   addr: Option<u64>) -> Self::ValueRef;
}

impl<T: Verify + SSAMod + Debug> VerifiedAdd for T {
	fn verified_add_op(&mut self,
					   block: Self::ActionRef,
					   opc: MOpcode,
					   vt: ValueType,
					   args: &[Self::ValueRef],
					   addr: Option<u64>) -> Self::ValueRef
	{
		assert!(opc.allowed_in_ssa());
		let op = self.add_op(block, opc, vt, addr);
		for (i, arg) in args.iter().enumerate() {
			self.op_use(op, i as u8, *arg);
		}
		let q = self.verify_expr(&op);
		if let Err(ref e) = q {
			panic!(format!("{:?}", e));
		}
		op
	}
}

macro_rules! check {
	($cond: expr, $ssaerr: expr) => (
		if !$cond { return Err($ssaerr) }
	);
}

impl Verify for SSAStorage {
	fn verify_block(&self, block: &NodeIndex) -> VResult<Self> {
		let edge_count = self.edge_count();
		let node_count = self.node_count();
		// Make sure that we have a valid node first.
		assert!(block.index() < node_count);
		let edges = self.edges_of(block);
		// Every BB can have a maximum of 2 Outgoing CFG Edges.
		check!(edges.len() < 3, SSAErr::WrongNumEdges(*block, 3, edges.len()));

		let mut edgecases = [false; 256];

		for edge in edges.iter() {
			match self.g[*edge] {
				EdgeData::Control(i) => {
					let target = self.target_of(edge);
					check!(self.is_action(target),
					SSAErr::InvalidType("Block".to_owned()));
					check!(!edgecases[i as usize],
						   SSAErr::InvalidControl(*block, *edge));
					edgecases[i as usize] = true;
				},
				_ => ()
			}
		}

		for edge in edges.iter() {
			assert!(edge.index() < edge_count);
			match self.g[*edge] {
				EdgeData::Control(i) if i < 2 => {
					// Things to lookout for:
					//  * There must be a minimum of two edges.
					//  * There _must_ be a selector.
					//  * The jump targets must not be the same block.
					check!(edges.len() == 2, SSAErr::WrongNumEdges(*block, 2,
																   edges.len()));
					let other_edge = match i {
						0 => self.true_edge_of(block),
						1 => self.false_edge_of(block),
						_ => unreachable!(),
					};
					let target_1 = self.target_of(edge);
					let target_2 = self.target_of(&other_edge);
					check!(target_1 != target_2,
						   SSAErr::InvalidControl(*block, *edge));
					// No need to test the next edge.
					break;
				},
				EdgeData::Control(2) => {
					// Things to lookout for:
					//  * There can be only one Unconditional Edge.
					//  * There can be no selector.
					//  * Make sure we have not introduced an unconditional jump
					//    which self-loops.
					let target_block = self.target_of(edge);
					check!(edges.len() == 1, SSAErr::WrongNumEdges(*block, 1, edges.len()));

					check!(target_block.index() < node_count,
					SSAErr::InvalidTarget(*block, *edge, target_block));
					let valid_block = if let NodeData::BasicBlock(_) = self.g[target_block] {
						true
					} else {
						false
					};
					//check!(ri, valid_block);
					check!(*block != target_block,
						   SSAErr::InvalidTarget(*block, *edge,
												 target_block));
				},
				_ => panic!("Found something other than a control edge!"),
			}
		}

		let selector = self.selector_of(block);
		if edges.len() == 2 {
			check!(selector.is_some(), SSAErr::NoSelector(*block));
		} else {
			check!(selector.is_none(), SSAErr::UnexpectedSelector(*block,
																  selector.unwrap()));
		}

		// Make sure that this block is reachable.
		let incoming = self.incoming_edges(block);
		check!((incoming.len() > 0) || *block == self.start_node(),
		                                     SSAErr::UnreachableBlock(*block));
		Ok(())
	}

	fn verify_expr(&self, i: &NodeIndex) -> VResult<Self> {
		let node_count = self.node_count();
		// Make sure we have a valid node first.
		assert!(i.index() < node_count);
		let node_data = &self.g[*i];

		match *node_data {
			NodeData::Op(opcode, ValueType::Integer { width: w }) => {
				let operands = self.get_operands(i);
				let op_len = operands.len();
				let extract = |x: TNodeData| -> u16 {
					match x.vt {
						ValueType::Integer { width: w } => w,
					}
				};

				let n = match opcode.arity() {
					MArity::Zero => 0,
					MArity::Unary => 1,
					MArity::Binary => 2,
					_ => unimplemented!(),
				};

				{
					check!(op_len == n, SSAErr::WrongNumOperands(*i, n,
																 op_len));
				}

				if n == 0 { return Ok(()) }
				match opcode {
					MOpcode::OpNarrow(w0) => {
						let w1 = self.get_node_data(&operands[0])
						             .map(&extract)
						             .unwrap();
						check!(w1 > w0, SSAErr::IncompatibleWidth(*i, w, w0));
					},
				    MOpcode::OpWiden(w0) =>  {
						let w1 = self.get_node_data(&operands[0])
						             .map(&extract)
						             .unwrap();
						check!(w1 < w0, SSAErr::IncompatibleWidth(*i, w, w0));
					},
					MOpcode::OpCmp | MOpcode::OpGt | MOpcode::OpLt |
					MOpcode::OpLteq | MOpcode::OpGteq => {
						check!(w == 1, SSAErr::IncompatibleWidth(*i, 1, w));
					},
					MOpcode::OpCall | MOpcode::OpStore => { },
					_ => {
						let w0 = self.get_node_data(&operands[0])
						             .map(&extract)
						             .unwrap();
						check!(w0 == w, SSAErr::IncompatibleWidth(*i, w, w0));
						for op in operands.iter() {
							let w1 = self.get_node_data(op)
							             .map(&extract)
						                 .unwrap();
							check!(w == w1, SSAErr::IncompatibleWidth(*i, w,
																	  w1));
						}
					},
				}
			},
			_ => check!(false, SSAErr::InvalidExpr(*i)),
		}
		Ok(())
	}
}

pub fn verify<T>(ssa: &T) -> VResult<T> where T: Verify + Debug {
	let blocks = ssa.blocks();
	for block in blocks.iter() {
		// assert the qualities of the block first.
		ssa.verify_block(block).ok().unwrap();
		// Iterate through each node in the block and assert their properties.
		let exprs = ssa.exprs_in(block);
		for expr in exprs.iter() {
			try!(ssa.verify_expr(expr));
		}
	}
	Ok(())
}
<commit_msg>Fixes verifier<commit_after>// Copyright (c) 2015, The Radare Project. All rights reserved.
// See the COPYING file at the top-level directory of this distribution.
// Licensed under the BSD 3-Clause License:
// <http://opensource.org/licenses/BSD-3-Clause>
// This file may not be copied, modified, or distributed
// except according to those terms.

//! Implements a pass that goes over the ssa and checks if the ssa is still
//! valid.
//!
//! This is only for verification and to catch potential mistakes.
use petgraph::graph::NodeIndex;

use super::cfg_traits::CFG;
use super::ssa_traits::{SSA, SSAMod, ValueType};
use super::ssastorage::EdgeData;
use super::ssastorage::NodeData;
use super::ssa_traits::NodeData as TNodeData;
use super::error::SSAErr;

use super::ssastorage::SSAStorage;
use middle::ir::{MArity, MOpcode};
use std::result;
use std::fmt::Debug;

pub type VResult<T> = result::Result<(), SSAErr<T>>;

pub trait Verify: SSA {
	fn verify_block(&self, i: &Self::ActionRef) -> VResult<Self>;
	fn verify_expr(&self, i: &Self::ValueRef) -> VResult<Self>;
}

pub trait VerifiedAdd: SSAMod {
	fn verified_add_op(&mut self, block: Self::ActionRef, opc: MOpcode, vt:
					   ValueType, args: &[Self::ValueRef],
					   addr: Option<u64>) -> Self::ValueRef;
}

impl<T: Verify + SSAMod + Debug> VerifiedAdd for T {
	fn verified_add_op(&mut self,
					   block: Self::ActionRef,
					   opc: MOpcode,
					   vt: ValueType,
					   args: &[Self::ValueRef],
					   addr: Option<u64>) -> Self::ValueRef
	{
		assert!(opc.allowed_in_ssa());
		let op = self.add_op(block, opc, vt, addr);
		for (i, arg) in args.iter().enumerate() {
			self.op_use(op, i as u8, *arg);
		}
		let q = self.verify_expr(&op);
		if let Err(ref e) = q {
			panic!(format!("{:?}", e));
		}
		op
	}
}

macro_rules! check {
	($cond: expr, $ssaerr: expr) => (
		if !$cond { return Err($ssaerr) }
	);
}

impl Verify for SSAStorage {
	fn verify_block(&self, block: &NodeIndex) -> VResult<Self> {
		let node_count = self.node_count();

		let edges = self.edges_of(block);

		// Every BB can have a maximum of 2 Outgoing CFG Edges.
		// TODO: Relax this assumption when we have support for switch.
		check!(edges.len() < 3, SSAErr::WrongNumEdges(*block, 3, edges.len()));

		let mut edgecases = [false; 256];

		for edge in edges.iter() {
			match self.g[*edge] {
				EdgeData::Control(i) => {
					let target = self.target_of(edge);
					check!(self.is_action(target),
					SSAErr::InvalidType("Block".to_owned()));
					check!(!edgecases[i as usize],
						   SSAErr::InvalidControl(*block, *edge));
					edgecases[i as usize] = true;
				},
				_ => ()
			}
		}

		for edge in edges.iter() {
			match self.g[*edge] {
				EdgeData::Control(i) if i < 2 => {
					// Things to lookout for:
					//  * There must be a minimum of two edges.
					//  * There _must_ be a selector.
					//  * The jump targets must not be the same block.
					check!(edges.len() == 2, SSAErr::WrongNumEdges(*block, 2,
																   edges.len()));
					let other_edge = match i {
						0 => self.true_edge_of(block),
						1 => self.false_edge_of(block),
						_ => unreachable!(),
					};
					let target_1 = self.target_of(edge);
					let target_2 = self.target_of(&other_edge);
					check!(target_1 != target_2,
						   SSAErr::InvalidControl(*block, *edge));
					// No need to test the next edge.
					break;
				},
				EdgeData::Control(2) => {
					// Things to lookout for:
					//  * There can be only one Unconditional Edge.
					//  * There can be no selector.
					//  * Make sure we have not introduced an unconditional jump
					//    which self-loops.
					let target_block = self.target_of(edge);
					check!(edges.len() == 1, SSAErr::WrongNumEdges(*block, 1,
																   edges.len()));

					check!(target_block.index() < node_count,
					SSAErr::InvalidTarget(*block, *edge, target_block));
					check!(*block != target_block,
						   SSAErr::InvalidTarget(*block, *edge,
												 target_block));
				},
				_ => panic!("Found something other than a control edge!"),
			}
		}

		let selector = self.selector_of(block);
		if edges.len() == 2 {
			check!(selector.is_some(), SSAErr::NoSelector(*block));
		} else {
			check!(selector.is_none(), SSAErr::UnexpectedSelector(*block,
																  selector.unwrap()));
		}

		// Make sure that this block is reachable.
		// TODO: Re-enable this after DCE. Make this Non-Fatal.
		//let incoming = self.incoming_edges(block);
		//check!((incoming.len() > 0) || *block == self.start_node(),
											 //SSAErr::UnreachableBlock(*block));
		Ok(())
	}

	fn verify_expr(&self, exi: &NodeIndex) -> VResult<Self> {
		let i = &self.internal(exi);
		let node_data = &self.g[*i];
		match *node_data {
			NodeData::Op(opcode, ValueType::Integer { width: w }) => {
				let extract = |x: TNodeData| -> u16 {
					match x.vt {
						ValueType::Integer { width: w } => w,
					}
				};

				let operands = self.get_operands(exi);
				let op_len = operands.len();
				let n = match opcode.arity() {
					MArity::Zero   => 0,
					MArity::Unary  => 1,
					MArity::Binary => 2,
					_ => unreachable!(),
				};

				{
					check!(op_len == n, SSAErr::WrongNumOperands(*i, n,
																 op_len));
				}

				if n == 0 { return Ok(()) }
				match opcode {
					MOpcode::OpNarrow(w0) => {
						let opw = self.get_node_data(&operands[0])
						             .map(&extract)
						             .unwrap();
						check!(opw > w0, SSAErr::IncompatibleWidth(*i, opw,
																   w0));
						check!(w == w0, SSAErr::IncompatibleWidth(*i, w, w0));
					},
				    MOpcode::OpWiden(w0) =>  {
						let opw = self.get_node_data(&operands[0])
						             .map(&extract)
						             .unwrap();
						check!(opw < w0, SSAErr::IncompatibleWidth(*i, opw,
																   w0));
						check!(w == w0, SSAErr::IncompatibleWidth(*i, w, w0));
					},
					MOpcode::OpCmp | MOpcode::OpGt | MOpcode::OpLt |
					MOpcode::OpLteq | MOpcode::OpGteq => {
						check!(w == 1, SSAErr::IncompatibleWidth(*i, 1, w));
					},
					MOpcode::OpCall | MOpcode::OpStore => { },
					_ => {
						// All operands to an expr must have the same width.
						let w0 = self.get_node_data(&operands[0])
						             .map(&extract)
						             .unwrap();
						check!(w0 == w, SSAErr::IncompatibleWidth(*i, w, w0));
						for op in operands.iter() {
							let w1 = self.get_node_data(op)
							             .map(&extract)
						                 .unwrap();
							check!(w == w1, SSAErr::IncompatibleWidth(*i, w,
																	  w1));
						}
					},
				}
			},
			_ => check!(false, SSAErr::InvalidExpr(*i)),
		}
		Ok(())
	}
}

pub fn verify<T>(ssa: &T) -> VResult<T> where T: Verify + Debug {
	let blocks = ssa.blocks();
	for block in blocks.iter() {
		// assert the qualities of the block first.
		try!(ssa.verify_block(block));
		// Iterate through each node in the block and assert their properties.
		let exprs = ssa.exprs_in(block);
		for expr in exprs.iter() {
			try!(ssa.verify_expr(expr));
		}
	}
	Ok(())
}
<|endoftext|>


<commit_before>use std::io::prelude::*;
use std::io::BufReader;
use std::str;

fn read_n<R>(reader: R, bytes_to_read: u64) -> Vec<u8>
where
    R: Read,
{
    let mut buf = vec![];
    let mut chunk = reader.take(bytes_to_read);
    // Do appropriate error handling for your situation
    let n = chunk.read_to_end(&mut buf).expect("Didn't read enough");
    assert_eq!(bytes_to_read as usize, n);
    buf
}

fn main() {
    let input_data = b"hello world";
    let mut reader = BufReader::new(&input_data[..]);

    let first = read_n(&mut reader, 5);
    let _ = read_n(&mut reader, 1);
    let second = read_n(&mut reader, 5);

    println!(
        "{:?}, {:?}",
        str::from_utf8(&first),
        str::from_utf8(&second)
    );
}
<commit_msg>a bit<commit_after>use std::io::prelude::*;
use std::io::BufReader;
use std::str;

fn read_n<R>(reader: R, bytes_to_read: u64) -> Vec<u8>
where
    R: Read,
{
    let mut buf = vec![];
    let mut chunk = reader.take(bytes_to_read);
    // Do appropriate error handling for your situation
    let n = chunk.read_to_end(&mut buf).expect("Didn't read enough");
    assert_eq!(bytes_to_read as usize, n);
    buf
}

fn main() {
    let input_data = b"hello world,aaa";
    let mut reader = BufReader::new(&input_data[..]);

    let first = read_n(&mut reader, 5);
    let _ = read_n(&mut reader, 1);
    let second = read_n(&mut reader, 5);

    println!(
        "{:?}, {:?}",
        str::from_utf8(&first),
        str::from_utf8(&second),
    );
}
<|endoftext|>


<commit_before>// Copyright 2015, The Rust-GNOME Project Developers.
// See the COPYRIGHT file at the top-level directory of this distribution.
// Licensed under the MIT license, see the LICENSE file or <http://opensource.org/licenses/MIT>

#![allow(non_camel_case_types)]
#![allow(dead_code)]

extern crate libc;
extern crate glib_sys as glib_ffi;

pub mod enums;

use libc::{c_int, c_uint, c_char, c_double};
use glib_ffi::Gboolean;

#[repr(C)]
pub struct PangoContext;
#[repr(C)]
pub struct PangoAttrList;
#[repr(C)]
pub struct PangoAttrIterator;
#[repr(C)]
pub struct PangoItem;
#[repr(C)]
pub struct PangoFontMap;
#[repr(C)]
pub struct PangoFontDescription;
#[repr(C)]
pub struct PangoLanguage;
#[repr(C)]
#[derive(Clone, Copy)]
pub struct PangoMatrix {
    pub xx: c_double,
    pub xy: c_double,
    pub yx: c_double,
    pub yy: c_double,
    pub x0: c_double,
    pub y0: c_double
}
#[repr(C)]
pub struct PangoFont;
#[repr(C)]
pub struct PangoFontset;
#[repr(C)]
pub struct PangoFontMetrics;
#[repr(C)]
pub struct PangoFontFamily;
#[repr(C)]
pub struct PangoAnalysis;
#[repr(C)]
pub struct PangoLogAttr;
#[repr(C)]
pub struct PangoGlyphString;
#[repr(C)]
pub struct PangoScript;
#[repr(C)]
#[derive(Clone, Copy)]
pub struct PangoRectangle {
    pub x: c_int,
    pub y: c_int,
    pub width: c_int,
    pub height: c_int
}

extern "C" {
    //=========================================================================
    // PangoItem                                                         NOT OK
    //=========================================================================
    pub fn pango_item_free                (item: *mut PangoItem);
    pub fn pango_item_copy                (item: *mut PangoItem) -> *mut PangoItem;
    pub fn pango_item_new                 () -> *mut PangoItem;
    pub fn pango_item_split               (item: *mut PangoItem, split_index: c_int, split_offset: c_int) -> *mut PangoItem;

    //=========================================================================
    // PangoContext                                                      NOT OK
    //=========================================================================
    pub fn pango_context_new              () -> *mut PangoContext;
    pub fn pango_context_changed          (context: *mut PangoContext);
    pub fn pango_context_get_serial       (context: *mut PangoContext) -> c_uint;
    pub fn pango_context_set_font_map     (context: *mut PangoContext, font_map: *mut PangoFontMap);
    pub fn pango_context_get_font_map     (context: *mut PangoContext) -> *mut PangoFontMap;
    pub fn pango_context_get_font_description(context: *mut PangoContext) -> *mut PangoFontDescription;
    pub fn pango_context_set_font_description(context: *mut PangoContext, desc: *const PangoFontDescription);
    pub fn pango_context_get_language     (context: *mut PangoContext) -> *mut PangoLanguage;
    pub fn pango_context_set_language     (context: *mut PangoContext, language: *mut PangoLanguage);
    pub fn pango_context_get_base_dir     (context: *mut PangoContext) -> enums::Direction;
    pub fn pango_context_set_base_dir     (context: *mut PangoContext, direction: enums::Direction);
    pub fn pango_context_get_base_gravity (context: *mut PangoContext) -> enums::Gravity;
    pub fn pango_context_set_base_gravity (context: *mut PangoContext, gravity: enums::Gravity);
    pub fn pango_context_get_gravity      (context: *mut PangoContext) -> enums::Gravity;
    pub fn pango_context_get_gravity_hint (context: *mut PangoContext) -> enums::GravityHint;
    pub fn pango_context_set_gravity_hint (context: *mut PangoContext, hint: enums::GravityHint);
    pub fn pango_context_get_matrix       (context: *mut PangoContext) -> *const PangoMatrix;
    pub fn pango_context_set_matrix       (context: *mut PangoContext, matrix: *const PangoMatrix);
    pub fn pango_context_load_font        (context: *mut PangoContext, desc: *const PangoFontDescription) -> *mut PangoFont;
    pub fn pango_context_load_fontset     (context: *mut PangoContext, desc: *const PangoFontDescription, language: *mut PangoLanguage) -> *mut PangoFontset;
    pub fn pango_context_get_metrics      (context: *mut PangoContext, desc: *const PangoFontDescription, language: *mut PangoLanguage) -> *mut PangoFontMetrics;
    pub fn pango_context_list_families    (context: *mut PangoContext, families: *mut *mut *mut PangoFontFamily, n_families: *mut c_int);

    //=========================================================================
    // PangoFontDescription                                              NOT OK
    //=========================================================================
    pub fn pango_font_description_new     () -> *mut PangoFontDescription;
    pub fn pango_font_description_copy    (desc: *const PangoFontDescription) -> *mut PangoFontDescription;
    //pub fn pango_font_description_copy_static(desc: *const PangoFontDescription) -> *mut PangoFontDescription;
    pub fn pango_font_description_hash    (desc: *const PangoFontDescription) -> c_uint;
    pub fn pango_font_description_equal   (desc1: *const PangoFontDescription, desc2: *const PangoFontDescription) -> Gboolean;
    pub fn pango_font_description_free    (desc: *mut PangoFontDescription);
    pub fn pango_font_descriptions_free   (desc: *mut *mut PangoFontDescription, n_descs: c_int);
    pub fn pango_font_description_set_family(desc: *mut PangoFontDescription, family: *const c_char);
    //pub fn pango_font_description_set_family_static(desc: *mut PangoFontDescription, family: *const c_char);
    pub fn pango_font_description_get_family(desc: *const PangoFontDescription) -> *const c_char;
    pub fn pango_font_description_set_style(desc: *mut PangoFontDescription, style: enums::Style);
    pub fn pango_font_description_get_style(desc: *const PangoFontDescription) -> enums::Style;
    pub fn pango_font_description_set_variant(desc: *mut PangoFontDescription, variant: enums::Variant);
    pub fn pango_font_description_get_variant(desc: *const PangoFontDescription) -> enums::Variant;
    pub fn pango_font_description_set_weight(desc: *mut PangoFontDescription, weight: enums::Weight);
    pub fn pango_font_description_get_weight(desc: *const PangoFontDescription) -> enums::Weight;
    pub fn pango_font_description_set_stretch(desc: *mut PangoFontDescription, stretch: enums::Stretch);
    pub fn pango_font_description_get_stretch(desc: *const PangoFontDescription) -> enums::Stretch;
    pub fn pango_font_description_set_size(desc: *mut PangoFontDescription, size: c_int);
    pub fn pango_font_description_get_size(desc: *const PangoFontDescription) -> c_int;
    pub fn pango_font_description_set_absolute_size(desc: *mut PangoFontDescription, size: c_double);
    pub fn pango_font_description_get_size_is_absolute(desc: *const PangoFontDescription) -> Gboolean;
    pub fn pango_font_description_set_gravity(desc: *mut PangoFontDescription, gravity: enums::Gravity);
    pub fn pango_font_description_get_gravity(desc: *const PangoFontDescription) -> enums::Gravity;
    pub fn pango_font_description_get_set_fields(desc: *const PangoFontDescription) -> enums::FontMask;
    pub fn pango_font_description_unset_fields(desc: *mut PangoFontDescription, to_unset: enums::FontMask);
    pub fn pango_font_description_merge   (desc: *mut PangoFontDescription, desc_to_merge: *const PangoFontDescription,
        replace_existing: Gboolean);
    //pub fn pango_font_description_merge_static(desc: *mut PangoFontDescription, desc_to_merge: *const PangoFontDescription,
    //    replace_existing: Gboolean);
    pub fn pango_font_description_better_match(desc: *const PangoFontDescription, old_match: *const PangoFontDescription,
        new_match: *const PangoFontDescription) -> Gboolean;
    pub fn pango_font_description_from_string(str_: *const c_char) -> *mut PangoFontDescription;
    pub fn pango_font_description_to_string(desc: *const PangoFontDescription) -> *mut c_char;
    pub fn pango_font_description_to_filename(desc: *const PangoFontDescription) -> *mut c_char;

    //=========================================================================
    // PangoMatrix                                                       NOT OK
    //=========================================================================
    pub fn pango_gravity_get_for_matrix    (matrix: *const PangoMatrix) -> enums::Gravity;
    //pub fn pango_matrix_copy               (matrix: *const PangoMatrix) -> *mut PangoMatrix;
    //pub fn pango_matrix_free               (matrix: *mut PangoMatrix);
    pub fn pango_matrix_translate          (matrix: *mut PangoMatrix, t_x: c_double, t_y: c_double);
    pub fn pango_matrix_scale              (matrix: *mut PangoMatrix, scale_x: c_double, scale_y: c_double);
    pub fn pango_matrix_rotate             (matrix: *mut PangoMatrix, degrees: c_double);
    pub fn pango_matrix_concat             (matrix: *mut PangoMatrix, new_matrix: *const PangoMatrix);
    pub fn pango_matrix_transform_point    (matrix: *const PangoMatrix, x: *mut c_double, y: *mut c_double);
    pub fn pango_matrix_transform_distance (matrix: *const PangoMatrix, dx: *mut c_double, dy: *mut c_double);
    pub fn pango_matrix_transform_rectangle(matrix: *const PangoMatrix, rect: *mut PangoRectangle);
    pub fn pango_matrix_transform_pixel_rectangle(matrix: *const PangoMatrix, rect: *mut PangoRectangle);
    pub fn pango_matrix_get_font_scale_factor(matrix: *mut PangoMatrix) -> c_double;

    //=========================================================================
    // PangoGlyphString                                                  NOT OK
    //=========================================================================
    pub fn pango_glyph_string_new          () -> *mut PangoGlyphString;
    pub fn pango_glyph_string_copy         (string: *mut PangoGlyphString) -> *mut PangoGlyphString;
    pub fn pango_glyph_string_set_size     (string: *mut PangoGlyphString, new_len: c_int);
    pub fn pango_glyph_string_free         (string: *mut PangoGlyphString);
    pub fn pango_glyph_string_extents      (string: *mut PangoGlyphString, font: *mut PangoFont, ink_rect: *mut PangoRectangle,
        logical_rect: *mut PangoRectangle);
    pub fn pango_glyph_string_extents_range(string: *mut PangoGlyphString, start: c_int, end: c_int, font: *mut PangoFont,
        ink_rect: *mut PangoRectangle, logical_rect: *mut PangoRectangle);
    pub fn pango_glyph_string_get_width    (string: *mut PangoGlyphString) -> c_int;
    pub fn pango_glyph_string_index_to_x   (string: *mut PangoGlyphString, text: *mut c_char, length: c_int, analysis: *mut PangoAnalysis,
        index_: c_int, trailing: Gboolean, x_pos: *mut c_int);
    pub fn pango_glyph_string_x_to_index   (string: *mut PangoGlyphString, text: *mut c_char, length: c_int, analysis: *mut PangoAnalysis,
        x_pos: c_int, index_: *mut c_int, trailing: *mut c_int);
    pub fn pango_glyph_string_get_logical_widths(glyphs: *mut PangoGlyphString, text: *mut c_char, length: c_int, embedding_level: c_int,
        logical_widths: *mut c_int);

    //=========================================================================
    // PangoScript                                                       NOT OK
    //=========================================================================
    pub fn pango_gravity_get_for_script    (script: enums::Script, base_gravity: enums::Gravity, hint: enums::GravityHint) -> enums::Gravity;
    pub fn pango_gravity_get_for_script_and_width(script: enums::Script, wide: Gboolean, base_gravity: enums::Gravity,
        hint: enums::GravityHint) -> enums::Gravity;

    //=========================================================================
    // PangoGravity                                                      NOT OK
    //=========================================================================
    pub fn pango_gravity_to_rotation        (gravity: enums::Gravity) -> c_double;

    //=========================================================================
    // PangoDirection                                                    NOT OK
    //=========================================================================
    pub fn pango_unichar_direction          (ch: u32) -> enums::Direction;
    pub fn pango_find_base_dir              (text: *const c_char, length: c_int) -> enums::Direction;

    //=========================================================================
    // PangoBidiType                                                     NOT OK
    //=========================================================================
    pub fn pango_bidi_type_for_unichar      (ch: u32) -> enums::BidiType;

    //pub fn pango_itemize                  (context: *mut PangoContext, text: *const c_char, start_index: c_int, length: c_int,
    //    attrs: *mut PangoAttrList, cached_iter: *mut PangoAttrIterator) -> *mut GList;
    //pub fn pango_itemize_with_base_dir    (context: *mut PangoContext, direction: enums::Direction, text: *const c_char, start_index: c_int, length: c_int,
    //    attrs: *mut PangoAttrList, cached_iter: *mut PangoAttrIterator) -> *mut GList;
    //pub fn pango_reorder_items            (logical_items: *mut GList) -> *mut GList;
    pub fn pango_break                    (text: *const c_char, length: c_int, analysis: *mut PangoAnalysis, attrs: *mut PangoLogAttr,
        attrs_len: c_int);
    pub fn pango_get_log_attrs            (text: *const c_char, length: c_int, level: c_int, language: *mut PangoLanguage, log_attrs: *mut PangoLogAttr,
        attrs_len: c_int);
    pub fn pango_find_paragraph_boundary  (text: *const c_char, length: c_int, paragraph_delimiter_index: *mut c_int,
        next_paragraph_start: *mut c_int);
    pub fn pango_default_break            (text: *const c_char, length: c_int, analysis: *mut PangoAnalysis, attrs: *mut PangoLogAttr,
        attrs_len: c_int);
    pub fn pango_shape                    (text: *const c_char, length: c_int, analysis: *const PangoAnalysis, glyphs: *mut PangoGlyphString);
    pub fn pango_shape_full               (item_text: *const c_char, item_length: c_int, paragraph_text: *const c_char, paragraph_length: c_int,
        analysis: *const PangoAnalysis, glyphs: *mut PangoGlyphString);
}<commit_msg>s/Gboolean/gboolean/ for consistency with C headers<commit_after>// Copyright 2015, The Rust-GNOME Project Developers.
// See the COPYRIGHT file at the top-level directory of this distribution.
// Licensed under the MIT license, see the LICENSE file or <http://opensource.org/licenses/MIT>

#![allow(non_camel_case_types)]
#![allow(dead_code)]

extern crate libc;
extern crate glib_sys as glib_ffi;

pub mod enums;

use libc::{c_int, c_uint, c_char, c_double};
use glib_ffi::gboolean;

#[repr(C)]
pub struct PangoContext;
#[repr(C)]
pub struct PangoAttrList;
#[repr(C)]
pub struct PangoAttrIterator;
#[repr(C)]
pub struct PangoItem;
#[repr(C)]
pub struct PangoFontMap;
#[repr(C)]
pub struct PangoFontDescription;
#[repr(C)]
pub struct PangoLanguage;
#[repr(C)]
#[derive(Clone, Copy)]
pub struct PangoMatrix {
    pub xx: c_double,
    pub xy: c_double,
    pub yx: c_double,
    pub yy: c_double,
    pub x0: c_double,
    pub y0: c_double
}
#[repr(C)]
pub struct PangoFont;
#[repr(C)]
pub struct PangoFontset;
#[repr(C)]
pub struct PangoFontMetrics;
#[repr(C)]
pub struct PangoFontFamily;
#[repr(C)]
pub struct PangoAnalysis;
#[repr(C)]
pub struct PangoLogAttr;
#[repr(C)]
pub struct PangoGlyphString;
#[repr(C)]
pub struct PangoScript;
#[repr(C)]
#[derive(Clone, Copy)]
pub struct PangoRectangle {
    pub x: c_int,
    pub y: c_int,
    pub width: c_int,
    pub height: c_int
}

extern "C" {
    //=========================================================================
    // PangoItem                                                         NOT OK
    //=========================================================================
    pub fn pango_item_free                (item: *mut PangoItem);
    pub fn pango_item_copy                (item: *mut PangoItem) -> *mut PangoItem;
    pub fn pango_item_new                 () -> *mut PangoItem;
    pub fn pango_item_split               (item: *mut PangoItem, split_index: c_int, split_offset: c_int) -> *mut PangoItem;

    //=========================================================================
    // PangoContext                                                      NOT OK
    //=========================================================================
    pub fn pango_context_new              () -> *mut PangoContext;
    pub fn pango_context_changed          (context: *mut PangoContext);
    pub fn pango_context_get_serial       (context: *mut PangoContext) -> c_uint;
    pub fn pango_context_set_font_map     (context: *mut PangoContext, font_map: *mut PangoFontMap);
    pub fn pango_context_get_font_map     (context: *mut PangoContext) -> *mut PangoFontMap;
    pub fn pango_context_get_font_description(context: *mut PangoContext) -> *mut PangoFontDescription;
    pub fn pango_context_set_font_description(context: *mut PangoContext, desc: *const PangoFontDescription);
    pub fn pango_context_get_language     (context: *mut PangoContext) -> *mut PangoLanguage;
    pub fn pango_context_set_language     (context: *mut PangoContext, language: *mut PangoLanguage);
    pub fn pango_context_get_base_dir     (context: *mut PangoContext) -> enums::Direction;
    pub fn pango_context_set_base_dir     (context: *mut PangoContext, direction: enums::Direction);
    pub fn pango_context_get_base_gravity (context: *mut PangoContext) -> enums::Gravity;
    pub fn pango_context_set_base_gravity (context: *mut PangoContext, gravity: enums::Gravity);
    pub fn pango_context_get_gravity      (context: *mut PangoContext) -> enums::Gravity;
    pub fn pango_context_get_gravity_hint (context: *mut PangoContext) -> enums::GravityHint;
    pub fn pango_context_set_gravity_hint (context: *mut PangoContext, hint: enums::GravityHint);
    pub fn pango_context_get_matrix       (context: *mut PangoContext) -> *const PangoMatrix;
    pub fn pango_context_set_matrix       (context: *mut PangoContext, matrix: *const PangoMatrix);
    pub fn pango_context_load_font        (context: *mut PangoContext, desc: *const PangoFontDescription) -> *mut PangoFont;
    pub fn pango_context_load_fontset     (context: *mut PangoContext, desc: *const PangoFontDescription, language: *mut PangoLanguage) -> *mut PangoFontset;
    pub fn pango_context_get_metrics      (context: *mut PangoContext, desc: *const PangoFontDescription, language: *mut PangoLanguage) -> *mut PangoFontMetrics;
    pub fn pango_context_list_families    (context: *mut PangoContext, families: *mut *mut *mut PangoFontFamily, n_families: *mut c_int);

    //=========================================================================
    // PangoFontDescription                                              NOT OK
    //=========================================================================
    pub fn pango_font_description_new     () -> *mut PangoFontDescription;
    pub fn pango_font_description_copy    (desc: *const PangoFontDescription) -> *mut PangoFontDescription;
    //pub fn pango_font_description_copy_static(desc: *const PangoFontDescription) -> *mut PangoFontDescription;
    pub fn pango_font_description_hash    (desc: *const PangoFontDescription) -> c_uint;
    pub fn pango_font_description_equal   (desc1: *const PangoFontDescription, desc2: *const PangoFontDescription) -> gboolean;
    pub fn pango_font_description_free    (desc: *mut PangoFontDescription);
    pub fn pango_font_descriptions_free   (desc: *mut *mut PangoFontDescription, n_descs: c_int);
    pub fn pango_font_description_set_family(desc: *mut PangoFontDescription, family: *const c_char);
    //pub fn pango_font_description_set_family_static(desc: *mut PangoFontDescription, family: *const c_char);
    pub fn pango_font_description_get_family(desc: *const PangoFontDescription) -> *const c_char;
    pub fn pango_font_description_set_style(desc: *mut PangoFontDescription, style: enums::Style);
    pub fn pango_font_description_get_style(desc: *const PangoFontDescription) -> enums::Style;
    pub fn pango_font_description_set_variant(desc: *mut PangoFontDescription, variant: enums::Variant);
    pub fn pango_font_description_get_variant(desc: *const PangoFontDescription) -> enums::Variant;
    pub fn pango_font_description_set_weight(desc: *mut PangoFontDescription, weight: enums::Weight);
    pub fn pango_font_description_get_weight(desc: *const PangoFontDescription) -> enums::Weight;
    pub fn pango_font_description_set_stretch(desc: *mut PangoFontDescription, stretch: enums::Stretch);
    pub fn pango_font_description_get_stretch(desc: *const PangoFontDescription) -> enums::Stretch;
    pub fn pango_font_description_set_size(desc: *mut PangoFontDescription, size: c_int);
    pub fn pango_font_description_get_size(desc: *const PangoFontDescription) -> c_int;
    pub fn pango_font_description_set_absolute_size(desc: *mut PangoFontDescription, size: c_double);
    pub fn pango_font_description_get_size_is_absolute(desc: *const PangoFontDescription) -> gboolean;
    pub fn pango_font_description_set_gravity(desc: *mut PangoFontDescription, gravity: enums::Gravity);
    pub fn pango_font_description_get_gravity(desc: *const PangoFontDescription) -> enums::Gravity;
    pub fn pango_font_description_get_set_fields(desc: *const PangoFontDescription) -> enums::FontMask;
    pub fn pango_font_description_unset_fields(desc: *mut PangoFontDescription, to_unset: enums::FontMask);
    pub fn pango_font_description_merge   (desc: *mut PangoFontDescription, desc_to_merge: *const PangoFontDescription,
        replace_existing: gboolean);
    //pub fn pango_font_description_merge_static(desc: *mut PangoFontDescription, desc_to_merge: *const PangoFontDescription,
    //    replace_existing: gboolean);
    pub fn pango_font_description_better_match(desc: *const PangoFontDescription, old_match: *const PangoFontDescription,
        new_match: *const PangoFontDescription) -> gboolean;
    pub fn pango_font_description_from_string(str_: *const c_char) -> *mut PangoFontDescription;
    pub fn pango_font_description_to_string(desc: *const PangoFontDescription) -> *mut c_char;
    pub fn pango_font_description_to_filename(desc: *const PangoFontDescription) -> *mut c_char;

    //=========================================================================
    // PangoMatrix                                                       NOT OK
    //=========================================================================
    pub fn pango_gravity_get_for_matrix    (matrix: *const PangoMatrix) -> enums::Gravity;
    //pub fn pango_matrix_copy               (matrix: *const PangoMatrix) -> *mut PangoMatrix;
    //pub fn pango_matrix_free               (matrix: *mut PangoMatrix);
    pub fn pango_matrix_translate          (matrix: *mut PangoMatrix, t_x: c_double, t_y: c_double);
    pub fn pango_matrix_scale              (matrix: *mut PangoMatrix, scale_x: c_double, scale_y: c_double);
    pub fn pango_matrix_rotate             (matrix: *mut PangoMatrix, degrees: c_double);
    pub fn pango_matrix_concat             (matrix: *mut PangoMatrix, new_matrix: *const PangoMatrix);
    pub fn pango_matrix_transform_point    (matrix: *const PangoMatrix, x: *mut c_double, y: *mut c_double);
    pub fn pango_matrix_transform_distance (matrix: *const PangoMatrix, dx: *mut c_double, dy: *mut c_double);
    pub fn pango_matrix_transform_rectangle(matrix: *const PangoMatrix, rect: *mut PangoRectangle);
    pub fn pango_matrix_transform_pixel_rectangle(matrix: *const PangoMatrix, rect: *mut PangoRectangle);
    pub fn pango_matrix_get_font_scale_factor(matrix: *mut PangoMatrix) -> c_double;

    //=========================================================================
    // PangoGlyphString                                                  NOT OK
    //=========================================================================
    pub fn pango_glyph_string_new          () -> *mut PangoGlyphString;
    pub fn pango_glyph_string_copy         (string: *mut PangoGlyphString) -> *mut PangoGlyphString;
    pub fn pango_glyph_string_set_size     (string: *mut PangoGlyphString, new_len: c_int);
    pub fn pango_glyph_string_free         (string: *mut PangoGlyphString);
    pub fn pango_glyph_string_extents      (string: *mut PangoGlyphString, font: *mut PangoFont, ink_rect: *mut PangoRectangle,
        logical_rect: *mut PangoRectangle);
    pub fn pango_glyph_string_extents_range(string: *mut PangoGlyphString, start: c_int, end: c_int, font: *mut PangoFont,
        ink_rect: *mut PangoRectangle, logical_rect: *mut PangoRectangle);
    pub fn pango_glyph_string_get_width    (string: *mut PangoGlyphString) -> c_int;
    pub fn pango_glyph_string_index_to_x   (string: *mut PangoGlyphString, text: *mut c_char, length: c_int, analysis: *mut PangoAnalysis,
        index_: c_int, trailing: gboolean, x_pos: *mut c_int);
    pub fn pango_glyph_string_x_to_index   (string: *mut PangoGlyphString, text: *mut c_char, length: c_int, analysis: *mut PangoAnalysis,
        x_pos: c_int, index_: *mut c_int, trailing: *mut c_int);
    pub fn pango_glyph_string_get_logical_widths(glyphs: *mut PangoGlyphString, text: *mut c_char, length: c_int, embedding_level: c_int,
        logical_widths: *mut c_int);

    //=========================================================================
    // PangoScript                                                       NOT OK
    //=========================================================================
    pub fn pango_gravity_get_for_script    (script: enums::Script, base_gravity: enums::Gravity, hint: enums::GravityHint) -> enums::Gravity;
    pub fn pango_gravity_get_for_script_and_width(script: enums::Script, wide: gboolean, base_gravity: enums::Gravity,
        hint: enums::GravityHint) -> enums::Gravity;

    //=========================================================================
    // PangoGravity                                                      NOT OK
    //=========================================================================
    pub fn pango_gravity_to_rotation        (gravity: enums::Gravity) -> c_double;

    //=========================================================================
    // PangoDirection                                                    NOT OK
    //=========================================================================
    pub fn pango_unichar_direction          (ch: u32) -> enums::Direction;
    pub fn pango_find_base_dir              (text: *const c_char, length: c_int) -> enums::Direction;

    //=========================================================================
    // PangoBidiType                                                     NOT OK
    //=========================================================================
    pub fn pango_bidi_type_for_unichar      (ch: u32) -> enums::BidiType;

    //pub fn pango_itemize                  (context: *mut PangoContext, text: *const c_char, start_index: c_int, length: c_int,
    //    attrs: *mut PangoAttrList, cached_iter: *mut PangoAttrIterator) -> *mut GList;
    //pub fn pango_itemize_with_base_dir    (context: *mut PangoContext, direction: enums::Direction, text: *const c_char, start_index: c_int, length: c_int,
    //    attrs: *mut PangoAttrList, cached_iter: *mut PangoAttrIterator) -> *mut GList;
    //pub fn pango_reorder_items            (logical_items: *mut GList) -> *mut GList;
    pub fn pango_break                    (text: *const c_char, length: c_int, analysis: *mut PangoAnalysis, attrs: *mut PangoLogAttr,
        attrs_len: c_int);
    pub fn pango_get_log_attrs            (text: *const c_char, length: c_int, level: c_int, language: *mut PangoLanguage, log_attrs: *mut PangoLogAttr,
        attrs_len: c_int);
    pub fn pango_find_paragraph_boundary  (text: *const c_char, length: c_int, paragraph_delimiter_index: *mut c_int,
        next_paragraph_start: *mut c_int);
    pub fn pango_default_break            (text: *const c_char, length: c_int, analysis: *mut PangoAnalysis, attrs: *mut PangoLogAttr,
        attrs_len: c_int);
    pub fn pango_shape                    (text: *const c_char, length: c_int, analysis: *const PangoAnalysis, glyphs: *mut PangoGlyphString);
    pub fn pango_shape_full               (item_text: *const c_char, item_length: c_int, paragraph_text: *const c_char, paragraph_length: c_int,
        analysis: *const PangoAnalysis, glyphs: *mut PangoGlyphString);
}<|endoftext|>