summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--!compile.txt20
-rw-r--r--!linklib.txt20
-rw-r--r--ChangeLog5
-rw-r--r--NON-UNIX-USE16
-rw-r--r--README26
-rw-r--r--makevp.bat30
-rw-r--r--pcre_internal.h2
-rw-r--r--pcregexp.pas782
8 files changed, 875 insertions, 26 deletions
diff --git a/!compile.txt b/!compile.txt
new file mode 100644
index 0000000..6048517
--- /dev/null
+++ b/!compile.txt
@@ -0,0 +1,20 @@
+pcre_chartables.c
+pcre_compile.c
+pcre_config.c
+pcre_dfa_exec.c
+pcre_exec.c
+pcre_fullinfo.c
+pcre_get.c
+pcre_globals.c
+pcre_info.c
+pcre_maketables.c
+pcre_newline.c
+pcre_ord2utf8.c
+pcre_refcount.c
+pcre_study.c
+pcre_tables.c
+pcre_try_flipped.c
+pcre_ucp_searchfuncs.c
+pcre_valid_utf8.c
+pcre_version.c
+pcre_xclass.c
diff --git a/!linklib.txt b/!linklib.txt
new file mode 100644
index 0000000..cd02aa5
--- /dev/null
+++ b/!linklib.txt
@@ -0,0 +1,20 @@
++pcre_chartables.obj &
++pcre_compile.obj &
++pcre_config.obj &
++pcre_dfa_exec.obj &
++pcre_exec.obj &
++pcre_fullinfo.obj &
++pcre_get.obj &
++pcre_globals.obj &
++pcre_info.obj &
++pcre_maketables.obj &
++pcre_newline.obj &
++pcre_ord2utf8.obj &
++pcre_refcount.obj &
++pcre_study.obj &
++pcre_tables.obj &
++pcre_try_flipped.obj &
++pcre_ucp_searchfuncs.obj &
++pcre_valid_utf8.obj &
++pcre_version.obj &
++pcre_xclass.obj
diff --git a/ChangeLog b/ChangeLog
index b32c837..7973d8a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -29,6 +29,11 @@ Version 7.1 05-Mar-07
arranged for config.h to be included in the distribution, for the benefit
of those who have to compile without Autotools (compare pcre.h).
+ 5. Updated the support (such as it is) for Virtual Pascal, thanks to Stefan
+ Weber: (1) pcre_internal.h was missing some function renames; (2) updated
+ makevp.bat for the current PCRE, using the additional files !compile.txt,
+ !linklib.txt, and pcregexp.pas.
+
Version 7.0 19-Dec-06
---------------------
diff --git a/NON-UNIX-USE b/NON-UNIX-USE
index bcc0dc9..6ac4ce8 100644
--- a/NON-UNIX-USE
+++ b/NON-UNIX-USE
@@ -1,11 +1,13 @@
Compiling PCRE on non-Unix systems
----------------------------------
-See below for comments on Cygwin or MinGW and OpenVMS usage. I (Philip Hazel)
-have no knowledge of Windows or VMS sytems and how their libraries work. The
-items in the PCRE Makefile that relate to anything other than Unix-like systems
-have been contributed by PCRE users. There are some other comments and files in
-the Contrib directory on the ftp site that you may find useful. See
+I (Philip Hazel) have no knowledge of Windows or VMS sytems and how their
+libraries work. The items in the PCRE distribution and Makefile that relate to
+anything other than Unix-like systems have been contributed by PCRE users and
+are untested by me.
+
+There are some other comments and files in the Contrib directory on the ftp
+site that you may find useful. See
ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/Contrib
@@ -136,6 +138,10 @@ If you have a system without "configure" but where you can use a Makefile, edit
Makefile.in to create Makefile, substituting suitable values for the variables
at the head of the file.
+Stefan Weber contributed the following files in the distribution for building
+PCRE for use with VP/Borland: !compile.txt, !linklib.txt, makevp.bat,
+pcregexp.pas.
+
Michael Roy sent these comments about building PCRE under Windows with BCC5.5:
Some of the core BCC libraries have a version of PCRE from 1998 built in,
diff --git a/README b/README
index 1a86dee..0b942ee 100644
--- a/README
+++ b/README
@@ -65,6 +65,19 @@ Windows systems (I myself do not use Windows). Some are complete in themselves;
others are pointers to URLs containing relevant files.
+Building on non-Unix systems
+----------------------------
+
+For a non-Unix system, read the comments in the file NON-UNIX-USE, though if
+the system supports the use of "configure" and "make" you may be able to build
+PCRE in the same way as for Unix systems.
+
+PCRE has been compiled on Windows systems and on Macintoshes, but I don't know
+the details because I don't use those systems. It should be straightforward to
+build PCRE on any system that has a Standard C compiler and library, because it
+uses only Standard C functions.
+
+
Building PCRE on a Unix-like system
-----------------------------------
@@ -302,19 +315,6 @@ running the "configure" script:
CXXLDFLAGS="-lstd_v2 -lCsup_v2"
-Building on non-Unix systems
-----------------------------
-
-For a non-Unix system, read the comments in the file NON-UNIX-USE, though if
-the system supports the use of "configure" and "make" you may be able to build
-PCRE in the same way as for Unix systems.
-
-PCRE has been compiled on Windows systems and on Macintoshes, but I don't know
-the details because I don't use those systems. It should be straightforward to
-build PCRE on any system that has a Standard C compiler and library, because it
-uses only Standard C functions.
-
-
Testing PCRE
------------
diff --git a/makevp.bat b/makevp.bat
index 10bd248..47ca388 100644
--- a/makevp.bat
+++ b/makevp.bat
@@ -1,24 +1,38 @@
@echo off
+:: AH 20-12-06 modified for new PCRE-7.0 and VP/BCC
+
REM This file was contributed by Alexander Tokarev for building PCRE for use
REM with Virtual Pascal. It has not been tested with the latest PCRE release.
REM CHANGE THIS FOR YOUR BORLAND C++ COMPILER PATH
-SET BORLAND=c:\usr\apps\bcc55
+SET BORLAND=F:\bcc
+SET PATH=%PATH%;%BORLAND%\bin;f:\tasm\bin
+SET PCRE_VER=70
-sh configure
+:: sh configure
-bcc32 -DDFTABLES -DSTATIC -DVPCOMPAT -I%BORLAND%\include -L%BORLAND%\lib dftables.c
+bcc32 -DDFTABLES -DSTATIC -I%BORLAND%\include -L%BORLAND%\lib dftables.c
+:: bcc32 -DDFTABLES -DSTATIC -DVPCOMPAT -I%BORLAND%\include -L%BORLAND%\lib dftables.c
+IF ERRORLEVEL 1 EXIT
-dftables > chartables.c
+:: dftables > chartables.c
+dftables pcre_chartables.c
-bcc32 -c -RT- -y- -v- -u- -P- -O2 -5 -DSTATIC -DVPCOMPAT -UDFTABLES -I%BORLAND%\include get.c maketables.c pcre.c study.c
+REM compile and link the PCRE library into lib: option -B for ASM compile works too
+bcc32 -a4 -c -RT- -y- -v- -u- -R- -Q- -X -d -fp -ff -P- -O2 -Oc -Ov -3 -w-8004 -w-8064 -w-8065 -w-8012 -DSTATIC -DVPCOMPAT -UDFTABLES -I%BORLAND%\include @!compile.txt
+:: bcc32 -c -RT- -y- -v- -u- -P- -O2 -5 -DSTATIC -DVPCOMPAT -UDFTABLES -I%BORLAND%\include get.c maketables.c pcre.c study.c
+IF ERRORLEVEL 1 EXIT
-tlib %BORLAND%\lib\cw32.lib *calloc *del *strncmp *memcpy *memmove *memset
-tlib pcre.lib +get.obj +maketables.obj +pcre.obj +study.obj +calloc.obj +del.obj +strncmp.obj +memcpy.obj +memmove.obj +memset.obj
+tlib %BORLAND%\lib\cw32.lib *calloc *del *strncmp *memcpy *memmove *memset *memcmp *strlen
+:: tlib %BORLAND%\lib\cw32.lib *calloc *del *strncmp *memcpy *memmove *memset
+IF ERRORLEVEL 1 EXIT
+tlib pcre%PCRE_VER%.lib @!linklib.txt +calloc.obj +del.obj +strncmp.obj +memcpy.obj +memmove.obj +memset.obj +memcmp.obj +strlen.obj
+:: tlib pcre.lib +get.obj +maketables.obj +pcre.obj +study.obj +calloc.obj +del.obj +strncmp.obj +memcpy.obj +memmove.obj +memset.obj
+IF ERRORLEVEL 1 EXIT
-del *.obj *.exe *.tds *.bak >nul 2>nul
+del *.obj *.tds *.bak >nul 2>nul
echo ---
echo Now the library should be complete. Please check all messages above.
diff --git a/pcre_internal.h b/pcre_internal.h
index 47fa59a..b534894 100644
--- a/pcre_internal.h
+++ b/pcre_internal.h
@@ -189,7 +189,9 @@ need to have their names changed. PCRE must be compiled with the -DVPCOMPAT
option on the command line. */
#ifdef VPCOMPAT
+#define strlen(s) _strlen(s)
#define strncmp(s1,s2,m) _strncmp(s1,s2,m)
+#define memcmp(s,c,n) _memcmp(s,c,n)
#define memcpy(d,s,n) _memcpy(d,s,n)
#define memmove(d,s,n) _memmove(d,s,n)
#define memset(s,c,n) _memset(s,c,n)
diff --git a/pcregexp.pas b/pcregexp.pas
new file mode 100644
index 0000000..b678961
--- /dev/null
+++ b/pcregexp.pas
@@ -0,0 +1,782 @@
+{
+ pcRegExp - Perl compatible regular expressions for Virtual Pascal
+ (c) 2001 Peter S. Voronov aka Chem O'Dun <petervrn@yahoo.com>
+
+ Based on PCRE library interface unit for Virtual Pascal.
+ (c) 2001 Alexander Tokarev <dwalin@dwalin.ru>
+
+ The current PCRE version is: 3.7
+
+ This software must be distributed as Freeware.
+
+ The PCRE library is written by: Philip Hazel <ph10@cam.ac.uk>
+ Copyright (c) 1997-2004 University of Cambridge
+
+ AngelsHolocaust 4-11-04 updated to use version v5.0
+ (INFO: this is regex-directed, NFA)
+ AH: 9-11-04 - pcre_free: removed var, pcre already gives the ptr, now
+ everything works as it should (no more crashes)
+ -> removed CheckRegExp because pcre handles errors perfectly
+ 10-11-04 - added pcError (errorhandling), pcInit
+ 13-11-04 - removed the ErrorPos = 0 check -> always print erroroffset
+ 17-10-05 - support for \1-\9 backreferences in TpcRegExp.GetReplStr
+ 17-02-06 - added RunTimeOptions: caller can set options while searching
+ 19-02-06 - added SearchOfs(): let PCRE use the complete string and offset
+ into the string itself
+ 20-12-06 - support for version 7.0
+}
+
+{$H+} {$DEFINE PCRE_3_7} {$DEFINE PCRE_5_0} {$DEFINE PCRE_7_0}
+
+Unit pcregexp;
+
+Interface
+
+uses objects;
+
+Type
+ PpcRegExp = ^TpcRegExp;
+// TpcRegExp = object
+ TpcRegExp = object(TObject)
+ MatchesCount: integer;
+ RegExpC, RegExpExt : Pointer;
+ Matches:Pointer;
+ RegExp: shortstring;
+ SourceLen: integer;
+ PartialMatch : boolean;
+ Error : boolean;
+ ErrorMsg : Pchar;
+ ErrorPos : integer;
+ RunTimeOptions: Integer; // options which can be set by the caller
+ constructor Init(const ARegExp : shortstring; AOptions : integer; ALocale : Pointer);
+ function Search(AStr: Pchar; ALen : longint) : boolean; virtual;
+ function SearchNext( AStr: Pchar; ALen : longint) : boolean; virtual;
+ function SearchOfs ( AStr: Pchar; ALen, AOfs : longint) : boolean; virtual;
+ function MatchSub(ANom: integer; var Pos, Len : longint) : boolean; virtual;
+ function MatchFull(var Pos, Len : longint) : boolean; virtual;
+ function GetSubStr(ANom: integer; AStr: Pchar) : string; virtual;
+ function GetFullStr(AStr: Pchar) : string; virtual;
+ function GetReplStr(AStr: Pchar; const ARepl: string) : string; virtual;
+ function GetPreSubStr(AStr: Pchar) : string; virtual;
+ function GetPostSubStr(AStr: Pchar) : string; virtual;
+ function ErrorStr : string; virtual;
+ destructor Done; virtual;
+ end;
+
+ function pcGrepMatch(WildCard, aStr: string; AOptions:integer; ALocale : Pointer): Boolean;
+ function pcGrepSub(WildCard, aStr, aRepl: string; AOptions:integer; ALocale : Pointer): string;
+
+ function pcFastGrepMatch(WildCard, aStr: string): Boolean;
+ function pcFastGrepSub(WildCard, aStr, aRepl: string): string;
+
+{$IFDEF PCRE_5_0}
+ function pcGetVersion : pchar;
+{$ENDIF}
+
+ function pcError (var pRegExp : Pointer) : Boolean;
+ function pcInit (const Pattern: Shortstring; CaseSens: Boolean) : Pointer;
+
+Const { Options }
+ PCRE_CASELESS = $0001;
+ PCRE_MULTILINE = $0002;
+ PCRE_DOTALL = $0004;
+ PCRE_EXTENDED = $0008;
+ PCRE_ANCHORED = $0010;
+ PCRE_DOLLAR_ENDONLY = $0020;
+ PCRE_EXTRA = $0040;
+ PCRE_NOTBOL = $0080;
+ PCRE_NOTEOL = $0100;
+ PCRE_UNGREEDY = $0200;
+ PCRE_NOTEMPTY = $0400;
+{$IFDEF PCRE_5_0}
+ PCRE_UTF8 = $0800;
+ PCRE_NO_AUTO_CAPTURE = $1000;
+ PCRE_NO_UTF8_CHECK = $2000;
+ PCRE_AUTO_CALLOUT = $4000;
+ PCRE_PARTIAL = $8000;
+{$ENDIF}
+{$IFDEF PCRE_7_0}
+ PCRE_DFA_SHORTEST = $00010000;
+ PCRE_DFA_RESTART = $00020000;
+ PCRE_FIRSTLINE = $00040000;
+ PCRE_DUPNAMES = $00080000;
+ PCRE_NEWLINE_CR = $00100000;
+ PCRE_NEWLINE_LF = $00200000;
+ PCRE_NEWLINE_CRLF = $00300000;
+ PCRE_NEWLINE_ANY = $00400000;
+{$ENDIF}
+
+ PCRE_COMPILE_ALLOWED_OPTIONS = PCRE_ANCHORED + PCRE_AUTO_CALLOUT + PCRE_CASELESS +
+ PCRE_DOLLAR_ENDONLY + PCRE_DOTALL + PCRE_EXTENDED +
+ PCRE_EXTRA + PCRE_MULTILINE + PCRE_NO_AUTO_CAPTURE +
+ PCRE_UNGREEDY + PCRE_UTF8 + PCRE_NO_UTF8_CHECK
+ {$IFDEF PCRE_7_0}
+ + PCRE_DUPNAMES + PCRE_FIRSTLINE + PCRE_NEWLINE_CRLF
+ + PCRE_NEWLINE_ANY
+ {$ENDIF}
+ ;
+
+ PCRE_EXEC_ALLOWED_OPTIONS = PCRE_ANCHORED + PCRE_NOTBOL + PCRE_NOTEOL +
+ PCRE_NOTEMPTY + PCRE_NO_UTF8_CHECK + PCRE_PARTIAL
+ {$IFDEF PCRE_7_0}
+ + PCRE_NEWLINE_CRLF + PCRE_NEWLINE_ANY
+ {$ENDIF}
+ ;
+
+{$IFDEF PCRE_7_0}
+ PCRE_DFA_EXEC_ALLOWED_OPTIONS = PCRE_ANCHORED + PCRE_NOTBOL + PCRE_NOTEOL +
+ PCRE_NOTEMPTY + PCRE_NO_UTF8_CHECK + PCRE_PARTIAL +
+ PCRE_DFA_SHORTEST + PCRE_DFA_RESTART +
+ PCRE_NEWLINE_CR + PCRE_NEWLINE_LF + PCRE_NEWLINE_CRLF +
+ PCRE_NEWLINE_ANY;
+{$ENDIF}
+
+{ Exec-time and get/set-time error codes }
+ PCRE_ERROR_NOMATCH = -1;
+ PCRE_ERROR_NULL = -2;
+ PCRE_ERROR_BADOPTION = -3;
+ PCRE_ERROR_BADMAGIC = -4;
+ PCRE_ERROR_UNKNOWN_MODE = -5;
+ PCRE_ERROR_NOMEMORY = -6;
+ PCRE_ERROR_NOSUBSTRING = -7;
+{$IFDEF PCRE_5_0}
+ PCRE_ERROR_MATCHLIMIT = -8;
+ PCRE_ERROR_CALLOUT = -9; { Never used by PCRE itself }
+ PCRE_ERROR_BADUTF8 = -10;
+ PCRE_ERROR_BADUTF8_OFFSET = -11;
+ PCRE_ERROR_PARTIAL = -12;
+ PCRE_ERROR_BADPARTIAL = -13;
+ PCRE_ERROR_INTERNAL = -14;
+ PCRE_ERROR_BADCOUNT = -15;
+{$ENDIF}
+{$IFDEF PCRE_7_0}
+ PCRE_ERROR_DFA_UITEM = -16;
+ PCRE_ERROR_DFA_UCOND = -17;
+ PCRE_ERROR_DFA_UMLIMIT = -18;
+ PCRE_ERROR_DFA_WSSIZE = -19;
+ PCRE_ERROR_DFA_RECURSE = -20;
+ PCRE_ERROR_RECURSIONLIMIT = -21;
+ PCRE_ERROR_NULLWSLIMIT = -22;
+ PCRE_ERROR_BADNEWLINE = -23;
+{$ENDIF}
+
+{ Request types for pcre_fullinfo() }
+
+ PCRE_INFO_OPTIONS = 0;
+ PCRE_INFO_SIZE = 1;
+ PCRE_INFO_CAPTURECOUNT = 2;
+ PCRE_INFO_BACKREFMAX = 3;
+ PCRE_INFO_FIRSTBYTE = 4;
+ PCRE_INFO_FIRSTCHAR = 4; { For backwards compatibility }
+ PCRE_INFO_FIRSTTABLE = 5;
+{$IFDEF PCRE_5_0}
+ PCRE_INFO_LASTLITERAL = 6;
+ PCRE_INFO_NAMEENTRYSIZE = 7;
+ PCRE_INFO_NAMECOUNT = 8;
+ PCRE_INFO_NAMETABLE = 9;
+ PCRE_INFO_STUDYSIZE = 10;
+ PCRE_INFO_DEFAULT_TABLES = 11;
+{$ENDIF PCRE_5_0}
+
+{ Request types for pcre_config() }
+{$IFDEF PCRE_5_0}
+ PCRE_CONFIG_UTF8 = 0;
+ PCRE_CONFIG_NEWLINE = 1;
+ PCRE_CONFIG_LINK_SIZE = 2;
+ PCRE_CONFIG_POSIX_MALLOC_THRESHOLD = 3;
+ PCRE_CONFIG_MATCH_LIMIT = 4;
+ PCRE_CONFIG_STACKRECURSE = 5;
+ PCRE_CONFIG_UNICODE_PROPERTIES = 6;
+{$ENDIF PCRE_5_0}
+{$IFDEF PCRE_7_0}
+ PCRE_CONFIG_MATCH_LIMIT_RECURSION = 7;
+{$ENDIF}
+
+{ Bit flags for the pcre_extra structure }
+{$IFDEF PCRE_5_0}
+ PCRE_EXTRA_STUDY_DATA = $0001;
+ PCRE_EXTRA_MATCH_LIMIT = $0002;
+ PCRE_EXTRA_CALLOUT_DATA = $0004;
+ PCRE_EXTRA_TABLES = $0008;
+{$ENDIF PCRE_5_0}
+{$IFDEF PCRE_7_0}
+ PCRE_EXTRA_MATCH_LIMIT_RECURSION = $0010;
+{$ENDIF}
+
+Const
+// DefaultOptions : integer = 0;
+ DefaultLocaleTable : pointer = nil;
+
+{$IFDEF PCRE_5_0}
+{ The structure for passing additional data to pcre_exec(). This is defined in
+such as way as to be extensible. Always add new fields at the end, in order to
+remain compatible. }
+
+type ppcre_extra = ^tpcre_extra;
+ tpcre_extra = record
+ flags : longint; { Bits for which fields are set }
+ study_data : pointer; { Opaque data from pcre_study() }
+ match_limit : longint; { Maximum number of calls to match() }
+ callout_data : pointer; { Data passed back in callouts }
+ tables : pointer; { Pointer to character tables }
+ match_limit_recursion: longint; { Max recursive calls to match() }
+ end;
+
+type ppcre_callout_block = ^pcre_callout_block;
+ pcre_callout_block = record
+ version,
+ (* ------------------------ Version 0 ------------------------------- *)
+ callout_number : integer;
+ offset_vector : pointer;
+ subject : pchar;
+ subject_length, start_match, current_position, capture_top,
+ capture_last : integer;
+ callout_data : pointer;
+ (* ------------------- Added for Version 1 -------------------------- *)
+ pattern_position, next_item_length : integer;
+ end;
+{$ENDIF PCRE_5_0}
+
+{$OrgName+}
+{$IFDEF VIRTUALPASCAL} {&Cdecl+} {$ENDIF VIRTUALPASCAL}
+
+ { local replacement of external pcre memory management functions }
+ function pcre_malloc( size : integer ) : pointer;
+ procedure pcre_free( {var} p : pointer );
+{$IFDEF PCRE_5_0}
+ const pcre_stack_malloc: function ( size : integer ): pointer = pcre_malloc;
+ pcre_stack_free: procedure ( {var} p : pointer ) = pcre_free;
+ function pcre_callout(var p : ppcre_callout_block) : integer;
+{$ENDIF PCRE_5_0}
+{$IFDEF VIRTUALPASCAL} {&Cdecl-} {$ENDIF VIRTUALPASCAL}
+
+Implementation
+
+Uses strings, collect, messages, dnapp, commands, advance0, stringsx
+ {$IFDEF VIRTUALPASCAL} ,vpsyslow {$ENDIF VIRTUALPASCAL};
+
+Const
+ MAGIC_NUMBER = $50435245; { 'PCRE' }
+ MAX_MATCHES = 90; { changed in 3.5 version; should be divisible by 3, was 64}
+
+Type
+ PMatchArray = ^TMatchArray;
+ TMatchArray = array[0..( MAX_MATCHES * 3 )] of integer;
+
+ PRegExpCollection = ^TRegExpCollection;
+ TRegExpCollection = object(TSortedCollection)
+ MaxRegExp : integer;
+ SearchRegExp : shortstring;
+ CompareModeInsert : boolean;
+ constructor Init(AMaxRegExp:integer);
+ procedure FreeItem(P: Pointer); virtual;
+ function Compare(P1, P2: Pointer): Integer; virtual;
+ function Find(ARegExp:shortstring;var P: PpcRegExp):boolean; virtual;
+ function CheckNew(ARegExp:shortstring):PpcRegExp;virtual;
+ end;
+
+Var
+ PRegExpCache : PRegExpCollection;
+
+
+{$IFDEF VIRTUALPASCAL} {&Cdecl+} {$ENDIF VIRTUALPASCAL}
+
+ { imported original pcre functions }
+
+ function pcre_compile( const pattern : PChar; options : integer;
+ var errorptr : PChar; var erroroffset : integer;
+ const tables : PChar ) : pointer {pcre}; external;
+{$IFDEF PCRE_7_0}
+ function pcre_compile2( const pattern : PChar; options : integer;
+ var errorcodeptr : Integer;
+ var errorptr : PChar; var erroroffset : integer;
+ const tables : PChar ) : pointer {pcre}; external;
+{$ENDIF}
+{$IFDEF PCRE_5_0}
+ function pcre_config( what : integer; where : pointer) : integer; external;
+ function pcre_copy_named_substring( const code : pointer {pcre};
+ const subject : pchar;
+ var ovector : integer;
+ stringcount : integer;
+ const stringname : pchar;
+ var buffer : pchar;
+ size : integer) : integer; external;
+ function pcre_copy_substring( const subject : pchar; var ovector : integer;
+ stringcount, stringnumber : integer;
+ var buffer : pchar; size : integer )
+ : integer; external;
+ function pcre_exec( const argument_re : pointer {pcre};
+ const extra_data : pointer {pcre_extra};
+{$ELSE}
+ function pcre_exec( const external_re : pointer;
+ const external_extra : pointer;
+{$ENDIF}
+ const subject : PChar;
+ length, start_offset, options : integer;
+ offsets : pointer;
+ offsetcount : integer ) : integer; external;
+{$IFDEF PCRE_7_0}
+ function pcre_dfa_exec( const argument_re : pointer {pcre};
+ const extra_data : pointer {pcre_extra};
+ const subject : pchar;
+ length, start_offset, options : integer;
+ offsets : pointer;
+ offsetcount : integer;
+ workspace : pointer;
+ wscount : integer ) : integer; external;
+{$ENDIF}
+{$IFDEF PCRE_5_0}
+ procedure pcre_free_substring( const p : pchar ); external;
+ procedure pcre_free_substring_list( var p : pchar ); external;
+ function pcre_fullinfo( const argument_re : pointer {pcre};
+ const extra_data : pointer {pcre_extra};
+ what : integer;
+ where : pointer ) : integer; external;
+ function pcre_get_named_substring( const code : pointer {pcre};
+ const subject : pchar;
+ var ovector : integer;
+ stringcount : integer;
+ const stringname : pchar;
+ var stringptr : pchar ) : integer; external;
+ function pcre_get_stringnumber( const code : pointer {pcre};
+ const stringname : pchar ) : integer; external;
+ function pcre_get_stringtable_entries( const code : pointer {pcre};
+ const stringname : pchar;
+ var firstptr,
+ lastptr : pchar ) : integer; external;
+ function pcre_get_substring( const subject : pchar; var ovector : integer;
+ stringcount, stringnumber : integer;
+ var stringptr : pchar ) : integer; external;
+ function pcre_get_substring_list( const subject : pchar; var ovector : integer;
+ stringcount : integer;
+ listptr : pointer {const char ***listptr}) : integer; external;
+ function pcre_info( const argument_re : pointer {pcre};
+ var optptr : integer;
+ var first_byte : integer ) : integer; external;
+ function pcre_maketables : pchar; external;
+{$ENDIF}
+{$IFDEF PCRE_7_0}
+ function pcre_refcount( const argument_re : pointer {pcre};
+ adjust : integer ) : pchar; external;
+{$ENDIF}
+ function pcre_study( const external_re : pointer {pcre};
+ options : integer;
+ var errorptr : PChar ) : pointer {pcre_extra}; external;
+{$IFDEF PCRE_5_0}
+ function pcre_version : pchar; external;
+{$ENDIF}
+
+ function pcre_malloc( size : integer ) : pointer;
+ begin
+ GetMem( result, size );
+ end;
+
+ procedure pcre_free( {var} p : pointer );
+ begin
+ if (p <> nil) then
+ FreeMem( p, 0 );
+ {@p := nil;}
+ end;
+
+{$IFDEF PCRE_5_0}
+(* Called from PCRE as a result of the (?C) item. We print out where we are in
+the match. Yield zero unless more callouts than the fail count, or the callout
+data is not zero. *)
+
+ function pcre_callout;
+ begin
+ end;
+{$ENDIF}
+
+{$IFDEF VIRTUALPASCAL} {&Cdecl-} {$ENDIF VIRTUALPASCAL}
+
+// Always include the newest version of the library
+{$IFDEF PCRE_3_7} {$IFNDEF PCRE_5_0} {$IFNDEF PCRE_7_0} {$L pcre37.lib} {$ENDIF PCRE_7_0} {$ENDIF PCRE_5_0} {$ENDIF PCRE_3_7}
+{$IFDEF PCRE_5_0} {$IFNDEF PCRE_7_0} {$L pcre50.lib} {$ENDIF PCRE_7_0} {$ENDIF PCRE_5_0}
+{$IFDEF PCRE_7_0} {$L pcre70.lib} {$ENDIF PCRE_7_0}
+
+{TpcRegExp}
+
+ constructor TpcRegExp.Init(const ARegExp:shortstring; AOptions:integer; ALocale : Pointer);
+ var
+ pRegExp : PChar;
+ begin
+ RegExp:=ARegExp;
+ RegExpC:=nil;
+ RegExpExt:=nil;
+ Matches:=nil;
+ MatchesCount:=0;
+ Error:=true;
+ ErrorMsg:=nil;
+ ErrorPos:=0;
+ RunTimeOptions := 0;
+ if length(RegExp) < 255 then
+ begin
+ RegExp[length(RegExp)+1]:=#0;
+ pRegExp:=@RegExp[1];
+ end
+ else
+ begin
+ GetMem(pRegExp,length(RegExp)+1);
+ pRegExp:=strpcopy(pRegExp,RegExp);
+ end;
+ RegExpC := pcre_compile( pRegExp,
+ AOptions and PCRE_COMPILE_ALLOWED_OPTIONS,
+ ErrorMsg, ErrorPos, ALocale);
+ if length(RegExp) = 255 then
+ StrDispose(pRegExp);
+ if RegExpC = nil then
+ exit;
+ ErrorMsg:=nil;
+ RegExpExt := pcre_study( RegExpC, 0, ErrorMsg );
+ if (RegExpExt = nil) and (ErrorMsg <> nil) then
+ begin
+ pcre_free(RegExpC);
+ exit;
+ end;
+ GetMem(Matches,SizeOf(TMatchArray));
+ Error:=false;
+ end;
+
+ destructor TpcRegExp.Done;
+ begin
+ if RegExpC <> nil then
+ pcre_free(RegExpC);
+ if RegExpExt <> nil then
+ pcre_free(RegExpExt);
+ if Matches <> nil then
+ FreeMem(Matches,SizeOf(TMatchArray));
+ end;
+
+ function TpcRegExp.SearchNext( AStr: Pchar; ALen : longint ) : boolean;
+ var Options: Integer;
+ begin // must handle PCRE_ERROR_PARTIAL here
+ Options := (RunTimeOptions or startup.MiscMultiData.cfgRegEx.DefaultOptions) and
+ PCRE_EXEC_ALLOWED_OPTIONS;
+ if MatchesCount > 0 then
+ MatchesCount:=pcre_exec( RegExpC, RegExpExt, AStr, ALen, PMatchArray(Matches)^[1],
+ Options, Matches, MAX_MATCHES ) else
+ MatchesCount:=pcre_exec( RegExpC, RegExpExt, AStr, ALen, 0,
+ Options, Matches, MAX_MATCHES );
+{ if MatchesCount = 0 then
+ MatchesCount := MatchesCount div 3;}
+ PartialMatch := MatchesCount = PCRE_ERROR_PARTIAL;
+ SearchNext := MatchesCount > 0;
+ end;
+
+ function TpcRegExp.Search( AStr: Pchar; ALen : longint):boolean;
+ begin
+ MatchesCount:=0;
+ Search:=SearchNext(AStr,ALen);
+ SourceLen:=ALen;
+ end;
+
+ function TpcRegExp.SearchOfs( AStr: Pchar; ALen, AOfs: longint ) : boolean;
+ var Options: Integer;
+ begin
+ MatchesCount:=0;
+ Options := (RunTimeOptions or startup.MiscMultiData.cfgRegEx.DefaultOptions) and
+ PCRE_EXEC_ALLOWED_OPTIONS;
+ MatchesCount:=pcre_exec( RegExpC, RegExpExt, AStr, ALen, AOfs,
+ Options, Matches, MAX_MATCHES );
+ PartialMatch := MatchesCount = PCRE_ERROR_PARTIAL;
+ SearchOfs := MatchesCount > 0;
+ SourceLen := ALen-AOfs;
+ end;
+
+ function TpcRegExp.MatchSub(ANom:integer; var Pos,Len:longint):boolean;
+ begin
+ if (MatchesCount > 0) and (ANom <= (MatchesCount-1)) then
+ begin
+ ANom:=ANom*2;
+ Pos:=PMatchArray(Matches)^[ANom];
+ Len:=PMatchArray(Matches)^[ANom+1]-Pos;
+ MatchSub:=true;
+ end
+ else
+ MatchSub:=false;
+ end;
+
+ function TpcRegExp.MatchFull(var Pos,Len:longint):boolean;
+ begin
+ MatchFull:=MatchSub(0,Pos,Len);
+ end;
+
+ function TpcRegExp.GetSubStr(ANom: integer; AStr: Pchar):string;
+ var
+ s: ansistring;
+ pos,len: longint;
+ begin
+ s:='';
+ if MatchSub(ANom, pos, len) then
+ begin
+ setlength(s, len);
+ Move(AStr[pos], s[1], len);
+ end;
+ GetSubStr:=s;
+ end;
+
+ function TpcRegExp.GetPreSubStr(AStr: Pchar):string;
+ var
+ s: ansistring;
+ l: longint;
+ begin
+ s:='';
+ if (MatchesCount > 0) then
+ begin
+ l:=PMatchArray(Matches)^[0]-1;
+ if l > 0 then
+ begin
+ setlength(s,l);
+ Move(AStr[1],s[1],l);
+ end;
+ end;
+ GetPreSubStr:=s;
+ end;
+
+ function TpcRegExp.GetPostSubStr(AStr: Pchar):string;
+ var
+ s: ansistring;
+ l: longint;
+ ANom: integer;
+ begin
+ s:='';
+ if (MatchesCount > 0) then
+ begin
+ ANom:=(MatchesCount-1){*2} shl 1;
+ l:=SourceLen-PMatchArray(Matches)^[ANom+1]+1;
+ if l > 0 then
+ begin
+ setlength(s,l);
+ Move(AStr[PMatchArray(Matches)^[ANom+1]],s[1],l);
+ end;
+ end;
+ GetPostSubStr:=s;
+ end;
+
+
+ function TpcRegExp.GetFullStr(AStr: Pchar):string;
+ var
+ s: ansistring;
+ l: longint;
+ begin
+ GetFullStr:=GetSubStr(0,AStr);
+ end;
+
+ function TpcRegExp.GetReplStr(AStr: Pchar; const ARepl: string):string;
+ var
+ s: ansistring;
+ l,i,lasti: longint;
+ begin
+ l:=length(ARepl);
+ i:=1;
+ lasti:=1;
+ s:='';
+ while i <= l do
+ begin
+ case ARepl[i] of
+ '\' :
+ begin
+ if i < l then
+ begin
+ s:=s+copy(ARepl,lasti,i-lasti){+ARepl[i+1]};
+ {AH 17-10-05 support for POSIX \1-\9 backreferences}
+ case ARepl[i+1] of
+ '0' : s:=s+GetFullStr(AStr);
+ '1'..'9' : s:=s+GetSubStr(ord(ARepl[i+1])-ord('0'),AStr);
+ else s:=s+ARepl[i+1]; // copy the escaped character
+ end;
+ end;
+ inc(i);
+ lasti:=i+1;
+ end;
+ '$' :
+ begin
+ if i < l then
+ begin
+ s:=s+copy(ARepl,lasti,i-lasti);
+ case ARepl[i+1] of
+ '&' : s:=s+GetFullStr(AStr);
+ '1'..'9' : s:=s+GetSubStr(ord(ARepl[i+1])-ord('0'),AStr);
+ '`' : s:=s+GetPreSubStr(AStr);
+ #39 : s:=s+GetPostSubStr(AStr);
+ end;
+ end;
+ inc(i);
+ lasti:=i+1;
+ end;
+ end;
+ inc(i);
+ end;
+ if lasti <= {AH 25-10-2004 added =, else l==1 won't work} l then
+ s:=s+copy(ARepl,lasti,l-lasti+1);
+ GetReplStr:=s;
+ end;
+
+ function TpcRegExp.ErrorStr:string;
+ begin
+ ErrorStr:=StrPas(ErrorMsg);
+ end;
+
+{TRegExpCollection}
+
+constructor TRegExpCollection.Init(AMaxRegExp: integer);
+begin
+ Inherited Init(1,1);
+ MaxRegExp:=AMaxRegExp;
+ CompareModeInsert:=true;
+end;
+
+procedure TRegExpCollection.FreeItem(P: Pointer);
+begin
+ if P <> nil then
+ begin
+ Dispose(PpcRegExp(P),Done);
+ end;
+end;
+
+function TRegExpCollection.Compare(P1, P2: Pointer): Integer;
+//var
+// l,l1,l2,i : byte;
+//// wPos: pchar;
+begin
+ if CompareModeInsert then
+ begin
+// l1:=length(PpcRegExp(P1)^.RegExp);
+// l2:=length(PpcRegExp(P2)^.RegExp);
+// if l1 > l2 then l:=l2 else
+// l:=l1;
+// for i:=1 to l do
+// if PpcRegExp(P1).RegExp[i] <> PpcRegExp(P2).RegExp[i] then break;
+// if i <=l then
+// Compare:=ord(PpcRegExp(P1).RegExp[i])-ord(PpcRegExp(P2).RegExp[i]) else
+// Compare:=l1-l2;
+ Compare := stringsx.PasStrCmp(PpcRegExp(P1).RegExp, PpcRegExp(P2).RegExp, False);
+ end
+ else
+ begin
+// l1:=length(PpcRegExp(P1)^.RegExp);
+// l2:=length(SearchRegExp);
+// if l1 > l2 then l:=l2 else
+// l:=l1;
+// for i:=1 to l do
+// if PpcRegExp(P1).RegExp[i] <> SearchRegExp[i] then
+// begin
+// Compare:=ord(PpcRegExp(P1).RegExp[i])-ord(SearchRegExp[i]);
+// break;
+// end;
+// if i > l then Compare:=l1-l2;
+ Compare := stringsx.PasStrCmp(PpcRegExp(P1).RegExp, SearchRegExp, False);
+ end;
+end;
+
+function TRegExpCollection.Find(ARegExp:shortstring;var P: PpcRegExp):boolean;
+var I : integer;
+begin
+ CompareModeInsert:=false;
+ SearchRegExp:=ARegExp;
+ if Search(nil,I) then
+ begin
+ P:=PpcRegExp(At(I));
+ Find:=true;
+ end
+ else
+ begin
+ P:=nil;
+ Find:=false;
+ end;
+ CompareModeInsert:=true;
+end;
+
+function TRegExpCollection.CheckNew(ARegExp:shortstring):PpcRegExp;
+var
+ P : PpcRegExp;
+begin
+ if not Find(ARegExp,P) then
+ begin
+ if Count = MaxRegExp then
+ AtFree(0);
+ P:=New(ppcRegExp,Init(ARegExp,PCRE_CASELESS,nil));
+ Insert(P);
+ end;
+ CheckNew:=P;
+end;
+
+function pcGrepMatch(WildCard, aStr: string; AOptions:integer; ALocale : Pointer): Boolean;
+var
+ PpcRE:PpcRegExp;
+begin
+ PpcRE:=New(ppcRegExp,Init(WildCard,AOptions,Alocale));
+ pcGrepMatch:=PpcRE^.Search(pchar(AStr),Length(AStr));
+ Dispose(PpcRE,Done);
+end;
+
+function pcGrepSub(WildCard, aStr, aRepl: string; AOptions:integer; ALocale : Pointer): string;
+var
+ PpcRE:PpcRegExp;
+begin
+ PpcRE:=New(ppcRegExp,Init(WildCard,AOptions,Alocale));
+ if PpcRE^.Search(pchar(AStr),Length(AStr)) then
+ pcGrepSub:=PpcRE^.GetReplStr(pchar(AStr),ARepl)
+ else
+ pcGrepSub:='';
+ Dispose(PpcRE,Done);
+end;
+
+function pcFastGrepMatch(WildCard, aStr: string): Boolean;
+var
+ PpcRE:PpcRegExp;
+begin
+ PpcRE:=PRegExpCache^.CheckNew(WildCard);
+ pcFastGrepMatch:=PpcRE^.Search(pchar(AStr),Length(AStr));
+end;
+
+function pcFastGrepSub(WildCard, aStr, aRepl: string): string;
+var
+ PpcRE:PpcRegExp;
+begin
+ PpcRE:=PRegExpCache^.CheckNew(WildCard);
+ if PpcRE^.Search(pchar(AStr),Length(AStr)) then
+ pcFastGrepSub:=PpcRE^.GetReplStr(pchar(AStr),ARepl)
+ else
+ pcFastGrepSub:='';
+end;
+
+{$IFDEF PCRE_5_0}
+function pcGetVersion : pchar; assembler; {$FRAME-}{$USES none}
+asm
+ call pcre_version
+end;
+{$ENDIF PCRE_5_0}
+
+function pcError;
+var P: ppcRegExp absolute pRegExp;
+begin
+ Result := (P = nil) or P^.Error;
+ If Result and (P <> nil) then
+ begin
+{ if P^.ErrorPos = 0 then
+ MessageBox(GetString(erRegExpCompile)+'"'+P^.ErrorStr+'"', nil,mfConfirmation+mfOkButton)
+ else}
+ MessageBox(GetString(erRegExpCompile)+'"'+P^.ErrorStr+'"'+GetString(erRegExpCompPos),
+ @P^.ErrorPos,mfConfirmation+mfOkButton);
+ Dispose(P, Done);
+ P:=nil;
+ end;
+end;
+
+function pcInit;
+var Options : Integer;
+begin
+ If CaseSens then Options := 0 else Options := PCRE_CASELESS;
+ Result := New( PpcRegExp, Init( Pattern,
+ {DefaultOptions}
+ startup.MiscMultiData.cfgRegEx.DefaultOptions or Options,
+ DefaultLocaleTable) );
+end;
+
+Initialization
+ PRegExpCache:=New(PRegExpCollection,Init(64));
+Finalization
+ Dispose(PRegExpCache,Done);
+End.