home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 5 Edit
/
05-Edit.zip
/
epm603a.zip
/
EPMSMP.ZIP
/
EGREPXMP.E
< prev
next >
Wrap
Text File
|
1995-11-10
|
7KB
|
132 lines
; Extended GREP searching in EPM 6.0x
;
; EGREP can be used for more than just searching though a file - you can
; also use it directly to search a given string, and can pre-compile the
; search string into an EGREP program for better performance in a loop.
; Here are some examples.
;
; Larry Margolis
--------------------------------------------------------------------------
; Some examples of using Extended GREP from the macros for other than searching
; through a file.
; First, we pass 'X' as a fourth parameter to Pos(), to tell it that the search
; string is an EGREP expression rather than a simple string:
defc qpos =
prog = 'a.*t'
searchstr = 'This is a test.'
sayerror 'Result =' pos(prog, searchstr, 1, 'X')
; Next, we also pass in 'M' to specify that we want to be given a result
; showing all matches, not just the starting column of the "hit". This
; gives a start and end column for the entire match, followed by start
; and end columns for each parenthesized expression in the search string
; (in the order in which the open parens were seen).
defc qposm =
prog = '(q:a*) (:c)'
searchstr = 'The quick brown fox jumps over the lazy dog.'
Result = pos(prog, searchstr, 1, 'XM')
parse value result with s0 e0 s1 e1 s2 e2 -- We know this succeeded; failure would return just 0.
sayerror 'Result =' result 'entire match = "'substr(searchstr, s0, e0-s0+1)'", q:a* = "'substr(searchstr, s1, e1-s1+1)'", following word = "'substr(searchstr, s2, e2-s2+1)'"'
include 'stdconst.e'
; Here, we split the compilation of the regular expression into a program, and
; the execution of that program, into two pieces. This saves on the overhead of
; recompiling the program every time, if it will be used repeatedly.
defc regtest =
prog = 'a.*t'
regprog = RegExpComp(prog)
searchstr = 'This is a test.'
exec_result = RegExpExec(regprog, searchstr)
call dynalink32(E_DLL, -- dynamic link library name
'myfree', -- DosFreeSeg
atol(regprog))
sayerror 'Result =' exec_result 'regprog =' regprog '= 0x'ltoa(atol(regprog), 16)
; Here, we use the E Toolkit dynalink calls to do something similar. The
; differences are that the program must have a null at the end; the
; program string and string to be searched are passed as pointers rather
; than EPM strings (meaning that strings much longer than EPM's limit of
; 1600 characters can be passed, by using a buffer instead of an EPM
; string); and the result positions are offsets (0-based) rather than
; character positions (1-based). This returns a Boolean for success or
; failure, and up to 20 shorts in the provided buffer, corresponding to
; 10 start positions and 10 end positions as returned in qposm(), above.
; Note that non-matched positions are set to -1, which itoa() returns
; as 65535.
defc regtktest =
prog = 'a.*t'\0
regprog = dynalink32( E_DLL, -- library name
'EtkRegexpComp', -- function name
gethwndc(EPMINFO_EDITCLIENT) ||
address(prog), 2 )
if not regprog then
sayerror 'regprog is 0!'
return
endif
searchstr = 'This is a test.'
resultbuf = copies(\0, 40)
exec_result = dynalink32( E_DLL, -- library name
'EtkRegexpSearch', -- function name
gethwndc(EPMINFO_EDITCLIENT) || -- Window handle
atol(regprog) || -- pointer to program
address(searchstr) || -- pointer to input string
atol(length(searchstr)) || -- length of input string
atol(0) || -- Boolean REVERSE flag
address(resultbuf) || -- pointer to result buffer
atol(length(resultbuf)) ) -- length of result buffer
call dynalink32(E_DLL, -- dynamic link library name
'myfree', -- DosFreeSeg
atol(regprog))
; startptrs = leftstr(result_buf, 20)
; endptrs = substr(result_buf, 20)
s0 = itoa(substr(resultbuf, 1, 2), 10)
e0 = itoa(substr(resultbuf, 21, 2), 10)
s1 = itoa(substr(resultbuf, 3, 2), 10)
e1 = itoa(substr(resultbuf, 23, 2), 10)
sayerror 'Result =' exec_result 'start =' s0 'end =' e0 'start1 =' s1 'end1 =' e1
; Finally, we use a combination of techniques: we precompile the program, but
; then pass it to Pos() (because we want to use the Match option). We include
; a 'P' in the fourth parameter to Pos() to indicate that we're passing a
; Precompiled program. This example removes all comments (delimited with
; /* ... */ ) and quoted strings from the input line. The original code first
; obtained the position of the first '/*', the first single quote, and the
; first double quote on the line; determined which was smallest (but non-zero,
; because pos() returns 0 if the search string isn't found), then looked for
; the appropriate end for the first quote or comment starter found. If the
; end was found, the match (start to end) was blanked out; if no end was found,
; the input string was truncated at the start point. When rewritten to use the
; EGREP option, the resulting code is much shorter. It's also slower - 100
; iterations of the original code took 3.469 seconds, while 100 iterations of
; the EGREP code took 6.5 seconds. Precompiling the program outside of the loop
; cured the slowness; the same 100 iterations now took 2.125 seconds - even
; faster than the original code (for this test string). The original code
; can be seen in TAGS.E, in rexx_proc_search() - it's still fastest when
; there are no comments or quoted strings in the text.
defc stripstuff =
regprog = RegExpComp('/\*.@(\*/|$)|"[^"]*("|$)|''[^'']*(''|$)')
line = '12"/*"34''*/"''56/*a''"''"*/78''"a"''9'
e0 = 0
loop -- Remove comments & quotes
parse value pos(regprog, line, e0+1, 'XMP') with s0 e0 .
if not s0 then leave; endif
if e0 = length(line) then
line=leftstr(line, s0-1)
else
line=overlay('', line, s0, e0-s0+1) -- Keep column alignment
endif
endloop
call dynalink32(E_DLL, -- dynamic link library name
'myfree', -- DosFreeSeg
atol(regprog))
sayerror 'result = >'line'<'