aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorflu0r1ne <flu0r1ne@flu0r1ne.net>2021-07-21 23:00:00 -0500
committerflu0r1ne <flu0r1ne@flu0r1ne.net>2021-07-21 23:00:00 -0500
commitfb8aee6c5147b8751a3920f613934d90b79ef4c5 (patch)
tree46dd389d9695b3c4f9f1e65962e76b383f703863
parenta10f10119f05320fb71574ad54b3161f5a37d371 (diff)
downloadzsu-fb8aee6c5147b8751a3920f613934d90b79ef4c5.tar.xz
zsu-fb8aee6c5147b8751a3920f613934d90b79ef4c5.zip
Added parser for +- syntax for relative references to snapshots
-rw-r--r--cmd/cat.go5
-rw-r--r--cmds/list.go21
-rw-r--r--snap/parsing.go89
-rw-r--r--snap/parsing_test.go31
-rw-r--r--snap/snap.go6
5 files changed, 130 insertions, 22 deletions
diff --git a/cmd/cat.go b/cmd/cat.go
index 99b48fb..4f54abc 100644
--- a/cmd/cat.go
+++ b/cmd/cat.go
@@ -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