in LCM/codec/mof/parser/utility.c [706:859]
MI_Boolean mof_match(MOF_Encoding e, _In_ MOF_StringLen *data, _In_ MOF_StringLen *pattern)
{
unsigned char cset[256];
MOF_Buffer d = {0}, p ={0};
if (!(data->str.data) || !(pattern->str.data))
{
return MI_FALSE;
}
/* setup buffers for matching */
{
size_t ds = data->len * (e.u ? sizeof(wchar_t) : sizeof(char));
size_t ps = pattern->len * (e.u ? sizeof(wchar_t) : sizeof(char));
mof_setupbuffer_intl(data->str.data, ds, e, &d);
mof_setupbuffer_intl(pattern->str.data, ps, e, &p);
}
while (mof_neof(&p))
{
int c = mof_getchar(p.e, p.cur);
switch(c)
{
case '[':
// a set, find ']', and read one more char, a char after ']' could be '*', '?', '+'
// only support [x-ym-n] [xyz]
{
int c1, c2, c3;
int ci;
memset(cset, 0, 256*sizeof(unsigned char));
c1 = mof_nextchar(&p);
while(mof_neof(&p) && (c1 != ']'))
{
c2 = mof_nextchar(&p);
if (isalnum(c1) && c2 == '-')
{
c3 = mof_nextchar(&p);
for (ci = c1; ci <= c3; ci++)
{
cset[ci] = 1;
}
}
else
{
_Analysis_assume_(c1 < 256);
_Analysis_assume_(c2 < 256);
cset[c1] = cset[c2] = 1;
}
c1 = mof_nextchar(&p);
}
if (mof_eof(&p))
{
return MI_FALSE;
}
c1 = mof_nextchar(&p);
switch(c1)
{
case '*':// 0+ match
{
while(mof_neof(&d))
{
if (cset[mof_getchar(d.e, d.cur)] != 1)
break;
mof_nextchar(&d);
}
}
mof_nextchar(&p);
break;
case '+':// 1+ match
{
int dc;
if (mof_eof(&d))
return MI_FALSE;
// match first char
if (cset[mof_getchar(d.e, d.cur)] != 1)
{
return MI_FALSE;
}
dc = mof_nextchar(&d);
while(mof_neof(&d))
{
if (cset[dc] != 1)
break;
dc = mof_nextchar(&d);
}
}
mof_nextchar(&p);
break;
case '?':// 0 or 1 match
{
if (mof_neof(&d))
{
if (cset[mof_getchar(d.e, d.cur)] == 1)
{
mof_nextchar(&d);
}
}
}
mof_nextchar(&p);
break;
default: // 1 match
{
if (mof_eof(&d))
return MI_FALSE;
// have to match one char
if (cset[mof_getchar(d.e, d.cur)] != 1)
{
return MI_FALSE;
}
mof_nextchar(&d);
}
break;
}
}
break;
case '(':
// only support '()?' pattern which at the end, for realvalue only
{
if (mof_neof(&d))
{
MOF_StringLen d2;
MOF_StringLen p2;
d2.str.data = d.cur;
d2.len = data->len - mof_offset(d.e.u, data->str.data, d.cur);
mof_nextchar(&p);
p2.str.data = p.cur;
p2.len = pattern->len - mof_offset(p.e.u, pattern->str.data, p.cur) -2;
return mof_match(e, &d2, &p2);
}
else // in this case, it is matched
{
return MI_TRUE;
}
}
break;
default:
// single char match
{
if (mof_eof(&d))
return MI_FALSE;
if (c != mof_getchar(d.e, d.cur))
return MI_FALSE;
mof_nextchar(&d);
mof_nextchar(&p);
}
break;
}
}
if (mof_eof(&p) && mof_eof(&d)) return MI_TRUE;
return MI_FALSE;
}