From owner-svn-src-all@FreeBSD.ORG Fri Jan 30 10:08:40 2015 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 4F30D4EA; Fri, 30 Jan 2015 10:08:40 +0000 (UTC) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 3B11AD2; Fri, 30 Jan 2015 10:08:40 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.9/8.14.9) with ESMTP id t0UA8epC032922; Fri, 30 Jan 2015 10:08:40 GMT (envelope-from pjd@FreeBSD.org) Received: (from pjd@localhost) by svn.freebsd.org (8.14.9/8.14.9/Submit) id t0UA8dCu032918; Fri, 30 Jan 2015 10:08:39 GMT (envelope-from pjd@FreeBSD.org) Message-Id: <201501301008.t0UA8dCu032918@svn.freebsd.org> X-Authentication-Warning: svn.freebsd.org: pjd set sender to pjd@FreeBSD.org using -f From: Pawel Jakub Dawidek Date: Fri, 30 Jan 2015 10:08:39 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r277921 - head/lib/libnv X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 30 Jan 2015 10:08:40 -0000 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 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); } }