Configuring Notepad++ "Function List" for Perl - regex

I'm trying to get the "Fucntion List" feature on notepad++ (v 6.7.5) working for Perl with classes (or packages, in perl parlance). Only regular subroutines outside of packages are supported by default.
Below is the XML snippet in question from the Function List config file (located on my windows machine at C:\Users\user\AppData\Roaming\Notepad++\functionList.xml ). I added the "classRange" node myself on top of the default "function" node.
EDIT: below is the corrected XML, thanks to user stribizhev
UPDATE: I've commented out the "normal" function section, because it was causing all my methods to appear twice in the function list.
<parser id="perl_function" displayName="Perl">
<classRange mainExpr="^package.*?(?=\npackage|\Z)">
<className>
<nameExpr expr="\s\K[^;]+"/>
</className>
<function mainExpr="^[\s]*(?<!#)[\s]*sub[\s]+[\w]+[\s]*\(?[^\)\(]*?\)?[\n\s]*\{" displayMode="$className->$functionName">
<functionName>
<funcNameExpr expr="(sub[\s]+)?\K[\w]+"/>
</functionName>
</function>
</classRange>
<!--
<function mainExpr="^[\s]*(?<!#)[\s]*sub[\s]+[\w]+[\s]*\(?[^\)\(]*?\)?[\n\s]*\{" displayMode="$className->$functionName">
<functionName>
<nameExpr expr="(sub[\s]+)?\K[\w]+"/>
</functionName>
</function>
-->
</parser>
The documentation for this is here.

I tried your XML in Notepad++ 6.8.1 and while it does work for Perl with 'packages', my plain scripts without packages fail to produce subs now. I uncommented the lines you commented out and it fixes that problem, but does exhibit the behavior you mentioned - doubled up subs within the 'packages'.
I found the following works nicely and even ignores subs in POD (which may be there as example usage) so they aren't added to the list:
<parser id="perl_function" displayName="Perl" commentExpr="(#.*?$|(__END__.*\Z))">
<classRange mainExpr="(?<=^package).*?(?=\npackage|\Z)">
<className>
<nameExpr expr="\s\K[^;]+"/>
</className>
<function mainExpr="^[\s]*(?<!#)[\s]*sub[\s]+[\w]+[\s]*\(?[^\)\(]*?\)?[\n\s]*\{">
<functionName>
<funcNameExpr expr="(sub[\s]+)?\K[\w]+"/>
</functionName>
</function>
</classRange>
<function mainExpr="^[\s]*(?<!#)[\s]*sub[\s]+[\w]+[\s]*\(?[^\)\(]*?\)?[\n\s]*\{">
<functionName>
<nameExpr expr="(?:sub[\s]+)?\K[\w]+"/>
</functionName>
</function>
</parser>

Most probably, you should use funcNameExpr instead of nameExpr:
Example:
<functionName>
<funcNameExpr expr="(sub[\s]+)?\K[\w]+"/>
</functionName>

funcNameExpr or uncomment did not work for me. What worked - commenting out the three regex lines with parentheses:
#\(
#[^()]*
#\)
As Perl does not consider parentheses after function name correct, I do not have such. Parentheses can be at each call of the function, but not where the function is.

Related

JAVAMETHOD grok pattern with optional thread number at the end

I'm trying to parse log4j messages:
2019-12-02 20:48:20.198utc DEBUG UnknownElementContentHandler,streamLock-9-th-11:32 - blabla
2019-11-19 23:40:04.014utc WARN AnnotationBinder,localhost-startStop-1:611 - blabla
2019-11-19 23:40:04.014utc INFO CovImCtl,main:109 - blabla
with grok pattern
%{TIMESTAMP_ISO8601:timestamp}utc%{SPACE}%{LOGLEVEL:level}%{SPACE}%{JAVACLASS:class},%{JAVAMETHOD1:method}:%{POSINT:lineno}%{SPACE}-%{SPACE}%{GREEDYDATA:message}
with using a variation on the standard:
JAVAMETHOD (?:(<(?:cl)?init>)|[a-zA-Z$_][a-zA-Z$_0-9]*)
JAVAMETHOD1 (?:(<(?:cl)?init>)|[a-zA-Z$_][a-zA-Z$_\-0-9]*)
The JAVAMETHOD worked for "main" but not for the others, (the pattern was missing -).
JAVAMETHOD1 works, but I need to get the optional trailing integer retrieved as a "thread_no" field (11 from streamLock-9-th-11, 1 from localhost-startStop-1)
I'm wrecking my brain, the methods like streamLock-9-th-11 has the internal "-\d+" "-9" which belongs to "streamLock-9-th"
Any ideas?

Robot Framework parsing for Notepad++ Function List

