master_lexer.cc 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. // Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC")
  2. //
  3. // Permission to use, copy, modify, and/or distribute this software for any
  4. // purpose with or without fee is hereby granted, provided that the above
  5. // copyright notice and this permission notice appear in all copies.
  6. //
  7. // THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
  8. // REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
  9. // AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
  10. // INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
  11. // LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
  12. // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  13. // PERFORMANCE OF THIS SOFTWARE.
  14. #include <exceptions/exceptions.h>
  15. #include <dns/master_lexer.h>
  16. #include <dns/master_lexer_inputsource.h>
  17. #include <boost/shared_ptr.hpp>
  18. #include <cassert>
  19. #include <string>
  20. #include <sstream>
  21. #include <vector>
  22. namespace isc {
  23. namespace dns {
  24. namespace {
  25. typedef boost::shared_ptr<master_lexer_internal::InputSource> InputSourcePtr;
  26. }
  27. using namespace master_lexer_internal;
  28. struct MasterLexer::MasterLexerImpl {
  29. MasterLexerImpl() : token_(Token::NOT_STARTED) {}
  30. std::vector<InputSourcePtr> sources_;
  31. Token token_;
  32. };
  33. MasterLexer::MasterLexer() : impl_(new MasterLexerImpl) {
  34. }
  35. MasterLexer::~MasterLexer() {
  36. delete impl_;
  37. }
  38. void
  39. MasterLexer::open(const char* filename) {
  40. if (filename == NULL) {
  41. isc_throw(InvalidParameter, "NULL filename for MasterLexer::open");
  42. }
  43. impl_->sources_.push_back(InputSourcePtr(new InputSource(filename)));
  44. }
  45. void
  46. MasterLexer::open(std::istream& input) {
  47. impl_->sources_.push_back(InputSourcePtr(new InputSource(input)));
  48. }
  49. void
  50. MasterLexer::close() {
  51. if (impl_->sources_.empty()) {
  52. isc_throw(InvalidOperation, "MasterLexer::close on an empty source");
  53. }
  54. impl_->sources_.pop_back();
  55. }
  56. std::string
  57. MasterLexer::getSourceName() const {
  58. if (impl_->sources_.empty()) {
  59. return (std::string());
  60. }
  61. return (impl_->sources_.back()->getName());
  62. }
  63. size_t
  64. MasterLexer::getSourceLine() const {
  65. if (impl_->sources_.empty()) {
  66. return (0);
  67. }
  68. return (impl_->sources_.back()->getCurrentLine());
  69. }
  70. namespace {
  71. const char* const error_text[] = {
  72. "lexer not started", // NOT_STARTED
  73. "unbalanced parentheses", // UNBALANCED_PAREN
  74. "unexpected end of input", // UNEXPECTED_END
  75. "unbalanced quotes" // UNBALANCED_QUOTES
  76. };
  77. const size_t error_text_max_count = sizeof(error_text) / sizeof(error_text[0]);
  78. }
  79. std::string
  80. MasterLexer::Token::getErrorText() const {
  81. if (type_ != ERROR) {
  82. isc_throw(InvalidOperation,
  83. "Token::getErrorText() for non error type");
  84. }
  85. // The class integrity ensures the following:
  86. assert(val_.error_code_ < error_text_max_count);
  87. return (error_text[val_.error_code_]);
  88. }
  89. } // end of namespace dns
  90. } // end of namespace isc