Some changes that will appear in 0.5.0:
* Add proplib-0.4.1 source and use it in XBPS. This is to avoid an external dependency, so that we depend on the features of the internal library. This also means that proplib is not required anymore. * Added support to read/write gzip compressed plists by default, thanks to proplib-0.4 that gained new functionality. That means that from now, XBPS will be able to write compressed gzip plist files for all metadata related work. This will vastly reduce bandwidth required for fetching remote repo's pkg index file and binary packages. --HG-- extra : convert_revision : xtraeme%40gmail.com-20100420122238-zcb85rudt9p34e10
This commit is contained in:
parent
ab76f9d5e7
commit
6256b34ccc
5
3RDPARTY
Normal file
5
3RDPARTY
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
XBPS includes the following software from third parties for internal
|
||||||
|
use in the code:
|
||||||
|
|
||||||
|
- libfetch-2.30 from NetBSD
|
||||||
|
- portableproplib-0.4.1 from http://code.google.com/p/portableproplib
|
9
NEWS
9
NEWS
@ -1,3 +1,12 @@
|
|||||||
|
xbps-0.5.0 (2010-05-01):
|
||||||
|
|
||||||
|
* Add proplib-0.4.1 source and use it in XBPS. This is to avoid
|
||||||
|
an external dependency, so that we depend on the features of the
|
||||||
|
internal library. This also means that proplib is not required anymore.
|
||||||
|
|
||||||
|
* Added support to read/write gzip compressed plists by default, thanks
|
||||||
|
to proplib-0.4 that gained new functionality.
|
||||||
|
|
||||||
xbps-0.4.1 (2010-02-28):
|
xbps-0.4.1 (2010-02-28):
|
||||||
|
|
||||||
* xbps-bin(8): fixed the install target to work with package names containing
|
* xbps-bin(8): fixed the install target to work with package names containing
|
||||||
|
4
README
4
README
@ -4,9 +4,7 @@ To build this you'll need:
|
|||||||
|
|
||||||
- pkg-config
|
- pkg-config
|
||||||
- openssl (development package with static libs)
|
- openssl (development package with static libs)
|
||||||
- libarchive (development package with static libs)
|
- libarchive >= 2.8.0 (development package with static libs)
|
||||||
- proplib (development package with static lib),
|
|
||||||
available at http://code.google.com/p/portableproplib
|
|
||||||
- asciidoc (to build the manpages)
|
- asciidoc (to build the manpages)
|
||||||
|
|
||||||
Optionally to build the API documentation (enabled with BUILD_API_DOCS
|
Optionally to build the API documentation (enabled with BUILD_API_DOCS
|
||||||
|
@ -126,7 +126,7 @@ xbps_check_pkg_integrity(const char *pkgname)
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
propsd = prop_dictionary_internalize_from_file(path);
|
propsd = prop_dictionary_internalize_from_zfile(path);
|
||||||
free(path);
|
free(path);
|
||||||
if (propsd == NULL) {
|
if (propsd == NULL) {
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
@ -158,7 +158,7 @@ xbps_check_pkg_integrity(const char *pkgname)
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
filesd = prop_dictionary_internalize_from_file(path);
|
filesd = prop_dictionary_internalize_from_zfile(path);
|
||||||
free(path);
|
free(path);
|
||||||
if (filesd == NULL) {
|
if (filesd == NULL) {
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
|
@ -56,7 +56,7 @@ xbps_show_pkg_deps(const char *pkgname)
|
|||||||
if (path == NULL)
|
if (path == NULL)
|
||||||
return errno;
|
return errno;
|
||||||
|
|
||||||
propsd = prop_dictionary_internalize_from_file(path);
|
propsd = prop_dictionary_internalize_from_zfile(path);
|
||||||
free(path);
|
free(path);
|
||||||
if (propsd == NULL) {
|
if (propsd == NULL) {
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
|
@ -45,7 +45,7 @@ show_pkg_info_from_metadir(const char *pkgname)
|
|||||||
if (plist == NULL)
|
if (plist == NULL)
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
|
|
||||||
pkgd = prop_dictionary_internalize_from_file(plist);
|
pkgd = prop_dictionary_internalize_from_zfile(plist);
|
||||||
if (pkgd == NULL) {
|
if (pkgd == NULL) {
|
||||||
free(plist);
|
free(plist);
|
||||||
return errno;
|
return errno;
|
||||||
@ -70,7 +70,7 @@ show_pkg_files_from_metadir(const char *pkgname)
|
|||||||
if (plist == NULL)
|
if (plist == NULL)
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
|
|
||||||
pkgd = prop_dictionary_internalize_from_file(plist);
|
pkgd = prop_dictionary_internalize_from_zfile(plist);
|
||||||
if (pkgd == NULL) {
|
if (pkgd == NULL) {
|
||||||
free(plist);
|
free(plist);
|
||||||
return errno;
|
return errno;
|
||||||
|
@ -49,7 +49,7 @@ repoidx_getdict(const char *pkgdir)
|
|||||||
if (plist == NULL)
|
if (plist == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
dict = prop_dictionary_internalize_from_file(plist);
|
dict = prop_dictionary_internalize_from_zfile(plist);
|
||||||
if (dict == NULL) {
|
if (dict == NULL) {
|
||||||
dict = prop_dictionary_create();
|
dict = prop_dictionary_create();
|
||||||
if (dict == NULL)
|
if (dict == NULL)
|
||||||
@ -365,7 +365,7 @@ xbps_repo_genindex(const char *pkgdir)
|
|||||||
* If any package was registered in package index, write
|
* If any package was registered in package index, write
|
||||||
* plist file to storage.
|
* plist file to storage.
|
||||||
*/
|
*/
|
||||||
if (!prop_dictionary_externalize_to_file(idxdict, plist))
|
if (!prop_dictionary_externalize_to_zfile(idxdict, plist))
|
||||||
rv = errno;
|
rv = errno;
|
||||||
}
|
}
|
||||||
out:
|
out:
|
||||||
|
@ -44,7 +44,7 @@ pkgindex_verify(const char *plist, const char *uri, bool only_sync)
|
|||||||
|
|
||||||
assert(plist != NULL);
|
assert(plist != NULL);
|
||||||
|
|
||||||
d = prop_dictionary_internalize_from_file(plist);
|
d = prop_dictionary_internalize_from_zfile(plist);
|
||||||
if (d == NULL) {
|
if (d == NULL) {
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"E: repository %s does not contain any "
|
"E: repository %s does not contain any "
|
||||||
|
@ -45,7 +45,7 @@ write_plist_file(prop_dictionary_t dict, const char *file)
|
|||||||
{
|
{
|
||||||
assert(dict != NULL || file != NULL);
|
assert(dict != NULL || file != NULL);
|
||||||
|
|
||||||
if (!prop_dictionary_externalize_to_file(dict, file)) {
|
if (!prop_dictionary_externalize_to_zfile(dict, file)) {
|
||||||
prop_object_release(dict);
|
prop_object_release(dict);
|
||||||
printf("=> ERROR: couldn't write to %s (%s)",
|
printf("=> ERROR: couldn't write to %s (%s)",
|
||||||
file, strerror(errno));
|
file, strerror(errno));
|
||||||
@ -221,7 +221,7 @@ main(int argc, char **argv)
|
|||||||
if (argc != 2)
|
if (argc != 2)
|
||||||
usage();
|
usage();
|
||||||
|
|
||||||
dict = prop_dictionary_internalize_from_file(argv[1]);
|
dict = prop_dictionary_internalize_from_zfile(argv[1]);
|
||||||
if (dict == NULL) {
|
if (dict == NULL) {
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"=> ERROR: couldn't sanitize %s plist file "
|
"=> ERROR: couldn't sanitize %s plist file "
|
||||||
@ -334,6 +334,12 @@ main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} else if (strcasecmp(argv[0], "gzprint") == 0) {
|
||||||
|
if (argc != 2)
|
||||||
|
usage();
|
||||||
|
|
||||||
|
dict = prop_dictionary_internalize_from_zfile(argv[1]);
|
||||||
|
printf("%s", prop_dictionary_externalize(dict));
|
||||||
} else {
|
} else {
|
||||||
usage();
|
usage();
|
||||||
}
|
}
|
||||||
|
697
include/queue.h
Normal file
697
include/queue.h
Normal file
@ -0,0 +1,697 @@
|
|||||||
|
/* $NetBSD: queue.h,v 1.49 2008/06/15 16:42:18 christos Exp $ */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 1991, 1993
|
||||||
|
* The Regents of the University of California. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of the University nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* @(#)queue.h 8.5 (Berkeley) 8/20/94
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _SYS_QUEUE_H_
|
||||||
|
#define _SYS_QUEUE_H_
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file defines five types of data structures: singly-linked lists,
|
||||||
|
* lists, simple queues, tail queues, and circular queues.
|
||||||
|
*
|
||||||
|
* A singly-linked list is headed by a single forward pointer. The
|
||||||
|
* elements are singly linked for minimum space and pointer manipulation
|
||||||
|
* overhead at the expense of O(n) removal for arbitrary elements. New
|
||||||
|
* elements can be added to the list after an existing element or at the
|
||||||
|
* head of the list. Elements being removed from the head of the list
|
||||||
|
* should use the explicit macro for this purpose for optimum
|
||||||
|
* efficiency. A singly-linked list may only be traversed in the forward
|
||||||
|
* direction. Singly-linked lists are ideal for applications with large
|
||||||
|
* datasets and few or no removals or for implementing a LIFO queue.
|
||||||
|
*
|
||||||
|
* A list is headed by a single forward pointer (or an array of forward
|
||||||
|
* pointers for a hash table header). The elements are doubly linked
|
||||||
|
* so that an arbitrary element can be removed without a need to
|
||||||
|
* traverse the list. New elements can be added to the list before
|
||||||
|
* or after an existing element or at the head of the list. A list
|
||||||
|
* may only be traversed in the forward direction.
|
||||||
|
*
|
||||||
|
* A simple queue is headed by a pair of pointers, one the head of the
|
||||||
|
* list and the other to the tail of the list. The elements are singly
|
||||||
|
* linked to save space, so elements can only be removed from the
|
||||||
|
* head of the list. New elements can be added to the list after
|
||||||
|
* an existing element, at the head of the list, or at the end of the
|
||||||
|
* list. A simple queue may only be traversed in the forward direction.
|
||||||
|
*
|
||||||
|
* A tail queue is headed by a pair of pointers, one to the head of the
|
||||||
|
* list and the other to the tail of the list. The elements are doubly
|
||||||
|
* linked so that an arbitrary element can be removed without a need to
|
||||||
|
* traverse the list. New elements can be added to the list before or
|
||||||
|
* after an existing element, at the head of the list, or at the end of
|
||||||
|
* the list. A tail queue may be traversed in either direction.
|
||||||
|
*
|
||||||
|
* A circle queue is headed by a pair of pointers, one to the head of the
|
||||||
|
* list and the other to the tail of the list. The elements are doubly
|
||||||
|
* linked so that an arbitrary element can be removed without a need to
|
||||||
|
* traverse the list. New elements can be added to the list before or after
|
||||||
|
* an existing element, at the head of the list, or at the end of the list.
|
||||||
|
* A circle queue may be traversed in either direction, but has a more
|
||||||
|
* complex end of list detection.
|
||||||
|
*
|
||||||
|
* For details on the use of these macros, see the queue(3) manual page.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* List definitions.
|
||||||
|
*/
|
||||||
|
#define LIST_HEAD(name, type) \
|
||||||
|
struct name { \
|
||||||
|
struct type *lh_first; /* first element */ \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define LIST_HEAD_INITIALIZER(head) \
|
||||||
|
{ NULL }
|
||||||
|
|
||||||
|
#define LIST_ENTRY(type) \
|
||||||
|
struct { \
|
||||||
|
struct type *le_next; /* next element */ \
|
||||||
|
struct type **le_prev; /* address of previous next element */ \
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* List functions.
|
||||||
|
*/
|
||||||
|
#if defined(_KERNEL) && defined(QUEUEDEBUG)
|
||||||
|
#define QUEUEDEBUG_LIST_INSERT_HEAD(head, elm, field) \
|
||||||
|
if ((head)->lh_first && \
|
||||||
|
(head)->lh_first->field.le_prev != &(head)->lh_first) \
|
||||||
|
panic("LIST_INSERT_HEAD %p %s:%d", (head), __FILE__, __LINE__);
|
||||||
|
#define QUEUEDEBUG_LIST_OP(elm, field) \
|
||||||
|
if ((elm)->field.le_next && \
|
||||||
|
(elm)->field.le_next->field.le_prev != \
|
||||||
|
&(elm)->field.le_next) \
|
||||||
|
panic("LIST_* forw %p %s:%d", (elm), __FILE__, __LINE__);\
|
||||||
|
if (*(elm)->field.le_prev != (elm)) \
|
||||||
|
panic("LIST_* back %p %s:%d", (elm), __FILE__, __LINE__);
|
||||||
|
#define QUEUEDEBUG_LIST_POSTREMOVE(elm, field) \
|
||||||
|
(elm)->field.le_next = (void *)1L; \
|
||||||
|
(elm)->field.le_prev = (void *)1L;
|
||||||
|
#else
|
||||||
|
#define QUEUEDEBUG_LIST_INSERT_HEAD(head, elm, field)
|
||||||
|
#define QUEUEDEBUG_LIST_OP(elm, field)
|
||||||
|
#define QUEUEDEBUG_LIST_POSTREMOVE(elm, field)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define LIST_INIT(head) do { \
|
||||||
|
(head)->lh_first = NULL; \
|
||||||
|
} while (/*CONSTCOND*/0)
|
||||||
|
|
||||||
|
#define LIST_INSERT_AFTER(listelm, elm, field) do { \
|
||||||
|
QUEUEDEBUG_LIST_OP((listelm), field) \
|
||||||
|
if (((elm)->field.le_next = (listelm)->field.le_next) != NULL) \
|
||||||
|
(listelm)->field.le_next->field.le_prev = \
|
||||||
|
&(elm)->field.le_next; \
|
||||||
|
(listelm)->field.le_next = (elm); \
|
||||||
|
(elm)->field.le_prev = &(listelm)->field.le_next; \
|
||||||
|
} while (/*CONSTCOND*/0)
|
||||||
|
|
||||||
|
#define LIST_INSERT_BEFORE(listelm, elm, field) do { \
|
||||||
|
QUEUEDEBUG_LIST_OP((listelm), field) \
|
||||||
|
(elm)->field.le_prev = (listelm)->field.le_prev; \
|
||||||
|
(elm)->field.le_next = (listelm); \
|
||||||
|
*(listelm)->field.le_prev = (elm); \
|
||||||
|
(listelm)->field.le_prev = &(elm)->field.le_next; \
|
||||||
|
} while (/*CONSTCOND*/0)
|
||||||
|
|
||||||
|
#define LIST_INSERT_HEAD(head, elm, field) do { \
|
||||||
|
QUEUEDEBUG_LIST_INSERT_HEAD((head), (elm), field) \
|
||||||
|
if (((elm)->field.le_next = (head)->lh_first) != NULL) \
|
||||||
|
(head)->lh_first->field.le_prev = &(elm)->field.le_next;\
|
||||||
|
(head)->lh_first = (elm); \
|
||||||
|
(elm)->field.le_prev = &(head)->lh_first; \
|
||||||
|
} while (/*CONSTCOND*/0)
|
||||||
|
|
||||||
|
#define LIST_REMOVE(elm, field) do { \
|
||||||
|
QUEUEDEBUG_LIST_OP((elm), field) \
|
||||||
|
if ((elm)->field.le_next != NULL) \
|
||||||
|
(elm)->field.le_next->field.le_prev = \
|
||||||
|
(elm)->field.le_prev; \
|
||||||
|
*(elm)->field.le_prev = (elm)->field.le_next; \
|
||||||
|
QUEUEDEBUG_LIST_POSTREMOVE((elm), field) \
|
||||||
|
} while (/*CONSTCOND*/0)
|
||||||
|
|
||||||
|
#define LIST_FOREACH(var, head, field) \
|
||||||
|
for ((var) = ((head)->lh_first); \
|
||||||
|
(var); \
|
||||||
|
(var) = ((var)->field.le_next))
|
||||||
|
|
||||||
|
/*
|
||||||
|
* List access methods.
|
||||||
|
*/
|
||||||
|
#define LIST_EMPTY(head) ((head)->lh_first == NULL)
|
||||||
|
#define LIST_FIRST(head) ((head)->lh_first)
|
||||||
|
#define LIST_NEXT(elm, field) ((elm)->field.le_next)
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Singly-linked List definitions.
|
||||||
|
*/
|
||||||
|
#define SLIST_HEAD(name, type) \
|
||||||
|
struct name { \
|
||||||
|
struct type *slh_first; /* first element */ \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define SLIST_HEAD_INITIALIZER(head) \
|
||||||
|
{ NULL }
|
||||||
|
|
||||||
|
#define SLIST_ENTRY(type) \
|
||||||
|
struct { \
|
||||||
|
struct type *sle_next; /* next element */ \
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Singly-linked List functions.
|
||||||
|
*/
|
||||||
|
#define SLIST_INIT(head) do { \
|
||||||
|
(head)->slh_first = NULL; \
|
||||||
|
} while (/*CONSTCOND*/0)
|
||||||
|
|
||||||
|
#define SLIST_INSERT_AFTER(slistelm, elm, field) do { \
|
||||||
|
(elm)->field.sle_next = (slistelm)->field.sle_next; \
|
||||||
|
(slistelm)->field.sle_next = (elm); \
|
||||||
|
} while (/*CONSTCOND*/0)
|
||||||
|
|
||||||
|
#define SLIST_INSERT_HEAD(head, elm, field) do { \
|
||||||
|
(elm)->field.sle_next = (head)->slh_first; \
|
||||||
|
(head)->slh_first = (elm); \
|
||||||
|
} while (/*CONSTCOND*/0)
|
||||||
|
|
||||||
|
#define SLIST_REMOVE_HEAD(head, field) do { \
|
||||||
|
(head)->slh_first = (head)->slh_first->field.sle_next; \
|
||||||
|
} while (/*CONSTCOND*/0)
|
||||||
|
|
||||||
|
#define SLIST_REMOVE(head, elm, type, field) do { \
|
||||||
|
if ((head)->slh_first == (elm)) { \
|
||||||
|
SLIST_REMOVE_HEAD((head), field); \
|
||||||
|
} \
|
||||||
|
else { \
|
||||||
|
struct type *curelm = (head)->slh_first; \
|
||||||
|
while(curelm->field.sle_next != (elm)) \
|
||||||
|
curelm = curelm->field.sle_next; \
|
||||||
|
curelm->field.sle_next = \
|
||||||
|
curelm->field.sle_next->field.sle_next; \
|
||||||
|
} \
|
||||||
|
} while (/*CONSTCOND*/0)
|
||||||
|
|
||||||
|
#define SLIST_REMOVE_AFTER(slistelm, field) do { \
|
||||||
|
(slistelm)->field.sle_next = \
|
||||||
|
SLIST_NEXT(SLIST_NEXT((slistelm), field), field); \
|
||||||
|
} while (/*CONSTCOND*/0)
|
||||||
|
|
||||||
|
#define SLIST_FOREACH(var, head, field) \
|
||||||
|
for((var) = (head)->slh_first; (var); (var) = (var)->field.sle_next)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Singly-linked List access methods.
|
||||||
|
*/
|
||||||
|
#define SLIST_EMPTY(head) ((head)->slh_first == NULL)
|
||||||
|
#define SLIST_FIRST(head) ((head)->slh_first)
|
||||||
|
#define SLIST_NEXT(elm, field) ((elm)->field.sle_next)
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Singly-linked Tail queue declarations.
|
||||||
|
*/
|
||||||
|
#define STAILQ_HEAD(name, type) \
|
||||||
|
struct name { \
|
||||||
|
struct type *stqh_first; /* first element */ \
|
||||||
|
struct type **stqh_last; /* addr of last next element */ \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define STAILQ_HEAD_INITIALIZER(head) \
|
||||||
|
{ NULL, &(head).stqh_first }
|
||||||
|
|
||||||
|
#define STAILQ_ENTRY(type) \
|
||||||
|
struct { \
|
||||||
|
struct type *stqe_next; /* next element */ \
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Singly-linked Tail queue functions.
|
||||||
|
*/
|
||||||
|
#define STAILQ_INIT(head) do { \
|
||||||
|
(head)->stqh_first = NULL; \
|
||||||
|
(head)->stqh_last = &(head)->stqh_first; \
|
||||||
|
} while (/*CONSTCOND*/0)
|
||||||
|
|
||||||
|
#define STAILQ_INSERT_HEAD(head, elm, field) do { \
|
||||||
|
if (((elm)->field.stqe_next = (head)->stqh_first) == NULL) \
|
||||||
|
(head)->stqh_last = &(elm)->field.stqe_next; \
|
||||||
|
(head)->stqh_first = (elm); \
|
||||||
|
} while (/*CONSTCOND*/0)
|
||||||
|
|
||||||
|
#define STAILQ_INSERT_TAIL(head, elm, field) do { \
|
||||||
|
(elm)->field.stqe_next = NULL; \
|
||||||
|
*(head)->stqh_last = (elm); \
|
||||||
|
(head)->stqh_last = &(elm)->field.stqe_next; \
|
||||||
|
} while (/*CONSTCOND*/0)
|
||||||
|
|
||||||
|
#define STAILQ_INSERT_AFTER(head, listelm, elm, field) do { \
|
||||||
|
if (((elm)->field.stqe_next = (listelm)->field.stqe_next) == NULL)\
|
||||||
|
(head)->stqh_last = &(elm)->field.stqe_next; \
|
||||||
|
(listelm)->field.stqe_next = (elm); \
|
||||||
|
} while (/*CONSTCOND*/0)
|
||||||
|
|
||||||
|
#define STAILQ_REMOVE_HEAD(head, field) do { \
|
||||||
|
if (((head)->stqh_first = (head)->stqh_first->field.stqe_next) == NULL) \
|
||||||
|
(head)->stqh_last = &(head)->stqh_first; \
|
||||||
|
} while (/*CONSTCOND*/0)
|
||||||
|
|
||||||
|
#define STAILQ_REMOVE(head, elm, type, field) do { \
|
||||||
|
if ((head)->stqh_first == (elm)) { \
|
||||||
|
STAILQ_REMOVE_HEAD((head), field); \
|
||||||
|
} else { \
|
||||||
|
struct type *curelm = (head)->stqh_first; \
|
||||||
|
while (curelm->field.stqe_next != (elm)) \
|
||||||
|
curelm = curelm->field.stqe_next; \
|
||||||
|
if ((curelm->field.stqe_next = \
|
||||||
|
curelm->field.stqe_next->field.stqe_next) == NULL) \
|
||||||
|
(head)->stqh_last = &(curelm)->field.stqe_next; \
|
||||||
|
} \
|
||||||
|
} while (/*CONSTCOND*/0)
|
||||||
|
|
||||||
|
#define STAILQ_FOREACH(var, head, field) \
|
||||||
|
for ((var) = ((head)->stqh_first); \
|
||||||
|
(var); \
|
||||||
|
(var) = ((var)->field.stqe_next))
|
||||||
|
|
||||||
|
#define STAILQ_CONCAT(head1, head2) do { \
|
||||||
|
if (!STAILQ_EMPTY((head2))) { \
|
||||||
|
*(head1)->stqh_last = (head2)->stqh_first; \
|
||||||
|
(head1)->stqh_last = (head2)->stqh_last; \
|
||||||
|
STAILQ_INIT((head2)); \
|
||||||
|
} \
|
||||||
|
} while (/*CONSTCOND*/0)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Singly-linked Tail queue access methods.
|
||||||
|
*/
|
||||||
|
#define STAILQ_EMPTY(head) ((head)->stqh_first == NULL)
|
||||||
|
#define STAILQ_FIRST(head) ((head)->stqh_first)
|
||||||
|
#define STAILQ_NEXT(elm, field) ((elm)->field.stqe_next)
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Simple queue definitions.
|
||||||
|
*/
|
||||||
|
#define SIMPLEQ_HEAD(name, type) \
|
||||||
|
struct name { \
|
||||||
|
struct type *sqh_first; /* first element */ \
|
||||||
|
struct type **sqh_last; /* addr of last next element */ \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define SIMPLEQ_HEAD_INITIALIZER(head) \
|
||||||
|
{ NULL, &(head).sqh_first }
|
||||||
|
|
||||||
|
#define SIMPLEQ_ENTRY(type) \
|
||||||
|
struct { \
|
||||||
|
struct type *sqe_next; /* next element */ \
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Simple queue functions.
|
||||||
|
*/
|
||||||
|
#define SIMPLEQ_INIT(head) do { \
|
||||||
|
(head)->sqh_first = NULL; \
|
||||||
|
(head)->sqh_last = &(head)->sqh_first; \
|
||||||
|
} while (/*CONSTCOND*/0)
|
||||||
|
|
||||||
|
#define SIMPLEQ_INSERT_HEAD(head, elm, field) do { \
|
||||||
|
if (((elm)->field.sqe_next = (head)->sqh_first) == NULL) \
|
||||||
|
(head)->sqh_last = &(elm)->field.sqe_next; \
|
||||||
|
(head)->sqh_first = (elm); \
|
||||||
|
} while (/*CONSTCOND*/0)
|
||||||
|
|
||||||
|
#define SIMPLEQ_INSERT_TAIL(head, elm, field) do { \
|
||||||
|
(elm)->field.sqe_next = NULL; \
|
||||||
|
*(head)->sqh_last = (elm); \
|
||||||
|
(head)->sqh_last = &(elm)->field.sqe_next; \
|
||||||
|
} while (/*CONSTCOND*/0)
|
||||||
|
|
||||||
|
#define SIMPLEQ_INSERT_AFTER(head, listelm, elm, field) do { \
|
||||||
|
if (((elm)->field.sqe_next = (listelm)->field.sqe_next) == NULL)\
|
||||||
|
(head)->sqh_last = &(elm)->field.sqe_next; \
|
||||||
|
(listelm)->field.sqe_next = (elm); \
|
||||||
|
} while (/*CONSTCOND*/0)
|
||||||
|
|
||||||
|
#define SIMPLEQ_REMOVE_HEAD(head, field) do { \
|
||||||
|
if (((head)->sqh_first = (head)->sqh_first->field.sqe_next) == NULL) \
|
||||||
|
(head)->sqh_last = &(head)->sqh_first; \
|
||||||
|
} while (/*CONSTCOND*/0)
|
||||||
|
|
||||||
|
#define SIMPLEQ_REMOVE(head, elm, type, field) do { \
|
||||||
|
if ((head)->sqh_first == (elm)) { \
|
||||||
|
SIMPLEQ_REMOVE_HEAD((head), field); \
|
||||||
|
} else { \
|
||||||
|
struct type *curelm = (head)->sqh_first; \
|
||||||
|
while (curelm->field.sqe_next != (elm)) \
|
||||||
|
curelm = curelm->field.sqe_next; \
|
||||||
|
if ((curelm->field.sqe_next = \
|
||||||
|
curelm->field.sqe_next->field.sqe_next) == NULL) \
|
||||||
|
(head)->sqh_last = &(curelm)->field.sqe_next; \
|
||||||
|
} \
|
||||||
|
} while (/*CONSTCOND*/0)
|
||||||
|
|
||||||
|
#define SIMPLEQ_FOREACH(var, head, field) \
|
||||||
|
for ((var) = ((head)->sqh_first); \
|
||||||
|
(var); \
|
||||||
|
(var) = ((var)->field.sqe_next))
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Simple queue access methods.
|
||||||
|
*/
|
||||||
|
#define SIMPLEQ_EMPTY(head) ((head)->sqh_first == NULL)
|
||||||
|
#define SIMPLEQ_FIRST(head) ((head)->sqh_first)
|
||||||
|
#define SIMPLEQ_NEXT(elm, field) ((elm)->field.sqe_next)
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Tail queue definitions.
|
||||||
|
*/
|
||||||
|
#define _TAILQ_HEAD(name, type, qual) \
|
||||||
|
struct name { \
|
||||||
|
qual type *tqh_first; /* first element */ \
|
||||||
|
qual type *qual *tqh_last; /* addr of last next element */ \
|
||||||
|
}
|
||||||
|
#define TAILQ_HEAD(name, type) _TAILQ_HEAD(name, struct type,)
|
||||||
|
|
||||||
|
#define TAILQ_HEAD_INITIALIZER(head) \
|
||||||
|
{ NULL, &(head).tqh_first }
|
||||||
|
|
||||||
|
#define _TAILQ_ENTRY(type, qual) \
|
||||||
|
struct { \
|
||||||
|
qual type *tqe_next; /* next element */ \
|
||||||
|
qual type *qual *tqe_prev; /* address of previous next element */\
|
||||||
|
}
|
||||||
|
#define TAILQ_ENTRY(type) _TAILQ_ENTRY(struct type,)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Tail queue functions.
|
||||||
|
*/
|
||||||
|
#if defined(_KERNEL) && defined(QUEUEDEBUG)
|
||||||
|
#define QUEUEDEBUG_TAILQ_INSERT_HEAD(head, elm, field) \
|
||||||
|
if ((head)->tqh_first && \
|
||||||
|
(head)->tqh_first->field.tqe_prev != &(head)->tqh_first) \
|
||||||
|
panic("TAILQ_INSERT_HEAD %p %s:%d", (head), __FILE__, __LINE__);
|
||||||
|
#define QUEUEDEBUG_TAILQ_INSERT_TAIL(head, elm, field) \
|
||||||
|
if (*(head)->tqh_last != NULL) \
|
||||||
|
panic("TAILQ_INSERT_TAIL %p %s:%d", (head), __FILE__, __LINE__);
|
||||||
|
#define QUEUEDEBUG_TAILQ_OP(elm, field) \
|
||||||
|
if ((elm)->field.tqe_next && \
|
||||||
|
(elm)->field.tqe_next->field.tqe_prev != \
|
||||||
|
&(elm)->field.tqe_next) \
|
||||||
|
panic("TAILQ_* forw %p %s:%d", (elm), __FILE__, __LINE__);\
|
||||||
|
if (*(elm)->field.tqe_prev != (elm)) \
|
||||||
|
panic("TAILQ_* back %p %s:%d", (elm), __FILE__, __LINE__);
|
||||||
|
#define QUEUEDEBUG_TAILQ_PREREMOVE(head, elm, field) \
|
||||||
|
if ((elm)->field.tqe_next == NULL && \
|
||||||
|
(head)->tqh_last != &(elm)->field.tqe_next) \
|
||||||
|
panic("TAILQ_PREREMOVE head %p elm %p %s:%d", \
|
||||||
|
(head), (elm), __FILE__, __LINE__);
|
||||||
|
#define QUEUEDEBUG_TAILQ_POSTREMOVE(elm, field) \
|
||||||
|
(elm)->field.tqe_next = (void *)1L; \
|
||||||
|
(elm)->field.tqe_prev = (void *)1L;
|
||||||
|
#else
|
||||||
|
#define QUEUEDEBUG_TAILQ_INSERT_HEAD(head, elm, field)
|
||||||
|
#define QUEUEDEBUG_TAILQ_INSERT_TAIL(head, elm, field)
|
||||||
|
#define QUEUEDEBUG_TAILQ_OP(elm, field)
|
||||||
|
#define QUEUEDEBUG_TAILQ_PREREMOVE(head, elm, field)
|
||||||
|
#define QUEUEDEBUG_TAILQ_POSTREMOVE(elm, field)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define TAILQ_INIT(head) do { \
|
||||||
|
(head)->tqh_first = NULL; \
|
||||||
|
(head)->tqh_last = &(head)->tqh_first; \
|
||||||
|
} while (/*CONSTCOND*/0)
|
||||||
|
|
||||||
|
#define TAILQ_INSERT_HEAD(head, elm, field) do { \
|
||||||
|
QUEUEDEBUG_TAILQ_INSERT_HEAD((head), (elm), field) \
|
||||||
|
if (((elm)->field.tqe_next = (head)->tqh_first) != NULL) \
|
||||||
|
(head)->tqh_first->field.tqe_prev = \
|
||||||
|
&(elm)->field.tqe_next; \
|
||||||
|
else \
|
||||||
|
(head)->tqh_last = &(elm)->field.tqe_next; \
|
||||||
|
(head)->tqh_first = (elm); \
|
||||||
|
(elm)->field.tqe_prev = &(head)->tqh_first; \
|
||||||
|
} while (/*CONSTCOND*/0)
|
||||||
|
|
||||||
|
#define TAILQ_INSERT_TAIL(head, elm, field) do { \
|
||||||
|
QUEUEDEBUG_TAILQ_INSERT_TAIL((head), (elm), field) \
|
||||||
|
(elm)->field.tqe_next = NULL; \
|
||||||
|
(elm)->field.tqe_prev = (head)->tqh_last; \
|
||||||
|
*(head)->tqh_last = (elm); \
|
||||||
|
(head)->tqh_last = &(elm)->field.tqe_next; \
|
||||||
|
} while (/*CONSTCOND*/0)
|
||||||
|
|
||||||
|
#define TAILQ_INSERT_AFTER(head, listelm, elm, field) do { \
|
||||||
|
QUEUEDEBUG_TAILQ_OP((listelm), field) \
|
||||||
|
if (((elm)->field.tqe_next = (listelm)->field.tqe_next) != NULL)\
|
||||||
|
(elm)->field.tqe_next->field.tqe_prev = \
|
||||||
|
&(elm)->field.tqe_next; \
|
||||||
|
else \
|
||||||
|
(head)->tqh_last = &(elm)->field.tqe_next; \
|
||||||
|
(listelm)->field.tqe_next = (elm); \
|
||||||
|
(elm)->field.tqe_prev = &(listelm)->field.tqe_next; \
|
||||||
|
} while (/*CONSTCOND*/0)
|
||||||
|
|
||||||
|
#define TAILQ_INSERT_BEFORE(listelm, elm, field) do { \
|
||||||
|
QUEUEDEBUG_TAILQ_OP((listelm), field) \
|
||||||
|
(elm)->field.tqe_prev = (listelm)->field.tqe_prev; \
|
||||||
|
(elm)->field.tqe_next = (listelm); \
|
||||||
|
*(listelm)->field.tqe_prev = (elm); \
|
||||||
|
(listelm)->field.tqe_prev = &(elm)->field.tqe_next; \
|
||||||
|
} while (/*CONSTCOND*/0)
|
||||||
|
|
||||||
|
#define TAILQ_REMOVE(head, elm, field) do { \
|
||||||
|
QUEUEDEBUG_TAILQ_PREREMOVE((head), (elm), field) \
|
||||||
|
QUEUEDEBUG_TAILQ_OP((elm), field) \
|
||||||
|
if (((elm)->field.tqe_next) != NULL) \
|
||||||
|
(elm)->field.tqe_next->field.tqe_prev = \
|
||||||
|
(elm)->field.tqe_prev; \
|
||||||
|
else \
|
||||||
|
(head)->tqh_last = (elm)->field.tqe_prev; \
|
||||||
|
*(elm)->field.tqe_prev = (elm)->field.tqe_next; \
|
||||||
|
QUEUEDEBUG_TAILQ_POSTREMOVE((elm), field); \
|
||||||
|
} while (/*CONSTCOND*/0)
|
||||||
|
|
||||||
|
#define TAILQ_FOREACH(var, head, field) \
|
||||||
|
for ((var) = ((head)->tqh_first); \
|
||||||
|
(var); \
|
||||||
|
(var) = ((var)->field.tqe_next))
|
||||||
|
|
||||||
|
#define TAILQ_FOREACH_SAFE(var, head, field, next) \
|
||||||
|
for ((var) = ((head)->tqh_first); \
|
||||||
|
(var) != NULL && ((next) = TAILQ_NEXT(var, field), 1); \
|
||||||
|
(var) = (next))
|
||||||
|
|
||||||
|
#define TAILQ_FOREACH_REVERSE(var, head, headname, field) \
|
||||||
|
for ((var) = (*(((struct headname *)((head)->tqh_last))->tqh_last)); \
|
||||||
|
(var); \
|
||||||
|
(var) = (*(((struct headname *)((var)->field.tqe_prev))->tqh_last)))
|
||||||
|
|
||||||
|
#define TAILQ_CONCAT(head1, head2, field) do { \
|
||||||
|
if (!TAILQ_EMPTY(head2)) { \
|
||||||
|
*(head1)->tqh_last = (head2)->tqh_first; \
|
||||||
|
(head2)->tqh_first->field.tqe_prev = (head1)->tqh_last; \
|
||||||
|
(head1)->tqh_last = (head2)->tqh_last; \
|
||||||
|
TAILQ_INIT((head2)); \
|
||||||
|
} \
|
||||||
|
} while (/*CONSTCOND*/0)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Tail queue access methods.
|
||||||
|
*/
|
||||||
|
#define TAILQ_EMPTY(head) ((head)->tqh_first == NULL)
|
||||||
|
#define TAILQ_FIRST(head) ((head)->tqh_first)
|
||||||
|
#define TAILQ_NEXT(elm, field) ((elm)->field.tqe_next)
|
||||||
|
|
||||||
|
#define TAILQ_LAST(head, headname) \
|
||||||
|
(*(((struct headname *)((head)->tqh_last))->tqh_last))
|
||||||
|
#define TAILQ_PREV(elm, headname, field) \
|
||||||
|
(*(((struct headname *)((elm)->field.tqe_prev))->tqh_last))
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Circular queue definitions.
|
||||||
|
*/
|
||||||
|
#if defined(_KERNEL) && defined(QUEUEDEBUG)
|
||||||
|
#define QUEUEDEBUG_CIRCLEQ_HEAD(head, field) \
|
||||||
|
if ((head)->cqh_first != (void *)(head) && \
|
||||||
|
(head)->cqh_first->field.cqe_prev != (void *)(head)) \
|
||||||
|
panic("CIRCLEQ head forw %p %s:%d", (head), \
|
||||||
|
__FILE__, __LINE__); \
|
||||||
|
if ((head)->cqh_last != (void *)(head) && \
|
||||||
|
(head)->cqh_last->field.cqe_next != (void *)(head)) \
|
||||||
|
panic("CIRCLEQ head back %p %s:%d", (head), \
|
||||||
|
__FILE__, __LINE__);
|
||||||
|
#define QUEUEDEBUG_CIRCLEQ_ELM(head, elm, field) \
|
||||||
|
if ((elm)->field.cqe_next == (void *)(head)) { \
|
||||||
|
if ((head)->cqh_last != (elm)) \
|
||||||
|
panic("CIRCLEQ elm last %p %s:%d", (elm), \
|
||||||
|
__FILE__, __LINE__); \
|
||||||
|
} else { \
|
||||||
|
if ((elm)->field.cqe_next->field.cqe_prev != (elm)) \
|
||||||
|
panic("CIRCLEQ elm forw %p %s:%d", (elm), \
|
||||||
|
__FILE__, __LINE__); \
|
||||||
|
} \
|
||||||
|
if ((elm)->field.cqe_prev == (void *)(head)) { \
|
||||||
|
if ((head)->cqh_first != (elm)) \
|
||||||
|
panic("CIRCLEQ elm first %p %s:%d", (elm), \
|
||||||
|
__FILE__, __LINE__); \
|
||||||
|
} else { \
|
||||||
|
if ((elm)->field.cqe_prev->field.cqe_next != (elm)) \
|
||||||
|
panic("CIRCLEQ elm prev %p %s:%d", (elm), \
|
||||||
|
__FILE__, __LINE__); \
|
||||||
|
}
|
||||||
|
#define QUEUEDEBUG_CIRCLEQ_POSTREMOVE(elm, field) \
|
||||||
|
(elm)->field.cqe_next = (void *)1L; \
|
||||||
|
(elm)->field.cqe_prev = (void *)1L;
|
||||||
|
#else
|
||||||
|
#define QUEUEDEBUG_CIRCLEQ_HEAD(head, field)
|
||||||
|
#define QUEUEDEBUG_CIRCLEQ_ELM(head, elm, field)
|
||||||
|
#define QUEUEDEBUG_CIRCLEQ_POSTREMOVE(elm, field)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define CIRCLEQ_HEAD(name, type) \
|
||||||
|
struct name { \
|
||||||
|
struct type *cqh_first; /* first element */ \
|
||||||
|
struct type *cqh_last; /* last element */ \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define CIRCLEQ_HEAD_INITIALIZER(head) \
|
||||||
|
{ (void *)&head, (void *)&head }
|
||||||
|
|
||||||
|
#define CIRCLEQ_ENTRY(type) \
|
||||||
|
struct { \
|
||||||
|
struct type *cqe_next; /* next element */ \
|
||||||
|
struct type *cqe_prev; /* previous element */ \
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Circular queue functions.
|
||||||
|
*/
|
||||||
|
#define CIRCLEQ_INIT(head) do { \
|
||||||
|
(head)->cqh_first = (void *)(head); \
|
||||||
|
(head)->cqh_last = (void *)(head); \
|
||||||
|
} while (/*CONSTCOND*/0)
|
||||||
|
|
||||||
|
#define CIRCLEQ_INSERT_AFTER(head, listelm, elm, field) do { \
|
||||||
|
QUEUEDEBUG_CIRCLEQ_HEAD((head), field) \
|
||||||
|
QUEUEDEBUG_CIRCLEQ_ELM((head), (listelm), field) \
|
||||||
|
(elm)->field.cqe_next = (listelm)->field.cqe_next; \
|
||||||
|
(elm)->field.cqe_prev = (listelm); \
|
||||||
|
if ((listelm)->field.cqe_next == (void *)(head)) \
|
||||||
|
(head)->cqh_last = (elm); \
|
||||||
|
else \
|
||||||
|
(listelm)->field.cqe_next->field.cqe_prev = (elm); \
|
||||||
|
(listelm)->field.cqe_next = (elm); \
|
||||||
|
} while (/*CONSTCOND*/0)
|
||||||
|
|
||||||
|
#define CIRCLEQ_INSERT_BEFORE(head, listelm, elm, field) do { \
|
||||||
|
QUEUEDEBUG_CIRCLEQ_HEAD((head), field) \
|
||||||
|
QUEUEDEBUG_CIRCLEQ_ELM((head), (listelm), field) \
|
||||||
|
(elm)->field.cqe_next = (listelm); \
|
||||||
|
(elm)->field.cqe_prev = (listelm)->field.cqe_prev; \
|
||||||
|
if ((listelm)->field.cqe_prev == (void *)(head)) \
|
||||||
|
(head)->cqh_first = (elm); \
|
||||||
|
else \
|
||||||
|
(listelm)->field.cqe_prev->field.cqe_next = (elm); \
|
||||||
|
(listelm)->field.cqe_prev = (elm); \
|
||||||
|
} while (/*CONSTCOND*/0)
|
||||||
|
|
||||||
|
#define CIRCLEQ_INSERT_HEAD(head, elm, field) do { \
|
||||||
|
QUEUEDEBUG_CIRCLEQ_HEAD((head), field) \
|
||||||
|
(elm)->field.cqe_next = (head)->cqh_first; \
|
||||||
|
(elm)->field.cqe_prev = (void *)(head); \
|
||||||
|
if ((head)->cqh_last == (void *)(head)) \
|
||||||
|
(head)->cqh_last = (elm); \
|
||||||
|
else \
|
||||||
|
(head)->cqh_first->field.cqe_prev = (elm); \
|
||||||
|
(head)->cqh_first = (elm); \
|
||||||
|
} while (/*CONSTCOND*/0)
|
||||||
|
|
||||||
|
#define CIRCLEQ_INSERT_TAIL(head, elm, field) do { \
|
||||||
|
QUEUEDEBUG_CIRCLEQ_HEAD((head), field) \
|
||||||
|
(elm)->field.cqe_next = (void *)(head); \
|
||||||
|
(elm)->field.cqe_prev = (head)->cqh_last; \
|
||||||
|
if ((head)->cqh_first == (void *)(head)) \
|
||||||
|
(head)->cqh_first = (elm); \
|
||||||
|
else \
|
||||||
|
(head)->cqh_last->field.cqe_next = (elm); \
|
||||||
|
(head)->cqh_last = (elm); \
|
||||||
|
} while (/*CONSTCOND*/0)
|
||||||
|
|
||||||
|
#define CIRCLEQ_REMOVE(head, elm, field) do { \
|
||||||
|
QUEUEDEBUG_CIRCLEQ_HEAD((head), field) \
|
||||||
|
QUEUEDEBUG_CIRCLEQ_ELM((head), (elm), field) \
|
||||||
|
if ((elm)->field.cqe_next == (void *)(head)) \
|
||||||
|
(head)->cqh_last = (elm)->field.cqe_prev; \
|
||||||
|
else \
|
||||||
|
(elm)->field.cqe_next->field.cqe_prev = \
|
||||||
|
(elm)->field.cqe_prev; \
|
||||||
|
if ((elm)->field.cqe_prev == (void *)(head)) \
|
||||||
|
(head)->cqh_first = (elm)->field.cqe_next; \
|
||||||
|
else \
|
||||||
|
(elm)->field.cqe_prev->field.cqe_next = \
|
||||||
|
(elm)->field.cqe_next; \
|
||||||
|
QUEUEDEBUG_CIRCLEQ_POSTREMOVE((elm), field) \
|
||||||
|
} while (/*CONSTCOND*/0)
|
||||||
|
|
||||||
|
#define CIRCLEQ_FOREACH(var, head, field) \
|
||||||
|
for ((var) = ((head)->cqh_first); \
|
||||||
|
(var) != (const void *)(head); \
|
||||||
|
(var) = ((var)->field.cqe_next))
|
||||||
|
|
||||||
|
#define CIRCLEQ_FOREACH_REVERSE(var, head, field) \
|
||||||
|
for ((var) = ((head)->cqh_last); \
|
||||||
|
(var) != (const void *)(head); \
|
||||||
|
(var) = ((var)->field.cqe_prev))
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Circular queue access methods.
|
||||||
|
*/
|
||||||
|
#define CIRCLEQ_EMPTY(head) ((head)->cqh_first == (void *)(head))
|
||||||
|
#define CIRCLEQ_FIRST(head) ((head)->cqh_first)
|
||||||
|
#define CIRCLEQ_LAST(head) ((head)->cqh_last)
|
||||||
|
#define CIRCLEQ_NEXT(elm, field) ((elm)->field.cqe_next)
|
||||||
|
#define CIRCLEQ_PREV(elm, field) ((elm)->field.cqe_prev)
|
||||||
|
|
||||||
|
#define CIRCLEQ_LOOP_NEXT(head, elm, field) \
|
||||||
|
(((elm)->field.cqe_next == (void *)(head)) \
|
||||||
|
? ((head)->cqh_first) \
|
||||||
|
: (elm->field.cqe_next))
|
||||||
|
#define CIRCLEQ_LOOP_PREV(head, elm, field) \
|
||||||
|
(((elm)->field.cqe_prev == (void *)(head)) \
|
||||||
|
? ((head)->cqh_last) \
|
||||||
|
: (elm->field.cqe_prev))
|
||||||
|
|
||||||
|
#endif /* !_SYS_QUEUE_H_ */
|
@ -30,7 +30,6 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#include <sys/cdefs.h>
|
#include <sys/cdefs.h>
|
||||||
#include <sys/queue.h>
|
|
||||||
/**
|
/**
|
||||||
* @cond
|
* @cond
|
||||||
*/
|
*/
|
||||||
@ -45,6 +44,9 @@
|
|||||||
#include <archive.h>
|
#include <archive.h>
|
||||||
#include <archive_entry.h>
|
#include <archive_entry.h>
|
||||||
|
|
||||||
|
/* Use our own queue header (from NetBSD) */
|
||||||
|
#include "queue.h"
|
||||||
|
|
||||||
__BEGIN_DECLS
|
__BEGIN_DECLS
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
27
lib/Makefile
27
lib/Makefile
@ -4,9 +4,24 @@ LIBXBPS_MAJOR = 0
|
|||||||
LIBXBPS_MINOR = 0
|
LIBXBPS_MINOR = 0
|
||||||
LIBXBPS_MICRO = 0
|
LIBXBPS_MICRO = 0
|
||||||
LIBXBPS_SHLIB = libxbps.so.$(LIBXBPS_MAJOR).$(LIBXBPS_MINOR).$(LIBXBPS_MICRO)
|
LIBXBPS_SHLIB = libxbps.so.$(LIBXBPS_MAJOR).$(LIBXBPS_MINOR).$(LIBXBPS_MICRO)
|
||||||
LDFLAGS += -lprop -larchive -lssl
|
LDFLAGS += -larchive -lssl -lz
|
||||||
LDFLAGS += -shared -Wl,-soname,libxbps.so.$(LIBXBPS_MAJOR)
|
LDFLAGS += -shared -Wl,-soname,libxbps.so.$(LIBXBPS_MAJOR)
|
||||||
|
|
||||||
|
# portableproplib
|
||||||
|
LIBPROP_OBJS = portableproplib/prop_array.o portableproplib/prop_bool.o
|
||||||
|
LIBPROP_OBJS += portableproplib/prop_dictionary.o portableproplib/prop_ingest.o
|
||||||
|
LIBPROP_OBJS += portableproplib/prop_object.o portableproplib/prop_rb.o
|
||||||
|
LIBPROP_OBJS += portableproplib/prop_stack.o portableproplib/prop_string.o
|
||||||
|
LIBPROP_OBJS += portableproplib/prop_array_util.o portableproplib/prop_number.o
|
||||||
|
LIBPROP_OBJS += portableproplib/prop_dictionary_util.o
|
||||||
|
LIBPROP_OBJS += portableproplib/prop_data.o
|
||||||
|
LIBPROP_CFLAGS = -Wno-error -Wno-cast-qual -Wno-cast-align -Wno-extra
|
||||||
|
|
||||||
|
ifdef USE_EXTERNAL_PROPLIB
|
||||||
|
LIBPROP_OBJS =
|
||||||
|
LDFLAGS += -lprop
|
||||||
|
endif
|
||||||
|
|
||||||
# libfetch
|
# libfetch
|
||||||
LIBFETCH_OBJS = fetch/common.o fetch/fetch.o fetch/file.o
|
LIBFETCH_OBJS = fetch/common.o fetch/fetch.o fetch/file.o
|
||||||
LIBFETCH_OBJS += fetch/ftp.o fetch/http.o
|
LIBFETCH_OBJS += fetch/ftp.o fetch/http.o
|
||||||
@ -40,17 +55,21 @@ $(LIBFETCH_OBJS): %.o: %.c $(LIBFETCH_INCS) $(LIBFETCH_GEN)
|
|||||||
@$(CC) $(CPPFLAGS) $(LIBFETCH_CPPFLAGS) $(CFLAGS) \
|
@$(CC) $(CPPFLAGS) $(LIBFETCH_CPPFLAGS) $(CFLAGS) \
|
||||||
$(LIBFETCH_CFLAGS) $(LIBFETCH_SHLIBCFLAGS) -c $< -o $@
|
$(LIBFETCH_CFLAGS) $(LIBFETCH_SHLIBCFLAGS) -c $< -o $@
|
||||||
|
|
||||||
|
$(LIBPROP_OBJS): %.o: %.c
|
||||||
|
@printf " [CC]\t\t$@\n"
|
||||||
|
@$(CC) $(CPPFLAGS) $(CFLAGS) $(LIBPROP_CFLAGS) -c $< -o $@
|
||||||
|
|
||||||
$(OBJS): %.o: %.c
|
$(OBJS): %.o: %.c
|
||||||
@printf " [CC]\t\t$@\n"
|
@printf " [CC]\t\t$@\n"
|
||||||
@$(CC) $(CPPFLAGS) $(CFLAGS) $(SHAREDLIB_CFLAGS) -c $< -o $@
|
@$(CC) $(CPPFLAGS) $(CFLAGS) $(SHAREDLIB_CFLAGS) -c $< -o $@
|
||||||
|
|
||||||
libxbps.so: $(OBJS) $(LIBFETCH_OBJS)
|
libxbps.so: $(OBJS) $(LIBFETCH_OBJS) $(LIBPROP_OBJS)
|
||||||
@printf " [CCLD]\t\t$@\n"
|
@printf " [CCLD]\t\t$@\n"
|
||||||
@$(CC) $(LDFLAGS) $^ -o $(LIBXBPS_SHLIB)
|
@$(CC) $(LDFLAGS) $^ -o $(LIBXBPS_SHLIB)
|
||||||
@-ln -sf $(LIBXBPS_SHLIB) libxbps.so.$(LIBXBPS_MAJOR)
|
@-ln -sf $(LIBXBPS_SHLIB) libxbps.so.$(LIBXBPS_MAJOR)
|
||||||
@-ln -sf $(LIBXBPS_SHLIB) libxbps.so
|
@-ln -sf $(LIBXBPS_SHLIB) libxbps.so
|
||||||
|
|
||||||
libxbps.a: $(OBJS) $(LIBFETCH_OBJS)
|
libxbps.a: $(OBJS) $(LIBFETCH_OBJS) $(LIBPROP_OBJS)
|
||||||
@printf " [AR]\t\t$@\n"
|
@printf " [AR]\t\t$@\n"
|
||||||
@$(AR) rcs $@ $^
|
@$(AR) rcs $@ $^
|
||||||
@printf " [RANLIB]\t$@\n"
|
@printf " [RANLIB]\t$@\n"
|
||||||
@ -70,5 +89,5 @@ uninstall:
|
|||||||
|
|
||||||
.PHONY: clean
|
.PHONY: clean
|
||||||
clean:
|
clean:
|
||||||
-rm -f libxbps* $(OBJS) $(LIBFETCH_OBJS)
|
-rm -f libxbps* $(OBJS) $(LIBFETCH_OBJS) $(LIBPROP_OBJS)
|
||||||
-rm -f $(LIBFETCH_GEN)
|
-rm -f $(LIBFETCH_GEN)
|
||||||
|
@ -63,7 +63,7 @@ xbps_config_file_from_archive_entry(prop_dictionary_t d,
|
|||||||
if (buf == NULL)
|
if (buf == NULL)
|
||||||
return errno;
|
return errno;
|
||||||
|
|
||||||
forigd = prop_dictionary_internalize_from_file(buf);
|
forigd = prop_dictionary_internalize_from_zfile(buf);
|
||||||
free(buf);
|
free(buf);
|
||||||
if (forigd == NULL) {
|
if (forigd == NULL) {
|
||||||
install_new = true;
|
install_new = true;
|
||||||
|
@ -138,7 +138,7 @@ xbps_find_pkg_from_plist(const char *plist, const char *pkgname)
|
|||||||
assert(plist != NULL);
|
assert(plist != NULL);
|
||||||
assert(pkgname != NULL);
|
assert(pkgname != NULL);
|
||||||
|
|
||||||
dict = prop_dictionary_internalize_from_file(plist);
|
dict = prop_dictionary_internalize_from_zfile(plist);
|
||||||
if (dict == NULL)
|
if (dict == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
@ -375,7 +375,7 @@ xbps_remove_pkg_dict_from_file(const char *pkg, const char *plist)
|
|||||||
assert(pkg != NULL);
|
assert(pkg != NULL);
|
||||||
assert(plist != NULL);
|
assert(plist != NULL);
|
||||||
|
|
||||||
pdict = prop_dictionary_internalize_from_file(plist);
|
pdict = prop_dictionary_internalize_from_zfile(plist);
|
||||||
if (pdict == NULL)
|
if (pdict == NULL)
|
||||||
return errno;
|
return errno;
|
||||||
|
|
||||||
@ -385,7 +385,7 @@ xbps_remove_pkg_dict_from_file(const char *pkg, const char *plist)
|
|||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!prop_dictionary_externalize_to_file(pdict, plist)) {
|
if (!prop_dictionary_externalize_to_zfile(pdict, plist)) {
|
||||||
prop_object_release(pdict);
|
prop_object_release(pdict);
|
||||||
return errno;
|
return errno;
|
||||||
}
|
}
|
||||||
|
142
lib/portableproplib/prop/prop_array.h
Normal file
142
lib/portableproplib/prop/prop_array.h
Normal file
@ -0,0 +1,142 @@
|
|||||||
|
/* $NetBSD: prop_array.h,v 1.8 2008/09/11 13:15:13 haad Exp $ */
|
||||||
|
|
||||||
|
/*-
|
||||||
|
* Copyright (c) 2006 The NetBSD Foundation, Inc.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This code is derived from software contributed to The NetBSD Foundation
|
||||||
|
* by Jason R. Thorpe.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||||
|
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||||
|
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||||
|
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _PROPLIB_PROP_ARRAY_H_
|
||||||
|
#define _PROPLIB_PROP_ARRAY_H_
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <prop/prop_object.h>
|
||||||
|
|
||||||
|
typedef struct _prop_array *prop_array_t;
|
||||||
|
|
||||||
|
__BEGIN_DECLS
|
||||||
|
prop_array_t prop_array_create(void);
|
||||||
|
prop_array_t prop_array_create_with_capacity(unsigned int);
|
||||||
|
|
||||||
|
prop_array_t prop_array_copy(prop_array_t);
|
||||||
|
prop_array_t prop_array_copy_mutable(prop_array_t);
|
||||||
|
|
||||||
|
unsigned int prop_array_capacity(prop_array_t);
|
||||||
|
unsigned int prop_array_count(prop_array_t);
|
||||||
|
bool prop_array_ensure_capacity(prop_array_t, unsigned int);
|
||||||
|
|
||||||
|
void prop_array_make_immutable(prop_array_t);
|
||||||
|
bool prop_array_mutable(prop_array_t);
|
||||||
|
|
||||||
|
prop_object_iterator_t prop_array_iterator(prop_array_t);
|
||||||
|
|
||||||
|
prop_object_t prop_array_get(prop_array_t, unsigned int);
|
||||||
|
bool prop_array_set(prop_array_t, unsigned int, prop_object_t);
|
||||||
|
bool prop_array_add(prop_array_t, prop_object_t);
|
||||||
|
void prop_array_remove(prop_array_t, unsigned int);
|
||||||
|
|
||||||
|
bool prop_array_equals(prop_array_t, prop_array_t);
|
||||||
|
|
||||||
|
char * prop_array_externalize(prop_array_t);
|
||||||
|
prop_array_t prop_array_internalize(const char *);
|
||||||
|
|
||||||
|
bool prop_array_externalize_to_file(prop_array_t, const char *);
|
||||||
|
bool prop_array_externalize_to_zfile(prop_array_t, const char *);
|
||||||
|
prop_array_t prop_array_internalize_from_file(const char *);
|
||||||
|
prop_array_t prop_array_internalize_from_zfile(const char *);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Utility routines to make it more convenient to work with values
|
||||||
|
* stored in dictionaries.
|
||||||
|
*/
|
||||||
|
bool prop_array_get_bool(prop_array_t, unsigned int,
|
||||||
|
bool *);
|
||||||
|
bool prop_array_set_bool(prop_array_t, unsigned int,
|
||||||
|
bool);
|
||||||
|
|
||||||
|
bool prop_array_get_int8(prop_array_t, unsigned int,
|
||||||
|
int8_t *);
|
||||||
|
bool prop_array_get_uint8(prop_array_t, unsigned int,
|
||||||
|
uint8_t *);
|
||||||
|
bool prop_array_set_int8(prop_array_t, unsigned int,
|
||||||
|
int8_t);
|
||||||
|
bool prop_array_set_uint8(prop_array_t, unsigned int,
|
||||||
|
uint8_t);
|
||||||
|
|
||||||
|
bool prop_array_get_int16(prop_array_t, unsigned int,
|
||||||
|
int16_t *);
|
||||||
|
bool prop_array_get_uint16(prop_array_t, unsigned int,
|
||||||
|
uint16_t *);
|
||||||
|
bool prop_array_set_int16(prop_array_t, unsigned int,
|
||||||
|
int16_t);
|
||||||
|
bool prop_array_set_uint16(prop_array_t, unsigned int,
|
||||||
|
uint16_t);
|
||||||
|
|
||||||
|
bool prop_array_get_int32(prop_array_t, unsigned int,
|
||||||
|
int32_t *);
|
||||||
|
bool prop_array_get_uint32(prop_array_t, unsigned int,
|
||||||
|
uint32_t *);
|
||||||
|
bool prop_array_set_int32(prop_array_t, unsigned int,
|
||||||
|
int32_t);
|
||||||
|
bool prop_array_set_uint32(prop_array_t, unsigned int,
|
||||||
|
uint32_t);
|
||||||
|
|
||||||
|
bool prop_array_get_int64(prop_array_t, unsigned int,
|
||||||
|
int64_t *);
|
||||||
|
bool prop_array_get_uint64(prop_array_t, unsigned int,
|
||||||
|
uint64_t *);
|
||||||
|
bool prop_array_set_int64(prop_array_t, unsigned int,
|
||||||
|
int64_t);
|
||||||
|
bool prop_array_set_uint64(prop_array_t, unsigned int,
|
||||||
|
uint64_t);
|
||||||
|
|
||||||
|
bool prop_array_add_int8(prop_array_t, int8_t);
|
||||||
|
bool prop_array_add_uint8(prop_array_t, uint8_t);
|
||||||
|
|
||||||
|
bool prop_array_add_int16(prop_array_t, int16_t);
|
||||||
|
bool prop_array_add_uint16(prop_array_t, uint16_t);
|
||||||
|
|
||||||
|
bool prop_array_add_int32(prop_array_t, int32_t);
|
||||||
|
bool prop_array_add_uint32(prop_array_t, uint32_t);
|
||||||
|
|
||||||
|
bool prop_array_add_int64(prop_array_t, int64_t);
|
||||||
|
bool prop_array_add_uint64(prop_array_t, uint64_t);
|
||||||
|
|
||||||
|
bool prop_array_get_cstring(prop_array_t, unsigned int,
|
||||||
|
char **);
|
||||||
|
bool prop_array_set_cstring(prop_array_t, unsigned int,
|
||||||
|
const char *);
|
||||||
|
|
||||||
|
bool prop_array_get_cstring_nocopy(prop_array_t,
|
||||||
|
unsigned int,
|
||||||
|
const char **);
|
||||||
|
bool prop_array_set_cstring_nocopy(prop_array_t,
|
||||||
|
unsigned int,
|
||||||
|
const char *);
|
||||||
|
|
||||||
|
__END_DECLS
|
||||||
|
|
||||||
|
#endif /* _PROPLIB_PROP_ARRAY_H_ */
|
49
lib/portableproplib/prop/prop_bool.h
Normal file
49
lib/portableproplib/prop/prop_bool.h
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
/* $NetBSD: prop_bool.h,v 1.4 2008/04/28 20:22:51 martin Exp $ */
|
||||||
|
|
||||||
|
/*-
|
||||||
|
* Copyright (c) 2006 The NetBSD Foundation, Inc.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This code is derived from software contributed to The NetBSD Foundation
|
||||||
|
* by Jason R. Thorpe.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||||
|
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||||
|
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||||
|
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _PROPLIB_PROP_BOOL_H_
|
||||||
|
#define _PROPLIB_PROP_BOOL_H_
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <prop/prop_object.h>
|
||||||
|
|
||||||
|
typedef struct _prop_bool *prop_bool_t;
|
||||||
|
|
||||||
|
__BEGIN_DECLS
|
||||||
|
prop_bool_t prop_bool_create(bool);
|
||||||
|
prop_bool_t prop_bool_copy(prop_bool_t);
|
||||||
|
|
||||||
|
bool prop_bool_true(prop_bool_t);
|
||||||
|
|
||||||
|
bool prop_bool_equals(prop_bool_t, prop_bool_t);
|
||||||
|
__END_DECLS
|
||||||
|
|
||||||
|
#endif /* _PROPLIB_PROP_BOOL_H_ */
|
56
lib/portableproplib/prop/prop_data.h
Normal file
56
lib/portableproplib/prop/prop_data.h
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
/* $NetBSD: prop_data.h,v 1.3 2008/04/28 20:22:51 martin Exp $ */
|
||||||
|
|
||||||
|
/*-
|
||||||
|
* Copyright (c) 2006 The NetBSD Foundation, Inc.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This code is derived from software contributed to The NetBSD Foundation
|
||||||
|
* by Jason R. Thorpe.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||||
|
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||||
|
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||||
|
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _PROPLIB_PROP_DATA_H_
|
||||||
|
#define _PROPLIB_PROP_DATA_H_
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <prop/prop_object.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
typedef struct _prop_data *prop_data_t;
|
||||||
|
|
||||||
|
__BEGIN_DECLS
|
||||||
|
prop_data_t prop_data_create_data(const void *, size_t);
|
||||||
|
prop_data_t prop_data_create_data_nocopy(const void *, size_t);
|
||||||
|
|
||||||
|
prop_data_t prop_data_copy(prop_data_t);
|
||||||
|
|
||||||
|
size_t prop_data_size(prop_data_t);
|
||||||
|
|
||||||
|
void * prop_data_data(prop_data_t);
|
||||||
|
const void * prop_data_data_nocopy(prop_data_t);
|
||||||
|
|
||||||
|
bool prop_data_equals(prop_data_t, prop_data_t);
|
||||||
|
bool prop_data_equals_data(prop_data_t, const void *, size_t);
|
||||||
|
__END_DECLS
|
||||||
|
|
||||||
|
#endif /* _PROPLIB_PROP_DATA_H_ */
|
148
lib/portableproplib/prop/prop_dictionary.h
Normal file
148
lib/portableproplib/prop/prop_dictionary.h
Normal file
@ -0,0 +1,148 @@
|
|||||||
|
/* $NetBSD: prop_dictionary.h,v 1.9 2008/04/28 20:22:51 martin Exp $ */
|
||||||
|
|
||||||
|
/*-
|
||||||
|
* Copyright (c) 2006 The NetBSD Foundation, Inc.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This code is derived from software contributed to The NetBSD Foundation
|
||||||
|
* by Jason R. Thorpe.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||||
|
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||||
|
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||||
|
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _PROPLIB_PROP_DICTIONARY_H_
|
||||||
|
#define _PROPLIB_PROP_DICTIONARY_H_
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <prop/prop_object.h>
|
||||||
|
#include <prop/prop_array.h>
|
||||||
|
|
||||||
|
typedef struct _prop_dictionary *prop_dictionary_t;
|
||||||
|
typedef struct _prop_dictionary_keysym *prop_dictionary_keysym_t;
|
||||||
|
|
||||||
|
__BEGIN_DECLS
|
||||||
|
prop_dictionary_t prop_dictionary_create(void);
|
||||||
|
prop_dictionary_t prop_dictionary_create_with_capacity(unsigned int);
|
||||||
|
|
||||||
|
prop_dictionary_t prop_dictionary_copy(prop_dictionary_t);
|
||||||
|
prop_dictionary_t prop_dictionary_copy_mutable(prop_dictionary_t);
|
||||||
|
|
||||||
|
unsigned int prop_dictionary_count(prop_dictionary_t);
|
||||||
|
bool prop_dictionary_ensure_capacity(prop_dictionary_t,
|
||||||
|
unsigned int);
|
||||||
|
|
||||||
|
void prop_dictionary_make_immutable(prop_dictionary_t);
|
||||||
|
bool prop_dictionary_mutable(prop_dictionary_t);
|
||||||
|
|
||||||
|
prop_object_iterator_t prop_dictionary_iterator(prop_dictionary_t);
|
||||||
|
prop_array_t prop_dictionary_all_keys(prop_dictionary_t);
|
||||||
|
|
||||||
|
prop_object_t prop_dictionary_get(prop_dictionary_t, const char *);
|
||||||
|
bool prop_dictionary_set(prop_dictionary_t, const char *,
|
||||||
|
prop_object_t);
|
||||||
|
void prop_dictionary_remove(prop_dictionary_t, const char *);
|
||||||
|
|
||||||
|
prop_object_t prop_dictionary_get_keysym(prop_dictionary_t,
|
||||||
|
prop_dictionary_keysym_t);
|
||||||
|
bool prop_dictionary_set_keysym(prop_dictionary_t,
|
||||||
|
prop_dictionary_keysym_t,
|
||||||
|
prop_object_t);
|
||||||
|
void prop_dictionary_remove_keysym(prop_dictionary_t,
|
||||||
|
prop_dictionary_keysym_t);
|
||||||
|
|
||||||
|
bool prop_dictionary_equals(prop_dictionary_t, prop_dictionary_t);
|
||||||
|
|
||||||
|
char * prop_dictionary_externalize(prop_dictionary_t);
|
||||||
|
prop_dictionary_t prop_dictionary_internalize(const char *);
|
||||||
|
|
||||||
|
bool prop_dictionary_externalize_to_file(prop_dictionary_t,
|
||||||
|
const char *);
|
||||||
|
bool prop_dictionary_externalize_to_zfile(prop_dictionary_t,
|
||||||
|
const char *);
|
||||||
|
prop_dictionary_t prop_dictionary_internalize_from_file(const char *);
|
||||||
|
prop_dictionary_t prop_dictionary_internalize_from_zfile(const char *);
|
||||||
|
|
||||||
|
const char * prop_dictionary_keysym_cstring_nocopy(prop_dictionary_keysym_t);
|
||||||
|
|
||||||
|
bool prop_dictionary_keysym_equals(prop_dictionary_keysym_t,
|
||||||
|
prop_dictionary_keysym_t);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Utility routines to make it more convenient to work with values
|
||||||
|
* stored in dictionaries.
|
||||||
|
*/
|
||||||
|
bool prop_dictionary_get_bool(prop_dictionary_t, const char *,
|
||||||
|
bool *);
|
||||||
|
bool prop_dictionary_set_bool(prop_dictionary_t, const char *,
|
||||||
|
bool);
|
||||||
|
|
||||||
|
bool prop_dictionary_get_int8(prop_dictionary_t, const char *,
|
||||||
|
int8_t *);
|
||||||
|
bool prop_dictionary_get_uint8(prop_dictionary_t, const char *,
|
||||||
|
uint8_t *);
|
||||||
|
bool prop_dictionary_set_int8(prop_dictionary_t, const char *,
|
||||||
|
int8_t);
|
||||||
|
bool prop_dictionary_set_uint8(prop_dictionary_t, const char *,
|
||||||
|
uint8_t);
|
||||||
|
|
||||||
|
bool prop_dictionary_get_int16(prop_dictionary_t, const char *,
|
||||||
|
int16_t *);
|
||||||
|
bool prop_dictionary_get_uint16(prop_dictionary_t, const char *,
|
||||||
|
uint16_t *);
|
||||||
|
bool prop_dictionary_set_int16(prop_dictionary_t, const char *,
|
||||||
|
int16_t);
|
||||||
|
bool prop_dictionary_set_uint16(prop_dictionary_t, const char *,
|
||||||
|
uint16_t);
|
||||||
|
|
||||||
|
bool prop_dictionary_get_int32(prop_dictionary_t, const char *,
|
||||||
|
int32_t *);
|
||||||
|
bool prop_dictionary_get_uint32(prop_dictionary_t, const char *,
|
||||||
|
uint32_t *);
|
||||||
|
bool prop_dictionary_set_int32(prop_dictionary_t, const char *,
|
||||||
|
int32_t);
|
||||||
|
bool prop_dictionary_set_uint32(prop_dictionary_t, const char *,
|
||||||
|
uint32_t);
|
||||||
|
|
||||||
|
bool prop_dictionary_get_int64(prop_dictionary_t, const char *,
|
||||||
|
int64_t *);
|
||||||
|
bool prop_dictionary_get_uint64(prop_dictionary_t, const char *,
|
||||||
|
uint64_t *);
|
||||||
|
bool prop_dictionary_set_int64(prop_dictionary_t, const char *,
|
||||||
|
int64_t);
|
||||||
|
bool prop_dictionary_set_uint64(prop_dictionary_t, const char *,
|
||||||
|
uint64_t);
|
||||||
|
|
||||||
|
bool prop_dictionary_get_cstring(prop_dictionary_t, const char *,
|
||||||
|
char **);
|
||||||
|
bool prop_dictionary_set_cstring(prop_dictionary_t, const char *,
|
||||||
|
const char *);
|
||||||
|
|
||||||
|
bool prop_dictionary_get_cstring_nocopy(prop_dictionary_t,
|
||||||
|
const char *,
|
||||||
|
const char **);
|
||||||
|
bool prop_dictionary_set_cstring_nocopy(prop_dictionary_t,
|
||||||
|
const char *,
|
||||||
|
const char *);
|
||||||
|
|
||||||
|
__END_DECLS
|
||||||
|
|
||||||
|
#endif /* _PROPLIB_PROP_DICTIONARY_H_ */
|
91
lib/portableproplib/prop/prop_ingest.h
Normal file
91
lib/portableproplib/prop/prop_ingest.h
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
/* $NetBSD: prop_ingest.h,v 1.3 2008/04/28 20:22:51 martin Exp $ */
|
||||||
|
|
||||||
|
/*-
|
||||||
|
* Copyright (c) 2006 The NetBSD Foundation, Inc.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This code is derived from software contributed to The NetBSD Foundation
|
||||||
|
* by Jason R. Thorpe.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||||
|
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||||
|
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||||
|
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _PROPLIB_PROP_INGEST_H_
|
||||||
|
#define _PROPLIB_PROP_INGEST_H_
|
||||||
|
|
||||||
|
#include <prop/prop_object.h>
|
||||||
|
#include <prop/prop_dictionary.h>
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
PROP_INGEST_ERROR_NO_ERROR = 0,
|
||||||
|
PROP_INGEST_ERROR_NO_KEY = 1,
|
||||||
|
PROP_INGEST_ERROR_WRONG_TYPE = 2,
|
||||||
|
PROP_INGEST_ERROR_HANDLER_FAILED = 3
|
||||||
|
} prop_ingest_error_t;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
PROP_INGEST_FLAG_OPTIONAL = 0x01
|
||||||
|
} prop_ingest_flag_t;
|
||||||
|
|
||||||
|
typedef struct _prop_ingest_context *prop_ingest_context_t;
|
||||||
|
|
||||||
|
typedef bool (*prop_ingest_handler_t)(prop_ingest_context_t, prop_object_t);
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
const char *pite_key;
|
||||||
|
prop_type_t pite_type;
|
||||||
|
unsigned int pite_flags;
|
||||||
|
prop_ingest_handler_t pite_handler;
|
||||||
|
} prop_ingest_table_entry;
|
||||||
|
|
||||||
|
#define PROP_INGEST(key_, type_, handler_) \
|
||||||
|
{ .pite_key = key_ , \
|
||||||
|
.pite_type = type_ , \
|
||||||
|
.pite_flags = 0 , \
|
||||||
|
.pite_handler = handler_ }
|
||||||
|
|
||||||
|
#define PROP_INGEST_OPTIONAL(key_, type_, handler_) \
|
||||||
|
{ .pite_key = key_ , \
|
||||||
|
.pite_type = type_ , \
|
||||||
|
.pite_flags = PROP_INGEST_FLAG_OPTIONAL , \
|
||||||
|
.pite_handler = handler_ }
|
||||||
|
|
||||||
|
#define PROP_INGEST_END \
|
||||||
|
{ .pite_key = NULL }
|
||||||
|
|
||||||
|
__BEGIN_DECLS
|
||||||
|
prop_ingest_context_t
|
||||||
|
prop_ingest_context_alloc(void *);
|
||||||
|
void prop_ingest_context_free(prop_ingest_context_t);
|
||||||
|
|
||||||
|
prop_ingest_error_t
|
||||||
|
prop_ingest_context_error(prop_ingest_context_t);
|
||||||
|
prop_type_t prop_ingest_context_type(prop_ingest_context_t);
|
||||||
|
const char * prop_ingest_context_key(prop_ingest_context_t);
|
||||||
|
void * prop_ingest_context_private(prop_ingest_context_t);
|
||||||
|
|
||||||
|
bool prop_dictionary_ingest(prop_dictionary_t,
|
||||||
|
const prop_ingest_table_entry[],
|
||||||
|
prop_ingest_context_t);
|
||||||
|
__END_DECLS
|
||||||
|
|
||||||
|
#endif /* _PROPLIB_PROP_INGEST_H_ */
|
57
lib/portableproplib/prop/prop_number.h
Normal file
57
lib/portableproplib/prop/prop_number.h
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
/* $NetBSD: prop_number.h,v 1.6 2008/04/28 20:22:51 martin Exp $ */
|
||||||
|
|
||||||
|
/*-
|
||||||
|
* Copyright (c) 2006 The NetBSD Foundation, Inc.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This code is derived from software contributed to The NetBSD Foundation
|
||||||
|
* by Jason R. Thorpe.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||||
|
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||||
|
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||||
|
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _PROPLIB_PROP_NUMBER_H_
|
||||||
|
#define _PROPLIB_PROP_NUMBER_H_
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <prop/prop_object.h>
|
||||||
|
|
||||||
|
typedef struct _prop_number *prop_number_t;
|
||||||
|
|
||||||
|
__BEGIN_DECLS
|
||||||
|
prop_number_t prop_number_create_integer(int64_t);
|
||||||
|
prop_number_t prop_number_create_unsigned_integer(uint64_t);
|
||||||
|
|
||||||
|
prop_number_t prop_number_copy(prop_number_t);
|
||||||
|
|
||||||
|
int prop_number_size(prop_number_t);
|
||||||
|
bool prop_number_unsigned(prop_number_t);
|
||||||
|
|
||||||
|
int64_t prop_number_integer_value(prop_number_t);
|
||||||
|
uint64_t prop_number_unsigned_integer_value(prop_number_t);
|
||||||
|
|
||||||
|
bool prop_number_equals(prop_number_t, prop_number_t);
|
||||||
|
bool prop_number_equals_integer(prop_number_t, int64_t);
|
||||||
|
bool prop_number_equals_unsigned_integer(prop_number_t, uint64_t);
|
||||||
|
__END_DECLS
|
||||||
|
|
||||||
|
#endif /* _PROPLIB_PROP_NUMBER_H_ */
|
67
lib/portableproplib/prop/prop_object.h
Normal file
67
lib/portableproplib/prop/prop_object.h
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
/* $NetBSD: prop_object.h,v 1.7 2008/04/28 20:22:51 martin Exp $ */
|
||||||
|
|
||||||
|
/*-
|
||||||
|
* Copyright (c) 2006 The NetBSD Foundation, Inc.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This code is derived from software contributed to The NetBSD Foundation
|
||||||
|
* by Jason R. Thorpe.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||||
|
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||||
|
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||||
|
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _PROPLIB_PROP_OBJECT_H_
|
||||||
|
#define _PROPLIB_PROP_OBJECT_H_
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
typedef void *prop_object_t;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
PROP_TYPE_UNKNOWN = 0x00000000,
|
||||||
|
PROP_TYPE_BOOL = 0x626f6f6c, /* 'bool' */
|
||||||
|
PROP_TYPE_NUMBER = 0x6e6d6272, /* 'nmbr' */
|
||||||
|
PROP_TYPE_STRING = 0x73746e67, /* 'stng' */
|
||||||
|
PROP_TYPE_DATA = 0x64617461, /* 'data' */
|
||||||
|
PROP_TYPE_ARRAY = 0x61726179, /* 'aray' */
|
||||||
|
PROP_TYPE_DICTIONARY = 0x64696374, /* 'dict' */
|
||||||
|
PROP_TYPE_DICT_KEYSYM = 0x646b6579 /* 'dkey' */
|
||||||
|
} prop_type_t;
|
||||||
|
|
||||||
|
__BEGIN_DECLS
|
||||||
|
void prop_object_retain(prop_object_t);
|
||||||
|
void prop_object_release(prop_object_t);
|
||||||
|
|
||||||
|
prop_type_t prop_object_type(prop_object_t);
|
||||||
|
|
||||||
|
bool prop_object_equals(prop_object_t, prop_object_t);
|
||||||
|
bool prop_object_equals_with_error(prop_object_t, prop_object_t, bool *);
|
||||||
|
|
||||||
|
typedef struct _prop_object_iterator *prop_object_iterator_t;
|
||||||
|
|
||||||
|
prop_object_t prop_object_iterator_next(prop_object_iterator_t);
|
||||||
|
void prop_object_iterator_reset(prop_object_iterator_t);
|
||||||
|
void prop_object_iterator_release(prop_object_iterator_t);
|
||||||
|
__END_DECLS
|
||||||
|
|
||||||
|
#endif /* _PROPLIB_PROP_OBJECT_H_ */
|
62
lib/portableproplib/prop/prop_string.h
Normal file
62
lib/portableproplib/prop/prop_string.h
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
/* $NetBSD: prop_string.h,v 1.3 2008/04/28 20:22:51 martin Exp $ */
|
||||||
|
|
||||||
|
/*-
|
||||||
|
* Copyright (c) 2006 The NetBSD Foundation, Inc.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This code is derived from software contributed to The NetBSD Foundation
|
||||||
|
* by Jason R. Thorpe.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||||
|
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||||
|
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||||
|
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _PROPLIB_PROP_STRING_H_
|
||||||
|
#define _PROPLIB_PROP_STRING_H_
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <prop/prop_object.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
typedef struct _prop_string *prop_string_t;
|
||||||
|
|
||||||
|
__BEGIN_DECLS
|
||||||
|
prop_string_t prop_string_create(void);
|
||||||
|
prop_string_t prop_string_create_cstring(const char *);
|
||||||
|
prop_string_t prop_string_create_cstring_nocopy(const char *);
|
||||||
|
|
||||||
|
prop_string_t prop_string_copy(prop_string_t);
|
||||||
|
prop_string_t prop_string_copy_mutable(prop_string_t);
|
||||||
|
|
||||||
|
size_t prop_string_size(prop_string_t);
|
||||||
|
bool prop_string_mutable(prop_string_t);
|
||||||
|
|
||||||
|
char * prop_string_cstring(prop_string_t);
|
||||||
|
const char * prop_string_cstring_nocopy(prop_string_t);
|
||||||
|
|
||||||
|
bool prop_string_append(prop_string_t, prop_string_t);
|
||||||
|
bool prop_string_append_cstring(prop_string_t, const char *);
|
||||||
|
|
||||||
|
bool prop_string_equals(prop_string_t, prop_string_t);
|
||||||
|
bool prop_string_equals_cstring(prop_string_t, const char *);
|
||||||
|
__END_DECLS
|
||||||
|
|
||||||
|
#endif /* _PROPLIB_PROP_STRING_H_ */
|
45
lib/portableproplib/prop/proplib.h
Normal file
45
lib/portableproplib/prop/proplib.h
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
/* $NetBSD: proplib.h,v 1.6 2008/04/28 20:22:51 martin Exp $ */
|
||||||
|
|
||||||
|
/*-
|
||||||
|
* Copyright (c) 2006 The NetBSD Foundation, Inc.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This code is derived from software contributed to The NetBSD Foundation
|
||||||
|
* by Jason R. Thorpe.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||||
|
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||||
|
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||||
|
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _PROPLIB_PROPLIB_H_
|
||||||
|
#define _PROPLIB_PROPLIB_H_
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include <prop/prop_array.h>
|
||||||
|
#include <prop/prop_bool.h>
|
||||||
|
#include <prop/prop_data.h>
|
||||||
|
#include <prop/prop_dictionary.h>
|
||||||
|
#include <prop/prop_number.h>
|
||||||
|
#include <prop/prop_string.h>
|
||||||
|
#include <prop/prop_ingest.h>
|
||||||
|
|
||||||
|
#endif /* _PROPLIB_PROPLIB_H_ */
|
1044
lib/portableproplib/prop_array.c
Normal file
1044
lib/portableproplib/prop_array.c
Normal file
File diff suppressed because it is too large
Load Diff
240
lib/portableproplib/prop_array_util.c
Normal file
240
lib/portableproplib/prop_array_util.c
Normal file
@ -0,0 +1,240 @@
|
|||||||
|
/* $NetBSD: prop_array_util.c,v 1.2 2008/09/11 13:15:13 haad Exp $ */
|
||||||
|
|
||||||
|
/*-
|
||||||
|
* Copyright (c) 2006 The NetBSD Foundation, Inc.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This code is derived from software contributed to The NetBSD Foundation
|
||||||
|
* by Jason R. Thorpe.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||||
|
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||||
|
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||||
|
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Utility routines to make it more convenient to work with values
|
||||||
|
* stored in array.
|
||||||
|
*
|
||||||
|
* Note: There is no special magic going on here. We use the standard
|
||||||
|
* proplib(3) APIs to do all of this work. Any application could do
|
||||||
|
* exactly what we're doing here.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <prop/proplib.h>
|
||||||
|
#include "prop_object_impl.h"
|
||||||
|
|
||||||
|
bool
|
||||||
|
prop_array_get_bool(prop_array_t array,
|
||||||
|
unsigned int indx,
|
||||||
|
bool *valp)
|
||||||
|
{
|
||||||
|
prop_bool_t b;
|
||||||
|
|
||||||
|
b = prop_array_get(array, indx);
|
||||||
|
if (prop_object_type(b) != PROP_TYPE_BOOL)
|
||||||
|
return (false);
|
||||||
|
|
||||||
|
*valp = prop_bool_true(b);
|
||||||
|
|
||||||
|
return (true);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
prop_array_set_bool(prop_array_t array,
|
||||||
|
unsigned int indx,
|
||||||
|
bool val)
|
||||||
|
{
|
||||||
|
prop_bool_t b;
|
||||||
|
int rv;
|
||||||
|
|
||||||
|
b = prop_bool_create(val);
|
||||||
|
if (b == NULL)
|
||||||
|
return (false);
|
||||||
|
rv = prop_array_set(array, indx, b);
|
||||||
|
prop_object_release(b);
|
||||||
|
|
||||||
|
return (rv);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define TEMPLATE(size) \
|
||||||
|
bool \
|
||||||
|
prop_array_get_int ## size (prop_array_t array, \
|
||||||
|
unsigned int indx, \
|
||||||
|
int ## size ## _t *valp) \
|
||||||
|
{ \
|
||||||
|
prop_number_t num; \
|
||||||
|
\
|
||||||
|
num = prop_array_get(array, indx); \
|
||||||
|
if (prop_object_type(num) != PROP_TYPE_NUMBER) \
|
||||||
|
return (false); \
|
||||||
|
\
|
||||||
|
if (prop_number_unsigned(num) && \
|
||||||
|
prop_number_unsigned_integer_value(num) > \
|
||||||
|
/*CONSTCOND*/((size) == 8 ? INT8_MAX : \
|
||||||
|
(size) == 16 ? INT16_MAX : \
|
||||||
|
(size) == 32 ? INT32_MAX : INT64_MAX)) { \
|
||||||
|
return (false); \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
if (prop_number_size(num) > (size)) \
|
||||||
|
return (false); \
|
||||||
|
\
|
||||||
|
*valp = (int ## size ## _t) prop_number_integer_value(num); \
|
||||||
|
\
|
||||||
|
return (true); \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
bool \
|
||||||
|
prop_array_get_uint ## size (prop_array_t array, \
|
||||||
|
unsigned int indx, \
|
||||||
|
uint ## size ## _t *valp) \
|
||||||
|
{ \
|
||||||
|
prop_number_t num; \
|
||||||
|
\
|
||||||
|
num = prop_array_get(array, indx); \
|
||||||
|
if (prop_object_type(num) != PROP_TYPE_NUMBER) \
|
||||||
|
return (false); \
|
||||||
|
\
|
||||||
|
if (prop_number_unsigned(num) == false && \
|
||||||
|
prop_number_integer_value(num) < 0) { \
|
||||||
|
return (false); \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
if (prop_number_size(num) > (size)) \
|
||||||
|
return (false); \
|
||||||
|
\
|
||||||
|
*valp = (uint ## size ## _t) \
|
||||||
|
prop_number_unsigned_integer_value(num); \
|
||||||
|
\
|
||||||
|
return (true); \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
bool \
|
||||||
|
prop_array_set_int ## size (prop_array_t array, \
|
||||||
|
unsigned int indx, \
|
||||||
|
int ## size ## _t val) \
|
||||||
|
{ \
|
||||||
|
prop_number_t num; \
|
||||||
|
int rv; \
|
||||||
|
\
|
||||||
|
num = prop_number_create_integer((int64_t) val); \
|
||||||
|
if (num == NULL) \
|
||||||
|
return (false); \
|
||||||
|
rv = prop_array_set(array, indx, num); \
|
||||||
|
prop_object_release(num); \
|
||||||
|
\
|
||||||
|
return (rv); \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
bool \
|
||||||
|
prop_array_set_uint ## size (prop_array_t array, \
|
||||||
|
unsigned int indx, \
|
||||||
|
uint ## size ## _t val) \
|
||||||
|
{ \
|
||||||
|
prop_number_t num; \
|
||||||
|
int rv; \
|
||||||
|
\
|
||||||
|
num = prop_number_create_unsigned_integer((uint64_t) val); \
|
||||||
|
if (num == NULL) \
|
||||||
|
return (false); \
|
||||||
|
rv = prop_array_set(array, indx, num); \
|
||||||
|
prop_object_release(num); \
|
||||||
|
\
|
||||||
|
return (rv); \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
bool \
|
||||||
|
prop_array_add_int ## size (prop_array_t array, \
|
||||||
|
int ## size ## _t val) \
|
||||||
|
{ \
|
||||||
|
prop_number_t num; \
|
||||||
|
int rv; \
|
||||||
|
\
|
||||||
|
num = prop_number_create_integer((int64_t) val); \
|
||||||
|
if (num == NULL) \
|
||||||
|
return (false); \
|
||||||
|
rv = prop_array_add(array, num); \
|
||||||
|
prop_object_release(num); \
|
||||||
|
\
|
||||||
|
return (rv); \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
bool \
|
||||||
|
prop_array_add_uint ## size (prop_array_t array, \
|
||||||
|
uint ## size ## _t val) \
|
||||||
|
{ \
|
||||||
|
prop_number_t num; \
|
||||||
|
int rv; \
|
||||||
|
\
|
||||||
|
num = prop_number_create_integer((int64_t) val); \
|
||||||
|
if (num == NULL) \
|
||||||
|
return (false); \
|
||||||
|
rv = prop_array_add(array, num); \
|
||||||
|
prop_object_release(num); \
|
||||||
|
\
|
||||||
|
return (rv); \
|
||||||
|
}
|
||||||
|
|
||||||
|
TEMPLATE(8)
|
||||||
|
TEMPLATE(16)
|
||||||
|
TEMPLATE(32)
|
||||||
|
TEMPLATE(64)
|
||||||
|
|
||||||
|
#undef TEMPLATE
|
||||||
|
|
||||||
|
#define TEMPLATE(variant, qualifier) \
|
||||||
|
bool \
|
||||||
|
prop_array_get_cstring ## variant (prop_array_t array, \
|
||||||
|
unsigned int indx, \
|
||||||
|
qualifier char **cpp) \
|
||||||
|
{ \
|
||||||
|
prop_string_t str; \
|
||||||
|
\
|
||||||
|
str = prop_array_get(array, indx); \
|
||||||
|
if (prop_object_type(str) != PROP_TYPE_STRING) \
|
||||||
|
return (false); \
|
||||||
|
\
|
||||||
|
*cpp = prop_string_cstring ## variant (str); \
|
||||||
|
\
|
||||||
|
return (*cpp == NULL ? false : true); \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
bool \
|
||||||
|
prop_array_set_cstring ## variant (prop_array_t array, \
|
||||||
|
unsigned int indx, \
|
||||||
|
const char *cp) \
|
||||||
|
{ \
|
||||||
|
prop_string_t str; \
|
||||||
|
int rv; \
|
||||||
|
\
|
||||||
|
str = prop_string_create_cstring ## variant (cp); \
|
||||||
|
if (str == NULL) \
|
||||||
|
return (false); \
|
||||||
|
rv = prop_array_set(array, indx, str); \
|
||||||
|
prop_object_release(str); \
|
||||||
|
\
|
||||||
|
return (rv); \
|
||||||
|
}
|
||||||
|
|
||||||
|
TEMPLATE(,)
|
||||||
|
TEMPLATE(_nocopy,const)
|
||||||
|
|
||||||
|
#undef TEMPLATE
|
223
lib/portableproplib/prop_bool.c
Normal file
223
lib/portableproplib/prop_bool.c
Normal file
@ -0,0 +1,223 @@
|
|||||||
|
/* $NetBSD: prop_bool.c,v 1.16 2008/08/03 04:00:12 thorpej Exp $ */
|
||||||
|
|
||||||
|
/*-
|
||||||
|
* Copyright (c) 2006 The NetBSD Foundation, Inc.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This code is derived from software contributed to The NetBSD Foundation
|
||||||
|
* by Jason R. Thorpe.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||||
|
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||||
|
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||||
|
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <prop/prop_bool.h>
|
||||||
|
#include "prop_object_impl.h"
|
||||||
|
|
||||||
|
struct _prop_bool {
|
||||||
|
struct _prop_object pb_obj;
|
||||||
|
bool pb_value;
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct _prop_bool _prop_bool_true;
|
||||||
|
static struct _prop_bool _prop_bool_false;
|
||||||
|
|
||||||
|
_PROP_MUTEX_DECL_STATIC(_prop_bool_initialized_mutex)
|
||||||
|
static bool _prop_bool_initialized;
|
||||||
|
|
||||||
|
static _prop_object_free_rv_t
|
||||||
|
_prop_bool_free(prop_stack_t, prop_object_t *);
|
||||||
|
static bool _prop_bool_externalize(
|
||||||
|
struct _prop_object_externalize_context *,
|
||||||
|
void *);
|
||||||
|
static _prop_object_equals_rv_t
|
||||||
|
_prop_bool_equals(prop_object_t, prop_object_t,
|
||||||
|
void **, void **,
|
||||||
|
prop_object_t *, prop_object_t *);
|
||||||
|
|
||||||
|
static const struct _prop_object_type _prop_object_type_bool = {
|
||||||
|
.pot_type = PROP_TYPE_BOOL,
|
||||||
|
.pot_free = _prop_bool_free,
|
||||||
|
.pot_extern = _prop_bool_externalize,
|
||||||
|
.pot_equals = _prop_bool_equals,
|
||||||
|
};
|
||||||
|
|
||||||
|
#define prop_object_is_bool(x) \
|
||||||
|
((x) != NULL && (x)->pb_obj.po_type == &_prop_object_type_bool)
|
||||||
|
|
||||||
|
/* ARGSUSED */
|
||||||
|
static _prop_object_free_rv_t
|
||||||
|
_prop_bool_free(prop_stack_t stack, prop_object_t *obj)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* This should never happen as we "leak" our initial reference
|
||||||
|
* count.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* XXX forced assertion failure? */
|
||||||
|
return (_PROP_OBJECT_FREE_DONE);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
_prop_bool_externalize(struct _prop_object_externalize_context *ctx,
|
||||||
|
void *v)
|
||||||
|
{
|
||||||
|
prop_bool_t pb = v;
|
||||||
|
|
||||||
|
return (_prop_object_externalize_empty_tag(ctx,
|
||||||
|
pb->pb_value ? "true" : "false"));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ARGSUSED */
|
||||||
|
static _prop_object_equals_rv_t
|
||||||
|
_prop_bool_equals(prop_object_t v1, prop_object_t v2,
|
||||||
|
void **stored_pointer1, void **stored_pointer2,
|
||||||
|
prop_object_t *next_obj1, prop_object_t *next_obj2)
|
||||||
|
{
|
||||||
|
prop_bool_t b1 = v1;
|
||||||
|
prop_bool_t b2 = v2;
|
||||||
|
|
||||||
|
if (! (prop_object_is_bool(b1) &&
|
||||||
|
prop_object_is_bool(b2)))
|
||||||
|
return (_PROP_OBJECT_EQUALS_FALSE);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Since we only ever allocate one true and one false,
|
||||||
|
* save ourselves a couple of memory operations.
|
||||||
|
*/
|
||||||
|
if (b1 == b2)
|
||||||
|
return (_PROP_OBJECT_EQUALS_TRUE);
|
||||||
|
else
|
||||||
|
return (_PROP_OBJECT_EQUALS_FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
static prop_bool_t
|
||||||
|
_prop_bool_alloc(bool val)
|
||||||
|
{
|
||||||
|
prop_bool_t pb;
|
||||||
|
|
||||||
|
if (! _prop_bool_initialized) {
|
||||||
|
_PROP_MUTEX_LOCK(_prop_bool_initialized_mutex);
|
||||||
|
if (! _prop_bool_initialized) {
|
||||||
|
_prop_object_init(&_prop_bool_true.pb_obj,
|
||||||
|
&_prop_object_type_bool);
|
||||||
|
_prop_bool_true.pb_value = true;
|
||||||
|
|
||||||
|
_prop_object_init(&_prop_bool_false.pb_obj,
|
||||||
|
&_prop_object_type_bool);
|
||||||
|
_prop_bool_false.pb_value = false;
|
||||||
|
|
||||||
|
_prop_bool_initialized = true;
|
||||||
|
}
|
||||||
|
_PROP_MUTEX_UNLOCK(_prop_bool_initialized_mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
pb = val ? &_prop_bool_true : &_prop_bool_false;
|
||||||
|
prop_object_retain(pb);
|
||||||
|
|
||||||
|
return (pb);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* prop_bool_create --
|
||||||
|
* Create a prop_bool_t and initialize it with the
|
||||||
|
* provided boolean value.
|
||||||
|
*/
|
||||||
|
prop_bool_t
|
||||||
|
prop_bool_create(bool val)
|
||||||
|
{
|
||||||
|
|
||||||
|
return (_prop_bool_alloc(val));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* prop_bool_copy --
|
||||||
|
* Copy a prop_bool_t.
|
||||||
|
*/
|
||||||
|
prop_bool_t
|
||||||
|
prop_bool_copy(prop_bool_t opb)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (! prop_object_is_bool(opb))
|
||||||
|
return (NULL);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Because we only ever allocate one true and one false, this
|
||||||
|
* can be reduced to a simple retain operation.
|
||||||
|
*/
|
||||||
|
prop_object_retain(opb);
|
||||||
|
return (opb);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* prop_bool_true --
|
||||||
|
* Get the value of a prop_bool_t.
|
||||||
|
*/
|
||||||
|
bool
|
||||||
|
prop_bool_true(prop_bool_t pb)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (! prop_object_is_bool(pb))
|
||||||
|
return (false);
|
||||||
|
|
||||||
|
return (pb->pb_value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* prop_bool_equals --
|
||||||
|
* Return true if the boolean values are equivalent.
|
||||||
|
*/
|
||||||
|
bool
|
||||||
|
prop_bool_equals(prop_bool_t b1, prop_bool_t b2)
|
||||||
|
{
|
||||||
|
if (!prop_object_is_bool(b1) || !prop_object_is_bool(b2))
|
||||||
|
return (false);
|
||||||
|
|
||||||
|
return (prop_object_equals(b1, b2));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* _prop_bool_internalize --
|
||||||
|
* Parse a <true/> or <false/> and return the object created from
|
||||||
|
* the external representation.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* ARGSUSED */
|
||||||
|
bool
|
||||||
|
_prop_bool_internalize(prop_stack_t stack, prop_object_t *obj,
|
||||||
|
struct _prop_object_internalize_context *ctx)
|
||||||
|
{
|
||||||
|
bool val;
|
||||||
|
|
||||||
|
/* No attributes, and it must be an empty element. */
|
||||||
|
if (ctx->poic_tagattr != NULL ||
|
||||||
|
ctx->poic_is_empty_element == false)
|
||||||
|
return (true);
|
||||||
|
|
||||||
|
if (_PROP_TAG_MATCH(ctx, "true"))
|
||||||
|
val = true;
|
||||||
|
else {
|
||||||
|
_PROP_ASSERT(_PROP_TAG_MATCH(ctx, "false"));
|
||||||
|
val = false;
|
||||||
|
}
|
||||||
|
*obj = prop_bool_create(val);
|
||||||
|
return (true);
|
||||||
|
}
|
616
lib/portableproplib/prop_data.c
Normal file
616
lib/portableproplib/prop_data.c
Normal file
@ -0,0 +1,616 @@
|
|||||||
|
/* $NetBSD: prop_data.c,v 1.13 2008/08/03 04:00:12 thorpej Exp $ */
|
||||||
|
|
||||||
|
/*-
|
||||||
|
* Copyright (c) 2006 The NetBSD Foundation, Inc.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This code is derived from software contributed to The NetBSD Foundation
|
||||||
|
* by Jason R. Thorpe.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||||
|
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||||
|
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||||
|
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <prop/prop_data.h>
|
||||||
|
#include "prop_object_impl.h"
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include <limits.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
struct _prop_data {
|
||||||
|
struct _prop_object pd_obj;
|
||||||
|
union {
|
||||||
|
void * pdu_mutable;
|
||||||
|
const void * pdu_immutable;
|
||||||
|
} pd_un;
|
||||||
|
#define pd_mutable pd_un.pdu_mutable
|
||||||
|
#define pd_immutable pd_un.pdu_immutable
|
||||||
|
size_t pd_size;
|
||||||
|
int pd_flags;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define PD_F_NOCOPY 0x01
|
||||||
|
|
||||||
|
_PROP_POOL_INIT(_prop_data_pool, sizeof(struct _prop_data), "propdata")
|
||||||
|
|
||||||
|
_PROP_MALLOC_DEFINE(M_PROP_DATA, "prop data",
|
||||||
|
"property data container object")
|
||||||
|
|
||||||
|
static _prop_object_free_rv_t
|
||||||
|
_prop_data_free(prop_stack_t, prop_object_t *);
|
||||||
|
static bool _prop_data_externalize(
|
||||||
|
struct _prop_object_externalize_context *,
|
||||||
|
void *);
|
||||||
|
static _prop_object_equals_rv_t
|
||||||
|
_prop_data_equals(prop_object_t, prop_object_t,
|
||||||
|
void **, void **,
|
||||||
|
prop_object_t *, prop_object_t *);
|
||||||
|
|
||||||
|
static const struct _prop_object_type _prop_object_type_data = {
|
||||||
|
.pot_type = PROP_TYPE_DATA,
|
||||||
|
.pot_free = _prop_data_free,
|
||||||
|
.pot_extern = _prop_data_externalize,
|
||||||
|
.pot_equals = _prop_data_equals,
|
||||||
|
};
|
||||||
|
|
||||||
|
#define prop_object_is_data(x) \
|
||||||
|
((x) != NULL && (x)->pd_obj.po_type == &_prop_object_type_data)
|
||||||
|
|
||||||
|
/* ARGSUSED */
|
||||||
|
static _prop_object_free_rv_t
|
||||||
|
_prop_data_free(prop_stack_t stack, prop_object_t *obj)
|
||||||
|
{
|
||||||
|
prop_data_t pd = *obj;
|
||||||
|
|
||||||
|
if ((pd->pd_flags & PD_F_NOCOPY) == 0 && pd->pd_mutable != NULL)
|
||||||
|
_PROP_FREE(pd->pd_mutable, M_PROP_DATA);
|
||||||
|
_PROP_POOL_PUT(_prop_data_pool, pd);
|
||||||
|
|
||||||
|
return (_PROP_OBJECT_FREE_DONE);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char _prop_data_base64[] =
|
||||||
|
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||||
|
static const char _prop_data_pad64 = '=';
|
||||||
|
|
||||||
|
static bool
|
||||||
|
_prop_data_externalize(struct _prop_object_externalize_context *ctx, void *v)
|
||||||
|
{
|
||||||
|
prop_data_t pd = v;
|
||||||
|
size_t i, srclen;
|
||||||
|
const uint8_t *src;
|
||||||
|
uint8_t output[4];
|
||||||
|
uint8_t input[3];
|
||||||
|
|
||||||
|
if (pd->pd_size == 0)
|
||||||
|
return (_prop_object_externalize_empty_tag(ctx, "data"));
|
||||||
|
|
||||||
|
if (_prop_object_externalize_start_tag(ctx, "data") == false)
|
||||||
|
return (false);
|
||||||
|
|
||||||
|
for (src = pd->pd_immutable, srclen = pd->pd_size;
|
||||||
|
srclen > 2; srclen -= 3) {
|
||||||
|
input[0] = *src++;
|
||||||
|
input[1] = *src++;
|
||||||
|
input[2] = *src++;
|
||||||
|
|
||||||
|
output[0] = (uint32_t)input[0] >> 2;
|
||||||
|
output[1] = ((uint32_t)(input[0] & 0x03) << 4) +
|
||||||
|
((uint32_t)input[1] >> 4);
|
||||||
|
output[2] = ((uint32_t)(input[1] & 0x0f) << 2) +
|
||||||
|
((uint32_t)input[2] >> 6);
|
||||||
|
output[3] = input[2] & 0x3f;
|
||||||
|
_PROP_ASSERT(output[0] < 64);
|
||||||
|
_PROP_ASSERT(output[1] < 64);
|
||||||
|
_PROP_ASSERT(output[2] < 64);
|
||||||
|
_PROP_ASSERT(output[3] < 64);
|
||||||
|
|
||||||
|
if (_prop_object_externalize_append_char(ctx,
|
||||||
|
_prop_data_base64[output[0]]) == false ||
|
||||||
|
_prop_object_externalize_append_char(ctx,
|
||||||
|
_prop_data_base64[output[1]]) == false ||
|
||||||
|
_prop_object_externalize_append_char(ctx,
|
||||||
|
_prop_data_base64[output[2]]) == false ||
|
||||||
|
_prop_object_externalize_append_char(ctx,
|
||||||
|
_prop_data_base64[output[3]]) == false)
|
||||||
|
return (false);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (srclen != 0) {
|
||||||
|
input[0] = input[1] = input[2] = '\0';
|
||||||
|
for (i = 0; i < srclen; i++)
|
||||||
|
input[i] = *src++;
|
||||||
|
|
||||||
|
output[0] = (uint32_t)input[0] >> 2;
|
||||||
|
output[1] = ((uint32_t)(input[0] & 0x03) << 4) +
|
||||||
|
((uint32_t)input[1] >> 4);
|
||||||
|
output[2] = ((uint32_t)(input[1] & 0x0f) << 2) +
|
||||||
|
((uint32_t)input[2] >> 6);
|
||||||
|
_PROP_ASSERT(output[0] < 64);
|
||||||
|
_PROP_ASSERT(output[1] < 64);
|
||||||
|
_PROP_ASSERT(output[2] < 64);
|
||||||
|
|
||||||
|
if (_prop_object_externalize_append_char(ctx,
|
||||||
|
_prop_data_base64[output[0]]) == false ||
|
||||||
|
_prop_object_externalize_append_char(ctx,
|
||||||
|
_prop_data_base64[output[1]]) == false ||
|
||||||
|
_prop_object_externalize_append_char(ctx,
|
||||||
|
srclen == 1 ? _prop_data_pad64
|
||||||
|
: _prop_data_base64[output[2]]) == false ||
|
||||||
|
_prop_object_externalize_append_char(ctx,
|
||||||
|
_prop_data_pad64) == false)
|
||||||
|
return (false);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_prop_object_externalize_end_tag(ctx, "data") == false)
|
||||||
|
return (false);
|
||||||
|
|
||||||
|
return (true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ARGSUSED */
|
||||||
|
static _prop_object_equals_rv_t
|
||||||
|
_prop_data_equals(prop_object_t v1, prop_object_t v2,
|
||||||
|
void **stored_pointer1, void **stored_pointer2,
|
||||||
|
prop_object_t *next_obj1, prop_object_t *next_obj2)
|
||||||
|
{
|
||||||
|
prop_data_t pd1 = v1;
|
||||||
|
prop_data_t pd2 = v2;
|
||||||
|
|
||||||
|
if (pd1 == pd2)
|
||||||
|
return (_PROP_OBJECT_EQUALS_TRUE);
|
||||||
|
if (pd1->pd_size != pd2->pd_size)
|
||||||
|
return (_PROP_OBJECT_EQUALS_FALSE);
|
||||||
|
if (pd1->pd_size == 0) {
|
||||||
|
_PROP_ASSERT(pd1->pd_immutable == NULL);
|
||||||
|
_PROP_ASSERT(pd2->pd_immutable == NULL);
|
||||||
|
return (_PROP_OBJECT_EQUALS_TRUE);
|
||||||
|
}
|
||||||
|
if (memcmp(pd1->pd_immutable, pd2->pd_immutable, pd1->pd_size) == 0)
|
||||||
|
return _PROP_OBJECT_EQUALS_TRUE;
|
||||||
|
else
|
||||||
|
return _PROP_OBJECT_EQUALS_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static prop_data_t
|
||||||
|
_prop_data_alloc(void)
|
||||||
|
{
|
||||||
|
prop_data_t pd;
|
||||||
|
|
||||||
|
pd = _PROP_POOL_GET(_prop_data_pool);
|
||||||
|
if (pd != NULL) {
|
||||||
|
_prop_object_init(&pd->pd_obj, &_prop_object_type_data);
|
||||||
|
|
||||||
|
pd->pd_mutable = NULL;
|
||||||
|
pd->pd_size = 0;
|
||||||
|
pd->pd_flags = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (pd);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* prop_data_create_data --
|
||||||
|
* Create a data container that contains a copy of the data.
|
||||||
|
*/
|
||||||
|
prop_data_t
|
||||||
|
prop_data_create_data(const void *v, size_t size)
|
||||||
|
{
|
||||||
|
prop_data_t pd;
|
||||||
|
void *nv;
|
||||||
|
|
||||||
|
pd = _prop_data_alloc();
|
||||||
|
if (pd != NULL && size != 0) {
|
||||||
|
nv = _PROP_MALLOC(size, M_PROP_DATA);
|
||||||
|
if (nv == NULL) {
|
||||||
|
prop_object_release(pd);
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
memcpy(nv, v, size);
|
||||||
|
pd->pd_mutable = nv;
|
||||||
|
pd->pd_size = size;
|
||||||
|
}
|
||||||
|
return (pd);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* prop_data_create_data_nocopy --
|
||||||
|
* Create an immutable data container that contains a refrence to the
|
||||||
|
* provided external data.
|
||||||
|
*/
|
||||||
|
prop_data_t
|
||||||
|
prop_data_create_data_nocopy(const void *v, size_t size)
|
||||||
|
{
|
||||||
|
prop_data_t pd;
|
||||||
|
|
||||||
|
pd = _prop_data_alloc();
|
||||||
|
if (pd != NULL) {
|
||||||
|
pd->pd_immutable = v;
|
||||||
|
pd->pd_size = size;
|
||||||
|
pd->pd_flags |= PD_F_NOCOPY;
|
||||||
|
}
|
||||||
|
return (pd);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* prop_data_copy --
|
||||||
|
* Copy a data container. If the original data is external, then
|
||||||
|
* the copy is also references the same external data.
|
||||||
|
*/
|
||||||
|
prop_data_t
|
||||||
|
prop_data_copy(prop_data_t opd)
|
||||||
|
{
|
||||||
|
prop_data_t pd;
|
||||||
|
|
||||||
|
if (! prop_object_is_data(opd))
|
||||||
|
return (NULL);
|
||||||
|
|
||||||
|
pd = _prop_data_alloc();
|
||||||
|
if (pd != NULL) {
|
||||||
|
pd->pd_size = opd->pd_size;
|
||||||
|
pd->pd_flags = opd->pd_flags;
|
||||||
|
if (opd->pd_flags & PD_F_NOCOPY)
|
||||||
|
pd->pd_immutable = opd->pd_immutable;
|
||||||
|
else if (opd->pd_size != 0) {
|
||||||
|
void *nv = _PROP_MALLOC(pd->pd_size, M_PROP_DATA);
|
||||||
|
if (nv == NULL) {
|
||||||
|
prop_object_release(pd);
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
memcpy(nv, opd->pd_immutable, opd->pd_size);
|
||||||
|
pd->pd_mutable = nv;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (pd);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* prop_data_size --
|
||||||
|
* Return the size of the data.
|
||||||
|
*/
|
||||||
|
size_t
|
||||||
|
prop_data_size(prop_data_t pd)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (! prop_object_is_data(pd))
|
||||||
|
return (0);
|
||||||
|
|
||||||
|
return (pd->pd_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* prop_data_data --
|
||||||
|
* Return a copy of the contents of the data container.
|
||||||
|
* The data is allocated with the M_TEMP malloc type.
|
||||||
|
* If the data container is empty, NULL is returned.
|
||||||
|
*/
|
||||||
|
void *
|
||||||
|
prop_data_data(prop_data_t pd)
|
||||||
|
{
|
||||||
|
void *v;
|
||||||
|
|
||||||
|
if (! prop_object_is_data(pd))
|
||||||
|
return (NULL);
|
||||||
|
|
||||||
|
if (pd->pd_size == 0) {
|
||||||
|
_PROP_ASSERT(pd->pd_immutable == NULL);
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
_PROP_ASSERT(pd->pd_immutable != NULL);
|
||||||
|
|
||||||
|
v = _PROP_MALLOC(pd->pd_size, M_TEMP);
|
||||||
|
if (v != NULL)
|
||||||
|
memcpy(v, pd->pd_immutable, pd->pd_size);
|
||||||
|
|
||||||
|
return (v);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* prop_data_data_nocopy --
|
||||||
|
* Return an immutable reference to the contents of the data
|
||||||
|
* container.
|
||||||
|
*/
|
||||||
|
const void *
|
||||||
|
prop_data_data_nocopy(prop_data_t pd)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (! prop_object_is_data(pd))
|
||||||
|
return (NULL);
|
||||||
|
|
||||||
|
_PROP_ASSERT((pd->pd_size == 0 && pd->pd_immutable == NULL) ||
|
||||||
|
(pd->pd_size != 0 && pd->pd_immutable != NULL));
|
||||||
|
|
||||||
|
return (pd->pd_immutable);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* prop_data_equals --
|
||||||
|
* Return true if two strings are equivalent.
|
||||||
|
*/
|
||||||
|
bool
|
||||||
|
prop_data_equals(prop_data_t pd1, prop_data_t pd2)
|
||||||
|
{
|
||||||
|
if (!prop_object_is_data(pd1) || !prop_object_is_data(pd2))
|
||||||
|
return (false);
|
||||||
|
|
||||||
|
return (prop_object_equals(pd1, pd2));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* prop_data_equals_data --
|
||||||
|
* Return true if the contained data is equivalent to the specified
|
||||||
|
* external data.
|
||||||
|
*/
|
||||||
|
bool
|
||||||
|
prop_data_equals_data(prop_data_t pd, const void *v, size_t size)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (! prop_object_is_data(pd))
|
||||||
|
return (false);
|
||||||
|
|
||||||
|
if (pd->pd_size != size)
|
||||||
|
return (false);
|
||||||
|
return (memcmp(pd->pd_immutable, v, size) == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
_prop_data_internalize_decode(struct _prop_object_internalize_context *ctx,
|
||||||
|
uint8_t *target, size_t targsize, size_t *sizep,
|
||||||
|
const char **cpp)
|
||||||
|
{
|
||||||
|
const char *src;
|
||||||
|
size_t tarindex;
|
||||||
|
int state, ch;
|
||||||
|
const char *pos;
|
||||||
|
|
||||||
|
state = 0;
|
||||||
|
tarindex = 0;
|
||||||
|
src = ctx->poic_cp;
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
ch = (unsigned char) *src++;
|
||||||
|
if (_PROP_EOF(ch))
|
||||||
|
return (false);
|
||||||
|
if (_PROP_ISSPACE(ch))
|
||||||
|
continue;
|
||||||
|
if (ch == '<') {
|
||||||
|
src--;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (ch == _prop_data_pad64)
|
||||||
|
break;
|
||||||
|
|
||||||
|
pos = strchr(_prop_data_base64, ch);
|
||||||
|
if (pos == NULL)
|
||||||
|
return (false);
|
||||||
|
|
||||||
|
switch (state) {
|
||||||
|
case 0:
|
||||||
|
if (target) {
|
||||||
|
if (tarindex >= targsize)
|
||||||
|
return (false);
|
||||||
|
target[tarindex] =
|
||||||
|
(uint8_t)((pos - _prop_data_base64) << 2);
|
||||||
|
}
|
||||||
|
state = 1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 1:
|
||||||
|
if (target) {
|
||||||
|
if (tarindex + 1 >= targsize)
|
||||||
|
return (false);
|
||||||
|
target[tarindex] |=
|
||||||
|
(uint32_t)(pos - _prop_data_base64) >> 4;
|
||||||
|
target[tarindex + 1] =
|
||||||
|
(uint8_t)(((pos - _prop_data_base64) & 0xf)
|
||||||
|
<< 4);
|
||||||
|
}
|
||||||
|
tarindex++;
|
||||||
|
state = 2;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
if (target) {
|
||||||
|
if (tarindex + 1 >= targsize)
|
||||||
|
return (false);
|
||||||
|
target[tarindex] |=
|
||||||
|
(uint32_t)(pos - _prop_data_base64) >> 2;
|
||||||
|
target[tarindex + 1] =
|
||||||
|
(uint8_t)(((pos - _prop_data_base64)
|
||||||
|
& 0x3) << 6);
|
||||||
|
}
|
||||||
|
tarindex++;
|
||||||
|
state = 3;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 3:
|
||||||
|
if (target) {
|
||||||
|
if (tarindex >= targsize)
|
||||||
|
return (false);
|
||||||
|
target[tarindex] |= (uint8_t)
|
||||||
|
(pos - _prop_data_base64);
|
||||||
|
}
|
||||||
|
tarindex++;
|
||||||
|
state = 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
_PROP_ASSERT(/*CONSTCOND*/0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We are done decoding the Base64 characters. Let's see if we
|
||||||
|
* ended up on a byte boundary and/or with unrecognized trailing
|
||||||
|
* characters.
|
||||||
|
*/
|
||||||
|
if (ch == _prop_data_pad64) {
|
||||||
|
ch = (unsigned char) *src; /* src already advanced */
|
||||||
|
if (_PROP_EOF(ch))
|
||||||
|
return (false);
|
||||||
|
switch (state) {
|
||||||
|
case 0: /* Invalid = in first position */
|
||||||
|
case 1: /* Invalid = in second position */
|
||||||
|
return (false);
|
||||||
|
|
||||||
|
case 2: /* Valid, one byte of info */
|
||||||
|
/* Skip whitespace */
|
||||||
|
for (ch = (unsigned char) *src++;
|
||||||
|
ch != '<'; ch = (unsigned char) *src++) {
|
||||||
|
if (_PROP_EOF(ch))
|
||||||
|
return (false);
|
||||||
|
if (!_PROP_ISSPACE(ch))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
/* Make sure there is another trailing = */
|
||||||
|
if (ch != _prop_data_pad64)
|
||||||
|
return (false);
|
||||||
|
ch = (unsigned char) *src;
|
||||||
|
/* FALLTHROUGH */
|
||||||
|
|
||||||
|
case 3: /* Valid, two bytes of info */
|
||||||
|
/*
|
||||||
|
* We know this char is a =. Is there anything but
|
||||||
|
* whitespace after it?
|
||||||
|
*/
|
||||||
|
for (ch = (unsigned char) *src++;
|
||||||
|
ch != '<'; ch = (unsigned char) *src++) {
|
||||||
|
if (_PROP_EOF(ch))
|
||||||
|
return (false);
|
||||||
|
if (!_PROP_ISSPACE(ch))
|
||||||
|
return (false);
|
||||||
|
}
|
||||||
|
/* back up to '<' */
|
||||||
|
src--;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/*
|
||||||
|
* We ended by seeing the end of the Base64 string. Make
|
||||||
|
* sure there are no partial bytes lying around.
|
||||||
|
*/
|
||||||
|
if (state != 0)
|
||||||
|
return (false);
|
||||||
|
}
|
||||||
|
|
||||||
|
_PROP_ASSERT(*src == '<');
|
||||||
|
if (sizep != NULL)
|
||||||
|
*sizep = tarindex;
|
||||||
|
if (cpp != NULL)
|
||||||
|
*cpp = src;
|
||||||
|
|
||||||
|
return (true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* _prop_data_internalize --
|
||||||
|
* Parse a <data>...</data> and return the object created from the
|
||||||
|
* external representation.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* strtoul is used for parsing, enforce. */
|
||||||
|
typedef int PROP_DATA_ASSERT[/* CONSTCOND */sizeof(size_t) == sizeof(unsigned long) ? 1 : -1];
|
||||||
|
|
||||||
|
/* ARGSUSED */
|
||||||
|
bool
|
||||||
|
_prop_data_internalize(prop_stack_t stack, prop_object_t *obj,
|
||||||
|
struct _prop_object_internalize_context *ctx)
|
||||||
|
{
|
||||||
|
prop_data_t data;
|
||||||
|
uint8_t *buf;
|
||||||
|
size_t len, alen;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We don't accept empty elements.
|
||||||
|
* This actually only checks for the node to be <data/>
|
||||||
|
* (Which actually causes another error if found.)
|
||||||
|
*/
|
||||||
|
if (ctx->poic_is_empty_element)
|
||||||
|
return (true);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If we got a "size" attribute, get the size of the data blob
|
||||||
|
* from that. Otherwise, we have to figure it out from the base64.
|
||||||
|
*/
|
||||||
|
if (ctx->poic_tagattr != NULL) {
|
||||||
|
char *cp;
|
||||||
|
|
||||||
|
if (!_PROP_TAGATTR_MATCH(ctx, "size") ||
|
||||||
|
ctx->poic_tagattrval_len == 0)
|
||||||
|
return (true);
|
||||||
|
|
||||||
|
errno = 0;
|
||||||
|
len = strtoul(ctx->poic_tagattrval, &cp, 0);
|
||||||
|
if (len == ULONG_MAX && errno == ERANGE)
|
||||||
|
return (true);
|
||||||
|
if (cp != ctx->poic_tagattrval + ctx->poic_tagattrval_len)
|
||||||
|
return (true);
|
||||||
|
_PROP_ASSERT(*cp == '\"');
|
||||||
|
} else if (_prop_data_internalize_decode(ctx, NULL, 0, &len,
|
||||||
|
NULL) == false)
|
||||||
|
return (true);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Always allocate one extra in case we don't land on an even byte
|
||||||
|
* boundary during the decode.
|
||||||
|
*/
|
||||||
|
buf = _PROP_MALLOC(len + 1, M_PROP_DATA);
|
||||||
|
if (buf == NULL)
|
||||||
|
return (true);
|
||||||
|
|
||||||
|
if (_prop_data_internalize_decode(ctx, buf, len + 1, &alen,
|
||||||
|
&ctx->poic_cp) == false) {
|
||||||
|
_PROP_FREE(buf, M_PROP_DATA);
|
||||||
|
return (true);
|
||||||
|
}
|
||||||
|
if (alen != len) {
|
||||||
|
_PROP_FREE(buf, M_PROP_DATA);
|
||||||
|
return (true);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_prop_object_internalize_find_tag(ctx, "data",
|
||||||
|
_PROP_TAG_TYPE_END) == false) {
|
||||||
|
_PROP_FREE(buf, M_PROP_DATA);
|
||||||
|
return (true);
|
||||||
|
}
|
||||||
|
|
||||||
|
data = _prop_data_alloc();
|
||||||
|
if (data == NULL) {
|
||||||
|
_PROP_FREE(buf, M_PROP_DATA);
|
||||||
|
return (true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Handle alternate type of empty node.
|
||||||
|
* XML document could contain open/close tags, yet still be empty.
|
||||||
|
*/
|
||||||
|
if (alen == 0) {
|
||||||
|
_PROP_FREE(buf, M_PROP_DATA);
|
||||||
|
data->pd_mutable = NULL;
|
||||||
|
} else {
|
||||||
|
data->pd_mutable = buf;
|
||||||
|
}
|
||||||
|
data->pd_size = len;
|
||||||
|
|
||||||
|
*obj = data;
|
||||||
|
return (true);
|
||||||
|
}
|
1542
lib/portableproplib/prop_dictionary.c
Normal file
1542
lib/portableproplib/prop_dictionary.c
Normal file
File diff suppressed because it is too large
Load Diff
208
lib/portableproplib/prop_dictionary_util.c
Normal file
208
lib/portableproplib/prop_dictionary_util.c
Normal file
@ -0,0 +1,208 @@
|
|||||||
|
/* $NetBSD: prop_dictionary_util.c,v 1.3 2008/04/28 20:22:53 martin Exp $ */
|
||||||
|
|
||||||
|
/*-
|
||||||
|
* Copyright (c) 2006 The NetBSD Foundation, Inc.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This code is derived from software contributed to The NetBSD Foundation
|
||||||
|
* by Jason R. Thorpe.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||||
|
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||||
|
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||||
|
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Utility routines to make it more convenient to work with values
|
||||||
|
* stored in dictionaries.
|
||||||
|
*
|
||||||
|
* Note: There is no special magic going on here. We use the standard
|
||||||
|
* proplib(3) APIs to do all of this work. Any application could do
|
||||||
|
* exactly what we're doing here.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <prop/proplib.h>
|
||||||
|
#include "prop_object_impl.h" /* only to hide kernel vs. not-kernel */
|
||||||
|
|
||||||
|
bool
|
||||||
|
prop_dictionary_get_bool(prop_dictionary_t dict,
|
||||||
|
const char *key,
|
||||||
|
bool *valp)
|
||||||
|
{
|
||||||
|
prop_bool_t b;
|
||||||
|
|
||||||
|
b = prop_dictionary_get(dict, key);
|
||||||
|
if (prop_object_type(b) != PROP_TYPE_BOOL)
|
||||||
|
return (false);
|
||||||
|
|
||||||
|
*valp = prop_bool_true(b);
|
||||||
|
|
||||||
|
return (true);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
prop_dictionary_set_bool(prop_dictionary_t dict,
|
||||||
|
const char *key,
|
||||||
|
bool val)
|
||||||
|
{
|
||||||
|
prop_bool_t b;
|
||||||
|
int rv;
|
||||||
|
|
||||||
|
b = prop_bool_create(val);
|
||||||
|
if (b == NULL)
|
||||||
|
return (false);
|
||||||
|
rv = prop_dictionary_set(dict, key, b);
|
||||||
|
prop_object_release(b);
|
||||||
|
|
||||||
|
return (rv);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define TEMPLATE(size) \
|
||||||
|
bool \
|
||||||
|
prop_dictionary_get_int ## size (prop_dictionary_t dict, \
|
||||||
|
const char *key, \
|
||||||
|
int ## size ## _t *valp) \
|
||||||
|
{ \
|
||||||
|
prop_number_t num; \
|
||||||
|
\
|
||||||
|
num = prop_dictionary_get(dict, key); \
|
||||||
|
if (prop_object_type(num) != PROP_TYPE_NUMBER) \
|
||||||
|
return (false); \
|
||||||
|
\
|
||||||
|
if (prop_number_unsigned(num) && \
|
||||||
|
prop_number_unsigned_integer_value(num) > \
|
||||||
|
/*CONSTCOND*/((size) == 8 ? INT8_MAX : \
|
||||||
|
(size) == 16 ? INT16_MAX : \
|
||||||
|
(size) == 32 ? INT32_MAX : INT64_MAX)) { \
|
||||||
|
return (false); \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
if (prop_number_size(num) > (size)) \
|
||||||
|
return (false); \
|
||||||
|
\
|
||||||
|
*valp = (int ## size ## _t) prop_number_integer_value(num); \
|
||||||
|
\
|
||||||
|
return (true); \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
bool \
|
||||||
|
prop_dictionary_get_uint ## size (prop_dictionary_t dict, \
|
||||||
|
const char *key, \
|
||||||
|
uint ## size ## _t *valp) \
|
||||||
|
{ \
|
||||||
|
prop_number_t num; \
|
||||||
|
\
|
||||||
|
num = prop_dictionary_get(dict, key); \
|
||||||
|
if (prop_object_type(num) != PROP_TYPE_NUMBER) \
|
||||||
|
return (false); \
|
||||||
|
\
|
||||||
|
if (prop_number_unsigned(num) == false && \
|
||||||
|
prop_number_integer_value(num) < 0) { \
|
||||||
|
return (false); \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
if (prop_number_size(num) > (size)) \
|
||||||
|
return (false); \
|
||||||
|
\
|
||||||
|
*valp = (uint ## size ## _t) \
|
||||||
|
prop_number_unsigned_integer_value(num); \
|
||||||
|
\
|
||||||
|
return (true); \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
bool \
|
||||||
|
prop_dictionary_set_int ## size (prop_dictionary_t dict, \
|
||||||
|
const char *key, \
|
||||||
|
int ## size ## _t val) \
|
||||||
|
{ \
|
||||||
|
prop_number_t num; \
|
||||||
|
int rv; \
|
||||||
|
\
|
||||||
|
num = prop_number_create_integer((int64_t) val); \
|
||||||
|
if (num == NULL) \
|
||||||
|
return (false); \
|
||||||
|
rv = prop_dictionary_set(dict, key, num); \
|
||||||
|
prop_object_release(num); \
|
||||||
|
\
|
||||||
|
return (rv); \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
bool \
|
||||||
|
prop_dictionary_set_uint ## size (prop_dictionary_t dict, \
|
||||||
|
const char *key, \
|
||||||
|
uint ## size ## _t val) \
|
||||||
|
{ \
|
||||||
|
prop_number_t num; \
|
||||||
|
int rv; \
|
||||||
|
\
|
||||||
|
num = prop_number_create_unsigned_integer((uint64_t) val); \
|
||||||
|
if (num == NULL) \
|
||||||
|
return (false); \
|
||||||
|
rv = prop_dictionary_set(dict, key, num); \
|
||||||
|
prop_object_release(num); \
|
||||||
|
\
|
||||||
|
return (rv); \
|
||||||
|
}
|
||||||
|
|
||||||
|
TEMPLATE(8)
|
||||||
|
TEMPLATE(16)
|
||||||
|
TEMPLATE(32)
|
||||||
|
TEMPLATE(64)
|
||||||
|
|
||||||
|
#undef TEMPLATE
|
||||||
|
|
||||||
|
#define TEMPLATE(variant, qualifier) \
|
||||||
|
bool \
|
||||||
|
prop_dictionary_get_cstring ## variant (prop_dictionary_t dict, \
|
||||||
|
const char *key, \
|
||||||
|
qualifier char **cpp) \
|
||||||
|
{ \
|
||||||
|
prop_string_t str; \
|
||||||
|
\
|
||||||
|
str = prop_dictionary_get(dict, key); \
|
||||||
|
if (prop_object_type(str) != PROP_TYPE_STRING) \
|
||||||
|
return (false); \
|
||||||
|
\
|
||||||
|
*cpp = prop_string_cstring ## variant (str); \
|
||||||
|
\
|
||||||
|
return (*cpp == NULL ? false : true); \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
bool \
|
||||||
|
prop_dictionary_set_cstring ## variant (prop_dictionary_t dict, \
|
||||||
|
const char *key, \
|
||||||
|
const char *cp) \
|
||||||
|
{ \
|
||||||
|
prop_string_t str; \
|
||||||
|
int rv; \
|
||||||
|
\
|
||||||
|
str = prop_string_create_cstring ## variant (cp); \
|
||||||
|
if (str == NULL) \
|
||||||
|
return (false); \
|
||||||
|
rv = prop_dictionary_set(dict, key, str); \
|
||||||
|
prop_object_release(str); \
|
||||||
|
\
|
||||||
|
return (rv); \
|
||||||
|
}
|
||||||
|
|
||||||
|
TEMPLATE(,)
|
||||||
|
TEMPLATE(_nocopy,const)
|
||||||
|
|
||||||
|
#undef TEMPLATE
|
159
lib/portableproplib/prop_ingest.c
Normal file
159
lib/portableproplib/prop_ingest.c
Normal file
@ -0,0 +1,159 @@
|
|||||||
|
/* $NetBSD: prop_ingest.c,v 1.3 2008/04/28 20:22:53 martin Exp $ */
|
||||||
|
|
||||||
|
/*-
|
||||||
|
* Copyright (c) 2006 The NetBSD Foundation, Inc.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This code is derived from software contributed to The NetBSD Foundation
|
||||||
|
* by Jason R. Thorpe.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||||
|
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||||
|
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||||
|
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <prop/proplib.h>
|
||||||
|
#include "prop_object_impl.h"
|
||||||
|
|
||||||
|
struct _prop_ingest_context {
|
||||||
|
prop_ingest_error_t pic_error;
|
||||||
|
prop_type_t pic_type;
|
||||||
|
const char * pic_key;
|
||||||
|
void * pic_private;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* prop_ingest_context_alloc --
|
||||||
|
* Allocate and initialize an ingest context.
|
||||||
|
*/
|
||||||
|
prop_ingest_context_t
|
||||||
|
prop_ingest_context_alloc(void *private)
|
||||||
|
{
|
||||||
|
prop_ingest_context_t ctx;
|
||||||
|
|
||||||
|
ctx = _PROP_MALLOC(sizeof(*ctx), M_TEMP);
|
||||||
|
if (ctx != NULL) {
|
||||||
|
ctx->pic_error = PROP_INGEST_ERROR_NO_ERROR;
|
||||||
|
ctx->pic_type = PROP_TYPE_UNKNOWN;
|
||||||
|
ctx->pic_key = NULL;
|
||||||
|
ctx->pic_private = private;
|
||||||
|
}
|
||||||
|
return (ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* prop_ingest_context_free --
|
||||||
|
* Free an ingest context.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
prop_ingest_context_free(prop_ingest_context_t ctx)
|
||||||
|
{
|
||||||
|
|
||||||
|
_PROP_FREE(ctx, M_TEMP);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* prop_ingest_context_error --
|
||||||
|
* Get the error code from an ingest context.
|
||||||
|
*/
|
||||||
|
prop_ingest_error_t
|
||||||
|
prop_ingest_context_error(prop_ingest_context_t ctx)
|
||||||
|
{
|
||||||
|
|
||||||
|
return (ctx->pic_error);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* prop_ingest_context_type --
|
||||||
|
* Return the type of last object visisted by an ingest context.
|
||||||
|
*/
|
||||||
|
prop_type_t
|
||||||
|
prop_ingest_context_type(prop_ingest_context_t ctx)
|
||||||
|
{
|
||||||
|
|
||||||
|
return (ctx->pic_type);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* prop_ingest_context_key --
|
||||||
|
* Return the last key looked up by an ingest context.
|
||||||
|
*/
|
||||||
|
const char *
|
||||||
|
prop_ingest_context_key(prop_ingest_context_t ctx)
|
||||||
|
{
|
||||||
|
|
||||||
|
return (ctx->pic_key);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* prop_ingest_context_private --
|
||||||
|
* Return the caller-private data associated with an ingest context.
|
||||||
|
*/
|
||||||
|
void *
|
||||||
|
prop_ingest_context_private(prop_ingest_context_t ctx)
|
||||||
|
{
|
||||||
|
|
||||||
|
return (ctx->pic_private);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* prop_dictionary_ingest --
|
||||||
|
* Ingest a dictionary using handlers for each object to translate
|
||||||
|
* into an arbitrary binary format.
|
||||||
|
*/
|
||||||
|
bool
|
||||||
|
prop_dictionary_ingest(prop_dictionary_t dict,
|
||||||
|
const prop_ingest_table_entry rules[],
|
||||||
|
prop_ingest_context_t ctx)
|
||||||
|
{
|
||||||
|
const prop_ingest_table_entry *pite;
|
||||||
|
prop_object_t obj;
|
||||||
|
|
||||||
|
ctx->pic_error = PROP_INGEST_ERROR_NO_ERROR;
|
||||||
|
|
||||||
|
for (pite = rules; pite->pite_key != NULL; pite++) {
|
||||||
|
ctx->pic_key = pite->pite_key;
|
||||||
|
obj = prop_dictionary_get(dict, pite->pite_key);
|
||||||
|
ctx->pic_type = prop_object_type(obj);
|
||||||
|
if (obj == NULL) {
|
||||||
|
if (pite->pite_flags & PROP_INGEST_FLAG_OPTIONAL) {
|
||||||
|
if ((*pite->pite_handler)(ctx, NULL) == false) {
|
||||||
|
ctx->pic_error =
|
||||||
|
PROP_INGEST_ERROR_HANDLER_FAILED;
|
||||||
|
return (false);
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
ctx->pic_error = PROP_INGEST_ERROR_NO_KEY;
|
||||||
|
return (false);
|
||||||
|
}
|
||||||
|
if (ctx->pic_type != pite->pite_type &&
|
||||||
|
pite->pite_type != PROP_TYPE_UNKNOWN) {
|
||||||
|
ctx->pic_error = PROP_INGEST_ERROR_WRONG_TYPE;
|
||||||
|
return (false);
|
||||||
|
}
|
||||||
|
if ((*pite->pite_handler)(ctx, obj) == false) {
|
||||||
|
ctx->pic_error = PROP_INGEST_ERROR_HANDLER_FAILED;
|
||||||
|
return (false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (true);
|
||||||
|
}
|
576
lib/portableproplib/prop_number.c
Normal file
576
lib/portableproplib/prop_number.c
Normal file
@ -0,0 +1,576 @@
|
|||||||
|
/* $NetBSD: prop_number.c,v 1.20 2008/11/30 00:17:07 haad Exp $ */
|
||||||
|
|
||||||
|
/*-
|
||||||
|
* Copyright (c) 2006 The NetBSD Foundation, Inc.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This code is derived from software contributed to The NetBSD Foundation
|
||||||
|
* by Jason R. Thorpe.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||||
|
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||||
|
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||||
|
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <prop/prop_number.h>
|
||||||
|
#include "prop_object_impl.h"
|
||||||
|
#include "prop_rb_impl.h"
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
struct _prop_number {
|
||||||
|
struct _prop_object pn_obj;
|
||||||
|
struct rb_node pn_link;
|
||||||
|
struct _prop_number_value {
|
||||||
|
union {
|
||||||
|
int64_t pnu_signed;
|
||||||
|
uint64_t pnu_unsigned;
|
||||||
|
} pnv_un;
|
||||||
|
#define pnv_signed pnv_un.pnu_signed
|
||||||
|
#define pnv_unsigned pnv_un.pnu_unsigned
|
||||||
|
unsigned int pnv_is_unsigned :1,
|
||||||
|
:31;
|
||||||
|
} pn_value;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define RBNODE_TO_PN(n) \
|
||||||
|
((struct _prop_number *) \
|
||||||
|
((uintptr_t)n - offsetof(struct _prop_number, pn_link)))
|
||||||
|
|
||||||
|
_PROP_POOL_INIT(_prop_number_pool, sizeof(struct _prop_number), "propnmbr")
|
||||||
|
|
||||||
|
static _prop_object_free_rv_t
|
||||||
|
_prop_number_free(prop_stack_t, prop_object_t *);
|
||||||
|
static bool _prop_number_externalize(
|
||||||
|
struct _prop_object_externalize_context *,
|
||||||
|
void *);
|
||||||
|
static _prop_object_equals_rv_t
|
||||||
|
_prop_number_equals(prop_object_t, prop_object_t,
|
||||||
|
void **, void **,
|
||||||
|
prop_object_t *, prop_object_t *);
|
||||||
|
|
||||||
|
static void _prop_number_lock(void);
|
||||||
|
static void _prop_number_unlock(void);
|
||||||
|
|
||||||
|
static const struct _prop_object_type _prop_object_type_number = {
|
||||||
|
.pot_type = PROP_TYPE_NUMBER,
|
||||||
|
.pot_free = _prop_number_free,
|
||||||
|
.pot_extern = _prop_number_externalize,
|
||||||
|
.pot_equals = _prop_number_equals,
|
||||||
|
.pot_lock = _prop_number_lock,
|
||||||
|
.pot_unlock = _prop_number_unlock,
|
||||||
|
};
|
||||||
|
|
||||||
|
#define prop_object_is_number(x) \
|
||||||
|
((x) != NULL && (x)->pn_obj.po_type == &_prop_object_type_number)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Number objects are immutable, and we are likely to have many number
|
||||||
|
* objects that have the same value. So, to save memory, we unique'ify
|
||||||
|
* numbers so we only have one copy of each.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static int
|
||||||
|
_prop_number_compare_values(const struct _prop_number_value *pnv1,
|
||||||
|
const struct _prop_number_value *pnv2)
|
||||||
|
{
|
||||||
|
|
||||||
|
/* Signed numbers are sorted before unsigned numbers. */
|
||||||
|
|
||||||
|
if (pnv1->pnv_is_unsigned) {
|
||||||
|
if (! pnv2->pnv_is_unsigned)
|
||||||
|
return (1);
|
||||||
|
if (pnv1->pnv_unsigned < pnv2->pnv_unsigned)
|
||||||
|
return (-1);
|
||||||
|
if (pnv1->pnv_unsigned > pnv2->pnv_unsigned)
|
||||||
|
return (1);
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pnv2->pnv_is_unsigned)
|
||||||
|
return (-1);
|
||||||
|
if (pnv1->pnv_signed < pnv2->pnv_signed)
|
||||||
|
return (-1);
|
||||||
|
if (pnv1->pnv_signed > pnv2->pnv_signed)
|
||||||
|
return (1);
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
_prop_number_rb_compare_nodes(const struct rb_node *n1,
|
||||||
|
const struct rb_node *n2)
|
||||||
|
{
|
||||||
|
const prop_number_t pn1 = RBNODE_TO_PN(n1);
|
||||||
|
const prop_number_t pn2 = RBNODE_TO_PN(n2);
|
||||||
|
|
||||||
|
return (_prop_number_compare_values(&pn1->pn_value, &pn2->pn_value));
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
_prop_number_rb_compare_key(const struct rb_node *n,
|
||||||
|
const void *v)
|
||||||
|
{
|
||||||
|
const prop_number_t pn = RBNODE_TO_PN(n);
|
||||||
|
const struct _prop_number_value *pnv = v;
|
||||||
|
|
||||||
|
return (_prop_number_compare_values(&pn->pn_value, pnv));
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct rb_tree_ops _prop_number_rb_tree_ops = {
|
||||||
|
.rbto_compare_nodes = _prop_number_rb_compare_nodes,
|
||||||
|
.rbto_compare_key = _prop_number_rb_compare_key,
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct rb_tree _prop_number_tree;
|
||||||
|
static bool _prop_number_tree_initialized;
|
||||||
|
|
||||||
|
_PROP_MUTEX_DECL_STATIC(_prop_number_tree_mutex)
|
||||||
|
|
||||||
|
/* ARGSUSED */
|
||||||
|
static _prop_object_free_rv_t
|
||||||
|
_prop_number_free(prop_stack_t stack, prop_object_t *obj)
|
||||||
|
{
|
||||||
|
prop_number_t pn = *obj;
|
||||||
|
|
||||||
|
_prop_rb_tree_remove_node(&_prop_number_tree, &pn->pn_link);
|
||||||
|
|
||||||
|
_PROP_POOL_PUT(_prop_number_pool, pn);
|
||||||
|
|
||||||
|
return (_PROP_OBJECT_FREE_DONE);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_prop_number_lock()
|
||||||
|
{
|
||||||
|
_PROP_MUTEX_LOCK(_prop_number_tree_mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_prop_number_unlock()
|
||||||
|
{
|
||||||
|
_PROP_MUTEX_UNLOCK(_prop_number_tree_mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
_prop_number_externalize(struct _prop_object_externalize_context *ctx,
|
||||||
|
void *v)
|
||||||
|
{
|
||||||
|
prop_number_t pn = v;
|
||||||
|
char tmpstr[32];
|
||||||
|
|
||||||
|
/*
|
||||||
|
* For the record:
|
||||||
|
* The original implementation used hex for signed numbers,
|
||||||
|
* but we changed it to be human readable.
|
||||||
|
*/
|
||||||
|
if (pn->pn_value.pnv_is_unsigned)
|
||||||
|
sprintf(tmpstr, "%" PRIu64, pn->pn_value.pnv_unsigned);
|
||||||
|
else
|
||||||
|
sprintf(tmpstr, "%" PRIi64, pn->pn_value.pnv_signed);
|
||||||
|
|
||||||
|
if (_prop_object_externalize_start_tag(ctx, "integer") == false ||
|
||||||
|
_prop_object_externalize_append_cstring(ctx, tmpstr) == false ||
|
||||||
|
_prop_object_externalize_end_tag(ctx, "integer") == false)
|
||||||
|
return (false);
|
||||||
|
|
||||||
|
return (true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ARGSUSED */
|
||||||
|
static _prop_object_equals_rv_t
|
||||||
|
_prop_number_equals(prop_object_t v1, prop_object_t v2,
|
||||||
|
void **stored_pointer1, void **stored_pointer2,
|
||||||
|
prop_object_t *next_obj1, prop_object_t *next_obj2)
|
||||||
|
{
|
||||||
|
prop_number_t num1 = v1;
|
||||||
|
prop_number_t num2 = v2;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* There is only ever one copy of a number object at any given
|
||||||
|
* time, so we can reduce this to a simple pointer equality check
|
||||||
|
* in the common case.
|
||||||
|
*/
|
||||||
|
if (num1 == num2)
|
||||||
|
return (_PROP_OBJECT_EQUALS_TRUE);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If the numbers are the same signed-ness, then we know they
|
||||||
|
* cannot be equal because they would have had pointer equality.
|
||||||
|
*/
|
||||||
|
if (num1->pn_value.pnv_is_unsigned == num2->pn_value.pnv_is_unsigned)
|
||||||
|
return (_PROP_OBJECT_EQUALS_FALSE);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We now have one signed value and one unsigned value. We can
|
||||||
|
* compare them iff:
|
||||||
|
* - The unsigned value is not larger than the signed value
|
||||||
|
* can represent.
|
||||||
|
* - The signed value is not smaller than the unsigned value
|
||||||
|
* can represent.
|
||||||
|
*/
|
||||||
|
if (num1->pn_value.pnv_is_unsigned) {
|
||||||
|
/*
|
||||||
|
* num1 is unsigned and num2 is signed.
|
||||||
|
*/
|
||||||
|
if (num1->pn_value.pnv_unsigned > INT64_MAX)
|
||||||
|
return (_PROP_OBJECT_EQUALS_FALSE);
|
||||||
|
if (num2->pn_value.pnv_signed < 0)
|
||||||
|
return (_PROP_OBJECT_EQUALS_FALSE);
|
||||||
|
} else {
|
||||||
|
/*
|
||||||
|
* num1 is signed and num2 is unsigned.
|
||||||
|
*/
|
||||||
|
if (num1->pn_value.pnv_signed < 0)
|
||||||
|
return (_PROP_OBJECT_EQUALS_FALSE);
|
||||||
|
if (num2->pn_value.pnv_unsigned > INT64_MAX)
|
||||||
|
return (_PROP_OBJECT_EQUALS_FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (num1->pn_value.pnv_signed == num2->pn_value.pnv_signed)
|
||||||
|
return _PROP_OBJECT_EQUALS_TRUE;
|
||||||
|
else
|
||||||
|
return _PROP_OBJECT_EQUALS_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static prop_number_t
|
||||||
|
_prop_number_alloc(const struct _prop_number_value *pnv)
|
||||||
|
{
|
||||||
|
prop_number_t opn, pn;
|
||||||
|
struct rb_node *n;
|
||||||
|
bool rv;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check to see if this already exists in the tree. If it does,
|
||||||
|
* we just retain it and return it.
|
||||||
|
*/
|
||||||
|
_PROP_MUTEX_LOCK(_prop_number_tree_mutex);
|
||||||
|
if (! _prop_number_tree_initialized) {
|
||||||
|
_prop_rb_tree_init(&_prop_number_tree,
|
||||||
|
&_prop_number_rb_tree_ops);
|
||||||
|
_prop_number_tree_initialized = true;
|
||||||
|
} else {
|
||||||
|
n = _prop_rb_tree_find(&_prop_number_tree, pnv);
|
||||||
|
if (n != NULL) {
|
||||||
|
opn = RBNODE_TO_PN(n);
|
||||||
|
prop_object_retain(opn);
|
||||||
|
_PROP_MUTEX_UNLOCK(_prop_number_tree_mutex);
|
||||||
|
return (opn);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_PROP_MUTEX_UNLOCK(_prop_number_tree_mutex);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Not in the tree. Create it now.
|
||||||
|
*/
|
||||||
|
|
||||||
|
pn = _PROP_POOL_GET(_prop_number_pool);
|
||||||
|
if (pn == NULL)
|
||||||
|
return (NULL);
|
||||||
|
|
||||||
|
_prop_object_init(&pn->pn_obj, &_prop_object_type_number);
|
||||||
|
|
||||||
|
pn->pn_value = *pnv;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We dropped the mutex when we allocated the new object, so
|
||||||
|
* we have to check again if it is in the tree.
|
||||||
|
*/
|
||||||
|
_PROP_MUTEX_LOCK(_prop_number_tree_mutex);
|
||||||
|
n = _prop_rb_tree_find(&_prop_number_tree, pnv);
|
||||||
|
if (n != NULL) {
|
||||||
|
opn = RBNODE_TO_PN(n);
|
||||||
|
prop_object_retain(opn);
|
||||||
|
_PROP_MUTEX_UNLOCK(_prop_number_tree_mutex);
|
||||||
|
_PROP_POOL_PUT(_prop_number_pool, pn);
|
||||||
|
return (opn);
|
||||||
|
}
|
||||||
|
rv = _prop_rb_tree_insert_node(&_prop_number_tree, &pn->pn_link);
|
||||||
|
_PROP_ASSERT(rv == true);
|
||||||
|
_PROP_MUTEX_UNLOCK(_prop_number_tree_mutex);
|
||||||
|
return (pn);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* prop_number_create_integer --
|
||||||
|
* Create a prop_number_t and initialize it with the
|
||||||
|
* provided integer value.
|
||||||
|
*/
|
||||||
|
prop_number_t
|
||||||
|
prop_number_create_integer(int64_t val)
|
||||||
|
{
|
||||||
|
struct _prop_number_value pnv;
|
||||||
|
|
||||||
|
memset(&pnv, 0, sizeof(pnv));
|
||||||
|
pnv.pnv_signed = val;
|
||||||
|
pnv.pnv_is_unsigned = false;
|
||||||
|
|
||||||
|
return (_prop_number_alloc(&pnv));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* prop_number_create_unsigned_integer --
|
||||||
|
* Create a prop_number_t and initialize it with the
|
||||||
|
* provided unsigned integer value.
|
||||||
|
*/
|
||||||
|
prop_number_t
|
||||||
|
prop_number_create_unsigned_integer(uint64_t val)
|
||||||
|
{
|
||||||
|
struct _prop_number_value pnv;
|
||||||
|
|
||||||
|
memset(&pnv, 0, sizeof(pnv));
|
||||||
|
pnv.pnv_unsigned = val;
|
||||||
|
pnv.pnv_is_unsigned = true;
|
||||||
|
|
||||||
|
return (_prop_number_alloc(&pnv));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* prop_number_copy --
|
||||||
|
* Copy a prop_number_t.
|
||||||
|
*/
|
||||||
|
prop_number_t
|
||||||
|
prop_number_copy(prop_number_t opn)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (! prop_object_is_number(opn))
|
||||||
|
return (NULL);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Because we only ever allocate one object for any given
|
||||||
|
* value, this can be reduced to a simple retain operation.
|
||||||
|
*/
|
||||||
|
prop_object_retain(opn);
|
||||||
|
return (opn);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* prop_number_unsigned --
|
||||||
|
* Returns true if the prop_number_t has an unsigned value.
|
||||||
|
*/
|
||||||
|
bool
|
||||||
|
prop_number_unsigned(prop_number_t pn)
|
||||||
|
{
|
||||||
|
|
||||||
|
return (pn->pn_value.pnv_is_unsigned);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* prop_number_size --
|
||||||
|
* Return the size, in bits, required to hold the value of
|
||||||
|
* the specified number.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
prop_number_size(prop_number_t pn)
|
||||||
|
{
|
||||||
|
struct _prop_number_value *pnv;
|
||||||
|
|
||||||
|
if (! prop_object_is_number(pn))
|
||||||
|
return (0);
|
||||||
|
|
||||||
|
pnv = &pn->pn_value;
|
||||||
|
|
||||||
|
if (pnv->pnv_is_unsigned) {
|
||||||
|
if (pnv->pnv_unsigned > UINT32_MAX)
|
||||||
|
return (64);
|
||||||
|
if (pnv->pnv_unsigned > UINT16_MAX)
|
||||||
|
return (32);
|
||||||
|
if (pnv->pnv_unsigned > UINT8_MAX)
|
||||||
|
return (16);
|
||||||
|
return (8);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pnv->pnv_signed > INT32_MAX || pnv->pnv_signed < INT32_MIN)
|
||||||
|
return (64);
|
||||||
|
if (pnv->pnv_signed > INT16_MAX || pnv->pnv_signed < INT16_MIN)
|
||||||
|
return (32);
|
||||||
|
if (pnv->pnv_signed > INT8_MAX || pnv->pnv_signed < INT8_MIN)
|
||||||
|
return (16);
|
||||||
|
return (8);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* prop_number_integer_value --
|
||||||
|
* Get the integer value of a prop_number_t.
|
||||||
|
*/
|
||||||
|
int64_t
|
||||||
|
prop_number_integer_value(prop_number_t pn)
|
||||||
|
{
|
||||||
|
|
||||||
|
/*
|
||||||
|
* XXX Impossible to distinguish between "not a prop_number_t"
|
||||||
|
* XXX and "prop_number_t has a value of 0".
|
||||||
|
*/
|
||||||
|
if (! prop_object_is_number(pn))
|
||||||
|
return (0);
|
||||||
|
|
||||||
|
return (pn->pn_value.pnv_signed);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* prop_number_unsigned_integer_value --
|
||||||
|
* Get the unsigned integer value of a prop_number_t.
|
||||||
|
*/
|
||||||
|
uint64_t
|
||||||
|
prop_number_unsigned_integer_value(prop_number_t pn)
|
||||||
|
{
|
||||||
|
|
||||||
|
/*
|
||||||
|
* XXX Impossible to distinguish between "not a prop_number_t"
|
||||||
|
* XXX and "prop_number_t has a value of 0".
|
||||||
|
*/
|
||||||
|
if (! prop_object_is_number(pn))
|
||||||
|
return (0);
|
||||||
|
|
||||||
|
return (pn->pn_value.pnv_unsigned);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* prop_number_equals --
|
||||||
|
* Return true if two numbers are equivalent.
|
||||||
|
*/
|
||||||
|
bool
|
||||||
|
prop_number_equals(prop_number_t num1, prop_number_t num2)
|
||||||
|
{
|
||||||
|
if (!prop_object_is_number(num1) || !prop_object_is_number(num2))
|
||||||
|
return (false);
|
||||||
|
|
||||||
|
return (prop_object_equals(num1, num2));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* prop_number_equals_integer --
|
||||||
|
* Return true if the number is equivalent to the specified integer.
|
||||||
|
*/
|
||||||
|
bool
|
||||||
|
prop_number_equals_integer(prop_number_t pn, int64_t val)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (! prop_object_is_number(pn))
|
||||||
|
return (false);
|
||||||
|
|
||||||
|
if (pn->pn_value.pnv_is_unsigned &&
|
||||||
|
(pn->pn_value.pnv_unsigned > INT64_MAX || val < 0))
|
||||||
|
return (false);
|
||||||
|
|
||||||
|
return (pn->pn_value.pnv_signed == val);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* prop_number_equals_unsigned_integer --
|
||||||
|
* Return true if the number is equivalent to the specified
|
||||||
|
* unsigned integer.
|
||||||
|
*/
|
||||||
|
bool
|
||||||
|
prop_number_equals_unsigned_integer(prop_number_t pn, uint64_t val)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (! prop_object_is_number(pn))
|
||||||
|
return (false);
|
||||||
|
|
||||||
|
if (! pn->pn_value.pnv_is_unsigned &&
|
||||||
|
(pn->pn_value.pnv_signed < 0 || val > INT64_MAX))
|
||||||
|
return (false);
|
||||||
|
|
||||||
|
return (pn->pn_value.pnv_unsigned == val);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
_prop_number_internalize_unsigned(struct _prop_object_internalize_context *ctx,
|
||||||
|
struct _prop_number_value *pnv)
|
||||||
|
{
|
||||||
|
char *cp;
|
||||||
|
|
||||||
|
_PROP_ASSERT(/*CONSTCOND*/sizeof(unsigned long long) ==
|
||||||
|
sizeof(uint64_t));
|
||||||
|
|
||||||
|
errno = 0;
|
||||||
|
pnv->pnv_unsigned = (uint64_t) strtoull(ctx->poic_cp, &cp, 0);
|
||||||
|
if (pnv->pnv_unsigned == UINT64_MAX && errno == ERANGE)
|
||||||
|
return (false);
|
||||||
|
pnv->pnv_is_unsigned = true;
|
||||||
|
ctx->poic_cp = cp;
|
||||||
|
|
||||||
|
return (true);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
_prop_number_internalize_signed(struct _prop_object_internalize_context *ctx,
|
||||||
|
struct _prop_number_value *pnv)
|
||||||
|
{
|
||||||
|
char *cp;
|
||||||
|
|
||||||
|
_PROP_ASSERT(/*CONSTCOND*/sizeof(long long) == sizeof(int64_t));
|
||||||
|
|
||||||
|
errno = 0;
|
||||||
|
pnv->pnv_signed = (int64_t) strtoll(ctx->poic_cp, &cp, 0);
|
||||||
|
if ((pnv->pnv_signed == INT64_MAX || pnv->pnv_signed == INT64_MIN) &&
|
||||||
|
errno == ERANGE)
|
||||||
|
return (false);
|
||||||
|
pnv->pnv_is_unsigned = false;
|
||||||
|
ctx->poic_cp = cp;
|
||||||
|
|
||||||
|
return (true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* _prop_number_internalize --
|
||||||
|
* Parse a <number>...</number> and return the object created from
|
||||||
|
* the external representation.
|
||||||
|
*/
|
||||||
|
/* ARGSUSED */
|
||||||
|
bool
|
||||||
|
_prop_number_internalize(prop_stack_t stack, prop_object_t *obj,
|
||||||
|
struct _prop_object_internalize_context *ctx)
|
||||||
|
{
|
||||||
|
struct _prop_number_value pnv;
|
||||||
|
|
||||||
|
memset(&pnv, 0, sizeof(pnv));
|
||||||
|
|
||||||
|
/* No attributes, no empty elements. */
|
||||||
|
if (ctx->poic_tagattr != NULL || ctx->poic_is_empty_element)
|
||||||
|
return (true);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If the first character is '-', then we treat as signed.
|
||||||
|
* If the first two characters are "0x" (i.e. the number is
|
||||||
|
* in hex), then we treat as unsigned. Otherwise, we try
|
||||||
|
* signed first, and if that fails (presumably due to ERANGE),
|
||||||
|
* then we switch to unsigned.
|
||||||
|
*/
|
||||||
|
if (ctx->poic_cp[0] == '-') {
|
||||||
|
if (_prop_number_internalize_signed(ctx, &pnv) == false)
|
||||||
|
return (true);
|
||||||
|
} else if (ctx->poic_cp[0] == '0' && ctx->poic_cp[1] == 'x') {
|
||||||
|
if (_prop_number_internalize_unsigned(ctx, &pnv) == false)
|
||||||
|
return (true);
|
||||||
|
} else {
|
||||||
|
if (_prop_number_internalize_signed(ctx, &pnv) == false &&
|
||||||
|
_prop_number_internalize_unsigned(ctx, &pnv) == false)
|
||||||
|
return (true);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_prop_object_internalize_find_tag(ctx, "integer",
|
||||||
|
_PROP_TAG_TYPE_END) == false)
|
||||||
|
return (true);
|
||||||
|
|
||||||
|
*obj = _prop_number_alloc(&pnv);
|
||||||
|
return (true);
|
||||||
|
}
|
1241
lib/portableproplib/prop_object.c
Normal file
1241
lib/portableproplib/prop_object.c
Normal file
File diff suppressed because it is too large
Load Diff
274
lib/portableproplib/prop_object_impl.h
Normal file
274
lib/portableproplib/prop_object_impl.h
Normal file
@ -0,0 +1,274 @@
|
|||||||
|
/* $NetBSD: prop_object_impl.h,v 1.28 2008/11/30 00:17:07 haad Exp $ */
|
||||||
|
|
||||||
|
/*-
|
||||||
|
* Copyright (c) 2006 The NetBSD Foundation, Inc.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This code is derived from software contributed to The NetBSD Foundation
|
||||||
|
* by Jason R. Thorpe.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||||
|
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||||
|
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||||
|
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _PROPLIB_PROP_OBJECT_IMPL_H_
|
||||||
|
#define _PROPLIB_PROP_OBJECT_IMPL_H_
|
||||||
|
|
||||||
|
#include <inttypes.h>
|
||||||
|
|
||||||
|
#include "prop_stack.h"
|
||||||
|
|
||||||
|
struct _prop_object_externalize_context {
|
||||||
|
char * poec_buf; /* string buffer */
|
||||||
|
size_t poec_capacity; /* capacity of buffer */
|
||||||
|
size_t poec_len; /* current length of string */
|
||||||
|
unsigned int poec_depth; /* nesting depth */
|
||||||
|
};
|
||||||
|
|
||||||
|
bool _prop_object_externalize_start_tag(
|
||||||
|
struct _prop_object_externalize_context *,
|
||||||
|
const char *);
|
||||||
|
bool _prop_object_externalize_end_tag(
|
||||||
|
struct _prop_object_externalize_context *,
|
||||||
|
const char *);
|
||||||
|
bool _prop_object_externalize_empty_tag(
|
||||||
|
struct _prop_object_externalize_context *,
|
||||||
|
const char *);
|
||||||
|
bool _prop_object_externalize_append_cstring(
|
||||||
|
struct _prop_object_externalize_context *,
|
||||||
|
const char *);
|
||||||
|
bool _prop_object_externalize_append_encoded_cstring(
|
||||||
|
struct _prop_object_externalize_context *,
|
||||||
|
const char *);
|
||||||
|
bool _prop_object_externalize_append_char(
|
||||||
|
struct _prop_object_externalize_context *,
|
||||||
|
unsigned char);
|
||||||
|
bool _prop_object_externalize_header(
|
||||||
|
struct _prop_object_externalize_context *);
|
||||||
|
bool _prop_object_externalize_footer(
|
||||||
|
struct _prop_object_externalize_context *);
|
||||||
|
|
||||||
|
struct _prop_object_externalize_context *
|
||||||
|
_prop_object_externalize_context_alloc(void);
|
||||||
|
void _prop_object_externalize_context_free(
|
||||||
|
struct _prop_object_externalize_context *);
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
_PROP_TAG_TYPE_START, /* e.g. <dict> */
|
||||||
|
_PROP_TAG_TYPE_END, /* e.g. </dict> */
|
||||||
|
_PROP_TAG_TYPE_EITHER
|
||||||
|
} _prop_tag_type_t;
|
||||||
|
|
||||||
|
struct _prop_object_internalize_context {
|
||||||
|
const char *poic_xml;
|
||||||
|
const char *poic_cp;
|
||||||
|
|
||||||
|
const char *poic_tag_start;
|
||||||
|
|
||||||
|
const char *poic_tagname;
|
||||||
|
size_t poic_tagname_len;
|
||||||
|
const char *poic_tagattr;
|
||||||
|
size_t poic_tagattr_len;
|
||||||
|
const char *poic_tagattrval;
|
||||||
|
size_t poic_tagattrval_len;
|
||||||
|
|
||||||
|
bool poic_is_empty_element;
|
||||||
|
_prop_tag_type_t poic_tag_type;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
_PROP_OBJECT_FREE_DONE,
|
||||||
|
_PROP_OBJECT_FREE_RECURSE,
|
||||||
|
_PROP_OBJECT_FREE_FAILED
|
||||||
|
} _prop_object_free_rv_t;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
_PROP_OBJECT_EQUALS_FALSE,
|
||||||
|
_PROP_OBJECT_EQUALS_TRUE,
|
||||||
|
_PROP_OBJECT_EQUALS_RECURSE
|
||||||
|
} _prop_object_equals_rv_t;
|
||||||
|
|
||||||
|
#define _PROP_EOF(c) ((c) == '\0')
|
||||||
|
#define _PROP_ISSPACE(c) \
|
||||||
|
((c) == ' ' || (c) == '\t' || (c) == '\n' || (c) == '\r' || \
|
||||||
|
_PROP_EOF(c))
|
||||||
|
|
||||||
|
#define _PROP_TAG_MATCH(ctx, t) \
|
||||||
|
_prop_object_internalize_match((ctx)->poic_tagname, \
|
||||||
|
(ctx)->poic_tagname_len, \
|
||||||
|
(t), strlen(t))
|
||||||
|
|
||||||
|
#define _PROP_TAGATTR_MATCH(ctx, a) \
|
||||||
|
_prop_object_internalize_match((ctx)->poic_tagattr, \
|
||||||
|
(ctx)->poic_tagattr_len, \
|
||||||
|
(a), strlen(a))
|
||||||
|
|
||||||
|
#define _PROP_TAGATTRVAL_MATCH(ctx, a) \
|
||||||
|
_prop_object_internalize_match((ctx)->poic_tagattrval, \
|
||||||
|
(ctx)->poic_tagattrval_len,\
|
||||||
|
(a), strlen(a))
|
||||||
|
|
||||||
|
bool _prop_object_internalize_find_tag(
|
||||||
|
struct _prop_object_internalize_context *,
|
||||||
|
const char *, _prop_tag_type_t);
|
||||||
|
bool _prop_object_internalize_match(const char *, size_t,
|
||||||
|
const char *, size_t);
|
||||||
|
prop_object_t _prop_object_internalize_by_tag(
|
||||||
|
struct _prop_object_internalize_context *);
|
||||||
|
bool _prop_object_internalize_decode_string(
|
||||||
|
struct _prop_object_internalize_context *,
|
||||||
|
char *, size_t, size_t *, const char **);
|
||||||
|
prop_object_t _prop_generic_internalize(const char *, const char *);
|
||||||
|
|
||||||
|
struct _prop_object_internalize_context *
|
||||||
|
_prop_object_internalize_context_alloc(const char *);
|
||||||
|
void _prop_object_internalize_context_free(
|
||||||
|
struct _prop_object_internalize_context *);
|
||||||
|
|
||||||
|
bool _prop_object_externalize_write_file(const char *,
|
||||||
|
const char *,
|
||||||
|
size_t, bool);
|
||||||
|
|
||||||
|
struct _prop_object_internalize_mapped_file {
|
||||||
|
char * poimf_xml;
|
||||||
|
size_t poimf_mapsize;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct _prop_object_internalize_mapped_file *
|
||||||
|
_prop_object_internalize_map_file(const char *);
|
||||||
|
void _prop_object_internalize_unmap_file(
|
||||||
|
struct _prop_object_internalize_mapped_file *);
|
||||||
|
|
||||||
|
typedef bool (*prop_object_internalizer_t)(prop_stack_t, prop_object_t *,
|
||||||
|
struct _prop_object_internalize_context *);
|
||||||
|
typedef bool (*prop_object_internalizer_continue_t)(prop_stack_t,
|
||||||
|
prop_object_t *,
|
||||||
|
struct _prop_object_internalize_context *,
|
||||||
|
void *, prop_object_t);
|
||||||
|
|
||||||
|
/* These are here because they're required by shared code. */
|
||||||
|
bool _prop_array_internalize(prop_stack_t, prop_object_t *,
|
||||||
|
struct _prop_object_internalize_context *);
|
||||||
|
bool _prop_bool_internalize(prop_stack_t, prop_object_t *,
|
||||||
|
struct _prop_object_internalize_context *);
|
||||||
|
bool _prop_data_internalize(prop_stack_t, prop_object_t *,
|
||||||
|
struct _prop_object_internalize_context *);
|
||||||
|
bool _prop_dictionary_internalize(prop_stack_t, prop_object_t *,
|
||||||
|
struct _prop_object_internalize_context *);
|
||||||
|
bool _prop_number_internalize(prop_stack_t, prop_object_t *,
|
||||||
|
struct _prop_object_internalize_context *);
|
||||||
|
bool _prop_string_internalize(prop_stack_t, prop_object_t *,
|
||||||
|
struct _prop_object_internalize_context *);
|
||||||
|
|
||||||
|
struct _prop_object_type {
|
||||||
|
/* type indicator */
|
||||||
|
uint32_t pot_type;
|
||||||
|
/* func to free object */
|
||||||
|
_prop_object_free_rv_t
|
||||||
|
(*pot_free)(prop_stack_t, prop_object_t *);
|
||||||
|
/*
|
||||||
|
* func to free the child returned by pot_free with stack == NULL.
|
||||||
|
*
|
||||||
|
* Must be implemented if pot_free can return anything other than
|
||||||
|
* _PROP_OBJECT_FREE_DONE.
|
||||||
|
*/
|
||||||
|
void (*pot_emergency_free)(prop_object_t);
|
||||||
|
/* func to externalize object */
|
||||||
|
bool (*pot_extern)(struct _prop_object_externalize_context *,
|
||||||
|
void *);
|
||||||
|
/* func to test quality */
|
||||||
|
_prop_object_equals_rv_t
|
||||||
|
(*pot_equals)(prop_object_t, prop_object_t,
|
||||||
|
void **, void **,
|
||||||
|
prop_object_t *, prop_object_t *);
|
||||||
|
/*
|
||||||
|
* func to finish equality iteration.
|
||||||
|
*
|
||||||
|
* Must be implemented if pot_equals can return
|
||||||
|
* _PROP_OBJECT_EQUALS_RECURSE
|
||||||
|
*/
|
||||||
|
void (*pot_equals_finish)(prop_object_t, prop_object_t);
|
||||||
|
void (*pot_lock)(void);
|
||||||
|
void (*pot_unlock)(void);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct _prop_object {
|
||||||
|
const struct _prop_object_type *po_type;/* type descriptor */
|
||||||
|
uint32_t po_refcnt; /* reference count */
|
||||||
|
};
|
||||||
|
|
||||||
|
void _prop_object_init(struct _prop_object *,
|
||||||
|
const struct _prop_object_type *);
|
||||||
|
void _prop_object_fini(struct _prop_object *);
|
||||||
|
|
||||||
|
struct _prop_object_iterator {
|
||||||
|
prop_object_t (*pi_next_object)(void *);
|
||||||
|
void (*pi_reset)(void *);
|
||||||
|
prop_object_t pi_obj;
|
||||||
|
uint32_t pi_version;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* proplib in user space...
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
#define _PROP_ASSERT(x) /*LINTED*/assert(x)
|
||||||
|
|
||||||
|
#define _PROP_MALLOC(s, t) malloc((s))
|
||||||
|
#define _PROP_CALLOC(s, t) calloc(1, (s))
|
||||||
|
#define _PROP_REALLOC(v, s, t) realloc((v), (s))
|
||||||
|
#define _PROP_FREE(v, t) free((v))
|
||||||
|
|
||||||
|
#define _PROP_POOL_GET(p) malloc((p))
|
||||||
|
#define _PROP_POOL_PUT(p, v) free((v))
|
||||||
|
|
||||||
|
#define _PROP_POOL_INIT(p, s, d) static const size_t p = s;
|
||||||
|
|
||||||
|
#define _PROP_MALLOC_DEFINE(t, s, l) /* nothing */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Use pthread mutexes everywhere else.
|
||||||
|
*/
|
||||||
|
#include <pthread.h>
|
||||||
|
#define _PROP_MUTEX_DECL_STATIC(x) \
|
||||||
|
static pthread_mutex_t x = PTHREAD_MUTEX_INITIALIZER;
|
||||||
|
#define _PROP_MUTEX_LOCK(x) pthread_mutex_lock(&(x))
|
||||||
|
#define _PROP_MUTEX_UNLOCK(x) pthread_mutex_unlock(&(x))
|
||||||
|
|
||||||
|
#define _PROP_RWLOCK_DECL(x) pthread_rwlock_t x ;
|
||||||
|
#define _PROP_RWLOCK_INIT(x) pthread_rwlock_init(&(x), NULL)
|
||||||
|
#define _PROP_RWLOCK_RDLOCK(x) pthread_rwlock_rdlock(&(x))
|
||||||
|
#define _PROP_RWLOCK_WRLOCK(x) pthread_rwlock_wrlock(&(x))
|
||||||
|
#define _PROP_RWLOCK_UNLOCK(x) pthread_rwlock_unlock(&(x))
|
||||||
|
#define _PROP_RWLOCK_DESTROY(x) pthread_rwlock_destroy(&(x))
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Language features.
|
||||||
|
*/
|
||||||
|
#define _PROP_ARG_UNUSED /* delete */
|
||||||
|
|
||||||
|
#endif /* _PROPLIB_PROP_OBJECT_IMPL_H_ */
|
1056
lib/portableproplib/prop_rb.c
Normal file
1056
lib/portableproplib/prop_rb.c
Normal file
File diff suppressed because it is too large
Load Diff
137
lib/portableproplib/prop_rb_impl.h
Normal file
137
lib/portableproplib/prop_rb_impl.h
Normal file
@ -0,0 +1,137 @@
|
|||||||
|
/* $NetBSD: prop_rb_impl.h,v 1.7 2008/06/30 20:14:09 matt Exp $ */
|
||||||
|
|
||||||
|
/*-
|
||||||
|
* Copyright (c) 2001 The NetBSD Foundation, Inc.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This code is derived from software contributed to The NetBSD Foundation
|
||||||
|
* by Matt Thomas <matt@3am-software.com>.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||||
|
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||||
|
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||||
|
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _PROP_RB_IMPL_H_
|
||||||
|
#define _PROP_RB_IMPL_H_
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include "queue.h"
|
||||||
|
|
||||||
|
struct rb_node {
|
||||||
|
struct rb_node *rb_nodes[3];
|
||||||
|
#define RB_NODE_LEFT 0
|
||||||
|
#define RB_NODE_RIGHT 1
|
||||||
|
#define RB_NODE_OTHER 1
|
||||||
|
#define RB_NODE_PARENT 2
|
||||||
|
#define rb_left rb_nodes[RB_NODE_LEFT]
|
||||||
|
#define rb_right rb_nodes[RB_NODE_RIGHT]
|
||||||
|
#define rb_parent rb_nodes[RB_NODE_PARENT]
|
||||||
|
union {
|
||||||
|
struct {
|
||||||
|
#if BYTE_ORDER == LITTLE_ENDIAN
|
||||||
|
unsigned int : 28;
|
||||||
|
unsigned int s_root : 1;
|
||||||
|
unsigned int s_position : 1;
|
||||||
|
unsigned int s_color : 1;
|
||||||
|
unsigned int s_sentinel : 1;
|
||||||
|
#endif
|
||||||
|
#if BYTE_ORDER == BIG_ENDIAN
|
||||||
|
unsigned int s_sentinel : 1;
|
||||||
|
unsigned int s_color : 1;
|
||||||
|
unsigned int s_position : 1;
|
||||||
|
unsigned int s_root : 1;
|
||||||
|
unsigned int : 28;
|
||||||
|
#endif
|
||||||
|
} u_s;
|
||||||
|
unsigned int u_i;
|
||||||
|
} rb_u;
|
||||||
|
#define rb_root rb_u.u_s.s_root
|
||||||
|
#define rb_position rb_u.u_s.s_position
|
||||||
|
#define rb_color rb_u.u_s.s_color
|
||||||
|
#define rb_sentinel rb_u.u_s.s_sentinel
|
||||||
|
#define rb_properties rb_u.u_i
|
||||||
|
#define RB_SENTINEL_P(rb) ((rb)->rb_sentinel + 0)
|
||||||
|
#define RB_LEFT_SENTINEL_P(rb) ((rb)->rb_left->rb_sentinel + 0)
|
||||||
|
#define RB_RIGHT_SENTINEL_P(rb) ((rb)->rb_right->rb_sentinel + 0)
|
||||||
|
#define RB_PARENT_SENTINEL_P(rb) ((rb)->rb_parent->rb_sentinel + 0)
|
||||||
|
#define RB_CHILDLESS_P(rb) (RB_LEFT_SENTINEL_P(rb) \
|
||||||
|
&& RB_RIGHT_SENTINEL_P(rb))
|
||||||
|
#define RB_TWOCHILDREN_P(rb) (!RB_LEFT_SENTINEL_P(rb) \
|
||||||
|
&& !RB_RIGHT_SENTINEL_P(rb))
|
||||||
|
#define RB_ROOT_P(rb) ((rb)->rb_root != false)
|
||||||
|
#define RB_RED_P(rb) ((rb)->rb_color + 0)
|
||||||
|
#define RB_BLACK_P(rb) (!(rb)->rb_color)
|
||||||
|
#define RB_MARK_RED(rb) ((void)((rb)->rb_color = 1))
|
||||||
|
#define RB_MARK_BLACK(rb) ((void)((rb)->rb_color = 0))
|
||||||
|
#define RB_MARK_ROOT(rb) ((void)((rb)->rb_root = 1))
|
||||||
|
#ifdef RBDEBUG
|
||||||
|
TAILQ_ENTRY(rb_node) rb_link;
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef RBDEBUG
|
||||||
|
TAILQ_HEAD(rb_node_qh, rb_node);
|
||||||
|
|
||||||
|
#define RB_TAILQ_REMOVE TAILQ_REMOVE
|
||||||
|
#define RB_TAILQ_INIT TAILQ_INIT
|
||||||
|
#define RB_TAILQ_INSERT_HEAD(a, b, c) TAILQ_INSERT_HEAD
|
||||||
|
#define RB_TAILQ_INSERT_BEFORE(a, b, c) TAILQ_INSERT_BEFORE
|
||||||
|
#define RB_TAILQ_INSERT_AFTER(a, b, c, d) TAILQ_INSERT_AFTER
|
||||||
|
#else
|
||||||
|
#define RB_TAILQ_REMOVE(a, b, c) do { } while (/*CONSTCOND*/0)
|
||||||
|
#define RB_TAILQ_INIT(a) do { } while (/*CONSTCOND*/0)
|
||||||
|
#define RB_TAILQ_INSERT_HEAD(a, b, c) do { } while (/*CONSTCOND*/0)
|
||||||
|
#define RB_TAILQ_INSERT_BEFORE(a, b, c) do { } while (/*CONSTCOND*/0)
|
||||||
|
#define RB_TAILQ_INSERT_AFTER(a, b, c, d) do { } while (/*CONSTCOND*/0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef int (*rb_compare_nodes_fn)(const struct rb_node *,
|
||||||
|
const struct rb_node *);
|
||||||
|
typedef int (*rb_compare_key_fn)(const struct rb_node *, const void *);
|
||||||
|
|
||||||
|
struct rb_tree_ops {
|
||||||
|
rb_compare_nodes_fn rbto_compare_nodes;
|
||||||
|
rb_compare_key_fn rbto_compare_key;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct rb_tree {
|
||||||
|
struct rb_node *rbt_root;
|
||||||
|
#ifdef RBDEBUG
|
||||||
|
struct rb_node_qh rbt_nodes;
|
||||||
|
#endif
|
||||||
|
const struct rb_tree_ops *rbt_ops;
|
||||||
|
#ifdef RBDEBUG
|
||||||
|
unsigned int rbt_count;
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
void _prop_rb_tree_init(struct rb_tree *, const struct rb_tree_ops *);
|
||||||
|
bool _prop_rb_tree_insert_node(struct rb_tree *, struct rb_node *);
|
||||||
|
struct rb_node *
|
||||||
|
_prop_rb_tree_find(struct rb_tree *, const void *);
|
||||||
|
void _prop_rb_tree_remove_node(struct rb_tree *, struct rb_node *);
|
||||||
|
#ifdef RBDEBUG
|
||||||
|
void _prop_rb_tree_check(const struct rb_tree *, bool);
|
||||||
|
#endif
|
||||||
|
struct rb_node *
|
||||||
|
_prop_rb_tree_iterate(struct rb_tree *, struct rb_node *, unsigned int);
|
||||||
|
|
||||||
|
#endif /* _PROP_RB_IMPL_H_*/
|
118
lib/portableproplib/prop_stack.c
Normal file
118
lib/portableproplib/prop_stack.c
Normal file
@ -0,0 +1,118 @@
|
|||||||
|
/* $NetBSD: prop_stack.c,v 1.2 2007/08/30 12:23:54 joerg Exp $ */
|
||||||
|
|
||||||
|
/*-
|
||||||
|
* Copyright (c) 2007 Joerg Sonnenberger <joerg@NetBSD.org>.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in
|
||||||
|
* the documentation and/or other materials provided with the
|
||||||
|
* distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
* COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
* INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||||
|
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||||
|
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||||
|
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "prop_stack.h"
|
||||||
|
#include "prop_object_impl.h"
|
||||||
|
|
||||||
|
void
|
||||||
|
_prop_stack_init(prop_stack_t stack)
|
||||||
|
{
|
||||||
|
stack->used_intern_elems = 0;
|
||||||
|
SLIST_INIT(&stack->extern_elems);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
_prop_stack_push(prop_stack_t stack, prop_object_t obj, void *data1,
|
||||||
|
void *data2, void *data3)
|
||||||
|
{
|
||||||
|
struct _prop_stack_extern_elem *eelem;
|
||||||
|
struct _prop_stack_intern_elem *ielem;
|
||||||
|
|
||||||
|
if (stack->used_intern_elems == PROP_STACK_INTERN_ELEMS) {
|
||||||
|
eelem = _PROP_MALLOC(sizeof(*eelem), M_TEMP);
|
||||||
|
|
||||||
|
if (eelem == NULL)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
eelem->object = obj;
|
||||||
|
eelem->object_data[0] = data1;
|
||||||
|
eelem->object_data[1] = data2;
|
||||||
|
eelem->object_data[2] = data3;
|
||||||
|
|
||||||
|
SLIST_INSERT_HEAD(&stack->extern_elems, eelem, stack_link);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
_PROP_ASSERT(stack->used_intern_elems < PROP_STACK_INTERN_ELEMS);
|
||||||
|
_PROP_ASSERT(SLIST_EMPTY(&stack->extern_elems));
|
||||||
|
|
||||||
|
ielem = &stack->intern_elems[stack->used_intern_elems];
|
||||||
|
ielem->object = obj;
|
||||||
|
ielem->object_data[0] = data1;
|
||||||
|
ielem->object_data[1] = data2;
|
||||||
|
ielem->object_data[2] = data3;
|
||||||
|
|
||||||
|
++stack->used_intern_elems;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
_prop_stack_pop(prop_stack_t stack, prop_object_t *obj, void **data1,
|
||||||
|
void **data2, void **data3)
|
||||||
|
{
|
||||||
|
struct _prop_stack_extern_elem *eelem;
|
||||||
|
struct _prop_stack_intern_elem *ielem;
|
||||||
|
|
||||||
|
if (stack->used_intern_elems == 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if ((eelem = SLIST_FIRST(&stack->extern_elems)) != NULL) {
|
||||||
|
_PROP_ASSERT(stack->used_intern_elems == PROP_STACK_INTERN_ELEMS);
|
||||||
|
|
||||||
|
SLIST_REMOVE_HEAD(&stack->extern_elems, stack_link);
|
||||||
|
if (obj)
|
||||||
|
*obj = eelem->object;
|
||||||
|
if (data1)
|
||||||
|
*data1 = eelem->object_data[0];
|
||||||
|
if (data2)
|
||||||
|
*data2 = eelem->object_data[1];
|
||||||
|
if (data3)
|
||||||
|
*data3 = eelem->object_data[2];
|
||||||
|
_PROP_FREE(eelem, M_TEMP);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
--stack->used_intern_elems;
|
||||||
|
ielem = &stack->intern_elems[stack->used_intern_elems];
|
||||||
|
|
||||||
|
if (obj)
|
||||||
|
*obj = ielem->object;
|
||||||
|
if (data1)
|
||||||
|
*data1 = ielem->object_data[0];
|
||||||
|
if (data2)
|
||||||
|
*data2 = ielem->object_data[1];
|
||||||
|
if (data3)
|
||||||
|
*data3 = ielem->object_data[2];
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
64
lib/portableproplib/prop_stack.h
Normal file
64
lib/portableproplib/prop_stack.h
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
/* $NetBSD: prop_stack.h,v 1.2 2007/08/30 12:23:54 joerg Exp $ */
|
||||||
|
|
||||||
|
/*-
|
||||||
|
* Copyright (c) 2007 Joerg Sonnenberger <joerg@NetBSD.org>.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in
|
||||||
|
* the documentation and/or other materials provided with the
|
||||||
|
* distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
* COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
* INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||||
|
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||||
|
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||||
|
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _PROP_STACK_H
|
||||||
|
#define _PROP_STACK_H
|
||||||
|
|
||||||
|
#include <queue.h>
|
||||||
|
#include <prop/prop_object.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
struct _prop_stack_intern_elem {
|
||||||
|
prop_object_t object;
|
||||||
|
void *object_data[3];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct _prop_stack_extern_elem {
|
||||||
|
SLIST_ENTRY(_prop_stack_extern_elem) stack_link;
|
||||||
|
prop_object_t object;
|
||||||
|
void *object_data[3];
|
||||||
|
};
|
||||||
|
|
||||||
|
#define PROP_STACK_INTERN_ELEMS 16
|
||||||
|
|
||||||
|
struct _prop_stack {
|
||||||
|
struct _prop_stack_intern_elem intern_elems[PROP_STACK_INTERN_ELEMS];
|
||||||
|
size_t used_intern_elems;
|
||||||
|
SLIST_HEAD(, _prop_stack_extern_elem) extern_elems;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct _prop_stack *prop_stack_t;
|
||||||
|
|
||||||
|
void _prop_stack_init(prop_stack_t);
|
||||||
|
bool _prop_stack_push(prop_stack_t, prop_object_t, void *, void *, void *);
|
||||||
|
bool _prop_stack_pop(prop_stack_t, prop_object_t *, void **, void **, void **);
|
||||||
|
|
||||||
|
#endif
|
471
lib/portableproplib/prop_string.c
Normal file
471
lib/portableproplib/prop_string.c
Normal file
@ -0,0 +1,471 @@
|
|||||||
|
/* $NetBSD: prop_string.c,v 1.11 2008/08/03 04:00:12 thorpej Exp $ */
|
||||||
|
|
||||||
|
/*-
|
||||||
|
* Copyright (c) 2006 The NetBSD Foundation, Inc.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This code is derived from software contributed to The NetBSD Foundation
|
||||||
|
* by Jason R. Thorpe.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||||
|
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||||
|
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||||
|
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <prop/prop_string.h>
|
||||||
|
#include "prop_object_impl.h"
|
||||||
|
|
||||||
|
struct _prop_string {
|
||||||
|
struct _prop_object ps_obj;
|
||||||
|
union {
|
||||||
|
char * psu_mutable;
|
||||||
|
const char * psu_immutable;
|
||||||
|
} ps_un;
|
||||||
|
#define ps_mutable ps_un.psu_mutable
|
||||||
|
#define ps_immutable ps_un.psu_immutable
|
||||||
|
size_t ps_size; /* not including \0 */
|
||||||
|
int ps_flags;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define PS_F_NOCOPY 0x01
|
||||||
|
|
||||||
|
_PROP_POOL_INIT(_prop_string_pool, sizeof(struct _prop_string), "propstng")
|
||||||
|
|
||||||
|
_PROP_MALLOC_DEFINE(M_PROP_STRING, "prop string",
|
||||||
|
"property string container object")
|
||||||
|
|
||||||
|
static _prop_object_free_rv_t
|
||||||
|
_prop_string_free(prop_stack_t, prop_object_t *);
|
||||||
|
static bool _prop_string_externalize(
|
||||||
|
struct _prop_object_externalize_context *,
|
||||||
|
void *);
|
||||||
|
static _prop_object_equals_rv_t
|
||||||
|
_prop_string_equals(prop_object_t, prop_object_t,
|
||||||
|
void **, void **,
|
||||||
|
prop_object_t *, prop_object_t *);
|
||||||
|
|
||||||
|
static const struct _prop_object_type _prop_object_type_string = {
|
||||||
|
.pot_type = PROP_TYPE_STRING,
|
||||||
|
.pot_free = _prop_string_free,
|
||||||
|
.pot_extern = _prop_string_externalize,
|
||||||
|
.pot_equals = _prop_string_equals,
|
||||||
|
};
|
||||||
|
|
||||||
|
#define prop_object_is_string(x) \
|
||||||
|
((x) != NULL && (x)->ps_obj.po_type == &_prop_object_type_string)
|
||||||
|
#define prop_string_contents(x) ((x)->ps_immutable ? (x)->ps_immutable : "")
|
||||||
|
|
||||||
|
/* ARGSUSED */
|
||||||
|
static _prop_object_free_rv_t
|
||||||
|
_prop_string_free(prop_stack_t stack, prop_object_t *obj)
|
||||||
|
{
|
||||||
|
prop_string_t ps = *obj;
|
||||||
|
|
||||||
|
if ((ps->ps_flags & PS_F_NOCOPY) == 0 && ps->ps_mutable != NULL)
|
||||||
|
_PROP_FREE(ps->ps_mutable, M_PROP_STRING);
|
||||||
|
_PROP_POOL_PUT(_prop_string_pool, ps);
|
||||||
|
|
||||||
|
return (_PROP_OBJECT_FREE_DONE);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
_prop_string_externalize(struct _prop_object_externalize_context *ctx,
|
||||||
|
void *v)
|
||||||
|
{
|
||||||
|
prop_string_t ps = v;
|
||||||
|
|
||||||
|
if (ps->ps_size == 0)
|
||||||
|
return (_prop_object_externalize_empty_tag(ctx, "string"));
|
||||||
|
|
||||||
|
if (_prop_object_externalize_start_tag(ctx, "string") == false ||
|
||||||
|
_prop_object_externalize_append_encoded_cstring(ctx,
|
||||||
|
ps->ps_immutable) == false ||
|
||||||
|
_prop_object_externalize_end_tag(ctx, "string") == false)
|
||||||
|
return (false);
|
||||||
|
|
||||||
|
return (true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ARGSUSED */
|
||||||
|
static _prop_object_equals_rv_t
|
||||||
|
_prop_string_equals(prop_object_t v1, prop_object_t v2,
|
||||||
|
void **stored_pointer1, void **stored_pointer2,
|
||||||
|
prop_object_t *next_obj1, prop_object_t *next_obj2)
|
||||||
|
{
|
||||||
|
prop_string_t str1 = v1;
|
||||||
|
prop_string_t str2 = v2;
|
||||||
|
|
||||||
|
if (str1 == str2)
|
||||||
|
return (_PROP_OBJECT_EQUALS_TRUE);
|
||||||
|
if (str1->ps_size != str2->ps_size)
|
||||||
|
return (_PROP_OBJECT_EQUALS_FALSE);
|
||||||
|
if (strcmp(prop_string_contents(str1), prop_string_contents(str2)))
|
||||||
|
return (_PROP_OBJECT_EQUALS_FALSE);
|
||||||
|
else
|
||||||
|
return (_PROP_OBJECT_EQUALS_TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
static prop_string_t
|
||||||
|
_prop_string_alloc(void)
|
||||||
|
{
|
||||||
|
prop_string_t ps;
|
||||||
|
|
||||||
|
ps = _PROP_POOL_GET(_prop_string_pool);
|
||||||
|
if (ps != NULL) {
|
||||||
|
_prop_object_init(&ps->ps_obj, &_prop_object_type_string);
|
||||||
|
|
||||||
|
ps->ps_mutable = NULL;
|
||||||
|
ps->ps_size = 0;
|
||||||
|
ps->ps_flags = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (ps);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* prop_string_create --
|
||||||
|
* Create an empty mutable string.
|
||||||
|
*/
|
||||||
|
prop_string_t
|
||||||
|
prop_string_create(void)
|
||||||
|
{
|
||||||
|
|
||||||
|
return (_prop_string_alloc());
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* prop_string_create_cstring --
|
||||||
|
* Create a string that contains a copy of the provided C string.
|
||||||
|
*/
|
||||||
|
prop_string_t
|
||||||
|
prop_string_create_cstring(const char *str)
|
||||||
|
{
|
||||||
|
prop_string_t ps;
|
||||||
|
char *cp;
|
||||||
|
size_t len;
|
||||||
|
|
||||||
|
ps = _prop_string_alloc();
|
||||||
|
if (ps != NULL) {
|
||||||
|
len = strlen(str);
|
||||||
|
cp = _PROP_MALLOC(len + 1, M_PROP_STRING);
|
||||||
|
if (cp == NULL) {
|
||||||
|
prop_object_release(ps);
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
strcpy(cp, str);
|
||||||
|
ps->ps_mutable = cp;
|
||||||
|
ps->ps_size = len;
|
||||||
|
}
|
||||||
|
return (ps);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* prop_string_create_cstring_nocopy --
|
||||||
|
* Create an immutable string that contains a refrence to the
|
||||||
|
* provided C string.
|
||||||
|
*/
|
||||||
|
prop_string_t
|
||||||
|
prop_string_create_cstring_nocopy(const char *str)
|
||||||
|
{
|
||||||
|
prop_string_t ps;
|
||||||
|
|
||||||
|
ps = _prop_string_alloc();
|
||||||
|
if (ps != NULL) {
|
||||||
|
ps->ps_immutable = str;
|
||||||
|
ps->ps_size = strlen(str);
|
||||||
|
ps->ps_flags |= PS_F_NOCOPY;
|
||||||
|
}
|
||||||
|
return (ps);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* prop_string_copy --
|
||||||
|
* Copy a string. If the original string is immutable, then the
|
||||||
|
* copy is also immutable and references the same external data.
|
||||||
|
*/
|
||||||
|
prop_string_t
|
||||||
|
prop_string_copy(prop_string_t ops)
|
||||||
|
{
|
||||||
|
prop_string_t ps;
|
||||||
|
|
||||||
|
if (! prop_object_is_string(ops))
|
||||||
|
return (NULL);
|
||||||
|
|
||||||
|
ps = _prop_string_alloc();
|
||||||
|
if (ps != NULL) {
|
||||||
|
ps->ps_size = ops->ps_size;
|
||||||
|
ps->ps_flags = ops->ps_flags;
|
||||||
|
if (ops->ps_flags & PS_F_NOCOPY)
|
||||||
|
ps->ps_immutable = ops->ps_immutable;
|
||||||
|
else {
|
||||||
|
char *cp = _PROP_MALLOC(ps->ps_size + 1, M_PROP_STRING);
|
||||||
|
if (cp == NULL) {
|
||||||
|
prop_object_release(ps);
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
strcpy(cp, prop_string_contents(ops));
|
||||||
|
ps->ps_mutable = cp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (ps);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* prop_string_copy_mutable --
|
||||||
|
* Copy a string, always returning a mutable copy.
|
||||||
|
*/
|
||||||
|
prop_string_t
|
||||||
|
prop_string_copy_mutable(prop_string_t ops)
|
||||||
|
{
|
||||||
|
prop_string_t ps;
|
||||||
|
char *cp;
|
||||||
|
|
||||||
|
if (! prop_object_is_string(ops))
|
||||||
|
return (NULL);
|
||||||
|
|
||||||
|
ps = _prop_string_alloc();
|
||||||
|
if (ps != NULL) {
|
||||||
|
ps->ps_size = ops->ps_size;
|
||||||
|
cp = _PROP_MALLOC(ps->ps_size + 1, M_PROP_STRING);
|
||||||
|
if (cp == NULL) {
|
||||||
|
prop_object_release(ps);
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
strcpy(cp, prop_string_contents(ops));
|
||||||
|
ps->ps_mutable = cp;
|
||||||
|
}
|
||||||
|
return (ps);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* prop_string_size --
|
||||||
|
* Return the size of the string, not including the terminating NUL.
|
||||||
|
*/
|
||||||
|
size_t
|
||||||
|
prop_string_size(prop_string_t ps)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (! prop_object_is_string(ps))
|
||||||
|
return (0);
|
||||||
|
|
||||||
|
return (ps->ps_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* prop_string_mutable --
|
||||||
|
* Return true if the string is a mutable string.
|
||||||
|
*/
|
||||||
|
bool
|
||||||
|
prop_string_mutable(prop_string_t ps)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (! prop_object_is_string(ps))
|
||||||
|
return (false);
|
||||||
|
|
||||||
|
return ((ps->ps_flags & PS_F_NOCOPY) == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* prop_string_cstring --
|
||||||
|
* Return a copy of the contents of the string as a C string.
|
||||||
|
* The string is allocated with the M_TEMP malloc type.
|
||||||
|
*/
|
||||||
|
char *
|
||||||
|
prop_string_cstring(prop_string_t ps)
|
||||||
|
{
|
||||||
|
char *cp;
|
||||||
|
|
||||||
|
if (! prop_object_is_string(ps))
|
||||||
|
return (NULL);
|
||||||
|
|
||||||
|
cp = _PROP_MALLOC(ps->ps_size + 1, M_TEMP);
|
||||||
|
if (cp != NULL)
|
||||||
|
strcpy(cp, prop_string_contents(ps));
|
||||||
|
|
||||||
|
return (cp);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* prop_string_cstring_nocopy --
|
||||||
|
* Return an immutable reference to the contents of the string
|
||||||
|
* as a C string.
|
||||||
|
*/
|
||||||
|
const char *
|
||||||
|
prop_string_cstring_nocopy(prop_string_t ps)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (! prop_object_is_string(ps))
|
||||||
|
return (NULL);
|
||||||
|
|
||||||
|
return (prop_string_contents(ps));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* prop_string_append --
|
||||||
|
* Append the contents of one string to another. Returns true
|
||||||
|
* upon success. The destination string must be mutable.
|
||||||
|
*/
|
||||||
|
bool
|
||||||
|
prop_string_append(prop_string_t dst, prop_string_t src)
|
||||||
|
{
|
||||||
|
char *ocp, *cp;
|
||||||
|
size_t len;
|
||||||
|
|
||||||
|
if (! (prop_object_is_string(dst) &&
|
||||||
|
prop_object_is_string(src)))
|
||||||
|
return (false);
|
||||||
|
|
||||||
|
if (dst->ps_flags & PS_F_NOCOPY)
|
||||||
|
return (false);
|
||||||
|
|
||||||
|
len = dst->ps_size + src->ps_size;
|
||||||
|
cp = _PROP_MALLOC(len + 1, M_PROP_STRING);
|
||||||
|
if (cp == NULL)
|
||||||
|
return (false);
|
||||||
|
sprintf(cp, "%s%s", prop_string_contents(dst),
|
||||||
|
prop_string_contents(src));
|
||||||
|
ocp = dst->ps_mutable;
|
||||||
|
dst->ps_mutable = cp;
|
||||||
|
dst->ps_size = len;
|
||||||
|
if (ocp != NULL)
|
||||||
|
_PROP_FREE(ocp, M_PROP_STRING);
|
||||||
|
|
||||||
|
return (true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* prop_string_append_cstring --
|
||||||
|
* Append a C string to a string. Returns true upon success.
|
||||||
|
* The destination string must be mutable.
|
||||||
|
*/
|
||||||
|
bool
|
||||||
|
prop_string_append_cstring(prop_string_t dst, const char *src)
|
||||||
|
{
|
||||||
|
char *ocp, *cp;
|
||||||
|
size_t len;
|
||||||
|
|
||||||
|
if (! prop_object_is_string(dst))
|
||||||
|
return (false);
|
||||||
|
|
||||||
|
_PROP_ASSERT(src != NULL);
|
||||||
|
|
||||||
|
if (dst->ps_flags & PS_F_NOCOPY)
|
||||||
|
return (false);
|
||||||
|
|
||||||
|
len = dst->ps_size + strlen(src);
|
||||||
|
cp = _PROP_MALLOC(len + 1, M_PROP_STRING);
|
||||||
|
if (cp == NULL)
|
||||||
|
return (false);
|
||||||
|
sprintf(cp, "%s%s", prop_string_contents(dst), src);
|
||||||
|
ocp = dst->ps_mutable;
|
||||||
|
dst->ps_mutable = cp;
|
||||||
|
dst->ps_size = len;
|
||||||
|
if (ocp != NULL)
|
||||||
|
_PROP_FREE(ocp, M_PROP_STRING);
|
||||||
|
|
||||||
|
return (true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* prop_string_equals --
|
||||||
|
* Return true if two strings are equivalent.
|
||||||
|
*/
|
||||||
|
bool
|
||||||
|
prop_string_equals(prop_string_t str1, prop_string_t str2)
|
||||||
|
{
|
||||||
|
if (!prop_object_is_string(str1) || !prop_object_is_string(str2))
|
||||||
|
return (false);
|
||||||
|
|
||||||
|
return prop_object_equals(str1, str2);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* prop_string_equals_cstring --
|
||||||
|
* Return true if the string is equivalent to the specified
|
||||||
|
* C string.
|
||||||
|
*/
|
||||||
|
bool
|
||||||
|
prop_string_equals_cstring(prop_string_t ps, const char *cp)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (! prop_object_is_string(ps))
|
||||||
|
return (false);
|
||||||
|
|
||||||
|
return (strcmp(prop_string_contents(ps), cp) == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* _prop_string_internalize --
|
||||||
|
* Parse a <string>...</string> and return the object created from the
|
||||||
|
* external representation.
|
||||||
|
*/
|
||||||
|
/* ARGSUSED */
|
||||||
|
bool
|
||||||
|
_prop_string_internalize(prop_stack_t stack, prop_object_t *obj,
|
||||||
|
struct _prop_object_internalize_context *ctx)
|
||||||
|
{
|
||||||
|
prop_string_t string;
|
||||||
|
char *str;
|
||||||
|
size_t len, alen;
|
||||||
|
|
||||||
|
if (ctx->poic_is_empty_element) {
|
||||||
|
*obj = prop_string_create();
|
||||||
|
return (true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* No attributes recognized here. */
|
||||||
|
if (ctx->poic_tagattr != NULL)
|
||||||
|
return (true);
|
||||||
|
|
||||||
|
/* Compute the length of the result. */
|
||||||
|
if (_prop_object_internalize_decode_string(ctx, NULL, 0, &len,
|
||||||
|
NULL) == false)
|
||||||
|
return (true);
|
||||||
|
|
||||||
|
str = _PROP_MALLOC(len + 1, M_PROP_STRING);
|
||||||
|
if (str == NULL)
|
||||||
|
return (true);
|
||||||
|
|
||||||
|
if (_prop_object_internalize_decode_string(ctx, str, len, &alen,
|
||||||
|
&ctx->poic_cp) == false ||
|
||||||
|
alen != len) {
|
||||||
|
_PROP_FREE(str, M_PROP_STRING);
|
||||||
|
return (true);
|
||||||
|
}
|
||||||
|
str[len] = '\0';
|
||||||
|
|
||||||
|
if (_prop_object_internalize_find_tag(ctx, "string",
|
||||||
|
_PROP_TAG_TYPE_END) == false) {
|
||||||
|
_PROP_FREE(str, M_PROP_STRING);
|
||||||
|
return (true);
|
||||||
|
}
|
||||||
|
|
||||||
|
string = _prop_string_alloc();
|
||||||
|
if (string == NULL) {
|
||||||
|
_PROP_FREE(str, M_PROP_STRING);
|
||||||
|
return (true);
|
||||||
|
}
|
||||||
|
|
||||||
|
string->ps_mutable = str;
|
||||||
|
string->ps_size = len;
|
||||||
|
*obj = string;
|
||||||
|
|
||||||
|
return (true);
|
||||||
|
}
|
@ -167,7 +167,7 @@ xbps_purge_pkg(const char *pkgname, bool check_state)
|
|||||||
if (path == NULL)
|
if (path == NULL)
|
||||||
return errno;
|
return errno;
|
||||||
|
|
||||||
dict = prop_dictionary_internalize_from_file(path);
|
dict = prop_dictionary_internalize_from_zfile(path);
|
||||||
if (dict == NULL) {
|
if (dict == NULL) {
|
||||||
free(path);
|
free(path);
|
||||||
return errno;
|
return errno;
|
||||||
|
@ -71,7 +71,7 @@ xbps_register_pkg(prop_dictionary_t pkgrd, bool automatic)
|
|||||||
return EINVAL;
|
return EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((dict = prop_dictionary_internalize_from_file(plist)) != NULL) {
|
if ((dict = prop_dictionary_internalize_from_zfile(plist)) != NULL) {
|
||||||
pkgd = xbps_find_pkg_in_dict_by_name(dict,
|
pkgd = xbps_find_pkg_in_dict_by_name(dict,
|
||||||
"packages", pkgname);
|
"packages", pkgname);
|
||||||
if (pkgd == NULL) {
|
if (pkgd == NULL) {
|
||||||
@ -136,7 +136,7 @@ xbps_register_pkg(prop_dictionary_t pkgrd, bool automatic)
|
|||||||
/*
|
/*
|
||||||
* Write plist file to storage.
|
* Write plist file to storage.
|
||||||
*/
|
*/
|
||||||
if (!prop_dictionary_externalize_to_file(dict, plist))
|
if (!prop_dictionary_externalize_to_zfile(dict, plist))
|
||||||
rv = errno;
|
rv = errno;
|
||||||
} else {
|
} else {
|
||||||
free(plist);
|
free(plist);
|
||||||
|
@ -71,7 +71,7 @@ xbps_regpkgs_dictionary_init(void)
|
|||||||
if (plist == NULL)
|
if (plist == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
regpkgs_dict = prop_dictionary_internalize_from_file(plist);
|
regpkgs_dict = prop_dictionary_internalize_from_zfile(plist);
|
||||||
if (regpkgs_dict == NULL) {
|
if (regpkgs_dict == NULL) {
|
||||||
free(plist);
|
free(plist);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -251,7 +251,7 @@ xbps_remove_pkg(const char *pkgname, const char *version, bool update)
|
|||||||
return errno;
|
return errno;
|
||||||
}
|
}
|
||||||
|
|
||||||
dict = prop_dictionary_internalize_from_file(path);
|
dict = prop_dictionary_internalize_from_zfile(path);
|
||||||
if (dict == NULL) {
|
if (dict == NULL) {
|
||||||
free(buf);
|
free(buf);
|
||||||
free(path);
|
free(path);
|
||||||
|
@ -53,7 +53,7 @@ xbps_repository_register(const char *uri)
|
|||||||
return errno;
|
return errno;
|
||||||
|
|
||||||
/* First check if we have the repository plist file. */
|
/* First check if we have the repository plist file. */
|
||||||
dict = prop_dictionary_internalize_from_file(plist);
|
dict = prop_dictionary_internalize_from_zfile(plist);
|
||||||
if (dict == NULL) {
|
if (dict == NULL) {
|
||||||
/* Looks like not, create it. */
|
/* Looks like not, create it. */
|
||||||
dict = prop_dictionary_create();
|
dict = prop_dictionary_create();
|
||||||
@ -98,7 +98,7 @@ xbps_repository_register(const char *uri)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Write dictionary into plist file. */
|
/* Write dictionary into plist file. */
|
||||||
if (!prop_dictionary_externalize_to_file(dict, plist)) {
|
if (!prop_dictionary_externalize_to_zfile(dict, plist)) {
|
||||||
if (obj)
|
if (obj)
|
||||||
prop_object_release(obj);
|
prop_object_release(obj);
|
||||||
rv = errno;
|
rv = errno;
|
||||||
@ -127,7 +127,7 @@ xbps_repository_unregister(const char *uri)
|
|||||||
if (plist == NULL)
|
if (plist == NULL)
|
||||||
return errno;
|
return errno;
|
||||||
|
|
||||||
dict = prop_dictionary_internalize_from_file(plist);
|
dict = prop_dictionary_internalize_from_zfile(plist);
|
||||||
if (dict == NULL) {
|
if (dict == NULL) {
|
||||||
free(plist);
|
free(plist);
|
||||||
return errno;
|
return errno;
|
||||||
@ -142,7 +142,7 @@ xbps_repository_unregister(const char *uri)
|
|||||||
rv = xbps_remove_string_from_array(array, uri);
|
rv = xbps_remove_string_from_array(array, uri);
|
||||||
if (rv == 0) {
|
if (rv == 0) {
|
||||||
/* Update plist file. */
|
/* Update plist file. */
|
||||||
if (!prop_dictionary_externalize_to_file(dict, plist))
|
if (!prop_dictionary_externalize_to_zfile(dict, plist))
|
||||||
rv = errno;
|
rv = errno;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -66,7 +66,7 @@ xbps_repository_pool_init(void)
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
dict = prop_dictionary_internalize_from_file(plist);
|
dict = prop_dictionary_internalize_from_zfile(plist);
|
||||||
if (dict == NULL) {
|
if (dict == NULL) {
|
||||||
free(plist);
|
free(plist);
|
||||||
rv = errno;
|
rv = errno;
|
||||||
@ -112,7 +112,7 @@ xbps_repository_pool_init(void)
|
|||||||
rv = errno;
|
rv = errno;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
rpool->rp_repod = prop_dictionary_internalize_from_file(plist);
|
rpool->rp_repod = prop_dictionary_internalize_from_zfile(plist);
|
||||||
if (rpool->rp_repod == NULL) {
|
if (rpool->rp_repod == NULL) {
|
||||||
free(rpool->rp_uri);
|
free(rpool->rp_uri);
|
||||||
free(rpool);
|
free(rpool);
|
||||||
|
@ -133,7 +133,7 @@ xbps_requiredby_pkg_remove(const char *pkgname)
|
|||||||
if (plist == NULL)
|
if (plist == NULL)
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
|
|
||||||
if ((dict = prop_dictionary_internalize_from_file(plist)) == NULL) {
|
if ((dict = prop_dictionary_internalize_from_zfile(plist)) == NULL) {
|
||||||
free(plist);
|
free(plist);
|
||||||
return errno;
|
return errno;
|
||||||
}
|
}
|
||||||
@ -141,7 +141,7 @@ xbps_requiredby_pkg_remove(const char *pkgname)
|
|||||||
rv = xbps_callback_array_iter_in_dict(dict, "packages",
|
rv = xbps_callback_array_iter_in_dict(dict, "packages",
|
||||||
remove_pkg_from_reqby, __UNCONST(pkgname));
|
remove_pkg_from_reqby, __UNCONST(pkgname));
|
||||||
if (rv == 0) {
|
if (rv == 0) {
|
||||||
if (!prop_dictionary_externalize_to_file(dict, plist))
|
if (!prop_dictionary_externalize_to_zfile(dict, plist))
|
||||||
rv = errno;
|
rv = errno;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -153,7 +153,7 @@ xbps_set_pkg_state_installed(const char *pkgname, pkg_state_t state)
|
|||||||
if (plist == NULL)
|
if (plist == NULL)
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
|
|
||||||
if ((dict = prop_dictionary_internalize_from_file(plist)) == NULL) {
|
if ((dict = prop_dictionary_internalize_from_zfile(plist)) == NULL) {
|
||||||
dict = prop_dictionary_create();
|
dict = prop_dictionary_create();
|
||||||
if (dict == NULL) {
|
if (dict == NULL) {
|
||||||
rv = errno;
|
rv = errno;
|
||||||
@ -230,7 +230,7 @@ xbps_set_pkg_state_installed(const char *pkgname, pkg_state_t state)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!prop_dictionary_externalize_to_file(dict, plist))
|
if (!prop_dictionary_externalize_to_zfile(dict, plist))
|
||||||
rv = errno;
|
rv = errno;
|
||||||
|
|
||||||
out:
|
out:
|
||||||
|
@ -320,7 +320,7 @@ unpack_archive_fini(struct archive *ar, prop_dictionary_t pkg)
|
|||||||
*/
|
*/
|
||||||
if (!preserve && (access(buf, R_OK) == 0)) {
|
if (!preserve && (access(buf, R_OK) == 0)) {
|
||||||
old_filesd =
|
old_filesd =
|
||||||
prop_dictionary_internalize_from_file(buf);
|
prop_dictionary_internalize_from_zfile(buf);
|
||||||
if (old_filesd == NULL) {
|
if (old_filesd == NULL) {
|
||||||
prop_object_release(filesd);
|
prop_object_release(filesd);
|
||||||
free(buf);
|
free(buf);
|
||||||
@ -340,7 +340,7 @@ unpack_archive_fini(struct archive *ar, prop_dictionary_t pkg)
|
|||||||
* can safely externalize files.plist because the path
|
* can safely externalize files.plist because the path
|
||||||
* is reachable.
|
* is reachable.
|
||||||
*/
|
*/
|
||||||
if (!prop_dictionary_externalize_to_file(filesd, buf)) {
|
if (!prop_dictionary_externalize_to_zfile(filesd, buf)) {
|
||||||
prop_object_release(filesd);
|
prop_object_release(filesd);
|
||||||
free(buf);
|
free(buf);
|
||||||
return errno;
|
return errno;
|
||||||
|
13
vars.mk
13
vars.mk
@ -12,23 +12,32 @@ INSTALL_STRIPPED ?= -s
|
|||||||
# Uncomment this to enable.
|
# Uncomment this to enable.
|
||||||
#BUILD_API_DOCS = 1
|
#BUILD_API_DOCS = 1
|
||||||
|
|
||||||
|
# Uncomment this to build and link from an external proplib.
|
||||||
|
#USE_EXTERNAL_PROPLIB = 1
|
||||||
|
|
||||||
LDFLAGS = -L$(TOPDIR)/lib
|
LDFLAGS = -L$(TOPDIR)/lib
|
||||||
CPPFLAGS = -I$(TOPDIR)/include -D_XOPEN_SOURCE=600 -D_GNU_SOURCE
|
CPPFLAGS = -I$(TOPDIR)/include -D_XOPEN_SOURCE=600 -D_GNU_SOURCE
|
||||||
CPPFLAGS += -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -D_LARGE_FILES
|
CPPFLAGS += -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -D_LARGE_FILES
|
||||||
|
|
||||||
|
ifndef USE_EXTERNAL_PROPLIB
|
||||||
|
CPPFLAGS += -I$(TOPDIR)/lib/portableproplib
|
||||||
|
else
|
||||||
|
STATIC_PROPLIB = -lprop
|
||||||
|
endif
|
||||||
|
|
||||||
ifdef DEBUG
|
ifdef DEBUG
|
||||||
INSTALL_STRIPPED =
|
INSTALL_STRIPPED =
|
||||||
DEBUG_FLAGS = -g
|
DEBUG_FLAGS = -g
|
||||||
CPPFLAGS += -DDEBUG
|
CPPFLAGS += -DDEBUG
|
||||||
endif
|
endif
|
||||||
|
|
||||||
WARNFLAGS = -pedantic -std=c99 -Wall -Wextra -Werror -Wshadow -Wformat=2
|
WARNFLAGS = -std=c99 -Wall -Wextra -Werror -Wshadow -Wformat=2
|
||||||
WARNFLAGS += -Wmissing-declarations -Wcomment -Wunused-macros -Wendif-labels
|
WARNFLAGS += -Wmissing-declarations -Wcomment -Wunused-macros -Wendif-labels
|
||||||
WARNFLAGS += -Wcast-qual -Wcast-align -Wstack-protector
|
WARNFLAGS += -Wcast-qual -Wcast-align -Wstack-protector
|
||||||
CFLAGS = $(DEBUG_FLAGS) $(WARNFLAGS) -fPIC -DPIC -fstack-protector-all
|
CFLAGS = $(DEBUG_FLAGS) $(WARNFLAGS) -fPIC -DPIC -fstack-protector-all
|
||||||
SHAREDLIB_CFLAGS = -fvisibility=default
|
SHAREDLIB_CFLAGS = -fvisibility=default
|
||||||
|
|
||||||
# Grr, hate the static libs!
|
# Grr, hate the static libs!
|
||||||
STATIC_LIBS = -lprop -lpthread
|
STATIC_LIBS = -lz $(STATIC_PROPLIB) -lpthread
|
||||||
STATIC_LIBS += `pkg-config openssl --libs --static`
|
STATIC_LIBS += `pkg-config openssl --libs --static`
|
||||||
STATIC_LIBS += `pkg-config libarchive --libs --static`
|
STATIC_LIBS += `pkg-config libarchive --libs --static`
|
||||||
|
Loading…
Reference in New Issue
Block a user