37 |
|
|
38 |
#define LOOPREPEAT 50000 |
#define LOOPREPEAT 50000 |
39 |
|
|
40 |
|
#define BUFFER_SIZE 30000 |
41 |
|
#define DBUFFER_SIZE BUFFER_SIZE |
42 |
|
|
43 |
|
|
44 |
static FILE *outfile; |
static FILE *outfile; |
45 |
static int log_store = 0; |
static int log_store = 0; |
48 |
static int callout_fail_count; |
static int callout_fail_count; |
49 |
static int callout_fail_id; |
static int callout_fail_id; |
50 |
static int first_callout; |
static int first_callout; |
51 |
static int utf8; |
static int show_malloc; |
52 |
|
static int use_utf8; |
53 |
static size_t gotten_store; |
static size_t gotten_store; |
54 |
|
|
55 |
|
|
56 |
|
static const int utf8_table1[] = { |
|
static int utf8_table1[] = { |
|
57 |
0x0000007f, 0x000007ff, 0x0000ffff, 0x001fffff, 0x03ffffff, 0x7fffffff}; |
0x0000007f, 0x000007ff, 0x0000ffff, 0x001fffff, 0x03ffffff, 0x7fffffff}; |
58 |
|
|
59 |
static int utf8_table2[] = { |
static const int utf8_table2[] = { |
60 |
0, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc}; |
0, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc}; |
61 |
|
|
62 |
static int utf8_table3[] = { |
static const int utf8_table3[] = { |
63 |
0xff, 0x1f, 0x0f, 0x07, 0x03, 0x01}; |
0xff, 0x1f, 0x0f, 0x07, 0x03, 0x01}; |
64 |
|
|
65 |
|
|
158 |
-6 to 0 => malformed UTF-8 character at offset = (-return) |
-6 to 0 => malformed UTF-8 character at offset = (-return) |
159 |
*/ |
*/ |
160 |
|
|
161 |
int |
static int |
162 |
utf82ord(unsigned char *buffer, int *vptr) |
utf82ord(unsigned char *buffer, int *vptr) |
163 |
{ |
{ |
164 |
int c = *buffer++; |
int c = *buffer++; |
216 |
|
|
217 |
while (length-- > 0) |
while (length-- > 0) |
218 |
{ |
{ |
219 |
if (utf8) |
if (use_utf8) |
220 |
{ |
{ |
221 |
int rc = utf82ord(p, &c); |
int rc = utf82ord(p, &c); |
222 |
|
|
273 |
|
|
274 |
if (callout_extra) |
if (callout_extra) |
275 |
{ |
{ |
|
int i; |
|
276 |
fprintf(f, "Callout %d: last capture = %d\n", |
fprintf(f, "Callout %d: last capture = %d\n", |
277 |
cb->callout_number, cb->capture_last); |
cb->callout_number, cb->capture_last); |
278 |
|
|
321 |
} |
} |
322 |
|
|
323 |
fprintf(outfile, "\n"); |
fprintf(outfile, "\n"); |
|
|
|
324 |
first_callout = 0; |
first_callout = 0; |
325 |
|
|
326 |
if ((int)(cb->callout_data) != 0) |
if (cb->callout_data != NULL) |
327 |
{ |
{ |
328 |
fprintf(outfile, "Callout data = %d\n", (int)(cb->callout_data)); |
int callout_data = *((int *)(cb->callout_data)); |
329 |
return (int)(cb->callout_data); |
if (callout_data != 0) |
330 |
|
{ |
331 |
|
fprintf(outfile, "Callout data = %d\n", callout_data); |
332 |
|
return callout_data; |
333 |
|
} |
334 |
} |
} |
335 |
|
|
336 |
return (cb->callout_number != callout_fail_id)? 0 : |
return (cb->callout_number != callout_fail_id)? 0 : |
339 |
|
|
340 |
|
|
341 |
/************************************************* |
/************************************************* |
342 |
* Local malloc function * |
* Local malloc functions * |
343 |
*************************************************/ |
*************************************************/ |
344 |
|
|
345 |
/* Alternative malloc function, to test functionality and show the size of the |
/* Alternative malloc function, to test functionality and show the size of the |
347 |
|
|
348 |
static void *new_malloc(size_t size) |
static void *new_malloc(size_t size) |
349 |
{ |
{ |
350 |
|
void *block = malloc(size); |
351 |
gotten_store = size; |
gotten_store = size; |
352 |
return malloc(size); |
if (show_malloc) |
353 |
|
fprintf(outfile, "malloc %3d %p\n", size, block); |
354 |
|
return block; |
355 |
} |
} |
356 |
|
|
357 |
|
static void new_free(void *block) |
358 |
|
{ |
359 |
|
if (show_malloc) |
360 |
|
fprintf(outfile, "free %p\n", block); |
361 |
|
free(block); |
362 |
|
} |
363 |
|
|
364 |
|
|
365 |
|
/* For recursion malloc/free, to test stacking calls */ |
366 |
|
|
367 |
|
static void *stack_malloc(size_t size) |
368 |
|
{ |
369 |
|
void *block = malloc(size); |
370 |
|
if (show_malloc) |
371 |
|
fprintf(outfile, "stack_malloc %3d %p\n", size, block); |
372 |
|
return block; |
373 |
|
} |
374 |
|
|
375 |
|
static void stack_free(void *block) |
376 |
|
{ |
377 |
|
if (show_malloc) |
378 |
|
fprintf(outfile, "stack_free %p\n", block); |
379 |
|
free(block); |
380 |
|
} |
381 |
|
|
382 |
|
|
383 |
/************************************************* |
/************************************************* |
420 |
#endif |
#endif |
421 |
int debug = 0; |
int debug = 0; |
422 |
int done = 0; |
int done = 0; |
423 |
unsigned char buffer[30000]; |
|
424 |
unsigned char dbuffer[1024]; |
unsigned char *buffer; |
425 |
|
unsigned char *dbuffer; |
426 |
|
|
427 |
|
/* Get buffers from malloc() so that Electric Fence will check their misuse |
428 |
|
when I am debugging. */ |
429 |
|
|
430 |
|
buffer = (unsigned char *)malloc(BUFFER_SIZE); |
431 |
|
dbuffer = (unsigned char *)malloc(DBUFFER_SIZE); |
432 |
|
|
433 |
/* Static so that new_malloc can use it. */ |
/* Static so that new_malloc can use it. */ |
434 |
|
|
446 |
else if (strcmp(argv[op], "-i") == 0) showinfo = 1; |
else if (strcmp(argv[op], "-i") == 0) showinfo = 1; |
447 |
else if (strcmp(argv[op], "-d") == 0) showinfo = debug = 1; |
else if (strcmp(argv[op], "-d") == 0) showinfo = debug = 1; |
448 |
else if (strcmp(argv[op], "-o") == 0 && argc > 2 && |
else if (strcmp(argv[op], "-o") == 0 && argc > 2 && |
449 |
((size_offsets = get_value(argv[op+1], &endptr)), *endptr == 0)) |
((size_offsets = get_value((unsigned char *)argv[op+1], &endptr)), |
450 |
|
*endptr == 0)) |
451 |
{ |
{ |
452 |
op++; |
op++; |
453 |
argc--; |
argc--; |
470 |
printf(" POSIX malloc threshold = %d\n", rc); |
printf(" POSIX malloc threshold = %d\n", rc); |
471 |
(void)pcre_config(PCRE_CONFIG_MATCH_LIMIT, &rc); |
(void)pcre_config(PCRE_CONFIG_MATCH_LIMIT, &rc); |
472 |
printf(" Default match limit = %d\n", rc); |
printf(" Default match limit = %d\n", rc); |
473 |
|
(void)pcre_config(PCRE_CONFIG_STACKRECURSE, &rc); |
474 |
|
printf(" Match recursion uses %s\n", rc? "stack" : "heap"); |
475 |
exit(0); |
exit(0); |
476 |
} |
} |
477 |
else |
else |
496 |
/* Get the store for the offsets vector, and remember what it was */ |
/* Get the store for the offsets vector, and remember what it was */ |
497 |
|
|
498 |
size_offsets_max = size_offsets; |
size_offsets_max = size_offsets; |
499 |
offsets = malloc(size_offsets_max * sizeof(int)); |
offsets = (int *)malloc(size_offsets_max * sizeof(int)); |
500 |
if (offsets == NULL) |
if (offsets == NULL) |
501 |
{ |
{ |
502 |
printf("** Failed to get %d bytes of memory for offsets vector\n", |
printf("** Failed to get %d bytes of memory for offsets vector\n", |
529 |
/* Set alternative malloc function */ |
/* Set alternative malloc function */ |
530 |
|
|
531 |
pcre_malloc = new_malloc; |
pcre_malloc = new_malloc; |
532 |
|
pcre_free = new_free; |
533 |
|
pcre_stack_malloc = stack_malloc; |
534 |
|
pcre_stack_free = stack_free; |
535 |
|
|
536 |
/* Heading line, then prompt for first regex if stdin */ |
/* Heading line, then prompt for first regex if stdin */ |
537 |
|
|
560 |
int do_showrest = 0; |
int do_showrest = 0; |
561 |
int erroroffset, len, delimiter; |
int erroroffset, len, delimiter; |
562 |
|
|
563 |
utf8 = 0; |
use_utf8 = 0; |
564 |
|
|
565 |
if (infile == stdin) printf(" re> "); |
if (infile == stdin) printf(" re> "); |
566 |
if (fgets((char *)buffer, sizeof(buffer), infile) == NULL) break; |
if (fgets((char *)buffer, BUFFER_SIZE, infile) == NULL) break; |
567 |
if (infile != stdin) fprintf(outfile, "%s", (char *)buffer); |
if (infile != stdin) fprintf(outfile, "%s", (char *)buffer); |
568 |
fflush(outfile); |
fflush(outfile); |
569 |
|
|
594 |
} |
} |
595 |
if (*pp != 0) break; |
if (*pp != 0) break; |
596 |
|
|
597 |
len = sizeof(buffer) - (pp - buffer); |
len = BUFFER_SIZE - (pp - buffer); |
598 |
if (len < 256) |
if (len < 256) |
599 |
{ |
{ |
600 |
fprintf(outfile, "** Expression too long - missing delimiter?\n"); |
fprintf(outfile, "** Expression too long - missing delimiter?\n"); |
653 |
case 'S': do_study = 1; break; |
case 'S': do_study = 1; break; |
654 |
case 'U': options |= PCRE_UNGREEDY; break; |
case 'U': options |= PCRE_UNGREEDY; break; |
655 |
case 'X': options |= PCRE_EXTRA; break; |
case 'X': options |= PCRE_EXTRA; break; |
656 |
case '8': options |= PCRE_UTF8; utf8 = 1; break; |
case '8': options |= PCRE_UTF8; use_utf8 = 1; break; |
657 |
|
case '?': options |= PCRE_NO_UTF8_CHECK; break; |
658 |
|
|
659 |
case 'L': |
case 'L': |
660 |
ppp = pp; |
ppp = pp; |
694 |
|
|
695 |
if (rc != 0) |
if (rc != 0) |
696 |
{ |
{ |
697 |
(void)regerror(rc, &preg, (char *)buffer, sizeof(buffer)); |
(void)regerror(rc, &preg, (char *)buffer, BUFFER_SIZE); |
698 |
fprintf(outfile, "Failed: POSIX code %d: %s\n", rc, buffer); |
fprintf(outfile, "Failed: POSIX code %d: %s\n", rc, buffer); |
699 |
goto SKIP_DATA; |
goto SKIP_DATA; |
700 |
} |
} |
735 |
{ |
{ |
736 |
for (;;) |
for (;;) |
737 |
{ |
{ |
738 |
if (fgets((char *)buffer, sizeof(buffer), infile) == NULL) |
if (fgets((char *)buffer, BUFFER_SIZE, infile) == NULL) |
739 |
{ |
{ |
740 |
done = 1; |
done = 1; |
741 |
goto CONTINUE; |
goto CONTINUE; |
782 |
new_info(re, NULL, PCRE_INFO_LASTLITERAL, &need_char); |
new_info(re, NULL, PCRE_INFO_LASTLITERAL, &need_char); |
783 |
new_info(re, NULL, PCRE_INFO_NAMEENTRYSIZE, &nameentrysize); |
new_info(re, NULL, PCRE_INFO_NAMEENTRYSIZE, &nameentrysize); |
784 |
new_info(re, NULL, PCRE_INFO_NAMECOUNT, &namecount); |
new_info(re, NULL, PCRE_INFO_NAMECOUNT, &namecount); |
785 |
new_info(re, NULL, PCRE_INFO_NAMETABLE, &nametable); |
new_info(re, NULL, PCRE_INFO_NAMETABLE, (void *)&nametable); |
786 |
|
|
787 |
old_count = pcre_info(re, &old_options, &old_first_char); |
old_count = pcre_info(re, &old_options, &old_first_char); |
788 |
if (count < 0) fprintf(outfile, |
if (count < 0) fprintf(outfile, |
823 |
} |
} |
824 |
|
|
825 |
if (get_options == 0) fprintf(outfile, "No options\n"); |
if (get_options == 0) fprintf(outfile, "No options\n"); |
826 |
else fprintf(outfile, "Options:%s%s%s%s%s%s%s%s%s\n", |
else fprintf(outfile, "Options:%s%s%s%s%s%s%s%s%s%s\n", |
827 |
((get_options & PCRE_ANCHORED) != 0)? " anchored" : "", |
((get_options & PCRE_ANCHORED) != 0)? " anchored" : "", |
828 |
((get_options & PCRE_CASELESS) != 0)? " caseless" : "", |
((get_options & PCRE_CASELESS) != 0)? " caseless" : "", |
829 |
((get_options & PCRE_EXTENDED) != 0)? " extended" : "", |
((get_options & PCRE_EXTENDED) != 0)? " extended" : "", |
832 |
((get_options & PCRE_DOLLAR_ENDONLY) != 0)? " dollar_endonly" : "", |
((get_options & PCRE_DOLLAR_ENDONLY) != 0)? " dollar_endonly" : "", |
833 |
((get_options & PCRE_EXTRA) != 0)? " extra" : "", |
((get_options & PCRE_EXTRA) != 0)? " extra" : "", |
834 |
((get_options & PCRE_UNGREEDY) != 0)? " ungreedy" : "", |
((get_options & PCRE_UNGREEDY) != 0)? " ungreedy" : "", |
835 |
((get_options & PCRE_UTF8) != 0)? " utf8" : ""); |
((get_options & PCRE_UTF8) != 0)? " utf8" : "", |
836 |
|
((get_options & PCRE_NO_UTF8_CHECK) != 0)? " no_utf8_check" : ""); |
837 |
|
|
838 |
if (((((real_pcre *)re)->options) & PCRE_ICHANGED) != 0) |
if (((((real_pcre *)re)->options) & PCRE_ICHANGED) != 0) |
839 |
fprintf(outfile, "Case state changes\n"); |
fprintf(outfile, "Case state changes\n"); |
849 |
else |
else |
850 |
{ |
{ |
851 |
int ch = first_char & 255; |
int ch = first_char & 255; |
852 |
char *caseless = ((first_char & REQ_CASELESS) == 0)? |
const char *caseless = ((first_char & REQ_CASELESS) == 0)? |
853 |
"" : " (caseless)"; |
"" : " (caseless)"; |
854 |
if (isprint(ch)) |
if (isprint(ch)) |
855 |
fprintf(outfile, "First char = \'%c\'%s\n", ch, caseless); |
fprintf(outfile, "First char = \'%c\'%s\n", ch, caseless); |
864 |
else |
else |
865 |
{ |
{ |
866 |
int ch = need_char & 255; |
int ch = need_char & 255; |
867 |
char *caseless = ((need_char & REQ_CASELESS) == 0)? |
const char *caseless = ((need_char & REQ_CASELESS) == 0)? |
868 |
"" : " (caseless)"; |
"" : " (caseless)"; |
869 |
if (isprint(ch)) |
if (isprint(ch)) |
870 |
fprintf(outfile, "Need char = \'%c\'%s\n", ch, caseless); |
fprintf(outfile, "Need char = \'%c\'%s\n", ch, caseless); |
898 |
else if (extra == NULL) |
else if (extra == NULL) |
899 |
fprintf(outfile, "Study returned NULL\n"); |
fprintf(outfile, "Study returned NULL\n"); |
900 |
|
|
901 |
|
/* Don't output study size; at present it is in any case a fixed |
902 |
|
value, but it varies, depending on the computer architecture, and |
903 |
|
so messes up the test suite. */ |
904 |
|
|
905 |
else if (do_showinfo) |
else if (do_showinfo) |
906 |
{ |
{ |
907 |
size_t size; |
size_t size; |
908 |
uschar *start_bits = NULL; |
uschar *start_bits = NULL; |
909 |
new_info(re, extra, PCRE_INFO_STUDYSIZE, &size); |
new_info(re, extra, PCRE_INFO_STUDYSIZE, &size); |
910 |
new_info(re, extra, PCRE_INFO_FIRSTTABLE, &start_bits); |
new_info(re, extra, PCRE_INFO_FIRSTTABLE, &start_bits); |
911 |
fprintf(outfile, "Study size = %d\n", size); |
/* fprintf(outfile, "Study size = %d\n", size); */ |
912 |
if (start_bits == NULL) |
if (start_bits == NULL) |
913 |
fprintf(outfile, "No starting character set\n"); |
fprintf(outfile, "No starting character set\n"); |
914 |
else |
else |
970 |
callout_count = 0; |
callout_count = 0; |
971 |
callout_fail_count = 999999; |
callout_fail_count = 999999; |
972 |
callout_fail_id = -1; |
callout_fail_id = -1; |
973 |
|
show_malloc = 0; |
974 |
|
|
975 |
if (infile == stdin) printf("data> "); |
if (infile == stdin) printf("data> "); |
976 |
if (fgets((char *)buffer, sizeof(buffer), infile) == NULL) |
if (fgets((char *)buffer, BUFFER_SIZE, infile) == NULL) |
977 |
{ |
{ |
978 |
done = 1; |
done = 1; |
979 |
goto CONTINUE; |
goto CONTINUE; |
1024 |
c = c * 16 + tolower(*pt) - ((isdigit(*pt))? '0' : 'W'); |
c = c * 16 + tolower(*pt) - ((isdigit(*pt))? '0' : 'W'); |
1025 |
if (*pt == '}') |
if (*pt == '}') |
1026 |
{ |
{ |
1027 |
unsigned char buffer[8]; |
unsigned char buff8[8]; |
1028 |
int ii, utn; |
int ii, utn; |
1029 |
utn = ord2utf8(c, buffer); |
utn = ord2utf8(c, buff8); |
1030 |
for (ii = 0; ii < utn - 1; ii++) *q++ = buffer[ii]; |
for (ii = 0; ii < utn - 1; ii++) *q++ = buff8[ii]; |
1031 |
c = buffer[ii]; /* Last byte */ |
c = buff8[ii]; /* Last byte */ |
1032 |
p = pt + 1; |
p = pt + 1; |
1033 |
break; |
break; |
1034 |
} |
} |
1066 |
else if (isalnum(*p)) |
else if (isalnum(*p)) |
1067 |
{ |
{ |
1068 |
uschar name[256]; |
uschar name[256]; |
1069 |
uschar *pp = name; |
uschar *npp = name; |
1070 |
while (isalnum(*p)) *pp++ = *p++; |
while (isalnum(*p)) *npp++ = *p++; |
1071 |
*pp = 0; |
*npp = 0; |
1072 |
n = pcre_get_stringnumber(re, name); |
n = pcre_get_stringnumber(re, (char *)name); |
1073 |
if (n < 0) |
if (n < 0) |
1074 |
fprintf(outfile, "no parentheses with name \"%s\"\n", name); |
fprintf(outfile, "no parentheses with name \"%s\"\n", name); |
1075 |
else copystrings |= 1 << n; |
else copystrings |= 1 << n; |
1119 |
else if (isalnum(*p)) |
else if (isalnum(*p)) |
1120 |
{ |
{ |
1121 |
uschar name[256]; |
uschar name[256]; |
1122 |
uschar *pp = name; |
uschar *npp = name; |
1123 |
while (isalnum(*p)) *pp++ = *p++; |
while (isalnum(*p)) *npp++ = *p++; |
1124 |
*pp = 0; |
*npp = 0; |
1125 |
n = pcre_get_stringnumber(re, name); |
n = pcre_get_stringnumber(re, (char *)name); |
1126 |
if (n < 0) |
if (n < 0) |
1127 |
fprintf(outfile, "no parentheses with name \"%s\"\n", name); |
fprintf(outfile, "no parentheses with name \"%s\"\n", name); |
1128 |
else getstrings |= 1 << n; |
else getstrings |= 1 << n; |
1147 |
{ |
{ |
1148 |
size_offsets_max = n; |
size_offsets_max = n; |
1149 |
free(offsets); |
free(offsets); |
1150 |
use_offsets = offsets = malloc(size_offsets_max * sizeof(int)); |
use_offsets = offsets = (int *)malloc(size_offsets_max * sizeof(int)); |
1151 |
if (offsets == NULL) |
if (offsets == NULL) |
1152 |
{ |
{ |
1153 |
printf("** Failed to get %d bytes of memory for offsets vector\n", |
printf("** Failed to get %d bytes of memory for offsets vector\n", |
1159 |
if (n == 0) use_offsets = NULL; /* Ensures it can't write to it */ |
if (n == 0) use_offsets = NULL; /* Ensures it can't write to it */ |
1160 |
continue; |
continue; |
1161 |
|
|
1162 |
|
case 'S': |
1163 |
|
show_malloc = 1; |
1164 |
|
continue; |
1165 |
|
|
1166 |
case 'Z': |
case 'Z': |
1167 |
options |= PCRE_NOTEOL; |
options |= PCRE_NOTEOL; |
1168 |
continue; |
continue; |
1169 |
|
|
1170 |
|
case '?': |
1171 |
|
options |= PCRE_NO_UTF8_CHECK; |
1172 |
|
continue; |
1173 |
} |
} |
1174 |
*q++ = c; |
*q++ = c; |
1175 |
} |
} |
1186 |
int eflags = 0; |
int eflags = 0; |
1187 |
regmatch_t *pmatch = NULL; |
regmatch_t *pmatch = NULL; |
1188 |
if (use_size_offsets > 0) |
if (use_size_offsets > 0) |
1189 |
pmatch = malloc(sizeof(regmatch_t) * use_size_offsets); |
pmatch = (regmatch_t *)malloc(sizeof(regmatch_t) * use_size_offsets); |
1190 |
if ((options & PCRE_NOTBOL) != 0) eflags |= REG_NOTBOL; |
if ((options & PCRE_NOTBOL) != 0) eflags |= REG_NOTBOL; |
1191 |
if ((options & PCRE_NOTEOL) != 0) eflags |= REG_NOTEOL; |
if ((options & PCRE_NOTEOL) != 0) eflags |= REG_NOTEOL; |
1192 |
|
|
1194 |
|
|
1195 |
if (rc != 0) |
if (rc != 0) |
1196 |
{ |
{ |
1197 |
(void)regerror(rc, &preg, (char *)buffer, sizeof(buffer)); |
(void)regerror(rc, &preg, (char *)buffer, BUFFER_SIZE); |
1198 |
fprintf(outfile, "No match: POSIX code %d: %s\n", rc, buffer); |
fprintf(outfile, "No match: POSIX code %d: %s\n", rc, buffer); |
1199 |
} |
} |
1200 |
else |
else |
1253 |
|
|
1254 |
if (extra == NULL) |
if (extra == NULL) |
1255 |
{ |
{ |
1256 |
extra = malloc(sizeof(pcre_extra)); |
extra = (pcre_extra *)malloc(sizeof(pcre_extra)); |
1257 |
extra->flags = 0; |
extra->flags = 0; |
1258 |
} |
} |
1259 |
extra->flags |= PCRE_EXTRA_MATCH_LIMIT; |
extra->flags |= PCRE_EXTRA_MATCH_LIMIT; |
1292 |
{ |
{ |
1293 |
if (extra == NULL) |
if (extra == NULL) |
1294 |
{ |
{ |
1295 |
extra = malloc(sizeof(pcre_extra)); |
extra = (pcre_extra *)malloc(sizeof(pcre_extra)); |
1296 |
extra->flags = 0; |
extra->flags = 0; |
1297 |
} |
} |
1298 |
extra->flags |= PCRE_EXTRA_CALLOUT_DATA; |
extra->flags |= PCRE_EXTRA_CALLOUT_DATA; |
1299 |
extra->callout_data = (void *)callout_data; |
extra->callout_data = &callout_data; |
1300 |
count = pcre_exec(re, extra, (char *)bptr, len, start_offset, |
count = pcre_exec(re, extra, (char *)bptr, len, start_offset, |
1301 |
options | g_notempty, use_offsets, use_size_offsets); |
options | g_notempty, use_offsets, use_size_offsets); |
1302 |
extra->flags &= ~PCRE_EXTRA_CALLOUT_DATA; |
extra->flags &= ~PCRE_EXTRA_CALLOUT_DATA; |
1395 |
|
|
1396 |
/* Failed to match. If this is a /g or /G loop and we previously set |
/* Failed to match. If this is a /g or /G loop and we previously set |
1397 |
g_notempty after a null match, this is not necessarily the end. |
g_notempty after a null match, this is not necessarily the end. |
1398 |
We want to advance the start offset, and continue. Fudge the offset |
We want to advance the start offset, and continue. In the case of UTF-8 |
1399 |
values to achieve this. We won't be at the end of the string - that |
matching, the advance must be one character, not one byte. Fudge the |
1400 |
was checked before setting g_notempty. */ |
offset values to achieve this. We won't be at the end of the string - |
1401 |
|
that was checked before setting g_notempty. */ |
1402 |
|
|
1403 |
else |
else |
1404 |
{ |
{ |
1405 |
if (g_notempty != 0) |
if (g_notempty != 0) |
1406 |
{ |
{ |
1407 |
|
int onechar = 1; |
1408 |
use_offsets[0] = start_offset; |
use_offsets[0] = start_offset; |
1409 |
use_offsets[1] = start_offset + 1; |
if (use_utf8) |
1410 |
|
{ |
1411 |
|
while (start_offset + onechar < len) |
1412 |
|
{ |
1413 |
|
int tb = bptr[start_offset+onechar]; |
1414 |
|
if (tb <= 127) break; |
1415 |
|
tb &= 0xc0; |
1416 |
|
if (tb != 0 && tb != 0xc0) onechar++; |
1417 |
|
} |
1418 |
|
} |
1419 |
|
use_offsets[1] = start_offset + onechar; |
1420 |
} |
} |
1421 |
else |
else |
1422 |
{ |
{ |
1423 |
if (gmatched == 0) /* Error if no previous matches */ |
if (count == PCRE_ERROR_NOMATCH) |
1424 |
{ |
{ |
1425 |
if (count == -1) fprintf(outfile, "No match\n"); |
if (gmatched == 0) fprintf(outfile, "No match\n"); |
|
else fprintf(outfile, "Error %d\n", count); |
|
1426 |
} |
} |
1427 |
|
else fprintf(outfile, "Error %d\n", count); |
1428 |
break; /* Out of the /g loop */ |
break; /* Out of the /g loop */ |
1429 |
} |
} |
1430 |
} |
} |
1476 |
} |
} |
1477 |
} |
} |
1478 |
|
|
1479 |
fprintf(outfile, "\n"); |
if (infile == stdin) fprintf(outfile, "\n"); |
1480 |
return 0; |
return 0; |
1481 |
} |
} |
1482 |
|
|