small.scm 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. ; Copyright (c) 1993-2008 by Richard Kelsey and Jonathan Rees. See file COPYING.
  2. ; Minimal full-I/O test system
  3. (define (start arg in-channel out-channel error-channel)
  4. (set! *error-channel* error-channel)
  5. (set-exception-handlers! exception-handlers)
  6. (let* ((ch (open-channel "small-test.image"
  7. "small-test.image"
  8. (enum open-channel-option input-file)
  9. #f))
  10. (out (output-channel->port out-channel))
  11. (in (input-channel->port in-channel)))
  12. (write-string "Hello " out)
  13. (collect)
  14. (if (< 0 (vector-length arg))
  15. (write-block (vector-ref arg 0)
  16. 0
  17. (string-length (vector-ref arg 0))
  18. out))
  19. (newline out)
  20. (force-output out)
  21. (let ((b (make-string 12 #\space)))
  22. (channel-read b 0 12 ch)
  23. (close-channel ch)
  24. (write-string b out)
  25. (newline out)
  26. (force-output out))
  27. (write-string "Eight chars> " out)
  28. (force-output out)
  29. (do ((i 0 (+ i 1)))
  30. ((= i 8))
  31. (write-char (peek-char in) out)
  32. (read-char in))
  33. (newline out)
  34. (force-output out)
  35. (write-image "small-test.image" start "A small image")
  36. 0))
  37. (define buffer-size 4) ; for testing
  38. (define (output-channel->port channel)
  39. (make-port #f
  40. 'text-codec
  41. #f
  42. (bitwise-ior (arithmetic-shift 1 (enum port-status-options
  43. output))
  44. (arithmetic-shift 1 (enum port-status-options
  45. open-for-output)))
  46. #f ; lock
  47. channel
  48. (make-byte-vector buffer-size 0)
  49. 0 buffer-size
  50. #f #f))
  51. (define (input-channel->port channel)
  52. (make-port #f
  53. 'text-codec
  54. #f
  55. (bitwise-ior (arithmetic-shift 1 (enum port-status-options
  56. input))
  57. (arithmetic-shift 1 (enum port-status-options
  58. open-for-input)))
  59. #f ; lock
  60. channel
  61. (make-byte-vector buffer-size 0)
  62. 0 buffer-size
  63. #f #f))
  64. (define *error-channel* #f)
  65. (define (error string . stuff)
  66. (channel-write-string string *error-channel*)
  67. (channel-newline *error-channel*)
  68. (exit -1))
  69. (define (message string)
  70. (channel-write-string string *error-channel*)
  71. (channel-newline *error-channel*))
  72. (define (channel-write-string string channel)
  73. (channel-write string
  74. 0
  75. (string-length string)
  76. channel))
  77. (define (channel-newline channel)
  78. (channel-write-string "
  79. " channel))
  80. (define (define-vm-exception-handler opcode proc)
  81. (vector-set! vm-exception-handlers opcode proc))
  82. (define vm-exception-handlers
  83. (make-vector op-count #f))
  84. (define-vm-exception-handler (enum op write-char)
  85. (lambda (opcode reason char port)
  86. (cond ((= reason (enum exception buffer-full/empty))
  87. (force-output port)
  88. (message "[overflow]")
  89. (write-char char port))
  90. (else
  91. (apply signal-vm-exception opcode reason args)))))
  92. (define-vm-exception-handler (enum op read-char)
  93. (lambda (opcode reason port)
  94. (cond ((= reason (enum exception buffer-full/empty))
  95. (fill-buffer port)
  96. (message "[underflow]")
  97. (read-char port))
  98. (else
  99. (apply signal-vm-exception opcode reason args)))))
  100. (define-vm-exception-handler (enum op peek-char)
  101. (lambda (opcode reason port)
  102. (cond ((= reason (enum exception buffer-full/empty))
  103. (fill-buffer port)
  104. (message "[underflow]")
  105. (peek-char port))
  106. (else
  107. (apply signal-vm-exception opcode reason args)))))
  108. (define-vm-exception-handler (enum op write-block)
  109. (lambda (opcode reason thing start count port)
  110. (cond ((= reason (enum exception buffer-full/empty))
  111. (force-output port)
  112. (write-buffer thing start count (port-data port)))
  113. (else
  114. (apply signal-vm-exception opcode reason args)))))
  115. (define (force-output port)
  116. (write-buffer (port-out-buffer port) 0 (port-out-index port) (port-data port))
  117. (set-port-out-index! port 0))
  118. (define (write-buffer buffer start count channel)
  119. (let loop ((start start) (count count))
  120. (let ((sent (channel-write buffer start count channel)))
  121. (if (< sent count)
  122. (loop (+ start sent) (- count sent))))))
  123. (define (fill-buffer port)
  124. (let ((got (channel-read (port-in-buffer port)
  125. 0
  126. (code-byte-length (port-in-buffer port))
  127. (port-data port))))
  128. (cond ((= got 0)
  129. (fill-buffer port))
  130. (else
  131. (set-port-in-index! port 0)
  132. (set-port-in-limit! port got)))))
  133. (define (write-string string port)
  134. (let ((l (string-length string)))
  135. (do ((i 0 (+ i 1)))
  136. ((= i l))
  137. (write-char (string-ref string i) port))))
  138. (define (newline port)
  139. (write-char #\newline port))