~ubuntu-branches/ubuntu/precise/lilypond/precise

« back to all changes in this revision

Viewing changes to scm/lily.scm

  • Committer: Bazaar Package Importer
  • Author(s): Thomas Bushnell, BSG
  • Date: 2006-12-19 10:18:12 UTC
  • mfrom: (3.1.4 feisty)
  • Revision ID: james.westby@ubuntu.com-20061219101812-7awtjkp0i393wxty
Tags: 2.8.7-3
scripts/midi2ly.py: When setting DATADIR, find Lilypond python files
in the @TOPLEVEL_VERSION@ directory, not 'current'.  Patch thanks to
Chris Lamb (chris@chris-lamb.co.uk).  (Closes: #400550)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
;;;; lily.scm -- implement Scheme output routines for TeX and PostScript
 
1
;;;; lily.scm -- toplevel Scheme stuff
2
2
;;;;
3
3
;;;;  source file of the GNU LilyPond music typesetter
4
4
;;;; 
5
 
;;;; (c)  1998--2004 Jan Nieuwenhuizen <janneke@gnu.org>
 
5
;;;; (c) 1998--2006 Jan Nieuwenhuizen <janneke@gnu.org>
6
6
;;;; Han-Wen Nienhuys <hanwen@cs.uu.nl>
7
7
 
8
 
;;; Library functions
 
8
 
 
9
(define (define-scheme-options)
 
10
  (for-each (lambda (x)
 
11
              (ly:add-option (car x) (cadr x) (caddr x)))
 
12
          
 
13
            `((point-and-click #t "use point & click")
 
14
              (paper-size "a4" "the default paper size")
 
15
              (midi-debug #f "generate human readable MIDI")
 
16
              (dump-signatures #f "dump output signatures of each system (EPS backend)")
 
17
              (internal-type-checking #f "check every property assignment for types")
 
18
              (parse-protect #t    "continue when finding errors in inline
 
19
scheme are caught in the parser. If off, halt 
 
20
on errors, and print a stack trace.")
 
21
              (profile-property-accesses #f "keep statistics of get_property() calls.")
 
22
              (old-relative #f
 
23
                            "relative for simultaneous music works
 
24
similar to chord syntax")
 
25
              (object-keys #f
 
26
                           "experimental mechanism for remembering tweaks")
 
27
              (resolution 101 "resolution for generating bitmaps")
 
28
              (anti-alias-factor 1 "render at higher resolution and scale down result\nto prevent jaggies in PNG")
 
29
              (book-title-preview #t "include book-titles in preview images.")
 
30
              (eps-font-include #f "Include fonts in separate-system EPS files.")
 
31
              (gs-font-load #f
 
32
                            "load fonts via Ghostscript.")
 
33
              (gui #f "running from gui; redirect stderr to log file")
 
34
              (delete-intermediate-files #f
 
35
                                         "delete unusable PostScript files")
 
36
              (safe #f "Run safely")
 
37
              (verbose ,(ly:command-line-verbose?) "value for the --verbose flag")
 
38
              (strict-infinity-checking #f "If yes, crash on encountering Inf/NaN")
 
39
              (ttf-verbosity 0
 
40
                           "how much verbosity for TTF font embedding?")
 
41
              (debug-gc #f
 
42
                        "dump GC protection info")
 
43
              (show-available-fonts #f
 
44
                                    "List  font names available.")
 
45
              )))
 
46
 
 
47
 
 
48
;; need to do this in the beginning. Other parts of the
 
49
;; Scheme init depend on these options.
 
50
;;
 
51
(define-scheme-options)
9
52
 
10
53
(if (defined? 'set-debug-cell-accesses!)
11
54
    (set-debug-cell-accesses! #f))
12
55
 
 
56
;(set-debug-cell-accesses! 1000)
 
57
 
13
58
(use-modules (ice-9 regex)
14
59
             (ice-9 safe)
 
60
             (ice-9 optargs)
15
61
             (oop goops)
16
 
             (srfi srfi-1)  ; lists
17
 
             (srfi srfi-13)) ; strings
18
 
 
19
 
(define-public safe-module (make-safe-module))
20
 
 
 
62
             (srfi srfi-1)
 
63
             (srfi srfi-13)
 
64
             (srfi srfi-14))
 
65
 
 
66
 
 
67
;; my display
21
68
(define-public (myd k v) (display k) (display ": ") (display v) (display ", "))
22
69
 
 
70
(define-public (print . args)
 
71
  (apply format (cons (current-output-port) args)))
 
72
 
 
73
 
23
74
;;; General settings
24
75
;;; debugging evaluator is slower.  This should
25
76
;;; have a more sensible default.
26
77
 
27
 
 
28
78
(if (ly:get-option 'verbose)
29
79
    (begin
30
80
      (debug-enable 'debug)
31
81
      (debug-enable 'backtrace)
32
 
      (read-enable 'positions) ))
33
 
 
34
 
 
35
 
(define-public (line-column-location line col file)
36
 
  "Print an input location, including column number ."
37
 
  (string-append (number->string line) ":"
38
 
                 (number->string col) " " file)
39
 
  )
40
 
 
41
 
(define-public (line-location line col file)
42
 
  "Print an input location, without column number ."
43
 
  (string-append (number->string line) " " file)
44
 
  )
45
 
 
46
 
(define-public point-and-click #f)
 
82
      (read-enable 'positions)))
 
83
 
 
84
(define-public tex-backend?
 
85
  (member (ly:output-backend) '("texstr" "tex")))
 
86
 
 
87
(define-public parser #f)
47
88
 
48
89
(define-public (lilypond-version)
49
90
  (string-join
50
91
   (map (lambda (x) (if (symbol? x)
51
92
                        (symbol->string x)
52
93
                        (number->string x)))
53
 
                (ly:version))
 
94
        (ly:version))
54
95
   "."))
55
96
 
56
97
 
57
 
 
58
 
;; cpp hack to get useful error message
59
 
(define ifdef "First run this through cpp.")
60
 
(define ifndef "First run this through cpp.")
61
 
 
62
 
 
63
 
 
64
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
65
 
 
66
 
(define-public X 0)
67
 
(define-public Y 1)
68
 
(define-public START -1)
69
 
(define-public STOP 1)
70
 
(define-public LEFT -1)
71
 
(define-public RIGHT 1)
72
 
(define-public UP 1)
73
 
(define-public DOWN -1)
74
 
(define-public CENTER 0)
75
 
 
76
 
(define-public DOUBLE-FLAT -4)
77
 
(define-public THREE-Q-FLAT -3)
78
 
(define-public FLAT -2)
79
 
(define-public SEMI-FLAT -1)
80
 
(define-public NATURAL 0)
81
 
(define-public SEMI-SHARP 1)
82
 
(define-public SHARP 2)
83
 
(define-public THREE-Q-SHARP 3)
84
 
(define-public DOUBLE-SHARP 4)
85
 
(define-public SEMI-TONE 2)
86
 
 
87
 
(define-public ZERO-MOMENT (ly:make-moment 0 1)) 
88
 
 
89
 
(define-public (moment-min a b)
90
 
  (if (ly:moment<? a b) a b))
91
 
 
92
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
93
 
;; lily specific variables.
94
 
(define-public default-script-alist '())
95
 
 
96
 
(define-public safe-mode? #f)
97
 
 
98
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
99
 
;;; Unassorted utility functions.
100
 
 
101
 
 
102
 
;;;;;;;;;;;;;;;;
103
 
; alist
104
 
(define (uniqued-alist  alist acc)
105
 
  (if (null? alist) acc
106
 
      (if (assoc (caar alist) acc)
107
 
          (uniqued-alist (cdr alist) acc)
108
 
          (uniqued-alist (cdr alist) (cons (car alist) acc)))))
109
 
 
110
 
 
111
 
(define-public (assoc-get key alist . default)
112
 
  "Return value if KEY in ALIST, else DEFAULT (or #f if not specified)."
113
 
  (let ((entry (assoc key alist)))
114
 
    (if (pair? entry)
115
 
        (cdr entry)
116
 
        (if (pair? default) (car default) #f)
117
 
        )))
118
 
 
119
 
(define-public (uniqued-alist  alist acc)
120
 
  (if (null? alist) acc
121
 
      (if (assoc (caar alist) acc)
122
 
          (uniqued-alist (cdr alist) acc)
123
 
          (uniqued-alist (cdr alist) (cons (car alist) acc)))))
124
 
 
125
 
(define-public (alist<? x y)
126
 
  (string<? (symbol->string (car x))
127
 
            (symbol->string (car y))))
128
 
 
129
 
(define-public (chain-assoc x alist-list)
130
 
  (if (null? alist-list)
131
 
      #f
132
 
      (let* ((handle (assoc x (car alist-list))))
133
 
        (if (pair? handle)
134
 
            handle
135
 
            (chain-assoc x (cdr alist-list))))))
136
 
 
137
 
(define-public (chain-assoc-get x alist-list . default)
138
 
  "Return ALIST entry for X. Return DEFAULT (optional, else #f) if not
139
 
found."
140
 
 
141
 
  (define (helper x alist-list default)
142
 
    (if (null? alist-list)
143
 
        default
144
 
        (let* ((handle (assoc x (car alist-list))))
145
 
          (if (pair? handle)
146
 
              (cdr handle)
147
 
              (helper x (cdr alist-list) default)))))
148
 
 
149
 
  (helper x alist-list
150
 
          (if (pair? default) (car default) #f)))
151
 
 
152
 
(define (map-alist-vals func list)
153
 
  "map FUNC over the vals of  LIST, leaving the keys."
154
 
  (if (null?  list)
155
 
      '()
156
 
      (cons (cons  (caar list) (func (cdar list)))
157
 
            (map-alist-vals func (cdr list)))
158
 
      ))
159
 
 
160
 
(define (map-alist-keys func list)
161
 
  "map FUNC over the keys of an alist LIST, leaving the vals. "
162
 
  (if (null?  list)
163
 
      '()
164
 
      (cons (cons (func (caar list)) (cdar list))
165
 
            (map-alist-keys func (cdr list)))
166
 
      ))
167
 
 
168
 
;;;;;;;;;;;;;;;;
169
 
;; hash
170
 
 
171
 
 
172
 
 
173
 
(if (not (defined? 'hash-table?))       ; guile 1.6 compat
174
 
    (begin
175
 
      (define hash-table? vector?)
176
 
 
177
 
      (define-public (hash-table->alist t)
178
 
        "Convert table t to list"
179
 
        (apply append
180
 
               (vector->list t)
181
 
               )))
182
 
 
183
 
    ;; native hashtabs.
184
 
    (begin
185
 
      (define-public (hash-table->alist t)
186
 
 
187
 
        (hash-fold (lambda (k v acc) (acons  k v  acc))
188
 
                   '() t)
189
 
        )
190
 
      ))
191
 
 
192
 
;; todo: code dup with C++. 
193
 
(define-public (alist->hash-table l)
194
 
  "Convert alist to table"
195
 
  (let
196
 
      ((m (make-hash-table (length l))))
197
 
 
198
 
    (map (lambda (k-v)
199
 
           (hashq-set! m (car k-v) (cdr k-v)))
200
 
         l)
201
 
 
202
 
    m))
203
 
       
204
 
 
205
 
 
206
 
;;;;;;;;;;;;;;;;
207
 
; list
208
 
 
209
 
(define (flatten-list lst)
210
 
  "Unnest LST" 
211
 
  (if (null? lst)
212
 
      '()
213
 
      (if (pair? (car lst))
214
 
          (append (flatten-list (car lst)) (flatten-list  (cdr lst)))
215
 
          (cons (car lst) (flatten-list (cdr lst))))
216
 
  ))
217
 
 
218
 
(define (list-minus a b)
219
 
  "Return list of elements in A that are not in B."
220
 
  (lset-difference eq? a b))
221
 
 
222
 
 
223
 
;; TODO: use the srfi-1 partition function.
224
 
(define-public (uniq-list l)
225
 
  
226
 
  "Uniq LIST, assuming that it is sorted"
227
 
  (define (helper acc l) 
228
 
    (if (null? l)
229
 
        acc
230
 
        (if (null? (cdr l))
231
 
            (cons (car l) acc)
232
 
            (if (equal? (car l) (cadr l))
233
 
                (helper acc (cdr l))
234
 
                (helper (cons (car l) acc)  (cdr l)))
235
 
            )))
236
 
  (reverse! (helper '() l) '()))
237
 
 
238
 
 
239
 
(define (split-at-predicate predicate l)
240
 
 "Split L = (a_1 a_2 ... a_k b_1 ... b_k)
241
 
into L1 = (a_1 ... a_k ) and L2 =(b_1 .. b_k) 
242
 
Such that (PREDICATE a_i a_{i+1}) and not (PREDICATE a_k b_1).
243
 
L1 is copied, L2 not.
244
 
 
245
 
(split-at-predicate (lambda (x y) (= (- y x) 2))  '(1 3 5 9 11) (cons '() '()))"
246
 
;; "
247
 
 
248
 
;; KUT EMACS MODE.
249
 
 
250
 
  (define (inner-split predicate l acc)
251
 
  (cond
252
 
   ((null? l) acc)
253
 
   ((null? (cdr l))
254
 
    (set-car! acc (cons (car l) (car acc)))
255
 
    acc)
256
 
   ((predicate (car l) (cadr l))
257
 
    (set-car! acc (cons (car l) (car acc)))
258
 
    (inner-split predicate (cdr l) acc))
259
 
   (else
260
 
    (set-car! acc (cons (car l) (car acc)))
261
 
    (set-cdr! acc (cdr l))
262
 
    acc)
263
 
 
264
 
  ))
265
 
 (let*
266
 
    ((c (cons '() '()))
267
 
     )
268
 
  (inner-split predicate l  c)
269
 
  (set-car! c (reverse! (car c))) 
270
 
  c)
271
 
)
272
 
 
273
 
 
274
 
(define-public (split-list l sep?)
275
 
"
276
 
(display (split-list '(a b c / d e f / g) (lambda (x) (equal? x '/))) )
277
 
=>
278
 
((a b c) (d e f) (g))
279
 
 
280
 
"
281
 
;; " KUT EMACS.
282
 
 
283
 
(define (split-one sep?  l acc)
284
 
  "Split off the first parts before separator and return both parts."
285
 
  (if (null? l)
286
 
      (cons acc '())
287
 
      (if (sep? (car l))
288
 
          (cons acc (cdr l))
289
 
          (split-one sep? (cdr l) (cons (car l) acc))
290
 
          )
291
 
      ))
292
 
 
293
 
(if (null? l)
294
 
    '()
295
 
    (let* ((c (split-one sep? l '())))
296
 
      (cons (reverse! (car c) '()) (split-list (cdr c) sep?))
297
 
      )))
298
 
 
299
 
 
300
 
(define-public (interval-length x)
301
 
  "Length of the number-pair X, when an interval"
302
 
  (max 0 (- (cdr x) (car x)))
303
 
  )
304
 
  
305
 
 
306
 
(define (other-axis a)
307
 
  (remainder (+ a 1) 2))
308
 
  
309
 
 
310
 
(define-public (interval-widen iv amount)
311
 
   (cons (- (car iv) amount)
312
 
         (+ (cdr iv) amount)))
313
 
 
314
 
(define-public (interval-union i1 i2)
315
 
   (cons (min (car i1) (car i2))
316
 
         (max (cdr i1) (cdr i2))))
317
 
 
318
 
 
319
 
(define-public (write-me message x)
320
 
  "Return X.  Display MESSAGE and write X.  Handy for debugging, possibly turned off."
321
 
  (display message) (write x) (newline) x)
322
 
;;  x)
323
 
 
324
 
(define (index-cell cell dir)
325
 
  (if (equal? dir 1)
326
 
      (cdr cell)
327
 
      (car cell)))
328
 
 
329
 
(define (cons-map f x)
330
 
  "map F to contents of X"
331
 
  (cons (f (car x)) (f (cdr x))))
332
 
 
333
 
 
334
 
(define-public (list-insert-separator lst between)
335
 
  "Create new list, inserting BETWEEN between elements of LIST"
336
 
  (define (conc x y )
337
 
    (if (eq? y #f)
338
 
        (list x)
339
 
        (cons x  (cons between y))
340
 
        ))
341
 
  (fold-right conc #f lst))
342
 
 
343
 
;;;;;;;;;;;;;;;;
344
 
; other
345
 
(define (sign x)
346
 
  (if (= x 0)
347
 
      0
348
 
      (if (< x 0) -1 1)))
349
 
 
350
 
(define-public (symbol<? l r)
351
 
  (string<? (symbol->string l) (symbol->string r)))
352
 
 
353
 
(define-public (!= l r)
354
 
  (not (= l r)))
 
98
;; TeX C++ code actually hooks into TEX_STRING_HASHLIMIT 
 
99
(define-public TEX_STRING_HASHLIMIT 10000000)
 
100
 
 
101
 
 
102
 
 
103
;; gettext wrapper for guile < 1.7.2
 
104
(if (defined? 'gettext)
 
105
    (define-public _ gettext)
 
106
    (define-public _ ly:gettext))
355
107
 
356
108
(define-public (ly:load x)
357
 
  (let* (
358
 
         (fn (%search-load-path x))
359
 
 
360
 
         )
361
 
    (if (ly:get-option 'verbose)
362
 
        (format (current-error-port) "[~A]" fn))
363
 
    (primitive-load fn)))
364
 
 
 
109
  (let* ((file-name (%search-load-path x)))
 
110
    (if (ly:get-option 'verbose)
 
111
        (ly:progress "[~A" file-name))
 
112
    (if (not file-name)
 
113
        (ly:error (_ "Can't find ~A" x)))
 
114
    (primitive-load file-name)
 
115
    (if (ly:get-option 'verbose)
 
116
        (ly:progress "]"))))
 
117
 
 
118
;; Cygwin
 
119
;; #(CYGWIN_NT-5.1 Hostname 1.5.12(0.116/4/2) 2004-11-10 08:34 i686)
 
120
;;
 
121
;; Debian
 
122
;; #(Linux hostname 2.4.27-1-686 #1 Fri Sep 3 06:28:00 UTC 2004 i686)
 
123
;;
 
124
;; Mingw
 
125
;; #(Windows XP HOSTNAME build 2600 5.01 Service Pack 1 i686)
 
126
;;
 
127
 
 
128
;; ugh, code dup.
 
129
(define-public PLATFORM
 
130
  (string->symbol
 
131
   (string-downcase
 
132
    (car (string-tokenize (vector-ref (uname) 0) char-set:letter)))))
 
133
 
 
134
(define-public DOS
 
135
  (let ((platform (string-tokenize
 
136
                   (vector-ref (uname) 0) char-set:letter+digit)))
 
137
    (if (null? (cdr platform)) #f
 
138
        (member (string-downcase (cadr platform)) '("95" "98" "me")))))
 
139
 
 
140
(case PLATFORM
 
141
  ((windows)
 
142
   (define native-getcwd getcwd)
 
143
   (define (slashify x)
 
144
     (if (string-index x #\\)
 
145
         x
 
146
         (string-regexp-substitute
 
147
          "//*" "/"
 
148
          (string-regexp-substitute "\\\\" "/" x))))
 
149
   ;; FIXME: this prints a warning.
 
150
  (define-public (ly-getcwd)
 
151
     (slashify (native-getcwd))))
 
152
  (else (define-public ly-getcwd getcwd)))
 
153
 
 
154
(define-public (is-absolute? file-name)
 
155
  (let ((file-name-length (string-length file-name)))
 
156
    (if (= file-name-length 0)
 
157
        #f
 
158
        (or (eq? (string-ref file-name 0) #\/)
 
159
            (and (eq? PLATFORM 'windows)
 
160
                 (> file-name-length 2)
 
161
                 (eq? (string-ref file-name 1) #\:)
 
162
                 (eq? (string-ref file-name 2) #\/))))))
 
163
 
 
164
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
165
 
 
166
(define (type-check-list location signature arguments)
 
167
  "Typecheck a list of arguments against a list of type
 
168
predicates. Print a message at LOCATION if any predicate failed."
 
169
  (define (recursion-helper signature arguments count) 
 
170
    (define (helper pred? arg count) 
 
171
      (if (not (pred? arg))
 
172
 
 
173
          (begin
 
174
            (ly:input-message
 
175
             location
 
176
             (format
 
177
              #f (_ "wrong type for argument ~a.  Expecting ~a, found ~s")
 
178
              count (type-name pred?) arg))
 
179
            #f)
 
180
          #t))
 
181
 
 
182
    (if (null? signature)
 
183
        #t
 
184
        (and (helper (car signature) (car arguments) count)
 
185
             (recursion-helper (cdr signature) (cdr arguments) (1+ count)))))
 
186
  (recursion-helper signature arguments 1))
365
187
 
366
188
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
367
189
;;  output
368
 
(use-modules
369
 
             ;(scm output-sketch)
370
 
             ;(scm output-sodipodi)
371
 
             ;(scm output-pdftex)
372
 
 
373
 
             )
374
 
 
 
190
 
 
191
 
 
192
;;(define-public (output-framework) (write "hello\n"))
375
193
 
376
194
(define output-tex-module
377
195
  (make-module 1021 (list (resolve-interface '(scm output-tex)))))
378
196
(define output-ps-module
379
197
  (make-module 1021 (list (resolve-interface '(scm output-ps)))))
380
 
(define-public (tex-output-expression expr port)
381
 
  (display (eval expr output-tex-module) port))
 
198
 
382
199
(define-public (ps-output-expression expr port)
383
200
  (display (eval expr output-ps-module) port))
384
201
 
385
 
(define output-alist
386
 
  `(
387
 
    ("tex" . ("TeX output. The default output form." ,tex-output-expression))
388
 
    ("scm" . ("Scheme dump: debug scheme stencil expressions" ,write))
389
 
;    ("sketch" . ("Bare bones Sketch output." ,sketch-output-expression))
390
 
;    ("sodipodi" . ("Bare bones Sodipodi output." ,sodipodi-output-expression))
391
 
;    ("pdftex" . ("PDFTeX output. Was last seen nonfunctioning." ,pdftex-output-expression))
392
 
    ))
393
 
 
394
 
 
395
 
(define (document-format-dumpers)
396
 
  (map
397
 
   (lambda (x)
398
 
     (display (string-append  (pad-string-to 5 (car x)) (cadr x) "\n"))
399
 
     output-alist)
400
 
   ))
401
 
 
402
 
(define-public (find-dumper format)
403
 
  (let ((d (assoc format output-alist)))
404
 
    (if (pair? d)
405
 
        (caddr d)
406
 
        (scm-error "Could not find dumper for format ~s" format))))
 
202
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
203
;; Safe definitions utility
 
204
(define safe-objects (list))
 
205
 
 
206
(define-macro (define-safe-public arglist . body)
 
207
  "Define a variable, export it, and mark it as safe, ie usable in LilyPond safe mode.
 
208
The syntax is the same as `define*-public'."
 
209
  (define (get-symbol arg)
 
210
    (if (pair? arg)
 
211
        (get-symbol (car arg))
 
212
        arg))
 
213
  (let ((safe-symbol (get-symbol arglist)))
 
214
    `(begin
 
215
       (define*-public ,arglist
 
216
         ,@body)
 
217
       (set! safe-objects (cons (cons ',safe-symbol ,safe-symbol)
 
218
                                safe-objects))
 
219
       ,safe-symbol)))
 
220
 
407
221
 
408
222
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
409
223
;; other files.
410
224
 
411
225
(for-each ly:load
412
 
     ;; load-from-path
413
 
     '("define-music-types.scm"
414
 
       "output-lib.scm"
415
 
       "c++.scm"
416
 
       "chord-ignatzek-names.scm"
417
 
       "chord-entry.scm"
418
 
       "chord-generic-names.scm"
419
 
       "stencil.scm"
420
 
       "new-markup.scm"
421
 
       "bass-figure.scm"
422
 
       "music-functions.scm"
423
 
       "part-combiner.scm"
424
 
       "define-music-properties.scm"
425
 
       "auto-beam.scm"
426
 
       "chord-name.scm"
427
 
       
428
 
       "define-context-properties.scm"
429
 
       "translation-functions.scm"
430
 
       "script.scm"
431
 
       "midi.scm"
432
 
 
433
 
       "beam.scm"
434
 
       "clef.scm"
435
 
       "slur.scm"
436
 
       "font.scm"
437
 
       
438
 
       "define-markup-commands.scm"
439
 
       "define-grob-properties.scm"
440
 
       "define-grobs.scm"
441
 
       "define-grob-interfaces.scm"
442
 
 
443
 
       "page-layout.scm"
444
 
       "paper.scm"
445
 
       ))
 
226
          ;; load-from-path
 
227
          '("lily-library.scm"
 
228
            "file-cache.scm"
 
229
;           "define-event-classes.scm"
 
230
            "define-music-types.scm"
 
231
            "output-lib.scm"
 
232
            "c++.scm"
 
233
            "chord-ignatzek-names.scm"
 
234
            "chord-entry.scm"
 
235
            "chord-generic-names.scm"
 
236
            "stencil.scm"
 
237
            "markup.scm"
 
238
            "music-functions.scm"
 
239
            "part-combiner.scm"
 
240
            "autochange.scm"
 
241
            "define-music-properties.scm"
 
242
            "auto-beam.scm"
 
243
            "chord-name.scm"
 
244
 
 
245
            "parser-ly-from-scheme.scm"
 
246
            
 
247
            "define-context-properties.scm"
 
248
            "translation-functions.scm"
 
249
            "script.scm"
 
250
            "midi.scm"
 
251
            "layout-beam.scm"
 
252
            "parser-clef.scm"
 
253
            "layout-slur.scm"
 
254
            "font.scm"
 
255
            "encoding.scm"
 
256
            
 
257
            "fret-diagrams.scm"
 
258
            "define-markup-commands.scm"
 
259
            "define-grob-properties.scm"
 
260
            "define-grobs.scm"
 
261
            "define-grob-interfaces.scm"
 
262
            "define-stencil-commands.scm"
 
263
            "layout-page-layout.scm"
 
264
            "titling.scm"
 
265
            
 
266
            "paper.scm"
 
267
            "backend-library.scm"
 
268
            "x11-color.scm"
 
269
 
 
270
            ;; must be after everything has been defined
 
271
            "safe-lily.scm"))
