⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pcretest.c

📁 PHP v6.0 For Linux 运行环境:Win9X/ WinME/ WinNT/ Win2K/ WinXP
💻 C
📖 第 1 页 / 共 4 页
字号:
/**************************************************             PCRE testing program               **************************************************//* This program was hacked up as a tester for PCRE. I really should havewritten it more tidily in the first place. Will I ever learn? It has grown andbeen extended and consequently is now rather, er, *very* untidy in places.-----------------------------------------------------------------------------Redistribution and use in source and binary forms, with or withoutmodification, are permitted provided that the following conditions are met:    * Redistributions of source code must retain the above copyright notice,      this list of conditions and the following disclaimer.    * Redistributions in binary form must reproduce the above copyright      notice, this list of conditions and the following disclaimer in the      documentation and/or other materials provided with the distribution.    * Neither the name of the University of Cambridge nor the names of its      contributors may be used to endorse or promote products derived from      this software without specific prior written permission.THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THEIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSEARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BELIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, ORCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OFSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESSINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER INCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THEPOSSIBILITY OF SUCH DAMAGE.-----------------------------------------------------------------------------*/#include <ctype.h>#include <stdio.h>#include <string.h>#include <stdlib.h>#include <time.h>#include <locale.h>#include <errno.h>#define PCRE_SPY        /* For Win32 build, import data, not export *//* We include pcre_internal.h because we need the internal info for displayingthe results of pcre_study() and we also need to know about the internalmacros, structures, and other internal data values; pcretest has "insideinformation" compared to a program that strictly follows the PCRE API. */#include "pcre_internal.h"/* We need access to the data tables that PCRE uses. So as not to have to keeptwo copies, we include the source file here, changing the names of the externalsymbols to prevent clashes. */#define _pcre_utf8_table1      utf8_table1#define _pcre_utf8_table1_size utf8_table1_size#define _pcre_utf8_table2      utf8_table2#define _pcre_utf8_table3      utf8_table3#define _pcre_utf8_table4      utf8_table4#define _pcre_utt              utt#define _pcre_utt_size         utt_size#define _pcre_OP_lengths       OP_lengths#include "pcre_tables.c"/* We also need the pcre_printint() function for printing out compiledpatterns. This function is in a separate file so that it can be included inpcre_compile.c when that module is compiled with debugging enabled. */#include "pcre_printint.src"/* It is possible to compile this test program without including support fortesting the POSIX interface, though this is not available via the standardMakefile. */#if !defined NOPOSIX#include "pcreposix.h"#endif/* It is also possible, for the benefit of the version imported into Exim, tobuild pcretest without support for UTF8 (define NOUTF8), without the interfaceto the DFA matcher (NODFA), and without the doublecheck of the old "info"function (define NOINFOCHECK). *//* Other parameters */#ifndef CLOCKS_PER_SEC#ifdef CLK_TCK#define CLOCKS_PER_SEC CLK_TCK#else#define CLOCKS_PER_SEC 100#endif#endif#define LOOPREPEAT 500000#define BUFFER_SIZE 30000#define PBUFFER_SIZE BUFFER_SIZE#define DBUFFER_SIZE BUFFER_SIZE/* Static variables */static FILE *outfile;static int log_store = 0;static int callout_count;static int callout_extra;static int callout_fail_count;static int callout_fail_id;static int first_callout;static int show_malloc;static int use_utf8;static size_t gotten_store;static uschar *pbuffer = NULL;/**************************************************          Read number from string               **************************************************//* We don't use strtoul() because SunOS4 doesn't have it. Rather than messaround with conditional compilation, just do the job by hand. It is only usedfor unpicking the -o argument, so just keep it simple.Arguments:  str           string to be converted  endptr        where to put the end pointerReturns:        the unsigned long*/static intget_value(unsigned char *str, unsigned char **endptr){int result = 0;while(*str != 0 && isspace(*str)) str++;while (isdigit(*str)) result = result * 10 + (int)(*str++ - '0');*endptr = str;return(result);}/**************************************************            Convert UTF-8 string to value       **************************************************//* This function takes one or more bytes that represents a UTF-8 character,and returns the value of the character.Argument:  buffer   a pointer to the byte vector  vptr     a pointer to an int to receive the valueReturns:   >  0 => the number of bytes consumed           -6 to 0 => malformed UTF-8 character at offset = (-return)*/#if !defined NOUTF8static intutf82ord(unsigned char *buffer, int *vptr){int c = *buffer++;int d = c;int i, j, s;for (i = -1; i < 6; i++)               /* i is number of additional bytes */  {  if ((d & 0x80) == 0) break;  d <<= 1;  }if (i == -1) { *vptr = c; return 1; }  /* ascii character */if (i == 0 || i == 6) return 0;        /* invalid UTF-8 *//* i now has a value in the range 1-5 */s = 6*i;d = (c & utf8_table3[i]) << s;for (j = 0; j < i; j++)  {  c = *buffer++;  if ((c & 0xc0) != 0x80) return -(j+1);  s -= 6;  d |= (c & 0x3f) << s;  }/* Check that encoding was the correct unique one */for (j = 0; j < utf8_table1_size; j++)  if (d <= utf8_table1[j]) break;if (j != i) return -(i+1);/* Valid value */*vptr = d;return i+1;}#endif/**************************************************       Convert character value to UTF-8         **************************************************//* This function takes an integer value in the range 0 - 0x7fffffffand encodes it as a UTF-8 character in 0 to 6 bytes.Arguments:  cvalue     the character value  buffer     pointer to buffer for result - at least 6 bytes longReturns:     number of characters placed in the buffer*/static intord2utf8(int cvalue, uschar *buffer){register int i, j;for (i = 0; i < utf8_table1_size; i++)  if (cvalue <= utf8_table1[i]) break;buffer += i;for (j = i; j > 0; j--) { *buffer-- = 0x80 | (cvalue & 0x3f); cvalue >>= 6; }*buffer = utf8_table2[i] | cvalue;return i + 1;}/**************************************************             Print character string             **************************************************//* Character string printing function. Must handle UTF-8 strings in utf8mode. Yields number of characters printed. If handed a NULL file, just countschars without printing. */static int pchars(unsigned char *p, int length, FILE *f){int c = 0;int yield = 0;while (length-- > 0)  {#if !defined NOUTF8  if (use_utf8)    {    int rc = utf82ord(p, &c);    if (rc > 0 && rc <= length + 1)   /* Mustn't run over the end */      {      length -= rc - 1;      p += rc;      if (c < 256 && isprint(c))        {        if (f != NULL) fprintf(f, "%c", c);        yield++;        }      else        {        int n;        if (f != NULL) fprintf(f, "\\x{%02x}%n", c, &n);        yield += n;        }      continue;      }    }#endif   /* Not UTF-8, or malformed UTF-8  */  if (isprint(c = *(p++)))    {    if (f != NULL) fprintf(f, "%c", c);    yield++;    }  else    {    if (f != NULL) fprintf(f, "\\x%02x", c);    yield += 4;    }  }return yield;}/**************************************************              Callout function                  **************************************************//* Called from PCRE as a result of the (?C) item. We print out where we are inthe match. Yield zero unless more callouts than the fail count, or the calloutdata is not zero. */static int callout(pcre_callout_block *cb){FILE *f = (first_callout | callout_extra)? outfile : NULL;int i, pre_start, post_start, subject_length;if (callout_extra)  {  fprintf(f, "Callout %d: last capture = %d\n",    cb->callout_number, cb->capture_last);  for (i = 0; i < cb->capture_top * 2; i += 2)    {    if (cb->offset_vector[i] < 0)      fprintf(f, "%2d: <unset>\n", i/2);    else      {      fprintf(f, "%2d: ", i/2);      (void)pchars((unsigned char *)cb->subject + cb->offset_vector[i],        cb->offset_vector[i+1] - cb->offset_vector[i], f);      fprintf(f, "\n");      }    }  }/* Re-print the subject in canonical form, the first time or if giving fulldatails. On subsequent calls in the same match, we use pchars just to find theprinted lengths of the substrings. */if (f != NULL) fprintf(f, "--->");pre_start = pchars((unsigned char *)cb->subject, cb->start_match, f);post_start = pchars((unsigned char *)(cb->subject + cb->start_match),  cb->current_position - cb->start_match, f);subject_length = pchars((unsigned char *)cb->subject, cb->subject_length, NULL);(void)pchars((unsigned char *)(cb->subject + cb->current_position),  cb->subject_length - cb->current_position, f);if (f != NULL) fprintf(f, "\n");/* Always print appropriate indicators, with callout number if not alreadyshown. For automatic callouts, show the pattern offset. */if (cb->callout_number == 255)  {  fprintf(outfile, "%+3d ", cb->pattern_position);  if (cb->pattern_position > 99) fprintf(outfile, "\n    ");  }else  {  if (callout_extra) fprintf(outfile, "    ");    else fprintf(outfile, "%3d ", cb->callout_number);  }for (i = 0; i < pre_start; i++) fprintf(outfile, " ");fprintf(outfile, "^");if (post_start > 0)  {  for (i = 0; i < post_start - 1; i++) fprintf(outfile, " ");  fprintf(outfile, "^");  }for (i = 0; i < subject_length - pre_start - post_start + 4; i++)  fprintf(outfile, " ");fprintf(outfile, "%.*s", (cb->next_item_length == 0)? 1 : cb->next_item_length,  pbuffer + cb->pattern_position);fprintf(outfile, "\n");first_callout = 0;if (cb->callout_data != NULL)  {  int callout_data = *((int *)(cb->callout_data));  if (callout_data != 0)    {    fprintf(outfile, "Callout data = %d\n", callout_data);    return callout_data;    }  }return (cb->callout_number != callout_fail_id)? 0 :       (++callout_count >= callout_fail_count)? 1 : 0;}/**************************************************            Local malloc functions              **************************************************//* Alternative malloc function, to test functionality and show the size of thecompiled re. */static void *new_malloc(size_t size){void *block = malloc(size);gotten_store = size;if (show_malloc)  fprintf(outfile, "malloc       %3d %p\n", (int)size, block);return block;}static void new_free(void *block){if (show_malloc)  fprintf(outfile, "free             %p\n", block);free(block);}/* For recursion malloc/free, to test stacking calls */static void *stack_malloc(size_t size){void *block = malloc(size);if (show_malloc)  fprintf(outfile, "stack_malloc %3d %p\n", (int)size, block);return block;}static void stack_free(void *block){if (show_malloc)  fprintf(outfile, "stack_free       %p\n", block);free(block);}/**************************************************          Call pcre_fullinfo()                  **************************************************//* Get one piece of information from the pcre_fullinfo() function */static void new_info(pcre *re, pcre_extra *study, int option, void *ptr){int rc;if ((rc = pcre_fullinfo(re, study, option, ptr)) < 0)  fprintf(outfile, "Error %d from pcre_fullinfo(%d)\n", rc, option);}/**************************************************         Byte flipping function                 **************************************************/static long intbyteflip(long int value, int n){if (n == 2) return ((value & 0x00ff) << 8) | ((value & 0xff00) >> 8);return ((value & 0x000000ff) << 24) |       ((value & 0x0000ff00) <<  8) |       ((value & 0x00ff0000) >>  8) |       ((value & 0xff000000) >> 24);}/**************************************************        Check match or recursion limit          **************************************************/static intcheck_match_limit(pcre *re, pcre_extra *extra, uschar *bptr, int len,  int start_offset, int options, int *use_offsets, int use_size_offsets,  int flag, unsigned long int *limit, int errnumber, const char *msg){int count;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -