summaryrefslogtreecommitdiff
path: root/module/system/base/message.scm
blob: 6b68c5639b57e038b0992f8d6fe1691186f83130 (plain)
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
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
;;; User interface messages

;; Copyright (C) 2009 Free Software Foundation, Inc.

;;; This library is free software; you can redistribute it and/or
;;; modify it under the terms of the GNU Lesser General Public
;;; License as published by the Free Software Foundation; either
;;; version 3 of the License, or (at your option) any later version.
;;;
;;; This library 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
;;; Lesser General Public License for more details.
;;;
;;; You should have received a copy of the GNU Lesser General Public
;;; License along with this library; if not, write to the Free Software
;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA

;;; Commentary:
;;;
;;; This module provide a simple interface to send messages to the user.
;;; TODO: Internationalize messages.
;;;
;;; Code:

(define-module (system base message)
  #:use-module (srfi srfi-1)
  #:use-module (srfi srfi-9)
  #:export (*current-warning-port* warning

            warning-type? warning-type-name warning-type-description
            warning-type-printer lookup-warning-type

            %warning-types))


;;;
;;; Source location
;;;

(define (location-string loc)
  (if (pair? loc)
      (format #f "~a:~a:~a"
              (or (assoc-ref loc 'filename) "<stdin>")
              (1+ (assoc-ref loc 'line))
              (assoc-ref loc 'column))
      "<unknown-location>"))


;;;
;;; Warnings
;;;

(define *current-warning-port*
  ;; The port where warnings are sent.
  (make-fluid))

(fluid-set! *current-warning-port* (current-error-port))

(define-record-type <warning-type>
  (make-warning-type name description printer)
  warning-type?
  (name         warning-type-name)
  (description  warning-type-description)
  (printer      warning-type-printer))

(define %warning-types
  ;; List of know warning types.
  (map (lambda (args)
         (apply make-warning-type args))

       `((unsupported-warning ;; a "meta warning"
          "warn about unknown warning types"
          ,(lambda (port unused name)
             (format port "warning: unknown warning type `~A'~%"
                     name)))

         (unused-variable
          "report unused variables"
          ,(lambda (port loc name)
             (format port "~A: warning: unused variable `~A'~%"
                     loc name))))))

(define (lookup-warning-type name)
  "Return the warning type NAME or `#f' if not found."
  (find (lambda (wt)
          (eq? name (warning-type-name wt)))
        %warning-types))

(define (warning type location . args)
  "Emit a warning of type TYPE for source location LOCATION (a source
property alist) using the data in ARGS."
  (let ((wt   (lookup-warning-type type))
        (port (fluid-ref *current-warning-port*)))
    (if (warning-type? wt)
        (apply (warning-type-printer wt)
               port (location-string location)
               args)
        (format port "~A: unknown warning type `~A': ~A~%"
                (location-string location) type args))))

;;; message.scm ends here