]> git.ipfire.org Git - thirdparty/nettle.git/commitdiff
Rewrite sexp_iterator_exit_list to not recurse to sexp_iterator_next. fix-sexp_iterator_exit_list
authorNiels Möller <nisse@lysator.liu.se>
Sun, 28 Dec 2025 18:39:24 +0000 (19:39 +0100)
committerNiels Möller <nisse@lysator.liu.se>
Sun, 28 Dec 2025 18:39:24 +0000 (19:39 +0100)
sexp.c
sexp.h
testsuite/sexp-test.c

diff --git a/sexp.c b/sexp.c
index 3ef4b6bcea2d23c60657341f1c3184db17e24205..fe09a1a4c3428530974881443a21c4e516e0e158 100644 (file)
--- a/sexp.c
+++ b/sexp.c
@@ -214,30 +214,29 @@ sexp_iterator_exit_list(struct sexp_iterator *iterator)
   if (!iterator->level)
     return 0;
 
-  while(iterator->type != SEXP_END)
-    if (!sexp_iterator_next(iterator))
-      return 0;
-      
-  iterator->level--;
-
-  return sexp_iterator_parse(iterator);
-}
-
-#if 0
-/* What's a reasonable interface for this? */
-int
-sexp_iterator_exit_lists(struct sexp_iterator *iterator,
-                        unsigned level)
-{
-  assert(iterator->level >= level);
-
-  while (iterator->level > level)
-    if (!sexp_iterator_exit_list(iterator))
-      return 0;
-
-  return 1;
+  unsigned start_level = iterator->level;
+  for (;;)
+    switch (iterator->type)
+      {
+      case SEXP_END:
+       iterator->level--;
+       if (!sexp_iterator_parse (iterator))
+         return 0;
+       if (iterator->level < start_level)
+         return 1;
+       break;
+      case SEXP_ATOM:
+       if (!sexp_iterator_parse (iterator))
+         return 0;
+       break;
+      case SEXP_LIST:
+       if (!sexp_iterator_enter_list (iterator))
+         return 0;
+       break;
+      default:
+       abort ();
+      }
 }
-#endif
 
 const uint8_t *
 sexp_iterator_subexpr(struct sexp_iterator *iterator,
diff --git a/sexp.h b/sexp.h
index f6b3df646d4f497474158902f50fb3f177b66d0a..587cd48dd049e56481c3fe73cb8b3e488184b492 100644 (file)
--- a/sexp.h
+++ b/sexp.h
@@ -105,14 +105,6 @@ sexp_iterator_enter_list(struct sexp_iterator *iterator);
 int
 sexp_iterator_exit_list(struct sexp_iterator *iterator);
 
-#if 0
-/* Skips out of as many lists as necessary to get back to the given
- * level. */
-int
-sexp_iterator_exit_lists(struct sexp_iterator *iterator,
-                        unsigned level);
-#endif
-
 /* Gets start and length of the current subexpression. Implies
  * sexp_iterator_next. */
 const uint8_t *
index c1d421fc576390bf44828454179ca3dbe97cb569..84b228cdd7e6f0c66cbb5d21b24b587638af6ebc 100644 (file)
@@ -73,7 +73,7 @@ test_main(void)
     static const char * const keys[2] = { "n", "e" };
     struct sexp_iterator v[2];
     
-    ASSERT(sexp_iterator_first(&i, LDATA("((1:n2:xx3:foo)0:(1:y)(1:e))")));
+    ASSERT(sexp_iterator_first(&i, LDATA("((1:n2:xx3:foo)((((((1:z))))))0:(1:y)(1:e))")));
     ASSERT(sexp_iterator_enter_list(&i)
           && sexp_iterator_assoc(&i, 2, keys, v));