Source File: go-coreutils/cat/main.go

package main

import (
  "fmt"
  "flag"
  "os"
  "log"
  "strings"
)

func Fail(err error, format string, v ...any) {
  err_format := fmt.Sprintf("ERROR: %v; %s", err, format)
  log.Printf(err_format, v...)
  os.Exit(1)
}

type Opts struct {
  Number bool
  Squeeze bool
  Filenames []string
}

func parse_opts() (Opts) {
  var opts Opts

  flag.BoolVar(&opts.Number, "n", false, "Number all nonempty output lines, starting with 1")
  flag.BoolVar(&opts.Squeeze, "s", false, "Suppress repeated adjacent blank lines")
  flag.Parse()

  if flag.NArg() < 1 {
    log.Fatal("USAGE: cat [-n] [-s] file0 [fileN]")
    os.Exit(1)
  }

  opts.Filenames = flag.Args()

  return opts
}

func main() {
  opts := parse_opts()

  for _, filename := range opts.Filenames {
    in_file, err := os.ReadFile(filename)

    if err != nil { Fail(err, "cannot open %s:", filename) }

    if(opts.Number) {
      count := 1
      for line := range strings.Lines(string(in_file)) {
        if opts.Squeeze && len(line) <= 1 {
          continue
        }

        fmt.Printf("%0.4d: %s", count, line)
        count++
      }
    } else {
      fmt.Print(string(in_file))
    }
  }
}