;-----------------------------------------------------------------------------
; Assplus (01.11.93)
; (c) by Weiss Christan
; Anmerkungen: V1.4
;-----------------------------------------------------------------------------


;-----------------------------------------------------------------------------
; Include
;-----------------------------------------------------------------------------

	incdir	"ainc:"
	include "src:include/macros.i"
	include "exec/libraries.i"
	include	"exec/exec_lib.i"
	include	"exec/memory.i"
	include	"exec/ables.i"
	include "dos/dos.i"
	include	"dos/dos_lib.i"
	include	"dos/dosextens.i"

;-----------------------------------------------------------------------------
; dos.library V37 öffnen (falls möglich)
;-----------------------------------------------------------------------------

	movem.l	d2-d5/a2-a5,-(sp)

	moveq	#0,d0			; Dos.Library öffnen
	lea	libname(pc),a1
	CALLEXEC OpenLibrary
	lea	_DOSBase(pc),a0
	move.l	d0,(a0) 		; Base sichern
	beq	nolib

;-----------------------------------------------------------------------------
; testen ob V37 oder höher
;-----------------------------------------------------------------------------

	movea.l	d0,a0
	move.w	LIB_VERSION(a0),d0
	cmp.w	#36,d0			; Versionsnummer mit 36 vergleichen
	bls	olddos			; falls kleiner oder gleich: Fehler

;-----------------------------------------------------------------------------
; ok V37 dos.library offen
; Kommandozeile einlesen
;-----------------------------------------------------------------------------

	lea	Templ(pc),a0		; Template holen
	move.l	a0,d1
	lea	ArgsArray(pc),a0	; Initialisiertes Array übergeben
	move.l	a0,d2
	moveq	#0,d3			; keine eigenen ReadArgs!
	CLDOS ReadArgs
	move.l	d0,d5			; ReadArgs sichern
	beq.s	noargs			; dos.library schliessen + Ende

;-----------------------------------------------------------------------------
; Argumente erfolgreich eingelesen (wenn keine Argument => Defaultwerte)
;-----------------------------------------------------------------------------

	move.l	Quiet(pc),d0
	bne.s	SayNoVersion

	lea	String2(pc),a0		; Version ausgeben
	move.l	a0,d1
	CLDOS	PutStr

SayNoVersion

;-----------------------------------------------------------------------------
; PreAssign (BIND ... TO ...) (14.08.93)
;-----------------------------------------------------------------------------

Pre	move.l	Bind(pc),d0
	beq.s	NoPre

	move.l	d0,a3			; Devicename in a3

	move.l	d0,a4
.loop	move.b	(a4)+,d0
	beq.s	.weiter			; kein Doppelpunkt
	cmp.b	#":",d0			; oder doch?
	bne.s	.loop			; nein, dann weitersuchen
	moveq	#0,d0			; 0 anstatt ":"
	move.b	d0,-(a4)		; eintragen

.weiter	move.l	To(pc),d0
	beq.s	NoPre

	move.l	d0,a4			; Directoryname in a4
	lea	String16(pc),a2		; "CLI" als Dateiname

	move.l	d5,-(sp)		; d5 sichern

	moveq	#0,d5			; Zeile 0, weil eigentlich keine Zeile

	moveq	#%1000,d4		; Default Option N
	bsr	AssignIt
	
	move.l	(sp)+,d5		; und restaurieren


;-----------------------------------------------------------------------------
; Iteratives einlesen aller angegebenen Files !
;-----------------------------------------------------------------------------

NoPre	lea	ArgsArray(pc),a4	; Adresse Argument Array in a0
	move.l	(a4),a4			; Adresse Pointer Array
	move.l	a4,d0			; testen ob Argumente vorhanden waren
	bne.s	loadloop		; ok da waren Argumente

	lea	AssList(pc),a0		
	lea	PArray(pc),a4
	move.l	a0,(a4)			; Default-Werte initialisieren

loadloop
	move.l	(a4)+,d0		; Adresse erster (nächster) Filename
	beq	nomore			; testen, wenn 0 => fertig

	move.l	d0,a2
	bsr	LoadIt
	bra.s	loadloop

;-----------------------------------------------------------------------------
; letztes File nachgeladen => Programm beenden
;-----------------------------------------------------------------------------

nomore	move.l	d5,d1			; Argumente freigeben
	CLDOS	FreeArgs
	bra.s	cllib			; dos.library schliessen & ENDE

;-----------------------------------------------------------------------------
; Einlesen der Kommandozeile nicht erfolgreich
;-----------------------------------------------------------------------------

noargs	lea	String3(pc),a0		; Fehler in der Eingabezeile
	move.l	a0,d1
	CLDOS PutStr
	bra.s	cllib			; dos.library schliessen & ENDE

;-----------------------------------------------------------------------------
; Falsche DOS Version 
;-----------------------------------------------------------------------------

olddos	CLDOS	Output
	move.l	d0,d1
	bne.s	oputok			; Standart Output beschaffen

	moveq	#20,d0			; Mit FehlerCode 20 terminieren
	bra	quit

oputok	lea	String1(pc),a0
	move.l	a0,d2			; Adresse String
	moveq	#Str1End-String1,d3	; Länge String
	CLDOS	Write			; und ausgeben

cllib	move.l	_DOSBase(pc),a1
	CALLEXEC CloseLibrary		; dos.library schliessen

;-----------------------------------------------------------------------------
; Ende
;-----------------------------------------------------------------------------

nolib	moveq	#0,d0			; terminieren
quit	movem.l	(sp)+,d2-d5/a2-a5	; Register restaurieren
	rts


;-----------------------------------------------------------------------------
; File laden und analysieren
;-----------------------------------------------------------------------------
LoadIt
	movea.l	a2,a0
	bsr	LoadFile		; File Laden
	tst.l	d0			; und prüfen ob Fehler
	beq.s	loadfail
	movea.l	d0,a5			; Speicher merken

	bsr	Assign			; und File analysieren + Assigns

	movea.l	a5,a1
	move.l	4.w,a6
	jmp	_LVOFreeVec(a6)		; FileBuffer freigeben

;-----------------------------------------------------------------------------
; Fehler beim Laden aufgetreten (I/O oder Speicher)
;-----------------------------------------------------------------------------

loadfail
	lea	String6(pc),a0		; Fehlermeldung ausgeben
	lea	Array(pc),a1
	move.l	a2,(a1)			; Filename eintragen
	bra	pf2
;--------------------------------------------------------------------------
; LoadFile (01.08.93)
;
;    Input : a0 - File Name mit 0 byte terminiert
;    Output: d0 - Adresse an der Speicherblock mit geladenem File beginnt
;            d1 - Laenge des Files
;            Tritt ein Fehler auf so ist d0 0 !
;
;    Anmerkungen: Routine ist nur unter OS2.0 (oder höher) lauffähig
;                 Der SpeicherBlock muß mit FreeVec freigegeben werden
;		  Speziel angepasst für AssPlus !
;--------------------------------------------------------------------------

LoadFile

	movem.l	d2-d6,-(sp)		; Register sichern

	moveq	#0,d6			; Zeiger für Speicher initialisieren

	move.l	a0,d1
	move.l	#MODE_OLDFILE,d2
	CLDOS	Open			; File Öffnen
	move.l	d0,d4			; FileHandle sichern
	beq.s	.nohandle

	move.l	#fib_SIZEOF,d0		; Speicher für FIB anfordern
	moveq	#0,d1			; keine Anforderungen
	CALLEXEC AllocVec
	move.l	d0,d5			; und sichern
	beq.s	.nomem

	move.l	d4,d1
	move.l	d0,d2
	CLDOS	ExamineFH
	tst.l	d0
	beq.s	.exerror		; Examine fehlgeschlagen ?

	movea.l	d5,a0
	move.l	fib_Size(a0),d0		; Länge ermitteln
	move.l	d0,d3			; Länge sichern
	addq.l	#2,d0			; +1 für EndOfFile (0 Byte)

	moveq	#0,d1			; leeren Speicher anfordern
	CALLEXEC AllocVec
	move.l	d0,d6
	beq.s	.noreadbuf

	move.l	d0,d2
	move.l	d4,d1			; Länge in d3 !
	CLDOS Read			; File einlesen
	bpl.s	.noreaderror

	movea.l	d6,a1
	CALLEXEC FreeVec		; Speicher für File freigeben

	moveq	#0,d6

.noreaderror

	move.l	d6,a0
	move.b	#10,(a0,d0)		; Mit RETURN terminieren
	move.b	#0,1(a0,d0)		; und EOF

.noreadbuf
.exerror
	movea.l	d5,a1
	CALLEXEC FreeVec		; Speicher freigeben

.nomem
	move.l	d4,d1
	CLDOS	Close			; File schließen

.nohandle
	move.l	d6,d0			; Fehler wenn kein FBuffer! (=> d0=0)
	move.l	d3,d1

