aboutsummaryrefslogtreecommitdiffstats
path: root/src/files_map.ads
blob: 573d924837b2a20fecc6c3c0ebb8c91ad8ef1005 (plain)
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
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
--  Loading of source files.
--  Copyright (C) 2002, 2003, 2004, 2005 Tristan Gingold
--
--  This program is free software: you can redistribute it and/or modify
--  it under the terms of the GNU General Public License as published by
--  the Free Software Foundation, either version 2 of the License, or
--  (at your option) any later version.
--
--  This program is distributed in the hope that it will be useful,
--  but WITHOUT ANY WARRANTY; without even the implied warranty of
--  MERCHANTABILITY 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
--  along with this program.  If not, see <gnu.org/licenses>.
with Types; use Types;
with Tables;
with Dyn_Tables;
with Vhdl.Types;

--  Source file handling

package Files_Map is

   --  Range for Tab_Stop.
   subtype Tab_Stop_Range is Natural range 1 .. 120;

   --  Tab width: a tab character jumps to the next column that is one plus a
   --  multiple of this witdh (if columns are numbered from 1).
   Tab_Stop : Tab_Stop_Range := 8;

   --  Create the path from DIRECTORY and NAME:
   --  If NAME is an absolute pathname, then return NAME.
   --  Otherwise, return the concatenation of DIRECTORY and NAME.
   function Get_Pathname (Directory : Name_Id; Name : Name_Id) return String;

   --  If NAME contains a directory separator, move it to the DIRECTORY name.
   --  At the return point, NAME has no directory components.
   procedure Normalize_Pathname
     (Directory : in out Name_Id; Name : in out Name_Id);

   --  Return an entry for a filename.  Null_Identifier for DIRECTORY means
   --  current directory.
   --  Load the filename if necessary.
   --  Return No_Source_File_Entry if the file does not exist.
   function Read_Source_File (Directory : Name_Id; Name : Name_Id)
                              return Source_File_Entry;

   --  Reserve an entry, but do not read any file.
   --  The length should includes the two terminal EOT.
   function Reserve_Source_File
     (Directory : Name_Id; Name : Name_Id; Length : Source_Ptr)
     return Source_File_Entry;

   --  Each file in memory has two terminal EOT.
   EOT : constant Character := Character'Val (4);

   --  From the extension of FILENAME, extract the language.
   --  Return Language_Unknown is not known.
   function Find_Language (Filename : String) return Language_Type;

   --  Create an empty Source_File for a virtual file name.  Used for implicit,
   --  command-line and std.standard library.
   function Create_Virtual_Source_File (Name : Name_Id)
                                       return Source_File_Entry;

   --  Create a Source_File for a possible virtual file NAME using CONTENT
   --  as content of the file.  The file must not already exist.
   function Create_Source_File_From_String (Name : Name_Id; Content : String)
                                           return Source_File_Entry;

   --  Create a pseudo source file from REF for instance INST (created at
   --  location LOC).  The content of this file is the same as REF, but with
   --  new locations so that it is possible to retrieve the instance from
   --  the new locations.
   function Create_Instance_Source_File (Ref : Source_File_Entry;
                                         Loc : Location_Type;
                                         Inst : Vhdl.Types.Vhdl_Node)
                                        return Source_File_Entry;

   --  Unload last source file.  Works only with the last one.  Must be
   --  carefully used as the corresponding locations will be reused.
   procedure Unload_Last_Source_File (File : Source_File_Entry);

   --  Mark FILE as unavailable: clear the name and directory.
   --  This is needed before creating a new source file with the same name.
   procedure Discard_Source_File (File : Source_File_Entry);

   --  Free resources used by FILE, but keep the entry.
   --  (It could be recycled for files that could fit - not implemented).
   procedure Free_Source_File (File : Source_File_Entry);

   --  Relocate location LOC (which must be in the reference of INST_FILE)
   --  for instrnace INST_FILE.
   function Instance_Relocate
     (Inst_File : Source_File_Entry; Loc : Location_Type)
     return Location_Type;

   --  If LOC is a location of an instance (in a file created by
   --  create_instance_source_file), return the location where the instance
   --  has been created.  Otherwise, return No_Location.
   function Location_Instance_To_Location
     (Loc : Location_Type) return Location_Type;

   --  If POS points to the start of the gap of FILE, it will be updated
   --  to the next character after the gap.
   procedure Skip_Gap (File : Source_File_Entry; Pos : in out Source_Ptr);

   --  Return a buffer (access to the contents of the file) for a file entry.
   function Get_File_Source (File : Source_File_Entry) return File_Buffer_Acc;

   --  Likewise but return a pointer.  To be used only from non-Ada code.
   function Get_File_Buffer (File : Source_File_Entry) return File_Buffer_Ptr;

   --  Set the length of the file (which is less than the size of the
   --  file buffer).
   --  Set also append two EOT at the end of the file.
   procedure Set_File_Length (File : Source_File_Entry; Length : Source_Ptr);

   --  Get the position of the first EOT character.
   function Get_File_Length (File : Source_File_Entry) return Source_Ptr;

   --  Get the length of the content; this is the file length minus the gap,
   --  if the gap is before the end.
   function Get_Content_Length (File : Source_File_Entry) return Source_Ptr;

   --  Get the length of the buffer, which always includes the gap and the
   --  two terminal EOT.
   function Get_Buffer_Length (File : Source_File_Entry) return Source_Ptr;

   --  Return the name of the file.
   function Get_File_Name (File : Source_File_Entry) return Name_Id;

   --  Return the directory of the file.
   function Get_Directory_Name (File : Source_File_Entry) return Name_Id;

   --  Return the entry of the last known file.
   --  This allow the user to create a table of Source_File_Entry.
   function Get_Last_Source_File_Entry return Source_File_Entry;

   --  Time stamp handling.
   function Is_Eq (L : Time_Stamp_Id; R : Time_Stamp_Id) return Boolean;
   function Is_Gt (L : Time_Stamp_Id; R : Time_Stamp_Id) return Boolean;
   function Get_Time_Stamp_String (Ts : Time_Stamp_Id) return String;

   --  Return the checksum of the content of FILE.
   function Get_File_Checksum (File : Source_File_Entry)
                              return File_Checksum_Id;

   --  True if two file checksums are identical.
   function Is_Eq (L, R : File_Checksum_Id) return Boolean;

   --  String image of CHECKSUM.
   function Get_File_Checksum_String (Checksum : File_Checksum_Id)
                                     return String;

   --  Return the current date of the system.
   function Get_Os_Time_Stamp return Time_Stamp_Id;

   --  Return the home directory (current directory).
   function Get_Home_Directory return Name_Id;

   --  Add a new entry in the lines_table.
   --  The new entry must be the next one after the last entry.
   procedure File_Add_Line_Number
     (File : Source_File_Entry; Line : Positive; Pos : Source_Ptr);

   --  Convert LOCATION to a source file.  Return No_Source_File_Entry if
   --  LOCATION is incorrect.
   function Location_To_File (Location : Location_Type)
                             return Source_File_Entry;

   --  Convert LOCATION and FILE to a position (offset) into the source file.
   function Location_File_To_Pos
     (Location : Location_Type; File : Source_File_Entry) return Source_Ptr;

   --  Convert LOCATION and FILE to a line number.
   function Location_File_To_Line
     (Location : Location_Type; File : Source_File_Entry) return Positive;

   --  Get the offset in the line LINE of LOC.
   function Location_File_Line_To_Offset
     (Loc : Location_Type; File : Source_File_Entry; Line : Positive)
     return Natural;

   --  Get logical column (with HT expanded) from LOC, FILE and LINE.
   function Location_File_Line_To_Col
     (Loc : Location_Type; File : Source_File_Entry; Line : Positive)
     return Natural;

   --  Convert LOCATION into a source file FILE and an offset POS in the
   --  file.
   procedure Location_To_File_Pos (Location : Location_Type;
                                   File : out Source_File_Entry;
                                   Pos : out Source_Ptr);

   --  Convert a FILE and an offset POS in the file into a location.
   function File_Pos_To_Location (File : Source_File_Entry; Pos : Source_Ptr)
                                 return Location_Type;

   --  Convert a FILE into a location.
   function File_To_Location (File : Source_File_Entry) return Location_Type;

   --  Convert a FILE+LINE into a position.
   --  Return Source_Ptr_Bad in case of error (LINE out of bounds).
   function File_Line_To_Position (File : Source_File_Entry; Line : Positive)
                                  return Source_Ptr;

   --  Translate LOCATION into coordinate (physical position).
   --  FILE identifies the filename.
   --  LINE_POS is the offset in the file of the first character of the line,
   --  LINE is the line number (first line is 1),
   --  OFFSET is the offset of the location in the line (first character is 0,
   --     a tabulation is one character),
   procedure Location_To_Coord (Location : Location_Type;
                                File : out Source_File_Entry;
                                Line_Pos : out Source_Ptr;
                                Line : out Positive;
                                Offset : out Natural);

   --  Convert FILE and POS to coordinate.
   procedure File_Pos_To_Coord (File : Source_File_Entry;
                                Pos : Source_Ptr;
                                Line_Pos : out Source_Ptr;
                                Line : out Positive;
                                Offset : out Natural);

   --  Convert a physical column to a logical column.
   --  A physical column is the offset in byte from the first byte of the line.
   --  A logical column is the position of the character when displayed.
   --  A HT (tabulation) moves the cursor to the next position multiple of the
   --  tab stop.
   --  The first character is at position 1 and at offset 0.
   function Coord_To_Col (File : Source_File_Entry;
                          Line_Pos : Source_Ptr;
                          Offset : Natural) return Natural;

   --  Translate coordinate into logical position.
   --  NAME is the name of the file,
   --  COL is the column (first character is 1, tabulation are at every 8
   --    positions).
   procedure Coord_To_Position (File : Source_File_Entry;
                                Line_Pos : Source_Ptr;
                                Offset : Natural;
                                Name : out Name_Id;
                                Col : out Natural);

   --  Translate LOCATION to NAME, LINE and COL.
   --  It is like to two procedures above.
   procedure Location_To_Position (Location : Location_Type;
                                   Name : out Name_Id;
                                   Line : out Positive;
                                   Col : out Natural);

   --  Return the line LINE from FILE (without end of line).  The line is
   --  expanded: tabs are replaced by spaces according to Tab_Stop.  This
   --  function is slow.
   function Extract_Expanded_Line (File : Source_File_Entry;
                                   Line : Positive) return String;

   --  Return the image of LOC using the "FILENAME:LINE:COL" format or
   --  "LINE:COL" format if FILENAME is false;
   function Image (Loc : Location_Type; Filename : Boolean := True)
                  return String;

   --  Initialize.
   procedure Initialize;

   --  Free all memory.
   procedure Finalize;

