home *** CD-ROM | disk | FTP | other *** search
- ; Format input lines to standard output
-
- INCLUDE "/include/init.i"
-
- ; OPT D+
-
- ; Local Equs
-
- FormatBufSize EQU 1500
- MaxLineSize EQU 512
- MaxFormatArgs EQU 20
-
- ; Variable storage
-
- STRUCT ArgArray,(1+1)*4
- STRUCT ArgStream,MaxFormatArgs*4
- STRUCT FormatClipInfo,2*4
- LONG StdIn
- LONG StdOut
- LONG FormatBufPtr
- SIZE
-
- ; Regs
-
- ByteFetch EQUR D4
- ReadBytesLeft EQUR D5
- LineBufPtr EQUR D6
- LineBufLeft EQUR D7
- LineEndPtr EQUR A2
- ErrorStrPtr EQUR A4
-
- ; Startup
-
- STACK 4000
- INIT
-
- ; Let ARP interpret the commandline
-
- MOVE.L ComLineBase(GP),A0
- MOVE.L ComLineSize(GP),D0
- LEA HelpMsg(PC),A1
- LEA ArgArray(GP),A2
- LEA Template(PC),A3
- MOVE.L A1,(A2)
- CALL GADS
- MOVE.L (A2),ErrorStrPtr
- TST.L D0
- BEQ ErrorExit
- BMI ErrorExit
-
- ; Open the standard input & output
-
- CALL Input
- MOVE.L D0,StdIn(GP)
- CALL Output
- MOVE.L D0,StdOut(GP)
-
- ; Alloc tracked mem for the string format buffer.
-
- LEA OutOfMem(PC),ErrorStrPtr
- MOVE.L #FormatBufSize,D0
- MOVEQ #0,D1
- CALL ArpAllocMem
- MOVE.L D0,FormatBufPtr(GP)
- BEQ ErrorExit
-
- ; Allocate the read-line buffer
-
- MOVE.L #MaxLineSize+4+MaxLineSize,D0 ; 2 part buf with 0 term space.
- MOVEQ #0,D1
- CALL ArpAllocMem
- MOVE.L D0,LineBufPtr
- BEQ ErrorExit
-
- ; Initialize the argument stream
-
- MOVEQ #MaxFormatArgs-1,D0
- LEA ArgStream(GP),A0
- InitArgStreamLongs:
- MOVE.L LineBufPtr,(A0)+
- DBRA D0,InitArgStreamLongs
-
-
- ; ** This is an intelligent ReadLine routine.
-
- MOVEQ #0,ReadBytesLeft
-
- ; Reinitialize the line buffer. (First part of dual buffer space)
-
- DoForEachLine:
- LEA ReadError(PC),ErrorStrPtr
- MOVE.L LineBufPtr,LineEndPtr
- MOVE.L #MaxLineSize,LineBufLeft
-
- ; Extract lines from the readbuffer into the line buffer.
-
- BRA.S ExtractEntry
- CopyLineBytes:
- MOVE.L ByteFetch,A0
- ADDQ.L #1,ByteFetch
- SUBQ.L #1,ReadBytesLeft
- MOVE.B (A0),D0
- CMP.B #10,D0
- BEQ.S GotLine
- MOVE.B D0,(LineEndPtr)+
- SUBQ.L #1,LineBufLeft
- BEQ.S GotLine
- ExtractEntry:
- TST.L ReadBytesLeft
- BNE CopyLineBytes
-
- ; Refill the read buffer.
-
- MOVE.L StdIn(GP),D1
- MOVE.L LineBufPtr,D2
- MOVE.L #MaxLineSize,D3
- ADD.L D3,D2
- ADDQ.L #4,D2
- CALL Read
- TST.L D0
- BMI.S ErrorExit
- BNE.S NotYetDone
- CMP.L LineBufPtr,LineEndPtr
- BEQ.S Exit
- NotYetDone:
- MOVE.L D2,ByteFetch
- MOVE.L D0,ReadBytesLeft
- BNE CopyLineBytes
-
- ; Null terminate the line.
-
- GotLine:
- CLR.B (LineEndPtr)
-
- ; Format things, terminate with a LF, and write the format buffer
-
- BSR.S VanillaDoFmt
- MOVE.L FormatBufPtr(GP),A0
- MOVE.B #10,-1(A0,D0.L)
-
- LEA WriteError(PC),ErrorStrPtr
- MOVE.L StdOut(GP),D1
- MOVE.L A0,D2
- MOVE.L D0,D3
- BEQ.S WriteDone
- CALL Write
- CMP.L D0,D3
- BNE.S ErrorExit
- WriteDone:
-
- ; Check if user hit ^C
-
- SUB.L A1,A1
- CALL CheckAbort
- MOVE.L A1,ErrorStrPtr
- TST.L D0
- BNE.S ErrorExit
- BRA DoForEachLine
-
- ; Done, cleanup
-
- Exit:
- CLR.W ReturnCode(GP)
- SUB.L ErrorStrPtr,ErrorStrPtr
- ErrorExit:
-
- ; Display error string, if any, and exit
-
- MOVE.L ErrorStrPtr,D0
- BEQ.S NoErrorMsg
- MOVE.L D0,A1
- CALL Puts
- NoErrorMsg:
- RTS
-
- ; Subroutines
-
- ; This sub uses exec's RawDoFmt to do string formatting while clipping
- ; any surplus data to fit the buffer size. Arps format routines have
- ; no overflow checks, and since the user is not guaranteed to act
- ; sanely, clipping is essential.
- ; I : Assumes a valid format string and buffer
- ; O : The format buffer contain the formatted string.
- ; : D0.L = Size of formatted string.
-
- Vanilla_Regs REG A2/A3/A6
-
- VanillaDoFmt:
- MOVEM.L Vanilla_Regs,-(SP)
- MOVE.L ArgArray(GP),A0
- LEA ArgStream(GP),A1
- LEA DoClippedBufferFill(PC),A2
- LEA FormatClipInfo(GP),A3
- MOVE.L FormatBufPtr(GP),(A3)
- MOVE.L (A3),4(A3)
- ADD.L #FormatBufSize,4(A3)
- MOVE.L $4.W,A6 ; exec
- CALL RawDoFmt
- MOVE.L (A3),D0
- SUB.L FormatBufPtr(GP),D0
- MOVEM.L (SP)+,Vanilla_Regs
- RTS
-
- ; Assumes A0 is usable, not clear from autodocs whether this is true.
- ; (Default calling conventions and ROM code suggest it is)
-
- DoClippedBufferFill:
- MOVE.L (A3)+,A0
- CMP.L (A3),A0
- BNE.S NotYetAtBufEnd
- SUBQ.L #1,A0
- NotYetAtBufEnd:
- MOVE.B D0,(A0)+
- MOVE.L A0,-(A3)
- RTS
-
- ; The string section
-
- Template:
- DC.B 'FormatString/a',0
- HelpMsg:
- DC.B 'PForm - Pipe formatted lines.',10
- DC.B 'Usage: PForm "prefix %[width.limit]s postfix"',0
- OutOfMem:
- DC.B 'Out of memory!',0
- ReadError:
- DC.B 'Error while reading',0
- WriteError:
- DC.B 'Error while writing',0
- CNOP 0,2
-
- END
-