704 |
int copystrings = 0; |
int copystrings = 0; |
705 |
int getstrings = 0; |
int getstrings = 0; |
706 |
int getlist = 0; |
int getlist = 0; |
707 |
|
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 |
{ |
{ |
850 |
else |
else |
851 |
#endif /* !defined NOPOSIX */ |
#endif /* !defined NOPOSIX */ |
852 |
|
|
853 |
for (;;) |
for (;; gmatched++) /* Loop for /g or /G */ |
854 |
{ |
{ |
855 |
if (timeit) |
if (timeit) |
856 |
{ |
{ |
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 |
(do_g? start_offset : 0), 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 |
(do_g? start_offset : 0), options, offsets, size_offsets); |
start_offset, options | g_notempty, offsets, size_offsets); |
871 |
|
|
872 |
if (count == 0) |
if (count == 0) |
873 |
{ |
{ |
875 |
count = size_offsets/3; |
count = size_offsets/3; |
876 |
} |
} |
877 |
|
|
878 |
|
/* Matched */ |
879 |
|
|
880 |
if (count >= 0) |
if (count >= 0) |
881 |
{ |
{ |
882 |
int i; |
int i; |
891 |
fprintf(outfile, "\n"); |
fprintf(outfile, "\n"); |
892 |
if (i == 0) |
if (i == 0) |
893 |
{ |
{ |
|
start_offset = offsets[1]; |
|
894 |
if (do_showrest) |
if (do_showrest) |
895 |
{ |
{ |
896 |
fprintf(outfile, " 0+ "); |
fprintf(outfile, " 0+ "); |
948 |
free((void *)stringlist); |
free((void *)stringlist); |
949 |
} |
} |
950 |
} |
} |
|
|
|
951 |
} |
} |
952 |
|
|
953 |
|
/* 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 (start_offset == 0) |
if (g_notempty != 0) |
962 |
|
{ |
963 |
|
offsets[0] = start_offset; |
964 |
|
offsets[1] = start_offset + 1; |
965 |
|
} |
966 |
|
else |
967 |
{ |
{ |
968 |
if (count == -1) fprintf(outfile, "No match\n"); |
if (gmatched == 0) /* Error if no previous matches */ |
969 |
else fprintf(outfile, "Error %d\n", count); |
{ |
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 |
} |
} |
|
start_offset = -1; |
|
975 |
} |
} |
976 |
|
|
977 |
if ((!do_g && !do_G) || start_offset <= 0) break; |
/* If not /g or /G we are done */ |
978 |
if (do_G) |
|
979 |
|
if (!do_g && !do_G) break; |
980 |
|
|
981 |
|
/* If we have matched an empty string, first check to see if we are at |
982 |
|
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 |
|
g_notempty = 0; |
988 |
|
if (offsets[0] == offsets[1]) |
989 |
{ |
{ |
990 |
bptr += start_offset; |
if (offsets[0] == len) break; |
991 |
len -= start_offset; |
g_notempty = PCRE_NOTEMPTY; |
992 |
} |
} |
993 |
} |
|
994 |
} |
/* For /g, update the start offset, leaving the rest alone */ |
995 |
|
|
996 |
|
if (do_g) start_offset = offsets[1]; |
997 |
|
|
998 |
|
/* For /G, update the pointer and length */ |
999 |
|
|
1000 |
|
else |
1001 |
|
{ |
1002 |
|
bptr += offsets[1]; |
1003 |
|
len -= offsets[1]; |
1004 |
|
} |
1005 |
|
} /* End of loop for /g and /G */ |
1006 |
|
} /* End of loop for data lines */ |
1007 |
|
|
1008 |
CONTINUE: |
CONTINUE: |
1009 |
|
|