Branch data 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 : 3432 : 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 : 3408 : int get_char ()
51 : : {
52 : 3408 : int c = this->peek_char ();
53 : 6816 : this->advance (1);
54 : 3408 : return c;
55 : : }
56 : :
57 : : // Return true if at the end of the stream.
58 : 3408 : 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 : 3480 : void advance (size_t skip)
82 : : {
83 : 3480 : 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
|