compiler: List imported packages in export information.
[gcc.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 type = ntype;
673 }
674 else if (no->is_type())
675 {
676 // We have seen this type before. FIXME: it would be a good
677 // idea to check that the two imported types are identical,
678 // but we have not finalized the methods yet, which means
679 // that we can not reliably compare interface types.
680 type = no->type_value();
681
682 // Don't change the visibility of the existing type.
683 }
684
685 this->types_[index] = type;
686
687 // Read the type methods.
688 if (this->match_c_string("\n"))
689 {
690 this->advance(1);
691 while (this->match_c_string(" func"))
692 {
693 this->advance(1);
694 this->import_func(package);
695 }
696 }
697 }
698
699 this->require_c_string(">");
700
701 return type;
702 }
703
704 // Register the builtin types.
705
706 void
707 Import::register_builtin_types(Gogo* gogo)
708 {
709 this->register_builtin_type(gogo, "int8", BUILTIN_INT8);
710 this->register_builtin_type(gogo, "int16", BUILTIN_INT16);
711 this->register_builtin_type(gogo, "int32", BUILTIN_INT32);
712 this->register_builtin_type(gogo, "int64", BUILTIN_INT64);
713 this->register_builtin_type(gogo, "uint8", BUILTIN_UINT8);
714 this->register_builtin_type(gogo, "uint16", BUILTIN_UINT16);
715 this->register_builtin_type(gogo, "uint32", BUILTIN_UINT32);
716 this->register_builtin_type(gogo, "uint64", BUILTIN_UINT64);
717 this->register_builtin_type(gogo, "float32", BUILTIN_FLOAT32);
718 this->register_builtin_type(gogo, "float64", BUILTIN_FLOAT64);
719 this->register_builtin_type(gogo, "complex64", BUILTIN_COMPLEX64);
720 this->register_builtin_type(gogo, "complex128", BUILTIN_COMPLEX128);
721 this->register_builtin_type(gogo, "int", BUILTIN_INT);
722 this->register_builtin_type(gogo, "uint", BUILTIN_UINT);
723 this->register_builtin_type(gogo, "uintptr", BUILTIN_UINTPTR);
724 this->register_builtin_type(gogo, "bool", BUILTIN_BOOL);
725 this->register_builtin_type(gogo, "string", BUILTIN_STRING);
726 this->register_builtin_type(gogo, "error", BUILTIN_ERROR);
727 this->register_builtin_type(gogo, "byte", BUILTIN_BYTE);
728 this->register_builtin_type(gogo, "rune", BUILTIN_RUNE);
729 }
730
731 // Register a single builtin type.
732
733 void
734 Import::register_builtin_type(Gogo* gogo, const char* name, Builtin_code code)
735 {
736 Named_object* named_object = gogo->lookup_global(name);
737 go_assert(named_object != NULL && named_object->is_type());
738 int index = - static_cast<int>(code);
739 go_assert(index > 0
740 && static_cast<size_t>(index) < this->builtin_types_.size());
741 this->builtin_types_[index] = named_object->type_value();
742 }
743
744 // Read an identifier from the stream.
745
746 std::string
747 Import::read_identifier()
748 {
749 std::string ret;
750 Stream* stream = this->stream_;
751 int c;
752 while (true)
753 {
754 c = stream->peek_char();
755 if (c == -1 || c == ' ' || c == ';')
756 break;
757 ret += c;
758 stream->advance(1);
759 }
760 return ret;
761 }
762
763 // Read a name from the stream.
764
765 std::string
766 Import::read_name()
767 {
768 std::string ret = this->read_identifier();
769 if (ret == "?")
770 ret.clear();
771 else if (!Lex::is_exported_name(ret))
772 ret = ('.' + this->package_->unique_prefix()
773 + '.' + this->package_->name()
774 + '.' + ret);
775 return ret;
776 }
777
778 // Turn a string into a integer with appropriate error handling.
779
780 bool
781 Import::string_to_int(const std::string &s, bool is_neg_ok, int* ret)
782 {
783 char* end;
784 long prio = strtol(s.c_str(), &end, 10);
785 if (*end != '\0' || prio > 0x7fffffff || (prio < 0 && !is_neg_ok))
786 {
787 error_at(this->location_, "invalid integer in import data at %d",
788 this->stream_->pos());
789 this->stream_->set_saw_error();
790 return false;
791 }
792 *ret = prio;
793 return true;
794 }
795
796 // Class Import::Stream.
797
798 Import::Stream::Stream()
799 : pos_(0), saw_error_(false)
800 {
801 }
802
803 Import::Stream::~Stream()
804 {
805 }
806
807 // Return the next character to come from the stream.
808
809 int
810 Import::Stream::peek_char()
811 {
812 const char* read;
813 if (!this->do_peek(1, &read))
814 return -1;
815 // Make sure we return an unsigned char, so that we don't get
816 // confused by \xff.
817 unsigned char ret = *read;
818 return ret;
819 }
820
821 // Return true if the next LENGTH characters from the stream match
822 // BYTES
823
824 bool
825 Import::Stream::match_bytes(const char* bytes, size_t length)
826 {
827 const char* read;
828 if (!this->do_peek(length, &read))
829 return false;
830 return memcmp(bytes, read, length) == 0;
831 }
832
833 // Require that the next LENGTH bytes from the stream match BYTES.
834
835 void
836 Import::Stream::require_bytes(Location location, const char* bytes,
837 size_t length)
838 {
839 const char* read;
840 if (!this->do_peek(length, &read)
841 || memcmp(bytes, read, length) != 0)
842 {
843 if (!this->saw_error_)
844 error_at(location, "import error at %d: expected %<%.*s%>",
845 this->pos(), static_cast<int>(length), bytes);
846 this->saw_error_ = true;
847 return;
848 }
849 this->advance(length);
850 }
851
852 // Class Stream_from_file.
853
854 Stream_from_file::Stream_from_file(int fd)
855 : fd_(fd), data_()
856 {
857 if (lseek(fd, 0, SEEK_SET) != 0)
858 {
859 error("lseek failed: %m");
860 this->set_saw_error();
861 }
862 }
863
864 Stream_from_file::~Stream_from_file()
865 {
866 close(this->fd_);
867 }
868
869 // Read next bytes.
870
871 bool
872 Stream_from_file::do_peek(size_t length, const char** bytes)
873 {
874 if (this->data_.length() <= length)
875 {
876 *bytes = this->data_.data();
877 return true;
878 }
879 // Don't bother to handle the general case, since we don't need it.
880 go_assert(length < 64);
881 char buf[64];
882 ssize_t got = read(this->fd_, buf, length);
883
884 if (got < 0)
885 {
886 if (!this->saw_error())
887 error("read failed: %m");
888 this->set_saw_error();
889 return false;
890 }
891
892 if (lseek(this->fd_, - got, SEEK_CUR) != 0)
893 {
894 if (!this->saw_error())
895 error("lseek failed: %m");
896 this->set_saw_error();
897 return false;
898 }
899
900 if (static_cast<size_t>(got) < length)
901 return false;
902
903 this->data_.assign(buf, got);
904
905 *bytes = this->data_.data();
906 return true;
907 }
908
909 // Advance.
910
911 void
912 Stream_from_file::do_advance(size_t skip)
913 {
914 if (lseek(this->fd_, skip, SEEK_CUR) != 0)
915 {
916 if (!this->saw_error())
917 error("lseek failed: %m");
918 this->set_saw_error();
919 }
920 if (!this->data_.empty())
921 {
922 if (this->data_.length() < skip)
923 this->data_.erase(0, skip);
924 else
925 this->data_.clear();
926 }
927 }