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)
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) <<
"(?";
226 while ((pos = buf_str.find (
'\0')) != std::string::npos)
227 buf_str.replace (pos, 1,
"\\000");
238 data = pcre_compile (buf_str.c_str (), pcre_options,
239 &
err, &erroffset,
nullptr);
242 (*current_liboctave_error_handler)
243 (
"%s: %s at position %d of expression",
who.c_str (),
err, erroffset);
251 std::list<regexp::match_element> lst;
259 pcre *re =
static_cast<pcre *
> (
data);
261 pcre_fullinfo (re,
nullptr, PCRE_INFO_CAPTURECOUNT, &subpatterns);
262 pcre_fullinfo (re,
nullptr, PCRE_INFO_NAMECOUNT, &namecount);
263 pcre_fullinfo (re,
nullptr, PCRE_INFO_NAMEENTRYSIZE, &nameentrysize);
264 pcre_fullinfo (re,
nullptr, PCRE_INFO_NAMETABLE, &nametable);
269 for (
int i = 0;
i < namecount;
i++)
273 nidx[
i] = (
static_cast<int> (nametable[
i*nameentrysize])) << 8
274 |
static_cast<int> (nametable[
i*nameentrysize+1]);
281 int matches = pcre_exec (re,
nullptr, buffer.c_str (),
282 buffer.length (), idx,
283 (idx ? PCRE_NOTBOL : 0),
284 ovector, (subpatterns+1)*3);
286 if (matches == PCRE_ERROR_MATCHLIMIT)
290 (*current_liboctave_warning_with_id_handler)
291 (
"Octave:regexp-match-limit",
292 "your pattern caused PCRE to hit its MATCH_LIMIT; trying harder now, but this will be slow");
296 pcre_config (PCRE_CONFIG_MATCH_LIMIT,
297 static_cast<void *> (&pe.match_limit));
299 pe.flags = PCRE_EXTRA_MATCH_LIMIT;
302 while (matches == PCRE_ERROR_MATCHLIMIT
307 pe.match_limit *= 10;
308 matches = pcre_exec (re, &pe, buffer.c_str (),
309 buffer.length (), idx,
310 (idx ? PCRE_NOTBOL : 0),
311 ovector, (subpatterns+1)*3);
315 if (matches < 0 && matches != PCRE_ERROR_NOMATCH)
316 (*current_liboctave_error_handler)
317 (
"%s: internal error calling pcre_exec; " 318 "error code from pcre_exec is %i",
who.c_str (), matches);
320 if (matches == PCRE_ERROR_NOMATCH)
325 idx = ovector[0] + 1;
326 if (idx < buffer.length ())
334 Matrix token_extents (matches-1, 2);
336 for (
int i = 1;
i < matches;
i++)
338 if (ovector[2*
i] >= 0 && ovector[2*
i+1] > 0
339 && (
i == 1 || ovector[2*
i] != ovector[2*
i-2]
340 || ovector[2*
i-1] != ovector[2*
i+1]))
342 token_extents(pos_match,0) =
double (ovector[2*
i]+1);
343 token_extents(pos_match++,1) =
double (ovector[2*
i+1]);
347 token_extents.
resize (pos_match, 2);
350 double end =
double (ovector[1]);
352 const char **listptr;
353 int status = pcre_get_substring_list (buffer.c_str (), ovector,
356 if (status == PCRE_ERROR_NOMEMORY)
357 (*current_liboctave_error_handler)
358 (
"%s: cannot allocate memory in pcre_get_substring_list",
369 for (
int i = 1;
i < matches;
i++)
371 if (ovector[2*
i] >= 0 && ovector[2*
i+1] > 0)
373 if (
i == 1 || ovector[2*
i] != ovector[2*
i-2]
374 || ovector[2*
i-1] != ovector[2*
i+1])
382 for (
int j = 0; j < namecount; j++)
386 size_t len = ovector[2*
i+1] - ovector[2*
i];
395 size_t len = ovector[2*
i+1] - ovector[2*
i];
403 pcre_free_substring_list (listptr);
406 token_extents,
start, end);
407 lst.push_back (new_elem);
409 if (ovector[1] <= ovector[0])
412 idx = ovector[0] + 1;
413 if (idx <= buffer.length ())
434 return rx_lst.
size () > 0;
464 size_t num_matches = rx_lst.
size ();
466 if (num_matches == 0)
481 std::vector<rep_token_t> tokens;
484 for (
size_t i=0;
i < repstr.size ();
i++)
486 if (repstr[
i] ==
'\\')
488 if (
i < repstr.size () - 1 && repstr[
i+1] ==
'$')
494 if (
i < repstr.size () - 1 && repstr[
i+1] ==
'\\')
500 else if (repstr[
i] ==
'$')
502 if (
i < repstr.size () - 1 && isdigit (repstr[
i+1]))
507 tmp_token.
num = repstr[
i+1]-
'0';
508 tokens.push_back (tmp_token);
514 int num_tokens = tokens.size ();
519 const size_t replen = repstr.size () - 2*num_tokens;
522 for (
size_t i = 0;
i < num_matches;
i++)
526 double start =
p->start ();
527 double end =
p->end ();
529 const Matrix pairs (
p->token_extents ());
531 for (
int j = 0; j < num_tokens; j++)
533 if (tokens[j].num == 0)
534 pairlen +=
static_cast<size_t> (end -
start + 1);
535 else if (tokens[j].num <= pairs.rows ())
536 pairlen += static_cast<size_t> (pairs(tokens[j].num-1,1)
537 - pairs(tokens[j].num-1,0)
540 delta += (
static_cast<int> (replen + pairlen)
541 - static_cast<int> (end -
start + 1));
546 rep.reserve (buffer.size () + delta);
549 for (
size_t i = 0;
i < num_matches;
i++)
553 double start =
p->start ();
554 double end =
p->end ();
556 const Matrix pairs (
p->token_extents ());
557 rep.
append (&buffer[from], static_cast<size_t> (
start - 1 - from));
558 from =
static_cast<size_t> (end);
562 for (
int j = 0; j < num_tokens; j++)
564 rep.
append (&repstr[cur_pos], (tokens[j].pos) - cur_pos);
565 cur_pos = tokens[j].pos+2;
567 int k = tokens[j].num;
571 rep.append (&buffer[static_cast<size_t> (end - 1)],
572 static_cast<size_t> (end -
start + 1));
574 else if (
k <= pairs.rows ())
577 rep.append (&buffer[static_cast<size_t> (pairs(
k-1,0)-1)],
578 static_cast<size_t> (pairs(
k-1,1)
579 - pairs(
k-1,0) + 1));
586 if (cur_pos < repstr.size ())
587 rep.append (&repstr[cur_pos], repstr.size () - cur_pos);
591 rep.append (&buffer[from], buffer.size () - from);
596 const size_t replen = repstr.size ();
599 for (
size_t i = 0;
i < num_matches;
i++)
603 delta +=
static_cast<int> (replen)
604 - static_cast<int> (
p->end () -
p->start () + 1);
609 rep.reserve (buffer.size () + delta);
612 for (
size_t i = 0;
i < num_matches;
i++)
616 rep.append (&buffer[from],
617 static_cast<size_t> (
p->start () - 1 - from));
618 from =
static_cast<size_t> (
p->end ());
622 rep.append (&buffer[from], buffer.size () - from);
is already an absolute the name is checked against the file system instead of Octave s loadpath In this if otherwise an empty string is returned If the first argument is a cell array of 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 resize(octave_idx_type nr, octave_idx_type nc, double rfv=0)
void dotexceptnewline(bool val)
string_vector & append(const std::string &s)
void resize(const dim_vector &dv, const T &rfv)
Resizing (with fill).
Matrix append(const Matrix &a) const
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)
void compile_internal(void)
#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)
octave_idx_type numel(void) const
Number of elements in the array.
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
void freespacing(bool val)