aboutsummaryrefslogtreecommitdiff
path: root/snap/parsing.go
diff options
context:
space:
mode:
Diffstat (limited to 'snap/parsing.go')
-rw-r--r--snap/parsing.go89
1 files changed, 89 insertions, 0 deletions
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