/*-
* Copyright (c) 2021 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.
*/
/*
* strlist --
*
* A set of routines for interacting with IEEE 1275 (OpenFirmware)
* style string lists.
*
* An OpenFirmware string list is simply a buffer containing
* multiple NUL-terminated strings concatenated together.
*
* So, for example, the a string list consisting of the strings
* "foo", "bar", and "baz" would be represented in memory like:
*
* foo\0bar\0baz\0
*/
#include <sys/types.h>
/*
* Memory allocation wrappers to handle different environments.
*/
#if defined(_KERNEL)
#include <sys/kmem.h>
#include <sys/systm.h>
/*
* strlist_next --
*
* Return a pointer to the next string in the strlist,
* or NULL if there are no more strings.
*/
const char *
strlist_next(const char * const sl, size_t const slsize, size_t * const cursorp)
{
/*
* strlist_string --
*
* Returns the string in the strlist at the specified index.
* Returns NULL if the index is beyond the strlist range.
*/
const char *
strlist_string(const char * sl, size_t slsize, unsigned int const idx)
{
if (sl == NULL || slsize == 0) {
return NULL;
}
size_t cursize;
unsigned int i;
for (i = 0; slsize != 0; i++, slsize -= cursize, sl += cursize) {
cursize = strlen(sl) + 1;
if (i == idx) {
return sl;
}
}
for (i = 0; slsize != 0;
l = strlen(cp) + 1, slsize -= l, cp += l, i++) {
if (rv) {
/*
* We've already matched. We must be
* counting to the end.
*/
continue;
}
if ((*match_fn)(cp, str)) {
/*
* Matched! Get the index. If we don't
* also want the total count, then get
* out early.
*/
*indexp = i;
rv = true;
if (countp == NULL) {
break;
}
}
}
if (countp != NULL) {
*countp = i;
}
return rv;
}
/*
* strlist_match --
*
* Returns a weighted match value (1 <= match <= sl->count) if the
* specified string appears in the strlist. A match at the
* beginning of the list carriest the greatest weight (i.e. sl->count)
* and a match at the end of the list carriest the least (i.e. 1).
* Returns 0 if there is no match.
*
* This routine operates independently of the cursor used to enumerate
* a strlist.
*/
int
strlist_match(const char * const sl, size_t const slsize,
const char * const str)
{
unsigned int count;
int idx = 0 /* XXXGCC 12 */;
/*
* strlist_index --
*
* Returns the index of the specified string if it appears
* in the strlist. Returns -1 if the string is not found.
*
* This routine operates independently of the cursor used to enumerate
* a strlist.
*/
int
strlist_index(const char * const sl, size_t const slsize,
const char * const str)
{
int idx;