about summary refs log tree commit diff
path: root/pkgs/profpatsch/execline
diff options
context:
space:
mode:
authorProfpatsch <mail@profpatsch.de>2020-01-26 22:59:09 +0100
committerProfpatsch <mail@profpatsch.de>2020-01-26 22:59:09 +0100
commite8d7cb8c2c5feed0157cace50b3fc5bebe9755c4 (patch)
treec465f15e9111e3e7e9a4476ad21246c7610d3475 /pkgs/profpatsch/execline
parent905248dcb80e56903a0a8cbe13f8966a4b940330 (diff)
pkgs/profpatsch/execline: add runblock
Diffstat (limited to 'pkgs/profpatsch/execline')
-rw-r--r--pkgs/profpatsch/execline/runblock.nix69
1 files changed, 69 insertions, 0 deletions
diff --git a/pkgs/profpatsch/execline/runblock.nix b/pkgs/profpatsch/execline/runblock.nix
new file mode 100644
index 00000000..0b380229
--- /dev/null
+++ b/pkgs/profpatsch/execline/runblock.nix
@@ -0,0 +1,69 @@
+{ pkgs }:
+let
+
+  # This is a rewrite of execline’s runblock.
+  # It adds the feature that instead of just
+  # executing the block it reads, it can also
+  # pass it as argv to given commands.
+  #
+  # This is going to be added to a future version
+  # of execline by skarnet, but for now it’s easier
+  # to just dirtily reimplement it in Python.
+  runblock = pkgs.writers.writePython3 "runblock" {} ''
+    import sys
+    import os
+
+    skip = False
+    one = sys.argv[1]
+    if one == "-r":
+        skip = True
+        block_number = int(sys.argv[2])
+        block_start = 3
+    elif one.startswith("-"):
+        print("only -r supported", file=sys.stderr)
+        sys.exit(100)
+    else:
+        block_number = int(one)
+        block_start = 2
+
+    execline_argv_no = int(os.getenvb(b"#"))
+    runblock_argv = [os.getenv(str(no)) for no in range(1, execline_argv_no + 1)]
+
+
+    def parse_block(args):
+        new_args = []
+        for arg in args:
+            if arg == "":
+                break
+            elif arg.startswith(" "):
+                new_args.append(arg[1:])
+            else:
+                print(
+                  "unterminated block: {}".format(args),
+                  file=sys.stderr
+                )
+                sys.exit(100)
+        args_rest = args[len(new_args)+1:]
+        return (new_args, args_rest)
+
+
+    if skip:
+        rest = runblock_argv
+        for _ in range(0, block_number-1):
+            (_, rest) = parse_block(rest)
+        new_argv = rest
+    else:
+        new_argv = []
+        rest = runblock_argv
+        for _ in range(0, block_number):
+            (new_argv, rest) = parse_block(rest)
+
+    given_argv = sys.argv[block_start:]
+    run = given_argv + new_argv
+    os.execvp(
+        file=run[0],
+        args=run
+    )
+  '';
+
+in { inherit runblock; }