I'm trying to create a Notepad++ function list for Robot Framework scripts using the class structure to encapsulate the 4 different sections in a robot file:
Settings
Variables
Test Cases
Keywords
Using the documentation and some experimentation I created a simple filter that will return the keywords and test cases based on the fact that they start at the beginning of the line. But the more complex class grouping I need some regex help with. It seems that the *** should help with clear marking.
This is what I have thusfar:
I have installed the User Defined Robot Syntax Highlighting and have added the following section to the %app%\notepad++\functionList.xml
<association userDefinedLangName="Robotframework" id="robot_function"/>
And then in the parser section:
<parser
id="robot_function"
displayName="Robot Section"
commentExpr="((#.*?$)|(^Documentation*\w.*?$)|(^Meta*\w.*?$))|(^Library*\w.*?$)">
<function
mainExpr="^(\w.*?$)"
displayMode="$functionName">
<functionName>
<nameExpr expr="^(\w.*?$)"/>
</functionName>
</function>
</parser>
So, the part I'm having trouble with and I'd appreciate some help is:
<classRange mainExpr="^(\*).*(?=\n\S|\Z)">
<className>
<nameExpr expr="^(\w.*?$)"/>
</className>
<function mainExpr="^(\w.*?$)">
<functionName>
<nameExpr expr="^(\w.*?$)"/>
</functionName>
</function>
</classRange>
Below is an example robot file
*** Variables ***
${variable} variable value
*** Settings ***
Documentation multi
... line
... documentation.
Metadata Version 0.1
Library LibraryName some variable
Library String
*** Test Cases ***
Test Case RF 01
Run Keyword ${TEST_NAME}
Test Case RF 02
Run Keyword ${TEST_NAME}
*** Keywords ***
Test Case RF ${tc}
Sleep 30ms
Test Keyword
Sleep 300ms
I'm sure that if I can make it work for one of the sections, for example test cases, then that will allow me to also apply it to the other sections. Predominantly I'm interested in the test cases and keywords.
With the settings below I am able to use Notepad++ Function List for Robot Framework keywords and test cases:
<association id="robot_syntax" userDefinedLangName="Robotframework" />
<association id="robot_syntax" ext=".robot" />
<parser
displayName="Robot Framework"
id ="robot_syntax"
commentExpr="(^(\h*)|(#.*?)|(\[\w.*?)|(Documentation*\w.*?)|(Library*\w.*?)|(Metadata*\w.*?)|(Resource*\w.*?)|(Test (Setup|Teardown|Template|Timeout)*\w.*?)||(Suite (Setup|Teardown)*\w.*?)|((Force|Default) Tags*\w.*?))$"
>
<function mainExpr="(?m-s:(?:^)[A-Za-z0-9].*$)"/>
</parser>

xbuild with [System.Text.RegularExpressions.Regex]::Match(string,string) parameters doesn't work properly (MSBuild is fine)

I have a target that reads a .proj file with ReadLinesFromFile and then try to match a version number (e.g. 1.0.23) from the contained lines like:
<Target Name="GetRevision">
<ReadLinesFromFile File="$(MyDir)GetStuff.Data.proj">
<Output TaskParameter="Lines" ItemName="GetStuffLines" />
</ReadLinesFromFile>
<PropertyGroup>
<In>#(GetStuffLines)</In>
<Out>$([System.Text.RegularExpressions.Regex]::Match($(In), "(\d+)\.(\d+)\.(\d+)"))</Out>
</PropertyGroup>
<Message Text="Revision number [$(Out)]" />
<CreateProperty Value="$(Out)">
<Output TaskParameter="Value" PropertyName="RevisionNumber" />
</CreateProperty>
</Target>
The result is always empty.. Even if I try to do a simple Match($(In), "somestring") its not working correctly in linux/xbuild. This does work on windows/msbuild
Any tricks/ideas? An alternative would be to get the property version out of the first .proj file, instead of reading all lines and matching the number with a regex, but I don't even know if that is possible.
I am running versions:
XBuild Engine Version 12.0
Mono, Version 4.2.1.0
EDIT:
I've been able to trace it further down into the parameters that go into Match(), there is something wrong with the variables evaluation. The function actually works with for example Match("foobar","bar") I will get bar
But weird things happen with other inputs, e.g. Match($(In), "Get") will match Get because it is actually matching against the string "#(GetStuffLines)"
When I do Match($(In), "#..") I will get a match of #(G
But then, when I do Match($(In), "#.*") I actually get the entire content of the input file GetStuff.Data.proj which indicates that the variable was correctly expanded somewhere and the matching matched the entire input string.
I needed to circumvent Match() because it seems to be bugged at this point.
The ugly solution I came up with was to use Exec and grep the pattern like:
<Exec Command="grep -o -P '[0-9]+[.][0-9]+[.][0-9]+' $(MyDir)GetStuff.Data.proj > extractedRevisionNumber.tmp" Condition="$(OSTYPE.Contains('linux'))"/>
<ReadLinesFromFile File="$(ComponentRootDir)extractedRevisionNumber.tmp" Condition="$(OSTYPE.Contains('linux'))">
<Output TaskParameter="Lines" ItemName="GetExtractedRevisionNumber" />
</ReadLinesFromFile>
I couldn't even use the properties ConsoleToMSBuild and ConsoleOutput (https://msdn.microsoft.com/en-us/library/ms124731%28v=VS.110%29.aspx) because xbuild didn't recognize those.. That's why I grep the pattern and save it into a temp file which can be read with ReadLinesFromFile into the ItemName="GetExtractedRevisionNumber" that I use later.