.exit	movem.l	(sp)+,d2-d6		; Stack restaurieren
	rts

;-----------------------------------------------------------------------------
; Assign (31.10.93)
; 
;-----------------------------------------------------------------------------

Assign	movem.l	d5/a3-a5,-(sp)

;-----------------------------------------------------------------------------
; Initialisierung
;-----------------------------------------------------------------------------

	move.l	#1001+32,d0
	move.l	#MEMF_CLEAR,d1
	CALLEXEC AllocVec		; Speicher für Puffer anfordern
	tst.l	d0
	beq	nomem

	movea.l	d0,a3			; in a3 Puffer für Devicename
	add.l	#32,d0
	movea.l	d0,a4			; in a4	Puffer für Directoryname

	moveq	#0,d5			; Zeilennummer in d5

;-----------------------------------------------------------------------------
; Begin des Parsers
;-----------------------------------------------------------------------------

Start	addq.l	#1,d5			; +1 für Zeilenzähler

	tst.b	(a5)			; Auf EOF testen
	beq	Ende

	move.l	#%1000000000000,d1
	CLDOS	CheckSignal		; auf CTRL_C testen
	tst.l	d0
	bne	Ende

	bsr	SkipSpace		; führende Spaces eliminieren

;-----------------------------------------------------------------------------
; Devicename holen
;-----------------------------------------------------------------------------

	moveq	#31,d0			; Maximale Länge des Wortes
	movea.l	a3,a0			; und Zeiger auf Puffer übergeben
	bsr	GetWord			; und Wort holen

	cmp.b	#";",d1			; Wars ein ; ?
	beq	Komment

	tst.l	d0			; auf Fehler testen
	bmi	devfehler

	bne.s	TestIt

	cmp.b	#10,d1
	beq.s	Start			; leere Zeile

;-----------------------------------------------------------------------------
; Prüfen ob Spezialanweisung
;-----------------------------------------------------------------------------

TestIt	cmp.b	#"*",(a3)		; Prüfen ob Include
	beq	Include

;-----------------------------------------------------------------------------
; Ist der Devicename ok ?
;-----------------------------------------------------------------------------

	cmp.b	#10,d1			; schon EOL ?
	beq	nodname

	subq	#1,d0
	beq	devfehler		; nur ein Zeichen ( "?:" ist Minimum)

	cmp.b	#":",-(a0)
	bne	devfehler		; ":" am Schluß ?

	moveq	#0,d0			; Devicename
	move.b	d0,(a0)			; mit 0 terminieren

	move.l	a3,a0			; testen ob ":" im Namen
.loop	move.b	(a0)+,d0
	beq.s	.go			; Ist er jetzt ok ?
	cmp.b	#":",d0
	bne.s	.loop
	bra	devfehler

;-----------------------------------------------------------------------------
; Directoryname holen
;-----------------------------------------------------------------------------

.go	bsr	SkipSpace

	move.l	#1000,d0		; Maximale Länge des Wortes
	movea.l	a4,a0			; und Zeiger auf Puffer übergeben
	bsr	GetWord			; und Wort holen
	tst.l	d0			; auf Fehler testen
	beq	nodname			; auch wenn kein Name d0=0
	bmi	dirfehler	

	moveq	#0,d0			; Devicename
	move.b	d0,(a0)			; mit 0 terminieren

;-----------------------------------------------------------------------------
; Directoryname ok!
;-----------------------------------------------------------------------------

	cmp.b	#10,d1
	bne.s	Optpars
	moveq	#%1000,d4		; keine Optionen => Default Option N
	bsr	AssignIt
	bra	Start

;-----------------------------------------------------------------------------
; Optionen Parsen
;-----------------------------------------------------------------------------

Optpars	moveq	#0,d4			; Option initialisieren

	bsr	SkipSpace

.loop	move.b	(a5)+,d1
	cmp.b	#10,d1
	beq	.ret			; EOL => AssignIt
	and.b	#%11011111,d1		; Case egal !
	cmp.b	#"A",d1
	beq.s	.A
	cmp.b	#"C",d1
	beq.s	.C
	cmp.b	#"D",d1
	beq	.D
	cmp.b	#"E",d1
	beq.s	.E
	cmp.b	#"N",d1
	beq.s	.N
	cmp.b	#"P",d1
	beq.s	.P
	cmp.b	#"M",d1
	beq.s	.M
	cmp.b	#"X",d1
	bne	.error1


