1 ------------------------------------------------------------------------------
3 -- GNAT COMPILER COMPONENTS --
9 -- Copyright (C) 2008-2023, Free Software Foundation, Inc. --
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 3, 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 COPYING3. If not, go to --
19 -- http://www.gnu.org/licenses for a complete copy of the license. --
21 -- GNAT was originally developed by the GNAT team at New York University. --
22 -- Extensive contributions were provided by Ada Core Technologies Inc. --
24 ------------------------------------------------------------------------------
28 with System
.WCh_Cnv
; use System
.WCh_Cnv
;
30 with GNAT
.UTF_32_Spelling_Checker
;
32 package body Namet
.Sp
is
34 -----------------------
35 -- Local Subprograms --
36 -----------------------
38 procedure Get_Name_String_UTF_32
40 Result
: out UTF_32_String
;
41 Length
: out Natural);
42 -- This procedure is similar to Get_Decoded_Name except that the output
43 -- is stored in the given Result array as single codes, so in particular
44 -- any Uhh, Whhhh, or WWhhhhhhhh sequences are decoded to appear as a
45 -- single value in the output. This call does not affect the contents of
46 -- either Name_Buffer or Name_Len. The result is in Result (1 .. Length).
47 -- The caller must ensure that the result buffer is long enough.
49 ------------------------
50 -- Aspect_Spell_Check --
51 ------------------------
53 function Aspect_Spell_Check
(Name
: Name_Id
) return Boolean is
54 (Aspect_Spell_Check
(Name
) /= No_Name
);
56 function Aspect_Spell_Check
(Name
: Name_Id
) return Name_Id
is
59 for J
in Aspect_Id_Exclude_No_Aspect
loop
60 if Is_Bad_Spelling_Of
(Name
, Aspect_Names
(J
)) then
61 return Aspect_Names
(J
);
66 end Aspect_Spell_Check
;
68 ---------------------------
69 -- Attribute_Spell_Check --
70 ---------------------------
72 function Attribute_Spell_Check
(N
: Name_Id
) return Boolean is
73 (Attribute_Spell_Check
(N
) /= No_Name
);
75 function Attribute_Spell_Check
(N
: Name_Id
) return Name_Id
is
78 for J
in First_Attribute_Name
.. Last_Attribute_Name
loop
79 if Is_Bad_Spelling_Of
(N
, J
) then
85 end Attribute_Spell_Check
;
87 ----------------------------
88 -- Get_Name_String_UTF_32 --
89 ----------------------------
91 procedure Get_Name_String_UTF_32
93 Result
: out UTF_32_String
;
96 pragma Assert
(Result
'First = 1);
98 SPtr
: Int
:= Name_Entries
.Table
(Id
).Name_Chars_Index
+ 1;
99 -- Index through characters of name in Name_Chars table. Initial value
100 -- points to first character of the name.
102 SLen
: constant Nat
:= Nat
(Name_Entries
.Table
(Id
).Name_Len
);
103 -- Length of the name
105 SLast
: constant Int
:= SPtr
+ SLen
- 1;
106 -- Last index in Name_Chars table for name
109 -- Current character from Name_Chars table
111 procedure Store_Hex
(N
: Natural);
112 -- Read and store next N characters starting at SPtr and store result
113 -- in next character of Result. Update SPtr past characters read.
119 procedure Store_Hex
(N
: Natural) is
126 C
:= Name_Chars
.Table
(SPtr
);
129 if C
in '0' .. '9' then
130 T
:= 16 * T
+ Character'Pos (C
) - Character'Pos ('0');
132 pragma Assert
(C
in 'a' .. 'f');
134 T
:= 16 * T
+ Character'Pos (C
) - (Character'Pos ('a') - 10);
138 Length
:= Length
+ 1;
139 pragma Assert
(Length
<= Result
'Length);
140 Result
(Length
) := T
;
143 -- Start of processing for Get_Name_String_UTF_32
147 while SPtr
<= SLast
loop
148 C
:= Name_Chars
.Table
(SPtr
);
153 and then SPtr
<= SLast
- 2
154 and then Name_Chars
.Table
(SPtr
+ 1) not in 'A' .. 'Z'
162 and then SPtr
<= SLast
- 4
163 and then Name_Chars
.Table
(SPtr
+ 1) not in 'A' .. 'Z'
168 -- WWhhhhhhhh encoding
171 and then SPtr
<= SLast
- 8
172 and then Name_Chars
.Table
(SPtr
+ 1) = 'W'
177 -- Q encoding (character literal)
179 elsif C
= 'Q' and then SPtr
< SLast
then
181 -- Put apostrophes around character
183 pragma Assert
(Length
<= Result
'Last - 3);
184 Result
(Length
+ 1) := UTF_32_Code
'Val (Character'Pos ('''));
185 Result
(Length
+ 2) :=
186 UTF_32_Code
(Get_Char_Code
(Name_Chars
.Table
(SPtr
+ 1)));
187 Result
(Length
+ 3) := UTF_32_Code
'Val (Character'Pos ('''));
189 Length
:= Length
+ 3;
195 Length
:= Length
+ 1;
196 pragma Assert
(Length
<= Result
'Last);
197 Result
(Length
) := UTF_32_Code
(Get_Char_Code
(C
));
200 end Get_Name_String_UTF_32
;
202 ------------------------
203 -- Is_Bad_Spelling_Of --
204 ------------------------
206 function Is_Bad_Spelling_Of
(Found
, Expect
: Name_Id
) return Boolean is
207 FL
: constant Natural := Natural (Length_Of_Name
(Found
));
208 EL
: constant Natural := Natural (Length_Of_Name
(Expect
));
209 -- Length of input names
211 FB
: UTF_32_String
(1 .. 2 * FL
);
212 EB
: UTF_32_String
(1 .. 2 * EL
);
213 -- Buffers for results, a factor of 2 is more than enough, the only
214 -- sequence which expands is Q (character literal) by 1.5 times.
218 -- Length of decoded names
221 Get_Name_String_UTF_32
(Found
, FB
, FBL
);
222 Get_Name_String_UTF_32
(Expect
, EB
, EBL
);
224 -- For an exact match, return False, otherwise check bad spelling. We
225 -- need this special test because the library routine returns True for
228 if FB
(1 .. FBL
) = EB
(1 .. EBL
) then
232 GNAT
.UTF_32_Spelling_Checker
.Is_Bad_Spelling_Of
233 (FB
(1 .. FBL
), EB
(1 .. EBL
));
235 end Is_Bad_Spelling_Of
;