25 #if defined (HAVE_CONFIG_H)
34 #if defined (HAVE_PCRE_H)
36 #elif defined (HAVE_PCRE_PCRE_H)
37 # include <pcre/pcre.h>
50 #define PCRE_MATCHLIMIT_MAX 10
53 #define MAXLOOKBEHIND 10
66 pcre_free (static_cast<pcre *> (
data));
80 std::ostringstream buf;
82 while ((new_pos =
pattern.find (
"(?", pos)) != std::string::npos)
84 if (
pattern.at (new_pos + 2) ==
'<'
85 && !(
pattern.at (new_pos + 3) ==
'='
86 ||
pattern.at (new_pos + 3) ==
'!'))
97 size_t tmp_pos =
pattern.find_first_of (
'>', new_pos);
99 if (tmp_pos == std::string::npos)
100 (*current_liboctave_error_handler)
101 (
"regexp: syntax error in pattern");
104 pattern.substr (new_pos+3, tmp_pos-new_pos-3);
127 if (new_pos - pos > 0)
128 buf <<
pattern.substr (pos, new_pos-pos);
130 buf <<
"(?P<n00" << inames++;
131 else if (inames < 100)
132 buf <<
"(?P<n0" << inames++;
134 buf <<
"(?P<n" << inames++;
138 else if (
pattern.at (new_pos + 2) ==
'<')
147 size_t tmp_pos1 = new_pos + 2;
148 size_t tmp_pos2 = tmp_pos1;
150 while (tmp_pos1 <
pattern.length () && brackets > 0)
152 char ch =
pattern.at (tmp_pos1);
169 buf <<
pattern.substr (pos, new_pos - pos) <<
"(?";
174 size_t tmp_pos3 =
pattern.find_first_of (
"*+", tmp_pos2);
176 if (tmp_pos3 != std::string::npos && tmp_pos3 < tmp_pos1)
178 if (! lookbehind_warned)
180 lookbehind_warned =
true;
181 (*current_liboctave_warning_with_id_handler)
182 (
"Octave:regexp-lookbehind-limit",
183 "%s: arbitrary length lookbehind patterns are only supported up to length %d",
187 buf <<
pattern.substr (pos, new_pos - pos) <<
"(";
191 if (
pattern.at (tmp_pos3) ==
'*')
196 for (; i < max_length + 1; i++)
198 buf <<
pattern.substr (new_pos, tmp_pos3 - new_pos)
200 buf <<
pattern.substr (tmp_pos3 + 1,
201 tmp_pos1 - tmp_pos3 - 1);
208 buf <<
pattern.substr (pos, tmp_pos1 - pos);
215 buf <<
pattern.substr (pos, new_pos - pos) <<
"(?";
233 data = pcre_compile (buf_str.c_str (), pcre_options, &
err, &erroffset, 0);
236 (*current_liboctave_error_handler)
237 (
"%s: %s at position %d of expression",
who.c_str (),
err, erroffset);
245 std::list<regexp::match_element> lst;
253 pcre *re =
static_cast<pcre *
> (
data);
255 pcre_fullinfo (re, 0, PCRE_INFO_CAPTURECOUNT, &subpatterns);
256 pcre_fullinfo (re, 0, PCRE_INFO_NAMECOUNT, &namecount);
257 pcre_fullinfo (re, 0, PCRE_INFO_NAMEENTRYSIZE, &nameentrysize);
258 pcre_fullinfo (re, 0, PCRE_INFO_NAMETABLE, &nametable);
263 for (
int i = 0;
i < namecount;
i++)
267 nidx[
i] = (
static_cast<int> (nametable[
i*nameentrysize])) << 8
268 |
static_cast<int> (nametable[
i*nameentrysize+1]);
275 int matches = pcre_exec (re, 0, buffer.c_str (),
276 buffer.length (), idx,
277 (idx ? PCRE_NOTBOL : 0),
278 ovector, (subpatterns+1)*3);
280 if (matches == PCRE_ERROR_MATCHLIMIT)
284 (*current_liboctave_warning_with_id_handler)
285 (
"Octave:regexp-match-limit",
286 "your pattern caused PCRE to hit its MATCH_LIMIT; trying harder now, but this will be slow");
290 pcre_config (PCRE_CONFIG_MATCH_LIMIT,
291 static_cast<void *> (&pe.match_limit));
293 pe.flags = PCRE_EXTRA_MATCH_LIMIT;
296 while (matches == PCRE_ERROR_MATCHLIMIT
301 pe.match_limit *= 10;
302 matches = pcre_exec (re, &pe, buffer.c_str (),
303 buffer.length (), idx,
304 (idx ? PCRE_NOTBOL : 0),
305 ovector, (subpatterns+1)*3);
309 if (matches < 0 && matches != PCRE_ERROR_NOMATCH)
310 (*current_liboctave_error_handler)
311 (
"%s: internal error calling pcre_exec; "
312 "error code from pcre_exec is %i",
who.c_str (), matches);
314 if (matches == PCRE_ERROR_NOMATCH)
319 idx = ovector[0] + 1;
320 if (idx < buffer.length ())
328 Matrix token_extents (matches-1, 2);
330 for (
int i = 1;
i < matches;
i++)
332 if (ovector[2*
i] >= 0 && ovector[2*
i+1] > 0
333 && (
i == 1 || ovector[2*
i] != ovector[2*
i-2]
334 || ovector[2*
i-1] != ovector[2*
i+1]))
336 token_extents(pos_match,0) =
double (ovector[2*
i]+1);
337 token_extents(pos_match++,1) =
double (ovector[2*
i+1]);
341 token_extents.
resize (pos_match, 2);
344 double end =
double (ovector[1]);
346 const char **listptr;
347 int status = pcre_get_substring_list (buffer.c_str (), ovector,
350 if (status == PCRE_ERROR_NOMEMORY)
351 (*current_liboctave_error_handler)
352 (
"%s: cannot allocate memory in pcre_get_substring_list",
360 for (
int i = 1;
i < matches;
i++)
362 if (ovector[2*
i] >= 0 && ovector[2*
i+1] > 0)
364 if (
i == 1 || ovector[2*
i] != ovector[2*
i-2]
365 || ovector[2*
i-1] != ovector[2*
i+1])
373 for (
int j = 0; j < namecount; j++)
393 pcre_free_substring_list (listptr);
396 token_extents, start, end);
397 lst.push_back (new_elem);
399 if (ovector[1] <= ovector[0])
402 idx = ovector[0] + 1;
403 if (idx <= buffer.length ())
424 return rx_lst.
size () > 0;
454 size_t num_matches = rx_lst.
size ();
456 if (num_matches == 0)
471 std::vector<rep_token_t> tokens;
474 for (
size_t i=0;
i < repstr.size ();
i++)
476 if (repstr[
i] ==
'\\')
478 if (
i < repstr.size () - 1 && repstr[
i+1] ==
'$')
484 if (
i < repstr.size () - 1 && repstr[
i+1] ==
'\\')
490 else if (repstr[
i] ==
'$')
492 if (
i < repstr.size () - 1 && isdigit (repstr[
i+1]))
497 tmp_token.
num = repstr[
i+1]-
'0';
498 tokens.push_back (tmp_token);
504 int num_tokens = tokens.size ();
509 const size_t replen = repstr.size () - 2*num_tokens;
512 for (
size_t i = 0;
i < num_matches;
i++)
516 double start = p->start ();
517 double end = p->end ();
519 const Matrix pairs (p->token_extents ());
521 for (
int j = 0; j < num_tokens; j++)
523 if (tokens[j].num == 0)
524 pairlen +=
static_cast<size_t> (end -
start) + 1;
525 else if (tokens[j].num <= pairs.rows ())
526 pairlen += static_cast<size_t> (pairs(tokens[j].num-1,1)
527 - pairs(tokens[j].num-1,0)) + 1;
529 delta += (
static_cast<int> (replen + pairlen)
530 - static_cast<int> (end - start + 1));
535 rep.reserve (buffer.size () + delta);
538 for (
size_t i = 0;
i < num_matches;
i++)
542 double start = p->start ();
543 double end = p->end ();
545 const Matrix pairs (p->token_extents ());
546 rep.
append (&buffer[from], static_cast<size_t> (start - 1) - from);
547 from =
static_cast<size_t> (end);
551 for (
int j = 0; j < num_tokens; j++)
553 rep.
append (&repstr[cur_pos], (tokens[j].pos) - cur_pos);
554 cur_pos = tokens[j].pos+2;
556 int k = tokens[j].num;
560 rep.append (&buffer[static_cast<size_t> (end - 1)],
561 static_cast<size_t> (end - start) + 1);
563 else if (k <= pairs.rows ())
566 rep.append (&buffer[static_cast<size_t> (pairs(k-1,0)-1)],
567 static_cast<size_t> (pairs(k-1,1)
568 - pairs(k-1,0)) + 1);
575 if (cur_pos < repstr.size ())
576 rep.append (&repstr[cur_pos], repstr.size () - cur_pos);
580 rep.append (&buffer[from], buffer.size () - from);
585 const size_t replen = repstr.size ();
588 for (
size_t i = 0;
i < num_matches;
i++)
591 delta +=
static_cast<int> (replen)
592 - static_cast<int> (p->end () - p->start () + 1);
597 rep.reserve (buffer.size () + delta);
600 for (
size_t i = 0;
i < num_matches;
i++)
603 rep.append (&buffer[from],
604 static_cast<size_t> (p->start () - 1) - from);
605 from =
static_cast<size_t> (p->end ());
609 rep.append (&buffer[from], buffer.size () - from);
Octave interface to the compression and uncompression libraries.
void resize(octave_idx_type nr, octave_idx_type nc, double rfv=0)
octave_idx_type numel(void) const
Number of elements in the array.
OCTAVE_EXPORT octave_value_list search each directory of the loadpath for element of the cell array and return the first that matches If the second optional argument return a cell array containing the list of all files that have the same name in the path If no files are found
void dotexceptnewline(bool val)
string_vector & append(const std::string &s)
void resize(const dim_vector &dv, const T &rfv)
std::string replace(const std::string &buffer, const std::string &replacement)
bool is_match(const std::string &buffer)
match_data match(const std::string &buffer)
std::list< match_element >::const_iterator const_iterator
void emptymatch(bool val)
=val(i)}if ode{val(i)}occurs in table i
void compile_internal(void)
issues an error eealso double
#define OCTAVE_LOCAL_BUFFER(T, buf, size)
#define PCRE_MATCHLIMIT_MAX
OCTAVE_EXPORT octave_value_list error nd deftypefn *const octave_scalar_map err
void case_insensitive(bool val)
void lineanchors(bool val)
Vector representing the dimensions (size) of an Array.
If this string is the system will ring the terminal sometimes it is useful to be able to print the original representation of the string
static bool lookbehind_warned
Matrix append(const Matrix &a) const
void freespacing(bool val)