(******************************************************************************
 * Name : Wandler.Mod                                                         *
 * Version : 01.50                                                            *
 * Created : 27.07.1990                                                       *
 * Author  : Gerhard Heeke                                                    *
 * Address : Eichendorffstr. 28, D-4047 Dormagen 5                            *
 * Beschreibung : Dieses Modula-2 Programm (Benchmark-Modula-Compiler) wandelt*
 * die Codes für deutsche Umlaute in ASCII-Files von Amiga-Codes in IBM-Codes *
 * und umgekehrt um.                                                          *
 * Aufruf: Wandler I <Input-File> <Output-File> (* IBM -> Amiga *)            *
 *         Wandler A <Input-File> <Output-File> (* Amiga -> IBM *)            *
 ******************************************************************************)
MODULE Wandler;
IMPORT TermInOut;
FROM TermInOut IMPORT WriteString;
FROM Strings IMPORT CompareStringCAP, Relation;
FROM System IMPORT argc,argv;
FROM Tasks IMPORT SetSignal, SignalSet;
FROM SYSTEM IMPORT ADR, ADDRESS;
FROM Memory IMPORT AvailMem, MemLargest, MemChip, MemPublic, AllocMem,
        FreeMem, MemReqSet;
FROM AmigaDos IMPORT FileLock, FileInfoBlockPtr, FileInfoBlock,
        FileHandle, Lock, UnLock, Open, Close, Examine, Seek,
        Read, Write, SharedLock, ExclusiveLock, ModeOldFile,
        ModeNewFile, OffsetCurrent;

VAR Zeichen           : CHAR;
    Lock1, Lock2      : FileLock;
    Handle1,Handle2   : FileHandle;
    pointer           : FileInfoBlockPtr;
    memblock, wert, i, oldPos, lesen, schreiben, Laenge2,
    GroesseSpeicher, LaengeFile : LONGINT;
    flag              : BOOLEAN;
    help              : POINTER TO CHAR;


PROCEDURE Break(): BOOLEAN;
CONST BreakC = 12;
BEGIN
  RETURN BreakC IN SetSignal(SignalSet{}, SignalSet{BreakC});
END Break;

PROCEDURE Help ();
BEGIN
WriteString ("\n                  WANDLER V 1.50\n");
WriteString ("© by Gerhard Heeke 1990. Dieses Programm ist Public-Domain\n");
WriteString ("Dieses Programm paßt die deutschen Umlaut-Codes in IBM-Dateien\n");
WriteString ("an die Codes des Amiga an. Voraussetzung ist, daß die Dateien\n");
WriteString ("im ASCII-Format vorliegen. Quell- und Zieldatei dürfen nicht\n");
WriteString ("den gleichen Namen haben.\n");
WriteString ("IBM nach AMIGA: ");WriteString(argv^[0]^);
WriteString (" I <Quelle> <Ziel>\n");
WriteString ("Amiga nach IBM: ");WriteString(argv^[0]^);
WriteString (" A <Quelle> <Ziel>\n");
HALT;
END Help;

PROCEDURE CloseDown();

BEGIN
(* Alles dicht machen und aufräumen*)
IF Handle1 # NIL THEN Close (Handle1); END;
IF Handle2 # NIL THEN Close (Handle2); END;
IF Lock1 # NIL THEN UnLock (Lock1); END;
IF Lock2 # NIL THEN UnLock (Lock2); END;
IF memblock #0D THEN
    FreeMem(memblock,LONGCARD(GroesseSpeicher));
END;

END CloseDown;


BEGIN (* Hauptprogramm *)
(* Feststellen von woher der Aufruf erfolgte und welche Argumente übergeben
wurden *)
IF argc = 0 THEN HALT;END; (* Aufruf von der Workbench *)

(* Fehler bei der Parameter-Eingabe oder Hilfeanforderung? *)
IF argc # 4 THEN Help;END;

IF CompareStringCAP (argv^[1]^,"?") = equal THEN Help; END;
IF CompareStringCAP (argv^[2]^,argv^[3]^) = equal THEN Help; END;

(*Quelldatei da?*)
Lock1 := Lock (ADR(argv^[2]^),SharedLock);
IF Lock1 = NIL THEN
    WriteString ("\nFEHLER: Quelldatei kann nicht geöffnet werden.\n");
    HALT;
END;

