in CmdLineParser/CmdLineParser.cpp [403:545]
bool CmdLineParser::_ParseAffinity(const char *arg, TimeSpan *pTimeSpan)
{
bool fOk = true;
assert(nullptr != arg);
assert('\0' != *arg);
const char *c = arg + 1;
// -a and -ag are functionally equivalent; group-aware affinity.
// Note that group-aware affinity is default.
// look for the -a simple case
if (*c == '\0')
{
return true;
}
// look for the -ag simple case
if (*c == 'g')
{
// peek ahead, done?
if (*(c + 1) == '\0')
{
return true;
}
// leave the parser at the g; this is the start of a group number
}
// more complex affinity -ag0,0,1,2,g1,0,1,2,... OR -a0,1,2,..
// n counts the -a prefix, the first parsed character is string index 2
DWORD nGroup = 0, nNum = 0, n = 2;
bool fGroup = false, fNum = false;
while (*c != '\0')
{
if ((*c >= '0') && (*c <= '9'))
{
// accumulating a number
fNum = true;
nNum = 10 * nNum + (*c - '0');
}
else if (*c == 'g')
{
// bad: ggggg
if (fGroup)
{
fOk = false;
}
// now parsing a group number
fGroup = true;
}
else if (*c == ',')
{
// separator; if parsing group and have a number, now have the group
if (fGroup && fNum)
{
if (nNum > MAXWORD)
{
fprintf(stderr, "ERROR: group %u is out of range\n", nNum);
fOk = false;
}
else
{
nGroup = nNum;
nNum = 0;
fGroup = false;
}
}
// at a split but don't have a parsed number, error
else if (!fNum)
{
fOk = false;
}
// have a parsed core number
else
{
if (nNum > MAXBYTE)
{
fprintf(stderr, "ERROR: core %u is out of range\n", nNum);
fOk = false;
}
else
{
pTimeSpan->AddAffinityAssignment((WORD)nGroup, (BYTE)nNum);
nNum = 0;
fNum = false;
}
}
}
else
{
fOk = false;
}
// bail out to error pretty print on error
if (!fOk)
{
break;
}
c++;
n++;
}
// if parsing a group or don't have a final number, error
if (fGroup || !fNum)
{
fOk = false;
}
if (fOk && nNum > MAXBYTE)
{
fprintf(stderr, "ERROR: core %u is out of range\n", nNum);
fOk = false;
}
if (!fOk)
{
// mid-parse error, show the point at which it occured
if (*c != '\0') {
fprintf(stderr, "ERROR: syntax error parsing affinity at highlighted character\n-%s\n", arg);
while (n-- > 0)
{
fprintf(stderr, " ");
}
fprintf(stderr, "^\n");
}
else
{
fprintf(stderr, "ERROR: incomplete affinity specification\n");
}
}
if (fOk)
{
// fprintf(stderr, "FINAL parsed group %d core %d\n", nGroup, nNum);
pTimeSpan->AddAffinityAssignment((WORD)nGroup, (BYTE)nNum);
}
return fOk;
}