CVS difference for arm/progs/arm_indx.adb

Differences between 1.11 and version 1.12
Log of other versions for file arm/progs/arm_indx.adb

--- arm/progs/arm_indx.adb	2007/12/20 07:43:33	1.11
+++ arm/progs/arm_indx.adb	2010/03/31 23:56:36	1.12
@@ -14,7 +14,7 @@
     -- This package contains the routines to manage and generate the index.
     --
     -- ---------------------------------------
-    -- Copyright 2000, 2002, 2003, 2004, 2005, 2006, 2007  AXE Consultants.
+    -- Copyright 2000, 2002, 2003, 2004, 2005, 2006, 2007, 2010  AXE Consultants.
     -- P.O. Box 1512, Madison WI  53701
     -- E-Mail: randy@rrsoftware.com
     --
@@ -59,6 +59,8 @@
     --  9/22/06 - RLB - Changed to use Clause_Number_Type.
     --  2/13/07 - RLB - Changed Start_Paragraph to use explicit indents.
     -- 12/19/07 - RLB - Revised Text_Format calls.
+    --  3/31/10 - RLB - Fixed sorting to ignore embedded commands (like
+    --			soft hyphens).
 
     Next_Index_Key : Index_Key;
 
@@ -108,7 +110,8 @@
     function Clean (Item : in String;
 		    Remove_Soft_Hyphens : in Boolean) return String is
 	-- Remove any commands from Item. (Except for soft hyphens
-	-- if Remove_Soft_Hyphens is False.)
+	-- if Remove_Soft_Hyphens is False.) We keep the contents of any
+	-- commands (we assume the commands are basic formatting).
 	Result : String (1 .. Item'Length);
 	Len : Natural := 0;
 	In_Command : Boolean := False;
@@ -150,7 +153,7 @@
 		    -- Skip it.
 		end if;
 	    elsif Skip_Next_Char then
-		Skip_Next_Char := True;
+		Skip_Next_Char := False;
 	    elsif In_Command then
 		if Item(I) = '{' then
 		    Close_Char := '}';
@@ -597,21 +600,82 @@
 
 		type Compare_Result is (Less, Greater, Equal);
 		function Compare (Left, Right : in String) return Compare_Result is
-		    -- By binding the arguments, we cut the heap usage by
-		    -- nearly half, and thus the runtime of the compare routine.
+		    -- Compare two items; the compare is case insensitive and
+		    -- ignores embedded commands.
 		begin
-		    if Left < Right then
-			return Less;
-		    elsif Left > Right then
+		    -- Simple cases in order to increase performance.
+		    -- Check for null cases so we don't have to worry about them
+		    -- later.
+		    if Left = Right then
+		        return Equal;
+		    elsif Left'Length = 0 then
+		        return Less; -- Right can't be null or they'd be equal.
+		    elsif Right'Length = 0 then
 			return Greater;
-		    else
-			return Equal;
 		    end if;
+		    -- Both strings are non-null.
+		    if Left(Left'First) in '0'..'9' or else
+		       Left(Left'First) in 'A'..'Z' then
+			if Right(Right'First) in '0'..'9' or else
+			   Right(Right'First) in 'A'..'Z' then
+			   if Left(Left'First) < Right(Right'First) then
+			       return Less;
+			   elsif Left(Left'First) > Right(Right'First) then
+			       return Greater;
+			   -- else continue below.
+			   end if;
+			elsif Right(Right'First) in 'a'..'z' then
+			   if Left(Left'First) < Character'Val(Character'Pos(Right(Right'First))+Character'Pos('A')-Character'Pos('a')) then
+			       return Less;
+			   elsif Left(Left'First) > Character'Val(Character'Pos(Right(Right'First))+Character'Pos('A')-Character'Pos('a')) then
+			       return Greater;
+			   end if;
+			-- else continue below.
+			end if;
+		    elsif Left(Left'First) in 'a'..'z' then
+			if Right(Right'First) in '0'..'9' or else
+			   Right(Right'First) in 'A'..'Z' then
+			   if Character'Val(Character'Pos(Left(Left'First))+Character'Pos('A')-Character'Pos('a')) < Right(Right'First) then
+			       return Less;
+			   elsif Character'Val(Character'Pos(Left(Left'First))+Character'Pos('A')-Character'Pos('a')) > Right(Right'First) then
+			       return Greater;
+			   -- else continue below.
+			   end if;
+			elsif Right(Right'First) in 'a'..'z' then -- Both lower.
+			   if Left(Left'First) < Right(Right'First) then
+			       return Less;
+			   elsif Left(Left'First) > Right(Right'First) then
+			       return Greater;
+			   end if;
+			-- else continue below.
+			end if;
+		    -- else continue below.
+		    end if;
+
+		    -- OK, do a full compare:
+		    declare
+		        -- %% Warning: This has terrible performance, too much heap use.
+		        L : constant String := Clean (To_Lower (Left), Remove_Soft_Hyphens => True);
+		        R : constant String := Clean (To_Lower (Right), Remove_Soft_Hyphens => True);
+		    begin
+--Ada.Text_IO.Put_Line("Full compare: Left=" & Left & "; Right=" & Right);
+--Ada.Text_IO.Put_Line("   Clean Left=" & L & "; Clean Right=" & R);
+		        if L < R then
+--Ada.Text_IO.Put_Line("   Result=Less");
+			    return Less;
+		        elsif L > R then
+--Ada.Text_IO.Put_Line("   Result=Greater");
+			    return Greater;
+		        else
+--Ada.Text_IO.Put_Line("   Result=Equal");
+			    return Equal;
+		        end if;
+		    end;
 		end Compare;
 	    begin
 		-- We sort first on "Term", then on "Kind", then on "Subterm",
 		-- then on "Clause", and finally on "Paragraph".
-		case Compare (To_Lower (Left.Term (1..Left.Term_Len)), To_Lower (Right.Term (1..Right.Term_Len))) is
+		case Compare (Left.Term (1..Left.Term_Len), Right.Term (1..Right.Term_Len)) is
 		    when Less => return True;
 		    when Greater => return False;
 		    when Equal => null; -- Continue to next compare.
@@ -630,7 +694,7 @@
 		else --if Left.Kind > Right.Kind then
 		    return False;
 		end if;
-		case Compare (To_Lower (Left.Subterm (1..Left.Subterm_Len)), To_Lower (Right.Subterm (1..Right.Subterm_Len))) is
+		case Compare (Left.Subterm (1..Left.Subterm_Len), Right.Subterm (1..Right.Subterm_Len)) is
 		    when Less => return True;
 		    when Greater => return False;
 		    when Equal => null; -- Continue to next compare.

Questions? Ask the ACAA Technical Agent