gitlab.com/apertussolutions/u-root@v7.0.0+incompatible/cmds/core/seq/seq.go (about) 1 // Copyright 2013-2017 the u-root Authors. All rights reserved 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 // Print a sequence of numbers. 6 // 7 // Synopsis: 8 // seq [-f FORMAT] [-w] [-s SEPARATOR] [START [STEP [END]]] 9 // 10 // Examples: 11 // % seq -s=' ' 3 12 // 1 2 3 13 // % seq -s=' ' 2 4 14 // 2 3 4 15 // % seq -s=' ' 3 2 7 16 // 3 5 7 17 // 18 // Options: 19 // -f: use printf style floating-point FORMAT (default: %v) 20 // -s: use STRING to separate numbers (default: \n) 21 // -w: equalize width by padding with leading zeroes (default: false) 22 package main 23 24 import ( 25 "errors" 26 "flag" 27 "fmt" 28 "io" 29 "log" 30 "os" 31 "strings" 32 ) 33 34 var ( 35 flags struct { 36 format string 37 separator string 38 widthEqual bool 39 } 40 cmd = "seq [-f format] [-w] [-s separator] [start [step [end]]]" 41 ) 42 43 func init() { 44 defUsage := flag.Usage 45 flag.Usage = func() { 46 os.Args[0] = cmd 47 defUsage() 48 } 49 flag.StringVar(&flags.format, "f", "%v", "use printf style floating-point FORMAT") 50 flag.StringVar(&flags.separator, "s", "\n", "use STRING to separate numbers") 51 flag.BoolVar(&flags.widthEqual, "w", false, "equalize width by padding with leading zeroes") 52 } 53 54 func seq(w io.Writer, args []string) error { 55 var ( 56 stt = 1.0 57 stp = 1.0 58 end float64 59 width int 60 ) 61 62 format := flags.format // I use that because I'll modify a global variable 63 argv, argc := args, len(args) 64 if argc < 1 || argc > 4 { 65 return fmt.Errorf("mismatch n args; got %v, wants 1 >= n args >= 3", argc) 66 } 67 68 // loading step value if args is <start> <step> <end> 69 if argc == 3 { 70 _, err := fmt.Sscanf(argv[1], "%v", &stp) 71 if stp-float64(int(stp)) > 0 && format == "%v" { 72 d := len(fmt.Sprintf("%v", stp-float64(int(stp)))) - 2 // get the nums of y.xx decimal part 73 format = fmt.Sprintf("%%.%df", d) 74 } 75 if stp == 0.0 { 76 return errors.New("step value should be != 0") 77 } 78 79 if err != nil { 80 return err 81 } 82 } 83 84 if argc >= 2 { // cases: start + end || start + step + end 85 if _, err := fmt.Sscanf(argv[0]+" "+argv[argc-1], "%v %v", &stt, &end); err != nil { 86 return err 87 } 88 } else { // only <end> 89 if _, err := fmt.Sscanf(argv[0], "%v", &end); err != nil { 90 return err 91 } 92 } 93 94 format = strings.Replace(format, "%", "%0*", 1) // support widthEqual 95 if flags.widthEqual { 96 width = len(fmt.Sprintf(format, 0, end)) 97 } 98 99 defer fmt.Fprint(w, "\n") // last char is always '\n' 100 for stt <= end { 101 fmt.Fprintf(w, format, width, stt) 102 stt += stp 103 if stt <= end { // print only between the values 104 fmt.Fprint(w, flags.separator) 105 } 106 } 107 108 return nil 109 } 110 111 func main() { 112 flag.Parse() 113 114 if err := seq(os.Stdout, flag.Args()); err != nil { 115 log.Println(err) 116 flag.Usage() 117 os.Exit(1) 118 } 119 }