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

extern crate aplib;
extern crate docopt;
extern crate rustc_serialize;
extern crate pbr;

use docopt::Docopt;
use rustc_serialize::{Decodable, Decoder};
use std::io::stderr;
use pbr::ProgressBar;

use aplib::AplibObject;
use aplib::Library;
use aplib::ModelInfo;
use aplib::Keyword;
use aplib::StoreWrapper;
use aplib::audit::{Reporter,Report};
use aplib::AlbumSubclass;
use aplib::FolderType;

const USAGE: &'static str = "
Usage:
  dumper <command> ([--all] | [--albums] [--versions] [--masters] [--folders] [--keywords]) <path>

Options:
    --all          Select all objects
    --albums       Select only albums
    --masters      Select only masters
    --folders      Select only folders
    --keywords     Select only keywords

Commands are:
    dump           Dump the objects
    audit          Audit mode: output what we ignored
";

#[derive(Debug, RustcDecodable)]
struct Args {
    arg_command: Command,
    arg_path: String,
    flag_all: bool,
    flag_albums: bool,
    flag_versions: bool,
    flag_masters: bool,
    flag_folders: bool,
    flag_keywords: bool
}

#[derive(Debug)]
enum Command {
    Dump,
    Audit,
    Unknown(String)
}

impl Decodable for Command {
    fn decode<D: Decoder>(d: &mut D) -> Result<Command, D::Error> {
        let s = try!(d.read_str());
        Ok(match &*s {
            "dump" => Command::Dump,
            "audit" => Command::Audit,
            s => Command::Unknown(s.to_owned()),
        })
    }
}

fn main() {

    let args: Args = Docopt::new(USAGE)
        .and_then(|d| d.decode())
        .unwrap_or_else(|e| e.exit());
    {
        match args.arg_command {
            Command::Dump =>
                process_dump(&args),
            Command::Audit =>
                process_audit(&args),
            _ =>
                ()
        };
    }
}

fn print_report(report: &Report) {
    println!("+---- Ignored {}", report.ignored_count());
    for key in report.get_ignored() {
        println!("    +- {}", key);
    }
    println!("+---- Skipped {}", report.skipped_count());
    for (key, reason) in report.get_skipped() {
        println!("    +- {} ({:?})", key, reason);
    }
}

fn process_audit(args: &Args) {

    let mut library = Library::new(&args.arg_path);

    let auditor = Reporter::new();
    library.set_auditor(Some(auditor));

    library.library_version();
    library.load_folders(&mut |_: u64| true);
    library.load_albums(&mut |_: u64| true);
    library.load_masters(&mut |_: u64| true);
    library.load_versions(&mut |_: u64| true);

    println!("Audit:");
    let auditor = library.get_auditor().unwrap();
    println!("Parsed {}", auditor.parsed_count());
    println!("+-----------------------------");
    for (key, ref report) in auditor.get_parsed() {
        if report.skipped_count() > 0 || report.ignored_count() > 0 {
            println!("| {} ", key);
            print_report(report);
        }
    }
    println!("+-----------------------------");
    println!("Skipped {}", auditor.skipped_count());
    for (key, _) in auditor.get_skipped() {
        println!("| {} ", key);
    }
    println!("Ignored {}", auditor.ignored_count());
    for key in auditor.get_ignored() {
        println!("| {} ", key);
    }
}

/// print the keywords with indentation for the hierarchy
fn print_keywords(keywords: &Vec<Keyword>, indent: &str) {
    for keyword in keywords {
        if !keyword.is_valid() {
            continue;
        }
        let name = keyword.name.as_ref().unwrap();
        let uuid = keyword.uuid().as_ref().unwrap();
        let parent = if let &Some(ref p) = keyword.parent() {
            p.clone()
        } else {
            "".to_owned()
        };
        println!("| {:<26} | {:<26} | {}{}",
                 uuid, parent, indent, name);
        if keyword.children.is_some() {
            let new_indent;
            if indent.is_empty() {
                new_indent = "+- ".to_owned() + indent;
            } else {
                new_indent = "\t".to_owned() + indent;
            }
            print_keywords(keyword.children.as_ref().unwrap(), &new_indent);
        }
    }
}

fn process_dump(args: &Args) {
    let mut library = Library::new(&args.arg_path);

    {
        let version = library.library_version();
        println!("Version {}", version);
    }

    let model_info = library.get_model_info().unwrap();
    println!("model info");
    println!("\tDB version: {}", model_info.db_version.unwrap_or(0));
    println!("\tDB minor version: {}", model_info.db_minor_version.unwrap_or(0));
    println!("\tDB back compat: {}", model_info.db_minor_back_compatible_version.unwrap_or(0));
    println!("\tProject version: {}", model_info.project_version.unwrap_or(0));
    println!("\tCreation date: {}", model_info.create_date.as_ref().unwrap_or(&"NONE".to_owned()));
    println!("\tImageIO: {} Camera RAW: {}",
             model_info.image_io_version.as_ref().unwrap_or(&"NONE".to_owned()),
             model_info.raw_camera_bundle_version.as_ref().unwrap_or(&"NONE".to_owned()));

    if args.flag_all || args.flag_folders {
        dump_folders(&mut library);
    }
    if args.flag_all || args.flag_albums {
        dump_albums(&mut library);
    }
    if args.flag_all || args.flag_keywords {
        dump_keywords(&mut library);
    }

    if args.flag_all || args.flag_masters  {
        dump_masters(&model_info, &mut library);
    }
    if args.flag_all || args.flag_versions  {
        dump_versions(&model_info, &mut library);
    }
}

fn dump_folders(library: &mut Library) {
    let mut pb = ProgressBar::on(stderr(), 1);
    pb.tick_format("|/-\\");

    library.load_folders(&mut |_: u64| {
        pb.tick();
        true
    });
    pb.finish();

    let folders = library.get_folders();
    println!("{} Folders:", folders.len());
    println!("| Name                       | uuid                       | impl album                 | type | model id | path");
    println!("+----------------------------+----------------------------+----------------------------+------+----------+----------");
    for folder_uuid in folders {
        if folder_uuid.is_empty() {
            continue;
        }
        match library.get(folder_uuid) {
            Some(&StoreWrapper::Folder(ref folder)) => {
                let name = folder.name.as_ref().unwrap();
                let uuid = folder.uuid().as_ref().unwrap();
                let implicit_album_uuid = if let Some(value) =
                    folder.implicit_album_uuid.as_ref() {
                        value
                    } else {
                        ""
                    };
                let path = folder.path.as_ref().unwrap();
                let folder_type = if let Some(ref ft) = folder.folder_type {
                    FolderType::to_int(ft)
                } else {
                    0
                };
                println!("| {:<26} | {:<26} | {:<26} | {:>4} | {:>8} | {}",
                         name, uuid, implicit_album_uuid,
                         folder_type, folder.model_id(), path)
            },
            _ => println!("folder {} not found", folder_uuid)
        }
    }
}

fn dump_albums(library: &mut Library) {
    let mut pb = ProgressBar::on(stderr(), 1);
    pb.tick_format("|/-\\");

    library.load_albums(&mut |_: u64| {
        pb.tick();
        true
    });
    pb.finish();

    let albums = library.get_albums();
    println!("{} Albums:", albums.len());
    println!("| uuid                       | parent (fldr)              | query (fldr)               | type | class | model id | name");
    println!("+----------------------------+----------------------------+----------------------------+------+-------+----------+-----");
    for album_uuid in albums {
        if album_uuid.is_empty() {
            continue;
        }
        match library.get(album_uuid) {
            Some(&StoreWrapper::Album(ref album)) => {
                let name = if let Some(ref n) = album.name {
                    n.clone()
                } else {
                    "".to_owned()
                };
                let uuid = album.uuid().as_ref().unwrap();
                let parent = if let &Some(ref p) = album.parent() {
                    p.clone()
                } else {
                    "".to_owned()
                };
                let query_folder_uuid = if let Some(ref qf) =
                    album.query_folder_uuid {
                        qf.clone()
                    } else {
                        "".to_owned()
                    };
                let album_class = if let Some(ref c) = album.subclass {
                    AlbumSubclass::to_int(c)
                } else {
                    0
                };
                println!("| {:<26} | {:<26} | {:<26} | {:>4} | {:>5} | {:>8} | {}",
                         uuid, parent, query_folder_uuid,
                         album.album_type.unwrap_or(0),
                         album_class, album.model_id(), name)
            },
            _ => println!("album {} not found", album_uuid)
        }
    }
}

fn dump_keywords(library: &mut Library) {
    if let Some(ref keywords) = library.list_keywords() {
        println!("{} keywords:", keywords.len());
        println!("| uuid                       | parent                     | name");
        println!("+----------------------------+----------------------------+-----------");
        print_keywords(keywords, &"".to_owned());
    }
}

fn dump_masters(model_info: &ModelInfo, library: &mut Library) {
    let count = model_info.master_count.unwrap_or(0) as u64;
    let mut pb = ProgressBar::on(stderr(), count);

    library.load_masters(&mut |inc: u64| {
        pb.add(inc);
        true
    });
    pb.finish();

    let masters = library.get_masters();
    println!("{} Masters:", masters.len());
    println!("| uuid                       | project                    | path");
    println!("+----------------------------+----------------------------+-----------------------");
    for master_uuid in masters {
        if master_uuid.is_empty() {
            continue;
        }
        match library.get(master_uuid) {
            Some(&StoreWrapper::Master(ref master)) => {
                let uuid = master.uuid().as_ref().unwrap();
                let parent = master.parent().as_ref().unwrap();
                let image_path = master.image_path.as_ref().unwrap();
                println!("| {:<26} | {:<26} | {}", uuid, parent, image_path)
            },
            _ => println!("master {} not found", master_uuid)
        }
    }
}

fn dump_versions(model_info: &ModelInfo, library: &mut Library) {

    let count = model_info.version_count.unwrap_or(0) as u64;
    let mut pb = ProgressBar::on(stderr(), count);

    library.load_versions(&mut |inc: u64| {
        pb.add(inc);
        true
    });
    pb.finish();

    let versions = library.get_versions();
    println!("{} Versions:", versions.len());
    println!("| uuid                       | master                     | project                    | original | name");
    println!("+----------------------------+----------------------------+----------------------------+----------+------------");
    for version_uuid in versions {
        if version_uuid.is_empty() {
            continue;
        }
        match library.get(version_uuid) {
            Some(&StoreWrapper::Version(ref version)) => {
                let uuid = version.uuid().as_ref().unwrap();
                let parent = version.parent().as_ref().unwrap();
                let project_uuid = version.project_uuid.as_ref().unwrap();
                let name = version.name.as_ref().unwrap();

                println!("| {:<26} | {:<26} | {:<26} | {:>8} | {}",
                         uuid, parent, project_uuid,
                         version.is_original.unwrap_or(false),
                         name)
                },
            _ => println!("version {} not found", version_uuid)
        }
    }
}
<commit_msg>dumper: sort the keys before displaying<commit_after>/*
  This Source Code Form is subject to the terms of the Mozilla Public
  License, v. 2.0. If a copy of the MPL was not distributed with this
  file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */

extern crate aplib;
extern crate docopt;
extern crate rustc_serialize;
extern crate pbr;

use docopt::Docopt;
use rustc_serialize::{Decodable, Decoder};
use std::io::stderr;
use pbr::ProgressBar;

use aplib::AplibObject;
use aplib::Library;
use aplib::ModelInfo;
use aplib::Keyword;
use aplib::StoreWrapper;
use aplib::audit::{Reporter,Report};
use aplib::AlbumSubclass;
use aplib::FolderType;

const USAGE: &'static str = "
Usage:
  dumper <command> ([--all] | [--albums] [--versions] [--masters] [--folders] [--keywords]) <path>

Options:
    --all          Select all objects
    --albums       Select only albums
    --masters      Select only masters
    --folders      Select only folders
    --keywords     Select only keywords

Commands are:
    dump           Dump the objects
    audit          Audit mode: output what we ignored
";

#[derive(Debug, RustcDecodable)]
struct Args {
    arg_command: Command,
    arg_path: String,
    flag_all: bool,
    flag_albums: bool,
    flag_versions: bool,
    flag_masters: bool,
    flag_folders: bool,
    flag_keywords: bool
}

#[derive(Debug)]
enum Command {
    Dump,
    Audit,
    Unknown(String)
}

impl Decodable for Command {
    fn decode<D: Decoder>(d: &mut D) -> Result<Command, D::Error> {
        let s = try!(d.read_str());
        Ok(match &*s {
            "dump" => Command::Dump,
            "audit" => Command::Audit,
            s => Command::Unknown(s.to_owned()),
        })
    }
}

fn main() {

    let args: Args = Docopt::new(USAGE)
        .and_then(|d| d.decode())
        .unwrap_or_else(|e| e.exit());
    {
        match args.arg_command {
            Command::Dump =>
                process_dump(&args),
            Command::Audit =>
                process_audit(&args),
            _ =>
                ()
        };
    }
}

fn print_report(report: &Report) {
    println!("+---- Ignored {}", report.ignored_count());
    let mut ignored: Vec<&String> = report.get_ignored().iter().collect();
    ignored.sort();
    for key in ignored {
        println!("    +- {}", key);
    }
    println!("+---- Skipped {}", report.skipped_count());
    let mut skipped: Vec<&String> = report.get_skipped().keys().collect();
    skipped.sort();
    for key in skipped {
        let reason = &report.get_skipped()[key];
        println!("    +- {} ({:?})", key, reason);
    }
}

fn process_audit(args: &Args) {

    let mut library = Library::new(&args.arg_path);

    let auditor = Reporter::new();
    library.set_auditor(Some(auditor));

    library.library_version();
    library.load_folders(&mut |_: u64| true);
    library.load_albums(&mut |_: u64| true);
    library.load_masters(&mut |_: u64| true);
    library.load_versions(&mut |_: u64| true);

    println!("Audit:");
    let auditor = library.get_auditor().unwrap();
    println!("Parsed {}", auditor.parsed_count());
    println!("+-----------------------------");
    for (key, ref report) in auditor.get_parsed() {
        if report.skipped_count() > 0 || report.ignored_count() > 0 {
            println!("| {} ", key);
            print_report(report);
        }
    }
    println!("+-----------------------------");
    println!("Skipped {}", auditor.skipped_count());
    for (key, _) in auditor.get_skipped() {
        println!("| {} ", key);
    }
    println!("Ignored {}", auditor.ignored_count());
    for key in auditor.get_ignored() {
        println!("| {} ", key);
    }
}

/// print the keywords with indentation for the hierarchy
fn print_keywords(keywords: &Vec<Keyword>, indent: &str) {
    for keyword in keywords {
        if !keyword.is_valid() {
            continue;
        }
        let name = keyword.name.as_ref().unwrap();
        let uuid = keyword.uuid().as_ref().unwrap();
        let parent = if let &Some(ref p) = keyword.parent() {
            p.clone()
        } else {
            "".to_owned()
        };
        println!("| {:<26} | {:<26} | {}{}",
                 uuid, parent, indent, name);
        if keyword.children.is_some() {
            let new_indent;
            if indent.is_empty() {
                new_indent = "+- ".to_owned() + indent;
            } else {
                new_indent = "\t".to_owned() + indent;
            }
            print_keywords(keyword.children.as_ref().unwrap(), &new_indent);
        }
    }
}

fn process_dump(args: &Args) {
    let mut library = Library::new(&args.arg_path);

    {
        let version = library.library_version();
        println!("Version {}", version);
    }

    let model_info = library.get_model_info().unwrap();
    println!("model info");
    println!("\tDB version: {}", model_info.db_version.unwrap_or(0));
    println!("\tDB minor version: {}", model_info.db_minor_version.unwrap_or(0));
    println!("\tDB back compat: {}", model_info.db_minor_back_compatible_version.unwrap_or(0));
    println!("\tProject version: {}", model_info.project_version.unwrap_or(0));
    println!("\tCreation date: {}", model_info.create_date.as_ref().unwrap_or(&"NONE".to_owned()));
    println!("\tImageIO: {} Camera RAW: {}",
             model_info.image_io_version.as_ref().unwrap_or(&"NONE".to_owned()),
             model_info.raw_camera_bundle_version.as_ref().unwrap_or(&"NONE".to_owned()));

    if args.flag_all || args.flag_folders {
        dump_folders(&mut library);
    }
    if args.flag_all || args.flag_albums {
        dump_albums(&mut library);
    }
    if args.flag_all || args.flag_keywords {
        dump_keywords(&mut library);
    }

    if args.flag_all || args.flag_masters  {
        dump_masters(&model_info, &mut library);
    }
    if args.flag_all || args.flag_versions  {
        dump_versions(&model_info, &mut library);
    }
}

fn dump_folders(library: &mut Library) {
    let mut pb = ProgressBar::on(stderr(), 1);
    pb.tick_format("|/-\\");

    library.load_folders(&mut |_: u64| {
        pb.tick();
        true
    });
    pb.finish();

    let folders = library.get_folders();
    println!("{} Folders:", folders.len());
    println!("| Name                       | uuid                       | impl album                 | type | model id | path");
    println!("+----------------------------+----------------------------+----------------------------+------+----------+----------");
    for folder_uuid in folders {
        if folder_uuid.is_empty() {
            continue;
        }
        match library.get(folder_uuid) {
            Some(&StoreWrapper::Folder(ref folder)) => {
                let name = folder.name.as_ref().unwrap();
                let uuid = folder.uuid().as_ref().unwrap();
                let implicit_album_uuid = if let Some(value) =
                    folder.implicit_album_uuid.as_ref() {
                        value
                    } else {
                        ""
                    };
                let path = folder.path.as_ref().unwrap();
                let folder_type = if let Some(ref ft) = folder.folder_type {
                    FolderType::to_int(ft)
                } else {
                    0
                };
                println!("| {:<26} | {:<26} | {:<26} | {:>4} | {:>8} | {}",
                         name, uuid, implicit_album_uuid,
                         folder_type, folder.model_id(), path)
            },
            _ => println!("folder {} not found", folder_uuid)
        }
    }
}

fn dump_albums(library: &mut Library) {
    let mut pb = ProgressBar::on(stderr(), 1);
    pb.tick_format("|/-\\");

    library.load_albums(&mut |_: u64| {
        pb.tick();
        true
    });
    pb.finish();

    let albums = library.get_albums();
    println!("{} Albums:", albums.len());
    println!("| uuid                       | parent (fldr)              | query (fldr)               | type | class | model id | name");
    println!("+----------------------------+----------------------------+----------------------------+------+-------+----------+-----");
    for album_uuid in albums {
        if album_uuid.is_empty() {
            continue;
        }
        match library.get(album_uuid) {
            Some(&StoreWrapper::Album(ref album)) => {
                let name = if let Some(ref n) = album.name {
                    n.clone()
                } else {
                    "".to_owned()
                };
                let uuid = album.uuid().as_ref().unwrap();
                let parent = if let &Some(ref p) = album.parent() {
                    p.clone()
                } else {
                    "".to_owned()
                };
                let query_folder_uuid = if let Some(ref qf) =
                    album.query_folder_uuid {
                        qf.clone()
                    } else {
                        "".to_owned()
                    };
                let album_class = if let Some(ref c) = album.subclass {
                    AlbumSubclass::to_int(c)
                } else {
                    0
                };
                println!("| {:<26} | {:<26} | {:<26} | {:>4} | {:>5} | {:>8} | {}",
                         uuid, parent, query_folder_uuid,
                         album.album_type.unwrap_or(0),
                         album_class, album.model_id(), name)
            },
            _ => println!("album {} not found", album_uuid)
        }
    }
}

fn dump_keywords(library: &mut Library) {
    if let Some(ref keywords) = library.list_keywords() {
        println!("{} keywords:", keywords.len());
        println!("| uuid                       | parent                     | name");
        println!("+----------------------------+----------------------------+-----------");
        print_keywords(keywords, &"".to_owned());
    }
}

fn dump_masters(model_info: &ModelInfo, library: &mut Library) {
    let count = model_info.master_count.unwrap_or(0) as u64;
    let mut pb = ProgressBar::on(stderr(), count);

    library.load_masters(&mut |inc: u64| {
        pb.add(inc);
        true
    });
    pb.finish();

    let masters = library.get_masters();
    println!("{} Masters:", masters.len());
    println!("| uuid                       | project                    | path");
    println!("+----------------------------+----------------------------+-----------------------");
    for master_uuid in masters {
        if master_uuid.is_empty() {
            continue;
        }
        match library.get(master_uuid) {
            Some(&StoreWrapper::Master(ref master)) => {
                let uuid = master.uuid().as_ref().unwrap();
                let parent = master.parent().as_ref().unwrap();
                let image_path = master.image_path.as_ref().unwrap();
                println!("| {:<26} | {:<26} | {}", uuid, parent, image_path)
            },
            _ => println!("master {} not found", master_uuid)
        }
    }
}

fn dump_versions(model_info: &ModelInfo, library: &mut Library) {

    let count = model_info.version_count.unwrap_or(0) as u64;
    let mut pb = ProgressBar::on(stderr(), count);

    library.load_versions(&mut |inc: u64| {
        pb.add(inc);
        true
    });
    pb.finish();

    let versions = library.get_versions();
    println!("{} Versions:", versions.len());
    println!("| uuid                       | master                     | project                    | original | name");
    println!("+----------------------------+----------------------------+----------------------------+----------+------------");
    for version_uuid in versions {
        if version_uuid.is_empty() {
            continue;
        }
        match library.get(version_uuid) {
            Some(&StoreWrapper::Version(ref version)) => {
                let uuid = version.uuid().as_ref().unwrap();
                let parent = version.parent().as_ref().unwrap();
                let project_uuid = version.project_uuid.as_ref().unwrap();
                let name = version.name.as_ref().unwrap();

                println!("| {:<26} | {:<26} | {:<26} | {:>8} | {}",
                         uuid, parent, project_uuid,
                         version.is_original.unwrap_or(false),
                         name)
                },
            _ => println!("version {} not found", version_uuid)
        }
    }
}
<|endoftext|>