;--------------------------------------------------------------------------
; Options eintragen und kontrolieren
; d4=XMDPNACE
;--------------------------------------------------------------------------

.X	move.b	d4,d0
	and.b	#%10110000,d0
	bne	.error2
	bset	#7,d4
	bra.s	.loop

.M	move.b	d4,d0
	and.b	#%01111000,d0
	bne.s	.error2
	bset	#6,d4
	bra.s	.loop

.P	tst.b	d4
	bne.s	.error2			; andere Option gewählt => Fehler
	bset	#4,d4
	bra.s	.loop   

.E	move.b	d4,d0
	and.b	#%00110001,d0
	bne.s	.error2			; Option schon eingetragen => Fehler
	bset	#0,d4			; Maske setzen
	bra.s	.loop

.C	move.b	d4,d0
	and.b	#%00110010,d0
	bne.s	.error2			; Option schon eingetragen => Fehler
	bset	#1,d4			; Maske setzen
	bra	.loop

.A	move.b	d4,d0
	and.b	#%00110100,d0
	bne.s	.error2			; ja => Fehler
	bset	#2,d4
	bra	.loop

.N	move.b	d4,d0
	and.b	#%01111000,d0
	bne.s	.error2			; Option schon eingetragen => Fehler
	bset	#3,d4			; Maske setzen
	bra	.loop

.D	tst.b	d4
	bne.s	.error2			; andere Option gewählt => Fehler
	bset	#5,d4			; Option eintragen
	bra	.loop

;-----------------------------------------------------------------------------
; Ende Zeile oder File erreicht
;-----------------------------------------------------------------------------

.ret	tst.b	d4
	bne.s	.ret2
	moveq	#%1000,d4		; Default
.ret2	bsr	AssignIt		; Assign durchführen
	bra	Start

;--------------------------------------------------------------------------
; Fehler in Optionspars !
;--------------------------------------------------------------------------

.error1	bsr	SkipLine

	lea	String7(pc),a0
	bra.s	jp3

.error2	bsr	SkipLine

	lea	String8(pc),a0
	bra	jp3

;-----------------------------------------------------------------------------
; Fehler im Devicenamen
;-----------------------------------------------------------------------------
devfehler
	bsr	SkipLine

	lea	String10(pc),a0
	bra.s	jp3
;-----------------------------------------------------------------------------
; Directory Name fehlt
;-----------------------------------------------------------------------------
nodname
	bsr SkipLine

	lea String12(pc),a0
	bra.s	jp3

;-----------------------------------------------------------------------------
; Fehler im Directorynamen
;-----------------------------------------------------------------------------

dirfehler
	bsr	SkipLine

	lea	String9(pc),a0
jp3	bsr	Printf
	bra	Start

;-----------------------------------------------------------------------------
; Kommentar
;-----------------------------------------------------------------------------

Komment	suba.l	a3,a0
	move.l	a0,d0
	bne.s	devfehler

Skip	bsr SkipLine			; war ein Kommentar (Include)
	bra Start			; Rest ignorieren und Weitermachen

;-----------------------------------------------------------------------------
; Include
;-----------------------------------------------------------------------------

Include
	subq.l	#1,d0
	bne.s	incfehler		; nicht * allein

	cmp.b	#10,d1
	beq.s	incfehler		; Dateiname fehlt

	bsr	SkipSpace

	move.l	#1001+31,d0
	movea.l	a3,a0			; und Zeiger auf Puffer übergeben
	bsr	GetWord			; und Wort holen
	tst.l	d0			; auf Fehler testen
	bmi	incfehler
	beq	incfehler

	moveq	#0,d0
	move.b	d0,(a0)			; Mit 0 terminieren

	movem.l	a2/a5/d1,-(sp)
	movea.l	a3,a2
	bsr	LoadIt

	movem.l	(sp)+,a2/a5/d1

	bra.s	Skip			; Rest ignor. und weiter

;-----------------------------------------------------------------------------
incfehler
	bsr	SkipLine

	lea	String11(pc),a0
	bra.s	jp3

;-----------------------------------------------------------------------------
; Ende (alles freigeben und verlassen)
;-----------------------------------------------------------------------------

Ende	movea.l	a3,a1
	CALLEXEC FreeVec

nomem	movem.l	(sp)+,d5/a3-a5
	rts

;-----------------------------------------------------------------------------
; Printf
;-----------------------------------------------------------------------------