private
   Lines_Table_Init : Natural := 64;

   package Lines_Tables is new Dyn_Tables
     (Table_Component_Type => Source_Ptr,
      Table_Index_Type => Natural,
      Table_Low_Bound => 1);

   --  There are several kinds of source file.
   type Source_File_Kind is
     (
      --  A *real* source file, read from the filesystem.
      Source_File_File,

      --  A virtual source file, created from a string.
      Source_File_String,

      --  A duplicated source file (there is no copy however), created by
      --  an instantiation.
      Source_File_Instance
     );

   --  Data associed with a file.
   type Source_File_Record (Kind : Source_File_Kind := Source_File_File) is
      record
      --  All location between first and last belong to this file.
      First_Location : Location_Type;
      Last_Location : Location_Type;

      --  The name_id that identify this file.
      --  FIXME: what about file aliasing (links) ?
      File_Name : Name_Id;

      Directory : Name_Id;

      --  The buffer containing the file.
      Source : File_Buffer_Acc;

      --  Position of the EOT character after the file.  Also the length of
      --  the file + 1, unless there is a gap.
      File_Length : Source_Ptr;

      Checksum : File_Checksum_Id;

      case Kind is
         when Source_File_File =>
            --  Line table

            Lines : Lines_Tables.Instance;

            --  Cache for line table.
            Cache_Line : Positive;
            Cache_Pos : Source_Ptr;

            --  Gap
            Gap_Start : Source_Ptr;
            Gap_Last : Source_Ptr;

         when Source_File_String =>
            --  There is only one line.
            null;

         when Source_File_Instance =>
            --  The instance was created from REF.
            Ref : Source_File_Entry;
            --  The ultimate non-instance is BASE.
            Base : Source_File_Entry;

            Instance_Loc : Location_Type;
      end case;
   end record;

   package Source_Files is new Tables
     (Table_Index_Type => Source_File_Entry,
      Table_Component_Type => Source_File_Record,
      Table_Low_Bound => No_Source_File_Entry + 1,
      Table_Initial => 16);

   --  Debug procedures.

   --  Disp info about all source files
   procedure Debug_Source_Files;
end Files_Map;