diff options
| author | Benedict <benedict@0xb8000.de> | 2016-11-11 21:53:37 +0100 |
|---|---|---|
| committer | Benedict <benedict@0xb8000.de> | 2016-11-12 19:29:52 +0100 |
| commit | f8fb703ac7bb2767e2659a6e7ec7fa3a64c4168a (patch) | |
| tree | c0028e8e613460c7e727e38d8d93906c6239a4fd | |
intial commit: line of code in rust
| -rw-r--r-- | Cargo.lock | 4 | ||||
| -rw-r--r-- | Cargo.toml | 6 | ||||
| -rw-r--r-- | src/config.rs | 96 | ||||
| -rw-r--r-- | src/main.rs | 81 |
4 files changed, 187 insertions, 0 deletions
diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..0d14a1a --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,4 @@ +[root] +name = "loc" +version = "0.1.0" + diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..3916615 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "loc" +version = "0.1.0" +authors = ["Benedict Boerger <benedict.boerger@cs.tu-dortmund.de>"] + +[dependencies] diff --git a/src/config.rs b/src/config.rs new file mode 100644 index 0000000..b054c00 --- /dev/null +++ b/src/config.rs @@ -0,0 +1,96 @@ +use std::fs::File; +use std::option::Option; +use std::process::*; +use std::env::home_dir; +use std::io::*; +use std::io::ErrorKind::Other; + +static LOCAL_CONF_FILE_NAME: &'static str = ".loc.config"; +static GLOBAL_CONF_FILE_NAME: &'static str = "/etc/loc/config"; + +pub struct CommentTokens { + pub file_ending: String, + pub single_line: String, + pub begin_comment_block: String, + pub end_comment_block: String, +} + +pub fn read_config() -> Result<Vec<CommentTokens>>{ + // first read the local files .loc.config + let mut local_error = false; + let mut global_error = false; + let mut user_error = false; + let mut conf: Vec<CommentTokens> = Vec::new(); + + match read_config_file(LOCAL_CONF_FILE_NAME, &mut conf) { + Ok(_i) => {}, + Err(_e) => {local_error = true}, + } + + if let Some(mut x) = home_dir() { + x.push(LOCAL_CONF_FILE_NAME); + let user_conf_file_name = x.to_str().unwrap(); + + match read_config_file(user_conf_file_name, &mut conf) { + Ok(_i) => {}, + Err(_e) => { user_error = true}, + } + } + + match read_config_file(GLOBAL_CONF_FILE_NAME,&mut conf) { + Ok(_i) => {}, + Err(_e) => {global_error= true}, + } + + // quit programm if could not read any config file + if local_error && global_error && user_error { + println!("failed to read config files:\n\ + {}: \n\ + {}:", LOCAL_CONF_FILE_NAME, + GLOBAL_CONF_FILE_NAME); + exit(1); + } + + Ok(conf) +} + +fn read_config_file(config_file: &str, conf: &mut Vec<CommentTokens>) -> Result<i32> { + let f = try!(File::open(config_file)); + let bufread = BufReader::new(f); + + for (index, line) in bufread.lines().enumerate() { + match parse_config_file_line(&try!(line)) { + Ok(conf_tok) => conf.push(conf_tok), + Err(e)=> println!("error file {}, line {}: {}", config_file, index+1, e), + } + + } + + Ok(10) +} + +fn config_file_line_unwrap_element(elem: Option<&str>) -> Result<String>{ + match elem { + Some(line) => Ok(line.to_string()), + None => Err(Error::new(Other, "must have four tokens")), + } +} + +fn parse_config_file_line(line: &str) -> Result<CommentTokens>{ + let mut tokens = line.split_whitespace(); + + let conf = CommentTokens { + file_ending : try!(config_file_line_unwrap_element(tokens.next())), + single_line : try!(config_file_line_unwrap_element(tokens.next())), + begin_comment_block : try!(config_file_line_unwrap_element(tokens.next())), + end_comment_block : try!(config_file_line_unwrap_element(tokens.next())), + }; + + // there should not be anymore value otherwise print warning + // for wrong config file format + if tokens.next() != None { + return Err(Error::new(Other, "more than four tokens")); + } + + Ok(conf) +} diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..57a8196 --- /dev/null +++ b/src/main.rs @@ -0,0 +1,81 @@ +use std::fs::File; +use std::env; +use std::path::Path; +use std::io::*; + +mod config; + +fn omit_line(line: String, in_comment_section: &mut bool, comment_tokens: &config::CommentTokens) -> bool { + let s = line.trim(); + let begin_comment_section = s.starts_with(comment_tokens.begin_comment_block.as_str()); + let end_comment_section = s.starts_with(comment_tokens.end_comment_block.as_str()); + + if begin_comment_section { + *in_comment_section = true; + return true; + } + else if *in_comment_section && !end_comment_section { + return true; + } + else if *in_comment_section && end_comment_section { + *in_comment_section = false; + return true; + } + + s.starts_with(comment_tokens.single_line.as_str()) || s.is_empty() +} + +fn get_config<'a>(config: &'a Vec<config::CommentTokens>, extension: &str) -> Option<&'a config::CommentTokens> { + for conf in config.iter() { + if conf.file_ending == extension { + return Some(conf); + } + } + None +} + +fn count_lines(filename: &str, config: &mut Vec<config::CommentTokens>) -> Result<i32>{ + let mut sum = 0; + let mut in_comment_section = false; + + // do we have config for this type of file? + let extension = match Path::new(filename).extension() { + Some(ext) => ext.to_str().unwrap(), + None => return Err(Error::new(std::io::ErrorKind::Other, "could not get extension")), + }; + + let comment_tokens = match get_config(&config, extension) { + Some(conf) => conf, + None => return Err(Error::new(std::io::ErrorKind::NotFound, "config not found")), + }; + + let bufread = BufReader::new(try!(File::open(filename))); + for line in bufread.lines() { + if omit_line(try!(line), &mut in_comment_section, &comment_tokens) { + continue; + } + sum += 1; + } + Ok(sum) +} + +fn main() { + let mut config = match config::read_config() { + Err(e) => panic!("error reading config file(s): {}", e), + Ok(i) => i, + }; + + let mut sum = 0; + + // TODO read files from standard input option + // TODO read all file below this dictionary + for argument in env::args().skip(1) { + match count_lines(argument.as_str(), &mut config) { + Ok(i) => { + println!("{}\t: {}", i, argument); + sum += i; }, + Err(e) => println!("error for file {}: {}", argument, e), + } + } + println!("{}\t: total", sum); +} |
