aboutsummaryrefslogtreecommitdiff
path: root/gcc/rust/metadata/rust-imports.h
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/rust/metadata/rust-imports.h')
-rw-r--r--gcc/rust/metadata/rust-imports.h257
1 files changed, 257 insertions, 0 deletions
diff --git a/gcc/rust/metadata/rust-imports.h b/gcc/rust/metadata/rust-imports.h
new file mode 100644
index 0000000..51cc4fc
--- /dev/null
+++ b/gcc/rust/metadata/rust-imports.h
@@ -0,0 +1,257 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#ifndef RUST_IMPORTS_H
+#define RUST_IMPORTS_H
+
+#include "rust-system.h"
+#include "rust-location.h"
+
+namespace Rust {
+
+extern void
+add_search_path (const std::string &path);
+
+class Import
+{
+public:
+ // The Stream class is an interface used to read the data. The
+ // caller should instantiate a child of this class.
+ class Stream
+ {
+ public:
+ Stream ();
+ virtual ~Stream ();
+
+ // Set the position, for error messages.
+ void set_pos (int pos) { this->pos_ = pos; }
+
+ // Return whether we have seen an error.
+ bool saw_error () const { return this->saw_error_; }
+
+ // Record that we've seen an error.
+ void set_saw_error () { this->saw_error_ = true; }
+
+ // Return the next character (a value from 0 to 0xff) without
+ // advancing. Returns -1 at end of stream.
+ int peek_char ();
+
+ // Look for LENGTH characters, setting *BYTES to point to them.
+ // Returns false if the bytes are not available. Does not
+ // advance.
+ bool peek (size_t length, const char **bytes)
+ {
+ return this->do_peek (length, bytes);
+ }
+
+ // Return the next character (a value from 0 to 0xff) and advance
+ // the read position by 1. Returns -1 at end of stream.
+ int get_char ()
+ {
+ int c = this->peek_char ();
+ this->advance (1);
+ return c;
+ }
+
+ // Return true if at the end of the stream.
+ bool at_eof () { return this->peek_char () == -1; }
+
+ // Return true if the next bytes match STR.
+ bool match_c_string (const char *str)
+ {
+ return this->match_bytes (str, strlen (str));
+ }
+
+ // Return true if the next LENGTH bytes match BYTES.
+ bool match_bytes (const char *bytes, size_t length);
+
+ // Give an error if the next bytes do not match STR. Advance the
+ // read position by the length of STR.
+ void require_c_string (Location location, const char *str)
+ {
+ this->require_bytes (location, str, strlen (str));
+ }
+
+ // Given an error if the next LENGTH bytes do not match BYTES.
+ // Advance the read position by LENGTH.
+ void require_bytes (Location, const char *bytes, size_t length);
+
+ // Advance the read position by SKIP bytes.
+ void advance (size_t skip)
+ {
+ this->do_advance (skip);
+ this->pos_ += skip;
+ }
+
+ // Return the current read position. This returns int because it
+ // is more convenient in error reporting. FIXME.
+ int pos () { return static_cast<int> (this->pos_); }
+
+ // This function should set *BYTES to point to a buffer holding
+ // the LENGTH bytes at the current read position. It should
+ // return false if the bytes are not available. This should not
+ // change the current read position.
+ virtual bool do_peek (size_t length, const char **bytes) = 0;
+
+ // This function should advance the current read position LENGTH
+ // bytes.
+ virtual void do_advance (size_t skip) = 0;
+
+ private:
+ // The current read position.
+ size_t pos_;
+ // True if we've seen an error reading from this stream.
+ bool saw_error_;
+ };
+
+ // Find import data. This searches the file system for FILENAME and
+ // returns a pointer to a Stream object to read the data that it
+ // exports. LOCATION is the location of the import statement.
+ // RELATIVE_IMPORT_PATH is used as a prefix for a relative import.
+ static Stream *open_package (const std::string &filename, Location location,
+ const std::string &relative_import_path);
+
+ // Constructor.
+ Import (Stream *, Location);
+
+ // The location of the import statement.
+ Location location () const { return this->location_; }
+
+ // Return the next character.
+ int peek_char () { return this->stream_->peek_char (); }
+
+ // Return the next character and advance.
+ int get_char () { return this->stream_->get_char (); }
+
+ // Read LENGTH characters into *OUT and advance past them. On
+ // EOF reports an error and sets *OUT to an empty string.
+ void read (size_t length, std::string *out);
+
+ // Return true at the end of the stream.
+ bool at_eof () { return this->stream_->at_eof (); }
+
+ // Return whether the next bytes match STR.
+ bool match_c_string (const char *str)
+ {
+ return this->stream_->match_c_string (str);
+ }
+
+ // Require that the next bytes match STR.
+ void require_c_string (const char *str)
+ {
+ this->stream_->require_c_string (this->location_, str);
+ }
+
+ // Advance the stream SKIP bytes.
+ void advance (size_t skip) { this->stream_->advance (skip); }
+
+ // Stream position, for error reporting.
+ int pos () { return this->stream_->pos (); }
+
+ // Clear the stream when it is no longer accessible.
+ void clear_stream () { this->stream_ = NULL; }
+
+private:
+ static Stream *try_package_in_directory (const std::string &, Location);
+
+ static int try_suffixes (std::string *);
+
+ static Stream *find_export_data (const std::string &filename, int fd,
+ Location);
+
+ static Stream *find_object_export_data (const std::string &filename, int fd,
+ off_t offset, Location);
+
+ static bool is_archive_magic (const char *);
+
+ static Stream *find_archive_export_data (const std::string &filename, int fd,
+ Location);
+
+ // The stream from which to read import data.
+ Stream *stream_;
+ // The location of the import statement we are processing.
+ Location location_;
+};
+
+// Read import data from a string.
+
+class Stream_from_string : public Import::Stream
+{
+public:
+ Stream_from_string (const std::string &str) : str_ (str), pos_ (0) {}
+
+ bool do_peek (size_t length, const char **bytes)
+ {
+ if (this->pos_ + length > this->str_.length ())
+ return false;
+ *bytes = this->str_.data () + this->pos_;
+ return true;
+ }
+
+ void do_advance (size_t len) { this->pos_ += len; }
+
+private:
+ // The string of data we are reading.
+ std::string str_;
+ // The current position within the string.
+ size_t pos_;
+};
+
+// Read import data from a buffer allocated using malloc.
+
+class Stream_from_buffer : public Import::Stream
+{
+public:
+ Stream_from_buffer (char *buf, size_t length)
+ : buf_ (buf), length_ (length), pos_ (0)
+ {}
+
+ ~Stream_from_buffer () { free (this->buf_); }
+
+ bool do_peek (size_t length, const char **bytes)
+ {
+ if (this->pos_ + length > this->length_)
+ return false;
+ *bytes = this->buf_ + this->pos_;
+ return true;
+ }
+
+ void do_advance (size_t len) { this->pos_ += len; }
+
+private:
+ // The data we are reading.
+ char *buf_;
+ // The length of the buffer.
+ size_t length_;
+ // The current position within the buffer.
+ size_t pos_;
+};
+
+// Read import data from an open file descriptor.
+
+class Stream_from_file : public Import::Stream
+{
+public:
+ Stream_from_file (int fd);
+
+ ~Stream_from_file ();
+
+ bool do_peek (size_t, const char **);
+
+ void do_advance (size_t);
+
+private:
+ // No copying.
+ Stream_from_file (const Stream_from_file &);
+ Stream_from_file &operator= (const Stream_from_file &);
+
+ // The file descriptor.
+ int fd_;
+ // Data read from the file.
+ std::string data_;
+};
+
+} // namespace Rust
+
+#endif // RUST_IMPORTS_H