<commit_before>
fn main() {

    // formatted output
    println!("Hello, Rust!");
    println!("Integer number = {}", 23);
    println!("Float number = {}", 1.012);
    println!("Repeat printing: {0}, {1}, {1}, {3}, {2}", 2, 1, 44, 9);
    println!("Named arguments: {name}, {age}, {occupation}", age="24", name="Ann", occupation="Designer");
    println!("{:08b} XOR {:08b} = {:08b}", 3i8, 32i8, 3i8 ^ 34i8);
    println!("Floating point number {:?}", 2.910210);
    println!("Hex: {:08X}, {:08x}", 131342112, 131342112);
    // TODO find out why this doesn't work:
    //println!("{0:08X}, {0:08x}", 7661);

    // variables
    let integer = 3i32;
    let floatingPoint = 2.1137;

    let mut uInteger = 3u32;
    //integer += 1; error: an immutable variable
    uInteger += 1;

    println!("{}, {}, {}", integer, floatingPoint, uInteger);
    // TODO find out why snake case instead of camel case

    // shadowing
    let first_var = 4;
    {
        let first_var = 51;
        println!("first_var = {}", first_var);
    }
    println!("first_var = {}", first_var);

    // unitialized variables
    let uninit_var;
    //println!("uninit_var = {}", uninit_var); error: use of an init variable
    uninit_var = 231.2;
    println!("already initialized uninit_var = {}", uninit_var);

    // type casting
    let a_integer = 0x40_u8;
    let a_char = a_integer as char;
    println!("char cast from integer {}: {}", a_integer, a_char);

    let a_float = 8.45511;
    println!("integer cast from float {}: {}", a_float, a_float as i32);

    println!("Binary represntation of {}: {:08b}", -1_i8, -1_i8);
    println!("Binary represntation of {}: {:08b}", -2_i8, -2_i8);

    // aliases
    type FloatingPoint32 = f32;
    let a_float_2 : FloatingPoint32 = 3 as f32;
    println!("Type alias: {}, size of var {}", a_float_2, std::mem::size_of_val(&a_float_2));

    // expressions
    let expr = {
        let x = 4.09;
        let y = 1.28;
        println!("x = {}, y = {}", x, y);
        x / y
    };
    println!("expr = {}", expr);

    // if-statement (every if-statement is an expression too, which is really a cool thing)
    let speed = 10;
    let mass = 890;
    let consumption =
        if speed < 0 {
            -1.0
        }
        else if speed == 0 {
            0.8
        }
        else if speed > 0 && speed < 10 {
            18.52
        }
        else if speed >= 10 && speed < 30 {
            let x = mass / speed;
            (x as f32) * 0.05
        }
        else {
            11.71
        };
        println!("Speed = {}, consumption = {}", speed, consumption);

        // loop
        let mut count = 0u32;
        loop {
            println!("loop iteration #{}", count);
            count += 1;
            if count > 9 {
            break;
            }
        }

        count = 0;
        while count < 10 {
            println!("while loop iteration #{}", count);
            count += 1;
        }

        for n in 0u32..10 {
            println!("for loop iteration #{}", n);
        }

        // matching
        let age = 19;
        match age {
            1  => println!("Seems like 1"),
            5  => println!("It's 5"),
            18 => println!("Exactly 18!"),
            _  => println!("I couldn't guess :("),
        }

        match age {
            a if a > 1 && a <= 9  => println!("The age is in range [1,9]"),
            a if a > 9 && a <= 19 => println!("The age is in range [10, 19]"),
            _                     => println!("Nothing, I don't know what range the age is in :("),
        }

        // the previous match is equivalent to the following:
        match age {
            a @ 1...9   => println!("The age is in range [1,9]"),
            a @ 10...19 => println!("The age is in range [10, 19]"),
            a           => println!("Nothing, I don't know what range the age is in :("),
        }
}
<commit_msg>Progress: if-let<commit_after>
fn main() {

    // formatted output
    println!("Hello, Rust!");
    println!("Integer number = {}", 23);
    println!("Float number = {}", 1.012);
    println!("Repeat printing: {0}, {1}, {1}, {3}, {2}", 2, 1, 44, 9);
    println!("Named arguments: {name}, {age}, {occupation}", age="24", name="Ann", occupation="Designer");
    println!("{:08b} XOR {:08b} = {:08b}", 3i8, 32i8, 3i8 ^ 34i8);
    println!("Floating point number {:?}", 2.910210);
    println!("Hex: {:08X}, {:08x}", 131342112, 131342112);
    // TODO find out why this doesn't work:
    //println!("{0:08X}, {0:08x}", 7661);

    // variables
    let integer = 3i32;
    let floatingPoint = 2.1137;

    let mut uInteger = 3u32;
    //integer += 1; error: an immutable variable
    uInteger += 1;

    println!("{}, {}, {}", integer, floatingPoint, uInteger);
    // TODO find out why snake case instead of camel case

    // shadowing
    let first_var = 4;
    {
        let first_var = 51;
        println!("first_var = {}", first_var);
    }
    println!("first_var = {}", first_var);

    // unitialized variables
    let uninit_var;
    //println!("uninit_var = {}", uninit_var); error: use of an init variable
    uninit_var = 231.2;
    println!("already initialized uninit_var = {}", uninit_var);

    // type casting
    let a_integer = 0x40_u8;
    let a_char = a_integer as char;
    println!("char cast from integer {}: {}", a_integer, a_char);

    let a_float = 8.45511;
    println!("integer cast from float {}: {}", a_float, a_float as i32);

    println!("Binary represntation of {}: {:08b}", -1_i8, -1_i8);
    println!("Binary represntation of {}: {:08b}", -2_i8, -2_i8);

    // aliases
    type FloatingPoint32 = f32;
    let a_float_2 : FloatingPoint32 = 3 as f32;
    println!("Type alias: {}, size of var {}", a_float_2, std::mem::size_of_val(&a_float_2));

    // expressions
    let expr = {
        let x = 4.09;
        let y = 1.28;
        println!("x = {}, y = {}", x, y);
        x / y
    };
    println!("expr = {}", expr);

    // if-statement (every if-statement is an expression too, which is really a cool thing)
    let speed = 10;
    let mass = 890;
    let consumption =
        if speed < 0 {
            -1.0
        }
        else if speed == 0 {
            0.8
        }
        else if speed > 0 && speed < 10 {
            18.52
        }
        else if speed >= 10 && speed < 30 {
            let x = mass / speed;
            (x as f32) * 0.05
        }
        else {
            11.71
        };
        println!("Speed = {}, consumption = {}", speed, consumption);

        // loop
        let mut count = 0u32;
        loop {
            println!("loop iteration #{}", count);
            count += 1;
            if count > 9 {
            break;
            }
        }

        count = 0;
        while count < 10 {
            println!("while loop iteration #{}", count);
            count += 1;
        }

        for n in 0u32..10 {
            println!("for loop iteration #{}", n);
        }

        // matching
        let age = 19;
        match age {
            1  => println!("Seems like 1"),
            5  => println!("It's 5"),
            18 => println!("Exactly 18!"),
            _  => println!("I couldn't guess :("),
        }

        match age {
            a if a > 1 && a <= 9  => println!("The age is in range [1,9]"),
            a if a > 9 && a <= 19 => println!("The age is in range [10, 19]"),
            _                     => println!("Nothing, I don't know what range the age is in :("),
        }

        // the previous match is equivalent to the following:
        match age {
            a @ 1...9   => println!("The age is in range [1,9]"),
            a @ 10...19 => println!("The age is in range [10, 19]"),
            a           => println!("Nothing, I don't know what range the age is in :("),
        }

        // if let
        let a_some = Some(0.0008);
        if let Some(i) = a_some {
            println!("a_some is not None, {}", i);
            println!("result {}",  9.0 / i);
        }
        else {
            println!("None");
        }

}
<|endoftext|>


<commit_before>//! Write systems to disk.

//use error::Result;
use config::Result;
use grafen::system::System;

use std::fs::File;
use std::io::{BufWriter, Write};
use std::path::PathBuf;

/// Output a system to disk as a GROMOS formatted file.
/// The filename extension is adjusted to .gro.
///
/// # Errors
/// Returns an error if the file could not be written to.
pub fn write_gromos(system: &System, output_file: &str, title: &str, box_z: f64) -> Result<()> {
    let path = PathBuf::from(output_file).with_extension("gro");
    let file = File::create(&path)?;
    let mut writer = BufWriter::new(file);

    writer.write_fmt(format_args!("{}\n", title))?;
    writer.write_fmt(format_args!("{}\n", system.num_atoms()))?;

    for (i, residue) in system.residues.iter().enumerate() {
        for (j, atom) in residue.atoms.iter().enumerate() {
            let residue_number = (i + 1) % 100_000;
            let atom_number = (j + 1) % 100_000;

            let position = residue.position.add(&atom.position);

            writer.write_fmt(format_args!("{:>5}{:<5}{:>5}{:>5}{:>8.3}{:>8.3}{:>8.3}\n",
                                        residue_number,
                                        residue.code,
                                        atom.code,
                                        atom_number,
                                        position.x,
                                        position.y,
                                        position.z))?;

        }
    }

    writer.write_fmt(format_args!("{:12.8} {:12.8} {:12.8}\n",
                                system.dimensions.x,
                                system.dimensions.y,
                                system.dimensions.z + box_z))?;

    Ok(())
}
<commit_msg>Add comment about GROMOS numbering output<commit_after>//! Write systems to disk.

//use error::Result;
use config::Result;
use grafen::system::System;

use std::fs::File;
use std::io::{BufWriter, Write};
use std::path::PathBuf;

/// Output a system to disk as a GROMOS formatted file.
/// The filename extension is adjusted to .gro.
///
/// # Errors
/// Returns an error if the file could not be written to.
pub fn write_gromos(system: &System, output_file: &str, title: &str, box_z: f64) -> Result<()> {
    let path = PathBuf::from(output_file).with_extension("gro");
    let file = File::create(&path)?;
    let mut writer = BufWriter::new(file);

    writer.write_fmt(format_args!("{}\n", title))?;
    writer.write_fmt(format_args!("{}\n", system.num_atoms()))?;

    for (i, residue) in system.residues.iter().enumerate() {
        for (j, atom) in residue.atoms.iter().enumerate() {
            // GROMOS files wrap atom and residue numbering after five digits
            // so we must output at most that. We also switch to indexing the
            // numbers from 1 instead of from 0.
            let residue_number = (i + 1) % 100_000;
            let atom_number = (j + 1) % 100_000;

            let position = residue.position.add(&atom.position);

            writer.write_fmt(format_args!("{:>5}{:<5}{:>5}{:>5}{:>8.3}{:>8.3}{:>8.3}\n",
                                        residue_number,
                                        residue.code,
                                        atom.code,
                                        atom_number,
                                        position.x,
                                        position.y,
                                        position.z))?;

        }
    }

    writer.write_fmt(format_args!("{:12.8} {:12.8} {:12.8}\n",
                                system.dimensions.x,
                                system.dimensions.y,
                                system.dimensions.z + box_z))?;

    Ok(())
}
<|endoftext|>


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

