diff options
author | flu0r1ne <flu0r1ne@flu0r1ne.net> | 2021-07-21 23:00:00 -0500 |
---|---|---|
committer | flu0r1ne <flu0r1ne@flu0r1ne.net> | 2021-07-21 23:00:00 -0500 |
commit | fb8aee6c5147b8751a3920f613934d90b79ef4c5 (patch) | |
tree | 46dd389d9695b3c4f9f1e65962e76b383f703863 | |
parent | a10f10119f05320fb71574ad54b3161f5a37d371 (diff) | |
download | zsu-fb8aee6c5147b8751a3920f613934d90b79ef4c5.tar.xz zsu-fb8aee6c5147b8751a3920f613934d90b79ef4c5.zip |
Added parser for +- syntax for relative references to snapshots
-rw-r--r-- | cmd/cat.go | 5 | ||||
-rw-r--r-- | cmds/list.go | 21 | ||||
-rw-r--r-- | snap/parsing.go | 89 | ||||
-rw-r--r-- | snap/parsing_test.go | 31 | ||||
-rw-r--r-- | snap/snap.go | 6 |
5 files changed, 130 insertions, 22 deletions
@@ -2,8 +2,11 @@ package cmd import ( "fmt" + "golang.flu0r1ne.net/zfdiff/snap" ) func Cat(params []string) { - fmt.Println(params) + snapRef := snap.ToRelative(params[0]) + + fmt.Println(snapRef); }
\ No newline at end of file diff --git a/cmds/list.go b/cmds/list.go deleted file mode 100644 index 14fa53d..0000000 --- a/cmds/list.go +++ /dev/null @@ -1,21 +0,0 @@ -package cmd - -import ( - "flag" - "fmt" -) - -func List(params []string) { - flags := flag.NewFlagSet("list", flag.ExitOnError) - - var withPaths bool - - const WITH_PATHS_HELP = "print paths to the provided reference within the snapshot" - - flags.BoolVar(&withPaths, "paths", false, WITH_PATHS_HELP); - flags.BoolVar(&withPaths, "p", false, WITH_PATHS_HELP); - - flags.Parse(params); - - fmt.Printf("Your flag is: %t", withPaths); -} diff --git a/snap/parsing.go b/snap/parsing.go new file mode 100644 index 0000000..a848c33 --- /dev/null +++ b/snap/parsing.go @@ -0,0 +1,89 @@ +package snap + +import ( + "strings" + "log" + "os" + "strconv" +) + +var die = log.New(os.Stderr, "", 0) + +func isEscaped(str string) bool { + n := len(str) + return n > 1 && str[0] == '"' && str[n - 1] == '"'; +} + +func parseEscaped(snapish string) *Relative { + if isEscaped(snapish) { + snapshot := strings.Trim(snapish, `"`); + + if(snapshot == "") { + die.Fatal("Snapshot cannot be empty \"\"") + + } + + return &Relative { + snapshot: snapshot, + } + } + + return nil +} + +func parseRelativeSyntax(snapish, directionToken string) *Relative { + parts := strings.Split(snapish, directionToken) + n_parts := len(parts) + + if n_parts == 1 { + return nil; + } + + // Test if the last the last token is a numeric offset + if offset, err := strconv.Atoi(parts[n_parts - 1]); + err == nil { + + // Two tokens (e.g. ++ or --) indicates increment syntax + if n_parts > 2 && parts[n_parts - 2] == "" { + die.Fatal("A snapshot reference cannot be a mix of increment syntax (e.g. my_snap++) and literal syntax (e.g. my_snap+4).") + } + + snapshot := strings.TrimRight(snapish, directionToken + "0123456789") + + return &Relative { + offset: offset, + snapshot: snapshot, + } + } + + // Parse the increment / decrement syntax + // E.g. snapshot+++ or snapshot--- + offset := 0; + for i := n_parts - 1; i >= 1 && parts[i] == ""; i-- { + offset += 1 + } + + return &Relative { + offset: offset, + snapshot: snapish[:len(snapish) - offset], + } +} + +func ToRelative(snapish string) * Relative { + if ref := parseEscaped(snapish); ref != nil { + return ref; + } + + if ref := parseRelativeSyntax(snapish, "+"); ref != nil { + return ref; + } + + if ref := parseRelativeSyntax(snapish, "-"); ref != nil { + ref.offset = -ref.offset; + return ref; + } + + return &Relative{ + snapshot: snapish, + }; +}
\ No newline at end of file diff --git a/snap/parsing_test.go b/snap/parsing_test.go new file mode 100644 index 0000000..1a87723 --- /dev/null +++ b/snap/parsing_test.go @@ -0,0 +1,31 @@ +package snap + +import "testing" + +func TestRelativeParsing(t * testing.T) { + cases := []struct { + snapish string + snapshot string + offset int + } { + {"snapshot", "snapshot", 0}, + {"testing--", "testing", -2}, + {"%SNAPSHOT%^+++", "%SNAPSHOT%^", 3}, + {"--prefixed", "--prefixed", 0}, + {"+++", "", 3}, + {"---", "", -3}, + {"+5", "", 5}, + {"-3", "", -3}, + {"+", "", 1}, + {"-", "", -1}, + {`"-"`, "-", 0}, + } + + for _, c := range cases { + got := ToRelative(c.snapish) + + if got.offset != c.offset || got.snapshot != c.snapshot { + t.Errorf("ToRelative(%s) == %+v, wanted %+v", c.snapish, got, c) + } + } +}
\ No newline at end of file diff --git a/snap/snap.go b/snap/snap.go new file mode 100644 index 0000000..fde60c4 --- /dev/null +++ b/snap/snap.go @@ -0,0 +1,6 @@ +package snap + +type Relative struct { + snapshot string + offset int +}
\ No newline at end of file |