blob: d2dd9b50be73e4f280095e8a640d50c5962b79ca (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
|
;;;; -*- mode: Scheme; indent-tabs-mode: nil; fill-column: 80; -*-
;;;;
;;;; Copyright © 2018 Amirouche Boubekki <amirouche@hypermove.net>
;;;;
;;;; This program is free software: you can redistribute it and/or modify
;;;; it under the terms of the GNU General Public License as published by
;;;; the Free Software Foundation, either version 3 of the License, or
;;;; (at your option) any later version.
;;;;
;;;; This program is distributed in the hope that it will be useful,
;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;;;; GNU General Public License for more details.
;;;;
;;;; You should have received a copy of the GNU General Public License
;;;; along with this program. If not, see <http://www.gnu.org/licenses/>.
;;
;; Comment:
;;
;; Command line interface subcommands parsing
;;
(define-module (gnunet subcommand))
(use-modules ((srfi srfi-1)))
(define (path-display path)
(display " ")
(let loop ((path path))
(unless (null? path)
(display (car path))
(display " ")
(loop (cdr path))))
(display #\newline))
(define (%spec-help path)
(lambda (spec)
(if (procedure? (cadr spec))
(path-display (append path (list (car spec))))
(for-each (%spec-help (append path (list (car spec)))) (cdr spec)))))
(define (spec-help name spec)
"Display the usage message for this SPEC for the program named NAME"
(display "Usage:\n\n")
(for-each (%spec-help (list name)) spec))
(define (%lookup spec args)
(if (string=? (symbol->string (car spec)) (car args))
(values (cdr spec) (cdr args))
(values #f #f)))
(define (lookup spec args)
(let loop ((spec spec))
(if (null? spec)
(values #f #f)
(call-with-values (lambda () (%lookup (car spec) args))
(lambda (procedure-or-spec args)
(cond
((and (not procedure-or-spec) (not args))
(loop (cdr spec)))
((procedure? (car procedure-or-spec))
(values (car procedure-or-spec) args))
(else (lookup procedure-or-spec args))))))))
(define-public (subcommand name spec args)
"Execute the subcommand of SPEC based on ARGS for the command NAME"
(if (or (null? args) (equal? args '("--help")) (equal? args '("-h")))
(spec-help name spec)
(call-with-values (lambda () (lookup spec args))
(lambda (procedure args)
(cond
((and procedure args)
(procedure args))
(else (spec-help name spec)))))))
|