// compile-flags: -C no-prepopulate-passes

#![crate_type = "lib"]

struct SomeUniqueName;

impl Drop for SomeUniqueName {
    fn drop(&mut self) {
    }
}

pub fn possibly_unwinding() {
}

// CHECK-LABEL: @droppy
#[no_mangle]
pub fn droppy() {
// Check that there are exactly 6 drop calls. The cleanups for the unwinding should be reused, so
// that's one new drop call per call to possibly_unwinding(), and finally 3 drop calls for the
// regular function exit. We used to have problems with quadratic growths of drop calls in such
// functions.
// CHECK-NOT: invoke{{.*}}drop{{.*}}SomeUniqueName
// CHECK: call{{.*}}drop{{.*}}SomeUniqueName
// CHECK: call{{.*}}drop{{.*}}SomeUniqueName
// CHECK: call{{.*}}drop{{.*}}SomeUniqueName
// CHECK-NOT: call{{.*}}drop{{.*}}SomeUniqueName
// CHECK: invoke{{.*}}drop{{.*}}SomeUniqueName
// CHECK: invoke{{.*}}drop{{.*}}SomeUniqueName
// CHECK: call{{.*}}drop{{.*}}SomeUniqueName
// CHECK-NOT: {{(call|invoke).*}}drop{{.*}}SomeUniqueName
// The next line checks for the } that ends the function definition
// CHECK-LABEL: {{^[}]}}
    let _s = SomeUniqueName;
    possibly_unwinding();
    let _s = SomeUniqueName;
    possibly_unwinding();
    let _s = SomeUniqueName;
    possibly_unwinding();
}
<commit_msg>Update test/codegen/drop.rs to reflect inconsequential change in basic block ordering.<commit_after>// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// compile-flags: -C no-prepopulate-passes

#![crate_type = "lib"]

struct SomeUniqueName;

impl Drop for SomeUniqueName {
    fn drop(&mut self) {
    }
}

pub fn possibly_unwinding() {
}

// CHECK-LABEL: @droppy
#[no_mangle]
pub fn droppy() {
// Check that there are exactly 6 drop calls. The cleanups for the unwinding should be reused, so
// that's one new drop call per call to possibly_unwinding(), and finally 3 drop calls for the
// regular function exit. We used to have problems with quadratic growths of drop calls in such
// functions.
// CHECK-NOT: invoke{{.*}}drop{{.*}}SomeUniqueName
// CHECK: call{{.*}}drop{{.*}}SomeUniqueName
// CHECK: call{{.*}}drop{{.*}}SomeUniqueName
// CHECK-NOT: call{{.*}}drop{{.*}}SomeUniqueName
// CHECK: invoke{{.*}}drop{{.*}}SomeUniqueName
// CHECK: call{{.*}}drop{{.*}}SomeUniqueName
// CHECK: invoke{{.*}}drop{{.*}}SomeUniqueName
// CHECK: call{{.*}}drop{{.*}}SomeUniqueName
// CHECK-NOT: {{(call|invoke).*}}drop{{.*}}SomeUniqueName
// The next line checks for the } that ends the function definition
// CHECK-LABEL: {{^[}]}}
    let _s = SomeUniqueName;
    possibly_unwinding();
    let _s = SomeUniqueName;
    possibly_unwinding();
    let _s = SomeUniqueName;
    possibly_unwinding();
}
<|endoftext|>


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

use browser_host::{ServoCefBrowserHost, ServoCefBrowserHostExtensions};
use eutil::Downcast;
use frame::{ServoCefFrame, ServoCefFrameExtensions};
use interfaces::{CefBrowser, CefBrowserHost, CefClient, CefFrame, CefRequestContext};
use interfaces::{cef_browser_t, cef_browser_host_t, cef_client_t, cef_frame_t};
use interfaces::{cef_request_context_t};
use servo::Browser;
use types::{cef_browser_settings_t, cef_string_t, cef_window_info_t, cef_window_handle_t};
use window;
use wrappers::CefWrap;

use compositing::windowing::{WindowNavigateMsg, WindowEvent};
use glutin_app;
use libc::c_int;
use std::cell::{Cell, RefCell, BorrowState};
use std::ptr;
use std::rc::Rc;
use std::sync::atomic::{AtomicIsize, Ordering};

thread_local!(pub static ID_COUNTER: AtomicIsize = AtomicIsize::new(0));
thread_local!(pub static BROWSERS: RefCell<Vec<CefBrowser>> = RefCell::new(vec!()));

pub enum ServoBrowser {
    Invalid,
    OnScreen(Browser),
    OffScreen(Browser),
}

impl ServoBrowser {
    fn handle_event(&mut self, event: WindowEvent) {
        match *self {
            ServoBrowser::OnScreen(ref mut browser) => { browser.handle_events(vec![event]); }
            ServoBrowser::OffScreen(ref mut browser) => { browser.handle_events(vec![event]); }
            ServoBrowser::Invalid => {}
        }
    }

    pub fn get_title_for_main_frame(&self) {
        match *self {
            ServoBrowser::OnScreen(ref browser) => browser.get_title_for_main_frame(),
            ServoBrowser::OffScreen(ref browser) => browser.get_title_for_main_frame(),
            ServoBrowser::Invalid => {}
        }
    }

    pub fn pinch_zoom_level(&self) -> f32 {
        match *self {
            ServoBrowser::OnScreen(ref browser) => browser.pinch_zoom_level(),
            ServoBrowser::OffScreen(ref browser) => browser.pinch_zoom_level(),
            ServoBrowser::Invalid => 1.0,
        }
    }
}

cef_class_impl! {
    ServoCefBrowser : CefBrowser, cef_browser_t {
        fn get_host(&this,) -> *mut cef_browser_host_t {{
            this.downcast().host.clone()
        }}

        fn can_go_back(&this,) -> c_int {{
            this.downcast().back.get() as c_int
        }}

        fn can_go_forward(&this,) -> c_int {{
            this.downcast().forward.get() as c_int
        }}

        fn is_loading(&this,) -> c_int {{
            this.downcast().loading.get() as c_int
        }}

        fn go_back(&this,) -> () {{
            this.send_window_event(WindowEvent::Navigation(WindowNavigateMsg::Back));
        }}

        fn go_forward(&this,) -> () {{
            this.send_window_event(WindowEvent::Navigation(WindowNavigateMsg::Forward));
        }}

        // Returns the main (top-level) frame for the browser window.
        fn get_main_frame(&this,) -> *mut cef_frame_t {{
            this.downcast().frame.clone()
        }}

        fn get_identifier(&this,) -> c_int {{
            this.downcast().id as c_int
        }}
    }
}

pub struct ServoCefBrowser {
    /// A reference to the browser's primary frame.
    pub frame: CefFrame,
    /// A reference to the browser's host.
    pub host: CefBrowserHost,
    /// A reference to the browser client.
    pub client: CefClient,
    /// the glutin window when using windowed rendering
    pub window: Option<Rc<glutin_app::window::Window>>,
    /// Whether the on-created callback has fired yet.
    pub callback_executed: Cell<bool>,
    /// whether the browser can navigate back
    pub back: Cell<bool>,
    /// whether the browser can navigate forward
    pub forward: Cell<bool>,
    /// whether the browser is loading
    pub loading: Cell<bool>,
    /// the display system window handle: only to be used with host.get_window_handle()
    window_handle: cef_window_handle_t,

    id: isize,
    servo_browser: RefCell<ServoBrowser>,
    message_queue: RefCell<Vec<WindowEvent>>,
}

impl ServoCefBrowser {
    pub fn new(window_info: &cef_window_info_t, client: CefClient) -> ServoCefBrowser {
        let frame = ServoCefFrame::new().as_cef_interface();
        let host = ServoCefBrowserHost::new(client.clone()).as_cef_interface();
        let mut window_handle: cef_window_handle_t = get_null_window_handle();
        let mut glutin_window: Option<Rc<glutin_app::window::Window>> = None;

        let servo_browser = if window_info.windowless_rendering_enabled == 0 {
            glutin_window = Some(glutin_app::create_window(window_info.parent_window as glutin_app::WindowID));
            let servo_browser = Browser::new(glutin_window.clone());
            window_handle = match glutin_window {
                Some(ref win) => win.platform_window() as cef_window_handle_t,
                None => get_null_window_handle()
            };
            ServoBrowser::OnScreen(servo_browser)
        } else {
            ServoBrowser::Invalid
        };

        let id = ID_COUNTER.with(|counter| {
            counter.fetch_add(1, Ordering::SeqCst)
        });

        ServoCefBrowser {
            frame: frame,
            host: host,
            client: client,
            window: glutin_window,
            callback_executed: Cell::new(false),
            servo_browser: RefCell::new(servo_browser),
            message_queue: RefCell::new(vec!()),
            id: id,
            back: Cell::new(false),
            forward: Cell::new(false),
            loading: Cell::new(false),
            window_handle: window_handle,
        }
    }
}

pub trait ServoCefBrowserExtensions {
    fn init(&self, window_info: &cef_window_info_t);
    fn send_window_event(&self, event: WindowEvent);
    fn get_title_for_main_frame(&self);
    fn pinch_zoom_level(&self) -> f32;
}

impl ServoCefBrowserExtensions for CefBrowser {
    fn init(&self, window_info: &cef_window_info_t) {
        if window_info.windowless_rendering_enabled != 0 {
            let window = window::Window::new(window_info.width, window_info.height);
            window.set_browser(self.clone());
            let servo_browser = Browser::new(Some(window.clone()));
            *self.downcast().servo_browser.borrow_mut() = ServoBrowser::OffScreen(servo_browser);
        }

        self.downcast().host.set_browser((*self).clone());
        self.downcast().frame.set_browser((*self).clone());
        if window_info.windowless_rendering_enabled == 0 {
            self.downcast().host.initialize_compositing();
        }
    }

    fn send_window_event(&self, event: WindowEvent) {
        self.downcast().message_queue.borrow_mut().push(event);

        loop {
            match self.downcast().servo_browser.borrow_state() {
                BorrowState::Unused => {
                    let event = match self.downcast().message_queue.borrow_mut().pop() {
                        None => return,
                        Some(event) => event,
                    };
                    self.downcast().servo_browser.borrow_mut().handle_event(event);
                }
                _ => {
                    // We're trying to send an event while processing another one. This will
                    // cause general badness, so queue up that event instead of immediately
                    // processing it.
                    break
                }
            }
        }
    }

    fn get_title_for_main_frame(&self) {
        self.downcast().servo_browser.borrow().get_title_for_main_frame()
    }

