(module find-acl2 mzscheme
(require (lib "framework.ss" "framework")
(lib "mred.ss" "mred")
(lib "process.ss")
(lib "etc.ss")
(lib "port.ss"))
(require "acl2-path-to-lisp-command.ss")
(require "acl2-location-pref.ss")
(provide find-acl2)
(define find-acl2
(opt-lambda ([path (get-acl2-location)])
(if (valid-path? path)
path
(let ([supplied-path
(finder:get-file #f "Select ACL2 Executable" (byte-regexp #".*acl2.*")
"The file must contain `acl2' in the name.")])
(and (path? supplied-path)
(if (valid-path? supplied-path)
(begin (preferences:set *acl2-loc-key* supplied-path)
supplied-path)
(begin (message-box
"That is not ACL2"
(format
"The supplied executable ~s does not appear to be ACL2."
supplied-path)
#f
'(ok))
#f)))))))
(define (valid-path? path)
(with-handlers ([exn:fail:read? (lambda (e) #f)])
(let ([path (cond [(string? path) (string->path path)]
[(path? path) path]
[else #f])])
(and (path? path)
(file-exists? path)
(let-values ([(proc->me me->proc pid err->me control)
(apply values
(apply process*
(acl2-path->command-list path)))])
(let* ([evt (regexp-match-evt #"ACL2" proc->me)]
[running? (eq? (control 'status) 'running)]
[is-acl2? (and running? (sync/timeout/enable-break 5 evt) #t)])
(when is-acl2? (write-string ":q (good-bye)" me->proc)
(newline me->proc)
(flush-output me->proc))
(control 'kill)
(close-input-port proc->me)
(close-input-port err->me)
(close-output-port me->proc)
is-acl2?))))))
)