RegexFilter with RollingFileAppender not working properly

I am trying to use Regexfilter in RollingFileAppender. For 1st matching instance it retreived the logger, but after that I different patttern but nothing is logged in the file. Here is what I am using:
Main Class:
public class MainApp {
public static void main(String[] args) {
final Logger logger = LogManager.getLogger(MainApp.class.getName());
ApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml");
HelloWorld obj = (HelloWorld) context.getBean("helloWorld");
logger.trace("NPF:Trace:Entering Log4j2 Example.");
logger.debug("NTL:debug Entering Log4j2 Example.");
obj.getMessage();
Company comp = new Company();
comp.setCompName("ANC");
comp.setEstablish(1889);
CompanyBusiness compBus = (CompanyBusiness)context.getBean("compBus");
compBus.finaceBusiness(comp.getCompName(), comp.getEstablish());
logger.trace("NTL: Trace: Exiting Log4j2 Example.");
}
}
log4j2.xml:
<?xml version="1.0" encoding="UTF-8" ?>
<Configuration>
<Appenders>
<Console name="STDOUT" target="SYSTEM_OUT">
<PatternLayout pattern="%d{yyyy-MM-dd [%t] HH:mm:ss} %-5p %c{1}:%L - %m%X%n" />
</Console>
<RollingFile name="RollingFile" fileName="C:\logTest\runtime\tla\els3.log" append="true" filePattern="C:\logTest\runtime\tla\els3-%d{yyyy-MM-dd}-%i.log" >
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %m%X%n" />
<RegexFilter regex=".*business*." onMatch="ACCEPT" onMismatch="DENY"/>
<Policies>
<SizeBasedTriggeringPolicy size="20 MB" />
</Policies>
</RollingFile>
</Appenders>
<Loggers>
<Logger name="com.anc" level="trace"/>
<Root level="trace">
<AppenderRef ref="STDOUT" />
<AppenderRef ref="RollingFile"/>
</Root>
</Loggers>
</Configuration>
When I ran for the first time, in my logfile I got logs having only "business" related line. Latter I changed the patter from .business (pattern has astreik before and after business word). to "business", logging did not happen in file nor on the console. Also my application terminated without any kind of logging.
Then I tried to revert back the pattern to '.business.' (pattern has astreik before and after business word), thereafter no logging happened on the log file, but on the console all the log trace is printed. When I comment out the Regexfilter after trying for long time, my logs was printed in the log file.
I am not sure if this is a bug of Regexfilter works only for one time. Also if we do not pass any patter matching characters, the application stops without any log printing either on console or file.
If you want to log all events containing the word "business", then you shall use the regex .*business.* instead of .*business*.. Here is an example:
<RegexFilter regex=".*business.*" onMatch="ACCEPT" onMismatch="DENY"/>
For information, .*business*. means: anything, followed by business, followed by s character 0 or more time, followed by any single character.
More explaining:
. means any single character
* means 0 or more times
so .* means any character, 0 or more times.

Use Ivy to get latest X.X.X.Final Hibernate

I am using IvyDE in Eclipse and getting
unresolved dependency: org.hibernate#hibernate-core;final: not found
using code:
ivysettings.xml
<ivysettings>
<settings defaultResolver="maven2"/>
<resolvers>
<ibiblio name="maven2" m2compatible="true"/>
</resolvers>
<version-matchers>
<pattern-vm>
<match revision="final" pattern="\*Final" matcher="regexp"/>
</pattern-vm>
</version-matchers>
</ivysettings>
ivy.xml
...
<dependency org="org.hibernate" name="hibernate-core" rev="final"/>
...
I have tried rev="final()" and get the same error. I am using http://ant.apache.org/ivy/history/latest-milestone/settings/version-matchers.html as a guide.
I want to get the latest X.X.X.Final version of Hibernate.
Thank you for your help.
Your regular expression does not match any of revision numbers (You're looking for a non-existent "*" character).
Try this instead:
<version-matchers usedefaults="true">
<pattern-vm>
<match revision="final" pattern=".*Final$" matcher="regexp"/>
</pattern-vm>
</version-matchers>