#! /bin/sh

# click-buildtool -- build tools for Click
# Eddie Kohler
#
# Copyright (c) 2000-2001 Massachusetts Institute of Technology
# Copyright (c) 2000-2001 Mazu Networks, Inc.
# Copyright (c) 2001-2002 International Computer Science Institute
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the "Software"),
# to deal in the Software without restriction, subject to the conditions
# listed in the Click LICENSE file. These conditions include: you must
# preserve this copyright notice, and you cannot mention the copyright
# holders in advertising related to the Software without their permission.
# The Software is provided WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED. This
# notice is a summary of the Click LICENSE file; the license in that file is
# legally binding.

verbose=""
elem2=""

# find a good version of awk
if test -x /usr/bin/gawk; then
    awk=gawk
elif test -x /usr/bin/nawk; then
    awk=nawk
else
    awk=awk
fi



findelem_usage () {
    echo "Usage: click-buildtool findelem [-a] [-V] [-p PREFIX] < [FILES AND DIRECTORIES]
Try \`click-buildtool findelem --help' for more information." 1>&2
    exit 1
}

findelem_elementmap_provisions () {
    elementmap="$1"
    $awk '/^<elementmap( .* | )provides="([^"]*)"/ {
  sub(/.* provides="/, "", $0);
  sub(/".*/, "", $0);
  split($0, d, / +/);
  for (j in d) deps[d[j]] = 1;
}
/^<entry( .* | )provides="([^"]*)"/ {
  sub(/.* provides="/, "", $0);
  sub(/".*/, "", $0);
  split($0, d, / +/);
  for (j in d) deps[d[j]] = 1;
}
/^<entry( .* | )name="([^"]*)"/ {
  sub(/.* name="/, "", $0);
  sub(/".*/, "", $0);
  deps[$0] = 1;
}
END {
  # delete references to drivers
  delete deps["userlevel"]; delete deps["linuxmodule"]; 
  delete deps["bsdmodule"]; delete deps["ns"];
  for (j in deps) print j;
}' <"$elementmap"
}

findelements () {
    prefix=""
    all=
    provisions=""
    filenames=""
    standards=''
    unprovisions='false 0'
    while [ x"$1" != x ]; do
    case $1 in
    -S|--s|--st|--sta|--stan|--stand|--standa|--standar|--standard|--standards)
	standards=1; shift 1;;
    -p|--pre|--pref|--prefi|--prefix)
	if test $# -lt 2; then findelem_usage; fi
	shift 1; prefix="$1/"; shift 1;;
    -p*)
	prefix=`echo "$1" | sed 's/^-p//'`/; shift 1;;
    --pre=*|--pref=*|--prefi=*|--prefix=*)
	prefix=`echo "$1" | sed 's/^[^=]*=//'`/; shift 1;;
    -f|--filenames)
	filenames=f; shift 1;;
    -F|--filename-|--filename-p|--filename-pa|--filename-pai|--filename-pair|--filename-pairs)
	filenames=F; shift 1;;
    -V|--verb|--verbo|--verbos|--verbose)
	verbose=1; shift 1;;
    -a|--a|--al|--all)
	all=1; shift 1;;
    -r|--pro|--prov|--provi|--provid|--provide)
	if test $# -lt 2; then findelem_usage; fi
	shift 1; provisions="$1
$provisions"; shift 1;;
    -r*)
	provisions=`echo "$1" | sed 's/^-r//'`"
$provisions"; shift 1;;
    --pro=*|--prov=*|--provi=*|--provid=*|--provide=*)
	provisions=`echo "$1" | sed 's/^[^=]*=//'`"
$provisions"; shift 1;;
    -x|--u|--un|--unp|--unpr|--unpro|--unprov|--unprovi|--unprovid|--unprovide)
	if test $# -lt 2; then findelem_usage; fi
	shift 1; unprovisions="$1
$unprovisions"; shift 1;;
    -x*)
	unprovisions=`echo "$1" | sed 's/^-x//'`"
$unprovisions"; shift 1;;
    --u=*|--un=*|--unp=*|--unpr=*|--unpro=*|--unprov=*|--unprovi=*|--unprovid=*|--unprovide=*)
	unprovisions=`echo "$1" | sed 's/^[^=]*=//'`"
$unprovisions"; shift 1;;
    -e|--e|--el|--ele|--elem|--eleme|--elemen|--element|--elementm|--elementma|--elementmap)
	if test $# -lt 2; then findelem_usage; fi
	shift 1; provisions=`findelem_elementmap_provisions $1`"
$provisions"; shift 1;;
    -e*)
	emap=`echo "$1" | sed 's/^-e//'`
	provisions=`findelem_elementmap_provisions $emap`"
$provisions"; shift 1;;
    --e=*|--el=*|--ele=*|--elem=*|--eleme=*|--elemen=*|--element=*|--elementm=*|--elementma=*|--elementmap=*)
	emap=`echo "$1" | sed 's/^[^=]*=//'`
	provisions=`findelem_elementmap_provisions $emap`"
$provisions"; shift 1;;
    -h|--h|--he|--hel|--help)
	cat <<'EOF' 1>&2
`Click-buildtool findelem' locates valid Click element source code. It starts
with a collection of source code, then eliminates files whose requirements
are not available until reaching a stable set of sources. It expects a list of
files and directories on standard input. Directories are searched for .cc/.c
source files. Only files containing EXPORT_ELEMENT() or ELEMENT_PROVIDES() are
considered. The initial list of available requirements is the list of
requirements specified with `-r', plus the list of EXPORT_ELEMENT() and
ELEMENT_PROVIDES() keywords.

Usage: click-buildtool findelem [-a] [-V] [-p PREFIX] < [FILES AND DIRECTORIES]

Options:
  -a, --all                  Include all subdirectories of `elements' rather
                             than reading standard input, and pretend all
                             requirements are available (except for `-x').
  -V, --verbose              Print more information about dependency checking.
  -p, --prefix PREFIX        Preprend PREFIX to every file and/or directory.
  -r, --provide REQ          Mark requirement(s) REQ as available.
  -e, --elementmap EMAP      Mark requirement(s) from EMAP as available.
  -S, --standards            Mark standard elements as available.
  -x, --unprovide REQ        Mark requirement(s) REQ as unavailable.
  -f, --filenames            Output filenames only.
  -F, --filename-pairs       Output "sourcefile:headerfile" pairs for elements.
  -h, --help                 Print this message and exit.

Report bugs to <click@pdos.lcs.mit.edu>.
EOF
	exit 0;;
    *)
	findelem_usage;;
    esac
    done

    if test -n "$verbose" -a -n "$prefix"; then
	echo "Prefix: $prefix" 1>&2
    fi

    # add standards to provisions if necessary
    if test "x$standards" != x; then
	provisions="$provisions AddressInfo AlignmentInfo DriverManager ErrorElement PortInfo ScheduleInfo Storage"
    fi

    # expand provisions and unprovisions: require one per line
    provisions=`echo "$provisions" | tr -s ' \011\015\014\013' '\012'`
    unprovisions=`echo "$unprovisions" | tr -s ' \011\015\014\013' '\012'`
    if test -n "$verbose" -a -n "$provisions"; then
	echo 1>&2
	echo "Provisions: $provisions" 1>&2
    fi
    if test -n "$verbose" -a -n "$unprovisions"; then
	echo 1>&2
	echo "Unprovisions: $unprovisions" 1>&2
    fi

    # expand list of files
    if test -n "$all"; then
	first_files=`cd ${prefix}elements >/dev/null && ls`
	bad_first_files=`echo "$first_files
$unprovisions" | sort | uniq -d`
	first_files=`echo "$first_files
$bad_first_files" | sort | uniq -u`
    else
	first_files=`cat`
    fi

    files=""
    for i in $first_files; do
	pprefix="$prefix"
	if test -d "${prefix}elements/$i" && echo "$i" | grep -v '^\.' >/dev/null; then
	    pprefix="${prefix}elements/"
	fi
	if test -d "${pprefix}$i"; then
	    files="$files
"`find ${pprefix}$i -follow \( -name \*.cc -o -name \*.c \) -print | grep -v '/[.,][^/]*$'`
	elif test -r "${pprefix}$i"; then
	    files="$files
${pprefix}$i"
	fi
    done
    files=`echo "$files" | sort | uniq | grep .`

    # die if no files
    if test -z "$files"; then
	echo "no files found" 1>&2
	exit 1
    fi

    # if `$all', then accept all dependencies except the unprovisions
    dep_test='<='
    if test -n "$all"; then
	dep_test='<'
    fi

    # check dependencies: generate a list of bad files, then remove those files
    # from the list of good files

    # first remove files that provide an unprovision
    awk_exports=`echo "$unprovisions" | sed 's/\(..*\)/dep["\1"]=-1;/'`
    bad_files=`egrep '^EXPORT_ELEMENT|^ELEMENT_PROVIDES' $files | sed 's/EXPORT_ELEMENT(\(.*\)).*/\1/
s/ELEMENT_PROVIDES(\(.*\)).*/\1/' | $awk -F: 'BEGIN {OFS="";'"$awk_exports"'}
{
  split($2, deps, / +/);
  for (j in deps) {
    if (dep[deps[j]] < 0) {
      print $1;
      break;
    }
  }
}' | sort | uniq`
    if test -n "$verbose" -a -n "$bad_files"; then
	echo 1>&2
	echo "Files: $files" 1>&2
	echo 1>&2
	echo "Bad files: $bad_files" 1>&2
    fi
    if test -n "$bad_files"; then
	files=`echo "$files
$bad_files" | sort | uniq -u`
    fi

    # then cycle, removing files that require something not provided
    while true; do
	provides=`egrep '^EXPORT_ELEMENT|^ELEMENT_PROVIDES' $files | sed 's/.*(\(.*\)).*/\1/' | tr ' \011' '\012'`
	awk_exports=`echo "$provides"'
'"$provisions" | sed 's/\(..*\)/dep["\1"]=1;/'`"
"`echo "$unprovisions" | sed 's/\(..*\)/dep["\1"]=-1;/'`
	new_bad_files=`grep '^ELEMENT_REQUIRES' $files | sed 's/ELEMENT_REQUIRES(\(.*\)).*/\1/' | $awk -F: 'BEGIN {OFS="";'"$awk_exports"'dep["true"]=1; dep["1"]=1;}
{
  split($2, deps, / +/);
  for (j in deps) {
    i = deps[j]
    if (dep[i] <= 0) {
      bad = 1;
      split(i, or_deps, /\|+/);
      for (k in or_deps) {
	if (!(dep[or_deps[k]] '"$dep_test"' 0))
	  bad = 0;
      }
      if (bad) {
	print $1;
	break;
      }
    }
  }
}' | sort | uniq`
	if test -n "$verbose"; then
	    echo 1>&2
	    echo "Files: $files" 1>&2
	    echo 1>&2
	    echo "Bad files: $new_bad_files" 1>&2
	fi
	if test -z "$new_bad_files"; then
	    break
	else
	    files=`echo "$files
$new_bad_files" | sort | uniq -u`
	    bad_files="$new_bad_files
$bad_files"
	fi
    done

    # generate output
    if test "$filenames" = f; then
	postprocess='awk "{ print $1 }"'
    elif test "$filenames" = F; then
	postprocess="awk '{ if (NF > 2) printf "'"%s:%s\n", $1, $2; else print $1; }'"'"
    else
	echo "# Generated by 'click-buildtool findelem' on" `date`
	postprocess=sort
    fi

    egrep '^ELEMENT_PROVIDES|^EXPORT_ELEMENT|^ELEMENT_HEADER' $files /dev/null | $awk -F: 'BEGIN { 
  OFS = ""
}
/EXPORT/ {
  sub(/.*EXPORT_ELEMENT\(/, "", $2);
  sub(/\).*/, "", $2);
  if (exports[$1] != "") {
    exports[$1] = exports[$1] " " $2
  } else {
    exports[$1] = $2
  }
  next;
}
/PROVIDES/ {
  if (!($1 in exports)) {
    exports[$1] = ""
  }
  next;
}
/HEADER/ {
  sub(/.*ELEMENT_HEADER\(/, "", $2)
  sub(/\).*/, "", $2)
  header[$1] = $2
  next;
}
END {
  n = 0
  for (i in exports) {
    if (exports[i] == "") {
      print i
      n++
    } else {
      if (header[i] == "") {
	header[i] = "\"" i "\""; sub(/\.cc/, ".hh", header[i])
      }
      print i, "\t", header[i], "\t", exports[i]
      n++
    }
  }
  if (n == 0)
    print "click-buildtool: warning: No elements found" | "cat 1>&2"
}' | eval "$postprocess"

}