446
272
 
447
273
 
448
274
(set! type-p-name-alist
449
 
  `(
450
 
   (,boolean-or-symbol? . "boolean or symbol")
451
 
   (,boolean? . "boolean")
452
 
   (,char? . "char")
453
 
   (,grob-list? . "list of grobs")
454
 
   (,hash-table? . "hash table")
455
 
   (,input-port? . "input port")
456
 
   (,integer? . "integer")
457
 
   (,list? . "list")
458
 
   (,ly:context? . "context")
459
 
   (,ly:dimension? . "dimension, in staff space")
460
 
   (,ly:dir? . "direction")
461
 
   (,ly:duration? . "duration")
462
 
   (,ly:grob? . "layout object")
463
 
   (,ly:input-location? . "input location")
464
 
   (,ly:moment? . "moment")
465
 
   (,ly:music? . "music")
466
 
   (,ly:pitch? . "pitch")
467
 
   (,ly:translator? . "translator")
468
 
   (,ly:font-metric? . "font metric")
469
 
   (,markup-list? . "list of markups")
470
 
   (,markup? . "markup")
471
 
   (,ly:music-list? . "list of music")
472
 
   (,number-or-grob? . "number or grob")
473
 
   (,number-or-string? . "number or string")
474
 
   (,number-pair? . "pair of numbers")
475
 
   (,number? . "number")
476
 
   (,output-port? . "output port")   
477
 
   (,pair? . "pair")
478
 
   (,procedure? . "procedure") 
479
 
   (,scheme? . "any type")
480
 
   (,string? . "string")
481
 
   (,symbol? . "symbol")
482
 
   (,vector? . "vector")
483
 
   ))
 
275
      `(
 
276
        (,boolean-or-symbol? . "boolean or symbol")
 
277
        (,boolean? . "boolean")
 
278
        (,char? . "char")
 
279
        (,grob-list? . "list of grobs")
 
280
        (,hash-table? . "hash table")
 
281
        (,input-port? . "input port")
 
282
        (,integer? . "integer")
 
283
        (,list? . "list")
 
284
        (,ly:context? . "context")
 
285
        (,ly:dimension? . "dimension, in staff space")
 
286
        (,ly:dir? . "direction")
 
287
        (,ly:duration? . "duration")
 
288
        (,ly:grob? . "layout object")
 
289
        (,ly:input-location? . "input location")
 
290
        (,ly:moment? . "moment")
 
291
        (,ly:music? . "music")
 
292
        (,ly:pitch? . "pitch")
 
293
        (,ly:translator? . "translator")
 
294
        (,ly:font-metric? . "font metric")
 
295
        (,ly:simple-closure? . "simple closure")
 
296
        (,markup-list? . "list of markups")
 
297
        (,markup? . "markup")
 
298
        (,ly:music-list? . "list of music")
 
299
        (,number-or-grob? . "number or grob")
 
300
        (,number-or-string? . "number or string")
 
301
        (,number-pair? . "pair of numbers")
 
302
        (,number? . "number")
 
303
        (,output-port? . "output port")   
 
304
        (,pair? . "pair")
 
305
        (,procedure? . "procedure") 
 
306
        (,scheme? . "any type")
 
307
        (,string? . "string")
 
308
        (,symbol? . "symbol")
 
309
        (,vector? . "vector")))
