<commit_before>use std::mem::size_of;

use crate::baseline;
use crate::baseline::fct::{BailoutInfo, JitBaselineFct, JitDescriptor, JitFct};
use crate::baseline::map::CodeDescriptor;
use crate::cpu::{
    Mem, FREG_PARAMS, REG_FP, REG_PARAMS, REG_RESULT, REG_SP, REG_THREAD, REG_TMP1,
};
use crate::exception::DoraToNativeInfo;
use crate::gc::Address;
use crate::masm::MacroAssembler;
use crate::mem;
use crate::object::Obj;
use crate::threads::ThreadLocalData;
use crate::ty::{MachineMode, TypeList};
use crate::vm::FctId;
use crate::vm::{get_vm, VM};

// This code generates the compiler thunk, there should only be one instance
// of this function be used in Dora. It is necessary for lazy compilation, where
// functions are only compiled on their first invocation. The compiler can use
// the address of this thunk for invocations of functions that have not been compiled
// yet. The thunk compiles the function and patches the call site to invoke the
// now-compiled function directly on the next invocation. In the end the function is
// executed.

pub fn generate<'a, 'ast: 'a>(vm: &'a VM<'ast>) -> Address {
    let ngen = DoraCompileGen {
        vm,
        masm: MacroAssembler::new(),
        dbg: vm.args.flag_emit_debug_compile,
    };

    let jit_fct = ngen.generate();
    let addr = jit_fct.fct_ptr();
    vm.insert_code_map(
        jit_fct.ptr_start(),
        jit_fct.ptr_end(),
        CodeDescriptor::CompilerThunk,
    );
    vm.jit_fcts.push(JitFct::Base(jit_fct));

    addr
}

struct DoraCompileGen<'a, 'ast: 'a> {
    vm: &'a VM<'ast>,
    masm: MacroAssembler,
    dbg: bool,
}

impl<'a, 'ast> DoraCompileGen<'a, 'ast>
where
    'ast: 'a,
{
    pub fn generate(mut self) -> JitBaselineFct {
        let offset_dtn = 0;
        let offset_params = offset_dtn + size_of::<DoraToNativeInfo>() as i32;
        let offset_thread =
            offset_params + (FREG_PARAMS.len() + REG_PARAMS.len()) as i32 * mem::ptr_width();
        let framesize = mem::align_i32(offset_thread + mem::ptr_width(), 16) as i32;

        if self.dbg {
            self.masm.debug();
        }

        // the return address is the call-site we need to patch
        self.masm.prolog_size(framesize);

        // store params passed in registers on the stack
        self.store_params(offset_params);

        // prepare the native call
        self.masm.load_mem(
            MachineMode::Ptr,
            REG_TMP1.into(),
            Mem::Base(REG_THREAD, ThreadLocalData::dtn_offset()),
        );

        self.masm.store_mem(
            MachineMode::Ptr,
            Mem::Base(REG_SP, offset_dtn + DoraToNativeInfo::last_offset()),
            REG_TMP1.into(),
        );

        self.masm.store_mem(
            MachineMode::Ptr,
            Mem::Base(REG_SP, offset_dtn + DoraToNativeInfo::fp_offset()),
            REG_FP.into(),
        );

        self.masm.copy_pc(REG_TMP1);

        self.masm.store_mem(
            MachineMode::Ptr,
            Mem::Base(REG_SP, offset_dtn + DoraToNativeInfo::pc_offset()),
            REG_TMP1.into(),
        );

        self.masm.store_mem(
            MachineMode::Ptr,
            Mem::Base(REG_THREAD, ThreadLocalData::dtn_offset()),
            REG_SP.into(),
        );

        // invoke the compiler for the call site
        self.masm.load_mem(
            MachineMode::Ptr,
            REG_PARAMS[0].into(),
            Mem::Base(REG_FP, mem::ptr_width()),
        );
        self.masm.load_mem(
            MachineMode::Ptr,
            REG_PARAMS[1].into(),
            Mem::Base(REG_SP, offset_params),
        );
        self.masm.raw_call(compile_request as *const u8);

        self.masm.load_mem(
            MachineMode::Ptr,
            REG_TMP1.into(),
            Mem::Base(REG_SP, offset_dtn + DoraToNativeInfo::last_offset()),
        );

        self.masm.store_mem(
            MachineMode::Ptr,
            Mem::Base(REG_THREAD, ThreadLocalData::dtn_offset()),
            REG_TMP1.into(),
        );

        // restore argument registers from the stack
        self.load_params(offset_params);

        // remove the stack frame
        self.masm.epilog_without_return();

        // jump to compiled function
        self.masm.jump_reg(REG_RESULT);

        self.masm
            .jit(self.vm, framesize, JitDescriptor::CompilerThunk, false)
    }

    fn store_params(&mut self, mut offset: i32) {
        for reg in &REG_PARAMS {
            self.masm
                .store_mem(MachineMode::Ptr, Mem::Base(REG_SP, offset), (*reg).into());
            offset += mem::ptr_width();
        }

        for reg in &FREG_PARAMS {
            self.masm.store_mem(
                MachineMode::Float64,
                Mem::Base(REG_SP, offset),
                (*reg).into(),
            );
            offset += mem::ptr_width();
        }
    }

    fn load_params(&mut self, mut offset: i32) {
        for reg in &REG_PARAMS {
            self.masm
                .load_mem(MachineMode::Ptr, (*reg).into(), Mem::Base(REG_SP, offset));
            offset += mem::ptr_width();
        }

        for reg in &FREG_PARAMS {
            self.masm.load_mem(
                MachineMode::Float64,
                (*reg).into(),
                Mem::Base(REG_SP, offset),
            );
            offset += mem::ptr_width();
        }
    }
}

fn compile_request(ra: usize, receiver: Address) -> Address {
    let vm = get_vm();

    let bailout = {
        let data = {
            let code_map = vm.code_map.lock();
            code_map.get(ra.into()).expect("return address not found")
        };

        let fct_id = match data {
            CodeDescriptor::DoraFct(fct_id) => fct_id,
            _ => panic!("expected function for code"),
        };

        let jit_fct = vm.jit_fcts.idx(fct_id);

        let offset = ra - jit_fct.fct_ptr().to_usize();
        let jit_fct = jit_fct.to_base().expect("baseline expected");
        jit_fct
            .bailouts
            .get(offset as i32)
            .expect("bailout info not found")
            .clone()
    };

    match bailout {
        BailoutInfo::Compile(fct_id, disp, ref cls_tps, ref fct_tps) => {
            patch_fct_call(vm, ra, fct_id, cls_tps, fct_tps, disp)
        }

        BailoutInfo::VirtCompile(vtable_index, ref cls_tps, ref fct_tps) => {
            patch_vtable_call(vm, receiver, vtable_index, cls_tps, fct_tps)
        }
    }
}

fn patch_vtable_call(
    vm: &VM,
    receiver: Address,
    vtable_index: u32,
    cls_tps: &TypeList,
    fct_tps: &TypeList,
) -> Address {
    let obj = unsafe { &mut *receiver.to_mut_ptr::<Obj>() };
    let vtable = obj.header().vtbl();
    let cls_id = vtable.class().cls_id.expect("no corresponding class");
    let cls = vm.classes.idx(cls_id);
    let cls = cls.read();

    let fct_id = cls.virtual_fcts[vtable_index as usize];
    let fct_ptr = baseline::generate(vm, fct_id, cls_tps, fct_tps);

    let methodtable = vtable.table_mut();
    methodtable[vtable_index as usize] = fct_ptr.to_usize();

    fct_ptr
}

fn patch_fct_call(
    vm: &VM,
    ra: usize,
    fct_id: FctId,
    cls_tps: &TypeList,
    fct_tps: &TypeList,
    disp: i32,
) -> Address {
    let fct_ptr = baseline::generate(vm, fct_id, cls_tps, fct_tps);
    let fct_addr: *mut usize = (ra as isize - disp as isize) as *mut _;

    // update function pointer in data segment
    unsafe {
        *fct_addr = fct_ptr.to_usize();
    }

    fct_ptr
}
<commit_msg>reformat<commit_after>use std::mem::size_of;

use crate::baseline;
use crate::baseline::fct::{BailoutInfo, JitBaselineFct, JitDescriptor, JitFct};
use crate::baseline::map::CodeDescriptor;
use crate::cpu::{Mem, FREG_PARAMS, REG_FP, REG_PARAMS, REG_RESULT, REG_SP, REG_THREAD, REG_TMP1};
use crate::exception::DoraToNativeInfo;
use crate::gc::Address;
use crate::masm::MacroAssembler;
use crate::mem;
use crate::object::Obj;
use crate::threads::ThreadLocalData;
use crate::ty::{MachineMode, TypeList};
use crate::vm::FctId;
use crate::vm::{get_vm, VM};

// This code generates the compiler thunk, there should only be one instance
// of this function be used in Dora. It is necessary for lazy compilation, where
// functions are only compiled on their first invocation. The compiler can use
// the address of this thunk for invocations of functions that have not been compiled
// yet. The thunk compiles the function and patches the call site to invoke the
// now-compiled function directly on the next invocation. In the end the function is
// executed.

pub fn generate<'a, 'ast: 'a>(vm: &'a VM<'ast>) -> Address {
    let ngen = DoraCompileGen {
        vm,
        masm: MacroAssembler::new(),
        dbg: vm.args.flag_emit_debug_compile,
    };

    let jit_fct = ngen.generate();
    let addr = jit_fct.fct_ptr();
    vm.insert_code_map(
        jit_fct.ptr_start(),
        jit_fct.ptr_end(),
        CodeDescriptor::CompilerThunk,
    );
    vm.jit_fcts.push(JitFct::Base(jit_fct));

    addr
}

struct DoraCompileGen<'a, 'ast: 'a> {
    vm: &'a VM<'ast>,
    masm: MacroAssembler,
    dbg: bool,
}

