Subject: bug#63196: Further on this error message

From: <[email-masked]>
Date: Sat, 6 May 2023 14:38:06 +0200

On Mon, May 01, 2023 at 10:44:18AM +0800, Christopher Lam wrote:
> The source seems to be sxpath.scm -- see "yikes" error which triggers when
> n is -2 -4 -6 etc. I don't know how to build guile from sources and cannot
> debug further.
> 
> 
> (define (node-pos n)
>   (lambda (nodeset)
>     (cond
>      ((not (nodeset? nodeset)) '())
>      ((null? nodeset) nodeset)
>      ((eqv? n 1) (list (car nodeset)))
>      ((negative? n) ((node-pos (+ n 1 (length nodeset))) nodeset))
>      (else
>       (or (positive? n) (error "yikes!"))
>       ((node-pos (1- n)) (cdr nodeset))))))

Hm. It seems that calling `node-pos' with n == 0 runs straight into the
"yikes" case (unless `nodeset' is #f or null, that is).

And we would get this when n ==-2 and (length nodeset) equals 1 on the
next recursive call. Or when n == -3 and (length nodeset) == 2, and so
on -- i.e. when n == -1 - (length nodeset).

We reach such a point again when n == 2*(-1 - (length nodeset)): it runs
into the case (negative? n), retries with n' = (+ n 1 (length nodeset))
which is still negative, next try is 0 => yikes.

So in your case I guess your (length nodeset) is 1, because you have
a cycle length of two :-)

Reading between the lines in the code above for the positive case, I
gather that the intention is to return an empty nodeset (i.e. '())
when n runs off the nodeset. So I'd extend the ((negative? n) ...)
case like so:

  ((negative? n)
    (let ((nn (+ 1 (length nodeset))))
      (if (positive? nn) (node-pos nn) '())))

Comments?

Cheers
-- 
t