fn preprocess(cmdline: &mut CommandLine) {
    let tmp = cmdline.cmd.clone();
    // TODO: this is awful, refactor to not use a loop
    for (i, each) in tmp.split(' ').enumerate() {

        if each.trim() == "" {
            // eat extra tabs/spaces
            continue;
        } else if each.trim().chars().nth(0).unwrap() == '#' {
            // stop parsing if there's a comment
            // ok to use unwrap because we've guaranteed input isn't empty
            break;
        } else if each.trim().chars().nth(0).unwrap() == '&'  {
            // background process, ignoring rest of input
            // TODO: probably shouldn't just ignore rest of input. also,
            // the & has to have a space before it right now

            if cmdline.bg == true {
                printerr!("background symbol `&` specified twice");
            }
            cmdline.bg = true;
            break;
        } else {
            // ok, this is real input

            let mut tmp = each.trim().to_string();

            // did they not include a space before the bg symbol?
            if each.trim().chars().nth(each.len()-1).unwrap() == '&' {
                if cmdline.bg == true {
                    printerr!("background symbol `&` specified twice");
                }
                cmdline.bg = true;
                tmp.pop();
            }
        

            // if it's the very first split word
            if i == 0 {
                cmdline.cmd = tmp;
                // handle `exit` builtin so we can handle it ASAP
                if each.trim() == "exit" {
                    builtin(&cmdline);
                }
            } else {
                // regular argument
                cmdline.args.push(tmp);
            }
        }
    }
}
/*
 * preprocess - main parsing routine responsible for populating CommandLine
 * struct
 */
main parsing routine responsible for populating CommandLine
struct
main parsing routine responsible for populating CommandLine struct
fn preprocess(cmdline: &mut CommandLine) {
    let tmp = cmdline.cmd.clone();
    // TODO: this is awful, refactor to not use a loop
    for (i, each) in tmp.split(' ').enumerate() {
        if each.trim() == "" {
            // eat extra tabs/spaces
            continue;
        } else if each.trim().chars().nth(0).unwrap() == '#' {
            // stop parsing if there's a comment
            // ok to use unwrap because we've guaranteed input isn't empty
            break;
        } else if each.trim().chars().nth(0).unwrap() == '&'  {
            // background process, ignoring rest of input
            // TODO: probably shouldn't just ignore rest of input. also,
            // the & has to have a space before it right now
            if cmdline.bg == true {
                printerr!("background symbol `&` specified twice");
            }
            cmdline.bg = true;
            break;
        } else {
            // ok, this is real input
            let mut tmp = each.trim().to_string();
            // did they not include a space before the bg symbol?
            if each.trim().chars().nth(each.len()-1).unwrap() == '&' {
                if cmdline.bg == true {
                    printerr!("background symbol `&` specified twice");
                }
                cmdline.bg = true;
                tmp.pop();
            }
            // if it's the very first split word
            if i == 0 {
                cmdline.cmd = tmp;
                // handle `exit` builtin so we can handle it ASAP
                if each.trim() == "exit" {
                    builtin(&cmdline);
                }
            } else {
                // regular argument
                cmdline.args.push(tmp);
            }
        }
    }
}
fn preprocess ( cmdline : & mut CommandLine ) { let tmp = cmdline . cmd . clone ( ) ; // TODO: this is awful, refactor to not use a loop for ( i , each ) in tmp . split ( ' ' ) . enumerate ( ) { if each . trim ( ) == " " { // eat extra tabs/spaces continue ; } else if each . trim ( ) . chars ( ) . nth ( 0 ) . unwrap ( ) == '#' { // stop parsing if there's a comment // ok to use unwrap because we've guaranteed input isn't empty break ; } else if each . trim ( ) . chars ( ) . nth ( 0 ) . unwrap ( ) == '&' { // background process, ignoring rest of input // TODO: probably shouldn't just ignore rest of input. also, // the & has to have a space before it right now if cmdline . bg == true { printerr ! ( " " ) ; } cmdline . bg = true ; break ; } else { // ok, this is real input let mut tmp = each . trim ( ) . to_string ( ) ; // did they not include a space before the bg symbol? if each . trim ( ) . chars ( ) . nth ( each . len ( ) - 1 ) . unwrap ( ) == '&' { if cmdline . bg == true { printerr ! ( " " ) ; } cmdline . bg = true ; tmp . pop ( ) ; } // if it's the very first split word if i == 0 { cmdline . cmd = tmp ; // handle `exit` builtin so we can handle it ASAP if each . trim ( ) == " " { builtin ( & cmdline ) ; } } else { // regular argument cmdline . args . push ( tmp ) ; } } } }
preprocess - main parsing routine responsible for populating CommandLine
 struct
preprocess - main parsing routine responsible for populating CommandLine struct
cmdline
&mut CommandLine
cmdline
&mut CommandLine