Commit d2c2a1fd authored by Niels Möller's avatar Niels Möller

(sexp_iterator_assoc): Don't enter the list, associate

keys within the current list. Still exit the list when done.
(sexp_iterator_assoc): Represent keys as plain NUL-terminated
strings.
(sexp_iterator_check_type, sexp_iterator_check_types): New
functions.

Rev: src/nettle/sexp.c:1.4
Rev: src/nettle/sexp.h:1.3
parent dc652126
......@@ -186,19 +186,49 @@ sexp_iterator_exit_list(struct sexp_iterator *iterator)
}
}
int
sexp_iterator_check_type(struct sexp_iterator *iterator,
const uint8_t *type)
{
return (sexp_iterator_enter_list(iterator)
&& sexp_iterator_next(iterator)
&& iterator->type == SEXP_ATOM
&& !iterator->display
&& strlen(type) == iterator->atom_length
&& !memcmp(type, iterator->atom, iterator->atom_length));
}
const uint8_t *
sexp_iterator_check_types(struct sexp_iterator *iterator,
unsigned ntypes,
const uint8_t **types)
{
if (sexp_iterator_enter_list(iterator)
&& sexp_iterator_next(iterator)
&& iterator->type == SEXP_ATOM
&& !iterator->display)
{
unsigned i;
for (i = 0; i<ntypes; i++)
if (strlen(types[i]) == iterator->atom_length
&& !memcmp(types[i], iterator->atom,
iterator->atom_length))
return types[i];
}
return 0;
}
int
sexp_iterator_assoc(struct sexp_iterator *iterator,
unsigned nkeys,
const struct sexp_assoc_key *keys,
const uint8_t **keys,
struct sexp_iterator *values)
{
int *found;
unsigned nfound;
unsigned i;
if (!sexp_iterator_enter_list(iterator))
return 0;
found = alloca(nkeys * sizeof(*found));
for (i = 0; i<nkeys; i++)
found[i] = 0;
......@@ -213,7 +243,8 @@ sexp_iterator_assoc(struct sexp_iterator *iterator,
switch (iterator->type)
{
case SEXP_LIST:
/* FIXME: Use sexp_iterator_check_type? */
if (! (sexp_iterator_enter_list(iterator)
&& sexp_iterator_next(iterator)))
return 0;
......@@ -224,9 +255,11 @@ sexp_iterator_assoc(struct sexp_iterator *iterator,
/* Compare to the given keys */
for (i = 0; i<nkeys; i++)
{
if (keys[i].length == iterator->atom_length
&& !memcmp(keys[i].name, iterator->atom,
keys[i].length))
/* NOTE: The strlen could be put outside of the
* loop */
if (strlen(keys[i]) == iterator->atom_length
&& !memcmp(keys[i], iterator->atom,
iterator->atom_length))
{
if (found[i])
/* We don't allow duplicates */
......
......@@ -50,11 +50,6 @@ struct sexp_iterator
const uint8_t *atom;
};
struct sexp_assoc_key
{
unsigned length;
const uint8_t *name;
};
/* Initializes the iterator. You have to call next to get to the first
* element. */
......@@ -74,17 +69,42 @@ sexp_iterator_enter_list(struct sexp_iterator *iterator);
int
sexp_iterator_exit_list(struct sexp_iterator *iterator);
/* Checks the type of the current expression, which should be a list
*
* (<type> ...)
*/
int
sexp_iterator_check_type(struct sexp_iterator *iterator,
const uint8_t *type);
const uint8_t *
sexp_iterator_check_types(struct sexp_iterator *iterator,
unsigned ntypes,
const uint8_t **types);
/* Current element must be a list. Looks up element of type
*
* (key rest...)
*
* For a matching key, the corersponding iterator is initialized
* For a matching key, the corresponding iterator is initialized
* pointing at the start of REST.
*/
int
sexp_iterator_assoc(struct sexp_iterator *iterator,
unsigned nkeys,
const struct sexp_assoc_key *keys,
const uint8_t **keys,
struct sexp_iterator *values);
/* Output functions. What is a reasonable API for this? It seems
* ugly to have to reimplement string streams. */
/* Declared for real in buffer.h */
struct nettle_buffer;
int
sexp_format(struct nettle_buffer *buffer, const char *format, ...);
#endif /* NETTLE_SEXP_H_INCLUDED */
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment