OSDN Git Service

2008-04-08 Hristian Kirtchev <kirtchev@adacore.com>
[pf3gnuchains/gcc-fork.git] / gcc / ada / g-spchge.adb
1 ------------------------------------------------------------------------------
2 --                                                                          --
3 --                         GNAT RUN-TIME COMPONENTS                         --
4 --                                                                          --
5 --          G N A T . S P E L L I N G _ C H E C K E R _ G E N E R I C       --
6 --                                                                          --
7 --                                 B o d y                                  --
8 --                                                                          --
9 --                     Copyright (C) 1998-2007, AdaCore                     --
10 --                                                                          --
11 -- GNAT is free software;  you can  redistribute it  and/or modify it under --
12 -- terms of the  GNU General Public License as published  by the Free Soft- --
13 -- ware  Foundation;  either version 2,  or (at your option) any later ver- --
14 -- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
15 -- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
16 -- or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License --
17 -- for  more details.  You should have  received  a copy of the GNU General --
18 -- Public License  distributed with GNAT;  see file COPYING.  If not, write --
19 -- to  the  Free Software Foundation,  51  Franklin  Street,  Fifth  Floor, --
20 -- Boston, MA 02110-1301, USA.                                              --
21 --                                                                          --
22 -- As a special exception,  if other files  instantiate  generics from this --
23 -- unit, or you link  this unit with other files  to produce an executable, --
24 -- this  unit  does not  by itself cause  the resulting  executable  to  be --
25 -- covered  by the  GNU  General  Public  License.  This exception does not --
26 -- however invalidate  any other reasons why  the executable file  might be --
27 -- covered by the  GNU Public License.                                      --
28 --                                                                          --
29 -- GNAT was originally developed  by the GNAT team at  New York University. --
30 -- Extensive contributions were provided by Ada Core Technologies Inc.      --
31 --                                                                          --
32 ------------------------------------------------------------------------------
33
34 pragma Warnings (Off);
35 pragma Compiler_Unit;
36 pragma Warnings (On);
37
38 package body GNAT.Spelling_Checker_Generic is
39
40    ------------------------
41    -- Is_Bad_Spelling_Of --
42    ------------------------
43
44    function Is_Bad_Spelling_Of
45      (Found  : String_Type;
46       Expect : String_Type) return Boolean
47    is
48       FN : constant Natural := Found'Length;
49       FF : constant Natural := Found'First;
50       FL : constant Natural := Found'Last;
51
52       EN : constant Natural := Expect'Length;
53       EF : constant Natural := Expect'First;
54       EL : constant Natural := Expect'Last;
55
56       Letter_o : constant Char_Type := Char_Type'Val (Character'Pos ('o'));
57       Digit_0  : constant Char_Type := Char_Type'Val (Character'Pos ('0'));
58       Digit_9  : constant Char_Type := Char_Type'Val (Character'Pos ('9'));
59
60    begin
61       --  If both strings null, then we consider this a match, but if one
62       --  is null and the other is not, then we definitely do not match
63
64       if FN = 0 then
65          return (EN = 0);
66
67       elsif EN = 0 then
68          return False;
69
70          --  If first character does not match, then we consider that this is
71          --  definitely not a misspelling. An exception is when we expect a
72          --  letter O and found a zero.
73
74       elsif Found (FF) /= Expect (EF)
75         and then (Found (FF) /= Digit_0 or else Expect (EF) /= Letter_o)
76       then
77          return False;
78
79       --  Not a bad spelling if both strings are 1-2 characters long
80
81       elsif FN < 3 and then EN < 3 then
82          return False;
83
84       --  Lengths match. Execute loop to check for a single error, single
85       --  transposition or exact match (we only fall through this loop if
86       --  one of these three conditions is found).
87
88       elsif FN = EN then
89          for J in 1 .. FN - 2 loop
90             if Expect (EF + J) /= Found (FF + J) then
91
92                --  If both mismatched characters are digits, then we do
93                --  not consider it a misspelling (e.g. B345 is not a
94                --  misspelling of B346, it is something quite different)
95
96                if Expect (EF + J) in Digit_0 .. Digit_9
97                  and then Found (FF + J) in Digit_0 .. Digit_9
98                then
99                   return False;
100
101                elsif Expect (EF + J + 1) = Found (FF + J + 1)
102                  and then Expect (EF + J + 2 .. EL) = Found (FF + J + 2 .. FL)
103                then
104                   return True;
105
106                elsif Expect (EF + J) = Found (FF + J + 1)
107                  and then Expect (EF + J + 1) = Found (FF + J)
108                  and then Expect (EF + J + 2 .. EL) = Found (FF + J + 2 .. FL)
109                then
110                   return True;
111
112                else
113                   return False;
114                end if;
115             end if;
116          end loop;
117
118          --  At last character. Test digit case as above, otherwise we
119          --  have a match since at most this last character fails to match.
120
121          if Expect (EL) in Digit_0 .. Digit_9
122            and then Found (FL) in Digit_0 .. Digit_9
123            and then Expect (EL) /= Found (FL)
124          then
125             return False;
126          else
127             return True;
128          end if;
129
130       --  Length is 1 too short. Execute loop to check for single deletion
131
132       elsif FN = EN - 1 then
133          for J in 1 .. FN - 1 loop
134             if Found (FF + J) /= Expect (EF + J) then
135                return Found (FF + J .. FL) = Expect (EF + J + 1 .. EL);
136             end if;
137          end loop;
138
139          --  If we fall through then the last character was missing, which
140          --  we consider to be a match (e.g. found xyz, expected xyza).
141
142          return True;
143
144       --  Length is 1 too long. Execute loop to check for single insertion
145
146       elsif FN = EN + 1 then
147          for J in 1 .. EN - 1 loop
148             if Found (FF + J) /= Expect (EF + J) then
149                return Found (FF + J + 1 .. FL) = Expect (EF + J .. EL);
150             end if;
151          end loop;
152
153          --  If we fall through then the last character was an additional
154          --  character, which is a match (e.g. found xyza, expected xyz).
155
156          return True;
157
158       --  Length is completely wrong
159
160       else
161          return False;
162       end if;
163    end Is_Bad_Spelling_Of;
164
165 end GNAT.Spelling_Checker_Generic;