1 //-------------------------------------------------------------------------
\r
3 // This file contains DataFlex functions to provide basic regex
\r
4 // functionality based on the GNU POSIX regex library, and accessed
\r
5 // via Win32 API calls to df32func.dll.
\r
6 // See df32func.h for external function definitions.
\r
8 // This file is to be included when using Win32 capabilities in df32func.mk
\r
10 // Copyright (c) 2006-2015, glyn@8kb.co.uk
\r
12 // df32func/regex.inc
\r
13 //-------------------------------------------------------------------------
\r
15 #IFDEF __df32func_h__
\r
20 //-------------------------------------------------------------------------
\r
22 //-------------------------------------------------------------------------
\r
24 // All the regex function accept a set of flags, this can be one or more of:
\r
25 // g = Perform match against each substring rather than just the first (greedy)
\r
26 // n = Perform newline-sensitive matching
\r
27 // i = Perform cases insensitive matching
\r
29 //Purely check if a regex expression produces match in the input string
\r
30 // Returns 1 on match, 0 on no match
\r
32 // move (regexp_match('the quick brown fox jumps over the lazy dog.', 'fox', 'g'))
\r
33 function regexp_match global string str string pattern string flags returns integer
\r
34 local integer l_iReturn
\r
35 local pointer l_pStr l_pPattern l_pFlags
\r
37 getaddress of str to l_pStr
\r
38 getaddress of pattern to l_pPattern
\r
39 getaddress of flags to l_pFlags
\r
41 move (RegexpMatch(l_pStr, l_pPattern, l_pFlags, ERRORS_TO_STDERR)) to l_iReturn
\r
43 function_return l_iReturn
\r
46 //Return a string containing all regex matches in the input string
\r
48 // move (regexp_matches('the quick brown fox jumps over the la\{zy d"og.', 'fox|(the)|brown|(la\\\{zy)|(d"og)', 'g')) to myString
\r
49 function regexp_matches global string str string pattern string flags returns string
\r
50 local integer l_iReturn
\r
51 local pointer l_pStr l_pPattern l_pFlags l_pOut
\r
52 local string l_sOut l_sReturn
\r
54 move "" to l_sReturn
\r
55 getaddress of str to l_pStr
\r
56 getaddress of pattern to l_pPattern
\r
57 getaddress of flags to l_pFlags
\r
58 zerostring MAX_DFREGEX_BUFFER to l_sOut
\r
59 getaddress of l_sOut to l_pOut
\r
61 move (RegexpMatches(l_pStr, l_pPattern, l_pFlags, l_pOut, MAX_DFREGEX_BUFFER, ERRORS_TO_STDERR)) to l_iReturn
\r
64 move (cstring(l_sOut)) To l_sReturn
\r
66 if (l_iReturn = -1);
\r
67 custom_error ERROR_CODE_REGEX_BUFFER_OVERFLOW$ ERROR_MSG_REGEX_BUFFER_OVERFLOW MAX_DFREGEX_BUFFER
\r
68 if (l_iReturn = -2);
\r
69 custom_error ERROR_CODE_REGEX_COMPILE_FAILURE$ ERROR_MSG_REGEX_COMPILE_FAILURE
\r
70 move "" to l_sReturn
\r
73 function_return l_sReturn
\r
76 //Perform a replacement on the input string all matches with the given pattern
\r
78 // move (regexp_replace('22 quick brown foxes jump over the 44 lazy dogs.', '([0-9]*).* (foxes) .* ([0-9]*) .* (dogs).*', 'SELECT build_data(\1,\2), build_data(\3,\4);', 'g')) to myString
\r
79 function regexp_replace global string str string pattern string replacement string flags returns string
\r
80 local integer l_iReturn
\r
81 local pointer l_pStr l_pPattern l_pFlags l_pReplacement l_pOut
\r
82 local string l_sOut l_sReturn
\r
84 move "" to l_sReturn
\r
85 getaddress of str to l_pStr
\r
86 getaddress of pattern to l_pPattern
\r
87 getaddress of flags to l_pFlags
\r
88 getaddress of replacement to l_pReplacement
\r
89 zerostring MAX_DFREGEX_BUFFER to l_sOut
\r
90 getaddress of l_sOut to l_pOut
\r
92 move (RegexpReplace(l_pStr, l_pPattern, l_pReplacement, l_pFlags, l_pOut, MAX_DFREGEX_BUFFER, ERRORS_TO_STDERR)) to l_iReturn
\r
95 move (cstring(l_sOut)) To l_sReturn
\r
97 if (l_iReturn = -1);
\r
98 custom_error ERROR_CODE_REGEX_BUFFER_OVERFLOW$ ERROR_MSG_REGEX_BUFFER_OVERFLOW MAX_DFREGEX_BUFFER
\r
99 if (l_iReturn = -2);
\r
100 custom_error ERROR_CODE_REGEX_COMPILE_FAILURE$ ERROR_MSG_REGEX_COMPILE_FAILURE
\r
101 move "" to l_sReturn
\r
104 function_return l_sReturn
\r
107 // Parse an output string from regexp_matches to get the result count
\r
109 // move (regexp_matches_count(myRegexMatchesOutput)) to myInt
\r
110 function regexp_matches_count global string argv returns integer
\r
111 local integer l_iCount l_i
\r
112 local string l_sChar l_sLast
\r
116 for l_i from 0 to (length(argv))
\r
117 move (mid(argv,1,l_i)) to l_sChar
\r
118 if ((l_sChar = '{') and (l_sLast <> '\')) increment l_iCount
\r
119 move l_sChar to l_sLast
\r
122 function_return l_iCount
\r
125 // Parse an output string from regexp_matches to get the result at an index
\r
127 // move (regexp_matches_item(myRegexMatchesOutput,muInt)) to myString
\r
128 function regexp_matches_item global string argv integer argv2 returns string
\r
129 local integer l_iCount l_i l_iOpen l_iQuot
\r
130 local string l_sChar l_sLast l_sNext l_sBuf
\r
136 for l_i from 0 to (length(argv))
\r
137 move (mid(argv,1,l_i)) to l_sChar
\r
138 move (mid(argv,1,l_i-1)) to l_sLast
\r
140 if ((l_sChar = '{') and (l_sLast <> '\')) increment l_iCount
\r
141 if (l_iCount <> argv2) break begin
\r
143 move (mid(argv,1,l_i+1)) to l_sNext
\r
145 if ((l_sChar = '{') and not (l_iQuot)) begin
\r
149 else if ((l_sChar = '}') and not (l_iQuot)) begin
\r
152 else if ((l_sChar = '"') and (l_sLast <> '\')) begin
\r
153 if (l_iQuot) move 0 to l_iQuot
\r
154 else move 1 to l_iQuot
\r
156 if ((l_sChar = ',') and not (l_iOpen)) break begin
\r
157 if (((l_sChar = '{') or (l_sChar = '}')) and not (l_iQuot)) break begin
\r
158 if ((l_sChar = '"') and (l_sLast <> '\')) break begin
\r
159 if ((l_iQuot) and (l_sChar = '\') and ((l_sNext = '"') or (l_sNext = '\'))) break begin
\r
161 append l_sBuf l_sChar
\r
164 function_return l_sBuf
\r