MODULE MergeSort; IMPORT Read, Write, UnixArguments, Streams, UnixFiles; VAR flag: CHAR; stream1,stream2,stream3: Streams.Stream; int1,int2: INTEGER; (* Achtung: Die Dateinamen sind hier fest vorgegeben. *) (* Besser waere es natuerlich die Dateinamen ueber stdin *) (* einzulesen... *) PROCEDURE MergeForward(); BEGIN IF UnixFiles.Open(stream1, "Daten1.dat", UnixFiles.read, 1, NIL) THEN IF UnixFiles.Open(stream2, "Daten2.dat", UnixFiles.read, 1, NIL) THEN IF UnixFiles.Open(stream3, "Daten3.dat", 5, 1, NIL) THEN Read.IntS(stream1,int1); Read.IntS(stream2,int2); WHILE (~stream1.eof) & (~stream2.eof) DO IF (int1 <= int2) THEN Write.String("Lese aus Datei 1"); Write.Ln; WHILE (~stream1.eof) & (int1 <= int2) DO Write.Int(int1,0); Write.Ln; IF ~(int1 = int2) THEN Write.IntS(stream3,int1,0); Write.LnS(stream3); END; Read.IntS(stream1,int1); END; ELSE Write.String("Lese aus Datei 2"); Write.Ln; WHILE (~stream2.eof) & (int2 <= int1) DO Write.Int(int2,0); Write.Ln; IF ~(int1 = int2) THEN Write.IntS(stream3,int2,0); Write.LnS(stream3); END; Read.IntS(stream2,int2); END; END; END; (* Die restlichen Werte aus der Datei auslesen, *) (* deren Ende noch nicht erreicht wurde *) IF ~(stream1.eof) THEN Write.String("Lese aus Datei 1"); Write.Ln; WHILE (~stream1.eof) DO Write.Int(int1,0); Write.Ln; Write.IntS(stream3,int1,0); Write.LnS(stream3); Read.IntS(stream1,int1); END; END; IF ~(stream2.eof) THEN Write.String("Lese aus Datei 2"); Write.Ln; WHILE (~stream2.eof) DO Write.Int(int2,0); Write.Ln; Write.IntS(stream3,int2,0); Write.LnS(stream3); Read.IntS(stream2,int2); END; END; END; END; END; IF Streams.Close(stream3) THEN END; IF Streams.Close(stream2) THEN END; IF Streams.Close(stream1) THEN END; END MergeForward; PROCEDURE MergeBackward(); BEGIN IF UnixFiles.Open(stream1, "Daten7.dat", UnixFiles.read, 1, NIL) THEN IF UnixFiles.Open(stream2, "Daten8.dat", UnixFiles.read, 1, NIL) THEN IF UnixFiles.Open(stream3, "Daten9.dat", 5, 1, NIL) THEN Read.IntS(stream1,int1); Read.IntS(stream2,int2); WHILE (~stream1.eof) & (~stream2.eof) DO IF (int1 >= int2) THEN Write.String("Lese aus Datei 1"); Write.Ln; WHILE (~stream1.eof) & (int1 >= int2) DO Write.Int(int1,0); Write.Ln; IF ~(int1 = int2) THEN Write.IntS(stream3,int1,0); Write.LnS(stream3); END; Read.IntS(stream1,int1); END; ELSE Write.String("Lese aus Datei 2"); Write.Ln; WHILE (~stream2.eof) & (int2 >= int1) DO Write.Int(int2,0); Write.Ln; IF ~(int1 = int2) THEN Write.IntS(stream3,int2,0); Write.LnS(stream3); END; Read.IntS(stream2,int2); END; END; END; (* Die restlichen Werte aus der Datei auslesen, *) (* deren Ende noch nicht erreicht wurde *) IF ~(stream1.eof) THEN Write.String("Lese aus Datei 1"); Write.Ln; WHILE (~stream1.eof) DO Write.Int(int1,0); Write.Ln; Write.IntS(stream3,int1,0); Write.LnS(stream3); Read.IntS(stream1,int1); END; END; IF ~(stream2.eof) THEN Write.String("Lese aus Datei 2"); Write.Ln; WHILE (~stream2.eof) DO Write.Int(int2,0); Write.Ln; Write.IntS(stream3,int2,0); Write.LnS(stream3); Read.IntS(stream2,int2); END; END; END; END; END; IF Streams.Close(stream3) THEN END; IF Streams.Close(stream2) THEN END; IF Streams.Close(stream1) THEN END; END MergeBackward; BEGIN Write.Ln; UnixArguments.Init("[-r]"); (* Falls kein Flag MergeForward *) IF ~UnixArguments.GetFlag(flag) THEN MergeForward; ELSE (* Fall r-Flag MergeBackward *) CASE flag OF | "r", "R": MergeBackward; ELSE Write.Ln; Write.String("Ungueltiges Argument"); Write.Ln; UnixArguments.Usage; END; (* Ein Argument "zurueckgehen" UnixArguments.UngetArg; *) END; Write.Ln; Write.Ln; END MergeSort.