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