Skip to content

Instantly share code, notes, and snippets.

@doccaico
Last active December 2, 2023 17:30
Show Gist options
  • Select an option

  • Save doccaico/b503c562698bf77dbbee56fd47806f66 to your computer and use it in GitHub Desktop.

Select an option

Save doccaico/b503c562698bf77dbbee56fd47806f66 to your computer and use it in GitHub Desktop.
Naive cat In Golang and Rust
package main
// http://www.nct9.ne.jp/m_hiroi/golang/abcgo33.html#chap02
import (
"bufio"
"flag"
"fmt"
"os"
"strings"
)
var bflag bool
var nflag bool
var tflag bool
func cat(file *os.File, n int) int {
s := bufio.NewScanner(file)
for s.Scan() {
var line string
if tflag {
line = strings.Replace(s.Text(), "\t", "^I", -1)
} else {
line = s.Text()
}
if (bflag && line != "") || nflag {
fmt.Printf("%6d\t%s\n", n, line)
n++
} else {
fmt.Println(line)
}
}
return n
}
func main() {
flag.BoolVar(&bflag, "b", false, "number nonempty output lines, overrides -n")
flag.BoolVar(&nflag, "n", false, "number all output lines")
flag.BoolVar(&tflag, "T", false, "display TAB characters as ^I")
flag.Parse()
if bflag && nflag {
nflag = false
}
n := 1
if flag.NArg() == 0 {
cat(os.Stdin, n)
} else {
for _, filename := range flag.Args() {
file, err := os.Open(filename)
if err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
n = cat(file, n)
file.Close()
}
}
}
use std::env;
use std::fs;
use std::io::{self, BufRead, BufReader};
use std::process;
macro_rules! base_usage {
() => {
"\
Usage: {exe} [OPTION]... [FILE]...
Concatenate FILE(s) to standard output.
With no FILE, or when FILE is -, read standard input.
-n number nonempty output lines, overrides -n
-b number all output lines
-T display TAB characters as ^I"
};
}
struct Option {
bflag: bool,
nflag: bool,
tflag: bool,
}
fn cat(readable: &mut dyn io::Read, opt: &Option, mut n: usize) -> usize {
let f = BufReader::new(readable);
for line in f.lines() {
let mut s = line.unwrap();
if opt.tflag {
s = s.replace("\t", "^I");
}
if (opt.bflag && s != "") || opt.nflag {
println!("{:>6}\t{}", n, s);
n += 1;
} else {
println!("{}", s);
}
}
return n;
}
fn main() -> io::Result<()> {
let mut opt = Option {
bflag: false,
nflag: false,
tflag: false,
};
let exe = env::current_exe();
let mut files = Vec::new();
let mut it = env::args();
let mut stdin_flag = false;
it.next();
for arg in it {
if arg.starts_with("-") {
if arg == "-" {
stdin_flag = true;
} else if arg == "-b" {
opt.bflag = true;
} else if arg == "-n" {
opt.nflag = true;
} else if arg == "-T" {
opt.tflag = true;
} else if arg == "-h" || arg == "--help" {
println!(base_usage!(), exe = exe.unwrap().display());
process::exit(0);
} else {
eprintln!(
"unknown option {}\nTry '{} --help' for more information.",
arg,
exe.unwrap().display()
);
process::exit(1);
}
} else {
files.push(arg);
}
}
if opt.bflag && opt.nflag {
opt.nflag = false;
}
if files.is_empty() {
stdin_flag = true
};
let mut n: usize = 1;
if stdin_flag {
cat(&mut io::stdin() as &mut dyn io::Read, &opt, n);
} else {
for file in files {
let mut f = fs::File::open(file)?;
n = cat(&mut f as &mut dyn io::Read, &opt, n);
}
}
Ok(())
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment