Skip to content
Snippets Groups Projects
Commit d2c2a1fd authored by Niels Möller's avatar Niels Möller
Browse files

(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
Branches
Tags
No related merge requests found
...@@ -186,19 +186,49 @@ sexp_iterator_exit_list(struct sexp_iterator *iterator) ...@@ -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 int
sexp_iterator_assoc(struct sexp_iterator *iterator, sexp_iterator_assoc(struct sexp_iterator *iterator,
unsigned nkeys, unsigned nkeys,
const struct sexp_assoc_key *keys, const uint8_t **keys,
struct sexp_iterator *values) struct sexp_iterator *values)
{ {
int *found; int *found;
unsigned nfound; unsigned nfound;
unsigned i; unsigned i;
if (!sexp_iterator_enter_list(iterator))
return 0;
found = alloca(nkeys * sizeof(*found)); found = alloca(nkeys * sizeof(*found));
for (i = 0; i<nkeys; i++) for (i = 0; i<nkeys; i++)
found[i] = 0; found[i] = 0;
...@@ -214,6 +244,7 @@ sexp_iterator_assoc(struct sexp_iterator *iterator, ...@@ -214,6 +244,7 @@ sexp_iterator_assoc(struct sexp_iterator *iterator,
{ {
case SEXP_LIST: case SEXP_LIST:
/* FIXME: Use sexp_iterator_check_type? */
if (! (sexp_iterator_enter_list(iterator) if (! (sexp_iterator_enter_list(iterator)
&& sexp_iterator_next(iterator))) && sexp_iterator_next(iterator)))
return 0; return 0;
...@@ -224,9 +255,11 @@ sexp_iterator_assoc(struct sexp_iterator *iterator, ...@@ -224,9 +255,11 @@ sexp_iterator_assoc(struct sexp_iterator *iterator,
/* Compare to the given keys */ /* Compare to the given keys */
for (i = 0; i<nkeys; i++) for (i = 0; i<nkeys; i++)
{ {
if (keys[i].length == iterator->atom_length /* NOTE: The strlen could be put outside of the
&& !memcmp(keys[i].name, iterator->atom, * loop */
keys[i].length)) if (strlen(keys[i]) == iterator->atom_length
&& !memcmp(keys[i], iterator->atom,
iterator->atom_length))
{ {
if (found[i]) if (found[i])
/* We don't allow duplicates */ /* We don't allow duplicates */
......
...@@ -50,11 +50,6 @@ struct sexp_iterator ...@@ -50,11 +50,6 @@ struct sexp_iterator
const uint8_t *atom; 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 /* Initializes the iterator. You have to call next to get to the first
* element. */ * element. */
...@@ -74,17 +69,42 @@ sexp_iterator_enter_list(struct sexp_iterator *iterator); ...@@ -74,17 +69,42 @@ sexp_iterator_enter_list(struct sexp_iterator *iterator);
int int
sexp_iterator_exit_list(struct sexp_iterator *iterator); 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 /* Current element must be a list. Looks up element of type
* *
* (key rest...) * (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. * pointing at the start of REST.
*/ */
int int
sexp_iterator_assoc(struct sexp_iterator *iterator, sexp_iterator_assoc(struct sexp_iterator *iterator,
unsigned nkeys, unsigned nkeys,
const struct sexp_assoc_key *keys, const uint8_t **keys,
struct sexp_iterator *values); 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 */ #endif /* NETTLE_SEXP_H_INCLUDED */
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment