#!/bin/sh
# configure - The hackerlab configure script
#
################################################################
# Copyright (C) 2001, 2002 Tom Lord
#
# See the file "COPYING" for further information about
# the copyright and warranty status of this work.
#
################################################################
# The generic top-level configure file.
#
# This is the workhorse of the configuration process. It's job is
# to compute nearly all configure-time variables, and prepare them
# for export to Makefiles and subdirectories.
#
# `configure-dirs' does the remaining work when we know that a
# source dir is a directory of subdirs.
#
# `configure-leaf' does the # remaining work when we know that a
# source dir is a directory of actual source;
#
# `configure-autoconf' provides a callout for directories which
# have a `configure' script generated by `autoconf'.
#
# `configure-generic' decides which of `configure-{dirs,leaf,autoconf}'
# to use for a given directory.
#
# This computes the variables:
#
# srcroot the root of the source tree
# objroot the root of the build tree
# srcdir the source dir (the same as srcroot here)
# package the name of the package (from =plugin/distribution)
# branchname the branch name of the package
# ($package sans version and snapshot numbers)
# pkgbasename the basename name of the package
# ($branchname sans branch name)
#
# It parses $srcroot/PLUGIN/options and $srcroot/*/PLUGIN/options to get
# default option values and handles command line arguments:
#
# --yes option
# -y option
# --no option
# -n option
# --with option value
# --with-option value
# --with option=value
# --with-option=value
#
# and:
#
# --version | -V
# --help | -h
# --help-options
# --help-compatibility
# --prefix
# --destdir
# --config-shell
#
# Finally, it can handle one optional argument which is a system
# name.
#
# It then invokes $srcroot/build-tools/scripts/configure-dirs
#
#
set -e
################################################################
# srcdir
#
# Compute the source directory for this configure script.
#
# Normally this is inherited from the environment. See "src/configure".
#
# If $srcdir is not set from the environment,
# make it "dirname $0":
#
# ./configure => .
# configure => .
# $dir/configure => $dir
#
if test x$srcdir = x ; then
srcdir=`dirname $0`
fi
# make "$srcdir" an absolute path
#
here="`pwd`"
cd "$srcdir"
srcdir="`pwd`"
cd "$here"
export srcdir
################################################################
# How to Read Various Configuration Files
#
config_files()
{
# Print the concatenated contents of a particular type
# of config file.
#
type="$1"
here="`pwd`"
cd "$srcdir"
files=
if test -f "PLUGIN/$type" ; then
files="PLUGIN/$type"
fi
for dir in * ; do
if test -d "$dir" -a -d "$dir/PLUGIN" -a -f "$dir/PLUGIN/$type" ; then
files="$files $dir/PLUGIN/$type"
fi
done
if test ! -z "$files" ; then
cat $files
fi
}
directives()
{
# Print the directives from a particular type
# of config file.
#
# Directives are found by:
#
# Joining continued lines (lines ending with backslash) to
# the lines that follow them.
#
# Selecting lines with a letter in column 0.
#
# The general form of a directive is:
#
# directive-name variable-name params...
#
# for a directive that can set VARIABLE-NAME. PARAMS is arbitrary.
#
config_files "$1" \
| awk 'BEGIN { saved_line = ""; saving = 0; }
# Join continuation lines
#
saving { $0 = saved_line " " $0; }
match($0, "\\\\$") {
saved_line = substr($0, 1, length($0) - 1);
saving = 1;
next;
}
# Process completed lines
#
{
saved_line = "";
saving = 0;
process_line($0);
}
# Watch out for a left-over line:
#
END { if (saving) process_line(saved_line); }
function process_line(line)
{
# Print apparent directive lines.
#
if (match(line, "^[a-zA-Z]"))
{
print line;
}
}' \
| sort -k 2 -u
}
options_files()
{
config_files "options"
}
auto_files()
{
config_files "auto"
}
options_directives()
{
directives "options"
}
auto_directives()
{
directives "auto"
}
################################################################
# special options
#
# Some options are special:
#
# --version | -V
# --help | -h
# --help-options
# --help-compatibility
#
# They cause all other options to have no effect and the
# first special option found causes the script to exit.
#
if test $# -ne 0 ; then
for opt in "$@" ; do
case $opt in
--version|-V)
printf "Hackerlab configure 0.0\\n"
printf "Copyright 2001, Tom Lord\\n"
printf "\\n"
printf "This is free software; see the source for copying conditions.\\n"
printf "There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A\\n"
printf "PARTICULAR PURPOSE.\\n"
printf "\\n"
exit 0
;;
--help|-h)
printf "usage: configure [options]\\n"
printf "\\n"
printf " --version | -V print version information\\n"
printf " --help | -h print this message\\n"
printf " --help-options print a list of configuration options\\n"
printf " --help-compatibility print the list of packages with which\\n"
printf " this package is purportedly compatible\\n"
printf "\\n"
printf " --prefix dir specify the installation root\\n"
printf " --prefix=dir\\n"
printf "\\n"
printf " --destdir dir for use when creating binary packages\\n"
printf " --destdir=dir\\n"
printf "\\n"
printf " --config-shell SHELL specify a shell for configure scripts\\n"
printf "\\n"
printf " --yes option specify a binary option\\n"
printf " -y option\\n"
printf " --no option\\n"
printf " -n option\\n"
printf " --with option [yes|y|1|no|n|0]\\n"
printf " --with-option [yes|y|1|no|n|0]\\n"
printf " --with option=[yes|y|1|no|n|0]\\n"
printf " --with-option=[yes|y|1|no|n|0]\\n"
printf "\\n"
printf " --with option value specify a string or package option\\n"
printf " --with-option value\\n"
printf " --with option=value\\n"
printf " --with-option=value\\n"
printf "\\n"
exit 0
;;
--help-options)
printf "\\n"
printf "Available options and default values: \\n"
printf "\\n"
str="`options_files \
| grep -E -v \"^[ ]*(;.*)?\$\" \
| sed -e \"s/^binary[ ]*//\" \
-e \"s/^string[ ]*//\"`"
if test -z "$str" ; then
str=" (none)"
fi
printf "%s\\n" "$str"
printf "\\n"
exit 0
;;
--help-compatibility)
printf "\\n"
printf "Compatibility List:\\n"
printf "\\n"
if test -f "$srcdir/PLUGIN/compatible" ; then
cat "$srcdir/PLUGIN/compatible"
else
printf " (none)\\n"
fi
printf "\\n"
exit 0
;;
--) break
;;
*) ;;
esac
done
fi
################################################################
# Sanity Check and Process Defaults
#
# Don't try to configure a source directory. Always build in a
# separate directory.
#
#
if test -r PLUGIN ; then
echo "Running configure in a source directory is not recommended" 1>&2
echo "(source directory detected by existence of ./PLUGIN)" 1>&2
exit 1
fi
# If "$prefix" is not set from the environment, make
# it "`pwd`/=install".
#
if test x$prefix = x ; then
prefix=`pwd`/=install
fi
# Set srcroot and objroot
#
srcroot="$srcdir"
objroot=`pwd`
################################################################
# Compute the Package Name
#
pkgfile="$srcroot/../=RELEASE-ID"
if test ! -f "$pkgfile" ; then
echo "ERROR: no distribution name file found ($pkgfile)." 1>&2
exit 1
else
package=`grep -E -e "^[a-zA-Z].*$" "$pkgfile" | head -n 1`
if test "x$package" = x ; then
echo "ERROR: ill-formed distribution name in $pkgfile." 1>&2
exit 1
fi
fi
################################################################
# Find the Top-Level PLUGIN Directory, If It Exists
#
if test -d "$srcdir/PLUGIN" ; then
plugindir="$srcdir/PLUGIN"
else
plugindir=
fi
################################################################
# Obtain Lists of Options
#
#
binaryopts=`options_directives | grep "^binary" | sed -e "s/binary[ ][ ]*\([a-zA-Z][-a-zA-Z0-9]*\).*/\1/"`
binaryopts=`echo $binaryopts`
stringopts=`options_directives | grep "^string" | sed -e "s/string[ ][ ]*\([a-zA-Z][-a-zA-Z0-9]*\).*/\1/"`
stringopts=`echo $stringopts`
packageopts=`grep -E "^(required|optional)" "$plugindir/packages" \
| sed -e "s/required[ ][ ]*\([a-zA-Z][-a-zA-Z0-9]*\).*/\1/" \
| sed -e "s/optional[ ][ ]*\([a-zA-Z][-a-zA-Z0-9]*\).*/\1/"`
packageopts=`echo $packageopts`
################################################################
# Clear Out the List of Option Settings
#
optfile="$objroot/Options"
tmpoptfile="$objroot/,,Options"
rm -f "$optfile" "$tmpoptfile"
touch "$optfile" "$tmpoptfile"
printf ";; variables determined by command line arguments\\n" >> "$tmpoptfile"
printf ";;\\n" >> "$tmpoptfile"
################################################################
# Command line arguments can override the environment variable "prefix"
#
# --prefix dir
# --prefix=dir
#
# the destination dir
#
# --destdir dir
# --destdir=dir
#
# the shell used by configure
#
# --config-shell SHELL
#
# and configuration options (see the comment at the top of the file)
#
config_shell=/bin/sh
while test $# -ne 0 ; do
case "$1" in
--) shift
break
;;
--prefix=*) prefix="`printf '%s\n' \"$1\" | sed -e 's/^--prefix=//'`"
shift
;;
--prefix) shift
if test $# -eq 0 ; then
echo ERROR: --prefix requires an argument 1>&2
exit 1
fi
prefix="$1"
shift
;;
--destdir=*) destdir="`printf '%s\n' \"$1\" | sed -e 's/^--destdir=//'`"
shift
;;
--destdir) shift
if test $# -eq 0 ; then
echo ERROR: --destdir requires an argument 1>&2
exit 1
fi
destdir="$1"
shift
;;
--config-shell) shift
if test $# -eq 0 ; then
echo ERROR: --config-shell requires an argument 1>&2
exit 1
fi
config_shell="$1"
shift
;;
--yes | -y | -n | --no)
# Compute the implicit value for the option.
# Either 0 or 1.
#
if test $1 = --yes -o $1 = -y ; then
value=1
else
value=0
fi
shift
# Get the raw option name
#
if test $# -eq 0 ; then
echo ERROR: --yes and --no require an argument 1>&2
exit 1
fi
rawopt="$1"
shift
# Search the list of valid binary option names
# for a matching option and remove it from
# that list if found.
#
leftover=
thisopt=
if test ! -z "$binaryopts" ; then
for opt in $binaryopts ; do
if test "$opt" = "$rawopt" ; then
thisopt="$opt"
else
leftover="$leftover $opt"
fi
done
fi
binaryopts="$leftover"
# If we didn't find a matching option, that's an error.
#
if test -z "$thisopt" ; then
echo "ERROR: unrecognized option for --yes or --no ($1)" 1>&2
exit 1
fi
# Record the value:
#
echo "binary $thisopt=$value" >> "$tmpoptfile"
;;
--with-*|--with)
# Just to be fancy, we permit:
#
# --with var value
# --with var=value
# --with-var value
# --with-var=value
#
# What we don't permit is:
#
# --with-var
#
# as a way to set a binary option to "yes", because that
# leads to horrible ambiguities.
#
# Compute the raw option name.
#
# Either var or var=value.
#
case $1 in
--with) shift
if [ $# = 0 ] ; then
echo ERROR: --with requires an option and value 1>&2
exit 1
fi
rawopt="$1"
erroruse="--with $rawopt"
shift
;;
--with-*) rawopt="`printf '%s\n' \"$1\" | sed -e 's/^--with-//'`"
erroruse="--with-$rawopt"
shift
;;
esac
# invariant:
#
# $rawopt either the option name or option=value
# $erroruse either --with $rawopt or --with-$rawopt
#
# If the value is a separate argument, it is $1.
#
# Is rawopt foo=bar just foo?
#
case "$rawopt" in
*=*) withopt="`printf '%s\n' \"$rawopt\" | sed -e 's/=.*//'`"
withval="`printf '%s\n' \"$rawopt\" | sed -e 's/^[^=]*=//'`"
;;
*) withopt="$rawopt"
if [ $# = 0 ] ; then
echo "ERROR: $erroruse requires an argument" 1>&2
exit 1
fi
withval="$1"
shift
;;
esac
# invariant
#
# $withopt -- the option name
# $withval -- the raw option value
#
# search for a matching binary option:
#
# Remove it from the list of binary options,
# if it is found.
#
leftover=
thisopt=
if test ! -z "$binaryopts" ; then
for opt in $binaryopts ; do
if test "$opt" = "$withopt" ; then
thisopt=$opt
else
leftover="$leftover $opt"
fi
done
fi
binaryopts="$leftover"
# Is it a binary option?
#
if test ! -z "$thisopt" ; then
# Yes, binary option.
#
# Is the value provided recognizable as a binary value?
# Convert it to 0 or 1.
#
case "$withval" in
yes|y|1) withval=1
;;
no|n|0) withval=0
;;
*) echo "ERROR: unrecognized value for binary option ($withopt $withval)" 1>&2
exit 1
;;
esac
# Valid binary option.
# Store it.
#
echo "binary $thisopt=$withval" >> "$tmpoptfile"
else
# Not a binary option.
#
# Search for a matching string option:
#
leftover=
thisopt=
if test ! -z "$stringopts" ; then
for opt in $stringopts ; do
if test "$opt" = "$withopt" ; then
thisopt=$opt
else
leftover="$leftover $opt"
fi
done
fi
stringopts="$leftover"
# Is it a string option?
#
if test ! -z "$thisopt" ; then
# Yes, a string option.
# Store it.
#
echo "string $thisopt=$withval" >> "$tmpoptfile"
else
# Not a string option.
#
# Search for a matching package option:
#
leftover=
thisopt=
if test ! -z "$packageopts" ; then
for opt in $packageopts ; do
if test "$opt" = "$withopt" ; then
thisopt=$opt
else
leftover="$leftover $opt"
fi
done
fi
packageopts="$leftover"
# Is it a package option?
#
if test -z "$thisopt" ; then
# No, its an unrecognized option.
#
echo "ERROR: unrecognized argument ($erroruse)" 1>&2
exit 1
else
# Yes, its a package option.
#
# Pass it as a hint to the package finder script
#
echo "PACKAGE HANDLERS NOT DONE YET" 1>&2
exit 1
fi
fi
fi
;;
*) printf "configure: unrecognized option (%s)\\n" "$1" 1>&2
printf "try --help\\n" 1>&2
exit 1
;;
esac
done
################################################################
# No Other Arguments are Permitted
#
if [ $# != 0 ] ; then
echo "ERROR: unrecognized arguments" 1>&2
echo " " "$*" 1>&2
exit 1
fi
################################################################
# Make Sure That prefix and destdir are Absolute Paths
#
# The catch: prefix might not already exist, and any number
# of its parent directories might not already exist.
#
if printf "%s\n" "$prefix" | grep -v -q -E '^/' ; then
prefix="`pwd`/$prefix"
fi
if test "$destdir" ; then
if printf "%s\n" "$destdir" | grep -v -E '^/' >/dev/null 2>&1 ; then
destdir="`pwd`/$destdir"
fi
fi
################################################################
# Provide Default Values for Options not Specified
#
# Default binary option values:
#
if test ! -z "$binaryopts" ; then
for opt in $binaryopts ; do
default=`options_directives | grep "^binary[ ][ ]*$opt[ ]" \
| sed -e "s/binary[ ][ ]*[a-zA-Z][-a-zA-Z0-9]*[ ][ ]*\([^ ][^ ]*\)/\1/"`
# Is the default value recognizable?
# Convert it to 0 or 1.
#
case "$default" in
0|1) ;;
yes|y) default=1
;;
no|n) default=0
;;
*) echo "ERROR: Bad default value for $opt ($default) in PLUGIN dir" 1>&2
exit
;;
esac
echo "binary $opt=$default" >> "$tmpoptfile"
done
fi
# Default string option values:
#
if test ! -z "$stringopts" ; then
for opt in $stringopts ; do
default=`options_directives | grep "^string[ ][ ]*$opt[ ]" \
| sed -e "s/string[ ][ ]*[a-zA-Z][-a-zA-Z0-9]*[ ][ ]*\(.*\)/\1/"`
echo "string $opt=$default" >> "$tmpoptfile"
done
fi
# Default package option values:
#
if test ! -z "$packageopts" ; then
for opt in $packageopts ; do
default=`options_directives | grep "^string[ ][ ]*$opt[ ]" \
| sed -e "s/string[ ][ ]*[a-zA-Z][-a-zA-Z0-9]*[ ][ ]*\(.*\)/\1/"`
echo "PACKAGE HANDLERS NOT DONE YET" 1>&2
exit 1
done
fi
################################################################
# What's the Canonical System Name?
#
if [ $# != 0 ] ; then
system=`$srcdir/build-tools/gnu/config.sub "$1"`
shift
else
system=`$srcdir/build-tools/gnu/config.guess`
fi
echo >> "$tmpoptfile"
echo >> "$tmpoptfile"
printf ";; variables determined by system name (%s)\\n" "$system" >> "$tmpoptfile"
printf ";;\\n" >> "$tmpoptfile"
export config_shell
"$config_shell" $srcdir/build-tools/platforms/sysconfig "$system" >> "$tmpoptfile"
echo >> "$tmpoptfile"
echo >> "$tmpoptfile"
################################################################
# Add the Standard Config Variables to $optfile
#
printf "\\n" >> "$optfile"
printf ";; standard config variables (computed by \"configure-top\").\\n" >> "$optfile"
printf ";;\\n" >> "$optfile"
printf "string std--system=%s\\n" "$system" >> "$optfile"
printf "string std--package=%s\\n" "$package" >> "$optfile"
printf "string std--pkgfile=%s\\n" "$pkgfile" >> "$optfile"
printf "string std--prefix=%s\\n" "$prefix" >> "$optfile"
printf "string std--destdir=%s\\n" "$destdir" >> "$optfile"
printf "string std--srcroot=%s\\n" "$srcroot" >> "$optfile"
printf "string std--objroot=%s\\n" "$objroot" >> "$optfile"
printf "\\n" >> "$optfile"
printf "\\n" >> "$optfile"
################################################################
# Autoconf Options
#
auto_conf="$config_shell $srcroot/build-tools/scripts/auto"
export auto_conf
export srcroot
export objroot
export srcdir
export prefix
export destdir
export config_shell
# This (setting CC) is a temporary hack. A more systematic way
# to handle non-standard names for the standard tools known to
# make is in the works:
#
cc_setting="`cat \"$optfile\" \"$tmpoptfile\" | grep -E -e '^string cc=' | sed -n '$p' | sed -e 's/string cc=//'`"
if test -z "$cc_setting" ; then
CC=cc
else
CC="$cc_setting"
fi
export CC
cat "$tmpoptfile" >> "$optfile"
rm "$tmpoptfile"
printf ";; automatically determined values:\\n" >> "$optfile"
printf ";;\\n" >> "$optfile"
auto_directives \
| awk -v auto_conf="$auto_conf" '{ print auto_conf " " $0; }' \
| "$config_shell" -e \
>> "$optfile"
printf "\\n" >> "$optfile"
printf "\\n" >> "$optfile"
################################################################
# Build config-include/config-options.h
#
rm -rf config-include
mkdir config-include
cat > config-include/config-options.h << EOF
#ifndef INCLUDE__CONFIG_OPTIONS_H
#define INCLUDE__CONFIG_OPTIONS_H
#include "release-id-string.h"
EOF
grep "^binary" "$optfile" | sed -e "s/^binary[ ]*/#define cfg__/" -e "s/-/_/g" -e "s/=/ /" >> config-include/config-options.h
printf "\\n#define CFG__BINARY_OPTIONS() \\\\\\n" >> config-include/config-options.h
grep "^binary" "$optfile" | sed -e "s/^binary[ ]*/ CFG__BINARY_OPTION(cfg__/" -e "s/-/_/g" -e "s/=/, /" -e "s/\$/) \\\\/" >> config-include/config-options.h
printf "\\n\\n" >> config-include/config-options.h
grep "^string" "$optfile" \
| sed -e "s/^[a-z]*[ ]*//" \
-e h \
-e "s/[^=]*=//" \
-e "s/\"/\\\\\"/g" \
-e "s/\\\\/\\\\\\\\/g" \
-e "s/.*/\"&\"/" \
-e x \
-e "s/=.*/ /" \
-e "s/^/#define cfg__/" \
-e "s/-/_/"g \
-e G \
-e "s/\\n//" \
>> config-include/config-options.h
printf "\\n#define CFG__STRING_OPTIONS() \\\\\\n" >> config-include/config-options.h
grep "^string" "$optfile" \
| sed -e "s/^[a-z]*[ ]*//" \
-e h \
-e "s/[^=]*=//" \
-e "s/\"/\\\\\"/g" \
-e "s/\\\\/\\\\\\\\/g" \
-e "s/.*/\"&\"/" \
-e "s/\$/) \\\\/" \
-e x \
-e "s/=.*/ /" \
-e "s/^/ CFG__STRING_OPTION(cfg__/" \
-e "s/-/_/"g \
-e "s/\$/, /" \
-e G \
-e "s/\\n//" \
>> config-include/config-options.h
printf "\\n\\n" >> config-include/config-options.h
if test -f "$srcroot/PLUGIN/compatible" ; then
printf "\\n\\n#define CFG__COMPATIBLE_RELEASES() \\\\\n" >> config-include/config-options.h
grep -E -v "^[ ]*(;.*)?\$" "$srcroot/PLUGIN/compatible" \
| sed -e "s/[ ]*//g" \
-e "s/;.*//" \
-e "s/\\\\/\\\\\\\\/g" \
-e "s/\"/\\\\\"/g" \
-e "s/^/\"/" \
-e "s/\$/\"/" \
-e "s/^/ CFG__COMPATIBLE_RELEASE(/" \
-e "s/\$/) \\\\/" \
>> config-include/config-options.h
printf "\\n\\n" >> config-include/config-options.h
fi
cat >> config-include/config-options.h << EOF
#endif
EOF
################################################################
# Build config-include/config-options.h
#
cat > config-include/release-id-string.h << EOF
#ifndef INCLUDE__CONFIG_INCLUDE__RELEASE_ID_STRING
#define INCLUDE__CONFIG_INCLUDE__RELEASE_ID_STRING
EOF
printf '#define cfg__std__release_id_string \\\n' >> config-include/release-id-string.h
cat "$pkgfile" \
| sed -e 's/[\"]/\\&/g' \
-e 's/^/ "/' \
-e 's/$/\\n" \\/' \
>> config-include/release-id-string.h
printf "\n\n\n#endif\n" >> config-include/release-id-string.h
################################################################
# Build Makefile-config.mk
#
rm -f Makefile-config.mk
cat > Makefile-config.mk << EOF
ifndef makefile-config-mk
makefile-config-mk := 1
EOF
grep "^binary" "$optfile" | sed -e "s/^binary[ ]*/cfg__/" -e "s/-/_/g" -e "s/=/ := /" >> Makefile-config.mk
grep "^string" "$optfile" \
| sed -e "s/^[a-z]*[ ]*//" \
-e h \
-e "s/[^=]*=//" \
-e "s/\\\$/\$\$/g" \
-e "s/[\\\\#]/\\\\&/g" \
-e x \
-e "s/=.*/ := \$(subst x,,x)/" \
-e "s/^/cfg__/" \
-e "s/-/_/g" \
-e G \
-e "s/\\n//" \
>> Makefile-config.mk
cat >> Makefile-config.mk << EOF
endif
EOF
################################################################
# Report the Configuration Values to the User
#
printf "\\n"
printf "Standard Configuration Settings: \\n"
printf "\\n"
cat "$optfile" | grep "^[a-z]*[ ]*std--" | sed -e "s/^[a-z]*[ ]*std--/ /" -e "s/=/ = /"
printf "\\n"
printf "\\n"
printf "Configuration Options: \\n"
printf "\\n"
cat "$optfile" \
| sort -k 2 \
| grep -v "^[a-z]*[ ]*std--" \
| grep -E "^(binary|string)[ ]*" \
| sed -e 's/binary[ ]*\([^=]*\)=1/ \1 = yes/' \
-e 's/binary[ ]*\([^=]*\)=0/ \1 = no/' \
-e 's/string[ ]*\([^=]*\)=\(.*\)/ \1 = \2/'
printf "\\n"
printf "\\n"
printf "Shell Used by Configure Scripts: \\n"
printf "\\n"
printf " %s\\n" "$config_shell"
printf "\\n"
printf "\\n"
################################################################
# Configure Subdirectories
#
export auto_conf
export srcroot
export objroot
export srcdir
export prefix
export destdir
export config_shell
"$config_shell" $srcdir/build-tools/scripts/configure-dirs
# arch-tag: Tom Lord Tue Dec 4 15:07:58 2001 (scripts/configure-top)
#
syntax highlighted by Code2HTML, v. 0.9.1