dirk/C++/glibmm/patternSpec
Ravensburg, 10-02-08
patternSpec – Glob-style Pattern Matching
Actually, I was looking for a possibility to search directories for files with a certain pattern.
Instead of the desired functions/classes, I found the Glib::PatternSpec class.
Although this wasn't my actual intention, I gave it a try having in mind just another problem I had to solve in my current professional development.
One of my main issues: does the pattern matching accept slashes ('/') in place-holder expressions like '*'.
If so, I could use it to process certain property rules in the manner of X11 resource files.
Glob-Style vs. Regular Expressions
Glob-style pattern matching is easy to use and for most users wellknown due to daily file work.
Regular expressions are much more powerful but only few people know how it works.
IMHO user friendly software should left the choice to the user.
Source Code
patternSpec.cc |
/** @file sample for Glib::PatternSpec
*
* Last CVS checkin:
* $Date: $
* $Author: scheff $
*/
/**************************************************************************/
// standard C/C++ header:
#include <iostream>
#include <string>
// Gnome header:
#include <glibmm/init.h>
#include <glibmm/pattern.h>
using namespace std;
/**************************************************************************/
/** waits for user confirm.
*
* @param action text with next action
*/
static void pause(const char *action)
{
cout << "Press [ENTER] to " << action << ": " << flush;
string str; getline(cin, str);
}
/** provides the main function of application.
*
* @param argc number of command line arguments
* @param argv pointer to array of pointers to strings with command line
* arguments
* @return 0 ... application exited regularly\n
* else ... execution of application aborted
*/
int main(int argc, char *argv[])
{
Glib::init();
pause("start");
// sample data
const char *patterns[] = {
"*",
"Base*",
"Base/*",
"*Base*",
"Robot*",
"*Robot*",
"*/Robot",
"*/Robot*",
"*/Robot/*"
};
int m = sizeof patterns / sizeof patterns[0];
const char *samples[] = {
"",
"Base",
"Base/Resource",
"Base/Resource/Robot",
"Base/Resource/Robot/KUKA",
"Base/Resource/Robot/KUKA/KR360"
};
int n = sizeof samples / sizeof samples[0];
// for each pattern and each sample do:
for (int i = 0; i < m; ++i) {
Glib::PatternSpec patternSpec(patterns[i]);
cout << "Pattern: '" << patterns[i] << "':" << endl;
for (int j = 0; j < n; ++j) {
const char *sample = samples[j];
cout << " Check '" << sample << "':" << endl
<< " " << (patternSpec.match(sample) ? "OK." : "Not matching.")
<< endl;
}
// wait for confirm
pause("continue");
}
// done
pause("finish");
return 0;
}
|
I compiled this sample on Linux with:
> g++ -o patternSpec `pkg-config glibmm-2.4 --cflags --libs` patternSpec.cc↵
>
|
Output
| Console: |
Press [ENTER] to start: ↵
Pattern: '*':
Check '':
OK.
Check 'Base':
OK.
Check 'Base/Resource':
OK.
Check 'Base/Resource/Robot':
OK.
Check 'Base/Resource/Robot/KUKA':
OK.
Check 'Base/Resource/Robot/KUKA/KR360':
OK.
Press [ENTER] to continue: ↵
Pattern: 'Base*':
Check '':
Not matching.
Check 'Base':
OK.
Check 'Base/Resource':
OK.
Check 'Base/Resource/Robot':
OK.
Check 'Base/Resource/Robot/KUKA':
OK.
Check 'Base/Resource/Robot/KUKA/KR360':
OK.
Press [ENTER] to continue: ↵
Pattern: 'Base/*':
Check '':
Not matching.
Check 'Base':
Not matching.
Check 'Base/Resource':
OK.
Check 'Base/Resource/Robot':
OK.
Check 'Base/Resource/Robot/KUKA':
OK.
Check 'Base/Resource/Robot/KUKA/KR360':
OK.
Press [ENTER] to continue: ↵
Pattern: '*Base*':
Check '':
Not matching.
Check 'Base':
OK.
Check 'Base/Resource':
OK.
Check 'Base/Resource/Robot':
OK.
Check 'Base/Resource/Robot/KUKA':
OK.
Check 'Base/Resource/Robot/KUKA/KR360':
OK.
Press [ENTER] to continue: ↵
Pattern: 'Robot*':
Check '':
Not matching.
Check 'Base':
Not matching.
Check 'Base/Resource':
Not matching.
Check 'Base/Resource/Robot':
Not matching.
Check 'Base/Resource/Robot/KUKA':
Not matching.
Check 'Base/Resource/Robot/KUKA/KR360':
Not matching.
Press [ENTER] to continue: ↵
Pattern: '*Robot*':
Check '':
Not matching.
Check 'Base':
Not matching.
Check 'Base/Resource':
Not matching.
Check 'Base/Resource/Robot':
OK.
Check 'Base/Resource/Robot/KUKA':
OK.
Check 'Base/Resource/Robot/KUKA/KR360':
OK.
Press [ENTER] to continue: ↵
Pattern: '*/Robot':
Check '':
Not matching.
Check 'Base':
Not matching.
Check 'Base/Resource':
Not matching.
Check 'Base/Resource/Robot':
OK.
Check 'Base/Resource/Robot/KUKA':
Not matching.
Check 'Base/Resource/Robot/KUKA/KR360':
Not matching.
Press [ENTER] to continue: ↵
Pattern: '*/Robot*':
Check '':
Not matching.
Check 'Base':
Not matching.
Check 'Base/Resource':
Not matching.
Check 'Base/Resource/Robot':
OK.
Check 'Base/Resource/Robot/KUKA':
OK.
Check 'Base/Resource/Robot/KUKA/KR360':
OK.
Press [ENTER] to continue: ↵
Pattern: '*/Robot/*':
Check '':
Not matching.
Check 'Base':
Not matching.
Check 'Base/Resource':
Not matching.
Check 'Base/Resource/Robot':
Not matching.
Check 'Base/Resource/Robot/KUKA':
OK.
Check 'Base/Resource/Robot/KUKA/KR360':
OK.
Press [ENTER] to continue: ↵
Press [ENTER] to finish: ↵
|
Conclusion
It does exactly what I expected.
Files
dirk/C++/glibmm/patternSpec
Last modified: Sun Feb 28 13:52:07 2010