-- Line sorting program to run in Laurel -- -- [Cherry]Laurel>LineSorter.mesa -- Mike Schroeder, June 30, 1981 12:41 PM -- -- Edited by Brotz, November 19, 1981 3:56 PM -- DIRECTORY BTreeDefs, csD: FROM "CoreStreamDefs", Inline, IODefs, String, VMDefs; LineSorter: PROGRAM IMPORTS BTreeDefs, csD, 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 = [48]; inputStr, outputStr: csD.StreamHandle _ NIL; NextLine: 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/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; --NextLine-- 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]; WriteChar[CR]; DO WriteChar[CR]; WriteString["Type input file name: "L]; ReadID[buffer ! Rubout => LOOP]; IF buffer.length = 0 THEN GOTO cleanup; inputStr _ csD.OpenFromName[buffer, byte, read ! VMDefs.Error, VMDefs.CantOpen => {WriteString["Can't open input file."L]; LOOP}]; EXIT; ENDLOOP; DO WriteChar[CR]; WriteString["Type output file name: "L]; ReadID[buffer ! Rubout => LOOP]; IF buffer.length = 0 THEN GOTO cleanup; outputStr _ csD.OpenFromName[buffer, byte, overwrite ! VMDefs.Error, VMDefs.CantOpen => {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 => {WriteChar[CR]; WriteLine["File error."L]; GOTO cleanup}]; IF buffer.length = 0 THEN EXIT; PutEntry[buffer, start, length]; ENDLOOP; WriteLine["Writing output file."L]; BTreeDefs.EnumerateFrom[tree, DESCRIPTOR[NIL, 0], PrintingWork ! VMDefs.Error => {WriteChar[CR]; WriteLine["File error."L]; GOTO cleanup}]; GOTO cleanup; EXITS cleanup => BEGIN IF inputStr # NIL THEN csD.Close[inputStr ! VMDefs.Error => CONTINUE]; IF outputStr # NIL THEN csD.Close[outputStr ! VMDefs.Error => CONTINUE]; VMDefs.AbandonFile[LOOPHOLE[BTreeDefs.ReleaseBTree[tree]]]; END; END; WriteLine["Done"L]; END; -- of Run -- Run[]; END. -- of LineSorter --z20461(1792)\f1