Printf	lea	Array(pc),a1
	move.l	a2,(a1)			; Filename eintragen
	move.l	a0,4(a1)		; Fehlerstring eintragen
	move.l	d5,8(a1)		; Zeilennr. eintragen

	lea	String13(pc),a0
pf2	move.l	a0,d1			; d1=String
	move.l	a1,d2			; d2=Array
	move.l	_DOSBase(pc),a6
	jmp	_LVOVPrintf(a6)		; Zeilennummer ausgeben

;-----------------------------------------------------------------------------
;-----------------------------------------------------------------------------

;-----------------------------------------------------------------------------
; SkipLine (01.08.93)
;-----------------------------------------------------------------------------

SkipLine
	cmp.b	#10,d1
	beq.s	.ok
.loop	move.b	(a5)+,d1
	cmp.b	#10,d1
	bne.s	.loop
.ok	rts

;-----------------------------------------------------------------------------
;-----------------------------------------------------------------------------


;-----------------------------------------------------------------------------
; SkipSpace (29.03.93)
; Routine überspringt Spaces und Tabs
; veränderte Variablen d1,a5(?)
;-----------------------------------------------------------------------------

SkipSpace

	move.b	(a5),d1
	cmp.b	#32,d1
	beq.s	.skipit			; Space überspringen
	cmp.b	#9,d1
	beq.s	.skipit			; Tab überspringen
	cmp.b	#160,d1
	beq.s	.skipit			; ShiftSpace überspringen
	rts

.skipit	addq.l	#1,a5
	bra.s	SkipSpace

;-----------------------------------------------------------------------------
;-----------------------------------------------------------------------------


;-----------------------------------------------------------------------------
; GetWord (01.08.93)
;
; Input : a0 - Adresse des Pufferspeichers
;	  a5 - Adresse Quelltext
;	  d0 - max. Wortlänge
; Output: d0 - Länge des Wortes
;	  d1 - Zeichen, welches das Ende des Wortes anzeigte
;	  a0 - Stellt Adresse des letzten Zeichens +1 dar
;         Tritt ein Fehler auf so ist d0 -1 ! d1 enthält falsches Zeichen
;-----------------------------------------------------------------------------

GetWord	move.l	d0,d3			; max. Länge sichern
	move.l	d2,-(sp)		; d2 sichern
	moveq	#0,d2			; d2 initialisieren

.loop	move.b	(a5)+,d1		; Zeichen holen

;-----------------------------------------------------------------------------
; Testen ob Zeichen korekt
;-----------------------------------------------------------------------------

	cmp.b	#34,d1
	beq.s	.quotes			; auf Anführungsstriche testen

	cmp.b	#";",d1			; ";" Kommentar Zeichen
	beq.s	.error
	cmp.b	#34,d1
	beq.s	.error			; Anführungsstriche nicht erlaubt
	cmp.b	#32,d1			; <33 nicht erlaubt
	bls.s	.ertest
	cmp.b	#160,d1			; >160 erlaubt
	bhi.s	.ok
	cmp.b	#127,d1			; >127 und <161 nicht erlaubt
	bhi.s	.ertest

;-----------------------------------------------------------------------------

.ok	move.b	d1,(a0)+
	
	dbra	d0,.loop		; von vorne
	bra.s	.error			; Wort zu lang

.quotes	tst.l	d2			; Prüfen ob schon mal
	bne.s	.secondq
	moveq	#-1,d2			; Setzen daß schon mal
	bra.s	.loop

.secondq
	moveq	#0,d2			; wieder löschen, da 2tes
	move.b	(a5)+,d1		; Zeichen holen
;	bra.s	.ertest


.ertest	cmp.b	#10,d1
	beq.s	.noerror		; RETURN
	cmp.b	#32,d1
	beq.s	.noerror2		; SPACE
	cmp.b	#160,d1
	beq.s	.noerror		; SHIFT SPACE
	cmp.b	#9,d1
	beq.s	.noerror		; TAB

.error 	move.l	(sp)+,d2		; d2 restaurieren

	moveq	#-1,d0
	rts

.noerror2
	tst.l	d2
	beq.s	.okexit
	bra.s	.ok			; SPACE schreiben

.noerror
	tst.l	d2
	bne.s	.error			; nur ein Anführungsstrich ?

.okexit	move.l	(sp)+,d2		; d2 restaurieren

	sub.l	d0,d3
	move.l	d3,d0			; Länge des Wortes in d0
	rts

;-----------------------------------------------------------------------------
;-----------------------------------------------------------------------------

