;;; -*- Mode: Common-Lisp; Package: User; Base: 10.; Patch-File: T -*-
;;; Written 04/12/88 12:54:47 by WALTON,
;;; Reason: Fixes handling of multiple successive newline characters in a file.
;;; Code readers : LER and CRW
;;; while running on CHARLIE from band LODA
;;; With SYSTEM 4.57, VIRTUAL-MEMORY 4.1, EH 4.2, MAKE-SYSTEM 4.4, MICRONET 4.4, Experimental LOCAL-FILE 4.0,
;;;  BASIC-PATHNAME 4.10, DISK-IO 4.6, Experimental DISK-LABEL 4.0, BASIC-FILE 4.6,
;;;  MAC-PATHNAME 4.3, Experimental NETWORK-PATHNAME 4.0, COMPILER 4.7, NETWORK-NAMESPACE 4.3,
;;;  TV 4.73, DATALINK 4.14, CHAOSNET 4.15, GC 4.3, Experimental MEMORY-AUX 4.0, NVRAM 4.4,
;;;  Experimental SYSLOG 4.0, Experimental STREAMER-TAPE 4.2, UCL 4.1, Experimental INPUT-EDITOR 4.0,
;;;  METER 4.3, ZWEI 4.17, DEBUG-TOOLS 4.2, NETWORK-SUPPORT 4.5, Experimental NETWORK-SERVICE 4.0,
;;;  Experimental DATALINK-DISPLAYS 4.0, Experimental FONT-EDITOR 4.0, Experimental SERIAL 4.0,
;;;  PRINTER 4.7, Experimental PRINTER-TYPES 4.2, Experimental IMAGEN 4.0, Experimental SUGGESTIONS 4.0,
;;;  MAIL-DAEMON 4.6, MAIL-READER 4.5, TELNET 4.1, VT100 4.4, NAMESPACE-EDITOR 4.5,
;;;  PROFILE 4.4, VISIDOC 4.4, NAMESPACE 4.18, NETWORK-SUPPORT-COLD 4.1, IP 3.12,
;;;  Experimental BUG 10.0, Experimental KERMIT 3.8,  microcode 528, Band Name: pre 4.1 + IP 4/11