    fn pinch_zoom_level(&self) -> f32 {
        self.downcast().servo_browser.borrow().pinch_zoom_level()
    }
}

#[cfg(target_os="macos")]
pub fn get_null_window_handle() -> cef_window_handle_t {
    ptr::null_mut()
}
#[cfg(target_os="linux")]
pub fn get_null_window_handle() -> cef_window_handle_t {
    0
}

pub fn update() {
    BROWSERS.with(|browsers| {
        for browser in browsers.borrow().iter() {
            if browser.downcast().callback_executed.get() == false {
                browser_callback_after_created(browser.clone());
            }
            let mut events = match browser.downcast().window {
                Some(ref win) => win.wait_events(),
                None => vec![WindowEvent::Idle]
            };
            loop {
               match events.pop() {
                   Some(event) => browser.send_window_event(event),
                   None => break
               }
            }
        }
    });
}

pub fn close(browser: CefBrowser) {
    BROWSERS.with(|browsers| {
        let mut browsers = browsers.borrow_mut();
        browsers.iter()
                .position(|&ref n| n.downcast().id == browser.downcast().id)
                .map(|e| browsers.remove(e));
    });
}

pub fn get_window(browser: &CefBrowser) -> cef_window_handle_t {
    browser.downcast().window_handle
}

pub fn browser_callback_after_created(browser: CefBrowser) {
    if browser.downcast().client.is_null_cef_object() {
        return
    }
    let client = browser.downcast().client.clone();
    let life_span_handler = client.get_life_span_handler();
    if life_span_handler.is_not_null_cef_object() {
        life_span_handler.on_after_created(browser.clone());
    }
    browser.downcast().callback_executed.set(true);
    browser.downcast().frame.load();
}

fn browser_host_create(window_info: &cef_window_info_t,
                       client: CefClient,
                       url: *const cef_string_t,
                       callback_executed: bool)
                       -> CefBrowser {
    let browser = ServoCefBrowser::new(window_info, client).as_cef_interface();
    browser.init(window_info);
    if url != ptr::null() {
       unsafe { browser.downcast().frame.set_url(CefWrap::to_rust(url)); }
    }
    if callback_executed {
        browser_callback_after_created(browser.clone());
    }
    BROWSERS.with(|browsers| {
        browsers.borrow_mut().push(browser.clone());
    });
    browser
}

cef_static_method_impls! {
    fn cef_browser_host_create_browser(window_info: *const cef_window_info_t,
                                       client: *mut cef_client_t,
                                       url: *const cef_string_t,
                                       _browser_settings: *const cef_browser_settings_t,
                                       _request_context: *mut cef_request_context_t)
                                       -> c_int {{
        let client: CefClient = client;
        let _browser_settings: &cef_browser_settings_t = _browser_settings;
        let _request_context: CefRequestContext = _request_context;
        browser_host_create(window_info, client, url, false);
        1i32
    }}
    fn cef_browser_host_create_browser_sync(window_info: *const cef_window_info_t,
                                            client: *mut cef_client_t,
                                            url: *const cef_string_t,
                                            _browser_settings: *const cef_browser_settings_t,
                                            _request_context: *mut cef_request_context_t)
                                            -> *mut cef_browser_t {{
        let client: CefClient = client;
        let _browser_settings: &cef_browser_settings_t = _browser_settings;
        let _request_context: CefRequestContext = _request_context;
        browser_host_create(window_info, client, url, true)
    }}
}
<commit_msg>spawn a task for cef async browser creation to kick the main loop awake<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use browser_host::{ServoCefBrowserHost, ServoCefBrowserHostExtensions};
use eutil::Downcast;
use frame::{ServoCefFrame, ServoCefFrameExtensions};
use interfaces::{CefBrowser, CefBrowserHost, CefClient, CefFrame, CefRequestContext};
use interfaces::{cef_browser_t, cef_browser_host_t, cef_client_t, cef_frame_t};
use interfaces::{cef_request_context_t};
use servo::Browser;
use types::{cef_browser_settings_t, cef_string_t, cef_window_info_t, cef_window_handle_t};
use util::task::spawn_named;
use window;
use wrappers::CefWrap;

use compositing::windowing::{WindowNavigateMsg, WindowEvent};
use glutin_app;
use libc::c_int;
use std::cell::{Cell, RefCell, BorrowState};
use std::ptr;
use std::rc::Rc;
use std::sync::atomic::{AtomicIsize, Ordering};

thread_local!(pub static ID_COUNTER: AtomicIsize = AtomicIsize::new(0));
thread_local!(pub static BROWSERS: RefCell<Vec<CefBrowser>> = RefCell::new(vec!()));

pub enum ServoBrowser {
    Invalid,
    OnScreen(Browser),
    OffScreen(Browser),
}

impl ServoBrowser {
    fn handle_event(&mut self, event: WindowEvent) {
        match *self {
            ServoBrowser::OnScreen(ref mut browser) => { browser.handle_events(vec![event]); }
            ServoBrowser::OffScreen(ref mut browser) => { browser.handle_events(vec![event]); }
            ServoBrowser::Invalid => {}
        }
    }

    pub fn get_title_for_main_frame(&self) {
        match *self {
            ServoBrowser::OnScreen(ref browser) => browser.get_title_for_main_frame(),
            ServoBrowser::OffScreen(ref browser) => browser.get_title_for_main_frame(),
            ServoBrowser::Invalid => {}
        }
    }

    pub fn pinch_zoom_level(&self) -> f32 {
        match *self {
            ServoBrowser::OnScreen(ref browser) => browser.pinch_zoom_level(),
            ServoBrowser::OffScreen(ref browser) => browser.pinch_zoom_level(),
            ServoBrowser::Invalid => 1.0,
        }
    }
}

cef_class_impl! {
    ServoCefBrowser : CefBrowser, cef_browser_t {
        fn get_host(&this,) -> *mut cef_browser_host_t {{
            this.downcast().host.clone()
        }}

        fn can_go_back(&this,) -> c_int {{
            this.downcast().back.get() as c_int
        }}

        fn can_go_forward(&this,) -> c_int {{
            this.downcast().forward.get() as c_int
        }}

        fn is_loading(&this,) -> c_int {{
            this.downcast().loading.get() as c_int
        }}

        fn go_back(&this,) -> () {{
            this.send_window_event(WindowEvent::Navigation(WindowNavigateMsg::Back));
        }}

        fn go_forward(&this,) -> () {{
            this.send_window_event(WindowEvent::Navigation(WindowNavigateMsg::Forward));
        }}

        // Returns the main (top-level) frame for the browser window.
        fn get_main_frame(&this,) -> *mut cef_frame_t {{
            this.downcast().frame.clone()
        }}

        fn get_identifier(&this,) -> c_int {{
            this.downcast().id as c_int
        }}
    }
}

pub struct ServoCefBrowser {
    /// A reference to the browser's primary frame.
    pub frame: CefFrame,
    /// A reference to the browser's host.
    pub host: CefBrowserHost,
    /// A reference to the browser client.
    pub client: CefClient,
    /// the glutin window when using windowed rendering
    pub window: Option<Rc<glutin_app::window::Window>>,
    /// Whether the on-created callback has fired yet.
    pub callback_executed: Cell<bool>,
    /// whether the browser can navigate back
    pub back: Cell<bool>,
    /// whether the browser can navigate forward
    pub forward: Cell<bool>,
    /// whether the browser is loading
    pub loading: Cell<bool>,
    /// the display system window handle: only to be used with host.get_window_handle()
    window_handle: cef_window_handle_t,

    id: isize,
    servo_browser: RefCell<ServoBrowser>,
    message_queue: RefCell<Vec<WindowEvent>>,
}

impl ServoCefBrowser {
    pub fn new(window_info: &cef_window_info_t, client: CefClient) -> ServoCefBrowser {
        let frame = ServoCefFrame::new().as_cef_interface();
        let host = ServoCefBrowserHost::new(client.clone()).as_cef_interface();
        let mut window_handle: cef_window_handle_t = get_null_window_handle();
        let mut glutin_window: Option<Rc<glutin_app::window::Window>> = None;

        let servo_browser = if window_info.windowless_rendering_enabled == 0 {
            glutin_window = Some(glutin_app::create_window(window_info.parent_window as glutin_app::WindowID));
            let servo_browser = Browser::new(glutin_window.clone());
            window_handle = match glutin_window {
                Some(ref win) => win.platform_window() as cef_window_handle_t,
                None => get_null_window_handle()
            };
            ServoBrowser::OnScreen(servo_browser)
        } else {
            ServoBrowser::Invalid
        };

        let id = ID_COUNTER.with(|counter| {
            counter.fetch_add(1, Ordering::SeqCst)
        });

        ServoCefBrowser {
            frame: frame,
            host: host,
            client: client,
            window: glutin_window,
            callback_executed: Cell::new(false),
            servo_browser: RefCell::new(servo_browser),
            message_queue: RefCell::new(vec!()),
            id: id,
            back: Cell::new(false),
            forward: Cell::new(false),
            loading: Cell::new(false),
            window_handle: window_handle,
        }
    }
}

pub trait ServoCefBrowserExtensions {
    fn init(&self, window_info: &cef_window_info_t);
    fn send_window_event(&self, event: WindowEvent);
    fn get_title_for_main_frame(&self);
    fn pinch_zoom_level(&self) -> f32;
}

impl ServoCefBrowserExtensions for CefBrowser {
    fn init(&self, window_info: &cef_window_info_t) {
        if window_info.windowless_rendering_enabled != 0 {
            let window = window::Window::new(window_info.width, window_info.height);
            window.set_browser(self.clone());
            let servo_browser = Browser::new(Some(window.clone()));
            *self.downcast().servo_browser.borrow_mut() = ServoBrowser::OffScreen(servo_browser);
        }

        self.downcast().host.set_browser((*self).clone());
        self.downcast().frame.set_browser((*self).clone());
        if window_info.windowless_rendering_enabled == 0 {
            self.downcast().host.initialize_compositing();
        }
    }

    fn send_window_event(&self, event: WindowEvent) {
        self.downcast().message_queue.borrow_mut().push(event);

        loop {
            match self.downcast().servo_browser.borrow_state() {
                BorrowState::Unused => {
                    let event = match self.downcast().message_queue.borrow_mut().pop() {
                        None => return,
                        Some(event) => event,
                    };
                    self.downcast().servo_browser.borrow_mut().handle_event(event);
                }
                _ => {
                    // We're trying to send an event while processing another one. This will
                    // cause general badness, so queue up that event instead of immediately
                    // processing it.
                    break
                }
            }
        }
    }

    fn get_title_for_main_frame(&self) {
        self.downcast().servo_browser.borrow().get_title_for_main_frame()
    }

    fn pinch_zoom_level(&self) -> f32 {
        self.downcast().servo_browser.borrow().pinch_zoom_level()
    }
}

