-- LineSorter.mesa -- Line sorting program to run in Laurel -- -- Mike Schroeder, March 1, 1982 4:38 PM -- -- Taft, May 9, 1983 4:21 PM -- DIRECTORY AltoFile, BTreeDefs, csD: FROM "CoreStreamDefs", DiskIODefs, Inline, IODefs, String, VMDefs; LineSorter: PROGRAM IMPORTS AltoFile, BTreeDefs, csD, DiskIODefs, Inline, IODefs, String, VMDefs = BEGIN OPEN IODefs, String; MyLowerCase: PROCEDURE[c: CHARACTER] RETURNS[CHARACTER] = INLINE BEGIN RETURN[IF c IN ['A..'Z] THEN c - 'A + 'a ELSE c]; END; --MyLowerCase-- IsFirstGE: BTreeDefs.TestKeys --[a, b: DESC] RETURNS[BOOLEAN] -- = BEGIN aC: POINTER TO PACKED ARRAY OF CHARACTER = LOOPHOLE[BASE[a]]; bC: POINTER TO PACKED ARRAY OF CHARACTER = LOOPHOLE[BASE[b]]; FOR i:CARDINAL IN [0..2*MIN[LENGTH[a],LENGTH[b]]) DO IF MyLowerCase[aC[i]] < MyLowerCase[bC[i]] THEN RETURN[FALSE]; IF MyLowerCase[aC[i]] > MyLowerCase[bC[i]] THEN RETURN[TRUE]; ENDLOOP; RETURN[LENGTH[a] >= LENGTH[b]]; END; -- of IsFirstGE -- AreTheyE: BTreeDefs.TestKeys --[a, b: DESC] RETURNS[BOOLEAN] -- = BEGIN aC: POINTER TO PACKED ARRAY OF CHARACTER = LOOPHOLE[BASE[a]]; bC: POINTER TO PACKED ARRAY OF CHARACTER = LOOPHOLE[BASE[b]]; IF LENGTH[a] = LENGTH[b] THEN FOR i:CARDINAL IN [0..2*LENGTH[a]) DO IF MyLowerCase[aC[i]] # MyLowerCase[bC[i]] THEN EXIT; REPEAT FINISHED => RETURN[TRUE]; ENDLOOP; RETURN[FALSE]; END; -- of AreTheyE -- Run: PROCEDURE = BEGIN tree: BTreeDefs.BTreeHandle; buffer: STRING = [62]; inputStr, outputStr: csD.StreamHandle _ NIL; NextLine: PROCEDURE [s: STRING] RETURNS [ f: LONG CARDINAL, n: CARDINAL]; FWNextLine: PROCEDURE [s: STRING] RETURNS [ f: LONG CARDINAL, n: CARDINAL] = BEGIN c: CHARACTER; s.length _ 0; f _ csD.GetPosition[inputStr]; BEGIN ENABLE csD.EndOfStream => CONTINUE; c _ csD.Read[inputStr]; UNTIL c # SP AND c # TAB DO c _ csD.Read[inputStr]; ENDLOOP; UNTIL c = SP OR c = TAB OR c = CR DO AppendChar[s, c ! StringBoundsFault => CONTINUE]; c _ csD.Read[inputStr]; ENDLOOP; IF s.length MOD 2 # 0 THEN AppendChar[s, SP]; UNTIL c = CR DO c _ csD.Read[inputStr]; ENDLOOP; END; --enable-- n _ Inline.LowHalf[ csD.GetPosition[inputStr] - f ]; END; --FWNextLine-- MarkerNextLine: PROCEDURE [s: STRING] RETURNS [ f: LONG CARDINAL, n: CARDINAL] = BEGIN c: CHARACTER; s.length _ 0; f _ csD.GetPosition[inputStr]; BEGIN ENABLE csD.EndOfStream => CONTINUE; c _ csD.Read[inputStr]; UNTIL c = ControlA OR c = CR DO c _ csD.Read[inputStr]; ENDLOOP; IF c # CR THEN BEGIN c _ csD.Read[inputStr]; UNTIL c # SP AND c # TAB DO c _ csD.Read[inputStr]; ENDLOOP; UNTIL c = ControlB OR c = CR DO AppendChar[s, c ! StringBoundsFault => CONTINUE]; c _ csD.Read[inputStr]; ENDLOOP; IF s.length MOD 2 # 0 THEN AppendChar[s, SP]; UNTIL c = CR DO c _ csD.Read[inputStr]; ENDLOOP; END ELSE IF csD.GetPosition[inputStr] - f > 1 THEN{ csD.SetPosition[inputStr, f]; [] _ FWNextLine[s]}; END; --enable-- n _ Inline.LowHalf[ csD.GetPosition[inputStr] - f ]; END; --MarkerNextLine-- PutEntry: PROCEDURE [key: STRING, start: LONG CARDINAL, count: CARDINAL] = BEGIN keyWords: CARDINAL = (key.length+1)/2; k: DESCRIPTOR FOR ARRAY OF WORD = DESCRIPTOR [@(key.text), (keyWords+SIZE[LONG CARDINAL]+SIZE[CARDINAL])]; v: DESCRIPTOR FOR ARRAY OF WORD = DESCRIPTOR[NIL, 0]; Inline.COPY[from:@start, to:BASE[k]+keyWords, nwords:SIZE[LONG CARDINAL]]; Inline.COPY[from:@count, to:BASE[k]+keyWords+SIZE[LONG CARDINAL], nwords:SIZE[CARDINAL]]; BTreeDefs.Insert[tree, k, v]; END; --PutEntry-- PrintingWork: BTreeDefs.Call --PROCEDURE[k, v: DESCRIPTOR] RETURNS[more, dirty: BOOLEAN]-- = BEGIN first: LONG CARDINAL; number: CARDINAL; more _ TRUE; dirty _ FALSE; IF LENGTH[k] = 0 THEN RETURN; Inline.COPY[from:BASE[k]+LENGTH[k] - SIZE[LONG CARDINAL] - SIZE[CARDINAL], to:@first, nwords:SIZE[LONG CARDINAL]]; Inline.COPY[from:BASE[k]+LENGTH[k] - SIZE[CARDINAL], to:@number, nwords:SIZE[CARDINAL]]; csD.SetPosition[inputStr, first]; csD.StreamCopy[inputStr, outputStr, LONG[number]]; END; --PrintingWork-- BEGIN --for EXITS -- tree _ BTreeDefs.CreateAndInitializeBTree[ fileH:LOOPHOLE[VMDefs.OpenFile[name: "DLMap.btree$", options: oldOrNew]], initializeFile:TRUE, useDefaultOrderingRoutines:FALSE, isFirstGreaterOrEqual:IsFirstGE, areTheyEqual:AreTheyE]; DO WriteChar[CR]; WriteString["Sort by f(irst word) or m(arkers)? "L]; SELECT LowerCase[ReadChar[]] FROM 'f => NextLine _ FWNextLine; 'm => NextLine _ MarkerNextLine; ENDCASE => LOOP; EXIT; ENDLOOP; DO WriteChar[CR]; WriteString["Type input file name: "L]; buffer.length _ 0; AppendString[buffer, "temp$$"L]; ReadID[buffer ! Rubout => LOOP]; IF buffer.length = 0 THEN GOTO cleanup; inputStr _ csD.OpenFromName[buffer, byte, read ! VMDefs.Error, VMDefs.CantOpen, DiskIODefs.DiskError => { WriteString["Can't open input file."L]; LOOP}]; EXIT; ENDLOOP; DO WriteChar[CR]; WriteString["Type output file name: "L]; buffer.length _ 0; AppendString[buffer, "temp$"L]; ReadID[buffer ! Rubout => LOOP]; IF buffer.length = 0 THEN GOTO cleanup; outputStr _ csD.OpenFromName[buffer, byte, overwrite ! VMDefs.Error, VMDefs.CantOpen, DiskIODefs.DiskError, AltoFile.DiskFull => { WriteString["Can't open output file."L]; LOOP}]; EXIT; ENDLOOP; WriteChar[CR]; WriteLine["Reading input file."L]; DO start: LONG CARDINAL; length: CARDINAL; [start, length] _ NextLine[buffer ! VMDefs.Error, DiskIODefs.DiskError => { WriteChar[CR]; WriteLine["File error."L]; GOTO cleanup}]; IF length=0 THEN EXIT; IF buffer.length # 0 THEN PutEntry[buffer, start, length]; ENDLOOP; WriteLine["Writing output file."L]; BTreeDefs.EnumerateFrom[tree, DESCRIPTOR[NIL, 0], PrintingWork ! VMDefs.Error, DiskIODefs.DiskError, AltoFile.DiskFull => { WriteChar[CR]; WriteLine["File error."L]; GOTO cleanup}]; GOTO cleanup; EXITS cleanup => BEGIN IF inputStr # NIL THEN csD.Close[inputStr ! VMDefs.Error, DiskIODefs.DiskError => CONTINUE]; IF outputStr # NIL THEN csD.Close[outputStr ! VMDefs.Error, DiskIODefs.DiskError, AltoFile.DiskFull => CONTINUE]; VMDefs.AbandonFile[LOOPHOLE[BTreeDefs.ReleaseBTree[tree]]]; END; END; WriteLine["Done"L]; END; Run[]; END.z20461(1792)\f7 143f1 119f7 69f0 6f7 14f0 6f7 32f0 6f7 1455f1 15f7 398f0 6f7 256f1 15f7 745f0 6f7 387f0 6f7 151f0 6f7 448f0 6f7 244f0 6f7 1107f1 125f7 250f1 204f7 184f1 118f7 225f1 133f7 113f1 6f7 8f1 10f7 89f1 6f7 8f1 10f7