summaryrefslogtreecommitdiff
path: root/sexp.c
diff options
context:
space:
mode:
authorNiels Möller <nisse@lysator.liu.se>2002-10-07 00:04:21 +0200
committerNiels Möller <nisse@lysator.liu.se>2002-10-07 00:04:21 +0200
commit48ee3f6bf6078b922c96f009314f111a86d5eaef (patch)
tree815655705ae23f04c2cde692c2edb24eac2cbc49 /sexp.c
parent7ba605d58f822004285bdb0c2a734cbfc5bab67f (diff)
downloadnettle-48ee3f6bf6078b922c96f009314f111a86d5eaef.tar.gz
(sexp_iterator_parse): New function, similar to the old
sexp_iterator_next, but independent of the previous value of the iterator->type. (sexp_iterator_first): Use sexp_iterator_parse. (sexp_iterator_next): Likewise. (sexp_iterator_enter_list): Use sexp_iterator_parse. SEXP_START not needed anymore. (sexp_iterator_exit_list): Likewise. Rev: src/nettle/sexp.c:1.9
Diffstat (limited to 'sexp.c')
-rw-r--r--sexp.c81
1 files changed, 48 insertions, 33 deletions
diff --git a/sexp.c b/sexp.c
index d066dea4..6cf4be6f 100644
--- a/sexp.c
+++ b/sexp.c
@@ -28,8 +28,8 @@
#include <stdlib.h>
#include <string.h>
-/* Initializes the iterator. You have to call next to get to the first
- * element. */
+/* Initializes the iterator, but one has to call next to get to the
+ * first element. */
static void
sexp_iterator_init(struct sexp_iterator *iterator,
unsigned length, const uint8_t *input)
@@ -38,7 +38,7 @@ sexp_iterator_init(struct sexp_iterator *iterator,
iterator->buffer = input;
iterator->pos = 0;
iterator->level = 0;
- iterator->type = SEXP_START;
+ iterator->type = SEXP_END; /* Value doesn't matter */
iterator->display_length = 0;
iterator->display = NULL;
iterator->atom_length = 0;
@@ -48,14 +48,6 @@ sexp_iterator_init(struct sexp_iterator *iterator,
* skip white space here. */
}
-int
-sexp_iterator_first(struct sexp_iterator *iterator,
- unsigned length, const uint8_t *input)
-{
- sexp_iterator_init(iterator, length, input);
- return sexp_iterator_next(iterator);
-}
-
#define EMPTY(i) ((i)->pos == (i)->length)
#define NEXT(i) ((i)->buffer[(i)->pos++])
@@ -100,12 +92,13 @@ sexp_iterator_simple(struct sexp_iterator *iterator,
}
/* All these functions return 1 on success, 0 on failure */
-int
-sexp_iterator_next(struct sexp_iterator *iterator)
+
+/* Look at the current position in the data. Sets iterator->type, and
+ * ignores the old value. */
+
+static int
+sexp_iterator_parse(struct sexp_iterator *iterator)
{
- if (iterator->type == SEXP_END)
- return 1;
-
if (EMPTY(iterator))
{
if (iterator->level)
@@ -117,18 +110,15 @@ sexp_iterator_next(struct sexp_iterator *iterator)
switch (iterator->buffer[iterator->pos])
{
case '(': /* A list */
- if (iterator->type == SEXP_LIST)
- /* Skip this list */
- return sexp_iterator_enter_list(iterator)
- && sexp_iterator_exit_list(iterator);
- else
- {
- iterator->type = SEXP_LIST;
- return 1;
- }
+ iterator->type = SEXP_LIST;
+ return 1;
+
case ')':
+ if (!iterator->level)
+ return 0;
+
iterator->pos++;
- iterator->type = SEXP_END;
+ iterator->type = SEXP_END;
return 1;
case '[': /* Atom with display type */
@@ -158,6 +148,32 @@ sexp_iterator_next(struct sexp_iterator *iterator)
&iterator->atom);
}
+int
+sexp_iterator_first(struct sexp_iterator *iterator,
+ unsigned length, const uint8_t *input)
+{
+ sexp_iterator_init(iterator, length, input);
+ return sexp_iterator_parse(iterator);
+}
+
+int
+sexp_iterator_next(struct sexp_iterator *iterator)
+{
+ switch (iterator->type)
+ {
+ case SEXP_END:
+ return 1;
+ case SEXP_LIST:
+ /* Skip this list */
+ return sexp_iterator_enter_list(iterator)
+ && sexp_iterator_exit_list(iterator);
+ case SEXP_ATOM:
+ /* iterator->pos should already point at the start of the next
+ * element. */
+ return sexp_iterator_parse(iterator);
+ }
+}
+
/* Current element must be a list. */
int
sexp_iterator_enter_list(struct sexp_iterator *iterator)
@@ -170,9 +186,8 @@ sexp_iterator_enter_list(struct sexp_iterator *iterator)
abort();
iterator->level++;
- iterator->type = SEXP_START;
-
- return sexp_iterator_next(iterator);
+
+ return sexp_iterator_parse(iterator);
}
/* Skips the rest of the current list */
@@ -186,10 +201,9 @@ sexp_iterator_exit_list(struct sexp_iterator *iterator)
if (!sexp_iterator_next(iterator))
return 0;
- iterator->type = SEXP_START;
iterator->level--;
- return sexp_iterator_next(iterator);
+ return sexp_iterator_parse(iterator);
}
int
@@ -222,7 +236,6 @@ sexp_iterator_check_types(struct sexp_iterator *iterator,
}
return NULL;
}
-
int
sexp_iterator_assoc(struct sexp_iterator *iterator,
@@ -246,7 +259,9 @@ sexp_iterator_assoc(struct sexp_iterator *iterator,
{
case SEXP_LIST:
- /* FIXME: Use sexp_iterator_check_type? */
+ /* FIXME: Use sexp_iterator_check_type? Problem is to
+ * distinguish syntax errors from unkown keys (which we want
+ * to just ignore). */
if (!sexp_iterator_enter_list(iterator))
return 0;