1# =============================================================================
2#               ____ _   _ ____  _       _ _ _           _         _ _
3#  _ __  _   _ / ___| | | |  _ \| |     | (_) |__   __ _| |__   __| | |
4# | '_ \| | | | |  _| |_| | | | | |     | | | '_ \ / _` | '_ \ / _` | |
5# | |_) | |_| | |_| |  _  | |_| | |___ _| | | |_) | (_| | | | | (_| | |
6# | .__/ \__, |\____|_| |_|____/|_____(_)_|_|_.__/ \__, |_| |_|\__,_|_|
7# |_|    |___/                                     |___/
8# =============================================================================
9#  Authors:
10#    Tristan Gingold
11#    Patrick Lehmann
12#
13# Package package:  Python binding and low-level API for shared library 'libghdl'.
14#
15# License:
16# ============================================================================
17#  Copyright (C) 2019-2021 Tristan Gingold
18#
19#  This program is free software: you can redistribute it and/or modify
20#  it under the terms of the GNU General Public License as published by
21#  the Free Software Foundation, either version 2 of the License, or
22#  (at your option) any later version.
23#
24#  This program is distributed in the hope that it will be useful,
25#  but WITHOUT ANY WARRANTY; without even the implied warranty of
26#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
27#  GNU General Public License for more details.
28#
29#  You should have received a copy of the GNU General Public License
30#  along with this program.  If not, see <gnu.org/licenses>.
31#
32# SPDX-License-Identifier: GPL-2.0-or-later
33# ============================================================================
34
35from ctypes import c_void_p
36
37from pydecor import export
38
39from pyGHDL.libghdl import libghdl
40from pyGHDL.libghdl._types import NameId, SourceFileEntry
41
42__all__ = [
43	'EOT',
44	'No_Source_File_Entry',
45	'No_Location',
46]
47
48EOT = b"\x04"
49
50No_Source_File_Entry = 0
51
52No_Location = 0
53
54
55@export
56def Location_To_File(Location) -> SourceFileEntry:
57	"""
58	Convert :obj:`Location` to a source file.
59
60	:param Location: Location
61	:return:         Source file. Return ``No_Source_File_Entry`` if location is incorrect.
62	"""
63	return libghdl.files_map__location_to_file(Location)
64
65
66@export
67def Location_File_To_Pos(Location, File: SourceFileEntry) -> int:
68	"""
69	Convert :obj:`Location` and :obj:`File` to a position (offset) into the source file.
70
71	:param Location: Location
72	:param File:     Source file
73	:return:         Offset
74	"""
75	return libghdl.files_map__location_file_to_pos(Location, File)
76
77
78@export
79def Location_File_To_Line(Location, File: SourceFileEntry) -> int:
80	"""
81	Convert :obj:`Location` and :obj:`File` to a line number.
82
83	:param Location: Location
84	:param File:     Source file
85	:return:         Line number
86	"""
87	return libghdl.files_map__location_file_to_line(Location, File)
88
89
90@export
91def Location_File_Line_To_Offset(Location, File: SourceFileEntry, Line: int) -> int:
92	"""
93	Get the offset in :obj:`Line` of :obj:`Location`.
94
95	:param Location: Location
96	:param File:     Source file
97	:param Line:     Line number
98	:return:         Offset
99	"""
100	return libghdl.files_map__location_file_line_to_offset(Location, File, Line)
101
102
103@export
104def Location_File_Line_To_Col(Location, File: SourceFileEntry, Line: int) -> int:
105	"""
106	Get logical column (with HT expanded) from :obj:`Location`, :obj:`File` and
107	:obj:`Line`.
108
109	:param Location: Location
110	:param File:     Source file
111	:param Line:     Line number
112	:return:         logical column (horizontal tabs are expanded)
113	"""
114	return libghdl.files_map__location_file_line_to_col(Location, File, Line)
115
116
117@export
118def File_To_Location(File: SourceFileEntry):
119	"""Convert a :obj:`File` into a location.
120
121	:param File: Source file
122	:return:     Location. Type: ``Location_Type``
123	"""
124	return libghdl.files_map__file_to_location(File)
125
126
127@export
128def File_Pos_To_Location(File: SourceFileEntry, Pos: int):
129	"""
130	Convert a :obj:`File` and an offset :obj:`Pos` in the file into a location.
131
132	:param File: Source file
133	:param Pos:  Offset in the file
134	:return:     Location. Type: ``Location_Type``
135	"""
136	return libghdl.files_map__file_pos_to_location(File, Pos)
137
138
139@export
140def File_Line_To_Position(File: SourceFileEntry, Line: int) -> int:
141	"""
142	Convert a :obj:`File` and :obj:`Line` into a position.
143
144	:param File: Source file
145	:param Line: Line number
146	:return:     Return ``Source_Ptr_Bad`` in case of error (:obj:`Line` out of bounds).
147	"""
148	return libghdl.files_map__file_line_to_position(File, Line)
149
150
151@export
152def Get_File_Name(File: SourceFileEntry) -> NameId:
153	"""
154	Return the name of the file.
155
156	:param File: Source file to get the filename from.
157	:return:     NameId for the filename.
158	"""
159	return libghdl.files_map__get_file_name(File)
160
161
162@export
163def Get_Directory_Name(File: SourceFileEntry) -> NameId:
164	"""
165	Return the directory of the file.
166
167	:param File: Source file to get the directory name from.
168	:return:     NameId for the directory.
169	"""
170	return libghdl.files_map__get_directory_name(File)
171
172
173@export
174def Get_File_Buffer(File: SourceFileEntry) -> bytes:
175	"""
176	Return a buffer (access to the contents of the file) for a file entry.
177
178	:param File: Source file to get the buffer from.
179	:return:     Type: ``File_Buffer_Ptr``
180	"""
181	func = libghdl.files_map__get_file_buffer
182	func.restype = c_void_p
183
184	return func(File)
185
186
187@export
188def Get_File_Length(File: SourceFileEntry) -> int:
189	"""
190	Get the position of the first EOT character.
191
192	:param File: Source file
193	:return:     Type: ``Source_Ptr``
194	"""
195	return libghdl.files_map__get_file_length(File)
196
197
198@export
199def Set_File_Length(File: SourceFileEntry, Length: int) -> None:
200	"""
201	Set the length of the file (which is less than the size of the file buffer).
202
203	Set also append two EOT at the end of the file.
204
205	:param File:   Source file
206	:param Length: Length for the file. Type: ``Source_Ptr``
207	"""
208	libghdl.files_map__set_file_length(File, Length)
209
210
211@export
212def Read_Source_File(Directory: NameId, Name: NameId) -> SourceFileEntry:
213	"""
214	Return an entry for a filename.
215
216	Load the filename if necessary.
217
218	:param Directory: ``Null_Identifier`` for :obj:`DirectoryId` means current directory.
219	:param Name:      File name
220	:return:          Return ``No_Source_File_Entry``, if the file does not exist.
221	"""
222	return libghdl.files_map__read_source_file(Directory, Name)
223
224
225@export
226def Reserve_Source_File(Directory: NameId, Name: NameId, Length) -> SourceFileEntry:
227	"""
228	Reserve an entry, but do not read any file.
229
230	The length should includes the two terminal EOT.
231
232	:param Directory: Directory name
233	:param Name:      File name
234	:param Length:    Length to reserve. Type: ``Source_Ptr``
235	:return:          SourceFile
236	"""
237	return libghdl.files_map__reserve_source_file(Directory, Name, Length)
238
239@export
240def Discard_Source_File(File: SourceFileEntry) -> None:
241	"""
242	Mark :obj:`File` as unavailable: clear the name and directory.
243
244	.. hint:: This is needed before creating a new source file with the same name.
245
246	:param File: Source file to discard.
247	"""
248	libghdl.files_map__discard_source_file(File)
249
250
251@export
252def Free_Source_File(File: SourceFileEntry) -> None:
253	"""
254	Free resources used by :obj:`File`, but keep the entry.
255
256	.. note:: It could be recycled for files that could fit - not implemented.
257
258	:param File: Source file to free.
259	"""
260	libghdl.files_map__free_source_file(File)
261
262
263@export
264def Get_Last_Source_File_Entry() -> SourceFileEntry:
265	"""
266	Returns the entry of the last known file.
267
268	.. hint:: This allows creating a table of ``SourceFileEntry``.
269
270	:return: Last SourceFileEntry. Type: ``SourceFileEntry``
271	"""
272	return libghdl.files_map__get_last_source_file_entry()
273