I'm trying to use the Glib::Regex, but it keeps returning junk.
Here is a simplified version of the code:
void testGetPos(std::string fileName){
auto regEx = Glib::Regex::create(
"^sprite_[0-9]+__x(-?[0-9]+)_y(-?[0-9]+)\\.tif$",
Glib::REGEX_CASELESS
)
Glib::MatchInfo match;
if(!regEx->match(fileName, match)){
continue;
}
if(!match.matches()){
continue;
}
auto posX = match.fetch(1);
auto posY = match.fetch(2);
// ... Use posX and posY
}
int main(){
testGetPos("sprite_000__x-28_y-32.tif");
}
After this has run, posX and posY are filled with junk. However, using C functions on the wrapped objects:
void testGetPos(std::string fileName){
auto regEx = Glib::Regex::create(
"^sprite_[0-9]+__x(-?[0-9]+)_y(-?[0-9]+)\\.tif$",
Glib::REGEX_CASELESS
)
GMatchInfo *match = nullptr;
if(!g_regex_match(regEx->gobj(), fileName.c_str(), (GRegexMatchFlags)0, &match)){
if(match != nullptr){
g_match_info_free(match);
}
return;
}
auto posX = g_match_info_fetch(match, 1);
auto posY = g_match_info_fetch(match, 2);
// ... Use posX and posY
g_free(posX);
g_free(posY);
g_match_info_free(match);
}
int main(){
testGetPos("sprite_000__x-28_y-32.tif");
}
Works fine. Am I doing something wrong or is this broken.
So, after writing this question, I tried one more thing and that fixed it. Thought I'd better document it here in case someone else hits the same issue.
I changed the equivalent of:
void testGetPos(std::string fileName){
to something like this:
void testGetPos(std::string _fileName){
Glib::ustring fileName = Glib::filename_to_utf8(_fileName);
TL;DR: Was passing an implicitly created temporary to regEx->match
and Glib::MatchInfo
needs to access the Glib::ustring
reference.
Turns out that the problem is this: regEx->match(fileName, match)
takes const Glib::ustring &
as its first parameter, but I was passing it const std::string &
which was being implicitly converted. In most cases, this would be fine, however, the GMatchInfo
object under the hood of Glib::MatchInfo
does not copy the string that is passed to the match function and it needs that data to be available until the object is freed. When I call regEx->match
with a std::string
parameter, a temporary Glib::ustring
object is created while regEx->match
is executing and is destroyed after it finishes. This means that the data that Glib::MatchInfo
is accessing is now invalid and therefore junk is returned. By using Glib::filename_to_utf8
, I create a variable with a lifetime that exceeds the use of the Glib::MatchInfo
object that is using it, and use and appropriate conversion function.
Hopefully, this helps anyone else that encounters this.