Skip to content
Snippets Groups Projects
Commit cfaa487b authored by Stéphane Poirier's avatar Stéphane Poirier
Browse files

regex test program based on cfg files

parent 9077a509
No related branches found
No related tags found
No related merge requests found
<?xml version="1.0" encoding="utf-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>fr.soleil</groupId>
<artifactId>super-pom-C-CPP-device</artifactId>
<version>RELEASE</version>
</parent>
<groupId>fr.soleil.device</groupId>
<artifactId>yat-regex-test-${aol}-${mode}</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>nar</packaging>
<name>RegexTester</name>
<description>a few yat::Regex samples</description>
<build>
<plugins>
<plugin>
<groupId>org.freehep</groupId>
<artifactId>freehep-nar-plugin</artifactId>
<configuration>
<cpp>
<includePaths>
<includePath>${project.basedir}/src</includePath>
</includePaths>
<options>
<!--option>-Wno-uninitialized</option-->
<!--option>-Wno-unused-parameter</option-->
<!--option>-Wno-unused-variable</option-->
</options>
</cpp>
</configuration>
</plugin>
</plugins>
</build>
<scm>
<connection>${scm.connection.svn.tango-cs}:share/yat</connection>
<developerConnection>${scm.developerConnection.svn.tango-cs}:share/yat</developerConnection>
<url>${scm.url.svn.tango-cs}/share/yat</url>
</scm>
<dependencies>
<dependency>
<groupId>fr.soleil.lib</groupId>
<artifactId>YAT-${aol}-${library}-${mode}</artifactId>
<!--!version>${env.YAT_VERSION_DEV}</version-->
</dependency>
</dependencies>
<developers>
<developer>
<id>poirier</id>
<name>poirier</name>
<url>http://controle/</url>
<organization>Synchrotron Soleil</organization>
<organizationUrl>http://www.synchrotron-soleil.fr</organizationUrl>
<roles>
<role>manager</role>
</roles>
<timezone>1</timezone>
</developer>
</developers>
</project>
#---------------------
# Some basic variables
#---------------------
$a = [:alpha:]
$u = [:upper:]
$l = [:lower:]
$n = [:digit:]
$d = [:digit:]
$an = [:alnum:]
$ln = $l$n
$un = $u$n
$w = $(a)_
$x = [:xdigit:]
$b = [:blank:]
$p = [:punct:]
$g = [:graph:]
$p = [:print:]
$c = [:cntrl:]
$A = [[:alpha:]]
$U = [[:upper:]]
$L = [[:lower:]]
$N = [[:digit:]]
$LN = [$l$n]
$UN = [$u$n]
$D = [[:digit:]]
$AN = [[:alnum:]]
$W = [$w]
$X = [[:xdigit:]]
$B = [[:blank:]]
$P = [[:punct:]]
$G = [[:graph:]]
$P = [[:print:]]
$C = [[:cntrl:]]
#-------------------------------------------------------------------------------
[var_test]
$var_name = ([_$an]+)
function = search
pattern = \$$($var_name|(\($var_name\))|\$$)
'bla$blu$$bli$gu$(bu)$(zo)meu$0
#-------------------------------------------------------------------------------
[hex]
function = search
pattern = (0[xX]$X{2})
'bla 0xa2 blu 0XFF
#-------------------------------------------------------------------------------
[wordmp]
function = search
pattern = [-$w+]+
'hello world_ bi-bop bla+blup !
#-------------------------------------------------------------------------------
[bracket]
function = match
pattern = \[toto\]
'[toto]
#-------------------------------------------------------------------------------
[escape]
function = search
pattern = [^\\]:
'to\:to
#-------------------------------------------------------------------------------
[search_1]
function = search
pattern = .*:
'to:to:
[search_2]
function = search
pattern = \w+
'what a beautiful day!
[search_3]
function = search
pattern = [^:]+
'ga:bu:
[search_4]
function = match
pattern = ([^:]+):([^:]+):(.*)
'ga:bu:zo
#-------------------------------------------------------------------------------
# File transfer job file
#-------------------------------------------------------------------------------
[ft]
function=match
pattern = ([0-9]+)\|([^ ]+) > ([^|]+)\|state=([a-z]+)(\|uid=([0-9]+))?(\|gid=([0-9]+))?(\|dir_mode=([0-7]+))?(\|file_mode=([0-7]+))?(\|delete_time=([0-9]{4}\-[0-9]{2}\-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}))?
'12|/ga/bu > /zo/meu|state=pending|uid=12|gid=1212|delete_time=2021-01-04T12:00:00
#-------------------------------------------------------------------------------
# RecordingManager hook declaraction (propriété ExternalActions)
#-------------------------------------------------------------------------------
[hook_rm]
$hook_device = ([^/]+/[^/]+/[^/]+)
$hook_cmd = (\w+)
$hook_vararg = (\[(\w+)\])
$hook_varval = ('(\w*)')
$hook_argtype = \s*(\w+)\s*
$hook_arg = ($hook_vararg|$hook_varval)(\s*:$hook_argtype)?
$hook_opt = [ a-zA-Z0-9_,:]+
$hook = $hook_device/$hook_cmd\s*(\(\s*($hook_arg)?\))?($hook_opt)?
function = match
pattern = $hook
'steph/transverse/file-transfer.1/AutoTransfer10([sc]:devstring),state:ON,tmo: 12
'steph/transverse/file-transfer.1/AutoTransfer10([sc]),state:ON,tmo: 12
'steph/transverse/file-transfer.1/AutoTransfer10('sc':devstring),state:ON,tmo: 12
'steph/transverse/file-transfer.1/AutoTransfer10('sc'),state:ON,tmo: 12
'steph/transverse/file-transfer.1/AutoTransfer10,state:ON,tmo: 12
'steph/transverse/file-transfer.1/AutoTransfer10(''),state:ON,tmo: 12
'steph/transverse/file-transfer.1/AutoTransfer10(),state:ON,tmo: 12
[hook_options]
function = search
pattern = (\w+)\s*:\s*(\w+)
',state: ON, tmo: 12
#-------------------------------------------------------------------------------
[alt]
function = search
pattern = ab|cd
'abcdefghahbocz
[search_var]
function = search
pattern = \$(([_[:alnum:]]+)|\(([_[:alnum:]]+)\))|\$
'bla $ga bu $(zo) bla
#-------------------------------------------------------------------------------
# device name validation
#-------------------------------------------------------------------------------
[device]
$node = [-_.[:alpha:]][-_.[:alnum:]]+
$domain = $node
$family = $node
$member = $node
$attr = $node
pattern = ($domain)/($family)/($member)
function = match
'i13-ln/vi/c00-tc.2
'mos1-c016sep/ep/rawdatareader
'boo-b4/vi/statecomposer.1
#-------------------------------------------------------------------------------
# delete delay (FileTransfer)
#-------------------------------------------------------------------------------
[delay]
$day = (\$?)([0-9]+)d
$hr = (\$?)([0-9]|[01][0-9]|2[0-4])h
$mn = (\$?)([0-9]|[0-5][0-9])m
$sec = (\$?)([0-9]|[0-5][0-9])s
function = match
pattern = ($day)?\s*($hr)?\s*($mn)?\s*($sec)?
'1h
'$1d $1h $24m $30s
'20s
'
$key = (_[a-zA-Z]+_|[a-zA-Z]+)
$attr_field = ([[:alnum:]]+|-)
$format = \((%[0-9dfxle.]+)\)
$key_attr = $key\s*@\s*$attr_field($format)?
$label = ([^:]+|-)
$domain = [-.[:alnum:]]+
$family = [-.[:alnum:]]+
$member = [-.[:alnum:]]+
$attr = [[:alnum:]]+
$dev_attr = \s*:\s*($domain/$family/$member/$attr)\s*
$prop = \s*:\s*(\([a-zA-Z,/@_]+\)|-)
[testvar]
$def_val = \s*:\s*(.*)
pattern = $key_attr\s*:\s*$label($dev_attr)?$prop($def_val)?
function = match
'_ab_ @attr(%.2f):Label:domain/family/member/attr:(O,W):def
'Yr@-:-:-:[y]
'sdir@sDirectory: Sub directory : (O,L,C@_destpath_)
'_destpath_@destPath:Destination Path:(E,R,C@_destpath_): [rp]/[pr]/[sdir]
'XX@theYear:Year:(O,R):[Yr]
'pr@project:Project Code : steph/transverse/projectmanager/currentProject : (O,R)
'id@uniqueId : Unique Id : (O,R) : $(uc\:BEAMLINE)\:contacq\:[sc]
[prop]
pattern = ([A-Z])\s*(@\s*(([a-zA-Z_])+))?
function = search
'(O,R,C@_dest_path_)
'(O,R)
//----------------------------------------------------------------------------
// Copyright (c) 2004-2015 Synchrotron SOLEIL
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the GNU Lesser Public License v3
// which accompanies this distribution, and is available at
// http://www.gnu.org/licenses/lgpl.html
//----------------------------------------------------------------------------
/*!
* \file
* \brief An example of yat::Regex usage
* \author S. Poirier - Synchrotron SOLEIL
*/
#include <iostream>
#include <yat/utils/Json.h>
#include <yat/utils/Logging.h>
#include <yat/file/FileName.h>
#include <yat/utils/CommandLine.h>
#include <yat/Exception.h>
#include <yat/regex/Regex.h>
typedef yat::StringFormat _strf;
typedef enum ShowOpt
{
none = 0, prefix = 1, suffix = 2, empty = 4, var = 8, sub = 16
} ShowOpt;
yat::String substitute(const yat::CfgFile::Parameters& kvg,
const yat::CfgFile::Parameters& kvl, const yat::String& in)
{
// Allow variable like $var or $(var), where var is made of any
// characters in [0-9a-zA-Z_]
yat::Regex re(R"(\$(([_[:alnum:]]+)|(\(([_[:alnum:]]+)\))|\$))");
yat::String v, to;
yat::Regex::Match m;
std::size_t non_match_start = 0, non_match_end = 0;
while( re.search(in, &m) )
{
non_match_end = m.position(0);
if( non_match_end - non_match_start > 0 )
to.append(in.substr(non_match_start, non_match_end - non_match_start));
v = m.str(4).empty() ? m.str(1): m.str(4);
if( v == "$" )
to.append(v);
else
{
yat::CfgFile::Parameters::const_iterator cit1 = kvg.find(yat::String("$") + v);
yat::CfgFile::Parameters::const_iterator cit2 = kvl.find(yat::String("$") + v);
if( cit2 != kvl.end() )
to.append(substitute(kvg, kvl, cit2->second));
else if( cit1 != kvg.end() )
to.append(substitute(kvg, kvg, cit1->second));
else
{
std::cout << "error: unknown variable " << v << std::endl;
return "";
}
}
non_match_start = non_match_end + m.length(0);
}
if( non_match_start < in.size() )
to.append(in.substr(non_match_start));
return to;
}
//-----------------------------------------------------------------------------
void extract_submatches(const yat::Regex::Match& m, int opt)
{
if( m.size() > 1 )
std::cout << m.size() - 1 << " Submatches:\n";
if( opt & prefix )
std::cout << " Prefix: '" << m.prefix() << "'\n";
for (size_t j = 1; j < m.size(); ++j)
{
if( !m.str(j).empty() || (m.str(j).empty() && (opt & empty)) )
std::cout << _strf("{%3d}: '{}'\n").format(j).format(m.str(j));
}
if( opt & suffix )
std::cout << " Suffix: '" << m.suffix() << "'\n";
std::cout << '-' << std::endl;
}
//-----------------------------------------------------------------------------
void match(yat::RegexPtr re_ptr, const yat::String& str, int opt)
{
yat::Regex::Match m;
bool is_match = re_ptr->match(str, &m);
std::cout << _strf("'{}' match -> {}").format(str).format(is_match) << std::endl;
// show contents of marked subexpressions within each match
if( is_match && (opt & sub) )
{
extract_submatches(m, opt);
}
}
//-----------------------------------------------------------------------------
void search(yat::RegexPtr re_ptr, const yat::String& str, int opt)
{
yat::Regex::Match m;
std::cout << _strf("Search matches in '{}': ").format(str) << std::endl;
while( re_ptr->search(str, &m) )
{
std::cout << "Match found: '" << m.str() << "'" << std::endl;
if( opt & sub )
extract_submatches(m, opt);
}
}
//-----------------------------------------------------------------------------
// main
//-----------------------------------------------------------------------------
int main(int argc, char* argv[])
{
yat::CommandLine cl;
yat::String def_cfg_file("regex_tester.cfg");
cl.add_opt('c', "cfg-file", "regex file", "Configuration file");
cl.add_opt('p', "show-prefix", "", "Show prefix");
cl.add_opt('s', "show-suffix", "", "Show suffix");
cl.add_opt('v', "show-variables", "", "Show variables");
cl.add_opt('m', "show-submatches", "", "Show sub-matches");
cl.add_opt('e', "show-empty-submatch", "", "Show empty submatch");
cl.add_opt('x', "test-to-be-executed", "test name", "Execute a specific test by its section name");
int opt = 0;
yat::String test_exec;
try
{
bool b = cl.read(argc, argv);
if( b )
{
yat::String file_name = "regex_tester.cfg";
if( cl.is_option("cfg-file") )
file_name = cl.option_value("cfg-file");
if( cl.is_option("show-prefix") )
opt |= prefix;
if( cl.is_option("show-suffix") )
opt |= suffix;
if( cl.is_option("show-empty-submatch") )
opt |= empty;
if( cl.is_option("show-submatches") )
opt |= sub;
if( cl.is_option("show-variables") )
opt |= var;
if( cl.is_option("test-to-be-executed") )
test_exec = cl.option_value("test-to-be-executed");
yat::Regex re_test(test_exec);
yat::CfgFile f(file_name);
f.load();
f.set_section(CFG_FILE_DEFAULT_SECTION);
// pre-defined pattern
yat::CfgFile::Parameters pg = f.get_parameters();
for( yat::CfgFile::Parameters::const_iterator cit = pg.begin(); opt & var && cit != pg.end(); ++cit )
std::cout << cit->first << " -> " << substitute(pg, yat::CfgFile::Parameters(), cit->second) << std::endl;
std::list<std::string> sections;
f.get_sections(&sections);
for( std::list<std::string>::const_iterator cit = sections.begin(); cit != sections.end(); ++cit )
{
if( CFG_FILE_DEFAULT_SECTION == *cit || (!test_exec.empty() && !re_test.search(*cit)) )
continue;
std::cout << "----\ntest name: " << *cit << std::endl;
f.set_section(*cit);
yat::CfgFile::Parameters pl = f.get_parameters();
for( yat::CfgFile::Parameters::const_iterator cit = pl.begin(); opt & var && cit != pl.end(); ++cit )
{
if( yat::StringUtil::start_with(cit->first, '$') )
std::cout << cit->first << " -> " << substitute(pg, pl, cit->second) << std::endl;
}
yat::RegexPtr re_ptr = new yat::Regex(substitute(pg, pl, f.get_param_value("pattern")));
std::cout << "Pattern: " << re_ptr->pattern() << "\n-" << std::endl;
yat::String op = f.get_param_value("function");
yat::CfgFile::Values test_strings = f.get_values();
for( std::size_t i = 0; i < test_strings.size(); ++i )
{
if( op.is_equal_no_case("match") )
match(re_ptr, test_strings[i], opt);
else if( op.is_equal_no_case("search") )
search(re_ptr, test_strings[i], opt);
}
}
}
}
catch(const yat::Exception& e)
{
YAT_LOG_EXCEPTION(e);
}
return 0;
}
# URI RFC-3986
$pct_encoded = %[[:xdigit:]][[:xdigit:]]
$gen_delims = []:/?@#[]
$sub_delims = [!$&'()*+,;=]
$unreserved = [-.~_[:alnum:]]
$pchar = ($unreserved|$pct_encoded|$sub_delims|:|@)
$segment = $pchar*
$segment_nz = $pchar+
$segment_nz_nc = ($unreserved|$pct_encoded|$sub_delims|@)+
$path_abempty = ((/$segment)*)
$path_absolute = (/($segment_nz(/$segment)*)*)
$path_noscheme = ($segment_nz_nc(/$segment)*)
$path_rootless = ($segment_nz(/$segment)*)
$path_empty = $pchar{0}
$path = ($path_abempty|$path_absolute|$path_noscheme|$path_rootless|$path_empty)
$scheme = ([[:alpha:]][-+.[:alnum:]]*)
$query = (($pchar|/|\?)*)
$fragment = (($pchar|/|\?)*)
$reg_name = ($unreserved|$pct_encoded|$sub_delims)*
$userinfo = (($unreserved|$pct_encoded|$gen_delims|:)*)
$dec_octet = ([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])
$authority = (($userinfo@)?$host(:$port)?)
$port = ([0-9]*)
$host = ($IP_literal|$IPv4|$reg_name)
#$host = ($IPv4|$reg_name)
$IPv4 = $dec_octet\.$dec_octet\.$dec_octet\.$dec_octet
$h16 = [[:xdigit:]]{1,4}
$ls32 = ($h16:$h16|$IPv4)
$IPv6_1 = ($h16:){6}$ls32
$IPv6_2 = ::($h16:){5}$ls32
$IPv6_3 = ($h16)?::($h16:){4}$ls32
$IPv6_4 = (($h16:){0,1}$h16)?::($h16:){3}$ls32
$IPv6_5 = (($h16:){0,2}$h16)?::($h16:){2}$ls32
$IPv6_6 = (($h16:){0,3}$h16)?::($h16:){1}$ls32
$IPv6_7 = (($h16:){0,4}$h16)?::$ls32
$IPv6_8 = (($h16:){0,5}$h16)?::$h16
$IPv6_9 = (($h16:){0,6}$h16)?::
$IPv6 = ($IPv6_1|$IPv6_2|$IPv6_3|$IPv6_4|$IPv6_5|$IPv6_6|$IPv6_7|$IPv6_8|$IPv6_9)
$IPvFuture = ([vV][[:xdigit:]]+\.($unreserved|$sub_delims|:))
$IP_literal = (\[($IPv6|$IPvFuture)\])
$hier_part = ((//$authority$path_abempty)|$path_absolute|$path_rootless|$path_empty)
$URI = $scheme:$hier_part(\?$query)?(#$fragment)?
[ipv4]
function = match
pattern = $IPv4
'172.85.69.25
[ipv6]
function = match
pattern = $IPv6
'0:0:0:0:0:FFFF:129.144.52.38
[ip_literal]
function = match
pattern = $IP_literal
'[2001:db8::7]
[uri_scheme]
function = match
pattern = $scheme
'foo
[full_uri]
function = match
pattern = $URI
strings = |
'foo://example.com:8042/over/there?name=ferret#nose
'urn:example:animal:ferret:nose
'ftp://foo.bar/baz
'http://userid:passwd@example.com:8080/
'http://example.com:8080/
'http://example.com/blabla_(blu)
'ldap://[2001:db8::7]/c=GB?objectClass?one
'tel:+145349836
'mailto:paf092@gmail.com
'telnet://192.168.0.1:80/
'http://[fe80:3::1ff:fe23:4567:890a]:443/over/there?name=ferret#nose
'https://[2001:db8:85a3:8d3:1319:8a2e:370:7348]:443/
'http://www.mapy.cz:1212/
'http://[FEDC:BA98:7654:3210:FEDC:BA98:7654:3210]:80/index.html
'http://[1080:0:0:0:8:800:200C:417A]/index.html
'http://[3ffe:2a00:100:7031::1]
'http://[1080::8:800:200C:417A]/foo
'http://[::192.9.5.5]/ipng
'http://[::FFFF:129.144.52.38]:80/index.html
'http://[2010:836B:4179::836B:4179]
'https://john.doe@www.example.com:123/forum/questions/?tag=networking&order=newest#top
'news:comp.infosystems.www.servers.unix
'tango://acs.esrf.fr:10000/my/funny/dev/state.change
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment