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>