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