#!C
; From file KERMIT.LISP#> PUBLIC.KERMIT; SYS:
#10R KERMIT#:
(COMPILER-LET ((*PACKAGE* (FIND-PACKAGE "KERMIT"))
                          (SI:*LISP-MODE* :COMMON-LISP)
                          (*READTABLE* SYS:COMMON-LISP-READTABLE)
                          (SI:*READER-SYMBOL-SUBSTITUTIONS* SYS::*COMMON-LISP-SYMBOL-SUBSTITUTIONS*))
  (COMPILER#:PATCH-SOURCE-FILE "SYS: PUBLIC.KERMIT; KERMIT.#"


(DEFUN BUFILL (BUFFER FILEPOINTER)
  "Fill a packet buffer with data from a file.
   Input parameters are the buffer in which to place the file data,
   and a file pointer from which to read the data.  As a result of
   processing, BUFFER is filled and the position in FILEPOINTER is
   advanced.  Returned value is the length of the buffer.
   K*BUFILLPTR and K*BUFILLBUF are used to buffer the file data
   for look-ahead processing."
  
  (DECLARE (SPECIAL K*BUFILLBUF K*BUFILLPTR K*YOURMAXPACSIZ K*YOURQUOTE
		    K*REPEAT K*BINQUOTE K*FILE-CHARS))
  (LET
    ((7-CHAR NIL)
     (8-CHAR NIL)
     (EOF NIL)
     (INDEX 0)
     (TMPBUFILLPTR NIL)
     (LENBUFILLBUF (LENGTH K*BUFILLBUF))
     (ACTUALMAXPACSIZ (- K*YOURMAXPACSIZ 8))
     (QUOTABLES (LIST K*YOURQUOTE
		      (WHEN (NOT (= K*BINQUOTE *ASCII-N*)) K*BINQUOTE)
		      (WHEN (NOT (= K*REPEAT *ASCII-SP*)) K*REPEAT))))
    
    (LOOP
      UNTIL (OR (>= INDEX  ACTUALMAXPACSIZ) EOF)	; Until we exceed length of the packet or are at EOF
      
      WHEN (= K*BUFILLPTR LENBUFILLBUF)		; When we run out of data in the buffer
      DO
      (SETQ K*BUFILLPTR 0)				; Reset the pointer
      (WHEN (ZEROP (SEND FILEPOINTER :STRING-IN NIL K*BUFILLBUF))	; and get more
	(SETQ EOF T))				; If no more, set EOF
      (SETQ LENBUFILLBUF (LENGTH K*BUFILLBUF))	; Newly filled buffer so get the length
      ELSE
      DO
      (SETQ 8-CHAR (AREF K*BUFILLBUF K*BUFILLPTR))	; Get the next character from the file buffer
      (INCF K*BUFILLPTR)				; Increment the pointer
      (INCF K*FILE-CHARS)                       ; Increment the total number of file chars read
      
      (WHEN (AND (NOT (= K*REPEAT *ASCII-SP*))	; If we have agreed to do repeat processing,
		 (NOT (EQUAL 8-CHAR #\NEWLINE)))   ; and we are not processing a newline character,
	(SETQ TMPBUFILLPTR K*BUFILLPTR)			; handle the repeat characters
	(LOOP					; Loop until
	  UNTIL (OR (= TMPBUFILLPTR LENBUFILLBUF)       ; either we run out of chars from the buffer 
		    (NOT (= 8-CHAR (AREF K*BUFILLBUF TMPBUFILLPTR)))) ; or we get one that's not equal to 8-char
	  DO (INCF TMPBUFILLPTR))
	(SETQ TMPBUFILLPTR (1+ (- TMPBUFILLPTR K*BUFILLPTR)))	; We repeat the char TMPBUFILLPTR times
	(WHEN (> TMPBUFILLPTR 3)			; If this is more than 3, do repeat prefixing!
	  (WHEN (> TMPBUFILLPTR 94) (SETQ TMPBUFILLPTR 94))	; Also, truncate the number of repeats to 94
	  (SETF (AREF BUFFER INDEX) K*REPEAT)	; Put repeat character in the packet
	  (INCF INDEX)				; Increment
	  (SETF (AREF BUFFER INDEX) (TOCHAR TMPBUFILLPTR))	; Put my repeat count in the packet
	  (INCF INDEX)				; Increment
	  (SETQ K*BUFILLPTR (+ K*BUFILLPTR TMPBUFILLPTR -1))	; adjust the buffer index for the next character
	  (SETQ K*FILE-CHARS (+ K*FILE-CHARS TMPBUFILLPTR -1)))) ; Adjust the total file chars read
     
      (WHEN (AND (NOT (= K*BINQUOTE *ASCII-N*))	; Handle 8-bit quoting
		 (> 8-CHAR *ASCII-DEL*))	; If the 8-bit char is > 127
	(SETF (AREF BUFFER INDEX) K*BINQUOTE)	; Put K*BINQUOTE in buffer
	(INCF INDEX))				; Increment
       
      (WHEN (NOT *IMAGE*)			; As long as we're not in image mode
	(SETQ 8-CHAR (CONVERT-TO-ASCII 8-CHAR)))	; force characters to ASCII 
      
      (SETQ 7-CHAR (LOGAND 8-CHAR #b1111111))	; Get low order 7 bits - #b1111111 is #o177

      (WHEN (OR (< 7-CHAR *ASCII-SP*)		; Does char require special handling?
		(MEMBER 7-CHAR QUOTABLES)
		(= 7-CHAR *ASCII-DEL*))
	
	(WHEN (AND (= 7-CHAR *ASCII-CR*)	; Map CR->CRLF when
		   (NOT *IMAGE*))		; not in image mode
	  (SETF (AREF BUFFER INDEX) K*YOURQUOTE)	; Put K*YOURQUOTE in buffer
	  (INCF INDEX)				; Increment
	  (SETF (AREF BUFFER INDEX) (CTL *ASCII-CR*))	; Put the character in buffer
	  (INCF INDEX)				; Increment
	  (SETQ 8-CHAR *ASCII-LF*)		; Replace the char with a linefeed
	  (SETQ 7-CHAR (LOGAND 8-CHAR #b1111111)))	; Get low order 7 bits - #b1111111 is #o177
	
	(SETF (AREF BUFFER INDEX) K*YOURQUOTE)	; Put K*YOURQUOTE in buffer
	(INCF INDEX)				; Increment
	
	(WHEN					; Make printable characters
	  (NOT(MEMBER 7-CHAR QUOTABLES))        ; As long as it's not the active quote, binquote or repeat 
	  (SETQ 7-CHAR (CTL 7-CHAR))
	  (SETQ 8-CHAR (CTL 8-CHAR))))
      
      (IF *IMAGE*
	  (SETF (AREF BUFFER INDEX) 8-CHAR)
	  (SETF (AREF BUFFER INDEX) 7-CHAR))
      (INCF INDEX))
    
    (SETF (FILL-POINTER BUFFER) INDEX)
    INDEX))					; Return the index

))
