]> git.donarmstrong.com Git - lilypond.git/blobdiff - scm/lily.scm
* Documentation/topdocs/INSTALL.texi (Top): Remove information
[lilypond.git] / scm / lily.scm
index 0025dacb7ce4e444614284896fb4e220c8a54a51..0fe8fbfb22512e515f7d5fbcb89aa48be4c03188 100644 (file)
-;;;; lily.scm -- implement Scheme output routines for TeX and PostScript
+;;;; lily.scm -- toplevel Scheme stuff
 ;;;;
 ;;;;  source file of the GNU LilyPond music typesetter
 ;;;; 
-;;;; (c) 1998--2001 Jan Nieuwenhuizen <janneke@gnu.org>
+;;;; (c) 1998--2005 Jan Nieuwenhuizen <janneke@gnu.org>
 ;;;; Han-Wen Nienhuys <hanwen@cs.uu.nl>
 
-;;; Library functions
 
-(use-modules (ice-9 regex))
+(if (defined? 'set-debug-cell-accesses!)
+    (set-debug-cell-accesses! #f))
 
-;;(write standalone (current-error-port))
+;;(set-debug-cell-accesses! 5000)
 
-;;; General settings
+(use-modules (ice-9 regex)
+            (ice-9 safe)
+             (ice-9 optargs)
+            (oop goops)
+            (srfi srfi-1)  ; lists
+            (srfi srfi-13)) ; strings
 
 
+;; my display
+(define-public (myd k v) (display k) (display ": ") (display v) (display ", "))
 
+(define-public (print . args)
+  (apply format (cons (current-output-port) args)))
 
-(debug-enable 'backtrace)
 
+;;; General settings
+;;; debugging evaluator is slower.  This should
+;;; have a more sensible default.
 
-(define point-and-click #f)
-(define security-paranoia #f)
-(define midi-debug #f)
+(if (ly:get-option 'verbose)
+    (begin
+      (debug-enable 'debug)
+      (debug-enable 'backtrace)
+      (read-enable 'positions)))
 
-(define (line-column-location line col file)
+(define-public (line-column-location file line col)
   "Print an input location, including column number ."
   (string-append (number->string line) ":"
-                (number->string col) " " file)
-  )
+                (number->string col) " " file))
 
-(define (line-location line col file)
+(define-public (line-location  file line col)
   "Print an input location, without column number ."
-  (string-append (number->string line) " " file)
-  )
+  (string-append (number->string line) " " file))
+
+(define-public point-and-click #f)
+
+(define-public tex-backend?
+  (member (ly:output-backend) '("texstr" "tex")))
+
+(define-public parser #f)
+
+(define-public (lilypond-version)
+  (string-join
+   (map (lambda (x) (if (symbol? x)
+                       (symbol->string x)
+                       (number->string x)))
+       (ly:version))
+   "."))
+
+
 
 ;; cpp hack to get useful error message
 (define ifdef "First run this through cpp.")
 (define ifndef "First run this through cpp.")
-  
-(define default-script-alist '())
-(define font-name-alist  '())
-
-(if (not (defined? 'standalone))
-    (define standalone (not (defined? 'ly-gulp-file))))
-
-;; The regex module may not be available, or may be broken.
-(define use-regex
-  (let ((os (string-downcase (vector-ref (uname) 0))))
-    (not (equal? "cygwin" (substring os 0 (min 6 (string-length os)))))))
-
-;; If you have trouble with regex, define #f
-(define use-regex #t)
-;;(define use-regex #f)
-
-
-;;; Un-assorted stuff
-
-;; URG guile-1.4/1.4.x compatibility
-(if (not (defined? 'primitive-eval))
-    (define (primitive-eval form)
-      (eval2 form #f)))
-
-(define (sign x)
-  (if (= x 0)
-      0
-      (if (< x 0) -1 1)))
-
-(define (write-me n x)
-  (display n)
-  (write x)
-  (newline)
-  x)
-
-(define (empty? x)
-  (equal? x '()))
-
-(define (!= l r)
-  (not (= l r)))
-
-(define (filter-list pred? list)
-  "return that part of LIST for which PRED is true."
-  (if (null? list) '()
-      (let* ((rest  (filter-list pred? (cdr list))))
-       (if (pred?  (car list))
-           (cons (car list)  rest)
-           rest))))
-
-(define (filter-out-list pred? list)
-  "return that part of LIST for which PRED is true."
-  (if (null? list) '()
-      (let* ((rest  (filter-list pred? (cdr list))))
-       (if (not (pred?  (car list)))
-           (cons (car list)  rest)
-           rest))))
-
-(define (uniqued-alist  alist acc)
-  (if (null? alist) acc
-      (if (assoc (caar alist) acc)
-         (uniqued-alist (cdr alist) acc)
-         (uniqued-alist (cdr alist) (cons (car alist) acc)))))
-
-(define (uniq-list list)
-  (if (null? list) '()
-      (if (null? (cdr list))
-         list
-         (if (equal? (car list) (cadr list))
-             (uniq-list (cdr list))
-             (cons (car list) (uniq-list (cdr list)))))))
-
-(define (alist<? x y)
-  (string<? (symbol->string (car x))
-           (symbol->string (car y))))
-
-
-(define (ly-load x) (eval-string (ly-gulp-file x)))
-
-(ly-load "output-lib.scm")
-
-
-
-(use-modules (scm tex)
-            (scm ps)
-            (scm pysk)
-            (scm ascii-script)
-            (scm sketch)
-            )
-
-(define output-alist
-  `(
-    ("tex" . ,tex-output-expression)
-    ("ps" . ,ps-output-expression)
-    ("scm" . ,write)
-    ("as" . ,as-output-expression)
-    ("pysk" . ,pysk-output-expression)
-    ("sketch" . ,sketch-output-expression)
-))
-
-
-(define (find-dumper format )
-  (let*
-      ((d (assoc format output-alist)))
-    
-    (if (pair?  d)
-               (cdr d)
-            scm-output-expression)
-           ))
-
-
-(if (not standalone)
-    (map ly-load
-                                       ; load-from-path
-        '("output-lib.scm"
-          "pdf.scm"
-          "pdftex.scm"
-          "c++.scm"
-          "grob-property-description.scm"
-          "translator-property-description.scm"
-          "context-description.scm"
-          "interface-description.scm"
-          "beam.scm"
-          "clef.scm"
-          "slur.scm"
-          "font.scm"
-          "music-functions.scm"
-          "music-property-description.scm"
-          "auto-beam.scm"
-          "generic-property.scm"
-          "basic-properties.scm"
-          "chord-name.scm"
-          "grob-description.scm"
-          "script.scm"
-          "drums.scm"
-          "midi.scm"
-          )))
 
+;; gettext wrapper for guile < 1.7.2
+(if (defined? 'gettext)
+    (define-public _ gettext)
+    (define-public _ ly:gettext))
+
+(define-public (ly:load x)
+  (let* ((fn (%search-load-path x)))
+    (if (ly:get-option 'verbose)
+       (format (current-error-port) "[~A]" fn))
+    (primitive-load fn)))
+
+(define-public TEX_STRING_HASHLIMIT 10000000)
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(define (type-check-list location signature arguments)
+  "Typecheck a list of arguments against a list of type
+predicates. Print a message at LOCATION if any predicate failed."
+  (define (recursion-helper signature arguments count) 
+    (define (helper pred? arg count) 
+      (if (not (pred? arg))
+
+         (begin
+           (ly:input-message
+            location
+            (format
+             #f (_ "wrong type for argument ~a.  Expecting ~a, found ~s")
+             count (type-name pred?) arg))
+           #f)
+         #t))
+
+    (if (null? signature)
+       #t
+       (and (helper (car signature) (car arguments) count)
+            (recursion-helper (cdr signature) (cdr arguments) (1+ count)))))
+  (recursion-helper signature arguments 1))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;  output
+
+
+;;(define-public (output-framework) (write "hello\n"))
+
+(define output-tex-module
+  (make-module 1021 (list (resolve-interface '(scm output-tex)))))
+(define output-ps-module
+  (make-module 1021 (list (resolve-interface '(scm output-ps)))))
+
+(define-public (ps-output-expression expr port)
+  (display (eval expr output-ps-module) port))
+
+;; TODO: generate this list by registering the stencil expressions
+;;       stencil expressions should have docstrings.
+(define-public (ly:all-stencil-expressions)
+  "Return list of stencil expressions."
+  '(beam
+    bezier-sandwich
+    blank
+    bracket
+    char
+    dashed-line
+    dashed-slur
+    dot
+    draw-line
+    ez-ball
+    filledbox
+    glyph-string
+    horizontal-line
+    named-glyph
+    polygon
+    repeat-slash
+    round-filled-box
+    text
+    url-link
+    white-dot
+    white-text
+    embedded-ps
+    zigzag-line))
+
+;; TODO:
+;;  - generate this list by registering the output-backend-commands
+;;    output-backend-commands should have docstrings.
+;;  - remove hard copies in output-ps output-tex
+(define-public (ly:all-output-backend-commands)
+  "Return list of output backend commands."
+  '(
+    comment
+    grob-cause
+    no-origin
+    placebox
+    unknown))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Safe definitions utility
+(define safe-objects (list))
+
+(define-macro (define-safe-public arglist . body)
+  "Define a variable, export it, and mark it as safe, ie usable in LilyPond safe mode.
+The syntax is the same as `define*-public'."
+  (define (get-symbol arg)
+    (if (pair? arg)
+        (get-symbol (car arg))
+        arg))
+  (let ((safe-symbol (get-symbol arglist)))
+    `(begin
+       (define*-public ,arglist
+         ,@body)
+       (set! safe-objects (cons (cons ',safe-symbol ,safe-symbol)
+                                safe-objects))
+       ,safe-symbol)))
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; other files.
+
+(for-each ly:load
+         ;; load-from-path
+         '("lily-library.scm"
+           "file-cache.scm"
+           "define-music-types.scm"
+           "output-lib.scm"
+           "c++.scm"
+           "chord-ignatzek-names.scm"
+           "chord-entry.scm"
+           "chord-generic-names.scm"
+           "stencil.scm"
+           "new-markup.scm"
+           "bass-figure.scm"
+           "music-functions.scm"
+           "part-combiner.scm"
+           "define-music-properties.scm"
+           "auto-beam.scm"
+           "chord-name.scm"
+
+           "ly-from-scheme.scm"
+           
+           "define-context-properties.scm"
+           "translation-functions.scm"
+           "script.scm"
+           "midi.scm"
+           "beam.scm"
+           "clef.scm"
+           "slur.scm"
+           "font.scm"
+           "encoding.scm"
+           
+           "fret-diagrams.scm"
+           "define-markup-commands.scm"
+           "define-grob-properties.scm"
+           "define-grobs.scm"
+           "define-grob-interfaces.scm"
+           "page-layout.scm"
+           "titling.scm"
+           
+           "paper.scm"
+           "backend-library.scm"
+                                       ; last:
+           "safe-lily.scm"))
+
+
+(set! type-p-name-alist
+      `(
+       (,boolean-or-symbol? . "boolean or symbol")
+       (,boolean? . "boolean")
+       (,char? . "char")
+       (,grob-list? . "list of grobs")
+       (,hash-table? . "hash table")
+       (,input-port? . "input port")
+       (,integer? . "integer")
+       (,list? . "list")
+       (,ly:context? . "context")
+       (,ly:dimension? . "dimension, in staff space")
+       (,ly:dir? . "direction")
+       (,ly:duration? . "duration")
+       (,ly:grob? . "layout object")
+       (,ly:input-location? . "input location")
+       (,ly:moment? . "moment")
+       (,ly:music? . "music")
+       (,ly:pitch? . "pitch")
+       (,ly:translator? . "translator")
+       (,ly:font-metric? . "font metric")
+       (,markup-list? . "list of markups")
+       (,markup? . "markup")
+       (,ly:music-list? . "list of music")
+       (,number-or-grob? . "number or grob")
+       (,number-or-string? . "number or string")
+       (,number-pair? . "pair of numbers")
+       (,number? . "number")
+       (,output-port? . "output port")   
+       (,pair? . "pair")
+       (,procedure? . "procedure") 
+       (,scheme? . "any type")
+       (,string? . "string")
+       (,symbol? . "symbol")
+       (,vector? . "vector")))
+
+
+;; debug mem leaks
+
+(define gc-protect-stat-count 0)
+(define-public (dump-gc-protects)
+  (set! gc-protect-stat-count (1+ gc-protect-stat-count))
+  (let* ((protects (sort
+                   (hash-table->alist (ly:protects))
+                   (lambda (a b)
+                     (< (object-address (car a))
+                        (object-address (car b))))))
+        (out-file-name (string-append
+                        "gcstat-" (number->string gc-protect-stat-count)
+                        ".scm"))
+        (outfile    (open-file  out-file-name  "w")))
+
+    (display "Dumping gc protected objs to ...\n")
+    (display
+     (filter
+      (lambda (x) (not (symbol? x))) 
+      (map (lambda (y)
+            (let ((x (car y))
+                  (c (cdr y)))
+
+              (string-append
+               (string-join
+                (map object->string (list (object-address x) c x))
+                " ")
+               "\n")))
+          protects))
+     outfile)))
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(define-public (lilypond-main files)
+  "Entry point for LilyPond."
+  (let* ((failed '())
+        (handler (lambda (key . arg) (set! failed (append arg failed)))))
+    (for-each
+     (lambda (f)
+       (catch 'ly-file-failed (lambda () (ly:parse-file f))
+             (lambda (x) (handler x f)))
+       (if #f
+          (dump-gc-protects)))
+     files)
+    
+    (if (pair? failed)
+       (begin
+         (newline (current-error-port))
+         (display (_ "error: failed files: ") (current-error-port))
+         (display (string-join failed) (current-error-port))
+         (newline (current-error-port))
+         (newline (current-error-port))
+         (exit 1))
+       (exit 0))))
+
+(define-public (tweak-grob-property grob sym val)
+  (set! (ly:grob-property grob sym) val))