summaryrefslogtreecommitdiff
path: root/cmd
diff options
context:
space:
mode:
authorMartin Atkins <mart@degeneration.co.uk>2017-06-24 08:25:08 -0700
committerMartin Atkins <mart@degeneration.co.uk>2017-06-24 09:02:11 -0700
commitaba54359ba7dab7950002378c50ea9ad26c42e27 (patch)
tree01ef7e86e8ad89fe3af30476e0eea69fb3606bec /cmd
parente24fecb79d929523c4082233245a0cdd1d8956d1 (diff)
cmd/zclfmt: zcl native syntax pretty-printer
This applies the simple native syntax reformatting function to one or more files. It does not support JSON or any other syntax. Calling applications might provide their own versions of this that e.g. can format an entire directory by matching on filename patterns, but this serves as an example and a utility for single files.
Diffstat (limited to 'cmd')
-rw-r--r--cmd/zclfmt/main.go93
1 files changed, 93 insertions, 0 deletions
diff --git a/cmd/zclfmt/main.go b/cmd/zclfmt/main.go
new file mode 100644
index 0000000..17ad9f0
--- /dev/null
+++ b/cmd/zclfmt/main.go
@@ -0,0 +1,93 @@
+package main
+
+import (
+ "errors"
+ "flag"
+ "fmt"
+ "io/ioutil"
+ "os"
+
+ "github.com/zclconf/go-zcl/zclwrite"
+)
+
+const versionStr = "0.0.1-dev"
+
+var (
+ overwrite = flag.Bool("w", false, "overwrite source files instead of writing to stdout")
+ showVersion = flag.Bool("version", false, "show the version number and immediately exit")
+)
+
+func main() {
+ if err := realmain(); err != nil {
+ fmt.Fprintln(os.Stderr, err.Error())
+ os.Exit(1)
+ }
+}
+
+func realmain() error {
+ flag.Usage = usage
+ flag.Parse()
+
+ if *showVersion {
+ fmt.Println(versionStr)
+ return nil
+ }
+
+ if flag.NArg() == 0 {
+ if *overwrite {
+ return errors.New("error: cannot use -w without source filenames")
+ }
+
+ return processFile("<stdin>", os.Stdin)
+ }
+
+ for i := 0; i < flag.NArg(); i++ {
+ path := flag.Arg(i)
+ switch dir, err := os.Stat(path); {
+ case err != nil:
+ return err
+ case dir.IsDir():
+ // This tool can't walk a whole directory because it doesn't
+ // know what file naming schemes will be used by different
+ // zcl-embedding applications, so it'll leave that sort of
+ // functionality for apps themselves to implement.
+ return fmt.Errorf("can't format directory %s", path)
+ default:
+ if err := processFile(path, nil); err != nil {
+ return err
+ }
+ }
+ }
+
+ return nil
+}
+
+func processFile(fn string, in *os.File) error {
+ var err error
+ if in == nil {
+ in, err = os.Open(fn)
+ if err != nil {
+ return fmt.Errorf("failed to open %s: %s", fn, err)
+ }
+ }
+
+ inSrc, err := ioutil.ReadAll(in)
+ if err != nil {
+ return fmt.Errorf("failed to read %s: %s", fn, err)
+ }
+
+ outSrc := zclwrite.Format(inSrc)
+
+ if *overwrite {
+ return ioutil.WriteFile(fn, outSrc, 0644)
+ }
+
+ _, err = os.Stdout.Write(outSrc)
+ return err
+}
+
+func usage() {
+ fmt.Fprintf(os.Stderr, "usage: zclfmt [flags] [path ...]\n")
+ flag.PrintDefaults()
+ os.Exit(2)
+}