From 3946f0ded4acc53406acb7b2ccc29c25182d97c1 Mon Sep 17 00:00:00 2001 From: Mikael Djurfeldt Date: Tue, 16 Mar 1999 16:37:51 +0000 Subject: [PATCH] * list.c (scm_reverse): Report an error if given a circular list instead of filling memory. * list.c (scm_reverse_x): Check args. --- libguile/list.c | 63 ++++++++++++++++++++++++++++--------------------- 1 file changed, 36 insertions(+), 27 deletions(-) diff --git a/libguile/list.c b/libguile/list.c index d7683fbd8..789cb57d7 100644 --- a/libguile/list.c +++ b/libguile/list.c @@ -259,42 +259,51 @@ scm_last_pair(sx) /* reversing lists */ SCM_PROC (s_reverse, "reverse", 1, 0, 0, scm_reverse); + SCM -scm_reverse(lst) - SCM lst; +scm_reverse (SCM ls) { - SCM res = SCM_EOL; - SCM p = lst; - for(;SCM_NIMP(p);p = SCM_CDR(p)) { - SCM_ASSERT(SCM_CONSP(p), lst, SCM_ARG1, s_reverse); - res = scm_cons(SCM_CAR(p), res); - } - SCM_ASSERT(SCM_NULLP(p), lst, SCM_ARG1, s_reverse); - return res; + SCM res = SCM_EOL; + SCM p = ls, t = ls; + while (SCM_NIMP (p)) + { + SCM_ASSERT (SCM_CONSP (p), ls, SCM_ARG1, s_reverse); + res = scm_cons (SCM_CAR (p), res); + p = SCM_CDR (p); + if (SCM_IMP (p)) + break; + SCM_ASSERT (SCM_CONSP (p), ls, SCM_ARG1, s_reverse); + res = scm_cons (SCM_CAR (p), res); + p = SCM_CDR (p); + t = SCM_CDR (t); + if (t == p) + scm_misc_error (s_reverse, "Circular structure: %S", SCM_LIST1 (ls)); + } + SCM_ASSERT (SCM_NULLP (p), ls, SCM_ARG1, s_reverse); + return res; } SCM_PROC (s_reverse_x, "reverse!", 1, 1, 0, scm_reverse_x); SCM -scm_reverse_x (lst, newtail) - SCM lst; - SCM newtail; +scm_reverse_x (ls, new_tail) + SCM ls; + SCM new_tail; { SCM old_tail; - if (newtail == SCM_UNDEFINED) - newtail = SCM_EOL; + SCM_ASSERT (scm_ilength (ls) >= 0, ls, SCM_ARG1, s_reverse_x); + if (SCM_UNBNDP (new_tail)) + new_tail = SCM_EOL; + else + SCM_ASSERT (scm_ilength (new_tail) >= 0, new_tail, SCM_ARG2, s_reverse_x); - loop: - if (!(SCM_NIMP (lst) && SCM_CONSP (lst))) - return lst; - - old_tail = SCM_CDR (lst); - SCM_SETCDR (lst, newtail); - if (SCM_NULLP (old_tail)) - return lst; - - newtail = lst; - lst = old_tail; - goto loop; + while (SCM_NIMP (ls)) + { + old_tail = SCM_CDR (ls); + SCM_SETCDR (ls, new_tail); + new_tail = ls; + ls = old_tail; + } + return new_tail; }