summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLudovic Courtès2018-03-30 15:34:38 +0200
committerLudovic Courtès2018-03-30 15:42:53 +0200
commit869c137fd84eddf71b074898ff7210cddc35a877 (patch)
treeff62ebffd26c1aeb341c440505b2f700d44b35e8
parent08a4706b2c220048b138fcedfec822a1d319e138 (diff)
downloadskribilo-869c137fd84eddf71b074898ff7210cddc35a877.tar.gz
skribilo-869c137fd84eddf71b074898ff7210cddc35a877.tar.lz
skribilo-869c137fd84eddf71b074898ff7210cddc35a877.zip
Do not mutate lists that may be literal.
On Guile 2.2 this would lead to a segmentation fault or a 'set-car!' error ("expecting mutable pair") on 2.2.3+. * src/guile/skribilo/engine.scm (engine-custom-set!): Do not mutate CUSTOMS. * src/guile/skribilo/resolve.scm (do-resolve! <pair>): Do not mutate AST. (do-resolve! <node>): Do not mutate OPTIONS. (do-resolve! <document>): Do not mutate the list of customs.
-rw-r--r--src/guile/skribilo/engine.scm10
-rw-r--r--src/guile/skribilo/resolve.scm52
2 files changed, 29 insertions, 33 deletions
diff --git a/src/guile/skribilo/engine.scm b/src/guile/skribilo/engine.scm
index fb1bcb2..5f82044 100644
--- a/src/guile/skribilo/engine.scm
+++ b/src/guile/skribilo/engine.scm
@@ -29,6 +29,7 @@
:use-module (ice-9 optargs)
:use-module (ice-9 format)
+ :use-module (srfi srfi-1)
:autoload (srfi srfi-34) (raise guard)
:use-module (srfi srfi-35)
:autoload (srfi srfi-39) (make-parameter)
@@ -350,11 +351,10 @@ otherwise the requested engine is returned."
(define (engine-custom-set! e id val)
- (let* ((customs (slot-ref e 'customs))
- (c (assq id customs)))
- (if (pair? c)
- (set-car! (cdr c) val)
- (slot-set! e 'customs (cons (list id val) customs)))))
+ (let ((customs (slot-ref e 'customs)))
+ (slot-set! e 'customs
+ (cons (list id val)
+ (alist-delete id customs eq?)))))
(define (engine-custom-add! e id val)
(let ((old (engine-custom e id)))
diff --git a/src/guile/skribilo/resolve.scm b/src/guile/skribilo/resolve.scm
index 2ef49b1..7058d90 100644
--- a/src/guile/skribilo/resolve.scm
+++ b/src/guile/skribilo/resolve.scm
@@ -1,6 +1,6 @@
;;; resolve.scm -- Skribilo reference resolution.
;;;
-;;; Copyright 2005, 2006, 2008, 2009 Ludovic Courtès <ludo@gnu.org>
+;;; Copyright 2005, 2006, 2008, 2009, 2018 Ludovic Courtès <ludo@gnu.org>
;;; Copyright 2003, 2004 Erick Gallesio - I3S-CNRS/ESSI <eg@unice.fr>
;;;
;;;
@@ -30,6 +30,7 @@
:use-module (skribilo condition)
:use-module (srfi srfi-34)
:use-module (srfi srfi-35)
+ :use-module (ice-9 match)
:export (resolve! resolve-search-parent
resolve-counter resolve-parent resolve-ident
@@ -91,21 +92,14 @@
(define-method (do-resolve! (ast <pair>) engine env)
- (let Loop ((n* ast))
- (cond
- ((null? n*)
- ast)
- ((list? n*)
- (set-car! n* (do-resolve! (car n*) engine env))
- (Loop (cdr n*)))
- ((pair? n*)
- (set-car! n* (do-resolve! (car n*) engine env))
- (set-cdr! n* (do-resolve! (cdr n*) engine env))
- n*)
- (else
- (raise (condition (&invalid-argument-error
- (proc-name "do-resolve!<pair>")
- (argument n*))))))))
+ (match ast
+ ((? list?) ;proper list
+ (map (lambda (elt)
+ (do-resolve! elt engine env))
+ ast))
+ ((head . tail) ;pair or improper list
+ (cons (do-resolve! head engine env)
+ (do-resolve! tail engine env)))))
(define-method (do-resolve! (node <node>) engine env)
@@ -125,11 +119,13 @@
(when (pair? options)
(debug-item "unresolved options=" options)
- (for-each (lambda (o)
- (set-car! (cdr o)
- (do-resolve! (cadr o) engine env)))
- options)
- (debug-item "resolved options=" options))
+ (let ((resolved (map (match-lambda
+ ((option value)
+ (list option
+ (do-resolve! value engine env))))
+ options)))
+ (slot-set! node 'options resolved)
+ (debug-item "resolved options=" options)))
(slot-set! node 'body (do-resolve! body engine env))
(slot-set! node 'resolved? (not (*unresolved*))))
@@ -182,13 +178,13 @@
(parameterize ((*document-being-resolved* node))
(next-method)
;; resolve the engine custom
- (let ((env (append `((parent ,node)) env0)))
- (for-each (lambda (c)
- (let ((i (car c))
- (a (cadr c)))
- (debug-item "custom=" i " " a)
- (set-car! (cdr c) (do-resolve! a engine env))))
- (slot-ref engine 'customs)))
+ (let* ((env (append `((parent ,node)) env0))
+ (resolved (map (match-lambda
+ ((i a)
+ (debug-item "custom=" i " " a)
+ (list i (do-resolve! a engine env))))
+ (slot-ref engine 'customs))))
+ (slot-set! engine 'customs resolved))
node))