From d2c2a1fd6cfdc3e1d1a9c9b05cd04751d3763a57 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20M=C3=B6ller?= <nisse@lysator.liu.se> Date: Sun, 29 Sep 2002 23:02:29 +0200 Subject: [PATCH] (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 --- sexp.c | 49 +++++++++++++++++++++++++++++++++++++++++-------- sexp.h | 34 +++++++++++++++++++++++++++------- 2 files changed, 68 insertions(+), 15 deletions(-) diff --git a/sexp.c b/sexp.c index bd60e29c..3c653548 100644 --- a/sexp.c +++ b/sexp.c @@ -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 */ diff --git a/sexp.h b/sexp.h index 3f7bcec4..bf0d9adb 100644 --- a/sexp.h +++ b/sexp.h @@ -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 */ -- GitLab