Branch data Line data Source code
1 : : // Copyright (C) 2023-2024 Free Software Foundation, Inc.
2 : :
3 : : // This file is part of GCC.
4 : :
5 : : // GCC is free software; you can redistribute it and/or modify it under
6 : : // the terms of the GNU General Public License as published by the Free
7 : : // Software Foundation; either version 3, or (at your option) any later
8 : : // version.
9 : :
10 : : // GCC is distributed in the hope that it will be useful, but WITHOUT ANY
11 : : // WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 : : // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 : : // for more details.
14 : :
15 : : // You should have received a copy of the GNU General Public License
16 : : // along with GCC; see the file COPYING3. If not see
17 : : // <http://www.gnu.org/licenses/>.
18 : :
19 : : #ifndef RUST_FMT_H
20 : : #define RUST_FMT_H
21 : :
22 : : #include "rust-system.h"
23 : : #include <cstddef>
24 : :
25 : : // FIXME: How to encode Option?
26 : :
27 : : namespace Rust {
28 : : namespace Fmt {
29 : :
30 : : namespace ffi {
31 : :
32 : : struct RustHamster
33 : : {
34 : : const char *ptr;
35 : : size_t len;
36 : :
37 : : std::string to_string () const;
38 : : };
39 : :
40 : : /// Enum of alignments which are supported.
41 : : enum class Alignment
42 : : {
43 : : /// The value will be aligned to the left.
44 : : AlignLeft,
45 : : /// The value will be aligned to the right.
46 : : AlignRight,
47 : : /// The value will be aligned in the center.
48 : : AlignCenter,
49 : : /// The value will take on a default alignment.
50 : : AlignUnknown,
51 : : };
52 : :
53 : : /// Enum for the debug hex flags.
54 : : enum class DebugHex
55 : : {
56 : : /// The `x` flag in `{:x?}`.
57 : : Lower,
58 : : /// The `X` flag in `{:X?}`.
59 : : Upper,
60 : : };
61 : :
62 : : /// Enum for the sign flags.
63 : : enum class Sign
64 : : {
65 : : /// The `+` flag.
66 : : Plus,
67 : : /// The `-` flag.
68 : : Minus,
69 : : };
70 : :
71 : : /// Enum describing where an argument for a format can be located.
72 : : struct Position
73 : : {
74 : : enum class Tag
75 : : {
76 : : /// The argument is implied to be located at an index
77 : : ArgumentImplicitlyIs,
78 : : /// The argument is located at a specific index given in the format,
79 : : ArgumentIs,
80 : : /// The argument has a name.
81 : : ArgumentNamed,
82 : : };
83 : :
84 : : struct ArgumentImplicitlyIs_Body
85 : : {
86 : : size_t _0;
87 : : };
88 : :
89 : : struct ArgumentIs_Body
90 : : {
91 : : size_t _0;
92 : : };
93 : :
94 : : struct ArgumentNamed_Body
95 : : {
96 : : RustHamster _0;
97 : : };
98 : :
99 : : Tag tag;
100 : : union
101 : : {
102 : : ArgumentImplicitlyIs_Body argument_implicitly_is;
103 : : ArgumentIs_Body argument_is;
104 : : ArgumentNamed_Body argument_named;
105 : : };
106 : : };
107 : :
108 : : /// Range inside of a `Span` used for diagnostics when we only have access to
109 : : /// relative positions.
110 : : struct InnerSpan
111 : : {
112 : : size_t start;
113 : : size_t end;
114 : : };
115 : :
116 : : /// A count is used for the precision and width parameters of an integer, and
117 : : /// can reference either an argument or a literal integer.
118 : : struct Count
119 : : {
120 : : enum class Tag
121 : : {
122 : : /// The count is specified explicitly.
123 : : CountIs,
124 : : /// The count is specified by the argument with the given name.
125 : : CountIsName,
126 : : /// The count is specified by the argument at the given index.
127 : : CountIsParam,
128 : : /// The count is specified by a star (like in `{:.*}`) that refers to the
129 : : /// argument at the given index.
130 : : CountIsStar,
131 : : /// The count is implied and cannot be explicitly specified.
132 : : CountImplied,
133 : : };
134 : :
135 : : struct CountIs_Body
136 : : {
137 : : size_t _0;
138 : : };
139 : :
140 : : struct CountIsName_Body
141 : : {
142 : : RustHamster _0;
143 : : InnerSpan _1;
144 : : };
145 : :
146 : : struct CountIsParam_Body
147 : : {
148 : : size_t _0;
149 : : };
150 : :
151 : : struct CountIsStar_Body
152 : : {
153 : : size_t _0;
154 : : };
155 : :
156 : : Tag tag;
157 : : union
158 : : {
159 : : CountIs_Body count_is;
160 : : CountIsName_Body count_is_name;
161 : : CountIsParam_Body count_is_param;
162 : : CountIsStar_Body count_is_star;
163 : : };
164 : : };
165 : :
166 : : /// Specification for the formatting of an argument in the format string.
167 : : struct FormatSpec
168 : : {
169 : : /// Optionally specified character to fill alignment with.
170 : : const uint32_t *fill;
171 : : /// Span of the optionally specified fill character.
172 : : const InnerSpan *fill_span;
173 : : /// Optionally specified alignment.
174 : : Alignment align;
175 : : /// The `+` or `-` flag.
176 : : const Sign *sign;
177 : : /// The `#` flag.
178 : : bool alternate;
179 : : /// The `0` flag.
180 : : bool zero_pad;
181 : : /// The `x` or `X` flag. (Only for `Debug`.)
182 : : const DebugHex *debug_hex;
183 : : /// The integer precision to use.
184 : : Count precision;
185 : : /// The span of the precision formatting flag (for diagnostics).
186 : : const InnerSpan *precision_span;
187 : : /// The string width requested for the resulting format.
188 : : Count width;
189 : : /// The span of the width formatting flag (for diagnostics).
190 : : const InnerSpan *width_span;
191 : : /// The descriptor string representing the name of the format desired for
192 : : /// this argument, this can be empty or any number of characters, although
193 : : /// it is required to be one word.
194 : : RustHamster ty;
195 : : /// The span of the descriptor string (for diagnostics).
196 : : const InnerSpan *ty_span;
197 : : };
198 : :
199 : : /// Representation of an argument specification.
200 : : struct Argument
201 : : {
202 : : /// Where to find this argument
203 : : Position position;
204 : : /// The span of the position indicator. Includes any whitespace in implicit
205 : : /// positions (`{ }`).
206 : : InnerSpan position_span;
207 : : /// How to format the argument
208 : : FormatSpec format;
209 : : };
210 : :
211 : : /// A piece is a portion of the format string which represents the next part
212 : : /// to emit. These are emitted as a stream by the `Parser` class.
213 : : struct Piece
214 : : {
215 : : enum class Tag
216 : : {
217 : : /// A literal string which should directly be emitted
218 : : String,
219 : : /// This describes that formatting should process the next argument (as
220 : : /// specified inside) for emission.
221 : : NextArgument,
222 : : };
223 : :
224 : : struct String_Body
225 : : {
226 : : RustHamster _0;
227 : : };
228 : :
229 : : struct NextArgument_Body
230 : : {
231 : : Argument _0;
232 : : };
233 : :
234 : : Tag tag;
235 : : union
236 : : {
237 : : String_Body string;
238 : : NextArgument_Body next_argument;
239 : : };
240 : : };
241 : :
242 : : struct PieceSlice
243 : : {
244 : : const Piece *base_ptr;
245 : : size_t len;
246 : : size_t cap;
247 : : };
248 : :
249 : : struct RustString
250 : : {
251 : : const unsigned char *ptr;
252 : : size_t len;
253 : : size_t cap;
254 : : };
255 : :
256 : : struct FormatArgsHandle
257 : : {
258 : : PieceSlice piece_slice;
259 : : RustString rust_string;
260 : : };
261 : :
262 : : extern "C" {
263 : :
264 : : FormatArgsHandle
265 : : collect_pieces (const char *input, bool append_newline);
266 : :
267 : : FormatArgsHandle
268 : : clone_pieces (const FormatArgsHandle &);
269 : :
270 : : void destroy_pieces (FormatArgsHandle);
271 : :
272 : : } // extern "C"
273 : :
274 : : } // namespace ffi
275 : :
276 : : struct Pieces
277 : : {
278 : : static Pieces collect (const std::string &to_parse, bool append_newline);
279 : : ~Pieces ();
280 : :
281 : : Pieces (const Pieces &other);
282 : : Pieces &operator= (const Pieces &other);
283 : :
284 : : Pieces (Pieces &&other);
285 : :
286 : 1 : const std::vector<ffi::Piece> &get_pieces () const { return pieces_vector; }
287 : :
288 : : // {
289 : : // slice = clone_pieces (&other.slice);
290 : : // to_parse = other.to_parse;
291 : :
292 : : // return *this;
293 : : // }
294 : :
295 : : private:
296 : 1 : Pieces (ffi::FormatArgsHandle handle, std::vector<ffi::Piece> &&pieces_vector)
297 : 1 : : pieces_vector (std::move (pieces_vector)), handle (handle)
298 : : {}
299 : :
300 : : std::vector<ffi::Piece> pieces_vector;
301 : :
302 : : // this memory is held for FFI reasons - it needs to be released and cloned
303 : : // precisely, so try to not access it/modify it if possible. you should
304 : : // instead work with `pieces_vector`
305 : : ffi::FormatArgsHandle handle;
306 : : };
307 : :
308 : : } // namespace Fmt
309 : : } // namespace Rust
310 : :
311 : : #endif // !RUST_FMT_H
|