--- po/POTFILES.in | 1 + src/libvirt_private.syms | 1 + src/util/viruuid.c | 81 ++++++++++++++++++++++++++++++++++++++++++++++ src/util/viruuid.h | 1 + 4 files changed, 84 insertions(+) diff --git a/po/POTFILES.in b/po/POTFILES.in index 15afdec..451a6fc 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -196,6 +196,7 @@ src/util/virtypedparam.c src/util/viruri.c src/util/virusb.c src/util/virutil.c +src/util/viruuid.c src/util/virxml.c src/vbox/vbox_MSCOMGlue.c src/vbox/vbox_XPCOMCGlue.c diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index a705c56..99cc32a 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -1915,6 +1915,7 @@ virValidateWWN; # util/viruuid.h virGetHostUUID; +virSearchUuid; virSetHostUUIDStr; virUUIDFormat; virUUIDGenerate; diff --git a/src/util/viruuid.c b/src/util/viruuid.c index c5fa9a8..2cda4ac 100644 --- a/src/util/viruuid.c +++ b/src/util/viruuid.c @@ -34,6 +34,7 @@ #include <sys/stat.h> #include <time.h> #include <unistd.h> +#include <regex.h> #include "c-ctype.h" #include "internal.h" @@ -43,11 +44,14 @@ #include "viralloc.h" #include "virfile.h" #include "virrandom.h" +#include "virstring.h" #ifndef ENODATA # define ENODATA EIO #endif +#define VIR_FROM_THIS VIR_FROM_NONE + static unsigned char host_uuid[VIR_UUID_BUFLEN]; static int @@ -333,3 +337,80 @@ int virGetHostUUID(unsigned char *uuid) return ret; } + + +/** + * virSearchUuid: + * Allows you to get the nth occurrence of a substring in sourceString which matches an uuid pattern. + * If there is no substring, ret is not modified. + * return -1 on error, 0 if not found and 1 if found. + * + * @sourceString: String to parse + * @occurrence: We will return the nth occurrence of uuid in substring, if equals to 0 (or negative), will return the first occurence + * @ret: nth occurrence substring matching an uuid pattern + * @code + char *source = "6853a496-1c10-472e-867a-8244937bd6f0 773ab075-4cd7-4fc2-8b6e-21c84e9cb391 bbb3c75c-d60f-43b0-b802-fd56b84a4222 60c04aa1-0375-4654-8d9f-e149d9885273 4548d465-9891-4c34-a184-3b1c34a26aa8"; + char *ret1=NULL; + char *ret2=NULL; + char *ret3=NULL; + char *ret4=NULL; + virSearchUuid(source, 4,&ret1); //ret1 = "60c04aa1-0375-4654-8d9f-e149d9885273" + virSearchUuid(source, 0,&ret2); //ret2 = "6853a496-1c10-472e-867a-8244937bd6f0" + virSearchUuid(source, 1,&ret3); //ret3 = "6853a496-1c10-472e-867a-8244937bd6f0" + virSearchUuid(source, -4,&ret4); //ret4 = "6853a496-1c10-472e-867a-8244937bd6f0" + * @endcode + */ + +int +virSearchUuid(const char *sourceString, int occurrence, char **ret) +{ + unsigned int position = ((occurrence -1) > 0) ? (occurrence -1) : 0; + const char *uuidRegex = "([a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12})"; + regex_t pregUuidBracket; + size_t i = 0; + size_t nmatch = 0; + regmatch_t *pmatch = NULL; + int retCode = 0; + if (regcomp(&pregUuidBracket, uuidRegex, REG_EXTENDED) != 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("Error while compiling regular expression")); + return -1; + } + nmatch = pregUuidBracket.re_nsub; + if (VIR_ALLOC_N(pmatch, nmatch) != 0) { + retCode = -1; + goto cleanup; + } + + while (i < (position+1)) { + if (regexec(&pregUuidBracket, sourceString, nmatch, pmatch, 0) == 0) { + regoff_t start = pmatch[0].rm_so; + regoff_t end = pmatch[0].rm_eo; + if (i == position || (position > i && regexec(&pregUuidBracket, &sourceString[end], nmatch, pmatch, 0) != 0)) { + /* We copy only if i == position (so that it is the uuid we're looking for), or position > i AND + * there is no matches left in the rest of the string (this is the case where we + * give a biggest @occurence than the number of matches and we want to return the last + * one) + */ + if (VIR_STRNDUP(*ret, sourceString + start, end - start) < 0) { + retCode = -1; + goto cleanup; + } + retCode = 1; + goto cleanup; + } + + sourceString = &sourceString[end]; + } else { + break; + retCode = 0; + goto cleanup; + } + ++i; + } + +cleanup: + regfree(&pregUuidBracket); + VIR_FREE(pmatch); + return retCode; +} diff --git a/src/util/viruuid.h b/src/util/viruuid.h index bebd338..2ce4fce 100644 --- a/src/util/viruuid.h +++ b/src/util/viruuid.h @@ -40,4 +40,5 @@ int virUUIDParse(const char *uuidstr, const char *virUUIDFormat(const unsigned char *uuid, char *uuidstr) ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2); +int virSearchUuid(const char *sourceString, int occurrence, char **ret); #endif /* __VIR_UUID_H__ */ -- 1.7.10.4 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list