home *** CD-ROM | disk | FTP | other *** search
/ PC Welt 2006 November (DVD) / PCWELT_11_2006.ISO / casper / filesystem.squashfs / usr / share / guile / 1.6 / ice-9 / slib-old.scm < prev    next >
Encoding:
Text File  |  2006-06-19  |  13.2 KB  |  406 lines

  1. ;;;; slib.scm --- definitions needed to get SLIB to work with Guile
  2. ;;;;
  3. ;;;;    Copyright (C) 1997, 1998, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
  4. ;;;;
  5. ;;;; This file is part of GUILE.
  6. ;;;; 
  7. ;;;; GUILE is free software; you can redistribute it and/or modify it
  8. ;;;; under the terms of the GNU General Public License as published by
  9. ;;;; the Free Software Foundation; either version 2, or (at your
  10. ;;;; option) any later version.
  11. ;;;; 
  12. ;;;; GUILE is distributed in the hope that it will be useful, but
  13. ;;;; WITHOUT ANY WARRANTY; without even the implied warranty of
  14. ;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  15. ;;;; General Public License for more details.
  16. ;;;; 
  17. ;;;; You should have received a copy of the GNU General Public License
  18. ;;;; along with GUILE; see the file COPYING.  If not, write to the
  19. ;;;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
  20. ;;;; Boston, MA 02110-1301 USA
  21. ;;;;
  22. ;;;; As a special exception, the Free Software Foundation gives permission
  23. ;;;; for additional uses of the text contained in its release of GUILE.
  24. ;;;;
  25. ;;;; The exception is that, if you link the GUILE library with other files
  26. ;;;; to produce an executable, this does not by itself cause the
  27. ;;;; resulting executable to be covered by the GNU General Public License.
  28. ;;;; Your use of that executable is in no way restricted on account of
  29. ;;;; linking the GUILE library code into it.
  30. ;;;;
  31. ;;;; This exception does not however invalidate any other reasons why
  32. ;;;; the executable file might be covered by the GNU General Public License.
  33. ;;;;
  34. ;;;; This exception applies only to the code released by the
  35. ;;;; Free Software Foundation under the name GUILE.  If you copy
  36. ;;;; code from other Free Software Foundation releases into a copy of
  37. ;;;; GUILE, as the General Public License permits, the exception does
  38. ;;;; not apply to the code that you add in this way.  To avoid misleading
  39. ;;;; anyone as to the status of such modified files, you must delete
  40. ;;;; this exception notice from them.
  41. ;;;;
  42. ;;;; If you write modifications of your own for GUILE, it is your choice
  43. ;;;; whether to permit this exception to apply to your modifications.
  44. ;;;; If you do not wish that, delete this exception notice.
  45. ;;;;
  46. (define-module (ice-9 slib)
  47.   :export (slib:load
  48.        implementation-vicinity
  49.        library-vicinity
  50.        home-vicinity
  51.        scheme-implementation-type
  52.        scheme-implementation-version
  53.        make-random-state
  54.        <? <=? =? >? >=?
  55.        require)
  56.   :no-backtrace)
  57.  
  58.  
  59.  
  60. (define (eval-load <filename> evl)
  61.   (if (not (file-exists? <filename>))
  62.       (set! <filename> (string-append <filename> (scheme-file-suffix))))
  63.   (call-with-input-file <filename>
  64.     (lambda (port)
  65.       (let ((old-load-pathname *load-pathname*))
  66.     (set! *load-pathname* <filename>)
  67.     (do ((o (read port) (read port)))
  68.         ((eof-object? o))
  69.       (evl o))
  70.     (set! *load-pathname* old-load-pathname)))))
  71.  
  72.  
  73.  
  74. (define-public slib:exit quit)
  75. (define-public slib:error error)
  76. (define-public slib:warn warn)
  77. (define-public slib:eval (lambda (x) (eval x slib-module)))
  78. (define defmacro:eval (lambda (x) (eval x (interaction-environment))))
  79. (define logical:logand logand)
  80. (define logical:logior logior)
  81. (define logical:logxor logxor)
  82. (define logical:lognot lognot)
  83. (define logical:ash ash)
  84. (define logical:logcount logcount)
  85. (define logical:integer-length integer-length)
  86. (define logical:bit-extract bit-extract)
  87. (define logical:integer-expt integer-expt)
  88. (define logical:ipow-by-squaring ipow-by-squaring)
  89. (define-public slib:eval-load eval-load)
  90. (define-public slib:tab #\tab)
  91. (define-public slib:form-feed #\page)
  92.  
  93. (define slib-module (current-module))
  94.  
  95. (define (defined? symbol)
  96.   (module-defined? slib-module symbol))
  97.  
  98. (define slib:features
  99.   (append '(source
  100.         eval
  101.         abort
  102.         alist
  103.         defmacro
  104.         delay
  105.         dynamic-wind
  106.         full-continuation
  107.         hash
  108.         hash-table
  109.         line-i/o
  110.         logical
  111.         multiarg/and-
  112.         multiarg-apply
  113.         promise
  114.         rev2-procedures
  115.         rev4-optional-procedures
  116.         string-port
  117.         with-file)
  118.  
  119.       (if (defined? 'getenv)
  120.           '(getenv)
  121.           '())
  122.  
  123.       (if (defined? 'current-time)
  124.           '(current-time)
  125.           '())
  126.  
  127.       (if (defined? 'system)
  128.           '(system)
  129.           '())
  130.  
  131.       (if (defined? 'char-ready?)
  132.           '(char-ready?)
  133.           '())
  134.  
  135.       (if (and (string->number "0.0") (inexact? (string->number "0.0")))
  136.           '(inexact)
  137.           '())
  138.  
  139.       (if (rational? (string->number "1/19"))
  140.           '(rational)
  141.           '())
  142.  
  143.       (if (real? (string->number "0.0"))
  144.           '(real)
  145.           ())
  146.  
  147.       (if (complex? (string->number "1+i"))
  148.           '(complex)
  149.           '())
  150.  
  151.       (let ((n (string->number "9999999999999999999999999999999")))
  152.         (if (and n (exact? n))
  153.         '(bignum)
  154.         '()))))
  155.  
  156.  
  157. ;; The array module specified by slib 3a1 is not the same as what guile
  158. ;; provides, so we must remove `array' from the features list.
  159. ;;
  160. ;; The main difference is `create-array' which is similar to
  161. ;; `make-uniform-array', but the `Ac64' etc prototype procedures incorporate
  162. ;; an initial fill element into the prototype.
  163. ;;
  164. ;; Believe the array-for-each module will need to be taken from slib when
  165. ;; the array module is taken from there, since what the array module creates
  166. ;; won't be understood by the guile functions.  So remove `array-for-each'
  167. ;; from the features list too.
  168. ;;
  169. ;; Also, slib 3a1 array-for-each specifies an `array-map' which is not in
  170. ;; guile (but could be implemented quite easily).
  171. ;;
  172. ;; ENHANCE-ME: It'd be nice to implement what's necessary, since the guile
  173. ;; functions should be more efficient than the implementation in slib.
  174. ;;
  175. ;; FIXME: Since the *features* variable is shared by slib and the guile
  176. ;; core, removing these feature symbols has the unhappy effect of making it
  177. ;; look like they aren't in the core either.  Let's assume that arrays have
  178. ;; been present unconditionally long enough that no guile-specific code will
  179. ;; bother to test.  An alternative would be to make a new separate
  180. ;; *features* variable which the slib stuff operated on, leaving the core
  181. ;; mechanism alone.  That might be a good thing anyway.
  182. ;;
  183. (set! *features* (delq 'array          *features*))
  184. (set! *features* (delq 'array-for-each *features*))
  185.  
  186. ;; The random module in slib 3a1 provides a `random:chunk' which is used by
  187. ;; the random-inexact module.  Guile doesn't provide random:chunk so we must
  188. ;; remove 'random from `*features*' to use the slib code.
  189. ;;
  190. ;; ENHANCE-ME: Maybe Guile could provide a `random:chunk', the rest of the
  191. ;; random module is already the same as Guile.
  192. ;;
  193. ;; FIXME: As per the array bits above, *features* is shared by slib and the
  194. ;; guile core, so removing 'random has the unhappy effect of making it look
  195. ;; like this isn't in the core.  Let's assume random numbers have been
  196. ;; present unconditionally long enough that no guile-specific code will
  197. ;; bother to test.
  198. ;;
  199. (set! *features* (delq 'random *features*))
  200.  
  201.  
  202. ;;; FIXME: Because uers want require to search the path, this uses
  203. ;;; load-from-path, which probably isn't a hot idea.  slib
  204. ;;; doesn't expect this function to search a path, so I expect to get
  205. ;;; bug reports at some point complaining that the wrong file gets
  206. ;;; loaded when something accidentally appears in the path before
  207. ;;; slib, etc. ad nauseum.  However, the right fix seems to involve
  208. ;;; changing catalog:get in slib/require.scm, and I don't expect
  209. ;;; Aubrey will integrate such a change.  So I'm just going to punt
  210. ;;; for the time being.
  211. (define (slib:load name)
  212.   (save-module-excursion
  213.    (lambda ()
  214.      (set-current-module slib-module)
  215.      (let ((errinfo (catch 'system-error
  216.                (lambda ()
  217.                  (load-from-path name)
  218.                  #f)
  219.                (lambda args args))))
  220.        (if (and errinfo
  221.         (catch 'system-error
  222.                (lambda ()
  223.              (load-from-path
  224.               (string-append name ".scm"))
  225.              #f)
  226.                (lambda args args)))
  227.        (apply throw errinfo))))))
  228.  
  229. (define-public slib:load-source slib:load)
  230. (define defmacro:load slib:load)
  231.  
  232. (define slib-parent-dir
  233.   (let* ((path (%search-load-path "slib/require.scm")))
  234.     (if path
  235.     (substring path 0 (- (string-length path) 17))
  236.     (error "Could not find slib/require.scm in " %load-path))))
  237.  
  238. (define (implementation-vicinity)
  239.   (string-append slib-parent-dir "/"))
  240. (define (library-vicinity)
  241.   (string-append (implementation-vicinity) "slib/"))
  242. (define home-vicinity
  243.   (let ((home-path (getenv "HOME")))
  244.     (lambda () home-path)))
  245. (define (scheme-implementation-type) 'guile)
  246. (define (scheme-implementation-version) "")
  247.  
  248. ;; legacy from r3rs, but slib says all implementations provide these
  249. ;; ("Legacy" section of the "Miscellany" node in the manual)
  250. (define-public t   #t)
  251. (define-public nil #f)
  252.  
  253. (define-public (output-port-width . arg) 80)
  254. (define-public (output-port-height . arg) 24)
  255. (define (identity x) x)
  256.  
  257. ;; slib 3a1 and up, straight from Template.scm
  258. (define-public (call-with-open-ports . ports)
  259.   (define proc (car ports))
  260.   (cond ((procedure? proc) (set! ports (cdr ports)))
  261.     (else (set! ports (reverse ports))
  262.           (set! proc (car ports))
  263.           (set! ports (reverse (cdr ports)))))
  264.   (let ((ans (apply proc ports)))
  265.     (for-each close-port ports)
  266.     ans))
  267.  
  268. ;; slib (version 3a1) requires open-file accept a symbol r, rb, w or wb for
  269. ;; MODES, so extend the guile core open-file accordingly.
  270. ;;
  271. ;; slib (version 3a1) also calls open-file with strings "rb" or "wb", not
  272. ;; sure if that's intentional, but in any case this extension continues to
  273. ;; accept strings to make that work.
  274. ;;
  275. (define-public open-file
  276.   (let ((guile-core-open-file open-file))
  277.     (lambda (filename modes)
  278.       (if (symbol? modes)
  279.       (set! modes (symbol->string modes)))
  280.       (guile-core-open-file filename modes))))
  281.  
  282. ;; returning #t/#f instead of throwing an error for failure
  283. (define-public delete-file
  284.   (let ((guile-core-delete-file delete-file))
  285.     (lambda (filename)
  286.       (catch 'system-error
  287.     (lambda () (guile-core-delete-file filename) #t)
  288.     (lambda args #f)))))
  289.  
  290. ;; Nothing special to do for this, so straight from Template.scm.  Maybe
  291. ;; "sensible-browser" for a debian system would be worth trying too (and
  292. ;; would be good on a tty).
  293. (define-public (browse-url url)
  294.   (define (try cmd end) (zero? (system (string-append cmd url end))))
  295.   (or (try "netscape-remote -remote 'openURL(" ")'")
  296.       (try "netscape -remote 'openURL(" ")'")
  297.       (try "netscape '" "'&")
  298.       (try "netscape '" "'")))
  299.  
  300. ;;; {Random numbers}
  301. ;;;
  302. (define (make-random-state . args)
  303.   (let ((seed (if (null? args) *random-state* (car args))))
  304.     (cond ((string? seed))
  305.       ((number? seed) (set! seed (number->string seed)))
  306.       (else (let ()
  307.           (require 'object->string)
  308.           (set! seed (object->limited-string seed 50)))))
  309.     (seed->random-state seed)))
  310.  
  311. ;;; {rev2-procedures}
  312. ;;;
  313.  
  314. (define <?  <)
  315. (define <=? <=)
  316. (define =?  =)
  317. (define >?  >)
  318. (define >=? >=)
  319.  
  320. ;;; {system}
  321. ;;;
  322.  
  323. ;; If the program run is killed by a signal, the shell normally gives an
  324. ;; exit code of 128+signum.  If the shell itself is killed by a signal then
  325. ;; we do the same 128+signum here.
  326. ;;
  327. ;; "stop-sig" shouldn't arise here, since system shouldn't be calling
  328. ;; waitpid with WUNTRACED, but allow for it anyway, just in case.
  329. ;;
  330. (if (defined? 'system)
  331.     (define-public system
  332.       (let ((guile-core-system system))
  333.     (lambda (str)
  334.       (let ((st (guile-core-system str)))
  335.         (or (status:exit-val st)
  336.         (+ 128 (or (status:term-sig st)
  337.                (status:stop-sig st)))))))))
  338.  
  339. ;;; {Time}
  340. ;;;
  341.  
  342. (define-public difftime -)
  343. (define-public offset-time +)
  344.  
  345.  
  346. (define %system-define define)
  347.  
  348. (define define
  349.   (procedure->memoizing-macro
  350.    (lambda (exp env)
  351.      (if (= (length env) 1)
  352.      `(define-public ,@(cdr exp))
  353.      `(%system-define ,@(cdr exp))))))
  354.  
  355. ;;; Hack to make syncase macros work in the slib module
  356. (if (nested-ref the-root-module '(app modules ice-9 syncase))
  357.     (set-object-property! (module-local-variable (current-module) 'define)
  358.               '*sc-expander*
  359.               '(define)))
  360.  
  361. (define (software-type)
  362.   "Return a symbol describing the current platform's operating system.
  363. This may be one of AIX, VMS, UNIX, COHERENT, WINDOWS, MS-DOS, OS/2,
  364. THINKC, AMIGA, ATARIST, MACH, or ACORN.
  365.  
  366. Note that most varieties of Unix are considered to be simply \"UNIX\".
  367. That is because when a program depends on features that are not present
  368. on every operating system, it is usually better to test for the presence
  369. or absence of that specific feature.  The return value of
  370. @code{software-type} should only be used for this purpose when there is
  371. no other easy or unambiguous way of detecting such features."
  372.  'UNIX)
  373.  
  374. (slib:load (in-vicinity (library-vicinity) "require.scm"))
  375.  
  376. (define require require:require)
  377.  
  378. ;; {Extensions to the require system so that the user can add new
  379. ;;  require modules easily.}
  380.  
  381. (define *vicinity-table*
  382.   (list
  383.    (cons 'implementation (implementation-vicinity))
  384.    (cons 'library (library-vicinity))))
  385.  
  386. (define (install-require-vicinity name vicinity)
  387.   (let ((entry (assq name *vicinity-table*)))
  388.     (if entry
  389.     (set-cdr! entry vicinity)
  390.     (set! *vicinity-table*
  391.           (acons name vicinity *vicinity-table*)))))
  392.  
  393. (define (install-require-module name vicinity-name file-name)
  394.   (if (not *catalog*)         ;Fix which loads catalog in slib
  395.       (catalog:get 'random)) ;(doesn't load the feature 'random)
  396.   (let ((entry (assq name *catalog*))
  397.     (vicinity (cdr (assq vicinity-name *vicinity-table*))))
  398.     (let ((path-name (in-vicinity vicinity file-name)))
  399.       (if entry
  400.       (set-cdr! entry path-name)
  401.       (set! *catalog*
  402.         (acons name path-name *catalog*))))))
  403.  
  404. (define (make-exchanger obj)
  405.   (lambda (rep) (let ((old obj)) (set! obj rep) old)))
  406.