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