Line data Source code
1 : // Copyright 2009 The Go Authors. All rights reserved.
2 : // Use of this source code is governed by a BSD-style
3 : // license that can be found in the LICENSE file.
4 :
5 : #ifndef RUST_IMPORTS_H
6 : #define RUST_IMPORTS_H
7 :
8 : #include "rust-system.h"
9 : #include "rust-location.h"
10 : #include "rust-proc-macro.h"
11 :
12 : namespace Rust {
13 :
14 : extern void add_search_path (const std::string &path);
15 :
16 : class Import
17 : {
18 : public:
19 : // The Stream class is an interface used to read the data. The
20 : // caller should instantiate a child of this class.
21 : class Stream
22 : {
23 : public:
24 : Stream ();
25 : virtual ~Stream ();
26 :
27 : // Set the position, for error messages.
28 : void set_pos (int pos) { this->pos_ = pos; }
29 :
30 : // Return whether we have seen an error.
31 3104 : bool saw_error () const { return this->saw_error_; }
32 :
33 : // Record that we've seen an error.
34 0 : void set_saw_error () { this->saw_error_ = true; }
35 :
36 : // Return the next character (a value from 0 to 0xff) without
37 : // advancing. Returns -1 at end of stream.
38 : int peek_char ();
39 :
40 : // Look for LENGTH characters, setting *BYTES to point to them.
41 : // Returns false if the bytes are not available. Does not
42 : // advance.
43 0 : bool peek (size_t length, const char **bytes)
44 : {
45 0 : return this->do_peek (length, bytes);
46 : }
47 :
48 : // Return the next character (a value from 0 to 0xff) and advance
49 : // the read position by 1. Returns -1 at end of stream.
50 3080 : int get_char ()
51 : {
52 3080 : int c = this->peek_char ();
53 6160 : this->advance (1);
54 3080 : return c;
55 : }
56 :
57 : // Return true if at the end of the stream.
58 3080 : bool at_eof () { return this->peek_char () == -1; }
59 :
60 : // Return true if the next bytes match STR.
61 : bool match_c_string (const char *str)
62 : {
63 : return this->match_bytes (str, strlen (str));
64 : }
65 :
66 : // Return true if the next LENGTH bytes match BYTES.
67 : bool match_bytes (const char *bytes, size_t length);
68 :
69 : // Give an error if the next bytes do not match STR. Advance the
70 : // read position by the length of STR.
71 : void require_c_string (location_t location, const char *str)
72 : {
73 : this->require_bytes (location, str, strlen (str));
74 : }
75 :
76 : // Given an error if the next LENGTH bytes do not match BYTES.
77 : // Advance the read position by LENGTH.
78 : void require_bytes (location_t, const char *bytes, size_t length);
79 :
80 : // Advance the read position by SKIP bytes.
81 3152 : void advance (size_t skip)
82 : {
83 3152 : this->do_advance (skip);
84 72 : this->pos_ += skip;
85 : }
86 :
87 : // Return the current read position. This returns int because it
88 : // is more convenient in error reporting. FIXME.
89 0 : int pos () { return static_cast<int> (this->pos_); }
90 :
91 : // This function should set *BYTES to point to a buffer holding
92 : // the LENGTH bytes at the current read position. It should
93 : // return false if the bytes are not available. This should not
94 : // change the current read position.
95 : virtual bool do_peek (size_t length, const char **bytes) = 0;
96 :
97 : // This function should advance the current read position LENGTH
98 : // bytes.
99 : virtual void do_advance (size_t skip) = 0;
100 :
101 : private:
102 : // The current read position.
103 : size_t pos_;
104 : // True if we've seen an error reading from this stream.
105 : bool saw_error_;
106 : };
107 :
108 : // Find import data. This searches the file system for FILENAME and
109 : // returns a pointer to a Stream object to read the data that it
110 : // exports. LOCATION is the location of the import statement.
111 : // RELATIVE_IMPORT_PATH is used as a prefix for a relative import.
112 : static std::pair<std::unique_ptr<Stream>, std::vector<ProcMacro::Procmacro>>
113 : open_package (const std::string &filename, location_t location,
114 : const std::string &relative_import_path);
115 :
116 : static std::pair<std::unique_ptr<Stream>, std::vector<ProcMacro::Procmacro>>
117 : try_package_in_directory (const std::string &, location_t);
118 :
119 : // Constructor.
120 : Import (std::unique_ptr<Stream>, location_t);
121 :
122 : // The location of the import statement.
123 : location_t location () const { return this->location_; }
124 :
125 : // Return the next character.
126 : int peek_char () { return this->stream_->peek_char (); }
127 :
128 : // Return the next character and advance.
129 : int get_char () { return this->stream_->get_char (); }
130 :
131 : // Read LENGTH characters into *OUT and advance past them. On
132 : // EOF reports an error and sets *OUT to an empty string.
133 : void read (size_t length, std::string *out);
134 :
135 : // Return true at the end of the stream.
136 : bool at_eof () { return this->stream_->at_eof (); }
137 :
138 : // Return whether the next bytes match STR.
139 : bool match_c_string (const char *str)
140 : {
141 : return this->stream_->match_c_string (str);
142 : }
143 :
144 : // Require that the next bytes match STR.
145 : void require_c_string (const char *str)
146 : {
147 : this->stream_->require_c_string (this->location_, str);
148 : }
149 :
150 : // Advance the stream SKIP bytes.
151 0 : void advance (size_t skip) { this->stream_->advance (skip); }
152 :
153 : // Stream position, for error reporting.
154 : int pos () { return this->stream_->pos (); }
155 :
156 : // Clear the stream when it is no longer accessible.
157 : void clear_stream () { this->stream_ = NULL; }
158 :
159 : private:
160 : static int try_suffixes (std::string *);
161 :
162 : static std::unique_ptr<Stream> find_export_data (const std::string &filename,
163 : int fd, location_t);
164 :
165 : static std::unique_ptr<Stream>
166 : find_object_export_data (const std::string &filename, int fd, off_t offset,
167 : location_t);
168 :
169 : static bool is_archive_magic (const char *);
170 :
171 : static std::unique_ptr<Stream>
172 : find_archive_export_data (const std::string &filename, int fd, location_t);
173 :
174 : // The stream from which to read import data.
175 : std::unique_ptr<Stream> stream_;
176 : // The location of the import statement we are processing.
177 : location_t location_;
178 : };
179 :
180 : // Read import data from a string.
181 :
182 : class Stream_from_string : public Import::Stream
183 : {
184 : public:
185 0 : Stream_from_string (const std::string &str) : str_ (str), pos_ (0) {}
186 :
187 0 : bool do_peek (size_t length, const char **bytes)
188 : {
189 0 : if (this->pos_ + length > this->str_.length ())
190 : return false;
191 0 : *bytes = this->str_.data () + this->pos_;
192 0 : return true;
193 : }
194 :
195 0 : void do_advance (size_t len) { this->pos_ += len; }
196 :
197 : private:
198 : // The string of data we are reading.
199 : std::string str_;
200 : // The current position within the string.
201 : size_t pos_;
202 : };
203 :
204 : // Read import data from a buffer allocated using malloc.
205 :
206 : class Stream_from_buffer : public Import::Stream
207 : {
208 : public:
209 0 : Stream_from_buffer (char *buf, size_t length)
210 0 : : buf_ (buf), length_ (length), pos_ (0)
211 : {}
212 :
213 0 : ~Stream_from_buffer () { free (this->buf_); }
214 :
215 0 : bool do_peek (size_t length, const char **bytes)
216 : {
217 0 : if (this->pos_ + length > this->length_)
218 : return false;
219 0 : *bytes = this->buf_ + this->pos_;
220 0 : return true;
221 : }
222 :
223 0 : void do_advance (size_t len) { this->pos_ += len; }
224 :
225 : private:
226 : // The data we are reading.
227 : char *buf_;
228 : // The length of the buffer.
229 : size_t length_;
230 : // The current position within the buffer.
231 : size_t pos_;
232 : };
233 :
234 : // Read import data from an open file descriptor.
235 :
236 : class Stream_from_file : public Import::Stream
237 : {
238 : public:
239 : Stream_from_file (int fd);
240 :
241 : ~Stream_from_file ();
242 :
243 : bool do_peek (size_t, const char **);
244 :
245 : void do_advance (size_t);
246 :
247 : private:
248 : // No copying.
249 : Stream_from_file (const Stream_from_file &);
250 : Stream_from_file &operator= (const Stream_from_file &);
251 :
252 : // The file descriptor.
253 : int fd_;
254 : // Data read from the file.
255 : std::string data_;
256 : };
257 :
258 : } // namespace Rust
259 :
260 : #endif // RUST_IMPORTS_H
|