######################## RE function library ############################################
# LIB: misha_std_re_func_lib
################################################################################
# $Revision: 1.2 $
# $Author: drajovic $
# $Date: 2004/11/07 22:26:27 $
# $Source: C:/Archive/FRAMEWORK/EMOS_GPL/STD/misha_std_re_func_lib/script,v $
################################################################################
#/***
#* Regular expression functions search and match for WinRunner.
#*<p>
#* Copyright (c) 2003 Misha Verplak
#*<p>
#* Supporting regex++ c++ library at www.boost.org:
#* Copyright (c) 1998-2001 Dr John Maddock
#*<p>
#* Permission is granted to use, modify and redistribute this
#* software provided both copyrights appear in all copies.
#*<p>
#* This script and dll provides WinRunner with perl-like
#* regular expression search and match functions, to supplement
#* the limited builtin function match() and add GUI properties
#* "label_like" and "id_like" for window recognition.
#*<p>
#* Known bugs:
#* <ul>
#* <li> Garbage in re can cause regex library to crash</li>
#* </ul>
#* @author Misha Verplack
#* @version 0.2 2003-01-21
#*
#* @see <a href="readme.txt">Readme</a>
#* @see <a href="re_sample.tsl">sample</a>
#* @see <a href="re_startup.tsl">startup</a>
#* @see <a href="syntax.html">Regex syntax description</a>
#*/
# regular expressions from DLL
#/**
#* Match a regular expression to a whole string.
#* Submatch results in 'detail', use re_get_details() or re_get_match().
#* @param str string to search
#* @param re regular expression
#* @param m_pos matched position
#* @param m_len matched length
#* @param detail detail
#* @return 0 = no match, 1 = found match, gets position and length
#*/
extern int re_match(string str, string re, out int m_pos, out int m_len, inout string detail <252>);
#/**
#* Search a string for a regular expression.
#* Submatch results in 'detail', use re_get_details() or re_get_match().
#* @param str string to search
#* @param re regular expression
#* @param m_pos matched position
#* @param m_len matched length
#* @param detail detail
#* @return 0 = no match, 1 = found match, gets position and length
#*/
extern int re_search(string str, string re, out int m_pos, out int m_len, inout string detail <252>);
#/**
#* initialises the re_func
#*/
public function re_func_init()
{
auto re_func_dll;
# replace with location of dll
re_func_dll = getvar("testname") & "\\re_func.dll";
# to access exported functions
load_dll(re_func_dll);
# to use re's in a GUI property
add_record_attr("label_like", re_func_dll, "re_query_label", "re_verify_label");
add_record_attr("id_like", re_func_dll, "re_query_id", "re_verify_id");
# function generator declarations
generator_add_function("re_search","Search a string for a regular expression.\n"&
"Returns 0 no match, 1 found match, gets position and length.\n"&
"Submatch results in 'detail', use re_get_details() or re_get_match().",5,
"search_string","type_edit","\"string to search\"",
"regular_expression","type_edit","\"regexp\"", "Out position","type_edit","position",
"Out length","type_edit","len", "Out detail","type_edit","detail");
generator_add_category("regex");
generator_add_function_to_category("regex","re_search");
generator_set_default_function("regex","re_search");
generator_add_function("re_match","Match a regular expression to a whole string.\n"&
"Returns 0 no match, 1 found match, gets position and length.\n"&
"Submatch results in 'detail', use re_get_details() or re_get_match().",5,
"match_string","type_edit","\"string to match\"",
"regular_expression","type_edit","\"regexp\"", "Out position","type_edit","position",
"Out length","type_edit","len", "Out detail","type_edit","detail");
generator_add_function_to_category("regex","re_match");
generator_add_function("re_get_detail","Get the (sub)match position and length from the detail.\n"&
"Typically used after re_search() or re_match()\nsubmatch can be 0 for whole match",6,
"detail","type_edit","detail", "submatch","type_edit","0", "Out nsubs","type_edit","nsubs",
"Out line","type_edit","line", "Out position","type_edit","position", "Out length","type_edit","len");
generator_add_function_to_category("regex","re_get_detail");
generator_add_function("re_get_match","Get the (sub)matched string from the detail.\n"&
"Typically used after re_search() or re_match()\nsubmatch can be 0 for whole match",4,
"original_string","type_edit","orig_str", "detail","type_edit","detail",
"submatch","type_edit","0", "Out match_str","type_edit","match_str");
generator_add_function_to_category("regex","re_get_match");
generator_add_function("re_print_detail","Print the re match details to the debug window.\n"&
"Typically used after re_search() or re_match().",1, "detail","type_edit","detail");
generator_add_function_to_category("regex","re_print_detail");
}
# internal function to decode detail from DLL
#/**
#* @param detail
#* @param position
#* @param nbytes
#* @return
#*/
static function _detail_decode(detail, position, nbytes)
{
auto v, v_hi;
v = int(ascii(substr(detail, position, 1))/2);
if(nbytes == 2)
{
v_hi = int(ascii(substr(detail, position+1, 1))/2);
v += v_hi*256;
}
return v;
}
# dump the detail to WinRunner's debug window
# structure of the detail string:
#/**
#* Print the re match details to the debug window.
#* Typically used after re_search() or re_match().
#* @param detail
#* (1 byte ) size of this detail, ie. number of submatches + 1
#* (2 bytes) line number where match occurred, counting from 1
#* [(2 bytes) position of (sub)match, 0-th submatch is whole match
#* [(2 bytes) length of (sub)match
#* [--------- repeated to a maximum of 50 submatches ---]
#* @return
#*/
public function re_print_detail(detail)
{
auto size, line, i, pos, len, s;
size = _detail_decode(detail, 1, 1);
print "size " & size;
if (size == 0) return E_OK;
print "submatches " & (size-1);
line = _detail_decode(detail, 2, 2);
print "line " & line;
for (s=0; s<size; s++)
{
pos = _detail_decode(detail, s*4+4, 2);
len = _detail_decode(detail, s*4+6, 2);
print "sub(" & s & ") pos: " & pos & " len: " & len;
}
return E_OK;
}
# get the (sub)match position and length from the detail
#/**
#* Get the (sub)match position and length from the detail.
#* Typically used after re_search() or re_match()\nsubmatch can be 0 for whole match.
#*
#* @param detail
#* @param submatch
#* @param nsubs
#* @param line
#* @param position
#* @param len
#* @return
#*/
public function re_get_detail(in detail, in submatch, out nsubs, out line, out position, out len)
{
auto size;
nsubs = 0;
position = 0;
len = 0;
line = 0;
size = _detail_decode(detail, 1, 1);
if (size == 0) return E_NOT_FOUND;
nsubs = size-1;
if (submatch < 0) return E_OUT_OF_RANGE;
if (submatch+1 > size) return E_OUT_OF_RANGE;
line = _detail_decode(detail, 2, 2);
position = _detail_decode(detail, submatch*4+4, 2);
len = _detail_decode(detail, submatch*4+6, 2);
return E_OK;
}
# get the (sub)matched string from the detail
#/**
#* Get the (sub)matched string from the detail.
#* Typically used after re_search() or re_match()\nsubmatch can be 0 for whole match.
#* @param orig_str
#* @param detail
#* @param submatch
#* @param match_str
#* @return
#*/
public function re_get_match(in orig_str, in detail, in submatch, out match_str)
{
auto rc, nsubs, position, len, line;
match_str = "";
rc = re_get_detail(detail, submatch, nsubs, line, position, len);
if (rc != E_OK) return rc;
match_str = substr(orig_str, position+1, len);
return E_OK;
}
#------------------------------------------------------