elem2xxx_usage () {
    echo -n "Usage: click-buildtool elem2$elem2 [-p PREFIX] [-V]" 1>&2
    if test "$elem2" = package; then echo -n " PKGNAME" 1>&2; fi
    echo " < elements.conf
Try \`click-buildtool elem2$elem2 --help' for more information." 1>&2
    exit 1
}


elem2make () {
    driver=""
    makevar=""
    date=`date`
    while [ x"$1" != x ]; do
    case $1 in
    -t|--t|--ta|--tar|--targ|--targe|--target)
	if test $# -lt 2; then elem2xxx_usage; fi
	shift 1; driver="$1"; shift 1;;
    -t*)
	driver=`echo "$1" | sed 's/^-t//'`; shift 1;;
    --t=*|--ta=*|--tar=*|--targ=*|--targe=*|--target=*)
	driver=`echo "$1" | sed 's/^[^=]*=//'`; shift 1;;
    -v|--m|--ma|--mak|--make|--make-|--make-v|--make-va|--make-var|--make-vari|--make-varia|--make-variab|--make-variabl|--make-variable)
	if test $# -lt 2; then elem2xxx_usage; fi
	shift 1; makevar="$1"; shift 1;;
    -v*)
	makevar=`echo "$1" | sed 's/^-v//'`; shift 1;;
    --m=*|--ma=*|--mak=*|--make=*|--make-=*|--make-v=*|--make-va=*|--make-var=*|--make-vari=*|--make-varia=*|--make-variab=*|--make-variabl=*|--make-variable=*)
	makevar=`echo "$1" | sed 's/^[^=]*=//'`; shift 1;;
    -x|--e|--ex|--exc|--excl|--exclu|--exclud|--exclude)
        if test $# -lt 2; then elem2xxx_usage; fi
	shift 1
	for i in $1; do excludes=";s/^$i"' \\$'"//$excludes"; done
	shift 1;;
    -x*)
	this_exclude=`echo "$1" | sed 's/^-p//'`
	for i in $this_exclude; do excludes=";s/^$i"' \\$'"//$excludes"; done
	shift 1;;
    --e=*|--ex=*|--exc=*|--excl=*|--exclu=*|--exclud=*|--exclude=*)
	this_exclude=`echo "$1" | sed 's/^[^=]*=//'`
	for i in $this_exclude; do excludes=";s/^$i"' \\$'"//$excludes"; done
	shift 1;;
    -V|--verb|--verbo|--verbos|--verbose)
	verbose=1; shift 1;;
    -h|--h|--he|--hel|--help)
	cat <<'EOF' 1>&2
`Click-buildtool elem2make' reads an `elements.conf' file generated by
`click-buildtool findelem' on the standard input, and writes a Makefile
fragment defining the ELEMENT_OBJS variable to the standard output.

Usage: click-buildtool elem2make [-t TARGET] [-V] < elements.conf

Options:
  -t, --target TARGET      Set target to TARGET (`userlevel', `linuxmodule', 
                           `bsdmodule', or `ns').
  -v, --make-variable N    Use make variable N.
  -x, --exclude FILE       Do not include FILE.
  -V, --verbose            Print more information.
  -h, --help               Print this message and exit.

Report bugs to <click@pdos.lcs.mit.edu>.
EOF
	exit 0;;
    *)
	elem2xxx_usage;;
    esac
    done

    osuffix=".o"
    defmakevar="ELEMENT_OBJS"
    if test -n "$driver"; then
	if test "$driver" = 'user' -o "$driver" = 'userlevel'; then
	    osuffix=".uo"
	    defmakevar="U_ELEMENT_OBJS"
	elif test "$driver" = 'kernel' -o "$driver" = 'linuxmodule'; then
	    osuffix=".ko"
	    defmakevar="K_ELEMENT_OBJS"
	elif test "$driver" = 'bsdmodule'; then
	    osuffix=".bo"
	    defmakevar="B_ELEMENT_OBJS"
	elif test "$driver" = 'ns' -o "$driver" = 'nsmodule'; then
	    osuffix=".no"
	    defmakevar="NS_ELEMENT_OBJS"
	else
	    echo "Unknown driver $driver" 1>&2
	    exit 1
	fi
    fi
    if test -z "$makevar"; then
	makevar=$defmakevar
    fi

    # expand list of files
    files=`grep -v '^#' | sed 's/[ 	].*//'`

    # output
    echo "# Generated by 'click-buildtool elem2make' on" `date`
    echo "$makevar = \\"
    echo "$files" | sed -e 's/\.cc*$/'"$osuffix"' \\/;s/^.*\///'"$excludes" | grep .
    echo
}


