#!/bin/sh
# py-compile - Compile a Python program

scriptversion=2011-06-08.12; # UTC

# Copyright (C) 2000-2014 Free Software Foundation, Inc.

# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.

# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.

# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.

# This file is maintained in Automake, please report
# bugs to <bug-automake@gnu.org> or send patches to
# <automake-patches@gnu.org>.

if [ -z "$PYTHON" ]; then
  PYTHON=python
fi

me=py-compile

usage_error ()
{
  echo "$me: $*" >&2
  echo "Try '$me --help' for more information." >&2
  exit 1
}

basedir=
destdir=
while test $# -ne 0; do
  case "$1" in
    --basedir)
      if test $# -lt 2; then
        usage_error "option '--basedir' requires an argument"
      else
        basedir=$2
      fi
      shift
      ;;
    --destdir)
      if test $# -lt 2; then
        usage_error "option '--destdir' requires an argument"
      else
        destdir=$2
      fi
      shift
      ;;
    -h|--help)
      cat <<\EOF
Usage: py-compile [--help] [--version] [--basedir DIR] [--destdir DIR] FILES..."

Byte compile some python scripts FILES.  Use --destdir to specify any
leading directory path to the FILES that you don't want to include in the
byte compiled file.  Specify --basedir for any additional path information you
do want to be shown in the byte compiled file.

Example:
  py-compile --destdir /tmp/pkg-root --basedir /usr/share/test test.py test2.py

Report bugs to <bug-automake@gnu.org>.
EOF
      exit $?
      ;;
    -v|--version)
      echo "$me $scriptversion"
      exit $?
      ;;
    --)
      shift
      break
      ;;
    -*)
      usage_error "unrecognized option '$1'"
      ;;
    *)
      break
      ;;
  esac
  shift
done

files=$*
if test -z "$files"; then
    usage_error "no files given"
fi

# if basedir was given, then it should be prepended to filenames before
# byte compilation.
if [ -z "$basedir" ]; then
    pathtrans="path = file"
else
    pathtrans="path = os.path.join('$basedir', file)"
fi

# if destdir was given, then it needs to be prepended to the filename to
# byte compile but not go into the compiled file.
if [ -z "$destdir" ]; then
    filetrans="filepath = path"
else
    filetrans="filepath = os.path.normpath('$destdir' + os.sep + path)"
fi

$PYTHON -c "
import sys, os, py_compile, imp

files = '''$files'''

sys.stdout.write('Byte-compiling python modules...\n')
for file in files.split():
    $pathtrans
    $filetrans
    if not os.path.exists(filepath) or not (len(filepath) >= 3
                                            and filepath[-3:] == '.py'):
	    continue
    sys.stdout.write(file)
    sys.stdout.flush()
    if hasattr(imp, 'get_tag'):
        py_compile.compile(filepath, imp.cache_from_source(filepath), path)
    else:
        py_compile.compile(filepath, filepath + 'c', path)
sys.stdout.write('\n')" || exit $?

# this will fail for python < 1.5, but that doesn't matter ...
$PYTHON -O -c "
import sys, os, py_compile, imp

# pypy does not use .pyo optimization
if hasattr(sys, 'pypy_translation_info'):
    sys.exit(0)

files = '''$files'''
sys.stdout.write('Byte-compiling python modules (optimized versions) ...\n')
for file in files.split():
    $pathtrans
    $filetrans
    if not os.path.exists(filepath) or not (len(filepath) >= 3
                                            and filepath[-3:] == '.py'):
	    continue
    sys.stdout.write(file)
    sys.stdout.flush()
    if hasattr(imp, 'get_tag'):
        py_compile.compile(filepath, imp.cache_from_source(filepath, False), path)
    else:
        py_compile.compile(filepath, filepath + 'o', path)
sys.stdout.write('\n')" 2>/dev/null || :

# Local Variables:
# mode: shell-script
# sh-indentation: 2
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-time-zone: "UTC"
# time-stamp-end: "; # UTC"
# End:
