~ubuntu-branches/ubuntu/jaunty/imms/jaunty

« back to all changes in this revision

Viewing changes to regexx.cc

  • Committer: Bazaar Package Importer
  • Author(s): Norbert Veber
  • Date: 2005-04-13 23:43:11 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20050413234311-kzr68z9l7z5mv551
Tags: 2.0.3-2
Build depend on xmms-dev (>= 1.2.10+cvs20050209)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*************************************************************************/
2
 
/*                                                                       */
3
 
/*  Regexx - Regular Expressions C++ solution.                           */
4
 
/*                                                                       */
5
 
/*  http://projects.nn.com.br/                                           */
6
 
/*                                                                       */
7
 
/*  Copyright (C) 2000 Gustavo Niemeyer <gustavo@nn.com.br>              */
8
 
/*                                                                       */
9
 
/*  This library is free software; you can redistribute it and/or        */
10
 
/*  modify it under the terms of the GNU Library General Public          */
11
 
/*  License as published by the Free Software Foundation; either         */
12
 
/*  version 2 of the License, or (at your option) any later version.     */
13
 
/*                                                                       */
14
 
/*  This library is distributed in the hope that it will be useful,      */
15
 
/*  but WITHOUT ANY WARRANTY; without even the implied warranty of       */
16
 
/*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU    */
17
 
/*  Library General Public License for more details.                     */
18
 
/*                                                                       */
19
 
/*  You should have received a copy of the GNU Library General Public    */
20
 
/*  License along with this library; if not, write to the                */
21
 
/*  Free Software Foundation, Inc., 59 Temple Place - Suite 330,         */
22
 
/*  Boston, MA  02111-1307, USA.                                         */
23
 
/*                                                                       */
24
 
/*************************************************************************/
25
 
 
26
 
// $Revision: 1.1 $
27
 
// $Date: 2003/08/04 03:54:01 $
28
 
 
29
 
#include "regexx.h"
30
 
 
31
 
const unsigned int&
32
 
regexx::Regexx::exec(int _flags)
33
 
  throw(CompileException)
34
 
