]> xenbits.xensource.com Git - libvirt.git/commitdiff
virStrndup: Accept negative values as string length
authorMichal Privoznik <mprivozn@redhat.com>
Fri, 24 May 2013 08:45:57 +0000 (10:45 +0200)
committerMichal Privoznik <mprivozn@redhat.com>
Fri, 24 May 2013 14:59:30 +0000 (16:59 +0200)
It may shorten the code a bit as the following pattern:

  VIR_STRNDUP(dst, src, cond ? n : strlen(src))

is used on several places among our code. However, we can
move the strlen into virStrndup and thus write just:

  VIR_STRNDUP(dst, src, cond ? n : -1)

src/util/virstring.c
src/util/virstring.h
tests/virstringtest.c

index fcbb37556e76ee665969ba1984c9b5aa3e8f98b1..b244e6c75f72746431caa5ac9af79438ce9cb16c 100644 (file)
@@ -568,12 +568,15 @@ virStrdup(char **dest,
  * caller's body where virStrndup is called from. Consider
  * using VIR_STRNDUP which sets these automatically.
  *
+ * In case @n is smaller than zero, the whole @src string is
+ * copied.
+ *
  * Returns: 0 for NULL src, 1 on successful copy, -1 otherwise.
  */
 int
 virStrndup(char **dest,
            const char *src,
-           size_t n,
+           ssize_t n,
            bool report,
            int domcode,
            const char *filename,
@@ -582,6 +585,8 @@ virStrndup(char **dest,
 {
     if (!src)
         return 0;
+    if (n < 0)
+        n = strlen(src);
     if (!(*dest = strndup(src, n))) {
         if (report)
             virReportOOMErrorFull(domcode, filename, funcname, linenr);
index 534ce9139e94a37be675e25be2c1325186fc25e7..34ffae118a9631b25455a53b25c07ea599d12332 100644 (file)
@@ -93,7 +93,7 @@ int virStrdup(char **dest, const char *src, bool report, int domcode,
               const char *filename, const char *funcname, size_t linenr)
     ATTRIBUTE_RETURN_CHECK ATTRIBUTE_NONNULL(1);
 
-int virStrndup(char **dest, const char *src, size_t n, bool report, int domcode,
+int virStrndup(char **dest, const char *src, ssize_t n, bool report, int domcode,
                const char *filename, const char *funcname, size_t linenr)
     ATTRIBUTE_RETURN_CHECK ATTRIBUTE_NONNULL(1);
 
@@ -132,7 +132,9 @@ int virStrndup(char **dest, const char *src, size_t n, bool report, int domcode,
  * @n: the maximum number of bytes to copy
  *
  * Duplicate @src string and store it into @dst. If @src is longer than @n,
- * only @n bytes are copied and terminating null byte '\0' is added.
+ * only @n bytes are copied and terminating null byte '\0' is added. If @n
+ * is a negative number, then the whole @src string is copied. That is,
+ * VIR_STRDUP(dst, src) and VIR_STRNDUP(dst, src, -1) are equal.
  *
  * This macro is safe to use on arguments with side effects.
  *
@@ -150,7 +152,10 @@ int virStrndup(char **dest, const char *src, size_t n, bool report, int domcode,
  * @n: the maximum number of bytes to copy
  *
  * Duplicate @src string and store it into @dst. If @src is longer than @n,
- * only @n bytes are copied and terminating null byte '\0' is added.
+ * only @n bytes are copied and terminating null byte '\0' is added. If @n
+ * is a negative number, then the whole @src string is copied. That is,
+ * VIR_STRDUP_QUIET(dst, src) and VIR_STRNDUP_QUIET(dst, src, -1) are
+ * equal.
  *
  * This macro is safe to use on arguments with side effects.
  *
index da06c0f7f70a2f9c734d2da0882ff4b955505f25..e249f684e9cc4906ac397921d2f220632741f29a 100644 (file)
@@ -196,6 +196,40 @@ cleanup:
     return ret;
 }
 
+static int
+testStrndupNegative(const void *opaque ATTRIBUTE_UNUSED)
+{
+    int ret = -1;
+    char *dst;
+    const char *src = "Hello world";
+    int value;
+
+    if ((value = VIR_STRNDUP(dst, src, 5)) != 1) {
+        fprintf(stderr, "unexpected virStrndup result %d, expected 1\n", value);
+        goto cleanup;
+    }
+
+    if (STRNEQ_NULLABLE(dst, "Hello")) {
+        fprintf(stderr, "unexpected content '%s'", dst);
+        goto cleanup;
+    }
+
+    VIR_FREE(dst);
+    if ((value = VIR_STRNDUP(dst, src, -1)) != 1) {
+        fprintf(stderr, "unexpected virStrndup result %d, expected 1\n", value);
+        goto cleanup;
+    }
+
+    if (STRNEQ_NULLABLE(dst, src)) {
+        fprintf(stderr, "unexpected content '%s'", dst);
+        goto cleanup;
+    }
+
+    ret = 0;
+cleanup:
+    VIR_FREE(dst);
+    return ret;
+}
 
 static int
 mymain(void)
@@ -245,6 +279,9 @@ mymain(void)
     if (virtTestRun("strdup", 1, testStrdup, NULL) < 0)
         ret = -1;
 
+    if (virtTestRun("strdup", 1, testStrndupNegative, NULL) < 0)
+        ret = -1;
+
     return ret==0 ? EXIT_SUCCESS : EXIT_FAILURE;
 }