Skip to content

Commit 3bb478a

Browse files
committed
Include SRFI 215.
1 parent f1505d2 commit 3bb478a

File tree

3 files changed

+164
-0
lines changed

3 files changed

+164
-0
lines changed

LispKit.xcodeproj/project.pbxproj

+8
Original file line numberDiff line numberDiff line change
@@ -363,6 +363,9 @@
363363
CC8A2AAF1F405E2500D1E4D8 /* 17.sld in Copy pre-installed SRFI libraries */ = {isa = PBXBuildFile; fileRef = CC8A2AAE1F405CDD00D1E4D8 /* 17.sld */; };
364364
CC8A2AB11F40681500D1E4D8 /* 48.sld in Copy pre-installed SRFI libraries */ = {isa = PBXBuildFile; fileRef = CC8A2AB01F40672700D1E4D8 /* 48.sld */; };
365365
CC8BBA2A26BF3B1A00552B8F /* text-table.sld in Copy pre-installed LispKit libraries */ = {isa = PBXBuildFile; fileRef = CC8BBA2926BF38F200552B8F /* text-table.sld */; };
366+
CC8BBA2C26BF532D00552B8F /* 215.sld in Copy pre-installed SRFI libraries */ = {isa = PBXBuildFile; fileRef = CC8BBA2B26BF527900552B8F /* 215.sld */; };
367+
CC8BBA2D26BF534E00552B8F /* 215.sld in Copy pre-installed SRFI libraries */ = {isa = PBXBuildFile; fileRef = CC8BBA2B26BF527900552B8F /* 215.sld */; };
368+
CC8BBA2E26BF53AF00552B8F /* text-table.sld in Copy pre-installed LispKit libraries */ = {isa = PBXBuildFile; fileRef = CC8BBA2926BF38F200552B8F /* text-table.sld */; };
366369
CC8C6EC81CFA65F200126BDD /* ControlFlow.scm in Resources */ = {isa = PBXBuildFile; fileRef = CC8C6EC71CFA65F200126BDD /* ControlFlow.scm */; };
367370
CC8D20F52533C3D100741D07 /* DrawTrees.scm in Copy examples */ = {isa = PBXBuildFile; fileRef = CC8D20F42533C35F00741D07 /* DrawTrees.scm */; };
368371
CC8E65FC23FCAC3A00D9D1F9 /* 6.sld in Copy pre-installed SRFI libraries */ = {isa = PBXBuildFile; fileRef = CC8E65FA23FCA98600D9D1F9 /* 6.sld */; };
@@ -1442,6 +1445,7 @@
14421445
dstPath = Root/LispKit/Libraries/srfi;
14431446
dstSubfolderSpec = 7;
14441447
files = (
1448+
CC8BBA2C26BF532D00552B8F /* 215.sld in Copy pre-installed SRFI libraries */,
14451449
CC1DDB6A26AA34E40049E99D /* 216.sld in Copy pre-installed SRFI libraries */,
14461450
CC1DDB6526A9BB200049E99D /* 222.sld in Copy pre-installed SRFI libraries */,
14471451
CC0E57C4268FAAC100693DD2 /* 223.sld in Copy pre-installed SRFI libraries */,
@@ -1537,6 +1541,7 @@
15371541
dstPath = Root/LispKit/Libraries/srfi;
15381542
dstSubfolderSpec = 7;
15391543
files = (
1544+
CC8BBA2D26BF534E00552B8F /* 215.sld in Copy pre-installed SRFI libraries */,
15401545
CC1DDB6B26AA35000049E99D /* 216.sld in Copy pre-installed SRFI libraries */,
15411546
CC1DDB6726A9BB5B0049E99D /* 222.sld in Copy pre-installed SRFI libraries */,
15421547
CC0E57C6268FAAE800693DD2 /* 223.sld in Copy pre-installed SRFI libraries */,
@@ -1690,6 +1695,7 @@
16901695
dstPath = Root/LispKit/Libraries/lispkit;
16911696
dstSubfolderSpec = 7;
16921697
files = (
1698+
CC8BBA2E26BF53AF00552B8F /* text-table.sld in Copy pre-installed LispKit libraries */,
16931699
CCC48D8D25E9806600D082AD /* log.sld in Copy pre-installed LispKit libraries */,
16941700
CCC48D8E25E9806600D082AD /* test.sld in Copy pre-installed LispKit libraries */,
16951701
CCC48D8F25E9806600D082AD /* match.sld in Copy pre-installed LispKit libraries */,
@@ -2428,6 +2434,7 @@
24282434
CC8A2AAE1F405CDD00D1E4D8 /* 17.sld */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = 17.sld; sourceTree = "<group>"; };
24292435
CC8A2AB01F40672700D1E4D8 /* 48.sld */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = 48.sld; sourceTree = "<group>"; };
24302436
CC8BBA2926BF38F200552B8F /* text-table.sld */ = {isa = PBXFileReference; lastKnownFileType = text; path = "text-table.sld"; sourceTree = "<group>"; };
2437+
CC8BBA2B26BF527900552B8F /* 215.sld */ = {isa = PBXFileReference; lastKnownFileType = text; path = 215.sld; sourceTree = "<group>"; };
24312438
CC8C6EC71CFA65F200126BDD /* ControlFlow.scm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = ControlFlow.scm; sourceTree = "<group>"; };
24322439
CC8D20F42533C35F00741D07 /* DrawTrees.scm */ = {isa = PBXFileReference; lastKnownFileType = text; path = DrawTrees.scm; sourceTree = "<group>"; };
24332440
CC8DC5C623E7408500396182 /* Makefile */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.make; path = Makefile; sourceTree = "<group>"; };
@@ -3006,6 +3013,7 @@
30063013
CC1D6CBD258CDE3700D36645 /* 209.sld */,
30073014
CC0D7B382544AF2600FB9301 /* 210.sld */,
30083015
CCD5E559262E31AE00C45EA0 /* 214.sld */,
3016+
CC8BBA2B26BF527900552B8F /* 215.sld */,
30093017
CC1DDB6926AA34780049E99D /* 216.sld */,
30103018
CC879885264D4739006950A7 /* 219.sld */,
30113019
CC0E57BC268BB7C900693DD2 /* 221.sld */,