{
35
 
  if(!m_compiled) {
36
 
    const char *errptr;
37
 
    int erroffset;
38
 
    int cflags =
39
 
      ((_flags&nocase)?PCRE_CASELESS:0)
40
 
      | ((_flags&newline)?PCRE_MULTILINE:0);
41
 
    m_preg = pcre_compile(m_expr.c_str(),cflags,&errptr,&erroffset,0);
42
 
    if(m_preg == NULL) {
43
 
      throw CompileException(errptr);
44
 
    }
45
 
    pcre_fullinfo(m_preg, NULL, PCRE_INFO_CAPTURECOUNT, (void*)&m_capturecount);
46
 
    m_compiled = true;
47
 
  }
48
 
 
49
 
  if(!m_study && (_flags&study)) {
50
 
    const char *errptr;
51
 
    m_extra = pcre_study(m_preg, 0, &errptr);
52
 
    if(errptr != NULL)
53
 
      throw CompileException(errptr);
54
 
    m_study = true;
55
 
  }
56
 
 
57
 
  match.clear();
58
 
 
59
 
  int eflags = ((_flags&notbol)?PCRE_NOTBOL:0) | ((_flags&noteol)?PCRE_NOTEOL:0);
60
 
 
61
 
  int ssv[33];
62
 
  int ssc;
63
 
  m_matches = 0;
64
 
 
65
 
  ssc = pcre_exec(m_preg,m_extra,m_str.c_str(),m_str.length(),0,eflags,ssv,33);
66
 
  bool ret = (ssc > 0);
67
 
 
68
 
  if(_flags&global) {
69
 
    if(_flags&nomatch)
70
 
      while(ret) {
71
 
        m_matches++;
72
 
        ret = (pcre_exec(m_preg,m_extra,m_str.c_str(),m_str.length(),ssv[1],eflags,ssv,33) > 0);
73
 
      }
74
 
    else if(_flags&noatom)
75
 
      while(ret) {
76
 
        m_matches++;
77
 
        match.push_back(RegexxMatch(m_str,ssv[0],ssv[1]-ssv[0]));
78
 
        ret = (pcre_exec(m_preg,m_extra,m_str.c_str(),m_str.length(),ssv[1],eflags,ssv,33) > 0);
79
 
      }
80
 
    else
81
 
      while(ret) {
82
 
        m_matches++;
83
 
        match.push_back(RegexxMatch(m_str,ssv[0],ssv[1]-ssv[0]));
84
 
        match.back().atom.reserve(m_capturecount);
85
 
        for(int i = 1; i < ssc; i++) {
86
 
          if (ssv[i*2] != -1)
87
 
            match.back().atom.push_back(RegexxMatchAtom(m_str,ssv[i*2],ssv[(i*2)+1]-ssv[i*2]));
88
 
          else
89
 
            match.back().atom.push_back(RegexxMatchAtom(m_str,0,0));
90
 
        }
91
 
        ret = (pcre_exec(m_preg,m_extra,m_str.c_str(),m_str.length(),ssv[1],eflags,ssv,33) > 0);
92
 
      }
93
 
  }
94
 
  else {
95
 
    if(_flags&nomatch) {
96
 
      if(ret)
97
 
        m_matches=1;
98
 
    }
99
 
    else if(_flags&noatom) {
100
 
      if(ret) {
101
 
        m_matches=1;
102
 
        match.push_back(RegexxMatch(m_str,ssv[0],ssv[1]-ssv[0]));
103
 
      }
104
 
    }
105
 
    else {
106
 
      if(ret) {
107
 
        m_matches=1;
108
 
        match.push_back(RegexxMatch(m_str,ssv[0],ssv[1]-ssv[0]));
109
 
        match.back().atom.reserve(m_capturecount);
110
 
        for(int i = 1; i < ssc; i++) {
111
 
          if (ssv[i*2] != -1)
112
 
            match.back().atom.push_back(RegexxMatchAtom(m_str,ssv[i*2],ssv[(i*2)+1]-ssv[i*2]));
113
 
          else
114
 
            match.back().atom.push_back(RegexxMatchAtom(m_str,0,0));
115
 
        }
116
 
        ret = (pcre_exec(m_preg,m_extra,m_str.c_str(),m_str.length(),ssv[1],eflags,ssv,33) > 0);
117
 
      }
118
 
    }
119
 
  }
120
 
  return m_matches;
121
 
}
122
 
 
123
 
const std::string&
124
 
regexx::Regexx::replace(const std::string& _repstr, int _flags)
125
 
  throw(CompileException)
126
 
{
127
 
  exec(_flags&~nomatch);
128
 
  std::vector< std::pair<unsigned int,std::string::size_type> > v;
129
 
  v.reserve(m_capturecount);
130
 
  std::string::size_type pos = _repstr.find("%");
131
 
  while(pos != std::string::npos) {
132
 
    if(_repstr[pos-1] != '%'
133
 
       && _repstr[pos+1] >= '0'
134
 
       && _repstr[pos+1] <= '9') {
135
 
      v.push_back(std::pair<unsigned int,std::string::size_type>(_repstr[pos+1]-'0',pos));
136
 
    }
137
 
    pos = _repstr.find("%",pos+1);
138
 
  }
139
 
  m_replaced = m_str;
140
 
  std::vector<RegexxMatch>::reverse_iterator m;
141
 
  std::vector< std::pair<unsigned int,std::string::size_type> >::reverse_iterator i;
142
 
  for(m = match.rbegin(); m != match.rend(); m++) {
143
 
    std::string tmprep = _repstr;
144
 
    for(i = v.rbegin(); i != v.rend(); i++) {
145
 
      if(i->first < m->atom.size())
146
 
        tmprep.replace(i->second,2,m->atom[i->first]);
147
 
      else
148
 
        tmprep.erase(i->second,2);
149
 
    }
150
 
    m_replaced.replace(m->start(),m->length(),tmprep);
151
 
  }
152
 
  return m_replaced;
153
 
}
154