summaryrefslogtreecommitdiff
path: root/mk/luapath
diff options
context:
space:
mode:
authorWilliam Ahern <william@25thandclement.com>2016-06-24 21:59:02 -0700
committerWilliam Ahern <william@25thandclement.com>2016-06-24 21:59:02 -0700
commitd99465ce769657b6946190377cc8a5223f5e8261 (patch)
treed4ff546c128543fbe97dc39c8fd8ac4d2f6a3a5a /mk/luapath
parent81bbb1fa5e14a1911cfd99f4ee791ed1e340602e (diff)
downloadluaossl-d99465ce769657b6946190377cc8a5223f5e8261.tar.gz
luaossl-d99465ce769657b6946190377cc8a5223f5e8261.tar.bz2
luaossl-d99465ce769657b6946190377cc8a5223f5e8261.zip
upgrade luapath script
Diffstat (limited to 'mk/luapath')
-rwxr-xr-xmk/luapath1518
1 files changed, 1518 insertions, 0 deletions
diff --git a/mk/luapath b/mk/luapath
new file mode 100755
index 0000000..fe5fc9f
--- /dev/null
+++ b/mk/luapath
@@ -0,0 +1,1518 @@
1#!/bin/sh
2#
3# This script is used to derive compiler flags and filesystem paths
4# necessary to utilize Lua, LuaJIT, and particular versions thereof in both
5# simple and mixed installation environments.
6#
7# For usage help information use the -h switch.
8#
9# This script attempts to adhere strictly to POSIX shell specifications. The
10# known non-POSIX features used are the path of the shell at the very first
11# line of this script, the default compiler command name of `cc' instead of
12# `c99', and the use of /dev/urandom for generating a random sandbox
13# directory suffix. All of these can be override. For any other issues
14# please contact the author.
15#
16# WARNING: When searching for a Lua interpreter this script may execute
17# various utilities in an attempt to deduce their fitness and release
18# version. By default this script will search for and execute utilities
19# using the glob patterns luac* and lua*. But this script CANNOT GUARANTEE
20# that executing such utilities, or any other utilities, either wittingly or
21# unwittingly, will not result in your COMPUTER EXPLODING. You have been
22# warned.
23#
24# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
25#
26# Changelog:
27#
28# * 2013-08-02 - Published. Derived from an earlier script, lua.path,
29# written for the cqueues project.
30#
31# * 2013-08-05 - Redirect stdin from /dev/null when probing so we don't
32# freeze if a utility tries to read from stdin.
33#
34# chdir to a read-only directory by default to try to prevent creation
35# of temporary files. These features address the issues of LuaTeX
36# reading from stdin and creating a luatex.out file in the current
37# working directory. By default a directory with a random suffix
38# generated from /dev/urandom is placed in TMPDIR and removed on exit.
39#
40# If CPPFLAGS is empty and no -I options directly specified then set
41# INCDIRS to "/usr/include:/usr/local/include".
42#
43# * 2013-08-07 - Add pkg-config support and refactor header probing to delay
44# recursive searching.
45#
46# * 2013-09-09 - NetBSD's sh gets upset over the noclobber option and
47# redirection to /dev/null, so use append operator. And check $#
48# before iterating over a null parameter set with `do X; ... done`
49# when `set -u` is enabled--it complains about $@ being unset.
50#
51# * 2013-10-22 - Initial ldflags detection.
52#
53# * 2014-01-26 - Migrate CC vendor detection from external script.
54#
55# * 2014-09-29 - Add ldir and cdir modes which print install path by parsing
56# package.path and package.cpath.
57#
58# * 2014-12-18 - Add -e GLOB option.
59#
60# Deprecate ldir and cdir modes.
61#
62# Add package.path and package.cpath to replace ldir and dir modes.
63# Optional arguments to the new modes are preferred install paths,
64# rather than globs for finding the lua utility path (use the new -e
65# option, instead).
66#
67# * 2014-12-19 - Fix pkg-config version matching. The --modversion of
68# the lua package might be stale. For example, it's 5.2.0 on Ubuntu
69# 14.04 even though the Lua release is 5.2.3.
70#
71# Use the interpreter path as a reference point when searching for
72# headers. $(dirname ${LUA_PATH})/../include is a very likely location
73# as bindir and includedir have the same prefix in most installations.
74#
75# * 2015-01-15 - Quote more command names and arguments. Still need to
76# handle space characters in code that employs command substitution. I
77# think we could handle all whitespace characters, including newlines,
78# by using a control character in IFS and using --exec printf "%s\1" {}
79# rather than -print with find(1).
80#
81# * 2015-01-19 - Add fix for LuaJIT's default package.cpath, which tends to
82# hardcode /usr/local/lib/lua/5.1, ordered before the LuaJIT
83# installation prefix.
84#
85# * 2015-07-14 - Add recursive glob function implemented in shell code
86# and use instead of find(1).
87#
88# * 2016-03-18 - Fix bug in tryluac where a continue statement was used
89# instead of return 0.
90#
91# * 2016-03-25 - Support ${CC} values with trailing flags, which invoke
92# the compiler through env(1), or which otherwise are intended to
93# expand as multiple words.
94#
95# OpenBSD 5.8 sh does not suppress strict errors within an eval
96# invoked from an if condition compound-list. Workaround by changing
97# trylua to return 0 on matching failure, like tryluainclude and
98# tryluac do.
99#
100# Undeprecate ldir and cdir. The names are more intuitive and
101# convenient as evidenced by the fact that I keep using them instead
102# of package.path and package.cpath. Try to maintain backwards
103# compatibility by using a simple heuristic to differentiate lua
104# interpreter glob patterns from preferred install directory
105# string.match expressions.
106#
107# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
108#
109# Copyright (C) 2012-2016 William Ahern
110#
111# Permission is hereby granted, free of charge, to any person obtaining a
112# copy of this software and associated documentation files (the "Software"),
113# to deal in the Software without restriction, including without limitation
114# the rights to use, copy, modify, merge, publish, distribute, sublicense,
115# and/or sell copies of the Software, and to permit persons to whom the
116# Software is furnished to do so, subject to the following conditions:
117#
118# The above copyright notice and this permission notice shall be included in
119# all copies or substantial portions of the Software.
120#
121# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
122# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
123# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
124# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
125# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
126# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
127# DEALINGS IN THE SOFTWARE.
128#
129set -e # strict errors
130set -u # don't expand unbound variables
131set -f # disable pathname expansion
132set -C # noclobber
133\unalias -a # no command surprises
134export LC_ALL=C # no locale headaches
135unset IFS # no field splitting surprises
136: ${TMPDIR:=/tmp} # sane TMPDIR
137: ${CC:=cc}
138unset LUA_PATH || true # interferes search for module install directory
139unset LUA_CPATH || true
140
141MYVERSION=20160325
142MYVENDOR="william@25thandClement.com"
143
144
145DEVRANDOM=/dev/urandom
146SANDBOX="${TMPDIR}/${0##*/}-"
147
148CPPDIRS= # -I directories from CPPFLAGS
149INCDIRS=
150LDDIRS= # -L directories from LDFLAGS
151LIBDIRS=
152BINDIRS=
153RECURSE=no
154MAXDEPTH=5 # maximum recursion depth
155SHORTEST= # continue searching until shortest pathname found
156PKGCONFIG= # path to pkg-config, found by `command -v` when -k option invoked
157GLOB= # -e GLOB expression for lua, luac, ldir, and cdir
158
159GLOB_LUA="lua:lua[5-9]*:lua-[5-9]*:luajit*"
160GLOB_LUAC="luac:luac[5-9]*:luac-[5-9]*"
161
162API_MIN=500
163API_MAX=999
164API_VER=
165API_DIR=
166
167JIT_REQ=
168JIT_MIN=20000
169JIT_MAX=99999
170JIT_VER=
171JIT_DIR=
172
173LIBLUA_VER=
174LIBLUA_DIR=
175LIBLUA_LIB=
176
177LIBJIT_VER=
178LIBJIT_DIR=
179LIBJIT_LIB=
180
181LUAC_PATH=
182LUAC_VER=
183
184LUA_PATH=
185LUA_VER=
186
187
188#
189# warn FORMAT [...]
190#
191# Print message to original stderr.
192#
193exec 9>&2
194warn() {
195 printf "%s: %.0s${1}\n" "${0##*/}" "$@" >&9
196}
197
198#
199# panic FORMAT [...]
200#
201# Print message to original stderr, then exit with failure.
202#
203panic() {
204 warn "$@"
205 exit 1
206}
207
208
209#
210# parse CPPFLAGS -I or LDFLAGS -L directories
211#
212xdirs() {
213 OPTC="${1:-I}"
214 DIRS=
215
216 set -- ${2:-}
217
218 while [ $# -gt 0 ]; do
219 case "${1}" in
220 -${OPTC})
221 shift
222
223 if [ -n "${1:-}" ]; then
224 DIRS="${DIRS}${DIRS:+:}${1}"
225 fi
226
227 ;;
228 -${OPTC}*)
229 if [ "${1}" != "-${OPTC}" ]; then
230 DIRS="${DIRS}${DIRS:+:}${1#-${OPTC}}"
231 fi
232
233 ;;
234 esac
235
236 shift
237 done
238
239 printf -- "${DIRS}"
240}
241
242idirs() {
243 xdirs "I" "${1:-}"
244}
245
246ldirs() {
247 xdirs "L" "${1:-}"
248}
249
250# count ":"-delimited substrings
251count() {
252 IFS=:
253 set -- ${1:-}
254 unset IFS
255
256 printf "$#"
257}
258
259# append to ":"-delimited string variable
260append() {
261 NAME=${1}
262 eval VALUE="\${${NAME}}"
263 shift
264
265 IFS=:
266 TMP="$*"
267
268 IFS="\n"
269 read -r "${NAME}" <<-EOF
270 ${VALUE:-}${VALUE:+:}${TMP}
271 EOF
272 unset IFS
273}
274
275#
276# glob PATTERN [MAXDEPTH] [EXEC-COMMAND] [INTERNAL:GLOB-COUNT]
277#
278glob() {
279 glob_N="${4:-0}"
280
281 IFS=
282 set +f
283 for F in ${1}; do
284 [ -e "${F}" ] || continue
285 if eval "${3:-printf '%s\\n'} \"\${F}\""; then
286 glob_N=$((${glob_N} + 1))
287 fi
288 done
289 set -f
290 unset IFS
291
292 if [ "${2-0}" -gt 0 ]; then
293 glob "${1%/*}/*/${1##*/}" "$((${2} - 1))" "${3:-}" "${glob_N}" || :
294 fi
295
296 [ "${glob_N}" -gt 0 ]
297} # glob
298
299
300#
301# runcc [...]
302#
303# Wrapper for invoking ${CC}. Some build system include flags in ${CC},
304# invoke the compiler through env(1), or employ other hacks.
305#
306# TODO: Optionally handle unescaping of words in a manner similar to how
307# ${CC} would be evaluated from a make rule--typically by being passed
308# through system(3).
309#
310runcc() {
311 (unset IFS; exec ${CC} "$@")
312}
313
314
315#
316# evalmacro PATH MACRO [REGEX] [SUBST]
317#
318# PATH Header identifier--#include <PATH>
319# MACRO Macro identifier
320# REGEX Optional regex pattern to match macro evaluation result
321# SUBST Optional replacement expression
322#
323evalmacro() {
324 printf "#include <$1>\n[===[$2]===]\n" \
325 | runcc ${CPPFLAGS:-} -E - 2>>/dev/null \
326 | sed -ne "
327 s/^.*\\[===\\[ *\\(${3:-.*}\\) *\\]===\\].*$/${4:-\\1}/
328 t Found
329 d
330 :Found
331 p
332 q
333 "
334}
335
336
337#
338# testsym PATH NAME
339#
340# Test whether global symbol NAME exists in object file at PATH. Exits with
341# 0 (true) when found, non-0 (false) otherwise.
342#
343testsym() {
344 # NOTE: No -P for OpenBSD nm(1), but the default output format is
345 # close enough. Section types always have a leading and trailing
346 # space. U section type means undefined. On AIX [VWZ] are weak
347 # global symbols. Solaris and OS X have additional symbol types
348 # beyond the canonical POSIX/BSD types, all of which are uppercase
349 # and within [A-T].
350 (nm -Pg ${1} 2>>/dev/null || nm -g 2>>/dev/null) \
351 | sed -ne '/ [A-T] /p' \
352 | grep -q "${2}"
353}
354
355
356tryluainclude() {
357 V="$(evalmacro "${1}" LUA_VERSION_NUM '[0123456789][0123456789]*')"
358 : ${V:=0}
359
360 if [ "${1%/*}" != "${1}" ]; then
361 D="${1%/*}"
362
363 # cleanup after Solaris directory prune trick
364 if [ "${D##*/./}" != "${D}" ]; then
365 D="${D%%/./*}/${D##*/./}"
366 else
367 D="${D%/.}"
368 fi
369 else
370 D=
371 fi
372
373 [ "$V" -gt 0 -a "$V" -ge "${API_VER:-0}" ] || return 0
374
375 [ "$V" -gt "${API_VER:-0}" -o "${#D}" -lt "${#API_DIR}" -o \( "${JIT_REQ}" = "yes" -a "${JIT_VER:-0}" -lt "${JIT_MAX}" \) ] || return 0
376
377 [ "$V" -ge "${API_MIN}" -a "$V" -le "${API_MAX}" ] || return 0
378
379 if [ -n "${JIT_REQ}" ]; then
380 J="$(evalmacro "${1%%lua.h}luajit.h" LUAJIT_VERSION_NUM '[0123456789][0123456789]*')"
381 : ${J:=0}
382
383 if [ "${JIT_REQ}" = "skip" ]; then
384 [ "${J}" -eq 0 ] || return 0
385 elif [ "${JIT_REQ}" = "yes" ]; then
386 [ "$J" -ge "${JIT_VER:-0}" ] || return 0
387 [ "$J" -gt "${JIT_VER:-0}" -o "${#D}" -lt "${#JIT_DIR}" ] || return 0
388 [ "$J" -ge ${JIT_MIN} ] || return 0
389 [ "$J" -le "${JIT_MAX}" ] || return 0
390
391 JIT_VER="$J"
392 JIT_DIR="$D"
393 fi
394 fi
395
396 API_VER="$V"
397 API_DIR="$D"
398}
399
400
401#
402# foundversion
403#
404# true if found the best (maximum) possible version, false otherwise
405#
406foundversion() {
407 if [ "${API_VER:-0}" -lt "${API_MAX}" ]; then
408 return 1
409 fi
410
411 if [ "${JIT_REQ}" = "yes" -a "${JIT_VER:-0}" -lt "${JIT_MAX}" ]; then
412 return 1
413 fi
414
415 if [ "${SHORTEST}" = "yes" ]; then
416 return 1
417 fi
418
419 return 0
420}
421
422
423#
424# luapc
425#
426# wrapper around `pkg-config ... LIB`, where LIB is derived by
427# searching for all libraries with "lua" in the name that have a
428# --modversion equal to the release version printed by ${LUA_PATH} -v.
429#
430LUAPC_LIB=
431
432luapc() {
433 [ -n "${LUA_PATH}" ] || return 0
434
435 [ -n "${PKGCONFIG}" ] || return 0
436
437 # find pkg-config library name
438 if [ -z "${LUAPC_LIB}" ]; then
439 V="$("${LUA_PATH}" -v </dev/null 2>&1 | head -n1 | sed -ne 's/^Lua[^ ]* \([0123456789][0123456789]*\(\.[0123456789][0123456789]*\)*\).*/\1/p')"
440
441 [ -n "${V}" ] || return 0
442
443 V_N=$(mmp2num "${V}")
444
445 for LIB in $("${PKGCONFIG}" --list-all </dev/null 2>>/dev/null | sed -ne 's/^\(lua[^ ]*\).*/\1/p'); do
446 M="$("${PKGCONFIG}" --modversion ${LIB} || true)"
447
448 # break immediately on exact match
449 if [ "${V}" = "${M}" ]; then
450 LUAPC_LIB="${LIB}"
451
452 break
453 fi
454
455 #
456 # NOTE: On Ubuntu 14.04 pkg-config --modversion
457 # lua5.2 prints 5.2.0 even though the release
458 # version is 5.2.3 (what lua5.2 -v prints).
459 #
460 # If the major.minor components match, then
461 # tentatively use that package name.
462 #
463 M_N=$(mmp2num "${M}" 0 0 0)
464
465 if [ "$((${V_N} / 100))" -eq "$((${M_N} / 100))" ]; then
466 LUAPC_LIB="${LIB}"
467 fi
468 done
469
470 [ -n "${LUAPC_LIB}" ] || return 0
471 fi
472
473 ${PKGCONFIG} "$@" "${LUAPC_LIB}" </dev/null 2>>/dev/null || true
474}
475
476
477#
478# findinstalldir package.path|package.cpath [preferred-path ...]
479#
480findinstalldir() {
481 V_DIR=$((${LUA_VER} / 100 % 100)).$((${LUA_VER} % 100))
482
483 if [ "${1}" = "package.cpath" -o "${1}" = "cdir" ]; then
484 ARRAY="package.cpath"
485
486 DIR="$(luapc --variable INSTALL_CMOD)"
487 [ -n "${DIR}" ] && set -- "$@" "${DIR}"
488
489 DIR="$(luapc --variable INSTALL_LIB)"
490 [ -n "${DIR}" ] && set -- "$@" "${DIR}/lua/${V_DIR}"
491
492 DIR="$(luapc --variable libdir)"
493 [ -n "${DIR}" ] && set -- "$@" "${DIR}/lua/${V_DIR}"
494
495 DIR="$(luapc --variable prefix)"
496 [ -n "${DIR}" ] && set -- "$@" "${DIR}/lib/lua/${V_DIR}"
497
498 # LuaJIT installations tend to include
499 # /usr/local/lib/lua/5.1 as one of the first paths, ordered
500 # before the LuaJIT installation prefix, and regardless of
501 # whether there exists a /usr/local/lib/lua/5.1.
502 set -- "$@" "${LUA_PATH}/../../lib/lua/${V_DIR}"
503 set -- "$@" "${LUA_PATH}/../../lib/*/lua/${V_DIR}" # e.g. lib/x86_64-linux-gnu
504 else
505 ARRAY="package.path"
506
507 DIR="$(luapc --variable INSTALL_LMOD)"
508 [ -n "${DIR}" ] && set -- "$@" "${DIR}"
509
510 DIR="$(luapc --variable prefix)"
511 [ -n "${DIR}" ] && set -- "$@" "${DIR}/share/lua/${V_DIR}"
512
513 # See above LuaJIT note. Although the built-in package.path
514 # usually orders the LuaJIT installation prefix first.
515 set -- "$@" "${LUA_PATH}/../../share/lua/${V_DIR}"
516 fi
517
518 shift
519
520 if [ $# -eq 0 ]; then
521 set -- "/nonexistent" # cannot expand empty $@ on some implementations
522 fi
523
524 "${LUA_PATH}" - "$@" <<-EOF
525 --
526 -- actual pkg-config variable on Ubuntu 14.04
527 --
528 -- /usr//share/lua/5.1
529 --
530 local function fixpath(path)
531 local stack = { path:match"^/" and "" or "." }
532
533 for ent in path:gmatch"([^/]+)" do
534 if ent == ".." and #stack > 1 then
535 stack[#stack] = nil
536 elseif ent ~= "." then
537 stack[#stack + 1] = ent
538 end
539 end
540
541 return table.concat(stack, "/")
542 end
543
544 local function topattern(path)
545 if string.match(path, "*") then
546 path = string.gsub(path, "%%", "%%")
547 return string.gsub(path, "*", "[^/]+")
548 end
549 end
550
551 local dirs = { }
552
553 for dir in ${ARRAY}:gmatch"([^;?]+)/" do
554 dir = fixpath(dir)
555
556 if dir ~= "." then
557 dirs[#dirs + 1] = dir
558 end
559 end
560
561 for _, arg in ipairs{ ... } do
562 arg = fixpath(arg)
563
564 local pat = topattern(arg)
565
566 for _, dir in ipairs(dirs) do
567 if arg == dir then
568 print(dir)
569 os.exit(0)
570 elseif pat and string.match(dir, pat) then
571 print(dir)
572 os.exit(0)
573 end
574 end
575 end
576
577 if dirs[1] then
578 print(dirs[1])
579 os.exit(0)
580 else
581 os.exit(1)
582 end
583 EOF
584}
585
586
587#
588# findversion
589#
590findversion() {
591 tryluainclude "lua.h"
592
593 if foundversion; then
594 return 0
595 fi
596
597
598 # iterate through CPPFLAGS to probe different precedence
599 if [ "${API_VER:-0}" -lt "${API_MAX}" ]; then
600 IFS=:
601 set -- ${CPPDIRS}
602 unset IFS
603
604 if [ $# -gt 0 ]; then
605 for D; do
606 tryluainclude "${D}/lua.h"
607
608 if foundversion; then
609 return 0
610 fi
611 done
612 fi
613 fi
614
615
616 if [ -n "${PKGCONFIG}" ]; then
617 PKGFLAGS="$("${PKGCONFIG}" --list-all </dev/null 2>>/dev/null | sed -ne 's/^\(lua[^ ]*\).*/\1/p' | xargs -- ${PKGCONFIG} --cflags 2>>/dev/null | cat)"
618 PKGDIRS="$(idirs "${PKGFLAGS}")"
619
620 IFS=:
621 set -- ${PKGDIRS}
622 unset IFS
623
624 if [ $# -gt 0 ]; then
625 for D; do
626 tryluainclude "${D}/lua.h"
627
628 if foundversion; then
629 return 0
630 fi
631 done
632 fi
633 fi
634
635
636 IFS=:
637 set -- ${INCDIRS}
638 unset IFS
639
640 if [ $# -gt 0 ]; then
641 for D; do
642 tryluainclude "${D}/lua.h"
643
644 if foundversion; then
645 return 0
646 fi
647 done
648 fi
649
650
651 if [ "${RECURSE}" != "yes" ]; then
652 [ "${API_VER:-0}" -gt 0 ]
653 return $?
654 fi
655
656
657 # recurse into CPPDIRS
658 IFS=:
659 set -- ${CPPDIRS}
660 unset IFS
661
662 if [ $# -gt 0 ]; then
663 for D; do
664 glob "${D}/lua.h" "${MAXDEPTH}" tryluainclude || :
665
666 if foundversion; then
667 return 0
668 fi
669 done
670 fi
671
672
673 # recurse into INCDIRS
674 IFS=:
675 set -- ${INCDIRS}
676 unset IFS
677
678 if [ $# -gt 0 ]; then
679 for D; do
680 glob "${D}/lua.h" "${MAXDEPTH}" tryluainclude || :
681
682 if foundversion; then
683 return 0
684 fi
685 done
686 fi
687
688
689 # if we can find the lua interpreter, use it as a reference for
690 # header locations.
691 if findlua; then
692 D="${LUA_PATH%/*}"
693 D="${D%/*}/include"
694
695 if [ -d "${D}" ]; then
696 glob "${D}/lua.h" "${MAXDEPTH}" tryluainclude || :
697
698 if foundversion; then
699 return 0
700 fi
701 fi
702 fi
703
704 [ "${API_VER:-0}" -gt 0 ]
705}
706
707
708#
709# Unlike API version checking, this is less likely to be accurately forward
710# compatible.
711#
712trylib() {
713 testsym "${1}" "lua_newstate" || return 1
714
715 # exclude C++
716 [ "${1#*++}" = "${1}" ] || return 1
717
718 V=0
719 J=0
720 D=
721 F="${1##*/}"
722 L=
723
724 if [ "${1%/*}" != "${1}" ]; then
725 D="${1%/*}"
726
727 # cleanup after Solaris directory prune trick
728 if [ "${D##*/./}" != "${D}" ]; then
729 D="${D%%/./*}/${D##*/./}"
730 else
731 D="${D%/.}"
732 fi
733 fi
734
735 L="${F#lib}"
736 L="${L%.so}"
737 L="${L%.a}"
738 L="${L%.dylib}"
739
740
741 # FIXME: need more versioning tests
742 if testsym "${1}" "lua_getfenv"; then
743 V=501
744 elif testsym "${1}" "lua_yieldk"; then
745 if testsym "${1}" "lua_getctx"; then
746 V=502
747 else
748 V=503
749 fi
750 else
751 return 1
752 fi
753
754 [ "$V" -gt 0 -a "$V" -ge "${LIBLUA_VER:-0}" ] || return 1
755
756 [ "$V" -gt "${LIBLUA_VER:-0}" -o "${#D}" -lt "${#LIBLUA_DIR}" -o \( "${JIT_REQ}" = "yes" -a "${LIBJIT_VER:-0}" -lt "${JIT_MAX}" \) ] || return 1
757
758 [ "$V" -ge "${API_MIN}" -a "$V" -le "${API_MAX}" ] || return 1
759
760
761 if [ -n "${JIT_REQ}" ]; then
762 # FIXME: need more versioning tests
763 if testsym "${1}" "luaopen_jit"; then
764 J=20000
765 fi
766
767 if [ "${JIT_REQ}" = "skip" ]; then
768 [ "${J}" -eq 0 ] || return 1
769 elif [ "${JIT_REQ}" = "yes" ]; then
770 [ "$J" -ge "${LIBJIT_VER:-0}" ] || return 1
771 [ "$J" -gt "${LIBJIT_VER:-0}" -o "${#D}" -lt "${#LIBJIT_DIR}" ] || return 1
772 [ "$J" -ge ${JIT_MIN} ] || return 1
773 [ "$J" -le "${JIT_MAX}" ] || return 1
774
775 LIBJIT_VER="$J"
776 LIBJIT_DIR="$D"
777 LIBJIT_LIB="$L"
778 fi
779 fi
780
781 LIBLUA_VER="$V"
782 LIBLUA_DIR="$D"
783 LIBLUA_LIB="$L"
784}
785
786
787#
788# foundlib
789#
790# true if found the best (maximum) possible version, false otherwise
791#
792foundlib() {
793 if [ "${LIBLUA_VER:-0}" -lt "${API_MAX}" ]; then
794 return 1
795 fi
796
797 if [ "${JIT_REQ}" = "yes" -a "${LIBJIT_VER:-0}" -lt "${JIT_MAX}" ]; then
798 return 1
799 fi
800
801 if [ "${SHORTEST}" = "yes" ]; then
802 return 1
803 fi
804
805 return 0
806}
807
808
809findlib() {
810 if [ -n "${PKGCONFIG}" ]; then
811 PKGFLAGS="$("${PKGCONFIG}" --list-all </dev/null 2>>/dev/null | sed -ne 's/^\(lua[^ ]*\).*/\1/p' | xargs -- ${PKGCONFIG} --libs 2>>/dev/null | cat)"
812 PKGDIRS="$(ldirs "${PKGFLAGS}")"
813 PKGDIRS="${PKGDIRS}${PKGDIRS:+:}/lib:/usr/lib:/usr/local/lib"
814 NUMDIRS="$(count "${PKGDIRS}")"
815 PKGLIBS="$(xdirs "l" "${PKGFLAGS}")"
816 NUMLIBS="$(count "${PKGLIBS}")"
817 ALLDIRS="${PKGDIRS}${PKGLIBS:+:}${PKGLIBS}"
818
819 IFS=:
820 set -- ${ALLDIRS}
821 unset IFS
822
823 I=1
824 while [ $I -le ${NUMDIRS} ]; do
825 K=$((1 + ${NUMDIRS}))
826 while [ $K -le $# ]; do
827 findlib_L=$(eval "printf \${$I}")
828 findlib_l=$(eval "printf \${$K}")
829
830 #printf -- "I=$I K=$K $findlib_L/lib$findlib_l*.*\n"
831
832 glob "${findlib_L}/lib${findlib_l}*.*" 0 trylib || :
833
834 if foundlib; then
835 return 0;
836 fi
837
838 glob "${findlib_L}/lib${findlib_l}*.*" ${MAXDEPTH} trylib || :
839
840 if foundlib; then
841 return 0;
842 fi
843
844 K=$(($K + 1))
845 done
846 I=$(($I + 1))
847 done
848 fi
849
850 ALLDIRS="${LDDIRS}${LDDIRS:+:}${LIBDIRS}"
851
852 IFS=:
853 set -- ${ALLDIRS}
854 unset IFS
855
856 for findlib_D; do
857 glob "${findlib_D}/liblua*.*" "${MAXDEPTH}" trylib || :
858
859 if foundlib; then
860 return 0
861 fi
862 done
863
864 # if we can find the lua interpreter, use it as a reference for
865 # library locations.
866 if findlua; then
867 findlib_D="${LUA_PATH%/*}"
868 findlib_D="${findlib_D%/*}/lib"
869
870 if [ -d "${findlib_D}" ]; then
871 glob "${findlib_D}/liblua*.*" "${MAXDEPTH}" trylib || :
872
873 if foundlib; then
874 return 0
875 fi
876 fi
877 fi
878}
879
880
881# check setuid and setgid mode
882safeperm() {
883 [ -f "$1" -a ! -u "$1" -a ! -g "$1" ]
884}
885
886
887tryluac() {
888 tryluac_F="${1}"
889
890 [ -x "${tryluac_F}" ] && safeperm "${tryluac_F}" || return 0
891
892 tryluac_V="$("${tryluac_F}" -v </dev/null 2>&1 | head -n1 | sed -ne 's/^Lua \([0123456789][0123456789]*\.[0123456789][0123456789]*\).*/\1/p')"
893 : ${tryluac_V:=0}
894 tryluac_V="$((${tryluac_V%%.*} * 100 + ${tryluac_V##*.} % 100))"
895
896 [ "${tryluac_V}" -gt 0 -a "${tryluac_V}" -ge "${LUAC_VER:-0}" ] || return 0
897
898 [ "${tryluac_V}" -gt "${LUAC_VER:-0}" -o "${#tryluac_F}" -lt "${#LUAC_PATH}" ] || return 0
899
900 [ "${tryluac_V}" -ge "${API_MIN}" -a "${tryluac_V}" -le "${API_MAX}" ] || return 0
901
902 printf "return true" 2>>/dev/null | ${tryluac_F} -p - </dev/null >>/dev/null 2>&1 || return 0
903
904 LUAC_PATH="${tryluac_F}"
905 LUAC_VER="${tryluac_V}"
906}
907
908#
909# foundluac
910#
911# true if found the best (maximum) possible version, false otherwise
912#
913foundluac() {
914 if [ "${LUAC_VER:-0}" -lt "${API_MAX}" ]; then
915 return 1
916 fi
917
918 if [ "${SHORTEST}" = "yes" ]; then
919 return 1
920 fi
921
922 return 0
923}
924
925findluac() {
926 if [ $# -eq 0 ]; then
927 IFS=:
928 set -- ${GLOB:-${GLOB_LUAC}}
929 unset IFS
930 fi
931
932 for findluac_G; do
933 IFS=:
934 for findluac_D in ${PATH}; do
935 unset IFS
936
937 glob "${findluac_D}/${findluac_G}" 0 tryluac || :
938
939 if foundluac; then
940 return 0
941 fi
942 done
943
944 IFS=:
945 for findluac_D in ${BINDIRS}; do
946 unset IFS
947
948 glob "${findluac_D}/${findluac_G}" "${MAXDEPTH}" tryluac || :
949
950 if foundluac; then
951 return 0
952 fi
953 done
954
955 unset IFS
956 done
957
958 [ "${LUAC_VER:-0}" -gt 0 ] && [ "${#LUAC_PATH}" -gt 0 ]
959}
960
961
962isinteger() {
963 I="${1}"
964
965 [ "${#I}" -gt 0 ] || return 1
966
967 while [ "${#I}" -gt 0 ]; do
968 if [ "${I##[0123456789]}" = "${I}" ]; then
969 return 1
970 fi
971
972 I=${I##[0123456789]}
973 done
974
975 return 0
976}
977
978
979checkints() {
980 while [ $# -gt 0 ]; do
981 if ! isinteger "${1}"; then
982 warn "%s: not a number" "${1}"
983 return 1
984 fi
985
986 shift
987 done
988}
989
990
991# Only major.minor for matching LUA_VERSION_NUM in lua.h. Also, _VERSION
992# only includes major.minor.
993lua2num() {
994 M=0
995 m="${2:-0}"
996
997 IFS=.
998 set -- ${1}
999 unset IFS
1000
1001 M=${1:-${M}}
1002 m=${2:-${m}}
1003
1004 checkints $M $m
1005
1006 printf "$((${M} * 100 + ${m}))\n"
1007}
1008
1009
1010# All major.minor.patch for matching LUAJIT_VERSION_NUM in luajit.h.
1011jit2num() {
1012 M=0
1013 m="${2:-0}"
1014 p="${3:-0}"
1015
1016 IFS=.
1017 set -- ${1}
1018 unset IFS
1019
1020 M=${1:-${M}}
1021 m=${2:-${m}}
1022 p=${3:-${p}}
1023
1024 checkints $M $m $p
1025
1026 printf "$((${M} * 10000 + ${m} * 100 + ${p}))\n"
1027}
1028
1029
1030mmp2num() {
1031 M="${2:-0}"
1032 m="${3:-0}"
1033 p="${4:-0}"
1034
1035 IFS=".+-_"
1036 set -- ${1}
1037 unset IFS
1038
1039 if isinteger "${1:-}"; then
1040 M=${1}
1041 fi
1042
1043 if isinteger "${2:-}"; then
1044 m=${2}
1045 fi
1046
1047 if isinteger "${3:-}"; then
1048 p=${3}
1049 fi
1050
1051 checkints $M $m $p
1052
1053 printf "$((${M} * 10000 + ${m} * 100 + ${p}))\n"
1054}
1055
1056
1057trylua() {
1058 trylua_F="${1}"
1059 [ -x "${trylua_F}" ] && safeperm "${trylua_F}" || return 0
1060
1061 trylua_V="$("${trylua_F}" -e 'print(string.match(_VERSION, [[[%d.]+]]))' </dev/null 2>>/dev/null | head -n1 | sed -ne 's/^\([0123456789][0123456789]*\.[0123456789][0123456789]*\).*/\1/p')"
1062 : ${trylua_V:=0}
1063 trylua_V="$((${trylua_V%%.*} * 100 + ${trylua_V##*.} % 100))"
1064
1065 [ "${trylua_V}" -gt 0 -a "${trylua_V}" -ge "${LUA_VER:-0}" ] || return 0
1066
1067 [ "${trylua_V}" -gt "${LUA_VER:-0}" -o "${#trylua_F}" -lt "${#LUA_PATH}" ] || return 0
1068
1069 [ "${trylua_V}" -ge "${API_MIN}" -a "${trylua_V}" -le "${API_MAX}" ] || return 0
1070
1071 if [ -n "${JIT_REQ}" ]; then
1072 J="$("${trylua_F}" -v </dev/null 2>&1 | head -n1 | sed -ne 's/^LuaJIT \([0123456789][0123456789]*\.[0123456789][0123456789]*\.[0123456789][0123456789]*\).*/\1/p')"
1073 J="$(jit2num ${J:-0})"
1074
1075 if [ "${JIT_REQ}" = "skip" ]; then
1076 [ "${J}" -eq 0 ] || return 0
1077 elif [ "${JIT_REQ}" = "yes" ]; then
1078 [ "${J}" -gt 0 ] || return 0
1079 [ "${J}" -ge "${JIT_MIN}" ] || return 0
1080 [ "${J}" -le "${JIT_MAX}" ] || return 0
1081 fi
1082 fi
1083
1084 LUA_PATH="${trylua_F}"
1085 LUA_VER="${trylua_V}"
1086}
1087
1088#
1089# foundlua
1090#
1091# true if found the best (maximum) possible version, false otherwise
1092#
1093foundlua() {
1094 if [ "${LUA_VER:-0}" -lt "${API_MAX}" ]; then
1095 return 1
1096 fi
1097
1098 if [ "${SHORTEST}" = "yes" ]; then
1099 return 1
1100 fi
1101
1102 return 0
1103}
1104
1105findlua() {
1106 if [ $# -eq 0 ]; then
1107 IFS=:
1108 set -- ${GLOB:-${GLOB_LUA}}
1109 unset IFS
1110 fi
1111
1112 for findlua_G; do
1113 IFS=:
1114 for findlua_D in ${PATH}; do
1115 unset IFS
1116
1117 glob "${findlua_D}/${findlua_G}" 0 trylua || :
1118
1119 if foundlua; then
1120 return 0
1121 fi
1122 done
1123
1124 IFS=:
1125 for findlua_D in ${BINDIRS}; do
1126 unset IFS
1127
1128 glob "${findlua_D}/${findlua_G}" "${MAXDEPTH}" trylua || :
1129
1130 if foundlua; then
1131 return 0
1132 fi
1133 done
1134
1135 unset IFS
1136 done
1137
1138 [ "${LUA_VER:-0}" -gt 0 ] && [ "${#LUA_PATH}" -gt 0 ]
1139}
1140
1141
1142ccname() {
1143 runcc -E - <<-EOF | awk '/sunpro/||/clang/||/gcc/||/other/{ print $1; exit; }'
1144 #if defined __SUNPRO_C
1145 sunpro
1146 #elif defined __clang__
1147 clang
1148 #elif defined __GNUC__
1149 gcc
1150 #else
1151 other
1152 #endif
1153 EOF
1154}
1155
1156
1157usage() {
1158 cat <<-EOF
1159 usage: ${0##*/} [-I:L:P:d:De:krm:xsv:j:JVh] cppflags|version|lua|luac|...
1160 -I PATH additional search directory for includes
1161 -L PATH additional search directory for libraries
1162 -P PATH additional search directory for binaries
1163 -d PATH use PATH as sandbox directory; a random 16 byte suffix is
1164 generated from /dev/urandom and the directory removed on exit
1165 unless a trailing "/" is present
1166 (default sandbox is \$TMPDIR/${0##*/}-XXXXXXXXXXXXXXXX)
1167 -D do not create a sandbox
1168 -e GLOB glob pattern for finding utilities (lua, luac, etc)
1169 -k query pkg-config if available
1170 -r recursively search directories
1171 -m MAXDEPTH limit recursion to MAXDEPTH
1172 -s find shortest pathname, otherwise print first best match
1173 -v VERSION require specific Lua version or range
1174 (e.g. "5.1" or "5.1-5.2")
1175 -j VERSION require specific LuaJIT version or range
1176 (e.g. "2.0.1"; empty ranges like "-" force any LuaJIT version)
1177 -J skip LuaJIT if encountered
1178 -V print this script's version information
1179 -h print this usage message
1180
1181 cppflags print derived additional CPPFLAGS necessary
1182 version print derived Lua API version from cppflags discovery
1183 ldflags print derived additional LDFLAGS necessary (TODO)
1184 libs print derived additional LIBS necessary (TODO)
1185 libversion print derived Lua API version from ldflags/libs discovery
1186 luac print path to luac utility ($(printf "${GLOB_LUA}" | tr ':' ' '))
1187 lua print path to lua interpreter ($(printf "${GLOB_LUAC}" | tr ':' ' '))
1188 package.path print preferred module install path
1189 package.cpath print preferred C module install path
1190 ccname print CC name (e.g. sunpro, clang, gcc)
1191 evalmacro run internal macro evaluator for debugging
1192 testsym run internal library symbol reader for debugging
1193
1194 This utility is used to derive compiler flags and filesystem paths
1195 necessary to utilize Lua, LuaJIT, and particular versions thereof.
1196 On success it prints the requested information and exits with 0,
1197 otherwise it fails with an exit status of 1.
1198
1199 Note that cppflags may not print anything if no additional flags are
1200 required to compile against the requested API version.
1201
1202 When searching, the highest Lua version is preferred. Searching
1203 stops once the highest version in the allowable range is found
1204 unless the -s flag is specified.
1205
1206 LuaJIT is treated like any other Lua installation. If an explicit
1207 LuaJIT version or range is specified, then only LuaJIT installations
1208 will match. To exclude LuaJIT entirely use the -J switch.
1209
1210 This utility processes the environment variables CC, CPPFLAGS,
1211 LDFLAGS, and PATH if present. If recursion is requested, then
1212 directories specified in CPPFLAGS, LDFLAGS, and PATH are also
1213 recursed.
1214
1215 If the environment variable CPPFLAGS is empty and no -I options are
1216 specified directly, then /usr/include and /usr/local/include are
1217 used when probing for cppflags and API version.
1218
1219 Report bugs to <william@25thandClement.com>
1220 EOF
1221}
1222
1223
1224version() {
1225 cat <<-EOF
1226 luapath $MYVERSION
1227 vendor $MYVENDOR
1228 release $MYVERSION
1229 EOF
1230}
1231
1232
1233while getopts I:L:P:d:De:krm:xsv:j:JVh OPT; do
1234 case "${OPT}" in
1235 I)
1236 INCDIRS="${INCDIRS:-}${INCDIRS:+:}${OPTARG}"
1237 ;;
1238 L)
1239 LIBDIRS="${LIBDIRS:-}${LIBDIRS:+:}${OPTARG}"
1240 ;;
1241 P)
1242 BINDIRS="${BINDIRS:-}${BINDIRS:+:}${OPTARG}"
1243 ;;
1244 d)
1245 SANDBOX="${OPTARG}"
1246 ;;
1247 D)
1248 SANDBOX=
1249 ;;
1250 e)
1251 GLOB="${GLOB:-}${GLOB:+:}${OPTARG}"
1252 ;;
1253 k)
1254 PKGCONFIG="$(command -v pkg-config || true)"
1255 ;;
1256 r)
1257 RECURSE=yes
1258 ;;
1259 m)
1260 if [ "${#OPTARG}" -eq 0 -o -n "${OPTARG##[0123456789]}" ]; then
1261 panic "%s: invalid maxdepth" "${OPTARG}"
1262 fi
1263
1264 MAXDEPTH="${OPTARG}"
1265 ;;
1266 x)
1267 #
1268 # NOTE: This option was
1269 #
1270 # -x do not cross device mounts when recursing
1271 #
1272 # but is currently unsupported as our built-in glob function
1273 # does not implement this functionality. Previously this
1274 # option caused -xdev to be added to invocations of find(1).
1275 ;;
1276 s)
1277 SHORTEST=yes
1278 ;;
1279 v)
1280 MIN=${OPTARG%%[,:-]*}
1281 MAX=${OPTARG##*[,:-]}
1282
1283 API_MIN="$(lua2num ${MIN:-0} 0)"
1284 API_MAX="$(lua2num ${MAX:-99} 99)"
1285
1286 if [ "${API_MIN}" -gt "${API_MAX}" ]; then
1287 panic "%s: invalid version range" "${OPTARG}"
1288 fi
1289
1290 ;;
1291 j)
1292 MIN=${OPTARG%%[,:-]*}
1293 MAX=${OPTARG##*[,:-]}
1294
1295 JIT_MIN="$(jit2num ${MIN:-0} 0 0)"
1296 JIT_MAX="$(jit2num ${MAX:-99} 99 99)"
1297
1298 if [ "${JIT_MIN}" -gt "${JIT_MAX}" ]; then
1299 panic "%s: invalid version range" "${OPTARG}"
1300 fi
1301
1302 JIT_REQ=yes
1303 ;;
1304 J)
1305 JIT_REQ=skip
1306 ;;
1307 V)
1308 version
1309 exit 0
1310 ;;
1311 h)
1312 usage
1313 exit 0
1314 ;;
1315 *)
1316 usage >&2
1317 exit 1
1318 ;;
1319 esac
1320done
1321
1322shift $(($OPTIND - 1))
1323
1324
1325[ "${RECURSE}" = "yes" ] || MAXDEPTH=0
1326
1327
1328for U in "${CC}" grep od rm rmdir sed xargs; do
1329 ! command -v "${U}" >>/dev/null 2>&1 || continue
1330
1331 # ${CC} might have trailing flags or invoke the compiler through env
1332 ! command -v "${U%% *}" >>/dev/null 2>&1 || continue
1333
1334 warn "%s: command not found" "${U}"
1335done
1336
1337
1338if [ -n "${SANDBOX}" ]; then
1339 if [ "${SANDBOX}" = "${SANDBOX%/}" ]; then
1340 if [ ! -c "${DEVRANDOM}" ]; then
1341 # TODO: expand DEVRANDOM into set of different possibilities to check
1342 panic "%s: no character random device available" "${DEVRANDOM}"
1343 fi
1344
1345 TMP="${SANDBOX}$(od -An -N8 -tx1 < ${DEVRANDOM} 2>>/dev/null | tr -d ' ')"
1346
1347 if [ ${#TMP} -ne $((${#SANDBOX} + 16)) ]; then
1348 panic "%s: unable to generate random suffix" "${SANDBOX}"
1349 fi
1350
1351 SANDBOX="${TMP}"
1352
1353 trap "cd .. && rm -f -- ${SANDBOX}/* && rmdir -- ${SANDBOX}" EXIT
1354 fi
1355
1356 if [ ! -d "${SANDBOX}" ]; then
1357 OMASK="$(umask)"
1358 umask 0777
1359 mkdir -m0550 -- "${SANDBOX}" || exit 1
1360 umask ${OMASK}
1361 fi
1362
1363 cd ${SANDBOX}
1364fi
1365
1366
1367CPPDIRS="$(idirs "${CPPFLAGS:-}")"
1368
1369if [ -z "${CPPDIRS}" -a -z "${INCDIRS}" ]; then
1370 INCDIRS="/usr/include:/usr/local/include"
1371fi
1372
1373
1374LDDIRS="$(ldirs "${LDFLAGS:-}")"
1375
1376if [ -z "${LDDIRS}" -a -z "${LIBDIRS}" ]; then
1377 LIBDIRS="/lib:/usr/lib:/usr/local/lib"
1378fi
1379
1380
1381case "${1:-}" in
1382cppflags)
1383 findversion || exit 1
1384
1385 [ "${API_VER:-0}" -gt 0 ] || exit 1
1386
1387 [ -z "${API_DIR:-}" ] || printf -- "-I${API_DIR}\n"
1388
1389 ;;
1390version)
1391 findversion || exit 1
1392
1393 printf "$(((${API_VER} / 100) % 100)).$((($API_VER) % 100))\n"
1394
1395 ;;
1396ldflags)
1397 findlib
1398
1399 [ "${LIBLUA_VER:-0}" -gt 0 ] || exit 1
1400
1401 if [ "${#LIBLUA_DIR}" -gt 0 ]; then
1402 printf -- "-L%s\n" "${LIBLUA_DIR}"
1403 fi
1404
1405 ;;
1406libs)
1407 findlib
1408
1409 [ "${LIBLUA_VER:-0}" -gt 0 ] || exit 1
1410
1411 printf -- "-l%s\n" "${LIBLUA_LIB}"
1412
1413 ;;
1414libv*)
1415 findlib
1416
1417 [ "${LIBLUA_VER:-0}" -gt 0 ] || exit 1
1418
1419 printf "$(((${LIBLUA_VER} / 100) % 100)).$((($LIBLUA_VER) % 100))\n"
1420
1421 ;;
1422luac)
1423 shift
1424
1425 if [ $# -gt 0 ]; then
1426 append GLOB $*
1427 fi
1428
1429 findluac || exit 1
1430
1431 printf -- "${LUAC_PATH}\n"
1432
1433 ;;
1434lua)
1435 shift
1436
1437 if [ $# -gt 0 ]; then
1438 append GLOB $*
1439 fi
1440
1441 findlua || exit 1
1442
1443 printf -- "${LUA_PATH}\n"
1444
1445 ;;
1446ldir|cdir)
1447 #
1448 # ldir and cdir were deprecated on 2014-12-18. On 2016-03-25 they
1449 # were revived because their names are more intuitive than
1450 # package.path and package.cpath. For now try to support the
1451 # semantics of both by assuming interpreter glob patterns only match
1452 # file names, while preferred install directory string.match
1453 # expressions have directory components.
1454 #
1455 if true; then
1456 MODE="${1}"
1457
1458 # move command to end; rotates to ${1} after loop
1459 set -- "$@" "${1}"
1460 shift
1461
1462 cdir_I=0
1463 cdir_N="$(($# - 1))"
1464 while [ "${cdir_I}" -lt "${cdir_N}" ]; do
1465 if [ "${1#*/}" = "${1}" ]; then
1466 append GLOB "${1}"
1467 warn "%s: passing glob patterns to %s is deprecated" "${1}" "${MODE}"
1468 else
1469 set -- "$@" "${1}"
1470 fi
1471 shift
1472 cdir_I=$((${cdir_I} + 1))
1473 done
1474 fi
1475
1476 findlua || exit 1
1477
1478 findinstalldir "$@" || exit 1
1479
1480 ;;
1481package.path|package.cpath)
1482 findlua || exit 1
1483
1484 findinstalldir "$@" || exit 1
1485
1486 ;;
1487ccname)
1488 ccname
1489
1490 ;;
1491evalmacro)
1492 shift
1493
1494 evalmacro $*
1495 ;;
1496testsym)
1497 shift
1498
1499 if testsym $*; then
1500 printf "found\n"
1501 exit 0
1502 else
1503 printf "not found\n"
1504 exit 1
1505 fi
1506 ;;
1507*)
1508 if [ -n "${1:-}" ]; then
1509 warn "%s: unknown command" "${1}"
1510 else
1511 warn "no command specified"
1512 fi
1513
1514 exit 1
1515 ;;
1516esac
1517
1518exit 0