Repository URL to install this package:
Version:
9.0~240807-1.fc42 ▾
|
//
// Rules to improve name readability
//
// Regular expressions in this file use PCRE2 extended syntax (PCRE2_EXTENDED)
// and substituon extended syntax (PCRE2_SUBSTITUTE_EXTENDED).
// Please do not forget to double backslashes, single backslashes are
// intepreted as escape sequences.
//
// Detailed explanations about the format of this file are at the end.
//
// Use -z2000000 command line IDA option to debug regular expressions.
// Regular expression library.
//
// Format:
// id : entry
//
// LIBRARY is a collection of named strings.
// The names can be used in SUBSTRULES, for example R0011 uses T1.
LIBRARY =
{
// placeholder for template argument,
// for example:
// unsigned short
// mytempl<int>
// mytempl2<int,myalloc<int>>
// void (*)(void*)
T1 : "[^><,)(]+"
"(?:"
"(?<idapn10> <([^<>]++|(?&idapn10))*> )" // match to the balanced <>
"|"
"(?: \\s*[(][*][)]\\s* (?<idapn11> [(]([^()]++|(?&idapn11))*[)] ))" // match to the balanced ()
")?",
// We need the second T1-like template, for example for std::map.
// But there is a need to change the used sub-pattern names.
T2 : { use: "T1", ptn : "idapn1", rpl : "idapn2" },
// Input/Output streams
IOstreams : "filebuf|fstream|ifstream|ofstream|ios|iostream|istream|ostream|streambuf",
// Operators
Ops : "[-+*/%^&|~!=<>]|[-+*/%^&|]=|<<|>>|>>=|<<=|==|!=|<=|>=|<=>|&&|[|][|]|[+][+]|--|,|->[*]|->|()|[[][\\]]"
}
// Rules.
//
// Format:
// name : { ptn : "pattern string", rpl : "replacement string" }
//
// The rule name is any string. It does not have any special meaning
// and is used only for diagnostics.
// Rules are applied in the order they're defined.
SUBSTRULES =
{
// remove the implementation (version) namespace
// std::__1::
// std::__ndk1::
// std::__cxx11::
// to
// std::
R0001 :
{
ptn : "std::(?: __[0-9]|__(ndk|cxx1)[0-9] )::",
rpl : "std::"
},
// std::
// std::basic_string<charT,std::char_traits<charT>,std::allocator<charT>>
// to
// std::basic_string<charT>
// std::basic_string<char,std::char_traits<char>,std::allocator<char>>::basic_string<char,std::char_traits<char>,std::allocator<char>>
R0011 :
{
ptn : "std::(?<C> basic_string<"
"(?<charT> (?&T1) )" // entry T1 will be taken from LIBRARY
",\\s*"
"std::char_traits<(?&charT) \\s*>"
",\\s*"
"std::allocator<(?&charT) \\s*>"
"(?: \\s*,\\s*_STL70)?"
"\\s*> )"
"(?<Ctor> ::(?<Dtor> [~])?(?&C) )?",
rpl : "std::basic_string<$charT>${Ctor:+\\:\\:${Dtor:+~:}basic_string<$charT>}"
},
// std::basic_string<char>
// to
// std::string
R0012 :
{
ptn : "std::basic_string<char>"
"(?: (?<Ctor> ::basic_string<char> )|(?<Dtor> ::~basic_string(?:<char>)? ) )?",
rpl : "std::string${Ctor:+\\:\\:string}${Dtor:+\\:\\:~string:}"
},
// std::basic_string<unsigned short>
// to
// std::wstring
//
// std::basic_string<wchar_t>
R0013 :
{
ptn : "std::basic_string<(?<Wchar> unsigned[ ]short|ushort|wchar_t \\s*)>" // remember about PCRE2 extended syntax
"(?: (?<Ctor> ::basic_string<(?&Wchar)> )|(?<Dtor> ::~basic_string(?:<(?&Wchar)>)? ) )?",
rpl : "std::wstring${Ctor:+\\:\\:wstring}${Dtor:+\\:\\:~wstring:}"
},
//
// Containers
//
// Sequence containers:
// std::TEMPLATE<T,std::allocator<T>>
// to
// std::TEMPLATE<T>
//
// std::vector<T,std::allocator<T> >
// std::deque<T,std::allocator<T> >
// std::forward_list<T,std::allocator<T> >
// std::list<T,std::allocator<T> >
R0021 :
{
ptn : "std::(?<C> (?<Vector> \\w+ )<"
"(?<T> (?&T1) )" // entry T1 will be taken from LIBRARY
",\\s*"
"std::allocator<(?&T) \\s*> \\s*[&]?"
"\\s*> )"
"(?<Ctor> ::(?<Dtor> [~])?(?&C) )?",
rpl : "std::$Vector<$T>${Ctor:+\\:\\:${Dtor:+~:}$Vector<$T>}"
},
// Container adaptors:
// std::stack<int,std::deque<int> >
// to
// std::stack<int>
//
// std::queue<int,std::deque<int> >
R0022 :
{
ptn : "std::(?<C> (?<Stack> stack|queue )<"
"(?<T> (?&T1) )" // entry T1 will be taken from LIBRARY
",\\s*"
"std::deque<(?&T) \\s*>"
"\\s*> )"
"(?<Ctor> ::(?<Dtor> [~])?(?&C) )?",
rpl : "std::$Stack<$T>${Ctor:+\\:\\:${Dtor:+~:}$Stack<$T>}"
},
// std::priority_queue<T3d::App::TimeEvent,std::vector<T3d::App::TimeEvent>,std::less<T3d::App::TimeEvent> >;
R0023 :
{
ptn : "std::(?<C> priority_queue<"
"(?<T> (?&T1) )" // entry T1 will be taken from LIBRARY
",\\s*"
"std::vector<(?&T) \\s*>"
",\\s*"
"std::less<(?&T) \\s*>"
"\\s*> )"
"(?<Ctor> ::(?<Dtor> [~])?(?&C) )?",
rpl : "std::priority_queue<$T>${Ctor:+\\:\\:${Dtor:+~:}$Stack<$T>}"
},
// Associative containers:
// std::TEMPLATE<T,std::less<T>,std::allocator<T>>
// to
// std::TEMPLATE<T>
//
// std::set<T,std::less<T>,std::allocator<T>>
// std::multiset<T,std::less<T>,std::allocator<T>>
// std::__tree<std::string,std::less<std::string>,std::allocator<std::string>>
R0031 :
{
ptn : "std::(?<C> (?<Set> \\w+ )<"
"(?<T> (?&T1) )"
",\\s*"
"std::less<(?&T) \\s*>"
",\\s*"
"std::allocator<(?&T) \\s*>"
"\\s*> )"
"(?<Ctor> ::(?<Dtor> [~])?(?&C) )?",
rpl : "std::$Set<$T>${Ctor:+\\:\\:${Dtor:+~:}$Set<$T>}"
},
// std::map<Key,T,std::less<Key>,std::allocator<std::pair<Key,T>>>
// to
// std::map<Key,T>
//
// std::multimap<Key,T,std::less<Key>,std::allocator<std::pair<Key,T>>>
R0032 :
{
ptn : "std::(?<C> (?<Map> map|multimap )<"
"(?<Key> (?&T1) )"
",\\s*"
"(?<T> (?&T2) )"
",\\s*"
"std::less<(?&Key) \\s*>"
",\\s*"
"std::allocator<"
"std::pair<(?: const\\s+ )? (?&Key) (?: \\s+const )?, (?&T) \\s*>"
"\\s*>"
"\\s*> )"
"(?<Ctor> ::(?<Dtor> [~])?(?&C) )?",
rpl : "std::$Map<$Key,$T>${Ctor:+\\:\\:${Dtor:+~:}$Map<$Key,$T>}"
},
// Unordered associative containers:
// std::unordered_set<Key,std::hash<Key>,std::equal_to<Key>,std::allocator<Key> >
// to
// std::unordered_set<Key>
//
// std::unordered_multiset<Key,std::hash<Key>,std::equal_to<Key>,std::allocator<Key> >
R0041 :
{
ptn : "std::(?<C> (?<UnSet> unordered_set|unordered_multiset )<"
"(?<Key> (?&T1) )"
",\\s*"
"std::hash<(?&Key) \\s*>"
",\\s*"
"std::equal_to<(?&Key) \\s*>"
",\\s*"
"std::allocator<(?&Key) \\s*>"
"\\s*> )"
"(?<Ctor> ::(?&C) )?",
rpl : "std::$UnSet<$Key>${Ctor:+\\:\\:$UnSet<$Key>}"
},
// std::unordered_map<Key,T,std::hash<Key>,std::equal_to<Key>,std::allocator<std::pair<const Key,T>>>
// to
// std::unordered_map<Key,T>
//
// std::unordered_multimap<Key,T,std::hash<Key>,std::equal_to<Key>,std::allocator<std::pair<const Key,T>>>
R0042 :
{
ptn : "std::(?<C> (?<UnMap> unordered_map|unordered_multimap )<"
"(?<Key> (?&T1) )"
","
"(?<T> (?&T2) )"
",\\s*"
"std::hash<(?&Key) \\s*>"
",\\s*"
"std::equal_to<(?&Key) \\s*>"
",\\s*"
"std::allocator<"
"std::pair<(?: const\\s+ )? (?&Key) (?: \\s+const )?, (?&T) \\s*>"
"\\s*>"
"\\s*> )"
"(?<Ctor> ::(?<Dtor> [~])?(?&C) )?",
rpl : "std::$UnMap<$Key,$T>${Ctor:+\\:\\:${Dtor:+~:}$UnMap<$Key,$T>}"
},
//
// Input/Output
//
// std::basic_filebuf<charT,std::char_traits<charT>>
// std::basic_fstream<charT,std::char_traits<charT>>
// std::basic_ifstream<charT,std::char_traits<charT> >
// std::basic_ofstream<charT,std::char_traits<charT> >
// std::basic_ios<charT,std::char_traits<charT>>
// std::basic_iostream<charT, std::char_traits<charT>>
// std::basic_istream<charT, std::char_traits<charT>>
// std::basic_ostream<charT, std::char_traits<charT>>
// std::basic_streambuf<charT,std::char_traits<charT>>
//
// std::istreambuf_iterator<charT,std::char_traits<charT>>
// std::ostreambuf_iterator<charT,std::char_traits<charT>>
R0051 :
{
ptn : "std::(?<C> (?<IO> basic_(?: (?&IOstreams) )|istreambuf_iterator|ostreambuf_iterator )<"
"(?<charT> (?&T1) )"
",\\s*"
"(?:struct\\s+)?std::char_traits<(?&charT) \\s*>"
"\\s*> )"
"(?<Ctor> ::(?&C) )?",
rpl : "std::$IO<$charT>${Ctor:+\\:\\:$IO<$charT>}"
},
// std::basic_istringstream<charT,std::char_traits<charT>,std::allocator<charT>>
// std::basic_ostringstream<charT, std::char_traits<charT>, std::allocator<charT>>
// std::basic_stringbuf<char,std::char_traits<char>,std::allocator<char>>
R0052 :
{
ptn : "std::(?<C> (?<IO> basic_(?: istringstream|ostringstream|stringbuf ) )<"
"(?<charT> (?&T1) )"
",\\s*"
"std::char_traits<(?&charT) \\s*>"
",\\s*"
"std::allocator<(?&charT) \\s*>"
"\\s*> )"
"(?<Ctor> ::(?<Dtor> [~])?(?&C) )?",
rpl : "std::$IO<$charT>${Ctor:+\\:\\:${Dtor:+~:}$IO<$charT>}"
},
// typedef basic_filebuf<char> filebuf
// typedef basic_fstream<char> fstream
// typedef basic_ifstream<char> ifstream
// typedef basic_ofstream<char> ofstream
// typedef basic_ios<char> ios
// typedef basic_iostream<char> iostream
// typedef basic_istream<char> iostream
// typedef basic_ostream<char> ostream
// typedef basic_streambuf<char> streambuf
// typedef basic_istringstream<char> istringstream
// typedef basic_ostringstream<char> ostringstream
// typedef basic_stringbuf<char> stringbuf
R0053 :
{
ptn : "std::(?<T> basic_(?<IO> (?&IOstreams)|istringstream|ostringstream|stringbuf ) )<char\\s*>"
"(?: (?<Ctor> ::(?&T)<char\\s*> )|(?<Dtor> ::~(?&T)\\b(?:<char\\s*>)? ) )?",
rpl : "std::$IO${Ctor:+\\:\\:$IO}${Dtor:+\\:\\:~$IO:}"
},
// typedef basic_filebuf<wchar_t> wfilebuf
// typedef basic_fstream<wchar_t> wfstream
// typedef basic_ifstream<wchar_t> wifstream
// typedef basic_ofstream<wchar_t> wofstream
// typedef basic_ios<wchar_t> ios
// typedef basic_iostream<wchar_t> wiostream
// typedef basic_istream<wchar_t> wiostream
// typedef basic_ostream<wchar_t> wostream
// typedef basic_streambuf<wchar_t> wstreambuf
// typedef basic_istringstream<wchar_t> wistringstream
// typedef basic_ostringstream<wchar_t> wostringstream
// typedef basic_stringbuf<wchar_t> wstringbuf
R0054 :
{
ptn : "std::(?<T> basic_(?<IO> (?&IOstreams)|istringstream|ostringstream|stringbuf ) )<wchar_t\\s*>"
"(?: (?<Ctor> ::(?&T)<wchar_t\\s*> )|(?<Dtor> ::~(?&T)\\b(?:<wchar_t\\s*>)? ) )?",
rpl : "std::w$IO${Ctor:+\\:\\:w$IO}${Dtor:+\\:\\:~w$IO:}"
},
//
// Memory
//
// std::unique_ptr<T,std::default_delete<T>>::~unique_ptr<T,std::default_delete<T>>
R0061 :
{
ptn : "std::(?<C> (?<Tpl> unique_ptr )<"
"(?<T> (?&T1) )"
",\\s*"
"std::default_delete<(?&T) \\s*>"
"\\s*> )"
"(?<Ctor> ::(?<Dtor> [~])?(?&C) )?",
rpl : "std::$Tpl<$T>${Ctor:+\\:\\:${Dtor:+~:}$Tpl<$T>}"
},
// std::__shared_ptr_pointer<std::vector<std::string> *,std::default_delete<std::vector<std::string>>,std::allocator<std::vector<std::string>>>
R0062 :
{
ptn : "std::(?<C> (?<Tpl> __shared_ptr_pointer )<"
"(?<T> (?&T1) ) \\s*[*]"
",\\s*"
"std::default_delete<(?&T) \\s*>"
",\\s*"
"std::allocator<(?&T) \\s*>"
"\\s*> )"
"(?<Ctor> ::(?<Dtor> [~])?(?&C) )?",
rpl : "std::$Tpl<$T *>${Ctor:+\\:\\:${Dtor:+~:}$Tpl<$T>}"
},
// __gnu_cxx::stdio_filebuf<wchar_t,std::char_traits<wchar_t> >
// __gnu_cxx::stdio_sync_filebuf<char,std::char_traits<char> >
R0071 :
{
ptn : "__gnu_cxx::(?<C> (?<Tpl> stdio_filebuf|stdio_sync_filebuf )<"
"(?<T> (?&T1) )"
",\\s*"
"std::char_traits<(?&T) \\s*>"
"\\s*> )"
"(?<Ctor> ::(?<Dtor> [~])?(?&C) )?",
rpl : "__gnu_cxx::$Tpl<$T>${Ctor:+\\:\\:${Dtor:+~:}$Tpl<$T>}"
},
// __gnu_cxx::rope<wchar_t,std::allocator<wchar_t> >
R0072 :
{
ptn : "__gnu_cxx::(?<C> (?<Tpl> rope )<"
"(?<T> (?&T1) )"
",\\s*"
"std::allocator<(?&T) \\s*>"
"\\s*> )"
"(?<Ctor> ::(?<Dtor> [~])?(?&C) )?",
rpl : "__gnu_cxx::$Tpl<$T>${Ctor:+\\:\\:${Dtor:+~:}$Tpl<$T>}"
},
// boost::variant<bar::A,bar::B,boost::detail::variant::void_,...>
R0081 :
{
ptn : "boost::variant<(?<U>.*?)(?:\\s*,\\s*boost::detail::variant::void_)+>",
rpl : "boost::variant<$U>"
},
// Operators
//
// std::operator!=<char,std::char_traits<char>,std::allocator<char>>
R0091 :
{
ptn : "std::operator (?<OP> (?&Ops) ) <"
"(?<T> (?&T1) )"
",\\s*"
"std::char_traits<(?&T) \\s*>"
",\\s*"
"std::allocator<(?&T) \\s*>"
"\\s*>",
rpl : "std::operator$OP<$T>"
},
// std::basic_string_view<char,std::char_traits<char>>
R0101 :
{
ptn : "std::basic_string_view<"
"(?<charT> (?&T1) )"
",\\s*"
"std::char_traits<(?&charT) \\s*>"
"\\s*>",
rpl : "std::basic_string_view<$charT>"
},
R0102 : { ptn : "std::basic_string_view<char>", rpl : "std::string_view" },
R0103 : { ptn : "std::basic_string_view<wchar_t>", rpl : "std::wstring_view" },
R0104 : { ptn : "std::basic_string_view<char8_t>", rpl : "std::u8string_view" },
R0105 : { ptn : "std::basic_string_view<char16_t>", rpl : "std::u16string_view" },
R0106 : { ptn : "std:::basic_string_view<char32_t>", rpl : "std::u32string_view" }
}
/* This is a markdown text
# How to add rules to goodname.cfg
Note: the reader is supposed to know and understand the syntax of the PCRE2 extended regular expressions.
## Structure of goodname.cfg
*goodname.cfg* consists of two variables: `LIBRARY` and `SUBSTRULES`.
`LIBRARY` is a collection of named entries of two different types:
1. a regular regex, for example:
IOstreams : "filebuf|fstream|ifstream|ofstream|ios|iostream|istream|ostream|streambuf"
2. a transformation, for example:
T2 : { use: "T1", ptn : "idapn1", rpl : "idapn2" }
This transformation rule generates a new string named "T2"
by replacing every "idapn1" by "idapn2" in "T1".
"T1" must be defined before "T2".
The `LIBRARY` entries may be referenced by `SUBSTRULES`.
For example, there is a useful entry named "T1" in goodname.cfg as it is shipped,
and you can use it in the place of a template type.
`SUBSTRULES` is a collection substitution rules.
The rule format is:
name : { ptn : "pattern string", rpl : "replacement string" }
Every rule has a name, any string may be used for it.
There are no limitations on the rule name.
If the rule name looks like an identifier, you can use it as is.
Otherwise enclose it in quotes.
`ptn` is a regular expression in the PCRE2 extended format with one addition.
It may contain references to library entries, which will be substituted by
their value. References to library entries look like this:
(?&T1)
where `T1` is the name of a LIBRARY entry.
All substitutions will be performed before compiling the regular expression.
After performing all subsitutions `ptn` must contain a valid regular expression.
`rpl` is a replacement string.
It is not possible to use LIBRARY entries in it.
The replacement string must follow the PCRE2 substitution extended syntax.
To beautify a name IDA applies all rules in the definition order.
## User config file
You can define rules in the local config file %USERDIR%/goodname.cfg.
New rules will be added to the end of the rule list.
Old rules will be overriden by the user's local definition without changing
their position in the list.
## How to debug regular expressions
As a trivial example we will add the following rule:
R9999 : { ptn : ">[ ]>", rpl : ">>" }
This rule will remove a space between angle brackets.
First you need to check that the regular expression is correct and can be
compiled by IDA. For that use the "-z2000000" command line option.
It is also a good idea to use the -L option to specify the log file.
For example:
idat -Lida.log -z2000000 any.idb
Check all lines which start with "RX: " prefix in the ida.log file.
The `LIBRARY` entries are printed first:
RX: LIBRARY T1 : ...
...
After that every rule is printed as it gets compiled.
Let us look at the output for the rule `R9999`:
RX: compiled ptn R9999 : />[ ]>/x,substitute_extended,replace=>>
The next step is to use a useful utility to debug regular expressions.
It is called `pcre2test`.
Let us create a test file named "inp.txt".
First copy the above string to "inp.txt" and
remove the "RX: compiled ptn R9999 : " prefix from it.
After that add your test cases, for example, like this:
# R9999
/>[ ]>/x,substitute_extended,replace=>>
std::set<std::vector<int> >
Now run the `pcre2test` utility:
pcre2test inp.txt >out.txt
If there are no errors, the out.txt will contain:
# R9999
/>[ ]>/x,substitute_extended,replace=>>
std::set<std::vector<int> >
1: std::set<std::vector<int>>
This is how you can debug regular expressions without running IDA or
opening a database.
Please note that IDA logs regular expressions
in the format accepted by the pcre2test utility.
This simplifies debugging of regular expressions.
### There is one exception
Because `pcre2test` can not handle commas in the substitution part
IDA will replace all commas by `"|comma|"` string.
For example, rule like a:
R9999 : { ptn : "abc", rpl : "x, y, z" }
will be logged as:
RX: compiled ptn R9999 : /abc/x,substitute_extended,replace=x|comma| y|comma| z
*/