impl<'a, 'ast> DoraCompileGen<'a, 'ast>
where
    'ast: 'a,
{
    pub fn generate(mut self) -> JitBaselineFct {
        let offset_dtn = 0;
        let offset_params = offset_dtn + size_of::<DoraToNativeInfo>() as i32;
        let offset_thread =
            offset_params + (FREG_PARAMS.len() + REG_PARAMS.len()) as i32 * mem::ptr_width();
        let framesize = mem::align_i32(offset_thread + mem::ptr_width(), 16) as i32;

        if self.dbg {
            self.masm.debug();
        }

        // the return address is the call-site we need to patch
        self.masm.prolog_size(framesize);

        // store params passed in registers on the stack
        self.store_params(offset_params);

        // prepare the native call
        self.masm.load_mem(
            MachineMode::Ptr,
            REG_TMP1.into(),
            Mem::Base(REG_THREAD, ThreadLocalData::dtn_offset()),
        );

        self.masm.store_mem(
            MachineMode::Ptr,
            Mem::Base(REG_SP, offset_dtn + DoraToNativeInfo::last_offset()),
            REG_TMP1.into(),
        );

        self.masm.store_mem(
            MachineMode::Ptr,
            Mem::Base(REG_SP, offset_dtn + DoraToNativeInfo::fp_offset()),
            REG_FP.into(),
        );

        self.masm.copy_pc(REG_TMP1);

        self.masm.store_mem(
            MachineMode::Ptr,
            Mem::Base(REG_SP, offset_dtn + DoraToNativeInfo::pc_offset()),
            REG_TMP1.into(),
        );

        self.masm.store_mem(
            MachineMode::Ptr,
            Mem::Base(REG_THREAD, ThreadLocalData::dtn_offset()),
            REG_SP.into(),
        );

        // invoke the compiler for the call site
        self.masm.load_mem(
            MachineMode::Ptr,
            REG_PARAMS[0].into(),
            Mem::Base(REG_FP, mem::ptr_width()),
        );
        self.masm.load_mem(
            MachineMode::Ptr,
            REG_PARAMS[1].into(),
            Mem::Base(REG_SP, offset_params),
        );
        self.masm.raw_call(compile_request as *const u8);

        self.masm.load_mem(
            MachineMode::Ptr,
            REG_TMP1.into(),
            Mem::Base(REG_SP, offset_dtn + DoraToNativeInfo::last_offset()),
        );

        self.masm.store_mem(
            MachineMode::Ptr,
            Mem::Base(REG_THREAD, ThreadLocalData::dtn_offset()),
            REG_TMP1.into(),
        );

        // restore argument registers from the stack
        self.load_params(offset_params);

        // remove the stack frame
        self.masm.epilog_without_return();

        // jump to compiled function
        self.masm.jump_reg(REG_RESULT);

        self.masm
            .jit(self.vm, framesize, JitDescriptor::CompilerThunk, false)
    }

    fn store_params(&mut self, mut offset: i32) {
        for reg in &REG_PARAMS {
            self.masm
                .store_mem(MachineMode::Ptr, Mem::Base(REG_SP, offset), (*reg).into());
            offset += mem::ptr_width();
        }

        for reg in &FREG_PARAMS {
            self.masm.store_mem(
                MachineMode::Float64,
                Mem::Base(REG_SP, offset),
                (*reg).into(),
            );
            offset += mem::ptr_width();
        }
    }

    fn load_params(&mut self, mut offset: i32) {
        for reg in &REG_PARAMS {
            self.masm
                .load_mem(MachineMode::Ptr, (*reg).into(), Mem::Base(REG_SP, offset));
            offset += mem::ptr_width();
        }

        for reg in &FREG_PARAMS {
            self.masm.load_mem(
                MachineMode::Float64,
                (*reg).into(),
                Mem::Base(REG_SP, offset),
            );
            offset += mem::ptr_width();
        }
    }
}

fn compile_request(ra: usize, receiver: Address) -> Address {
    let vm = get_vm();

    let bailout = {
        let data = {
            let code_map = vm.code_map.lock();
            code_map.get(ra.into()).expect("return address not found")
        };

        let fct_id = match data {
            CodeDescriptor::DoraFct(fct_id) => fct_id,
            _ => panic!("expected function for code"),
        };

        let jit_fct = vm.jit_fcts.idx(fct_id);

        let offset = ra - jit_fct.fct_ptr().to_usize();
        let jit_fct = jit_fct.to_base().expect("baseline expected");
        jit_fct
            .bailouts
            .get(offset as i32)
            .expect("bailout info not found")
            .clone()
    };

    match bailout {
        BailoutInfo::Compile(fct_id, disp, ref cls_tps, ref fct_tps) => {
            patch_fct_call(vm, ra, fct_id, cls_tps, fct_tps, disp)
        }

        BailoutInfo::VirtCompile(vtable_index, ref cls_tps, ref fct_tps) => {
            patch_vtable_call(vm, receiver, vtable_index, cls_tps, fct_tps)
        }
    }
}

fn patch_vtable_call(
    vm: &VM,
    receiver: Address,
    vtable_index: u32,
    cls_tps: &TypeList,
    fct_tps: &TypeList,
) -> Address {
    let obj = unsafe { &mut *receiver.to_mut_ptr::<Obj>() };
    let vtable = obj.header().vtbl();
    let cls_id = vtable.class().cls_id.expect("no corresponding class");
    let cls = vm.classes.idx(cls_id);
    let cls = cls.read();

    let fct_id = cls.virtual_fcts[vtable_index as usize];
    let fct_ptr = baseline::generate(vm, fct_id, cls_tps, fct_tps);

    let methodtable = vtable.table_mut();
    methodtable[vtable_index as usize] = fct_ptr.to_usize();

    fct_ptr
}

fn patch_fct_call(
    vm: &VM,
    ra: usize,
    fct_id: FctId,
    cls_tps: &TypeList,
    fct_tps: &TypeList,
    disp: i32,
) -> Address {
    let fct_ptr = baseline::generate(vm, fct_id, cls_tps, fct_tps);
    let fct_addr: *mut usize = (ra as isize - disp as isize) as *mut _;

    // update function pointer in data segment
    unsafe {
        *fct_addr = fct_ptr.to_usize();
    }

    fct_ptr
}
<|endoftext|>


<commit_before>//
// gash.rs
//
// Starting code for PS2
// Running on Rust 0.9
//
// University of Virginia - cs4414 Spring 2014
// Weilin Xu, David Evans
// Version 0.4
//

extern mod extra;

use std::{io, run, os};
use std::io::buffered::BufferedReader;
use std::io::stdin;
use std::io::signal::{Listener, Interrupt};
use std::libc;
use extra::getopts;

struct Shell {
    cmd_prompt: ~str,
    cmd_history: ~[~str]
}

impl Shell {
    fn new(prompt_str: &str) -> Shell {
        Shell {
            cmd_prompt: prompt_str.to_owned(),
	    cmd_history: ~[]
        }
    }

    fn run(&mut self) {
        let mut stdin = BufferedReader::new(stdin());

        loop {
            print(self.cmd_prompt);
            io::stdio::flush();

            let line = stdin.read_line().unwrap();
            let cmd_line = line.trim().to_owned();
	    self.cmd_history.push(cmd_line.clone());
            let program = cmd_line.splitn(' ', 1).nth(0).expect("no program");

	    let mut mod_prog = program.clone();
	    let prog_length = mod_prog.len();
	    if mod_prog.slice_from(prog_length - 1) == "&" {
	       mod_prog = mod_prog.slice_to(prog_length - 1);
	    }

            match mod_prog {
                ""      =>  { continue; }
                "exit"  =>  { return; }
                _       =>  { self.run_pipes(cmd_line); }
            }
        }
    }

    fn run_pipes(&mut self, cmd_line: &str) {
       let progs: ~[~str] =
       	       	      cmd_line.split('|').filter_map(|x| if x != "" { Some(x.to_owned()) } else { None }).to_owned_vec();
       let mut channels: ~[std::os::Pipe] = ~[];
       for _ in range(0, progs.len()) {
       	   channels.push(std::os::pipe());
       }
       for i in range(0, progs.len()) {
       	   let mut in_chan = libc::STDIN_FILENO;
	   let mut out_chan = libc::STDOUT_FILENO;
	   if i == 0 {
	      out_chan = channels[i].out;
	   }
       	   if i > 0 {
	      in_chan = channels[i-1].input;
	      out_chan = channels[i].out;
	   }
	   if i == progs.len() - 1 {
	      out_chan = libc::STDOUT_FILENO;
	   }
	   self.run_cmdline(progs[i].trim().clone(), in_chan, out_chan);
       }
    }

    fn run_cmdline(&mut self, cmd_line: &str, in_chan: libc::c_int, out_chan: libc::c_int) {
        let mut argv: ~[~str] =
            cmd_line.split(' ').filter_map(|x| if x != "" { Some(x.to_owned()) } else { None }).to_owned_vec();
        if argv.len() > 0 {
	   let program: ~str = argv.remove(0);
	   let mut mod_prog = program.clone();
	   if mod_prog == ~"grep" {
	      if argv.len() == 1 {
	      	 let mut matching = argv.pop();
		 if matching.slice_to(1) == "\"" && matching.slice_from(matching.len() - 1) == "\"" {
		    matching = matching.slice_to(matching.len() - 1).to_owned();
		    matching = matching.slice_from(1).to_owned();
	      	 }
		 argv.push(matching);
	      }
	   }
	   let mut background = false;
	   if argv.len() == 0 {
	      let prog_length = mod_prog.len();
	      if mod_prog.slice_from(prog_length - 1) == "&" {
	      	 mod_prog = mod_prog.slice_to(prog_length - 1).trim().to_owned();
	       	 background = true;
	      }
	   }
	   else {
	      let mut last_arg = argv[argv.len() - 1].clone();
	      if last_arg == ~"&" {
	      	 argv.pop();
		 background = true;
	      }
	      else {
	      	   let arg_length = last_arg.len();
	      	   if last_arg.slice_from(arg_length - 1) == "&" {
	      	      last_arg = last_arg.slice_to(arg_length - 1).to_owned();
		      argv.pop();
		      argv.push(last_arg);
		      background = true;
	      	   }
	      }
	   }

	   // Handle IO redirection
	   let mut input: libc::c_int = in_chan;
	   let mut output: libc::c_int = out_chan;
	   let argv_length = argv.len();
	   for i in range(0, argv_length) {
	       if i >= argv.len() {
	       	  break;
	       }
	       if argv[i] == ~"<" {
	       	  argv.remove(i);
	       	  if i >= argv.len() {
		     println!("No file specified for input.")
		     return;
		  }
		  else {
		       unsafe{
			let in_file_name = argv.remove(i);
		       	let mode = "r".to_c_str().unwrap();
			let file_path = Path::new(in_file_name.clone());
			if file_path.exists() {
			   let name_in_str = in_file_name.clone().to_c_str().unwrap();
			   let in_file = libc::fopen(name_in_str, mode);
		       	   input = libc::fileno(in_file);
			}
			else {
			   println!("Input file does not exists!");
			   return;
			}
		       }
		  }
	       }
	       if i >= argv.len() {
	       	  break;
	       }
	       if argv[i] == ~">" {
	       	  argv.remove(i);
		  if i >= argv.len() {
		     println!("No file specified for output.")
		     return;
		  }
		  else {
		       unsafe {
		       	 let out_file_name = argv.remove(i).to_c_str().unwrap();
		       	 let mode = "w".to_c_str().unwrap();
		       	 let out_file = libc::fopen(out_file_name, mode);
		       	 output = libc::fileno(out_file);
		       }
		     if output == -1 {
		     	println!("Invalid file for output.");
			return;
		     }
		  }
	       }
	   }

	   if background {
	      let prog = mod_prog.clone();
	      let arguments = argv.clone();
	      let fin_chan = input.clone();
	      let fout_chan = output.clone();
	      let err_chan = libc::STDERR_FILENO;
	      if self.cmd_exists(prog) {
	      	 do spawn {
		    let proc_run_opt = run::Process::new(prog, arguments, run::ProcessOptions {
		    		  			  	     env: None,
								     dir: None,
								     in_fd: Some(fin_chan),
								     out_fd: Some(fout_chan),
								     err_fd: Some(err_chan)
		    		  			  	     });
		    let mut proc_run = proc_run_opt.unwrap();
		    let mut listener = Listener::new();
		    listener.register(Interrupt);
		    proc_run.finish();
		    if fin_chan != 0 {
		       std::os::close(fin_chan);
		    }
		    if fout_chan != 1 {
		       std::os::close(fout_chan);
		    }
		 }
	      }
	      else {
	      	 println!("{:s}: command not found", prog);
	      }
	   }
	   else {
	   	self.run_cmd(program, argv, input, output);
	   }
        }
    }