;-----------------------------------------------------------------------------
; AssignIt Routine (01.11.93)
; führt die Assigns anhand der Maske in d4 durch (d4=XMDPNACE)
;-----------------------------------------------------------------------------

AssignIt
	move.l	Test(pc),d0		; test-Flag gesetzt?
	beq.s	.notest
	rts

.notest	move.l	Exists(pc),d0		; exists-Flag gesetzt?
	beq.s	.noX0

	move.b	d4,d0
	and.b	#%10110000,d0		; erlaubte Kombination?
	bne.s	.noX0
	bset	#7,d4			; wenn ja -> eintragen!

.noX0	move.l	a5,-(sp)		; Register sichern
					; Maske in d4 !

	btst	#6,d4			; Option M
	bne	.multi
	btst	#4,d4			; Option P
	bne	.path
	btst	#5,d4			; Option D
	bne	.defer

;-----------------------------------------------------------------------------

	btst	#7,d4			; Option X
	beq.s	.noX

	bsr	CheckX			; Existiert das Volume (Device/Assign)?
	bne	.quit			; Nein => Ende des Assigns

.noX	btst	#1,d4			; Option C
	beq.s	.nocreate

	bsr	MakeDir			; Directory erzeugen
	tst.l	d0
	beq.s	.go_on			; Lock vorhanden !

	move.l	Force(pc),d0		; Überprüfe FORCE-Option
	beq	.quit			; Fehler in MakeDir und nicht FORCE

;-----------------------------------------------------------------------------

.nocreate

	bsr	GetLock
	beq.s	.go_on

	move.l	Create(pc),d0
	beq	.quit			; keine CREATE-Option gesetzt

	btst	#1,d4			; auf Option C testen
	bne	.asserror1		; MKDir schon probiert !

	bsr	MakeDir			; Directory erzeugen
	tst.l	d0
	bne	.asserror1		; endgültiges Ende


.go_on	btst	#0,d4			; alles ok Lock vorhanden !
	beq	.noextra

;-----------------------------------------------------------------------------

	CALLEXEC Forbid

	CLDOS	Cli
	tst.l	d0
	beq.s	.errorpath

	addi.l	#cli_CommandDir,d0
	move.l	d0,a5
	move.l	(a5),d0
	beq.s	.jmp

.loop	lsl.l	#2,d0			; *4 wegen BPTR
	move.l	d0,a5

	bsr	CheckPath
	tst.l	d0
	bne.s	.endpath

	move.l	(a5),d0
	bne.s	.loop

.jmp	moveq	#8,d0
	move.l	#MEMF_CLEAR,d1
	CALLEXEC AllocVec
	move.l	d0,d1
	beq.s	.errorpath

	lsr.l	#2,d1
	move.l	d1,(a5)
	move.l	d0,a5

	move.l	ALock(pc),d1
	CLDOS	DupLock
	move.l	d0,4(a5)
	bne.s	.endpath

	move.l	a5,a1
	CALLEXEC FreeVec

.errorpath

	CALLEXEC Permit

	move.l	Force(pc),d0
	beq	.asserror2		; FORCE-Option nicht gesetzt

	lea	String15(pc),a0		; FORCE:Extra Fehler zur Unterscheidung
	bsr	Printf
	bra	.noextra
	
.endpath

	CALLEXEC Permit

;-----------------------------------------------------------------------------

.noextra

	btst	#2,d4
	bne.s	.add
	btst	#3,d4
	bne.s	.new

.quit2	move.l	ALock(pc),d1		; war nur c oder e Option
	CLDOS	UnLock

.quit	move.l	(sp)+,a5
	rts

.path	move.l	a3,d1
	move.l	a4,d2
	CLDOS	AssignPath
	bne.s	.quit
	bra	.asserror1

.defer	move.l	a3,d1
	move.l	a4,d2
	CLDOS	AssignLate
	bne.s	.quit
	bra	.asserror1

.new	move.l	a3,d1
	move.l	ALock(pc),d2
	CLDOS	AssignLock
	tst.l	d0
	bne.s	.quit
	bra.s	.asserror2

.add	bsr	CheckAdd
	tst.l	d0
	bne.s	.quit2

	move.l	a3,d1
	move.l	ALock(pc),d2
	CLDOS	AssignAdd
	tst.l	d0
	bne.s	.quit
	bra.s	.asserror2

.multi	move.b	d4,d0
	and.b	#%00111111,d0		; M-Opt und X-Opt ausfiltern
	bne.s	.m2			; eine Opt eingetragen ?

	bset	#2,d4			; A-Option als Standart Kombination