484
310
 
485
311
 
486
312
;; debug mem leaks
487
313
 
488
314
(define gc-protect-stat-count 0)
489
315
(define-public (dump-gc-protects)
490
 
  (set! gc-protect-stat-count (1+ gc-protect-stat-count) )
491
 
  (let*
492
 
      ((protects (sort
493
 
           (hash-table->alist (ly:protects))
494
 
           (lambda (a b)
495
 
             (< (object-address (car a))
496
 
                (object-address (car b))))))
497
 
       (outfile    (open-file (string-append
498
 
               "gcstat-" (number->string gc-protect-stat-count)
499
 
               ".scm"
500
 
               ) "w"))
501
 
       )
502
 
 
503
 
    (display "DUMPING...\n")
 
316
  (set! gc-protect-stat-count (1+ gc-protect-stat-count))
 
317
  (let* ((protects (sort
 
318
                    (hash-table->alist (ly:protects))
 
319
                    (lambda (a b)
 
320
                      (< (object-address (car a))
 
321
                         (object-address (car b))))))
 
322
 
 
323
         (out-file-name (string-append
 
324
                         "gcstat-" (number->string gc-protect-stat-count)
 
325
                         ".scm"))
 
326
         (outfile    (open-file  out-file-name  "w")))
 
327
 
 
328
    (display (format "Dumping gc protected objs to ~a...\n" out-file-name))
504
329
    (display
505
 
     (filter
506
 
      (lambda (x) (not (symbol? x))) 
507
 
      (map (lambda (y)
508
 
             (let
509
 
                 ((x (car y))
 
330
     (map (lambda (y)
 
331
            (let ((x (car y))
510
332
                  (c (cdr y)))
 
333
              
 
334
              (string-append
 
335
               (string-join
 
336
                (map object->string (list (object-address x) c x))
 
337
                " ")
 
338
               "\n")))
511
339
 
512
 
               (string-append
513
 
                (string-join
514
 
                 (map object->string (list (object-address x) c x))
515
 
                 " ")
516
 
                "\n")))
 
340
          (filter
 
341
           (lambda (x)
 
342
             (not (symbol? (car x))))
517
343
           protects))
518
344
     outfile)
519
345
 
520
 
    ))
521
 
 
 
346
;    (display (ly:smob-protects))
 
347
    (newline outfile)
 
348
    (if (defined? 'gc-live-object-stats)
 
349
        (let* ((stats #f))
 
350
          (display "Live object statistics: GC'ing\n")
 
351
          (gc)
 
352
          (gc)
 
353
          
 
354
          (set! stats (gc-live-object-stats))
 
355
          (display "Dumping live object statistics.\n")
 
356
          
 
357
          (for-each
 
358
           (lambda (x)
 
359
             (format outfile "~a: ~a\n" (car x) (cdr x)))
 
360
           (sort (gc-live-object-stats)
 
361
                 (lambda (x y)
 
362
                   (string<? (car x) (car y)))))))))
 
363
 
 
364
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
365
 
 
366
 
 
367
(define-public (lilypond-main files)
 
368
  "Entry point for LilyPond."
 
369
  
 
370
  (define (no-files-handler)
 
371
    (ly:usage)
 
372
    (exit 2))
 
373
 
 
374
  (if (ly:get-option 'gui)
 
375
      (gui-main files))
 
376
 
 
377
  (if (null? files)
 
378
      (no-files-handler))
 
379
 
 
380
  (let ((failed (lilypond-all files)))
 
381
    (if (pair? failed)
 
382
        (begin
 
383
          (ly:error (_ "failed files: ~S") (string-join failed))
 
384
          (exit 1))
 
385
        (begin
 
386
          ;; HACK: be sure to exit with single newline
 
387
          (ly:message "")
 
388
          (exit 0)))))
 
389
 
 
390
(define-public (lilypond-all files)
 
391
 
 
392
  (if (ly:get-option 'show-available-fonts)
 
393
      (begin
 
394
        (ly:font-config-display-fonts)
 
395
        (exit 0)
 
396
        ))
 
397
  
 
398
  (let* ((failed '())
 
399
         (handler (lambda (key failed-file)
 
400
                    (set! failed (append (list failed-file) failed)))))
 
401
 
 
402
    (for-each
 
403
     (lambda (x)
 
404
       (lilypond-file handler x)
 
405
       (ly:clear-anonymous-modules)
 
406
       (if (ly:get-option 'debug-gc)
 
407
           (dump-gc-protects)))
 
408
     
 
409
     files)
 
410
    failed))
 
411
 
 
412
(define (lilypond-file handler file-name)
 
413
  (catch 'ly-file-failed
 
414
         (lambda () (ly:parse-file file-name))
 
415
         (lambda (x . args) (handler x file-name))))
 
416
 
 
417
(use-modules (scm editor))
 
418
 
 
419
(define-public (gui-main files)
 
420
  (if (null? files)
 
421
      (gui-no-files-handler))
 
422
  (let* ((base (basename (car files) ".ly"))
 
423
         (log-name (string-append base ".log")))
 
424
    (if (not (ly:get-option 'gui))
 
425
        (ly:message (_ "Redirecting output to ~a...") log-name))
 
426
    (ly:stderr-redirect log-name "w")
 
427
    (ly:message "# -*-compilation-*-")
 
428
    
 
429
    (let ((failed (lilypond-all files)))
 
430
      (if (pair? failed)
 
431
          (begin
 
432
            ;; ugh
 
433
            (ly:stderr-redirect "foo" "r")
 
434
            (system (get-editor-command log-name 0 0 0))
 
435
            (ly:error (_ "failed files: ~S") (string-join failed))
 
436
            ;; not reached?
 
437
            (exit 1))
 
438
          (exit 0)))))
 
439
 
 
440
(define (gui-no-files-handler)
 
441
  (let* ((ly (string-append (ly:effective-prefix) "/ly/"))
 
442
         ;; FIXME: soft-code, localize
 
443
         (welcome-ly (string-append ly "Welcome_to_LilyPond.ly"))
 
444
         (cmd (get-editor-command welcome-ly 0 0 0)))
 
445
    (ly:message (_ "Invoking `~a'...") cmd)
 
446
    (system cmd)
 
447
    (exit 1)))