    fn run_cmd(&mut self, program: &str, argv: &[~str], input_chan: libc::c_int, output_chan: libc::c_int) {
        if self.cmd_exists(program) {
	    if program == "cd" {
	       if argv.len() > 1 {
	       	  println!("Usage: cd <directory>!");
	       }
	       else if argv.len() == 0 {
	       	  let tar_path = std::os::homedir().unwrap();
		  os::change_dir(&tar_path);
	       }
	       else {
	       	  let tar_path = Path::new(argv[0].clone());
		  match os::change_dir(&tar_path) {
		  	true => { return; }
			false => { println!("No such directory!"); }
		  }
	       }
	    }
	    else {
            	  let proc_run_opt = run::Process::new(program, argv, run::ProcessOptions {
		    		  			  	     env: None,
								     dir: None,
								     in_fd: Some(input_chan),
								     out_fd: Some(output_chan),
								     err_fd: Some(libc::STDERR_FILENO)
		    		  			  	     });
		  let mut proc_run = proc_run_opt.unwrap();
		  let mut listener = Listener::new();
		  listener.register(Interrupt);
		  proc_run.finish();
		  if input_chan != 0 {
		     std::os::close(input_chan);
		  }
		  if output_chan != 1 {
		     std::os::close(output_chan);
		  }
            }
        }
	else if program == "history" {
	     for i in range(0, self.cmd_history.len()) {
	     	 println!(" {:u} {:s}", i+1, self.cmd_history[i]);
	     }
	}
	else {
            println!("{:s}: command not found", program);
        }
    }

    fn cmd_exists(&mut self, cmd_path: &str) -> bool {
        let ret = run::process_output("which", [cmd_path.to_owned()]);
        return ret.expect("exit code error.").status.success();
    }
}

fn get_cmdline_from_args() -> Option<~str> {
    /* Begin processing program arguments and initiate the parameters. */
    let args = os::args();

    let opts = ~[
        getopts::optopt("c")
    ];

    let matches = match getopts::getopts(args.tail(), opts) {
        Ok(m) => { m }
        Err(f) => { fail!(f.to_err_msg()) }
    };

    if matches.opt_present("c") {
        let cmd_str = match matches.opt_str("c") {
                                                Some(cmd_str) => {cmd_str.to_owned()},
                                                None => {~""}
                                              };
        return Some(cmd_str);
    } else {
        return None;
    }
}

fn main() {
    let opt_cmd_line = get_cmdline_from_args();

    match opt_cmd_line {
        Some(cmd_line) => Shell::new("").run_cmdline(cmd_line, libc::STDIN_FILENO, libc::STDOUT_FILENO),
        None           => Shell::new("gash > ").run()
    }
}
<commit_msg>history list function added!<commit_after>//
// gash.rs
//
// Starting code for PS2
// Running on Rust 0.9
//
// University of Virginia - cs4414 Spring 2014
// Weilin Xu, David Evans
// Version 0.4
//

extern mod extra;

use std::{io, run, os};
use std::io::buffered::BufferedReader;
use std::io::stdin;
use std::io::signal::{Listener, Interrupt};
use std::libc;
use std::num;
use extra::getopts;

struct Shell {
    cmd_prompt: ~str,
    cmd_history: ~[~str]
}

impl Shell {
    fn new(prompt_str: &str) -> Shell {
        Shell {
            cmd_prompt: prompt_str.to_owned(),
	    cmd_history: ~[]
        }
    }

    fn run(&mut self) {
        let mut stdin = BufferedReader::new(stdin());

        loop {
            print(self.cmd_prompt);
            io::stdio::flush();

            let line = stdin.read_line().unwrap();
            let cmd_line = line.trim().to_owned();
	    self.cmd_history.push(cmd_line.clone());
            let program = cmd_line.splitn(' ', 1).nth(0).expect("no program");

	    let mut mod_prog = program.clone();
	    let prog_length = mod_prog.len();
	    if mod_prog.slice_from(prog_length - 1) == "&" {
	       mod_prog = mod_prog.slice_to(prog_length - 1);
	    }

            match mod_prog {
                ""      =>  { continue; }
                "exit"  =>  { return; }
                _       =>  { self.run_pipes(cmd_line); }
            }
        }
    }

    fn run_pipes(&mut self, cmd_line: &str) {
       let progs: ~[~str] =
       	       	      cmd_line.split('|').filter_map(|x| if x != "" { Some(x.to_owned()) } else { None }).to_owned_vec();
       let mut channels: ~[std::os::Pipe] = ~[];
       for _ in range(0, progs.len()) {
       	   channels.push(std::os::pipe());
       }
       for i in range(0, progs.len()) {
       	   let mut in_chan = libc::STDIN_FILENO;
	   let mut out_chan = libc::STDOUT_FILENO;
	   if i == 0 {
	      out_chan = channels[i].out;
	   }
       	   if i > 0 {
	      in_chan = channels[i-1].input;
	      out_chan = channels[i].out;
	   }
	   if i == progs.len() - 1 {
	      out_chan = libc::STDOUT_FILENO;
	   }
	   self.run_cmdline(progs[i].trim().clone(), in_chan, out_chan);
       }
    }

    fn run_cmdline(&mut self, cmd_line: &str, in_chan: libc::c_int, out_chan: libc::c_int) {
        let mut argv: ~[~str] =
            cmd_line.split(' ').filter_map(|x| if x != "" { Some(x.to_owned()) } else { None }).to_owned_vec();
        if argv.len() > 0 {
	   let program: ~str = argv.remove(0);
	   let mut mod_prog = program.clone();
	   if mod_prog == ~"grep" {
	      if argv.len() > 0 {
	      	 let mut matching = argv.pop();
		 if matching.slice_to(1) == "\"" && matching.slice_from(matching.len() - 1) == "\"" {
		    matching = matching.slice_to(matching.len() - 1).to_owned();
		    matching = matching.slice_from(1).to_owned();
	      	 }
		 argv.push(matching);
	      }
	   }
	   let mut background = false;
	   if argv.len() == 0 {
	      let prog_length = mod_prog.len();
	      if mod_prog.slice_from(prog_length - 1) == "&" {
	      	 mod_prog = mod_prog.slice_to(prog_length - 1).trim().to_owned();
	       	 background = true;
	      }
	   }
	   else {
	      let mut last_arg = argv[argv.len() - 1].clone();
	      if last_arg == ~"&" {
	      	 argv.pop();
		 background = true;
	      }
	      else {
	      	   let arg_length = last_arg.len();
	      	   if last_arg.slice_from(arg_length - 1) == "&" {
	      	      last_arg = last_arg.slice_to(arg_length - 1).to_owned();
		      argv.pop();
		      argv.push(last_arg);
		      background = true;
	      	   }
	      }
	   }

	   // Handle IO redirection
	   let mut input: libc::c_int = in_chan;
	   let mut output: libc::c_int = out_chan;
	   let argv_length = argv.len();
	   for i in range(0, argv_length) {
	       if i >= argv.len() {
	       	  break;
	       }
	       if argv[i] == ~"<" {
	       	  argv.remove(i);
	       	  if i >= argv.len() {
		     println!("No file specified for input.")
		     return;
		  }
		  else {
		       unsafe{
			let in_file_name = argv.remove(i);
		       	let mode = "r".to_c_str().unwrap();
			let file_path = Path::new(in_file_name.clone());
			if file_path.exists() {
			   let name_in_str = in_file_name.clone().to_c_str().unwrap();
			   let in_file = libc::fopen(name_in_str, mode);
		       	   input = libc::fileno(in_file);
			}
			else {
			   println!("Input file does not exists!");
			   return;
			}
		       }
		  }
	       }
	       if i >= argv.len() {
	       	  break;
	       }
	       if argv[i] == ~">" {
	       	  argv.remove(i);
		  if i >= argv.len() {
		     println!("No file specified for output.")
		     return;
		  }
		  else {
		       unsafe {
		       	 let out_file_name = argv.remove(i).to_c_str().unwrap();
		       	 let mode = "w".to_c_str().unwrap();
		       	 let out_file = libc::fopen(out_file_name, mode);
		       	 output = libc::fileno(out_file);
		       }
		     if output == -1 {
		     	println!("Invalid file for output.");
			return;
		     }
		  }
	       }
	   }

	   if background {
	      let prog = mod_prog.clone();
	      let arguments = argv.clone();
	      let fin_chan = input.clone();
	      let fout_chan = output.clone();
	      let err_chan = libc::STDERR_FILENO;
	      if self.cmd_exists(prog) {
	      	 do spawn {
		    let proc_run_opt = run::Process::new(prog, arguments, run::ProcessOptions {
		    		  			  	     env: None,
								     dir: None,
								     in_fd: Some(fin_chan),
								     out_fd: Some(fout_chan),
								     err_fd: Some(err_chan)
		    		  			  	     });
		    let mut proc_run = proc_run_opt.unwrap();
		    let mut listener = Listener::new();
		    listener.register(Interrupt);
		    proc_run.finish();
		    if fin_chan != 0 {
		       std::os::close(fin_chan);
		    }
		    if fout_chan != 1 {
		       std::os::close(fout_chan);
		    }
		 }
	      }
	      else {
	      	 println!("{:s}: command not found", prog);
	      }
	   }
	   else {
	   	self.run_cmd(program, argv, input, output);
	   }
        }
    }

