awa_2.4.0_59135a52/dynamo/src/asis/a4g-u_conv.adb

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
------------------------------------------------------------------------------
--                                                                          --
--                 ASIS-for-GNAT IMPLEMENTATION COMPONENTS                  --
--                                                                          --
--                          A 4 G . U _ C O N V                             --
--                                                                          --
--                                 B o d y                                  --
--                                                                          --
--            Copyright (c) 1995-2006, Free Software Foundation, Inc.       --
--                                                                          --
-- ASIS-for-GNAT is free software; you can redistribute it and/or modify it --
-- under terms of the  GNU General Public License  as published by the Free --
-- Software Foundation;  either version 2,  or  (at your option)  any later --
-- version. ASIS-for-GNAT is distributed  in the hope  that it will be use- --
-- ful, but WITHOUT ANY WARRANTY; without even the implied warranty of MER- --
-- CHANTABILITY  or  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General --
-- Public License for more details.  You should have received a copy of the --
-- GNU  General  Public License  distributed with ASIS-for-GNAT; see   file --
-- COPYING.  If not,  write  to the  Free Software Foundation,  51 Franklin --
-- Street, Fifth Floor, Boston, MA 02110-1301, USA.                         --
--                                                                          --
--                                                                          --
--                                                                          --
--                                                                          --
--                                                                          --
--                                                                          --
--                                                                          --
--                                                                          --
-- ASIS-for-GNAT was originally developed  by the ASIS-for-GNAT team at the --
-- Software  Engineering  Laboratory  of  the Swiss  Federal  Institute  of --
-- Technology (LGL-EPFL) in Lausanne,  Switzerland, in cooperation with the --
-- Scientific  Research  Computer  Center of  Moscow State University (SRCC --
-- MSU), Russia,  with funding partially provided  by grants from the Swiss --
-- National  Science  Foundation  and  the  Swiss  Academy  of  Engineering --
-- Sciences. ASIS-for-GNAT is now maintained by AdaCore                     --
-- (http://www.adaccore.com).                                               --
--                                                                          --
------------------------------------------------------------------------------

with Ada.Characters.Handling; use Ada.Characters.Handling;

with Namet;                   use Namet;
with Fname;                   use Fname;
with Krunch;
with Opt;                     use Opt;

package body A4G.U_Conv is

   ---------------------------------
   -- Local Types and Subprograms --
   ---------------------------------

   --  We use the trivial finite state automata to analyse and to transform
   --  strings passed as parameters to ASIS interfaces and processed by ASIS
   --  itself below there are type and routines definitions for various
   --  versions of this automata

   type State is (Beg_Ident, Mid_Ident, Und_Line);
   --  The states of the automata. Some versions may use only a part of the
   --  whole set of states.

   procedure Normalize_Char (In_Char    :        Character;
                             Curr_State : in out State;
                             Out_Char   : out    Character;
                             OK         : out    Boolean);
   --  One step of the finite-state-automata analyzing the string which is
   --  supposed to be an Ada unit name and producind the "normalized"
   --  version of the name. If In_Char under in the state Curr_State may be
   --  considered as belonging to the Ada unit name, the "low-case version"
   --  of this character is assigned to Out_Char, and OK is ste True,
   --  otherwise OK is set false

   function Convert_Char (Ch : Character) return Character;
   --  performs upper case -> lover case conversion in the GNAT file
   --  name style (see GNAT Document INTRO and Fnames.ads - only letters
   --  from the A .. Z range are folded to lower case)

   ------------------
   -- Convert_Char --
   ------------------

   function Convert_Char (Ch : Character) return Character is
   begin

      if Ch = '.' then
         return '-';
      else
         return To_Lower (Ch);
      end if;

   end Convert_Char;

   ------------------------
   -- Get_Norm_Unit_Name --
   ------------------------

   procedure Get_Norm_Unit_Name
     (U_Name           :     String;
      N_U_Name         : out String;
      Spec             :     Boolean;
      May_Be_Unit_Name : out Boolean)
   is
      Current_State : State := Beg_Ident;
   begin

      May_Be_Unit_Name := False;

      for I in U_Name'Range loop

         Normalize_Char (U_Name   (I), Current_State,
                         N_U_Name (I), May_Be_Unit_Name);

         exit when not May_Be_Unit_Name;

      end loop;

      if not May_Be_Unit_Name then
         return;

      elsif N_U_Name (U_Name'Last) = '_' or else
            N_U_Name (U_Name'Last) = '.'
      then
         --  something like "Ab_" -> "ab_" or "Ab_Cd." -> "ab_cd."
         May_Be_Unit_Name := False;
         return;
      end if;

      --  here we have all the content of U_Name parced and
      --  May_Be_Unit_Name is True. All we have to do is to append
      --  the "%s" or "%b" suffix

      N_U_Name (N_U_Name'Last - 1) := '%';

      if Spec then
         N_U_Name (N_U_Name'Last) := 's';
      else
         N_U_Name (N_U_Name'Last) := 'b';
      end if;

   end Get_Norm_Unit_Name;

   -----------------------------
   -- Is_Predefined_File_Name --
   -----------------------------

   function Is_Predefined_File_Name (S : String_Access) return Boolean is
   begin
      Namet.Name_Len := S'Length - 1;
      --  "- 1" is for trailing ASCII.NUL in the file name
      Namet.Name_Buffer (1 .. Namet.Name_Len) := To_String (S);
      return Fname.Is_Predefined_File_Name (Namet.Name_Enter);
   end Is_Predefined_File_Name;

   --------------------
   -- Normalize_Char --
   --------------------

   procedure Normalize_Char
     (In_Char    :        Character;
      Curr_State : in out State;
      Out_Char   : out    Character;
      OK         : out    Boolean)
   is
   begin

      OK := True;

      case Curr_State is

         when Beg_Ident =>

            if Is_Letter (In_Char) then
               Curr_State := Mid_Ident;
            else
               OK := False;
            end if;

         when Mid_Ident =>

            if Is_Letter (In_Char) or else
               Is_Digit (In_Char)
            then
               null;
            elsif In_Char = '_' then
               Curr_State := Und_Line;
            elsif In_Char = '.' then
               Curr_State := Beg_Ident;
            else
               OK := False;
            end if;

         when Und_Line =>
            if Is_Letter (In_Char) or else
               Is_Digit  (In_Char)
            then
               Curr_State := Mid_Ident;
            else
               OK := False;
            end if;

      end case;

      Out_Char := To_Lower (In_Char);

   end Normalize_Char;

   ---------------------------
   -- Source_From_Unit_Name --
   ---------------------------

   function Source_From_Unit_Name
     (S    : String;
      Spec : Boolean)
      return String_Access
   is
      Result_Prefix   : String (1 .. S'Length);
      Result_Selector : String (1 .. 4) := ".adb";

      Initial_Length  : constant Natural := S'Length;
      Result_Length   : Natural          := Initial_Length;
      --  this is for the name krunching
   begin
      for I in S'Range loop
         Result_Prefix (I) := Convert_Char (S (I));
      end loop;

      Krunch
       (Buffer    => Result_Prefix,
        Len       => Result_Length,
        Maxlen    => Integer (Maximum_File_Name_Length),
        No_Predef => False);

      if Spec then
         Result_Selector (4) := 's';
      end if;

      return new String'(Result_Prefix (1 .. Result_Length)
                       & Result_Selector
                       & ASCII.NUL);

   end Source_From_Unit_Name;

   ---------------
   -- To_String --
   ---------------

   function To_String (S : String_Access) return String is
   begin
      return S.all (S'First .. S'Last - 1);
   end To_String;

   ---------------------------
   -- Tree_From_Source_Name --
   ---------------------------

   function Tree_From_Source_Name (S : String_Access) return String_Access is
      Return_Val : String_Access;
   begin
      Return_Val := new String'(S.all);
      --  the content of S should be "*.ad?" & ASCII.NUL
      Return_Val (Return_Val'Last - 1) := 't'; -- ".ad?" -> ".adt"
      return Return_Val;
   end Tree_From_Source_Name;

end A4G.U_Conv;