elem2xxx () {
    package=""
    date=`date`
    standards=''
    while [ x"$1" != x ]; do
    case $1 in
    -S|--s|--st|--sta|--stan|--stand|--standa|--standar|--standard|--standards)
	standards=1; shift 1;;
    -V|--verb|--verbo|--verbos|--verbose)
	verbose=1; shift 1;;
    -h|--h|--he|--hel|--help)
	if test "$elem2" = export; then
	    cat <<'EOF' 1>&2
`Click-buildtool elem2export' reads an `elements.conf' file generated by
`click-buildtool findelem' on the standard input, examines those files for
exported elements, and writes a C++ source file defining the 
click_export_elements() function to the standard output.

Usage: click-buildtool elem2export [-V] < elements.conf
EOF
	elif test "$elem2" = package; then
	    cat <<'EOF' 1>&2
`Click-buildtool elem2package' reads an `elements.conf' file generated by
`click-buildtool findelem' on the standard input, examines those files for
exported elements, and writes a C++ source file suitable for creating a
dynamically linked package with those elements to the standard output. PKGNAME
is the name of the package.

Usage: click-buildtool elem2package [-p PREFIX] [-V] PKGNAME < elements.conf
EOF
	fi
	cat <<'EOF' 1>&2

Options:
  -S, --standards          Export standard required elements as well.
  -V, --verbose            Print more information.
  -h, --help               Print this message and exit.

Report bugs to <click@pdos.lcs.mit.edu>.
EOF
	exit 0;;
    -*)
	elem2xxx_usage;;
    *)
	if test -z "$package" -a "$elem2" = package; then package="$1"; shift 1; else elem2xxx_usage; fi;;
    esac
    done

    # set up awk program
    if test -n "$package"; then
	awk_program='BEGIN {
  OFS = ""; nrebecca = 0; packname="'"$package"'";
}
/^#/ { next; }
{
  if (NF == 1)
    next;
  INCLUDES[$2] = 1;
  for (i = 3; i <= NF; i++) {
    split($i, ans, /-/);
    name = (ans[2] == "" ? "0" : "\"" ans[2] "\"");
    B = B "  CLICK_DMALLOC_REG(\"" ans[1] "\");\n  hatred_of_rebecca[" nrebecca "] = click_add_element_type(" name ", new " ans[1] ");\n";
    C = C "  click_remove_element_type(hatred_of_rebecca[" nrebecca "]);\n";
    nrebecca++;
  }
}
END {
  print "/* Generated by \"click-buildtool elem2package\" on '"$date"' */";
  print "/* Package name: ", packname, " */\n";
  print "#ifdef HAVE_CONFIG_H\n#include <config.h>\n#endif\n#include <click/config.h>\n#include <click/package.hh>\n#include <click/glue.hh>";
  for (file in INCLUDES) {
    print "#include ", file;
  }
  print "CLICK_USING_DECLS";
  print "static int hatred_of_rebecca[", nrebecca, "];";
  print "#ifdef CLICK_BSDMODULE\nstatic int\nmodevent(module_t, int t, void *)\n{\n  if (t == MOD_LOAD) {\n#else\nextern \"C\" int\ninit_module()\n{\n#endif";
  print "  click_provide(\"", packname, "\");\n", B, "  CLICK_DMALLOC_REG(\"nXXX\");\n  while (MOD_IN_USE > 1)\n    MOD_DEC_USE_COUNT;\n  return 0;";
  print "#ifdef CLICK_BSDMODULE\n  } else if (t == MOD_UNLOAD) {\n#else\n}\nextern \"C\" void\ncleanup_module()\n{\n#endif";
  print C, "  click_unprovide(\"", packname, "\");";
  print "#ifdef CLICK_BSDMODULE\n  return 0;\n  } else\n    return 0;\n}\nstatic moduledata_t modinfo = {\n  \"", packname, "\", modevent, 0\n};\nDECLARE_MODULE(", packname, ", modinfo, SI_SUB_PSEUDO, SI_ORDER_ANY);\n#else\n}\n#endif";
}
'

    else
	awk_program='BEGIN {
  OFS = "";
}
/^#/ { next; }
{
  if (NF == 1)
    next;
  INCLUDES[$2] = 1;
  for (i = 3; i <= NF; i++) {
    split($i, ans, /-/);
    name = (ans[2] == "" ? "0" : "\"" ans[2] "\"");
    B = B "  CLICK_DMALLOC_REG(\"" ans[1] "\");\n  (void) click_add_element_type(" name ", new " ans[1] ");\n";
  }
}
END {
  print "/* Generated by \"click-buildtool elem2export\" on '"$date"' */\n";
  print "#include <click/config.h>\n#include <click/package.hh>";
  for (file in INCLUDES) {
    print "#include ", file;
  }
  print "CLICK_USING_DECLS";
  print "void\nclick_export_elements()\n{";
  print B, "  CLICK_DMALLOC_REG(\"nXXX\");\n}";
}
'
    fi

    # Actually generate the command!
    if test -z "$standards"; then
	$awk "$awk_program"
    else
	cat <<EOF >/tmp/click-buildtool-standards.$$
-	<click/standard/addressinfo.hh>	AddressInfo
-	<click/standard/alignmentinfo.hh>	AlignmentInfo
-	<click/standard/drivermanager.hh>	DriverManager
-	<click/standard/errorelement.hh>	ErrorElement
-	<click/standard/portinfo.hh>	PortInfo
-	<click/standard/scheduleinfo.hh>	ScheduleInfo
EOF
	cat - /tmp/click-buildtool-standards.$$ | $awk "$awk_program"
	/bin/rm -f /tmp/click-buildtool-standards.$$
    fi
}


quietlink_usage () {
    echo "Usage: click-buildtool quietlink" 1>&2
    echo "Try \`click-buildtool quietlink --help' for more information." 1>&2
    exit 1
}


quietlink () {
    while [ x"$1" != x ]; do
    case $1 in
    -h|--h|--he|--hel|--help)
	cat <<'EOF' 1>&2
`Click-buildtool quietlink' quiets the GNU linker when linking an element
package. Specifically, it removes undefined reference complaints.