    fn run_cmd(&mut self, program: &str, argv: &[~str], input_chan: libc::c_int, output_chan: libc::c_int) {
        if self.cmd_exists(program) {
	    if program == "cd" {
	       if argv.len() > 1 {
	       	  println!("Usage: cd <directory>!");
	       }
	       else if argv.len() == 0 {
	       	  let tar_path = std::os::homedir().unwrap();
		  os::change_dir(&tar_path);
	       }
	       else {
	       	  let tar_path = Path::new(argv[0].clone());
		  match os::change_dir(&tar_path) {
		  	true => { return; }
			false => { println!("No such directory!"); }
		  }
	       }
	    }
	    else {
            	  let proc_run_opt = run::Process::new(program, argv, run::ProcessOptions {
		    		  			  	     env: None,
								     dir: None,
								     in_fd: Some(input_chan),
								     out_fd: Some(output_chan),
								     err_fd: Some(libc::STDERR_FILENO)
		    		  			  	     });
		  let mut proc_run = proc_run_opt.unwrap();
		  let mut listener = Listener::new();
		  listener.register(Interrupt);
		  proc_run.finish();
		  if input_chan != 0 {
		     std::os::close(input_chan);
		  }
		  if output_chan != 1 {
		     std::os::close(output_chan);
		  }
            }
        }
	else if program == "history" {
	     for i in range(0, self.cmd_history.len()) {
	     	 println!(" {:u} {:s}", i+1, self.cmd_history[i]);
	     }
	     let mut stdin = BufferedReader::new(stdin());
	     loop {
	     	  println!("Enter the next command you want to run (-1 to quit): ");
	     	  let input_no_str = stdin.read_line().unwrap_or(~"-1");
		  let input_no = from_str::<int>(input_no_str.slice_to(input_no_str.len() - 1)).unwrap();
		  if input_no == -1 {
		     break;
		  }
		  else if input_no < num::from_uint(self.cmd_history.len()).unwrap() {
		     let retrieved_cmd = self.cmd_history[input_no - 1].clone();
		     self.cmd_history.push(retrieved_cmd.clone());
		     self.run_pipes(retrieved_cmd);
		     break;
		  }
		  else {
		      println!("Invalid index for command!");
		  }
	     }
	}
	else {
            println!("{:s}: command not found", program);
        }
    }

    fn cmd_exists(&mut self, cmd_path: &str) -> bool {
        let ret = run::process_output("which", [cmd_path.to_owned()]);
        return ret.expect("exit code error.").status.success();
    }
}

fn get_cmdline_from_args() -> Option<~str> {
    /* Begin processing program arguments and initiate the parameters. */
    let args = os::args();

    let opts = ~[
        getopts::optopt("c")
    ];

    let matches = match getopts::getopts(args.tail(), opts) {
        Ok(m) => { m }
        Err(f) => { fail!(f.to_err_msg()) }
    };

    if matches.opt_present("c") {
        let cmd_str = match matches.opt_str("c") {
                                                Some(cmd_str) => {cmd_str.to_owned()},
                                                None => {~""}
                                              };
        return Some(cmd_str);
    } else {
        return None;
    }
}

fn main() {
    let opt_cmd_line = get_cmdline_from_args();

    match opt_cmd_line {
        Some(cmd_line) => Shell::new("").run_cmdline(cmd_line, libc::STDIN_FILENO, libc::STDOUT_FILENO),
        None           => Shell::new("gash > ").run()
    }
}
<|endoftext|>


<commit_before>use std::fs;

use test_utils::{assert_eq_text, project_dir, read_text};

use crate::{
    mock_analysis::{single_file, MockAnalysis},
    FileRange, TextRange,
};

#[test]
fn test_highlighting() {
    let (analysis, file_id) = single_file(
        r#"
#[derive(Clone, Debug)]
struct Foo {
    pub x: i32,
    pub y: i32,
}

trait Bar {
    fn bar(&self) -> i32;
}

impl Bar for Foo {
    fn bar(&self) -> i32 {
        self.x
    }
}

static mut STATIC_MUT: i32 = 0;

fn foo<'a, T>() -> T {
    foo::<'a, i32>()
}

macro_rules! def_fn {
    ($($tt:tt)*) => {$($tt)*}
}

def_fn! {
    fn bar() -> u32 {
        100
    }
}

// comment
fn main() {
    println!("Hello, {}!", 92);

    let mut vec = Vec::new();
    if true {
        let x = 92;
        vec.push(Foo { x, y: 1 });
    }
    unsafe {
        vec.set_len(0);
        STATIC_MUT = 1;
    }

    for e in vec {
        // Do nothing
    }

    let mut x = 42;
    let y = &mut x;
    let z = &y;

    y;
}

enum Option<T> {
    Some(T),
    None,
}
use Option::*;

impl<T> Option<T> {
    fn and<U>(self, other: Option<U>) -> Option<(T, U)> {
        match other {
            None => unimplemented!(),
            Nope => Nope,
        }
    }
}
"#
        .trim(),
    );
    let dst_file = project_dir().join("crates/ra_ide/src/snapshots/highlighting.html");
    let actual_html = &analysis.highlight_as_html(file_id, false).unwrap();
    let expected_html = &read_text(&dst_file);
    fs::write(dst_file, &actual_html).unwrap();
    assert_eq_text!(expected_html, actual_html);
}

#[test]
fn test_rainbow_highlighting() {
    let (analysis, file_id) = single_file(
        r#"
fn main() {
    let hello = "hello";
    let x = hello.to_string();
    let y = hello.to_string();

    let x = "other color please!";
    let y = x.to_string();
}

fn bar() {
    let mut hello = "hello";
}
"#
        .trim(),
    );
    let dst_file = project_dir().join("crates/ra_ide/src/snapshots/rainbow_highlighting.html");
    let actual_html = &analysis.highlight_as_html(file_id, true).unwrap();
    let expected_html = &read_text(&dst_file);
    fs::write(dst_file, &actual_html).unwrap();
    assert_eq_text!(expected_html, actual_html);
}

#[test]
fn accidentally_quadratic() {
    let file = project_dir().join("crates/ra_syntax/test_data/accidentally_quadratic");
    let src = fs::read_to_string(file).unwrap();

    let mut mock = MockAnalysis::new();
    let file_id = mock.add_file("/main.rs", &src);
    let host = mock.analysis_host();

    // let t = std::time::Instant::now();
    let _ = host.analysis().highlight(file_id).unwrap();
    // eprintln!("elapsed: {:?}", t.elapsed());
}

#[test]
fn test_ranges() {
    let (analysis, file_id) = single_file(
        r#"
            #[derive(Clone, Debug)]
            struct Foo {
                pub x: i32,
                pub y: i32,
            }"#,
    );

    // The "x"
    let highlights = &analysis
        .highlight_range(FileRange { file_id, range: TextRange::at(82.into(), 1.into()) })
        .unwrap();

    assert_eq!(&highlights[0].highlight.to_string(), "field.declaration");
}

#[test]
fn test_flattening() {
    let (analysis, file_id) = single_file(
        r##"
fn fixture(ra_fixture: &str) {}

fn main() {
    fixture(r#"
        trait Foo {
            fn foo() {
                println!("2 + 2 = {}", 4);
            }
        }"#
    );
}"##
        .trim(),
    );

    let dst_file = project_dir().join("crates/ra_ide/src/snapshots/highlight_injection.html");
    let actual_html = &analysis.highlight_as_html(file_id, false).unwrap();
    let expected_html = &read_text(&dst_file);
    fs::write(dst_file, &actual_html).unwrap();
    assert_eq_text!(expected_html, actual_html);
}

#[test]
fn ranges_sorted() {
    let (analysis, file_id) = single_file(
        r#"
#[foo(bar = "bar")]
macro_rules! test {}
}"#
        .trim(),
    );
    let _ = analysis.highlight(file_id).unwrap();
}

#[test]
fn test_string_highlighting() {
    // The format string detection is based on macro-expansion,
    // thus, we have to copy the macro definition from `std`
    let (analysis, file_id) = single_file(
        r#"
macro_rules! println {
    ($($arg:tt)*) => ({
        $crate::io::_print($crate::format_args_nl!($($arg)*));
    })
}
#[rustc_builtin_macro]
macro_rules! format_args_nl {
    ($fmt:expr) => {{ /* compiler built-in */ }};
    ($fmt:expr, $($args:tt)*) => {{ /* compiler built-in */ }};
}

fn main() {
    // from https://doc.rust-lang.org/std/fmt/index.html
    println!("Hello");                 // => "Hello"
    println!("Hello, {}!", "world");   // => "Hello, world!"
    println!("The number is {}", 1);   // => "The number is 1"
    println!("{:?}", (3, 4));          // => "(3, 4)"
    println!("{value}", value=4);      // => "4"
    println!("{} {}", 1, 2);           // => "1 2"
    println!("{:04}", 42);             // => "0042" with leading zerosV
    println!("{1} {} {0} {}", 1, 2);   // => "2 1 1 2"
    println!("{argument}", argument = "test");   // => "test"
    println!("{name} {}", 1, name = 2);          // => "2 1"
    println!("{a} {c} {b}", a="a", b='b', c=3);  // => "a 3 b"
    println!("{{{}}}", 2);                       // => "{2}"
    println!("Hello {:5}!", "x");
    println!("Hello {:1$}!", "x", 5);
    println!("Hello {1:0$}!", 5, "x");
    println!("Hello {:width$}!", "x", width = 5);
    println!("Hello {:<5}!", "x");
    println!("Hello {:-<5}!", "x");
    println!("Hello {:^5}!", "x");
    println!("Hello {:>5}!", "x");
    println!("Hello {:+}!", 5);
    println!("{:#x}!", 27);
    println!("Hello {:05}!", 5);
    println!("Hello {:05}!", -5);
    println!("{:#010x}!", 27);
    println!("Hello {0} is {1:.5}", "x", 0.01);
    println!("Hello {1} is {2:.0$}", 5, "x", 0.01);
    println!("Hello {0} is {2:.1$}", "x", 5, 0.01);
    println!("Hello {} is {:.*}",    "x", 5, 0.01);
    println!("Hello {} is {2:.*}",   "x", 5, 0.01);
    println!("Hello {} is {number:.prec$}", "x", prec = 5, number = 0.01);
    println!("{}, `{name:.*}` has 3 fractional digits", "Hello", 3, name=1234.56);
    println!("{}, `{name:.*}` has 3 characters", "Hello", 3, name="1234.56");
    println!("{}, `{name:>8.*}` has 3 right-aligned characters", "Hello", 3, name="1234.56");
    println!("Hello {{}}");
    println!("{{ Hello");

    println!(r"Hello, {}!", "world");

    println!("{\x41}", A = 92);
    println!("{ничоси}", ничоси = 92);
}"#
        .trim(),
    );

    let dst_file = project_dir().join("crates/ra_ide/src/snapshots/highlight_strings.html");
    let actual_html = &analysis.highlight_as_html(file_id, false).unwrap();
    let expected_html = &read_text(&dst_file);
    fs::write(dst_file, &actual_html).unwrap();
    assert_eq_text!(expected_html, actual_html);
}

