[MAINTAINERS] Update my email address and move to DCO.
[official-gcc.git] / gcc / ada / namet-sp.adb
blob2895342bf459ccb19b9bb08f6bc6dff4d29b11d9
1 ------------------------------------------------------------------------------
2 -- --
3 -- GNAT COMPILER COMPONENTS --
4 -- --
5 -- N A M E T . S P --
6 -- --
7 -- B o d y --
8 -- --
9 -- Copyright (C) 2008-2024, Free Software Foundation, Inc. --
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 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. --
20 -- --
21 -- GNAT was originally developed by the GNAT team at New York University. --
22 -- Extensive contributions were provided by Ada Core Technologies Inc. --
23 -- --
24 ------------------------------------------------------------------------------
26 with Aspects;
27 with Snames;
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
39 (Id : Name_Id;
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
57 use Aspects;
58 begin
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);
62 end if;
63 end loop;
65 return No_Name;
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
76 use Snames;
77 begin
78 for J in First_Attribute_Name .. Last_Attribute_Name loop
79 if Is_Bad_Spelling_Of (N, J) then
80 return J;
81 end if;
82 end loop;
84 return No_Name;
85 end Attribute_Spell_Check;
87 ----------------------------
88 -- Get_Name_String_UTF_32 --
89 ----------------------------
91 procedure Get_Name_String_UTF_32
92 (Id : Name_Id;
93 Result : out UTF_32_String;
94 Length : out Natural)
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
108 C : Character;
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.
115 ---------------
116 -- Store_Hex --
117 ---------------
119 procedure Store_Hex (N : Natural) is
120 T : UTF_32_Code;
121 C : Character;
123 begin
124 T := 0;
125 for J in 1 .. N loop
126 C := Name_Chars.Table (SPtr);
127 SPtr := SPtr + 1;
129 if C in '0' .. '9' then
130 T := 16 * T + Character'Pos (C) - Character'Pos ('0');
131 else
132 pragma Assert (C in 'a' .. 'f');
134 T := 16 * T + Character'Pos (C) - (Character'Pos ('a') - 10);
135 end if;
136 end loop;
138 Length := Length + 1;
139 pragma Assert (Length <= Result'Length);
140 Result (Length) := T;
141 end Store_Hex;
143 -- Start of processing for Get_Name_String_UTF_32
145 begin
146 Length := 0;
147 while SPtr <= SLast loop
148 C := Name_Chars.Table (SPtr);
150 -- Uhh encoding
152 if C = 'U'
153 and then SPtr <= SLast - 2
154 and then Name_Chars.Table (SPtr + 1) not in 'A' .. 'Z'
155 then
156 SPtr := SPtr + 1;
157 Store_Hex (2);
159 -- Whhhh encoding
161 elsif C = 'W'
162 and then SPtr <= SLast - 4
163 and then Name_Chars.Table (SPtr + 1) not in 'A' .. 'Z'
164 then
165 SPtr := SPtr + 1;
166 Store_Hex (4);
168 -- WWhhhhhhhh encoding
170 elsif C = 'W'
171 and then SPtr <= SLast - 8
172 and then Name_Chars.Table (SPtr + 1) = 'W'
173 then
174 SPtr := SPtr + 2;
175 Store_Hex (8);
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 ('''));
188 SPtr := SPtr + 2;
189 Length := Length + 3;
191 -- Unencoded case
193 else
194 SPtr := SPtr + 1;
195 Length := Length + 1;
196 pragma Assert (Length <= Result'Last);
197 Result (Length) := UTF_32_Code (Get_Char_Code (C));
198 end if;
199 end loop;
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.
216 FBL : Natural;
217 EBL : Natural;
218 -- Length of decoded names
220 begin
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
226 -- an exact match.
228 if FB (1 .. FBL) = EB (1 .. EBL) then
229 return False;
230 else
231 return
232 GNAT.UTF_32_Spelling_Checker.Is_Bad_Spelling_Of
233 (FB (1 .. FBL), EB (1 .. EBL));
234 end if;
235 end Is_Bad_Spelling_Of;
237 end Namet.Sp;