.m2	moveq	#-1,d0

.loop2	addq.l	#1,d0
	move.b	(a4,d0),d1
	beq.s	.null

	cmp.b	#",",d1
	bne.s	.loop2

.komma	tst.l	d0			; nur Komma und kein Name !
	bne.s	.okmult

	move.l	a4,a5
	addq.l	#1,a5			; Komma überspringen
	bra.s	.rek

.okmult	moveq	#0,d1			; Komma durch 0 ersetzen
	move.b	d1,(a4,d0)

	add.l	a4,d0
	addq.l	#1,d0			; Ende des Namens+1=Anfang nächster
	move.l	d0,a5	

	bclr	#6,d4			; Option M löschen
	bsr	AssignIt

.rek	exg	a4,a5			; a4 und a5 austauschen
	bset	#6,d4			; Option M setzen
	bsr	AssignIt

	move.l	a5,a4			; a4 restaurieren
	bra	.quit			; a5 restaurieren und Ende

.null	tst.l	d0
	beq	.quit			; nichts mehr nach einem Komma

	bclr	#6,d4			; Option M löschen
	bsr	AssignIt		; letztes Assign in Multi-Anweisung

	bra	.quit			; Ende


;--------------------------------------------------------------------------
; Fehler aufgetreten beim Assign => Lock entfernen
;--------------------------------------------------------------------------

.asserror2

	move.l	ALock(pc),d1
	CLDOS	UnLock

;--------------------------------------------------------------------------
; Fehler und ausgeben 
;--------------------------------------------------------------------------

.asserror1

	lea	String4(pc),a0
.print	bsr	Printf
	bra	.quit


;-----------------------------------------------------------------------------
; GetLock (10.08.93)
;-----------------------------------------------------------------------------

GetLock	move.l	a4,d1
	moveq	#ACCESS_READ,d2
	CLDOS	Lock
	lea	ALock(pc),a0
	move.l	d0,(a0)
	beq.s	.geterror

	moveq	#0,d0
	rts				; Lock erzeugt und Ende

.geterror

	lea	String14(pc),a0		; Fehler ausgeben
	bsr	Printf
	moveq	#-1,d0
	rts

;-----------------------------------------------------------------------------
; Makedir (10.08.93)
;-----------------------------------------------------------------------------

MakeDir	move.l	a4,d1
	CLDOS	CreateDir
	lea	ALock(pc),a0
	move.l	d0,(a0)
	beq.s	.mkerror1		; Makedir fehlgeschlagen

	moveq	#CHANGE_LOCK,d1
	move.l	d0,d2			; Lock in d2
	moveq	#ACCESS_READ,d3
	CLDOS	ChangeMode		; von exclusive nach shared
	tst.l	d0
	beq.s	.mkerror2

	moveq	#0,d0
	rts				; Lock (und Dir) erzeugt und in
					; ALock gesichert

;-----------------------------------------------------------------------------
; Fehler in Makedir
;-----------------------------------------------------------------------------

.mkerror2				; ChangeLock-Fehler

	move.l	ALock(pc),d1
	CLDOS	UnLock

.mkerror1				; CreateDir-Fehler

	lea	String5(pc),a0
	bsr	Printf			; Fehler ausgeben
	moveq	#-1,d0			; Fehler setzen
	rts	

;-----------------------------------------------------------------------------
; Routine prüft ob Volume/Assign/Device existiert
;-----------------------------------------------------------------------------
CheckX

	moveq	#0,d0
.loop	addq.l	#1,d0			; 1. Zeichen muß nicht geprüft werden!
	move.b	(a4,d0),d1
	beq.s	.ok2			; gar kein Volume angegeben
	cmp.b	#":",d1			; ":" suchen
	bne.s	.loop

	moveq	#0,d1
	move.b	d1,(a4,d0)		; ":" durch 0 ersetzen
	move.l	d0,-(sp)		; Position sichern

	moveq	#LDF_ALL!LDF_READ,d1	; Lesen und alle Listen
	CLDOS	LockDosList
	tst.l	d0
	beq.s	.nodlist		; DosList alokieren

	move.l	d0,d1
	move.l	a4,d2			; Assign Name (Devicename)
	moveq	#LDF_ALL,d3
	CLDOS	FindDosEntry
	tst.l	d0
	bne.s	.ok

	moveq	#LDF_ASSIGNS!LDF_READ,d1; kein Entry gefunden!
	CLDOS	UnLockDosList

