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:
to something like this:
TL;DR: Was passing an implicitly created temporary to
regEx->match
andGlib::MatchInfo
needs to access theGlib::ustring
reference.Turns out that the problem is this:
regEx->match(fileName, match)
takesconst Glib::ustring &
as its first parameter, but I was passing itconst std::string &
which was being implicitly converted. In most cases, this would be fine, however, theGMatchInfo
object under the hood ofGlib::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 callregEx->match
with astd::string
parameter, a temporaryGlib::ustring
object is created whileregEx->match
is executing and is destroyed after it finishes. This means that the data thatGlib::MatchInfo
is accessing is now invalid and therefore junk is returned. By usingGlib::filename_to_utf8
, I create a variable with a lifetime that exceeds the use of theGlib::MatchInfo
object that is using it, and use and appropriate conversion function.Hopefully, this helps anyone else that encounters this.