Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 30 Jan 2015 10:08:39 +0000 (UTC)
From:      Pawel Jakub Dawidek <pjd@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r277921 - head/lib/libnv
Message-ID:  <201501301008.t0UA8dCu032918@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: pjd
Date: Fri Jan 30 10:08:38 2015
New Revision: 277921
URL: https://svnweb.freebsd.org/changeset/base/277921

Log:
  Modify nvlist_get_parent() API to take additional cookie argument.
  This allow for non-recursive iteration over nested nvlists, as in documented
  example.
  
  Submitted by:	Mariusz Zaborski <oshogbo@FreeBSD.org>

Modified:
  head/lib/libnv/nv.3
  head/lib/libnv/nv.h
  head/lib/libnv/nvlist.c

Modified: head/lib/libnv/nv.3
==============================================================================
--- head/lib/libnv/nv.3	Fri Jan 30 09:44:29 2015	(r277920)
+++ head/lib/libnv/nv.3	Fri Jan 30 10:08:38 2015	(r277921)
@@ -28,7 +28,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd September 25, 2014
+.Dd January 30, 2015
 .Dt NV 3
 .Os
 .Sh NAME
@@ -151,7 +151,7 @@
 .Ft "const void *"
 .Fn nvlist_get_binary "const nvlist_t *nvl" "const char *name" "size_t *sizep"
 .Ft "const nvlist_t *"
-.Fn nvlist_get_parent "const nvlist_t *nvl"
+.Fn nvlist_get_parent "const nvlist_t *nvl" "void **cookiep"
 .\"
 .Ft bool
 .Fn nvlist_take_bool "nvlist_t *nvl" "const char *name"
@@ -588,6 +588,28 @@ while ((name = nvlist_next(nvl, &type, &
 	printf("\\n");
 }
 .Ed
+.Pp
+Iterating over every nested nvlist:
+.Bd -literal
+nvlist_t *nvl;
+const char *name;
+void *cookie;
+int type;
+
+nvl = nvlist_recv(sock);
+if (nvl == NULL)
+	err(1, "nvlist_recv() failed");
+
+cookie = NULL;
+do {
+	while ((name = nvlist_next(nvl, &type, &cookie)) != NULL) {
+		if (type == NV_TYPE_NVLIST) {
+			nvl = nvlist_get_nvlist(nvl, name);
+			cookie = NULL;
+		}
+	}
+} while ((nvl = nvlist_get_parent(nvl, &cookie)) != NULL);
+.Ed
 .Sh SEE ALSO
 .Xr close 2 ,
 .Xr dup 2 ,

Modified: head/lib/libnv/nv.h
==============================================================================
--- head/lib/libnv/nv.h	Fri Jan 30 09:44:29 2015	(r277920)
+++ head/lib/libnv/nv.h	Fri Jan 30 10:08:38 2015	(r277921)
@@ -83,7 +83,7 @@ nvlist_t *nvlist_xfer(int sock, nvlist_t
 
 const char *nvlist_next(const nvlist_t *nvl, int *typep, void **cookiep);
 
-const nvlist_t *nvlist_get_parent(const nvlist_t *nvl);
+const nvlist_t *nvlist_get_parent(const nvlist_t *nvl, void **cookiep);
 
 /*
  * The nvlist_exists functions check if the given name (optionally of the given

Modified: head/lib/libnv/nvlist.c
==============================================================================
--- head/lib/libnv/nvlist.c	Fri Jan 30 09:44:29 2015	(r277920)
+++ head/lib/libnv/nvlist.c	Fri Jan 30 10:08:38 2015	(r277921)
@@ -159,15 +159,19 @@ nvlist_get_nvpair_parent(const nvlist_t 
 }
 
 const nvlist_t *
-nvlist_get_parent(const nvlist_t *nvl)
+nvlist_get_parent(const nvlist_t *nvl, void **cookiep)
 {
+	nvpair_t *nvp;
 
 	NVLIST_ASSERT(nvl);
 
-	if (nvl->nvl_parent == NULL)
+	nvp = nvl->nvl_parent;
+	if (cookiep != NULL)
+		*cookiep = nvp;
+	if (nvp == NULL)
 		return (NULL);
 
-	return (nvpair_nvlist(nvl->nvl_parent));
+	return (nvpair_nvlist(nvp));
 }
 
 void
@@ -384,11 +388,10 @@ nvlist_dump(const nvlist_t *nvl, int fd)
 			dprintf(fd, "\n");
 			nvl = nvpair_get_nvlist(nvp);
 			if (nvlist_dump_error_check(nvl, fd, level + 1)) {
-				nvl = nvlist_get_parent(nvl);
+				nvl = nvlist_get_parent(nvl, (void **)&nvp);
 				break;
 			}
-			level += 1;
-			nvp = nvlist_first_nvpair(nvl);
+			level++;
 			continue;
 		case NV_TYPE_DESCRIPTOR:
 			dprintf(fd, " %d\n", nvpair_get_descriptor(nvp));
@@ -411,11 +414,10 @@ nvlist_dump(const nvlist_t *nvl, int fd)
 		}
 
 		while ((nvp = nvlist_next_nvpair(nvl, nvp)) == NULL) {
-			nvp = nvlist_get_nvpair_parent(nvl);
-			if (nvp == NULL)
+			nvl = nvlist_get_parent(nvl, (void **)&nvp);
+			if (nvl == NULL)
 				return;
-			nvl = nvlist_get_parent(nvl);
-			level --;
+			level--;
 		}
 	}
 }
@@ -457,10 +459,9 @@ nvlist_size(const nvlist_t *nvl)
 		}
 
 		while ((nvp = nvlist_next_nvpair(nvl, nvp)) == NULL) {
-			nvp = nvlist_get_nvpair_parent(nvl);
-			if (nvp == NULL)
+			nvl = nvlist_get_parent(nvl, (void **)&nvp);
+			if (nvl == NULL)
 				goto out;
-			nvl = nvlist_get_parent(nvl);
 		}
 	}
 
@@ -635,13 +636,12 @@ nvlist_xpack(const nvlist_t *nvl, int64_
 			return (NULL);
 		}
 		while ((nvp = nvlist_next_nvpair(nvl, nvp)) == NULL) {
-			nvp = nvlist_get_nvpair_parent(nvl);
-			if (nvp == NULL)
+			nvl = nvlist_get_parent(nvl, (void **)&nvp);
+			if (nvl == NULL)
 				goto out;
 			ptr = nvpair_pack_nvlist_up(ptr, &left);
 			if (ptr == NULL)
 				goto out;
-			nvl = nvlist_get_parent(nvl);
 		}
 	}
 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201501301008.t0UA8dCu032918>