;
; choices.choices.s
;
; Locate user-configurable resource files
;
;  1995 Straylight
;

;----- Standard header ------------------------------------------------------

		GET	libs:header
		GET	libs:swis

		GET	libs:stream

;----- External dependencies ------------------------------------------------

		GET	sapphire:res
		GET	sapphire:sapphire
		GET	sapphire:string

;----- Main code ------------------------------------------------------------

		AREA	|Sapphire$$Code|,CODE,READONLY

; --- choices_useChoices ---
;
; On entry:	R0 == 0 to disable use of `Choices', >0 to enable, or <0 to
;			read
;
; On exit:	R0 == previous setting
;
; Use:		This call allows an application to determine whether its
;		user-configurable resources are looked for in Acorn's
;		`Choices' directory, or only in the application's directory.
;
;		An application would typically make this call after parsing
;		its command-line options, to allow a Network Manager to
;		enable the `Choices' support.

		EXPORT	choices_useChoices
choices_useChoices ROUT

		STMFD	R13!,{R12,R14}		;Save some registers
		WSPACE	chs__wSpace		;Find my workspace
		MOVS	R14,R0			;Copy arg, and set Z and N
		LDR	R0,chs__flags		;Load the flags word
		ORRPL	R14,R0,#chFlag__useChs	;If N clear, set the flag
		BICEQ	R14,R14,#chFlag__useChs	;But if Z set, clear it
		STRPL	R14,chs__flags		;If changed, save flag back
		AND	R0,R0,#chFlag__useChs	;Set up return value
		LDMFD	R13!,{R12,PC}^		;And return to caller

		LTORG

; --- choices_find ---
;
; On entry:	R0 == pointer to resource filename
;		R1 == pointer to buffer to build filename in
;		R2 == flags:
;			bit 0 == file will be written to (use Choices$Write)
;
; On exit:	R0 == pointer to filename
;		R1 == pointer to terminating NULL
;		CS if the file was found, else CC
;
; Use:		Locates a user-configurable resource file.  The search order
;		depends on (a) whether the file will be written (bit 0 of R2)
;		and (b) whether the use of Acorn's `Choices' system is
;		enabled.
;
;		The search order is as follows:
;
;		* Choices:appName.leaf / <Choices$Write>.appName.leaf
;		* res_find(leaf)
;
;		(i.e. it looks in the `Choices' structure first, and if that
;		fails, it will use res_find).

		EXPORT	choices_find
choices_find	ROUT

		STMFD	R13!,{R2-R6,R12,R14}	;Save some registers
		WSPACE	chs__wSpace		;Locate my workspace
		MOV	R5,R0			;Get the leafname safely
		MOV	R6,R1			;And the buffer pointer
		LDR	R14,chs__flags		;Load the flags
		TST	R14,#chFlag__useChs	;Are we using Acorn's thing?
		BEQ	%50choices_find		;No -- just use res then

		; --- Now sort out what we're doing ---

		TST	R2,#1			;Are we writing the file?
		BNE	%20choices_find		;Yes -- that's special

		; --- We're trying to read ---

		ADR	R0,chs__path		;Point to the variable name
		MOV	R1,R11			;Build value in scratchpad
		MOV	R2,#256			;Say this is very big
		MOV	R3,#0			;This is the first call
		MOV	R4,#3			;Please convert to a string
		SWI	XOS_ReadVarVal		;Try to read the value
		BVS	%50choices_find		;If it failed, try res_find

		MOV	R0,R6			;Point to his buffer
		ADR	R1,chs__prefix		;Point to path prefix
		BL	str_cpy			;Copy that over
		ADD	R2,R0,#10		;Allow 10 chars for appname
		LDR	R1,sapph_appName	;Find application's name
		BL	str_cpy			;Copy that over
		CMP	R0,R2			;Have we gone too far?
		MOVCS	R0,R2			;Yes -- backpedal a bit
		MOV	R14,#'.'		;Store directory separator
		STRB	R14,[R0],#1		;Save that out
		MOV	R1,R5			;Point to his leafname
		BL	str_cpy			;Add that to the end too
		MOV	R1,R0			;Get the end of the buffer
		MOV	R0,R6			;Point to buffer start
		BL	res_exists		;Is the file there?
		BCS	%90choices_find		;Yes -- return then
		B	%50choices_find		;No luck -- use res_find

		; --- We're trying to write ---

20choices_find	ADR	R0,chs__write		;Point to the variable name
		MOV	R1,R11			;Build value in scratchpad
		MOV	R2,#256			;Say this is very big
		MOV	R3,#0			;This is the first call
		MOV	R4,#3			;Please convert to a string
		SWI	XOS_ReadVarVal		;Try to read the value
		BVS	%50choices_find		;If it failed, try res_find

		MOV	R0,R6			;Point to his buffer
		MOV	R14,#'<'		;Wrap name in `<>'s
		STRB	R14,[R0],#1		;Save that in the buffer
		ADR	R1,chs__write		;Point to write prefix
		BL	str_cpy			;Copy that over
		MOV	R14,#'>'		;Close odd brackets
		STRB	R14,[R0],#1		;Save that in the buffer
		MOV	R14,#'.'		;Add a directory separator
		STRB	R14,[R0],#1		;Save that in the buffer
		ADD	R2,R0,#10		;Allow 10 chars for appname
		LDR	R1,sapph_appName	;Find application's name
		BL	str_cpy			;Copy that over
		CMP	R0,R2			;Have we gone too far?
		MOVCS	R0,R2			;Yes -- backpedal a bit
		MOV	R2,R0			;Remember where we are
		MOV	R14,#0			;Terminate name here
		STRB	R14,[R0],#1		;Save that out

		; --- Create <Choices$Write>.appName ---

		MOV	R4,#0			;Default number of entries
		MOV	R1,R6			;Point to the buffer
		MOV	R0,#8			;Create a directory
		SWI	XOS_File		;Try to create it at least
		BVS	%50choices_find		;If no luck, use res_find

		; --- Now attach the leafname ---

		MOV	R0,R2			;Find the end of the name
		MOV	R14,#'.'		;Add a directory separator
		STRB	R14,[R0],#1		;Store that
		MOV	R1,R5			;Point to the leafname
		BL	str_cpy			;Copy that on the end
		MOV	R0,R6			;Point to the buffer
		MOV	R1,R0			;Get the end of the buffer
		BL	res_exists		;Does that exist?
		B	%90choices_find		;Return that anyway

		; --- We had no luck ourselves -- try res_find ---

50choices_find	MOV	R0,R5			;Point to the leafname
		MOV	R1,R6			;And to the buffer
		BL	res_find		;Try to find the file

		; --- Return finally ---
		;
		; The correct file-exists state is already in C, as is the
		; end pointer.

90choices_find	LDMFD	R13!,{R2-R6,R12,R14}	;Restore registers
		ORRCSS	PC,R14,#C_flag		;If C set, set C on exit
		BICCCS	PC,R14,#C_flag		;Else clear C

chs__path	DCB	"Choices$Path",0
chs__prefix	DCB	"Choices:",0
chs__write	DCB	"Choices$Write",0

		LTORG

chs__wSpace	DCD	0

;----- Workspace ------------------------------------------------------------

		^	0,R12
chs__wStart	#	0

chs__flags	#	4			;Various interesting flags

chs__wSize	EQU	{VAR}-chs__wStart

chFlag__useChs	EQU	(1<<0)			;Use Acorn's `Choices' system

		AREA	|Sapphire$$LibData|,CODE,READONLY

		DCD	chs__wSize
		DCD	chs__wSpace
		DCD	256
		DCD	0

;----- That's all, folks ----------------------------------------------------

		END
