(##include "~~/lib/gambit#.scm")
(##include "~~/lib/_gambit#.scm")
(##include "~~/lib/r5rs#.scm")

(declare (standard-bindings)(extended-bindings)(block)(fixnum))
(declare (not safe))
(declare (inlining-limit 134))

(declare (not standard-bindings read-char peek-char write-char eof-object?))
(declare (not run-time-bindings eof-object?))


(define (ssax#peek-char port)

  (##declare (not interrupts-enabled))

  (macro-port-mutex-lock! port) ;; get exclusive access to port

    (let ((char-rlo (macro-character-port-rlo port))
          (char-rhi (macro-character-port-rhi port)))
      (if (##fixnum.< char-rlo char-rhi)

        ;; the next character is in the character read buffer

        (let ((c (##string-ref (macro-character-port-rbuf port) char-rlo)))
          (macro-port-mutex-unlock! port)
          c)

        (if (macro-character-port-peek-eof? port)

          (begin
            (macro-port-mutex-unlock! port)
            #!eof)
	  
	  (begin
	    (macro-port-mutex-unlock! port)
	    (##peek-char port))))))


(define (peek-char
	 #!optional
	 (port (macro-absent-obj)))
  (macro-force-vars (port)
    (let ((p
           (if (##eq? port (macro-absent-obj))
             (macro-current-input-port)
             port)))
      (macro-check-character-input-port p 1 (peek-char p)
        (ssax#peek-char p)))))


(define (ssax#read-char port)
  
  (##declare (not interrupts-enabled))
  
  (macro-port-mutex-lock! port) ;; get exclusive access to port
  
  (let ((char-rlo (macro-character-port-rlo port))
	(char-rhi (macro-character-port-rhi port)))
    (if (##fixnum.< char-rlo char-rhi)
	
        ;; the next character is in the character read buffer
	
        (let ((c (##string-ref (macro-character-port-rbuf port) char-rlo)))
          (if (##not (##char=? c #\newline))
	      
	      ;; frequent simple case, just advance rlo
	      
	      (begin
		(macro-character-port-rlo-set! port (##fixnum.+ char-rlo 1))
		(macro-port-mutex-unlock! port)
		c)
	      
	      (begin
		(macro-port-mutex-unlock! port)
		(##read-char port))))
	(begin
	  (macro-port-mutex-unlock! port)
	  (##read-char port)))))


(define (read-char
              #!optional
              (port (macro-absent-obj)))
  (macro-force-vars (port)
    (let ((p
           (if (##eq? port (macro-absent-obj))
             (macro-current-input-port)
             port)))
      (macro-check-character-input-port p 1 (read-char p)
        (ssax#read-char p)))))

(define (ssax#eof-object? x)
  (##eq? x #!eof))

(define (eof-object? x)
  (macro-force-vars (x)
    (ssax#eof-object? x)))

(define (ssax#write-char c port)

  (##declare (not interrupts-enabled))

  (macro-port-mutex-lock! port) ;; get exclusive access to port

  (let loop ()

    (let ((char-wbuf (macro-character-port-wbuf port))
          (char-whi+1 (##fixnum.+ (macro-character-port-whi port) 1)))
      (if (##not (##fixnum.< (##string-length char-wbuf) char-whi+1))

        ;; there is enough space in the character write buffer, so add
        ;; character and increment whi

        (let ()

          (##string-set! char-wbuf (##fixnum.- char-whi+1 1) c)

          ;; advance whi

          (macro-character-port-whi-set! port char-whi+1)

          (if (##not (##char=? c #\newline))

            ;; force output if port is set for unbuffered output

            (if (macro-unbuffered? (macro-port-woptions port))
              (begin
                (macro-port-mutex-unlock! port)
                ((macro-port-force-output port)
                 port
                 write-char
                 c
                 port
                 (macro-absent-obj)
                 (macro-absent-obj)))
              (begin
                (macro-port-mutex-unlock! port)
                (##void)))

            ;; end-of-line processing requires updating counters

            (begin

              ;; keep track of number of characters written

              (let ((char-wchars (macro-character-port-wchars port)))
                (macro-character-port-wcurline-set! port
                  (##fixnum.+ char-wchars char-whi+1)))

              ;; keep track of number of lines written

              (let ((char-wlines (macro-character-port-wlines port)))
                (macro-character-port-wlines-set! port
                  (##fixnum.+ char-wlines 1)))

              ;; force output if port is not fully buffered

              (if (##not (macro-fully-buffered?
                          (macro-port-woptions port)))
                (begin
                  (macro-port-mutex-unlock! port)
                  ((macro-port-force-output port)
                   port
                   write-char
                   c
                   port
                   (macro-absent-obj)
                   (macro-absent-obj)))
                (begin
                  (macro-port-mutex-unlock! port)
                  (##void))))))

        ;; make some space in the character buffer and try again

        (let ((code3 ((macro-character-port-wbuf-drain port) port)))
          (if (##fixnum? code3)
            (begin
              (macro-port-mutex-unlock! port)
              (if (##fixnum.= code3 ##err-code-EAGAIN)
                #f
                (##raise-os-exception #f code3 write-char c port)))
            (loop)))))))

(define (write-char
              c
              #!optional
              (port (macro-absent-obj)))
  (macro-force-vars (c port)
    (let ((p
           (if (##eq? port (macro-absent-obj))
             (macro-current-output-port)
             port)))
      (macro-check-char c 1 (write-char c port)
        (macro-check-character-output-port p 2 (write-char c p)
          (ssax#write-char c p))))))


(include "libs/gambit/common.scm")
(include "libs/gambit/myenv.scm")
(include "libs/srfi-13-local.scm")
(include "libs/util.scm")
(include "libs/gambit/parse-error.scm")
(include "libs/input-parse.scm")
(include "libs/look-for-str.scm")
(include "ssax/char-encoding.scm")
(include "ssax/SSAX-code.scm")
(include "ssax/SXML-tree-trans.scm")
(include "sxml-tools/sxpathlib.scm")
(include "multi-parser/id/srfi-12.scm")
(include "multi-parser/id/mime.scm")
(include "multi-parser/id/http.scm")
(include "multi-parser/id/access-remote.scm")
(include "multi-parser/id/id.scm")
(include "sxml-tools/xlink-parser.scm")
(include "multi-parser/ssax-prim.scm")
(include "multi-parser/multi-parser.scm")
(include "html-prag/htmlprag.scm")
(include "sxml-tools/sxml-tools.scm")
(include "sxml-tools/sxpath-ext.scm")
(include "sxml-tools/xpath-parser.scm")
(include "sxml-tools/txpath.scm")
(include "sxml-tools/sxpath.scm")
(include "sxml-tools/xpath-ast.scm")
(include "sxml-tools/xpath-context.scm")
(include "sxml-tools/xlink.scm")
(include "sxml-tools/ddo-axes.scm")
(include "sxml-tools/ddo-txpath.scm")
(include "sxml-tools/lazy-xpath.scm")
(include "ssax/lazy-ssax.scm")
(include "sxml-tools/modif.scm")
(include "sxml-tools/serializer.scm")
(include "sxml-tools/guides.scm")
(include "stx/libmisc.scm")
(include "stx/stx-engine.scm")
