Annotation of embedaddon/pcre/pcre_scanner.cc, revision 1.1

1.1     ! misho       1: // Copyright (c) 2005, Google Inc.
        !             2: // All rights reserved.
        !             3: //
        !             4: // Redistribution and use in source and binary forms, with or without
        !             5: // modification, are permitted provided that the following conditions are
        !             6: // met:
        !             7: //
        !             8: //     * Redistributions of source code must retain the above copyright
        !             9: // notice, this list of conditions and the following disclaimer.
        !            10: //     * Redistributions in binary form must reproduce the above
        !            11: // copyright notice, this list of conditions and the following disclaimer
        !            12: // in the documentation and/or other materials provided with the
        !            13: // distribution.
        !            14: //     * Neither the name of Google Inc. nor the names of its
        !            15: // contributors may be used to endorse or promote products derived from
        !            16: // this software without specific prior written permission.
        !            17: //
        !            18: // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
        !            19: // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
        !            20: // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
        !            21: // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
        !            22: // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
        !            23: // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
        !            24: // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
        !            25: // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
        !            26: // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
        !            27: // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
        !            28: // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
        !            29: //
        !            30: // Author: Sanjay Ghemawat
        !            31: 
        !            32: #ifdef HAVE_CONFIG_H
        !            33: #include "config.h"
        !            34: #endif
        !            35: 
        !            36: #include <vector>
        !            37: #include <assert.h>
        !            38: 
        !            39: #include "pcrecpp_internal.h"
        !            40: #include "pcre_scanner.h"
        !            41: 
        !            42: using std::vector;
        !            43: 
        !            44: namespace pcrecpp {
        !            45: 
        !            46: Scanner::Scanner()
        !            47:   : data_(),
        !            48:     input_(data_),
        !            49:     skip_(NULL),
        !            50:     should_skip_(false),
        !            51:     skip_repeat_(false),
        !            52:     save_comments_(false),
        !            53:     comments_(NULL),
        !            54:     comments_offset_(0) {
        !            55: }
        !            56: 
        !            57: Scanner::Scanner(const string& in)
        !            58:   : data_(in),
        !            59:     input_(data_),
        !            60:     skip_(NULL),
        !            61:     should_skip_(false),
        !            62:     skip_repeat_(false),
        !            63:     save_comments_(false),
        !            64:     comments_(NULL),
        !            65:     comments_offset_(0) {
        !            66: }
        !            67: 
        !            68: Scanner::~Scanner() {
        !            69:   delete skip_;
        !            70:   delete comments_;
        !            71: }
        !            72: 
        !            73: void Scanner::SetSkipExpression(const char* re) {
        !            74:   delete skip_;
        !            75:   if (re != NULL) {
        !            76:     skip_ = new RE(re);
        !            77:     should_skip_ = true;
        !            78:     skip_repeat_ = true;
        !            79:     ConsumeSkip();
        !            80:   } else {
        !            81:     skip_ = NULL;
        !            82:     should_skip_ = false;
        !            83:     skip_repeat_ = false;
        !            84:   }
        !            85: }
        !            86: 
        !            87: void Scanner::Skip(const char* re) {
        !            88:   delete skip_;
        !            89:   if (re != NULL) {
        !            90:     skip_ = new RE(re);
        !            91:     should_skip_ = true;
        !            92:     skip_repeat_ = false;
        !            93:     ConsumeSkip();
        !            94:   } else {
        !            95:     skip_ = NULL;
        !            96:     should_skip_ = false;
        !            97:     skip_repeat_ = false;
        !            98:   }
        !            99: }
        !           100: 
        !           101: void Scanner::DisableSkip() {
        !           102:   assert(skip_ != NULL);
        !           103:   should_skip_ = false;
        !           104: }
        !           105: 
        !           106: void Scanner::EnableSkip() {
        !           107:   assert(skip_ != NULL);
        !           108:   should_skip_ = true;
        !           109:   ConsumeSkip();
        !           110: }
        !           111: 
        !           112: int Scanner::LineNumber() const {
        !           113:   // TODO: Make it more efficient by keeping track of the last point
        !           114:   // where we computed line numbers and counting newlines since then.
        !           115:   // We could use std:count, but not all systems have it. :-(
        !           116:   int count = 1;
        !           117:   for (const char* p = data_.data(); p < input_.data(); ++p)
        !           118:     if (*p == '\n')
        !           119:       ++count;
        !           120:   return count;
        !           121: }
        !           122: 
        !           123: int Scanner::Offset() const {
        !           124:   return (int)(input_.data() - data_.c_str());
        !           125: }
        !           126: 
        !           127: bool Scanner::LookingAt(const RE& re) const {
        !           128:   int consumed;
        !           129:   return re.DoMatch(input_, RE::ANCHOR_START, &consumed, 0, 0);
        !           130: }
        !           131: 
        !           132: 
        !           133: bool Scanner::Consume(const RE& re,
        !           134:                       const Arg& arg0,
        !           135:                       const Arg& arg1,
        !           136:                       const Arg& arg2) {
        !           137:   const bool result = re.Consume(&input_, arg0, arg1, arg2);
        !           138:   if (result && should_skip_) ConsumeSkip();
        !           139:   return result;
        !           140: }
        !           141: 
        !           142: // helper function to consume *skip_ and honour save_comments_
        !           143: void Scanner::ConsumeSkip() {
        !           144:   const char* start_data = input_.data();
        !           145:   while (skip_->Consume(&input_)) {
        !           146:     if (!skip_repeat_) {
        !           147:       // Only one skip allowed.
        !           148:       break;
        !           149:     }
        !           150:   }
        !           151:   if (save_comments_) {
        !           152:     if (comments_ == NULL) {
        !           153:       comments_ = new vector<StringPiece>;
        !           154:     }
        !           155:     // already pointing one past end, so no need to +1
        !           156:     int length = (int)(input_.data() - start_data);
        !           157:     if (length > 0) {
        !           158:       comments_->push_back(StringPiece(start_data, length));
        !           159:     }
        !           160:   }
        !           161: }
        !           162: 
        !           163: 
        !           164: void Scanner::GetComments(int start, int end, vector<StringPiece> *ranges) {
        !           165:   // short circuit out if we've not yet initialized comments_
        !           166:   // (e.g., when save_comments is false)
        !           167:   if (!comments_) {
        !           168:     return;
        !           169:   }
        !           170:   // TODO: if we guarantee that comments_ will contain StringPieces
        !           171:   // that are ordered by their start, then we can do a binary search
        !           172:   // for the first StringPiece at or past start and then scan for the
        !           173:   // ones contained in the range, quit early (use equal_range or
        !           174:   // lower_bound)
        !           175:   for (vector<StringPiece>::const_iterator it = comments_->begin();
        !           176:        it != comments_->end(); ++it) {
        !           177:     if ((it->data() >= data_.c_str() + start &&
        !           178:          it->data() + it->size() <= data_.c_str() + end)) {
        !           179:       ranges->push_back(*it);
        !           180:     }
        !           181:   }
        !           182: }
        !           183: 
        !           184: 
        !           185: void Scanner::GetNextComments(vector<StringPiece> *ranges) {
        !           186:   // short circuit out if we've not yet initialized comments_
        !           187:   // (e.g., when save_comments is false)
        !           188:   if (!comments_) {
        !           189:     return;
        !           190:   }
        !           191:   for (vector<StringPiece>::const_iterator it =
        !           192:          comments_->begin() + comments_offset_;
        !           193:        it != comments_->end(); ++it) {
        !           194:     ranges->push_back(*it);
        !           195:     ++comments_offset_;
        !           196:   }
        !           197: }
        !           198: 
        !           199: }   // namespace pcrecpp

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>