Merge branch 'stable-2.0'
[bpt/guile.git] / module / scripts / compile.scm
index f0294b5..5b644c3 100644 (file)
@@ -1,21 +1,21 @@
-;;; Compile --- Command-line Guile Scheme compiler
+;;; Compile --- Command-line Guile Scheme compiler  -*- coding: iso-8859-1 -*-
 
-;; Copyright 2005,2008,2009 Free Software Foundation, Inc.
+;; Copyright 2005, 2008-2011, 2013, 2014 Free Software Foundation, Inc.
 ;;
 ;; 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 2, or
+;; modify it under the terms of the GNU Lesser General Public License
+;; as published by the Free Software Foundation; either version 3, 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.
+;; Lesser General Public License for more details.
 ;;
-;; You should have received a copy of the GNU General Public License
-;; along with this software; see the file COPYING.  If not, write to
-;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
-;; Boston, MA 02110-1301 USA
+;; You should have received a copy of the GNU Lesser General Public
+;; License along with this software; see the file COPYING.LESSER.  If
+;; not, write to the Free Software Foundation, Inc., 51 Franklin
+;; Street, Fifth Floor, Boston, MA 02110-1301 USA
 
 ;;; Author: Ludovic Courtès <ludo@gnu.org>
 ;;; Author: Andy Wingo <wingo@pobox.com>
 
 (define-module (scripts compile)
   #:use-module ((system base compile) #:select (compile-file))
+  #:use-module (system base target)
+  #:use-module (system base message)
   #:use-module (srfi srfi-1)
   #:use-module (srfi srfi-13)
   #:use-module (srfi srfi-37)
+  #:use-module (ice-9 format)
   #:export (compile))
 
+(define %summary "Compile a file.")
+
 \f
 (define (fail . messages)
-  (format (current-error-port)
-         (string-concatenate `("error: " ,@messages "~%")))
+  (format (current-error-port) "error: ~{~a~}~%" messages)
   (exit 1))
 
 (define %options
   (list (option '(#\h "help") #f #f
                 (lambda (opt name arg result)
                  (alist-cons 'help? #t result)))
+        (option '("version") #f #f
+                (lambda (opt name arg result)
+                  (show-version)
+                  (exit 0)))
 
        (option '(#\L "load-path") #t #f
                (lambda (opt name arg result)
                      (fail "`-o' option cannot be specified more than once")
                      (alist-cons 'output-file arg result))))
 
+        (option '(#\W "warn") #t #f
+                (lambda (opt name arg result)
+                  (if (string=? arg "help")
+                      (begin
+                        (show-warning-help)
+                        (exit 0))
+                      (let ((warnings (assoc-ref result 'warnings)))
+                        (alist-cons 'warnings
+                                    (cons (string->symbol arg) warnings)
+                                    (alist-delete 'warnings result))))))
+
        (option '(#\O "optimize") #f #f
                (lambda (opt name arg result)
                  (alist-cons 'optimize? #t result)))
                (lambda (opt name arg result)
                   (if (assoc-ref result 'to)
                       (fail "`--to' option cannot be specified more than once")
-                      (alist-cons 'to (string->symbol arg) result))))))
+                      (alist-cons 'to (string->symbol arg) result))))
+        (option '(#\T "target") #t #f
+                (lambda (opt name arg result)
+                  (if (assoc-ref result 'target)
+                      (fail "`--target' option cannot be specified more than once")
+                      (alist-cons 'target arg result))))))
 
 (define (parse-args args)
   "Parse argument list @var{args} and return an alist with all the relevant
 options."
   (args-fold args %options
              (lambda (opt name arg result)
-               (format (current-error-port) "~A: unrecognized option" opt)
+               (format (current-error-port) "~A: unrecognized option" name)
               (exit 1))
              (lambda (file result)
               (let ((input-files (assoc-ref result 'input-files)))
@@ -86,15 +110,37 @@ options."
 
             ;; default option values
              '((input-files)
-              (load-path))))
+              (load-path)
+               (warnings unsupported-warning))))
+
+(define (show-version)
+  (format #t "compile (GNU Guile) ~A~%" (version))
+  (format #t "Copyright (C) 2009, 2011 Free Software Foundation, Inc.
+License LGPLv3+: GNU LGPL version 3 or later <http://gnu.org/licenses/lgpl.html>.
+This is free software: you are free to change and redistribute it.
+There is NO WARRANTY, to the extent permitted by law.~%"))
+
+(define (show-warning-help)
+  (format #t "The available warning types are:~%~%")
+  (for-each (lambda (wt)
+              (format #t "  ~22A ~A~%"
+                      (format #f "`~A'" (warning-type-name wt))
+                      (warning-type-description wt)))
+            %warning-types)
+  (format #t "~%"))
 
 \f
 (define (compile . args)
   (let* ((options         (parse-args args))
          (help?           (assoc-ref options 'help?))
-         (compile-opts    (if (assoc-ref options 'optimize?) '(#:O) '()))
+         (compile-opts    (let ((o `(#:warnings
+                                     ,(assoc-ref options 'warnings))))
+                            (if (assoc-ref options 'optimize?)
+                                (cons #:O o)
+                                o)))
          (from            (or (assoc-ref options 'from) 'scheme))
-         (to              (or (assoc-ref options 'to) 'objcode))
+         (to              (or (assoc-ref options 'to) 'bytecode))
+         (target          (or (assoc-ref options 'target) %host-type))
         (input-files     (assoc-ref options 'input-files))
         (output-file     (assoc-ref options 'output-file))
         (load-path       (assoc-ref options 'load-path)))
@@ -108,13 +154,21 @@ Compile each Guile source file FILE into a Guile object.
   -L, --load-path=DIR  add DIR to the front of the module load path
   -o, --output=OFILE   write output to OFILE
 
+  -W, --warn=WARNING   emit warnings of type WARNING; use `--warn=help'
+                       for a list of available warnings
+
   -f, --from=LANG      specify a source language other than `scheme'
-  -t, --to=LANG        specify a target language other than `objcode'
+  -t, --to=LANG        specify a target language other than `bytecode'
+  -T, --target=TRIPLET produce bytecode for host TRIPLET
+
+Note that auto-compilation will be turned off.
 
-Report bugs to <guile-user@gnu.org>.~%")
+Report bugs to <~A>.~%"
+                  %guile-bug-report-address)
           (exit 0)))
 
     (set! %load-path (append load-path %load-path))
+    (set! %load-should-auto-compile #f)
 
     (if (and output-file
              (or (null? input-files)
@@ -122,17 +176,24 @@ Report bugs to <guile-user@gnu.org>.~%")
         (fail "`-o' option can only be specified "
               "when compiling a single file"))
 
+    ;; Install a SIGINT handler.  As a side effect, this gives unwind
+    ;; handlers an opportunity to run upon SIGINT; this includes that of
+    ;; 'call-with-output-file/atomic', called by 'compile-file', which
+    ;; removes the temporary output file.
+    (sigaction SIGINT
+      (lambda args
+        (fail "interrupted by the user")))
+
     (for-each (lambda (file)
                 (format #t "wrote `~A'\n"
-                        (compile-file file
-                                      #:output-file output-file
-                                      #:from from
-                                      #:to to
-                                      #:opts compile-opts)))
+                        (with-fluids ((*current-warning-prefix* ""))
+                          (with-target target
+                            (lambda ()
+                              (compile-file file
+                                            #:output-file output-file
+                                            #:from from
+                                            #:to to
+                                            #:opts compile-opts))))))
               input-files)))
 
 (define main compile)
-
-;;; Local Variables:
-;;; coding: latin-1
-;;; End: