706 |
int getlist = 0; |
int getlist = 0; |
707 |
int gmatched = 0; |
int gmatched = 0; |
708 |
int start_offset = 0; |
int start_offset = 0; |
709 |
|
int g_notempty = 0; |
710 |
int offsets[45]; |
int offsets[45]; |
711 |
int size_offsets = sizeof(offsets)/sizeof(int); |
int size_offsets = sizeof(offsets)/sizeof(int); |
712 |
|
|
812 |
{ |
{ |
813 |
int rc; |
int rc; |
814 |
int eflags = 0; |
int eflags = 0; |
815 |
regmatch_t pmatch[30]; |
regmatch_t pmatch[sizeof(offsets)/sizeof(int)]; |
816 |
if ((options & PCRE_NOTBOL) != 0) eflags |= REG_NOTBOL; |
if ((options & PCRE_NOTBOL) != 0) eflags |= REG_NOTBOL; |
817 |
if ((options & PCRE_NOTEOL) != 0) eflags |= REG_NOTEOL; |
if ((options & PCRE_NOTEOL) != 0) eflags |= REG_NOTEOL; |
818 |
|
|
819 |
rc = regexec(&preg, (const char *)bptr, |
rc = regexec(&preg, (const char *)bptr, size_offsets, pmatch, eflags); |
|
sizeof(pmatch)/sizeof(regmatch_t), pmatch, eflags); |
|
820 |
|
|
821 |
if (rc != 0) |
if (rc != 0) |
822 |
{ |
{ |
826 |
else |
else |
827 |
{ |
{ |
828 |
size_t i; |
size_t i; |
829 |
for (i = 0; i < sizeof(pmatch)/sizeof(regmatch_t); i++) |
for (i = 0; i < size_offsets; i++) |
830 |
{ |
{ |
831 |
if (pmatch[i].rm_so >= 0) |
if (pmatch[i].rm_so >= 0) |
832 |
{ |
{ |
859 |
clock_t start_time = clock(); |
clock_t start_time = clock(); |
860 |
for (i = 0; i < LOOPREPEAT; i++) |
for (i = 0; i < LOOPREPEAT; i++) |
861 |
count = pcre_exec(re, extra, (char *)bptr, len, |
count = pcre_exec(re, extra, (char *)bptr, len, |
862 |
start_offset, options, offsets, size_offsets); |
start_offset, options | g_notempty, offsets, size_offsets); |
863 |
time_taken = clock() - start_time; |
time_taken = clock() - start_time; |
864 |
fprintf(outfile, "Execute time %.3f milliseconds\n", |
fprintf(outfile, "Execute time %.3f milliseconds\n", |
865 |
((double)time_taken * 1000.0)/ |
((double)time_taken * 1000.0)/ |
867 |
} |
} |
868 |
|
|
869 |
count = pcre_exec(re, extra, (char *)bptr, len, |
count = pcre_exec(re, extra, (char *)bptr, len, |
870 |
start_offset, options, offsets, size_offsets); |
start_offset, options | g_notempty, offsets, size_offsets); |
871 |
|
|
872 |
if (count == 0) |
if (count == 0) |
873 |
{ |
{ |
950 |
} |
} |
951 |
} |
} |
952 |
|
|
953 |
/* Failed to match */ |
/* Failed to match. If this is a /g or /G loop and we previously set |
954 |
|
PCRE_NOTEMPTY after a null match, this is not necessarily the end. |
955 |
|
We want to advance the start offset, and continue. Fudge the offset |
956 |
|
values to achieve this. We won't be at the end of the string - that |
957 |
|
was checked before setting PCRE_NOTEMPTY. */ |
958 |
|
|
959 |
else |
else |
960 |
{ |
{ |
961 |
if (gmatched == 0) |
if (g_notempty != 0) |
962 |
{ |
{ |
963 |
if (count == -1) fprintf(outfile, "No match\n"); |
offsets[0] = start_offset; |
964 |
else fprintf(outfile, "Error %d\n", count); |
offsets[1] = start_offset + 1; |
965 |
|
} |
966 |
|
else |
967 |
|
{ |
968 |
|
if (gmatched == 0) /* Error if no previous matches */ |
969 |
|
{ |
970 |
|
if (count == -1) fprintf(outfile, "No match\n"); |
971 |
|
else fprintf(outfile, "Error %d\n", count); |
972 |
|
} |
973 |
|
break; /* Out of the /g loop */ |
974 |
} |
} |
|
break; /* Out of the /g loop */ |
|
975 |
} |
} |
976 |
|
|
977 |
/* If not /g or /G we are done */ |
/* If not /g or /G we are done */ |
978 |
|
|
979 |
if (!do_g && !do_G) break; |
if (!do_g && !do_G) break; |
980 |
|
|
981 |
/* If we have matched an empty string, set PCRE_NOTEMPTY for the next |
/* If we have matched an empty string, first check to see if we are at |
982 |
match. This mimics what Perl's /g option does. */ |
the end of the subject. If so, the /g loop is over. Otherwise, mimic |
983 |
|
what Perl's /g options does. This turns out to be rather cunning. First |
984 |
|
we set PCRE_NOTEMPTY and try the match again at the same point. If this |
985 |
|
fails (picked up above) we advance to the next character. */ |
986 |
|
|
987 |
if (offsets[1] == offsets[0]) |
g_notempty = 0; |
988 |
options |= PCRE_NOTEMPTY; |
if (offsets[0] == offsets[1]) |
989 |
else |
{ |
990 |
options &= ~PCRE_NOTEMPTY; |
if (offsets[0] == len) break; |
991 |
|
g_notempty = PCRE_NOTEMPTY; |
992 |
|
} |
993 |
|
|
994 |
/* For /g, update the start offset, leaving the rest alone */ |
/* For /g, update the start offset, leaving the rest alone */ |
995 |
|
|