#[cfg(target_os="macos")]
pub fn get_null_window_handle() -> cef_window_handle_t {
    ptr::null_mut()
}
#[cfg(target_os="linux")]
pub fn get_null_window_handle() -> cef_window_handle_t {
    0
}

pub fn update() {
    BROWSERS.with(|browsers| {
        for browser in browsers.borrow().iter() {
            if browser.downcast().callback_executed.get() == false {
                browser_callback_after_created(browser.clone());
            }
            let mut events = match browser.downcast().window {
                Some(ref win) => win.wait_events(),
                None => vec![WindowEvent::Idle]
            };
            loop {
               match events.pop() {
                   Some(event) => browser.send_window_event(event),
                   None => break
               }
            }
        }
    });
}

pub fn close(browser: CefBrowser) {
    BROWSERS.with(|browsers| {
        let mut browsers = browsers.borrow_mut();
        browsers.iter()
                .position(|&ref n| n.downcast().id == browser.downcast().id)
                .map(|e| browsers.remove(e));
    });
}

pub fn get_window(browser: &CefBrowser) -> cef_window_handle_t {
    browser.downcast().window_handle
}

pub fn browser_callback_after_created(browser: CefBrowser) {
    if browser.downcast().client.is_null_cef_object() {
        return
    }
    let client = browser.downcast().client.clone();
    let life_span_handler = client.get_life_span_handler();
    if life_span_handler.is_not_null_cef_object() {
        life_span_handler.on_after_created(browser.clone());
    }
    browser.downcast().callback_executed.set(true);
    browser.downcast().frame.load();
}

fn browser_host_create(window_info: &cef_window_info_t,
                       client: CefClient,
                       url: *const cef_string_t,
                       callback_executed: bool)
                       -> CefBrowser {
    let browser = ServoCefBrowser::new(window_info, client).as_cef_interface();
    browser.init(window_info);
    if url != ptr::null() {
       unsafe { browser.downcast().frame.set_url(CefWrap::to_rust(url)); }
    }
    if callback_executed {
        browser_callback_after_created(browser.clone());
    }
    BROWSERS.with(|browsers| {
        browsers.borrow_mut().push(browser.clone());
    });
    browser
}

cef_static_method_impls! {
    fn cef_browser_host_create_browser(window_info: *const cef_window_info_t,
                                       client: *mut cef_client_t,
                                       url: *const cef_string_t,
                                       _browser_settings: *const cef_browser_settings_t,
                                       _request_context: *mut cef_request_context_t)
                                       -> c_int {{
        let client: CefClient = client;
        let _browser_settings: &cef_browser_settings_t = _browser_settings;
        let _request_context: CefRequestContext = _request_context;
        browser_host_create(window_info, client, url, false);
        spawn_named("async_browser_creation".to_owned(), move || {
            window::app_wakeup();
        });
        1i32
    }}
    fn cef_browser_host_create_browser_sync(window_info: *const cef_window_info_t,
                                            client: *mut cef_client_t,
                                            url: *const cef_string_t,
                                            _browser_settings: *const cef_browser_settings_t,
                                            _request_context: *mut cef_request_context_t)
                                            -> *mut cef_browser_t {{
        let client: CefClient = client;
        let _browser_settings: &cef_browser_settings_t = _browser_settings;
        let _request_context: CefRequestContext = _request_context;
        browser_host_create(window_info, client, url, true)
    }}
}
<|endoftext|>


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

use browser_host::{ServoCefBrowserHost, ServoCefBrowserHostExtensions};
use eutil::Downcast;
use frame::{ServoCefFrame, ServoCefFrameExtensions};
use interfaces::{CefBrowser, CefBrowserHost, CefClient, CefFrame, CefRequestContext};
use interfaces::{cef_browser_t, cef_browser_host_t, cef_client_t, cef_frame_t};
use interfaces::{cef_request_context_t};
use servo::Browser;
use types::{cef_browser_settings_t, cef_string_t, cef_window_info_t, cef_window_handle_t};
use util::task::spawn_named;
use window;
use wrappers::CefWrap;

use compositing::windowing::{WindowNavigateMsg, WindowEvent};
use glutin_app;
use libc::c_int;
use std::cell::{Cell, RefCell, BorrowState};
use std::ptr;
use std::rc::Rc;
use std::sync::atomic::{AtomicIsize, Ordering};

thread_local!(pub static ID_COUNTER: AtomicIsize = AtomicIsize::new(0));
thread_local!(pub static BROWSERS: RefCell<Vec<CefBrowser>> = RefCell::new(vec!()));

pub enum ServoBrowser {
    Invalid,
    OnScreen(Browser),
    OffScreen(Browser),
}

impl ServoBrowser {
    fn handle_event(&mut self, event: WindowEvent) {
        match *self {
            ServoBrowser::OnScreen(ref mut browser) => { browser.handle_events(vec![event]); }
            ServoBrowser::OffScreen(ref mut browser) => { browser.handle_events(vec![event]); }
            ServoBrowser::Invalid => {}
        }
    }

    pub fn get_title_for_main_frame(&self) {
        match *self {
            ServoBrowser::OnScreen(ref browser) => browser.get_title_for_main_frame(),
            ServoBrowser::OffScreen(ref browser) => browser.get_title_for_main_frame(),
            ServoBrowser::Invalid => {}
        }
    }

    pub fn pinch_zoom_level(&self) -> f32 {
        match *self {
            ServoBrowser::OnScreen(ref browser) => browser.pinch_zoom_level(),
            ServoBrowser::OffScreen(ref browser) => browser.pinch_zoom_level(),
            ServoBrowser::Invalid => 1.0,
        }
    }
}

cef_class_impl! {
    ServoCefBrowser : CefBrowser, cef_browser_t {
        fn get_host(&this,) -> *mut cef_browser_host_t {{
            this.downcast().host.clone()
        }}

        fn can_go_back(&this,) -> c_int {{
            this.downcast().back.get() as c_int
        }}

        fn can_go_forward(&this,) -> c_int {{
            this.downcast().forward.get() as c_int
        }}

        fn is_loading(&this,) -> c_int {{
            this.downcast().loading.get() as c_int
        }}

        fn go_back(&this,) -> () {{
            this.send_window_event(WindowEvent::Navigation(WindowNavigateMsg::Back));
        }}

        fn go_forward(&this,) -> () {{
            this.send_window_event(WindowEvent::Navigation(WindowNavigateMsg::Forward));
        }}

        // Returns the main (top-level) frame for the browser window.
        fn get_main_frame(&this,) -> *mut cef_frame_t {{
            this.downcast().frame.clone()
        }}

        fn get_identifier(&this,) -> c_int {{
            this.downcast().id as c_int
        }}
    }
}

pub struct ServoCefBrowser {
    /// A reference to the browser's primary frame.
    pub frame: CefFrame,
    /// A reference to the browser's host.
    pub host: CefBrowserHost,
    /// A reference to the browser client.
    pub client: CefClient,
    /// the glutin window when using windowed rendering
    pub window: Option<Rc<glutin_app::window::Window>>,
    /// Whether the on-created callback has fired yet.
    pub callback_executed: Cell<bool>,
    /// whether the browser can navigate back
    pub back: Cell<bool>,
    /// whether the browser can navigate forward
    pub forward: Cell<bool>,
    /// whether the browser is loading
    pub loading: Cell<bool>,
    /// a vec of favicon urls for the current page
    pub favicons: RefCell<Vec<String>>,
    /// the display system window handle: only to be used with host.get_window_handle()
    window_handle: cef_window_handle_t,

    id: isize,
    servo_browser: RefCell<ServoBrowser>,
    message_queue: RefCell<Vec<WindowEvent>>,
}

impl ServoCefBrowser {
    pub fn new(window_info: &cef_window_info_t, client: CefClient) -> ServoCefBrowser {
        let frame = ServoCefFrame::new().as_cef_interface();
        let host = ServoCefBrowserHost::new(client.clone()).as_cef_interface();
        let mut window_handle: cef_window_handle_t = get_null_window_handle();
        let mut glutin_window: Option<Rc<glutin_app::window::Window>> = None;

        let servo_browser = if window_info.windowless_rendering_enabled == 0 {
            glutin_window = Some(glutin_app::create_window(window_info.parent_window as glutin_app::WindowID));
            let servo_browser = Browser::new(glutin_window.clone());
            window_handle = match glutin_window {
                Some(ref win) => win.platform_window() as cef_window_handle_t,
                None => get_null_window_handle()
            };
            ServoBrowser::OnScreen(servo_browser)
        } else {
            ServoBrowser::Invalid
        };

        let id = ID_COUNTER.with(|counter| {
            counter.fetch_add(1, Ordering::SeqCst)
        });

        ServoCefBrowser {
            frame: frame,
            host: host,
            client: client,
            window: glutin_window,
            callback_executed: Cell::new(false),
            servo_browser: RefCell::new(servo_browser),
            message_queue: RefCell::new(vec!()),
            id: id,
            back: Cell::new(false),
            forward: Cell::new(false),
            loading: Cell::new(false),
            favicons: RefCell::new(vec!()),
            window_handle: window_handle,
        }
    }
}

pub trait ServoCefBrowserExtensions {
    fn init(&self, window_info: &cef_window_info_t);
    fn send_window_event(&self, event: WindowEvent);
    fn get_title_for_main_frame(&self);
    fn pinch_zoom_level(&self) -> f32;
}

impl ServoCefBrowserExtensions for CefBrowser {
    fn init(&self, window_info: &cef_window_info_t) {
        if window_info.windowless_rendering_enabled != 0 {
            let window = window::Window::new(window_info.width, window_info.height);
            window.set_browser(self.clone());
            let servo_browser = Browser::new(Some(window.clone()));
            *self.downcast().servo_browser.borrow_mut() = ServoBrowser::OffScreen(servo_browser);
        }

        self.downcast().host.set_browser((*self).clone());
        self.downcast().frame.set_browser((*self).clone());
        if window_info.windowless_rendering_enabled == 0 {
            self.downcast().host.initialize_compositing();
        }
    }

    fn send_window_event(&self, event: WindowEvent) {
        self.downcast().message_queue.borrow_mut().push(event);

        loop {
            match self.downcast().servo_browser.borrow_state() {
                BorrowState::Unused => {
                    let event = match self.downcast().message_queue.borrow_mut().pop() {
                        None => return,
                        Some(event) => event,
                    };
                    self.downcast().servo_browser.borrow_mut().handle_event(event);
                }
                _ => {
                    // We're trying to send an event while processing another one. This will
                    // cause general badness, so queue up that event instead of immediately
                    // processing it.
                    break
                }
            }
        }
    }

    fn get_title_for_main_frame(&self) {
        self.downcast().servo_browser.borrow().get_title_for_main_frame()
    }

    fn pinch_zoom_level(&self) -> f32 {
        self.downcast().servo_browser.borrow().pinch_zoom_level()
    }
}

#[cfg(target_os="macos")]
pub fn get_null_window_handle() -> cef_window_handle_t {
    ptr::null_mut()
}
#[cfg(target_os="linux")]
pub fn get_null_window_handle() -> cef_window_handle_t {
    0
}

