// -*- c++ -*- /* * jakelib2-regex - Regular Expressions for Jakelib2 * Copyright (C) 2003 Florian Wolff (florian@donuz.de) * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id: Matcher.jlc,v 1.4 2003/09/27 08:10:29 florian Exp $ */ #include "jakelib2.h" #include "jakelib2/util/regex/Matcher.h" #include "jakelib2/util/regex/Pattern.h" using namespace jakelib::lang; using namespace jakelib::util; using namespace jakelib::util::regex; JAKELIB_IMPLEMENT_CLASS("jakelib.util.regex.Matcher", Matcher, Object); #pragma javasyntax /*****************************************************************************\ * Matcher | *****************************************************************************/ Matcher::Matcher(Pattern* pattern, String* input) { this->_pattern = pattern; resultsSize = (pattern->captureCount + 1) * 3; executed = false; results = (int*) malloc(sizeof(int) * resultsSize); reset(input); } Matcher::~Matcher() { free(results); } /*****************************************************************************\ * matches | *****************************************************************************/ jboolean Matcher::matches() { int rc = pcre_exec(_pattern->re, null, input->latin1(), input->length(), 0, 0, null, 0); return (rc >= 0); } /*****************************************************************************\ * pattern | *****************************************************************************/ Pattern* Matcher::pattern() { return _pattern; } /*****************************************************************************\ * groupCount | *****************************************************************************/ jint Matcher::groupCount() { return _pattern->captureCount; } /*****************************************************************************\ * find | *****************************************************************************/ jboolean Matcher::find(jint startIndex) { if (executed) { startIndex = results[1]; if (startIndex == previousStartIndex) startIndex ++; } substringCount = pcre_exec(_pattern->re, null, input->latin1(), input->length(), startIndex, 0, results, resultsSize); executed = true; previousStartIndex = startIndex; if (substringCount < 0) { return false; } else { return true; } } /*****************************************************************************\ * start | *****************************************************************************/ jint Matcher::start(jint idx) { if (!executed) throw new IllegalStateException("Match not yet attempted" .. JAKELIB_AT("jakelib.util.regex.Matcher.start")); if (substringCount < 0) throw new IllegalStateException("No match found" .. JAKELIB_AT("jakelib.util.regex.Matcher.start")); if (idx < 0) throw new IllegalArgumentException("start(" .. idx .. "): " .. idx .. " < 0" .. JAKELIB_AT("jakelib.util.regex.Matcher.start")); if (idx >= substringCount) throw new IndexOutOfBoundsException("start(" .. idx .. "): " .. idx .. " >= " .. substringCount .. JAKELIB_AT("jakelib.util.regex.Matcher.start")); return results[idx * 2]; } /*****************************************************************************\ * end | *****************************************************************************/ jint Matcher::end(jint idx) { if (!executed) throw new IllegalStateException("Match not yet attempted" .. JAKELIB_AT("jakelib.util.regex.Matcher.end")); if (substringCount < 0) throw new IllegalStateException("No match found" .. JAKELIB_AT("jakelib.util.regex.Matcher.end")); if (idx < 0) throw new IllegalArgumentException("end(" .. idx .. "): " .. idx .. " < 0" .. JAKELIB_AT("jakelib.util.regex.Matcher.end")); if (idx >= substringCount) throw new IndexOutOfBoundsException("end(" .. idx .. "): " .. idx .. " >= " .. substringCount .. JAKELIB_AT("jakelib.util.regex.Matcher.end")); return results[idx * 2 + 1]; } /*****************************************************************************\ * group | *****************************************************************************/ String* Matcher::group(jint idx) { if (!executed) throw new IllegalStateException("Match not yet attempted" .. JAKELIB_AT("jakelib.util.regex.Matcher.group")); if (substringCount < 0) throw new IllegalStateException("No match found" .. JAKELIB_AT("jakelib.util.regex.Matcher.group")); if (idx < 0) throw new IllegalArgumentException("group(" .. idx .. "): " .. idx .. " < 0" .. JAKELIB_AT("jakelib.util.regex.Matcher.group")); if (idx >= substringCount) throw new IndexOutOfBoundsException("group(" .. idx .. "): " .. idx .. " >= " .. substringCount .. JAKELIB_AT("jakelib.util.regex.Matcher.group")); if (results[idx * 2] < 0) return new String(); else return input->substring(results[idx * 2], results[idx * 2 + 1]); } /*****************************************************************************\ * reset | *****************************************************************************/ void Matcher::reset() { executed = false; appendPosition = 0; previousStartIndex = 0; } void Matcher::reset(String* input) { this->input = input; reset(); } /*****************************************************************************\ * appendReplacement | *****************************************************************************/ void Matcher::appendReplacement(StringBuffer* buf, String* replacement) { jint startPos = start(); jint endPos = end(); buf->append(input->substring(appendPosition, startPos)); for (int x = 0; x < replacement->length(); x++) { jchar c = replacement->charAt(x); if (c == '$' && x < replacement->length() -1) { c = replacement->charAt(++x); if (c != '$') { int idx = (c - '0'); if (idx >= 0 && idx <= 9) buf->append(group(idx)); continue; } } buf->append(c); } appendPosition = endPos; } /*****************************************************************************\ * appendTail | *****************************************************************************/ void Matcher::appendTail(StringBuffer* buf) { buf->append(input->substring(appendPosition)); } /*****************************************************************************\ * replaceAll | *****************************************************************************/ String* Matcher::replaceAll(String* replacement) { StringBuffer buf; reset(); while (find()) { appendReplacement(&buf, replacement); } appendTail(&buf); return buf.toString(); }