#[test]
fn test_unsafe_highlighting() {
    let (analysis, file_id) = single_file(
        r#"
unsafe fn unsafe_fn() {}

struct HasUnsafeFn;

impl HasUnsafeFn {
    unsafe fn unsafe_method(&self) {}
}

fn main() {
    let x = &5 as *const usize;
    unsafe {
        unsafe_fn();
        HasUnsafeFn.unsafe_method();
        let y = *x;
        let z = -x;
    }
}
"#
        .trim(),
    );
    let dst_file = project_dir().join("crates/ra_ide/src/snapshots/highlight_unsafe.html");
    let actual_html = &analysis.highlight_as_html(file_id, false).unwrap();
    let expected_html = &read_text(&dst_file);
    fs::write(dst_file, &actual_html).unwrap();
    assert_eq_text!(expected_html, actual_html);
}
<commit_msg>Remove redundancy in syntax highlighting tests<commit_after>use std::fs;

use test_utils::{assert_eq_text, project_dir, read_text};

use crate::{
    mock_analysis::{single_file, MockAnalysis},
    FileRange, TextRange,
};

/// Highlights the code given by the `ra_fixture` argument, renders the
/// result as HTML, and compares it with the HTML file given as `snapshot`.
/// Note that the `snapshot` file is overwritten by the rendered HTML.
fn check_highlighting(ra_fixture: &str, snapshot: &str, rainbow: bool) {
    let (analysis, file_id) = single_file(ra_fixture);
    let dst_file = project_dir().join(snapshot);
    let actual_html = &analysis.highlight_as_html(file_id, rainbow).unwrap();
    let expected_html = &read_text(&dst_file);
    fs::write(dst_file, &actual_html).unwrap();
    assert_eq_text!(expected_html, actual_html);
}

#[test]
fn test_highlighting() {
    check_highlighting(
        r#"
#[derive(Clone, Debug)]
struct Foo {
    pub x: i32,
    pub y: i32,
}

trait Bar {
    fn bar(&self) -> i32;
}

impl Bar for Foo {
    fn bar(&self) -> i32 {
        self.x
    }
}

static mut STATIC_MUT: i32 = 0;

fn foo<'a, T>() -> T {
    foo::<'a, i32>()
}

macro_rules! def_fn {
    ($($tt:tt)*) => {$($tt)*}
}

def_fn! {
    fn bar() -> u32 {
        100
    }
}

// comment
fn main() {
    println!("Hello, {}!", 92);

    let mut vec = Vec::new();
    if true {
        let x = 92;
        vec.push(Foo { x, y: 1 });
    }
    unsafe {
        vec.set_len(0);
        STATIC_MUT = 1;
    }

    for e in vec {
        // Do nothing
    }

    let mut x = 42;
    let y = &mut x;
    let z = &y;

    y;
}

enum Option<T> {
    Some(T),
    None,
}
use Option::*;

impl<T> Option<T> {
    fn and<U>(self, other: Option<U>) -> Option<(T, U)> {
        match other {
            None => unimplemented!(),
            Nope => Nope,
        }
    }
}
"#
        .trim(),
        "crates/ra_ide/src/snapshots/highlighting.html",
        false,
    );
}

#[test]
fn test_rainbow_highlighting() {
    check_highlighting(
        r#"
fn main() {
    let hello = "hello";
    let x = hello.to_string();
    let y = hello.to_string();

    let x = "other color please!";
    let y = x.to_string();
}

fn bar() {
    let mut hello = "hello";
}
"#
        .trim(),
        "crates/ra_ide/src/snapshots/rainbow_highlighting.html",
        true,
    );
}

#[test]
fn accidentally_quadratic() {
    let file = project_dir().join("crates/ra_syntax/test_data/accidentally_quadratic");
    let src = fs::read_to_string(file).unwrap();

    let mut mock = MockAnalysis::new();
    let file_id = mock.add_file("/main.rs", &src);
    let host = mock.analysis_host();

    // let t = std::time::Instant::now();
    let _ = host.analysis().highlight(file_id).unwrap();
    // eprintln!("elapsed: {:?}", t.elapsed());
}

#[test]
fn test_ranges() {
    let (analysis, file_id) = single_file(
        r#"
            #[derive(Clone, Debug)]
            struct Foo {
                pub x: i32,
                pub y: i32,
            }"#,
    );

    // The "x"
    let highlights = &analysis
        .highlight_range(FileRange { file_id, range: TextRange::at(82.into(), 1.into()) })
        .unwrap();

    assert_eq!(&highlights[0].highlight.to_string(), "field.declaration");
}

#[test]
fn test_flattening() {
    check_highlighting(
        r##"
fn fixture(ra_fixture: &str) {}

fn main() {
    fixture(r#"
        trait Foo {
            fn foo() {
                println!("2 + 2 = {}", 4);
            }
        }"#
    );
}"##
        .trim(),
        "crates/ra_ide/src/snapshots/highlight_injection.html",
        false,
    );
}

#[test]
fn ranges_sorted() {
    let (analysis, file_id) = single_file(
        r#"
#[foo(bar = "bar")]
macro_rules! test {}
}"#
        .trim(),
    );
    let _ = analysis.highlight(file_id).unwrap();
}

#[test]
fn test_string_highlighting() {
    // The format string detection is based on macro-expansion,
    // thus, we have to copy the macro definition from `std`
    check_highlighting(
        r#"
macro_rules! println {
    ($($arg:tt)*) => ({
        $crate::io::_print($crate::format_args_nl!($($arg)*));
    })
}
#[rustc_builtin_macro]
macro_rules! format_args_nl {
    ($fmt:expr) => {{ /* compiler built-in */ }};
    ($fmt:expr, $($args:tt)*) => {{ /* compiler built-in */ }};
}

fn main() {
    // from https://doc.rust-lang.org/std/fmt/index.html
    println!("Hello");                 // => "Hello"
    println!("Hello, {}!", "world");   // => "Hello, world!"
    println!("The number is {}", 1);   // => "The number is 1"
    println!("{:?}", (3, 4));          // => "(3, 4)"
    println!("{value}", value=4);      // => "4"
    println!("{} {}", 1, 2);           // => "1 2"
    println!("{:04}", 42);             // => "0042" with leading zerosV
    println!("{1} {} {0} {}", 1, 2);   // => "2 1 1 2"
    println!("{argument}", argument = "test");   // => "test"
    println!("{name} {}", 1, name = 2);          // => "2 1"
    println!("{a} {c} {b}", a="a", b='b', c=3);  // => "a 3 b"
    println!("{{{}}}", 2);                       // => "{2}"
    println!("Hello {:5}!", "x");
    println!("Hello {:1$}!", "x", 5);
    println!("Hello {1:0$}!", 5, "x");
    println!("Hello {:width$}!", "x", width = 5);
    println!("Hello {:<5}!", "x");
    println!("Hello {:-<5}!", "x");
    println!("Hello {:^5}!", "x");
    println!("Hello {:>5}!", "x");
    println!("Hello {:+}!", 5);
    println!("{:#x}!", 27);
    println!("Hello {:05}!", 5);
    println!("Hello {:05}!", -5);
    println!("{:#010x}!", 27);
    println!("Hello {0} is {1:.5}", "x", 0.01);
    println!("Hello {1} is {2:.0$}", 5, "x", 0.01);
    println!("Hello {0} is {2:.1$}", "x", 5, 0.01);
    println!("Hello {} is {:.*}",    "x", 5, 0.01);
    println!("Hello {} is {2:.*}",   "x", 5, 0.01);
    println!("Hello {} is {number:.prec$}", "x", prec = 5, number = 0.01);
    println!("{}, `{name:.*}` has 3 fractional digits", "Hello", 3, name=1234.56);
    println!("{}, `{name:.*}` has 3 characters", "Hello", 3, name="1234.56");
    println!("{}, `{name:>8.*}` has 3 right-aligned characters", "Hello", 3, name="1234.56");
    println!("Hello {{}}");
    println!("{{ Hello");

    println!(r"Hello, {}!", "world");

    println!("{\x41}", A = 92);
    println!("{ничоси}", ничоси = 92);
}"#
        .trim(),
        "crates/ra_ide/src/snapshots/highlight_strings.html",
        false,
    );
}

#[test]
fn test_unsafe_highlighting() {
    check_highlighting(
        r#"
unsafe fn unsafe_fn() {}

struct HasUnsafeFn;

impl HasUnsafeFn {
    unsafe fn unsafe_method(&self) {}
}

fn main() {
    let x = &5 as *const usize;
    unsafe {
        unsafe_fn();
        HasUnsafeFn.unsafe_method();
        let y = *x;
        let z = -x;
    }
}
"#
        .trim(),
        "crates/ra_ide/src/snapshots/highlight_unsafe.html",
        false,
    );
}
<|endoftext|>


<commit_before>#![allow(uppercase_variables)]

//! A few linear algebra operations on two-dimensional arrays.

use std::num::{zero, one, Zero, One};

use super::{Array, Ix};

/// Column vector.
pub type Col = Array;
/// Rectangular matrix.
pub type Mat = Array;

/// Return the identity matrix of dimension *n*.
pub fn eye(n: Ix) -> Mat
{
    let mut eye = Array::zeros((n, n));
    for a_ii in eye.diag_iter_mut() {
        *a_ii = one::();
    }
    eye
}

/*
/// Return the inverse matrix of square matrix `a`.
pub fn inverse(a: &Mat) -> Mat
{
    fail!()
}
*/

/// Solve *a x = b* with linear least squares approximation.
///
/// It is used to find the best fit for an overdetermined system,
/// i.e. the number of rows in *a* is larger than the number of
/// unknowns *x*.
///
/// Return best fit for *x*.
pub fn least_squares(a: &Mat, b: &Col) -> Col
{
    // Using transpose: a.T a x = a.T b;
    // a.T a being square gives naive solution
    // x_lstsq = inv(a.T a) a.T b
    //
    // Solve using cholesky decomposition
    // aT a x = aT b
    //
    // Factor aT a into L L.T
    //
    // L L.T x = aT b
    //
    // => L z = aT b
    //  fw subst for z
    // => L.T x = z
    //  bw subst for x estimate
    //
    let (m, n) = a.dim();

    let mut aT = a.clone();
    aT.swap_axes(0, 1);

    let aT_a = aT.mat_mul(a);
    let mut L = cholesky(&aT_a);
    let rhs = aT.mat_mul(&b.reshape((m, 1))).reshape(n);

    // Solve L z = aT b
    let z = subst_fw(&L, &rhs);

    // Solve L.T x = z
    L.swap_axes(0, 1);
    let x_lstsq = subst_bw(&L, &z);
    x_lstsq
}

