123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113 |
- // Copyright (C) 2015, Alberto Corona <alberto@0x1a.us>
- // All rights reserved. This file is part of core-utils, distributed under the
- // GPL v3 license. For full terms please see the LICENSE file.
- #![crate_type = "bin"]
- #![crate_name = "cat"]
- #![feature(path_ext)]
- static VERS: &'static str = "0.1.0";
- static PROG: &'static str = "cat";
- extern crate getopts;
- extern crate util;
- use getopts::{Options};
- use util::{Status};
- use std::env;
- use std::io::Read;
- use std::path::{PathBuf};
- use std::fs::{File,PathExt};
- fn files_to_string(file: Vec<String>) -> String {
- let mut return_string = String::new();
- for item in file {
- let mut fstring = String::new();
- let fpath = PathBuf::from(&item);
- if fpath.is_dir() {
- util::path_err(Status::Error, String::from("cat: file is a directory"), fpath);
- }
- let mut ffile = match File::open(PathBuf::from(&item)) {
- Ok(f) => { f },
- Err(e) => {
- util::err(PROG, Status::Error, e.to_string());
- panic!();
- }
- };
- match ffile.read_to_string(&mut fstring) {
- Ok(_) => { return_string.push_str(&fstring) },
- Err(e) => {
- util::err(PROG, Status::Error, e.to_string());
- panic!();
- }
- };
- }
- return return_string;
- }
- fn print_lines(file: String, new: bool, tabs: bool, num: bool) {
- let mut lineno: i32 = 1;
- let num_lines: u32 = file.lines().count() as u32;
- if num {
- print!("{} ", lineno);
- }
- for i in file.chars() {
- if num && new && i == '\n' {
- if lineno < num_lines as i32 {
- lineno += 1;
- print!("$\n{} ", lineno);
- }
- } else if num && i == '\n' {
- if lineno < num_lines as i32 {
- lineno += 1;
- print!("{}{} ", i, lineno);
- }
- } else if i == '\n' && new {
- print!("$\n");
- } else if i == '\t' && tabs {
- print!("^I");
- } else {
- print!("{}", i);
- }
- }
- }
- fn print_usage(prog: &str, opts: Options) {
- let brief = format!("Usage: {} [OPTION]", prog);
- print!("{}", opts.usage(&brief));
- util::exit(Status::Ok);
- }
- fn main() {
- let args: Vec<String> = env::args().collect();
- let mut opts = Options::new();
- opts.optflag("h", "help", "Print the help menu");
- opts.optflag("", "version", "Print the version");
- opts.optflag("a", "all", "Show all characters");
- opts.optflag("n", "numbered", "Show numbered lines");
- opts.optflag("E", "ends", "Show newline characters as '$'");
- opts.optflag("t", "tabs", "Show tab characters as '^I'");
- let matches = match opts.parse(&args[1..]) {
- Ok(m) => { m }
- Err(f) => {
- util::err(PROG, Status::OptError, f.to_string());
- panic!(f)
- }
- };
- let tabs = matches.opt_present("t");
- let new = matches.opt_present("E");
- let num = matches.opt_present("n");
- if matches.opt_present("h") {
- print_usage(PROG, opts);
- } else if matches.opt_present("version") {
- util::copyright(PROG, VERS, "2015", vec!["Alberto Corona"]);
- } else if matches.opt_present("a") {
- print_lines(files_to_string(matches.free), true, true, num);
- } else {
- print_lines(files_to_string(matches.free), new, tabs, num);
- }
- }
|