Ed,
This is so cool! It's been a while that I wanted to play with RegExp. This one finally pushed me to have a look. I was very impressed. It takes a while getting used to the pattern set but it's well worth the effort IMHO. Thanks Ed for sharing this with us!
I've just played with your code and threw a huge procedure file from the 2.6 days at it. The only issue I had was duplicate procedures/functions in case a procedure/function was commented out:
PROC MyProc
...
RETURN SomeVal
*-*commented out on 01.03.1995
*-*PROC MyProc
*-*...
*-**-*RETURN SomeVal
Another minor issue was the command SET PROCEDURE TO xxx resulted in a match "PROCEDURE TO".
I've changed the pattern as follows:
oReg.Pattern = '\n+\t*[ ]*\b(PROC(EDURE){0,1}|FUNC(TION){0,1})\s+\w+(\([^\)]*\)){0,1}[\t ]*(&'+'&[^\r]*){0,1}\r|$'
*-- the modification makes sure that we are on a new line and only tabs or spaces are allowed before the keywords PROCEDURE and FUNCTION
* \n - new line
* \t* - followed by 0 or more tabs
* [ ]* - followed by 0 or more spaces
For lurkers, here's a useful link that contains documentation about regular expressions in vbscript:
http://msdn.microsoft.com/workshop/languages/clinic/scripting051099.asp<
oUDFCollection = FindTheProcsAndFuncs('c:\MyProject\MyProcFile.PRG')
? oUDFCollection.Count
FOR EACH oFuncDeclaration IN oUDFCollection
? oFuncDeclaration.Value
ENDFOR
FUNCTION FindTheProcsAndFuncs
LPARAMETERS tcMyProcFile
LOCAL oReg, oMatches
oReg = CREATEOBJ('VBScript.RegExp')
oReg.Global = .T.
oReg.IgnoreCase = .T.
oReg.Pattern = '\b(PROC(EDURE){0,1}|FUNC(TION){0,1})\s+\w+(\([^\)]*\)){0,1}[\t ]*(&'+'&[^\r]*){0,1}\r|$'
*
* this pattern says start at a word boundary
* If the word PROC or PROCEDURE, or FUNC or FUNCTION, followed by at least
* one whitespace character, followed by a sequence of one or more letters,
* numbers and underscores, possibly followed with parameters encapsulated
* with parenthesis, possibly with an in-line comment, and terminated with
* CHR(13) or EOF, it matches
*
* \b a word boundary
* ( ... start a grouping
* "PROC"
* (EDURE){0,1} - followed by either 1 occurance or no occurance of "EDURE"
* | ... OR
* "FUNC"
* (TION){0,1} - followed by either one or no occurance of "TION"
* ) ... close grouping - this pattern must occur once
* \s+ followed by one or more whitespace characters
* \w+ followed by one or more letters, numbers and underscores
* ( ... start a grouping
* \( a "("
* [^\)]* followed by 0 or more non ")"
* \) a ")"
* ){0,1} ... the preceding grouping may occur 0 or 1 time
* [\t ]* ... any number of tabs and spaces
* ( ... start a grouping
* && ... note, this had to be split to avoid VFP parsing it into a comment
* [^\r]* ...followed by 0 or more characters other than a CR
* ){0,1} ... the grouping can occur 0 or 1 time
* \r|$ ... a CR or end of file
*
oMatches = oReg.Execute(FILETOSTR(tcMyProcFile))
RETURN oMatches>>
Daniel