mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-08-27 19:11:16 +00:00
util: bitmap: Unify parsing of bitmaps
There were two separate instances of string->virBitmap code: virBitmapParseInternal and virBitmapParseUnlimited. By adding a flag to switch to expanding APIs we can merge the two implementations into one. Signed-off-by: Peter Krempa <pkrempa@redhat.com> Reviewed-by: Ján Tomko <jtomko@redhat.com>
This commit is contained in:
parent
515672c0d9
commit
f33c86be1d
@ -367,6 +367,7 @@ virBitmapFormat(virBitmap *bitmap)
|
|||||||
* virBitmapParseInternal:
|
* virBitmapParseInternal:
|
||||||
* @str: points to a string representing a human-readable bitmap
|
* @str: points to a string representing a human-readable bitmap
|
||||||
* @bitmap: a bitmap populated from @str
|
* @bitmap: a bitmap populated from @str
|
||||||
|
* @limited: Don't use self-expanding APIs, report error if bit exceeds bitmap size
|
||||||
*
|
*
|
||||||
* This function is the counterpart of virBitmapFormat. This function creates
|
* This function is the counterpart of virBitmapFormat. This function creates
|
||||||
* a bitmap, in which bits are set according to the content of @str.
|
* a bitmap, in which bits are set according to the content of @str.
|
||||||
@ -379,7 +380,8 @@ virBitmapFormat(virBitmap *bitmap)
|
|||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
virBitmapParseInternal(const char *str,
|
virBitmapParseInternal(const char *str,
|
||||||
virBitmap *bitmap)
|
virBitmap *bitmap,
|
||||||
|
bool limited)
|
||||||
{
|
{
|
||||||
bool neg = false;
|
bool neg = false;
|
||||||
const char *cur = str;
|
const char *cur = str;
|
||||||
@ -421,11 +423,19 @@ virBitmapParseInternal(const char *str,
|
|||||||
|
|
||||||
if (*cur == ',' || *cur == 0) {
|
if (*cur == ',' || *cur == 0) {
|
||||||
if (neg) {
|
if (neg) {
|
||||||
if (virBitmapClearBit(bitmap, start) < 0)
|
if (limited) {
|
||||||
goto error;
|
if (virBitmapClearBit(bitmap, start) < 0)
|
||||||
|
goto error;
|
||||||
|
} else {
|
||||||
|
virBitmapClearBitExpand(bitmap, start);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if (virBitmapSetBit(bitmap, start) < 0)
|
if (limited) {
|
||||||
goto error;
|
if (virBitmapSetBit(bitmap, start) < 0)
|
||||||
|
goto error;
|
||||||
|
} else {
|
||||||
|
virBitmapSetBitExpand(bitmap, start);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else if (*cur == '-') {
|
} else if (*cur == '-') {
|
||||||
if (neg)
|
if (neg)
|
||||||
@ -442,8 +452,12 @@ virBitmapParseInternal(const char *str,
|
|||||||
cur = tmp;
|
cur = tmp;
|
||||||
|
|
||||||
for (i = start; i <= last; i++) {
|
for (i = start; i <= last; i++) {
|
||||||
if (virBitmapSetBit(bitmap, i) < 0)
|
if (limited) {
|
||||||
goto error;
|
if (virBitmapSetBit(bitmap, i) < 0)
|
||||||
|
goto error;
|
||||||
|
} else {
|
||||||
|
virBitmapSetBitExpand(bitmap, i);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
virSkipSpaces(&cur);
|
virSkipSpaces(&cur);
|
||||||
@ -491,7 +505,7 @@ virBitmapParse(const char *str,
|
|||||||
{
|
{
|
||||||
g_autoptr(virBitmap) tmp = virBitmapNew(bitmapSize);
|
g_autoptr(virBitmap) tmp = virBitmapNew(bitmapSize);
|
||||||
|
|
||||||
if (virBitmapParseInternal(str, tmp) < 0)
|
if (virBitmapParseInternal(str, tmp, true) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
*bitmap = g_steal_pointer(&tmp);
|
*bitmap = g_steal_pointer(&tmp);
|
||||||
@ -518,89 +532,12 @@ virBitmapParse(const char *str,
|
|||||||
virBitmap *
|
virBitmap *
|
||||||
virBitmapParseUnlimited(const char *str)
|
virBitmapParseUnlimited(const char *str)
|
||||||
{
|
{
|
||||||
virBitmap *bitmap = virBitmapNew(0);
|
g_autoptr(virBitmap) tmp = virBitmapNew(0);
|
||||||
bool neg = false;
|
|
||||||
const char *cur = str;
|
|
||||||
char *tmp;
|
|
||||||
size_t i;
|
|
||||||
int start, last;
|
|
||||||
|
|
||||||
if (!str)
|
if (virBitmapParseInternal(str, tmp, false) < 0)
|
||||||
goto error;
|
return NULL;
|
||||||
|
|
||||||
virSkipSpaces(&cur);
|
return g_steal_pointer(&tmp);
|
||||||
|
|
||||||
if (*cur == '\0')
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
while (*cur != 0) {
|
|
||||||
/*
|
|
||||||
* 3 constructs are allowed:
|
|
||||||
* - N : a single CPU number
|
|
||||||
* - N-M : a range of CPU numbers with N < M
|
|
||||||
* - ^N : remove a single CPU number from the current set
|
|
||||||
*/
|
|
||||||
if (*cur == '^') {
|
|
||||||
cur++;
|
|
||||||
neg = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!g_ascii_isdigit(*cur))
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
if (virStrToLong_i(cur, &tmp, 10, &start) < 0)
|
|
||||||
goto error;
|
|
||||||
if (start < 0)
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
cur = tmp;
|
|
||||||
|
|
||||||
virSkipSpaces(&cur);
|
|
||||||
|
|
||||||
if (*cur == ',' || *cur == 0) {
|
|
||||||
if (neg) {
|
|
||||||
virBitmapClearBitExpand(bitmap, start);
|
|
||||||
} else {
|
|
||||||
virBitmapSetBitExpand(bitmap, start);
|
|
||||||
}
|
|
||||||
} else if (*cur == '-') {
|
|
||||||
if (neg)
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
cur++;
|
|
||||||
virSkipSpaces(&cur);
|
|
||||||
|
|
||||||
if (virStrToLong_i(cur, &tmp, 10, &last) < 0)
|
|
||||||
goto error;
|
|
||||||
if (last < start)
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
cur = tmp;
|
|
||||||
|
|
||||||
for (i = start; i <= last; i++)
|
|
||||||
virBitmapSetBitExpand(bitmap, i);
|
|
||||||
|
|
||||||
virSkipSpaces(&cur);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (*cur == ',') {
|
|
||||||
cur++;
|
|
||||||
virSkipSpaces(&cur);
|
|
||||||
neg = false;
|
|
||||||
} else if (*cur == 0) {
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return bitmap;
|
|
||||||
|
|
||||||
error:
|
|
||||||
virReportError(VIR_ERR_INVALID_ARG,
|
|
||||||
_("Failed to parse bitmap '%s'"), NULLSTR(str));
|
|
||||||
virBitmapFree(bitmap);
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user