README.md

+3
Original file line numberDiff line numberDiff line change
@@ -203,8 +203,11 @@ framework:
203203
- [SRFI 209: Enums and Enum Sets](https://srfi.schemers.org/srfi-209/srfi-209.html)
204204
- [SRFI 210: Procedures and Syntax for Multiple Values](https://srfi.schemers.org/srfi-210/srfi-210.html)
205205
- [SRFI 214: Flexvectors](https://srfi.schemers.org/srfi-214/srfi-214.html)
206+
- [SRFI 215: Central Log Exchange](https://srfi.schemers.org/srfi-215/srfi-215.html)
207+
- [SRFI 216: SICP Prerequisites](https://srfi.schemers.org/srfi-216/srfi-216.html)
206208
- [SRFI 219: Define higher-order lambda](https://srfi.schemers.org/srfi-219/srfi-219.html)
207209
- [SRFI 221: Generator/accumulator sub-library](https://srfi.schemers.org/srfi-221/srfi-221.html)
210+
- [SRFI 222: Compound Objects](https://srfi.schemers.org/srfi-222/srfi-222.html)
208211
- [SRFI 223: Generalized binary search procedures](https://srfi.schemers.org/srfi-223/srfi-223.html)
209212

210213

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
;;; SRFI 215
2+
;;; Central Log Exchange
3+
;;;
4+
;;; This SRFI specifies a central log exchange for Scheme that connects log producers
5+
;;; with log consumers. It allows multiple logging systems to interoperate and co-exist
6+
;;; in the same program. Library code can produce log messages without knowledge of
7+
;;; which log system is actually used. Simple applications can easily get logs on
8+
;;; standard output, while more advanced applications can send them to a full
9+
;;; logging system.
10+
;;;
11+
;;; Copyright © 2020 Göran Weinholt. All rights reserved.
12+
;;;
13+
;;; Permission is hereby granted, free of charge, to any person obtaining a copy of this
14+
;;; software and associated documentation files (the "Software"), to deal in the Software
15+
;;; without restriction, including without limitation the rights to use, copy, modify, merge,
16+
;;; publish, distribute, sublicense, and/or sell copies of the Software, and to permit
17+
;;; persons to whom the Software is furnished to do so, subject to the following conditions:
18+
;;;
19+
;;; The above copyright notice and this permission notice shall be included in all copies or
20+
;;; substantial portions of the Software.
21+
;;;
22+
;;; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
23+
;;; INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
24+
;;; PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
25+
;;; FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
26+
;;; OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
27+
;;; DEALINGS IN THE SOFTWARE.
28+
;;;
29+
;;; Adaptation to LispKit
30+
;;; Copyright © 2021 Matthias Zenger. All rights reserved.
31+
32+
(define-library (srfi 215)
33+
34+
(export send-log
35+
current-log-fields
36+
current-log-callback
37+
EMERGENCY
38+
ALERT
39+
CRITICAL
40+
ERROR
41+
WARNING
42+
NOTICE
43+
INFO
44+
DEBUG)
45+
46+
(import (lispkit base))
47+
48+
(begin
49+
50+
;; This queue code is based on public domain code from SLIB,
51+
;; originally written by Andrew Wilcox in 1992. Here it has been
52+
;; reduced in size and rewritten to use mutable pairs.
53+
54+
(define (make-queue)
55+
(mcons '() '()))
56+
57+
(define (enqueue! q datum)
58+
(let ((new-pair (mcons datum '())))
59+
(if (null? (mcar q))
60+
(set-mcar! q new-pair)
61+
(set-mcdr! (mcdr q) new-pair))
62+
(set-mcdr! q new-pair)))
63+
64+
(define (dequeue! q)
65+
(let ((first-pair (mcar q)))
66+
(if (null? first-pair)
67+
(error "attempt to dequeue an empty queue"))
68+
(let ((first-cdr (mcdr first-pair)))
69+
(set-mcar! q first-cdr)
70+
(when (null? first-cdr)
71+
(set-mcdr! q '()))
72+
(mcar first-pair))))
73+
74+
(define (queue-empty? q)
75+
(null? (mcar q)))
76+
77+
;; These severities are from RFC 5424 ("The Syslog Protocol").
78+
(define EMERGENCY 0) ; system is unusable
79+
(define ALERT 1) ; action must be taken immediately
80+
(define CRITICAL 2) ; critical conditions
81+
(define ERROR 3) ; error conditions
82+
(define WARNING 4) ; warning conditions
83+
(define NOTICE 5) ; normal but significant condition
84+
(define INFO 6) ; informational messages
85+
(define DEBUG 7) ; debug-level messages
86+
87+
(define (field-list->alist plist)
88+
(let f ((fields plist))
89+
(cond ((null? fields)
90+
'())
91+
((or (not (pair? fields)) (not (pair? (cdr fields))))
92+
(error "short field list" plist))
93+
(else
94+
(let ((k (car fields)) (v (cadr fields)))
95+
(if (not v)
96+
(f (cddr fields))
97+
(let ((k^ (cond ((symbol? k) k)
98+
(else
99+
(error "invalid key" k plist))))
100+
(v^ (cond ((string? v) v)
101+
((and (integer? v) (exact? v)) v)
102+
((bytevector? v) v)
103+
;; ((condition?) v) ;R6RS
104+
((error-object? v) v) ;R7RS
105+
(else
106+
(let ((p (open-output-string)))
107+
(write v p)
108+
(get-output-string p))))))
109+
(cons (cons k^ v^)
110+
(f (cddr fields))))))))))
111+
112+
(define current-log-fields
113+
(make-parameter '()
114+
(lambda (plist)
115+
(field-list->alist plist)
116+
plist)))
117+
118+
(define current-log-callback
119+
(let ((num-pending-logs 0)
120+
(pending-logs (make-queue)))
121+
(make-parameter (lambda (log-entry)
122+
(enqueue! pending-logs log-entry)
123+
(if (eqv? num-pending-logs 100)
124+
(dequeue! pending-logs)
125+
(set! num-pending-logs (+ num-pending-logs 1))))
126+
(lambda (hook)
127+
(unless (procedure? hook)
128+
(error "current-log-hook: expected a procedure" hook))
129+
(let ((q pending-logs))
130+
(set! num-pending-logs 0)
131+
(set! pending-logs (make-queue))
132+
(let lp ()
133+
(unless (queue-empty? q)
134+
(hook (dequeue! q))
135+
(lp))))
136+
hook))))
137+
138+
;; Send a log entry with the given severity and message. This
139+
;; procedure also takes a list of extra keys and values.
140+
(define (send-log severity message . plist)
141+
(unless (and (exact? severity) (integer? severity) (<= 0 severity 7))
142+
(error "send-log: expected a severity from 0 to 7"
143+
severity message plist))
144+
(unless (string? message)
145+
(error "send-log: expected message to be a string"
146+
severity message plist))
147+
(let* ((fields (append plist (current-log-fields)))
148+
(alist (field-list->alist fields)))
149+
((current-log-callback) `((SEVERITY . ,severity)
150+
(MESSAGE . ,message)
151+
,@alist))))
152+
)
153+
)

0 commit comments

Comments
 (0)