Project

General

Profile

Download (8.33 KB) Statistics
| Branch: | Tag: | Revision:
1
(* This file is part of the Kind 2 model checker.
2

    
3
   Copyright (c) 2015 by the Board of Trustees of the University of Iowa
4

    
5
   Licensed under the Apache License, Version 2.0 (the "License"); you
6
   may not use this file except in compliance with the License.  You
7
   may obtain a copy of the License at
8

    
9
   http://www.apache.org/licenses/LICENSE-2.0 
10

    
11
   Unless required by applicable law or agreed to in writing, software
12
   distributed under the License is distributed on an "AS IS" BASIS,
13
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
14
   implied. See the License for the specific language governing
15
   permissions and limitations under the License. 
16

    
17
*)
18

    
19
open KindPretty
20
open KindLib
21

    
22

    
23
(* Signature of module for reuse in Event *)
24
module type Sig = sig
25
  type 'a log_printer =
26
    KindLib.log_level ->
27
    ('a, Format.formatter, unit, unit, unit, unit) format6 -> 'a
28
  type 'a m_log_printer =
29
    KindLib.kind_module -> 'a log_printer
30
  val set_module : KindLib.kind_module -> unit 
31
  val get_module : unit -> KindLib.kind_module
32
  type log_format = | F_pt | F_xml | F_json | F_relay
33
  val get_log_format : unit -> log_format
34
  val set_log_format : log_format -> unit
35
  val set_log_format_pt : unit -> unit
36
  val set_log_format_xml : unit -> unit
37
  val set_log_format_json : unit -> unit
38
  val set_relay_log : unit -> unit
39
  val unset_relay_log : unit -> unit
40
  val pp_print_kind_module_xml_src : Format.formatter -> KindLib.kind_module -> unit
41
  val print_xml_trailer : unit -> unit
42
  val printf_xml : 'a m_log_printer
43
  val printf_json : 'a m_log_printer
44
  val parse_log_xml : KindLib.log_level -> KindLib.position -> string -> unit
45
  val parse_log_json : KindLib.log_level -> KindLib.position -> string -> unit
46
end
47

    
48

    
49

    
50
(* ********************************************************************** *)
51
(* Initialization for the messaging system                                *)
52
(* ********************************************************************** *)
53

    
54
type 'a log_printer =
55
  KindLib.log_level ->
56
  ('a, Format.formatter, unit, unit, unit, unit) format6 -> 'a
57

    
58
type 'a m_log_printer =
59
  KindLib.kind_module -> 'a log_printer
60

    
61
(* Module currently running *)
62
let this_module = ref `Parser
63

    
64
(* Set module currently running *)
65
let set_module mdl = this_module := mdl 
66

    
67
(* Get module currently running *)
68
let get_module () = !this_module
69

    
70

    
71
(* ********************************************************************** *)
72
(* State of the logger                                                    *)
73
(* ********************************************************************** *)
74

    
75

    
76
(* Log formats *)
77
type log_format = 
78
  | F_pt
79
  | F_xml
80
  | F_json
81
  | F_relay
82

    
83

    
84
(* Current log format *)
85
let log_format = ref F_pt
86
let prev_log_format = ref !log_format
87

    
88
let get_log_format () = !log_format
89
let set_log_format l = log_format := l
90

    
91

    
92

    
93

    
94
(* ********************************************************************** *)
95
(* Plain text output                                                      *)
96
(* ********************************************************************** *)
97

    
98

    
99
(* Pretty-print kind module for plain text output *)
100
let pp_print_kind_module_pt =
101
  pp_print_kind_module
102

    
103

    
104
(* Output message as plain text *)
105
let printf_pt mdl level fmt =
106
  (ignore_or_fprintf level)
107
    !log_ppf ("%a @[<hov>" ^^ fmt ^^ "@]@.@.") tag_of_level level
108

    
109

    
110
(* Unconditional printing as plain text. *)
111
let printf_pt_uncond mdl fmt =
112
  Format.fprintf !log_ppf ("@[<hov>" ^^ fmt ^^ "@]@.@.")
113

    
114

    
115

    
116
(* ********************************************************************** *)
117
(* XML output                                                             *)
118
(* ********************************************************************** *)
119

    
120
(* Level to class attribute of log tag *)
121
let xml_cls_of_level = string_of_log_level
122

    
123
(* XML at the beginning the output *)
124
let print_xml_header () =
125
  Format.fprintf !log_ppf "<?xml version=\"1.0\"?>@."
126

    
127

    
128
(* Pretty-print level as class attribute of log tag *)
129
let pp_print_level_xml_cls ppf l = 
130
  Format.fprintf ppf "%s" (xml_cls_of_level l)
131

    
132
(* Kind module as source attribute of log tag *)
133
let xml_src_of_kind_module = short_name_of_kind_module
134

    
135
(* Pretty-print kind module as source attribute of log tag *)
136
let pp_print_kind_module_xml_src ppf m = 
137
  Format.fprintf ppf "%s" (xml_src_of_kind_module m)
138

    
139

    
140
(* XML at the end of the output *)
141
let print_xml_trailer () = 
142
  Format.fprintf !log_ppf "@.@.</Results>@."
143

    
144

    
145
(* Output message as XML *)
146
let printf_xml mdl level fmt = 
147

    
148
  (ignore_or_fprintf level)
149
    !log_ppf 
150
    ("@[<hv 2><Log class=\"%a\" source=\"%a\">@,@[<hov>" ^^ 
151
     fmt ^^ 
152
     "@]@;<0 -2></Log>@]@.") 
153
    pp_print_level_xml_cls level
154
    pp_print_kind_module_xml_src mdl
155

    
156

    
157
let parse_log_xml level pos msg =
158
  let pp_print_fname ppf fname =
159
    if fname = "" then () else
160
    Format.fprintf ppf " file=\"%s\"" fname
161
  in
162
  let file, lnum, cnum = file_row_col_of_pos pos in
163
  (ignore_or_fprintf level)
164
    !log_ppf
165
    "@[<hv 2><Log class=\"%a\" source=\"parse\" line=\"%d\" column=\"%d\"%a>\
166
    @,@[<hov>%s@]@;<0 -2></Log>@]@."
167
    pp_print_level_xml_cls level lnum cnum pp_print_fname file msg
168

    
169

    
170
(* ********************************************************************** *)
171
(* JSON output                                                            *)
172
(* ********************************************************************** *)
173

    
174
let escape_json_string s =
175
  let backslash = Str.regexp "\\" in
176
  let double_quotes = Str.regexp "\"" in
177
  let newline = Str.regexp "\n" in
178
  s |> Str.global_replace backslash "\\\\"
179
    |> Str.global_replace double_quotes "\\\""
180
    |> Str.global_replace newline "\\n"
181

    
182
(* Output message as JSON *)
183
let printf_json mdl level fmt =
184

    
185
  (ignore_or_fprintf level)
186
    !log_ppf
187
    (",@.{@[<v 1>@," ^^
188
      "\"objectType\" : \"log\",@," ^^
189
      "\"level\" : \"%s\",@," ^^
190
      "\"source\" : \"%s\",@," ^^
191
      "\"value\" : \"" ^^ fmt ^^ "\"" ^^
192
      "@]@.}@.")
193
    (string_of_log_level level)
194
    (short_name_of_kind_module mdl)
195

    
196
let parse_log_json level pos msg =
197
  let pp_print_fname ppf fname =
198
    if fname = "" then () else
199
    Format.fprintf ppf "\"file\" : \"%s\",@," fname
200
  in
201
  let file, lnum, cnum = file_row_col_of_pos pos in
202
  (ignore_or_fprintf level)
203
    !log_ppf
204
    ",@.{@[<v 1>@,\
205
     \"objectType\" : \"log\",@,\
206
     \"level\" : \"%s\",@,\
207
     \"source\" : \"parse\",@,\
208
     %a\
209
     \"line\" : %d,@,\
210
     \"column\" : %d,@,\
211
     \"value\" : \"%s\"\
212
     @]@.}@.\
213
    "
214
    (string_of_log_level level)
215
    pp_print_fname file
216
    lnum cnum msg
217

    
218

    
219
(*****************************************************************)
220
(* Setup                                                         *)
221
(*****************************************************************)
222
  
223
(* Set log format to plain text *)
224
let set_log_format_pt () = log_format := F_pt
225

    
226
(* Set log format to XML *)
227
let set_log_format_xml () = 
228
  log_format := F_xml;
229
  (* Print XML header *)
230
  print_xml_header ()
231

    
232
(* Set log format to JSON *)
233
let set_log_format_json () = log_format := F_json
234

    
235
(* Relay log messages to invariant manager *)
236
let set_relay_log () =
237
  prev_log_format := !log_format;
238
  log_format := F_relay
239

    
240

    
241
let unset_relay_log () = log_format := !prev_log_format
242

    
243

    
244
module type SLog = sig
245
  val log : 'a log_printer
246
  val log_uncond : ('a, Format.formatter, unit) format -> 'a
247
end
248

    
249
module Make (R : sig val printf_relay : 'a m_log_printer end) : SLog = struct
250

    
251
  (* ********************************************************************** *)
252
  (* Generic logging functions                                              *)
253
  (* ********************************************************************** *)
254

    
255
  (* Log a message with source and log level *)
256
  let log level fmt =
257

    
258
    let mdl = get_module () in
259

    
260
    match !log_format with 
261
    | F_pt -> printf_pt mdl level fmt
262
    | F_xml -> printf_xml mdl level fmt
263
    | F_json -> printf_json mdl level fmt
264
    | F_relay -> R.printf_relay mdl level fmt
265

    
266

    
267
  (* Unconditionally logs a message. *)
268
  let log_uncond fmt =
269

    
270
    let mdl = get_module () in
271

    
272
    match !log_format with 
273
    | F_pt -> printf_pt_uncond mdl fmt
274
    | F_xml -> printf_xml mdl L_info fmt
275
    | F_json -> printf_json mdl L_info fmt
276
    | F_relay -> R.printf_relay mdl L_info fmt
277
                   
278
end
279

    
280

    
281
include Make (struct let printf_relay _ _ _ = failwith "Uninitialized" end)
282

    
283

    
284
(* 
285
   Local Variables:
286
   compile-command: "make -C .. -k"
287
   tuareg-interactive-program: "./kind2.top -I ./_build -I ./_build/SExpr"
288
   indent-tabs-mode: nil
289
   End: 
290
*)
(5-5/12)