.nodlist
	move.l	(sp)+,d0		; nur Stack restaurieren, da Pfad
					; nicht mehr benötigt wird
	moveq	#-1,d0
	rts

.ok	moveq	#LDF_ASSIGNS!LDF_READ,d1
	CLDOS	UnLockDosList

	moveq	#":",d1
	move.l	(sp)+,d0
	move.b	d1,(a4,d0)		; ":" in Pfadnamen wieder eintragen

.ok2	moveq	#0,d0
	rts

;-----------------------------------------------------------------------------
; Routine testet ob AddAssign schon vorhanden
;-----------------------------------------------------------------------------

CheckAdd
	move.l	Check(pc),d0
	beq.s	.notset

	moveq	#LDF_ASSIGNS!LDF_READ,d1; Lesen und AssignListe
	CLDOS	LockDosList
	tst.l	d0
	beq.s	.nodlist		; DosList alokieren

	move.l	d0,d1
	move.l	a3,d2			; Assign Name (Devicename)
	moveq	#LDF_ASSIGNS,d3
	CLDOS	FindDosEntry
	tst.l	d0
	beq.s	.noentry

	addi.l	#dol_List,d0
	move.l	d0,a5
	move.l	(a5),a5
	move.l	a5,d0
	beq.s	.noentry

.loop	move.l	ALock(pc),d1
	move.l	4(a5),d2
	CLDOS	SameLock
	cmp.l	#LOCK_SAME,d0
	beq.s	.same

	move.l	(a5),a5
	move.l	a5,d0
	bne.s	.loop

.noentry
	moveq	#LDF_ASSIGNS!LDF_READ,d1
	CLDOS	UnLockDosList

.nodlist
.notset	moveq	#0,d0
	rts

.same	moveq	#LDF_ASSIGNS!LDF_READ,d1
	CLDOS	UnLockDosList

	moveq	#-1,d0
	rts

;-----------------------------------------------------------------------------
; Routine testet ob DirPath schon vorhanden
;-----------------------------------------------------------------------------

CheckPath
	move.l	Check(pc),d0
	beq.s	.notsame

	move.l	4(a5),d1
	move.l	ALock(pc),d2
	CLDOS	SameLock
	cmp.l	#LOCK_SAME,d0
	bne.s	.notsame

	moveq	#-1,d0
	rts

.notsame
	moveq	#0,d0
	rts

;-----------------------------------------------------------------------------
;-----------------------------------------------------------------------------

;-----------------------------------------------------------------------------
; Konstanten (14.08.93)
;-----------------------------------------------------------------------------

libname DOSNAME
	even

Templ	dc.b	"FILE/M,BIND/K,TO/K,Q=QUIET/S,C=CHECK/S,F=FORCE/S,CR=CREATE/S,T=TEST/S,X=EXISTS/S",0
	even

AssList dc.b "S:AssignList",0
	even

PArray	dc.l	0
	dc.l	0

;-----------------------------------------------------------------------------
; Variablen
;-----------------------------------------------------------------------------

_DOSBase	dc.l	0
ArgsArray	dc.l	0
Bind		dc.l	0
To		dc.l	0
Quiet		dc.l	0
Check		dc.l	0
Force		dc.l	0
Create		dc.l	0
Test		dc.l	0
Exists		dc.l	0
Array		dc.l	0
		dc.l	0
		dc.l	0
ALock		dc.l	0

;-----------------------------------------------------------------------------
; Strings (01.11.93)
;-----------------------------------------------------------------------------

Version	dc.b "$VER: "

String2 dc.b "AssPlus V1.4 (c) 1993 by Christian Weiss.",10,0
	even

String1 dc.b "Error: Incorrect dos.library.",10
Str1End
	even

String3 dc.b "Error: Command line incorrect.",10,0
	even

String4 dc.b "Assign failed",0
	even

String5	dc.b "MakeDir failed",0
	even

String6	dc.b "Error: Could not read %s.",10,0
	even

String7 dc.b "Invalid option",0
	even

String8 dc.b "Invalid combination of options",0
	even

String9 dc.b "Invalid directory name",0
	even

String10 dc.b "Invalid device name",0
 	even

String11 dc.b "Include failed",0
	even

String12 dc.b "Directory not specified",0
	even

String13 dc.b "Error (%s): %s ! Line: %ld",10,0
	even

String14 dc.b "Directory not found",0
	even

String15 dc.b "Unable to add path",0
	even

String16 dc.b "CLI",0
	end