/// Factor *a = L L.T*.
///
/// *a* should be hermitian and positive definite.
///
/// https://en.wikipedia.org/wiki/Cholesky_decomposition
///
/// “The Cholesky decomposition is mainly used for the numerical solution of
/// linear equations Ax = b.
///
/// If A is symmetric and positive definite, then we can solve Ax = b by first
/// computing the Cholesky decomposition A = LL*, then solving Ly = b for y by
/// forward substitution, and finally solving L*x = y for x by back
/// substitution.”
///
/// Return L.
pub fn cholesky(a: &Mat) -> Mat
{
    let z = zero::();
    let (m, n) = a.dim();
    assert!(m == n);
    let mut L = Array::::zeros((n, n));
    for i in range(0, m) {
        // Entries 0 .. i before the diagonal
        for j in range(0, i) {
            // L²_1,1
            // L_2,1 L_1,1  L²_2,1 + L²_2,2
            // L_3,1 L_1,1  L_3,1 L_2,1 + L_3,2 L_2,2  L²_3,1 + L²_3,2 + L²_3,3
            let mut lik_ljk_sum = z.clone();
            {
                // L[(i, k)] for k = 0 .. j
                // L[(j, k)] for k = 0 .. j
                let Lik = L.row_iter(i);
                let Ljk = L.row_iter(j);
                for (&lik, &ljk) in Lik.zip(Ljk).take(j) {
                    lik_ljk_sum = lik_ljk_sum + lik * ljk;
                }
            }

            L[(i, j)] = (a[(i, j)] - lik_ljk_sum) / L[(j, j)];
        }
        // diagonal where i == j
        // L_j,j = Sqrt[A_j,j - Sum_k=1 to (j-1) L²_j,k ]
        let j = i;
        let mut ljk_sum = z.clone();
        // L[(j, k)] for k = 0 .. j
        for &ljk in L.row_iter(j).take(j) {
            ljk_sum = ljk_sum + ljk * ljk;
        }
        L[(j, j)] = (a[(j, j)] - ljk_sum).sqrt();
    }
    L
}

/// Solve *L x = b* where *L* is a lower triangular matrix.
pub fn subst_fw(l: &Mat, b: &Col) -> Col
{
    let (m, n) = l.dim();
    assert!(m == n);
    assert!(m == b.dim());
    let mut x = Vec::from_elem(m, zero::());
    for (i, bi) in b.indexed_iter() {
        // b_lx_sum = b[i] - Sum(for j = 0 .. i) L_ij x_j
        let mut b_lx_sum = bi.clone();
        for (lij, xj) in l.row_iter(i).zip(x.iter()).take(i) {
            b_lx_sum = b_lx_sum - (*lij) * (*xj)
        }
        x.as_mut_slice()[i] = b_lx_sum / l[(i, i)];
    }
    Array::from_vec(x)
}

/// Solve *U x = b* where *U* is an upper triangular matrix.
pub fn subst_bw(u: &Mat, b: &Col) -> Col
{
    let (m, n) = u.dim();
    assert!(m == n);
    assert!(m == b.dim());
    let mut x = Vec::from_elem(m, zero::());
    for i in range(0, m).rev() {
        // b_ux_sum = b[i] - Sum(for j = i .. m) U_ij x_j
        let mut b_ux_sum = b[i].clone();
        for (uij, xj) in u.row_iter(i).rev().zip(x.iter().rev()).take(m - i - 1) {
            b_ux_sum = b_ux_sum - (*uij) * (*xj);
        }
        x.as_mut_slice()[i] = b_ux_sum / u[(i, i)];
    }
    Array::from_vec(x)
}
<commit_msg>linalg: Fix transpose symbol<commit_after>#![allow(uppercase_variables)]

//! A few linear algebra operations on two-dimensional arrays.

use std::num::{zero, one, Zero, One};

use super::{Array, Ix};

/// Column vector.
pub type Col = Array;
/// Rectangular matrix.
pub type Mat = Array;

/// Return the identity matrix of dimension *n*.
pub fn eye(n: Ix) -> Mat
{
    let mut eye = Array::zeros((n, n));
    for a_ii in eye.diag_iter_mut() {
        *a_ii = one::();
    }
    eye
}

/*
/// Return the inverse matrix of square matrix `a`.
pub fn inverse(a: &Mat) -> Mat
{
    fail!()
}
*/

/// Solve *a x = b* with linear least squares approximation.
///
/// It is used to find the best fit for an overdetermined system,
/// i.e. the number of rows in *a* is larger than the number of
/// unknowns *x*.
///
/// Return best fit for *x*.
pub fn least_squares(a: &Mat, b: &Col) -> Col
{
    // Using transpose: a.T a x = a.T b;
    // a.T a being square gives naive solution
    // x_lstsq = inv(a.T a) a.T b
    //
    // Solve using cholesky decomposition
    // aT a x = aT b
    //
    // Factor aT a into L L.T
    //
    // L L.T x = aT b
    //
    // => L z = aT b
    //  fw subst for z
    // => L.T x = z
    //  bw subst for x estimate
    //
    let (m, n) = a.dim();

    let mut aT = a.clone();
    aT.swap_axes(0, 1);

    let aT_a = aT.mat_mul(a);
    let mut L = cholesky(&aT_a);
    let rhs = aT.mat_mul(&b.reshape((m, 1))).reshape(n);

    // Solve L z = aT b
    let z = subst_fw(&L, &rhs);

    // Solve L.T x = z
    L.swap_axes(0, 1);
    let x_lstsq = subst_bw(&L, &z);
    x_lstsq
}

/// Factor *a = L LT*.
///
/// *a* should be hermitian and positive definite.
///
/// https://en.wikipedia.org/wiki/Cholesky_decomposition
///
/// “The Cholesky decomposition is mainly used for the numerical solution of
/// linear equations Ax = b.
///
/// If A is symmetric and positive definite, then we can solve Ax = b by first
/// computing the Cholesky decomposition A = LL*, then solving Ly = b for y by
/// forward substitution, and finally solving L*x = y for x by back
/// substitution.”
///
/// Return L.
pub fn cholesky(a: &Mat) -> Mat
{
    let z = zero::();
    let (m, n) = a.dim();
    assert!(m == n);
    let mut L = Array::::zeros((n, n));
    for i in range(0, m) {
        // Entries 0 .. i before the diagonal
        for j in range(0, i) {
            // L²_1,1
            // L_2,1 L_1,1  L²_2,1 + L²_2,2
            // L_3,1 L_1,1  L_3,1 L_2,1 + L_3,2 L_2,2  L²_3,1 + L²_3,2 + L²_3,3
            let mut lik_ljk_sum = z.clone();
            {
                // L[(i, k)] for k = 0 .. j
                // L[(j, k)] for k = 0 .. j
                let Lik = L.row_iter(i);
                let Ljk = L.row_iter(j);
                for (&lik, &ljk) in Lik.zip(Ljk).take(j) {
                    lik_ljk_sum = lik_ljk_sum + lik * ljk;
                }
            }

            L[(i, j)] = (a[(i, j)] - lik_ljk_sum) / L[(j, j)];
        }
        // diagonal where i == j
        // L_j,j = Sqrt[A_j,j - Sum_k=1 to (j-1) L²_j,k ]
        let j = i;
        let mut ljk_sum = z.clone();
        // L[(j, k)] for k = 0 .. j
        for &ljk in L.row_iter(j).take(j) {
            ljk_sum = ljk_sum + ljk * ljk;
        }
        L[(j, j)] = (a[(j, j)] - ljk_sum).sqrt();
    }
    L
}

/// Solve *L x = b* where *L* is a lower triangular matrix.
pub fn subst_fw(l: &Mat, b: &Col) -> Col
{
    let (m, n) = l.dim();
    assert!(m == n);
    assert!(m == b.dim());
    let mut x = Vec::from_elem(m, zero::());
    for (i, bi) in b.indexed_iter() {
        // b_lx_sum = b[i] - Sum(for j = 0 .. i) L_ij x_j
        let mut b_lx_sum = bi.clone();
        for (lij, xj) in l.row_iter(i).zip(x.iter()).take(i) {
            b_lx_sum = b_lx_sum - (*lij) * (*xj)
        }
        x.as_mut_slice()[i] = b_lx_sum / l[(i, i)];
    }
    Array::from_vec(x)
}

/// Solve *U x = b* where *U* is an upper triangular matrix.
pub fn subst_bw(u: &Mat, b: &Col) -> Col
{
    let (m, n) = u.dim();
    assert!(m == n);
    assert!(m == b.dim());
    let mut x = Vec::from_elem(m, zero::());
    for i in range(0, m).rev() {
        // b_ux_sum = b[i] - Sum(for j = i .. m) U_ij x_j
        let mut b_ux_sum = b[i].clone();
        for (uij, xj) in u.row_iter(i).rev().zip(x.iter().rev()).take(m - i - 1) {
            b_ux_sum = b_ux_sum - (*uij) * (*xj);
        }
        x.as_mut_slice()[i] = b_ux_sum / u[(i, i)];
    }
    Array::from_vec(x)
}
<|endoftext|>


<commit_before>use clap::{ArgMatches};
use std::path::Path;
use db;
use std::fs::File;
use std::io::Read;
use rustc_serialize;
use rustc_serialize::{Encodable};
use rustc_serialize::json::{self, Encoder};
use rustc_serialize::json::Json;

use std::collections::HashMap;
use std::result::Result;
use rusqlite::Connection;
use rusqlite::Error;

use dbFsFile;

use std::result;

#[derive(Debug)]
struct Person {
    id: i32,
    name: String,
    data: Option<Vec<u8>>
}

pub fn listy(direcory: &str) {
    let path = Path::new(direcory);
    for entry in path.read_dir().expect("read_dir call failed") {
        if let Ok(entry) = entry {
            println!("aaaa{:?}", entry.path());
        }
    }
}

pub fn job_files_list(direcory: &str)  {
    let path = Path::new(direcory);
    for entry in path.read_dir().expect("read_dir call failed") {
        if let Ok(entry) = entry {
            println!("job_files_list{:?}", entry.path());
        }
    }
}

pub fn listy2(direcory: &str) -> Vec<String>{
    println!("listy2{:?}", direcory);
    let mut items = Vec::<String>::new();

    let path = Path::new(direcory);
    for entry in path.read_dir().expect("read_dir call failed") {
        if let Ok(entry) = entry {
            let path = entry.path();
            if path.is_dir() {
                continue;
            }
            let pb_2 = path.as_path();
            let as_path_buf = pb_2.as_os_str();
            let path = String::new() + as_path_buf.to_str().unwrap() ;
            items.push(path);

        }
    }
    return items;
}

