]> granicus.if.org Git - zfs/blob - cmd/zed/zed_strings.c
Remove reverse indentation from zed comments.
[zfs] / cmd / zed / zed_strings.c
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license from the top-level
9  * OPENSOLARIS.LICENSE or <http://opensource.org/licenses/CDDL-1.0>.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each file
14  * and include the License file from the top-level OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21
22 /*
23  * Developed at Lawrence Livermore National Laboratory (LLNL-CODE-403049).
24  * Copyright (C) 2013-2014 Lawrence Livermore National Security, LLC.
25  */
26
27 #include <assert.h>
28 #include <errno.h>
29 #include <stddef.h>
30 #include <stdlib.h>
31 #include <string.h>
32 #include <sys/avl.h>
33 #include <sys/sysmacros.h>
34 #include "zed_strings.h"
35
36 struct zed_strings {
37         avl_tree_t tree;
38         avl_node_t *iteratorp;
39 };
40
41 struct zed_strings_node {
42         avl_node_t node;
43         char string[];
44 };
45
46 typedef struct zed_strings_node zed_strings_node_t;
47
48 /*
49  * Compare zed_strings_node_t nodes [x1] and [x2].
50  * As required for the AVL tree, return -1 for <, 0 for ==, and +1 for >.
51  */
52 static int
53 _zed_strings_node_compare(const void *x1, const void *x2)
54 {
55         const char *s1;
56         const char *s2;
57         int rv;
58
59         assert(x1 != NULL);
60         assert(x2 != NULL);
61
62         s1 = ((const zed_strings_node_t *) x1)->string;
63         assert(s1 != NULL);
64         s2 = ((const zed_strings_node_t *) x2)->string;
65         assert(s2 != NULL);
66         rv = strcmp(s1, s2);
67
68         if (rv < 0)
69                 return (-1);
70
71         if (rv > 0)
72                 return (1);
73
74         return (0);
75 }
76
77 /*
78  * Return a new string container, or NULL on error.
79  */
80 zed_strings_t *
81 zed_strings_create(void)
82 {
83         zed_strings_t *zsp;
84
85         zsp = malloc(sizeof (*zsp));
86         if (!zsp)
87                 return (NULL);
88
89         memset(zsp, 0, sizeof (*zsp));
90         avl_create(&zsp->tree, _zed_strings_node_compare,
91             sizeof (zed_strings_node_t), offsetof(zed_strings_node_t, node));
92
93         zsp->iteratorp = NULL;
94         return (zsp);
95 }
96
97 /*
98  * Destroy the string container [zsp] and all strings within.
99  */
100 void
101 zed_strings_destroy(zed_strings_t *zsp)
102 {
103         void *cookie;
104         zed_strings_node_t *np;
105
106         if (!zsp)
107                 return;
108
109         cookie = NULL;
110         while ((np = avl_destroy_nodes(&zsp->tree, &cookie)))
111                 free(np);
112
113         avl_destroy(&zsp->tree);
114         free(zsp);
115 }
116
117 /*
118  * Add a copy of the string [s] to the container [zsp].
119  * Return 0 on success, or -1 on error.
120  *
121  * FIXME: Handle dup strings.
122  */
123 int
124 zed_strings_add(zed_strings_t *zsp, const char *s)
125 {
126         size_t len;
127         zed_strings_node_t *np;
128
129         if (!zsp || !s) {
130                 errno = EINVAL;
131                 return (-1);
132         }
133         len = sizeof (zed_strings_node_t) + strlen(s) + 1;
134         np = malloc(len);
135         if (!np)
136                 return (-1);
137
138         memset(np, 0, len);
139         assert((char *) np->string + strlen(s) < (char *) np + len);
140         (void) strcpy(np->string, s);
141         avl_add(&zsp->tree, np);
142         return (0);
143 }
144
145 /*
146  * Return the first string in container [zsp].
147  * Return NULL if there are no strings, or on error.
148  * This can be called multiple times to re-traverse [zsp].
149  * XXX: Not thread-safe.
150  */
151 const char *
152 zed_strings_first(zed_strings_t *zsp)
153 {
154         if (!zsp) {
155                 errno = EINVAL;
156                 return (NULL);
157         }
158         zsp->iteratorp = avl_first(&zsp->tree);
159         if (!zsp->iteratorp)
160                 return (NULL);
161
162         return (((zed_strings_node_t *) zsp->iteratorp)->string);
163
164 }
165
166 /*
167  * Return the next string in container [zsp].
168  * Return NULL after the last string, or on error.
169  * This must be called after zed_strings_first().
170  * XXX: Not thread-safe.
171  */
172 const char *
173 zed_strings_next(zed_strings_t *zsp)
174 {
175         if (!zsp) {
176                 errno = EINVAL;
177                 return (NULL);
178         }
179         if (!zsp->iteratorp)
180                 return (NULL);
181
182         zsp->iteratorp = AVL_NEXT(&zsp->tree, zsp->iteratorp);
183         if (!zsp->iteratorp)
184                 return (NULL);
185
186         return (((zed_strings_node_t *)zsp->iteratorp)->string);
187 }
188
189 /*
190  * Return the number of strings in container [zsp], or -1 on error.
191  */
192 int
193 zed_strings_count(zed_strings_t *zsp)
194 {
195         if (!zsp) {
196                 errno = EINVAL;
197                 return (-1);
198         }
199         return (avl_numnodes(&zsp->tree));
200 }