	opt	AMIGA

;* $Revision Header built automatically *************** (do not edit) ************
;*
;* © Copyright by F.Delacroix
;*
;* File             : DH0{42MB}:Progs/ErrorMsg/Examples/ScanIFF.s
;* Created on       : Jeudi, 27-Oct-94   21:12:46
;* Created by       : Frédéric Delacroix
;* Current revision : V1.00
;*
;*
;* Purpose
;* -------
;*     This is an example for programming errormsg.library, it is
;*     public domain. Its job is to scan an IFF file and list all
;*     the chunks it contains. Use from CLI only. Added for V3.02
;*     on request by B.Beauchamp and F.Jardillier.
;*
;* Revision V1.00
;* --------------
;*     --- Initial release ---
;*
;*********************************************************************************
REVISION  MACRO
          dc.b "1.00"
          ENDM
REVDATE   MACRO
          dc.b "27-Oct-94"
          ENDM
REVTIME   MACRO
          dc.b "21:12:46"
          ENDM
AUTHOR    MACRO
          dc.b "Frédéric Delacroix"
          ENDM
VERNUM    EQU  01
REVNUM    EQU  00

	include	exec/execbase.i
	include	dos/dosasl.i
	include	libraries/errormsg.i
	include	libraries/errormsg_lib.i
	include	libraries/iffparse.i
	include	libraries/iffparse_lib.i

Start	move.l	4.w,a6
	move.l	ThisTask(a6),a4
	tst.l	pr_CLI(a4)
	bne.s	.FromCLI
	lea	pr_MsgPort(a4),a0
	jsr	_LVOWaitPort(a6)
	lea	pr_MsgPort(a4),a0
	jsr	_LVOGetMsg(a6)
	move.l	d0,WB.Startup
	bra.s	.Exit
.FromCLI
	move.l	a6,Exec.Base
	lea	ErrorMsg.Name(pc),a1
	moveq	#4,d0	; we use ermOpenLibraryIDA() => version 4 !
	jsr	_LVOOpenLibrary(a6)
	move.l	d0,ErrorMsg.Base
	beq.s	.Exit
	move.l	#ERMSYS_IFFPARSE,d1
	moveq	#37,d0
	lea	IFFParse.Base(pc),a0
	bsr.s	OpenLibID
	beq.s	.CloseERM

	bsr.s	ReadArgs
	beq.s	.CloseIFFParse
	bsr	Scan
	bsr	FreeArgs

.CloseIFFParse
	move.l	IFFParse.Base(pc),a1
	jsr	_LVOCloseLibrary(a6)
.CloseERM
	move.l	ErrorMsg.Base(pc),a1
	jsr	_LVOCloseLibrary(a6)
.Exit	move.l	WB.Startup(pc),d0
	beq.s	.ToCLI
	jsr	_LVOForbid(a6)
	move.l	d0,a1
	jsr	_LVOReplyMsg(a6)
.ToCLI	moveq	#0,d0
	rts

OpenLibID	; (D0,Z)Base=OpenLib(LibID,Version,Storage)(D1,D0,A0)
	movem.l	a2/a6,-(sp)
	suba.l	a2,a2
	move.l	ErrorMsg.Base(pc),a6
	jsr	_LVOermOpenLibraryIDA(a6)
.Good	movem.l	(sp)+,a2/a6
	rts

PrintError	; PrintError(Code,System,Subsystem)(D0,D1,D2)
	move.l	a6,-(sp)
	move.l	ErrorMsg.Base(pc),a6
	tst.l	Req.Arg
	bne.s	.Req
	lea	ScanIFF.Name(pc),a0
	jsr	_LVOPutErrorMsg(a6)
	bra.s	.Done
.Req	suba.l	a0,a0
	jsr	_LVODisplayErrorMsgA(a6)
.Done	move.l	(sp)+,a6
	rts

ReadArgs	; (Z=1)Success=ReadArgs()
	movem.l	d2-d3/a6,-(sp)
	move.l	ErrorMsg.Base(pc),a6
	move.l	emb_DOSBase(a6),a6
	move.l	#Args.Template,d1
	move.l	#Args.Array,d2
	moveq	#0,d3
	jsr	_LVOReadArgs(a6)
	move.l	d0,Args.RDArgs
	bne.s	.OK
	move.l	#ERMSYS_DOS,d1
	move.l	#ERMSUB_IoErr,d2
	bsr	PrintError
	moveq	#0,d0
.OK	movem.l	(sp)+,d2-d3/a6
	rts

FreeArgs	; FreeArgs()
	move.l	a6,-(sp)
	move.l	ErrorMsg.Base(pc),a6
	move.l	emb_DOSBase(a6),a6
	move.l	Args.RDArgs(pc),d1
	jsr	_LVOFreeArgs(a6)
	move.l	(sp)+,a6
	rts

Scan	; Scan()
	movem.l	d2-d3/a4/a6,-(sp)
	move.l	IFFParse.Base(pc),a6
	jsr	_LVOAllocIFF(a6)
	move.l	d0,a4
	move.l	a4,d0
	bne.s	.HandleOK
	move.l	#ERMSYS_EXEC,d1
	move.l	#ERMSUB_NoMemory,d2
	bsr	PrintError
	bra	.Ret
.HandleOK
	move.l	a4,a0
	jsr	_LVOInitIFFasDOS(a6)

	move.l	ErrorMsg.Base(pc),a6
	move.l	emb_DOSBase(a6),a6
	move.l	FileName.Arg(pc),d1
	move.l	#MODE_OLDFILE,d2
	jsr	_LVOOpen(a6)
	move.l	d0,iff_Stream(a4)
	bne.s	.FileOK
	move.l	#ERMSYS_DOS,d1
	move.l	#ERMSUB_IoErr,d2
	bsr	PrintError
	bra	.FreeHandle
.FileOK
	move.l	IFFParse.Base(pc),a6
	move.l	a4,a0
	move.l	#IFFF_READ,d0
	jsr	_LVOOpenIFF(a6)
	tst.l	d0
	beq.s	.OpenOK
	move.l	#ERMSYS_IFFPARSE,d1
	move.l	#ERMSUB_Generic,d2
	bsr	PrintError
	bra	.CloseFile
.OpenOK	moveq	#0,d3
.Loop	move.l	a4,a0
	move.l	#IFFPARSE_STEP,d0
	jsr	_LVOParseIFF(a6)
	cmp.l	#IFFERR_EOF,d0
	beq	.End
	tst.l	d0
	beq.s	.Push
	cmp.l	#IFFERR_EOC,d0
	beq.s	.Pop
	move.l	#ERMSYS_IFFPARSE,d1
	move.l	#ERMSUB_Generic,d2
	bsr	PrintError
	bra	.End
.Pop	subq.l	#1,d3	; ident amount
	bsr	CheckBreak
	beq	.Loop
	move.l	#ERROR_BREAK,d0
	move.l	#ERMSYS_DOS,d1
	move.l	#ERMSUB_IoErr,d2
	bsr	PrintError
	bra.s	.End
.Push	move.l	a4,a0
	jsr	_LVOCurrentChunk(a6)
	move.l	d0,a0
	move.l	a0,d0
	beq.s	.Loop
	bsr	Indent
	beq.s	.DOSError
	move.l	cn_ID(a0),ID.MSG
	move.l	cn_Type(a0),Type.MSG
	move.l	cn_Size(a0),-(sp)
	pea	Type.MSG
	pea	ID.MSG
	move.l	#Chunk.Fmt,d1
	move.l	sp,d2
	move.l	ErrorMsg.Base(pc),a6
	move.l	emb_DOSBase(a6),a6
	jsr	_LVOVPrintf(a6)
	add.l	#12,sp
	addq.l	#1,d3
	move.l	IFFParse.Base(pc),a6
	cmp.l	#-1,d0
	bne	.Loop
.DOSError
	move.l	#ERMSYS_DOS,d1
	move.l	#ERMSUB_IoErr,d2
	clr.l	Req.Arg
	bsr	PrintError
.End	move.l	a4,a0
	move.l	IFFParse.Base(pc),a6
	jsr	_LVOCloseIFF(a6)
.CloseFile
	move.l	iff_Stream(a4),d1
	move.l	ErrorMsg.Base(pc),a6
	move.l	emb_DOSBase(a6),a6
	jsr	_LVOClose(a6)
	; I ignore the return value from Close(), as this function is
	; very unlikely to fail for read accesses
.FreeHandle
	move.l	a4,a0
	move.l	IFFParse.Base(pc),a6
	jsr	_LVOFreeIFF(a6)
.Ret	movem.l	(sp)+,d2-d3/a4/a6
	rts

Indent	; (Z=0)Success=Indent(Number)(D3)
	movem.l	d0-d1/d3/a0-a1/a6,-(sp)
	move.l	ErrorMsg.Base(pc),a6
	move.l	emb_DOSBase(a6),a6
	bra.s	.Begin
.Loop	move.l	#Indent.MSG,d1
	jsr	_LVOPutStr(a6)
	eor.l	#-1,d0
	beq.s	.Ret
.Begin	dbra	d3,.Loop
	moveq	#-1,d0	; clear Z
.Ret	movem.l	(sp)+,d0-d1/d3/a0-a1/a6
	rts

CheckBreak	; (Z=0)Break=CheckBreak()
	movem.l	d0-d1/a0-a1/a6,-(sp)
	move.l	#SIGBREAKF_CTRL_C,d1
	move.l	ErrorMsg.Base(pc),a6
	move.l	emb_DOSBase(a6),a6
	jsr	_LVOCheckSignal(a6)
	tst.l	d0
	movem.l	(sp)+,d0-d1/a0-a1/a6
	rts

WB.Startup	dc.l	0
Exec.Base	dc.l	0
ErrorMsg.Base	dc.l	0
IFFParse.Base	dc.l	0

Args.Array
FileName.Arg	dc.l	0
Req.Arg	dc.l	0

Args.RDArgs	dc.l	0

Indent.MSG	dc.b	' > ',0
ScanIFF.Name	dc.b	'ScanIFF',0
	even
Type.MSG	dc.l	0
	dc.b	0
	even
ID.MSG	dc.l	0
	dc.b	0
Chunk.Fmt	dc.b	'ID: %s  Type: %s (%ld bytes)',10,0

Args.Template	dc.b	'FILE/A,REQ/S',0
ErrorMsg.Name	dc.b	'errormsg.library',0
