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