(* Speicher für FileInfoBlock anfordern *);
pointer := AllocMem(SIZE(FileInfoBlock),MemReqSet{MemChip});
IF pointer = NIL THEN
    WriteString("\nFEHLER: Speichermangel\n");
    CloseDown();
    HALT;
END;

flag := Examine (Lock1,pointer^);
IF flag = FALSE THEN
    WriteString("\nFEHLER\n");
    FreeMem(pointer,SIZE(FileInfoBlock));
    CloseDown;
    HALT;
END;

(* Länge des Files ermitteln *)
LaengeFile := pointer^.fibSize;

(* Für FileInfoBlock belegten Speicher wieder freigeben *);
FreeMem (pointer,SIZE(FileInfoBlock));

(* Wie sieht's mit der Zieldatei aus*);
Lock2 := Lock (ADR(argv^[3]^),ExclusiveLock);
IF Lock2 # NIL THEN
    CloseDown;
    WriteString ("\nFEHLER: Zieldatei existiert schon.\n");
    HALT;
END;

(*Dateien öffnen*)
Handle1 := Open (ADR(argv^[2]^),ModeOldFile);
IF Handle1 = NIL THEN
    WriteString("\nFEHLER: Datei existiert nicht! Merkwürdig!??");
    HALT;
END;
Handle2 := Open (ADR(argv^[3]^),ModeNewFile);
IF Handle2 = NIL THEN
    WriteString("\nFEHLER: Zieldatei läßt sich nicht öffnen!\n");
    HALT;
END;

(*Datei-Zeiger an den Anfang*)
oldPos := Seek (Handle1,0,OffsetCurrent);

(*Speicher für Dateiinhalt bereitstellen*);
GroesseSpeicher := LONGINT(AvailMem(MemReqSet{MemPublic,MemLargest}));
IF GroesseSpeicher >= LaengeFile THEN GroesseSpeicher := LaengeFile;END;
memblock := LONGINT(AllocMem(LONGCARD(GroesseSpeicher),MemReqSet{MemPublic}));

IF memblock = 0D THEN
    WriteString("\nFEHLER: Speichermangel!");
    CloseDown;
    HALT;
END;
Laenge2 := GroesseSpeicher;

REPEAT
    IF LaengeFile < GroesseSpeicher THEN
	Laenge2 := LaengeFile
    END;
    LaengeFile := LaengeFile - GroesseSpeicher;
    (*Datei lesen*)
    lesen := Read(Handle1,memblock,Laenge2);
    IF lesen = -1D  THEN
    	WriteString("\nFEHLER: Kann Quelle nicht lesen!\n");
        HALT;
    END;
    wert := memblock;

    (*Wandeln*)
    IF CompareStringCAP(argv^[1]^,"A") = equal THEN
        FOR i := 0D TO GroesseSpeicher DO
            IF Break() THEN CloseDown; HALT;END;
            help:=ADDRESS(wert);
            CASE ORD(help^) OF
                167: help^ := CHR(021)|
                196: help^ := CHR(142)|
                214: help^ := CHR(153)|
                220: help^ := CHR(154)|
                228: help^ := CHR(132)|
                246: help^ := CHR(148)|
                252: help^ := CHR(129)|
                223: help^ := CHR(225)|
            ELSE;
            END;
            INC(wert);
        END;
     ELSIF CompareStringCAP(argv^[1]^,"I") = equal THEN
         FOR i := 0D TO GroesseSpeicher DO
             IF Break() THEN CloseDown; HALT;END;
             help:=ADDRESS(wert);
             CASE ORD(help^) OF
                021: help^ := CHR(167)|
                142: help^ := CHR(196)|
                153: help^ := CHR(214)|
                154: help^ := CHR(220)|
                132: help^ := CHR(228)|
                148: help^ := CHR(246)|
                129: help^ := CHR(252)|
                225: help^ := CHR(223)|
             ELSE;
             END;
             INC(wert);
         END;
     ELSE
  	WriteString("\nFEHLER: Falscher Parameter\n");
	CloseDown;
	HALT;
     END;
schreiben := Write(Handle2,memblock,Laenge2);
IF schreiben = -1D THEN
    WriteString("\nFEHLER: Schreibfehler!\n");
    CloseDown;
    HALT;
END;
UNTIL LaengeFile <= 0D;
(* Wandlung abgeschlossen*)
CloseDown;

END Wandler.
