how to test for library existence

Asked by Marco Maggi on 2008-11-13

Ikarus should provide a no-brainer way to test if a library is installed.
At present the following (from a Unix prompt):

  $ echo '(import (unexistent))' | ikarus

does not cause Ikarus to terminate with a non-zero exit status. The way
should be easy to use from a GNU Autoconf macro, so IMHO it must not
require the creation of a temporary file.

The machinery required to find a library is already there, so I would like
a direct feature function that can be invoked like:

  $ echo '(display (library-available? (list-lib)))' | ikarus

and:

  $ echo '(test-library-availability-and-exit (list-lib))' | ikarus

or even:

  $ ikarus --library-exists '(list-lib)'

Question information

Language:
English Edit question
Status:
Solved
For:
Ikarus Scheme Edit question
Assignee:
No assignee Edit question
Solved by:
Derick Eddington
Solved:
2008-11-13
Last query:
2008-11-13
Last reply:
2008-11-13

On Thu, 2008-11-13 at 07:38 +0000, Marco Maggi wrote:
> Ikarus should provide a no-brainer way to test if a library is installed.
> At present the following (from a Unix prompt):
>
> $ echo '(import (unexistent))' | ikarus
>
> does not cause Ikarus to terminate with a non-zero exit status.

That's because you're piping it into ikarus in interactive mode. It's
reading that as REPL input.

> The way
> should be easy to use from a GNU Autoconf macro, so IMHO it must not
> require the creation of a temporary file.
>
> The machinery required to find a library is already there

Does something like this work?:

[d@eep:~/t10]-> cat library-available.sps
(import (ikarus))

(define main
  (case-lambda
    [(who lib-name)
     (let ([lib-name (read (open-string-input-port lib-name))])
       (with-exception-handler
         (lambda (ex)
           (display "no\n")
           (exit #F))
         (lambda ()
           (environment lib-name)))
       (display "yes\n")
       (exit))]
    [(who . args)
     (apply assertion-violation who "invalid arguments" args)]))

(apply main (command-line))
[d@eep:~/t10]->
[d@eep:~/t10]-> ikarus --r6rs-script library-available.sps '(xitomatl match)'
yes
[d@eep:~/t10]-> echo $?
0
[d@eep:~/t10]-> ikarus --r6rs-script library-available.sps '(doesnt exist)'
no
[d@eep:~/t10]-> echo $?
1
[d@eep:~/t10]-> ikarus --r6rs-script library-available.sps oops oops
Unhandled exception:
 Condition components:
   1. &assertion
   2. &who: "library-available.sps"
   3. &message: "invalid arguments"
   4. &irritants: ("oops" "oops")
[d@eep:~/t10]-> echo $?
255
[d@eep:~/t10]->

Marco Maggi (mrc-mgg) said : #2

The problem of this solution is that we need to write a script. And
then remove it. The following Autoconf macro does this: it is not
immediate, mh?

So, yes the problem is solved. Anyway AG could write a simple function
and add a command line switch to have the no-brainer solution.

# Synopsis:
#
# IKARUS_CHECK_LIBRARY(<NAME>, [IMPORT-SPEC],
# [ACTION-IF-FOUND],
# [ACTION-IF-NOT-FOUND])
#
# Description:
#
# Check the availability of the Ikarus library IMPORT-SPEC.
# If found set the output variable 'HAS_IKARUS_LIB_<NAME>'
# to 'yes', else set that variable to 'no'.
#
# ACTION-IF-FOUND is executed if the library is found.
#
# ACTION-IF-FOUND is executed if the library is not found.
#
# Prerequisites
#
# The variable 'IKARUS' must hold the pathname of the
# 'ikarus' executable.
#
# Example:
#
# To test if '(list-lib)' is available:
#
# IKARUS_CHECK_LIBRARY([LIST],[(list-lib)])
#
# if it is: the output variable 'HAS_IKARUS_LIB_LIST' is
# set to 'yes', otherwise it is set to 'no'.
#
AC_DEFUN([IKARUS_CHECK_LIBRARY],[
AC_MSG_CHECKING([availability of Ikarus library $2])

# This comes from the documentation of GNU Autoconf.
#
# Create a temporary directory "$nausicaa_TMPDIR" in "$TMPDIR"
# (default "/tmp"). Use mktemp if possible; otherwise fall
# back on mkdir, with $RANDOM to make collisions less likely.
: ${TMPDIR=/tmp}
{
    nausicaa_TMPDIR=`
    (umask 077 && mktemp -d "$TMPDIR/fooXXXXXX") 2>/dev/null
    ` &&
    test -n "$nausicaa_TMPDIR" && test -d "$nausicaa_TMPDIR"
} || {
    nausicaa_TMPDIR=$TMPDIR/foo$$-$RANDOM
    (umask 077 && mkdir "$nausicaa_TMPDIR")
} || exit $?

nausicaa_TMPFILE=${nausicaa_TMPDIR}/find-lib.sls

nausicaa_ANSWER=`echo '(import (ikarus))

(let ((lib-name (read (open-string-input-port
                        (cadr (command-line))))))
  (with-exception-handler
    (lambda (ex)
      (display "no\n")
      (exit 1))
    (lambda ()
      (environment lib-name)))
  (display "yes\n")
  (exit))

' >"${nausicaa_TMPFILE}"

"${IKARUS}" --r6rs-script "${nausicaa_TMPFILE}" '$2'`
rm -fr "${nausicaa_TMPDIR}"

AC_MSG_RESULT([${nausicaa_ANSWER}])
if test "${nausicaa_ANSWER}" = yes ; then
# Action if found.
:
$3
else
# Action if not found.
:
$4
fi

AC_SUBST([HAS_IKARUS_LIB_$1],[$nausicaa_ANSWER])
])

Marco Maggi (mrc-mgg) said : #3

Thanks Derick Eddington, that solved my question.