pub fn json_loader_old(name: &str)  {
    let mut f = File::open(name).expect("file not found");

    let mut contents = String::new();
    f.read_to_string(&mut contents).expect("something went wrong reading the file");

    let json = Json::from_str(&contents).unwrap();
    //println!("json={}", json);
    let found = json.find_path(&["provides"]);
    if found != None {
        for item in found {
            println!("provides={}", item);
            let as_a_str = item.to_string();
            //db::insert_provider(&conn, as_a_str);
        }
    }
    let found = json.find_path(&["name"]);
    if found != None {
        for item in found {
            println!("name={}", item);
        }
    }
    let found = json.find_path(&["script"]);
    if found != None {
        for item in found {
            println!("script={}", item);
        }
    }
    let found = json.find_path(&["variables"]);
    if found != None {

        for item in found {
            println!("variables={}", item);
            let bill = item.find_path(&["require_keys"]);
            if bill != None {
                for item2 in bill {
                    println!("variables::require_keys={}", item2);
                }
            }
            let bill = item.find_path(&["provides_keys"]);
            if bill != None {
                for item2 in bill {
                    println!("variables::provides_keys={}", item2);
                }
            }
            let bill = item.find_path(&["require_values"]);
            if bill != None {
                for item2 in bill {
                    let ben = item2.find_path(&[""]);

                    for itme3 in ben {
                        println!("variables::itme3={}", itme3);
                    }
                }
            }
        }

    }
    let found = json.find_path(&["depends"]);
    if found != None {
        for item in found {
            println!("depends={}", item);
        }
    }

}

pub fn loader(name: &str) -> String {
    let mut f = File::open(name).expect("file not found");

    let mut contents = String::new();
    f.read_to_string(&mut contents).expect("something went wrong reading the file");

    return contents;

}

fn json_loader_elephant_variable_pk(conn: &Connection, variable_pk :i32, text :&String) -> i32 {
    return variable_pk;
}

fn json_loader_elephant_job_pk(conn: &Connection, text :&String) -> i32 {
    let mut pk_job :i32 = 0;
    let rc = db::pk_job_by_name(conn, &text, &mut pk_job);
    match rc {
        Ok(pk) => {
            return pk_job;
        }
        Err(_) => {
            let doink = db::insert_job(conn, &text);
            if doink.is_err() {
                return 0;
            }
            match doink {
                Ok(pk) => {
                    let doin3k = db::pk_job_by_name(conn, &text, &mut pk_job);
                    match doin3k {
                        Ok(pk) => {
                            return pk_job;
                            }
                        Err(_) => {
                                println!("Failed to select job");
                                return 0;
                            }
                        }
                    }
                Err(_) => {
                    println!("Failed to insert job");
                    return 0;
                }
            }

        }
    }
    return pk_job;
}

pub fn json_loader_elephant(conn: &Connection, json :&rustc_serialize::json::Json) {
    let mut pk_job :i32 = 0;
    let found = json.find_path(&["name"]);
    if found != None {
        for item in found {
            let str_item = item.to_string();
            pk_job = json_loader_elephant_job_pk(conn, &str_item);
            println!("pk_job::name={}", pk_job);
        }
    }

    let found = json.find_path(&["variables"]);
    if found != None {

        for item in found {
            let bill = item.find_path(&["require_keys"]);
            if bill != None {
                for item2 in bill {
                    if item2.is_array() {
                        let ssd = item2.as_array();
                        let sdf = ssd.unwrap();
                        let george = sdf.len();
                        let itemfdsd = sdf.iter();
                        for elem in itemfdsd{
                            println!("variables::require_key={}", elem.to_string());
                        }
                    }
                }
            }
            let bill = item.find_path(&["provides_keys"]);
            if bill != None {
                for item2 in bill {

                    if item2.is_array() {
                        let ssd = item2.as_array();
                        let sdf = ssd.unwrap();
                        let george = sdf.len();
                        let itemfdsd = sdf.iter();
                        for elem in itemfdsd{
                            println!("variables::provide_key={}", elem.to_string());
                        }
                    }
                }
            }
            let bill = item.find_path(&["require_values"]);
            if bill != None {
                for item2 in bill {

                    let ben = item2.find_path(&[""]);

                    for itme3 in ben {
                        println!("variables::itme3={}", itme3);
                    }
                }
            }
        }

    }
    println!("pk_job={}", pk_job);
}

pub fn json_loader_name(conn: &Connection, content: &str)  {
    let mut contents = String::new();
    let json = Json::from_str(&content);
    let mut pk_job :i32 = 0;
    match json {
        Ok(json) => {
            json_loader_elephant(conn, &json);
        }
        Err(_)=> {}
    }
    //return json.unwrap();
}

pub fn json_loader_provides_keys(conn: &Connection, content: &str)  {
    let mut contents = String::new();
    let json = Json::from_str(&content);

    match json {
        Ok(json) => {
            let found = json.find_path(&["provides_keys"]);
            if found != None {
                for item in found {
                    let str_item = item.to_string();
                    let str_item_clone1 = str_item.clone();
                    db::insert_provider(conn, item.to_string());

                    //println!("provides_keys={}", item);
                }
            }
        }
        Err(_)=> {}
    }
    //return json.unwrap();
}

pub fn json_loader_require_keys(conn: &Connection, content: &str)  {
    let mut contents = String::new();
    let json = Json::from_str(&content);
    match json {
        Ok(json) => {
            let found = json.find_path(&["require_keys"]);
            if found != None {
                for item in found {

                    db::insert_job_variable_name(conn, item.to_string());

                    //println!("require_keys={}", item);
                }
            }
        }
        Err(_)=> {}
    }
    //return json.unwrap();
}

pub fn deligate(matches : ArgMatches) {

    let conn = db::connect();
    db::create_tables(&conn);

    if let Some(in_v) = matches.values_of("dir-scripts") {
        for in_file in in_v {
            //println!("An input dir-scripts: {}", in_file);
           listy(&in_file);

        }
    }

        // If we specified the multiple() setting we can get all the values
    if let Some(in_v) = matches.values_of("env") {
        for in_file in in_v {
            println!("An input file: {}", in_file);
            job_files_list(&in_file);
        }
    }

    if let Some(in_v) = matches.values_of("dir-jobs") {
        for in_file in in_v {
            let filename = in_file.to_string();
            db::insert_fs_dir(&conn, 0, filename);
        }
    }
    for directory in db::list_fs_dir(&conn) {
        let foo = directory.id;
        let foo_name = directory.name;
        let file_list = listy2(&foo_name);
        for fnccc in file_list {
            println!("An input file: {}", fnccc);
            let s1 = fnccc.clone();
            db::insert_fs_file(&conn, foo, fnccc);
            let mut pk = 10;
            db::pk_fs_file_by_name(&conn, s1, &mut pk);
            println!("ssss: {}", pk);
        }
    }

    let mut scores = HashMap::new();
    for filename in db::list_fs_file(&conn) {
        let mut name = String::from(filename.name);
        let name2 = name.clone();
        let loader_rc = loader(name2.trim());
        scores.insert(name,loader_rc );
    }

    for filename in db::list_fs_file(&conn) {
        let name = filename.name;
        json_loader_name(&conn, &loader(&name));

    }
    for filename in db::list_fs_file(&conn) {
        let name = filename.name;
        json_loader_provides_keys(&conn, &loader(&name));

    }

    for filename in db::list_fs_file(&conn) {
        let name = filename.name;
        json_loader_require_keys(&conn, &loader(&name));

    }

    for filename in db::list_fs_file(&conn) {
        let name = filename.name;
        json_loader_require_keys(&conn, &loader(&name));

    }

    for filename in db::list_provider(&conn) {
        println!("list_provider{:?}", filename);
    }
}

<commit_msg>Continuing the elephant walkt with loader<commit_after>use clap::{ArgMatches};
use std::path::Path;
use db;
use std::fs::File;
use std::io::Read;
use rustc_serialize;
use rustc_serialize::{Encodable};
use rustc_serialize::json::{self, Encoder};
use rustc_serialize::json::Json;

use std::collections::HashMap;
use std::result::Result;
use rusqlite::Connection;
use rusqlite::Error;

use dbFsFile;

use std::result;

#[derive(Debug)]
struct Person {
    id: i32,
    name: String,
    data: Option<Vec<u8>>
}

pub fn listy(direcory: &str) {
    let path = Path::new(direcory);
    for entry in path.read_dir().expect("read_dir call failed") {
        if let Ok(entry) = entry {
            println!("aaaa{:?}", entry.path());
        }
    }
}

pub fn job_files_list(direcory: &str)  {
    let path = Path::new(direcory);
    for entry in path.read_dir().expect("read_dir call failed") {
        if let Ok(entry) = entry {
            println!("job_files_list{:?}", entry.path());
        }
    }
}

pub fn listy2(direcory: &str) -> Vec<String>{
    println!("listy2{:?}", direcory);
    let mut items = Vec::<String>::new();

    let path = Path::new(direcory);
    for entry in path.read_dir().expect("read_dir call failed") {
        if let Ok(entry) = entry {
            let path = entry.path();
            if path.is_dir() {
                continue;
            }
            let pb_2 = path.as_path();
            let as_path_buf = pb_2.as_os_str();
            let path = String::new() + as_path_buf.to_str().unwrap() ;
            items.push(path);

        }
    }
    return items;
}

pub fn json_loader_old(name: &str)  {
    let mut f = File::open(name).expect("file not found");

    let mut contents = String::new();
    f.read_to_string(&mut contents).expect("something went wrong reading the file");

    let json = Json::from_str(&contents).unwrap();
    //println!("json={}", json);
    let found = json.find_path(&["provides"]);
    if found != None {
        for item in found {
            println!("provides={}", item);
            let as_a_str = item.to_string();
            //db::insert_provider(&conn, as_a_str);
        }
    }
    let found = json.find_path(&["name"]);
    if found != None {
        for item in found {
            println!("name={}", item);
        }
    }
    let found = json.find_path(&["script"]);
    if found != None {
        for item in found {
            println!("script={}", item);
        }
    }
    let found = json.find_path(&["variables"]);
    if found != None {

        for item in found {
            println!("variables={}", item);
            let bill = item.find_path(&["require_keys"]);
            if bill != None {
                for item2 in bill {
                    println!("variables::require_keys={}", item2);
                }
            }
            let bill = item.find_path(&["provides_keys"]);
            if bill != None {
                for item2 in bill {
                    println!("variables::provides_keys={}", item2);
                }
            }
            let bill = item.find_path(&["require_values"]);
            if bill != None {
                for item2 in bill {
                    let ben = item2.find_path(&[""]);

                    for itme3 in ben {
                        println!("variables::itme3={}", itme3);
                    }
                }
            }
        }

    }
    let found = json.find_path(&["depends"]);
    if found != None {
        for item in found {
            println!("depends={}", item);
        }
    }

}

pub fn loader(name: &str) -> String {
    let mut f = File::open(name).expect("file not found");

    let mut contents = String::new();
    f.read_to_string(&mut contents).expect("something went wrong reading the file");

    return contents;

}

fn elephant_variable_pk(conn: &Connection, variable_pk :i32, text :&String) -> i32 {
    return variable_pk;
}

