OSDN Git Service

compiler: Build import tables as needed for imported interfaces.
[pf3gnuchains/gcc-fork.git] / gcc / go / gofrontend / import.cc
1 // import.cc -- Go frontend import declarations.
2
3 // Copyright 2009 The Go Authors. All rights reserved.
4 // Use of this source code is governed by a BSD-style
5 // license that can be found in the LICENSE file.
6
7 #include "go-system.h"
8
9 #include "filenames.h"
10 #include "simple-object.h"
11
12 #include "go-c.h"
13 #include "gogo.h"
14 #include "lex.h"
15 #include "types.h"
16 #include "export.h"
17 #include "import.h"
18
19 #ifndef O_BINARY
20 #define O_BINARY 0
21 #endif
22
23 // The list of paths we search for import files.
24
25 static std::vector<std::string> search_path;
26
27 // Add a directory to the search path.  This is called from the option
28 // handling language hook.
29
30 GO_EXTERN_C
31 void
32 go_add_search_path(const char* path)
33 {
34   search_path.push_back(std::string(path));
35 }
36
37 // Find import data.  This searches the file system for FILENAME and
38 // returns a pointer to a Stream object to read the data that it
39 // exports.  If the file is not found, it returns NULL.
40
41 // When FILENAME is not an absolute path and does not start with ./ or
42 // ../, we use the search path provided by -I and -L options.
43
44 // When FILENAME does not exist, we try modifying FILENAME to find the
45 // file.  We use the first of these which exists:
46 //   * We append ".gox".
47 //   * We turn the base of FILENAME into libFILENAME.so.
48 //   * We turn the base of FILENAME into libFILENAME.a.
49 //   * We append ".o".
50
51 // When using a search path, we apply each of these transformations at
52 // each entry on the search path before moving on to the next entry.
53 // If the file exists, but does not contain any Go export data, we
54 // stop; we do not keep looking for another file with the same name
55 // later in the search path.
56
57 Import::Stream*
58 Import::open_package(const std::string& filename, Location location)
59 {
60   bool is_local;
61   if (IS_ABSOLUTE_PATH(filename))
62     is_local = true;
63   else if (filename[0] == '.' && IS_DIR_SEPARATOR(filename[1]))
64     is_local = true;
65   else if (filename[0] == '.'
66            && filename[1] == '.'
67            && IS_DIR_SEPARATOR(filename[2]))
68     is_local = true;
69   else
70     is_local = false;
71   if (!is_local)
72     {
73       for (std::vector<std::string>::const_iterator p = search_path.begin();
74            p != search_path.end();
75            ++p)
76         {
77           std::string indir = *p;
78           if (!indir.empty() && indir[indir.size() - 1] != '/')
79             indir += '/';
80           indir += filename;
81           Stream* s = Import::try_package_in_directory(indir, location);
82           if (s != NULL)
83             return s;
84         }
85     }
86
87   Stream* s = Import::try_package_in_directory(filename, location);
88   if (s != NULL)
89     return s;
90
91   return NULL;
92 }
93
94 // Try to find the export data for FILENAME.
95
96 Import::Stream*
97 Import::try_package_in_directory(const std::string& filename,
98                                  Location location)
99 {
100   std::string found_filename = filename;
101   int fd = open(found_filename.c_str(), O_RDONLY | O_BINARY);
102
103   if (fd >= 0)
104     {
105       struct stat s;
106       if (fstat(fd, &s) >= 0 && S_ISDIR(s.st_mode))
107         {
108           close(fd);
109           fd = -1;
110           errno = EISDIR;
111         }
112     }
113
114   if (fd < 0)
115     {
116       if (errno != ENOENT && errno != EISDIR)
117         warning_at(location, 0, "%s: %m", filename.c_str());
118
119       fd = Import::try_suffixes(&found_filename);
120       if (fd < 0)
121         return NULL;
122     }
123
124   // The export data may not be in this file.
125   Stream* s = Import::find_export_data(found_filename, fd, location);
126   if (s != NULL)
127     return s;
128
129   close(fd);
130
131   error_at(location, "%s exists but does not contain any Go export data",
132            found_filename.c_str());
133
134   return NULL;
135 }
136
137 // Given import "*PFILENAME", where *PFILENAME does not exist, try
138 // various suffixes.  If we find one, set *PFILENAME to the one we
139 // found.  Return the open file descriptor.
140
141 int
142 Import::try_suffixes(std::string* pfilename)
143 {
144   std::string filename = *pfilename + ".gox";
145   int fd = open(filename.c_str(), O_RDONLY | O_BINARY);
146   if (fd >= 0)
147     {
148       *pfilename = filename;
149       return fd;
150     }
151
152   const char* basename = lbasename(pfilename->c_str());
153   size_t basename_pos = basename - pfilename->c_str();
154   filename = pfilename->substr(0, basename_pos) + "lib" + basename + ".so";
155   fd = open(filename.c_str(), O_RDONLY | O_BINARY);
156   if (fd >= 0)
157     {
158       *pfilename = filename;
159       return fd;
160     }
161
162   filename = pfilename->substr(0, basename_pos) + "lib" + basename + ".a";
163   fd = open(filename.c_str(), O_RDONLY | O_BINARY);
164   if (fd >= 0)
165     {
166       *pfilename = filename;
167       return fd;
168     }
169
170   filename = *pfilename + ".o";
171   fd = open(filename.c_str(), O_RDONLY | O_BINARY);
172   if (fd >= 0)
173     {
174       *pfilename = filename;
175       return fd;
176     }
177
178   return -1;
179 }
180
181 // Look for export data in the file descriptor FD.
182
183 Import::Stream*
184 Import::find_export_data(const std::string& filename, int fd,
185                          Location location)
186 {
187   // See if we can read this as an object file.
188   Import::Stream* stream = Import::find_object_export_data(filename, fd, 0,
189                                                            location);
190   if (stream != NULL)
191     return stream;
192
193   const int len = MAX(Export::v1_magic_len, Import::archive_magic_len);
194
195   if (lseek(fd, 0, SEEK_SET) < 0)
196     {
197       error_at(location, "lseek %s failed: %m", filename.c_str());
198       return NULL;
199     }
200
201   char buf[len];
202   ssize_t c = read(fd, buf, len);
203   if (c < len)
204     return NULL;
205
206   // Check for a file containing nothing but Go export data.
207   if (memcmp(buf, Export::v1_magic, Export::v1_magic_len) == 0)
208     return new Stream_from_file(fd);
209
210   // See if we can read this as an archive.
211   if (Import::is_archive_magic(buf))
212     return Import::find_archive_export_data(filename, fd, location);
213
214   return NULL;
215 }
216
217 // Look for export data in a simple_object.
218
219 Import::Stream*
220 Import::find_object_export_data(const std::string& filename,
221                                 int fd,
222                                 off_t offset,
223                                 Location location)
224 {
225   char *buf;
226   size_t len;
227   int err;
228   const char *errmsg = go_read_export_data(fd, offset, &buf, &len, &err);
229   if (errmsg != NULL)
230     {
231       if (err == 0)
232         error_at(location, "%s: %s", filename.c_str(), errmsg);
233       else
234         error_at(location, "%s: %s: %s", filename.c_str(), errmsg,
235                  xstrerror(err));
236       return NULL;
237     }
238
239   if (buf == NULL)
240     return NULL;
241
242   return new Stream_from_buffer(buf, len);
243 }
244
245 // Class Import.
246
247 // Construct an Import object.  We make the builtin_types_ vector
248 // large enough to hold all the builtin types.
249
250 Import::Import(Stream* stream, Location location)
251   : gogo_(NULL), stream_(stream), location_(location), package_(NULL),
252     add_to_globals_(false),
253     builtin_types_((- SMALLEST_BUILTIN_CODE) + 1),
254     types_()
255 {
256 }
257
258 // Import the data in the associated stream.
259
260 Package*
261 Import::import(Gogo* gogo, const std::string& local_name,
262                bool is_local_name_exported)
263 {
264   // Hold on to the Gogo structure.  Otherwise we need to pass it
265   // through all the import functions, because we need it when reading
266   // a type.
267   this->gogo_ = gogo;
268
269   // A stream of export data can include data from more than one input
270   // file.  Here we loop over each input file.
271   Stream* stream = this->stream_;
272   while (!stream->at_eof() && !stream->saw_error())
273     {
274       // The vector of types is package specific.
275       this->types_.clear();
276
277       stream->require_bytes(this->location_, Export::v1_magic,
278                             Export::v1_magic_len);
279
280       this->require_c_string("package ");
281       std::string package_name = this->read_identifier();
282       this->require_c_string(";\n");
283
284       this->require_c_string("prefix ");
285       std::string unique_prefix = this->read_identifier();
286       this->require_c_string(";\n");
287
288       this->package_ = gogo->add_imported_package(package_name, local_name,
289                                                   is_local_name_exported,
290                                                   unique_prefix,
291                                                   this->location_,
292                                                   &this->add_to_globals_);
293       if (this->package_ == NULL)
294         {
295           stream->set_saw_error();
296           return NULL;
297         }
298
299       this->require_c_string("priority ");
300       std::string priority_string = this->read_identifier();
301       int prio;
302       if (!this->string_to_int(priority_string, false, &prio))
303         return NULL;
304       this->package_->set_priority(prio);
305       this->require_c_string(";\n");
306
307       while (stream->match_c_string("import"))
308         this->read_one_import();
309
310       if (stream->match_c_string("init"))
311         this->read_import_init_fns(gogo);
312
313       // Loop over all the input data for this package.
314       while (!stream->saw_error())
315         {
316           if (stream->match_c_string("const "))
317             this->import_const();
318           else if (stream->match_c_string("type "))
319             this->import_type();
320           else if (stream->match_c_string("var "))
321             this->import_var();
322           else if (stream->match_c_string("func "))
323             this->import_func(this->package_);
324           else if (stream->match_c_string("checksum "))
325             break;
326           else
327             {
328               error_at(this->location_,
329                        ("error in import data at %d: "
330                         "expected %<const%>, %<type%>, %<var%>, "
331                         "%<func%>, or %<checksum%>"),
332                        stream->pos());
333               stream->set_saw_error();
334               return NULL;
335             }
336         }
337
338       // We currently ignore the checksum.  In the future we could
339       // store the checksum somewhere in the generated object and then
340       // verify that the checksum matches at link time or at dynamic
341       // load time.
342       this->require_c_string("checksum ");
343       stream->advance(Export::v1_checksum_len * 2);
344       this->require_c_string(";\n");
345     }
346
347   return this->package_;
348 }
349
350 // Read an import line.  We don't actually care about these.
351
352 void
353 Import::read_one_import()
354 {
355   this->require_c_string("import ");
356   Stream* stream = this->stream_;
357   while (stream->peek_char() != ';')
358     stream->advance(1);
359   this->require_c_string(";\n");
360 }
361
362 // Read the list of import control functions.
363
364 void
365 Import::read_import_init_fns(Gogo* gogo)
366 {
367   this->require_c_string("init");
368   while (!this->match_c_string(";"))
369     {
370       this->require_c_string(" ");
371       std::string package_name = this->read_identifier();
372       this->require_c_string(" ");
373       std::string init_name = this->read_identifier();
374       this->require_c_string(" ");
375       std::string prio_string = this->read_identifier();
376       int prio;
377       if (!this->string_to_int(prio_string, false, &prio))
378         return;
379       gogo->add_import_init_fn(package_name, init_name, prio);
380     }
381   this->require_c_string(";\n");
382 }
383
384 // Import a constant.
385
386 void
387 Import::import_const()
388 {
389   std::string name;
390   Type* type;
391   Expression* expr;
392   Named_constant::import_const(this, &name, &type, &expr);
393   Typed_identifier tid(name, type, this->location_);
394   Named_object* no = this->package_->add_constant(tid, expr);
395   if (this->add_to_globals_)
396     this->gogo_->add_named_object(no);
397 }
398
399 // Import a type.
400
401 void
402 Import::import_type()
403 {
404   Named_type* type;
405   Named_type::import_named_type(this, &type);
406
407   // The named type has been added to the package by the type import
408   // process.  Here we need to make it visible to the parser, and it
409   // to the global bindings if necessary.
410   type->set_is_visible();
411
412   if (this->add_to_globals_)
413     this->gogo_->add_named_type(type);
414 }
415
416 // Import a variable.
417
418 void
419 Import::import_var()
420 {
421   std::string name;
422   Type* type;
423   Variable::import_var(this, &name, &type);
424   Variable* var = new Variable(type, NULL, true, false, false,
425                                this->location_);
426   Named_object* no;
427   no = this->package_->add_variable(name, var);
428   if (this->add_to_globals_)
429     this->gogo_->add_named_object(no);
430 }
431
432 // Import a function into PACKAGE.  PACKAGE is normally
433 // THIS->PACKAGE_, but it will be different for a method associated
434 // with a type defined in a different package.
435
436 Named_object*
437 Import::import_func(Package* package)
438 {
439   std::string name;
440   Typed_identifier* receiver;
441   Typed_identifier_list* parameters;
442   Typed_identifier_list* results;
443   bool is_varargs;
444   Function::import_func(this, &name, &receiver, &parameters, &results,
445                         &is_varargs);
446   Function_type *fntype = Type::make_function_type(receiver, parameters,
447                                                    results, this->location_);
448   if (is_varargs)
449     fntype->set_is_varargs();
450
451   Location loc = this->location_;
452   Named_object* no;
453   if (fntype->is_method())
454     {
455       Type* rtype = receiver->type();
456
457       // We may still be reading the definition of RTYPE, so we have
458       // to be careful to avoid calling base or convert.  If RTYPE is
459       // a named type or a forward declaration, then we know that it
460       // is not a pointer, because we are reading a method on RTYPE
461       // and named pointers can't have methods.
462
463       if (rtype->classification() == Type::TYPE_POINTER)
464         rtype = rtype->points_to();
465
466       if (rtype->is_error_type())
467         return NULL;
468       else if (rtype->named_type() != NULL)
469         no = rtype->named_type()->add_method_declaration(name, package, fntype,
470                                                          loc);
471       else if (rtype->forward_declaration_type() != NULL)
472         no = rtype->forward_declaration_type()->add_method_declaration(name,
473                                                                        package,
474                                                                        fntype,
475                                                                        loc);
476       else
477         go_unreachable();
478     }
479   else
480     {
481       no = package->add_function_declaration(name, fntype, loc);
482       if (this->add_to_globals_)
483         this->gogo_->add_named_object(no);
484     }
485   return no;
486 }
487
488 // Read a type in the import stream.  This records the type by the
489 // type index.  If the type is named, it registers the name, but marks
490 // it as invisible.
491
492 Type*
493 Import::read_type()
494 {
495   Stream* stream = this->stream_;
496   this->require_c_string("<type ");
497
498   std::string number;
499   int c;
500   while (true)
501     {
502       c = stream->get_char();
503       if (c != '-' && (c < '0' || c > '9'))
504         break;
505       number += c;
506     }
507
508   int index;
509   if (!this->string_to_int(number, true, &index))
510     return Type::make_error_type();
511
512   if (c == '>')
513     {
514       // This type was already defined.
515       if (index < 0
516           ? (static_cast<size_t>(- index) >= this->builtin_types_.size()
517              || this->builtin_types_[- index] == NULL)
518           : (static_cast<size_t>(index) >= this->types_.size()
519              || this->types_[index] == NULL))
520         {
521           error_at(this->location_,
522                    "error in import data at %d: bad type index %d",
523                    stream->pos(), index);
524           stream->set_saw_error();
525           return Type::make_error_type();
526         }
527
528       return index < 0 ? this->builtin_types_[- index] : this->types_[index];
529     }
530
531   if (c != ' ')
532     {
533       if (!stream->saw_error())
534         error_at(this->location_,
535                  "error in import data at %d: expect %< %> or %<>%>'",
536                  stream->pos());
537       stream->set_saw_error();
538       stream->advance(1);
539       return Type::make_error_type();
540     }
541
542   if (index <= 0
543       || (static_cast<size_t>(index) < this->types_.size()
544           && this->types_[index] != NULL))
545     {
546       error_at(this->location_,
547                "error in import data at %d: type index already defined",
548                stream->pos());
549       stream->set_saw_error();
550       return Type::make_error_type();
551     }
552
553   if (static_cast<size_t>(index) >= this->types_.size())
554     {
555       int newsize = std::max(static_cast<size_t>(index) + 1,
556                              this->types_.size() * 2);
557       this->types_.resize(newsize, NULL);
558     }
559
560   if (stream->peek_char() != '"')
561     {
562       Type* type = Type::import_type(this);
563       this->require_c_string(">");
564       this->types_[index] = type;
565       return type;
566     }
567
568   // This type has a name.
569
570   stream->advance(1);
571   std::string type_name;
572   while ((c = stream->get_char()) != '"')
573     type_name += c;
574
575   // If this type is in the current package, the name will be
576   // .PREFIX.PACKAGE.NAME or simply NAME with no dots.  Otherwise, a
577   // non-hidden symbol will be PREFIX.PACKAGE.NAME and a hidden symbol
578   // will be .PREFIX.PACKAGE.NAME.
579   std::string package_name;
580   std::string unique_prefix;
581   if (type_name.find('.') != std::string::npos)
582     {
583       bool is_hidden = false;
584       size_t start = 0;
585       if (type_name[0] == '.')
586         {
587           ++start;
588           is_hidden = true;
589         }
590       size_t dot1 = type_name.find('.', start);
591       size_t dot2;
592       if (dot1 == std::string::npos)
593         dot2 = std::string::npos;
594       else
595         dot2 = type_name.find('.', dot1 + 1);
596       if (dot1 == std::string::npos || dot2 == std::string::npos)
597         {
598           error_at(this->location_,
599                    ("error at import data at %d: missing dot in type name"),
600                    stream->pos());
601           stream->set_saw_error();
602         }
603       else
604         {
605           unique_prefix = type_name.substr(start, dot1 - start);
606           package_name = type_name.substr(dot1 + 1, dot2 - (dot1 + 1));
607         }
608       if (!is_hidden)
609         type_name.erase(0, dot2 + 1);
610     }
611
612   this->require_c_string(" ");
613
614   // Declare the type in the appropriate package.  If we haven't seen
615   // it before, mark it as invisible.  We declare it before we read
616   // the actual definition of the type, since the definition may refer
617   // to the type itself.
618   Package* package;
619   if (package_name.empty())
620     package = this->package_;
621   else
622     package = this->gogo_->register_package(package_name, unique_prefix,
623                                             Linemap::unknown_location());
624
625   Named_object* no = package->bindings()->lookup(type_name);
626   if (no == NULL)
627     no = package->add_type_declaration(type_name, this->location_);
628   else if (!no->is_type_declaration() && !no->is_type())
629     {
630       error_at(this->location_, "imported %<%s.%s%> both type and non-type",
631                Gogo::message_name(package->name()).c_str(),
632                Gogo::message_name(type_name).c_str());
633       stream->set_saw_error();
634       return Type::make_error_type();
635     }
636   else
637     go_assert(no->package() == package);
638
639   if (this->types_[index] == NULL)
640     {
641       if (no->is_type_declaration())
642         {
643           // FIXME: It's silly to make a forward declaration every time.
644           this->types_[index] = Type::make_forward_declaration(no);
645         }
646       else
647         {
648           go_assert(no->is_type());
649           this->types_[index] = no->type_value();
650         }
651     }
652
653   // If there is no type definition, then this is just a forward
654   // declaration of a type defined in some other file.
655   Type* type;
656   if (this->match_c_string(">"))
657     type = this->types_[index];
658   else
659     {
660       type = this->read_type();
661
662       if (no->is_type_declaration())
663         {
664           // We can define the type now.
665
666           no = package->add_type(type_name, type, this->location_);
667           Named_type* ntype = no->type_value();
668
669           // This type has not yet been imported.
670           ntype->clear_is_visible();
671
672           if (!type->is_undefined() && type->interface_type() != NULL)
673             this->gogo_->record_interface_type(type->interface_type());
674
675           type = ntype;
676         }
677       else if (no->is_type())
678         {
679           // We have seen this type before.  FIXME: it would be a good
680           // idea to check that the two imported types are identical,
681           // but we have not finalized the methods yet, which means
682           // that we can not reliably compare interface types.
683           type = no->type_value();
684
685           // Don't change the visibility of the existing type.
686         }
687
688       this->types_[index] = type;
689
690       // Read the type methods.
691       if (this->match_c_string("\n"))
692         {
693           this->advance(1);
694           while (this->match_c_string(" func"))
695             {
696               this->advance(1);
697               this->import_func(package);
698             }
699         }
700     }
701
702   this->require_c_string(">");
703
704   return type;
705 }
706
707 // Register the builtin types.
708
709 void
710 Import::register_builtin_types(Gogo* gogo)
711 {
712   this->register_builtin_type(gogo, "int8", BUILTIN_INT8);
713   this->register_builtin_type(gogo, "int16", BUILTIN_INT16);
714   this->register_builtin_type(gogo, "int32", BUILTIN_INT32);
715   this->register_builtin_type(gogo, "int64", BUILTIN_INT64);
716   this->register_builtin_type(gogo, "uint8", BUILTIN_UINT8);
717   this->register_builtin_type(gogo, "uint16", BUILTIN_UINT16);
718   this->register_builtin_type(gogo, "uint32", BUILTIN_UINT32);
719   this->register_builtin_type(gogo, "uint64", BUILTIN_UINT64);
720   this->register_builtin_type(gogo, "float32", BUILTIN_FLOAT32);
721   this->register_builtin_type(gogo, "float64", BUILTIN_FLOAT64);
722   this->register_builtin_type(gogo, "complex64", BUILTIN_COMPLEX64);
723   this->register_builtin_type(gogo, "complex128", BUILTIN_COMPLEX128);
724   this->register_builtin_type(gogo, "int", BUILTIN_INT);
725   this->register_builtin_type(gogo, "uint", BUILTIN_UINT);
726   this->register_builtin_type(gogo, "uintptr", BUILTIN_UINTPTR);
727   this->register_builtin_type(gogo, "bool", BUILTIN_BOOL);
728   this->register_builtin_type(gogo, "string", BUILTIN_STRING);
729   this->register_builtin_type(gogo, "error", BUILTIN_ERROR);
730   this->register_builtin_type(gogo, "byte", BUILTIN_BYTE);
731   this->register_builtin_type(gogo, "rune", BUILTIN_RUNE);
732 }
733
734 // Register a single builtin type.
735
736 void
737 Import::register_builtin_type(Gogo* gogo, const char* name, Builtin_code code)
738 {
739   Named_object* named_object = gogo->lookup_global(name);
740   go_assert(named_object != NULL && named_object->is_type());
741   int index = - static_cast<int>(code);
742   go_assert(index > 0
743              && static_cast<size_t>(index) < this->builtin_types_.size());
744   this->builtin_types_[index] = named_object->type_value();
745 }
746
747 // Read an identifier from the stream.
748
749 std::string
750 Import::read_identifier()
751 {
752   std::string ret;
753   Stream* stream = this->stream_;
754   int c;
755   while (true)
756     {
757       c = stream->peek_char();
758       if (c == -1 || c == ' ' || c == ';')
759         break;
760       ret += c;
761       stream->advance(1);
762     }
763   return ret;
764 }
765
766 // Read a name from the stream.
767
768 std::string
769 Import::read_name()
770 {
771   std::string ret = this->read_identifier();
772   if (ret == "?")
773     ret.clear();
774   else if (!Lex::is_exported_name(ret))
775     ret = ('.' + this->package_->unique_prefix()
776            + '.' + this->package_->name()
777            + '.' + ret);
778   return ret;
779 }
780
781 // Turn a string into a integer with appropriate error handling.
782
783 bool
784 Import::string_to_int(const std::string &s, bool is_neg_ok, int* ret)
785 {
786   char* end;
787   long prio = strtol(s.c_str(), &end, 10);
788   if (*end != '\0' || prio > 0x7fffffff || (prio < 0 && !is_neg_ok))
789     {
790       error_at(this->location_, "invalid integer in import data at %d",
791                this->stream_->pos());
792       this->stream_->set_saw_error();
793       return false;
794     }
795   *ret = prio;
796   return true;
797 }
798
799 // Class Import::Stream.
800
801 Import::Stream::Stream()
802   : pos_(0), saw_error_(false)
803 {
804 }
805
806 Import::Stream::~Stream()
807 {
808 }
809
810 // Return the next character to come from the stream.
811
812 int
813 Import::Stream::peek_char()
814 {
815   const char* read;
816   if (!this->do_peek(1, &read))
817     return -1;
818   // Make sure we return an unsigned char, so that we don't get
819   // confused by \xff.
820   unsigned char ret = *read;
821   return ret;
822 }
823
824 // Return true if the next LENGTH characters from the stream match
825 // BYTES
826
827 bool
828 Import::Stream::match_bytes(const char* bytes, size_t length)
829 {
830   const char* read;
831   if (!this->do_peek(length, &read))
832     return false;
833   return memcmp(bytes, read, length) == 0;
834 }
835
836 // Require that the next LENGTH bytes from the stream match BYTES.
837
838 void
839 Import::Stream::require_bytes(Location location, const char* bytes,
840                               size_t length)
841 {
842   const char* read;
843   if (!this->do_peek(length, &read)
844       || memcmp(bytes, read, length) != 0)
845     {
846       if (!this->saw_error_)
847         error_at(location, "import error at %d: expected %<%.*s%>",
848                  this->pos(), static_cast<int>(length), bytes);
849       this->saw_error_ = true;
850       return;
851     }
852   this->advance(length);
853 }
854
855 // Class Stream_from_file.
856
857 Stream_from_file::Stream_from_file(int fd)
858   : fd_(fd), data_()
859 {
860   if (lseek(fd, 0, SEEK_SET) != 0)
861     {
862       error("lseek failed: %m");
863       this->set_saw_error();
864     }
865 }
866
867 Stream_from_file::~Stream_from_file()
868 {
869   close(this->fd_);
870 }
871
872 // Read next bytes.
873
874 bool
875 Stream_from_file::do_peek(size_t length, const char** bytes)
876 {
877   if (this->data_.length() <= length)
878     {
879       *bytes = this->data_.data();
880       return true;
881     }
882   // Don't bother to handle the general case, since we don't need it.
883   go_assert(length < 64);
884   char buf[64];
885   ssize_t got = read(this->fd_, buf, length);
886
887   if (got < 0)
888     {
889       if (!this->saw_error())
890         error("read failed: %m");
891       this->set_saw_error();
892       return false;
893     }
894
895   if (lseek(this->fd_, - got, SEEK_CUR) != 0)
896     {
897       if (!this->saw_error())
898         error("lseek failed: %m");
899       this->set_saw_error();
900       return false;
901     }
902
903   if (static_cast<size_t>(got) < length)
904     return false;
905
906   this->data_.assign(buf, got);
907
908   *bytes = this->data_.data();
909   return true;
910 }
911
912 // Advance.
913
914 void
915 Stream_from_file::do_advance(size_t skip)
916 {
917   if (lseek(this->fd_, skip, SEEK_CUR) != 0)
918     {
919       if (!this->saw_error())
920         error("lseek failed: %m");
921       this->set_saw_error();
922     }
923   if (!this->data_.empty())
924     {
925       if (this->data_.length() < skip)
926         this->data_.erase(0, skip);
927       else
928         this->data_.clear();
929     }
930 }