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 <osho...@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);
                }
        }
 
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to