pub fn update() {
    BROWSERS.with(|browsers| {
        for browser in &browsers.borrow() {
            if browser.downcast().callback_executed.get() == false {
                browser_callback_after_created(browser.clone());
            }
            let mut events = match browser.downcast().window {
                Some(ref win) => win.wait_events(),
                None => vec![WindowEvent::Idle]
            };
            loop {
               match events.pop() {
                   Some(event) => browser.send_window_event(event),
                   None => break
               }
            }
        }
    });
}

pub fn close(browser: CefBrowser) {
    BROWSERS.with(|browsers| {
        let mut browsers = browsers.borrow_mut();
        browsers.iter()
                .position(|&ref n| n.downcast().id == browser.downcast().id)
                .map(|e| browsers.remove(e));
    });
}

pub fn get_window(browser: &CefBrowser) -> cef_window_handle_t {
    browser.downcast().window_handle
}

pub fn browser_callback_after_created(browser: CefBrowser) {
    if browser.downcast().client.is_null_cef_object() {
        return
    }
    let client = browser.downcast().client.clone();
    let life_span_handler = client.get_life_span_handler();
    if life_span_handler.is_not_null_cef_object() {
        life_span_handler.on_after_created(browser.clone());
    }
    browser.downcast().callback_executed.set(true);
    browser.downcast().frame.load();
    browser.downcast().host.was_resized();
}

fn browser_host_create(window_info: &cef_window_info_t,
                       client: CefClient,
                       url: *const cef_string_t,
                       callback_executed: bool)
                       -> CefBrowser {
    let browser = ServoCefBrowser::new(window_info, client).as_cef_interface();
    browser.init(window_info);
    if url != ptr::null() {
       unsafe { browser.downcast().frame.set_url(CefWrap::to_rust(url)); }
    }
    if callback_executed {
        browser_callback_after_created(browser.clone());
    }
    BROWSERS.with(|browsers| {
        browsers.borrow_mut().push(browser.clone());
    });
    browser
}

cef_static_method_impls! {
    fn cef_browser_host_create_browser(window_info: *const cef_window_info_t,
                                       client: *mut cef_client_t,
                                       url: *const cef_string_t,
                                       _browser_settings: *const cef_browser_settings_t,
                                       _request_context: *mut cef_request_context_t)
                                       -> c_int {{
        let client: CefClient = client;
        let _browser_settings: &cef_browser_settings_t = _browser_settings;
        let _request_context: CefRequestContext = _request_context;
        browser_host_create(window_info, client, url, false);
        spawn_named("async_browser_creation".to_owned(), move || {
            window::app_wakeup();
        });
        1i32
    }}
    fn cef_browser_host_create_browser_sync(window_info: *const cef_window_info_t,
                                            client: *mut cef_client_t,
                                            url: *const cef_string_t,
                                            _browser_settings: *const cef_browser_settings_t,
                                            _request_context: *mut cef_request_context_t)
                                            -> *mut cef_browser_t {{
        let client: CefClient = client;
        let _browser_settings: &cef_browser_settings_t = _browser_settings;
        let _request_context: CefRequestContext = _request_context;
        browser_host_create(window_info, client, url, true)
    }}
}
<commit_msg>Fix the CEF build.<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use browser_host::{ServoCefBrowserHost, ServoCefBrowserHostExtensions};
use eutil::Downcast;
use frame::{ServoCefFrame, ServoCefFrameExtensions};
use interfaces::{CefBrowser, CefBrowserHost, CefClient, CefFrame, CefRequestContext};
use interfaces::{cef_browser_t, cef_browser_host_t, cef_client_t, cef_frame_t};
use interfaces::{cef_request_context_t};
use servo::Browser;
use types::{cef_browser_settings_t, cef_string_t, cef_window_info_t, cef_window_handle_t};
use util::task::spawn_named;
use window;
use wrappers::CefWrap;

use compositing::windowing::{WindowNavigateMsg, WindowEvent};
use glutin_app;
use libc::c_int;
use std::cell::{Cell, RefCell, BorrowState};
use std::ptr;
use std::rc::Rc;
use std::sync::atomic::{AtomicIsize, Ordering};

thread_local!(pub static ID_COUNTER: AtomicIsize = AtomicIsize::new(0));
thread_local!(pub static BROWSERS: RefCell<Vec<CefBrowser>> = RefCell::new(vec!()));

pub enum ServoBrowser {
    Invalid,
    OnScreen(Browser),
    OffScreen(Browser),
}

impl ServoBrowser {
    fn handle_event(&mut self, event: WindowEvent) {
        match *self {
            ServoBrowser::OnScreen(ref mut browser) => { browser.handle_events(vec![event]); }
            ServoBrowser::OffScreen(ref mut browser) => { browser.handle_events(vec![event]); }
            ServoBrowser::Invalid => {}
        }
    }

    pub fn get_title_for_main_frame(&self) {
        match *self {
            ServoBrowser::OnScreen(ref browser) => browser.get_title_for_main_frame(),
            ServoBrowser::OffScreen(ref browser) => browser.get_title_for_main_frame(),
            ServoBrowser::Invalid => {}
        }
    }

    pub fn pinch_zoom_level(&self) -> f32 {
        match *self {
            ServoBrowser::OnScreen(ref browser) => browser.pinch_zoom_level(),
            ServoBrowser::OffScreen(ref browser) => browser.pinch_zoom_level(),
            ServoBrowser::Invalid => 1.0,
        }
    }
}

cef_class_impl! {
    ServoCefBrowser : CefBrowser, cef_browser_t {
        fn get_host(&this,) -> *mut cef_browser_host_t {{
            this.downcast().host.clone()
        }}

        fn can_go_back(&this,) -> c_int {{
            this.downcast().back.get() as c_int
        }}

        fn can_go_forward(&this,) -> c_int {{
            this.downcast().forward.get() as c_int
        }}

        fn is_loading(&this,) -> c_int {{
            this.downcast().loading.get() as c_int
        }}

        fn go_back(&this,) -> () {{
            this.send_window_event(WindowEvent::Navigation(WindowNavigateMsg::Back));
        }}

        fn go_forward(&this,) -> () {{
            this.send_window_event(WindowEvent::Navigation(WindowNavigateMsg::Forward));
        }}

        // Returns the main (top-level) frame for the browser window.
        fn get_main_frame(&this,) -> *mut cef_frame_t {{
            this.downcast().frame.clone()
        }}

        fn get_identifier(&this,) -> c_int {{
            this.downcast().id as c_int
        }}
    }
}

pub struct ServoCefBrowser {
    /// A reference to the browser's primary frame.
    pub frame: CefFrame,
    /// A reference to the browser's host.
    pub host: CefBrowserHost,
    /// A reference to the browser client.
    pub client: CefClient,
    /// the glutin window when using windowed rendering
    pub window: Option<Rc<glutin_app::window::Window>>,
    /// Whether the on-created callback has fired yet.
    pub callback_executed: Cell<bool>,
    /// whether the browser can navigate back
    pub back: Cell<bool>,
    /// whether the browser can navigate forward
    pub forward: Cell<bool>,
    /// whether the browser is loading
    pub loading: Cell<bool>,
    /// a vec of favicon urls for the current page
    pub favicons: RefCell<Vec<String>>,
    /// the display system window handle: only to be used with host.get_window_handle()
    window_handle: cef_window_handle_t,

    id: isize,
    servo_browser: RefCell<ServoBrowser>,
    message_queue: RefCell<Vec<WindowEvent>>,
}

impl ServoCefBrowser {
    pub fn new(window_info: &cef_window_info_t, client: CefClient) -> ServoCefBrowser {
        let frame = ServoCefFrame::new().as_cef_interface();
        let host = ServoCefBrowserHost::new(client.clone()).as_cef_interface();
        let mut window_handle: cef_window_handle_t = get_null_window_handle();
        let mut glutin_window: Option<Rc<glutin_app::window::Window>> = None;

        let servo_browser = if window_info.windowless_rendering_enabled == 0 {
            glutin_window = Some(glutin_app::create_window(window_info.parent_window as glutin_app::WindowID));
            let servo_browser = Browser::new(glutin_window.clone());
            window_handle = match glutin_window {
                Some(ref win) => win.platform_window() as cef_window_handle_t,
                None => get_null_window_handle()
            };
            ServoBrowser::OnScreen(servo_browser)
        } else {
            ServoBrowser::Invalid
        };

        let id = ID_COUNTER.with(|counter| {
            counter.fetch_add(1, Ordering::SeqCst)
        });

        ServoCefBrowser {
            frame: frame,
            host: host,
            client: client,
            window: glutin_window,
            callback_executed: Cell::new(false),
            servo_browser: RefCell::new(servo_browser),
            message_queue: RefCell::new(vec!()),
            id: id,
            back: Cell::new(false),
            forward: Cell::new(false),
            loading: Cell::new(false),
            favicons: RefCell::new(vec!()),
            window_handle: window_handle,
        }
    }
}

pub trait ServoCefBrowserExtensions {
    fn init(&self, window_info: &cef_window_info_t);
    fn send_window_event(&self, event: WindowEvent);
    fn get_title_for_main_frame(&self);
    fn pinch_zoom_level(&self) -> f32;
}

impl ServoCefBrowserExtensions for CefBrowser {
    fn init(&self, window_info: &cef_window_info_t) {
        if window_info.windowless_rendering_enabled != 0 {
            let window = window::Window::new(window_info.width, window_info.height);
            window.set_browser(self.clone());
            let servo_browser = Browser::new(Some(window.clone()));
            *self.downcast().servo_browser.borrow_mut() = ServoBrowser::OffScreen(servo_browser);
        }

        self.downcast().host.set_browser((*self).clone());
        self.downcast().frame.set_browser((*self).clone());
        if window_info.windowless_rendering_enabled == 0 {
            self.downcast().host.initialize_compositing();
        }
    }

    fn send_window_event(&self, event: WindowEvent) {
        self.downcast().message_queue.borrow_mut().push(event);

        loop {
            match self.downcast().servo_browser.borrow_state() {
                BorrowState::Unused => {
                    let event = match self.downcast().message_queue.borrow_mut().pop() {
                        None => return,
                        Some(event) => event,
                    };
                    self.downcast().servo_browser.borrow_mut().handle_event(event);
                }
                _ => {
                    // We're trying to send an event while processing another one. This will
                    // cause general badness, so queue up that event instead of immediately
                    // processing it.
                    break
                }
            }
        }
    }

    fn get_title_for_main_frame(&self) {
        self.downcast().servo_browser.borrow().get_title_for_main_frame()
    }

    fn pinch_zoom_level(&self) -> f32 {
        self.downcast().servo_browser.borrow().pinch_zoom_level()
    }
}

#[cfg(target_os="macos")]
pub fn get_null_window_handle() -> cef_window_handle_t {
    ptr::null_mut()
}
#[cfg(target_os="linux")]
pub fn get_null_window_handle() -> cef_window_handle_t {
    0
}

pub fn update() {
    BROWSERS.with(|browsers| {
        for browser in &*browsers.borrow() {
            if browser.downcast().callback_executed.get() == false {
                browser_callback_after_created(browser.clone());
            }
            let mut events = match browser.downcast().window {
                Some(ref win) => win.wait_events(),
                None => vec![WindowEvent::Idle]
            };
            loop {
               match events.pop() {
                   Some(event) => browser.send_window_event(event),
                   None => break
               }
            }
        }
    });
}

pub fn close(browser: CefBrowser) {
    BROWSERS.with(|browsers| {
        let mut browsers = browsers.borrow_mut();
        browsers.iter()
                .position(|&ref n| n.downcast().id == browser.downcast().id)
                .map(|e| browsers.remove(e));
    });
}

pub fn get_window(browser: &CefBrowser) -> cef_window_handle_t {
    browser.downcast().window_handle
}

pub fn browser_callback_after_created(browser: CefBrowser) {
    if browser.downcast().client.is_null_cef_object() {
        return
    }
    let client = browser.downcast().client.clone();
    let life_span_handler = client.get_life_span_handler();
    if life_span_handler.is_not_null_cef_object() {
        life_span_handler.on_after_created(browser.clone());
    }
    browser.downcast().callback_executed.set(true);
    browser.downcast().frame.load();
    browser.downcast().host.was_resized();
}

fn browser_host_create(window_info: &cef_window_info_t,
                       client: CefClient,
                       url: *const cef_string_t,
                       callback_executed: bool)
                       -> CefBrowser {
    let browser = ServoCefBrowser::new(window_info, client).as_cef_interface();
    browser.init(window_info);
    if url != ptr::null() {
       unsafe { browser.downcast().frame.set_url(CefWrap::to_rust(url)); }
    }
    if callback_executed {
        browser_callback_after_created(browser.clone());
    }
    BROWSERS.with(|browsers| {
        browsers.borrow_mut().push(browser.clone());
    });
    browser
}

cef_static_method_impls! {
    fn cef_browser_host_create_browser(window_info: *const cef_window_info_t,
                                       client: *mut cef_client_t,
                                       url: *const cef_string_t,
                                       _browser_settings: *const cef_browser_settings_t,
                                       _request_context: *mut cef_request_context_t)
                                       -> c_int {{
        let client: CefClient = client;
        let _browser_settings: &cef_browser_settings_t = _browser_settings;
        let _request_context: CefRequestContext = _request_context;
        browser_host_create(window_info, client, url, false);
        spawn_named("async_browser_creation".to_owned(), move || {
            window::app_wakeup();
        });
        1i32
    }}
    fn cef_browser_host_create_browser_sync(window_info: *const cef_window_info_t,
                                            client: *mut cef_client_t,
                                            url: *const cef_string_t,
                                            _browser_settings: *const cef_browser_settings_t,
                                            _request_context: *mut cef_request_context_t)
                                            -> *mut cef_browser_t {{
        let client: CefClient = client;
        let _browser_settings: &cef_browser_settings_t = _browser_settings;
        let _request_context: CefRequestContext = _request_context;
        browser_host_create(window_info, client, url, true)
    }}
}
<|endoftext|>


<commit_before>fn main() {
    let Π = 3.14;
    let लंच = Π * Π + 1.54;
    assert लंच - 1.54 == Π * Π;
    assert საჭმელად_გემრიელი_სადილი() == 0;
}

fn საჭმელად_გემრიელი_სადილი() -> int {

    // Lunch in several languages.

    let ランチ = 10;
    let 午餐 = 10;

    let ארוחת_צהריי = 10;
    let غداء = 10;
    let լանչ = 10;
    let обед = 10;
    let абед = 10;
    let μεσημεριανό = 10;
    let hádegismatur = 10;
    let ручек = 10;

    let ăn_trưa = 10;
    let อาหารกลางวัน = 10;

    // Lunchy arithmetic, mm.

    assert hádegismatur * ручек * обед == 1000;
    assert 10 ==  ארוחת_צהריי;
    assert ランチ + 午餐 + μεσημεριανό == 30;
    assert ăn_trưa + อาหารกลางวัน == 20;
    ret (абед + լանչ) >> غداء;
}
<commit_msg>Fix test floating point comparison to tolerate imprecise FPUs.<commit_after>fn main() {
    let ε = 0.00001;
    let Π = 3.14;
    let लंच = Π * Π + 1.54;
    assert float::abs((लंच - 1.54) - (Π * Π)) < ε;
    assert საჭმელად_გემრიელი_სადილი() == 0;
}

fn საჭმელად_გემრიელი_სადილი() -> int {

    // Lunch in several languages.

    let ランチ = 10;
    let 午餐 = 10;

    let ארוחת_צהריי = 10;
    let غداء = 10;
    let լանչ = 10;
    let обед = 10;
    let абед = 10;
    let μεσημεριανό = 10;
    let hádegismatur = 10;
    let ручек = 10;

    let ăn_trưa = 10;
    let อาหารกลางวัน = 10;

    // Lunchy arithmetic, mm.

    assert hádegismatur * ручек * обед == 1000;
    assert 10 ==  ארוחת_צהריי;
    assert ランチ + 午餐 + μεσημεριανό == 30;
    assert ăn_trưa + อาหารกลางวัน == 20;
    ret (абед + լանչ) >> غداء;
}
<|endoftext|>


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

type HANDLE = u32;
type DWORD = u32;
type SIZE_T = u32;
type LPVOID = uint;
type BOOL = u8;

#[cfg(target_os = "win32")]
#[abi = "stdcall"]
extern mod kernel32 {
    #[legacy_exports];
       fn GetProcessHeap() -> HANDLE;
       fn HeapAlloc(hHeap: HANDLE, dwFlags: DWORD, dwBytes: SIZE_T) -> LPVOID;
       fn HeapFree(hHeap: HANDLE, dwFlags: DWORD, lpMem: LPVOID) -> BOOL;
}

#[cfg(target_os = "win32")]
fn main() {
   let heap = kernel32::GetProcessHeap();
   let mem = kernel32::HeapAlloc(heap, 0u32, 100u32);
   assert mem != 0u;
   let res = kernel32::HeapFree(heap, 0u32, mem);
   assert res != 0u8;
}

#[cfg(target_os = "macos")]
#[cfg(target_os = "linux")]
#[cfg(target_os = "freebsd")]
fn main() { }
<commit_msg>testsuite: Fix Windows breakage harder in x86stdcall2<commit_after>// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

type HANDLE = u32;
type DWORD = u32;
type SIZE_T = u32;
type LPVOID = uint;
type BOOL = u8;

#[cfg(target_os = "win32")]
#[abi = "stdcall"]
extern mod kernel32 {
    #[legacy_exports];
       fn GetProcessHeap() -> HANDLE;
       fn HeapAlloc(hHeap: HANDLE, dwFlags: DWORD, dwBytes: SIZE_T) -> LPVOID;
       fn HeapFree(hHeap: HANDLE, dwFlags: DWORD, lpMem: LPVOID) -> BOOL;
}

#[cfg(target_os = "win32")]
fn main() {
    let heap = unsafe { kernel32::GetProcessHeap() };
    let mem = unsafe { kernel32::HeapAlloc(heap, 0u32, 100u32) };
    assert mem != 0u;
    let res = unsafe { kernel32::HeapFree(heap, 0u32, mem) };
    assert res != 0u8;
}

#[cfg(target_os = "macos")]
#[cfg(target_os = "linux")]
#[cfg(target_os = "freebsd")]
fn main() { }
<|endoftext|>


<commit_before>// run-pass

#![feature(or_patterns)]

fn main() {
    assert!(f("", 0));
    assert!(f("a", 1));
    assert!(f("b", 1));

    assert!(!f("", 1));
    assert!(!f("a", 0));
    assert!(!f("b", 0));

    assert!(!f("asdf", 032));

    ////

    assert!(!g(true, true, true));
    assert!(!g(false, true, true));
    assert!(!g(true, false, true));
    assert!(!g(false, false, true));
    assert!(!g(true, true, false));

    assert!(g(false, true, false));
    assert!(g(true, false, false));
    assert!(g(false, false, false));

    ////

    assert!(!h(true, true, true));
    assert!(!h(false, true, true));
    assert!(!h(true, false, true));
    assert!(!h(false, false, true));
    assert!(!h(true, true, false));

    assert!(h(false, true, false));
    assert!(h(true, false, false));
    assert!(h(false, false, false));
}

fn f(s: &str, num: usize) -> bool {
    match (s, num) {
        ("", 0) | ("a" | "b", 1) => true,

        _ => false,
    }
}

fn g(x: bool, y: bool, z: bool) -> bool {
    match (x, y, x, z) {
        (true | false, false, true, false) => true,
        (false, true | false, true | false, false) => true,
        (true | false, true | false, true | false, true) => false,
        (true, true | false, true | false, false) => false,
    }
}

fn h(x: bool, y: bool, z: bool) -> bool {
    match (x, (y, (x, (z,)))) {
        (true | false, (false, (true, (false,)))) => true,
        (false, (true | false, (true | false, (false,)))) => true,
        (true | false, (true | false, (true | false, (true,)))) => false,
        (true, (true | false, (true | false, (false,)))) => false,
    }
}
<commit_msg>Style nit<commit_after>// run-pass

#![feature(or_patterns)]

fn main() {
    assert!(f("", 0));
    assert!(f("a", 1));
    assert!(f("b", 1));

    assert!(!f("", 1));
    assert!(!f("a", 0));
    assert!(!f("b", 0));

    assert!(!f("asdf", 32));

    ////

    assert!(!g(true, true, true));
    assert!(!g(false, true, true));
    assert!(!g(true, false, true));
    assert!(!g(false, false, true));
    assert!(!g(true, true, false));

    assert!(g(false, true, false));
    assert!(g(true, false, false));
    assert!(g(false, false, false));

    ////

    assert!(!h(true, true, true));
    assert!(!h(false, true, true));
    assert!(!h(true, false, true));
    assert!(!h(false, false, true));
    assert!(!h(true, true, false));

    assert!(h(false, true, false));
    assert!(h(true, false, false));
    assert!(h(false, false, false));
}

fn f(s: &str, num: usize) -> bool {
    match (s, num) {
        ("", 0) | ("a" | "b", 1) => true,

        _ => false,
    }
}

fn g(x: bool, y: bool, z: bool) -> bool {
    match (x, y, x, z) {
        (true | false, false, true, false) => true,
        (false, true | false, true | false, false) => true,
        (true | false, true | false, true | false, true) => false,
        (true, true | false, true | false, false) => false,
    }
}

fn h(x: bool, y: bool, z: bool) -> bool {
    match (x, (y, (x, (z,)))) {
        (true | false, (false, (true, (false,)))) => true,
        (false, (true | false, (true | false, (false,)))) => true,
        (true | false, (true | false, (true | false, (true,)))) => false,
        (true, (true | false, (true | false, (false,)))) => false,
    }
}
<|endoftext|>