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.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/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]
22 * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
33 extern char *_strdup_null(char *);
34 extern char *_strtok_escape(char *, char *, char **);
35 extern char *_strpbrk_escape(char *, char *);
36 extern char *_unescape(char *, char *);
38 char *_do_unescape(char *);
42 * kva_match(): Given a key-value array and a key, return a pointer to the
43 * value that matches the key.
46 kva_match(kva_t
*kva
, char *key
)
51 if (kva
== NULL
|| key
== NULL
) {
55 for (i
= 0; i
< kva
->length
; i
++) {
56 if (strcmp(data
[i
].key
, key
) == 0) {
57 return (data
[i
].value
);
65 * _kva_free(): Free up memory.
77 for (i
= 0; i
< kva
->length
; i
++) {
78 if (data
[i
].key
!= NULL
) {
82 if (data
[i
].value
!= NULL
) {
92 * _kva_free_value(): Free up memory (value) for all the occurrences of
96 _kva_free_value(kva_t
*kva
, char *key
)
109 if (strcmp(data
->key
, key
) == 0 && data
->value
!= NULL
) {
118 * new_kva(): Allocate a key-value array.
125 if ((new_kva
= (kva_t
*)calloc(1, sizeof (kva_t
))) == NULL
) {
128 if ((new_kva
->data
= (kv_t
*)calloc(1, (size
*sizeof (kv_t
)))) == NULL
) {
137 * _str2kva(): Given a string (s) of key-value pairs, separated by delimeter
138 * (del), place the values into the key value array (nkva).
141 _str2kva(char *s
, char *ass
, char *del
)
145 int size
= KV_ADD_KEYS
;
164 while ((p
= _strpbrk_escape(p
, ass
)) != NULL
) {
173 size
= m
* KV_ADD_KEYS
;
175 if ((nkva
= _new_kva(size
)) == NULL
) {
180 if ((buf
= strdup(s
)) == NULL
) {
183 pair
= _strtok_escape(buf
, del
, &last_pair
);
185 key
= _strtok_escape(pair
, ass
, &last_key
);
187 data
[nkva
->length
].key
= _do_unescape(key
);
188 data
[nkva
->length
].value
= _do_unescape(last_key
);
191 } while ((pair
= _strtok_escape(NULL
, del
, &last_pair
)) != NULL
);
197 * _kva2str(): Given an array of key-value pairs, place them into a string
198 * (buf). Use delimeter (del) to separate pairs. Use assignment character
199 * (ass) to separate keys and values.
201 * Return Values: 0 Success 1 Buffer too small
204 _kva2str(kva_t
*kva
, char *buf
, int buflen
, char *ass
, char *del
)
218 for (i
= 0; i
< kva
->length
; i
++) {
219 if (data
[i
].value
!= NULL
) {
220 len
= snprintf(buf
+ off
, buflen
- off
, "%s%s%s%s",
221 data
[i
].key
, ass
, data
[i
].value
, del
);
222 if (len
< 0 || len
+ off
>= buflen
) {
233 _insert2kva(kva_t
*kva
, char *key
, char *value
)
242 for (i
= 0; i
< kva
->length
; i
++) {
243 if (strcmp(data
[i
].key
, key
) == 0) {
244 if (data
[i
].value
!= NULL
)
246 data
[i
].value
= _strdup_null(value
);
254 _kva_dup(kva_t
*old_kva
)
262 if (old_kva
== NULL
) {
265 old_data
= old_kva
->data
;
266 size
= old_kva
->length
;
267 if ((nkva
= _new_kva(size
)) == NULL
) {
270 new_data
= nkva
->data
;
271 nkva
->length
= old_kva
->length
;
272 for (i
= 0; i
< nkva
->length
; i
++) {
273 new_data
[i
].key
= _strdup_null(old_data
[i
].key
);
274 new_data
[i
].value
= _strdup_null(old_data
[i
].value
);
281 strip_spaces(char **valuep
)
285 /* Find first non-white space character and return pointer to it */
286 for (p
= *valuep
; *p
!= '\0' && isspace((unsigned char)*p
); p
++)
294 p
= p
+ strlen(p
) - 1;
296 /* Remove trailing spaces */
297 while (p
> start
&& isspace((unsigned char)*p
))
304 _do_unescape(char *src
)
310 dst
= _strdup_null(src
);
313 tmp
= _unescape(src
, "=;:,\\");
314 dst
= (tmp
== NULL
) ? _strdup_null(src
) : tmp
;
322 * Some utilities for handling comma-separated lists.
325 _argv_to_csl(char **strings
)
333 for (i
= 0; strings
[i
] != NULL
; i
++) {
334 len
+= strlen(strings
[i
]) + 1;
336 if ((len
> 0) && ((newstr
= (char *)malloc(len
+ 1)) != NULL
)) {
337 (void) memset(newstr
, 0, len
);
338 for (i
= 0; strings
[i
] != NULL
; i
++) {
339 (void) strcat(newstr
, strings
[i
]);
340 (void) strcat(newstr
, ",");
342 newstr
[len
-1] = NULL
;
350 _csl_to_argv(char *csl
)
361 for (i
= 0; i
< len
; i
++) {
365 if ((spc
= (char **)malloc((ncommas
+ 2) * sizeof (char *))) == NULL
) {
369 for (pc
= strtok_r(copy
, ",", &lasts
), i
= 0; pc
!= NULL
;
370 pc
= strtok_r(NULL
, ",", &lasts
), i
++) {
380 _free_argv(char **p_argv
)
384 for (p_a
= p_argv
; *p_a
!= NULL
; p_a
++)
392 print_kva(kva_t
*kva
)
398 (void) printf(" (empty)\n");
402 for (i
= 0; i
< kva
->length
; i
++) {
403 (void) printf(" %s = %s\n",
404 data
[i
].key
!= NULL
? data
[i
].key
: "NULL",
405 data
[i
].value
!= NULL
? data
[i
].value
: "NULL");