small.scm 4.4 KB

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