Usage: ld ... 2>&1 | click-buildtool quietlink

Options:
  -h, --help               Print this message and exit.

Report bugs to <click@pdos.lcs.mit.edu>.
EOF
	exit 0;;
    *)
	quietlink_usage;;
    esac
    done

    $awk -F: 'BEGIN {
  context = ""
}
/: In function/ {
  context = $0
  next
}
/: undefined reference to/ {
  next
}
/: more undefined references to/ {
  next
}
{
  if (context != "") {
    print context
    context = ""
  }
  print $0
}' 1>&2
}


################
# MAIN PROGRAM #
################

if test $# = 0; then
    # force usage message
    set crapfunc
fi

while [ x"$1" != x ]; do
case $1 in
  --vers|--versi|--versio|--version)
     cat <<'EOF'
click-buildtool (Click) 1.2.3
Copyright (C) 2000-2001 Massachusetts Institute of Technology
Copyright (C) 2000-2001 Mazu Networks, Inc.
Copyright (C) 2001 International Computer Science Institute
This is free software; see the source for copying conditions.
There is NO warranty, not even for merchantability or fitness for a
particular purpose.
EOF
     exit 0;;
  -V|--verb|--verbo|--verbos|--verbose)
     verbose=1; shift 1;;
  -h|--h|--he|--hel|--help)
     cat <<'EOF' 1>&2
