mjladd cmpb234cf214 years agoHistory
98 lines · 1.8 KB · Go
RawDownload
package main import (	"bufio"	"flag"	"fmt"	"io"	"os"	"strconv") var lflag = flag.Bool("l", false, "do not print and character")var sflag = flag.Bool("s", false, "silent, do not print errors")var Lflag = flag.Bool("L", false, "print line number of difference") func usage() {	fmt.Fprintf(os.Stderr, "usage: cmp [-lsL] file1 file2 [offset1 [offset2]]\n")	os.Exit(2)} func error(s string) {	if !*sflag {		fmt.Fprint(os.Stderr, s, "\n")	}	os.Exit(1)} func main() {	flag.Usage = usage	flag.Parse()	args := flag.Args()	if len(args) < 2 || len(args) > 4 {		usage()	}	f1, err := os.Open(args[0])	if err != nil {		error(fmt.Sprintf("open %s: %s", args[0], err))	}	f2, err := os.Open(args[1])	if err != nil {		error(fmt.Sprintf("open %s: %s", args[1], err))	} 	xseek := func(f *os.File, fn string, os string) {		o, err := strconv.ParseInt(os, 0, 64)		if err != nil {			error(fmt.Sprintf("bad offset %s: %s", os, err))		}		_, err = f.Seek(o, 0)		if err != nil {			error(fmt.Sprintf("seek %s %s: %s", fn, os, err))		}	} 	if len(args) >= 3 {		xseek(f1, args[0], args[2])	}	if len(args) >= 4 {		xseek(f2, args[1], args[2])	} 	r1 := bufio.NewReader(f1)	r2 := bufio.NewReader(f2)	nc := 1	l := 1	for {		b1, err1 := r1.ReadByte()		b2, err2 := r2.ReadByte()		if err1 == io.EOF && err2 == io.EOF {			break		}		if err1 != nil {			error(fmt.Sprintf("%s: read: %s", args[0], err1.Error()))		}		if err2 != nil {			error(fmt.Sprintf("%s: read: %s", args[1], err2.Error()))		}		if b1 != b2 {			if *sflag {				os.Exit(1)			}			if !*lflag {				fmt.Printf("%s %s differ: char %d", args[0], args[1], nc)				if !*Lflag {					fmt.Printf(" line %d", l)				}				fmt.Print("\n")				os.Exit(1)			}			fmt.Printf("%6d 0x%.2x 0x%.2x\n", nc, b1, b2)		}		nc++		if b1 == '\n' {			l++		}	}	os.Exit(0)}