fn elephant_job_pk(conn: &Connection, pk_file :&i32, text :&String) -> i32 {
    let mut pk_job :i32 = 0;
    let rc = db::pk_job_by_name(conn, &text, &mut pk_job);
    match rc {
        Ok(pk) => {
            return pk_job;
        }
        Err(_) => {
            let doink = db::insert_job(conn, &pk_file, &text);
            if doink.is_err() {
                return 0;
            }
            match doink {
                Ok(pk) => {
                    let doin3k = db::pk_job_by_name(conn, &text, &mut pk_job);
                    match doin3k {
                        Ok(pk) => {
                            return pk_job;
                            }
                        Err(_) => {
                                println!("Failed to select job");
                                return 0;
                            }
                        }
                    }
                Err(_) => {
                    println!("Failed to insert job");
                    return 0;
                }
            }

        }
    }
    return pk_job;
}

fn elephant_provider_pk(conn: &Connection, text :&String) -> i32 {
    let mut pk_provider :i32 = 0;
    let rc = db::pk_provider_by_name(conn, &text, &mut pk_provider);
    match rc {
        Ok(pk) => {
            return pk_provider;
        }
        Err(_) => {
            let doink = db::insert_provider(conn, &text);
            if doink.is_err() {
                println!("Failed to insert");
                return 0;
            }
            match doink {
                Ok(pk) => {
                    let doin3k = db::pk_provider_by_name(conn, &text, &mut pk_provider);
                    match doin3k {
                        Ok(pk) => {
                            return pk_provider;
                            }
                        Err(_) => {
                                println!("Failed to select provider");
                                return 0;
                            }
                        }
                    }
                Err(_) => {
                    println!("Failed to insert provider");
                    return 0;
                }
            }
        }
    }
    return pk_provider;
}

pub fn json_loader_elephant(conn: &Connection, pk_file: &i32, json :&rustc_serialize::json::Json) {
    let mut pk_job :i32 = 0;
    let mut pk_provider :i32 = 0;
    let found = json.find_path(&["name"]);
    if found != None {
        for item in found {
            let str_item = item.to_string();
            pk_job = elephant_job_pk(conn, &pk_file, &str_item);
            println!("pk_job::name={}", pk_job);
        }
    }
    let found = json.find_path(&["provides"]);
    if found != None {
        for item in found {
            let str_item = item.to_string();
            pk_provider = elephant_provider_pk(conn, &str_item);
            println!("pk_provider::name={}", pk_provider);
        }
    }
    println!("pk_provider::name={}", pk_provider);

    let found = json.find_path(&["variables"]);
    if found != None {

        for item in found {
            let bill = item.find_path(&["require_keys"]);
            if bill != None {
                for item2 in bill {
                    if item2.is_array() {
                        let ssd = item2.as_array();
                        let sdf = ssd.unwrap();
                        let george = sdf.len();
                        let itemfdsd = sdf.iter();
                        for elem in itemfdsd{
                            println!("variables::require_key={}", elem.to_string());
                        }
                    }
                }
            }
            let bill = item.find_path(&["provides_keys"]);
            if bill != None {
                for item2 in bill {

                    if item2.is_array() {
                        let ssd = item2.as_array();
                        let sdf = ssd.unwrap();
                        let george = sdf.len();
                        let itemfdsd = sdf.iter();
                        for elem in itemfdsd{
                            println!("variables::provide_key={}", elem.to_string());
                        }
                    }
                }
            }
            let bill = item.find_path(&["require_values"]);
            if bill != None {
                for item2 in bill {

                    let ben = item2.find_path(&[""]);

                    for itme3 in ben {
                        println!("variables::itme3={}", itme3);
                    }
                }
            }
        }

    }
}

pub fn json_loader_name(conn: &Connection, pk_file: &i32, content: &str)  {
    let mut contents = String::new();
    let json = Json::from_str(&content);
    let mut pk_job :i32 = 0;
    match json {
        Ok(json) => {
            json_loader_elephant(conn, &pk_file, &json);
        }
        Err(_)=> {}
    }
    //return json.unwrap();
}

pub fn json_loader_require_keys(conn: &Connection, content: &str)  {
    let mut contents = String::new();
    let json = Json::from_str(&content);
    match json {
        Ok(json) => {
            let found = json.find_path(&["require_keys"]);
            if found != None {
                for item in found {

                    db::insert_job_variable_name(conn, item.to_string());

                    //println!("require_keys={}", item);
                }
            }
        }
        Err(_)=> {}
    }
    //return json.unwrap();
}

pub fn deligate(matches : ArgMatches) {

    let conn = db::connect();
    db::create_tables(&conn);

    if let Some(in_v) = matches.values_of("dir-scripts") {
        for in_file in in_v {
            //println!("An input dir-scripts: {}", in_file);
           listy(&in_file);

        }
    }

        // If we specified the multiple() setting we can get all the values
    if let Some(in_v) = matches.values_of("env") {
        for in_file in in_v {
            println!("An input file: {}", in_file);
            job_files_list(&in_file);
        }
    }

    if let Some(in_v) = matches.values_of("dir-jobs") {
        for in_file in in_v {
            let filename = in_file.to_string();
            db::insert_fs_dir(&conn, 0, filename);
        }
    }
    for directory in db::list_fs_dir(&conn) {
        let foo = directory.id;
        let foo_name = directory.name;
        let file_list = listy2(&foo_name);
        for fnccc in file_list {
            println!("An input file: {}", fnccc);
            let s1 = fnccc.clone();
            db::insert_fs_file(&conn, foo, fnccc);
            let mut pk = 10;
            db::pk_fs_file_by_name(&conn, s1, &mut pk);
            println!("ssss: {}", pk);
        }
    }

    let mut scores = HashMap::new();
    for filename in db::list_fs_file(&conn) {
        let mut name = String::from(filename.name);
        let name2 = name.clone();
        let loader_rc = loader(name2.trim());
        scores.insert(name,loader_rc );
    }

    for filename in db::list_fs_file(&conn) {
        let pk_file = filename.id;
        let name = filename.name;
        json_loader_name(&conn, &pk_file, &loader(&name));

    }

    for filename in db::list_fs_file(&conn) {
        let name = filename.name;
        json_loader_require_keys(&conn, &loader(&name));

    }

    for filename in db::list_fs_file(&conn) {
        let name = filename.name;
        json_loader_require_keys(&conn, &loader(&name));

    }

    for filename in db::list_provider(&conn) {
        println!("list_provider{:?}", filename);
    }
}

<|endoftext|>


<commit_before>/// Create and populate a router.
///
/// ```ignore
/// let router = router!(index: get  "/"       => index,
///                      query: get  "/:query" => queryHandler,
///                      post:  post "/"       => postHandler);
/// ```
///
/// Is equivalent to:
///
/// ```ignore
/// let mut router = Router::new();
/// router.get("/", index, "index");
/// router.get("/:query", queryHandler, "query");
/// router.post("/", postHandler, "post");
/// ```
///
/// The method name must be lowercase, supported methods:
///
/// `get`, `post`, `put`, `delete`, `head`, `patch`, `options` and `any`.
#[macro_export]
macro_rules! router {
    ($($route_id:ident: $method:ident $glob:expr => $handler:expr),+ $(,)*) => ({
        let mut router = $crate::Router::new();
        $(router.$method($glob, $handler, stringify!($route_id));)*
        router
    });
}

/// Generate a URL based off of the requested one.
///
/// ```ignore
/// url_for!(request, "foo",
///          "query" => "test",
///          "extraparam" => "foo")
/// ```
///
/// Is equivalent to:
///
/// ```ignore
/// router::url_for(request, "foo", {
///     let mut rv = ::std::collections::HashMap::new();
///     rv.insert("query".to_owned(), "test".to_owned());
///     rv.insert("extraparam".to_owned(), "foo".to_owned());
///     rv
/// })
/// ```
#[macro_export]
macro_rules! url_for {
    ($request:expr, $route_id:expr, $($key:expr => $value:expr),* $(,)*) => (
        $crate::url_for($request, $route_id, {
            let mut params = ::std::collections::HashMap::<String, String>::new();
            $(params.insert($key.into(), $value.into());)*
            params
        })
    )
}

#[cfg(test)]
mod tests {
    use iron::{Response, Request, IronResult};

    //simple test to check that all methods expand without error
    #[test]
    fn methods() {
        fn handler(_: &mut Request) -> IronResult<Response> {Ok(Response::new())}
        let _ = router!(a: get     "/foo" => handler,
                        b: post    "/bar/" => handler,
                        c: put     "/bar/baz" => handler,
                        d: delete  "/bar/baz" => handler,
                        e: head    "/foo" => handler,
                        f: patch   "/bar/baz" => handler,
                        g: options "/foo" => handler,
                        h: any     "/" => handler);
    }
}
<commit_msg>Fix bug in url_for! with empty parameters<commit_after>/// Create and populate a router.
///
/// ```ignore
/// let router = router!(index: get  "/"       => index,
///                      query: get  "/:query" => queryHandler,
///                      post:  post "/"       => postHandler);
/// ```
///
/// Is equivalent to:
///
/// ```ignore
/// let mut router = Router::new();
/// router.get("/", index, "index");
/// router.get("/:query", queryHandler, "query");
/// router.post("/", postHandler, "post");
/// ```
///
/// The method name must be lowercase, supported methods:
///
/// `get`, `post`, `put`, `delete`, `head`, `patch`, `options` and `any`.
#[macro_export]
macro_rules! router {
    ($($route_id:ident: $method:ident $glob:expr => $handler:expr),+ $(,)*) => ({
        let mut router = $crate::Router::new();
        $(router.$method($glob, $handler, stringify!($route_id));)*
        router
    });
}

/// Generate a URL based off of the requested one.
///
/// ```ignore
/// url_for!(request, "foo",
///          "query" => "test",
///          "extraparam" => "foo")
/// ```
///
/// Is equivalent to:
///
/// ```ignore
/// router::url_for(request, "foo", {
///     let mut rv = ::std::collections::HashMap::new();
///     rv.insert("query".to_owned(), "test".to_owned());
///     rv.insert("extraparam".to_owned(), "foo".to_owned());
///     rv
/// })
/// ```
#[macro_export]
macro_rules! url_for {
    ($request:expr, $route_id:expr $(,$key:expr => $value:expr)* $(,)*) => (
        $crate::url_for($request, $route_id, {
            let mut params = ::std::collections::HashMap::<String, String>::new();
            $(params.insert($key.into(), $value.into());)*
            params
        })
    )
}

#[cfg(test)]
mod tests {
    use iron::{Response, Request, IronResult};

    //simple test to check that all methods expand without error
    #[test]
    fn methods() {
        fn handler(_: &mut Request) -> IronResult<Response> {Ok(Response::new())}
        let _ = router!(a: get     "/foo" => handler,
                        b: post    "/bar/" => handler,
                        c: put     "/bar/baz" => handler,
                        d: delete  "/bar/baz" => handler,
                        e: head    "/foo" => handler,
                        f: patch   "/bar/baz" => handler,
                        g: options "/foo" => handler,
                        h: any     "/" => handler);
    }
}
<|endoftext|>