]> Cypherpunks repositories - dsc.git/commitdiff
Ability to store binary data
authorSergey Matveev <stargrave@stargrave.org>
Sat, 4 Oct 2025 07:26:27 +0000 (10:26 +0300)
committerSergey Matveev <stargrave@stargrave.org>
Sat, 4 Oct 2025 07:26:27 +0000 (10:26 +0300)
dsc

diff --git a/dsc b/dsc
index e6b411abaf41e12dcf3c77ff020bf244117ec41b1cf17d0d1b48e01254dcbfd1..c89bfe4458a27befa774ec7d4e9ca7eac7aabe7471b01398ee6a129939b46cd0 100755 (executable)
--- a/dsc
+++ b/dsc
@@ -23,6 +23,7 @@ if {$argc == 0} {
     dsc has opt       -- check if specified /*/ option exists
     dsc set opt value -- set option's value
     dsc set opt ""    -- unset value, make it default one
+    dsc set opt <data -- set binary option's value
     dsc get opt       -- get option's value, maybe default one
     dsc get opt/*     -- list /*/ sections
     dsc diff [prefix] -- show the difference between saved and stash
@@ -67,11 +68,10 @@ proc fileread {fn} {
     return $v
 }
 
-proc find-checker {opt} {
+proc find-opt-schema {opt} {
     global Schema
     set path .
     set opt [string trimright $opt /]
-    set err "can not find checker for $opt"
     foreach e [split $opt /] {
         if {[file exists $Schema/$path/$e]} {
             set path $path/$e
@@ -81,20 +81,20 @@ proc find-checker {opt} {
             set path $path/*
             continue
         }
-        puts stderr $err
+        puts stderr "can not find $opt in schema"
         exit 1
     }
-    set path [string range $path 2 end]
-    if {! [file exists $Schema/$path/check]} {
-        puts stderr $err
-        exit 1
-    }
-    return $path
+    return [string range $path 2 end]
+}
+
+proc is-bin {opt} {
+    global Schema
+    return [file exists "$Schema/[find-opt-schema $opt]/bin"]
 }
 
 proc run-checker {opt v} {
     global Schema
-    set fh [open |[list "$Schema/[find-checker $opt]/check" $opt 2>@1] r+]
+    set fh [open |[list "$Schema/[find-opt-schema $opt]/check" $opt 2>@1] r+]
     puts $fh $v
     close $fh w
     set v [read $fh]
@@ -113,7 +113,7 @@ proc assure-exists {opt} {
     }
 }
 
-proc txtar-filename {line} {
+proc txtar-fn {line} {
     if {
         [string length $line] > 6 &&
         [string range $line 0 2] == "-- " &&
@@ -168,22 +168,32 @@ switch [lindex $argv 0] {
         file delete -force $Stash/$opt
     }
     set {
-        set v [lindex $argv 2]
-        if {$v == ""} {
-            file delete $Stash/$opt
-            exit
+        if {[llength $argv] > 2} {
+            set v [lindex $argv 2]
+            if {$v == ""} {
+                file delete $Stash/$opt
+                exit
+            }
         }
-        set v [run-checker $opt $v]
         file mkdir "$Stash/[file dirname $opt]"
-        set fh [open $Stash/$opt w]
-        puts -nonewline $fh $v
-        close $fh
+        if {[is-bin $opt]} {
+            set fh [open $Stash/$opt w]
+            fconfigure $fh -translation binary
+            fconfigure stdin -translation binary
+            fcopy stdin $fh
+            close $fh
+        } else {
+            set v [run-checker $opt $v]
+            set fh [open $Stash/$opt w]
+            puts -nonewline $fh $v
+            close $fh
+        }
     }
     has {
         assure-exists $opt
     }
     get-checker {
-        puts [find-checker $opt]
+        puts [find-opt-schema $opt]
     }
     get {
         if {[file tail $opt] == "*"} {
@@ -198,7 +208,15 @@ switch [lindex $argv 0] {
             exit
         }
         if {[file exists $Stash/$opt]} {
-            puts -nonewline [fileread $Stash/$opt]
+            if {[is-bin $opt]} {
+                set fh [open $Stash/$opt r]
+                fconfigure $fh -translation binary
+                fconfigure stdout -translation binary
+                fcopy $fh stdout
+                close $fh
+            } else {
+                puts -nonewline [fileread $Stash/$opt]
+            }
             exit
         }
         puts -nonewline [run-checker $opt ""]
@@ -264,54 +282,74 @@ switch [lindex $argv 0] {
         }
         foreach dir $dirs {
             foreach fn [walk $dir f] {
-                puts "-- [string range $fn [string length $Saved]+1 end] --"
-                set fh [open $fn]
-                while {[gets $fh line] >= 0} {
-                    if {[txtar-filename $line] != ""} {
-                        set line "-- $line --"
+                set sfn [string range $fn [string length $Saved]+1 end]
+                if {[is-bin $sfn]} {
+                    puts "-- $sfn:base64 --"
+                    set fh [open "|base64 $fn" r]
+                    fcopy $fh stdout
+                    close $fh
+                } else {
+                    puts "-- $sfn --"
+                    set fh [open $fn]
+                    while {[gets $fh line] >= 0} {
+                        if {[txtar-fn $line] != ""} {
+                            set line "-- $line --"
+                        }
+                        puts $line
                     }
-                    puts $line
+                    close $fh
                 }
-                close $fh
             }
         }
     }
     import {
-        set fn ""
-        set lines [list]
-        proc filewrite {fn v} {
-            global Stash
-            if {[llength $v] == 0} {
-                return
+        fconfigure stdin -translation binary
+        while {[gets stdin line] >= 0} {
+            set fn [txtar-fn $line]
+            if {$fn != ""} {
+                break
             }
-            if {$fn == ".dirs"} {
-                foreach dir $v {
-                    file mkdir $Stash/$dir
+        }
+        if {$fn == ".dirs"} {
+            while {[gets stdin line] >= 0} {
+                set fn [txtar-fn $line]
+                if {$fn == ""} {
+                    file mkdir $Stash/$fn
+                } else {
+                    break
                 }
-                return
             }
+        }
+        proc openfh {fn} {
+            set bin no
+            if {[string range $fn [expr {[string length $fn]-7}] end] == ":base64"} {
+                set bin yes
+                set fn [string range $fn 0 [expr {[string length $fn]-7-1}]]
+            }
+            global Stash
             file mkdir [file dirname $Stash/$fn]
-            set fh [open $Stash/$fn w]
-            puts $fh [join $v "\n"]
-            close $fh
+            if {$bin} {
+                set fh [open |[list base64 -d > $Stash/$fn] w]
+            } else {
+                set fh [open $Stash/$fn w]
+                fconfigure $fh -translation binary
+            }
+            return $fh
         }
+        set fh [openfh $fn]
         while {[gets stdin line] >= 0} {
-            set newFn [txtar-filename $line]
-            if {$newFn == ""} {
-                lappend lines $line
-            } elseif {[string range $newFn 0 2] == "-- "} {
-                lappend lines $newFn
+            set fn [txtar-fn $line]
+            if {$fn == ""} {
+                puts $fh $line
+            } elseif {[string range $fn 0 2] == "-- "} {
+                puts $fh $fn
             } else {
-                if {$fn != ""} {
-                    filewrite $fn $lines
-                    set lines [list]
-                }
-                set fn $newFn
+                close $fh
+                set fh [openfh $fn]
             }
         }
-        if {$fn != ""} {
-            filewrite $fn $lines
-        }
+        close $fh
+        exec sync
     }
     path {
         if {[file exists $Stash/$opt]} {