diff --git a/pkgs/racket-test-core/tests/racket/cmdline.rktl b/pkgs/racket-test-core/tests/racket/cmdline.rktl index 1780098b90..aaa763fb73 100644 --- a/pkgs/racket-test-core/tests/racket/cmdline.rktl +++ b/pkgs/racket-test-core/tests/racket/cmdline.rktl @@ -204,6 +204,16 @@ (syntax-test #'(command-line #:program "hello" #:argv #("ok") #:args 'done #:once-any [("-ok") a 7])) (syntax-test #'(command-line #:program "hello" #:argv #("ok") #:args (ok) 'done #:once-any [("-ok") a "the ok flag" 7])) +;; Make sure that `command-line` check flag syntax itself +(syntax-test #'(command-line #:once-any [("-1") "oops" (void)])) +(syntax-test #'(command-line #:once-any [("+5") "oops" (void)])) +(syntax-test #'(command-line #:once-any [("-") "oops" (void)])) +(syntax-test #'(command-line #:once-any [("++") "oops" (void)])) +(syntax-test #'(command-line #:once-any [("-+") "oops" (void)])) +(syntax-test #'(command-line #:once-any [("-xx") "oops" (void)])) +(syntax-test #'(command-line #:once-any [("-h") "oops" (void)])) +(syntax-test #'(command-line #:once-any [("--help") "oops" (void)])) + (err/rt-test (parse-command-line "test" #("x") null (lambda () 'too-few) '("arg"))) (err/rt-test (parse-command-line "test" #("x") null (lambda (x) 'still-too-few) '("arg"))) (err/rt-test (parse-command-line "test" #("x") null (lambda (x y z) 'too-many) '("arg"))) diff --git a/racket/collects/racket/cmdline.rkt b/racket/collects/racket/cmdline.rkt index 65ba375c25..e2686140aa 100644 --- a/racket/collects/racket/cmdline.rkt +++ b/racket/collects/racket/cmdline.rkt @@ -49,6 +49,13 @@ [(null? lst) null] [(keyword? (syntax-e (car lst))) lst] [else (at-next-keyword (cdr lst))])) + (define (check-ok-flag flag) + (unless (regexp-match? #rx"^([-+][^-+]$|(--|[+][+])[^-+])" (syntax-e flag)) + (serror "bad flag string" flag)) + (when (regexp-match? #rx"^[-+][0-9]$" (syntax-e flag)) + (serror "number flag not allowed" flag)) + (when (regexp-match? #rx"^(-h|--help)$" (syntax-e flag)) + (serror "pre-defined flag not allowed" flag))) (let ([lst (syntax->list stx)]) (unless lst (raise-syntax-error #f "bad syntax (misuse of `.')" stx)) @@ -99,17 +106,22 @@ ([flags (syntax-case (car sublines) () [((flag ...) . rest) - (begin + (let ([flags (syntax->list #'(flag ...))]) (unless (andmap (lambda (x) (string? (syntax-e x))) - (syntax->list #'(flag ...))) + flags) (serror - "flag specification is not a string or sequence of strings" - #'(flag ...))) + "flag specification is not a string or sequence of strings" + (syntax-case (car sublines) () + [(flags . rest) + #'flags]))) + (for-each check-ok-flag flags) #'(flag ...))] [(flag . rest) (string? (syntax-e #'flag)) - #'(flag)] + (begin + (check-ok-flag #'flag) + #'(flag))] [else (serror "clause does not start with flags")])]) (syntax-case* (car sublines) (=>) id=?