`Click-buildtool' is a set of tools used when building Click. For information
on a particular tool, run `click-buildtool TOOLNAME --help'.

Usage: click-buildtool findelem [-a] [-V] [-p PREFIX] < [FILES AND DIRECTORIES]
   or: click-buildtool elem2make [-V] [-p PREFIX] < [ELEMENTS]
   or: click-buildtool elem2export [-V] [-p PREFIX] < [ELEMENTS]
   or: click-buildtool elem2package [-V] [-p PREFIX] PACKAGENAME < [ELEMENTS]
   or: click-buildtool quietlink

Options:
  -V, --verbose            Print more information.
  -h, --help               Print this message and exit.
      --version            Print version number and exit.

Report bugs to <click@pdos.lcs.mit.edu>.
EOF
     exit 0;;
  findelem)
     shift 1; findelements "$@"; exit 0;;
  elem2make)
     elem2="make"; shift 1; elem2make "$@"; exit 0;;
  elem2export)
     elem2="export"; shift 1; elem2xxx "$@"; exit 0;;
  elem2package)
     elem2="package"; shift 1; elem2xxx "$@"; exit 0;;
  quietlink)
     shift 1; quietlink "$@"; exit 0;;
  *)
     echo "Usage: click-buildtool TOOLNAME [ARGUMENTS]
Try \`click-buildtool --help' for more information." 1>&2
     exit 1;;
esac
done
