Add files using upload-large-folder tool
Browse filesThis view is limited to 50 files because it contains too many changes.
See raw diff
- FacebookAI/xlm-roberta-large/onnx/sentencepiece.bpe.model +3 -0
- mosesdecoder/contrib/memscore/Makefile.am +24 -0
- mosesdecoder/contrib/memscore/aclocal.m4 +851 -0
- mosesdecoder/contrib/memscore/config.h.in +79 -0
- mosesdecoder/contrib/memscore/datastorage.h +52 -0
- mosesdecoder/contrib/memscore/depcomp +530 -0
- mosesdecoder/contrib/memscore/install-sh +323 -0
- mosesdecoder/contrib/memscore/lexdecom.cpp +183 -0
- mosesdecoder/contrib/memscore/phraselm.cpp +63 -0
- mosesdecoder/contrib/memscore/phrasetable.h +710 -0
- mosesdecoder/contrib/memscore/scorer-impl.h +124 -0
- mosesdecoder/contrib/promix/README.md +66 -0
- mosesdecoder/contrib/promix/bleu.py +27 -0
- mosesdecoder/contrib/promix/coll.py +260 -0
- mosesdecoder/contrib/promix/main.py +112 -0
- mosesdecoder/contrib/promix/nbest.py +230 -0
- mosesdecoder/contrib/promix/test.py +25 -0
- mosesdecoder/contrib/promix/test_sampler.py +53 -0
- mosesdecoder/contrib/promix/test_train.py +306 -0
- mosesdecoder/contrib/promix/util.py +12 -0
- mosesdecoder/jam-files/boost-build/build/ac.jam +198 -0
- mosesdecoder/jam-files/boost-build/build/project.jam +1121 -0
- mosesdecoder/jam-files/boost-build/build/property-set.jam +489 -0
- mosesdecoder/jam-files/boost-build/build/targets.jam +1659 -0
- mosesdecoder/jam-files/boost-build/build/version.jam +161 -0
- mosesdecoder/jam-files/boost-build/build/virtual-target.jam +1317 -0
- mosesdecoder/jam-files/boost-build/util/assert.jam +336 -0
- mosesdecoder/jam-files/boost-build/util/doc.jam +997 -0
- mosesdecoder/jam-files/boost-build/util/numbers.jam +218 -0
- mosesdecoder/jam-files/boost-build/util/regex.jam +193 -0
- mosesdecoder/jam-files/engine/build.bat +565 -0
- mosesdecoder/jam-files/engine/builtins.c +2354 -0
- mosesdecoder/jam-files/engine/builtins.h +70 -0
- mosesdecoder/jam-files/engine/bump_version.py +98 -0
- mosesdecoder/jam-files/engine/class.c +191 -0
- mosesdecoder/jam-files/engine/command.h +73 -0
- mosesdecoder/jam-files/engine/compile.h +59 -0
- mosesdecoder/jam-files/engine/cwd.c +83 -0
- mosesdecoder/jam-files/engine/filent.c +311 -0
- mosesdecoder/jam-files/engine/fileunix.c +180 -0
- mosesdecoder/jam-files/engine/frames.c +29 -0
- mosesdecoder/jam-files/engine/function.c +0 -0
- mosesdecoder/jam-files/engine/function.h +46 -0
- mosesdecoder/jam-files/engine/hash.h +79 -0
- mosesdecoder/jam-files/engine/hcache.c +519 -0
- mosesdecoder/jam-files/engine/hdrmacro.h +21 -0
- mosesdecoder/jam-files/engine/headers.c +197 -0
- mosesdecoder/jam-files/engine/jam.c +656 -0
- mosesdecoder/jam-files/engine/jam.h +475 -0
- mosesdecoder/jam-files/engine/jamgram.y +373 -0
FacebookAI/xlm-roberta-large/onnx/sentencepiece.bpe.model
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:cfc8146abe2a0488e9e2a0c56de7952f7c11ab059eca145a0a727afce0db2865
|
| 3 |
+
size 5069051
|
mosesdecoder/contrib/memscore/Makefile.am
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# memscore - in-memory phrase scoring for Statistical Machine Translation
|
| 2 |
+
# Christian Hardmeier, FBK-irst, Trento, 2010
|
| 3 |
+
# $Id$
|
| 4 |
+
|
| 5 |
+
## Process this file with automake to produce Makefile.in
|
| 6 |
+
|
| 7 |
+
ACLOCAL_AMFLAGS = -I m4
|
| 8 |
+
|
| 9 |
+
AUTOMAKE_OPTIONS = foreign
|
| 10 |
+
AM_CXXFLAGS = $(BOOST_CPPFLAGS) -Wall -ffast-math -ftrapping-math -fomit-frame-pointer
|
| 11 |
+
|
| 12 |
+
bin_PROGRAMS = memscore
|
| 13 |
+
memscore_SOURCES = datastorage.h memscore.h phrasetable.h scorer.h scorer-impl.h statistic.h timestamp.h \
|
| 14 |
+
phrasetable.cpp memscore.cpp scorer.cpp lexdecom.cpp lexdecom.h
|
| 15 |
+
|
| 16 |
+
if IRSTLM
|
| 17 |
+
memscore_SOURCES += phraselm.cpp phraselm.h
|
| 18 |
+
endif
|
| 19 |
+
if CHANNEL_SCORER
|
| 20 |
+
memscore_SOURCES += channel-scorer.cpp channel-scorer.h
|
| 21 |
+
endif
|
| 22 |
+
|
| 23 |
+
|
| 24 |
+
memscore_LDADD = $(IRSTLM_LIBS) $(GSL_LIBS)
|
mosesdecoder/contrib/memscore/aclocal.m4
ADDED
|
@@ -0,0 +1,851 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# generated automatically by aclocal 1.9.6 -*- Autoconf -*-
|
| 2 |
+
|
| 3 |
+
# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
|
| 4 |
+
# 2005 Free Software Foundation, Inc.
|
| 5 |
+
# This file is free software; the Free Software Foundation
|
| 6 |
+
# gives unlimited permission to copy and/or distribute it,
|
| 7 |
+
# with or without modifications, as long as this notice is preserved.
|
| 8 |
+
|
| 9 |
+
# This program is distributed in the hope that it will be useful,
|
| 10 |
+
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
|
| 11 |
+
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
| 12 |
+
# PARTICULAR PURPOSE.
|
| 13 |
+
|
| 14 |
+
# Copyright (C) 2002, 2003, 2005 Free Software Foundation, Inc.
|
| 15 |
+
#
|
| 16 |
+
# This file is free software; the Free Software Foundation
|
| 17 |
+
# gives unlimited permission to copy and/or distribute it,
|
| 18 |
+
# with or without modifications, as long as this notice is preserved.
|
| 19 |
+
|
| 20 |
+
# AM_AUTOMAKE_VERSION(VERSION)
|
| 21 |
+
# ----------------------------
|
| 22 |
+
# Automake X.Y traces this macro to ensure aclocal.m4 has been
|
| 23 |
+
# generated from the m4 files accompanying Automake X.Y.
|
| 24 |
+
AC_DEFUN([AM_AUTOMAKE_VERSION], [am__api_version="1.9"])
|
| 25 |
+
|
| 26 |
+
# AM_SET_CURRENT_AUTOMAKE_VERSION
|
| 27 |
+
# -------------------------------
|
| 28 |
+
# Call AM_AUTOMAKE_VERSION so it can be traced.
|
| 29 |
+
# This function is AC_REQUIREd by AC_INIT_AUTOMAKE.
|
| 30 |
+
AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
|
| 31 |
+
[AM_AUTOMAKE_VERSION([1.9.6])])
|
| 32 |
+
|
| 33 |
+
# AM_AUX_DIR_EXPAND -*- Autoconf -*-
|
| 34 |
+
|
| 35 |
+
# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc.
|
| 36 |
+
#
|
| 37 |
+
# This file is free software; the Free Software Foundation
|
| 38 |
+
# gives unlimited permission to copy and/or distribute it,
|
| 39 |
+
# with or without modifications, as long as this notice is preserved.
|
| 40 |
+
|
| 41 |
+
# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets
|
| 42 |
+
# $ac_aux_dir to `$srcdir/foo'. In other projects, it is set to
|
| 43 |
+
# `$srcdir', `$srcdir/..', or `$srcdir/../..'.
|
| 44 |
+
#
|
| 45 |
+
# Of course, Automake must honor this variable whenever it calls a
|
| 46 |
+
# tool from the auxiliary directory. The problem is that $srcdir (and
|
| 47 |
+
# therefore $ac_aux_dir as well) can be either absolute or relative,
|
| 48 |
+
# depending on how configure is run. This is pretty annoying, since
|
| 49 |
+
# it makes $ac_aux_dir quite unusable in subdirectories: in the top
|
| 50 |
+
# source directory, any form will work fine, but in subdirectories a
|
| 51 |
+
# relative path needs to be adjusted first.
|
| 52 |
+
#
|
| 53 |
+
# $ac_aux_dir/missing
|
| 54 |
+
# fails when called from a subdirectory if $ac_aux_dir is relative
|
| 55 |
+
# $top_srcdir/$ac_aux_dir/missing
|
| 56 |
+
# fails if $ac_aux_dir is absolute,
|
| 57 |
+
# fails when called from a subdirectory in a VPATH build with
|
| 58 |
+
# a relative $ac_aux_dir
|
| 59 |
+
#
|
| 60 |
+
# The reason of the latter failure is that $top_srcdir and $ac_aux_dir
|
| 61 |
+
# are both prefixed by $srcdir. In an in-source build this is usually
|
| 62 |
+
# harmless because $srcdir is `.', but things will broke when you
|
| 63 |
+
# start a VPATH build or use an absolute $srcdir.
|
| 64 |
+
#
|
| 65 |
+
# So we could use something similar to $top_srcdir/$ac_aux_dir/missing,
|
| 66 |
+
# iff we strip the leading $srcdir from $ac_aux_dir. That would be:
|
| 67 |
+
# am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"`
|
| 68 |
+
# and then we would define $MISSING as
|
| 69 |
+
# MISSING="\${SHELL} $am_aux_dir/missing"
|
| 70 |
+
# This will work as long as MISSING is not called from configure, because
|
| 71 |
+
# unfortunately $(top_srcdir) has no meaning in configure.
|
| 72 |
+
# However there are other variables, like CC, which are often used in
|
| 73 |
+
# configure, and could therefore not use this "fixed" $ac_aux_dir.
|
| 74 |
+
#
|
| 75 |
+
# Another solution, used here, is to always expand $ac_aux_dir to an
|
| 76 |
+
# absolute PATH. The drawback is that using absolute paths prevent a
|
| 77 |
+
# configured tree to be moved without reconfiguration.
|
| 78 |
+
|
| 79 |
+
AC_DEFUN([AM_AUX_DIR_EXPAND],
|
| 80 |
+
[dnl Rely on autoconf to set up CDPATH properly.
|
| 81 |
+
AC_PREREQ([2.50])dnl
|
| 82 |
+
# expand $ac_aux_dir to an absolute path
|
| 83 |
+
am_aux_dir=`cd $ac_aux_dir && pwd`
|
| 84 |
+
])
|
| 85 |
+
|
| 86 |
+
# AM_CONDITIONAL -*- Autoconf -*-
|
| 87 |
+
|
| 88 |
+
# Copyright (C) 1997, 2000, 2001, 2003, 2004, 2005
|
| 89 |
+
# Free Software Foundation, Inc.
|
| 90 |
+
#
|
| 91 |
+
# This file is free software; the Free Software Foundation
|
| 92 |
+
# gives unlimited permission to copy and/or distribute it,
|
| 93 |
+
# with or without modifications, as long as this notice is preserved.
|
| 94 |
+
|
| 95 |
+
# serial 7
|
| 96 |
+
|
| 97 |
+
# AM_CONDITIONAL(NAME, SHELL-CONDITION)
|
| 98 |
+
# -------------------------------------
|
| 99 |
+
# Define a conditional.
|
| 100 |
+
AC_DEFUN([AM_CONDITIONAL],
|
| 101 |
+
[AC_PREREQ(2.52)dnl
|
| 102 |
+
ifelse([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])],
|
| 103 |
+
[$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl
|
| 104 |
+
AC_SUBST([$1_TRUE])
|
| 105 |
+
AC_SUBST([$1_FALSE])
|
| 106 |
+
if $2; then
|
| 107 |
+
$1_TRUE=
|
| 108 |
+
$1_FALSE='#'
|
| 109 |
+
else
|
| 110 |
+
$1_TRUE='#'
|
| 111 |
+
$1_FALSE=
|
| 112 |
+
fi
|
| 113 |
+
AC_CONFIG_COMMANDS_PRE(
|
| 114 |
+
[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then
|
| 115 |
+
AC_MSG_ERROR([[conditional "$1" was never defined.
|
| 116 |
+
Usually this means the macro was only invoked conditionally.]])
|
| 117 |
+
fi])])
|
| 118 |
+
|
| 119 |
+
|
| 120 |
+
# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
|
| 121 |
+
# Free Software Foundation, Inc.
|
| 122 |
+
#
|
| 123 |
+
# This file is free software; the Free Software Foundation
|
| 124 |
+
# gives unlimited permission to copy and/or distribute it,
|
| 125 |
+
# with or without modifications, as long as this notice is preserved.
|
| 126 |
+
|
| 127 |
+
# serial 8
|
| 128 |
+
|
| 129 |
+
# There are a few dirty hacks below to avoid letting `AC_PROG_CC' be
|
| 130 |
+
# written in clear, in which case automake, when reading aclocal.m4,
|
| 131 |
+
# will think it sees a *use*, and therefore will trigger all it's
|
| 132 |
+
# C support machinery. Also note that it means that autoscan, seeing
|
| 133 |
+
# CC etc. in the Makefile, will ask for an AC_PROG_CC use...
|
| 134 |
+
|
| 135 |
+
|
| 136 |
+
# _AM_DEPENDENCIES(NAME)
|
| 137 |
+
# ----------------------
|
| 138 |
+
# See how the compiler implements dependency checking.
|
| 139 |
+
# NAME is "CC", "CXX", "GCJ", or "OBJC".
|
| 140 |
+
# We try a few techniques and use that to set a single cache variable.
|
| 141 |
+
#
|
| 142 |
+
# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was
|
| 143 |
+
# modified to invoke _AM_DEPENDENCIES(CC); we would have a circular
|
| 144 |
+
# dependency, and given that the user is not expected to run this macro,
|
| 145 |
+
# just rely on AC_PROG_CC.
|
| 146 |
+
AC_DEFUN([_AM_DEPENDENCIES],
|
| 147 |
+
[AC_REQUIRE([AM_SET_DEPDIR])dnl
|
| 148 |
+
AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl
|
| 149 |
+
AC_REQUIRE([AM_MAKE_INCLUDE])dnl
|
| 150 |
+
AC_REQUIRE([AM_DEP_TRACK])dnl
|
| 151 |
+
|
| 152 |
+
ifelse([$1], CC, [depcc="$CC" am_compiler_list=],
|
| 153 |
+
[$1], CXX, [depcc="$CXX" am_compiler_list=],
|
| 154 |
+
[$1], OBJC, [depcc="$OBJC" am_compiler_list='gcc3 gcc'],
|
| 155 |
+
[$1], GCJ, [depcc="$GCJ" am_compiler_list='gcc3 gcc'],
|
| 156 |
+
[depcc="$$1" am_compiler_list=])
|
| 157 |
+
|
| 158 |
+
AC_CACHE_CHECK([dependency style of $depcc],
|
| 159 |
+
[am_cv_$1_dependencies_compiler_type],
|
| 160 |
+
[if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then
|
| 161 |
+
# We make a subdir and do the tests there. Otherwise we can end up
|
| 162 |
+
# making bogus files that we don't know about and never remove. For
|
| 163 |
+
# instance it was reported that on HP-UX the gcc test will end up
|
| 164 |
+
# making a dummy file named `D' -- because `-MD' means `put the output
|
| 165 |
+
# in D'.
|
| 166 |
+
mkdir conftest.dir
|
| 167 |
+
# Copy depcomp to subdir because otherwise we won't find it if we're
|
| 168 |
+
# using a relative directory.
|
| 169 |
+
cp "$am_depcomp" conftest.dir
|
| 170 |
+
cd conftest.dir
|
| 171 |
+
# We will build objects and dependencies in a subdirectory because
|
| 172 |
+
# it helps to detect inapplicable dependency modes. For instance
|
| 173 |
+
# both Tru64's cc and ICC support -MD to output dependencies as a
|
| 174 |
+
# side effect of compilation, but ICC will put the dependencies in
|
| 175 |
+
# the current directory while Tru64 will put them in the object
|
| 176 |
+
# directory.
|
| 177 |
+
mkdir sub
|
| 178 |
+
|
| 179 |
+
am_cv_$1_dependencies_compiler_type=none
|
| 180 |
+
if test "$am_compiler_list" = ""; then
|
| 181 |
+
am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp`
|
| 182 |
+
fi
|
| 183 |
+
for depmode in $am_compiler_list; do
|
| 184 |
+
# Setup a source with many dependencies, because some compilers
|
| 185 |
+
# like to wrap large dependency lists on column 80 (with \), and
|
| 186 |
+
# we should not choose a depcomp mode which is confused by this.
|
| 187 |
+
#
|
| 188 |
+
# We need to recreate these files for each test, as the compiler may
|
| 189 |
+
# overwrite some of them when testing with obscure command lines.
|
| 190 |
+
# This happens at least with the AIX C compiler.
|
| 191 |
+
: > sub/conftest.c
|
| 192 |
+
for i in 1 2 3 4 5 6; do
|
| 193 |
+
echo '#include "conftst'$i'.h"' >> sub/conftest.c
|
| 194 |
+
# Using `: > sub/conftst$i.h' creates only sub/conftst1.h with
|
| 195 |
+
# Solaris 8's {/usr,}/bin/sh.
|
| 196 |
+
touch sub/conftst$i.h
|
| 197 |
+
done
|
| 198 |
+
echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
|
| 199 |
+
|
| 200 |
+
case $depmode in
|
| 201 |
+
nosideeffect)
|
| 202 |
+
# after this tag, mechanisms are not by side-effect, so they'll
|
| 203 |
+
# only be used when explicitly requested
|
| 204 |
+
if test "x$enable_dependency_tracking" = xyes; then
|
| 205 |
+
continue
|
| 206 |
+
else
|
| 207 |
+
break
|
| 208 |
+
fi
|
| 209 |
+
;;
|
| 210 |
+
none) break ;;
|
| 211 |
+
esac
|
| 212 |
+
# We check with `-c' and `-o' for the sake of the "dashmstdout"
|
| 213 |
+
# mode. It turns out that the SunPro C++ compiler does not properly
|
| 214 |
+
# handle `-M -o', and we need to detect this.
|
| 215 |
+
if depmode=$depmode \
|
| 216 |
+
source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \
|
| 217 |
+
depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \
|
| 218 |
+
$SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c \
|
| 219 |
+
>/dev/null 2>conftest.err &&
|
| 220 |
+
grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 &&
|
| 221 |
+
grep sub/conftest.${OBJEXT-o} sub/conftest.Po > /dev/null 2>&1 &&
|
| 222 |
+
${MAKE-make} -s -f confmf > /dev/null 2>&1; then
|
| 223 |
+
# icc doesn't choke on unknown options, it will just issue warnings
|
| 224 |
+
# or remarks (even with -Werror). So we grep stderr for any message
|
| 225 |
+
# that says an option was ignored or not supported.
|
| 226 |
+
# When given -MP, icc 7.0 and 7.1 complain thusly:
|
| 227 |
+
# icc: Command line warning: ignoring option '-M'; no argument required
|
| 228 |
+
# The diagnosis changed in icc 8.0:
|
| 229 |
+
# icc: Command line remark: option '-MP' not supported
|
| 230 |
+
if (grep 'ignoring option' conftest.err ||
|
| 231 |
+
grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else
|
| 232 |
+
am_cv_$1_dependencies_compiler_type=$depmode
|
| 233 |
+
break
|
| 234 |
+
fi
|
| 235 |
+
fi
|
| 236 |
+
done
|
| 237 |
+
|
| 238 |
+
cd ..
|
| 239 |
+
rm -rf conftest.dir
|
| 240 |
+
else
|
| 241 |
+
am_cv_$1_dependencies_compiler_type=none
|
| 242 |
+
fi
|
| 243 |
+
])
|
| 244 |
+
AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type])
|
| 245 |
+
AM_CONDITIONAL([am__fastdep$1], [
|
| 246 |
+
test "x$enable_dependency_tracking" != xno \
|
| 247 |
+
&& test "$am_cv_$1_dependencies_compiler_type" = gcc3])
|
| 248 |
+
])
|
| 249 |
+
|
| 250 |
+
|
| 251 |
+
# AM_SET_DEPDIR
|
| 252 |
+
# -------------
|
| 253 |
+
# Choose a directory name for dependency files.
|
| 254 |
+
# This macro is AC_REQUIREd in _AM_DEPENDENCIES
|
| 255 |
+
AC_DEFUN([AM_SET_DEPDIR],
|
| 256 |
+
[AC_REQUIRE([AM_SET_LEADING_DOT])dnl
|
| 257 |
+
AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl
|
| 258 |
+
])
|
| 259 |
+
|
| 260 |
+
|
| 261 |
+
# AM_DEP_TRACK
|
| 262 |
+
# ------------
|
| 263 |
+
AC_DEFUN([AM_DEP_TRACK],
|
| 264 |
+
[AC_ARG_ENABLE(dependency-tracking,
|
| 265 |
+
[ --disable-dependency-tracking speeds up one-time build
|
| 266 |
+
--enable-dependency-tracking do not reject slow dependency extractors])
|
| 267 |
+
if test "x$enable_dependency_tracking" != xno; then
|
| 268 |
+
am_depcomp="$ac_aux_dir/depcomp"
|
| 269 |
+
AMDEPBACKSLASH='\'
|
| 270 |
+
fi
|
| 271 |
+
AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno])
|
| 272 |
+
AC_SUBST([AMDEPBACKSLASH])
|
| 273 |
+
])
|
| 274 |
+
|
| 275 |
+
# Generate code to set up dependency tracking. -*- Autoconf -*-
|
| 276 |
+
|
| 277 |
+
# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
|
| 278 |
+
# Free Software Foundation, Inc.
|
| 279 |
+
#
|
| 280 |
+
# This file is free software; the Free Software Foundation
|
| 281 |
+
# gives unlimited permission to copy and/or distribute it,
|
| 282 |
+
# with or without modifications, as long as this notice is preserved.
|
| 283 |
+
|
| 284 |
+
#serial 3
|
| 285 |
+
|
| 286 |
+
# _AM_OUTPUT_DEPENDENCY_COMMANDS
|
| 287 |
+
# ------------------------------
|
| 288 |
+
AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS],
|
| 289 |
+
[for mf in $CONFIG_FILES; do
|
| 290 |
+
# Strip MF so we end up with the name of the file.
|
| 291 |
+
mf=`echo "$mf" | sed -e 's/:.*$//'`
|
| 292 |
+
# Check whether this is an Automake generated Makefile or not.
|
| 293 |
+
# We used to match only the files named `Makefile.in', but
|
| 294 |
+
# some people rename them; so instead we look at the file content.
|
| 295 |
+
# Grep'ing the first line is not enough: some people post-process
|
| 296 |
+
# each Makefile.in and add a new line on top of each file to say so.
|
| 297 |
+
# So let's grep whole file.
|
| 298 |
+
if grep '^#.*generated by automake' $mf > /dev/null 2>&1; then
|
| 299 |
+
dirpart=`AS_DIRNAME("$mf")`
|
| 300 |
+
else
|
| 301 |
+
continue
|
| 302 |
+
fi
|
| 303 |
+
# Extract the definition of DEPDIR, am__include, and am__quote
|
| 304 |
+
# from the Makefile without running `make'.
|
| 305 |
+
DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"`
|
| 306 |
+
test -z "$DEPDIR" && continue
|
| 307 |
+
am__include=`sed -n 's/^am__include = //p' < "$mf"`
|
| 308 |
+
test -z "am__include" && continue
|
| 309 |
+
am__quote=`sed -n 's/^am__quote = //p' < "$mf"`
|
| 310 |
+
# When using ansi2knr, U may be empty or an underscore; expand it
|
| 311 |
+
U=`sed -n 's/^U = //p' < "$mf"`
|
| 312 |
+
# Find all dependency output files, they are included files with
|
| 313 |
+
# $(DEPDIR) in their names. We invoke sed twice because it is the
|
| 314 |
+
# simplest approach to changing $(DEPDIR) to its actual value in the
|
| 315 |
+
# expansion.
|
| 316 |
+
for file in `sed -n "
|
| 317 |
+
s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \
|
| 318 |
+
sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do
|
| 319 |
+
# Make sure the directory exists.
|
| 320 |
+
test -f "$dirpart/$file" && continue
|
| 321 |
+
fdir=`AS_DIRNAME(["$file"])`
|
| 322 |
+
AS_MKDIR_P([$dirpart/$fdir])
|
| 323 |
+
# echo "creating $dirpart/$file"
|
| 324 |
+
echo '# dummy' > "$dirpart/$file"
|
| 325 |
+
done
|
| 326 |
+
done
|
| 327 |
+
])# _AM_OUTPUT_DEPENDENCY_COMMANDS
|
| 328 |
+
|
| 329 |
+
|
| 330 |
+
# AM_OUTPUT_DEPENDENCY_COMMANDS
|
| 331 |
+
# -----------------------------
|
| 332 |
+
# This macro should only be invoked once -- use via AC_REQUIRE.
|
| 333 |
+
#
|
| 334 |
+
# This code is only required when automatic dependency tracking
|
| 335 |
+
# is enabled. FIXME. This creates each `.P' file that we will
|
| 336 |
+
# need in order to bootstrap the dependency handling code.
|
| 337 |
+
AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS],
|
| 338 |
+
[AC_CONFIG_COMMANDS([depfiles],
|
| 339 |
+
[test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS],
|
| 340 |
+
[AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"])
|
| 341 |
+
])
|
| 342 |
+
|
| 343 |
+
# Do all the work for Automake. -*- Autoconf -*-
|
| 344 |
+
|
| 345 |
+
# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
|
| 346 |
+
# Free Software Foundation, Inc.
|
| 347 |
+
#
|
| 348 |
+
# This file is free software; the Free Software Foundation
|
| 349 |
+
# gives unlimited permission to copy and/or distribute it,
|
| 350 |
+
# with or without modifications, as long as this notice is preserved.
|
| 351 |
+
|
| 352 |
+
# serial 12
|
| 353 |
+
|
| 354 |
+
# This macro actually does too much. Some checks are only needed if
|
| 355 |
+
# your package does certain things. But this isn't really a big deal.
|
| 356 |
+
|
| 357 |
+
# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE])
|
| 358 |
+
# AM_INIT_AUTOMAKE([OPTIONS])
|
| 359 |
+
# -----------------------------------------------
|
| 360 |
+
# The call with PACKAGE and VERSION arguments is the old style
|
| 361 |
+
# call (pre autoconf-2.50), which is being phased out. PACKAGE
|
| 362 |
+
# and VERSION should now be passed to AC_INIT and removed from
|
| 363 |
+
# the call to AM_INIT_AUTOMAKE.
|
| 364 |
+
# We support both call styles for the transition. After
|
| 365 |
+
# the next Automake release, Autoconf can make the AC_INIT
|
| 366 |
+
# arguments mandatory, and then we can depend on a new Autoconf
|
| 367 |
+
# release and drop the old call support.
|
| 368 |
+
AC_DEFUN([AM_INIT_AUTOMAKE],
|
| 369 |
+
[AC_PREREQ([2.58])dnl
|
| 370 |
+
dnl Autoconf wants to disallow AM_ names. We explicitly allow
|
| 371 |
+
dnl the ones we care about.
|
| 372 |
+
m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl
|
| 373 |
+
AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl
|
| 374 |
+
AC_REQUIRE([AC_PROG_INSTALL])dnl
|
| 375 |
+
# test to see if srcdir already configured
|
| 376 |
+
if test "`cd $srcdir && pwd`" != "`pwd`" &&
|
| 377 |
+
test -f $srcdir/config.status; then
|
| 378 |
+
AC_MSG_ERROR([source directory already configured; run "make distclean" there first])
|
| 379 |
+
fi
|
| 380 |
+
|
| 381 |
+
# test whether we have cygpath
|
| 382 |
+
if test -z "$CYGPATH_W"; then
|
| 383 |
+
if (cygpath --version) >/dev/null 2>/dev/null; then
|
| 384 |
+
CYGPATH_W='cygpath -w'
|
| 385 |
+
else
|
| 386 |
+
CYGPATH_W=echo
|
| 387 |
+
fi
|
| 388 |
+
fi
|
| 389 |
+
AC_SUBST([CYGPATH_W])
|
| 390 |
+
|
| 391 |
+
# Define the identity of the package.
|
| 392 |
+
dnl Distinguish between old-style and new-style calls.
|
| 393 |
+
m4_ifval([$2],
|
| 394 |
+
[m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl
|
| 395 |
+
AC_SUBST([PACKAGE], [$1])dnl
|
| 396 |
+
AC_SUBST([VERSION], [$2])],
|
| 397 |
+
[_AM_SET_OPTIONS([$1])dnl
|
| 398 |
+
AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl
|
| 399 |
+
AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl
|
| 400 |
+
|
| 401 |
+
_AM_IF_OPTION([no-define],,
|
| 402 |
+
[AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package])
|
| 403 |
+
AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])])dnl
|
| 404 |
+
|
| 405 |
+
# Some tools Automake needs.
|
| 406 |
+
AC_REQUIRE([AM_SANITY_CHECK])dnl
|
| 407 |
+
AC_REQUIRE([AC_ARG_PROGRAM])dnl
|
| 408 |
+
AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version})
|
| 409 |
+
AM_MISSING_PROG(AUTOCONF, autoconf)
|
| 410 |
+
AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version})
|
| 411 |
+
AM_MISSING_PROG(AUTOHEADER, autoheader)
|
| 412 |
+
AM_MISSING_PROG(MAKEINFO, makeinfo)
|
| 413 |
+
AM_PROG_INSTALL_SH
|
| 414 |
+
AM_PROG_INSTALL_STRIP
|
| 415 |
+
AC_REQUIRE([AM_PROG_MKDIR_P])dnl
|
| 416 |
+
# We need awk for the "check" target. The system "awk" is bad on
|
| 417 |
+
# some platforms.
|
| 418 |
+
AC_REQUIRE([AC_PROG_AWK])dnl
|
| 419 |
+
AC_REQUIRE([AC_PROG_MAKE_SET])dnl
|
| 420 |
+
AC_REQUIRE([AM_SET_LEADING_DOT])dnl
|
| 421 |
+
_AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])],
|
| 422 |
+
[_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])],
|
| 423 |
+
[_AM_PROG_TAR([v7])])])
|
| 424 |
+
_AM_IF_OPTION([no-dependencies],,
|
| 425 |
+
[AC_PROVIDE_IFELSE([AC_PROG_CC],
|
| 426 |
+
[_AM_DEPENDENCIES(CC)],
|
| 427 |
+
[define([AC_PROG_CC],
|
| 428 |
+
defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl
|
| 429 |
+
AC_PROVIDE_IFELSE([AC_PROG_CXX],
|
| 430 |
+
[_AM_DEPENDENCIES(CXX)],
|
| 431 |
+
[define([AC_PROG_CXX],
|
| 432 |
+
defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl
|
| 433 |
+
])
|
| 434 |
+
])
|
| 435 |
+
|
| 436 |
+
|
| 437 |
+
# When config.status generates a header, we must update the stamp-h file.
|
| 438 |
+
# This file resides in the same directory as the config header
|
| 439 |
+
# that is generated. The stamp files are numbered to have different names.
|
| 440 |
+
|
| 441 |
+
# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the
|
| 442 |
+
# loop where config.status creates the headers, so we can generate
|
| 443 |
+
# our stamp files there.
|
| 444 |
+
AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK],
|
| 445 |
+
[# Compute $1's index in $config_headers.
|
| 446 |
+
_am_stamp_count=1
|
| 447 |
+
for _am_header in $config_headers :; do
|
| 448 |
+
case $_am_header in
|
| 449 |
+
$1 | $1:* )
|
| 450 |
+
break ;;
|
| 451 |
+
* )
|
| 452 |
+
_am_stamp_count=`expr $_am_stamp_count + 1` ;;
|
| 453 |
+
esac
|
| 454 |
+
done
|
| 455 |
+
echo "timestamp for $1" >`AS_DIRNAME([$1])`/stamp-h[]$_am_stamp_count])
|
| 456 |
+
|
| 457 |
+
# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc.
|
| 458 |
+
#
|
| 459 |
+
# This file is free software; the Free Software Foundation
|
| 460 |
+
# gives unlimited permission to copy and/or distribute it,
|
| 461 |
+
# with or without modifications, as long as this notice is preserved.
|
| 462 |
+
|
| 463 |
+
# AM_PROG_INSTALL_SH
|
| 464 |
+
# ------------------
|
| 465 |
+
# Define $install_sh.
|
| 466 |
+
AC_DEFUN([AM_PROG_INSTALL_SH],
|
| 467 |
+
[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
|
| 468 |
+
install_sh=${install_sh-"$am_aux_dir/install-sh"}
|
| 469 |
+
AC_SUBST(install_sh)])
|
| 470 |
+
|
| 471 |
+
# Copyright (C) 2003, 2005 Free Software Foundation, Inc.
|
| 472 |
+
#
|
| 473 |
+
# This file is free software; the Free Software Foundation
|
| 474 |
+
# gives unlimited permission to copy and/or distribute it,
|
| 475 |
+
# with or without modifications, as long as this notice is preserved.
|
| 476 |
+
|
| 477 |
+
# serial 2
|
| 478 |
+
|
| 479 |
+
# Check whether the underlying file-system supports filenames
|
| 480 |
+
# with a leading dot. For instance MS-DOS doesn't.
|
| 481 |
+
AC_DEFUN([AM_SET_LEADING_DOT],
|
| 482 |
+
[rm -rf .tst 2>/dev/null
|
| 483 |
+
mkdir .tst 2>/dev/null
|
| 484 |
+
if test -d .tst; then
|
| 485 |
+
am__leading_dot=.
|
| 486 |
+
else
|
| 487 |
+
am__leading_dot=_
|
| 488 |
+
fi
|
| 489 |
+
rmdir .tst 2>/dev/null
|
| 490 |
+
AC_SUBST([am__leading_dot])])
|
| 491 |
+
|
| 492 |
+
# Check to see how 'make' treats includes. -*- Autoconf -*-
|
| 493 |
+
|
| 494 |
+
# Copyright (C) 2001, 2002, 2003, 2005 Free Software Foundation, Inc.
|
| 495 |
+
#
|
| 496 |
+
# This file is free software; the Free Software Foundation
|
| 497 |
+
# gives unlimited permission to copy and/or distribute it,
|
| 498 |
+
# with or without modifications, as long as this notice is preserved.
|
| 499 |
+
|
| 500 |
+
# serial 3
|
| 501 |
+
|
| 502 |
+
# AM_MAKE_INCLUDE()
|
| 503 |
+
# -----------------
|
| 504 |
+
# Check to see how make treats includes.
|
| 505 |
+
AC_DEFUN([AM_MAKE_INCLUDE],
|
| 506 |
+
[am_make=${MAKE-make}
|
| 507 |
+
cat > confinc << 'END'
|
| 508 |
+
am__doit:
|
| 509 |
+
@echo done
|
| 510 |
+
.PHONY: am__doit
|
| 511 |
+
END
|
| 512 |
+
# If we don't find an include directive, just comment out the code.
|
| 513 |
+
AC_MSG_CHECKING([for style of include used by $am_make])
|
| 514 |
+
am__include="#"
|
| 515 |
+
am__quote=
|
| 516 |
+
_am_result=none
|
| 517 |
+
# First try GNU make style include.
|
| 518 |
+
echo "include confinc" > confmf
|
| 519 |
+
# We grep out `Entering directory' and `Leaving directory'
|
| 520 |
+
# messages which can occur if `w' ends up in MAKEFLAGS.
|
| 521 |
+
# In particular we don't look at `^make:' because GNU make might
|
| 522 |
+
# be invoked under some other name (usually "gmake"), in which
|
| 523 |
+
# case it prints its new name instead of `make'.
|
| 524 |
+
if test "`$am_make -s -f confmf 2> /dev/null | grep -v 'ing directory'`" = "done"; then
|
| 525 |
+
am__include=include
|
| 526 |
+
am__quote=
|
| 527 |
+
_am_result=GNU
|
| 528 |
+
fi
|
| 529 |
+
# Now try BSD make style include.
|
| 530 |
+
if test "$am__include" = "#"; then
|
| 531 |
+
echo '.include "confinc"' > confmf
|
| 532 |
+
if test "`$am_make -s -f confmf 2> /dev/null`" = "done"; then
|
| 533 |
+
am__include=.include
|
| 534 |
+
am__quote="\""
|
| 535 |
+
_am_result=BSD
|
| 536 |
+
fi
|
| 537 |
+
fi
|
| 538 |
+
AC_SUBST([am__include])
|
| 539 |
+
AC_SUBST([am__quote])
|
| 540 |
+
AC_MSG_RESULT([$_am_result])
|
| 541 |
+
rm -f confinc confmf
|
| 542 |
+
])
|
| 543 |
+
|
| 544 |
+
# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*-
|
| 545 |
+
|
| 546 |
+
# Copyright (C) 1997, 1999, 2000, 2001, 2003, 2005
|
| 547 |
+
# Free Software Foundation, Inc.
|
| 548 |
+
#
|
| 549 |
+
# This file is free software; the Free Software Foundation
|
| 550 |
+
# gives unlimited permission to copy and/or distribute it,
|
| 551 |
+
# with or without modifications, as long as this notice is preserved.
|
| 552 |
+
|
| 553 |
+
# serial 4
|
| 554 |
+
|
| 555 |
+
# AM_MISSING_PROG(NAME, PROGRAM)
|
| 556 |
+
# ------------------------------
|
| 557 |
+
AC_DEFUN([AM_MISSING_PROG],
|
| 558 |
+
[AC_REQUIRE([AM_MISSING_HAS_RUN])
|
| 559 |
+
$1=${$1-"${am_missing_run}$2"}
|
| 560 |
+
AC_SUBST($1)])
|
| 561 |
+
|
| 562 |
+
|
| 563 |
+
# AM_MISSING_HAS_RUN
|
| 564 |
+
# ------------------
|
| 565 |
+
# Define MISSING if not defined so far and test if it supports --run.
|
| 566 |
+
# If it does, set am_missing_run to use it, otherwise, to nothing.
|
| 567 |
+
AC_DEFUN([AM_MISSING_HAS_RUN],
|
| 568 |
+
[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
|
| 569 |
+
test x"${MISSING+set}" = xset || MISSING="\${SHELL} $am_aux_dir/missing"
|
| 570 |
+
# Use eval to expand $SHELL
|
| 571 |
+
if eval "$MISSING --run true"; then
|
| 572 |
+
am_missing_run="$MISSING --run "
|
| 573 |
+
else
|
| 574 |
+
am_missing_run=
|
| 575 |
+
AC_MSG_WARN([`missing' script is too old or missing])
|
| 576 |
+
fi
|
| 577 |
+
])
|
| 578 |
+
|
| 579 |
+
# Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc.
|
| 580 |
+
#
|
| 581 |
+
# This file is free software; the Free Software Foundation
|
| 582 |
+
# gives unlimited permission to copy and/or distribute it,
|
| 583 |
+
# with or without modifications, as long as this notice is preserved.
|
| 584 |
+
|
| 585 |
+
# AM_PROG_MKDIR_P
|
| 586 |
+
# ---------------
|
| 587 |
+
# Check whether `mkdir -p' is supported, fallback to mkinstalldirs otherwise.
|
| 588 |
+
#
|
| 589 |
+
# Automake 1.8 used `mkdir -m 0755 -p --' to ensure that directories
|
| 590 |
+
# created by `make install' are always world readable, even if the
|
| 591 |
+
# installer happens to have an overly restrictive umask (e.g. 077).
|
| 592 |
+
# This was a mistake. There are at least two reasons why we must not
|
| 593 |
+
# use `-m 0755':
|
| 594 |
+
# - it causes special bits like SGID to be ignored,
|
| 595 |
+
# - it may be too restrictive (some setups expect 775 directories).
|
| 596 |
+
#
|
| 597 |
+
# Do not use -m 0755 and let people choose whatever they expect by
|
| 598 |
+
# setting umask.
|
| 599 |
+
#
|
| 600 |
+
# We cannot accept any implementation of `mkdir' that recognizes `-p'.
|
| 601 |
+
# Some implementations (such as Solaris 8's) are not thread-safe: if a
|
| 602 |
+
# parallel make tries to run `mkdir -p a/b' and `mkdir -p a/c'
|
| 603 |
+
# concurrently, both version can detect that a/ is missing, but only
|
| 604 |
+
# one can create it and the other will error out. Consequently we
|
| 605 |
+
# restrict ourselves to GNU make (using the --version option ensures
|
| 606 |
+
# this.)
|
| 607 |
+
AC_DEFUN([AM_PROG_MKDIR_P],
|
| 608 |
+
[if mkdir -p --version . >/dev/null 2>&1 && test ! -d ./--version; then
|
| 609 |
+
# We used to keeping the `.' as first argument, in order to
|
| 610 |
+
# allow $(mkdir_p) to be used without argument. As in
|
| 611 |
+
# $(mkdir_p) $(somedir)
|
| 612 |
+
# where $(somedir) is conditionally defined. However this is wrong
|
| 613 |
+
# for two reasons:
|
| 614 |
+
# 1. if the package is installed by a user who cannot write `.'
|
| 615 |
+
# make install will fail,
|
| 616 |
+
# 2. the above comment should most certainly read
|
| 617 |
+
# $(mkdir_p) $(DESTDIR)$(somedir)
|
| 618 |
+
# so it does not work when $(somedir) is undefined and
|
| 619 |
+
# $(DESTDIR) is not.
|
| 620 |
+
# To support the latter case, we have to write
|
| 621 |
+
# test -z "$(somedir)" || $(mkdir_p) $(DESTDIR)$(somedir),
|
| 622 |
+
# so the `.' trick is pointless.
|
| 623 |
+
mkdir_p='mkdir -p --'
|
| 624 |
+
else
|
| 625 |
+
# On NextStep and OpenStep, the `mkdir' command does not
|
| 626 |
+
# recognize any option. It will interpret all options as
|
| 627 |
+
# directories to create, and then abort because `.' already
|
| 628 |
+
# exists.
|
| 629 |
+
for d in ./-p ./--version;
|
| 630 |
+
do
|
| 631 |
+
test -d $d && rmdir $d
|
| 632 |
+
done
|
| 633 |
+
# $(mkinstalldirs) is defined by Automake if mkinstalldirs exists.
|
| 634 |
+
if test -f "$ac_aux_dir/mkinstalldirs"; then
|
| 635 |
+
mkdir_p='$(mkinstalldirs)'
|
| 636 |
+
else
|
| 637 |
+
mkdir_p='$(install_sh) -d'
|
| 638 |
+
fi
|
| 639 |
+
fi
|
| 640 |
+
AC_SUBST([mkdir_p])])
|
| 641 |
+
|
| 642 |
+
# Helper functions for option handling. -*- Autoconf -*-
|
| 643 |
+
|
| 644 |
+
# Copyright (C) 2001, 2002, 2003, 2005 Free Software Foundation, Inc.
|
| 645 |
+
#
|
| 646 |
+
# This file is free software; the Free Software Foundation
|
| 647 |
+
# gives unlimited permission to copy and/or distribute it,
|
| 648 |
+
# with or without modifications, as long as this notice is preserved.
|
| 649 |
+
|
| 650 |
+
# serial 3
|
| 651 |
+
|
| 652 |
+
# _AM_MANGLE_OPTION(NAME)
|
| 653 |
+
# -----------------------
|
| 654 |
+
AC_DEFUN([_AM_MANGLE_OPTION],
|
| 655 |
+
[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])])
|
| 656 |
+
|
| 657 |
+
# _AM_SET_OPTION(NAME)
|
| 658 |
+
# ------------------------------
|
| 659 |
+
# Set option NAME. Presently that only means defining a flag for this option.
|
| 660 |
+
AC_DEFUN([_AM_SET_OPTION],
|
| 661 |
+
[m4_define(_AM_MANGLE_OPTION([$1]), 1)])
|
| 662 |
+
|
| 663 |
+
# _AM_SET_OPTIONS(OPTIONS)
|
| 664 |
+
# ----------------------------------
|
| 665 |
+
# OPTIONS is a space-separated list of Automake options.
|
| 666 |
+
AC_DEFUN([_AM_SET_OPTIONS],
|
| 667 |
+
[AC_FOREACH([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])])
|
| 668 |
+
|
| 669 |
+
# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET])
|
| 670 |
+
# -------------------------------------------
|
| 671 |
+
# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise.
|
| 672 |
+
AC_DEFUN([_AM_IF_OPTION],
|
| 673 |
+
[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])])
|
| 674 |
+
|
| 675 |
+
# Check to make sure that the build environment is sane. -*- Autoconf -*-
|
| 676 |
+
|
| 677 |
+
# Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005
|
| 678 |
+
# Free Software Foundation, Inc.
|
| 679 |
+
#
|
| 680 |
+
# This file is free software; the Free Software Foundation
|
| 681 |
+
# gives unlimited permission to copy and/or distribute it,
|
| 682 |
+
# with or without modifications, as long as this notice is preserved.
|
| 683 |
+
|
| 684 |
+
# serial 4
|
| 685 |
+
|
| 686 |
+
# AM_SANITY_CHECK
|
| 687 |
+
# ---------------
|
| 688 |
+
AC_DEFUN([AM_SANITY_CHECK],
|
| 689 |
+
[AC_MSG_CHECKING([whether build environment is sane])
|
| 690 |
+
# Just in case
|
| 691 |
+
sleep 1
|
| 692 |
+
echo timestamp > conftest.file
|
| 693 |
+
# Do `set' in a subshell so we don't clobber the current shell's
|
| 694 |
+
# arguments. Must try -L first in case configure is actually a
|
| 695 |
+
# symlink; some systems play weird games with the mod time of symlinks
|
| 696 |
+
# (eg FreeBSD returns the mod time of the symlink's containing
|
| 697 |
+
# directory).
|
| 698 |
+
if (
|
| 699 |
+
set X `ls -Lt $srcdir/configure conftest.file 2> /dev/null`
|
| 700 |
+
if test "$[*]" = "X"; then
|
| 701 |
+
# -L didn't work.
|
| 702 |
+
set X `ls -t $srcdir/configure conftest.file`
|
| 703 |
+
fi
|
| 704 |
+
rm -f conftest.file
|
| 705 |
+
if test "$[*]" != "X $srcdir/configure conftest.file" \
|
| 706 |
+
&& test "$[*]" != "X conftest.file $srcdir/configure"; then
|
| 707 |
+
|
| 708 |
+
# If neither matched, then we have a broken ls. This can happen
|
| 709 |
+
# if, for instance, CONFIG_SHELL is bash and it inherits a
|
| 710 |
+
# broken ls alias from the environment. This has actually
|
| 711 |
+
# happened. Such a system could not be considered "sane".
|
| 712 |
+
AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken
|
| 713 |
+
alias in your environment])
|
| 714 |
+
fi
|
| 715 |
+
|
| 716 |
+
test "$[2]" = conftest.file
|
| 717 |
+
)
|
| 718 |
+
then
|
| 719 |
+
# Ok.
|
| 720 |
+
:
|
| 721 |
+
else
|
| 722 |
+
AC_MSG_ERROR([newly created file is older than distributed files!
|
| 723 |
+
Check your system clock])
|
| 724 |
+
fi
|
| 725 |
+
AC_MSG_RESULT(yes)])
|
| 726 |
+
|
| 727 |
+
# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc.
|
| 728 |
+
#
|
| 729 |
+
# This file is free software; the Free Software Foundation
|
| 730 |
+
# gives unlimited permission to copy and/or distribute it,
|
| 731 |
+
# with or without modifications, as long as this notice is preserved.
|
| 732 |
+
|
| 733 |
+
# AM_PROG_INSTALL_STRIP
|
| 734 |
+
# ---------------------
|
| 735 |
+
# One issue with vendor `install' (even GNU) is that you can't
|
| 736 |
+
# specify the program used to strip binaries. This is especially
|
| 737 |
+
# annoying in cross-compiling environments, where the build's strip
|
| 738 |
+
# is unlikely to handle the host's binaries.
|
| 739 |
+
# Fortunately install-sh will honor a STRIPPROG variable, so we
|
| 740 |
+
# always use install-sh in `make install-strip', and initialize
|
| 741 |
+
# STRIPPROG with the value of the STRIP variable (set by the user).
|
| 742 |
+
AC_DEFUN([AM_PROG_INSTALL_STRIP],
|
| 743 |
+
[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl
|
| 744 |
+
# Installed binaries are usually stripped using `strip' when the user
|
| 745 |
+
# run `make install-strip'. However `strip' might not be the right
|
| 746 |
+
# tool to use in cross-compilation environments, therefore Automake
|
| 747 |
+
# will honor the `STRIP' environment variable to overrule this program.
|
| 748 |
+
dnl Don't test for $cross_compiling = yes, because it might be `maybe'.
|
| 749 |
+
if test "$cross_compiling" != no; then
|
| 750 |
+
AC_CHECK_TOOL([STRIP], [strip], :)
|
| 751 |
+
fi
|
| 752 |
+
INSTALL_STRIP_PROGRAM="\${SHELL} \$(install_sh) -c -s"
|
| 753 |
+
AC_SUBST([INSTALL_STRIP_PROGRAM])])
|
| 754 |
+
|
| 755 |
+
# Check how to create a tarball. -*- Autoconf -*-
|
| 756 |
+
|
| 757 |
+
# Copyright (C) 2004, 2005 Free Software Foundation, Inc.
|
| 758 |
+
#
|
| 759 |
+
# This file is free software; the Free Software Foundation
|
| 760 |
+
# gives unlimited permission to copy and/or distribute it,
|
| 761 |
+
# with or without modifications, as long as this notice is preserved.
|
| 762 |
+
|
| 763 |
+
# serial 2
|
| 764 |
+
|
| 765 |
+
# _AM_PROG_TAR(FORMAT)
|
| 766 |
+
# --------------------
|
| 767 |
+
# Check how to create a tarball in format FORMAT.
|
| 768 |
+
# FORMAT should be one of `v7', `ustar', or `pax'.
|
| 769 |
+
#
|
| 770 |
+
# Substitute a variable $(am__tar) that is a command
|
| 771 |
+
# writing to stdout a FORMAT-tarball containing the directory
|
| 772 |
+
# $tardir.
|
| 773 |
+
# tardir=directory && $(am__tar) > result.tar
|
| 774 |
+
#
|
| 775 |
+
# Substitute a variable $(am__untar) that extract such
|
| 776 |
+
# a tarball read from stdin.
|
| 777 |
+
# $(am__untar) < result.tar
|
| 778 |
+
AC_DEFUN([_AM_PROG_TAR],
|
| 779 |
+
[# Always define AMTAR for backward compatibility.
|
| 780 |
+
AM_MISSING_PROG([AMTAR], [tar])
|
| 781 |
+
m4_if([$1], [v7],
|
| 782 |
+
[am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'],
|
| 783 |
+
[m4_case([$1], [ustar],, [pax],,
|
| 784 |
+
[m4_fatal([Unknown tar format])])
|
| 785 |
+
AC_MSG_CHECKING([how to create a $1 tar archive])
|
| 786 |
+
# Loop over all known methods to create a tar archive until one works.
|
| 787 |
+
_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none'
|
| 788 |
+
_am_tools=${am_cv_prog_tar_$1-$_am_tools}
|
| 789 |
+
# Do not fold the above two line into one, because Tru64 sh and
|
| 790 |
+
# Solaris sh will not grok spaces in the rhs of `-'.
|
| 791 |
+
for _am_tool in $_am_tools
|
| 792 |
+
do
|
| 793 |
+
case $_am_tool in
|
| 794 |
+
gnutar)
|
| 795 |
+
for _am_tar in tar gnutar gtar;
|
| 796 |
+
do
|
| 797 |
+
AM_RUN_LOG([$_am_tar --version]) && break
|
| 798 |
+
done
|
| 799 |
+
am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"'
|
| 800 |
+
am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"'
|
| 801 |
+
am__untar="$_am_tar -xf -"
|
| 802 |
+
;;
|
| 803 |
+
plaintar)
|
| 804 |
+
# Must skip GNU tar: if it does not support --format= it doesn't create
|
| 805 |
+
# ustar tarball either.
|
| 806 |
+
(tar --version) >/dev/null 2>&1 && continue
|
| 807 |
+
am__tar='tar chf - "$$tardir"'
|
| 808 |
+
am__tar_='tar chf - "$tardir"'
|
| 809 |
+
am__untar='tar xf -'
|
| 810 |
+
;;
|
| 811 |
+
pax)
|
| 812 |
+
am__tar='pax -L -x $1 -w "$$tardir"'
|
| 813 |
+
am__tar_='pax -L -x $1 -w "$tardir"'
|
| 814 |
+
am__untar='pax -r'
|
| 815 |
+
;;
|
| 816 |
+
cpio)
|
| 817 |
+
am__tar='find "$$tardir" -print | cpio -o -H $1 -L'
|
| 818 |
+
am__tar_='find "$tardir" -print | cpio -o -H $1 -L'
|
| 819 |
+
am__untar='cpio -i -H $1 -d'
|
| 820 |
+
;;
|
| 821 |
+
none)
|
| 822 |
+
am__tar=false
|
| 823 |
+
am__tar_=false
|
| 824 |
+
am__untar=false
|
| 825 |
+
;;
|
| 826 |
+
esac
|
| 827 |
+
|
| 828 |
+
# If the value was cached, stop now. We just wanted to have am__tar
|
| 829 |
+
# and am__untar set.
|
| 830 |
+
test -n "${am_cv_prog_tar_$1}" && break
|
| 831 |
+
|
| 832 |
+
# tar/untar a dummy directory, and stop if the command works
|
| 833 |
+
rm -rf conftest.dir
|
| 834 |
+
mkdir conftest.dir
|
| 835 |
+
echo GrepMe > conftest.dir/file
|
| 836 |
+
AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar])
|
| 837 |
+
rm -rf conftest.dir
|
| 838 |
+
if test -s conftest.tar; then
|
| 839 |
+
AM_RUN_LOG([$am__untar <conftest.tar])
|
| 840 |
+
grep GrepMe conftest.dir/file >/dev/null 2>&1 && break
|
| 841 |
+
fi
|
| 842 |
+
done
|
| 843 |
+
rm -rf conftest.dir
|
| 844 |
+
|
| 845 |
+
AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool])
|
| 846 |
+
AC_MSG_RESULT([$am_cv_prog_tar_$1])])
|
| 847 |
+
AC_SUBST([am__tar])
|
| 848 |
+
AC_SUBST([am__untar])
|
| 849 |
+
]) # _AM_PROG_TAR
|
| 850 |
+
|
| 851 |
+
m4_include([m4/ax_boost_base.m4])
|
mosesdecoder/contrib/memscore/config.h.in
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/* config.h.in. Generated from configure.ac by autoheader. */
|
| 2 |
+
|
| 3 |
+
/* Define to enable channel scorer */
|
| 4 |
+
#undef ENABLE_CHANNEL_SCORER
|
| 5 |
+
|
| 6 |
+
/* define if the Boost library is available */
|
| 7 |
+
#undef HAVE_BOOST
|
| 8 |
+
|
| 9 |
+
/* Define to 1 if you have the <inttypes.h> header file. */
|
| 10 |
+
#undef HAVE_INTTYPES_H
|
| 11 |
+
|
| 12 |
+
/* flag for IRSTLM */
|
| 13 |
+
#undef HAVE_IRSTLM
|
| 14 |
+
|
| 15 |
+
/* Define to 1 if you have the `gsl' library (-lgsl). */
|
| 16 |
+
#undef HAVE_LIBGSL
|
| 17 |
+
|
| 18 |
+
/* Define to 1 if you have the `gslcblas' library (-lgslcblas). */
|
| 19 |
+
#undef HAVE_LIBGSLCBLAS
|
| 20 |
+
|
| 21 |
+
/* Define to 1 if you have the `m' library (-lm). */
|
| 22 |
+
#undef HAVE_LIBM
|
| 23 |
+
|
| 24 |
+
/* Define to 1 if you have the `z' library (-lz). */
|
| 25 |
+
#undef HAVE_LIBZ
|
| 26 |
+
|
| 27 |
+
/* Define to 1 if you have the <memory.h> header file. */
|
| 28 |
+
#undef HAVE_MEMORY_H
|
| 29 |
+
|
| 30 |
+
/* Define to 1 if the system has the type `ptrdiff_t'. */
|
| 31 |
+
#undef HAVE_PTRDIFF_T
|
| 32 |
+
|
| 33 |
+
/* Define to 1 if you have the <stdint.h> header file. */
|
| 34 |
+
#undef HAVE_STDINT_H
|
| 35 |
+
|
| 36 |
+
/* Define to 1 if you have the <stdlib.h> header file. */
|
| 37 |
+
#undef HAVE_STDLIB_H
|
| 38 |
+
|
| 39 |
+
/* Define to 1 if you have the <strings.h> header file. */
|
| 40 |
+
#undef HAVE_STRINGS_H
|
| 41 |
+
|
| 42 |
+
/* Define to 1 if you have the <string.h> header file. */
|
| 43 |
+
#undef HAVE_STRING_H
|
| 44 |
+
|
| 45 |
+
/* Define to 1 if you have the <sys/stat.h> header file. */
|
| 46 |
+
#undef HAVE_SYS_STAT_H
|
| 47 |
+
|
| 48 |
+
/* Define to 1 if you have the <sys/types.h> header file. */
|
| 49 |
+
#undef HAVE_SYS_TYPES_H
|
| 50 |
+
|
| 51 |
+
/* Define to 1 if you have the <unistd.h> header file. */
|
| 52 |
+
#undef HAVE_UNISTD_H
|
| 53 |
+
|
| 54 |
+
/* Name of package */
|
| 55 |
+
#undef PACKAGE
|
| 56 |
+
|
| 57 |
+
/* Define to the address where bug reports for this package should be sent. */
|
| 58 |
+
#undef PACKAGE_BUGREPORT
|
| 59 |
+
|
| 60 |
+
/* Define to the full name of this package. */
|
| 61 |
+
#undef PACKAGE_NAME
|
| 62 |
+
|
| 63 |
+
/* Define to the full name and version of this package. */
|
| 64 |
+
#undef PACKAGE_STRING
|
| 65 |
+
|
| 66 |
+
/* Define to the one symbol short name of this package. */
|
| 67 |
+
#undef PACKAGE_TARNAME
|
| 68 |
+
|
| 69 |
+
/* Define to the version of this package. */
|
| 70 |
+
#undef PACKAGE_VERSION
|
| 71 |
+
|
| 72 |
+
/* Define to 1 if you have the ANSI C header files. */
|
| 73 |
+
#undef STDC_HEADERS
|
| 74 |
+
|
| 75 |
+
/* Version number of package */
|
| 76 |
+
#undef VERSION
|
| 77 |
+
|
| 78 |
+
/* Define to `unsigned int' if <sys/types.h> does not define. */
|
| 79 |
+
#undef size_t
|
mosesdecoder/contrib/memscore/datastorage.h
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
// memscore - in-memory phrase scoring for Statistical Machine Translation
|
| 2 |
+
// Christian Hardmeier, FBK-irst, Trento, 2010
|
| 3 |
+
// $Id$
|
| 4 |
+
|
| 5 |
+
#ifndef DATASTORAGE_H
|
| 6 |
+
#define DATASTORAGE_H
|
| 7 |
+
|
| 8 |
+
#include "memscore.h"
|
| 9 |
+
|
| 10 |
+
template<class T>
|
| 11 |
+
class DataStorage
|
| 12 |
+
{
|
| 13 |
+
private:
|
| 14 |
+
T *base_;
|
| 15 |
+
size_t pos_;
|
| 16 |
+
size_t chunk_size_;
|
| 17 |
+
|
| 18 |
+
DataStorage() : base_(NULL), pos_(0) {
|
| 19 |
+
int ps = getpagesize();
|
| 20 |
+
chunk_size_ = 10 * ps * sizeof(T);
|
| 21 |
+
base_ = new T[chunk_size_];
|
| 22 |
+
}
|
| 23 |
+
|
| 24 |
+
DataStorage(const DataStorage &cc) {
|
| 25 |
+
abort();
|
| 26 |
+
}
|
| 27 |
+
|
| 28 |
+
~DataStorage() {}
|
| 29 |
+
|
| 30 |
+
public:
|
| 31 |
+
static DataStorage &get_instance() {
|
| 32 |
+
static DataStorage<T> instance;
|
| 33 |
+
return instance;
|
| 34 |
+
}
|
| 35 |
+
|
| 36 |
+
T *alloc(size_t count) {
|
| 37 |
+
if(count == 0)
|
| 38 |
+
return NULL;
|
| 39 |
+
|
| 40 |
+
// The memory leak is intended.
|
| 41 |
+
if(pos_ + count > chunk_size_) {
|
| 42 |
+
base_ = new T[chunk_size_];
|
| 43 |
+
pos_ = 0;
|
| 44 |
+
}
|
| 45 |
+
|
| 46 |
+
T *ret = base_ + pos_;
|
| 47 |
+
pos_ += count;
|
| 48 |
+
return ret;
|
| 49 |
+
}
|
| 50 |
+
};
|
| 51 |
+
|
| 52 |
+
#endif
|
mosesdecoder/contrib/memscore/depcomp
ADDED
|
@@ -0,0 +1,530 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#! /bin/sh
|
| 2 |
+
# depcomp - compile a program generating dependencies as side-effects
|
| 3 |
+
|
| 4 |
+
scriptversion=2005-07-09.11
|
| 5 |
+
|
| 6 |
+
# Copyright (C) 1999, 2000, 2003, 2004, 2005 Free Software Foundation, Inc.
|
| 7 |
+
|
| 8 |
+
# This program is free software; you can redistribute it and/or modify
|
| 9 |
+
# it under the terms of the GNU General Public License as published by
|
| 10 |
+
# the Free Software Foundation; either version 2, or (at your option)
|
| 11 |
+
# any later version.
|
| 12 |
+
|
| 13 |
+
# This program is distributed in the hope that it will be useful,
|
| 14 |
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
| 15 |
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
| 16 |
+
# GNU General Public License for more details.
|
| 17 |
+
|
| 18 |
+
# You should have received a copy of the GNU General Public License
|
| 19 |
+
# along with this program; if not, write to the Free Software
|
| 20 |
+
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
| 21 |
+
# 02110-1301, USA.
|
| 22 |
+
|
| 23 |
+
# As a special exception to the GNU General Public License, if you
|
| 24 |
+
# distribute this file as part of a program that contains a
|
| 25 |
+
# configuration script generated by Autoconf, you may include it under
|
| 26 |
+
# the same distribution terms that you use for the rest of that program.
|
| 27 |
+
|
| 28 |
+
# Originally written by Alexandre Oliva <oliva@dcc.unicamp.br>.
|
| 29 |
+
|
| 30 |
+
case $1 in
|
| 31 |
+
'')
|
| 32 |
+
echo "$0: No command. Try \`$0 --help' for more information." 1>&2
|
| 33 |
+
exit 1;
|
| 34 |
+
;;
|
| 35 |
+
-h | --h*)
|
| 36 |
+
cat <<\EOF
|
| 37 |
+
Usage: depcomp [--help] [--version] PROGRAM [ARGS]
|
| 38 |
+
|
| 39 |
+
Run PROGRAMS ARGS to compile a file, generating dependencies
|
| 40 |
+
as side-effects.
|
| 41 |
+
|
| 42 |
+
Environment variables:
|
| 43 |
+
depmode Dependency tracking mode.
|
| 44 |
+
source Source file read by `PROGRAMS ARGS'.
|
| 45 |
+
object Object file output by `PROGRAMS ARGS'.
|
| 46 |
+
DEPDIR directory where to store dependencies.
|
| 47 |
+
depfile Dependency file to output.
|
| 48 |
+
tmpdepfile Temporary file to use when outputing dependencies.
|
| 49 |
+
libtool Whether libtool is used (yes/no).
|
| 50 |
+
|
| 51 |
+
Report bugs to <bug-automake@gnu.org>.
|
| 52 |
+
EOF
|
| 53 |
+
exit $?
|
| 54 |
+
;;
|
| 55 |
+
-v | --v*)
|
| 56 |
+
echo "depcomp $scriptversion"
|
| 57 |
+
exit $?
|
| 58 |
+
;;
|
| 59 |
+
esac
|
| 60 |
+
|
| 61 |
+
if test -z "$depmode" || test -z "$source" || test -z "$object"; then
|
| 62 |
+
echo "depcomp: Variables source, object and depmode must be set" 1>&2
|
| 63 |
+
exit 1
|
| 64 |
+
fi
|
| 65 |
+
|
| 66 |
+
# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po.
|
| 67 |
+
depfile=${depfile-`echo "$object" |
|
| 68 |
+
sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`}
|
| 69 |
+
tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`}
|
| 70 |
+
|
| 71 |
+
rm -f "$tmpdepfile"
|
| 72 |
+
|
| 73 |
+
# Some modes work just like other modes, but use different flags. We
|
| 74 |
+
# parameterize here, but still list the modes in the big case below,
|
| 75 |
+
# to make depend.m4 easier to write. Note that we *cannot* use a case
|
| 76 |
+
# here, because this file can only contain one case statement.
|
| 77 |
+
if test "$depmode" = hp; then
|
| 78 |
+
# HP compiler uses -M and no extra arg.
|
| 79 |
+
gccflag=-M
|
| 80 |
+
depmode=gcc
|
| 81 |
+
fi
|
| 82 |
+
|
| 83 |
+
if test "$depmode" = dashXmstdout; then
|
| 84 |
+
# This is just like dashmstdout with a different argument.
|
| 85 |
+
dashmflag=-xM
|
| 86 |
+
depmode=dashmstdout
|
| 87 |
+
fi
|
| 88 |
+
|
| 89 |
+
case "$depmode" in
|
| 90 |
+
gcc3)
|
| 91 |
+
## gcc 3 implements dependency tracking that does exactly what
|
| 92 |
+
## we want. Yay! Note: for some reason libtool 1.4 doesn't like
|
| 93 |
+
## it if -MD -MP comes after the -MF stuff. Hmm.
|
| 94 |
+
"$@" -MT "$object" -MD -MP -MF "$tmpdepfile"
|
| 95 |
+
stat=$?
|
| 96 |
+
if test $stat -eq 0; then :
|
| 97 |
+
else
|
| 98 |
+
rm -f "$tmpdepfile"
|
| 99 |
+
exit $stat
|
| 100 |
+
fi
|
| 101 |
+
mv "$tmpdepfile" "$depfile"
|
| 102 |
+
;;
|
| 103 |
+
|
| 104 |
+
gcc)
|
| 105 |
+
## There are various ways to get dependency output from gcc. Here's
|
| 106 |
+
## why we pick this rather obscure method:
|
| 107 |
+
## - Don't want to use -MD because we'd like the dependencies to end
|
| 108 |
+
## up in a subdir. Having to rename by hand is ugly.
|
| 109 |
+
## (We might end up doing this anyway to support other compilers.)
|
| 110 |
+
## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like
|
| 111 |
+
## -MM, not -M (despite what the docs say).
|
| 112 |
+
## - Using -M directly means running the compiler twice (even worse
|
| 113 |
+
## than renaming).
|
| 114 |
+
if test -z "$gccflag"; then
|
| 115 |
+
gccflag=-MD,
|
| 116 |
+
fi
|
| 117 |
+
"$@" -Wp,"$gccflag$tmpdepfile"
|
| 118 |
+
stat=$?
|
| 119 |
+
if test $stat -eq 0; then :
|
| 120 |
+
else
|
| 121 |
+
rm -f "$tmpdepfile"
|
| 122 |
+
exit $stat
|
| 123 |
+
fi
|
| 124 |
+
rm -f "$depfile"
|
| 125 |
+
echo "$object : \\" > "$depfile"
|
| 126 |
+
alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
|
| 127 |
+
## The second -e expression handles DOS-style file names with drive letters.
|
| 128 |
+
sed -e 's/^[^:]*: / /' \
|
| 129 |
+
-e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile"
|
| 130 |
+
## This next piece of magic avoids the `deleted header file' problem.
|
| 131 |
+
## The problem is that when a header file which appears in a .P file
|
| 132 |
+
## is deleted, the dependency causes make to die (because there is
|
| 133 |
+
## typically no way to rebuild the header). We avoid this by adding
|
| 134 |
+
## dummy dependencies for each header file. Too bad gcc doesn't do
|
| 135 |
+
## this for us directly.
|
| 136 |
+
tr ' ' '
|
| 137 |
+
' < "$tmpdepfile" |
|
| 138 |
+
## Some versions of gcc put a space before the `:'. On the theory
|
| 139 |
+
## that the space means something, we add a space to the output as
|
| 140 |
+
## well.
|
| 141 |
+
## Some versions of the HPUX 10.20 sed can't process this invocation
|
| 142 |
+
## correctly. Breaking it into two sed invocations is a workaround.
|
| 143 |
+
sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
|
| 144 |
+
rm -f "$tmpdepfile"
|
| 145 |
+
;;
|
| 146 |
+
|
| 147 |
+
hp)
|
| 148 |
+
# This case exists only to let depend.m4 do its work. It works by
|
| 149 |
+
# looking at the text of this script. This case will never be run,
|
| 150 |
+
# since it is checked for above.
|
| 151 |
+
exit 1
|
| 152 |
+
;;
|
| 153 |
+
|
| 154 |
+
sgi)
|
| 155 |
+
if test "$libtool" = yes; then
|
| 156 |
+
"$@" "-Wp,-MDupdate,$tmpdepfile"
|
| 157 |
+
else
|
| 158 |
+
"$@" -MDupdate "$tmpdepfile"
|
| 159 |
+
fi
|
| 160 |
+
stat=$?
|
| 161 |
+
if test $stat -eq 0; then :
|
| 162 |
+
else
|
| 163 |
+
rm -f "$tmpdepfile"
|
| 164 |
+
exit $stat
|
| 165 |
+
fi
|
| 166 |
+
rm -f "$depfile"
|
| 167 |
+
|
| 168 |
+
if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files
|
| 169 |
+
echo "$object : \\" > "$depfile"
|
| 170 |
+
|
| 171 |
+
# Clip off the initial element (the dependent). Don't try to be
|
| 172 |
+
# clever and replace this with sed code, as IRIX sed won't handle
|
| 173 |
+
# lines with more than a fixed number of characters (4096 in
|
| 174 |
+
# IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines;
|
| 175 |
+
# the IRIX cc adds comments like `#:fec' to the end of the
|
| 176 |
+
# dependency line.
|
| 177 |
+
tr ' ' '
|
| 178 |
+
' < "$tmpdepfile" \
|
| 179 |
+
| sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \
|
| 180 |
+
tr '
|
| 181 |
+
' ' ' >> $depfile
|
| 182 |
+
echo >> $depfile
|
| 183 |
+
|
| 184 |
+
# The second pass generates a dummy entry for each header file.
|
| 185 |
+
tr ' ' '
|
| 186 |
+
' < "$tmpdepfile" \
|
| 187 |
+
| sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \
|
| 188 |
+
>> $depfile
|
| 189 |
+
else
|
| 190 |
+
# The sourcefile does not contain any dependencies, so just
|
| 191 |
+
# store a dummy comment line, to avoid errors with the Makefile
|
| 192 |
+
# "include basename.Plo" scheme.
|
| 193 |
+
echo "#dummy" > "$depfile"
|
| 194 |
+
fi
|
| 195 |
+
rm -f "$tmpdepfile"
|
| 196 |
+
;;
|
| 197 |
+
|
| 198 |
+
aix)
|
| 199 |
+
# The C for AIX Compiler uses -M and outputs the dependencies
|
| 200 |
+
# in a .u file. In older versions, this file always lives in the
|
| 201 |
+
# current directory. Also, the AIX compiler puts `$object:' at the
|
| 202 |
+
# start of each line; $object doesn't have directory information.
|
| 203 |
+
# Version 6 uses the directory in both cases.
|
| 204 |
+
stripped=`echo "$object" | sed 's/\(.*\)\..*$/\1/'`
|
| 205 |
+
tmpdepfile="$stripped.u"
|
| 206 |
+
if test "$libtool" = yes; then
|
| 207 |
+
"$@" -Wc,-M
|
| 208 |
+
else
|
| 209 |
+
"$@" -M
|
| 210 |
+
fi
|
| 211 |
+
stat=$?
|
| 212 |
+
|
| 213 |
+
if test -f "$tmpdepfile"; then :
|
| 214 |
+
else
|
| 215 |
+
stripped=`echo "$stripped" | sed 's,^.*/,,'`
|
| 216 |
+
tmpdepfile="$stripped.u"
|
| 217 |
+
fi
|
| 218 |
+
|
| 219 |
+
if test $stat -eq 0; then :
|
| 220 |
+
else
|
| 221 |
+
rm -f "$tmpdepfile"
|
| 222 |
+
exit $stat
|
| 223 |
+
fi
|
| 224 |
+
|
| 225 |
+
if test -f "$tmpdepfile"; then
|
| 226 |
+
outname="$stripped.o"
|
| 227 |
+
# Each line is of the form `foo.o: dependent.h'.
|
| 228 |
+
# Do two passes, one to just change these to
|
| 229 |
+
# `$object: dependent.h' and one to simply `dependent.h:'.
|
| 230 |
+
sed -e "s,^$outname:,$object :," < "$tmpdepfile" > "$depfile"
|
| 231 |
+
sed -e "s,^$outname: \(.*\)$,\1:," < "$tmpdepfile" >> "$depfile"
|
| 232 |
+
else
|
| 233 |
+
# The sourcefile does not contain any dependencies, so just
|
| 234 |
+
# store a dummy comment line, to avoid errors with the Makefile
|
| 235 |
+
# "include basename.Plo" scheme.
|
| 236 |
+
echo "#dummy" > "$depfile"
|
| 237 |
+
fi
|
| 238 |
+
rm -f "$tmpdepfile"
|
| 239 |
+
;;
|
| 240 |
+
|
| 241 |
+
icc)
|
| 242 |
+
# Intel's C compiler understands `-MD -MF file'. However on
|
| 243 |
+
# icc -MD -MF foo.d -c -o sub/foo.o sub/foo.c
|
| 244 |
+
# ICC 7.0 will fill foo.d with something like
|
| 245 |
+
# foo.o: sub/foo.c
|
| 246 |
+
# foo.o: sub/foo.h
|
| 247 |
+
# which is wrong. We want:
|
| 248 |
+
# sub/foo.o: sub/foo.c
|
| 249 |
+
# sub/foo.o: sub/foo.h
|
| 250 |
+
# sub/foo.c:
|
| 251 |
+
# sub/foo.h:
|
| 252 |
+
# ICC 7.1 will output
|
| 253 |
+
# foo.o: sub/foo.c sub/foo.h
|
| 254 |
+
# and will wrap long lines using \ :
|
| 255 |
+
# foo.o: sub/foo.c ... \
|
| 256 |
+
# sub/foo.h ... \
|
| 257 |
+
# ...
|
| 258 |
+
|
| 259 |
+
"$@" -MD -MF "$tmpdepfile"
|
| 260 |
+
stat=$?
|
| 261 |
+
if test $stat -eq 0; then :
|
| 262 |
+
else
|
| 263 |
+
rm -f "$tmpdepfile"
|
| 264 |
+
exit $stat
|
| 265 |
+
fi
|
| 266 |
+
rm -f "$depfile"
|
| 267 |
+
# Each line is of the form `foo.o: dependent.h',
|
| 268 |
+
# or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'.
|
| 269 |
+
# Do two passes, one to just change these to
|
| 270 |
+
# `$object: dependent.h' and one to simply `dependent.h:'.
|
| 271 |
+
sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile"
|
| 272 |
+
# Some versions of the HPUX 10.20 sed can't process this invocation
|
| 273 |
+
# correctly. Breaking it into two sed invocations is a workaround.
|
| 274 |
+
sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" |
|
| 275 |
+
sed -e 's/$/ :/' >> "$depfile"
|
| 276 |
+
rm -f "$tmpdepfile"
|
| 277 |
+
;;
|
| 278 |
+
|
| 279 |
+
tru64)
|
| 280 |
+
# The Tru64 compiler uses -MD to generate dependencies as a side
|
| 281 |
+
# effect. `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'.
|
| 282 |
+
# At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put
|
| 283 |
+
# dependencies in `foo.d' instead, so we check for that too.
|
| 284 |
+
# Subdirectories are respected.
|
| 285 |
+
dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
|
| 286 |
+
test "x$dir" = "x$object" && dir=
|
| 287 |
+
base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
|
| 288 |
+
|
| 289 |
+
if test "$libtool" = yes; then
|
| 290 |
+
# With Tru64 cc, shared objects can also be used to make a
|
| 291 |
+
# static library. This mecanism is used in libtool 1.4 series to
|
| 292 |
+
# handle both shared and static libraries in a single compilation.
|
| 293 |
+
# With libtool 1.4, dependencies were output in $dir.libs/$base.lo.d.
|
| 294 |
+
#
|
| 295 |
+
# With libtool 1.5 this exception was removed, and libtool now
|
| 296 |
+
# generates 2 separate objects for the 2 libraries. These two
|
| 297 |
+
# compilations output dependencies in in $dir.libs/$base.o.d and
|
| 298 |
+
# in $dir$base.o.d. We have to check for both files, because
|
| 299 |
+
# one of the two compilations can be disabled. We should prefer
|
| 300 |
+
# $dir$base.o.d over $dir.libs/$base.o.d because the latter is
|
| 301 |
+
# automatically cleaned when .libs/ is deleted, while ignoring
|
| 302 |
+
# the former would cause a distcleancheck panic.
|
| 303 |
+
tmpdepfile1=$dir.libs/$base.lo.d # libtool 1.4
|
| 304 |
+
tmpdepfile2=$dir$base.o.d # libtool 1.5
|
| 305 |
+
tmpdepfile3=$dir.libs/$base.o.d # libtool 1.5
|
| 306 |
+
tmpdepfile4=$dir.libs/$base.d # Compaq CCC V6.2-504
|
| 307 |
+
"$@" -Wc,-MD
|
| 308 |
+
else
|
| 309 |
+
tmpdepfile1=$dir$base.o.d
|
| 310 |
+
tmpdepfile2=$dir$base.d
|
| 311 |
+
tmpdepfile3=$dir$base.d
|
| 312 |
+
tmpdepfile4=$dir$base.d
|
| 313 |
+
"$@" -MD
|
| 314 |
+
fi
|
| 315 |
+
|
| 316 |
+
stat=$?
|
| 317 |
+
if test $stat -eq 0; then :
|
| 318 |
+
else
|
| 319 |
+
rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4"
|
| 320 |
+
exit $stat
|
| 321 |
+
fi
|
| 322 |
+
|
| 323 |
+
for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4"
|
| 324 |
+
do
|
| 325 |
+
test -f "$tmpdepfile" && break
|
| 326 |
+
done
|
| 327 |
+
if test -f "$tmpdepfile"; then
|
| 328 |
+
sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile"
|
| 329 |
+
# That's a tab and a space in the [].
|
| 330 |
+
sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile"
|
| 331 |
+
else
|
| 332 |
+
echo "#dummy" > "$depfile"
|
| 333 |
+
fi
|
| 334 |
+
rm -f "$tmpdepfile"
|
| 335 |
+
;;
|
| 336 |
+
|
| 337 |
+
#nosideeffect)
|
| 338 |
+
# This comment above is used by automake to tell side-effect
|
| 339 |
+
# dependency tracking mechanisms from slower ones.
|
| 340 |
+
|
| 341 |
+
dashmstdout)
|
| 342 |
+
# Important note: in order to support this mode, a compiler *must*
|
| 343 |
+
# always write the preprocessed file to stdout, regardless of -o.
|
| 344 |
+
"$@" || exit $?
|
| 345 |
+
|
| 346 |
+
# Remove the call to Libtool.
|
| 347 |
+
if test "$libtool" = yes; then
|
| 348 |
+
while test $1 != '--mode=compile'; do
|
| 349 |
+
shift
|
| 350 |
+
done
|
| 351 |
+
shift
|
| 352 |
+
fi
|
| 353 |
+
|
| 354 |
+
# Remove `-o $object'.
|
| 355 |
+
IFS=" "
|
| 356 |
+
for arg
|
| 357 |
+
do
|
| 358 |
+
case $arg in
|
| 359 |
+
-o)
|
| 360 |
+
shift
|
| 361 |
+
;;
|
| 362 |
+
$object)
|
| 363 |
+
shift
|
| 364 |
+
;;
|
| 365 |
+
*)
|
| 366 |
+
set fnord "$@" "$arg"
|
| 367 |
+
shift # fnord
|
| 368 |
+
shift # $arg
|
| 369 |
+
;;
|
| 370 |
+
esac
|
| 371 |
+
done
|
| 372 |
+
|
| 373 |
+
test -z "$dashmflag" && dashmflag=-M
|
| 374 |
+
# Require at least two characters before searching for `:'
|
| 375 |
+
# in the target name. This is to cope with DOS-style filenames:
|
| 376 |
+
# a dependency such as `c:/foo/bar' could be seen as target `c' otherwise.
|
| 377 |
+
"$@" $dashmflag |
|
| 378 |
+
sed 's:^[ ]*[^: ][^:][^:]*\:[ ]*:'"$object"'\: :' > "$tmpdepfile"
|
| 379 |
+
rm -f "$depfile"
|
| 380 |
+
cat < "$tmpdepfile" > "$depfile"
|
| 381 |
+
tr ' ' '
|
| 382 |
+
' < "$tmpdepfile" | \
|
| 383 |
+
## Some versions of the HPUX 10.20 sed can't process this invocation
|
| 384 |
+
## correctly. Breaking it into two sed invocations is a workaround.
|
| 385 |
+
sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
|
| 386 |
+
rm -f "$tmpdepfile"
|
| 387 |
+
;;
|
| 388 |
+
|
| 389 |
+
dashXmstdout)
|
| 390 |
+
# This case only exists to satisfy depend.m4. It is never actually
|
| 391 |
+
# run, as this mode is specially recognized in the preamble.
|
| 392 |
+
exit 1
|
| 393 |
+
;;
|
| 394 |
+
|
| 395 |
+
makedepend)
|
| 396 |
+
"$@" || exit $?
|
| 397 |
+
# Remove any Libtool call
|
| 398 |
+
if test "$libtool" = yes; then
|
| 399 |
+
while test $1 != '--mode=compile'; do
|
| 400 |
+
shift
|
| 401 |
+
done
|
| 402 |
+
shift
|
| 403 |
+
fi
|
| 404 |
+
# X makedepend
|
| 405 |
+
shift
|
| 406 |
+
cleared=no
|
| 407 |
+
for arg in "$@"; do
|
| 408 |
+
case $cleared in
|
| 409 |
+
no)
|
| 410 |
+
set ""; shift
|
| 411 |
+
cleared=yes ;;
|
| 412 |
+
esac
|
| 413 |
+
case "$arg" in
|
| 414 |
+
-D*|-I*)
|
| 415 |
+
set fnord "$@" "$arg"; shift ;;
|
| 416 |
+
# Strip any option that makedepend may not understand. Remove
|
| 417 |
+
# the object too, otherwise makedepend will parse it as a source file.
|
| 418 |
+
-*|$object)
|
| 419 |
+
;;
|
| 420 |
+
*)
|
| 421 |
+
set fnord "$@" "$arg"; shift ;;
|
| 422 |
+
esac
|
| 423 |
+
done
|
| 424 |
+
obj_suffix="`echo $object | sed 's/^.*\././'`"
|
| 425 |
+
touch "$tmpdepfile"
|
| 426 |
+
${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@"
|
| 427 |
+
rm -f "$depfile"
|
| 428 |
+
cat < "$tmpdepfile" > "$depfile"
|
| 429 |
+
sed '1,2d' "$tmpdepfile" | tr ' ' '
|
| 430 |
+
' | \
|
| 431 |
+
## Some versions of the HPUX 10.20 sed can't process this invocation
|
| 432 |
+
## correctly. Breaking it into two sed invocations is a workaround.
|
| 433 |
+
sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
|
| 434 |
+
rm -f "$tmpdepfile" "$tmpdepfile".bak
|
| 435 |
+
;;
|
| 436 |
+
|
| 437 |
+
cpp)
|
| 438 |
+
# Important note: in order to support this mode, a compiler *must*
|
| 439 |
+
# always write the preprocessed file to stdout.
|
| 440 |
+
"$@" || exit $?
|
| 441 |
+
|
| 442 |
+
# Remove the call to Libtool.
|
| 443 |
+
if test "$libtool" = yes; then
|
| 444 |
+
while test $1 != '--mode=compile'; do
|
| 445 |
+
shift
|
| 446 |
+
done
|
| 447 |
+
shift
|
| 448 |
+
fi
|
| 449 |
+
|
| 450 |
+
# Remove `-o $object'.
|
| 451 |
+
IFS=" "
|
| 452 |
+
for arg
|
| 453 |
+
do
|
| 454 |
+
case $arg in
|
| 455 |
+
-o)
|
| 456 |
+
shift
|
| 457 |
+
;;
|
| 458 |
+
$object)
|
| 459 |
+
shift
|
| 460 |
+
;;
|
| 461 |
+
*)
|
| 462 |
+
set fnord "$@" "$arg"
|
| 463 |
+
shift # fnord
|
| 464 |
+
shift # $arg
|
| 465 |
+
;;
|
| 466 |
+
esac
|
| 467 |
+
done
|
| 468 |
+
|
| 469 |
+
"$@" -E |
|
| 470 |
+
sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \
|
| 471 |
+
-e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' |
|
| 472 |
+
sed '$ s: \\$::' > "$tmpdepfile"
|
| 473 |
+
rm -f "$depfile"
|
| 474 |
+
echo "$object : \\" > "$depfile"
|
| 475 |
+
cat < "$tmpdepfile" >> "$depfile"
|
| 476 |
+
sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile"
|
| 477 |
+
rm -f "$tmpdepfile"
|
| 478 |
+
;;
|
| 479 |
+
|
| 480 |
+
msvisualcpp)
|
| 481 |
+
# Important note: in order to support this mode, a compiler *must*
|
| 482 |
+
# always write the preprocessed file to stdout, regardless of -o,
|
| 483 |
+
# because we must use -o when running libtool.
|
| 484 |
+
"$@" || exit $?
|
| 485 |
+
IFS=" "
|
| 486 |
+
for arg
|
| 487 |
+
do
|
| 488 |
+
case "$arg" in
|
| 489 |
+
"-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI")
|
| 490 |
+
set fnord "$@"
|
| 491 |
+
shift
|
| 492 |
+
shift
|
| 493 |
+
;;
|
| 494 |
+
*)
|
| 495 |
+
set fnord "$@" "$arg"
|
| 496 |
+
shift
|
| 497 |
+
shift
|
| 498 |
+
;;
|
| 499 |
+
esac
|
| 500 |
+
done
|
| 501 |
+
"$@" -E |
|
| 502 |
+
sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::echo "`cygpath -u \\"\1\\"`":p' | sort | uniq > "$tmpdepfile"
|
| 503 |
+
rm -f "$depfile"
|
| 504 |
+
echo "$object : \\" > "$depfile"
|
| 505 |
+
. "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s:: \1 \\:p' >> "$depfile"
|
| 506 |
+
echo " " >> "$depfile"
|
| 507 |
+
. "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s::\1\::p' >> "$depfile"
|
| 508 |
+
rm -f "$tmpdepfile"
|
| 509 |
+
;;
|
| 510 |
+
|
| 511 |
+
none)
|
| 512 |
+
exec "$@"
|
| 513 |
+
;;
|
| 514 |
+
|
| 515 |
+
*)
|
| 516 |
+
echo "Unknown depmode $depmode" 1>&2
|
| 517 |
+
exit 1
|
| 518 |
+
;;
|
| 519 |
+
esac
|
| 520 |
+
|
| 521 |
+
exit 0
|
| 522 |
+
|
| 523 |
+
# Local Variables:
|
| 524 |
+
# mode: shell-script
|
| 525 |
+
# sh-indentation: 2
|
| 526 |
+
# eval: (add-hook 'write-file-hooks 'time-stamp)
|
| 527 |
+
# time-stamp-start: "scriptversion="
|
| 528 |
+
# time-stamp-format: "%:y-%02m-%02d.%02H"
|
| 529 |
+
# time-stamp-end: "$"
|
| 530 |
+
# End:
|
mosesdecoder/contrib/memscore/install-sh
ADDED
|
@@ -0,0 +1,323 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/bin/sh
|
| 2 |
+
# install - install a program, script, or datafile
|
| 3 |
+
|
| 4 |
+
scriptversion=2005-05-14.22
|
| 5 |
+
|
| 6 |
+
# This originates from X11R5 (mit/util/scripts/install.sh), which was
|
| 7 |
+
# later released in X11R6 (xc/config/util/install.sh) with the
|
| 8 |
+
# following copyright and license.
|
| 9 |
+
#
|
| 10 |
+
# Copyright (C) 1994 X Consortium
|
| 11 |
+
#
|
| 12 |
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
| 13 |
+
# of this software and associated documentation files (the "Software"), to
|
| 14 |
+
# deal in the Software without restriction, including without limitation the
|
| 15 |
+
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
| 16 |
+
# sell copies of the Software, and to permit persons to whom the Software is
|
| 17 |
+
# furnished to do so, subject to the following conditions:
|
| 18 |
+
#
|
| 19 |
+
# The above copyright notice and this permission notice shall be included in
|
| 20 |
+
# all copies or substantial portions of the Software.
|
| 21 |
+
#
|
| 22 |
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
| 23 |
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
| 24 |
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
| 25 |
+
# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
| 26 |
+
# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
|
| 27 |
+
# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
| 28 |
+
#
|
| 29 |
+
# Except as contained in this notice, the name of the X Consortium shall not
|
| 30 |
+
# be used in advertising or otherwise to promote the sale, use or other deal-
|
| 31 |
+
# ings in this Software without prior written authorization from the X Consor-
|
| 32 |
+
# tium.
|
| 33 |
+
#
|
| 34 |
+
#
|
| 35 |
+
# FSF changes to this file are in the public domain.
|
| 36 |
+
#
|
| 37 |
+
# Calling this script install-sh is preferred over install.sh, to prevent
|
| 38 |
+
# `make' implicit rules from creating a file called install from it
|
| 39 |
+
# when there is no Makefile.
|
| 40 |
+
#
|
| 41 |
+
# This script is compatible with the BSD install script, but was written
|
| 42 |
+
# from scratch. It can only install one file at a time, a restriction
|
| 43 |
+
# shared with many OS's install programs.
|
| 44 |
+
|
| 45 |
+
# set DOITPROG to echo to test this script
|
| 46 |
+
|
| 47 |
+
# Don't use :- since 4.3BSD and earlier shells don't like it.
|
| 48 |
+
doit="${DOITPROG-}"
|
| 49 |
+
|
| 50 |
+
# put in absolute paths if you don't have them in your path; or use env. vars.
|
| 51 |
+
|
| 52 |
+
mvprog="${MVPROG-mv}"
|
| 53 |
+
cpprog="${CPPROG-cp}"
|
| 54 |
+
chmodprog="${CHMODPROG-chmod}"
|
| 55 |
+
chownprog="${CHOWNPROG-chown}"
|
| 56 |
+
chgrpprog="${CHGRPPROG-chgrp}"
|
| 57 |
+
stripprog="${STRIPPROG-strip}"
|
| 58 |
+
rmprog="${RMPROG-rm}"
|
| 59 |
+
mkdirprog="${MKDIRPROG-mkdir}"
|
| 60 |
+
|
| 61 |
+
chmodcmd="$chmodprog 0755"
|
| 62 |
+
chowncmd=
|
| 63 |
+
chgrpcmd=
|
| 64 |
+
stripcmd=
|
| 65 |
+
rmcmd="$rmprog -f"
|
| 66 |
+
mvcmd="$mvprog"
|
| 67 |
+
src=
|
| 68 |
+
dst=
|
| 69 |
+
dir_arg=
|
| 70 |
+
dstarg=
|
| 71 |
+
no_target_directory=
|
| 72 |
+
|
| 73 |
+
usage="Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
|
| 74 |
+
or: $0 [OPTION]... SRCFILES... DIRECTORY
|
| 75 |
+
or: $0 [OPTION]... -t DIRECTORY SRCFILES...
|
| 76 |
+
or: $0 [OPTION]... -d DIRECTORIES...
|
| 77 |
+
|
| 78 |
+
In the 1st form, copy SRCFILE to DSTFILE.
|
| 79 |
+
In the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
|
| 80 |
+
In the 4th, create DIRECTORIES.
|
| 81 |
+
|
| 82 |
+
Options:
|
| 83 |
+
-c (ignored)
|
| 84 |
+
-d create directories instead of installing files.
|
| 85 |
+
-g GROUP $chgrpprog installed files to GROUP.
|
| 86 |
+
-m MODE $chmodprog installed files to MODE.
|
| 87 |
+
-o USER $chownprog installed files to USER.
|
| 88 |
+
-s $stripprog installed files.
|
| 89 |
+
-t DIRECTORY install into DIRECTORY.
|
| 90 |
+
-T report an error if DSTFILE is a directory.
|
| 91 |
+
--help display this help and exit.
|
| 92 |
+
--version display version info and exit.
|
| 93 |
+
|
| 94 |
+
Environment variables override the default commands:
|
| 95 |
+
CHGRPPROG CHMODPROG CHOWNPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG
|
| 96 |
+
"
|
| 97 |
+
|
| 98 |
+
while test -n "$1"; do
|
| 99 |
+
case $1 in
|
| 100 |
+
-c) shift
|
| 101 |
+
continue;;
|
| 102 |
+
|
| 103 |
+
-d) dir_arg=true
|
| 104 |
+
shift
|
| 105 |
+
continue;;
|
| 106 |
+
|
| 107 |
+
-g) chgrpcmd="$chgrpprog $2"
|
| 108 |
+
shift
|
| 109 |
+
shift
|
| 110 |
+
continue;;
|
| 111 |
+
|
| 112 |
+
--help) echo "$usage"; exit $?;;
|
| 113 |
+
|
| 114 |
+
-m) chmodcmd="$chmodprog $2"
|
| 115 |
+
shift
|
| 116 |
+
shift
|
| 117 |
+
continue;;
|
| 118 |
+
|
| 119 |
+
-o) chowncmd="$chownprog $2"
|
| 120 |
+
shift
|
| 121 |
+
shift
|
| 122 |
+
continue;;
|
| 123 |
+
|
| 124 |
+
-s) stripcmd=$stripprog
|
| 125 |
+
shift
|
| 126 |
+
continue;;
|
| 127 |
+
|
| 128 |
+
-t) dstarg=$2
|
| 129 |
+
shift
|
| 130 |
+
shift
|
| 131 |
+
continue;;
|
| 132 |
+
|
| 133 |
+
-T) no_target_directory=true
|
| 134 |
+
shift
|
| 135 |
+
continue;;
|
| 136 |
+
|
| 137 |
+
--version) echo "$0 $scriptversion"; exit $?;;
|
| 138 |
+
|
| 139 |
+
*) # When -d is used, all remaining arguments are directories to create.
|
| 140 |
+
# When -t is used, the destination is already specified.
|
| 141 |
+
test -n "$dir_arg$dstarg" && break
|
| 142 |
+
# Otherwise, the last argument is the destination. Remove it from $@.
|
| 143 |
+
for arg
|
| 144 |
+
do
|
| 145 |
+
if test -n "$dstarg"; then
|
| 146 |
+
# $@ is not empty: it contains at least $arg.
|
| 147 |
+
set fnord "$@" "$dstarg"
|
| 148 |
+
shift # fnord
|
| 149 |
+
fi
|
| 150 |
+
shift # arg
|
| 151 |
+
dstarg=$arg
|
| 152 |
+
done
|
| 153 |
+
break;;
|
| 154 |
+
esac
|
| 155 |
+
done
|
| 156 |
+
|
| 157 |
+
if test -z "$1"; then
|
| 158 |
+
if test -z "$dir_arg"; then
|
| 159 |
+
echo "$0: no input file specified." >&2
|
| 160 |
+
exit 1
|
| 161 |
+
fi
|
| 162 |
+
# It's OK to call `install-sh -d' without argument.
|
| 163 |
+
# This can happen when creating conditional directories.
|
| 164 |
+
exit 0
|
| 165 |
+
fi
|
| 166 |
+
|
| 167 |
+
for src
|
| 168 |
+
do
|
| 169 |
+
# Protect names starting with `-'.
|
| 170 |
+
case $src in
|
| 171 |
+
-*) src=./$src ;;
|
| 172 |
+
esac
|
| 173 |
+
|
| 174 |
+
if test -n "$dir_arg"; then
|
| 175 |
+
dst=$src
|
| 176 |
+
src=
|
| 177 |
+
|
| 178 |
+
if test -d "$dst"; then
|
| 179 |
+
mkdircmd=:
|
| 180 |
+
chmodcmd=
|
| 181 |
+
else
|
| 182 |
+
mkdircmd=$mkdirprog
|
| 183 |
+
fi
|
| 184 |
+
else
|
| 185 |
+
# Waiting for this to be detected by the "$cpprog $src $dsttmp" command
|
| 186 |
+
# might cause directories to be created, which would be especially bad
|
| 187 |
+
# if $src (and thus $dsttmp) contains '*'.
|
| 188 |
+
if test ! -f "$src" && test ! -d "$src"; then
|
| 189 |
+
echo "$0: $src does not exist." >&2
|
| 190 |
+
exit 1
|
| 191 |
+
fi
|
| 192 |
+
|
| 193 |
+
if test -z "$dstarg"; then
|
| 194 |
+
echo "$0: no destination specified." >&2
|
| 195 |
+
exit 1
|
| 196 |
+
fi
|
| 197 |
+
|
| 198 |
+
dst=$dstarg
|
| 199 |
+
# Protect names starting with `-'.
|
| 200 |
+
case $dst in
|
| 201 |
+
-*) dst=./$dst ;;
|
| 202 |
+
esac
|
| 203 |
+
|
| 204 |
+
# If destination is a directory, append the input filename; won't work
|
| 205 |
+
# if double slashes aren't ignored.
|
| 206 |
+
if test -d "$dst"; then
|
| 207 |
+
if test -n "$no_target_directory"; then
|
| 208 |
+
echo "$0: $dstarg: Is a directory" >&2
|
| 209 |
+
exit 1
|
| 210 |
+
fi
|
| 211 |
+
dst=$dst/`basename "$src"`
|
| 212 |
+
fi
|
| 213 |
+
fi
|
| 214 |
+
|
| 215 |
+
# This sed command emulates the dirname command.
|
| 216 |
+
dstdir=`echo "$dst" | sed -e 's,/*$,,;s,[^/]*$,,;s,/*$,,;s,^$,.,'`
|
| 217 |
+
|
| 218 |
+
# Make sure that the destination directory exists.
|
| 219 |
+
|
| 220 |
+
# Skip lots of stat calls in the usual case.
|
| 221 |
+
if test ! -d "$dstdir"; then
|
| 222 |
+
defaultIFS='
|
| 223 |
+
'
|
| 224 |
+
IFS="${IFS-$defaultIFS}"
|
| 225 |
+
|
| 226 |
+
oIFS=$IFS
|
| 227 |
+
# Some sh's can't handle IFS=/ for some reason.
|
| 228 |
+
IFS='%'
|
| 229 |
+
set x `echo "$dstdir" | sed -e 's@/@%@g' -e 's@^%@/@'`
|
| 230 |
+
shift
|
| 231 |
+
IFS=$oIFS
|
| 232 |
+
|
| 233 |
+
pathcomp=
|
| 234 |
+
|
| 235 |
+
while test $# -ne 0 ; do
|
| 236 |
+
pathcomp=$pathcomp$1
|
| 237 |
+
shift
|
| 238 |
+
if test ! -d "$pathcomp"; then
|
| 239 |
+
$mkdirprog "$pathcomp"
|
| 240 |
+
# mkdir can fail with a `File exist' error in case several
|
| 241 |
+
# install-sh are creating the directory concurrently. This
|
| 242 |
+
# is OK.
|
| 243 |
+
test -d "$pathcomp" || exit
|
| 244 |
+
fi
|
| 245 |
+
pathcomp=$pathcomp/
|
| 246 |
+
done
|
| 247 |
+
fi
|
| 248 |
+
|
| 249 |
+
if test -n "$dir_arg"; then
|
| 250 |
+
$doit $mkdircmd "$dst" \
|
| 251 |
+
&& { test -z "$chowncmd" || $doit $chowncmd "$dst"; } \
|
| 252 |
+
&& { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } \
|
| 253 |
+
&& { test -z "$stripcmd" || $doit $stripcmd "$dst"; } \
|
| 254 |
+
&& { test -z "$chmodcmd" || $doit $chmodcmd "$dst"; }
|
| 255 |
+
|
| 256 |
+
else
|
| 257 |
+
dstfile=`basename "$dst"`
|
| 258 |
+
|
| 259 |
+
# Make a couple of temp file names in the proper directory.
|
| 260 |
+
dsttmp=$dstdir/_inst.$$_
|
| 261 |
+
rmtmp=$dstdir/_rm.$$_
|
| 262 |
+
|
| 263 |
+
# Trap to clean up those temp files at exit.
|
| 264 |
+
trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
|
| 265 |
+
trap '(exit $?); exit' 1 2 13 15
|
| 266 |
+
|
| 267 |
+
# Copy the file name to the temp name.
|
| 268 |
+
$doit $cpprog "$src" "$dsttmp" &&
|
| 269 |
+
|
| 270 |
+
# and set any options; do chmod last to preserve setuid bits.
|
| 271 |
+
#
|
| 272 |
+
# If any of these fail, we abort the whole thing. If we want to
|
| 273 |
+
# ignore errors from any of these, just make sure not to ignore
|
| 274 |
+
# errors from the above "$doit $cpprog $src $dsttmp" command.
|
| 275 |
+
#
|
| 276 |
+
{ test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } \
|
| 277 |
+
&& { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } \
|
| 278 |
+
&& { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } \
|
| 279 |
+
&& { test -z "$chmodcmd" || $doit $chmodcmd "$dsttmp"; } &&
|
| 280 |
+
|
| 281 |
+
# Now rename the file to the real destination.
|
| 282 |
+
{ $doit $mvcmd -f "$dsttmp" "$dstdir/$dstfile" 2>/dev/null \
|
| 283 |
+
|| {
|
| 284 |
+
# The rename failed, perhaps because mv can't rename something else
|
| 285 |
+
# to itself, or perhaps because mv is so ancient that it does not
|
| 286 |
+
# support -f.
|
| 287 |
+
|
| 288 |
+
# Now remove or move aside any old file at destination location.
|
| 289 |
+
# We try this two ways since rm can't unlink itself on some
|
| 290 |
+
# systems and the destination file might be busy for other
|
| 291 |
+
# reasons. In this case, the final cleanup might fail but the new
|
| 292 |
+
# file should still install successfully.
|
| 293 |
+
{
|
| 294 |
+
if test -f "$dstdir/$dstfile"; then
|
| 295 |
+
$doit $rmcmd -f "$dstdir/$dstfile" 2>/dev/null \
|
| 296 |
+
|| $doit $mvcmd -f "$dstdir/$dstfile" "$rmtmp" 2>/dev/null \
|
| 297 |
+
|| {
|
| 298 |
+
echo "$0: cannot unlink or rename $dstdir/$dstfile" >&2
|
| 299 |
+
(exit 1); exit 1
|
| 300 |
+
}
|
| 301 |
+
else
|
| 302 |
+
:
|
| 303 |
+
fi
|
| 304 |
+
} &&
|
| 305 |
+
|
| 306 |
+
# Now rename the file to the real destination.
|
| 307 |
+
$doit $mvcmd "$dsttmp" "$dstdir/$dstfile"
|
| 308 |
+
}
|
| 309 |
+
}
|
| 310 |
+
fi || { (exit 1); exit 1; }
|
| 311 |
+
done
|
| 312 |
+
|
| 313 |
+
# The final little trick to "correctly" pass the exit status to the exit trap.
|
| 314 |
+
{
|
| 315 |
+
(exit 0); exit 0
|
| 316 |
+
}
|
| 317 |
+
|
| 318 |
+
# Local variables:
|
| 319 |
+
# eval: (add-hook 'write-file-hooks 'time-stamp)
|
| 320 |
+
# time-stamp-start: "scriptversion="
|
| 321 |
+
# time-stamp-format: "%:y-%02m-%02d.%02H"
|
| 322 |
+
# time-stamp-end: "$"
|
| 323 |
+
# End:
|
mosesdecoder/contrib/memscore/lexdecom.cpp
ADDED
|
@@ -0,0 +1,183 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/*
|
| 2 |
+
* File: lexdecom.cpp
|
| 3 |
+
* Author: Felipe Sánchez-Martínez, Universitat d'Alacant <fsanchez@dlsi.ua.es>
|
| 4 |
+
*
|
| 5 |
+
* Created on 2010/01/27
|
| 6 |
+
*/
|
| 7 |
+
|
| 8 |
+
#include "lexdecom.h"
|
| 9 |
+
#include "scorer-impl.h"
|
| 10 |
+
|
| 11 |
+
#include <iostream>
|
| 12 |
+
#include <fstream>
|
| 13 |
+
|
| 14 |
+
PhraseScorer*
|
| 15 |
+
LexicalDecompositionPhraseScorer::create_scorer(const char *argv[], int &argp, bool reverse, const PhraseScorerFactory &ptf)
|
| 16 |
+
{
|
| 17 |
+
|
| 18 |
+
if(argv[argp] == NULL)
|
| 19 |
+
usage();
|
| 20 |
+
|
| 21 |
+
String lwfile(argv[argp++]);
|
| 22 |
+
|
| 23 |
+
return new LexicalDecompositionPhraseScorer(ptf.get_phrase_table(), reverse, lwfile, argv, argp, ptf);
|
| 24 |
+
}
|
| 25 |
+
|
| 26 |
+
LexicalDecompositionPhraseScorer::LexicalDecompositionPhraseScorer(PhraseTable &pd, bool reverse,
|
| 27 |
+
const String &weightfile, const char *argv[], int &argp,
|
| 28 |
+
const PhraseScorerFactory &ptf) :
|
| 29 |
+
PhraseScorer(pd, reverse)
|
| 30 |
+
{
|
| 31 |
+
|
| 32 |
+
black_box_scorer = AbsoluteDiscountPhraseScorer::create_scorer(argv, argp, reverse, ptf);
|
| 33 |
+
|
| 34 |
+
std::ifstream wfile(weightfile.c_str());
|
| 35 |
+
|
| 36 |
+
//Code copied from LexicalWeightPhraseScorer; it should be factored !! -- 2010/01/27
|
| 37 |
+
|
| 38 |
+
std::cerr<<"Reading lexical weights from '"<<weightfile<<"' ... ";
|
| 39 |
+
|
| 40 |
+
while(!wfile.eof()) {
|
| 41 |
+
if(wfile.fail()) {
|
| 42 |
+
std::cerr << "Problem reading file: " << weightfile << std::endl;
|
| 43 |
+
exit(1);
|
| 44 |
+
}
|
| 45 |
+
String src, tgt;
|
| 46 |
+
Score weight;
|
| 47 |
+
|
| 48 |
+
wfile >> src >> tgt >> weight;
|
| 49 |
+
Count src_id = PhraseText::index_word(src);
|
| 50 |
+
Count tgt_id = PhraseText::index_word(tgt);
|
| 51 |
+
weight_map_.insert(std::make_pair(std::make_pair(src_id, tgt_id), weight));
|
| 52 |
+
}
|
| 53 |
+
|
| 54 |
+
wfile.close();
|
| 55 |
+
std::cerr<<"done."<<std::endl;
|
| 56 |
+
}
|
| 57 |
+
|
| 58 |
+
Score
|
| 59 |
+
LexicalDecompositionPhraseScorer::get_weight(const String &s_src, const String &s_tgt) const
|
| 60 |
+
{
|
| 61 |
+
//Code copied from LexicalWeightPhraseScorer; it should be factored !! -- 2010/01/27
|
| 62 |
+
|
| 63 |
+
Count src = PhraseText::index_word(s_src);
|
| 64 |
+
Count tgt = PhraseText::index_word(s_tgt);
|
| 65 |
+
return get_weight(src, tgt);
|
| 66 |
+
}
|
| 67 |
+
|
| 68 |
+
inline Score
|
| 69 |
+
LexicalDecompositionPhraseScorer::get_weight(Count src, Count tgt) const
|
| 70 |
+
{
|
| 71 |
+
//Code copied from LexicalWeightPhraseScorer; it should be factored !! -- 2010/01/27
|
| 72 |
+
|
| 73 |
+
WeightMapType_::const_iterator it = weight_map_.find(std::make_pair(src, tgt));
|
| 74 |
+
if(it == weight_map_.end())
|
| 75 |
+
return 0.00001; // default value copied from Philipp Koehn's scorer
|
| 76 |
+
return it->second;
|
| 77 |
+
}
|
| 78 |
+
|
| 79 |
+
void
|
| 80 |
+
LexicalDecompositionPhraseScorer::do_score_phrases()
|
| 81 |
+
{
|
| 82 |
+
|
| 83 |
+
//Estimate p(J|I) = p(src_len|tgt_len)
|
| 84 |
+
|
| 85 |
+
black_box_scorer->score_phrases();
|
| 86 |
+
|
| 87 |
+
std::cerr<<"LexicalDecompositionPhraseScorer::do_score_phrases"<<std::endl;
|
| 88 |
+
|
| 89 |
+
std::map<unsigned, std::map<unsigned, Count> > count_srclen_tgtlen;
|
| 90 |
+
std::map<unsigned, Count> total_tgtlen;
|
| 91 |
+
|
| 92 |
+
for(PhraseTable::iterator it = phrase_table_.begin(); it != phrase_table_.end(); it++) {
|
| 93 |
+
const PhrasePairInfo &ppair = *it;
|
| 94 |
+
PhraseInfo &src = phrase_table_.get_src_phrase(ppair.get_src());
|
| 95 |
+
PhraseInfo &tgt = phrase_table_.get_tgt_phrase(ppair.get_tgt());
|
| 96 |
+
unsigned src_len = src.get_phrase().size();
|
| 97 |
+
unsigned tgt_len = tgt.get_phrase().size();
|
| 98 |
+
|
| 99 |
+
/*//Debug code
|
| 100 |
+
for (unsigned i=0; i<src_len; i++)
|
| 101 |
+
std::cerr<<src.get_phrase().word(i)<<" ";
|
| 102 |
+
std::cerr<<"-> "<<src_len<<" ||| ";
|
| 103 |
+
for (unsigned i=0; i<tgt_len; i++)
|
| 104 |
+
std::cerr<<tgt.get_phrase().word(i)<<" ";
|
| 105 |
+
std::cerr<<"-> "<<tgt_len<<std::endl;
|
| 106 |
+
*/
|
| 107 |
+
|
| 108 |
+
count_srclen_tgtlen[src_len][tgt_len]+=ppair.get_count();
|
| 109 |
+
total_tgtlen[tgt_len]+=ppair.get_count();
|
| 110 |
+
}
|
| 111 |
+
|
| 112 |
+
std::map<unsigned, std::map<unsigned, Count> >::iterator its;
|
| 113 |
+
std::map<unsigned, Count>::iterator itt;
|
| 114 |
+
|
| 115 |
+
for (its=count_srclen_tgtlen.begin(); its!=count_srclen_tgtlen.end(); its++) {
|
| 116 |
+
unsigned src_len=its->first;
|
| 117 |
+
|
| 118 |
+
for(itt=its->second.begin(); itt!=its->second.end(); itt++) {
|
| 119 |
+
unsigned tgt_len=itt->first;
|
| 120 |
+
Count cnt=itt->second;
|
| 121 |
+
prob_srclen_tgtlen_[src_len][tgt_len] = static_cast<Score>(cnt)/static_cast<Score>(total_tgtlen[tgt_len]);
|
| 122 |
+
}
|
| 123 |
+
}
|
| 124 |
+
}
|
| 125 |
+
|
| 126 |
+
Score
|
| 127 |
+
LexicalDecompositionPhraseScorer::get_noisy_or_combination(Count src_word, PhraseInfo &tgt_phrase)
|
| 128 |
+
{
|
| 129 |
+
|
| 130 |
+
Score sc=1.0;
|
| 131 |
+
|
| 132 |
+
unsigned tgt_len=tgt_phrase.get_phrase().size();
|
| 133 |
+
|
| 134 |
+
for(unsigned i=0; i<tgt_len; i++) {
|
| 135 |
+
Count tgt_word=tgt_phrase.get_phrase()[i];
|
| 136 |
+
sc *= (1.0 - get_weight(src_word, tgt_word));
|
| 137 |
+
}
|
| 138 |
+
|
| 139 |
+
return (1.0 - sc);
|
| 140 |
+
}
|
| 141 |
+
|
| 142 |
+
Score
|
| 143 |
+
LexicalDecompositionPhraseScorer::do_get_score(const PhraseTable::const_iterator &it)
|
| 144 |
+
{
|
| 145 |
+
|
| 146 |
+
/*
|
| 147 |
+
The implementation of this method relies on the asumption that the
|
| 148 |
+
smoothed probabilities produced by AbsoluteDiscountPhraseScorer
|
| 149 |
+
are deficient.
|
| 150 |
+
*/
|
| 151 |
+
|
| 152 |
+
PhraseInfo &src_phrase = phrase_table_.get_src_phrase(it->get_src());
|
| 153 |
+
PhraseInfo &tgt_phrase = phrase_table_.get_tgt_phrase(it->get_tgt());
|
| 154 |
+
|
| 155 |
+
unsigned src_len=src_phrase.get_phrase().size();
|
| 156 |
+
unsigned tgt_len=tgt_phrase.get_phrase().size();
|
| 157 |
+
|
| 158 |
+
Score prod=1.0;
|
| 159 |
+
|
| 160 |
+
for(unsigned j=0; j<src_len; j++)
|
| 161 |
+
prod *= get_noisy_or_combination(src_phrase.get_phrase()[j], tgt_phrase);
|
| 162 |
+
|
| 163 |
+
Score lambda= static_cast<Score>(black_box_scorer->get_discount()) *
|
| 164 |
+
tgt_phrase.get_distinct() / tgt_phrase.get_count();
|
| 165 |
+
|
| 166 |
+
Score ret_value = black_box_scorer->get_score(it) + (lambda * prod * prob_srclen_tgtlen_[src_len][tgt_len]);
|
| 167 |
+
|
| 168 |
+
/*
|
| 169 |
+
//Debug code
|
| 170 |
+
for (unsigned i=0; i<src_len; i++)
|
| 171 |
+
std::cerr<<src_phrase.get_phrase().word(i)<<" ";
|
| 172 |
+
std::cerr<<" ||| ";
|
| 173 |
+
for (unsigned i=0; i<tgt_len; i++)
|
| 174 |
+
std::cerr<<tgt_phrase.get_phrase().word(i)<<" ";
|
| 175 |
+
std::cerr<<"==> discount: "<<black_box_scorer->get_discount()<<"; black box score: "<<black_box_scorer->get_score(it)
|
| 176 |
+
<<"; lambda: "<<lambda<<"; prod: "
|
| 177 |
+
<<prod<<"; prob_srclen_tgtlen_["<<src_len<<"]["<<tgt_len<<"]: "<<prob_srclen_tgtlen_[src_len][tgt_len]
|
| 178 |
+
<<"; count: "<<it->get_count()<<"; score: "<<ret_value;
|
| 179 |
+
std::cerr<<std::endl;
|
| 180 |
+
*/
|
| 181 |
+
|
| 182 |
+
return ret_value;
|
| 183 |
+
}
|
mosesdecoder/contrib/memscore/phraselm.cpp
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
// memscore - in-memory phrase scoring for Statistical Machine Translation
|
| 2 |
+
// Christian Hardmeier, FBK-irst, Trento, 2010
|
| 3 |
+
// $Id$
|
| 4 |
+
|
| 5 |
+
#include <cmath>
|
| 6 |
+
#include <iostream>
|
| 7 |
+
#include <fstream>
|
| 8 |
+
#include <sstream>
|
| 9 |
+
#include <string>
|
| 10 |
+
|
| 11 |
+
#include <n_gram.h>
|
| 12 |
+
#include <lmtable.h>
|
| 13 |
+
|
| 14 |
+
#include "phrasetable.h"
|
| 15 |
+
#include "phraselm.h"
|
| 16 |
+
|
| 17 |
+
void PhraseLanguageModel::attach(PhraseInfoList &pilist)
|
| 18 |
+
{
|
| 19 |
+
phrase_info_list_ = &pilist;
|
| 20 |
+
score_idx_ = pilist.register_data(1);
|
| 21 |
+
}
|
| 22 |
+
|
| 23 |
+
void PhraseLanguageModel::compute_statistic()
|
| 24 |
+
{
|
| 25 |
+
compute_lmscores(*phrase_info_list_, false);
|
| 26 |
+
}
|
| 27 |
+
|
| 28 |
+
void PhraseLanguageModel::compute_lmscores(PhraseInfoList &phrase_info_list, bool closed_world)
|
| 29 |
+
{
|
| 30 |
+
lmtable lm;
|
| 31 |
+
std::ifstream lmstream(lmfile_.c_str());
|
| 32 |
+
lm.load(lmstream, lmfile_.c_str(), NULL, 0);
|
| 33 |
+
lm.setlogOOVpenalty(10000000);
|
| 34 |
+
|
| 35 |
+
assert(!computation_done_);
|
| 36 |
+
|
| 37 |
+
Score marginal_score = .0;
|
| 38 |
+
for(PhraseInfoList::iterator it = phrase_info_list.begin(); it != phrase_info_list.end(); ++it) {
|
| 39 |
+
PhraseInfo &pi = *it;
|
| 40 |
+
ngram ng(lm.getDict());
|
| 41 |
+
Score lmscore = 0;
|
| 42 |
+
for(PhraseText::const_string_iterator it = pi.get_phrase().string_begin(); it != pi.get_phrase().string_end(); it++) {
|
| 43 |
+
ng.pushw(it->c_str());
|
| 44 |
+
lmscore += lm.clprob(ng);
|
| 45 |
+
}
|
| 46 |
+
|
| 47 |
+
pi.data(score_idx_) = exp10(lmscore);
|
| 48 |
+
marginal_score += pi.data(score_idx_);
|
| 49 |
+
}
|
| 50 |
+
|
| 51 |
+
if(closed_world)
|
| 52 |
+
for(PhraseInfoList::iterator it = phrase_info_list.begin(); it != phrase_info_list.end(); ++it) {
|
| 53 |
+
PhraseInfo &pi = *it;
|
| 54 |
+
pi.data(score_idx_) /= marginal_score;
|
| 55 |
+
}
|
| 56 |
+
|
| 57 |
+
computation_done_ = true;
|
| 58 |
+
}
|
| 59 |
+
|
| 60 |
+
void ClosedPhraseLanguageModel::compute_statistic()
|
| 61 |
+
{
|
| 62 |
+
compute_lmscores(*phrase_info_list_, true);
|
| 63 |
+
}
|
mosesdecoder/contrib/memscore/phrasetable.h
ADDED
|
@@ -0,0 +1,710 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
// memscore - in-memory phrase scoring for Statistical Machine Translation
|
| 2 |
+
// Christian Hardmeier, FBK-irst, Trento, 2010
|
| 3 |
+
// $Id$
|
| 4 |
+
|
| 5 |
+
#ifndef PHRASETABLE_H
|
| 6 |
+
#define PHRASETABLE_H
|
| 7 |
+
|
| 8 |
+
#include <cassert>
|
| 9 |
+
#include <iostream>
|
| 10 |
+
#include <iterator>
|
| 11 |
+
#include <list>
|
| 12 |
+
#include <map>
|
| 13 |
+
#include <set>
|
| 14 |
+
#include <string>
|
| 15 |
+
#include <vector>
|
| 16 |
+
|
| 17 |
+
#include <boost/bimap.hpp>
|
| 18 |
+
#include <boost/dynamic_bitset.hpp>
|
| 19 |
+
#include <boost/iterator/transform_iterator.hpp>
|
| 20 |
+
#include <boost/pool/object_pool.hpp>
|
| 21 |
+
#include <boost/pool/pool_alloc.hpp>
|
| 22 |
+
#include <boost/ptr_container/ptr_vector.hpp>
|
| 23 |
+
#include <boost/tuple/tuple.hpp>
|
| 24 |
+
#include <boost/tuple/tuple_comparison.hpp>
|
| 25 |
+
|
| 26 |
+
#include "datastorage.h"
|
| 27 |
+
#include "memscore.h"
|
| 28 |
+
|
| 29 |
+
class PhraseText
|
| 30 |
+
{
|
| 31 |
+
friend std::ostream &operator<<(std::ostream &os, const PhraseText &pt);
|
| 32 |
+
|
| 33 |
+
private:
|
| 34 |
+
typedef boost::ptr_vector<Count,boost::view_clone_allocator> WordListType_;
|
| 35 |
+
typedef boost::bimap<String,Count> DictionaryType_;
|
| 36 |
+
|
| 37 |
+
WordListType_ word_list_;
|
| 38 |
+
|
| 39 |
+
static DictionaryType_ dictionary_;
|
| 40 |
+
static Count last_id_;
|
| 41 |
+
|
| 42 |
+
typedef const String &(*LookupFunction_)(Count id);
|
| 43 |
+
|
| 44 |
+
public:
|
| 45 |
+
typedef WordListType_::const_iterator const_iterator;
|
| 46 |
+
typedef boost::transform_iterator<LookupFunction_,WordListType_::const_iterator> const_string_iterator;
|
| 47 |
+
typedef WordListType_::size_type size_type;
|
| 48 |
+
|
| 49 |
+
PhraseText(const String &s);
|
| 50 |
+
|
| 51 |
+
const_iterator begin() const {
|
| 52 |
+
return word_list_.begin();
|
| 53 |
+
}
|
| 54 |
+
|
| 55 |
+
const_iterator end() const {
|
| 56 |
+
return word_list_.end();
|
| 57 |
+
}
|
| 58 |
+
|
| 59 |
+
const_string_iterator string_begin() const {
|
| 60 |
+
return boost::make_transform_iterator(word_list_.begin(), dictionary_lookup);
|
| 61 |
+
}
|
| 62 |
+
|
| 63 |
+
const_string_iterator string_end() const {
|
| 64 |
+
return boost::make_transform_iterator(word_list_.end(), dictionary_lookup);
|
| 65 |
+
}
|
| 66 |
+
|
| 67 |
+
Count operator[](size_type i) const {
|
| 68 |
+
return word_list_[i];
|
| 69 |
+
}
|
| 70 |
+
|
| 71 |
+
const String &word(size_type i) const {
|
| 72 |
+
return dictionary_lookup(operator[](i));
|
| 73 |
+
}
|
| 74 |
+
|
| 75 |
+
size_type size() const {
|
| 76 |
+
return word_list_.size();
|
| 77 |
+
}
|
| 78 |
+
|
| 79 |
+
static const String &dictionary_lookup(Count id) {
|
| 80 |
+
DictionaryType_::right_const_iterator it = dictionary_.right.find(id);
|
| 81 |
+
assert(it != dictionary_.right.end());
|
| 82 |
+
return it->second;
|
| 83 |
+
}
|
| 84 |
+
|
| 85 |
+
static Count index_word(const String &word) {
|
| 86 |
+
Count id;
|
| 87 |
+
DictionaryType_::left_const_iterator it = dictionary_.left.find(word);
|
| 88 |
+
if(it != dictionary_.left.end())
|
| 89 |
+
id = it->second;
|
| 90 |
+
else {
|
| 91 |
+
id = last_id_++;
|
| 92 |
+
dictionary_.insert(DictionaryType_::value_type(word, id));
|
| 93 |
+
}
|
| 94 |
+
return id;
|
| 95 |
+
}
|
| 96 |
+
};
|
| 97 |
+
|
| 98 |
+
class PhraseInfo
|
| 99 |
+
{
|
| 100 |
+
friend class boost::object_pool<PhraseInfo>;
|
| 101 |
+
friend std::ostream &operator<<(std::ostream &os, const PhraseInfo &pt);
|
| 102 |
+
|
| 103 |
+
protected:
|
| 104 |
+
Count data_size_;
|
| 105 |
+
|
| 106 |
+
Count count_;
|
| 107 |
+
Count distinct_;
|
| 108 |
+
PhraseText phrase_;
|
| 109 |
+
Score *data_;
|
| 110 |
+
|
| 111 |
+
Count n1_;
|
| 112 |
+
Count n2_;
|
| 113 |
+
Count n3plus_;
|
| 114 |
+
|
| 115 |
+
PhraseInfo(Count data_size, const String &phrase) :
|
| 116 |
+
data_size_(data_size), count_(0), distinct_(0), phrase_(phrase), n1_(0), n2_(0), n3plus_(0) {
|
| 117 |
+
data_ = DataStorage<Score>::get_instance().alloc(data_size_);
|
| 118 |
+
}
|
| 119 |
+
|
| 120 |
+
public:
|
| 121 |
+
Score &data(Count base, Count i = 0) {
|
| 122 |
+
assert(base + i < data_size_);
|
| 123 |
+
return *(data_ + base + i);
|
| 124 |
+
}
|
| 125 |
+
|
| 126 |
+
const Score &data(Count base, Count i = 0) const {
|
| 127 |
+
assert(base + i < data_size_);
|
| 128 |
+
return *(data_ + base + i);
|
| 129 |
+
}
|
| 130 |
+
|
| 131 |
+
Count get_count() const {
|
| 132 |
+
return count_;
|
| 133 |
+
}
|
| 134 |
+
|
| 135 |
+
void inc_count() {
|
| 136 |
+
count_++;
|
| 137 |
+
}
|
| 138 |
+
|
| 139 |
+
Count get_distinct() const {
|
| 140 |
+
return distinct_;
|
| 141 |
+
}
|
| 142 |
+
|
| 143 |
+
void inc_distinct() {
|
| 144 |
+
distinct_++;
|
| 145 |
+
}
|
| 146 |
+
|
| 147 |
+
const PhraseText &get_phrase() const {
|
| 148 |
+
return phrase_;
|
| 149 |
+
}
|
| 150 |
+
|
| 151 |
+
void inc_n1() {
|
| 152 |
+
n1_++;
|
| 153 |
+
}
|
| 154 |
+
|
| 155 |
+
Count get_n1() {
|
| 156 |
+
return n1_;
|
| 157 |
+
}
|
| 158 |
+
|
| 159 |
+
void inc_n2() {
|
| 160 |
+
n2_++;
|
| 161 |
+
}
|
| 162 |
+
|
| 163 |
+
Count get_n2() {
|
| 164 |
+
return n2_;
|
| 165 |
+
}
|
| 166 |
+
|
| 167 |
+
void inc_n3plus() {
|
| 168 |
+
n3plus_++;
|
| 169 |
+
}
|
| 170 |
+
|
| 171 |
+
Count get_n3plus() {
|
| 172 |
+
return n3plus_;
|
| 173 |
+
}
|
| 174 |
+
|
| 175 |
+
};
|
| 176 |
+
|
| 177 |
+
inline std::ostream &operator<<(std::ostream &os, const PhraseInfo &pt)
|
| 178 |
+
{
|
| 179 |
+
return os << pt.get_phrase();
|
| 180 |
+
}
|
| 181 |
+
|
| 182 |
+
class PhraseInfoList
|
| 183 |
+
{
|
| 184 |
+
protected:
|
| 185 |
+
typedef std::map<String,Phrase> IDMapType_;
|
| 186 |
+
typedef boost::ptr_vector<PhraseInfo,boost::view_clone_allocator> ListType_;
|
| 187 |
+
//typedef std::vector<PhraseInfo *,boost::pool_allocator<PhraseInfo *> > ListType_;
|
| 188 |
+
//typedef std::vector<PhraseInfo> ListType_;
|
| 189 |
+
typedef std::list<PhraseStatistic *> StatListType_;
|
| 190 |
+
|
| 191 |
+
IDMapType_ idmap_;
|
| 192 |
+
ListType_ list_;
|
| 193 |
+
StatListType_ statistics_;
|
| 194 |
+
boost::object_pool<PhraseInfo> phrase_info_pool_;
|
| 195 |
+
|
| 196 |
+
Count data_size_;
|
| 197 |
+
public:
|
| 198 |
+
typedef ListType_::iterator iterator;
|
| 199 |
+
typedef ListType_::const_iterator const_iterator;
|
| 200 |
+
typedef ListType_::size_type size_type;
|
| 201 |
+
|
| 202 |
+
PhraseInfoList() : data_size_(0) {}
|
| 203 |
+
|
| 204 |
+
Phrase index_phrase(const String &s_phr);
|
| 205 |
+
DataIndex register_data(Count size);
|
| 206 |
+
void attach_statistic(PhraseStatistic &s);
|
| 207 |
+
void compute_statistics();
|
| 208 |
+
|
| 209 |
+
PhraseInfo &operator[](Phrase phr) {
|
| 210 |
+
return list_[phr];
|
| 211 |
+
}
|
| 212 |
+
|
| 213 |
+
iterator begin() {
|
| 214 |
+
return list_.begin();
|
| 215 |
+
}
|
| 216 |
+
|
| 217 |
+
iterator end() {
|
| 218 |
+
return list_.end();
|
| 219 |
+
}
|
| 220 |
+
|
| 221 |
+
const_iterator begin() const {
|
| 222 |
+
return list_.begin();
|
| 223 |
+
}
|
| 224 |
+
|
| 225 |
+
const_iterator end() const {
|
| 226 |
+
return list_.end();
|
| 227 |
+
}
|
| 228 |
+
|
| 229 |
+
size_type size() const {
|
| 230 |
+
return list_.size();
|
| 231 |
+
}
|
| 232 |
+
|
| 233 |
+
};
|
| 234 |
+
|
| 235 |
+
class PhraseAlignment
|
| 236 |
+
{
|
| 237 |
+
friend std::ostream &operator<<(std::ostream &os, const PhraseAlignment &pa);
|
| 238 |
+
|
| 239 |
+
private:
|
| 240 |
+
class Alignment
|
| 241 |
+
{
|
| 242 |
+
friend std::ostream &operator<<(std::ostream &os, const Alignment &pa);
|
| 243 |
+
|
| 244 |
+
private:
|
| 245 |
+
typedef boost::tuple<Count,Count,String> AlignmentTuple_;
|
| 246 |
+
typedef std::map<AlignmentTuple_,Count> AlignmentMapType_;
|
| 247 |
+
typedef std::vector<const Alignment *> AlignmentVectorType_;
|
| 248 |
+
|
| 249 |
+
static AlignmentMapType_ alignment_map_;
|
| 250 |
+
static AlignmentVectorType_ alignment_vector_;
|
| 251 |
+
|
| 252 |
+
Count slen_, tlen_;
|
| 253 |
+
boost::dynamic_bitset<unsigned int> matrix_;
|
| 254 |
+
|
| 255 |
+
Alignment(Count slen, Count tlen, const String &alignment);
|
| 256 |
+
|
| 257 |
+
public:
|
| 258 |
+
bool is_aligned(Count s, Count t) const {
|
| 259 |
+
assert(t < tlen_);
|
| 260 |
+
assert(s < slen_);
|
| 261 |
+
return matrix_[t * slen_ + s];
|
| 262 |
+
}
|
| 263 |
+
|
| 264 |
+
Count get_source_length() const {
|
| 265 |
+
return slen_;
|
| 266 |
+
}
|
| 267 |
+
|
| 268 |
+
Count get_target_length() const {
|
| 269 |
+
return tlen_;
|
| 270 |
+
}
|
| 271 |
+
|
| 272 |
+
bool operator<(const Alignment &pa) const {
|
| 273 |
+
if(slen_ < pa.slen_) return true;
|
| 274 |
+
if(tlen_ < pa.tlen_) return true;
|
| 275 |
+
return (matrix_ < pa.matrix_);
|
| 276 |
+
}
|
| 277 |
+
|
| 278 |
+
static Count index_alignment(Count slen, Count tlen, const String &alignment);
|
| 279 |
+
|
| 280 |
+
static const Alignment *find(Count index) {
|
| 281 |
+
return alignment_vector_[index];
|
| 282 |
+
}
|
| 283 |
+
};
|
| 284 |
+
friend std::ostream &operator<<(std::ostream &os, const Alignment &pa);
|
| 285 |
+
|
| 286 |
+
const Alignment *alignment_;
|
| 287 |
+
bool reverse_;
|
| 288 |
+
|
| 289 |
+
public:
|
| 290 |
+
PhraseAlignment(Count index, bool reverse = false) :
|
| 291 |
+
alignment_(Alignment::find(index)), reverse_(reverse) {}
|
| 292 |
+
|
| 293 |
+
bool is_aligned(Count s, Count t) const {
|
| 294 |
+
if(!reverse_)
|
| 295 |
+
return alignment_->is_aligned(s, t);
|
| 296 |
+
else
|
| 297 |
+
return alignment_->is_aligned(t, s);
|
| 298 |
+
}
|
| 299 |
+
|
| 300 |
+
Count get_source_length() const {
|
| 301 |
+
if(!reverse_)
|
| 302 |
+
return alignment_->get_source_length();
|
| 303 |
+
else
|
| 304 |
+
return alignment_->get_target_length();
|
| 305 |
+
}
|
| 306 |
+
|
| 307 |
+
Count get_target_length() const {
|
| 308 |
+
if(!reverse_)
|
| 309 |
+
return alignment_->get_target_length();
|
| 310 |
+
else
|
| 311 |
+
return alignment_->get_source_length();
|
| 312 |
+
}
|
| 313 |
+
|
| 314 |
+
static Count index_alignment(Count slen, Count tlen, const String &alignment) {
|
| 315 |
+
return Alignment::index_alignment(slen, tlen, alignment);
|
| 316 |
+
}
|
| 317 |
+
};
|
| 318 |
+
|
| 319 |
+
typedef std::map<PhrasePair,PhrasePairData> PhrasePairCounts;
|
| 320 |
+
|
| 321 |
+
class PhrasePairInfo
|
| 322 |
+
{
|
| 323 |
+
protected:
|
| 324 |
+
static const Count CONTINUATION_BIT;
|
| 325 |
+
|
| 326 |
+
static bool init_phase_;
|
| 327 |
+
static Count data_nscores_;
|
| 328 |
+
static Count data_ncounts_;
|
| 329 |
+
|
| 330 |
+
enum { COUNT_COUNT_IDX = 0, COUNT_FREE_IDX }; // COUNT_FREE_IDX must remain last!
|
| 331 |
+
enum { SCORE_FREE_IDX = 0 }; // SCORE_FREE_IDX must remain last!
|
| 332 |
+
|
| 333 |
+
Phrase src_, tgt_;
|
| 334 |
+
PhrasePairData data_;
|
| 335 |
+
bool reverse_;
|
| 336 |
+
|
| 337 |
+
void realloc_data(Count nalignments);
|
| 338 |
+
|
| 339 |
+
public:
|
| 340 |
+
typedef std::vector<std::pair<PhraseAlignment,Count> > AlignmentVector;
|
| 341 |
+
|
| 342 |
+
static DataIndex register_score_data(Count size);
|
| 343 |
+
static DataIndex register_count_data(Count size);
|
| 344 |
+
|
| 345 |
+
PhrasePairInfo(Count src, Count tgt, Count alignment, Count count);
|
| 346 |
+
|
| 347 |
+
PhrasePairInfo(Count src, Count tgt, PhrasePairData data, bool reverse = false) : src_(src), tgt_(tgt), data_(data), reverse_(reverse) {
|
| 348 |
+
init_phase_ = false;
|
| 349 |
+
}
|
| 350 |
+
|
| 351 |
+
PhrasePairInfo(const PhrasePairCounts::const_iterator &in) :
|
| 352 |
+
src_(in->first.first), tgt_(in->first.second), data_(in->second), reverse_(false) {}
|
| 353 |
+
|
| 354 |
+
PhrasePairData get_phrase_pair_data() {
|
| 355 |
+
return data_;
|
| 356 |
+
}
|
| 357 |
+
|
| 358 |
+
Phrase get_src() const {
|
| 359 |
+
return !reverse_ ? src_ : tgt_;
|
| 360 |
+
}
|
| 361 |
+
|
| 362 |
+
Phrase get_tgt() const {
|
| 363 |
+
return !reverse_ ? tgt_ : src_;
|
| 364 |
+
}
|
| 365 |
+
|
| 366 |
+
Count get_count() const {
|
| 367 |
+
return count_data(COUNT_COUNT_IDX);
|
| 368 |
+
}
|
| 369 |
+
|
| 370 |
+
Score &score_data(DataIndex base, DataIndex index = 0) {
|
| 371 |
+
return score_data(data_, base, index);
|
| 372 |
+
}
|
| 373 |
+
|
| 374 |
+
const Score &score_data(DataIndex base, DataIndex index = 0) const {
|
| 375 |
+
return score_data(data_, base, index);
|
| 376 |
+
}
|
| 377 |
+
|
| 378 |
+
Count &count_data(DataIndex base, DataIndex index = 0) {
|
| 379 |
+
return count_data(data_, base, index);
|
| 380 |
+
}
|
| 381 |
+
|
| 382 |
+
const Count &count_data(DataIndex base, DataIndex index = 0) const {
|
| 383 |
+
return count_data(data_, base, index);
|
| 384 |
+
}
|
| 385 |
+
|
| 386 |
+
void inc_count() {
|
| 387 |
+
count_data(data_, COUNT_COUNT_IDX)++;
|
| 388 |
+
}
|
| 389 |
+
|
| 390 |
+
AlignmentVector get_alignments() const;
|
| 391 |
+
void add_alignment(Count alignment);
|
| 392 |
+
|
| 393 |
+
private:
|
| 394 |
+
static Score &score_data(PhrasePairData data, DataIndex base, DataIndex index = 0) {
|
| 395 |
+
return *reinterpret_cast<Score *>(data + (base + index) * sizeof(Score));
|
| 396 |
+
}
|
| 397 |
+
|
| 398 |
+
static Count &count_data(PhrasePairData data, DataIndex base, DataIndex index = 0) {
|
| 399 |
+
return *reinterpret_cast<Count *>(data + data_nscores_ * sizeof(Score) + (base + index) * sizeof(Count));
|
| 400 |
+
}
|
| 401 |
+
|
| 402 |
+
static const Count COUNTS_PER_ALIGNMENT = 2;
|
| 403 |
+
|
| 404 |
+
static Count *alignment_data(PhrasePairData data, Count index) {
|
| 405 |
+
return reinterpret_cast<Count *>(data + data_nscores_ * sizeof(Score) + data_ncounts_ * sizeof(Count) + COUNTS_PER_ALIGNMENT * index * sizeof(Count));
|
| 406 |
+
}
|
| 407 |
+
|
| 408 |
+
Count *alignment_data(Count index) {
|
| 409 |
+
return alignment_data(data_, index);
|
| 410 |
+
}
|
| 411 |
+
|
| 412 |
+
const Count *alignment_data(Count index) const {
|
| 413 |
+
return alignment_data(data_, index);
|
| 414 |
+
}
|
| 415 |
+
};
|
| 416 |
+
|
| 417 |
+
class PhraseTable
|
| 418 |
+
{
|
| 419 |
+
public:
|
| 420 |
+
typedef PhrasePairInfo value_type;
|
| 421 |
+
|
| 422 |
+
protected:
|
| 423 |
+
typedef std::iterator_traits<PhrasePairCounts::iterator>::value_type InputEntry_;
|
| 424 |
+
typedef value_type (*EntryTransformer_)(InputEntry_);
|
| 425 |
+
|
| 426 |
+
static value_type pass_entry(InputEntry_ in) {
|
| 427 |
+
return PhrasePairInfo(in.first.first, in.first.second, in.second, false);
|
| 428 |
+
}
|
| 429 |
+
|
| 430 |
+
static value_type swap_src_tgt(InputEntry_ in) {
|
| 431 |
+
return PhrasePairInfo(in.first.first, in.first.second, in.second, true);
|
| 432 |
+
}
|
| 433 |
+
|
| 434 |
+
public:
|
| 435 |
+
typedef boost::transform_iterator<EntryTransformer_,PhrasePairCounts::iterator> iterator;
|
| 436 |
+
typedef boost::transform_iterator<EntryTransformer_,PhrasePairCounts::const_iterator> const_iterator;
|
| 437 |
+
|
| 438 |
+
virtual ~PhraseTable() {}
|
| 439 |
+
|
| 440 |
+
virtual PhraseInfo &get_src_phrase(Phrase src) = 0;
|
| 441 |
+
virtual Count n_src_phrases() const = 0;
|
| 442 |
+
virtual PhraseInfo &get_tgt_phrase(Phrase tgt) = 0;
|
| 443 |
+
virtual Count n_tgt_phrases() const = 0;
|
| 444 |
+
virtual PhrasePairCounts &get_joint_counts() = 0;
|
| 445 |
+
virtual void attach_src_statistic(PhraseStatistic &s) = 0;
|
| 446 |
+
virtual void attach_tgt_statistic(PhraseStatistic &s) = 0;
|
| 447 |
+
virtual void compute_phrase_statistics() = 0;
|
| 448 |
+
virtual DataIndex register_src_data(Count n) = 0;
|
| 449 |
+
virtual DataIndex register_tgt_data(Count n) = 0;
|
| 450 |
+
virtual PhraseTable &reverse() = 0;
|
| 451 |
+
|
| 452 |
+
virtual iterator begin() = 0;
|
| 453 |
+
virtual iterator end() = 0;
|
| 454 |
+
virtual iterator find(PhrasePair p) = 0;
|
| 455 |
+
virtual iterator find(const PhrasePairCounts::iterator &it) = 0;
|
| 456 |
+
|
| 457 |
+
virtual const_iterator begin() const = 0;
|
| 458 |
+
virtual const_iterator end() const = 0;
|
| 459 |
+
virtual const_iterator find(PhrasePair p) const = 0;
|
| 460 |
+
virtual const_iterator find(const PhrasePairCounts::const_iterator &it) const = 0;
|
| 461 |
+
|
| 462 |
+
virtual PhrasePairCounts::iterator raw_begin() = 0;
|
| 463 |
+
virtual PhrasePairCounts::iterator raw_end() = 0;
|
| 464 |
+
virtual PhrasePairCounts::iterator raw_find(PhrasePair p) = 0;
|
| 465 |
+
|
| 466 |
+
virtual PhrasePairCounts::const_iterator raw_begin() const = 0;
|
| 467 |
+
virtual PhrasePairCounts::const_iterator raw_end() const = 0;
|
| 468 |
+
virtual PhrasePairCounts::const_iterator raw_find(PhrasePair p) const = 0;
|
| 469 |
+
|
| 470 |
+
/*
|
| 471 |
+
static iterator swap_iterator(const iterator &it) {
|
| 472 |
+
if(it.functor() == swap_src_tgt)
|
| 473 |
+
return boost::make_transform_iterator(it.base(), pass_entry);
|
| 474 |
+
else if(it.functor() == pass_entry)
|
| 475 |
+
return boost::make_transform_iterator(it.base(), swap_src_tgt);
|
| 476 |
+
else
|
| 477 |
+
abort();
|
| 478 |
+
}
|
| 479 |
+
|
| 480 |
+
static const_iterator swap_iterator(const const_iterator &it) {
|
| 481 |
+
if(it.functor() == swap_src_tgt)
|
| 482 |
+
return boost::make_transform_iterator(it.base(), pass_entry);
|
| 483 |
+
else if(it.functor() == pass_entry)
|
| 484 |
+
return boost::make_transform_iterator(it.base(), swap_src_tgt);
|
| 485 |
+
else
|
| 486 |
+
abort();
|
| 487 |
+
}
|
| 488 |
+
*/
|
| 489 |
+
};
|
| 490 |
+
|
| 491 |
+
class ReversePhraseTable : public PhraseTable
|
| 492 |
+
{
|
| 493 |
+
protected:
|
| 494 |
+
PhraseTable &phrase_table_;
|
| 495 |
+
|
| 496 |
+
public:
|
| 497 |
+
ReversePhraseTable(PhraseTable &phrase_table) :
|
| 498 |
+
phrase_table_(phrase_table) {}
|
| 499 |
+
|
| 500 |
+
virtual PhraseInfo &get_src_phrase(Phrase src) {
|
| 501 |
+
return phrase_table_.get_tgt_phrase(src);
|
| 502 |
+
}
|
| 503 |
+
|
| 504 |
+
virtual Count n_src_phrases() const {
|
| 505 |
+
return phrase_table_.n_tgt_phrases();
|
| 506 |
+
}
|
| 507 |
+
|
| 508 |
+
virtual PhraseInfo &get_tgt_phrase(Phrase tgt) {
|
| 509 |
+
return phrase_table_.get_src_phrase(tgt);
|
| 510 |
+
}
|
| 511 |
+
|
| 512 |
+
virtual Count n_tgt_phrases() const {
|
| 513 |
+
return phrase_table_.n_src_phrases();
|
| 514 |
+
}
|
| 515 |
+
|
| 516 |
+
virtual PhrasePairCounts &get_joint_counts() {
|
| 517 |
+
return phrase_table_.get_joint_counts();
|
| 518 |
+
}
|
| 519 |
+
|
| 520 |
+
virtual void attach_src_statistic(PhraseStatistic &s) {
|
| 521 |
+
return phrase_table_.attach_tgt_statistic(s);
|
| 522 |
+
}
|
| 523 |
+
|
| 524 |
+
virtual void attach_tgt_statistic(PhraseStatistic &s) {
|
| 525 |
+
return phrase_table_.attach_src_statistic(s);
|
| 526 |
+
}
|
| 527 |
+
|
| 528 |
+
virtual void compute_phrase_statistics() {
|
| 529 |
+
phrase_table_.compute_phrase_statistics();
|
| 530 |
+
}
|
| 531 |
+
|
| 532 |
+
virtual DataIndex register_src_data(Count n) {
|
| 533 |
+
return phrase_table_.register_tgt_data(n);
|
| 534 |
+
}
|
| 535 |
+
|
| 536 |
+
virtual DataIndex register_tgt_data(Count n) {
|
| 537 |
+
return phrase_table_.register_src_data(n);
|
| 538 |
+
}
|
| 539 |
+
|
| 540 |
+
virtual PhraseTable &reverse() {
|
| 541 |
+
return phrase_table_;
|
| 542 |
+
}
|
| 543 |
+
|
| 544 |
+
virtual iterator begin() {
|
| 545 |
+
return boost::make_transform_iterator(phrase_table_.raw_begin(), swap_src_tgt);
|
| 546 |
+
}
|
| 547 |
+
|
| 548 |
+
virtual iterator end() {
|
| 549 |
+
return boost::make_transform_iterator(raw_end(), swap_src_tgt);
|
| 550 |
+
}
|
| 551 |
+
|
| 552 |
+
virtual iterator find(PhrasePair p) {
|
| 553 |
+
return boost::make_transform_iterator(raw_find(p), swap_src_tgt);
|
| 554 |
+
}
|
| 555 |
+
|
| 556 |
+
virtual iterator find(const PhrasePairCounts::iterator &it) {
|
| 557 |
+
return boost::make_transform_iterator(it, swap_src_tgt);
|
| 558 |
+
}
|
| 559 |
+
|
| 560 |
+
virtual const_iterator begin() const {
|
| 561 |
+
return boost::make_transform_iterator(phrase_table_.raw_begin(), swap_src_tgt);
|
| 562 |
+
}
|
| 563 |
+
|
| 564 |
+
virtual const_iterator end() const {
|
| 565 |
+
return boost::make_transform_iterator(raw_end(), swap_src_tgt);
|
| 566 |
+
}
|
| 567 |
+
|
| 568 |
+
virtual const_iterator find(PhrasePair p) const {
|
| 569 |
+
return boost::make_transform_iterator(raw_find(p), swap_src_tgt);
|
| 570 |
+
}
|
| 571 |
+
|
| 572 |
+
virtual const_iterator find(const PhrasePairCounts::const_iterator &it) const {
|
| 573 |
+
return boost::make_transform_iterator(it, swap_src_tgt);
|
| 574 |
+
}
|
| 575 |
+
|
| 576 |
+
virtual PhrasePairCounts::iterator raw_begin() {
|
| 577 |
+
return phrase_table_.raw_begin();
|
| 578 |
+
}
|
| 579 |
+
|
| 580 |
+
virtual PhrasePairCounts::iterator raw_end() {
|
| 581 |
+
return phrase_table_.raw_end();
|
| 582 |
+
}
|
| 583 |
+
|
| 584 |
+
virtual PhrasePairCounts::iterator raw_find(PhrasePair p) {
|
| 585 |
+
return phrase_table_.raw_find(std::make_pair(p.second, p.first));
|
| 586 |
+
}
|
| 587 |
+
|
| 588 |
+
virtual PhrasePairCounts::const_iterator raw_begin() const {
|
| 589 |
+
return phrase_table_.raw_begin();
|
| 590 |
+
}
|
| 591 |
+
|
| 592 |
+
virtual PhrasePairCounts::const_iterator raw_end() const {
|
| 593 |
+
return phrase_table_.raw_end();
|
| 594 |
+
}
|
| 595 |
+
|
| 596 |
+
virtual PhrasePairCounts::const_iterator raw_find(PhrasePair p) const {
|
| 597 |
+
return phrase_table_.raw_find(std::make_pair(p.second, p.first));
|
| 598 |
+
}
|
| 599 |
+
};
|
| 600 |
+
|
| 601 |
+
class MemoryPhraseTable : public PhraseTable
|
| 602 |
+
{
|
| 603 |
+
protected:
|
| 604 |
+
PhraseInfoList src_info_;
|
| 605 |
+
PhraseInfoList tgt_info_;
|
| 606 |
+
PhrasePairCounts joint_counts_;
|
| 607 |
+
|
| 608 |
+
ReversePhraseTable reverse_;
|
| 609 |
+
|
| 610 |
+
public:
|
| 611 |
+
MemoryPhraseTable() : reverse_(*this) {}
|
| 612 |
+
|
| 613 |
+
void load_data(std::istream &instream);
|
| 614 |
+
|
| 615 |
+
virtual PhraseInfo &get_src_phrase(Phrase src) {
|
| 616 |
+
assert(src < src_info_.size());
|
| 617 |
+
return src_info_[src];
|
| 618 |
+
}
|
| 619 |
+
|
| 620 |
+
virtual Count n_src_phrases() const {
|
| 621 |
+
return src_info_.size();
|
| 622 |
+
}
|
| 623 |
+
|
| 624 |
+
virtual PhraseInfo &get_tgt_phrase(Phrase tgt) {
|
| 625 |
+
assert(tgt < tgt_info_.size());
|
| 626 |
+
return tgt_info_[tgt];
|
| 627 |
+
}
|
| 628 |
+
|
| 629 |
+
virtual Count n_tgt_phrases() const {
|
| 630 |
+
return tgt_info_.size();
|
| 631 |
+
}
|
| 632 |
+
|
| 633 |
+
virtual PhrasePairCounts &get_joint_counts() {
|
| 634 |
+
return joint_counts_;
|
| 635 |
+
}
|
| 636 |
+
|
| 637 |
+
virtual void attach_src_statistic(PhraseStatistic &s);
|
| 638 |
+
virtual void attach_tgt_statistic(PhraseStatistic &s);
|
| 639 |
+
virtual void compute_phrase_statistics();
|
| 640 |
+
|
| 641 |
+
virtual DataIndex register_src_data(Count n) {
|
| 642 |
+
return src_info_.register_data(n);
|
| 643 |
+
}
|
| 644 |
+
|
| 645 |
+
virtual DataIndex register_tgt_data(Count n) {
|
| 646 |
+
return tgt_info_.register_data(n);
|
| 647 |
+
}
|
| 648 |
+
|
| 649 |
+
virtual PhraseTable &reverse() {
|
| 650 |
+
return reverse_;
|
| 651 |
+
}
|
| 652 |
+
|
| 653 |
+
virtual iterator begin() {
|
| 654 |
+
return boost::make_transform_iterator(raw_begin(), pass_entry);
|
| 655 |
+
}
|
| 656 |
+
|
| 657 |
+
virtual iterator end() {
|
| 658 |
+
return boost::make_transform_iterator(raw_end(), pass_entry);
|
| 659 |
+
}
|
| 660 |
+
|
| 661 |
+
virtual iterator find(PhrasePair p) {
|
| 662 |
+
return boost::make_transform_iterator(raw_find(p), pass_entry);
|
| 663 |
+
}
|
| 664 |
+
|
| 665 |
+
virtual iterator find(const PhrasePairCounts::iterator &it) {
|
| 666 |
+
return boost::make_transform_iterator(it, pass_entry);
|
| 667 |
+
}
|
| 668 |
+
|
| 669 |
+
virtual const_iterator begin() const {
|
| 670 |
+
return boost::make_transform_iterator(raw_begin(), pass_entry);
|
| 671 |
+
}
|
| 672 |
+
|
| 673 |
+
virtual const_iterator end() const {
|
| 674 |
+
return boost::make_transform_iterator(raw_end(), pass_entry);
|
| 675 |
+
}
|
| 676 |
+
|
| 677 |
+
virtual const_iterator find(PhrasePair p) const {
|
| 678 |
+
return boost::make_transform_iterator(raw_find(p), pass_entry);
|
| 679 |
+
}
|
| 680 |
+
|
| 681 |
+
virtual const_iterator find(const PhrasePairCounts::const_iterator &it) const {
|
| 682 |
+
return boost::make_transform_iterator(it, pass_entry);
|
| 683 |
+
}
|
| 684 |
+
|
| 685 |
+
virtual PhrasePairCounts::iterator raw_begin() {
|
| 686 |
+
return joint_counts_.begin();
|
| 687 |
+
}
|
| 688 |
+
|
| 689 |
+
virtual PhrasePairCounts::iterator raw_end() {
|
| 690 |
+
return joint_counts_.end();
|
| 691 |
+
}
|
| 692 |
+
|
| 693 |
+
virtual PhrasePairCounts::iterator raw_find(PhrasePair p) {
|
| 694 |
+
return joint_counts_.find(p);
|
| 695 |
+
}
|
| 696 |
+
|
| 697 |
+
virtual PhrasePairCounts::const_iterator raw_begin() const {
|
| 698 |
+
return joint_counts_.begin();
|
| 699 |
+
}
|
| 700 |
+
|
| 701 |
+
virtual PhrasePairCounts::const_iterator raw_end() const {
|
| 702 |
+
return joint_counts_.end();
|
| 703 |
+
}
|
| 704 |
+
|
| 705 |
+
virtual PhrasePairCounts::const_iterator raw_find(PhrasePair p) const {
|
| 706 |
+
return joint_counts_.find(p);
|
| 707 |
+
}
|
| 708 |
+
};
|
| 709 |
+
|
| 710 |
+
#endif
|
mosesdecoder/contrib/memscore/scorer-impl.h
ADDED
|
@@ -0,0 +1,124 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
// memscore - in-memory phrase scoring for Statistical Machine Translation
|
| 2 |
+
// Christian Hardmeier, FBK-irst, Trento, 2010
|
| 3 |
+
// $Id$
|
| 4 |
+
|
| 5 |
+
#ifndef SCORER_IMPL_H
|
| 6 |
+
#define SCORER_IMPL_H
|
| 7 |
+
|
| 8 |
+
#include "phrasetable.h"
|
| 9 |
+
#include "scorer.h"
|
| 10 |
+
|
| 11 |
+
class MLPhraseScorer : public PhraseScorer
|
| 12 |
+
{
|
| 13 |
+
private:
|
| 14 |
+
explicit MLPhraseScorer(PhraseTable &pd, bool reverse) :
|
| 15 |
+
PhraseScorer(pd, reverse) {}
|
| 16 |
+
|
| 17 |
+
virtual void do_score_phrases();
|
| 18 |
+
virtual Score do_get_score(const PhraseTable::const_iterator &it);
|
| 19 |
+
|
| 20 |
+
public:
|
| 21 |
+
static PhraseScorer *create_scorer(const char *argv[], int &argp, bool reverse, const PhraseScorerFactory &ptf);
|
| 22 |
+
};
|
| 23 |
+
|
| 24 |
+
class WittenBellPhraseScorer : public PhraseScorer
|
| 25 |
+
{
|
| 26 |
+
private:
|
| 27 |
+
explicit WittenBellPhraseScorer(PhraseTable &pd, bool reverse) :
|
| 28 |
+
PhraseScorer(pd, reverse) {}
|
| 29 |
+
|
| 30 |
+
virtual Score do_get_score(const PhraseTable::const_iterator &it);
|
| 31 |
+
|
| 32 |
+
public:
|
| 33 |
+
static PhraseScorer *create_scorer(const char *argv[], int &argp, bool reverse, const PhraseScorerFactory &ptf);
|
| 34 |
+
};
|
| 35 |
+
|
| 36 |
+
class AbsoluteDiscountPhraseScorer : public PhraseScorer
|
| 37 |
+
{
|
| 38 |
+
private:
|
| 39 |
+
Score discount_;
|
| 40 |
+
|
| 41 |
+
explicit AbsoluteDiscountPhraseScorer(PhraseTable &pd, bool reverse) :
|
| 42 |
+
PhraseScorer(pd, reverse) {}
|
| 43 |
+
|
| 44 |
+
virtual void do_score_phrases();
|
| 45 |
+
virtual Score do_get_score(const PhraseTable::const_iterator &it);
|
| 46 |
+
|
| 47 |
+
public:
|
| 48 |
+
Score get_discount();
|
| 49 |
+
static PhraseScorer *create_scorer(const char *argv[], int &argp, bool reverse, const PhraseScorerFactory &ptf);
|
| 50 |
+
};
|
| 51 |
+
|
| 52 |
+
class KNDiscount1PhraseScorer : public PhraseScorer
|
| 53 |
+
{
|
| 54 |
+
private:
|
| 55 |
+
Count total_distinct_;
|
| 56 |
+
Score discount_;
|
| 57 |
+
Count total_count_;
|
| 58 |
+
|
| 59 |
+
explicit KNDiscount1PhraseScorer(PhraseTable &pd, bool reverse) :
|
| 60 |
+
PhraseScorer(pd, reverse) {}
|
| 61 |
+
|
| 62 |
+
virtual void do_score_phrases();
|
| 63 |
+
virtual Score do_get_score(const PhraseTable::const_iterator &it);
|
| 64 |
+
|
| 65 |
+
public:
|
| 66 |
+
static PhraseScorer *create_scorer(const char *argv[], int &argp, bool reverse, const PhraseScorerFactory &ptf);
|
| 67 |
+
};
|
| 68 |
+
|
| 69 |
+
class KNDiscount3PhraseScorer : public PhraseScorer
|
| 70 |
+
{
|
| 71 |
+
private:
|
| 72 |
+
Score discount1_;
|
| 73 |
+
Score discount2_;
|
| 74 |
+
Score discount3plus_;
|
| 75 |
+
|
| 76 |
+
Count total_distinct_n1_;
|
| 77 |
+
Count total_distinct_n2_;
|
| 78 |
+
Count total_distinct_n3plus_;
|
| 79 |
+
|
| 80 |
+
explicit KNDiscount3PhraseScorer(PhraseTable &pd, bool reverse) :
|
| 81 |
+
PhraseScorer(pd, reverse) {}
|
| 82 |
+
|
| 83 |
+
virtual void do_score_phrases();
|
| 84 |
+
virtual Score do_get_score(const PhraseTable::const_iterator &it);
|
| 85 |
+
|
| 86 |
+
public:
|
| 87 |
+
static PhraseScorer *create_scorer(const char *argv[], int &argp, bool reverse, const PhraseScorerFactory &ptf);
|
| 88 |
+
};
|
| 89 |
+
|
| 90 |
+
class LexicalWeightPhraseScorer : public PhraseScorer
|
| 91 |
+
{
|
| 92 |
+
private:
|
| 93 |
+
typedef std::map<std::pair<Count,Count>,Score> WeightMapType_;
|
| 94 |
+
|
| 95 |
+
WeightMapType_ weight_map_;
|
| 96 |
+
bool overall_max_score_;
|
| 97 |
+
const Count null_word_;
|
| 98 |
+
|
| 99 |
+
LexicalWeightPhraseScorer(PhraseTable &pd, bool reverse, const String &weights, bool overall_max = true);
|
| 100 |
+
|
| 101 |
+
Score get_weight(const String &s_src, const String &s_tgt) const;
|
| 102 |
+
Score get_weight(Count src, Count tgt) const;
|
| 103 |
+
|
| 104 |
+
virtual void do_score_phrases();
|
| 105 |
+
virtual Score do_get_score(const PhraseTable::const_iterator &it);
|
| 106 |
+
|
| 107 |
+
public:
|
| 108 |
+
static PhraseScorer *create_scorer(const char *argv[], int &argp, bool reverse, const PhraseScorerFactory &ptf);
|
| 109 |
+
};
|
| 110 |
+
|
| 111 |
+
class ConstantPhraseScorer : public PhraseScorer
|
| 112 |
+
{
|
| 113 |
+
private:
|
| 114 |
+
Score constant_;
|
| 115 |
+
|
| 116 |
+
ConstantPhraseScorer(PhraseTable &pt, bool reverse, Score constant) : PhraseScorer(pt, reverse), constant_(constant) {}
|
| 117 |
+
|
| 118 |
+
virtual Score do_get_score(const PhraseTable::const_iterator &it);
|
| 119 |
+
|
| 120 |
+
public:
|
| 121 |
+
static PhraseScorer *create_scorer(const char *argv[], int &argp, bool reverse, const PhraseScorerFactory &ptf);
|
| 122 |
+
};
|
| 123 |
+
|
| 124 |
+
#endif
|
mosesdecoder/contrib/promix/README.md
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
promix - for training translation model interpolation weights using PRO
|
| 2 |
+
|
| 3 |
+
Author: Barry Haddow <bhaddow [AT] inf.ed.ac.uk>
|
| 4 |
+
|
| 5 |
+
ABOUT
|
| 6 |
+
-----
|
| 7 |
+
|
| 8 |
+
The code here provides the "inner loop" for a batch tuning algorithm (like MERT) which
|
| 9 |
+
optimises phrase table interpolation weights at the same time as the standard linear
|
| 10 |
+
model weights. Interpolation of the phrase tables uses the "naive" method of tmcombine.
|
| 11 |
+
|
| 12 |
+
Currently the interpolation only works for two phrase tables, but will soon
|
| 13 |
+
be extended to work for more than two.
|
| 14 |
+
|
| 15 |
+
|
| 16 |
+
REQUIREMENTS
|
| 17 |
+
------------
|
| 18 |
+
The scripts require the Moses Python interface (in contrib/python). It should be built
|
| 19 |
+
first, following the instructions in that directory.
|
| 20 |
+
|
| 21 |
+
The scripts also require scipy and numpy. They have been tested with the following versions:
|
| 22 |
+
|
| 23 |
+
* Python 2.7
|
| 24 |
+
* Scipy 0.11.0
|
| 25 |
+
* Numpy 1.6.2
|
| 26 |
+
|
| 27 |
+
Run the test.py script to check that everything is functioning correctly.
|
| 28 |
+
|
| 29 |
+
|
| 30 |
+
USAGE
|
| 31 |
+
-----
|
| 32 |
+
Since the code in this directory provides the inner loop for a batch tuning algorithm,
|
| 33 |
+
it is run from the increasingly inaccurately named mert-moses.pl. If you want to run
|
| 34 |
+
the optimiser directly, run `main.py -h` for usage.
|
| 35 |
+
|
| 36 |
+
A sample command for mert-moses.pl is as follows:
|
| 37 |
+
|
| 38 |
+
MOSES/scripts/training/mert-moses.pl \
|
| 39 |
+
input-file ref-file \
|
| 40 |
+
decoder \
|
| 41 |
+
ini-file \
|
| 42 |
+
--promix-training MOSES/contrib/promix/main.py \
|
| 43 |
+
--maximum-iterations 15 \
|
| 44 |
+
--promix-table phrase-table-1 \
|
| 45 |
+
--promix-table phrase-table-2 \
|
| 46 |
+
--filtercmd "MOSES/scripts/training/filter-model-given-input.pl --Binarizer MOSES/bin/processPhraseTable" \
|
| 47 |
+
--nbest 100 --working-dir ./tmp --decoder-flags "-threads 4 -v 0 " \
|
| 48 |
+
--rootdir MOSES/scripts -mertdir MOSES/bin \
|
| 49 |
+
--return-best-dev
|
| 50 |
+
|
| 51 |
+
Note that promix training requires a filter and binarise script, and that the phrase table
|
| 52 |
+
referenced in the ini file is not used. The argument `--return-best-dev` is not essential,
|
| 53 |
+
but recommended.
|
| 54 |
+
|
| 55 |
+
|
| 56 |
+
REFERENCES
|
| 57 |
+
----------
|
| 58 |
+
|
| 59 |
+
The code here was created for:
|
| 60 |
+
|
| 61 |
+
Haddow, Barry (2013) Applying Pairwise Ranked Optimisation to
|
| 62 |
+
Improve the Interpolation of Translation Models. In: Proceedings of NAACL 2013
|
| 63 |
+
|
| 64 |
+
See also:
|
| 65 |
+
|
| 66 |
+
Sennrich, Rico (2012). Perplexity Minimization for Translation Model Domain Adaptation in Statistical Machine Translation. In: Proceedings of EACL 2012.
|
mosesdecoder/contrib/promix/bleu.py
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env python
|
| 2 |
+
|
| 3 |
+
from math import exp,log
|
| 4 |
+
|
| 5 |
+
class BleuScoreException(Exception):
|
| 6 |
+
pass
|
| 7 |
+
|
| 8 |
+
class BleuScorer:
|
| 9 |
+
def __init__(self):
|
| 10 |
+
"""References should be a list. If each element is a string, assume
|
| 11 |
+
they are filenames, if a list, assume tokenised strings"""
|
| 12 |
+
self.smooth = 1.0
|
| 13 |
+
self.order = 4
|
| 14 |
+
|
| 15 |
+
def score(self,scores):
|
| 16 |
+
if len(scores) != self.order*2+1:
|
| 17 |
+
raise BleuScoreException("Wrong number of scores. Expected %d, but found %d" %
|
| 18 |
+
(self.order*2+1, len(scores)))
|
| 19 |
+
logbleu = 0.0
|
| 20 |
+
for j in range(self.order):
|
| 21 |
+
logbleu += log(scores[2*j] + self.smooth) - log(scores[2*j+1] + self.smooth)
|
| 22 |
+
logbleu /= self.order
|
| 23 |
+
brevity = 1.0 - float(scores[-1]) / scores[1]
|
| 24 |
+
if brevity < 0:
|
| 25 |
+
logbleu += brevity
|
| 26 |
+
return exp(logbleu)
|
| 27 |
+
|
mosesdecoder/contrib/promix/coll.py
ADDED
|
@@ -0,0 +1,260 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Backport of OrderedDict() class that runs on Python 2.4, 2.5, 2.6, 2.7 and pypy.
|
| 2 |
+
# Passes Python2.7's test suite and incorporates all the latest updates.
|
| 3 |
+
|
| 4 |
+
# From http://code.activestate.com/recipes/576693/
|
| 5 |
+
|
| 6 |
+
try:
|
| 7 |
+
from thread import get_ident as _get_ident
|
| 8 |
+
except ImportError:
|
| 9 |
+
from dummy_thread import get_ident as _get_ident
|
| 10 |
+
|
| 11 |
+
try:
|
| 12 |
+
from _abcoll import KeysView, ValuesView, ItemsView
|
| 13 |
+
except ImportError:
|
| 14 |
+
pass
|
| 15 |
+
|
| 16 |
+
|
| 17 |
+
class OrderedDict(dict):
|
| 18 |
+
'Dictionary that remembers insertion order'
|
| 19 |
+
# An inherited dict maps keys to values.
|
| 20 |
+
# The inherited dict provides __getitem__, __len__, __contains__, and get.
|
| 21 |
+
# The remaining methods are order-aware.
|
| 22 |
+
# Big-O running times for all methods are the same as for regular dictionaries.
|
| 23 |
+
|
| 24 |
+
# The internal self.__map dictionary maps keys to links in a doubly linked list.
|
| 25 |
+
# The circular doubly linked list starts and ends with a sentinel element.
|
| 26 |
+
# The sentinel element never gets deleted (this simplifies the algorithm).
|
| 27 |
+
# Each link is stored as a list of length three: [PREV, NEXT, KEY].
|
| 28 |
+
|
| 29 |
+
def __init__(self, *args, **kwds):
|
| 30 |
+
'''Initialize an ordered dictionary. Signature is the same as for
|
| 31 |
+
regular dictionaries, but keyword arguments are not recommended
|
| 32 |
+
because their insertion order is arbitrary.
|
| 33 |
+
|
| 34 |
+
'''
|
| 35 |
+
if len(args) > 1:
|
| 36 |
+
raise TypeError('expected at most 1 arguments, got %d' % len(args))
|
| 37 |
+
try:
|
| 38 |
+
self.__root
|
| 39 |
+
except AttributeError:
|
| 40 |
+
self.__root = root = [] # sentinel node
|
| 41 |
+
root[:] = [root, root, None]
|
| 42 |
+
self.__map = {}
|
| 43 |
+
self.__update(*args, **kwds)
|
| 44 |
+
|
| 45 |
+
def __setitem__(self, key, value, dict_setitem=dict.__setitem__):
|
| 46 |
+
'od.__setitem__(i, y) <==> od[i]=y'
|
| 47 |
+
# Setting a new item creates a new link which goes at the end of the linked
|
| 48 |
+
# list, and the inherited dictionary is updated with the new key/value pair.
|
| 49 |
+
if key not in self:
|
| 50 |
+
root = self.__root
|
| 51 |
+
last = root[0]
|
| 52 |
+
last[1] = root[0] = self.__map[key] = [last, root, key]
|
| 53 |
+
dict_setitem(self, key, value)
|
| 54 |
+
|
| 55 |
+
def __delitem__(self, key, dict_delitem=dict.__delitem__):
|
| 56 |
+
'od.__delitem__(y) <==> del od[y]'
|
| 57 |
+
# Deleting an existing item uses self.__map to find the link which is
|
| 58 |
+
# then removed by updating the links in the predecessor and successor nodes.
|
| 59 |
+
dict_delitem(self, key)
|
| 60 |
+
link_prev, link_next, key = self.__map.pop(key)
|
| 61 |
+
link_prev[1] = link_next
|
| 62 |
+
link_next[0] = link_prev
|
| 63 |
+
|
| 64 |
+
def __iter__(self):
|
| 65 |
+
'od.__iter__() <==> iter(od)'
|
| 66 |
+
root = self.__root
|
| 67 |
+
curr = root[1]
|
| 68 |
+
while curr is not root:
|
| 69 |
+
yield curr[2]
|
| 70 |
+
curr = curr[1]
|
| 71 |
+
|
| 72 |
+
def __reversed__(self):
|
| 73 |
+
'od.__reversed__() <==> reversed(od)'
|
| 74 |
+
root = self.__root
|
| 75 |
+
curr = root[0]
|
| 76 |
+
while curr is not root:
|
| 77 |
+
yield curr[2]
|
| 78 |
+
curr = curr[0]
|
| 79 |
+
|
| 80 |
+
def clear(self):
|
| 81 |
+
'od.clear() -> None. Remove all items from od.'
|
| 82 |
+
try:
|
| 83 |
+
for node in self.__map.itervalues():
|
| 84 |
+
del node[:]
|
| 85 |
+
root = self.__root
|
| 86 |
+
root[:] = [root, root, None]
|
| 87 |
+
self.__map.clear()
|
| 88 |
+
except AttributeError:
|
| 89 |
+
pass
|
| 90 |
+
dict.clear(self)
|
| 91 |
+
|
| 92 |
+
def popitem(self, last=True):
|
| 93 |
+
'''od.popitem() -> (k, v), return and remove a (key, value) pair.
|
| 94 |
+
Pairs are returned in LIFO order if last is true or FIFO order if false.
|
| 95 |
+
|
| 96 |
+
'''
|
| 97 |
+
if not self:
|
| 98 |
+
raise KeyError('dictionary is empty')
|
| 99 |
+
root = self.__root
|
| 100 |
+
if last:
|
| 101 |
+
link = root[0]
|
| 102 |
+
link_prev = link[0]
|
| 103 |
+
link_prev[1] = root
|
| 104 |
+
root[0] = link_prev
|
| 105 |
+
else:
|
| 106 |
+
link = root[1]
|
| 107 |
+
link_next = link[1]
|
| 108 |
+
root[1] = link_next
|
| 109 |
+
link_next[0] = root
|
| 110 |
+
key = link[2]
|
| 111 |
+
del self.__map[key]
|
| 112 |
+
value = dict.pop(self, key)
|
| 113 |
+
return key, value
|
| 114 |
+
|
| 115 |
+
# -- the following methods do not depend on the internal structure --
|
| 116 |
+
|
| 117 |
+
def keys(self):
|
| 118 |
+
'od.keys() -> list of keys in od'
|
| 119 |
+
return list(self)
|
| 120 |
+
|
| 121 |
+
def values(self):
|
| 122 |
+
'od.values() -> list of values in od'
|
| 123 |
+
return [self[key] for key in self]
|
| 124 |
+
|
| 125 |
+
def items(self):
|
| 126 |
+
'od.items() -> list of (key, value) pairs in od'
|
| 127 |
+
return [(key, self[key]) for key in self]
|
| 128 |
+
|
| 129 |
+
def iterkeys(self):
|
| 130 |
+
'od.iterkeys() -> an iterator over the keys in od'
|
| 131 |
+
return iter(self)
|
| 132 |
+
|
| 133 |
+
def itervalues(self):
|
| 134 |
+
'od.itervalues -> an iterator over the values in od'
|
| 135 |
+
for k in self:
|
| 136 |
+
yield self[k]
|
| 137 |
+
|
| 138 |
+
def iteritems(self):
|
| 139 |
+
'od.iteritems -> an iterator over the (key, value) items in od'
|
| 140 |
+
for k in self:
|
| 141 |
+
yield (k, self[k])
|
| 142 |
+
|
| 143 |
+
def update(*args, **kwds):
|
| 144 |
+
'''od.update(E, **F) -> None. Update od from dict/iterable E and F.
|
| 145 |
+
|
| 146 |
+
If E is a dict instance, does: for k in E: od[k] = E[k]
|
| 147 |
+
If E has a .keys() method, does: for k in E.keys(): od[k] = E[k]
|
| 148 |
+
Or if E is an iterable of items, does: for k, v in E: od[k] = v
|
| 149 |
+
In either case, this is followed by: for k, v in F.items(): od[k] = v
|
| 150 |
+
|
| 151 |
+
'''
|
| 152 |
+
if len(args) > 2:
|
| 153 |
+
raise TypeError('update() takes at most 2 positional '
|
| 154 |
+
'arguments (%d given)' % (len(args),))
|
| 155 |
+
elif not args:
|
| 156 |
+
raise TypeError('update() takes at least 1 argument (0 given)')
|
| 157 |
+
self = args[0]
|
| 158 |
+
# Make progressively weaker assumptions about "other"
|
| 159 |
+
other = ()
|
| 160 |
+
if len(args) == 2:
|
| 161 |
+
other = args[1]
|
| 162 |
+
if isinstance(other, dict):
|
| 163 |
+
for key in other:
|
| 164 |
+
self[key] = other[key]
|
| 165 |
+
elif hasattr(other, 'keys'):
|
| 166 |
+
for key in other.keys():
|
| 167 |
+
self[key] = other[key]
|
| 168 |
+
else:
|
| 169 |
+
for key, value in other:
|
| 170 |
+
self[key] = value
|
| 171 |
+
for key, value in kwds.items():
|
| 172 |
+
self[key] = value
|
| 173 |
+
|
| 174 |
+
__update = update # let subclasses override update without breaking __init__
|
| 175 |
+
|
| 176 |
+
__marker = object()
|
| 177 |
+
|
| 178 |
+
def pop(self, key, default=__marker):
|
| 179 |
+
'''od.pop(k[,d]) -> v, remove specified key and return the corresponding value.
|
| 180 |
+
If key is not found, d is returned if given, otherwise KeyError is raised.
|
| 181 |
+
|
| 182 |
+
'''
|
| 183 |
+
if key in self:
|
| 184 |
+
result = self[key]
|
| 185 |
+
del self[key]
|
| 186 |
+
return result
|
| 187 |
+
if default is self.__marker:
|
| 188 |
+
raise KeyError(key)
|
| 189 |
+
return default
|
| 190 |
+
|
| 191 |
+
def setdefault(self, key, default=None):
|
| 192 |
+
'od.setdefault(k[,d]) -> od.get(k,d), also set od[k]=d if k not in od'
|
| 193 |
+
if key in self:
|
| 194 |
+
return self[key]
|
| 195 |
+
self[key] = default
|
| 196 |
+
return default
|
| 197 |
+
|
| 198 |
+
def __repr__(self, _repr_running={}):
|
| 199 |
+
'od.__repr__() <==> repr(od)'
|
| 200 |
+
call_key = id(self), _get_ident()
|
| 201 |
+
if call_key in _repr_running:
|
| 202 |
+
return '...'
|
| 203 |
+
_repr_running[call_key] = 1
|
| 204 |
+
try:
|
| 205 |
+
if not self:
|
| 206 |
+
return '%s()' % (self.__class__.__name__,)
|
| 207 |
+
return '%s(%r)' % (self.__class__.__name__, self.items())
|
| 208 |
+
finally:
|
| 209 |
+
del _repr_running[call_key]
|
| 210 |
+
|
| 211 |
+
def __reduce__(self):
|
| 212 |
+
'Return state information for pickling'
|
| 213 |
+
items = [[k, self[k]] for k in self]
|
| 214 |
+
inst_dict = vars(self).copy()
|
| 215 |
+
for k in vars(OrderedDict()):
|
| 216 |
+
inst_dict.pop(k, None)
|
| 217 |
+
if inst_dict:
|
| 218 |
+
return (self.__class__, (items,), inst_dict)
|
| 219 |
+
return self.__class__, (items,)
|
| 220 |
+
|
| 221 |
+
def copy(self):
|
| 222 |
+
'od.copy() -> a shallow copy of od'
|
| 223 |
+
return self.__class__(self)
|
| 224 |
+
|
| 225 |
+
@classmethod
|
| 226 |
+
def fromkeys(cls, iterable, value=None):
|
| 227 |
+
'''OD.fromkeys(S[, v]) -> New ordered dictionary with keys from S
|
| 228 |
+
and values equal to v (which defaults to None).
|
| 229 |
+
|
| 230 |
+
'''
|
| 231 |
+
d = cls()
|
| 232 |
+
for key in iterable:
|
| 233 |
+
d[key] = value
|
| 234 |
+
return d
|
| 235 |
+
|
| 236 |
+
def __eq__(self, other):
|
| 237 |
+
'''od.__eq__(y) <==> od==y. Comparison to another OD is order-sensitive
|
| 238 |
+
while comparison to a regular mapping is order-insensitive.
|
| 239 |
+
|
| 240 |
+
'''
|
| 241 |
+
if isinstance(other, OrderedDict):
|
| 242 |
+
return len(self)==len(other) and self.items() == other.items()
|
| 243 |
+
return dict.__eq__(self, other)
|
| 244 |
+
|
| 245 |
+
def __ne__(self, other):
|
| 246 |
+
return not self == other
|
| 247 |
+
|
| 248 |
+
# -- the following methods are only used in Python 2.7 --
|
| 249 |
+
|
| 250 |
+
def viewkeys(self):
|
| 251 |
+
"od.viewkeys() -> a set-like object providing a view on od's keys"
|
| 252 |
+
return KeysView(self)
|
| 253 |
+
|
| 254 |
+
def viewvalues(self):
|
| 255 |
+
"od.viewvalues() -> an object providing a view on od's values"
|
| 256 |
+
return ValuesView(self)
|
| 257 |
+
|
| 258 |
+
def viewitems(self):
|
| 259 |
+
"od.viewitems() -> a set-like object providing a view on od's items"
|
| 260 |
+
return ItemsView(self)
|
mosesdecoder/contrib/promix/main.py
ADDED
|
@@ -0,0 +1,112 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env python
|
| 2 |
+
|
| 3 |
+
#
|
| 4 |
+
# Implementation of PRO training and extensions to train phrase weights
|
| 5 |
+
#
|
| 6 |
+
|
| 7 |
+
import gzip
|
| 8 |
+
import logging
|
| 9 |
+
from numpy import array
|
| 10 |
+
import optparse
|
| 11 |
+
import os.path
|
| 12 |
+
import sys
|
| 13 |
+
|
| 14 |
+
from nbest import *
|
| 15 |
+
from sampler import *
|
| 16 |
+
from train import *
|
| 17 |
+
|
| 18 |
+
|
| 19 |
+
logging.basicConfig(format = "%(asctime)-15s %(message)s")
|
| 20 |
+
log = logging.getLogger('main')
|
| 21 |
+
log.setLevel(logging.DEBUG)
|
| 22 |
+
|
| 23 |
+
class Config:
|
| 24 |
+
def __init__(self):
|
| 25 |
+
self.parser = optparse.OptionParser(usage="%prog [options] ")
|
| 26 |
+
self.parser.add_option("-t", "--trainer", action="store",\
|
| 27 |
+
dest="trainer", metavar="TYPE", type="choice", choices=("pro","mix"),\
|
| 28 |
+
default="pro",\
|
| 29 |
+
help="type of trainer to run (pro,mix)")
|
| 30 |
+
self.parser.add_option("-n", "--nbest", action="append", \
|
| 31 |
+
dest="nbest", metavar="NBEST-FILE",\
|
| 32 |
+
help="nbest output file(s) from decoder")
|
| 33 |
+
self.parser.add_option("-S", "--scfile", action="append",\
|
| 34 |
+
dest="score", metavar="SCORE-FILE",\
|
| 35 |
+
help="score file(s) from extractor (in same order as nbests)")
|
| 36 |
+
self.parser.add_option("-p", "--phrase-table" , action="append",\
|
| 37 |
+
dest="ttable", metavar="TTABLE",\
|
| 38 |
+
help="ttable to be used in mixture model training")
|
| 39 |
+
self.parser.add_option("-i", "--input-file", action="store",\
|
| 40 |
+
dest="input_file", metavar="INPUT-FILE",
|
| 41 |
+
help="source text file")
|
| 42 |
+
self.parser.add_option("-m", "--moses-bin-dir", action="store",\
|
| 43 |
+
dest="moses_bin_dir", metavar="DIR",
|
| 44 |
+
help="directory containing Moses binaries",
|
| 45 |
+
default=os.path.expanduser("~/moses/bin"))
|
| 46 |
+
self.nbest_files = []
|
| 47 |
+
self.score_files = []
|
| 48 |
+
self.ttables = []
|
| 49 |
+
|
| 50 |
+
def parse(self,args=sys.argv[1:]):
|
| 51 |
+
(options,args) = self.parser.parse_args(args)
|
| 52 |
+
self.nbest_files = options.nbest
|
| 53 |
+
self.score_files = options.score
|
| 54 |
+
self.ttables = options.ttable
|
| 55 |
+
self.input_file = options.input_file
|
| 56 |
+
self.trainer = options.trainer
|
| 57 |
+
self.moses_bin_dir = options.moses_bin_dir
|
| 58 |
+
if not self.nbest_files:
|
| 59 |
+
self.nbest_files = ["data/esen.nc.nbest.segment"]
|
| 60 |
+
if not self.score_files:
|
| 61 |
+
self.score_files = ["data/esen.nc.scores"]
|
| 62 |
+
if len(self.nbest_files) != len(self.score_files):
|
| 63 |
+
self.parser.error("Must have equal numbers of score files and nbest files")
|
| 64 |
+
if self.trainer == "mix":
|
| 65 |
+
if not self.input_file or not self.ttables:
|
| 66 |
+
self.parser.error("Need to specify input file and ttables for mix training")
|
| 67 |
+
#if len(self.ttables) != 2:
|
| 68 |
+
# self.parser.error("Can only train mix model with 2 ttables at the moment")
|
| 69 |
+
|
| 70 |
+
def main():
|
| 71 |
+
config = Config()
|
| 72 |
+
config.parse()
|
| 73 |
+
|
| 74 |
+
samples = []
|
| 75 |
+
sampler = HopkinsMaySampler()
|
| 76 |
+
nbests = 0
|
| 77 |
+
for nbest_file,score_data_file in zip(config.nbest_files,config.score_files):
|
| 78 |
+
log.debug("nbest: " + nbest_file + "; score:" + score_data_file)
|
| 79 |
+
segments = False
|
| 80 |
+
if config.trainer == "mix": segments = True
|
| 81 |
+
for nbest in get_scored_nbests(nbest_file, score_data_file, config.input_file, segments=segments):
|
| 82 |
+
samples += sampler.sample(nbest)
|
| 83 |
+
nbests += 1
|
| 84 |
+
log.debug("Samples loaded")
|
| 85 |
+
trainer = None
|
| 86 |
+
if config.trainer == "mix":
|
| 87 |
+
# Add the phrase table scores
|
| 88 |
+
scorer = MosesPhraseScorer(config.ttables)
|
| 89 |
+
log.debug("Scoring samples...")
|
| 90 |
+
for sample in samples:
|
| 91 |
+
scorer.add_scores(sample.hyp1)
|
| 92 |
+
scorer.add_scores(sample.hyp2)
|
| 93 |
+
log.debug("...samples scored")
|
| 94 |
+
trainer = MixtureModelTrainer(samples)
|
| 95 |
+
elif config.trainer == "pro":
|
| 96 |
+
trainer = ProTrainer(samples)
|
| 97 |
+
else: assert(0)
|
| 98 |
+
log.debug("Starting training...")
|
| 99 |
+
weights,mix_weights = trainer.train(debug=False)
|
| 100 |
+
log.debug("...training complete")
|
| 101 |
+
for i,w in enumerate(weights):
|
| 102 |
+
print "F%d %10.8f" % (i,w)
|
| 103 |
+
for i,f in enumerate(mix_weights):
|
| 104 |
+
for j,w in enumerate(f):
|
| 105 |
+
print "M%d_%d %10.8f" % (i,j,w)
|
| 106 |
+
|
| 107 |
+
|
| 108 |
+
|
| 109 |
+
|
| 110 |
+
|
| 111 |
+
if __name__ == "__main__":
|
| 112 |
+
main()
|
mosesdecoder/contrib/promix/nbest.py
ADDED
|
@@ -0,0 +1,230 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env python
|
| 2 |
+
|
| 3 |
+
import gzip
|
| 4 |
+
import os
|
| 5 |
+
import re
|
| 6 |
+
import numpy as np
|
| 7 |
+
import sys
|
| 8 |
+
|
| 9 |
+
from bleu import BleuScorer
|
| 10 |
+
from coll import OrderedDict
|
| 11 |
+
# Edit to set moses python path
|
| 12 |
+
sys.path.append(os.path.dirname(__file__) + "/../python")
|
| 13 |
+
import moses.dictree as binpt
|
| 14 |
+
|
| 15 |
+
class DataFormatException(Exception):
|
| 16 |
+
pass
|
| 17 |
+
|
| 18 |
+
class Hypothesis:
|
| 19 |
+
def __init__(self,text,fv,segments=False):
|
| 20 |
+
self.alignment = [] #only stored for segmented hypos
|
| 21 |
+
self.tokens = [] #only stored for segmented hypos
|
| 22 |
+
if not segments:
|
| 23 |
+
self.text = text
|
| 24 |
+
# Triples of (source-start, source-end, target-end) where segments end positions
|
| 25 |
+
# are 1 beyond the last token
|
| 26 |
+
else:
|
| 27 |
+
# recover segmentation
|
| 28 |
+
self.tokens = []
|
| 29 |
+
align_re = re.compile("\|(\d+)-(\d+)\|")
|
| 30 |
+
for token in text.split():
|
| 31 |
+
match = align_re.match(token)
|
| 32 |
+
if match:
|
| 33 |
+
self.alignment.append\
|
| 34 |
+
((int(match.group(1)), 1+int(match.group(2)), len(self.tokens)))
|
| 35 |
+
else:
|
| 36 |
+
self.tokens.append(token)
|
| 37 |
+
self.text = " ".join(self.tokens)
|
| 38 |
+
if not self.alignment:
|
| 39 |
+
raise DataFormatException("Expected segmentation information not found in nbest")
|
| 40 |
+
|
| 41 |
+
|
| 42 |
+
self.fv = np.array(fv)
|
| 43 |
+
self.score = 0
|
| 44 |
+
|
| 45 |
+
def __str__(self):
|
| 46 |
+
return "{text=%s fv=%s score=%5.4f}" % (self.text, str(self.fv), self.score)
|
| 47 |
+
|
| 48 |
+
class NBestList:
|
| 49 |
+
def __init__(self,id):
|
| 50 |
+
self.id = id
|
| 51 |
+
self.hyps = []
|
| 52 |
+
|
| 53 |
+
# Maps feature ids (short feature names) to their values
|
| 54 |
+
_feature_index = {}
|
| 55 |
+
def set_feature_start(name,index):
|
| 56 |
+
indexes = _feature_index.get(name, [index,0])
|
| 57 |
+
indexes[0] = index
|
| 58 |
+
_feature_index[name] = indexes
|
| 59 |
+
|
| 60 |
+
def set_feature_end(name,index):
|
| 61 |
+
indexes = _feature_index.get(name, [0,index])
|
| 62 |
+
indexes[1] = index
|
| 63 |
+
_feature_index[name] = indexes
|
| 64 |
+
|
| 65 |
+
def get_feature_index(name):
|
| 66 |
+
return _feature_index.get(name, [0,0])
|
| 67 |
+
|
| 68 |
+
def get_nbests(nbest_file, segments=False):
|
| 69 |
+
"""Iterate through nbest lists"""
|
| 70 |
+
if nbest_file.endswith("gz"):
|
| 71 |
+
fh = gzip.GzipFile(nbest_file)
|
| 72 |
+
else:
|
| 73 |
+
fh = open(nbest_file)
|
| 74 |
+
lineno = 0
|
| 75 |
+
nbest = None
|
| 76 |
+
for line in fh:
|
| 77 |
+
fields = line.split(" ||| ")
|
| 78 |
+
if len(fields) != 4:
|
| 79 |
+
raise DataFormatException("nbest(%d): %s" % (lineno,line))
|
| 80 |
+
(id, text, scores, total) = fields
|
| 81 |
+
if nbest and nbest.id != id:
|
| 82 |
+
yield nbest
|
| 83 |
+
nbest = None
|
| 84 |
+
if not nbest:
|
| 85 |
+
nbest = NBestList(id)
|
| 86 |
+
fv = []
|
| 87 |
+
score_name = None
|
| 88 |
+
for score in scores.split():
|
| 89 |
+
if score.endswith(":"):
|
| 90 |
+
score = score[:-1]
|
| 91 |
+
if score_name:
|
| 92 |
+
set_feature_end(score_name,len(fv))
|
| 93 |
+
score_name = score
|
| 94 |
+
set_feature_start(score_name,len(fv))
|
| 95 |
+
else:
|
| 96 |
+
fv.append(float(score))
|
| 97 |
+
if score_name: set_feature_end(score_name,len(fv))
|
| 98 |
+
hyp = Hypothesis(text[:-1],fv,segments)
|
| 99 |
+
nbest.hyps.append(hyp)
|
| 100 |
+
if nbest:
|
| 101 |
+
yield nbest
|
| 102 |
+
|
| 103 |
+
def get_scores(score_data_file):
|
| 104 |
+
"""Iterate through the score data, returning a set of scores for each sentence"""
|
| 105 |
+
scorer = BleuScorer()
|
| 106 |
+
fh = open(score_data_file)
|
| 107 |
+
lineno = 0
|
| 108 |
+
score_vectors = None
|
| 109 |
+
for line in fh:
|
| 110 |
+
if line.startswith("SCORES_TXT_BEGIN"):
|
| 111 |
+
score_vectors = []
|
| 112 |
+
elif line.startswith("SCORES_TXT_END"):
|
| 113 |
+
scores = [scorer.score(score_vector) for score_vector in score_vectors]
|
| 114 |
+
yield scores
|
| 115 |
+
else:
|
| 116 |
+
score_vectors.append([float(i) for i in line[:-1].split()])
|
| 117 |
+
|
| 118 |
+
|
| 119 |
+
def get_scored_nbests(nbest_file, score_data_file, input_file, segments=False):
|
| 120 |
+
score_gen = get_scores(score_data_file)
|
| 121 |
+
input_gen = None
|
| 122 |
+
if input_file: input_gen = open(input_file)
|
| 123 |
+
try:
|
| 124 |
+
for nbest in get_nbests(nbest_file, segments=segments):
|
| 125 |
+
scores = score_gen.next()
|
| 126 |
+
if len(scores) != len(nbest.hyps):
|
| 127 |
+
raise DataFormatException("Length of nbest %s does not match score list (%d != %d)" %
|
| 128 |
+
(nbest.id,len(nbest.hyps), len(scores)))
|
| 129 |
+
input_line = None
|
| 130 |
+
if input_gen:
|
| 131 |
+
input_line = input_gen.next()[:-1]
|
| 132 |
+
for hyp,score in zip(nbest.hyps, scores):
|
| 133 |
+
hyp.score = score
|
| 134 |
+
hyp.input_line = input_line
|
| 135 |
+
yield nbest
|
| 136 |
+
|
| 137 |
+
except StopIteration:
|
| 138 |
+
raise DataFormatException("Score file shorter than nbest list file")
|
| 139 |
+
|
| 140 |
+
class PhraseCache:
|
| 141 |
+
"""An LRU cache for ttable lookups"""
|
| 142 |
+
def __init__(self, max_size):
|
| 143 |
+
self.max_size = max_size
|
| 144 |
+
self.pairs_to_scores = OrderedDict()
|
| 145 |
+
|
| 146 |
+
def get(self, source, target):
|
| 147 |
+
key = (source,target)
|
| 148 |
+
scores = self.pairs_to_scores.get(key,None)
|
| 149 |
+
if scores:
|
| 150 |
+
# cache hit - update access time
|
| 151 |
+
del self.pairs_to_scores[key]
|
| 152 |
+
self.pairs_to_scores[key] = scores
|
| 153 |
+
return scores
|
| 154 |
+
|
| 155 |
+
def add(self,source,target,scores):
|
| 156 |
+
key = (source,target)
|
| 157 |
+
self.pairs_to_scores[key] = scores
|
| 158 |
+
while len(self.pairs_to_scores) > self.max_size:
|
| 159 |
+
self.pairs_to_scores.popitem(last=False)
|
| 160 |
+
|
| 161 |
+
#
|
| 162 |
+
# Should I store full lists of options, or just phrase pairs?
|
| 163 |
+
# Should probably store phrase-pairs, but may want to add
|
| 164 |
+
# high scoring pairs (say, 20?) when I load the translations
|
| 165 |
+
# of a given phrase
|
| 166 |
+
#
|
| 167 |
+
|
| 168 |
+
class CachedPhraseTable:
|
| 169 |
+
def __init__(self,ttable_file,nscores=5,cache_size=20000):
|
| 170 |
+
wa = False
|
| 171 |
+
if binpt.PhraseDictionaryTree.canLoad(ttable_file,True):
|
| 172 |
+
# assume word alignment is included
|
| 173 |
+
wa = True
|
| 174 |
+
self.ttable = binpt.PhraseDictionaryTree(ttable_file,nscores = nscores,wa = wa, tableLimit=0)
|
| 175 |
+
self.cache = PhraseCache(cache_size)
|
| 176 |
+
self.nscores = nscores
|
| 177 |
+
|
| 178 |
+
def get_scores(self,phrase):
|
| 179 |
+
source = " ".join(phrase[0])
|
| 180 |
+
target_tuple = tuple(phrase[1])
|
| 181 |
+
target = " ".join(target_tuple)
|
| 182 |
+
scores = self.cache.get(source,target)
|
| 183 |
+
if not scores:
|
| 184 |
+
# cache miss
|
| 185 |
+
scores = [0] * (self.nscores-1) # ignore penalty
|
| 186 |
+
entries = self.ttable.query(source, converter=None)
|
| 187 |
+
# find correct target
|
| 188 |
+
for entry in entries:
|
| 189 |
+
if entry.rhs == target_tuple:
|
| 190 |
+
scores = entry.scores[:-1]
|
| 191 |
+
break
|
| 192 |
+
#print "QUERY",source,"|||",target,"|||",scores
|
| 193 |
+
self.cache.add(source,target,scores)
|
| 194 |
+
#else:
|
| 195 |
+
# print "CACHE",source,"|||",target,"|||",scores
|
| 196 |
+
return scores
|
| 197 |
+
|
| 198 |
+
|
| 199 |
+
class MosesPhraseScorer:
|
| 200 |
+
def __init__(self,ttable_files, cache_size=20000):
|
| 201 |
+
self.ttables = []
|
| 202 |
+
for ttable_file in ttable_files:
|
| 203 |
+
self.ttables.append(CachedPhraseTable(ttable_file, cache_size=cache_size))
|
| 204 |
+
|
| 205 |
+
def add_scores(self, hyp):
|
| 206 |
+
"""Add the phrase scores to a hypothesis"""
|
| 207 |
+
# Collect up the phrase pairs
|
| 208 |
+
phrases = []
|
| 209 |
+
source_tokens = hyp.input_line.split()
|
| 210 |
+
tgt_st = 0
|
| 211 |
+
if not hyp.alignment:
|
| 212 |
+
raise DataFormatException("Alignments missing from: " + str(hyp))
|
| 213 |
+
for src_st,src_end,tgt_end in hyp.alignment:
|
| 214 |
+
phrases.append((source_tokens[src_st:src_end], hyp.tokens[tgt_st:tgt_end]))
|
| 215 |
+
tgt_st = tgt_end
|
| 216 |
+
# Look up the scores
|
| 217 |
+
phrase_scores = []
|
| 218 |
+
for ttable in self.ttables:
|
| 219 |
+
phrase_scores.append([])
|
| 220 |
+
for phrase in phrases:
|
| 221 |
+
phrase_scores[-1].append(ttable.get_scores(phrase))
|
| 222 |
+
# phrase_scores = np.array(phrase_scores)
|
| 223 |
+
# eps = np.exp(-100)
|
| 224 |
+
# phrase_scores[phrase_scores<eps]=eps
|
| 225 |
+
floor = np.exp(-100)
|
| 226 |
+
phrase_scores = np.clip(np.array(phrase_scores), floor, np.inf)
|
| 227 |
+
hyp.phrase_scores = phrase_scores
|
| 228 |
+
|
| 229 |
+
|
| 230 |
+
|
mosesdecoder/contrib/promix/test.py
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env python
|
| 2 |
+
|
| 3 |
+
import unittest
|
| 4 |
+
|
| 5 |
+
import test_bleu
|
| 6 |
+
import test_main
|
| 7 |
+
import test_moses
|
| 8 |
+
import test_nbest
|
| 9 |
+
import test_sampler
|
| 10 |
+
import test_train
|
| 11 |
+
|
| 12 |
+
def main():
|
| 13 |
+
test_list = []
|
| 14 |
+
test_list.append(test_bleu.suite)
|
| 15 |
+
test_list.append(test_main.suite)
|
| 16 |
+
# test_list.append(test_moses.suite)
|
| 17 |
+
test_list.append(test_nbest.suite)
|
| 18 |
+
test_list.append(test_sampler.suite)
|
| 19 |
+
test_list.append(test_train.suite)
|
| 20 |
+
|
| 21 |
+
suite = unittest.TestSuite(test_list)
|
| 22 |
+
unittest.TextTestRunner().run(suite)
|
| 23 |
+
|
| 24 |
+
if __name__ == "__main__":
|
| 25 |
+
main()
|
mosesdecoder/contrib/promix/test_sampler.py
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env python
|
| 2 |
+
|
| 3 |
+
import random
|
| 4 |
+
import unittest
|
| 5 |
+
|
| 6 |
+
from nbest import *
|
| 7 |
+
from sampler import *
|
| 8 |
+
|
| 9 |
+
|
| 10 |
+
class TestNBestSampler(unittest.TestCase):
|
| 11 |
+
|
| 12 |
+
def setUp(self):
|
| 13 |
+
self.h1 = Hypothesis("a",[])
|
| 14 |
+
self.h2 = Hypothesis("b",[])
|
| 15 |
+
self.h3 = Hypothesis("c",[])
|
| 16 |
+
self.nbest = NBestList(1)
|
| 17 |
+
self.nbest.hyps.append(self.h1)
|
| 18 |
+
self.nbest.hyps.append(self.h2)
|
| 19 |
+
self.nbest.hyps.append(self.h3)
|
| 20 |
+
self.sampler = HopkinsMaySampler()
|
| 21 |
+
|
| 22 |
+
def test_nsamples(self):
|
| 23 |
+
self.h1.score = 0.1
|
| 24 |
+
self.h2.score = 0.2
|
| 25 |
+
self.h3.score = 0.3
|
| 26 |
+
samples = self.sampler.sample(self.nbest)
|
| 27 |
+
self.assertEqual(len(samples), self.sampler.nsamples)
|
| 28 |
+
|
| 29 |
+
def test_biggest(self):
|
| 30 |
+
random.seed(0)
|
| 31 |
+
self.h1.score = 0.1
|
| 32 |
+
self.h2.score = 0.2
|
| 33 |
+
self.h3.score = 0.3
|
| 34 |
+
samples = self.sampler.sample(self.nbest)
|
| 35 |
+
for sample in samples:
|
| 36 |
+
self.assertAlmostEqual(sample.diff,0.2)
|
| 37 |
+
|
| 38 |
+
def test_score_diff(self):
|
| 39 |
+
self.h1.score = 0.1
|
| 40 |
+
self.h2.score = 0.1 + (0.9*self.sampler.min_diff)
|
| 41 |
+
self.h3.score = 0.1 + (1.8*self.sampler.min_diff)
|
| 42 |
+
|
| 43 |
+
# Should only see pairs with h1,h3
|
| 44 |
+
samples = self.sampler.sample(self.nbest)
|
| 45 |
+
for sample in samples:
|
| 46 |
+
self.assertTrue((sample.hyp1 == self.h1 and sample.hyp2 == self.h3) or \
|
| 47 |
+
(sample.hyp2 == self.h1 and sample.hyp1 == self.h3))
|
| 48 |
+
|
| 49 |
+
|
| 50 |
+
if __name__ == "__main__":
|
| 51 |
+
unittest.main()
|
| 52 |
+
|
| 53 |
+
suite = unittest.TestLoader().loadTestsFromTestCase(TestNBestSampler)
|
mosesdecoder/contrib/promix/test_train.py
ADDED
|
@@ -0,0 +1,306 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env python
|
| 2 |
+
|
| 3 |
+
import unittest
|
| 4 |
+
|
| 5 |
+
from math import log,exp
|
| 6 |
+
|
| 7 |
+
import nbest
|
| 8 |
+
import numpy.testing as nptest
|
| 9 |
+
import sampler
|
| 10 |
+
from train import *
|
| 11 |
+
import util
|
| 12 |
+
|
| 13 |
+
class TestParabaloidOptimiser(unittest.TestCase):
|
| 14 |
+
def setUp(self):
|
| 15 |
+
self.o = ParabaloidOptimiser(np.array([1,2,3,4]))
|
| 16 |
+
|
| 17 |
+
def test_parabaloid_bfgs(self):
|
| 18 |
+
start = np.array([2,2,2,2])
|
| 19 |
+
minimum = self.o.optimise_bfgs(start)
|
| 20 |
+
for m in minimum:
|
| 21 |
+
self.assertAlmostEqual(m,0)
|
| 22 |
+
|
| 23 |
+
|
| 24 |
+
def test_parabaloid_lbfgs(self):
|
| 25 |
+
start = np.array([2,2,2,2])
|
| 26 |
+
minimum = self.o.optimise_lbfgs(start)
|
| 27 |
+
for m in minimum:
|
| 28 |
+
self.assertAlmostEqual(m,0)
|
| 29 |
+
|
| 30 |
+
class TestLogisticRegressionOptimiser(unittest.TestCase):
|
| 31 |
+
|
| 32 |
+
def test_objective(self):
|
| 33 |
+
x = np.array([[1], [0]])
|
| 34 |
+
y = np.array([1,-1])
|
| 35 |
+
lro = LogisticRegressionOptimiser(x,y)
|
| 36 |
+
w = np.array([2])
|
| 37 |
+
expected = -log(1 / (1 + exp(-2))) - log(0.5)
|
| 38 |
+
self.assertAlmostEqual(lro.objective(w), expected)
|
| 39 |
+
|
| 40 |
+
def test_reg_objective(self):
|
| 41 |
+
x = np.array([[1], [0]])
|
| 42 |
+
y = np.array([1,-1])
|
| 43 |
+
alpha = 0.1
|
| 44 |
+
lro = LogisticRegressionOptimiser(x,y,alpha)
|
| 45 |
+
w = np.array([2])
|
| 46 |
+
expected = -log(1 / (1 + exp(-2))) - log(0.5) + 0.5*2*2 * alpha
|
| 47 |
+
self.assertAlmostEqual(lro.objective(w), expected)
|
| 48 |
+
|
| 49 |
+
def test_gradient_j(self):
|
| 50 |
+
x = np.array([[1], [0]])
|
| 51 |
+
y = np.array([1,-1])
|
| 52 |
+
lro = LogisticRegressionOptimiser(x,y)
|
| 53 |
+
w = np.array([2])
|
| 54 |
+
expected = -1 / (1 + exp(2))
|
| 55 |
+
self.assertAlmostEqual(lro.grad_j(w,0), expected)
|
| 56 |
+
|
| 57 |
+
def test_gradient(self):
|
| 58 |
+
x = np.array([[1,1], [0,1]])
|
| 59 |
+
y = np.array([1,-1])
|
| 60 |
+
w = np.array([2,1])
|
| 61 |
+
lro = LogisticRegressionOptimiser(x,y)
|
| 62 |
+
e0 = -1 / (1 + exp(3))
|
| 63 |
+
e1 = -1 / (1 + exp(3)) + 1/ (1 + exp(-1))
|
| 64 |
+
actual = lro.grad(w)
|
| 65 |
+
#print "expected: ",e0,e1
|
| 66 |
+
self.assertAlmostEqual(actual[0], e0)
|
| 67 |
+
self.assertAlmostEqual(actual[1], e1)
|
| 68 |
+
|
| 69 |
+
def test_reg_gradient(self):
|
| 70 |
+
x = np.array([[1,1], [0,1]])
|
| 71 |
+
y = np.array([1,-1])
|
| 72 |
+
alpha = 0.2
|
| 73 |
+
w = np.array([2,1])
|
| 74 |
+
lro = LogisticRegressionOptimiser(x,y, alpha)
|
| 75 |
+
e0 = -1 / (1 + exp(3)) + w[0]*alpha
|
| 76 |
+
e1 = -1 / (1 + exp(3)) + 1/ (1 + exp(-1)) +w[1]*alpha
|
| 77 |
+
actual = lro.grad(w)
|
| 78 |
+
self.assertAlmostEqual(actual[0], e0)
|
| 79 |
+
self.assertAlmostEqual(actual[1], e1)
|
| 80 |
+
|
| 81 |
+
|
| 82 |
+
def test_train(self):
|
| 83 |
+
x = np.array([[1,1],[-1,-2]])
|
| 84 |
+
y = np.array([1,-1])
|
| 85 |
+
w0 = np.array([1,-1])
|
| 86 |
+
lro = LogisticRegressionOptimiser(x,y)
|
| 87 |
+
actual = lro.train(w0, debug=False)
|
| 88 |
+
self.assertAlmostEqual(actual[0], 12.03882542)
|
| 89 |
+
self.assertAlmostEqual(actual[1], 8.02317419)
|
| 90 |
+
|
| 91 |
+
def test_train_reg(self):
|
| 92 |
+
x = np.array([[1,1],[-1,1]])
|
| 93 |
+
y = np.array([1,-1])
|
| 94 |
+
alpha = 0.1
|
| 95 |
+
w0 = np.array([1,-1])
|
| 96 |
+
lro = LogisticRegressionOptimiser(x,y,alpha)
|
| 97 |
+
actual = lro.train(w0, debug=False)
|
| 98 |
+
self.assertAlmostEqual(actual[1],0) # 2nd input should be ignored
|
| 99 |
+
# classify first example as negative, second as positive
|
| 100 |
+
self.assertTrue(1 / (1+exp(-np.dot(actual,np.array([1,1])))) > 0.5)
|
| 101 |
+
self.assertTrue(1 / (1+exp(-np.dot(actual,np.array([-1,-2])))) < 0.5)
|
| 102 |
+
|
| 103 |
+
def test_xy(self):
|
| 104 |
+
"""Test pre-calculation of the y_i*x_ij vectors"""
|
| 105 |
+
x = np.array([[1,3], [2,8], [1,3]])
|
| 106 |
+
y = np.array([1,1,-1])
|
| 107 |
+
lro = LogisticRegressionOptimiser(x,y)
|
| 108 |
+
expected = np.array([[1,3], [2,8], [-1,-3]])
|
| 109 |
+
for i in 0,1,2:
|
| 110 |
+
for j in 0,1:
|
| 111 |
+
self.assertEqual(lro.xy[i][j], expected[i][j])
|
| 112 |
+
#
|
| 113 |
+
class TestMixtureModelTrainer(unittest.TestCase):
|
| 114 |
+
|
| 115 |
+
def setUp(self):
|
| 116 |
+
# 3 phrase table features, but last one is ignored for interpolation
|
| 117 |
+
nbest._feature_index = {"tm" : [0,3], "lm" : [3,4]}
|
| 118 |
+
log05 = np.log(0.5)
|
| 119 |
+
log03 = np.log(0.3)
|
| 120 |
+
log02 = np.log(0.2)
|
| 121 |
+
log01 = np.log(0.1)
|
| 122 |
+
hyp0 = nbest.Hypothesis("a |0-0| b c |1-2|", [log05, log05, log02, log03], True)
|
| 123 |
+
hyp0.input_line = "A B C"
|
| 124 |
+
hyp0.score = 3
|
| 125 |
+
# Two ttables, columns correspond to features, rows to phrase pairs
|
| 126 |
+
hyp0.phrase_scores = np.array([\
|
| 127 |
+
[[0.2, 0.3],\
|
| 128 |
+
[0.4, 0.3]],\
|
| 129 |
+
[[0, 0.2],\
|
| 130 |
+
[0.4,0.2]]])
|
| 131 |
+
|
| 132 |
+
hyp1 = nbest.Hypothesis("x |0-2|", [log02, log03, log03, log01], True)
|
| 133 |
+
hyp1.input_line = "X Y Z"
|
| 134 |
+
hyp1.score = 2
|
| 135 |
+
hyp1.phrase_scores = np.array([\
|
| 136 |
+
[[0.1, 0.1]],\
|
| 137 |
+
[[0.8,0.1]]])
|
| 138 |
+
|
| 139 |
+
hyp2 = nbest.Hypothesis("z |0-1| w |2-2| p |3-3|", [log02, log02, log05, log05], True)
|
| 140 |
+
hyp2.score = 1
|
| 141 |
+
hyp2.input_line = "M N O"
|
| 142 |
+
# phrase_table x phrase_pair x feature
|
| 143 |
+
hyp2.phrase_scores = np.array([\
|
| 144 |
+
[[0.1, 0.2],\
|
| 145 |
+
[0.3,0.5],\
|
| 146 |
+
[0.4,0.6]],\
|
| 147 |
+
[[0.1,0.5],\
|
| 148 |
+
[0.6,0.1],\
|
| 149 |
+
[0.2,0.2]]])
|
| 150 |
+
self.samples = [sampler.Sample(hyp0,hyp1), sampler.Sample(hyp1,hyp2)]
|
| 151 |
+
self.trainer = MixtureModelTrainer(self.samples)
|
| 152 |
+
|
| 153 |
+
def get_phrase_scores(self, hypothesis, iw):
|
| 154 |
+
nptest.assert_almost_equal(np.sum(iw, axis=0), np.array([1.0,1.0]))
|
| 155 |
+
phrase_probs = hypothesis.phrase_scores
|
| 156 |
+
interpolated_probs = np.sum(np.expand_dims(iw,1)*phrase_probs, axis = 0)
|
| 157 |
+
|
| 158 |
+
total_probs = np.prod(interpolated_probs, axis = 0)
|
| 159 |
+
return util.safelog(total_probs)
|
| 160 |
+
|
| 161 |
+
def model_score(self, hypothesis, weights):
|
| 162 |
+
# interpolation weights
|
| 163 |
+
# ttable x feature
|
| 164 |
+
iw = np.array([[weights[-2], weights[-1]],
|
| 165 |
+
[1-weights[-2],1-weights[-1]]])
|
| 166 |
+
#print "iw:",iw
|
| 167 |
+
phrase_scores = self.get_phrase_scores(hypothesis,iw)
|
| 168 |
+
weighted_phrase_scores = weights[:2] * phrase_scores
|
| 169 |
+
score = np.sum(weighted_phrase_scores)
|
| 170 |
+
|
| 171 |
+
other_score = np.sum(weights[2:4]*hypothesis.fv[2:4])
|
| 172 |
+
return score + other_score
|
| 173 |
+
|
| 174 |
+
|
| 175 |
+
def test_objective(self):
|
| 176 |
+
# 2 phrase weights, 2 other feature weights,
|
| 177 |
+
# 2 interpolation weights (1 per model x 2 phrase features)
|
| 178 |
+
weights = np.array([0.2,0.1,0.4,0.5,0.3,0.6])
|
| 179 |
+
actual = self.trainer.objective(weights)
|
| 180 |
+
# Expected objective is the sum of the logs of sigmoids of the score differences
|
| 181 |
+
# Weighted by 1 if hyp1 > hyp2, -1 otherwise
|
| 182 |
+
expected = 0
|
| 183 |
+
for sample in self.samples:
|
| 184 |
+
hyp1_model_score = self.model_score(sample.hyp1, weights)
|
| 185 |
+
hyp2_model_score = self.model_score(sample.hyp2, weights)
|
| 186 |
+
y = 1
|
| 187 |
+
if sample.hyp2.score > sample.hyp1.score: y = -1
|
| 188 |
+
expected -= log(sigmoid(y * (hyp1_model_score - hyp2_model_score)))
|
| 189 |
+
# regularisation
|
| 190 |
+
expected += 0.5 * self.trainer.alpha * np.dot(weights[:-2], weights[:-2])
|
| 191 |
+
self.assertAlmostEquals(actual,expected)
|
| 192 |
+
|
| 193 |
+
def test_gradient_other(self):
|
| 194 |
+
# Gradients are just differences in feature vectors
|
| 195 |
+
# fv(hypo0)-fv(hyp1), fv(hyp1)-fv(hyp2)
|
| 196 |
+
delta_s = np.vstack((self.samples[0].hyp1.fv-self.samples[0].hyp2.fv,\
|
| 197 |
+
self.samples[1].hyp1.fv-self.samples[1].hyp2.fv))
|
| 198 |
+
# feature functions across rows, samples down columns
|
| 199 |
+
# choose other features
|
| 200 |
+
other_delta_s = delta_s[:,2:]
|
| 201 |
+
actual = self.trainer.gradient_other()
|
| 202 |
+
nptest.assert_almost_equal(actual,other_delta_s)
|
| 203 |
+
|
| 204 |
+
def test_gradient_phrase(self):
|
| 205 |
+
iw = np.array([[0.3, 0.4],[0.7,0.6]])
|
| 206 |
+
sample_deltaf_list = []
|
| 207 |
+
for sample in self.samples:
|
| 208 |
+
f_A = self.get_phrase_scores(sample.hyp1, iw)
|
| 209 |
+
f_B = self.get_phrase_scores(sample.hyp2, iw)
|
| 210 |
+
sample_deltaf_list.append(f_A - f_B)
|
| 211 |
+
expected = np.vstack(sample_deltaf_list) # samples down, features along
|
| 212 |
+
actual = self.trainer.gradient_phrase(iw)
|
| 213 |
+
nptest.assert_almost_equal(actual,expected)
|
| 214 |
+
|
| 215 |
+
def test_gradient_interp(self):
|
| 216 |
+
# The interpolation weights - ttable x feature
|
| 217 |
+
iw = np.array([[0.3, 0.4],[0.7,0.6]])
|
| 218 |
+
phrasew = np.array([1,2]) # The phrase weights
|
| 219 |
+
num_ttables = iw.shape[0]
|
| 220 |
+
num_phrase_features = iw.shape[1]
|
| 221 |
+
bysample_list = []
|
| 222 |
+
# Stack up gradients for each sample
|
| 223 |
+
for sample in self.samples:
|
| 224 |
+
# Get the gradient of the interpolation weights for each
|
| 225 |
+
# hypothesis (A and B) in the sample
|
| 226 |
+
byhyp = []
|
| 227 |
+
for hyp in [sample.hyp1,sample.hyp2]:
|
| 228 |
+
# the weights are flattened. rows of iw joined together, last row omitted
|
| 229 |
+
grad_k = np.array([0.0] * ((num_ttables - 1) * num_phrase_features))
|
| 230 |
+
# Iterate through the phrase features
|
| 231 |
+
for j,probs in enumerate(np.transpose(hyp.phrase_scores)):
|
| 232 |
+
# j is phrase feature index
|
| 233 |
+
# probs is phrase-pair, ttable
|
| 234 |
+
grad_jk = np.array([0.0] * (len(iw)-1))
|
| 235 |
+
for l,phi in enumerate(probs):
|
| 236 |
+
# For each phrase-pair the gradient term for the lambda
|
| 237 |
+
# is the probability for this ttable - probability for last ttable
|
| 238 |
+
# divided by overall phrase probability
|
| 239 |
+
num = phi[:-1] - phi[-1]
|
| 240 |
+
denom = np.sum(iw[:,j]*phi) # use interpolation weights for this feature
|
| 241 |
+
grad_jk = grad_jk + (num/denom)
|
| 242 |
+
self.assertEquals(len(grad_jk), num_ttables-1)
|
| 243 |
+
#print "num",num,"denom",denom,"grad_jk",grad_jk
|
| 244 |
+
# add gradient in correct place
|
| 245 |
+
#print "\n",j,grad_k,phrasew[j]*grad_jk
|
| 246 |
+
grad_k[j*(num_ttables-1):(j+1)*(num_ttables-1)] =\
|
| 247 |
+
grad_k[j*(num_ttables-1):(j+1)*(num_ttables-1)] + phrasew[j]*grad_jk
|
| 248 |
+
#print "\ngrad_k",grad_k
|
| 249 |
+
byhyp.append(grad_k)
|
| 250 |
+
bysample_list.append(byhyp[0]-byhyp[1])
|
| 251 |
+
#print "diff: ", bysample_list[-1]
|
| 252 |
+
expected = np.vstack(bysample_list)
|
| 253 |
+
actual = self.trainer.gradient_interp(iw,phrasew)
|
| 254 |
+
nptest.assert_almost_equal(actual,expected, decimal=5)
|
| 255 |
+
|
| 256 |
+
def test_gradient(self):
|
| 257 |
+
# 2 phrase weights, 2 other feature weights,
|
| 258 |
+
# 2 interpolation weights (2 models and 2 tables)
|
| 259 |
+
weights = np.array([0.2,0.1,0.4,0.5,0.6,0.3])
|
| 260 |
+
expected = np.array([0.0] * len(weights))
|
| 261 |
+
# Get the gradients
|
| 262 |
+
iw = np.array([[weights[-2], weights[-1]],
|
| 263 |
+
[1-weights[-2],1-weights[-1]]])
|
| 264 |
+
phrase_g = self.trainer.gradient_phrase(iw)
|
| 265 |
+
other_g = self.trainer.gradient_other()
|
| 266 |
+
interp_g = self.trainer.gradient_interp(iw,weights[:2])
|
| 267 |
+
for k,sample in enumerate(self.samples):
|
| 268 |
+
hyp1_model_score = self.model_score(sample.hyp1, weights)
|
| 269 |
+
hyp2_model_score = self.model_score(sample.hyp2, weights)
|
| 270 |
+
y = 1
|
| 271 |
+
if sample.hyp2.score > sample.hyp1.score: y = -1
|
| 272 |
+
delta_score = hyp1_model_score - hyp2_model_score
|
| 273 |
+
sig_delta_score = sigmoid(-y * delta_score)
|
| 274 |
+
# phrase derivative term
|
| 275 |
+
expected[:2] -= (phrase_g[k]*sig_delta_score*y)
|
| 276 |
+
# other derivative term
|
| 277 |
+
expected[2:4] -= (other_g[k]*sig_delta_score*y)
|
| 278 |
+
# inter derivative term
|
| 279 |
+
expected[-2:] -= (interp_g[k]*sig_delta_score*y)
|
| 280 |
+
expected += self.trainer.alpha*np.append(weights[:-2], np.array([0.0,0.0]))
|
| 281 |
+
actual = self.trainer.gradient(weights)
|
| 282 |
+
nptest.assert_almost_equal(actual,expected)
|
| 283 |
+
|
| 284 |
+
def test_split_weights(self):
|
| 285 |
+
w = np.array([1,2,3,4,0.2,0.3])
|
| 286 |
+
sw = self.trainer.get_split_weights(w)
|
| 287 |
+
self.assertEquals(len(sw),3)
|
| 288 |
+
nptest.assert_almost_equal(sw['phrase'], np.array([1,2]))
|
| 289 |
+
nptest.assert_almost_equal(sw['other'], np.array([3,4]))
|
| 290 |
+
nptest.assert_almost_equal(sw['interp'], \
|
| 291 |
+
np.array([[0.2,0.3], [0.8,0.7]]))
|
| 292 |
+
|
| 293 |
+
|
| 294 |
+
def test_train(self):
|
| 295 |
+
"""Simple test that it runs without errors"""
|
| 296 |
+
print "x=",self.trainer.train()
|
| 297 |
+
|
| 298 |
+
if __name__ == "__main__":
|
| 299 |
+
unittest.main()
|
| 300 |
+
|
| 301 |
+
suite = unittest.TestSuite([
|
| 302 |
+
unittest.TestLoader().loadTestsFromTestCase(TestParabaloidOptimiser),
|
| 303 |
+
unittest.TestLoader().loadTestsFromTestCase(TestLogisticRegressionOptimiser),
|
| 304 |
+
unittest.TestLoader().loadTestsFromTestCase(TestMixtureModelTrainer)])
|
| 305 |
+
|
| 306 |
+
|
mosesdecoder/contrib/promix/util.py
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/python
|
| 2 |
+
|
| 3 |
+
import numpy as np
|
| 4 |
+
|
| 5 |
+
|
| 6 |
+
floor = np.exp(-100)
|
| 7 |
+
def safelog(x):
|
| 8 |
+
"""Wraps np.log to give it a floor"""
|
| 9 |
+
#return np.log(x)
|
| 10 |
+
return np.log(np.clip(x,floor,np.inf))
|
| 11 |
+
|
| 12 |
+
|
mosesdecoder/jam-files/boost-build/build/ac.jam
ADDED
|
@@ -0,0 +1,198 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright (c) 2010 Vladimir Prus.
|
| 2 |
+
#
|
| 3 |
+
# Use, modification and distribution is subject to the Boost Software
|
| 4 |
+
# License Version 1.0. (See accompanying file LICENSE_1_0.txt or
|
| 5 |
+
# http://www.boost.org/LICENSE_1_0.txt)
|
| 6 |
+
|
| 7 |
+
import property-set ;
|
| 8 |
+
import path ;
|
| 9 |
+
import modules ;
|
| 10 |
+
import "class" ;
|
| 11 |
+
import errors ;
|
| 12 |
+
import configure ;
|
| 13 |
+
|
| 14 |
+
rule find-include-path ( variable : properties : header
|
| 15 |
+
: provided-path ? )
|
| 16 |
+
{
|
| 17 |
+
# FIXME: document which properties affect this function by
|
| 18 |
+
# default.
|
| 19 |
+
local target-os = [ $(properties).get <target-os> ] ;
|
| 20 |
+
properties = [ property-set.create <target-os>$(toolset) ] ;
|
| 21 |
+
if $($(variable)-$(properties))
|
| 22 |
+
{
|
| 23 |
+
return $($(variable)-$(properties)) ;
|
| 24 |
+
}
|
| 25 |
+
else
|
| 26 |
+
{
|
| 27 |
+
provided-path ?= [ modules.peek : $(variable) ] ;
|
| 28 |
+
includes = $(provided-path) ;
|
| 29 |
+
includes += [ $(properties).get <include> ] ;
|
| 30 |
+
if [ $(properties).get <target-os> ] != windows
|
| 31 |
+
{
|
| 32 |
+
# FIXME: use sysroot
|
| 33 |
+
includes += /usr/include ;
|
| 34 |
+
}
|
| 35 |
+
|
| 36 |
+
local result ;
|
| 37 |
+
while ! $(result) && $(includes)
|
| 38 |
+
{
|
| 39 |
+
local f = [ path.root $(header) $(includes[1]) ] ;
|
| 40 |
+
ECHO "Checking " $(f) ;
|
| 41 |
+
if [ path.exists $(f) ]
|
| 42 |
+
{
|
| 43 |
+
result = $(includes[1]) ;
|
| 44 |
+
}
|
| 45 |
+
else if $(provided-path)
|
| 46 |
+
{
|
| 47 |
+
errors.user-error "Could not find header" $(header)
|
| 48 |
+
: "in the user-specified directory" $(provided-path) ;
|
| 49 |
+
}
|
| 50 |
+
includes = $(includes[2-]) ;
|
| 51 |
+
}
|
| 52 |
+
$(variable)-$(properties) = $(result) ;
|
| 53 |
+
return $(result) ;
|
| 54 |
+
}
|
| 55 |
+
}
|
| 56 |
+
|
| 57 |
+
rule find-library ( variable : properties : names + : provided-path ? )
|
| 58 |
+
{
|
| 59 |
+
local target-os = [ $(properties).get <target-os> ] ;
|
| 60 |
+
properties = [ property-set.create <target-os>$(toolset) ] ;
|
| 61 |
+
if $($(variable)-$(properties))
|
| 62 |
+
{
|
| 63 |
+
return $($(variable)-$(properties)) ;
|
| 64 |
+
}
|
| 65 |
+
else
|
| 66 |
+
{
|
| 67 |
+
provided-path ?= [ modules.peek : $(variable) ] ;
|
| 68 |
+
paths = $(provided-path) ;
|
| 69 |
+
paths += [ $(properties).get <library-path> ] ;
|
| 70 |
+
if [ $(properties).get <target-os> ] != windows
|
| 71 |
+
{
|
| 72 |
+
paths += /usr/lib /usr/lib32 /usr/lib64 ;
|
| 73 |
+
}
|
| 74 |
+
|
| 75 |
+
local result ;
|
| 76 |
+
while ! $(result) && $(paths)
|
| 77 |
+
{
|
| 78 |
+
while ! $(result) && $(names)
|
| 79 |
+
{
|
| 80 |
+
local f ;
|
| 81 |
+
if $(target-os) = windows
|
| 82 |
+
{
|
| 83 |
+
f = $(paths[1])/$(names[1]).lib ;
|
| 84 |
+
if [ path.exists $(f) ]
|
| 85 |
+
{
|
| 86 |
+
result = $(f) ;
|
| 87 |
+
}
|
| 88 |
+
}
|
| 89 |
+
else
|
| 90 |
+
{
|
| 91 |
+
# FIXME: check for .a as well, depending on
|
| 92 |
+
# the 'link' feature.
|
| 93 |
+
f = $(paths[1])/lib$(names[1]).so ;
|
| 94 |
+
ECHO "CHECKING $(f) " ;
|
| 95 |
+
if [ path.exists $(f) ]
|
| 96 |
+
{
|
| 97 |
+
result = $(f) ;
|
| 98 |
+
}
|
| 99 |
+
}
|
| 100 |
+
if ! $(result) && $(provided-path)
|
| 101 |
+
{
|
| 102 |
+
errors.user-error "Could not find either of: " $(names)
|
| 103 |
+
: "in the user-specified directory" $(provided-path) ;
|
| 104 |
+
|
| 105 |
+
}
|
| 106 |
+
names = $(names[2-]) ;
|
| 107 |
+
}
|
| 108 |
+
paths = $(paths[2-]) ;
|
| 109 |
+
}
|
| 110 |
+
$(variable)-$(properties) = $(result) ;
|
| 111 |
+
return $(result) ;
|
| 112 |
+
}
|
| 113 |
+
}
|
| 114 |
+
|
| 115 |
+
class ac-library : basic-target
|
| 116 |
+
{
|
| 117 |
+
import errors ;
|
| 118 |
+
import indirect ;
|
| 119 |
+
import virtual-target ;
|
| 120 |
+
import ac ;
|
| 121 |
+
import configure ;
|
| 122 |
+
|
| 123 |
+
rule __init__ ( name : project : * : * )
|
| 124 |
+
{
|
| 125 |
+
basic-target.__init__ $(name) : $(project) : $(sources)
|
| 126 |
+
: $(requirements) ;
|
| 127 |
+
|
| 128 |
+
reconfigure $(3) : $(4) : $(5) : $(6) : $(7) : $(8) : $(9) ;
|
| 129 |
+
}
|
| 130 |
+
|
| 131 |
+
rule set-header ( header )
|
| 132 |
+
{
|
| 133 |
+
self.header = $(header) ;
|
| 134 |
+
}
|
| 135 |
+
|
| 136 |
+
rule set-default-names ( names + )
|
| 137 |
+
{
|
| 138 |
+
self.default-names = $(names) ;
|
| 139 |
+
}
|
| 140 |
+
|
| 141 |
+
rule reconfigure ( * : * )
|
| 142 |
+
{
|
| 143 |
+
ECHO "XXX" $(1) ;
|
| 144 |
+
if ! $(1)
|
| 145 |
+
{
|
| 146 |
+
# This is 'using xxx ;'. Nothing to configure, really.
|
| 147 |
+
}
|
| 148 |
+
else
|
| 149 |
+
{
|
| 150 |
+
for i in 1 2 3 4 5 6 7 8 9
|
| 151 |
+
{
|
| 152 |
+
# FIXME: this naming is inconsistent with XXX_INCLUDE/XXX_LIBRARY
|
| 153 |
+
if ! ( $($(i)[1]) in root include-path library-path library-name condition )
|
| 154 |
+
{
|
| 155 |
+
errors.user-error "Invalid named parameter" $($(i)[1]) ;
|
| 156 |
+
}
|
| 157 |
+
local name = $($(i)[1]) ;
|
| 158 |
+
local value = $($(i)[2-]) ;
|
| 159 |
+
if $($(name)) && $($(name)) != $(value)
|
| 160 |
+
{
|
| 161 |
+
errors.user-error "Attempt to change value of '$(name)'" ;
|
| 162 |
+
}
|
| 163 |
+
$(name) = $(value) ;
|
| 164 |
+
}
|
| 165 |
+
|
| 166 |
+
include-path ?= $(root)/include ;
|
| 167 |
+
library-path ?= $(root)/lib ;
|
| 168 |
+
}
|
| 169 |
+
}
|
| 170 |
+
|
| 171 |
+
rule construct ( name : sources * : property-set )
|
| 172 |
+
{
|
| 173 |
+
# FIXME: log results.
|
| 174 |
+
local libnames = $(library-name) ;
|
| 175 |
+
if ! $(libnames) && ! $(include-path) && ! $(library-path)
|
| 176 |
+
{
|
| 177 |
+
libnames = [ modules.peek : $(name:U)_NAME ] ;
|
| 178 |
+
# Backward compatibility only.
|
| 179 |
+
libnames ?= [ modules.peek : $(name:U)_BINARY ] ;
|
| 180 |
+
}
|
| 181 |
+
libnames ?= $(self.default-names) ;
|
| 182 |
+
|
| 183 |
+
local includes = [
|
| 184 |
+
ac.find-include-path $(name:U)_INCLUDE : $(property-set) : $(self.header) : $(include-path) ] ;
|
| 185 |
+
local library = [ ac.find-library $(name:U)_LIBRARY : $(property-set) : $(libnames) : $(library-path) ] ;
|
| 186 |
+
if $(includes) && $(library)
|
| 187 |
+
{
|
| 188 |
+
library = [ virtual-target.from-file $(library) : . : $(self.project) ] ;
|
| 189 |
+
configure.log-library-search-result $(name) : "found" ;
|
| 190 |
+
return [ property-set.create <include>$(includes) <source>$(library) ] ;
|
| 191 |
+
}
|
| 192 |
+
else
|
| 193 |
+
{
|
| 194 |
+
configure.log-library-search-result $(name) : "no found" ;
|
| 195 |
+
}
|
| 196 |
+
}
|
| 197 |
+
}
|
| 198 |
+
|
mosesdecoder/jam-files/boost-build/build/project.jam
ADDED
|
@@ -0,0 +1,1121 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright 2002, 2003 Dave Abrahams
|
| 2 |
+
# Copyright 2002, 2005, 2006 Rene Rivera
|
| 3 |
+
# Copyright 2002, 2003, 2004, 2005, 2006 Vladimir Prus
|
| 4 |
+
# Distributed under the Boost Software License, Version 1.0.
|
| 5 |
+
# (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
|
| 6 |
+
|
| 7 |
+
# Implements project representation and loading. Each project is represented by:
|
| 8 |
+
# - a module where all the Jamfile content live.
|
| 9 |
+
# - an instance of 'project-attributes' class.
|
| 10 |
+
# (given a module name, can be obtained using the 'attributes' rule)
|
| 11 |
+
# - an instance of 'project-target' class (from targets.jam)
|
| 12 |
+
# (given a module name, can be obtained using the 'target' rule)
|
| 13 |
+
#
|
| 14 |
+
# Typically, projects are created as result of loading a Jamfile, which is done
|
| 15 |
+
# by rules 'load' and 'initialize', below. First, module for Jamfile is loaded
|
| 16 |
+
# and new project-attributes instance is created. Some rules necessary for
|
| 17 |
+
# project are added to the module (see 'project-rules' module) at the bottom of
|
| 18 |
+
# this file. Default project attributes are set (inheriting attributes of parent
|
| 19 |
+
# project, if it exists). After that the Jamfile is read. It can declare its own
|
| 20 |
+
# attributes using the 'project' rule which will be combined with any already
|
| 21 |
+
# set attributes.
|
| 22 |
+
#
|
| 23 |
+
# The 'project' rule can also declare a project id which will be associated with
|
| 24 |
+
# the project module.
|
| 25 |
+
#
|
| 26 |
+
# There can also be 'standalone' projects. They are created by calling
|
| 27 |
+
# 'initialize' on an arbitrary module and not specifying their location. After
|
| 28 |
+
# the call, the module can call the 'project' rule, declare main targets and
|
| 29 |
+
# behave as a regular project except that, since it is not associated with any
|
| 30 |
+
# location, it should not declare targets that are not prebuilt.
|
| 31 |
+
#
|
| 32 |
+
# The list of all loaded Jamfile is stored in the .project-locations variable.
|
| 33 |
+
# It is possible to obtain a module name for a location using the 'module-name'
|
| 34 |
+
# rule. Standalone projects are not recorded and can only be referenced using
|
| 35 |
+
# their project id.
|
| 36 |
+
|
| 37 |
+
import "class" : new ;
|
| 38 |
+
import errors ;
|
| 39 |
+
import modules ;
|
| 40 |
+
import path ;
|
| 41 |
+
import print ;
|
| 42 |
+
import property-set ;
|
| 43 |
+
import sequence ;
|
| 44 |
+
|
| 45 |
+
|
| 46 |
+
# Loads the Jamfile at the given location. After loading, project global file
|
| 47 |
+
# and Jamfiles needed by the requested one will be loaded recursively. If the
|
| 48 |
+
# Jamfile at that location is loaded already, does nothing. Returns the project
|
| 49 |
+
# module for the Jamfile.
|
| 50 |
+
#
|
| 51 |
+
rule load ( jamfile-location )
|
| 52 |
+
{
|
| 53 |
+
if --debug-loading in [ modules.peek : ARGV ]
|
| 54 |
+
{
|
| 55 |
+
ECHO "Loading Jamfile at" '$(jamfile-location)' ;
|
| 56 |
+
}
|
| 57 |
+
|
| 58 |
+
local module-name = [ module-name $(jamfile-location) ] ;
|
| 59 |
+
# If Jamfile is already loaded, don't try again.
|
| 60 |
+
if ! $(module-name) in $(.jamfile-modules)
|
| 61 |
+
{
|
| 62 |
+
load-jamfile $(jamfile-location) : $(module-name) ;
|
| 63 |
+
|
| 64 |
+
# We want to make sure that child project are loaded only after parent
|
| 65 |
+
# projects. In particular, because parent projects define attributes
|
| 66 |
+
# which are inherited by children, and we don't want children to be
|
| 67 |
+
# loaded before parent has defined everything.
|
| 68 |
+
#
|
| 69 |
+
# While "build-project" and "use-project" can potentially refer to child
|
| 70 |
+
# projects from parent projects, we don't immediately load child
|
| 71 |
+
# projects when seeing those attributes. Instead, we record the minimal
|
| 72 |
+
# information to be used only later.
|
| 73 |
+
load-used-projects $(module-name) ;
|
| 74 |
+
}
|
| 75 |
+
return $(module-name) ;
|
| 76 |
+
}
|
| 77 |
+
|
| 78 |
+
|
| 79 |
+
rule load-used-projects ( module-name )
|
| 80 |
+
{
|
| 81 |
+
local used = [ modules.peek $(module-name) : .used-projects ] ;
|
| 82 |
+
local location = [ attribute $(module-name) location ] ;
|
| 83 |
+
import project ;
|
| 84 |
+
while $(used)
|
| 85 |
+
{
|
| 86 |
+
local id = $(used[1]) ;
|
| 87 |
+
local where = $(used[2]) ;
|
| 88 |
+
|
| 89 |
+
project.use $(id) : [ path.root [ path.make $(where) ] $(location) ] ;
|
| 90 |
+
used = $(used[3-]) ;
|
| 91 |
+
}
|
| 92 |
+
}
|
| 93 |
+
|
| 94 |
+
|
| 95 |
+
# Note the use of character groups, as opposed to listing 'Jamroot' and
|
| 96 |
+
# 'jamroot'. With the latter, we would get duplicate matches on Windows and
|
| 97 |
+
# would have to eliminate duplicates.
|
| 98 |
+
JAMROOT ?= [ modules.peek : JAMROOT ] ;
|
| 99 |
+
JAMROOT ?= project-root.jam [Jj]amroot [Jj]amroot.jam ;
|
| 100 |
+
|
| 101 |
+
|
| 102 |
+
# Loads parent of Jamfile at 'location'. Issues an error if nothing is found.
|
| 103 |
+
#
|
| 104 |
+
rule load-parent ( location )
|
| 105 |
+
{
|
| 106 |
+
local found = [ path.glob-in-parents $(location) : $(JAMROOT) $(JAMFILE) ] ;
|
| 107 |
+
|
| 108 |
+
if ! $(found)
|
| 109 |
+
{
|
| 110 |
+
ECHO error: Could not find parent for project at '$(location)' ;
|
| 111 |
+
EXIT error: Did not find Jamfile.jam or Jamroot.jam in any parent
|
| 112 |
+
directory. ;
|
| 113 |
+
}
|
| 114 |
+
|
| 115 |
+
return [ load $(found[1]:D) ] ;
|
| 116 |
+
}
|
| 117 |
+
|
| 118 |
+
|
| 119 |
+
# Makes the specified 'module' act as if it were a regularly loaded Jamfile at
|
| 120 |
+
# 'location'. Reports an error if a Jamfile has already been loaded for that
|
| 121 |
+
# location.
|
| 122 |
+
#
|
| 123 |
+
rule act-as-jamfile ( module : location )
|
| 124 |
+
{
|
| 125 |
+
if [ module-name $(location) ] in $(.jamfile-modules)
|
| 126 |
+
{
|
| 127 |
+
errors.error "Jamfile was already loaded for '$(location)'" ;
|
| 128 |
+
}
|
| 129 |
+
# Set up non-default mapping from location to module.
|
| 130 |
+
.module.$(location) = $(module) ;
|
| 131 |
+
|
| 132 |
+
# Add the location to the list of project locations so that we don't try to
|
| 133 |
+
# reload the same Jamfile in the future.
|
| 134 |
+
.jamfile-modules += [ module-name $(location) ] ;
|
| 135 |
+
|
| 136 |
+
initialize $(module) : $(location) ;
|
| 137 |
+
}
|
| 138 |
+
|
| 139 |
+
|
| 140 |
+
# Returns the project module corresponding to the given project-id or plain
|
| 141 |
+
# directory name. Returns nothing if such a project can not be found.
|
| 142 |
+
#
|
| 143 |
+
rule find ( name : current-location )
|
| 144 |
+
{
|
| 145 |
+
local project-module ;
|
| 146 |
+
|
| 147 |
+
# Try interpreting name as project id.
|
| 148 |
+
if [ path.is-rooted $(name) ]
|
| 149 |
+
{
|
| 150 |
+
project-module = $($(name).jamfile-module) ;
|
| 151 |
+
}
|
| 152 |
+
|
| 153 |
+
if ! $(project-module)
|
| 154 |
+
{
|
| 155 |
+
local location = [ path.root [ path.make $(name) ] $(current-location) ]
|
| 156 |
+
;
|
| 157 |
+
|
| 158 |
+
# If no project is registered for the given location, try to load it.
|
| 159 |
+
# First see if we have a Jamfile. If not, then see if we might have a
|
| 160 |
+
# project root willing to act as a Jamfile. In that case, project root
|
| 161 |
+
# must be placed in the directory referred by id.
|
| 162 |
+
|
| 163 |
+
project-module = [ module-name $(location) ] ;
|
| 164 |
+
if ! $(project-module) in $(.jamfile-modules)
|
| 165 |
+
{
|
| 166 |
+
if [ path.glob $(location) : $(JAMROOT) $(JAMFILE) ]
|
| 167 |
+
{
|
| 168 |
+
project-module = [ load $(location) ] ;
|
| 169 |
+
}
|
| 170 |
+
else
|
| 171 |
+
{
|
| 172 |
+
project-module = ;
|
| 173 |
+
}
|
| 174 |
+
}
|
| 175 |
+
}
|
| 176 |
+
|
| 177 |
+
return $(project-module) ;
|
| 178 |
+
}
|
| 179 |
+
|
| 180 |
+
|
| 181 |
+
# Returns the name of the module corresponding to 'jamfile-location'. If no
|
| 182 |
+
# module corresponds to that location yet, associates the default module name
|
| 183 |
+
# with that location.
|
| 184 |
+
#
|
| 185 |
+
rule module-name ( jamfile-location )
|
| 186 |
+
{
|
| 187 |
+
if ! $(.module.$(jamfile-location))
|
| 188 |
+
{
|
| 189 |
+
# Root the path, so that locations are always unambiguous. Without this,
|
| 190 |
+
# we can't decide if '../../exe/program1' and '.' are the same paths.
|
| 191 |
+
jamfile-location = [ path.root $(jamfile-location) [ path.pwd ] ] ;
|
| 192 |
+
.module.$(jamfile-location) = Jamfile<$(jamfile-location)> ;
|
| 193 |
+
}
|
| 194 |
+
return $(.module.$(jamfile-location)) ;
|
| 195 |
+
}
|
| 196 |
+
|
| 197 |
+
|
| 198 |
+
# Default patterns to search for the Jamfiles to use for build declarations.
|
| 199 |
+
#
|
| 200 |
+
JAMFILE = [ modules.peek : JAMFILE ] ;
|
| 201 |
+
JAMFILE ?= [Bb]uild.jam [Jj]amfile.v2 [Jj]amfile [Jj]amfile.jam ;
|
| 202 |
+
|
| 203 |
+
|
| 204 |
+
# Find the Jamfile at the given location. This returns the exact names of all
|
| 205 |
+
# the Jamfiles in the given directory. The optional parent-root argument causes
|
| 206 |
+
# this to search not the given directory but the ones above it up to the
|
| 207 |
+
# directory given in it.
|
| 208 |
+
#
|
| 209 |
+
rule find-jamfile (
|
| 210 |
+
dir # The directory(s) to look for a Jamfile.
|
| 211 |
+
parent-root ? # Optional flag indicating to search for the parent Jamfile.
|
| 212 |
+
: no-errors ?
|
| 213 |
+
)
|
| 214 |
+
{
|
| 215 |
+
# Glob for all the possible Jamfiles according to the match pattern.
|
| 216 |
+
#
|
| 217 |
+
local jamfile-glob = ;
|
| 218 |
+
if $(parent-root)
|
| 219 |
+
{
|
| 220 |
+
if ! $(.parent-jamfile.$(dir))
|
| 221 |
+
{
|
| 222 |
+
.parent-jamfile.$(dir) = [ path.glob-in-parents $(dir) : $(JAMFILE)
|
| 223 |
+
] ;
|
| 224 |
+
}
|
| 225 |
+
jamfile-glob = $(.parent-jamfile.$(dir)) ;
|
| 226 |
+
}
|
| 227 |
+
else
|
| 228 |
+
{
|
| 229 |
+
if ! $(.jamfile.$(dir))
|
| 230 |
+
{
|
| 231 |
+
.jamfile.$(dir) = [ path.glob $(dir) : $(JAMFILE) ] ;
|
| 232 |
+
}
|
| 233 |
+
jamfile-glob = $(.jamfile.$(dir)) ;
|
| 234 |
+
|
| 235 |
+
}
|
| 236 |
+
|
| 237 |
+
local jamfile-to-load = $(jamfile-glob) ;
|
| 238 |
+
# Multiple Jamfiles found in the same place. Warn about this and ensure we
|
| 239 |
+
# use only one of them. As a temporary convenience measure, if there is
|
| 240 |
+
# Jamfile.v2 among found files, suppress the warning and use it.
|
| 241 |
+
#
|
| 242 |
+
if $(jamfile-to-load[2-])
|
| 243 |
+
{
|
| 244 |
+
local v2-jamfiles = [ MATCH (.*[Jj]amfile\\.v2)|(.*[Bb]uild\\.jam) : $(jamfile-to-load) ] ;
|
| 245 |
+
|
| 246 |
+
if $(v2-jamfiles) && ! $(v2-jamfiles[2])
|
| 247 |
+
{
|
| 248 |
+
jamfile-to-load = $(v2-jamfiles) ;
|
| 249 |
+
}
|
| 250 |
+
else
|
| 251 |
+
{
|
| 252 |
+
local jamfile = [ path.basename $(jamfile-to-load[1]) ] ;
|
| 253 |
+
ECHO "warning: Found multiple Jamfiles at '"$(dir)"'!"
|
| 254 |
+
"Loading the first one: '$(jamfile)'." ;
|
| 255 |
+
}
|
| 256 |
+
|
| 257 |
+
jamfile-to-load = $(jamfile-to-load[1]) ;
|
| 258 |
+
}
|
| 259 |
+
|
| 260 |
+
# Could not find it, error.
|
| 261 |
+
#
|
| 262 |
+
if ! $(no-errors) && ! $(jamfile-to-load)
|
| 263 |
+
{
|
| 264 |
+
errors.error Unable to load Jamfile.
|
| 265 |
+
: Could not find a Jamfile in directory '$(dir)'.
|
| 266 |
+
: Attempted to find it with pattern '"$(JAMFILE:J= )"'.
|
| 267 |
+
: Please consult the documentation at 'http://www.boost.org'. ;
|
| 268 |
+
}
|
| 269 |
+
|
| 270 |
+
return $(jamfile-to-load) ;
|
| 271 |
+
}
|
| 272 |
+
|
| 273 |
+
|
| 274 |
+
# Load a Jamfile at the given directory. Returns nothing. Will attempt to load
|
| 275 |
+
# the file as indicated by the JAMFILE patterns. Effect of calling this rule
|
| 276 |
+
# twice with the same 'dir' is undefined.
|
| 277 |
+
#
|
| 278 |
+
local rule load-jamfile (
|
| 279 |
+
dir # The directory of the project Jamfile.
|
| 280 |
+
: jamfile-module
|
| 281 |
+
)
|
| 282 |
+
{
|
| 283 |
+
# See if the Jamfile is where it should be.
|
| 284 |
+
#
|
| 285 |
+
local jamfile-to-load = [ path.glob $(dir) : $(JAMROOT) ] ;
|
| 286 |
+
if ! $(jamfile-to-load)
|
| 287 |
+
{
|
| 288 |
+
jamfile-to-load = [ find-jamfile $(dir) ] ;
|
| 289 |
+
}
|
| 290 |
+
|
| 291 |
+
if $(jamfile-to-load[2])
|
| 292 |
+
{
|
| 293 |
+
errors.error "Multiple Jamfiles found at '$(dir)'"
|
| 294 |
+
: "Filenames are: " $(jamfile-to-load:D=) ;
|
| 295 |
+
}
|
| 296 |
+
|
| 297 |
+
# Now load the Jamfile in it's own context.
|
| 298 |
+
# The call to 'initialize' may load parent Jamfile, which might have
|
| 299 |
+
# 'use-project' statement that causes a second attempt to load the
|
| 300 |
+
# same project we're loading now. Checking inside .jamfile-modules
|
| 301 |
+
# prevents that second attempt from messing up.
|
| 302 |
+
if ! $(jamfile-module) in $(.jamfile-modules)
|
| 303 |
+
{
|
| 304 |
+
|
| 305 |
+
# Initialize the Jamfile module before loading.
|
| 306 |
+
#
|
| 307 |
+
initialize $(jamfile-module) : [ path.parent $(jamfile-to-load) ]
|
| 308 |
+
: $(jamfile-to-load:BS) ;
|
| 309 |
+
|
| 310 |
+
if ! $(jamfile-module) in $(.jamfile-modules)
|
| 311 |
+
{
|
| 312 |
+
.jamfile-modules += $(jamfile-module) ;
|
| 313 |
+
|
| 314 |
+
local saved-project = $(.current-project) ;
|
| 315 |
+
|
| 316 |
+
mark-as-user $(jamfile-module) ;
|
| 317 |
+
modules.load $(jamfile-module) : [ path.native $(jamfile-to-load) ] : . ;
|
| 318 |
+
if [ MATCH ($(JAMROOT)) : $(jamfile-to-load:BS) ]
|
| 319 |
+
{
|
| 320 |
+
jamfile = [ find-jamfile $(dir) : no-errors ] ;
|
| 321 |
+
if $(jamfile)
|
| 322 |
+
{
|
| 323 |
+
load-aux $(jamfile-module) : [ path.native $(jamfile) ] ;
|
| 324 |
+
}
|
| 325 |
+
}
|
| 326 |
+
|
| 327 |
+
# Now do some checks.
|
| 328 |
+
if $(.current-project) != $(saved-project)
|
| 329 |
+
{
|
| 330 |
+
errors.error "The value of the .current-project variable has magically"
|
| 331 |
+
: "changed after loading a Jamfile. This means some of the targets"
|
| 332 |
+
: "might be defined in the wrong project."
|
| 333 |
+
: "after loading" $(jamfile-module)
|
| 334 |
+
: "expected value" $(saved-project)
|
| 335 |
+
: "actual value" $(.current-project) ;
|
| 336 |
+
}
|
| 337 |
+
|
| 338 |
+
if $(.global-build-dir)
|
| 339 |
+
{
|
| 340 |
+
local id = [ attribute $(jamfile-module) id ] ;
|
| 341 |
+
local project-root = [ attribute $(jamfile-module) project-root ] ;
|
| 342 |
+
local location = [ attribute $(jamfile-module) location ] ;
|
| 343 |
+
|
| 344 |
+
if $(location) && $(project-root) = $(dir)
|
| 345 |
+
{
|
| 346 |
+
# This is Jamroot.
|
| 347 |
+
if ! $(id)
|
| 348 |
+
{
|
| 349 |
+
ECHO "warning: the --build-dir option was specified" ;
|
| 350 |
+
ECHO "warning: but Jamroot at '$(dir)'" ;
|
| 351 |
+
ECHO "warning: specified no project id" ;
|
| 352 |
+
ECHO "warning: the --build-dir option will be ignored" ;
|
| 353 |
+
}
|
| 354 |
+
}
|
| 355 |
+
}
|
| 356 |
+
}
|
| 357 |
+
}
|
| 358 |
+
}
|
| 359 |
+
|
| 360 |
+
|
| 361 |
+
rule mark-as-user ( module-name )
|
| 362 |
+
{
|
| 363 |
+
if USER_MODULE in [ RULENAMES ]
|
| 364 |
+
{
|
| 365 |
+
USER_MODULE $(module-name) ;
|
| 366 |
+
}
|
| 367 |
+
}
|
| 368 |
+
|
| 369 |
+
|
| 370 |
+
rule load-aux ( module-name : file )
|
| 371 |
+
{
|
| 372 |
+
mark-as-user $(module-name) ;
|
| 373 |
+
|
| 374 |
+
module $(module-name)
|
| 375 |
+
{
|
| 376 |
+
include $(2) ;
|
| 377 |
+
local rules = [ RULENAMES $(1) ] ;
|
| 378 |
+
IMPORT $(1) : $(rules) : $(1) : $(1).$(rules) ;
|
| 379 |
+
}
|
| 380 |
+
}
|
| 381 |
+
|
| 382 |
+
|
| 383 |
+
.global-build-dir = [ MATCH --build-dir=(.*) : [ modules.peek : ARGV ] ] ;
|
| 384 |
+
if $(.global-build-dir)
|
| 385 |
+
{
|
| 386 |
+
# If the option is specified several times, take the last value.
|
| 387 |
+
.global-build-dir = [ path.make $(.global-build-dir[-1]) ] ;
|
| 388 |
+
}
|
| 389 |
+
|
| 390 |
+
|
| 391 |
+
# Initialize the module for a project.
|
| 392 |
+
#
|
| 393 |
+
rule initialize (
|
| 394 |
+
module-name # The name of the project module.
|
| 395 |
+
: location ? # The location (directory) of the project to initialize. If
|
| 396 |
+
# not specified, a standalone project will be initialized.
|
| 397 |
+
: basename ?
|
| 398 |
+
)
|
| 399 |
+
{
|
| 400 |
+
if --debug-loading in [ modules.peek : ARGV ]
|
| 401 |
+
{
|
| 402 |
+
ECHO "Initializing project '$(module-name)'" ;
|
| 403 |
+
}
|
| 404 |
+
|
| 405 |
+
local jamroot ;
|
| 406 |
+
|
| 407 |
+
local parent-module ;
|
| 408 |
+
if $(module-name) = test-config
|
| 409 |
+
{
|
| 410 |
+
# No parent.
|
| 411 |
+
}
|
| 412 |
+
else if $(module-name) = site-config
|
| 413 |
+
{
|
| 414 |
+
parent-module = test-config ;
|
| 415 |
+
}
|
| 416 |
+
else if $(module-name) = user-config
|
| 417 |
+
{
|
| 418 |
+
parent-module = site-config ;
|
| 419 |
+
}
|
| 420 |
+
else if $(module-name) = project-config
|
| 421 |
+
{
|
| 422 |
+
parent-module = user-config ;
|
| 423 |
+
}
|
| 424 |
+
else
|
| 425 |
+
{
|
| 426 |
+
# We search for parent/project-root only if Jamfile was specified, i.e.
|
| 427 |
+
# if the project is not standalone.
|
| 428 |
+
if $(location) && ! [ MATCH ($(JAMROOT)) : $(basename) ]
|
| 429 |
+
{
|
| 430 |
+
parent-module = [ load-parent $(location) ] ;
|
| 431 |
+
}
|
| 432 |
+
else
|
| 433 |
+
{
|
| 434 |
+
# It's either jamroot or standalone project. If it's jamroot,
|
| 435 |
+
# inherit from user-config.
|
| 436 |
+
if $(location)
|
| 437 |
+
{
|
| 438 |
+
# If project-config module exist, inherit from it.
|
| 439 |
+
if $(project-config.attributes)
|
| 440 |
+
{
|
| 441 |
+
parent-module = project-config ;
|
| 442 |
+
}
|
| 443 |
+
else
|
| 444 |
+
{
|
| 445 |
+
parent-module = user-config ;
|
| 446 |
+
}
|
| 447 |
+
jamroot = true ;
|
| 448 |
+
}
|
| 449 |
+
}
|
| 450 |
+
}
|
| 451 |
+
|
| 452 |
+
# TODO: need to consider if standalone projects can do anything but define
|
| 453 |
+
# prebuilt targets. If so, we need to give it a more sensible "location", so
|
| 454 |
+
# that source paths are correct.
|
| 455 |
+
location ?= "" ;
|
| 456 |
+
# Create the module for the Jamfile first.
|
| 457 |
+
module $(module-name)
|
| 458 |
+
{
|
| 459 |
+
}
|
| 460 |
+
|
| 461 |
+
# load-parent can end up loading this module again.
|
| 462 |
+
# Make sure this isn't duplicated.
|
| 463 |
+
if ! $($(module-name).attributes) {
|
| 464 |
+
|
| 465 |
+
$(module-name).attributes = [ new project-attributes $(location)
|
| 466 |
+
$(module-name) ] ;
|
| 467 |
+
local attributes = $($(module-name).attributes) ;
|
| 468 |
+
|
| 469 |
+
if $(location)
|
| 470 |
+
{
|
| 471 |
+
$(attributes).set source-location : [ path.make $(location) ] : exact ;
|
| 472 |
+
}
|
| 473 |
+
else if ! $(module-name) in test-config site-config user-config project-config
|
| 474 |
+
{
|
| 475 |
+
# This is a standalone project with known location. Set source location
|
| 476 |
+
# so that it can declare targets. This is intended so that you can put
|
| 477 |
+
# a .jam file in your sources and use it via 'using'. Standard modules
|
| 478 |
+
# (in 'tools' subdir) may not assume source dir is set.
|
| 479 |
+
local s = [ modules.binding $(module-name) ] ;
|
| 480 |
+
if ! $(s)
|
| 481 |
+
{
|
| 482 |
+
errors.error "Could not determine project location $(module-name)" ;
|
| 483 |
+
}
|
| 484 |
+
$(attributes).set source-location : $(s:D) : exact ;
|
| 485 |
+
}
|
| 486 |
+
|
| 487 |
+
$(attributes).set requirements : [ property-set.empty ] : exact ;
|
| 488 |
+
$(attributes).set usage-requirements : [ property-set.empty ] : exact ;
|
| 489 |
+
|
| 490 |
+
# Import rules common to all project modules from project-rules module,
|
| 491 |
+
# defined at the end of this file.
|
| 492 |
+
local rules = [ RULENAMES project-rules ] ;
|
| 493 |
+
IMPORT project-rules : $(rules) : $(module-name) : $(rules) ;
|
| 494 |
+
|
| 495 |
+
if $(parent-module)
|
| 496 |
+
{
|
| 497 |
+
inherit-attributes $(module-name) : $(parent-module) ;
|
| 498 |
+
$(attributes).set parent-module : $(parent-module) : exact ;
|
| 499 |
+
}
|
| 500 |
+
|
| 501 |
+
if $(jamroot)
|
| 502 |
+
{
|
| 503 |
+
$(attributes).set project-root : $(location) : exact ;
|
| 504 |
+
}
|
| 505 |
+
|
| 506 |
+
local parent ;
|
| 507 |
+
if $(parent-module)
|
| 508 |
+
{
|
| 509 |
+
parent = [ target $(parent-module) ] ;
|
| 510 |
+
}
|
| 511 |
+
|
| 512 |
+
if ! $(.target.$(module-name))
|
| 513 |
+
{
|
| 514 |
+
.target.$(module-name) = [ new project-target $(module-name)
|
| 515 |
+
: $(module-name) $(parent)
|
| 516 |
+
: [ attribute $(module-name) requirements ] ] ;
|
| 517 |
+
|
| 518 |
+
if --debug-loading in [ modules.peek : ARGV ]
|
| 519 |
+
{
|
| 520 |
+
ECHO "Assigned project target" $(.target.$(module-name))
|
| 521 |
+
"to '$(module-name)'" ;
|
| 522 |
+
}
|
| 523 |
+
}
|
| 524 |
+
}
|
| 525 |
+
|
| 526 |
+
.current-project = [ target $(module-name) ] ;
|
| 527 |
+
}
|
| 528 |
+
|
| 529 |
+
|
| 530 |
+
# Make 'project-module' inherit attributes of project root and parent module.
|
| 531 |
+
#
|
| 532 |
+
rule inherit-attributes ( project-module : parent-module )
|
| 533 |
+
{
|
| 534 |
+
local attributes = $($(project-module).attributes) ;
|
| 535 |
+
local pattributes = [ attributes $(parent-module) ] ;
|
| 536 |
+
# Parent module might be locationless configuration module.
|
| 537 |
+
if [ modules.binding $(parent-module) ]
|
| 538 |
+
{
|
| 539 |
+
$(attributes).set parent : [ path.parent
|
| 540 |
+
[ path.make [ modules.binding $(parent-module) ] ] ] ;
|
| 541 |
+
}
|
| 542 |
+
local v = [ $(pattributes).get project-root ] ;
|
| 543 |
+
$(attributes).set project-root : $(v) : exact ;
|
| 544 |
+
$(attributes).set default-build
|
| 545 |
+
: [ $(pattributes).get default-build ] ;
|
| 546 |
+
$(attributes).set requirements
|
| 547 |
+
: [ $(pattributes).get requirements ] : exact ;
|
| 548 |
+
$(attributes).set usage-requirements
|
| 549 |
+
: [ $(pattributes).get usage-requirements ] : exact ;
|
| 550 |
+
|
| 551 |
+
local parent-build-dir = [ $(pattributes).get build-dir ] ;
|
| 552 |
+
if $(parent-build-dir)
|
| 553 |
+
{
|
| 554 |
+
# Have to compute relative path from parent dir to our dir. Convert both
|
| 555 |
+
# paths to absolute, since we cannot find relative path from ".." to
|
| 556 |
+
# ".".
|
| 557 |
+
|
| 558 |
+
local location = [ attribute $(project-module) location ] ;
|
| 559 |
+
local parent-location = [ attribute $(parent-module) location ] ;
|
| 560 |
+
|
| 561 |
+
local pwd = [ path.pwd ] ;
|
| 562 |
+
local parent-dir = [ path.root $(parent-location) $(pwd) ] ;
|
| 563 |
+
local our-dir = [ path.root $(location) $(pwd) ] ;
|
| 564 |
+
$(attributes).set build-dir : [ path.join $(parent-build-dir)
|
| 565 |
+
[ path.relative $(our-dir) $(parent-dir) ] ] : exact ;
|
| 566 |
+
}
|
| 567 |
+
}
|
| 568 |
+
|
| 569 |
+
|
| 570 |
+
# Associate the given id with the given project module.
|
| 571 |
+
#
|
| 572 |
+
rule register-id ( id : module )
|
| 573 |
+
{
|
| 574 |
+
$(id).jamfile-module = $(module) ;
|
| 575 |
+
}
|
| 576 |
+
|
| 577 |
+
|
| 578 |
+
# Class keeping all the attributes of a project.
|
| 579 |
+
#
|
| 580 |
+
# The standard attributes are "id", "location", "project-root", "parent"
|
| 581 |
+
# "requirements", "default-build", "source-location" and "projects-to-build".
|
| 582 |
+
#
|
| 583 |
+
class project-attributes
|
| 584 |
+
{
|
| 585 |
+
import property ;
|
| 586 |
+
import property-set ;
|
| 587 |
+
import errors ;
|
| 588 |
+
import path ;
|
| 589 |
+
import print ;
|
| 590 |
+
import sequence ;
|
| 591 |
+
import project ;
|
| 592 |
+
|
| 593 |
+
rule __init__ ( location project-module )
|
| 594 |
+
{
|
| 595 |
+
self.location = $(location) ;
|
| 596 |
+
self.project-module = $(project-module) ;
|
| 597 |
+
}
|
| 598 |
+
|
| 599 |
+
# Set the named attribute from the specification given by the user. The
|
| 600 |
+
# value actually set may be different.
|
| 601 |
+
#
|
| 602 |
+
rule set ( attribute : specification *
|
| 603 |
+
: exact ? # Sets value from 'specification' without any processing.
|
| 604 |
+
)
|
| 605 |
+
{
|
| 606 |
+
if $(exact)
|
| 607 |
+
{
|
| 608 |
+
self.$(attribute) = $(specification) ;
|
| 609 |
+
}
|
| 610 |
+
else if $(attribute) = "requirements"
|
| 611 |
+
{
|
| 612 |
+
local result = [ property-set.refine-from-user-input
|
| 613 |
+
$(self.requirements) : $(specification)
|
| 614 |
+
: $(self.project-module) : $(self.location) ] ;
|
| 615 |
+
|
| 616 |
+
if $(result[1]) = "@error"
|
| 617 |
+
{
|
| 618 |
+
errors.error Requirements for project at '$(self.location)'
|
| 619 |
+
conflict with parent's. : Explanation: $(result[2-]) ;
|
| 620 |
+
}
|
| 621 |
+
else
|
| 622 |
+
{
|
| 623 |
+
self.requirements = $(result) ;
|
| 624 |
+
}
|
| 625 |
+
}
|
| 626 |
+
else if $(attribute) = "usage-requirements"
|
| 627 |
+
{
|
| 628 |
+
local unconditional ;
|
| 629 |
+
for local p in $(specification)
|
| 630 |
+
{
|
| 631 |
+
local split = [ property.split-conditional $(p) ] ;
|
| 632 |
+
split ?= nothing $(p) ;
|
| 633 |
+
unconditional += $(split[2]) ;
|
| 634 |
+
}
|
| 635 |
+
|
| 636 |
+
local non-free = [ property.remove free : $(unconditional) ] ;
|
| 637 |
+
if $(non-free)
|
| 638 |
+
{
|
| 639 |
+
errors.error usage-requirements $(specification) have non-free
|
| 640 |
+
properties $(non-free) ;
|
| 641 |
+
}
|
| 642 |
+
local t = [ property.translate-paths $(specification)
|
| 643 |
+
: $(self.location) ] ;
|
| 644 |
+
if $(self.usage-requirements)
|
| 645 |
+
{
|
| 646 |
+
self.usage-requirements = [ property-set.create
|
| 647 |
+
[ $(self.usage-requirements).raw ] $(t) ] ;
|
| 648 |
+
}
|
| 649 |
+
else
|
| 650 |
+
{
|
| 651 |
+
self.usage-requirements = [ property-set.create $(t) ] ;
|
| 652 |
+
}
|
| 653 |
+
}
|
| 654 |
+
else if $(attribute) = "default-build"
|
| 655 |
+
{
|
| 656 |
+
self.default-build = [ property.make $(specification) ] ;
|
| 657 |
+
}
|
| 658 |
+
else if $(attribute) = "source-location"
|
| 659 |
+
{
|
| 660 |
+
self.source-location = ;
|
| 661 |
+
for local src-path in $(specification)
|
| 662 |
+
{
|
| 663 |
+
self.source-location += [ path.root [ path.make $(src-path) ]
|
| 664 |
+
$(self.location) ] ;
|
| 665 |
+
}
|
| 666 |
+
}
|
| 667 |
+
else if $(attribute) = "build-dir"
|
| 668 |
+
{
|
| 669 |
+
self.build-dir = [ path.root
|
| 670 |
+
[ path.make $(specification) ] $(self.location) ] ;
|
| 671 |
+
}
|
| 672 |
+
else if $(attribute) = "id"
|
| 673 |
+
{
|
| 674 |
+
id = [ path.root $(specification) / ] ;
|
| 675 |
+
project.register-id $(id) : $(self.project-module) ;
|
| 676 |
+
self.id = $(id) ;
|
| 677 |
+
}
|
| 678 |
+
else if ! $(attribute) in "default-build" "location" "parent"
|
| 679 |
+
"projects-to-build" "project-root" "source-location"
|
| 680 |
+
{
|
| 681 |
+
errors.error Invalid project attribute '$(attribute)' specified for
|
| 682 |
+
project at '$(self.location)' ;
|
| 683 |
+
}
|
| 684 |
+
else
|
| 685 |
+
{
|
| 686 |
+
self.$(attribute) = $(specification) ;
|
| 687 |
+
}
|
| 688 |
+
}
|
| 689 |
+
|
| 690 |
+
# Returns the value of the given attribute.
|
| 691 |
+
#
|
| 692 |
+
rule get ( attribute )
|
| 693 |
+
{
|
| 694 |
+
return $(self.$(attribute)) ;
|
| 695 |
+
}
|
| 696 |
+
|
| 697 |
+
# Prints the project attributes.
|
| 698 |
+
#
|
| 699 |
+
rule print ( )
|
| 700 |
+
{
|
| 701 |
+
local id = $(self.id) ; id ?= (none) ;
|
| 702 |
+
local parent = $(self.parent) ; parent ?= (none) ;
|
| 703 |
+
print.section "'"$(id)"'" ;
|
| 704 |
+
print.list-start ;
|
| 705 |
+
print.list-item "Parent project:" $(parent) ;
|
| 706 |
+
print.list-item "Requirements:" [ $(self.requirements).raw ] ;
|
| 707 |
+
print.list-item "Default build:" $(self.default-build) ;
|
| 708 |
+
print.list-item "Source location:" $(self.source-location) ;
|
| 709 |
+
print.list-item "Projects to build:"
|
| 710 |
+
[ sequence.insertion-sort $(self.projects-to-build) ] ;
|
| 711 |
+
print.list-end ;
|
| 712 |
+
}
|
| 713 |
+
}
|
| 714 |
+
|
| 715 |
+
|
| 716 |
+
# Returns the project which is currently being loaded.
|
| 717 |
+
#
|
| 718 |
+
rule current ( )
|
| 719 |
+
{
|
| 720 |
+
return $(.current-project) ;
|
| 721 |
+
}
|
| 722 |
+
|
| 723 |
+
|
| 724 |
+
# Temporarily changes the current project to 'project'. Should be followed by
|
| 725 |
+
# 'pop-current'.
|
| 726 |
+
#
|
| 727 |
+
rule push-current ( project )
|
| 728 |
+
{
|
| 729 |
+
.saved-current-project += $(.current-project) ;
|
| 730 |
+
.current-project = $(project) ;
|
| 731 |
+
}
|
| 732 |
+
|
| 733 |
+
|
| 734 |
+
rule pop-current ( )
|
| 735 |
+
{
|
| 736 |
+
.current-project = $(.saved-current-project[-1]) ;
|
| 737 |
+
.saved-current-project = $(.saved-current-project[1--2]) ;
|
| 738 |
+
}
|
| 739 |
+
|
| 740 |
+
|
| 741 |
+
# Returns the project-attribute instance for the specified Jamfile module.
|
| 742 |
+
#
|
| 743 |
+
rule attributes ( project )
|
| 744 |
+
{
|
| 745 |
+
return $($(project).attributes) ;
|
| 746 |
+
}
|
| 747 |
+
|
| 748 |
+
|
| 749 |
+
# Returns the value of the specified attribute in the specified Jamfile module.
|
| 750 |
+
#
|
| 751 |
+
rule attribute ( project attribute )
|
| 752 |
+
{
|
| 753 |
+
return [ $($(project).attributes).get $(attribute) ] ;
|
| 754 |
+
}
|
| 755 |
+
|
| 756 |
+
|
| 757 |
+
# Returns the project target corresponding to the 'project-module'.
|
| 758 |
+
#
|
| 759 |
+
rule target ( project-module )
|
| 760 |
+
{
|
| 761 |
+
if ! $(.target.$(project-module))
|
| 762 |
+
{
|
| 763 |
+
.target.$(project-module) = [ new project-target $(project-module)
|
| 764 |
+
: $(project-module)
|
| 765 |
+
: [ attribute $(project-module) requirements ] ] ;
|
| 766 |
+
}
|
| 767 |
+
return $(.target.$(project-module)) ;
|
| 768 |
+
}
|
| 769 |
+
|
| 770 |
+
|
| 771 |
+
# Use/load a project.
|
| 772 |
+
#
|
| 773 |
+
rule use ( id : location )
|
| 774 |
+
{
|
| 775 |
+
local saved-project = $(.current-project) ;
|
| 776 |
+
local project-module = [ project.load $(location) ] ;
|
| 777 |
+
local declared-id = [ project.attribute $(project-module) id ] ;
|
| 778 |
+
|
| 779 |
+
if ! $(declared-id) || $(declared-id) != $(id)
|
| 780 |
+
{
|
| 781 |
+
# The project at 'location' either has no id or that id is not equal to
|
| 782 |
+
# the 'id' parameter.
|
| 783 |
+
if $($(id).jamfile-module) && ( $($(id).jamfile-module) !=
|
| 784 |
+
$(project-module) )
|
| 785 |
+
{
|
| 786 |
+
errors.user-error Attempt to redeclare already existing project id
|
| 787 |
+
'$(id)'
|
| 788 |
+
location '$(location)' ;
|
| 789 |
+
}
|
| 790 |
+
$(id).jamfile-module = $(project-module) ;
|
| 791 |
+
}
|
| 792 |
+
.current-project = $(saved-project) ;
|
| 793 |
+
}
|
| 794 |
+
|
| 795 |
+
|
| 796 |
+
# Defines a Boost.Build extension project. Such extensions usually contain
|
| 797 |
+
# library targets and features that can be used by many people. Even though
|
| 798 |
+
# extensions are really projects, they can be initialized as a module would be
|
| 799 |
+
# with the "using" (project.project-rules.using) mechanism.
|
| 800 |
+
#
|
| 801 |
+
rule extension ( id : options * : * )
|
| 802 |
+
{
|
| 803 |
+
# The caller is a standalone module for the extension.
|
| 804 |
+
local mod = [ CALLER_MODULE ] ;
|
| 805 |
+
|
| 806 |
+
# We need to do the rest within the extension module.
|
| 807 |
+
module $(mod)
|
| 808 |
+
{
|
| 809 |
+
import path ;
|
| 810 |
+
|
| 811 |
+
# Find the root project.
|
| 812 |
+
local root-project = [ project.current ] ;
|
| 813 |
+
root-project = [ $(root-project).project-module ] ;
|
| 814 |
+
while
|
| 815 |
+
[ project.attribute $(root-project) parent-module ] &&
|
| 816 |
+
[ project.attribute $(root-project) parent-module ] != user-config
|
| 817 |
+
{
|
| 818 |
+
root-project = [ project.attribute $(root-project) parent-module ] ;
|
| 819 |
+
}
|
| 820 |
+
|
| 821 |
+
# Create the project data, and bring in the project rules into the
|
| 822 |
+
# module.
|
| 823 |
+
project.initialize $(__name__) : [ path.join [ project.attribute
|
| 824 |
+
$(root-project) location ] ext $(1:L) ] ;
|
| 825 |
+
|
| 826 |
+
# Create the project itself, i.e. the attributes. All extensions are
|
| 827 |
+
# created in the "/ext" project space.
|
| 828 |
+
project /ext/$(1) : $(2) : $(3) : $(4) : $(5) : $(6) : $(7) : $(8) :
|
| 829 |
+
$(9) ;
|
| 830 |
+
local attributes = [ project.attributes $(__name__) ] ;
|
| 831 |
+
|
| 832 |
+
# Inherit from the root project of whomever is defining us.
|
| 833 |
+
project.inherit-attributes $(__name__) : $(root-project) ;
|
| 834 |
+
$(attributes).set parent-module : $(root-project) : exact ;
|
| 835 |
+
}
|
| 836 |
+
}
|
| 837 |
+
|
| 838 |
+
|
| 839 |
+
rule glob-internal ( project : wildcards + : excludes * : rule-name )
|
| 840 |
+
{
|
| 841 |
+
local location = [ $(project).get source-location ] ;
|
| 842 |
+
|
| 843 |
+
local result ;
|
| 844 |
+
local paths = [ path.$(rule-name) $(location) :
|
| 845 |
+
[ sequence.transform path.make : $(wildcards) ] :
|
| 846 |
+
[ sequence.transform path.make : $(excludes) ] ] ;
|
| 847 |
+
if $(wildcards:D) || $(rule-name) != glob
|
| 848 |
+
{
|
| 849 |
+
# The paths we have found are relative to the current directory, but the
|
| 850 |
+
# names specified in the sources list are assumed to be relative to the
|
| 851 |
+
# source directory of the corresponding project. So, just make the names
|
| 852 |
+
# absolute.
|
| 853 |
+
for local p in $(paths)
|
| 854 |
+
{
|
| 855 |
+
# If the path is below source location, use relative path.
|
| 856 |
+
# Otherwise, use full path just to avoid any ambiguities.
|
| 857 |
+
local rel = [ path.relative $(p) $(location) : no-error ] ;
|
| 858 |
+
if $(rel) = not-a-child
|
| 859 |
+
{
|
| 860 |
+
result += [ path.root $(p) [ path.pwd ] ] ;
|
| 861 |
+
}
|
| 862 |
+
else
|
| 863 |
+
{
|
| 864 |
+
result += $(rel) ;
|
| 865 |
+
}
|
| 866 |
+
}
|
| 867 |
+
}
|
| 868 |
+
else
|
| 869 |
+
{
|
| 870 |
+
# There were no wildcards in the directory path, so the files are all in
|
| 871 |
+
# the source directory of the project. Just drop the directory, instead
|
| 872 |
+
# of making paths absolute.
|
| 873 |
+
result = $(paths:D="") ;
|
| 874 |
+
}
|
| 875 |
+
|
| 876 |
+
return $(result) ;
|
| 877 |
+
}
|
| 878 |
+
|
| 879 |
+
|
| 880 |
+
# This module defines rules common to all projects.
|
| 881 |
+
#
|
| 882 |
+
module project-rules
|
| 883 |
+
{
|
| 884 |
+
rule using ( toolset-module : * )
|
| 885 |
+
{
|
| 886 |
+
import toolset ;
|
| 887 |
+
import modules ;
|
| 888 |
+
import project ;
|
| 889 |
+
|
| 890 |
+
# Temporarily change the search path so the module referred to by
|
| 891 |
+
# 'using' can be placed in the same directory as Jamfile. User will
|
| 892 |
+
# expect the module to be found even though the directory is not in
|
| 893 |
+
# BOOST_BUILD_PATH.
|
| 894 |
+
local x = [ modules.peek : BOOST_BUILD_PATH ] ;
|
| 895 |
+
local caller = [ CALLER_MODULE ] ;
|
| 896 |
+
local caller-location = [ modules.binding $(caller) ] ;
|
| 897 |
+
modules.poke : BOOST_BUILD_PATH : $(caller-location:D) $(x) ;
|
| 898 |
+
toolset.using $(1) : $(2) : $(3) : $(4) : $(5) : $(6) : $(7) : $(8) : $(9) ;
|
| 899 |
+
modules.poke : BOOST_BUILD_PATH : $(x) ;
|
| 900 |
+
|
| 901 |
+
# The above might have clobbered .current-project. Restore the correct
|
| 902 |
+
# value.
|
| 903 |
+
modules.poke project : .current-project
|
| 904 |
+
: [ project.target $(caller) ] ;
|
| 905 |
+
}
|
| 906 |
+
|
| 907 |
+
import modules ;
|
| 908 |
+
|
| 909 |
+
rule import ( * : * : * )
|
| 910 |
+
{
|
| 911 |
+
modules.import project ;
|
| 912 |
+
|
| 913 |
+
local caller = [ CALLER_MODULE ] ;
|
| 914 |
+
local saved = [ modules.peek project : .current-project ] ;
|
| 915 |
+
module $(caller)
|
| 916 |
+
{
|
| 917 |
+
modules.import $(1) : $(2) : $(3) ;
|
| 918 |
+
}
|
| 919 |
+
modules.poke project : .current-project : $(saved) ;
|
| 920 |
+
}
|
| 921 |
+
|
| 922 |
+
rule project ( id ? : options * : * )
|
| 923 |
+
{
|
| 924 |
+
import errors ;
|
| 925 |
+
import path ;
|
| 926 |
+
import project ;
|
| 927 |
+
|
| 928 |
+
local caller = [ CALLER_MODULE ] ;
|
| 929 |
+
local attributes = [ project.attributes $(caller) ] ;
|
| 930 |
+
if $(id)
|
| 931 |
+
{
|
| 932 |
+
$(attributes).set id : $(id) ;
|
| 933 |
+
}
|
| 934 |
+
|
| 935 |
+
local explicit-build-dir ;
|
| 936 |
+
|
| 937 |
+
for n in 2 3 4 5 6 7 8 9
|
| 938 |
+
{
|
| 939 |
+
local option = $($(n)) ;
|
| 940 |
+
if $(option)
|
| 941 |
+
{
|
| 942 |
+
$(attributes).set $(option[1]) : $(option[2-]) ;
|
| 943 |
+
}
|
| 944 |
+
if $(option[1]) = "build-dir"
|
| 945 |
+
{
|
| 946 |
+
explicit-build-dir = [ path.make $(option[2-]) ] ;
|
| 947 |
+
}
|
| 948 |
+
}
|
| 949 |
+
|
| 950 |
+
# If '--build-dir' is specified, change the build dir for the project.
|
| 951 |
+
local global-build-dir =
|
| 952 |
+
[ modules.peek project : .global-build-dir ] ;
|
| 953 |
+
|
| 954 |
+
if $(global-build-dir)
|
| 955 |
+
{
|
| 956 |
+
local location = [ $(attributes).get location ] ;
|
| 957 |
+
# Project with an empty location is a 'standalone' project such as
|
| 958 |
+
# user-config or qt. It has no build dir. If we try to set build dir
|
| 959 |
+
# for user-config, we shall then try to inherit it, with either
|
| 960 |
+
# weird or wrong consequences.
|
| 961 |
+
if $(location) && $(location) = [ $(attributes).get project-root ]
|
| 962 |
+
{
|
| 963 |
+
# Re-read the project id, since it might have been changed in
|
| 964 |
+
# the project's attributes.
|
| 965 |
+
id = [ $(attributes).get id ] ;
|
| 966 |
+
# This is Jamroot.
|
| 967 |
+
if $(id)
|
| 968 |
+
{
|
| 969 |
+
if $(explicit-build-dir) &&
|
| 970 |
+
[ path.is-rooted $(explicit-build-dir) ]
|
| 971 |
+
{
|
| 972 |
+
errors.user-error Absolute directory specified via
|
| 973 |
+
'build-dir' project attribute : Do not know how to
|
| 974 |
+
combine that with the --build-dir option. ;
|
| 975 |
+
}
|
| 976 |
+
# Strip the leading slash from id.
|
| 977 |
+
local rid = [ MATCH /(.*) : $(id) ] ;
|
| 978 |
+
local p = [ path.join
|
| 979 |
+
$(global-build-dir) $(rid) $(explicit-build-dir) ] ;
|
| 980 |
+
|
| 981 |
+
$(attributes).set build-dir : $(p) : exact ;
|
| 982 |
+
}
|
| 983 |
+
}
|
| 984 |
+
else
|
| 985 |
+
{
|
| 986 |
+
# Not Jamroot.
|
| 987 |
+
if $(explicit-build-dir)
|
| 988 |
+
{
|
| 989 |
+
errors.user-error When --build-dir is specified, the
|
| 990 |
+
'build-dir' project : attribute is allowed only for
|
| 991 |
+
top-level 'project' invocations ;
|
| 992 |
+
}
|
| 993 |
+
}
|
| 994 |
+
}
|
| 995 |
+
}
|
| 996 |
+
|
| 997 |
+
# Declare and set a project global constant. Project global constants are
|
| 998 |
+
# normal variables but should not be changed. They are applied to every
|
| 999 |
+
# child Jamfile.
|
| 1000 |
+
#
|
| 1001 |
+
rule constant (
|
| 1002 |
+
name # Variable name of the constant.
|
| 1003 |
+
: value + # Value of the constant.
|
| 1004 |
+
)
|
| 1005 |
+
{
|
| 1006 |
+
import project ;
|
| 1007 |
+
local caller = [ CALLER_MODULE ] ;
|
| 1008 |
+
local p = [ project.target $(caller) ] ;
|
| 1009 |
+
$(p).add-constant $(name) : $(value) ;
|
| 1010 |
+
}
|
| 1011 |
+
|
| 1012 |
+
# Declare and set a project global constant, whose value is a path. The path
|
| 1013 |
+
# is adjusted to be relative to the invocation directory. The given value
|
| 1014 |
+
# path is taken to be either absolute, or relative to this project root.
|
| 1015 |
+
#
|
| 1016 |
+
rule path-constant (
|
| 1017 |
+
name # Variable name of the constant.
|
| 1018 |
+
: value + # Value of the constant.
|
| 1019 |
+
)
|
| 1020 |
+
{
|
| 1021 |
+
import project ;
|
| 1022 |
+
local caller = [ CALLER_MODULE ] ;
|
| 1023 |
+
local p = [ project.target $(caller) ] ;
|
| 1024 |
+
$(p).add-constant $(name) : $(value) : path ;
|
| 1025 |
+
}
|
| 1026 |
+
|
| 1027 |
+
rule use-project ( id : where )
|
| 1028 |
+
{
|
| 1029 |
+
import modules ;
|
| 1030 |
+
# See comment in 'load' for explanation.
|
| 1031 |
+
local caller = [ CALLER_MODULE ] ;
|
| 1032 |
+
modules.poke $(caller) : .used-projects :
|
| 1033 |
+
[ modules.peek $(caller) : .used-projects ]
|
| 1034 |
+
$(id) $(where) ;
|
| 1035 |
+
}
|
| 1036 |
+
|
| 1037 |
+
rule build-project ( dir )
|
| 1038 |
+
{
|
| 1039 |
+
import project ;
|
| 1040 |
+
local caller = [ CALLER_MODULE ] ;
|
| 1041 |
+
local attributes = [ project.attributes $(caller) ] ;
|
| 1042 |
+
|
| 1043 |
+
local now = [ $(attributes).get projects-to-build ] ;
|
| 1044 |
+
$(attributes).set projects-to-build : $(now) $(dir) ;
|
| 1045 |
+
}
|
| 1046 |
+
|
| 1047 |
+
rule explicit ( target-names * )
|
| 1048 |
+
{
|
| 1049 |
+
import project ;
|
| 1050 |
+
# If 'explicit' is used in a helper rule defined in Jamroot and
|
| 1051 |
+
# inherited by children, then most of the time we want 'explicit' to
|
| 1052 |
+
# operate on the Jamfile where the helper rule is invoked.
|
| 1053 |
+
local t = [ project.current ] ;
|
| 1054 |
+
for local n in $(target-names)
|
| 1055 |
+
{
|
| 1056 |
+
$(t).mark-target-as-explicit $(n) ;
|
| 1057 |
+
}
|
| 1058 |
+
}
|
| 1059 |
+
|
| 1060 |
+
rule always ( target-names * )
|
| 1061 |
+
{
|
| 1062 |
+
import project ;
|
| 1063 |
+
local t = [ project.current ] ;
|
| 1064 |
+
for local n in $(target-names)
|
| 1065 |
+
{
|
| 1066 |
+
$(t).mark-target-as-always $(n) ;
|
| 1067 |
+
}
|
| 1068 |
+
}
|
| 1069 |
+
|
| 1070 |
+
rule glob ( wildcards + : excludes * )
|
| 1071 |
+
{
|
| 1072 |
+
import project ;
|
| 1073 |
+
return [ project.glob-internal [ project.current ] : $(wildcards) :
|
| 1074 |
+
$(excludes) : glob ] ;
|
| 1075 |
+
}
|
| 1076 |
+
|
| 1077 |
+
rule glob-tree ( wildcards + : excludes * )
|
| 1078 |
+
{
|
| 1079 |
+
import project ;
|
| 1080 |
+
|
| 1081 |
+
if $(wildcards:D) || $(excludes:D)
|
| 1082 |
+
{
|
| 1083 |
+
errors.user-error The patterns to 'glob-tree' may not include
|
| 1084 |
+
directory ;
|
| 1085 |
+
}
|
| 1086 |
+
return [ project.glob-internal [ project.current ] : $(wildcards) :
|
| 1087 |
+
$(excludes) : glob-tree ] ;
|
| 1088 |
+
}
|
| 1089 |
+
|
| 1090 |
+
# Calculates conditional requirements for multiple requirements at once.
|
| 1091 |
+
# This is a shorthand to reduce duplication and to keep an inline
|
| 1092 |
+
# declarative syntax. For example:
|
| 1093 |
+
#
|
| 1094 |
+
# lib x : x.cpp : [ conditional <toolset>gcc <variant>debug :
|
| 1095 |
+
# <define>DEBUG_EXCEPTION <define>DEBUG_TRACE ] ;
|
| 1096 |
+
#
|
| 1097 |
+
rule conditional ( condition + : requirements * )
|
| 1098 |
+
{
|
| 1099 |
+
local condition = $(condition:J=,) ;
|
| 1100 |
+
if [ MATCH (:) : $(condition) ]
|
| 1101 |
+
{
|
| 1102 |
+
return $(condition)$(requirements) ;
|
| 1103 |
+
}
|
| 1104 |
+
else
|
| 1105 |
+
{
|
| 1106 |
+
return $(condition):$(requirements) ;
|
| 1107 |
+
}
|
| 1108 |
+
}
|
| 1109 |
+
|
| 1110 |
+
rule option ( name : value )
|
| 1111 |
+
{
|
| 1112 |
+
local m = [ CALLER_MODULE ] ;
|
| 1113 |
+
if $(m) != site-config && $(m) != user-config && $(m) != project-config
|
| 1114 |
+
{
|
| 1115 |
+
import errors ;
|
| 1116 |
+
errors.error "The 'option' rule may be used only in site-config or user-config" ;
|
| 1117 |
+
}
|
| 1118 |
+
import option ;
|
| 1119 |
+
option.set $(name) : $(value) ;
|
| 1120 |
+
}
|
| 1121 |
+
}
|
mosesdecoder/jam-files/boost-build/build/property-set.jam
ADDED
|
@@ -0,0 +1,489 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright 2003 Dave Abrahams
|
| 2 |
+
# Copyright 2003, 2004, 2005, 2006 Vladimir Prus
|
| 3 |
+
# Distributed under the Boost Software License, Version 1.0.
|
| 4 |
+
# (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
|
| 5 |
+
|
| 6 |
+
import "class" : new ;
|
| 7 |
+
import feature ;
|
| 8 |
+
import path ;
|
| 9 |
+
import project ;
|
| 10 |
+
import property ;
|
| 11 |
+
import sequence ;
|
| 12 |
+
import set ;
|
| 13 |
+
import option ;
|
| 14 |
+
|
| 15 |
+
# Class for storing a set of properties.
|
| 16 |
+
#
|
| 17 |
+
# There is 1<->1 correspondence between identity and value. No two instances
|
| 18 |
+
# of the class are equal. To maintain this property, the 'property-set.create'
|
| 19 |
+
# rule should be used to create new instances. Instances are immutable.
|
| 20 |
+
#
|
| 21 |
+
# Each property is classified with regard to its effect on build results.
|
| 22 |
+
# Incidental properties have no effect on build results, from Boost.Build's
|
| 23 |
+
# point of view. Others are either free, or non-free and we refer to non-free
|
| 24 |
+
# ones as 'base'. Each property belongs to exactly one of those categories.
|
| 25 |
+
#
|
| 26 |
+
# It is possible to get a list of properties belonging to each category as
|
| 27 |
+
# well as a list of properties with a specific attribute.
|
| 28 |
+
#
|
| 29 |
+
# Several operations, like and refine and as-path are provided. They all use
|
| 30 |
+
# caching whenever possible.
|
| 31 |
+
#
|
| 32 |
+
class property-set
|
| 33 |
+
{
|
| 34 |
+
import errors ;
|
| 35 |
+
import feature ;
|
| 36 |
+
import path ;
|
| 37 |
+
import property ;
|
| 38 |
+
import property-set ;
|
| 39 |
+
import set ;
|
| 40 |
+
|
| 41 |
+
rule __init__ ( raw-properties * )
|
| 42 |
+
{
|
| 43 |
+
self.raw = $(raw-properties) ;
|
| 44 |
+
|
| 45 |
+
for local p in $(raw-properties)
|
| 46 |
+
{
|
| 47 |
+
if ! $(p:G)
|
| 48 |
+
{
|
| 49 |
+
errors.error "Invalid property: '$(p)'" ;
|
| 50 |
+
}
|
| 51 |
+
}
|
| 52 |
+
}
|
| 53 |
+
|
| 54 |
+
# Returns Jam list of stored properties.
|
| 55 |
+
#
|
| 56 |
+
rule raw ( )
|
| 57 |
+
{
|
| 58 |
+
return $(self.raw) ;
|
| 59 |
+
}
|
| 60 |
+
|
| 61 |
+
rule str ( )
|
| 62 |
+
{
|
| 63 |
+
return "[" $(self.raw) "]" ;
|
| 64 |
+
}
|
| 65 |
+
|
| 66 |
+
# Returns properties that are neither incidental nor free.
|
| 67 |
+
#
|
| 68 |
+
rule base ( )
|
| 69 |
+
{
|
| 70 |
+
if ! $(self.base-initialized)
|
| 71 |
+
{
|
| 72 |
+
init-base ;
|
| 73 |
+
}
|
| 74 |
+
return $(self.base) ;
|
| 75 |
+
}
|
| 76 |
+
|
| 77 |
+
# Returns free properties which are not incidental.
|
| 78 |
+
#
|
| 79 |
+
rule free ( )
|
| 80 |
+
{
|
| 81 |
+
if ! $(self.base-initialized)
|
| 82 |
+
{
|
| 83 |
+
init-base ;
|
| 84 |
+
}
|
| 85 |
+
return $(self.free) ;
|
| 86 |
+
}
|
| 87 |
+
|
| 88 |
+
# Returns dependency properties.
|
| 89 |
+
#
|
| 90 |
+
rule dependency ( )
|
| 91 |
+
{
|
| 92 |
+
if ! $(self.dependency-initialized)
|
| 93 |
+
{
|
| 94 |
+
init-dependency ;
|
| 95 |
+
}
|
| 96 |
+
return $(self.dependency) ;
|
| 97 |
+
}
|
| 98 |
+
|
| 99 |
+
rule non-dependency ( )
|
| 100 |
+
{
|
| 101 |
+
if ! $(self.dependency-initialized)
|
| 102 |
+
{
|
| 103 |
+
init-dependency ;
|
| 104 |
+
}
|
| 105 |
+
return $(self.non-dependency) ;
|
| 106 |
+
}
|
| 107 |
+
|
| 108 |
+
rule conditional ( )
|
| 109 |
+
{
|
| 110 |
+
if ! $(self.conditional-initialized)
|
| 111 |
+
{
|
| 112 |
+
init-conditional ;
|
| 113 |
+
}
|
| 114 |
+
return $(self.conditional) ;
|
| 115 |
+
}
|
| 116 |
+
|
| 117 |
+
rule non-conditional ( )
|
| 118 |
+
{
|
| 119 |
+
if ! $(self.conditional-initialized)
|
| 120 |
+
{
|
| 121 |
+
init-conditional ;
|
| 122 |
+
}
|
| 123 |
+
return $(self.non-conditional) ;
|
| 124 |
+
}
|
| 125 |
+
|
| 126 |
+
# Returns incidental properties.
|
| 127 |
+
#
|
| 128 |
+
rule incidental ( )
|
| 129 |
+
{
|
| 130 |
+
if ! $(self.base-initialized)
|
| 131 |
+
{
|
| 132 |
+
init-base ;
|
| 133 |
+
}
|
| 134 |
+
return $(self.incidental) ;
|
| 135 |
+
}
|
| 136 |
+
|
| 137 |
+
rule refine ( ps )
|
| 138 |
+
{
|
| 139 |
+
if ! $(self.refined.$(ps))
|
| 140 |
+
{
|
| 141 |
+
local r = [ property.refine $(self.raw) : [ $(ps).raw ] ] ;
|
| 142 |
+
if $(r[1]) != "@error"
|
| 143 |
+
{
|
| 144 |
+
self.refined.$(ps) = [ property-set.create $(r) ] ;
|
| 145 |
+
}
|
| 146 |
+
else
|
| 147 |
+
{
|
| 148 |
+
self.refined.$(ps) = $(r) ;
|
| 149 |
+
}
|
| 150 |
+
}
|
| 151 |
+
return $(self.refined.$(ps)) ;
|
| 152 |
+
}
|
| 153 |
+
|
| 154 |
+
rule expand ( )
|
| 155 |
+
{
|
| 156 |
+
if ! $(self.expanded)
|
| 157 |
+
{
|
| 158 |
+
self.expanded = [ property-set.create [ feature.expand $(self.raw) ] ] ;
|
| 159 |
+
}
|
| 160 |
+
return $(self.expanded) ;
|
| 161 |
+
}
|
| 162 |
+
|
| 163 |
+
rule expand-composites ( )
|
| 164 |
+
{
|
| 165 |
+
if ! $(self.composites)
|
| 166 |
+
{
|
| 167 |
+
self.composites = [ property-set.create
|
| 168 |
+
[ feature.expand-composites $(self.raw) ] ] ;
|
| 169 |
+
}
|
| 170 |
+
return $(self.composites) ;
|
| 171 |
+
}
|
| 172 |
+
|
| 173 |
+
rule evaluate-conditionals ( context ? )
|
| 174 |
+
{
|
| 175 |
+
context ?= $(__name__) ;
|
| 176 |
+
if ! $(self.evaluated.$(context))
|
| 177 |
+
{
|
| 178 |
+
self.evaluated.$(context) = [ property-set.create
|
| 179 |
+
[ property.evaluate-conditionals-in-context $(self.raw) : [ $(context).raw ] ] ] ;
|
| 180 |
+
}
|
| 181 |
+
return $(self.evaluated.$(context)) ;
|
| 182 |
+
}
|
| 183 |
+
|
| 184 |
+
rule propagated ( )
|
| 185 |
+
{
|
| 186 |
+
if ! $(self.propagated-ps)
|
| 187 |
+
{
|
| 188 |
+
local result ;
|
| 189 |
+
for local p in $(self.raw)
|
| 190 |
+
{
|
| 191 |
+
if propagated in [ feature.attributes $(p:G) ]
|
| 192 |
+
{
|
| 193 |
+
result += $(p) ;
|
| 194 |
+
}
|
| 195 |
+
}
|
| 196 |
+
self.propagated-ps = [ property-set.create $(result) ] ;
|
| 197 |
+
}
|
| 198 |
+
return $(self.propagated-ps) ;
|
| 199 |
+
}
|
| 200 |
+
|
| 201 |
+
rule add-defaults ( )
|
| 202 |
+
{
|
| 203 |
+
if ! $(self.defaults)
|
| 204 |
+
{
|
| 205 |
+
self.defaults = [ property-set.create
|
| 206 |
+
[ feature.add-defaults $(self.raw) ] ] ;
|
| 207 |
+
}
|
| 208 |
+
return $(self.defaults) ;
|
| 209 |
+
}
|
| 210 |
+
|
| 211 |
+
rule as-path ( )
|
| 212 |
+
{
|
| 213 |
+
if ! $(self.as-path)
|
| 214 |
+
{
|
| 215 |
+
self.as-path = [ property.as-path [ base ] ] ;
|
| 216 |
+
}
|
| 217 |
+
return $(self.as-path) ;
|
| 218 |
+
}
|
| 219 |
+
|
| 220 |
+
# Computes the path to be used for a target with the given properties.
|
| 221 |
+
# Returns a list of
|
| 222 |
+
# - the computed path
|
| 223 |
+
# - if the path is relative to the build directory, a value of 'true'.
|
| 224 |
+
#
|
| 225 |
+
rule target-path ( )
|
| 226 |
+
{
|
| 227 |
+
if ! $(self.target-path)
|
| 228 |
+
{
|
| 229 |
+
# The <location> feature can be used to explicitly change the
|
| 230 |
+
# location of generated targets.
|
| 231 |
+
local l = [ get <location> ] ;
|
| 232 |
+
if $(l)
|
| 233 |
+
{
|
| 234 |
+
self.target-path = $(l) ;
|
| 235 |
+
}
|
| 236 |
+
else
|
| 237 |
+
{
|
| 238 |
+
local p = [ as-path ] ;
|
| 239 |
+
p = [ property-set.hash-maybe $(p) ] ;
|
| 240 |
+
|
| 241 |
+
# A real ugly hack. Boost regression test system requires
|
| 242 |
+
# specific target paths, and it seems that changing it to handle
|
| 243 |
+
# other directory layout is really hard. For that reason, we
|
| 244 |
+
# teach V2 to do the things regression system requires. The
|
| 245 |
+
# value of '<location-prefix>' is prepended to the path.
|
| 246 |
+
local prefix = [ get <location-prefix> ] ;
|
| 247 |
+
if $(prefix)
|
| 248 |
+
{
|
| 249 |
+
self.target-path = [ path.join $(prefix) $(p) ] ;
|
| 250 |
+
}
|
| 251 |
+
else
|
| 252 |
+
{
|
| 253 |
+
self.target-path = $(p) ;
|
| 254 |
+
}
|
| 255 |
+
if ! $(self.target-path)
|
| 256 |
+
{
|
| 257 |
+
self.target-path = . ;
|
| 258 |
+
}
|
| 259 |
+
# The path is relative to build dir.
|
| 260 |
+
self.target-path += true ;
|
| 261 |
+
}
|
| 262 |
+
}
|
| 263 |
+
return $(self.target-path) ;
|
| 264 |
+
}
|
| 265 |
+
|
| 266 |
+
rule add ( ps )
|
| 267 |
+
{
|
| 268 |
+
if ! $(self.added.$(ps))
|
| 269 |
+
{
|
| 270 |
+
self.added.$(ps) = [ property-set.create $(self.raw) [ $(ps).raw ] ] ;
|
| 271 |
+
}
|
| 272 |
+
return $(self.added.$(ps)) ;
|
| 273 |
+
}
|
| 274 |
+
|
| 275 |
+
rule add-raw ( properties * )
|
| 276 |
+
{
|
| 277 |
+
return [ add [ property-set.create $(properties) ] ] ;
|
| 278 |
+
}
|
| 279 |
+
|
| 280 |
+
# Returns all values of 'feature'.
|
| 281 |
+
#
|
| 282 |
+
rule get ( feature )
|
| 283 |
+
{
|
| 284 |
+
if ! $(self.map-built)
|
| 285 |
+
{
|
| 286 |
+
# For each feature, create a member var and assign all values to it.
|
| 287 |
+
# Since all regular member vars start with 'self', there will be no
|
| 288 |
+
# conflicts between names.
|
| 289 |
+
self.map-built = true ;
|
| 290 |
+
for local v in $(self.raw)
|
| 291 |
+
{
|
| 292 |
+
$(v:G) += $(v:G=) ;
|
| 293 |
+
}
|
| 294 |
+
}
|
| 295 |
+
return $($(feature)) ;
|
| 296 |
+
}
|
| 297 |
+
|
| 298 |
+
# private
|
| 299 |
+
|
| 300 |
+
rule init-base ( )
|
| 301 |
+
{
|
| 302 |
+
for local p in $(self.raw)
|
| 303 |
+
{
|
| 304 |
+
local att = [ feature.attributes $(p:G) ] ;
|
| 305 |
+
# A feature can be both incidental and free, in which case we add it
|
| 306 |
+
# to incidental.
|
| 307 |
+
if incidental in $(att)
|
| 308 |
+
{
|
| 309 |
+
self.incidental += $(p) ;
|
| 310 |
+
}
|
| 311 |
+
else if free in $(att)
|
| 312 |
+
{
|
| 313 |
+
self.free += $(p) ;
|
| 314 |
+
}
|
| 315 |
+
else
|
| 316 |
+
{
|
| 317 |
+
self.base += $(p) ;
|
| 318 |
+
}
|
| 319 |
+
}
|
| 320 |
+
self.base-initialized = true ;
|
| 321 |
+
}
|
| 322 |
+
|
| 323 |
+
rule init-dependency ( )
|
| 324 |
+
{
|
| 325 |
+
for local p in $(self.raw)
|
| 326 |
+
{
|
| 327 |
+
local att = [ feature.attributes $(p:G) ] ;
|
| 328 |
+
|
| 329 |
+
if dependency in $(att)
|
| 330 |
+
{
|
| 331 |
+
self.dependency += $(p) ;
|
| 332 |
+
}
|
| 333 |
+
else
|
| 334 |
+
{
|
| 335 |
+
self.non-dependency += $(p) ;
|
| 336 |
+
}
|
| 337 |
+
}
|
| 338 |
+
self.dependency-initialized = true ;
|
| 339 |
+
}
|
| 340 |
+
|
| 341 |
+
rule init-conditional ( )
|
| 342 |
+
{
|
| 343 |
+
for local p in $(self.raw)
|
| 344 |
+
{
|
| 345 |
+
if [ MATCH (:) : $(p:G=) ]
|
| 346 |
+
{
|
| 347 |
+
self.conditional += $(p) ;
|
| 348 |
+
}
|
| 349 |
+
else
|
| 350 |
+
{
|
| 351 |
+
self.non-conditional += $(p) ;
|
| 352 |
+
}
|
| 353 |
+
}
|
| 354 |
+
self.conditional-initialized = true ;
|
| 355 |
+
}
|
| 356 |
+
}
|
| 357 |
+
|
| 358 |
+
|
| 359 |
+
# Creates a new 'property-set' instance for the given raw properties or returns
|
| 360 |
+
# an already existing ones.
|
| 361 |
+
#
|
| 362 |
+
rule create ( raw-properties * )
|
| 363 |
+
{
|
| 364 |
+
raw-properties = [ sequence.unique
|
| 365 |
+
[ sequence.insertion-sort $(raw-properties) ] ] ;
|
| 366 |
+
|
| 367 |
+
local key = $(raw-properties:J=-:E=) ;
|
| 368 |
+
|
| 369 |
+
if ! $(.ps.$(key))
|
| 370 |
+
{
|
| 371 |
+
.ps.$(key) = [ new property-set $(raw-properties) ] ;
|
| 372 |
+
}
|
| 373 |
+
return $(.ps.$(key)) ;
|
| 374 |
+
}
|
| 375 |
+
NATIVE_RULE property-set : create ;
|
| 376 |
+
|
| 377 |
+
|
| 378 |
+
# Creates a new 'property-set' instance after checking that all properties are
|
| 379 |
+
# valid and converting incidental properties into gristed form.
|
| 380 |
+
#
|
| 381 |
+
rule create-with-validation ( raw-properties * )
|
| 382 |
+
{
|
| 383 |
+
property.validate $(raw-properties) ;
|
| 384 |
+
return [ create [ property.make $(raw-properties) ] ] ;
|
| 385 |
+
}
|
| 386 |
+
|
| 387 |
+
|
| 388 |
+
# Creates a property-set from the input given by the user, in the context of
|
| 389 |
+
# 'jamfile-module' at 'location'.
|
| 390 |
+
#
|
| 391 |
+
rule create-from-user-input ( raw-properties * : jamfile-module location )
|
| 392 |
+
{
|
| 393 |
+
local specification = [ property.translate-paths $(raw-properties)
|
| 394 |
+
: $(location) ] ;
|
| 395 |
+
specification = [ property.translate-indirect $(specification)
|
| 396 |
+
: $(jamfile-module) ] ;
|
| 397 |
+
local project-id = [ project.attribute $(jamfile-module) id ] ;
|
| 398 |
+
project-id ?= [ path.root $(location) [ path.pwd ] ] ;
|
| 399 |
+
specification = [ property.translate-dependencies
|
| 400 |
+
$(specification) : $(project-id) : $(location) ] ;
|
| 401 |
+
specification =
|
| 402 |
+
[ property.expand-subfeatures-in-conditions $(specification) ] ;
|
| 403 |
+
specification = [ property.make $(specification) ] ;
|
| 404 |
+
return [ property-set.create $(specification) ] ;
|
| 405 |
+
}
|
| 406 |
+
|
| 407 |
+
|
| 408 |
+
# Refines requirements with requirements provided by the user. Specially handles
|
| 409 |
+
# "-<property>value" syntax in specification to remove given requirements.
|
| 410 |
+
# - parent-requirements -- property-set object with requirements to refine.
|
| 411 |
+
# - specification -- string list of requirements provided by the user.
|
| 412 |
+
# - project-module -- module to which context indirect features will be
|
| 413 |
+
# bound.
|
| 414 |
+
# - location -- path to which path features are relative.
|
| 415 |
+
#
|
| 416 |
+
rule refine-from-user-input ( parent-requirements : specification * :
|
| 417 |
+
project-module : location )
|
| 418 |
+
{
|
| 419 |
+
if ! $(specification)
|
| 420 |
+
{
|
| 421 |
+
return $(parent-requirements) ;
|
| 422 |
+
}
|
| 423 |
+
else
|
| 424 |
+
{
|
| 425 |
+
local add-requirements ;
|
| 426 |
+
local remove-requirements ;
|
| 427 |
+
|
| 428 |
+
for local r in $(specification)
|
| 429 |
+
{
|
| 430 |
+
local m = [ MATCH "^-(.*)" : $(r) ] ;
|
| 431 |
+
if $(m)
|
| 432 |
+
{
|
| 433 |
+
remove-requirements += $(m) ;
|
| 434 |
+
}
|
| 435 |
+
else
|
| 436 |
+
{
|
| 437 |
+
add-requirements += $(r) ;
|
| 438 |
+
}
|
| 439 |
+
}
|
| 440 |
+
|
| 441 |
+
if $(remove-requirements)
|
| 442 |
+
{
|
| 443 |
+
# Need to create a property set, so that path features and indirect
|
| 444 |
+
# features are translated just like they are in project
|
| 445 |
+
# requirements.
|
| 446 |
+
local ps = [ property-set.create-from-user-input
|
| 447 |
+
$(remove-requirements) : $(project-module) $(location) ] ;
|
| 448 |
+
|
| 449 |
+
parent-requirements = [ property-set.create
|
| 450 |
+
[ set.difference [ $(parent-requirements).raw ]
|
| 451 |
+
: [ $(ps).raw ] ] ] ;
|
| 452 |
+
specification = $(add-requirements) ;
|
| 453 |
+
}
|
| 454 |
+
|
| 455 |
+
local requirements = [ property-set.create-from-user-input
|
| 456 |
+
$(specification) : $(project-module) $(location) ] ;
|
| 457 |
+
|
| 458 |
+
return [ $(parent-requirements).refine $(requirements) ] ;
|
| 459 |
+
}
|
| 460 |
+
}
|
| 461 |
+
|
| 462 |
+
|
| 463 |
+
# Returns a property-set with an empty set of properties.
|
| 464 |
+
#
|
| 465 |
+
rule empty ( )
|
| 466 |
+
{
|
| 467 |
+
if ! $(.empty)
|
| 468 |
+
{
|
| 469 |
+
.empty = [ create ] ;
|
| 470 |
+
}
|
| 471 |
+
return $(.empty) ;
|
| 472 |
+
}
|
| 473 |
+
|
| 474 |
+
if [ option.get hash : : yes ] = yes
|
| 475 |
+
{
|
| 476 |
+
rule hash-maybe ( path ? )
|
| 477 |
+
{
|
| 478 |
+
path ?= "" ;
|
| 479 |
+
return [ MD5 $(path) ] ;
|
| 480 |
+
}
|
| 481 |
+
}
|
| 482 |
+
else
|
| 483 |
+
{
|
| 484 |
+
rule hash-maybe ( path ? )
|
| 485 |
+
{
|
| 486 |
+
return $(path) ;
|
| 487 |
+
}
|
| 488 |
+
}
|
| 489 |
+
|
mosesdecoder/jam-files/boost-build/build/targets.jam
ADDED
|
@@ -0,0 +1,1659 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright Vladimir Prus 2002.
|
| 2 |
+
# Copyright Rene Rivera 2006.
|
| 3 |
+
#
|
| 4 |
+
# Distributed under the Boost Software License, Version 1.0.
|
| 5 |
+
# (See accompanying file LICENSE_1_0.txt or copy at
|
| 6 |
+
# http://www.boost.org/LICENSE_1_0.txt)
|
| 7 |
+
|
| 8 |
+
# Supports 'abstract' targets, which are targets explicitly defined in a
|
| 9 |
+
# Jamfile.
|
| 10 |
+
#
|
| 11 |
+
# Abstract targets are represented by classes derived from 'abstract-target'
|
| 12 |
+
# class. The first abstract target is 'project-target', which is created for
|
| 13 |
+
# each Jamfile, and can be obtained by the 'target' rule in the Jamfile's module
|
| 14 |
+
# (see project.jam).
|
| 15 |
+
#
|
| 16 |
+
# Project targets keep a list of 'main-target' instances. A main target is what
|
| 17 |
+
# the user explicitly defines in a Jamfile. It is possible to have several
|
| 18 |
+
# definitions for a main target, for example to have different lists of sources
|
| 19 |
+
# for different platforms. So, main targets keep a list of alternatives.
|
| 20 |
+
#
|
| 21 |
+
# Each alternative is an instance of 'abstract-target'. When a main target
|
| 22 |
+
# subvariant is defined by some rule, that rule will decide what class to use,
|
| 23 |
+
# create an instance of that class and add it to the list of alternatives for
|
| 24 |
+
# the main target.
|
| 25 |
+
#
|
| 26 |
+
# Rules supplied by the build system will use only targets derived from
|
| 27 |
+
# 'basic-target' class, which will provide some default behaviour. There will be
|
| 28 |
+
# different classes derived from it such as 'make-target', created by the 'make'
|
| 29 |
+
# rule, and 'typed-target', created by rules such as 'exe' and 'lib'.
|
| 30 |
+
|
| 31 |
+
#
|
| 32 |
+
# +------------------------+
|
| 33 |
+
# |abstract-target |
|
| 34 |
+
# +========================+
|
| 35 |
+
# |name |
|
| 36 |
+
# |project |
|
| 37 |
+
# | |
|
| 38 |
+
# |generate(properties) = 0|
|
| 39 |
+
# +-----------+------------+
|
| 40 |
+
# |
|
| 41 |
+
# ^
|
| 42 |
+
# / \
|
| 43 |
+
# +-+-+
|
| 44 |
+
# |
|
| 45 |
+
# |
|
| 46 |
+
# +------------------------+------+------------------------------+
|
| 47 |
+
# | | |
|
| 48 |
+
# | | |
|
| 49 |
+
# +----------+-----------+ +------+------+ +------+-------+
|
| 50 |
+
# | project-target | | main-target | | basic-target |
|
| 51 |
+
# +======================+ 1 * +=============+ alternatives +==============+
|
| 52 |
+
# | generate(properties) |o-----------+ generate |<>------------->| generate |
|
| 53 |
+
# | main-target | +-------------+ | construct = 0|
|
| 54 |
+
# +----------------------+ +--------------+
|
| 55 |
+
# |
|
| 56 |
+
# ^
|
| 57 |
+
# / \
|
| 58 |
+
# +-+-+
|
| 59 |
+
# |
|
| 60 |
+
# |
|
| 61 |
+
# ...--+----------------+------------------+----------------+---+
|
| 62 |
+
# | | | |
|
| 63 |
+
# | | | |
|
| 64 |
+
# ... ---+-----+ +------+-------+ +------+------+ +--------+-----+
|
| 65 |
+
# | | typed-target | | make-target | | stage-target |
|
| 66 |
+
# . +==============+ +=============+ +==============+
|
| 67 |
+
# . | construct | | construct | | construct |
|
| 68 |
+
# +--------------+ +-------------+ +--------------+
|
| 69 |
+
|
| 70 |
+
import assert ;
|
| 71 |
+
import "class" : new ;
|
| 72 |
+
import errors ;
|
| 73 |
+
import feature ;
|
| 74 |
+
import indirect ;
|
| 75 |
+
import path ;
|
| 76 |
+
import property ;
|
| 77 |
+
import property-set ;
|
| 78 |
+
import sequence ;
|
| 79 |
+
import set ;
|
| 80 |
+
import toolset ;
|
| 81 |
+
import build-request ;
|
| 82 |
+
|
| 83 |
+
|
| 84 |
+
# Base class for all abstract targets.
|
| 85 |
+
#
|
| 86 |
+
class abstract-target
|
| 87 |
+
{
|
| 88 |
+
import project ;
|
| 89 |
+
import assert ;
|
| 90 |
+
import "class" ;
|
| 91 |
+
import errors ;
|
| 92 |
+
|
| 93 |
+
rule __init__ ( name # Name of the target in Jamfile.
|
| 94 |
+
: project-target # The project target to which this one belongs.
|
| 95 |
+
)
|
| 96 |
+
{
|
| 97 |
+
# Note: it might seem that we don't need either name or project at all.
|
| 98 |
+
# However, there are places where we really need it. One example is
|
| 99 |
+
# error messages which should name problematic targets. Another is
|
| 100 |
+
# setting correct paths for sources and generated files.
|
| 101 |
+
|
| 102 |
+
self.name = $(name) ;
|
| 103 |
+
self.project = $(project-target) ;
|
| 104 |
+
self.location = [ errors.nearest-user-location ] ;
|
| 105 |
+
}
|
| 106 |
+
|
| 107 |
+
# Returns the name of this target.
|
| 108 |
+
rule name ( )
|
| 109 |
+
{
|
| 110 |
+
return $(self.name) ;
|
| 111 |
+
}
|
| 112 |
+
|
| 113 |
+
# Returns the project for this target.
|
| 114 |
+
rule project ( )
|
| 115 |
+
{
|
| 116 |
+
return $(self.project) ;
|
| 117 |
+
}
|
| 118 |
+
|
| 119 |
+
# Return the location where the target was declared.
|
| 120 |
+
rule location ( )
|
| 121 |
+
{
|
| 122 |
+
return $(self.location) ;
|
| 123 |
+
}
|
| 124 |
+
|
| 125 |
+
# Returns a user-readable name for this target.
|
| 126 |
+
rule full-name ( )
|
| 127 |
+
{
|
| 128 |
+
local location = [ $(self.project).get location ] ;
|
| 129 |
+
return $(location)/$(self.name) ;
|
| 130 |
+
}
|
| 131 |
+
|
| 132 |
+
# Generates virtual targets for this abstract target using the specified
|
| 133 |
+
# properties, unless a different value of some feature is required by the
|
| 134 |
+
# target.
|
| 135 |
+
# On success, returns:
|
| 136 |
+
# - a property-set with the usage requirements to be applied to dependants
|
| 137 |
+
# - a list of produced virtual targets, which may be empty.
|
| 138 |
+
# If 'property-set' is empty, performs the default build of this target, in
|
| 139 |
+
# a way specific to the derived class.
|
| 140 |
+
#
|
| 141 |
+
rule generate ( property-set )
|
| 142 |
+
{
|
| 143 |
+
errors.error "method should be defined in derived classes" ;
|
| 144 |
+
}
|
| 145 |
+
|
| 146 |
+
rule rename ( new-name )
|
| 147 |
+
{
|
| 148 |
+
self.name = $(new-name) ;
|
| 149 |
+
}
|
| 150 |
+
}
|
| 151 |
+
|
| 152 |
+
|
| 153 |
+
if --debug-building in [ modules.peek : ARGV ]
|
| 154 |
+
{
|
| 155 |
+
modules.poke : .debug-building : true ;
|
| 156 |
+
}
|
| 157 |
+
|
| 158 |
+
|
| 159 |
+
rule indent ( )
|
| 160 |
+
{
|
| 161 |
+
return $(.indent:J="") ;
|
| 162 |
+
}
|
| 163 |
+
|
| 164 |
+
|
| 165 |
+
rule increase-indent ( )
|
| 166 |
+
{
|
| 167 |
+
.indent += " " ;
|
| 168 |
+
}
|
| 169 |
+
|
| 170 |
+
|
| 171 |
+
rule decrease-indent ( )
|
| 172 |
+
{
|
| 173 |
+
.indent = $(.indent[2-]) ;
|
| 174 |
+
}
|
| 175 |
+
|
| 176 |
+
|
| 177 |
+
# Project target class (derived from 'abstract-target').
|
| 178 |
+
#
|
| 179 |
+
# This class has the following responsibilities:
|
| 180 |
+
# - Maintaining a list of main targets in this project and building them.
|
| 181 |
+
#
|
| 182 |
+
# Main targets are constructed in two stages:
|
| 183 |
+
# - When Jamfile is read, a number of calls to 'add-alternative' is made. At
|
| 184 |
+
# that time, alternatives can also be renamed to account for inline targets.
|
| 185 |
+
# - The first time 'main-target' or 'has-main-target' rule is called, all
|
| 186 |
+
# alternatives are enumerated and main targets are created.
|
| 187 |
+
#
|
| 188 |
+
class project-target : abstract-target
|
| 189 |
+
{
|
| 190 |
+
import project ;
|
| 191 |
+
import targets ;
|
| 192 |
+
import path ;
|
| 193 |
+
import print ;
|
| 194 |
+
import property-set ;
|
| 195 |
+
import set ;
|
| 196 |
+
import sequence ;
|
| 197 |
+
import "class" : new ;
|
| 198 |
+
import errors ;
|
| 199 |
+
|
| 200 |
+
rule __init__ ( name : project-module parent-project ?
|
| 201 |
+
: requirements * : default-build * )
|
| 202 |
+
{
|
| 203 |
+
abstract-target.__init__ $(name) : $(__name__) ;
|
| 204 |
+
|
| 205 |
+
self.project-module = $(project-module) ;
|
| 206 |
+
self.location = [ project.attribute $(project-module) location ] ;
|
| 207 |
+
self.requirements = $(requirements) ;
|
| 208 |
+
self.default-build = $(default-build) ;
|
| 209 |
+
|
| 210 |
+
if $(parent-project)
|
| 211 |
+
{
|
| 212 |
+
inherit $(parent-project) ;
|
| 213 |
+
}
|
| 214 |
+
}
|
| 215 |
+
|
| 216 |
+
# This is needed only by the 'make' rule. Need to find the way to make
|
| 217 |
+
# 'make' work without this method.
|
| 218 |
+
#
|
| 219 |
+
rule project-module ( )
|
| 220 |
+
{
|
| 221 |
+
return $(self.project-module) ;
|
| 222 |
+
}
|
| 223 |
+
|
| 224 |
+
rule get ( attribute )
|
| 225 |
+
{
|
| 226 |
+
return [ project.attribute $(self.project-module) $(attribute) ] ;
|
| 227 |
+
}
|
| 228 |
+
|
| 229 |
+
rule build-dir ( )
|
| 230 |
+
{
|
| 231 |
+
if ! $(self.build-dir)
|
| 232 |
+
{
|
| 233 |
+
self.build-dir = [ get build-dir ] ;
|
| 234 |
+
if ! $(self.build-dir)
|
| 235 |
+
{
|
| 236 |
+
self.build-dir = [ path.join [ $(self.project).get location ]
|
| 237 |
+
bin ] ;
|
| 238 |
+
}
|
| 239 |
+
}
|
| 240 |
+
return $(self.build-dir) ;
|
| 241 |
+
}
|
| 242 |
+
|
| 243 |
+
# Generates all possible targets contained in this project.
|
| 244 |
+
#
|
| 245 |
+
rule generate ( property-set * )
|
| 246 |
+
{
|
| 247 |
+
if [ modules.peek : .debug-building ]
|
| 248 |
+
{
|
| 249 |
+
ECHO [ targets.indent ] "building project" [ name ] " ('$(__name__)') with" [ $(property-set).raw ] ;
|
| 250 |
+
targets.increase-indent ;
|
| 251 |
+
}
|
| 252 |
+
|
| 253 |
+
local usage-requirements = [ property-set.empty ] ;
|
| 254 |
+
local targets ;
|
| 255 |
+
|
| 256 |
+
for local t in [ targets-to-build ]
|
| 257 |
+
{
|
| 258 |
+
local g = [ $(t).generate $(property-set) ] ;
|
| 259 |
+
usage-requirements = [ $(usage-requirements).add $(g[1]) ] ;
|
| 260 |
+
targets += $(g[2-]) ;
|
| 261 |
+
}
|
| 262 |
+
targets.decrease-indent ;
|
| 263 |
+
return $(usage-requirements) [ sequence.unique $(targets) ] ;
|
| 264 |
+
}
|
| 265 |
+
|
| 266 |
+
# Computes and returns a list of abstract-target instances which must be
|
| 267 |
+
# built when this project is built.
|
| 268 |
+
#
|
| 269 |
+
rule targets-to-build ( )
|
| 270 |
+
{
|
| 271 |
+
local result ;
|
| 272 |
+
|
| 273 |
+
if ! $(self.built-main-targets)
|
| 274 |
+
{
|
| 275 |
+
build-main-targets ;
|
| 276 |
+
}
|
| 277 |
+
|
| 278 |
+
# Collect all main targets here, except for "explicit" ones.
|
| 279 |
+
for local t in $(self.main-targets)
|
| 280 |
+
{
|
| 281 |
+
if ! [ $(t).name ] in $(self.explicit-targets)
|
| 282 |
+
{
|
| 283 |
+
result += $(t) ;
|
| 284 |
+
}
|
| 285 |
+
}
|
| 286 |
+
|
| 287 |
+
# Collect all projects referenced via "projects-to-build" attribute.
|
| 288 |
+
local self-location = [ get location ] ;
|
| 289 |
+
for local pn in [ get projects-to-build ]
|
| 290 |
+
{
|
| 291 |
+
result += [ find $(pn)/ ] ;
|
| 292 |
+
}
|
| 293 |
+
|
| 294 |
+
return $(result) ;
|
| 295 |
+
}
|
| 296 |
+
|
| 297 |
+
# Add 'target' to the list of targets in this project that should be build
|
| 298 |
+
# only by explicit request
|
| 299 |
+
#
|
| 300 |
+
rule mark-target-as-explicit ( target-name * )
|
| 301 |
+
{
|
| 302 |
+
# Record the name of the target, not instance, since this rule is called
|
| 303 |
+
# before main target instances are created.
|
| 304 |
+
self.explicit-targets += $(target-name) ;
|
| 305 |
+
}
|
| 306 |
+
|
| 307 |
+
rule mark-target-as-always ( target-name * )
|
| 308 |
+
{
|
| 309 |
+
# Record the name of the target, not instance, since this rule is called
|
| 310 |
+
# before main target instances are created.
|
| 311 |
+
self.always-targets += $(target-name) ;
|
| 312 |
+
}
|
| 313 |
+
|
| 314 |
+
# Add new target alternative
|
| 315 |
+
#
|
| 316 |
+
rule add-alternative ( target-instance )
|
| 317 |
+
{
|
| 318 |
+
if $(self.built-main-targets)
|
| 319 |
+
{
|
| 320 |
+
errors.error add-alternative called when main targets are already
|
| 321 |
+
created. : in project [ full-name ] ;
|
| 322 |
+
}
|
| 323 |
+
self.alternatives += $(target-instance) ;
|
| 324 |
+
}
|
| 325 |
+
|
| 326 |
+
# Returns a 'main-target' class instance corresponding to 'name'.
|
| 327 |
+
#
|
| 328 |
+
rule main-target ( name )
|
| 329 |
+
{
|
| 330 |
+
if ! $(self.built-main-targets)
|
| 331 |
+
{
|
| 332 |
+
build-main-targets ;
|
| 333 |
+
}
|
| 334 |
+
return $(self.main-target.$(name)) ;
|
| 335 |
+
}
|
| 336 |
+
|
| 337 |
+
# Returns whether a main target with the specified name exists.
|
| 338 |
+
#
|
| 339 |
+
rule has-main-target ( name )
|
| 340 |
+
{
|
| 341 |
+
if ! $(self.built-main-targets)
|
| 342 |
+
{
|
| 343 |
+
build-main-targets ;
|
| 344 |
+
}
|
| 345 |
+
|
| 346 |
+
if $(self.main-target.$(name))
|
| 347 |
+
{
|
| 348 |
+
return true ;
|
| 349 |
+
}
|
| 350 |
+
}
|
| 351 |
+
|
| 352 |
+
# Worker function for the find rule not implementing any caching and simply
|
| 353 |
+
# returning nothing in case the target can not be found.
|
| 354 |
+
#
|
| 355 |
+
rule find-really ( id )
|
| 356 |
+
{
|
| 357 |
+
local result ;
|
| 358 |
+
local current-location = [ get location ] ;
|
| 359 |
+
|
| 360 |
+
local split = [ MATCH (.*)//(.*) : $(id) ] ;
|
| 361 |
+
local project-part = $(split[1]) ;
|
| 362 |
+
local target-part = $(split[2]) ;
|
| 363 |
+
|
| 364 |
+
local extra-error-message ;
|
| 365 |
+
if $(project-part)
|
| 366 |
+
{
|
| 367 |
+
# There is an explicitly specified project part in id. Looks up the
|
| 368 |
+
# project and passes the request to it.
|
| 369 |
+
local pm = [ project.find $(project-part) : $(current-location) ] ;
|
| 370 |
+
if $(pm)
|
| 371 |
+
{
|
| 372 |
+
project-target = [ project.target $(pm) ] ;
|
| 373 |
+
result = [ $(project-target).find $(target-part) : no-error ] ;
|
| 374 |
+
}
|
| 375 |
+
else
|
| 376 |
+
{
|
| 377 |
+
# TODO: This extra error message will not get displayed most
|
| 378 |
+
# likely due to some buggy refactoring. Refactor the code so the
|
| 379 |
+
# message gets diplayed again.
|
| 380 |
+
extra-error-message = error: could not find project
|
| 381 |
+
'$(project-part)' ;
|
| 382 |
+
}
|
| 383 |
+
}
|
| 384 |
+
else
|
| 385 |
+
{
|
| 386 |
+
# Interpret target-name as name of main target. Need to do this
|
| 387 |
+
# before checking for file. Consider the following scenario with a
|
| 388 |
+
# toolset not modifying its executable's names, e.g. gcc on
|
| 389 |
+
# Unix-like platforms:
|
| 390 |
+
#
|
| 391 |
+
# exe test : test.cpp ;
|
| 392 |
+
# install s : test : <location>. ;
|
| 393 |
+
#
|
| 394 |
+
# After the first build we would have a target named 'test' in the
|
| 395 |
+
# Jamfile and a file named 'test' on the disk. We need the target to
|
| 396 |
+
# override the file.
|
| 397 |
+
result = [ main-target $(id) ] ;
|
| 398 |
+
|
| 399 |
+
# Interpret id as an existing file reference.
|
| 400 |
+
if ! $(result)
|
| 401 |
+
{
|
| 402 |
+
result = [ new file-reference [ path.make $(id) ] :
|
| 403 |
+
$(self.project) ] ;
|
| 404 |
+
if ! [ $(result).exists ]
|
| 405 |
+
{
|
| 406 |
+
result = ;
|
| 407 |
+
}
|
| 408 |
+
}
|
| 409 |
+
|
| 410 |
+
# Interpret id as project-id.
|
| 411 |
+
if ! $(result)
|
| 412 |
+
{
|
| 413 |
+
local project-module = [ project.find $(id) :
|
| 414 |
+
$(current-location) ] ;
|
| 415 |
+
if $(project-module)
|
| 416 |
+
{
|
| 417 |
+
result = [ project.target $(project-module) ] ;
|
| 418 |
+
}
|
| 419 |
+
}
|
| 420 |
+
}
|
| 421 |
+
|
| 422 |
+
return $(result) ;
|
| 423 |
+
}
|
| 424 |
+
|
| 425 |
+
# Find and return the target with the specified id, treated relative to
|
| 426 |
+
# self. Id may specify either a target or a file name with the target taking
|
| 427 |
+
# priority. May report an error or return nothing if the target is not found
|
| 428 |
+
# depending on the 'no-error' parameter.
|
| 429 |
+
#
|
| 430 |
+
rule find ( id : no-error ? )
|
| 431 |
+
{
|
| 432 |
+
local v = $(.id.$(id)) ;
|
| 433 |
+
if ! $(v)
|
| 434 |
+
{
|
| 435 |
+
v = [ find-really $(id) ] ;
|
| 436 |
+
if ! $(v)
|
| 437 |
+
{
|
| 438 |
+
v = none ;
|
| 439 |
+
}
|
| 440 |
+
.id.$(id) = $(v) ;
|
| 441 |
+
}
|
| 442 |
+
|
| 443 |
+
if $(v) != none
|
| 444 |
+
{
|
| 445 |
+
return $(v) ;
|
| 446 |
+
}
|
| 447 |
+
else
|
| 448 |
+
{
|
| 449 |
+
if ! $(no-error)
|
| 450 |
+
{
|
| 451 |
+
local current-location = [ get location ] ;
|
| 452 |
+
ECHO "error: Unable to find file or target named" ;
|
| 453 |
+
ECHO "error: '$(id)'" ;
|
| 454 |
+
ECHO "error: referred from project at" ;
|
| 455 |
+
ECHO "error: '$(current-location)'" ;
|
| 456 |
+
ECHO $(extra-error-message) ;
|
| 457 |
+
EXIT ;
|
| 458 |
+
}
|
| 459 |
+
}
|
| 460 |
+
}
|
| 461 |
+
|
| 462 |
+
rule build-main-targets ( )
|
| 463 |
+
{
|
| 464 |
+
self.built-main-targets = true ;
|
| 465 |
+
for local a in $(self.alternatives)
|
| 466 |
+
{
|
| 467 |
+
local name = [ $(a).name ] ;
|
| 468 |
+
local target = $(self.main-target.$(name)) ;
|
| 469 |
+
if ! $(target)
|
| 470 |
+
{
|
| 471 |
+
local t = [ new main-target $(name) : $(self.project) ] ;
|
| 472 |
+
self.main-target.$(name) = $(t) ;
|
| 473 |
+
self.main-targets += $(t) ;
|
| 474 |
+
target = $(self.main-target.$(name)) ;
|
| 475 |
+
}
|
| 476 |
+
|
| 477 |
+
if $(name) in $(self.always-targets)
|
| 478 |
+
{
|
| 479 |
+
$(a).always ;
|
| 480 |
+
}
|
| 481 |
+
|
| 482 |
+
$(target).add-alternative $(a) ;
|
| 483 |
+
}
|
| 484 |
+
}
|
| 485 |
+
|
| 486 |
+
# Accessor, add a constant.
|
| 487 |
+
#
|
| 488 |
+
rule add-constant (
|
| 489 |
+
name # Variable name of the constant.
|
| 490 |
+
: value + # Value of the constant.
|
| 491 |
+
: type ? # Optional type of value.
|
| 492 |
+
)
|
| 493 |
+
{
|
| 494 |
+
switch $(type)
|
| 495 |
+
{
|
| 496 |
+
case path :
|
| 497 |
+
local r ;
|
| 498 |
+
for local v in $(value)
|
| 499 |
+
{
|
| 500 |
+
local l = $(self.location) ;
|
| 501 |
+
if ! $(l)
|
| 502 |
+
{
|
| 503 |
+
# Project corresponding to config files do not have
|
| 504 |
+
# 'location' attribute, but do have source location.
|
| 505 |
+
# It might be more reasonable to make every project have
|
| 506 |
+
# a location and use some other approach to prevent buildable
|
| 507 |
+
# targets in config files, but that's for later.
|
| 508 |
+
l = [ get source-location ] ;
|
| 509 |
+
}
|
| 510 |
+
v = [ path.root [ path.make $(v) ] $(l) ] ;
|
| 511 |
+
# Now make the value absolute path.
|
| 512 |
+
v = [ path.root $(v) [ path.pwd ] ] ;
|
| 513 |
+
# Constants should be in platform-native form.
|
| 514 |
+
v = [ path.native $(v) ] ;
|
| 515 |
+
r += $(v) ;
|
| 516 |
+
}
|
| 517 |
+
value = $(r) ;
|
| 518 |
+
}
|
| 519 |
+
if ! $(name) in $(self.constants)
|
| 520 |
+
{
|
| 521 |
+
self.constants += $(name) ;
|
| 522 |
+
}
|
| 523 |
+
self.constant.$(name) = $(value) ;
|
| 524 |
+
# Inject the constant in the scope of the Jamroot module.
|
| 525 |
+
modules.poke $(self.project-module) : $(name) : $(value) ;
|
| 526 |
+
}
|
| 527 |
+
|
| 528 |
+
rule inherit ( parent )
|
| 529 |
+
{
|
| 530 |
+
for local c in [ modules.peek $(parent) : self.constants ]
|
| 531 |
+
{
|
| 532 |
+
# No need to pass the type. Path constants were converted to
|
| 533 |
+
# absolute paths already by parent.
|
| 534 |
+
add-constant $(c)
|
| 535 |
+
: [ modules.peek $(parent) : self.constant.$(c) ] ;
|
| 536 |
+
}
|
| 537 |
+
|
| 538 |
+
# Import rules from parent.
|
| 539 |
+
local this-module = [ project-module ] ;
|
| 540 |
+
local parent-module = [ $(parent).project-module ] ;
|
| 541 |
+
# Do not import rules coming from 'project-rules' as they must be
|
| 542 |
+
# imported localized.
|
| 543 |
+
local user-rules = [ set.difference
|
| 544 |
+
[ RULENAMES $(parent-module) ] :
|
| 545 |
+
[ RULENAMES project-rules ] ] ;
|
| 546 |
+
IMPORT $(parent-module) : $(user-rules) : $(this-module) : $(user-rules) ;
|
| 547 |
+
EXPORT $(this-module) : $(user-rules) ;
|
| 548 |
+
}
|
| 549 |
+
}
|
| 550 |
+
|
| 551 |
+
|
| 552 |
+
# Helper rules to detect cycles in main target references.
|
| 553 |
+
#
|
| 554 |
+
local rule start-building ( main-target-instance )
|
| 555 |
+
{
|
| 556 |
+
if $(main-target-instance) in $(.targets-being-built)
|
| 557 |
+
{
|
| 558 |
+
local names ;
|
| 559 |
+
for local t in $(.targets-being-built) $(main-target-instance)
|
| 560 |
+
{
|
| 561 |
+
names += [ $(t).full-name ] ;
|
| 562 |
+
}
|
| 563 |
+
|
| 564 |
+
errors.error "Recursion in main target references"
|
| 565 |
+
: "the following target are being built currently:"
|
| 566 |
+
: $(names) ;
|
| 567 |
+
}
|
| 568 |
+
.targets-being-built += $(main-target-instance) ;
|
| 569 |
+
}
|
| 570 |
+
|
| 571 |
+
|
| 572 |
+
local rule end-building ( main-target-instance )
|
| 573 |
+
{
|
| 574 |
+
.targets-being-built = $(.targets-being-built[1--2]) ;
|
| 575 |
+
}
|
| 576 |
+
|
| 577 |
+
|
| 578 |
+
# A named top-level target in Jamfile.
|
| 579 |
+
#
|
| 580 |
+
class main-target : abstract-target
|
| 581 |
+
{
|
| 582 |
+
import assert ;
|
| 583 |
+
import errors ;
|
| 584 |
+
import feature ;
|
| 585 |
+
import print ;
|
| 586 |
+
import property-set ;
|
| 587 |
+
import sequence ;
|
| 588 |
+
import targets : start-building end-building ;
|
| 589 |
+
|
| 590 |
+
rule __init__ ( name : project )
|
| 591 |
+
{
|
| 592 |
+
abstract-target.__init__ $(name) : $(project) ;
|
| 593 |
+
}
|
| 594 |
+
|
| 595 |
+
# Add a new alternative for this target
|
| 596 |
+
rule add-alternative ( target )
|
| 597 |
+
{
|
| 598 |
+
local d = [ $(target).default-build ] ;
|
| 599 |
+
if $(self.alternatives) && ( $(self.default-build) != $(d) )
|
| 600 |
+
{
|
| 601 |
+
errors.error "default build must be identical in all alternatives"
|
| 602 |
+
: "main target is" [ full-name ]
|
| 603 |
+
: "with" [ $(d).raw ]
|
| 604 |
+
: "differing from previous default build" [ $(self.default-build).raw ] ;
|
| 605 |
+
}
|
| 606 |
+
else
|
| 607 |
+
{
|
| 608 |
+
self.default-build = $(d) ;
|
| 609 |
+
}
|
| 610 |
+
self.alternatives += $(target) ;
|
| 611 |
+
}
|
| 612 |
+
|
| 613 |
+
# Returns the best viable alternative for this property-set. See the
|
| 614 |
+
# documentation for selection rules.
|
| 615 |
+
#
|
| 616 |
+
local rule select-alternatives ( property-set debug ? )
|
| 617 |
+
{
|
| 618 |
+
# When selecting alternatives we have to consider defaults, for example:
|
| 619 |
+
# lib l : l.cpp : <variant>debug ;
|
| 620 |
+
# lib l : l_opt.cpp : <variant>release ;
|
| 621 |
+
# won't work unless we add default value <variant>debug.
|
| 622 |
+
property-set = [ $(p).add-defaults ] ;
|
| 623 |
+
|
| 624 |
+
# The algorithm: we keep the current best viable alternative. When we've
|
| 625 |
+
# got a new best viable alternative, we compare it with the current one.
|
| 626 |
+
|
| 627 |
+
local best ;
|
| 628 |
+
local best-properties ;
|
| 629 |
+
|
| 630 |
+
if $(self.alternatives[2-])
|
| 631 |
+
{
|
| 632 |
+
local bad ;
|
| 633 |
+
local worklist = $(self.alternatives) ;
|
| 634 |
+
while $(worklist) && ! $(bad)
|
| 635 |
+
{
|
| 636 |
+
local v = $(worklist[1]) ;
|
| 637 |
+
local properties = [ $(v).match $(property-set) $(debug) ] ;
|
| 638 |
+
|
| 639 |
+
if $(properties) != no-match
|
| 640 |
+
{
|
| 641 |
+
if ! $(best)
|
| 642 |
+
{
|
| 643 |
+
best = $(v) ;
|
| 644 |
+
best-properties = $(properties) ;
|
| 645 |
+
}
|
| 646 |
+
else
|
| 647 |
+
{
|
| 648 |
+
if $(properties) = $(best-properties)
|
| 649 |
+
{
|
| 650 |
+
bad = true ;
|
| 651 |
+
}
|
| 652 |
+
else if $(properties) in $(best-properties)
|
| 653 |
+
{
|
| 654 |
+
# Do nothing, this alternative is worse
|
| 655 |
+
}
|
| 656 |
+
else if $(best-properties) in $(properties)
|
| 657 |
+
{
|
| 658 |
+
best = $(v) ;
|
| 659 |
+
best-properties = $(properties) ;
|
| 660 |
+
}
|
| 661 |
+
else
|
| 662 |
+
{
|
| 663 |
+
bad = true ;
|
| 664 |
+
}
|
| 665 |
+
}
|
| 666 |
+
}
|
| 667 |
+
worklist = $(worklist[2-]) ;
|
| 668 |
+
}
|
| 669 |
+
if ! $(bad)
|
| 670 |
+
{
|
| 671 |
+
return $(best) ;
|
| 672 |
+
}
|
| 673 |
+
}
|
| 674 |
+
else
|
| 675 |
+
{
|
| 676 |
+
return $(self.alternatives) ;
|
| 677 |
+
}
|
| 678 |
+
}
|
| 679 |
+
|
| 680 |
+
rule apply-default-build ( property-set )
|
| 681 |
+
{
|
| 682 |
+
return [ targets.apply-default-build $(property-set)
|
| 683 |
+
: $(self.default-build) ] ;
|
| 684 |
+
}
|
| 685 |
+
|
| 686 |
+
# Select an alternative for this main target, by finding all alternatives
|
| 687 |
+
# which requirements are satisfied by 'properties' and picking the one with
|
| 688 |
+
# the longest requirements set. Returns the result of calling 'generate' on
|
| 689 |
+
# that alternative.
|
| 690 |
+
#
|
| 691 |
+
rule generate ( property-set )
|
| 692 |
+
{
|
| 693 |
+
start-building $(__name__) ;
|
| 694 |
+
|
| 695 |
+
# We want composite properties in build request act as if all the
|
| 696 |
+
# properties it expands too are explicitly specified.
|
| 697 |
+
property-set = [ $(property-set).expand ] ;
|
| 698 |
+
|
| 699 |
+
local all-property-sets = [ apply-default-build $(property-set) ] ;
|
| 700 |
+
local usage-requirements = [ property-set.empty ] ;
|
| 701 |
+
local result ;
|
| 702 |
+
for local p in $(all-property-sets)
|
| 703 |
+
{
|
| 704 |
+
local r = [ generate-really $(p) ] ;
|
| 705 |
+
if $(r)
|
| 706 |
+
{
|
| 707 |
+
usage-requirements = [ $(usage-requirements).add $(r[1]) ] ;
|
| 708 |
+
result += $(r[2-]) ;
|
| 709 |
+
}
|
| 710 |
+
}
|
| 711 |
+
end-building $(__name__) ;
|
| 712 |
+
return $(usage-requirements) [ sequence.unique $(result) ] ;
|
| 713 |
+
}
|
| 714 |
+
|
| 715 |
+
# Generates the main target with the given property set and returns a list
|
| 716 |
+
# which first element is property-set object containing usage-requirements
|
| 717 |
+
# of generated target and with generated virtual target in other elements.
|
| 718 |
+
# It is possible that no targets are generated.
|
| 719 |
+
#
|
| 720 |
+
local rule generate-really ( property-set )
|
| 721 |
+
{
|
| 722 |
+
local best-alternatives = [ select-alternatives $(property-set) ] ;
|
| 723 |
+
if ! $(best-alternatives)
|
| 724 |
+
{
|
| 725 |
+
ECHO "error: No best alternative for" [ full-name ] ;
|
| 726 |
+
select-alternatives $(property-set) debug ;
|
| 727 |
+
return [ property-set.empty ] ;
|
| 728 |
+
}
|
| 729 |
+
else
|
| 730 |
+
{
|
| 731 |
+
# Now return virtual targets for the only alternative.
|
| 732 |
+
return [ $(best-alternatives).generate $(property-set) ] ;
|
| 733 |
+
}
|
| 734 |
+
}
|
| 735 |
+
|
| 736 |
+
rule rename ( new-name )
|
| 737 |
+
{
|
| 738 |
+
abstract-target.rename $(new-name) ;
|
| 739 |
+
for local a in $(self.alternatives)
|
| 740 |
+
{
|
| 741 |
+
$(a).rename $(new-name) ;
|
| 742 |
+
}
|
| 743 |
+
}
|
| 744 |
+
}
|
| 745 |
+
|
| 746 |
+
|
| 747 |
+
# Abstract target refering to a source file. This is an artificial entity
|
| 748 |
+
# allowing sources to a target to be represented using a list of abstract target
|
| 749 |
+
# instances.
|
| 750 |
+
#
|
| 751 |
+
class file-reference : abstract-target
|
| 752 |
+
{
|
| 753 |
+
import virtual-target ;
|
| 754 |
+
import property-set ;
|
| 755 |
+
import path ;
|
| 756 |
+
|
| 757 |
+
rule __init__ ( file : project )
|
| 758 |
+
{
|
| 759 |
+
abstract-target.__init__ $(file) : $(project) ;
|
| 760 |
+
}
|
| 761 |
+
|
| 762 |
+
rule generate ( properties )
|
| 763 |
+
{
|
| 764 |
+
return [ property-set.empty ] [ virtual-target.from-file $(self.name) :
|
| 765 |
+
[ location ] : $(self.project) ] ;
|
| 766 |
+
}
|
| 767 |
+
|
| 768 |
+
# Returns true if the referred file really exists.
|
| 769 |
+
rule exists ( )
|
| 770 |
+
{
|
| 771 |
+
location ;
|
| 772 |
+
return $(self.file-path) ;
|
| 773 |
+
}
|
| 774 |
+
|
| 775 |
+
# Returns the location of target. Needed by 'testing.jam'.
|
| 776 |
+
rule location ( )
|
| 777 |
+
{
|
| 778 |
+
if ! $(self.file-location)
|
| 779 |
+
{
|
| 780 |
+
local source-location = [ $(self.project).get source-location ] ;
|
| 781 |
+
for local src-dir in $(source-location)
|
| 782 |
+
{
|
| 783 |
+
if ! $(self.file-location)
|
| 784 |
+
{
|
| 785 |
+
local location = [ path.root $(self.name) $(src-dir) ] ;
|
| 786 |
+
if [ CHECK_IF_FILE [ path.native $(location) ] ]
|
| 787 |
+
{
|
| 788 |
+
self.file-location = $(src-dir) ;
|
| 789 |
+
self.file-path = $(location) ;
|
| 790 |
+
}
|
| 791 |
+
}
|
| 792 |
+
}
|
| 793 |
+
}
|
| 794 |
+
return $(self.file-location) ;
|
| 795 |
+
}
|
| 796 |
+
}
|
| 797 |
+
|
| 798 |
+
|
| 799 |
+
# Given a target-reference, made in context of 'project', returns the
|
| 800 |
+
# abstract-target instance that is referred to, as well as properties explicitly
|
| 801 |
+
# specified for this reference.
|
| 802 |
+
#
|
| 803 |
+
rule resolve-reference ( target-reference : project )
|
| 804 |
+
{
|
| 805 |
+
# Separate target name from properties override.
|
| 806 |
+
local split = [ MATCH "^([^<]*)(/(<.*))?$" : $(target-reference) ] ;
|
| 807 |
+
local id = $(split[1]) ;
|
| 808 |
+
local sproperties = ;
|
| 809 |
+
if $(split[3])
|
| 810 |
+
{
|
| 811 |
+
sproperties = [ property.make [ feature.split $(split[3]) ] ] ;
|
| 812 |
+
sproperties = [ feature.expand-composites $(sproperties) ] ;
|
| 813 |
+
}
|
| 814 |
+
|
| 815 |
+
# Find the target.
|
| 816 |
+
local target = [ $(project).find $(id) ] ;
|
| 817 |
+
|
| 818 |
+
return $(target) [ property-set.create $(sproperties) ] ;
|
| 819 |
+
}
|
| 820 |
+
|
| 821 |
+
|
| 822 |
+
# Attempts to generate the target given by target reference, which can refer
|
| 823 |
+
# both to a main target or to a file. Returns a list consisting of
|
| 824 |
+
# - usage requirements
|
| 825 |
+
# - generated virtual targets, if any
|
| 826 |
+
#
|
| 827 |
+
rule generate-from-reference (
|
| 828 |
+
target-reference # Target reference.
|
| 829 |
+
: project # Project where the reference is made.
|
| 830 |
+
: property-set # Properties of the main target that makes the reference.
|
| 831 |
+
)
|
| 832 |
+
{
|
| 833 |
+
local r = [ resolve-reference $(target-reference) : $(project) ] ;
|
| 834 |
+
local target = $(r[1]) ;
|
| 835 |
+
local sproperties = $(r[2]) ;
|
| 836 |
+
|
| 837 |
+
# Take properties which should be propagated and refine them with
|
| 838 |
+
# source-specific requirements.
|
| 839 |
+
local propagated = [ $(property-set).propagated ] ;
|
| 840 |
+
local rproperties = [ $(propagated).refine $(sproperties) ] ;
|
| 841 |
+
if $(rproperties[1]) = "@error"
|
| 842 |
+
{
|
| 843 |
+
errors.error
|
| 844 |
+
"When building" [ full-name ] " with properties " $(properties) :
|
| 845 |
+
"Invalid properties specified for " $(source) ":"
|
| 846 |
+
$(rproperties[2-]) ;
|
| 847 |
+
}
|
| 848 |
+
return [ $(target).generate $(rproperties) ] ;
|
| 849 |
+
}
|
| 850 |
+
|
| 851 |
+
rule apply-default-build ( property-set : default-build )
|
| 852 |
+
{
|
| 853 |
+
# 1. First, see what properties from default-build are already present
|
| 854 |
+
# in property-set.
|
| 855 |
+
|
| 856 |
+
local raw = [ $(property-set).raw ] ;
|
| 857 |
+
local specified-features = $(raw:G) ;
|
| 858 |
+
|
| 859 |
+
local defaults-to-apply ;
|
| 860 |
+
for local d in [ $(default-build).raw ]
|
| 861 |
+
{
|
| 862 |
+
if ! $(d:G) in $(specified-features)
|
| 863 |
+
{
|
| 864 |
+
defaults-to-apply += $(d) ;
|
| 865 |
+
}
|
| 866 |
+
}
|
| 867 |
+
|
| 868 |
+
# 2. If there are any defaults to be applied, form a new build request.
|
| 869 |
+
# Pass it through to 'expand-no-defaults' since default-build might
|
| 870 |
+
# contain "release debug" resulting in two property-sets.
|
| 871 |
+
local result ;
|
| 872 |
+
if $(defaults-to-apply)
|
| 873 |
+
{
|
| 874 |
+
properties = [
|
| 875 |
+
build-request.expand-no-defaults
|
| 876 |
+
|
| 877 |
+
# We have to compress subproperties here to prevent property
|
| 878 |
+
# lists like:
|
| 879 |
+
#
|
| 880 |
+
# <toolset>msvc <toolset-msvc:version>7.1 <threading>multi
|
| 881 |
+
#
|
| 882 |
+
# from being expanded into:
|
| 883 |
+
#
|
| 884 |
+
# <toolset-msvc:version>7.1/<threading>multi
|
| 885 |
+
# <toolset>msvc/<toolset-msvc:version>7.1/<threading>multi
|
| 886 |
+
#
|
| 887 |
+
# due to a cross-product property combination. That may be an
|
| 888 |
+
# indication that build-request.expand-no-defaults is the wrong
|
| 889 |
+
# rule to use here.
|
| 890 |
+
[ feature.compress-subproperties $(raw) ]
|
| 891 |
+
$(defaults-to-apply)
|
| 892 |
+
] ;
|
| 893 |
+
|
| 894 |
+
if $(properties)
|
| 895 |
+
{
|
| 896 |
+
for local p in $(properties)
|
| 897 |
+
{
|
| 898 |
+
result += [ property-set.create
|
| 899 |
+
[ feature.expand [ feature.split $(p) ] ] ] ;
|
| 900 |
+
}
|
| 901 |
+
}
|
| 902 |
+
else
|
| 903 |
+
{
|
| 904 |
+
result = [ property-set.empty ] ;
|
| 905 |
+
}
|
| 906 |
+
}
|
| 907 |
+
else
|
| 908 |
+
{
|
| 909 |
+
result = $(property-set) ;
|
| 910 |
+
}
|
| 911 |
+
return $(result) ;
|
| 912 |
+
}
|
| 913 |
+
|
| 914 |
+
|
| 915 |
+
# Given a build request and requirements, return properties common to dependency
|
| 916 |
+
# build request and target requirements.
|
| 917 |
+
#
|
| 918 |
+
# TODO: Document exactly what 'common properties' are, whether they should
|
| 919 |
+
# include default property values, whether they should contain any conditional
|
| 920 |
+
# properties or should those be already processed, etc. See whether there are
|
| 921 |
+
# any differences between use cases with empty and non-empty build-request as
|
| 922 |
+
# well as with requirements containing and those not containing any non-free
|
| 923 |
+
# features.
|
| 924 |
+
#
|
| 925 |
+
rule common-properties ( build-request requirements )
|
| 926 |
+
{
|
| 927 |
+
# For optimization, we add free requirements directly, without using a
|
| 928 |
+
# complex algorithm. This gives the complex algorithm a better chance of
|
| 929 |
+
# caching results.
|
| 930 |
+
local free = [ $(requirements).free ] ;
|
| 931 |
+
local non-free = [ property-set.create [ $(requirements).base ]
|
| 932 |
+
[ $(requirements).incidental ] ] ;
|
| 933 |
+
|
| 934 |
+
local key = .rp.$(build-request)-$(non-free) ;
|
| 935 |
+
if ! $($(key))
|
| 936 |
+
{
|
| 937 |
+
$(key) = [ common-properties2 $(build-request) $(non-free) ] ;
|
| 938 |
+
}
|
| 939 |
+
return [ $($(key)).add-raw $(free) ] ;
|
| 940 |
+
}
|
| 941 |
+
|
| 942 |
+
|
| 943 |
+
# Given a 'context' -- a set of already present properties, and 'requirements',
|
| 944 |
+
# decide which extra properties should be applied to 'context'. For conditional
|
| 945 |
+
# requirements, this means evaluating the condition. For indirect conditional
|
| 946 |
+
# requirements, this means calling a rule. Ordinary requirements are always
|
| 947 |
+
# applied.
|
| 948 |
+
#
|
| 949 |
+
# Handles the situation where evaluating one conditional requirement affects
|
| 950 |
+
# conditions of another conditional requirements, such as:
|
| 951 |
+
# <toolset>gcc:<variant>release <variant>release:<define>RELEASE
|
| 952 |
+
#
|
| 953 |
+
# If 'what' is 'refined' returns context refined with new requirements. If
|
| 954 |
+
# 'what' is 'added' returns just the requirements to be applied.
|
| 955 |
+
#
|
| 956 |
+
rule evaluate-requirements ( requirements : context : what )
|
| 957 |
+
{
|
| 958 |
+
# Apply non-conditional requirements. It is possible that further
|
| 959 |
+
# conditional requirement change a value set by non-conditional
|
| 960 |
+
# requirements. For example:
|
| 961 |
+
#
|
| 962 |
+
# exe a : a.cpp : <threading>single <toolset>foo:<threading>multi ;
|
| 963 |
+
#
|
| 964 |
+
# I am not sure if this should be an error, or not, especially given that
|
| 965 |
+
#
|
| 966 |
+
# <threading>single
|
| 967 |
+
#
|
| 968 |
+
# might come from project's requirements.
|
| 969 |
+
|
| 970 |
+
local unconditional = [ feature.expand [ $(requirements).non-conditional ] ] ;
|
| 971 |
+
|
| 972 |
+
local raw = [ $(context).raw ] ;
|
| 973 |
+
raw = [ property.refine $(raw) : $(unconditional) ] ;
|
| 974 |
+
|
| 975 |
+
# We have collected properties that surely must be present in common
|
| 976 |
+
# properties. We now try to figure out what other properties should be added
|
| 977 |
+
# in order to satisfy rules (4)-(6) from the docs.
|
| 978 |
+
|
| 979 |
+
local conditionals = [ $(requirements).conditional ] ;
|
| 980 |
+
# The 'count' variable has one element for each conditional feature and for
|
| 981 |
+
# each occurrence of '<indirect-conditional>' feature. It is used as a loop
|
| 982 |
+
# counter: for each iteration of the loop before we remove one element and
|
| 983 |
+
# the property set should stabilize before we are done. It is assumed that
|
| 984 |
+
# #conditionals iterations should be enough for properties to propagate
|
| 985 |
+
# along conditions in any direction.
|
| 986 |
+
local count = $(conditionals)
|
| 987 |
+
[ $(requirements).get <conditional> ]
|
| 988 |
+
and-once-more ;
|
| 989 |
+
|
| 990 |
+
local added-requirements ;
|
| 991 |
+
|
| 992 |
+
local current = $(raw) ;
|
| 993 |
+
|
| 994 |
+
# It is assumed that ordinary conditional requirements can not add
|
| 995 |
+
# <conditional> properties (a.k.a. indirect conditional properties), and
|
| 996 |
+
# that rules referred to by <conditional> properties can not add new
|
| 997 |
+
# <conditional> properties. So the list of indirect conditionals does not
|
| 998 |
+
# change.
|
| 999 |
+
local indirect = [ $(requirements).get <conditional> ] ;
|
| 1000 |
+
indirect = [ MATCH ^@(.*) : $(indirect) ] ;
|
| 1001 |
+
|
| 1002 |
+
local ok ;
|
| 1003 |
+
while $(count)
|
| 1004 |
+
{
|
| 1005 |
+
# Evaluate conditionals in context of current properties.
|
| 1006 |
+
local e = [ property.evaluate-conditionals-in-context $(conditionals)
|
| 1007 |
+
: $(current) ] ;
|
| 1008 |
+
|
| 1009 |
+
# Evaluate indirect conditionals.
|
| 1010 |
+
for local i in $(indirect)
|
| 1011 |
+
{
|
| 1012 |
+
e += [ indirect.call $(i) $(current) ] ;
|
| 1013 |
+
}
|
| 1014 |
+
|
| 1015 |
+
if $(e) = $(added-requirements)
|
| 1016 |
+
{
|
| 1017 |
+
# If we got the same result, we have found the final properties.
|
| 1018 |
+
count = ;
|
| 1019 |
+
ok = true ;
|
| 1020 |
+
}
|
| 1021 |
+
else
|
| 1022 |
+
{
|
| 1023 |
+
# Oops, conditional evaluation results have changed. Also 'current'
|
| 1024 |
+
# contains leftovers from a previous evaluation. Recompute 'current'
|
| 1025 |
+
# using initial properties and conditional requirements.
|
| 1026 |
+
added-requirements = $(e) ;
|
| 1027 |
+
current = [ property.refine $(raw) : [ feature.expand $(e) ] ] ;
|
| 1028 |
+
}
|
| 1029 |
+
count = $(count[2-]) ;
|
| 1030 |
+
}
|
| 1031 |
+
if ! $(ok)
|
| 1032 |
+
{
|
| 1033 |
+
errors.error "Can not evaluate conditional properties " $(conditionals) ;
|
| 1034 |
+
}
|
| 1035 |
+
|
| 1036 |
+
if $(what) = added
|
| 1037 |
+
{
|
| 1038 |
+
return [ property-set.create $(unconditional) $(added-requirements) ] ;
|
| 1039 |
+
}
|
| 1040 |
+
else if $(what) = refined
|
| 1041 |
+
{
|
| 1042 |
+
return [ property-set.create $(current) ] ;
|
| 1043 |
+
}
|
| 1044 |
+
else
|
| 1045 |
+
{
|
| 1046 |
+
errors.error "Invalid value of the 'what' parameter." ;
|
| 1047 |
+
}
|
| 1048 |
+
}
|
| 1049 |
+
|
| 1050 |
+
|
| 1051 |
+
rule common-properties2 ( build-request requirements )
|
| 1052 |
+
{
|
| 1053 |
+
# This guarantees that default properties are present in the result, unless
|
| 1054 |
+
# they are overriden by some requirement. FIXME: There is possibility that
|
| 1055 |
+
# we have added <foo>bar, which is composite and expands to <foo2>bar2, but
|
| 1056 |
+
# default value of <foo2> is not bar2, in which case it is not clear what to
|
| 1057 |
+
# do.
|
| 1058 |
+
#
|
| 1059 |
+
build-request = [ $(build-request).add-defaults ] ;
|
| 1060 |
+
# Features added by 'add-default' can be composite and expand to features
|
| 1061 |
+
# without default values -- so they are not added yet. It could be clearer/
|
| 1062 |
+
# /faster to expand only newly added properties but that is not critical.
|
| 1063 |
+
build-request = [ $(build-request).expand ] ;
|
| 1064 |
+
|
| 1065 |
+
return [ evaluate-requirements $(requirements) : $(build-request) :
|
| 1066 |
+
refined ] ;
|
| 1067 |
+
}
|
| 1068 |
+
|
| 1069 |
+
rule push-target ( target )
|
| 1070 |
+
{
|
| 1071 |
+
.targets = $(target) $(.targets) ;
|
| 1072 |
+
}
|
| 1073 |
+
|
| 1074 |
+
rule pop-target ( )
|
| 1075 |
+
{
|
| 1076 |
+
.targets = $(.targets[2-]) ;
|
| 1077 |
+
}
|
| 1078 |
+
|
| 1079 |
+
# Return the metatarget that is currently being generated.
|
| 1080 |
+
rule current ( )
|
| 1081 |
+
{
|
| 1082 |
+
return $(.targets[1]) ;
|
| 1083 |
+
}
|
| 1084 |
+
|
| 1085 |
+
|
| 1086 |
+
# Implements the most standard way of constructing main target alternative from
|
| 1087 |
+
# sources. Allows sources to be either file or other main target and handles
|
| 1088 |
+
# generation of those dependency targets.
|
| 1089 |
+
#
|
| 1090 |
+
class basic-target : abstract-target
|
| 1091 |
+
{
|
| 1092 |
+
import build-request ;
|
| 1093 |
+
import build-system ;
|
| 1094 |
+
import "class" : new ;
|
| 1095 |
+
import errors ;
|
| 1096 |
+
import feature ;
|
| 1097 |
+
import property ;
|
| 1098 |
+
import property-set ;
|
| 1099 |
+
import sequence ;
|
| 1100 |
+
import set ;
|
| 1101 |
+
import targets ;
|
| 1102 |
+
import virtual-target ;
|
| 1103 |
+
|
| 1104 |
+
rule __init__ ( name : project : sources * : requirements *
|
| 1105 |
+
: default-build * : usage-requirements * )
|
| 1106 |
+
{
|
| 1107 |
+
abstract-target.__init__ $(name) : $(project) ;
|
| 1108 |
+
|
| 1109 |
+
self.sources = $(sources) ;
|
| 1110 |
+
if ! $(requirements) {
|
| 1111 |
+
requirements = [ property-set.empty ] ;
|
| 1112 |
+
}
|
| 1113 |
+
self.requirements = $(requirements) ;
|
| 1114 |
+
if ! $(default-build)
|
| 1115 |
+
{
|
| 1116 |
+
default-build = [ property-set.empty ] ;
|
| 1117 |
+
}
|
| 1118 |
+
self.default-build = $(default-build) ;
|
| 1119 |
+
if ! $(usage-requirements)
|
| 1120 |
+
{
|
| 1121 |
+
usage-requirements = [ property-set.empty ] ;
|
| 1122 |
+
}
|
| 1123 |
+
self.usage-requirements = $(usage-requirements) ;
|
| 1124 |
+
|
| 1125 |
+
if $(sources:G)
|
| 1126 |
+
{
|
| 1127 |
+
errors.user-error properties found in the 'sources' parameter for
|
| 1128 |
+
[ full-name ] ;
|
| 1129 |
+
}
|
| 1130 |
+
}
|
| 1131 |
+
|
| 1132 |
+
rule always ( )
|
| 1133 |
+
{
|
| 1134 |
+
self.always = 1 ;
|
| 1135 |
+
}
|
| 1136 |
+
|
| 1137 |
+
# Returns the list of abstract-targets which are used as sources. The extra
|
| 1138 |
+
# properties specified for sources are not represented. The only user for
|
| 1139 |
+
# this rule at the moment is the "--dump-tests" feature of the test system.
|
| 1140 |
+
#
|
| 1141 |
+
rule sources ( )
|
| 1142 |
+
{
|
| 1143 |
+
if ! $(self.source-targets)
|
| 1144 |
+
{
|
| 1145 |
+
for local s in $(self.sources)
|
| 1146 |
+
{
|
| 1147 |
+
self.source-targets +=
|
| 1148 |
+
[ targets.resolve-reference $(s) : $(self.project) ] ;
|
| 1149 |
+
}
|
| 1150 |
+
}
|
| 1151 |
+
return $(self.source-targets) ;
|
| 1152 |
+
}
|
| 1153 |
+
|
| 1154 |
+
rule requirements ( )
|
| 1155 |
+
{
|
| 1156 |
+
return $(self.requirements) ;
|
| 1157 |
+
}
|
| 1158 |
+
|
| 1159 |
+
rule default-build ( )
|
| 1160 |
+
{
|
| 1161 |
+
return $(self.default-build) ;
|
| 1162 |
+
}
|
| 1163 |
+
|
| 1164 |
+
# Returns the alternative condition for this alternative, if the condition
|
| 1165 |
+
# is satisfied by 'property-set'.
|
| 1166 |
+
#
|
| 1167 |
+
rule match ( property-set debug ? )
|
| 1168 |
+
{
|
| 1169 |
+
# The condition is composed of all base non-conditional properties. It
|
| 1170 |
+
# is not clear if we should expand 'self.requirements' or not. For one
|
| 1171 |
+
# thing, it would be nice to be able to put
|
| 1172 |
+
# <toolset>msvc-6.0
|
| 1173 |
+
# in requirements. On the other hand, if we have <variant>release as a
|
| 1174 |
+
# condition it does not make sense to require <optimization>full to be
|
| 1175 |
+
# in the build request just to select this variant.
|
| 1176 |
+
local bcondition = [ $(self.requirements).base ] ;
|
| 1177 |
+
local ccondition = [ $(self.requirements).conditional ] ;
|
| 1178 |
+
local condition = [ set.difference $(bcondition) : $(ccondition) ] ;
|
| 1179 |
+
if $(debug)
|
| 1180 |
+
{
|
| 1181 |
+
ECHO " next alternative: required properties:" $(condition:E=(empty)) ;
|
| 1182 |
+
}
|
| 1183 |
+
|
| 1184 |
+
if $(condition) in [ $(property-set).raw ]
|
| 1185 |
+
{
|
| 1186 |
+
if $(debug)
|
| 1187 |
+
{
|
| 1188 |
+
ECHO " matched" ;
|
| 1189 |
+
}
|
| 1190 |
+
return $(condition) ;
|
| 1191 |
+
}
|
| 1192 |
+
else
|
| 1193 |
+
{
|
| 1194 |
+
if $(debug)
|
| 1195 |
+
{
|
| 1196 |
+
ECHO " not matched" ;
|
| 1197 |
+
}
|
| 1198 |
+
return no-match ;
|
| 1199 |
+
}
|
| 1200 |
+
}
|
| 1201 |
+
|
| 1202 |
+
# Takes a target reference, which might be either target id or a dependency
|
| 1203 |
+
# property, and generates that target using 'property-set' as build request.
|
| 1204 |
+
#
|
| 1205 |
+
# The results are added to the variable called 'result-var'. Usage
|
| 1206 |
+
# requirements are added to the variable called 'usage-requirements-var'.
|
| 1207 |
+
#
|
| 1208 |
+
rule generate-dependencies ( dependencies * : property-set
|
| 1209 |
+
: result-var usage-requirements-var )
|
| 1210 |
+
{
|
| 1211 |
+
for local dependency in $(dependencies)
|
| 1212 |
+
{
|
| 1213 |
+
local grist = $(dependency:G) ;
|
| 1214 |
+
local id = $(dependency:G=) ;
|
| 1215 |
+
|
| 1216 |
+
local result = [ targets.generate-from-reference $(id) :
|
| 1217 |
+
$(self.project) : $(property-set) ] ;
|
| 1218 |
+
|
| 1219 |
+
$(result-var) += $(result[2-]:G=$(grist)) ;
|
| 1220 |
+
$(usage-requirements-var) += [ $(result[1]).raw ] ;
|
| 1221 |
+
}
|
| 1222 |
+
}
|
| 1223 |
+
|
| 1224 |
+
# Determines final build properties, generates sources, and calls
|
| 1225 |
+
# 'construct'. This method should not be overridden.
|
| 1226 |
+
#
|
| 1227 |
+
rule generate ( property-set )
|
| 1228 |
+
{
|
| 1229 |
+
if [ modules.peek : .debug-building ]
|
| 1230 |
+
{
|
| 1231 |
+
ECHO ;
|
| 1232 |
+
local fn = [ full-name ] ;
|
| 1233 |
+
ECHO [ targets.indent ] "Building target '$(fn)'" ;
|
| 1234 |
+
targets.increase-indent ;
|
| 1235 |
+
ECHO [ targets.indent ] "Build request: " $(property-set) [ $(property-set).raw ] ;
|
| 1236 |
+
local cf = [ build-system.command-line-free-features ] ;
|
| 1237 |
+
ECHO [ targets.indent ] "Command line free features: " [ $(cf).raw ] ;
|
| 1238 |
+
ECHO [ targets.indent ] "Target requirements: " [ $(self.requirements).raw ] ;
|
| 1239 |
+
}
|
| 1240 |
+
targets.push-target $(__name__) ;
|
| 1241 |
+
|
| 1242 |
+
if ! $(self.generated.$(property-set))
|
| 1243 |
+
{
|
| 1244 |
+
# Apply free features from the command line. If user said
|
| 1245 |
+
# define=FOO
|
| 1246 |
+
# he most likely wants this define to be set for all compiles.
|
| 1247 |
+
property-set = [ $(property-set).refine
|
| 1248 |
+
[ build-system.command-line-free-features ] ] ;
|
| 1249 |
+
local rproperties = [ targets.common-properties $(property-set)
|
| 1250 |
+
$(self.requirements) ] ;
|
| 1251 |
+
|
| 1252 |
+
if [ modules.peek : .debug-building ]
|
| 1253 |
+
{
|
| 1254 |
+
ECHO ;
|
| 1255 |
+
ECHO [ targets.indent ] "Common properties: " [ $(rproperties).raw ] ;
|
| 1256 |
+
}
|
| 1257 |
+
|
| 1258 |
+
if ( $(rproperties[1]) != "@error" ) && ( [ $(rproperties).get
|
| 1259 |
+
<build> ] != no )
|
| 1260 |
+
{
|
| 1261 |
+
local source-targets ;
|
| 1262 |
+
local properties = [ $(rproperties).non-dependency ] ;
|
| 1263 |
+
local usage-requirements ;
|
| 1264 |
+
|
| 1265 |
+
generate-dependencies [ $(rproperties).dependency ] :
|
| 1266 |
+
$(rproperties) : properties usage-requirements ;
|
| 1267 |
+
|
| 1268 |
+
generate-dependencies $(self.sources) : $(rproperties) :
|
| 1269 |
+
source-targets usage-requirements ;
|
| 1270 |
+
|
| 1271 |
+
if [ modules.peek : .debug-building ]
|
| 1272 |
+
{
|
| 1273 |
+
ECHO ;
|
| 1274 |
+
ECHO [ targets.indent ] "Usage requirements for"
|
| 1275 |
+
$(self.name)": " $(usage-requirements) ;
|
| 1276 |
+
}
|
| 1277 |
+
|
| 1278 |
+
rproperties = [ property-set.create $(properties)
|
| 1279 |
+
$(usage-requirements) ] ;
|
| 1280 |
+
usage-requirements = [ property-set.create $(usage-requirements) ] ;
|
| 1281 |
+
|
| 1282 |
+
if [ modules.peek : .debug-building ]
|
| 1283 |
+
{
|
| 1284 |
+
ECHO [ targets.indent ] "Build properties: "
|
| 1285 |
+
[ $(rproperties).raw ] ;
|
| 1286 |
+
}
|
| 1287 |
+
|
| 1288 |
+
local extra = [ $(rproperties).get <source> ] ;
|
| 1289 |
+
source-targets += $(extra:G=) ;
|
| 1290 |
+
# We might get duplicate sources, for example if we link to two
|
| 1291 |
+
# libraries having the same <library> usage requirement.
|
| 1292 |
+
# Use stable sort, since for some targets the order is
|
| 1293 |
+
# important. E.g. RUN_PY target need python source to come
|
| 1294 |
+
# first.
|
| 1295 |
+
source-targets = [ sequence.unique $(source-targets) : stable ] ;
|
| 1296 |
+
|
| 1297 |
+
local result = [ construct $(self.name) : $(source-targets) :
|
| 1298 |
+
$(rproperties) ] ;
|
| 1299 |
+
|
| 1300 |
+
if $(result)
|
| 1301 |
+
{
|
| 1302 |
+
local gur = $(result[1]) ;
|
| 1303 |
+
result = $(result[2-]) ;
|
| 1304 |
+
|
| 1305 |
+
if $(self.always)
|
| 1306 |
+
{
|
| 1307 |
+
for local t in $(result)
|
| 1308 |
+
{
|
| 1309 |
+
$(t).always ;
|
| 1310 |
+
}
|
| 1311 |
+
}
|
| 1312 |
+
|
| 1313 |
+
local s = [ create-subvariant $(result)
|
| 1314 |
+
: [ virtual-target.recent-targets ]
|
| 1315 |
+
: $(property-set) : $(source-targets)
|
| 1316 |
+
: $(rproperties) : $(usage-requirements) ] ;
|
| 1317 |
+
virtual-target.clear-recent-targets ;
|
| 1318 |
+
|
| 1319 |
+
local ur = [ compute-usage-requirements $(s) ] ;
|
| 1320 |
+
ur = [ $(ur).add $(gur) ] ;
|
| 1321 |
+
$(s).set-usage-requirements $(ur) ;
|
| 1322 |
+
if [ modules.peek : .debug-building ]
|
| 1323 |
+
{
|
| 1324 |
+
ECHO [ targets.indent ] "Usage requirements from"
|
| 1325 |
+
$(self.name)": " [ $(ur).raw ] ;
|
| 1326 |
+
}
|
| 1327 |
+
|
| 1328 |
+
self.generated.$(property-set) = $(ur) $(result) ;
|
| 1329 |
+
}
|
| 1330 |
+
}
|
| 1331 |
+
else
|
| 1332 |
+
{
|
| 1333 |
+
if $(rproperties[1]) = "@error"
|
| 1334 |
+
{
|
| 1335 |
+
ECHO [ targets.indent ] "Skipping build of:" [ full-name ]
|
| 1336 |
+
"cannot compute common properties" ;
|
| 1337 |
+
}
|
| 1338 |
+
else if [ $(rproperties).get <build> ] = no
|
| 1339 |
+
{
|
| 1340 |
+
# If we just see <build>no, we cannot produce any reasonable
|
| 1341 |
+
# diagnostics. The code that adds this property is expected
|
| 1342 |
+
# to explain why a target is not built, for example using
|
| 1343 |
+
# the configure.log-component-configuration function.
|
| 1344 |
+
}
|
| 1345 |
+
else
|
| 1346 |
+
{
|
| 1347 |
+
ECHO [ targets.indent ] "Skipping build of: " [ full-name ]
|
| 1348 |
+
" unknown reason" ;
|
| 1349 |
+
}
|
| 1350 |
+
|
| 1351 |
+
# We are here either because there has been an error computing
|
| 1352 |
+
# properties or there is <build>no in properties. In the latter
|
| 1353 |
+
# case we do not want any diagnostic. In the former case, we
|
| 1354 |
+
# need diagnostics. FIXME
|
| 1355 |
+
|
| 1356 |
+
# If this target fails to build, add <build>no to properties to
|
| 1357 |
+
# cause any parent target to fail to build. Except that it
|
| 1358 |
+
# - does not work now, since we check for <build>no only in
|
| 1359 |
+
# common properties, but not in properties that came from
|
| 1360 |
+
# dependencies
|
| 1361 |
+
# - it is not clear if that is a good idea anyway. The alias
|
| 1362 |
+
# target, for example, should not fail to build if a
|
| 1363 |
+
# dependency fails.
|
| 1364 |
+
self.generated.$(property-set) = [ property-set.create <build>no ] ;
|
| 1365 |
+
}
|
| 1366 |
+
}
|
| 1367 |
+
else
|
| 1368 |
+
{
|
| 1369 |
+
if [ modules.peek : .debug-building ]
|
| 1370 |
+
{
|
| 1371 |
+
ECHO [ targets.indent ] "Already built" ;
|
| 1372 |
+
local ur = $(self.generated.$(property-set)) ;
|
| 1373 |
+
ur = $(ur[0]) ;
|
| 1374 |
+
targets.increase-indent ;
|
| 1375 |
+
ECHO [ targets.indent ] "Usage requirements from"
|
| 1376 |
+
$(self.name)": " [ $(ur).raw ] ;
|
| 1377 |
+
targets.decrease-indent ;
|
| 1378 |
+
}
|
| 1379 |
+
}
|
| 1380 |
+
|
| 1381 |
+
targets.pop-target ;
|
| 1382 |
+
targets.decrease-indent ;
|
| 1383 |
+
return $(self.generated.$(property-set)) ;
|
| 1384 |
+
}
|
| 1385 |
+
|
| 1386 |
+
# Given the set of generated targets, and refined build properties,
|
| 1387 |
+
# determines and sets appropriate usage requirements on those targets.
|
| 1388 |
+
#
|
| 1389 |
+
rule compute-usage-requirements ( subvariant )
|
| 1390 |
+
{
|
| 1391 |
+
local rproperties = [ $(subvariant).build-properties ] ;
|
| 1392 |
+
xusage-requirements = [ targets.evaluate-requirements
|
| 1393 |
+
$(self.usage-requirements) : $(rproperties) : added ] ;
|
| 1394 |
+
|
| 1395 |
+
# We generate all dependency properties and add them, as well as their
|
| 1396 |
+
# usage requirements, to the result.
|
| 1397 |
+
local extra ;
|
| 1398 |
+
generate-dependencies [ $(xusage-requirements).dependency ] :
|
| 1399 |
+
$(rproperties) : extra extra ;
|
| 1400 |
+
|
| 1401 |
+
local result = [ property-set.create
|
| 1402 |
+
[ $(xusage-requirements).non-dependency ] $(extra) ] ;
|
| 1403 |
+
|
| 1404 |
+
# Propagate usage requirements we got from sources, except for the
|
| 1405 |
+
# <pch-header> and <pch-file> features.
|
| 1406 |
+
#
|
| 1407 |
+
# That feature specifies which pch file to use, and should apply only to
|
| 1408 |
+
# direct dependents. Consider:
|
| 1409 |
+
#
|
| 1410 |
+
# pch pch1 : ...
|
| 1411 |
+
# lib lib1 : ..... pch1 ;
|
| 1412 |
+
# pch pch2 :
|
| 1413 |
+
# lib lib2 : pch2 lib1 ;
|
| 1414 |
+
#
|
| 1415 |
+
# Here, lib2 should not get <pch-header> property from pch1.
|
| 1416 |
+
#
|
| 1417 |
+
# Essentially, when those two features are in usage requirements, they
|
| 1418 |
+
# are propagated only to direct dependents. We might need a more general
|
| 1419 |
+
# mechanism, but for now, only those two features are special.
|
| 1420 |
+
#
|
| 1421 |
+
# TODO - Actually there are more possible candidates like for instance
|
| 1422 |
+
# when listing static library X as a source for another static library.
|
| 1423 |
+
# Then static library X will be added as a <source> property to the
|
| 1424 |
+
# second library's usage requirements but those requirements should last
|
| 1425 |
+
# only up to the first executable or shared library that actually links
|
| 1426 |
+
# to it.
|
| 1427 |
+
local raw = [ $(subvariant).sources-usage-requirements ] ;
|
| 1428 |
+
raw = [ $(raw).raw ] ;
|
| 1429 |
+
raw = [ property.change $(raw) : <pch-header> ] ;
|
| 1430 |
+
raw = [ property.change $(raw) : <pch-file> ] ;
|
| 1431 |
+
return [ $(result).add [ property-set.create $(raw) ] ] ;
|
| 1432 |
+
}
|
| 1433 |
+
|
| 1434 |
+
# Creates new subvariant instances for 'targets'.
|
| 1435 |
+
# 'root-targets' - virtual targets to be returned to dependants
|
| 1436 |
+
# 'all-targets' - virtual targets created while building this main target
|
| 1437 |
+
# 'build-request' - property-set instance with requested build properties
|
| 1438 |
+
#
|
| 1439 |
+
local rule create-subvariant ( root-targets * : all-targets * :
|
| 1440 |
+
build-request : sources * : rproperties : usage-requirements )
|
| 1441 |
+
{
|
| 1442 |
+
for local e in $(root-targets)
|
| 1443 |
+
{
|
| 1444 |
+
$(e).root true ;
|
| 1445 |
+
}
|
| 1446 |
+
|
| 1447 |
+
# Process all virtual targets that will be created if this main target
|
| 1448 |
+
# is created.
|
| 1449 |
+
local s = [ new subvariant $(__name__) : $(build-request) : $(sources) :
|
| 1450 |
+
$(rproperties) : $(usage-requirements) : $(all-targets) ] ;
|
| 1451 |
+
for local v in $(all-targets)
|
| 1452 |
+
{
|
| 1453 |
+
if ! [ $(v).creating-subvariant ]
|
| 1454 |
+
{
|
| 1455 |
+
$(v).creating-subvariant $(s) ;
|
| 1456 |
+
}
|
| 1457 |
+
}
|
| 1458 |
+
return $(s) ;
|
| 1459 |
+
}
|
| 1460 |
+
|
| 1461 |
+
# Constructs virtual targets for this abstract target and the dependency
|
| 1462 |
+
# graph. Returns a usage-requirements property-set and a list of virtual
|
| 1463 |
+
# targets. Should be overriden in derived classes.
|
| 1464 |
+
#
|
| 1465 |
+
rule construct ( name : source-targets * : properties * )
|
| 1466 |
+
{
|
| 1467 |
+
errors.error "method should be defined in derived classes" ;
|
| 1468 |
+
}
|
| 1469 |
+
}
|
| 1470 |
+
|
| 1471 |
+
|
| 1472 |
+
class typed-target : basic-target
|
| 1473 |
+
{
|
| 1474 |
+
import generators ;
|
| 1475 |
+
|
| 1476 |
+
rule __init__ ( name : project : type : sources * : requirements * :
|
| 1477 |
+
default-build * : usage-requirements * )
|
| 1478 |
+
{
|
| 1479 |
+
basic-target.__init__ $(name) : $(project) : $(sources) :
|
| 1480 |
+
$(requirements) : $(default-build) : $(usage-requirements) ;
|
| 1481 |
+
|
| 1482 |
+
self.type = $(type) ;
|
| 1483 |
+
}
|
| 1484 |
+
|
| 1485 |
+
rule type ( )
|
| 1486 |
+
{
|
| 1487 |
+
return $(self.type) ;
|
| 1488 |
+
}
|
| 1489 |
+
|
| 1490 |
+
rule construct ( name : source-targets * : property-set )
|
| 1491 |
+
{
|
| 1492 |
+
local r = [ generators.construct $(self.project) $(name:S=) : $(self.type)
|
| 1493 |
+
: [ property-set.create [ $(property-set).raw ]
|
| 1494 |
+
<main-target-type>$(self.type) ]
|
| 1495 |
+
: $(source-targets) : true ] ;
|
| 1496 |
+
if ! $(r)
|
| 1497 |
+
{
|
| 1498 |
+
ECHO "warn: Unable to construct" [ full-name ] ;
|
| 1499 |
+
|
| 1500 |
+
# Are there any top-level generators for this type/property set.
|
| 1501 |
+
if ! [ generators.find-viable-generators $(self.type)
|
| 1502 |
+
: $(property-set) ]
|
| 1503 |
+
{
|
| 1504 |
+
ECHO "error: no generators were found for type '$(self.type)'" ;
|
| 1505 |
+
ECHO "error: and the requested properties" ;
|
| 1506 |
+
ECHO "error: make sure you've configured the needed tools" ;
|
| 1507 |
+
ECHO "See http://boost.org/boost-build2/doc/html/bbv2/advanced/configuration.html" ;
|
| 1508 |
+
ECHO "To debug this problem, try the --debug-generators option." ;
|
| 1509 |
+
EXIT ;
|
| 1510 |
+
}
|
| 1511 |
+
}
|
| 1512 |
+
return $(r) ;
|
| 1513 |
+
}
|
| 1514 |
+
}
|
| 1515 |
+
|
| 1516 |
+
|
| 1517 |
+
# Return the list of sources to use, if main target rule is invoked with
|
| 1518 |
+
# 'sources'. If there are any objects in 'sources', they are treated as main
|
| 1519 |
+
# target instances, and the name of such targets are adjusted to be
|
| 1520 |
+
# '<name_of_this_target>__<name_of_source_target>'. Such renaming is disabled if
|
| 1521 |
+
# a non-empty value is passed as the 'no-renaming' parameter.
|
| 1522 |
+
#
|
| 1523 |
+
rule main-target-sources ( sources * : main-target-name : no-renaming ? )
|
| 1524 |
+
{
|
| 1525 |
+
local result ;
|
| 1526 |
+
for local t in $(sources)
|
| 1527 |
+
{
|
| 1528 |
+
if [ class.is-instance $(t) ]
|
| 1529 |
+
{
|
| 1530 |
+
local name = [ $(t).name ] ;
|
| 1531 |
+
if ! $(no-renaming)
|
| 1532 |
+
{
|
| 1533 |
+
name = $(main-target-name)__$(name) ;
|
| 1534 |
+
$(t).rename $(name) ;
|
| 1535 |
+
}
|
| 1536 |
+
# Inline targets are not built by default.
|
| 1537 |
+
local p = [ $(t).project ] ;
|
| 1538 |
+
$(p).mark-target-as-explicit $(name) ;
|
| 1539 |
+
result += $(name) ;
|
| 1540 |
+
}
|
| 1541 |
+
else
|
| 1542 |
+
{
|
| 1543 |
+
result += $(t) ;
|
| 1544 |
+
}
|
| 1545 |
+
}
|
| 1546 |
+
return $(result) ;
|
| 1547 |
+
}
|
| 1548 |
+
|
| 1549 |
+
|
| 1550 |
+
# Returns the requirements to use when declaring a main target, obtained by
|
| 1551 |
+
# translating all specified property paths and refining project requirements
|
| 1552 |
+
# with the ones specified for the target.
|
| 1553 |
+
#
|
| 1554 |
+
rule main-target-requirements (
|
| 1555 |
+
specification * # Properties explicitly specified for the main target.
|
| 1556 |
+
: project # Project where the main target is to be declared.
|
| 1557 |
+
)
|
| 1558 |
+
{
|
| 1559 |
+
specification += [ toolset.requirements ] ;
|
| 1560 |
+
|
| 1561 |
+
local requirements = [ property-set.refine-from-user-input
|
| 1562 |
+
[ $(project).get requirements ] : $(specification) :
|
| 1563 |
+
[ $(project).project-module ] : [ $(project).get location ] ] ;
|
| 1564 |
+
if $(requirements[1]) = "@error"
|
| 1565 |
+
{
|
| 1566 |
+
errors.error "Conflicting requirements for target:" $(requirements) ;
|
| 1567 |
+
}
|
| 1568 |
+
return $(requirements) ;
|
| 1569 |
+
}
|
| 1570 |
+
|
| 1571 |
+
|
| 1572 |
+
# Returns the usage requirements to use when declaring a main target, which are
|
| 1573 |
+
# obtained by translating all specified property paths and adding project's
|
| 1574 |
+
# usage requirements.
|
| 1575 |
+
#
|
| 1576 |
+
rule main-target-usage-requirements (
|
| 1577 |
+
specification * # Use-properties explicitly specified for a main target.
|
| 1578 |
+
: project # Project where the main target is to be declared.
|
| 1579 |
+
)
|
| 1580 |
+
{
|
| 1581 |
+
local project-usage-requirements = [ $(project).get usage-requirements ] ;
|
| 1582 |
+
|
| 1583 |
+
# We do not use 'refine-from-user-input' because:
|
| 1584 |
+
# - I am not sure if removing parent's usage requirements makes sense
|
| 1585 |
+
# - refining usage requirements is not needed, since usage requirements are
|
| 1586 |
+
# always free.
|
| 1587 |
+
local usage-requirements = [ property-set.create-from-user-input
|
| 1588 |
+
$(specification)
|
| 1589 |
+
: [ $(project).project-module ] [ $(project).get location ] ] ;
|
| 1590 |
+
|
| 1591 |
+
return [ $(project-usage-requirements).add $(usage-requirements) ] ;
|
| 1592 |
+
}
|
| 1593 |
+
|
| 1594 |
+
|
| 1595 |
+
# Return the default build value to use when declaring a main target, which is
|
| 1596 |
+
# obtained by using the specified value if not empty and parent's default build
|
| 1597 |
+
# attribute otherwise.
|
| 1598 |
+
#
|
| 1599 |
+
rule main-target-default-build (
|
| 1600 |
+
specification * # Default build explicitly specified for a main target.
|
| 1601 |
+
: project # Project where the main target is to be declared.
|
| 1602 |
+
)
|
| 1603 |
+
{
|
| 1604 |
+
local result ;
|
| 1605 |
+
if $(specification)
|
| 1606 |
+
{
|
| 1607 |
+
result = $(specification) ;
|
| 1608 |
+
}
|
| 1609 |
+
else
|
| 1610 |
+
{
|
| 1611 |
+
result = [ $(project).get default-build ] ;
|
| 1612 |
+
}
|
| 1613 |
+
return [ property-set.create-with-validation $(result) ] ;
|
| 1614 |
+
}
|
| 1615 |
+
|
| 1616 |
+
|
| 1617 |
+
# Registers the specified target as a main target alternative and returns it.
|
| 1618 |
+
#
|
| 1619 |
+
rule main-target-alternative ( target )
|
| 1620 |
+
{
|
| 1621 |
+
local ptarget = [ $(target).project ] ;
|
| 1622 |
+
$(ptarget).add-alternative $(target) ;
|
| 1623 |
+
return $(target) ;
|
| 1624 |
+
}
|
| 1625 |
+
|
| 1626 |
+
# Creates a new metargets with the specified properties, using 'klass' as
|
| 1627 |
+
# the class. The 'name', 'sources',
|
| 1628 |
+
# 'requirements', 'default-build' and 'usage-requirements' are assumed to be in
|
| 1629 |
+
# the form specified by the user in Jamfile corresponding to 'project'.
|
| 1630 |
+
#
|
| 1631 |
+
rule create-metatarget ( klass : project : name : sources * : requirements * :
|
| 1632 |
+
default-build * : usage-requirements * )
|
| 1633 |
+
{
|
| 1634 |
+
return [
|
| 1635 |
+
targets.main-target-alternative
|
| 1636 |
+
[ new $(klass) $(name) : $(project)
|
| 1637 |
+
: [ targets.main-target-sources $(sources) : $(name) ]
|
| 1638 |
+
: [ targets.main-target-requirements $(requirements) : $(project) ]
|
| 1639 |
+
: [ targets.main-target-default-build $(default-build) : $(project) ]
|
| 1640 |
+
: [ targets.main-target-usage-requirements $(usage-requirements) : $(project) ]
|
| 1641 |
+
] ] ;
|
| 1642 |
+
}
|
| 1643 |
+
|
| 1644 |
+
# Creates a typed-target with the specified properties. The 'name', 'sources',
|
| 1645 |
+
# 'requirements', 'default-build' and 'usage-requirements' are assumed to be in
|
| 1646 |
+
# the form specified by the user in Jamfile corresponding to 'project'.
|
| 1647 |
+
#
|
| 1648 |
+
rule create-typed-target ( type : project : name : sources * : requirements * :
|
| 1649 |
+
default-build * : usage-requirements * )
|
| 1650 |
+
{
|
| 1651 |
+
return [
|
| 1652 |
+
targets.main-target-alternative
|
| 1653 |
+
[ new typed-target $(name) : $(project) : $(type)
|
| 1654 |
+
: [ targets.main-target-sources $(sources) : $(name) ]
|
| 1655 |
+
: [ targets.main-target-requirements $(requirements) : $(project) ]
|
| 1656 |
+
: [ targets.main-target-default-build $(default-build) : $(project) ]
|
| 1657 |
+
: [ targets.main-target-usage-requirements $(usage-requirements) : $(project) ]
|
| 1658 |
+
] ] ;
|
| 1659 |
+
}
|
mosesdecoder/jam-files/boost-build/build/version.jam
ADDED
|
@@ -0,0 +1,161 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright 2002, 2003, 2004, 2006 Vladimir Prus
|
| 2 |
+
# Copyright 2008 Jurko Gospodnetic
|
| 3 |
+
# Distributed under the Boost Software License, Version 1.0.
|
| 4 |
+
# (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
|
| 5 |
+
|
| 6 |
+
import errors ;
|
| 7 |
+
import numbers ;
|
| 8 |
+
|
| 9 |
+
major = "2011" ;
|
| 10 |
+
minor = "12" ;
|
| 11 |
+
|
| 12 |
+
rule boost-build ( )
|
| 13 |
+
{
|
| 14 |
+
return "$(major).$(minor)-svn" ;
|
| 15 |
+
}
|
| 16 |
+
|
| 17 |
+
rule print ( )
|
| 18 |
+
{
|
| 19 |
+
if [ verify-engine-version ]
|
| 20 |
+
{
|
| 21 |
+
ECHO "Boost.Build" [ boost-build ] ;
|
| 22 |
+
}
|
| 23 |
+
}
|
| 24 |
+
|
| 25 |
+
rule verify-engine-version ( )
|
| 26 |
+
{
|
| 27 |
+
local v = [ modules.peek : JAM_VERSION ] ;
|
| 28 |
+
|
| 29 |
+
if $(v[1]) != $(major) || $(v[2]) != $(minor)
|
| 30 |
+
{
|
| 31 |
+
local argv = [ modules.peek : ARGV ] ;
|
| 32 |
+
local e = $(argv[1]) ;
|
| 33 |
+
local l = [ modules.binding version ] ;
|
| 34 |
+
l = $(l:D) ;
|
| 35 |
+
l = $(l:D) ;
|
| 36 |
+
ECHO "warning: mismatched versions of Boost.Build engine and core" ;
|
| 37 |
+
ECHO "warning: Boost.Build engine ($(e)) is $(v:J=.)" ;
|
| 38 |
+
ECHO "warning: Boost.Build core (at $(l)) is" [ boost-build ] ;
|
| 39 |
+
}
|
| 40 |
+
else
|
| 41 |
+
{
|
| 42 |
+
return true ;
|
| 43 |
+
}
|
| 44 |
+
}
|
| 45 |
+
|
| 46 |
+
|
| 47 |
+
|
| 48 |
+
# Utility rule for testing whether all elements in a sequence are equal to 0.
|
| 49 |
+
#
|
| 50 |
+
local rule is-all-zeroes ( sequence * )
|
| 51 |
+
{
|
| 52 |
+
local result = "true" ;
|
| 53 |
+
for local e in $(sequence)
|
| 54 |
+
{
|
| 55 |
+
if $(e) != "0"
|
| 56 |
+
{
|
| 57 |
+
result = "" ;
|
| 58 |
+
}
|
| 59 |
+
}
|
| 60 |
+
return $(result) ;
|
| 61 |
+
}
|
| 62 |
+
|
| 63 |
+
|
| 64 |
+
# Returns "true" if the first version is less than the second one.
|
| 65 |
+
#
|
| 66 |
+
rule version-less ( lhs + : rhs + )
|
| 67 |
+
{
|
| 68 |
+
numbers.check $(lhs) ;
|
| 69 |
+
numbers.check $(rhs) ;
|
| 70 |
+
|
| 71 |
+
local done ;
|
| 72 |
+
local result ;
|
| 73 |
+
|
| 74 |
+
while ! $(done) && $(lhs) && $(rhs)
|
| 75 |
+
{
|
| 76 |
+
if [ numbers.less $(lhs[1]) $(rhs[1]) ]
|
| 77 |
+
{
|
| 78 |
+
done = "true" ;
|
| 79 |
+
result = "true" ;
|
| 80 |
+
}
|
| 81 |
+
else if [ numbers.less $(rhs[1]) $(lhs[1]) ]
|
| 82 |
+
{
|
| 83 |
+
done = "true" ;
|
| 84 |
+
}
|
| 85 |
+
else
|
| 86 |
+
{
|
| 87 |
+
lhs = $(lhs[2-]) ;
|
| 88 |
+
rhs = $(rhs[2-]) ;
|
| 89 |
+
}
|
| 90 |
+
}
|
| 91 |
+
if ( ! $(done) && ! $(lhs) && ! [ is-all-zeroes $(rhs) ] )
|
| 92 |
+
{
|
| 93 |
+
result = "true" ;
|
| 94 |
+
}
|
| 95 |
+
|
| 96 |
+
return $(result) ;
|
| 97 |
+
}
|
| 98 |
+
|
| 99 |
+
|
| 100 |
+
# Returns "true" if the current JAM version version is at least the given
|
| 101 |
+
# version.
|
| 102 |
+
#
|
| 103 |
+
rule check-jam-version ( version + )
|
| 104 |
+
{
|
| 105 |
+
local version-tag = $(version:J=.) ;
|
| 106 |
+
if ! $(version-tag)
|
| 107 |
+
{
|
| 108 |
+
errors.error Invalid version specifier: : $(version:E="(undefined)") ;
|
| 109 |
+
}
|
| 110 |
+
|
| 111 |
+
if ! $(.jam-version-check.$(version-tag))-is-not-empty
|
| 112 |
+
{
|
| 113 |
+
local jam-version = [ modules.peek : JAM_VERSION ] ;
|
| 114 |
+
if ! $(jam-version)
|
| 115 |
+
{
|
| 116 |
+
errors.error "Unable to deduce Boost Jam version. Your Boost Jam"
|
| 117 |
+
"installation is most likely terribly outdated." ;
|
| 118 |
+
}
|
| 119 |
+
.jam-version-check.$(version-tag) = "true" ;
|
| 120 |
+
if [ version-less [ modules.peek : JAM_VERSION ] : $(version) ]
|
| 121 |
+
{
|
| 122 |
+
.jam-version-check.$(version-tag) = "" ;
|
| 123 |
+
}
|
| 124 |
+
}
|
| 125 |
+
return $(.jam-version-check.$(version-tag)) ;
|
| 126 |
+
}
|
| 127 |
+
|
| 128 |
+
|
| 129 |
+
rule __test__ ( )
|
| 130 |
+
{
|
| 131 |
+
import assert ;
|
| 132 |
+
|
| 133 |
+
local jam-version = [ modules.peek : JAM_VERSION ] ;
|
| 134 |
+
local future-version = $(jam-version) ;
|
| 135 |
+
future-version += "1" ;
|
| 136 |
+
|
| 137 |
+
assert.true check-jam-version $(jam-version) ;
|
| 138 |
+
assert.false check-jam-version $(future-version) ;
|
| 139 |
+
|
| 140 |
+
assert.true version-less 0 : 1 ;
|
| 141 |
+
assert.false version-less 0 : 0 ;
|
| 142 |
+
assert.true version-less 1 : 2 ;
|
| 143 |
+
assert.false version-less 1 : 1 ;
|
| 144 |
+
assert.false version-less 2 : 1 ;
|
| 145 |
+
assert.true version-less 3 1 20 : 3 4 10 ;
|
| 146 |
+
assert.false version-less 3 1 10 : 3 1 10 ;
|
| 147 |
+
assert.false version-less 3 4 10 : 3 1 20 ;
|
| 148 |
+
assert.true version-less 3 1 20 5 1 : 3 4 10 ;
|
| 149 |
+
assert.false version-less 3 1 10 5 1 : 3 1 10 ;
|
| 150 |
+
assert.false version-less 3 4 10 5 1 : 3 1 20 ;
|
| 151 |
+
assert.true version-less 3 1 20 : 3 4 10 5 1 ;
|
| 152 |
+
assert.true version-less 3 1 10 : 3 1 10 5 1 ;
|
| 153 |
+
assert.false version-less 3 4 10 : 3 1 20 5 1 ;
|
| 154 |
+
assert.false version-less 3 1 10 : 3 1 10 0 0 ;
|
| 155 |
+
assert.false version-less 3 1 10 0 0 : 3 1 10 ;
|
| 156 |
+
assert.false version-less 3 1 10 0 : 3 1 10 0 0 ;
|
| 157 |
+
assert.false version-less 3 1 10 0 : 03 1 10 0 0 ;
|
| 158 |
+
assert.false version-less 03 1 10 0 : 3 1 10 0 0 ;
|
| 159 |
+
|
| 160 |
+
# TODO: Add tests for invalid input data being sent to version-less.
|
| 161 |
+
}
|
mosesdecoder/jam-files/boost-build/build/virtual-target.jam
ADDED
|
@@ -0,0 +1,1317 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright 2003 Dave Abrahams
|
| 2 |
+
# Copyright 2005, 2006 Rene Rivera
|
| 3 |
+
# Copyright 2002, 2003, 2004, 2005, 2006 Vladimir Prus
|
| 4 |
+
# Distributed under the Boost Software License, Version 1.0.
|
| 5 |
+
# (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
|
| 6 |
+
|
| 7 |
+
# Implements virtual targets, which correspond to actual files created during a
|
| 8 |
+
# build, but are not yet targets in Jam sense. They are needed, for example,
|
| 9 |
+
# when searching for possible transformation sequences, when it is not yet known
|
| 10 |
+
# whether a particular target should be created at all.
|
| 11 |
+
|
| 12 |
+
import "class" : new ;
|
| 13 |
+
import errors ;
|
| 14 |
+
import path ;
|
| 15 |
+
import sequence ;
|
| 16 |
+
import set ;
|
| 17 |
+
import type ;
|
| 18 |
+
import utility ;
|
| 19 |
+
|
| 20 |
+
|
| 21 |
+
# +--------------------------+
|
| 22 |
+
# | virtual-target |
|
| 23 |
+
# +==========================+
|
| 24 |
+
# | actualize |
|
| 25 |
+
# +--------------------------+
|
| 26 |
+
# | actualize-action() = 0 |
|
| 27 |
+
# | actualize-location() = 0 |
|
| 28 |
+
# +----------------+---------+
|
| 29 |
+
# |
|
| 30 |
+
# ^
|
| 31 |
+
# / \
|
| 32 |
+
# +-+-+
|
| 33 |
+
# |
|
| 34 |
+
# +---------------------+ +-------+--------------+
|
| 35 |
+
# | action | | abstract-file-target |
|
| 36 |
+
# +=====================| * +======================+
|
| 37 |
+
# | action-name | +--+ action |
|
| 38 |
+
# | properties | | +----------------------+
|
| 39 |
+
# +---------------------+--+ | actualize-action() |
|
| 40 |
+
# | actualize() |0..1 +-----------+----------+
|
| 41 |
+
# | path() | |
|
| 42 |
+
# | adjust-properties() | sources |
|
| 43 |
+
# | actualize-sources() | targets |
|
| 44 |
+
# +------+--------------+ ^
|
| 45 |
+
# | / \
|
| 46 |
+
# ^ +-+-+
|
| 47 |
+
# / \ |
|
| 48 |
+
# +-+-+ +-------------+-------------+
|
| 49 |
+
# | | |
|
| 50 |
+
# | +------+---------------+ +--------+-------------+
|
| 51 |
+
# | | file-target | | searched-lib-target |
|
| 52 |
+
# | +======================+ +======================+
|
| 53 |
+
# | | actualize-location() | | actualize-location() |
|
| 54 |
+
# | +----------------------+ +----------------------+
|
| 55 |
+
# |
|
| 56 |
+
# +-+------------------------------+
|
| 57 |
+
# | |
|
| 58 |
+
# +----+----------------+ +---------+-----------+
|
| 59 |
+
# | compile-action | | link-action |
|
| 60 |
+
# +=====================+ +=====================+
|
| 61 |
+
# | adjust-properties() | | adjust-properties() |
|
| 62 |
+
# +---------------------+ | actualize-sources() |
|
| 63 |
+
# +---------------------+
|
| 64 |
+
#
|
| 65 |
+
# The 'compile-action' and 'link-action' classes are not defined here but in
|
| 66 |
+
# builtin.jam modules. They are shown in the diagram to give the big picture.
|
| 67 |
+
|
| 68 |
+
|
| 69 |
+
# Models a potential target. It can be converted into a Jam target and used in
|
| 70 |
+
# building, if needed. However, it can be also dropped, which allows us to
|
| 71 |
+
# search for different transformations and select only one.
|
| 72 |
+
#
|
| 73 |
+
class virtual-target
|
| 74 |
+
{
|
| 75 |
+
import scanner ;
|
| 76 |
+
import sequence ;
|
| 77 |
+
import utility ;
|
| 78 |
+
import virtual-target ;
|
| 79 |
+
|
| 80 |
+
rule __init__ (
|
| 81 |
+
name # Target/project name.
|
| 82 |
+
: project # Project to which this target belongs.
|
| 83 |
+
)
|
| 84 |
+
{
|
| 85 |
+
self.name = $(name) ;
|
| 86 |
+
self.project = $(project) ;
|
| 87 |
+
self.dependencies = ;
|
| 88 |
+
}
|
| 89 |
+
|
| 90 |
+
# Name of this target.
|
| 91 |
+
#
|
| 92 |
+
rule name ( )
|
| 93 |
+
{
|
| 94 |
+
return $(self.name) ;
|
| 95 |
+
}
|
| 96 |
+
|
| 97 |
+
# Project of this target.
|
| 98 |
+
#
|
| 99 |
+
rule project ( )
|
| 100 |
+
{
|
| 101 |
+
return $(self.project) ;
|
| 102 |
+
}
|
| 103 |
+
|
| 104 |
+
# Adds additional 'virtual-target' instances this one depends on.
|
| 105 |
+
#
|
| 106 |
+
rule depends ( d + )
|
| 107 |
+
{
|
| 108 |
+
self.dependencies = [ sequence.merge $(self.dependencies) :
|
| 109 |
+
[ sequence.insertion-sort $(d) ] ] ;
|
| 110 |
+
}
|
| 111 |
+
|
| 112 |
+
rule dependencies ( )
|
| 113 |
+
{
|
| 114 |
+
return $(self.dependencies) ;
|
| 115 |
+
}
|
| 116 |
+
|
| 117 |
+
rule always ( )
|
| 118 |
+
{
|
| 119 |
+
.always = 1 ;
|
| 120 |
+
}
|
| 121 |
+
|
| 122 |
+
# Generates all the actual targets and sets up build actions for this
|
| 123 |
+
# target.
|
| 124 |
+
#
|
| 125 |
+
# If 'scanner' is specified, creates an additional target with the same
|
| 126 |
+
# location as the actual target, which will depend on the actual target and
|
| 127 |
+
# be associated with a 'scanner'. That additional target is returned. See
|
| 128 |
+
# the docs (#dependency_scanning) for rationale. Target must correspond to a
|
| 129 |
+
# file if 'scanner' is specified.
|
| 130 |
+
#
|
| 131 |
+
# If scanner is not specified then the actual target is returned.
|
| 132 |
+
#
|
| 133 |
+
rule actualize ( scanner ? )
|
| 134 |
+
{
|
| 135 |
+
local actual-name = [ actualize-no-scanner ] ;
|
| 136 |
+
|
| 137 |
+
if $(.always)
|
| 138 |
+
{
|
| 139 |
+
ALWAYS $(actual-name) ;
|
| 140 |
+
}
|
| 141 |
+
|
| 142 |
+
if ! $(scanner)
|
| 143 |
+
{
|
| 144 |
+
return $(actual-name) ;
|
| 145 |
+
}
|
| 146 |
+
else
|
| 147 |
+
{
|
| 148 |
+
# Add the scanner instance to the grist for name.
|
| 149 |
+
local g = [ sequence.join
|
| 150 |
+
[ utility.ungrist $(actual-name:G) ] $(scanner) : - ] ;
|
| 151 |
+
local name = $(actual-name:G=$(g)) ;
|
| 152 |
+
|
| 153 |
+
if ! $(self.made.$(name))
|
| 154 |
+
{
|
| 155 |
+
self.made.$(name) = true ;
|
| 156 |
+
|
| 157 |
+
DEPENDS $(name) : $(actual-name) ;
|
| 158 |
+
|
| 159 |
+
actualize-location $(name) ;
|
| 160 |
+
|
| 161 |
+
scanner.install $(scanner) : $(name) $(__name__) ;
|
| 162 |
+
}
|
| 163 |
+
return $(name) ;
|
| 164 |
+
}
|
| 165 |
+
}
|
| 166 |
+
|
| 167 |
+
# private: (overridables)
|
| 168 |
+
|
| 169 |
+
# Sets up build actions for 'target'. Should call appropriate rules and set
|
| 170 |
+
# target variables.
|
| 171 |
+
#
|
| 172 |
+
rule actualize-action ( target )
|
| 173 |
+
{
|
| 174 |
+
errors.error "method should be defined in derived classes" ;
|
| 175 |
+
}
|
| 176 |
+
|
| 177 |
+
# Sets up variables on 'target' which specify its location.
|
| 178 |
+
#
|
| 179 |
+
rule actualize-location ( target )
|
| 180 |
+
{
|
| 181 |
+
errors.error "method should be defined in derived classes" ;
|
| 182 |
+
}
|
| 183 |
+
|
| 184 |
+
# If the target is a generated one, returns the path where it will be
|
| 185 |
+
# generated. Otherwise, returns an empty list.
|
| 186 |
+
#
|
| 187 |
+
rule path ( )
|
| 188 |
+
{
|
| 189 |
+
errors.error "method should be defined in derived classes" ;
|
| 190 |
+
}
|
| 191 |
+
|
| 192 |
+
# Returns the actual target name to be used in case when no scanner is
|
| 193 |
+
# involved.
|
| 194 |
+
#
|
| 195 |
+
rule actual-name ( )
|
| 196 |
+
{
|
| 197 |
+
errors.error "method should be defined in derived classes" ;
|
| 198 |
+
}
|
| 199 |
+
|
| 200 |
+
# implementation
|
| 201 |
+
rule actualize-no-scanner ( )
|
| 202 |
+
{
|
| 203 |
+
# In fact, we just need to merge virtual-target with
|
| 204 |
+
# abstract-file-target as the latter is the only class derived from the
|
| 205 |
+
# former. But that has been left for later.
|
| 206 |
+
|
| 207 |
+
errors.error "method should be defined in derived classes" ;
|
| 208 |
+
}
|
| 209 |
+
}
|
| 210 |
+
|
| 211 |
+
|
| 212 |
+
# Target corresponding to a file. The exact mapping for file is not yet
|
| 213 |
+
# specified in this class. (TODO: Actually, the class name could be better...)
|
| 214 |
+
#
|
| 215 |
+
# May be a source file (when no action is specified) or a derived file
|
| 216 |
+
# (otherwise).
|
| 217 |
+
#
|
| 218 |
+
# The target's grist is a concatenation of its project's location, action
|
| 219 |
+
# properties (for derived targets) and, optionally, value identifying the main
|
| 220 |
+
# target.
|
| 221 |
+
#
|
| 222 |
+
class abstract-file-target : virtual-target
|
| 223 |
+
{
|
| 224 |
+
import project ;
|
| 225 |
+
import regex ;
|
| 226 |
+
import sequence ;
|
| 227 |
+
import path ;
|
| 228 |
+
import type ;
|
| 229 |
+
import property-set ;
|
| 230 |
+
import indirect ;
|
| 231 |
+
|
| 232 |
+
rule __init__ (
|
| 233 |
+
name # Target's name.
|
| 234 |
+
exact ? # If non-empty, the name is exactly the name created file
|
| 235 |
+
# should have. Otherwise, the '__init__' method will add a
|
| 236 |
+
# suffix obtained from 'type' by calling
|
| 237 |
+
# 'type.generated-target-suffix'.
|
| 238 |
+
: type ? # Target's type.
|
| 239 |
+
: project
|
| 240 |
+
: action ?
|
| 241 |
+
)
|
| 242 |
+
{
|
| 243 |
+
virtual-target.__init__ $(name) : $(project) ;
|
| 244 |
+
|
| 245 |
+
self.type = $(type) ;
|
| 246 |
+
self.action = $(action) ;
|
| 247 |
+
if $(action)
|
| 248 |
+
{
|
| 249 |
+
$(action).add-targets $(__name__) ;
|
| 250 |
+
|
| 251 |
+
if $(self.type) && ! $(exact)
|
| 252 |
+
{
|
| 253 |
+
_adjust-name $(name) ;
|
| 254 |
+
}
|
| 255 |
+
}
|
| 256 |
+
}
|
| 257 |
+
|
| 258 |
+
rule type ( )
|
| 259 |
+
{
|
| 260 |
+
return $(self.type) ;
|
| 261 |
+
}
|
| 262 |
+
|
| 263 |
+
# Sets the path. When generating target name, it will override any path
|
| 264 |
+
# computation from properties.
|
| 265 |
+
#
|
| 266 |
+
rule set-path ( path )
|
| 267 |
+
{
|
| 268 |
+
self.path = [ path.native $(path) ] ;
|
| 269 |
+
}
|
| 270 |
+
|
| 271 |
+
# Returns the currently set action.
|
| 272 |
+
#
|
| 273 |
+
rule action ( )
|
| 274 |
+
{
|
| 275 |
+
return $(self.action) ;
|
| 276 |
+
}
|
| 277 |
+
|
| 278 |
+
# Sets/gets the 'root' flag. Target is root if it directly corresponds to
|
| 279 |
+
# some variant of a main target.
|
| 280 |
+
#
|
| 281 |
+
rule root ( set ? )
|
| 282 |
+
{
|
| 283 |
+
if $(set)
|
| 284 |
+
{
|
| 285 |
+
self.root = true ;
|
| 286 |
+
}
|
| 287 |
+
return $(self.root) ;
|
| 288 |
+
}
|
| 289 |
+
|
| 290 |
+
# Gets or sets the subvariant which created this target. Subvariant is set
|
| 291 |
+
# when target is brought into existance and is never changed after that. In
|
| 292 |
+
# particular, if a target is shared by a subvariant, only the first is
|
| 293 |
+
# stored.
|
| 294 |
+
#
|
| 295 |
+
rule creating-subvariant ( s ? # If specified, specifies the value to set,
|
| 296 |
+
# which should be a 'subvariant' class
|
| 297 |
+
# instance.
|
| 298 |
+
)
|
| 299 |
+
{
|
| 300 |
+
if $(s) && ! $(self.creating-subvariant)
|
| 301 |
+
{
|
| 302 |
+
self.creating-subvariant = $(s) ;
|
| 303 |
+
}
|
| 304 |
+
return $(self.creating-subvariant) ;
|
| 305 |
+
}
|
| 306 |
+
|
| 307 |
+
rule actualize-action ( target )
|
| 308 |
+
{
|
| 309 |
+
if $(self.action)
|
| 310 |
+
{
|
| 311 |
+
$(self.action).actualize ;
|
| 312 |
+
}
|
| 313 |
+
}
|
| 314 |
+
|
| 315 |
+
# Return a human-readable representation of this target. If this target has
|
| 316 |
+
# an action, that is:
|
| 317 |
+
#
|
| 318 |
+
# { <action-name>-<self.name>.<self.type> <action-sources>... }
|
| 319 |
+
#
|
| 320 |
+
# otherwise, it is:
|
| 321 |
+
#
|
| 322 |
+
# { <self.name>.<self.type> }
|
| 323 |
+
#
|
| 324 |
+
rule str ( )
|
| 325 |
+
{
|
| 326 |
+
local action = [ action ] ;
|
| 327 |
+
local name-dot-type = [ sequence.join $(self.name) "." $(self.type) ] ;
|
| 328 |
+
|
| 329 |
+
if $(action)
|
| 330 |
+
{
|
| 331 |
+
local sources = [ $(action).sources ] ;
|
| 332 |
+
local action-name = [ $(action).action-name ] ;
|
| 333 |
+
|
| 334 |
+
local ss ;
|
| 335 |
+
for local s in $(sources)
|
| 336 |
+
{
|
| 337 |
+
ss += [ $(s).str ] ;
|
| 338 |
+
}
|
| 339 |
+
|
| 340 |
+
return "{" $(action-name)-$(name-dot-type) $(ss) "}" ;
|
| 341 |
+
}
|
| 342 |
+
else
|
| 343 |
+
{
|
| 344 |
+
return "{" $(name-dot-type) "}" ;
|
| 345 |
+
}
|
| 346 |
+
}
|
| 347 |
+
|
| 348 |
+
rule less ( a )
|
| 349 |
+
{
|
| 350 |
+
if [ str ] < [ $(a).str ]
|
| 351 |
+
{
|
| 352 |
+
return true ;
|
| 353 |
+
}
|
| 354 |
+
}
|
| 355 |
+
|
| 356 |
+
rule equal ( a )
|
| 357 |
+
{
|
| 358 |
+
if [ str ] = [ $(a).str ]
|
| 359 |
+
{
|
| 360 |
+
return true ;
|
| 361 |
+
}
|
| 362 |
+
}
|
| 363 |
+
|
| 364 |
+
# private:
|
| 365 |
+
rule actual-name ( )
|
| 366 |
+
{
|
| 367 |
+
if ! $(self.actual-name)
|
| 368 |
+
{
|
| 369 |
+
local grist = [ grist ] ;
|
| 370 |
+
local basename = [ path.native $(self.name) ] ;
|
| 371 |
+
self.actual-name = <$(grist)>$(basename) ;
|
| 372 |
+
}
|
| 373 |
+
return $(self.actual-name) ;
|
| 374 |
+
}
|
| 375 |
+
|
| 376 |
+
# Helper to 'actual-name', above. Computes a unique prefix used to
|
| 377 |
+
# distinguish this target from other targets with the same name creating
|
| 378 |
+
# different files.
|
| 379 |
+
#
|
| 380 |
+
rule grist ( )
|
| 381 |
+
{
|
| 382 |
+
# Depending on target, there may be different approaches to generating
|
| 383 |
+
# unique prefixes. We generate prefixes in the form:
|
| 384 |
+
# <one letter approach code> <the actual prefix>
|
| 385 |
+
local path = [ path ] ;
|
| 386 |
+
if $(path)
|
| 387 |
+
{
|
| 388 |
+
# The target will be generated to a known path. Just use the path
|
| 389 |
+
# for identification, since path is as unique as it can get.
|
| 390 |
+
return p$(path) ;
|
| 391 |
+
}
|
| 392 |
+
else
|
| 393 |
+
{
|
| 394 |
+
# File is either source, which will be searched for, or is not a
|
| 395 |
+
# file at all. Use the location of project for distinguishing.
|
| 396 |
+
local project-location = [ $(self.project).get location ] ;
|
| 397 |
+
local location-grist = [ sequence.join [ regex.split
|
| 398 |
+
$(project-location) "/" ] : "!" ] ;
|
| 399 |
+
|
| 400 |
+
if $(self.action)
|
| 401 |
+
{
|
| 402 |
+
local ps = [ $(self.action).properties ] ;
|
| 403 |
+
local property-grist = [ $(ps).as-path ] ;
|
| 404 |
+
# 'property-grist' can be empty when 'ps' is an empty property
|
| 405 |
+
# set.
|
| 406 |
+
if $(property-grist)
|
| 407 |
+
{
|
| 408 |
+
location-grist = $(location-grist)/$(property-grist) ;
|
| 409 |
+
}
|
| 410 |
+
}
|
| 411 |
+
|
| 412 |
+
return l$(location-grist) ;
|
| 413 |
+
}
|
| 414 |
+
}
|
| 415 |
+
|
| 416 |
+
# Given the target name specified in constructor, returns the name which
|
| 417 |
+
# should be really used, by looking at the <tag> properties. Tag properties
|
| 418 |
+
# need to be specified as <tag>@rule-name. This makes Boost Build call the
|
| 419 |
+
# specified rule with the target name, type and properties to get the new
|
| 420 |
+
# name. If no <tag> property is specified or the rule specified by <tag>
|
| 421 |
+
# returns nothing, returns the result of calling
|
| 422 |
+
# virtual-target.add-prefix-and-suffix.
|
| 423 |
+
#
|
| 424 |
+
rule _adjust-name ( specified-name )
|
| 425 |
+
{
|
| 426 |
+
local ps ;
|
| 427 |
+
if $(self.action)
|
| 428 |
+
{
|
| 429 |
+
ps = [ $(self.action).properties ] ;
|
| 430 |
+
}
|
| 431 |
+
else
|
| 432 |
+
{
|
| 433 |
+
ps = [ property-set.empty ] ;
|
| 434 |
+
}
|
| 435 |
+
|
| 436 |
+
# We add ourselves to the properties so that any tag rule can get more
|
| 437 |
+
# direct information about the target than just that available through
|
| 438 |
+
# the properties. This is useful in implementing name changes based on
|
| 439 |
+
# the sources of the target. For example to make unique names of object
|
| 440 |
+
# files based on the source file. --grafik
|
| 441 |
+
ps = [ property-set.create [ $(ps).raw ] <target>$(__name__) ] ;
|
| 442 |
+
|
| 443 |
+
local tag = [ $(ps).get <tag> ] ;
|
| 444 |
+
|
| 445 |
+
if $(tag)
|
| 446 |
+
{
|
| 447 |
+
local rule-name = [ MATCH ^@(.*) : $(tag) ] ;
|
| 448 |
+
if $(rule-name)
|
| 449 |
+
{
|
| 450 |
+
if $(tag[2])
|
| 451 |
+
{
|
| 452 |
+
errors.error "<tag>@rulename is present but is not the only"
|
| 453 |
+
"<tag> feature" ;
|
| 454 |
+
}
|
| 455 |
+
|
| 456 |
+
self.name = [ indirect.call $(rule-name) $(specified-name)
|
| 457 |
+
: $(self.type) : $(ps) ] ;
|
| 458 |
+
}
|
| 459 |
+
else
|
| 460 |
+
{
|
| 461 |
+
errors.error
|
| 462 |
+
"The value of the <tag> feature must be '@rule-name'" ;
|
| 463 |
+
}
|
| 464 |
+
}
|
| 465 |
+
|
| 466 |
+
# If there is no tag or the tag rule returned nothing.
|
| 467 |
+
if ! $(tag) || ! $(self.name)
|
| 468 |
+
{
|
| 469 |
+
self.name = [ virtual-target.add-prefix-and-suffix $(specified-name)
|
| 470 |
+
: $(self.type) : $(ps) ] ;
|
| 471 |
+
}
|
| 472 |
+
}
|
| 473 |
+
|
| 474 |
+
rule actualize-no-scanner ( )
|
| 475 |
+
{
|
| 476 |
+
local name = [ actual-name ] ;
|
| 477 |
+
|
| 478 |
+
# Do anything only on the first invocation.
|
| 479 |
+
if ! $(self.made.$(name))
|
| 480 |
+
{
|
| 481 |
+
self.made.$(name) = true ;
|
| 482 |
+
|
| 483 |
+
if $(self.action)
|
| 484 |
+
{
|
| 485 |
+
# For non-derived target, we do not care if there are several
|
| 486 |
+
# virtual targets that refer to the same name. One case when
|
| 487 |
+
# this is unavoidable is when the file name is main.cpp and two
|
| 488 |
+
# targets have types CPP (for compiling) and MOCCABLE_CPP (for
|
| 489 |
+
# conversion to H via Qt tools).
|
| 490 |
+
virtual-target.register-actual-name $(name) : $(__name__) ;
|
| 491 |
+
}
|
| 492 |
+
|
| 493 |
+
for local i in $(self.dependencies)
|
| 494 |
+
{
|
| 495 |
+
DEPENDS $(name) : [ $(i).actualize ] ;
|
| 496 |
+
}
|
| 497 |
+
|
| 498 |
+
actualize-location $(name) ;
|
| 499 |
+
actualize-action $(name) ;
|
| 500 |
+
}
|
| 501 |
+
return $(name) ;
|
| 502 |
+
}
|
| 503 |
+
}
|
| 504 |
+
|
| 505 |
+
|
| 506 |
+
# Appends the suffix appropriate to 'type/property-set' combination to the
|
| 507 |
+
# specified name and returns the result.
|
| 508 |
+
#
|
| 509 |
+
rule add-prefix-and-suffix ( specified-name : type ? : property-set )
|
| 510 |
+
{
|
| 511 |
+
local suffix = [ type.generated-target-suffix $(type) : $(property-set) ] ;
|
| 512 |
+
|
| 513 |
+
# Handle suffixes for which no leading dot is desired. Those are specified
|
| 514 |
+
# by enclosing them in <...>. Needed by python so it can create "_d.so"
|
| 515 |
+
# extensions, for example.
|
| 516 |
+
if $(suffix:G)
|
| 517 |
+
{
|
| 518 |
+
suffix = [ utility.ungrist $(suffix) ] ;
|
| 519 |
+
}
|
| 520 |
+
else
|
| 521 |
+
{
|
| 522 |
+
suffix = .$(suffix) ;
|
| 523 |
+
}
|
| 524 |
+
|
| 525 |
+
local prefix = [ type.generated-target-prefix $(type) : $(property-set) ] ;
|
| 526 |
+
|
| 527 |
+
if [ MATCH ^($(prefix)) : $(specified-name) ]
|
| 528 |
+
{
|
| 529 |
+
prefix = ;
|
| 530 |
+
}
|
| 531 |
+
return $(prefix:E="")$(specified-name)$(suffix:E="") ;
|
| 532 |
+
}
|
| 533 |
+
|
| 534 |
+
|
| 535 |
+
# File targets with explicitly known location.
|
| 536 |
+
#
|
| 537 |
+
# The file path is determined as
|
| 538 |
+
# * Value passed to the 'set-path' method, if any.
|
| 539 |
+
# * For derived files, project's build dir, joined with components that
|
| 540 |
+
# describe action properties. If free properties are not equal to the
|
| 541 |
+
# project's reference properties an element with the name of the main
|
| 542 |
+
# target is added.
|
| 543 |
+
# * For source files, project's source dir.
|
| 544 |
+
#
|
| 545 |
+
# The file suffix is determined as:
|
| 546 |
+
# * The value passed to the 'suffix' method, if any.
|
| 547 |
+
# * The suffix corresponding to the target's type.
|
| 548 |
+
#
|
| 549 |
+
class file-target : abstract-file-target
|
| 550 |
+
{
|
| 551 |
+
import "class" : new ;
|
| 552 |
+
import common ;
|
| 553 |
+
import errors ;
|
| 554 |
+
|
| 555 |
+
rule __init__ (
|
| 556 |
+
name exact ?
|
| 557 |
+
: type ? # Optional type for this target.
|
| 558 |
+
: project
|
| 559 |
+
: action ?
|
| 560 |
+
: path ?
|
| 561 |
+
)
|
| 562 |
+
{
|
| 563 |
+
abstract-file-target.__init__ $(name) $(exact) : $(type) : $(project) :
|
| 564 |
+
$(action) ;
|
| 565 |
+
|
| 566 |
+
self.path = $(path) ;
|
| 567 |
+
}
|
| 568 |
+
|
| 569 |
+
rule clone-with-different-type ( new-type )
|
| 570 |
+
{
|
| 571 |
+
return [ new file-target $(self.name) exact : $(new-type) :
|
| 572 |
+
$(self.project) : $(self.action) : $(self.path) ] ;
|
| 573 |
+
}
|
| 574 |
+
|
| 575 |
+
rule actualize-location ( target )
|
| 576 |
+
{
|
| 577 |
+
if $(self.action)
|
| 578 |
+
{
|
| 579 |
+
# This is a derived file.
|
| 580 |
+
local path = [ path ] ;
|
| 581 |
+
LOCATE on $(target) = $(path) ;
|
| 582 |
+
|
| 583 |
+
# Make sure the path exists.
|
| 584 |
+
DEPENDS $(target) : $(path) ;
|
| 585 |
+
common.MkDir $(path) ;
|
| 586 |
+
|
| 587 |
+
# It is possible that the target name includes a directory too, for
|
| 588 |
+
# example when installing headers. Create that directory.
|
| 589 |
+
if $(target:D)
|
| 590 |
+
{
|
| 591 |
+
local d = $(target:D) ;
|
| 592 |
+
d = $(d:R=$(path)) ;
|
| 593 |
+
DEPENDS $(target) : $(d) ;
|
| 594 |
+
common.MkDir $(d) ;
|
| 595 |
+
}
|
| 596 |
+
|
| 597 |
+
# For a real file target, we create a fake target depending on the
|
| 598 |
+
# real target. This allows us to run
|
| 599 |
+
#
|
| 600 |
+
# bjam hello.o
|
| 601 |
+
#
|
| 602 |
+
# without trying to guess the name of the real target. Note that the
|
| 603 |
+
# target has no directory name and uses a special <e> grist.
|
| 604 |
+
#
|
| 605 |
+
# First, that means that "bjam hello.o" will build all known hello.o
|
| 606 |
+
# targets. Second, the <e> grist makes sure this target will not be
|
| 607 |
+
# confused with other targets, for example, if we have subdir 'test'
|
| 608 |
+
# with target 'test' in it that includes a 'test.o' file, then the
|
| 609 |
+
# target for directory will be just 'test' the target for test.o
|
| 610 |
+
# will be <ptest/bin/gcc/debug>test.o and the target we create below
|
| 611 |
+
# will be <e>test.o
|
| 612 |
+
DEPENDS $(target:G=e) : $(target) ;
|
| 613 |
+
# Allow bjam <path-to-file>/<file> to work. This will not catch all
|
| 614 |
+
# possible ways to refer to the path (relative/absolute, extra ".",
|
| 615 |
+
# various "..", but should help in obvious cases.
|
| 616 |
+
DEPENDS $(target:G=e:R=$(path)) : $(target) ;
|
| 617 |
+
}
|
| 618 |
+
else
|
| 619 |
+
{
|
| 620 |
+
SEARCH on $(target) = [ path.native $(self.path) ] ;
|
| 621 |
+
}
|
| 622 |
+
}
|
| 623 |
+
|
| 624 |
+
# Returns the directory for this target.
|
| 625 |
+
#
|
| 626 |
+
rule path ( )
|
| 627 |
+
{
|
| 628 |
+
if ! $(self.path)
|
| 629 |
+
{
|
| 630 |
+
if $(self.action)
|
| 631 |
+
{
|
| 632 |
+
local p = [ $(self.action).properties ] ;
|
| 633 |
+
local path,relative-to-build-dir = [ $(p).target-path ] ;
|
| 634 |
+
local path = $(path,relative-to-build-dir[1]) ;
|
| 635 |
+
local relative-to-build-dir = $(path,relative-to-build-dir[2]) ;
|
| 636 |
+
|
| 637 |
+
if $(relative-to-build-dir)
|
| 638 |
+
{
|
| 639 |
+
path = [ path.join [ $(self.project).build-dir ] $(path) ] ;
|
| 640 |
+
}
|
| 641 |
+
|
| 642 |
+
self.path = [ path.native $(path) ] ;
|
| 643 |
+
}
|
| 644 |
+
}
|
| 645 |
+
return $(self.path) ;
|
| 646 |
+
}
|
| 647 |
+
}
|
| 648 |
+
|
| 649 |
+
|
| 650 |
+
class notfile-target : abstract-file-target
|
| 651 |
+
{
|
| 652 |
+
rule __init__ ( name : project : action ? )
|
| 653 |
+
{
|
| 654 |
+
abstract-file-target.__init__ $(name) : : $(project) : $(action) ;
|
| 655 |
+
}
|
| 656 |
+
|
| 657 |
+
# Returns nothing to indicate that the target's path is not known.
|
| 658 |
+
#
|
| 659 |
+
rule path ( )
|
| 660 |
+
{
|
| 661 |
+
return ;
|
| 662 |
+
}
|
| 663 |
+
|
| 664 |
+
rule actualize-location ( target )
|
| 665 |
+
{
|
| 666 |
+
NOTFILE $(target) ;
|
| 667 |
+
ALWAYS $(target) ;
|
| 668 |
+
# TEMPORARY $(target) ;
|
| 669 |
+
NOUPDATE $(target) ;
|
| 670 |
+
}
|
| 671 |
+
}
|
| 672 |
+
|
| 673 |
+
|
| 674 |
+
# Class representing an action. Both 'targets' and 'sources' should list
|
| 675 |
+
# instances of 'virtual-target'. Action name should name a rule with this
|
| 676 |
+
# prototype:
|
| 677 |
+
# rule action-name ( targets + : sources * : properties * )
|
| 678 |
+
# Targets and sources are passed as actual Jam targets. The rule may not
|
| 679 |
+
# establish additional dependency relationships.
|
| 680 |
+
#
|
| 681 |
+
class action
|
| 682 |
+
{
|
| 683 |
+
import "class" ;
|
| 684 |
+
import errors ;
|
| 685 |
+
import type ;
|
| 686 |
+
import toolset ;
|
| 687 |
+
import property-set ;
|
| 688 |
+
import indirect ;
|
| 689 |
+
import path ;
|
| 690 |
+
import set : difference ;
|
| 691 |
+
|
| 692 |
+
rule __init__ ( sources * : action-name + : property-set ? )
|
| 693 |
+
{
|
| 694 |
+
self.sources = $(sources) ;
|
| 695 |
+
|
| 696 |
+
self.action-name = [ indirect.make-qualified $(action-name) ] ;
|
| 697 |
+
|
| 698 |
+
if ! $(property-set)
|
| 699 |
+
{
|
| 700 |
+
property-set = [ property-set.empty ] ;
|
| 701 |
+
}
|
| 702 |
+
|
| 703 |
+
if ! [ class.is-instance $(property-set) ]
|
| 704 |
+
{
|
| 705 |
+
errors.error "Property set instance required" ;
|
| 706 |
+
}
|
| 707 |
+
|
| 708 |
+
self.properties = $(property-set) ;
|
| 709 |
+
}
|
| 710 |
+
|
| 711 |
+
rule add-targets ( targets * )
|
| 712 |
+
{
|
| 713 |
+
self.targets += $(targets) ;
|
| 714 |
+
}
|
| 715 |
+
|
| 716 |
+
rule replace-targets ( old-targets * : new-targets * )
|
| 717 |
+
{
|
| 718 |
+
self.targets = [ set.difference $(self.targets) : $(old-targets) ] ;
|
| 719 |
+
self.targets += $(new-targets) ;
|
| 720 |
+
}
|
| 721 |
+
|
| 722 |
+
rule targets ( )
|
| 723 |
+
{
|
| 724 |
+
return $(self.targets) ;
|
| 725 |
+
}
|
| 726 |
+
|
| 727 |
+
rule sources ( )
|
| 728 |
+
{
|
| 729 |
+
return $(self.sources) ;
|
| 730 |
+
}
|
| 731 |
+
|
| 732 |
+
rule action-name ( )
|
| 733 |
+
{
|
| 734 |
+
return $(self.action-name) ;
|
| 735 |
+
}
|
| 736 |
+
|
| 737 |
+
rule properties ( )
|
| 738 |
+
{
|
| 739 |
+
return $(self.properties) ;
|
| 740 |
+
}
|
| 741 |
+
|
| 742 |
+
# Generates actual build instructions.
|
| 743 |
+
#
|
| 744 |
+
rule actualize ( )
|
| 745 |
+
{
|
| 746 |
+
if ! $(self.actualized)
|
| 747 |
+
{
|
| 748 |
+
self.actualized = true ;
|
| 749 |
+
|
| 750 |
+
local ps = [ properties ] ;
|
| 751 |
+
local properties = [ adjust-properties $(ps) ] ;
|
| 752 |
+
|
| 753 |
+
local actual-targets ;
|
| 754 |
+
for local i in [ targets ]
|
| 755 |
+
{
|
| 756 |
+
actual-targets += [ $(i).actualize ] ;
|
| 757 |
+
}
|
| 758 |
+
|
| 759 |
+
actualize-sources [ sources ] : $(properties) ;
|
| 760 |
+
|
| 761 |
+
DEPENDS $(actual-targets) : $(self.actual-sources)
|
| 762 |
+
$(self.dependency-only-sources) ;
|
| 763 |
+
|
| 764 |
+
# This works around a bug with -j and actions that
|
| 765 |
+
# produce multiple target, where:
|
| 766 |
+
# - dependency on the first output is found, and
|
| 767 |
+
# the action is started
|
| 768 |
+
# - dependency on the second output is found, and
|
| 769 |
+
# bjam noticed that command is already running
|
| 770 |
+
# - instead of waiting for the command, dependents
|
| 771 |
+
# of the second targets are immediately updated.
|
| 772 |
+
if $(actual-targets[2])
|
| 773 |
+
{
|
| 774 |
+
INCLUDES $(actual-targets) : $(actual-targets) ;
|
| 775 |
+
}
|
| 776 |
+
|
| 777 |
+
# Action name can include additional argument to rule, which should
|
| 778 |
+
# not be passed to 'set-target-variables'
|
| 779 |
+
toolset.set-target-variables
|
| 780 |
+
[ indirect.get-rule $(self.action-name[1]) ] $(actual-targets)
|
| 781 |
+
: $(properties) ;
|
| 782 |
+
|
| 783 |
+
# Reflect ourselves in a variable for the target. This allows
|
| 784 |
+
# looking up additional info for the action given the raw target.
|
| 785 |
+
# For example to debug or output action information from action
|
| 786 |
+
# rules.
|
| 787 |
+
.action on $(actual-targets) = $(__name__) ;
|
| 788 |
+
|
| 789 |
+
indirect.call $(self.action-name) $(actual-targets)
|
| 790 |
+
: $(self.actual-sources) : [ $(properties).raw ] ;
|
| 791 |
+
|
| 792 |
+
# Since we set up the creating action here, we set up the action for
|
| 793 |
+
# cleaning up as well.
|
| 794 |
+
common.Clean clean-all : $(actual-targets) ;
|
| 795 |
+
}
|
| 796 |
+
}
|
| 797 |
+
|
| 798 |
+
# Helper for 'actualize-sources'. For each passed source, actualizes it with
|
| 799 |
+
# the appropriate scanner. Returns the actualized virtual targets.
|
| 800 |
+
#
|
| 801 |
+
rule actualize-source-type ( sources * : property-set )
|
| 802 |
+
{
|
| 803 |
+
local result = ;
|
| 804 |
+
for local i in $(sources)
|
| 805 |
+
{
|
| 806 |
+
local scanner ;
|
| 807 |
+
if [ $(i).type ]
|
| 808 |
+
{
|
| 809 |
+
scanner = [ type.get-scanner [ $(i).type ] : $(property-set) ] ;
|
| 810 |
+
}
|
| 811 |
+
result += [ $(i).actualize $(scanner) ] ;
|
| 812 |
+
}
|
| 813 |
+
return $(result) ;
|
| 814 |
+
}
|
| 815 |
+
|
| 816 |
+
# Creates actual Jam targets for sources. Initializes the following member
|
| 817 |
+
# variables:
|
| 818 |
+
# 'self.actual-sources' -- sources passed to the updating action.
|
| 819 |
+
# 'self.dependency-only-sources' -- sources marked as dependencies, but
|
| 820 |
+
# are not used otherwise.
|
| 821 |
+
#
|
| 822 |
+
# New values will be *appended* to the variables. They may be non-empty if
|
| 823 |
+
# caller wants it.
|
| 824 |
+
#
|
| 825 |
+
rule actualize-sources ( sources * : property-set )
|
| 826 |
+
{
|
| 827 |
+
local dependencies = [ $(self.properties).get <dependency> ] ;
|
| 828 |
+
|
| 829 |
+
self.dependency-only-sources +=
|
| 830 |
+
[ actualize-source-type $(dependencies) : $(property-set) ] ;
|
| 831 |
+
self.actual-sources +=
|
| 832 |
+
[ actualize-source-type $(sources) : $(property-set) ] ;
|
| 833 |
+
|
| 834 |
+
# This is used to help bjam find dependencies in generated headers and
|
| 835 |
+
# other main targets, e.g. in:
|
| 836 |
+
#
|
| 837 |
+
# make a.h : ....... ;
|
| 838 |
+
# exe hello : hello.cpp : <implicit-dependency>a.h ;
|
| 839 |
+
#
|
| 840 |
+
# For bjam to find the dependency the generated target must be
|
| 841 |
+
# actualized (i.e. have its Jam target constructed). In the above case,
|
| 842 |
+
# if we are building just hello ("bjam hello"), 'a.h' will not be
|
| 843 |
+
# actualized unless we do it here.
|
| 844 |
+
local implicit = [ $(self.properties).get <implicit-dependency> ] ;
|
| 845 |
+
for local i in $(implicit)
|
| 846 |
+
{
|
| 847 |
+
$(i:G=).actualize ;
|
| 848 |
+
}
|
| 849 |
+
}
|
| 850 |
+
|
| 851 |
+
# Determines real properties when trying to build with 'properties'. This is
|
| 852 |
+
# the last chance to fix properties, for example to adjust includes to get
|
| 853 |
+
# generated headers correctly. Default implementation simply returns its
|
| 854 |
+
# argument.
|
| 855 |
+
#
|
| 856 |
+
rule adjust-properties ( property-set )
|
| 857 |
+
{
|
| 858 |
+
return $(property-set) ;
|
| 859 |
+
}
|
| 860 |
+
}
|
| 861 |
+
|
| 862 |
+
|
| 863 |
+
# Action class which does nothing --- it produces the targets with specific
|
| 864 |
+
# properties out of nowhere. It is needed to distinguish virtual targets with
|
| 865 |
+
# different properties that are known to exist and have no actions which create
|
| 866 |
+
# them.
|
| 867 |
+
#
|
| 868 |
+
class null-action : action
|
| 869 |
+
{
|
| 870 |
+
rule __init__ ( property-set ? )
|
| 871 |
+
{
|
| 872 |
+
action.__init__ : .no-action : $(property-set) ;
|
| 873 |
+
}
|
| 874 |
+
|
| 875 |
+
rule actualize ( )
|
| 876 |
+
{
|
| 877 |
+
if ! $(self.actualized)
|
| 878 |
+
{
|
| 879 |
+
self.actualized = true ;
|
| 880 |
+
for local i in [ targets ]
|
| 881 |
+
{
|
| 882 |
+
$(i).actualize ;
|
| 883 |
+
}
|
| 884 |
+
}
|
| 885 |
+
}
|
| 886 |
+
}
|
| 887 |
+
|
| 888 |
+
|
| 889 |
+
# Class which acts exactly like 'action', except that its sources are not
|
| 890 |
+
# scanned for dependencies.
|
| 891 |
+
#
|
| 892 |
+
class non-scanning-action : action
|
| 893 |
+
{
|
| 894 |
+
rule __init__ ( sources * : action-name + : property-set ? )
|
| 895 |
+
{
|
| 896 |
+
action.__init__ $(sources) : $(action-name) : $(property-set) ;
|
| 897 |
+
}
|
| 898 |
+
|
| 899 |
+
rule actualize-source-type ( sources * : property-set )
|
| 900 |
+
{
|
| 901 |
+
local result ;
|
| 902 |
+
for local i in $(sources)
|
| 903 |
+
{
|
| 904 |
+
result += [ $(i).actualize ] ;
|
| 905 |
+
}
|
| 906 |
+
return $(result) ;
|
| 907 |
+
}
|
| 908 |
+
}
|
| 909 |
+
|
| 910 |
+
|
| 911 |
+
# Creates a virtual target with an appropriate name and type from 'file'. If a
|
| 912 |
+
# target with that name in that project already exists, returns that already
|
| 913 |
+
# created target.
|
| 914 |
+
#
|
| 915 |
+
# FIXME: a more correct way would be to compute the path to the file, based on
|
| 916 |
+
# name and source location for the project, and use that path to determine if
|
| 917 |
+
# the target has already been created. This logic should be shared with how we
|
| 918 |
+
# usually find targets identified by a specific target id. It should also be
|
| 919 |
+
# updated to work correctly when the file is specified using both relative and
|
| 920 |
+
# absolute paths.
|
| 921 |
+
#
|
| 922 |
+
# TODO: passing a project with all virtual targets is starting to be annoying.
|
| 923 |
+
#
|
| 924 |
+
rule from-file ( file : file-loc : project )
|
| 925 |
+
{
|
| 926 |
+
import type ; # Had to do this here to break a circular dependency.
|
| 927 |
+
|
| 928 |
+
# Check whether we already created a target corresponding to this file.
|
| 929 |
+
local path = [ path.root [ path.root $(file) $(file-loc) ] [ path.pwd ] ] ;
|
| 930 |
+
|
| 931 |
+
if $(.files.$(path))
|
| 932 |
+
{
|
| 933 |
+
return $(.files.$(path)) ;
|
| 934 |
+
}
|
| 935 |
+
else
|
| 936 |
+
{
|
| 937 |
+
local name = [ path.make $(file) ] ;
|
| 938 |
+
local type = [ type.type $(file) ] ;
|
| 939 |
+
local result ;
|
| 940 |
+
|
| 941 |
+
result = [ new file-target $(file) : $(type) : $(project) : :
|
| 942 |
+
$(file-loc) ] ;
|
| 943 |
+
|
| 944 |
+
.files.$(path) = $(result) ;
|
| 945 |
+
return $(result) ;
|
| 946 |
+
}
|
| 947 |
+
}
|
| 948 |
+
|
| 949 |
+
|
| 950 |
+
# Registers a new virtual target. Checks if there is already a registered target
|
| 951 |
+
# with the same name, type, project and subvariant properties as well as the
|
| 952 |
+
# same sources and equal action. If such target is found it is returned and a
|
| 953 |
+
# new 'target' is not registered. Otherwise, 'target' is registered and
|
| 954 |
+
# returned.
|
| 955 |
+
#
|
| 956 |
+
rule register ( target )
|
| 957 |
+
{
|
| 958 |
+
local signature = [ sequence.join
|
| 959 |
+
[ $(target).path ] [ $(target).name ] : - ] ;
|
| 960 |
+
|
| 961 |
+
local result ;
|
| 962 |
+
for local t in $(.cache.$(signature))
|
| 963 |
+
{
|
| 964 |
+
local a1 = [ $(t).action ] ;
|
| 965 |
+
local a2 = [ $(target).action ] ;
|
| 966 |
+
|
| 967 |
+
if ! $(result)
|
| 968 |
+
{
|
| 969 |
+
if ! $(a1) && ! $(a2)
|
| 970 |
+
{
|
| 971 |
+
result = $(t) ;
|
| 972 |
+
}
|
| 973 |
+
else
|
| 974 |
+
{
|
| 975 |
+
if $(a1) && $(a2) &&
|
| 976 |
+
( [ $(a1).action-name ] = [ $(a2).action-name ] ) &&
|
| 977 |
+
( [ $(a1).sources ] = [ $(a2).sources ] )
|
| 978 |
+
{
|
| 979 |
+
local ps1 = [ $(a1).properties ] ;
|
| 980 |
+
local ps2 = [ $(a2).properties ] ;
|
| 981 |
+
local p1 = [ $(ps1).base ] [ $(ps1).free ] [ set.difference
|
| 982 |
+
[ $(ps1).dependency ] : [ $(ps1).incidental ] ] ;
|
| 983 |
+
local p2 = [ $(ps2).base ] [ $(ps2).free ] [ set.difference
|
| 984 |
+
[ $(ps2).dependency ] : [ $(ps2).incidental ] ] ;
|
| 985 |
+
if $(p1) = $(p2)
|
| 986 |
+
{
|
| 987 |
+
result = $(t) ;
|
| 988 |
+
}
|
| 989 |
+
}
|
| 990 |
+
}
|
| 991 |
+
}
|
| 992 |
+
}
|
| 993 |
+
|
| 994 |
+
if ! $(result)
|
| 995 |
+
{
|
| 996 |
+
.cache.$(signature) += $(target) ;
|
| 997 |
+
result = $(target) ;
|
| 998 |
+
}
|
| 999 |
+
|
| 1000 |
+
.recent-targets += $(result) ;
|
| 1001 |
+
.all-targets += $(result) ;
|
| 1002 |
+
|
| 1003 |
+
return $(result) ;
|
| 1004 |
+
}
|
| 1005 |
+
|
| 1006 |
+
|
| 1007 |
+
# Each target returned by 'register' is added to the .recent-targets list,
|
| 1008 |
+
# returned by this function. This allows us to find all virtual targets created
|
| 1009 |
+
# when building a specific main target, even those constructed only as
|
| 1010 |
+
# intermediate targets.
|
| 1011 |
+
#
|
| 1012 |
+
rule recent-targets ( )
|
| 1013 |
+
{
|
| 1014 |
+
return $(.recent-targets) ;
|
| 1015 |
+
}
|
| 1016 |
+
|
| 1017 |
+
|
| 1018 |
+
rule clear-recent-targets ( )
|
| 1019 |
+
{
|
| 1020 |
+
.recent-targets = ;
|
| 1021 |
+
}
|
| 1022 |
+
|
| 1023 |
+
|
| 1024 |
+
# Returns all virtual targets ever created.
|
| 1025 |
+
#
|
| 1026 |
+
rule all-targets ( )
|
| 1027 |
+
{
|
| 1028 |
+
return $(.all-targets) ;
|
| 1029 |
+
}
|
| 1030 |
+
|
| 1031 |
+
|
| 1032 |
+
# Returns all targets from 'targets' with types equal to 'type' or derived from
|
| 1033 |
+
# it.
|
| 1034 |
+
#
|
| 1035 |
+
rule select-by-type ( type : targets * )
|
| 1036 |
+
{
|
| 1037 |
+
local result ;
|
| 1038 |
+
for local t in $(targets)
|
| 1039 |
+
{
|
| 1040 |
+
if [ type.is-subtype [ $(t).type ] $(type) ]
|
| 1041 |
+
{
|
| 1042 |
+
result += $(t) ;
|
| 1043 |
+
}
|
| 1044 |
+
}
|
| 1045 |
+
return $(result) ;
|
| 1046 |
+
}
|
| 1047 |
+
|
| 1048 |
+
|
| 1049 |
+
rule register-actual-name ( actual-name : virtual-target )
|
| 1050 |
+
{
|
| 1051 |
+
if $(.actual.$(actual-name))
|
| 1052 |
+
{
|
| 1053 |
+
local cs1 = [ $(.actual.$(actual-name)).creating-subvariant ] ;
|
| 1054 |
+
local cs2 = [ $(virtual-target).creating-subvariant ] ;
|
| 1055 |
+
local cmt1 = [ $(cs1).main-target ] ;
|
| 1056 |
+
local cmt2 = [ $(cs2).main-target ] ;
|
| 1057 |
+
|
| 1058 |
+
local action1 = [ $(.actual.$(actual-name)).action ] ;
|
| 1059 |
+
local action2 = [ $(virtual-target).action ] ;
|
| 1060 |
+
local properties-added ;
|
| 1061 |
+
local properties-removed ;
|
| 1062 |
+
if $(action1) && $(action2)
|
| 1063 |
+
{
|
| 1064 |
+
local p1 = [ $(action1).properties ] ;
|
| 1065 |
+
p1 = [ $(p1).raw ] ;
|
| 1066 |
+
local p2 = [ $(action2).properties ] ;
|
| 1067 |
+
p2 = [ $(p2).raw ] ;
|
| 1068 |
+
properties-removed = [ set.difference $(p1) : $(p2) ] ;
|
| 1069 |
+
properties-removed ?= "none" ;
|
| 1070 |
+
properties-added = [ set.difference $(p2) : $(p1) ] ;
|
| 1071 |
+
properties-added ?= "none" ;
|
| 1072 |
+
}
|
| 1073 |
+
errors.error "Duplicate name of actual target:" $(actual-name)
|
| 1074 |
+
: "previous virtual target" [ $(.actual.$(actual-name)).str ]
|
| 1075 |
+
: "created from" [ $(cmt1).full-name ]
|
| 1076 |
+
: "another virtual target" [ $(virtual-target).str ]
|
| 1077 |
+
: "created from" [ $(cmt2).full-name ]
|
| 1078 |
+
: "added properties:" $(properties-added)
|
| 1079 |
+
: "removed properties:" $(properties-removed) ;
|
| 1080 |
+
}
|
| 1081 |
+
else
|
| 1082 |
+
{
|
| 1083 |
+
.actual.$(actual-name) = $(virtual-target) ;
|
| 1084 |
+
}
|
| 1085 |
+
}
|
| 1086 |
+
|
| 1087 |
+
|
| 1088 |
+
# Traverses the dependency graph of 'target' and return all targets that will be
|
| 1089 |
+
# created before this one is created. If the root of some dependency graph is
|
| 1090 |
+
# found during traversal, it is either included or not, depending on the
|
| 1091 |
+
# 'include-roots' value. In either case traversal stops at root targets, i.e.
|
| 1092 |
+
# root target sources are not traversed.
|
| 1093 |
+
#
|
| 1094 |
+
rule traverse ( target : include-roots ? : include-sources ? )
|
| 1095 |
+
{
|
| 1096 |
+
local result ;
|
| 1097 |
+
if [ $(target).action ]
|
| 1098 |
+
{
|
| 1099 |
+
local action = [ $(target).action ] ;
|
| 1100 |
+
# This includes the 'target' as well.
|
| 1101 |
+
result += [ $(action).targets ] ;
|
| 1102 |
+
|
| 1103 |
+
for local t in [ $(action).sources ]
|
| 1104 |
+
{
|
| 1105 |
+
if ! [ $(t).root ]
|
| 1106 |
+
{
|
| 1107 |
+
result += [ traverse $(t) : $(include-roots) : $(include-sources) ] ;
|
| 1108 |
+
}
|
| 1109 |
+
else if $(include-roots)
|
| 1110 |
+
{
|
| 1111 |
+
result += $(t) ;
|
| 1112 |
+
}
|
| 1113 |
+
}
|
| 1114 |
+
}
|
| 1115 |
+
else if $(include-sources)
|
| 1116 |
+
{
|
| 1117 |
+
result = $(target) ;
|
| 1118 |
+
}
|
| 1119 |
+
return $(result) ;
|
| 1120 |
+
}
|
| 1121 |
+
|
| 1122 |
+
|
| 1123 |
+
# Takes an 'action' instance and creates a new instance of it and all targets
|
| 1124 |
+
# produced by the action. The rule-name and properties are set to
|
| 1125 |
+
# 'new-rule-name' and 'new-properties', if those are specified. Returns the
|
| 1126 |
+
# cloned action.
|
| 1127 |
+
#
|
| 1128 |
+
rule clone-action ( action : new-project : new-action-name ? : new-properties ? )
|
| 1129 |
+
{
|
| 1130 |
+
if ! $(new-action-name)
|
| 1131 |
+
{
|
| 1132 |
+
new-action-name = [ $(action).action-name ] ;
|
| 1133 |
+
}
|
| 1134 |
+
if ! $(new-properties)
|
| 1135 |
+
{
|
| 1136 |
+
new-properties = [ $(action).properties ] ;
|
| 1137 |
+
}
|
| 1138 |
+
|
| 1139 |
+
local action-class = [ modules.peek $(action) : __class__ ] ;
|
| 1140 |
+
local cloned-action = [ class.new $(action-class)
|
| 1141 |
+
[ $(action).sources ] : $(new-action-name) : $(new-properties) ] ;
|
| 1142 |
+
|
| 1143 |
+
local cloned-targets ;
|
| 1144 |
+
for local target in [ $(action).targets ]
|
| 1145 |
+
{
|
| 1146 |
+
local n = [ $(target).name ] ;
|
| 1147 |
+
# Do not modify produced target names.
|
| 1148 |
+
local cloned-target = [ class.new file-target $(n) exact :
|
| 1149 |
+
[ $(target).type ] : $(new-project) : $(cloned-action) ] ;
|
| 1150 |
+
local d = [ $(target).dependencies ] ;
|
| 1151 |
+
if $(d)
|
| 1152 |
+
{
|
| 1153 |
+
$(cloned-target).depends $(d) ;
|
| 1154 |
+
}
|
| 1155 |
+
$(cloned-target).root [ $(target).root ] ;
|
| 1156 |
+
$(cloned-target).creating-subvariant [ $(target).creating-subvariant ] ;
|
| 1157 |
+
|
| 1158 |
+
cloned-targets += $(cloned-target) ;
|
| 1159 |
+
}
|
| 1160 |
+
|
| 1161 |
+
return $(cloned-action) ;
|
| 1162 |
+
}
|
| 1163 |
+
|
| 1164 |
+
|
| 1165 |
+
class subvariant
|
| 1166 |
+
{
|
| 1167 |
+
import sequence ;
|
| 1168 |
+
import type ;
|
| 1169 |
+
|
| 1170 |
+
rule __init__ ( main-target # The instance of main-target class.
|
| 1171 |
+
: property-set # Properties requested for this target.
|
| 1172 |
+
: sources *
|
| 1173 |
+
: build-properties # Actually used properties.
|
| 1174 |
+
: sources-usage-requirements # Properties propagated from sources.
|
| 1175 |
+
: created-targets * ) # Top-level created targets.
|
| 1176 |
+
{
|
| 1177 |
+
self.main-target = $(main-target) ;
|
| 1178 |
+
self.properties = $(property-set) ;
|
| 1179 |
+
self.sources = $(sources) ;
|
| 1180 |
+
self.build-properties = $(build-properties) ;
|
| 1181 |
+
self.sources-usage-requirements = $(sources-usage-requirements) ;
|
| 1182 |
+
self.created-targets = $(created-targets) ;
|
| 1183 |
+
|
| 1184 |
+
# Pre-compose a list of other dependency graphs this one depends on.
|
| 1185 |
+
local deps = [ $(build-properties).get <implicit-dependency> ] ;
|
| 1186 |
+
for local d in $(deps)
|
| 1187 |
+
{
|
| 1188 |
+
self.other-dg += [ $(d:G=).creating-subvariant ] ;
|
| 1189 |
+
}
|
| 1190 |
+
|
| 1191 |
+
self.other-dg = [ sequence.unique $(self.other-dg) ] ;
|
| 1192 |
+
}
|
| 1193 |
+
|
| 1194 |
+
rule main-target ( )
|
| 1195 |
+
{
|
| 1196 |
+
return $(self.main-target) ;
|
| 1197 |
+
}
|
| 1198 |
+
|
| 1199 |
+
rule created-targets ( )
|
| 1200 |
+
{
|
| 1201 |
+
return $(self.created-targets) ;
|
| 1202 |
+
}
|
| 1203 |
+
|
| 1204 |
+
rule requested-properties ( )
|
| 1205 |
+
{
|
| 1206 |
+
return $(self.properties) ;
|
| 1207 |
+
}
|
| 1208 |
+
|
| 1209 |
+
rule build-properties ( )
|
| 1210 |
+
{
|
| 1211 |
+
return $(self.build-properties) ;
|
| 1212 |
+
}
|
| 1213 |
+
|
| 1214 |
+
rule sources-usage-requirements ( )
|
| 1215 |
+
{
|
| 1216 |
+
return $(self.sources-usage-requirements) ;
|
| 1217 |
+
}
|
| 1218 |
+
|
| 1219 |
+
rule set-usage-requirements ( usage-requirements )
|
| 1220 |
+
{
|
| 1221 |
+
self.usage-requirements = $(usage-requirements) ;
|
| 1222 |
+
}
|
| 1223 |
+
|
| 1224 |
+
rule usage-requirements ( )
|
| 1225 |
+
{
|
| 1226 |
+
return $(self.usage-requirements) ;
|
| 1227 |
+
}
|
| 1228 |
+
|
| 1229 |
+
# Returns all targets referenced by this subvariant, either directly or
|
| 1230 |
+
# indirectly, and either as sources, or as dependency properties. Targets
|
| 1231 |
+
# referred to using the dependency property are returned as properties, not
|
| 1232 |
+
# targets.
|
| 1233 |
+
#
|
| 1234 |
+
rule all-referenced-targets ( theset )
|
| 1235 |
+
{
|
| 1236 |
+
# Find directly referenced targets.
|
| 1237 |
+
local deps = [ $(self.build-properties).dependency ] ;
|
| 1238 |
+
local all-targets = $(self.sources) $(deps) ;
|
| 1239 |
+
|
| 1240 |
+
# Find other subvariants.
|
| 1241 |
+
local r ;
|
| 1242 |
+
for local t in $(all-targets)
|
| 1243 |
+
{
|
| 1244 |
+
if ! [ $(theset).contains $(t) ]
|
| 1245 |
+
{
|
| 1246 |
+
$(theset).add $(t) ;
|
| 1247 |
+
r += [ $(t:G=).creating-subvariant ] ;
|
| 1248 |
+
}
|
| 1249 |
+
}
|
| 1250 |
+
r = [ sequence.unique $(r) ] ;
|
| 1251 |
+
for local s in $(r)
|
| 1252 |
+
{
|
| 1253 |
+
if $(s) != $(__name__)
|
| 1254 |
+
{
|
| 1255 |
+
$(s).all-referenced-targets $(theset) ;
|
| 1256 |
+
}
|
| 1257 |
+
}
|
| 1258 |
+
}
|
| 1259 |
+
|
| 1260 |
+
# Returns the properties specifying implicit include paths to generated
|
| 1261 |
+
# headers. This traverses all targets in this subvariant and subvariants
|
| 1262 |
+
# referred by <implcit-dependecy> properties. For all targets of type
|
| 1263 |
+
# 'target-type' (or for all targets, if 'target-type' is not specified), the
|
| 1264 |
+
# result will contain <$(feature)>path-to-that-target.
|
| 1265 |
+
#
|
| 1266 |
+
rule implicit-includes ( feature : target-type ? )
|
| 1267 |
+
{
|
| 1268 |
+
local key = ii$(feature)-$(target-type:E="") ;
|
| 1269 |
+
if ! $($(key))-is-not-empty
|
| 1270 |
+
{
|
| 1271 |
+
local target-paths = [ all-target-directories $(target-type) ] ;
|
| 1272 |
+
target-paths = [ sequence.unique $(target-paths) ] ;
|
| 1273 |
+
local result = $(target-paths:G=$(feature)) ;
|
| 1274 |
+
if ! $(result)
|
| 1275 |
+
{
|
| 1276 |
+
result = "" ;
|
| 1277 |
+
}
|
| 1278 |
+
$(key) = $(result) ;
|
| 1279 |
+
}
|
| 1280 |
+
if $($(key)) = ""
|
| 1281 |
+
{
|
| 1282 |
+
return ;
|
| 1283 |
+
}
|
| 1284 |
+
else
|
| 1285 |
+
{
|
| 1286 |
+
return $($(key)) ;
|
| 1287 |
+
}
|
| 1288 |
+
}
|
| 1289 |
+
|
| 1290 |
+
rule all-target-directories ( target-type ? )
|
| 1291 |
+
{
|
| 1292 |
+
if ! $(self.target-directories)
|
| 1293 |
+
{
|
| 1294 |
+
compute-target-directories $(target-type) ;
|
| 1295 |
+
}
|
| 1296 |
+
return $(self.target-directories) ;
|
| 1297 |
+
}
|
| 1298 |
+
|
| 1299 |
+
rule compute-target-directories ( target-type ? )
|
| 1300 |
+
{
|
| 1301 |
+
local result ;
|
| 1302 |
+
for local t in $(self.created-targets)
|
| 1303 |
+
{
|
| 1304 |
+
# Skip targets of the wrong type.
|
| 1305 |
+
if ! $(target-type) ||
|
| 1306 |
+
[ type.is-derived [ $(t).type ] $(target-type) ]
|
| 1307 |
+
{
|
| 1308 |
+
result = [ sequence.merge $(result) : [ $(t).path ] ] ;
|
| 1309 |
+
}
|
| 1310 |
+
}
|
| 1311 |
+
for local d in $(self.other-dg)
|
| 1312 |
+
{
|
| 1313 |
+
result += [ $(d).all-target-directories $(target-type) ] ;
|
| 1314 |
+
}
|
| 1315 |
+
self.target-directories = $(result) ;
|
| 1316 |
+
}
|
| 1317 |
+
}
|
mosesdecoder/jam-files/boost-build/util/assert.jam
ADDED
|
@@ -0,0 +1,336 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright 2001, 2002, 2003 Dave Abrahams
|
| 2 |
+
# Copyright 2006 Rene Rivera
|
| 3 |
+
# Copyright 2002, 2003 Vladimir Prus
|
| 4 |
+
# Distributed under the Boost Software License, Version 1.0.
|
| 5 |
+
# (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
|
| 6 |
+
|
| 7 |
+
import errors ;
|
| 8 |
+
import modules ;
|
| 9 |
+
|
| 10 |
+
|
| 11 |
+
################################################################################
|
| 12 |
+
#
|
| 13 |
+
# Private implementation details.
|
| 14 |
+
#
|
| 15 |
+
################################################################################
|
| 16 |
+
|
| 17 |
+
# Rule added as a replacement for the regular Jam = operator but which does not
|
| 18 |
+
# ignore trailing empty string elements.
|
| 19 |
+
#
|
| 20 |
+
local rule exact-equal-test ( lhs * : rhs * )
|
| 21 |
+
{
|
| 22 |
+
local lhs_extended = $(lhs) xxx ;
|
| 23 |
+
local rhs_extended = $(rhs) xxx ;
|
| 24 |
+
if $(lhs_extended) = $(rhs_extended)
|
| 25 |
+
{
|
| 26 |
+
return true ;
|
| 27 |
+
}
|
| 28 |
+
}
|
| 29 |
+
|
| 30 |
+
|
| 31 |
+
# Two lists are considered set-equal if they contain the same elements, ignoring
|
| 32 |
+
# duplicates and ordering.
|
| 33 |
+
#
|
| 34 |
+
local rule set-equal-test ( set1 * : set2 * )
|
| 35 |
+
{
|
| 36 |
+
if ( $(set1) in $(set2) ) && ( $(set2) in $(set1) )
|
| 37 |
+
{
|
| 38 |
+
return true ;
|
| 39 |
+
}
|
| 40 |
+
}
|
| 41 |
+
|
| 42 |
+
|
| 43 |
+
################################################################################
|
| 44 |
+
#
|
| 45 |
+
# Public interface.
|
| 46 |
+
#
|
| 47 |
+
################################################################################
|
| 48 |
+
|
| 49 |
+
# Assert the equality of A and B, ignoring trailing empty string elements.
|
| 50 |
+
#
|
| 51 |
+
rule equal ( a * : b * )
|
| 52 |
+
{
|
| 53 |
+
if $(a) != $(b)
|
| 54 |
+
{
|
| 55 |
+
errors.error-skip-frames 3 assertion failure: \"$(a)\" "==" \"$(b)\"
|
| 56 |
+
(ignoring trailing empty strings) ;
|
| 57 |
+
}
|
| 58 |
+
}
|
| 59 |
+
|
| 60 |
+
|
| 61 |
+
# Assert that the result of calling RULE-NAME on the given arguments has a false
|
| 62 |
+
# logical value (is either an empty list or all empty strings).
|
| 63 |
+
#
|
| 64 |
+
rule false ( rule-name args * : * )
|
| 65 |
+
{
|
| 66 |
+
local result ;
|
| 67 |
+
module [ CALLER_MODULE ]
|
| 68 |
+
{
|
| 69 |
+
modules.poke assert : result : [ $(1) : $(2) : $(3) : $(4) : $(5) : $(6)
|
| 70 |
+
: $(7) : $(8) : $(9) ] ;
|
| 71 |
+
}
|
| 72 |
+
|
| 73 |
+
if $(result)
|
| 74 |
+
{
|
| 75 |
+
errors.error-skip-frames 3 assertion failure: Expected false result from
|
| 76 |
+
"[" $(rule-name) [ errors.lol->list $(args) : $(2) : $(3) : $(4) :
|
| 77 |
+
$(5) : $(6) : $(7) : $(8) : $(9) ] "]" : Got: "[" \"$(result)\" "]" ;
|
| 78 |
+
}
|
| 79 |
+
}
|
| 80 |
+
|
| 81 |
+
|
| 82 |
+
# Assert that ELEMENT is present in LIST.
|
| 83 |
+
#
|
| 84 |
+
rule "in" ( element : list * )
|
| 85 |
+
{
|
| 86 |
+
if ! $(element) in $(list)
|
| 87 |
+
{
|
| 88 |
+
errors.error-skip-frames 3 assertion failure: Expected \"$(element)\" in
|
| 89 |
+
"[" \"$(list)\" "]" ;
|
| 90 |
+
}
|
| 91 |
+
}
|
| 92 |
+
|
| 93 |
+
|
| 94 |
+
# Assert the inequality of A and B, ignoring trailing empty string elements.
|
| 95 |
+
#
|
| 96 |
+
rule not-equal ( a * : b * )
|
| 97 |
+
{
|
| 98 |
+
if $(a) = $(b)
|
| 99 |
+
{
|
| 100 |
+
errors.error-skip-frames 3 assertion failure: \"$(a)\" "!=" \"$(b)\"
|
| 101 |
+
(ignoring trailing empty strings) ;
|
| 102 |
+
}
|
| 103 |
+
}
|
| 104 |
+
|
| 105 |
+
|
| 106 |
+
# Assert that ELEMENT is not present in LIST.
|
| 107 |
+
#
|
| 108 |
+
rule not-in ( element : list * )
|
| 109 |
+
{
|
| 110 |
+
if $(element) in $(list)
|
| 111 |
+
{
|
| 112 |
+
errors.error-skip-frames 3 assertion failure: Did not expect
|
| 113 |
+
\"$(element)\" in "[" \"$(list)\" "]" ;
|
| 114 |
+
}
|
| 115 |
+
}
|
| 116 |
+
|
| 117 |
+
|
| 118 |
+
# Assert the inequality of A and B as sets.
|
| 119 |
+
#
|
| 120 |
+
rule not-set-equal ( a * : b * )
|
| 121 |
+
{
|
| 122 |
+
if [ set-equal-test $(a) : $(b) ]
|
| 123 |
+
{
|
| 124 |
+
errors.error-skip-frames 3 assertion failure: Expected "[" \"$(a)\" "]"
|
| 125 |
+
and "[" \"$(b)\" "]" to not be equal as sets ;
|
| 126 |
+
}
|
| 127 |
+
}
|
| 128 |
+
|
| 129 |
+
|
| 130 |
+
# Assert that A and B are not exactly equal, not ignoring trailing empty string
|
| 131 |
+
# elements.
|
| 132 |
+
#
|
| 133 |
+
rule not-exact-equal ( a * : b * )
|
| 134 |
+
{
|
| 135 |
+
if [ exact-equal-test $(a) : $(b) ]
|
| 136 |
+
{
|
| 137 |
+
errors.error-skip-frames 3 assertion failure: \"$(a)\" "!=" \"$(b)\" ;
|
| 138 |
+
}
|
| 139 |
+
}
|
| 140 |
+
|
| 141 |
+
|
| 142 |
+
# Assert that EXPECTED is the result of calling RULE-NAME with the given
|
| 143 |
+
# arguments.
|
| 144 |
+
#
|
| 145 |
+
rule result ( expected * : rule-name args * : * )
|
| 146 |
+
{
|
| 147 |
+
local result ;
|
| 148 |
+
module [ CALLER_MODULE ]
|
| 149 |
+
{
|
| 150 |
+
modules.poke assert : result : [ $(2) : $(3) : $(4) : $(5) : $(6) : $(7)
|
| 151 |
+
: $(8) : $(9) ] ;
|
| 152 |
+
}
|
| 153 |
+
|
| 154 |
+
if ! [ exact-equal-test $(result) : $(expected) ]
|
| 155 |
+
{
|
| 156 |
+
errors.error-skip-frames 3 assertion failure: "[" $(rule-name) [
|
| 157 |
+
errors.lol->list $(args) : $(3) : $(4) : $(5) : $(6) : $(7) : $(8) :
|
| 158 |
+
$(9) ] "]" : Expected: "[" \"$(expected)\" "]" : Got: "["
|
| 159 |
+
\"$(result)\" "]" ;
|
| 160 |
+
}
|
| 161 |
+
}
|
| 162 |
+
|
| 163 |
+
|
| 164 |
+
# Assert that EXPECTED is set-equal (i.e. duplicates and ordering are ignored)
|
| 165 |
+
# to the result of calling RULE-NAME with the given arguments. Note that rules
|
| 166 |
+
# called this way may accept at most 8 parameters.
|
| 167 |
+
#
|
| 168 |
+
rule result-set-equal ( expected * : rule-name args * : * )
|
| 169 |
+
{
|
| 170 |
+
local result ;
|
| 171 |
+
module [ CALLER_MODULE ]
|
| 172 |
+
{
|
| 173 |
+
modules.poke assert : result : [ $(2) : $(3) : $(4) : $(5) : $(6) : $(7)
|
| 174 |
+
: $(8) : $(9) ] ;
|
| 175 |
+
}
|
| 176 |
+
|
| 177 |
+
if ! [ set-equal-test $(result) : $(expected) ]
|
| 178 |
+
{
|
| 179 |
+
errors.error-skip-frames 3 assertion failure: "[" $(rule-name) [
|
| 180 |
+
errors.lol->list $(args) : $(3) : $(4) : $(5) : $(6) : $(7) : $(8) :
|
| 181 |
+
$(9) ] "]" : Expected: "[" \"$(expected)\" "]" : Got: "["
|
| 182 |
+
\"$(result)\" "]" ;
|
| 183 |
+
}
|
| 184 |
+
}
|
| 185 |
+
|
| 186 |
+
|
| 187 |
+
# Assert the equality of A and B as sets.
|
| 188 |
+
#
|
| 189 |
+
rule set-equal ( a * : b * )
|
| 190 |
+
{
|
| 191 |
+
if ! [ set-equal-test $(a) : $(b) ]
|
| 192 |
+
{
|
| 193 |
+
errors.error-skip-frames 3 assertion failure: Expected "[" \"$(a)\" "]"
|
| 194 |
+
and "[" \"$(b)\" "]" to be equal as sets ;
|
| 195 |
+
}
|
| 196 |
+
}
|
| 197 |
+
|
| 198 |
+
|
| 199 |
+
# Assert that the result of calling RULE-NAME on the given arguments has a true
|
| 200 |
+
# logical value (is neither an empty list nor all empty strings).
|
| 201 |
+
#
|
| 202 |
+
rule true ( rule-name args * : * )
|
| 203 |
+
{
|
| 204 |
+
local result ;
|
| 205 |
+
module [ CALLER_MODULE ]
|
| 206 |
+
{
|
| 207 |
+
modules.poke assert : result : [ $(1) : $(2) : $(3) : $(4) : $(5) : $(6)
|
| 208 |
+
: $(7) : $(8) : $(9) ] ;
|
| 209 |
+
}
|
| 210 |
+
|
| 211 |
+
if ! $(result)
|
| 212 |
+
{
|
| 213 |
+
errors.error-skip-frames 3 assertion failure: Expected true result from
|
| 214 |
+
"[" $(rule-name) [ errors.lol->list $(args) : $(2) : $(3) : $(4) :
|
| 215 |
+
$(5) : $(6) : $(7) : $(8) : $(9) ] "]" ;
|
| 216 |
+
}
|
| 217 |
+
}
|
| 218 |
+
|
| 219 |
+
|
| 220 |
+
# Assert the exact equality of A and B, not ignoring trailing empty string
|
| 221 |
+
# elements.
|
| 222 |
+
#
|
| 223 |
+
rule exact-equal ( a * : b * )
|
| 224 |
+
{
|
| 225 |
+
if ! [ exact-equal-test $(a) : $(b) ]
|
| 226 |
+
{
|
| 227 |
+
errors.error-skip-frames 3 assertion failure: \"$(a)\" "==" \"$(b)\" ;
|
| 228 |
+
}
|
| 229 |
+
}
|
| 230 |
+
|
| 231 |
+
|
| 232 |
+
# Assert that the given variable is not an empty list.
|
| 233 |
+
#
|
| 234 |
+
rule variable-not-empty ( name )
|
| 235 |
+
{
|
| 236 |
+
local value = [ modules.peek [ CALLER_MODULE ] : $(name) ] ;
|
| 237 |
+
if ! $(value)-is-not-empty
|
| 238 |
+
{
|
| 239 |
+
errors.error-skip-frames 3 assertion failure: Expected variable
|
| 240 |
+
\"$(name)\" not to be an empty list ;
|
| 241 |
+
}
|
| 242 |
+
}
|
| 243 |
+
|
| 244 |
+
|
| 245 |
+
rule __test__ ( )
|
| 246 |
+
{
|
| 247 |
+
# Helper rule used to avoid test duplication related to different list
|
| 248 |
+
# equality test rules.
|
| 249 |
+
#
|
| 250 |
+
local rule run-equality-test ( equality-assert : ignore-trailing-empty-strings ? )
|
| 251 |
+
{
|
| 252 |
+
local not-equality-assert = not-$(equality-assert) ;
|
| 253 |
+
|
| 254 |
+
# When the given equality test is expected to ignore trailing empty
|
| 255 |
+
# strings some of the test results should be inverted.
|
| 256 |
+
local not-equality-assert-i = not-$(equality-assert) ;
|
| 257 |
+
if $(ignore-trailing-empty-strings)
|
| 258 |
+
{
|
| 259 |
+
not-equality-assert-i = $(equality-assert) ;
|
| 260 |
+
}
|
| 261 |
+
|
| 262 |
+
$(equality-assert) : ;
|
| 263 |
+
$(equality-assert) "" "" : "" "" ;
|
| 264 |
+
$(not-equality-assert-i) : "" "" ;
|
| 265 |
+
$(equality-assert) x : x ;
|
| 266 |
+
$(not-equality-assert) : x ;
|
| 267 |
+
$(not-equality-assert) "" : x ;
|
| 268 |
+
$(not-equality-assert) "" "" : x ;
|
| 269 |
+
$(not-equality-assert-i) x : x "" ;
|
| 270 |
+
$(equality-assert) x "" : x "" ;
|
| 271 |
+
$(not-equality-assert) x : "" x ;
|
| 272 |
+
$(equality-assert) "" x : "" x ;
|
| 273 |
+
|
| 274 |
+
$(equality-assert) 1 2 3 : 1 2 3 ;
|
| 275 |
+
$(not-equality-assert) 1 2 3 : 3 2 1 ;
|
| 276 |
+
$(not-equality-assert) 1 2 3 : 1 5 3 ;
|
| 277 |
+
$(not-equality-assert) 1 2 3 : 1 "" 3 ;
|
| 278 |
+
$(not-equality-assert) 1 2 3 : 1 1 2 3 ;
|
| 279 |
+
$(not-equality-assert) 1 2 3 : 1 2 2 3 ;
|
| 280 |
+
$(not-equality-assert) 1 2 3 : 5 6 7 ;
|
| 281 |
+
|
| 282 |
+
# Extra variables used here just to make sure Boost Jam or Boost Build
|
| 283 |
+
# do not handle lists with empty strings differently depending on
|
| 284 |
+
# whether they are literals or stored in variables.
|
| 285 |
+
|
| 286 |
+
local empty = ;
|
| 287 |
+
local empty-strings = "" "" ;
|
| 288 |
+
local x-empty-strings = x "" "" ;
|
| 289 |
+
local empty-strings-x = "" "" x ;
|
| 290 |
+
|
| 291 |
+
$(equality-assert) : $(empty) ;
|
| 292 |
+
$(not-equality-assert-i) "" : $(empty) ;
|
| 293 |
+
$(not-equality-assert-i) "" "" : $(empty) ;
|
| 294 |
+
$(not-equality-assert-i) : $(empty-strings) ;
|
| 295 |
+
$(not-equality-assert-i) "" : $(empty-strings) ;
|
| 296 |
+
$(equality-assert) "" "" : $(empty-strings) ;
|
| 297 |
+
$(equality-assert) $(empty) : $(empty) ;
|
| 298 |
+
$(equality-assert) $(empty-strings) : $(empty-strings) ;
|
| 299 |
+
$(not-equality-assert-i) $(empty) : $(empty-strings) ;
|
| 300 |
+
$(equality-assert) $(x-empty-strings) : $(x-empty-strings) ;
|
| 301 |
+
$(equality-assert) $(empty-strings-x) : $(empty-strings-x) ;
|
| 302 |
+
$(not-equality-assert) $(empty-strings-x) : $(x-empty-strings) ;
|
| 303 |
+
$(not-equality-assert-i) x : $(x-empty-strings) ;
|
| 304 |
+
$(not-equality-assert) x : $(empty-strings-x) ;
|
| 305 |
+
$(not-equality-assert-i) x : $(x-empty-strings) ;
|
| 306 |
+
$(not-equality-assert-i) x "" : $(x-empty-strings) ;
|
| 307 |
+
$(equality-assert) x "" "" : $(x-empty-strings) ;
|
| 308 |
+
$(not-equality-assert) x : $(empty-strings-x) ;
|
| 309 |
+
$(not-equality-assert) "" x : $(empty-strings-x) ;
|
| 310 |
+
$(equality-assert) "" "" x : $(empty-strings-x) ;
|
| 311 |
+
}
|
| 312 |
+
|
| 313 |
+
|
| 314 |
+
# ---------------
|
| 315 |
+
# Equality tests.
|
| 316 |
+
# ---------------
|
| 317 |
+
|
| 318 |
+
run-equality-test equal : ignore-trailing-empty-strings ;
|
| 319 |
+
run-equality-test exact-equal ;
|
| 320 |
+
|
| 321 |
+
|
| 322 |
+
# -------------------------
|
| 323 |
+
# assert.set-equal() tests.
|
| 324 |
+
# -------------------------
|
| 325 |
+
|
| 326 |
+
set-equal : ;
|
| 327 |
+
not-set-equal "" "" : ;
|
| 328 |
+
set-equal "" "" : "" ;
|
| 329 |
+
set-equal "" "" : "" "" ;
|
| 330 |
+
set-equal a b c : a b c ;
|
| 331 |
+
set-equal a b c : b c a ;
|
| 332 |
+
set-equal a b c a : a b c ;
|
| 333 |
+
set-equal a b c : a b c a ;
|
| 334 |
+
not-set-equal a b c : a b c d ;
|
| 335 |
+
not-set-equal a b c d : a b c ;
|
| 336 |
+
}
|
mosesdecoder/jam-files/boost-build/util/doc.jam
ADDED
|
@@ -0,0 +1,997 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright 2002, 2005 Dave Abrahams
|
| 2 |
+
# Copyright 2002, 2003, 2006 Rene Rivera
|
| 3 |
+
# Copyright 2003 Vladimir Prus
|
| 4 |
+
# Distributed under the Boost Software License, Version 1.0.
|
| 5 |
+
# (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
|
| 6 |
+
|
| 7 |
+
# Documentation system, handles --help requests.
|
| 8 |
+
# It defines rules that attach documentation to modules, rules, and variables.
|
| 9 |
+
# Collects and generates documentation for the various parts of the build
|
| 10 |
+
# system. The documentation is collected from comments integrated into the code.
|
| 11 |
+
|
| 12 |
+
import modules ;
|
| 13 |
+
import print ;
|
| 14 |
+
import set ;
|
| 15 |
+
import container ;
|
| 16 |
+
import "class" ;
|
| 17 |
+
import sequence ;
|
| 18 |
+
import path ;
|
| 19 |
+
|
| 20 |
+
|
| 21 |
+
# The type of output to generate.
|
| 22 |
+
# "console" is formated text echoed to the console (the default);
|
| 23 |
+
# "text" is formated text appended to the output file;
|
| 24 |
+
# "html" is HTML output to the file.
|
| 25 |
+
#
|
| 26 |
+
help-output = console ;
|
| 27 |
+
|
| 28 |
+
|
| 29 |
+
# The file to output documentation to when generating "text" or "html" help.
|
| 30 |
+
# This is without extension as the extension is determined by the type of
|
| 31 |
+
# output.
|
| 32 |
+
#
|
| 33 |
+
help-output-file = help ;
|
| 34 |
+
|
| 35 |
+
# Whether to include local rules in help output.
|
| 36 |
+
#
|
| 37 |
+
.option.show-locals ?= ;
|
| 38 |
+
|
| 39 |
+
# When showing documentation for a module, whether to also generate
|
| 40 |
+
# automatically the detailed docs for each item in the module.
|
| 41 |
+
#
|
| 42 |
+
.option.detailed ?= ;
|
| 43 |
+
|
| 44 |
+
# Generate debug output as the help is generated and modules are parsed.
|
| 45 |
+
#
|
| 46 |
+
.option.debug ?= ;
|
| 47 |
+
|
| 48 |
+
# Enable or disable a documentation option.
|
| 49 |
+
#
|
| 50 |
+
local rule set-option (
|
| 51 |
+
option # The option name.
|
| 52 |
+
: value ? # Enabled (non-empty), or disabled (empty)
|
| 53 |
+
)
|
| 54 |
+
{
|
| 55 |
+
.option.$(option) = $(value) ;
|
| 56 |
+
}
|
| 57 |
+
|
| 58 |
+
|
| 59 |
+
# Set the type of output.
|
| 60 |
+
#
|
| 61 |
+
local rule set-output ( type )
|
| 62 |
+
{
|
| 63 |
+
help-output = $(type) ;
|
| 64 |
+
}
|
| 65 |
+
|
| 66 |
+
|
| 67 |
+
# Set the output to a file.
|
| 68 |
+
#
|
| 69 |
+
local rule set-output-file ( file )
|
| 70 |
+
{
|
| 71 |
+
help-output-file = $(file) ;
|
| 72 |
+
}
|
| 73 |
+
|
| 74 |
+
|
| 75 |
+
# Extracts the brief comment from a complete comment. The brief comment is the
|
| 76 |
+
# first sentence.
|
| 77 |
+
#
|
| 78 |
+
local rule brief-comment (
|
| 79 |
+
docs * # The comment documentation.
|
| 80 |
+
)
|
| 81 |
+
{
|
| 82 |
+
local d = $(docs:J=" ") ;
|
| 83 |
+
local p = [ MATCH ".*([.])$" : $(d) ] ;
|
| 84 |
+
if ! $(p) { d = $(d)"." ; }
|
| 85 |
+
d = $(d)" " ;
|
| 86 |
+
local m = [ MATCH "^([^.]+[.])(.*)" : $(d) ] ;
|
| 87 |
+
local brief = $(m[1]) ;
|
| 88 |
+
while $(m[2]) && [ MATCH "^([^ ])" : $(m[2]) ]
|
| 89 |
+
{
|
| 90 |
+
m = [ MATCH "^([^.]+[.])(.*)" : $(m[2]) ] ;
|
| 91 |
+
brief += $(m[1]) ;
|
| 92 |
+
}
|
| 93 |
+
return $(brief:J="") ;
|
| 94 |
+
}
|
| 95 |
+
|
| 96 |
+
|
| 97 |
+
# Specifies the documentation for the current module.
|
| 98 |
+
#
|
| 99 |
+
local rule set-module-doc (
|
| 100 |
+
module-name ? # The name of the module to document.
|
| 101 |
+
: docs * # The documentation for the module.
|
| 102 |
+
)
|
| 103 |
+
{
|
| 104 |
+
module-name ?= * ;
|
| 105 |
+
|
| 106 |
+
$(module-name).brief = [ brief-comment $(docs) ] ;
|
| 107 |
+
$(module-name).docs = $(docs) ;
|
| 108 |
+
|
| 109 |
+
if ! $(module-name) in $(documented-modules)
|
| 110 |
+
{
|
| 111 |
+
documented-modules += $(module-name) ;
|
| 112 |
+
}
|
| 113 |
+
}
|
| 114 |
+
|
| 115 |
+
|
| 116 |
+
# Specifies the documentation for the current module.
|
| 117 |
+
#
|
| 118 |
+
local rule set-module-copyright (
|
| 119 |
+
module-name ? # The name of the module to document.
|
| 120 |
+
: copyright * # The copyright for the module.
|
| 121 |
+
)
|
| 122 |
+
{
|
| 123 |
+
module-name ?= * ;
|
| 124 |
+
|
| 125 |
+
$(module-name).copy-brief = [ brief-comment $(copyright) ] ;
|
| 126 |
+
$(module-name).copy-docs = $(docs) ;
|
| 127 |
+
|
| 128 |
+
if ! $(module-name) in $(documented-modules)
|
| 129 |
+
{
|
| 130 |
+
documented-modules += $(module-name) ;
|
| 131 |
+
}
|
| 132 |
+
}
|
| 133 |
+
|
| 134 |
+
|
| 135 |
+
# Specifies the documentation for a rule in the current module. If called in the
|
| 136 |
+
# global module, this documents a global rule.
|
| 137 |
+
#
|
| 138 |
+
local rule set-rule-doc (
|
| 139 |
+
name # The name of the rule.
|
| 140 |
+
module-name ? # The name of the module to document.
|
| 141 |
+
is-local ? # Whether the rule is local to the module.
|
| 142 |
+
: docs * # The documentation for the rule.
|
| 143 |
+
)
|
| 144 |
+
{
|
| 145 |
+
module-name ?= * ;
|
| 146 |
+
|
| 147 |
+
$(module-name).$(name).brief = [ brief-comment $(docs) ] ;
|
| 148 |
+
$(module-name).$(name).docs = $(docs) ;
|
| 149 |
+
$(module-name).$(name).is-local = $(is-local) ;
|
| 150 |
+
|
| 151 |
+
if ! $(name) in $($(module-name).rules)
|
| 152 |
+
{
|
| 153 |
+
$(module-name).rules += $(name) ;
|
| 154 |
+
}
|
| 155 |
+
}
|
| 156 |
+
|
| 157 |
+
|
| 158 |
+
# Specify a class, will turn a rule into a class.
|
| 159 |
+
#
|
| 160 |
+
local rule set-class-doc (
|
| 161 |
+
name # The name of the class.
|
| 162 |
+
module-name ? # The name of the module to document.
|
| 163 |
+
: super-name ? # The super class name.
|
| 164 |
+
)
|
| 165 |
+
{
|
| 166 |
+
module-name ?= * ;
|
| 167 |
+
|
| 168 |
+
$(module-name).$(name).is-class = true ;
|
| 169 |
+
$(module-name).$(name).super-name = $(super-name) ;
|
| 170 |
+
$(module-name).$(name).class-rules =
|
| 171 |
+
[ MATCH "^($(name)[.].*)" : $($(module-name).rules) ] ;
|
| 172 |
+
$(module-name).$($(module-name).$(name).class-rules).is-class-rule = true ;
|
| 173 |
+
|
| 174 |
+
$(module-name).classes += $(name) ;
|
| 175 |
+
$(module-name).class-rules += $($(module-name).$(name).class-rules) ;
|
| 176 |
+
$(module-name).rules =
|
| 177 |
+
[ set.difference $($(module-name).rules) :
|
| 178 |
+
$(name) $($(module-name).$(name).class-rules) ] ;
|
| 179 |
+
}
|
| 180 |
+
|
| 181 |
+
|
| 182 |
+
# Set the argument call signature of a rule.
|
| 183 |
+
#
|
| 184 |
+
local rule set-rule-arguments-signature (
|
| 185 |
+
name # The name of the rule.
|
| 186 |
+
module-name ? # The name of the module to document.
|
| 187 |
+
: signature * # The arguments signature.
|
| 188 |
+
)
|
| 189 |
+
{
|
| 190 |
+
module-name ?= * ;
|
| 191 |
+
|
| 192 |
+
$(module-name).$(name).signature = $(signature) ;
|
| 193 |
+
}
|
| 194 |
+
|
| 195 |
+
|
| 196 |
+
# Specifies the documentation for an argument of a rule.
|
| 197 |
+
#
|
| 198 |
+
local rule set-argument-doc (
|
| 199 |
+
name # The name of the argument.
|
| 200 |
+
qualifier # Argument syntax qualifier, "*", "+", etc.
|
| 201 |
+
rule-name # The name of the rule.
|
| 202 |
+
module-name ? # THe optional name of the module.
|
| 203 |
+
: docs * # The documentation.
|
| 204 |
+
)
|
| 205 |
+
{
|
| 206 |
+
module-name ?= * ;
|
| 207 |
+
|
| 208 |
+
$(module-name).$(rule-name).args.$(name).qualifier = $(qualifier) ;
|
| 209 |
+
$(module-name).$(rule-name).args.$(name).docs = $(docs) ;
|
| 210 |
+
|
| 211 |
+
if ! $(name) in $($(module-name).$(rule-name).args)
|
| 212 |
+
{
|
| 213 |
+
$(module-name).$(rule-name).args += $(name) ;
|
| 214 |
+
}
|
| 215 |
+
}
|
| 216 |
+
|
| 217 |
+
|
| 218 |
+
# Specifies the documentation for a variable in the current module. If called in
|
| 219 |
+
# the global module, the global variable is documented.
|
| 220 |
+
#
|
| 221 |
+
local rule set-variable-doc (
|
| 222 |
+
name # The name of the variable.
|
| 223 |
+
default # The default value.
|
| 224 |
+
initial # The initial value.
|
| 225 |
+
module-name ? # The name of the module to document.
|
| 226 |
+
: docs * # The documentation for the variable.
|
| 227 |
+
)
|
| 228 |
+
{
|
| 229 |
+
module-name ?= * ;
|
| 230 |
+
|
| 231 |
+
$(module-name).$(name).brief = [ brief-comment $(docs) ] ;
|
| 232 |
+
$(module-name).$(name).default = $(default) ;
|
| 233 |
+
$(module-name).$(name).initial = $(initial) ;
|
| 234 |
+
$(module-name).$(name).docs = $(docs) ;
|
| 235 |
+
|
| 236 |
+
if ! $(name) in $($(module-name).variables)
|
| 237 |
+
{
|
| 238 |
+
$(module-name).variables += $(name) ;
|
| 239 |
+
}
|
| 240 |
+
}
|
| 241 |
+
|
| 242 |
+
|
| 243 |
+
# Generates a general description of the documentation and help system.
|
| 244 |
+
#
|
| 245 |
+
local rule print-help-top ( )
|
| 246 |
+
{
|
| 247 |
+
print.section "General command line usage" ;
|
| 248 |
+
|
| 249 |
+
print.text " bjam [options] [properties] [targets]
|
| 250 |
+
|
| 251 |
+
Options, properties and targets can be specified in any order.
|
| 252 |
+
" ;
|
| 253 |
+
|
| 254 |
+
print.section "Important Options" ;
|
| 255 |
+
|
| 256 |
+
print.list-start ;
|
| 257 |
+
print.list-item "--clean Remove targets instead of building" ;
|
| 258 |
+
print.list-item "-a Rebuild everything" ;
|
| 259 |
+
print.list-item "-n Don't execute the commands, only print them" ;
|
| 260 |
+
print.list-item "-d+2 Show commands as they are executed" ;
|
| 261 |
+
print.list-item "-d0 Supress all informational messages" ;
|
| 262 |
+
print.list-item "-q Stop at first error" ;
|
| 263 |
+
print.list-item "--debug-configuration Diagnose configuration" ;
|
| 264 |
+
print.list-item "--debug-building Report which targets are built with what properties" ;
|
| 265 |
+
print.list-item "--debug-generator Diagnose generator search/execution" ;
|
| 266 |
+
print.list-end ;
|
| 267 |
+
|
| 268 |
+
print.section "Further Help"
|
| 269 |
+
The following options can be used to obtain additional documentation.
|
| 270 |
+
;
|
| 271 |
+
|
| 272 |
+
print.list-start ;
|
| 273 |
+
print.list-item "--help-options Print more obscure command line options." ;
|
| 274 |
+
print.list-item "--help-internal Boost.Build implementation details." ;
|
| 275 |
+
print.list-item "--help-doc-options Implementation details doc formatting." ;
|
| 276 |
+
print.list-end ;
|
| 277 |
+
}
|
| 278 |
+
|
| 279 |
+
|
| 280 |
+
# Generate Jam/Boost.Jam command usage information.
|
| 281 |
+
#
|
| 282 |
+
local rule print-help-usage ( )
|
| 283 |
+
{
|
| 284 |
+
print.section "Boost.Jam Usage"
|
| 285 |
+
"bjam [ options... ] targets..."
|
| 286 |
+
;
|
| 287 |
+
print.list-start ;
|
| 288 |
+
print.list-item -a;
|
| 289 |
+
Build all targets, even if they are current. ;
|
| 290 |
+
print.list-item -fx;
|
| 291 |
+
Read '"x"' as the Jamfile for building instead of searching for the
|
| 292 |
+
Boost.Build system. ;
|
| 293 |
+
print.list-item -jx;
|
| 294 |
+
Run up to '"x"' commands concurrently. ;
|
| 295 |
+
print.list-item -n;
|
| 296 |
+
Do not execute build commands. Instead print out the commands as they
|
| 297 |
+
would be executed if building. ;
|
| 298 |
+
print.list-item -ox;
|
| 299 |
+
Output the used build commands to file '"x"'. ;
|
| 300 |
+
print.list-item -q;
|
| 301 |
+
Quit as soon as a build failure is encountered. Without this option
|
| 302 |
+
Boost.Jam will continue building as many targets as it can.
|
| 303 |
+
print.list-item -sx=y;
|
| 304 |
+
Sets a Jam variable '"x"' to the value '"y"', overriding any value that
|
| 305 |
+
variable would have from the environment. ;
|
| 306 |
+
print.list-item -tx;
|
| 307 |
+
Rebuild the target '"x"', even if it is up-to-date. ;
|
| 308 |
+
print.list-item -v;
|
| 309 |
+
Display the version of bjam. ;
|
| 310 |
+
print.list-item --x;
|
| 311 |
+
Any option not explicitly handled by Boost.Jam remains available to
|
| 312 |
+
build scripts using the '"ARGV"' variable. ;
|
| 313 |
+
print.list-item -dn;
|
| 314 |
+
Enables output of diagnostic messages. The debug level '"n"' and all
|
| 315 |
+
below it are enabled by this option. ;
|
| 316 |
+
print.list-item -d+n;
|
| 317 |
+
Enables output of diagnostic messages. Only the output for debug level
|
| 318 |
+
'"n"' is enabled. ;
|
| 319 |
+
print.list-end ;
|
| 320 |
+
print.section "Debug Levels"
|
| 321 |
+
Each debug level shows a different set of information. Usually with
|
| 322 |
+
higher levels producing more verbose information. The following levels
|
| 323 |
+
are supported: ;
|
| 324 |
+
print.list-start ;
|
| 325 |
+
print.list-item 0;
|
| 326 |
+
Turn off all diagnostic output. Only errors are reported. ;
|
| 327 |
+
print.list-item 1;
|
| 328 |
+
Show the actions taken for building targets, as they are executed. ;
|
| 329 |
+
print.list-item 2;
|
| 330 |
+
Show "quiet" actions and display all action text, as they are executed. ;
|
| 331 |
+
print.list-item 3;
|
| 332 |
+
Show dependency analysis, and target/source timestamps/paths. ;
|
| 333 |
+
print.list-item 4;
|
| 334 |
+
Show arguments of shell invocations. ;
|
| 335 |
+
print.list-item 5;
|
| 336 |
+
Show rule invocations and variable expansions. ;
|
| 337 |
+
print.list-item 6;
|
| 338 |
+
Show directory/header file/archive scans, and attempts at binding to targets. ;
|
| 339 |
+
print.list-item 7;
|
| 340 |
+
Show variable settings. ;
|
| 341 |
+
print.list-item 8;
|
| 342 |
+
Show variable fetches, variable expansions, and evaluation of '"if"' expressions. ;
|
| 343 |
+
print.list-item 9;
|
| 344 |
+
Show variable manipulation, scanner tokens, and memory usage. ;
|
| 345 |
+
print.list-item 10;
|
| 346 |
+
Show execution times for rules. ;
|
| 347 |
+
print.list-item 11;
|
| 348 |
+
Show parsing progress of Jamfiles. ;
|
| 349 |
+
print.list-item 12;
|
| 350 |
+
Show graph for target dependencies. ;
|
| 351 |
+
print.list-item 13;
|
| 352 |
+
Show changes in target status (fate). ;
|
| 353 |
+
print.list-end ;
|
| 354 |
+
}
|
| 355 |
+
|
| 356 |
+
|
| 357 |
+
# Generates description of options controlling the help system. This
|
| 358 |
+
# automatically reads the options as all variables in the doc module of the form
|
| 359 |
+
# ".option.*".
|
| 360 |
+
#
|
| 361 |
+
local rule print-help-options (
|
| 362 |
+
module-name # The doc module.
|
| 363 |
+
)
|
| 364 |
+
{
|
| 365 |
+
print.section "Help Options"
|
| 366 |
+
These are all the options available for enabling or disabling to control
|
| 367 |
+
the help system in various ways. Options can be enabled or disabled with
|
| 368 |
+
'"--help-enable-<option>"', and "'--help-disable-<option>'"
|
| 369 |
+
respectively.
|
| 370 |
+
;
|
| 371 |
+
local options-to-list = [ MATCH ^[.]option[.](.*) : $($(module-name).variables) ] ;
|
| 372 |
+
if $(options-to-list)
|
| 373 |
+
{
|
| 374 |
+
print.list-start ;
|
| 375 |
+
for local option in [ sequence.insertion-sort $(options-to-list) ]
|
| 376 |
+
{
|
| 377 |
+
local def = disabled ;
|
| 378 |
+
if $($(module-name)..option.$(option).default) != "(empty)"
|
| 379 |
+
{
|
| 380 |
+
def = enabled ;
|
| 381 |
+
}
|
| 382 |
+
print.list-item $(option): $($(module-name)..option.$(option).docs)
|
| 383 |
+
Default is $(def). ;
|
| 384 |
+
}
|
| 385 |
+
print.list-end ;
|
| 386 |
+
}
|
| 387 |
+
}
|
| 388 |
+
|
| 389 |
+
|
| 390 |
+
# Generate brief documentation for all the known items in the section for a
|
| 391 |
+
# module. Possible sections are: "rules", and "variables".
|
| 392 |
+
#
|
| 393 |
+
local rule print-help-module-section (
|
| 394 |
+
module # The module name.
|
| 395 |
+
section # rules or variables.
|
| 396 |
+
: section-head # The title of the section.
|
| 397 |
+
section-description * # The detailed description of the section.
|
| 398 |
+
)
|
| 399 |
+
{
|
| 400 |
+
if $($(module).$(section))
|
| 401 |
+
{
|
| 402 |
+
print.section $(section-head) $(section-description) ;
|
| 403 |
+
print.list-start ;
|
| 404 |
+
for local item in [ sequence.insertion-sort $($(module).$(section)) ]
|
| 405 |
+
{
|
| 406 |
+
local show = ;
|
| 407 |
+
if ! $($(module).$(item).is-local)
|
| 408 |
+
{
|
| 409 |
+
show = yes ;
|
| 410 |
+
}
|
| 411 |
+
if $(.option.show-locals)
|
| 412 |
+
{
|
| 413 |
+
show = yes ;
|
| 414 |
+
}
|
| 415 |
+
if $(show)
|
| 416 |
+
{
|
| 417 |
+
print.list-item $(item): $($(module).$(item).brief) ;
|
| 418 |
+
}
|
| 419 |
+
}
|
| 420 |
+
print.list-end ;
|
| 421 |
+
}
|
| 422 |
+
}
|
| 423 |
+
|
| 424 |
+
|
| 425 |
+
# Generate documentation for all possible modules. We attempt to list all known
|
| 426 |
+
# modules together with a brief description of each.
|
| 427 |
+
#
|
| 428 |
+
local rule print-help-all (
|
| 429 |
+
ignored # Usually the module name, but is ignored here.
|
| 430 |
+
)
|
| 431 |
+
{
|
| 432 |
+
print.section "Modules"
|
| 433 |
+
"These are all the known modules. Use --help <module> to get more"
|
| 434 |
+
"detailed information."
|
| 435 |
+
;
|
| 436 |
+
if $(documented-modules)
|
| 437 |
+
{
|
| 438 |
+
print.list-start ;
|
| 439 |
+
for local module-name in [ sequence.insertion-sort $(documented-modules) ]
|
| 440 |
+
{
|
| 441 |
+
# The brief docs for each module.
|
| 442 |
+
print.list-item $(module-name): $($(module-name).brief) ;
|
| 443 |
+
}
|
| 444 |
+
print.list-end ;
|
| 445 |
+
}
|
| 446 |
+
# The documentation for each module when details are requested.
|
| 447 |
+
if $(documented-modules) && $(.option.detailed)
|
| 448 |
+
{
|
| 449 |
+
for local module-name in [ sequence.insertion-sort $(documented-modules) ]
|
| 450 |
+
{
|
| 451 |
+
# The brief docs for each module.
|
| 452 |
+
print-help-module $(module-name) ;
|
| 453 |
+
}
|
| 454 |
+
}
|
| 455 |
+
}
|
| 456 |
+
|
| 457 |
+
|
| 458 |
+
# Generate documentation for a module. Basic information about the module is
|
| 459 |
+
# generated.
|
| 460 |
+
#
|
| 461 |
+
local rule print-help-module (
|
| 462 |
+
module-name # The module to generate docs for.
|
| 463 |
+
)
|
| 464 |
+
{
|
| 465 |
+
# Print the docs.
|
| 466 |
+
print.section "Module '$(module-name)'" $($(module-name).docs) ;
|
| 467 |
+
|
| 468 |
+
# Print out the documented classes.
|
| 469 |
+
print-help-module-section $(module-name) classes : "Module '$(module-name)' classes"
|
| 470 |
+
Use --help $(module-name).<class-name> to get more information. ;
|
| 471 |
+
|
| 472 |
+
# Print out the documented rules.
|
| 473 |
+
print-help-module-section $(module-name) rules : "Module '$(module-name)' rules"
|
| 474 |
+
Use --help $(module-name).<rule-name> to get more information. ;
|
| 475 |
+
|
| 476 |
+
# Print out the documented variables.
|
| 477 |
+
print-help-module-section $(module-name) variables : "Module '$(module-name)' variables"
|
| 478 |
+
Use --help $(module-name).<variable-name> to get more information. ;
|
| 479 |
+
|
| 480 |
+
# Print out all the same information but indetailed form.
|
| 481 |
+
if $(.option.detailed)
|
| 482 |
+
{
|
| 483 |
+
print-help-classes $(module-name) ;
|
| 484 |
+
print-help-rules $(module-name) ;
|
| 485 |
+
print-help-variables $(module-name) ;
|
| 486 |
+
}
|
| 487 |
+
}
|
| 488 |
+
|
| 489 |
+
|
| 490 |
+
# Generate documentation for a set of rules in a module.
|
| 491 |
+
#
|
| 492 |
+
local rule print-help-rules (
|
| 493 |
+
module-name # Module of the rules.
|
| 494 |
+
: name * # Optional list of rules to describe.
|
| 495 |
+
)
|
| 496 |
+
{
|
| 497 |
+
name ?= $($(module-name).rules) ;
|
| 498 |
+
if [ set.intersection $(name) : $($(module-name).rules) $($(module-name).class-rules) ]
|
| 499 |
+
{
|
| 500 |
+
# Print out the given rules.
|
| 501 |
+
for local rule-name in [ sequence.insertion-sort $(name) ]
|
| 502 |
+
{
|
| 503 |
+
if $(.option.show-locals) || ! $($(module-name).$(rule-name).is-local)
|
| 504 |
+
{
|
| 505 |
+
local signature = $($(module-name).$(rule-name).signature:J=" ") ;
|
| 506 |
+
signature ?= "" ;
|
| 507 |
+
print.section "Rule '$(module-name).$(rule-name) ( $(signature) )'"
|
| 508 |
+
$($(module-name).$(rule-name).docs) ;
|
| 509 |
+
if $($(module-name).$(rule-name).args)
|
| 510 |
+
{
|
| 511 |
+
print.list-start ;
|
| 512 |
+
for local arg-name in $($(module-name).$(rule-name).args)
|
| 513 |
+
{
|
| 514 |
+
print.list-item $(arg-name): $($(module-name).$(rule-name).args.$(arg-name).docs) ;
|
| 515 |
+
}
|
| 516 |
+
print.list-end ;
|
| 517 |
+
}
|
| 518 |
+
}
|
| 519 |
+
}
|
| 520 |
+
}
|
| 521 |
+
}
|
| 522 |
+
|
| 523 |
+
|
| 524 |
+
# Generate documentation for a set of classes in a module.
|
| 525 |
+
#
|
| 526 |
+
local rule print-help-classes (
|
| 527 |
+
module-name # Module of the classes.
|
| 528 |
+
: name * # Optional list of classes to describe.
|
| 529 |
+
)
|
| 530 |
+
{
|
| 531 |
+
name ?= $($(module-name).classes) ;
|
| 532 |
+
if [ set.intersection $(name) : $($(module-name).classes) ]
|
| 533 |
+
{
|
| 534 |
+
# Print out the given classes.
|
| 535 |
+
for local class-name in [ sequence.insertion-sort $(name) ]
|
| 536 |
+
{
|
| 537 |
+
if $(.option.show-locals) || ! $($(module-name).$(class-name).is-local)
|
| 538 |
+
{
|
| 539 |
+
local signature = $($(module-name).$(class-name).signature:J=" ") ;
|
| 540 |
+
signature ?= "" ;
|
| 541 |
+
print.section "Class '$(module-name).$(class-name) ( $(signature) )'"
|
| 542 |
+
$($(module-name).$(class-name).docs)
|
| 543 |
+
"Inherits from '"$($(module-name).$(class-name).super-name)"'." ;
|
| 544 |
+
if $($(module-name).$(class-name).args)
|
| 545 |
+
{
|
| 546 |
+
print.list-start ;
|
| 547 |
+
for local arg-name in $($(module-name).$(class-name).args)
|
| 548 |
+
{
|
| 549 |
+
print.list-item $(arg-name): $($(module-name).$(class-name).args.$(arg-name).docs) ;
|
| 550 |
+
}
|
| 551 |
+
print.list-end ;
|
| 552 |
+
}
|
| 553 |
+
}
|
| 554 |
+
|
| 555 |
+
# Print out the documented rules of the class.
|
| 556 |
+
print-help-module-section $(module-name) $(class-name).class-rules : "Class '$(module-name).$(class-name)' rules"
|
| 557 |
+
Use --help $(module-name).<rule-name> to get more information. ;
|
| 558 |
+
|
| 559 |
+
# Print out all the rules if details are requested.
|
| 560 |
+
if $(.option.detailed)
|
| 561 |
+
{
|
| 562 |
+
print-help-rules $(module-name) : $($(module-name).$(class-name).class-rules) ;
|
| 563 |
+
}
|
| 564 |
+
}
|
| 565 |
+
}
|
| 566 |
+
}
|
| 567 |
+
|
| 568 |
+
|
| 569 |
+
# Generate documentation for a set of variables in a module.
|
| 570 |
+
#
|
| 571 |
+
local rule print-help-variables (
|
| 572 |
+
module-name ? # Module of the variables.
|
| 573 |
+
: name * # Optional list of variables to describe.
|
| 574 |
+
)
|
| 575 |
+
{
|
| 576 |
+
name ?= $($(module-name).variables) ;
|
| 577 |
+
if [ set.intersection $(name) : $($(module-name).variables) ]
|
| 578 |
+
{
|
| 579 |
+
# Print out the given variables.
|
| 580 |
+
for local variable-name in [ sequence.insertion-sort $(name) ]
|
| 581 |
+
{
|
| 582 |
+
print.section "Variable '$(module-name).$(variable-name)'" $($(module-name).$(variable-name).docs) ;
|
| 583 |
+
if $($(module-name).$(variable-name).default) ||
|
| 584 |
+
$($(module-name).$(variable-name).initial)
|
| 585 |
+
{
|
| 586 |
+
print.list-start ;
|
| 587 |
+
if $($(module-name).$(variable-name).default)
|
| 588 |
+
{
|
| 589 |
+
print.list-item "default value:" '$($(module-name).$(variable-name).default:J=" ")' ;
|
| 590 |
+
}
|
| 591 |
+
if $($(module-name).$(variable-name).initial)
|
| 592 |
+
{
|
| 593 |
+
print.list-item "initial value:" '$($(module-name).$(variable-name).initial:J=" ")' ;
|
| 594 |
+
}
|
| 595 |
+
print.list-end ;
|
| 596 |
+
}
|
| 597 |
+
}
|
| 598 |
+
}
|
| 599 |
+
}
|
| 600 |
+
|
| 601 |
+
|
| 602 |
+
# Generate documentation for a project.
|
| 603 |
+
#
|
| 604 |
+
local rule print-help-project (
|
| 605 |
+
unused ?
|
| 606 |
+
: jamfile * # The project Jamfile.
|
| 607 |
+
)
|
| 608 |
+
{
|
| 609 |
+
if $(jamfile<$(jamfile)>.docs)
|
| 610 |
+
{
|
| 611 |
+
# Print the docs.
|
| 612 |
+
print.section "Project-specific help"
|
| 613 |
+
Project has jamfile at $(jamfile) ;
|
| 614 |
+
|
| 615 |
+
print.lines $(jamfile<$(jamfile)>.docs) "" ;
|
| 616 |
+
}
|
| 617 |
+
}
|
| 618 |
+
|
| 619 |
+
|
| 620 |
+
# Generate documentation for a config file.
|
| 621 |
+
#
|
| 622 |
+
local rule print-help-config (
|
| 623 |
+
unused ?
|
| 624 |
+
: type # The type of configuration file user or site.
|
| 625 |
+
config-file # The configuration Jamfile.
|
| 626 |
+
)
|
| 627 |
+
{
|
| 628 |
+
if $(jamfile<$(config-file)>.docs)
|
| 629 |
+
{
|
| 630 |
+
# Print the docs.
|
| 631 |
+
print.section "Configuration help"
|
| 632 |
+
Configuration file at $(config-file) ;
|
| 633 |
+
|
| 634 |
+
print.lines $(jamfile<$(config-file)>.docs) "" ;
|
| 635 |
+
}
|
| 636 |
+
}
|
| 637 |
+
|
| 638 |
+
|
| 639 |
+
ws = " " ;
|
| 640 |
+
|
| 641 |
+
# Extract the text from a block of comments.
|
| 642 |
+
#
|
| 643 |
+
local rule extract-comment (
|
| 644 |
+
var # The name of the variable to extract from.
|
| 645 |
+
)
|
| 646 |
+
{
|
| 647 |
+
local comment = ;
|
| 648 |
+
local line = $($(var)[1]) ;
|
| 649 |
+
local l = [ MATCH "^[$(ws)]*(#)(.*)$" : $(line) ] ;
|
| 650 |
+
while $(l[1]) && $($(var))
|
| 651 |
+
{
|
| 652 |
+
if $(l[2]) { comment += [ MATCH "^[$(ws)]?(.*)$" : $(l[2]) ] ; }
|
| 653 |
+
else { comment += "" ; }
|
| 654 |
+
$(var) = $($(var)[2-]) ;
|
| 655 |
+
line = $($(var)[1]) ;
|
| 656 |
+
l = [ MATCH "^[$(ws)]*(#)(.*)$" : $(line) ] ;
|
| 657 |
+
}
|
| 658 |
+
return $(comment) ;
|
| 659 |
+
}
|
| 660 |
+
|
| 661 |
+
|
| 662 |
+
# Extract s single line of Jam syntax, ignoring any comments.
|
| 663 |
+
#
|
| 664 |
+
local rule extract-syntax (
|
| 665 |
+
var # The name of the variable to extract from.
|
| 666 |
+
)
|
| 667 |
+
{
|
| 668 |
+
local syntax = ;
|
| 669 |
+
local line = $($(var)[1]) ;
|
| 670 |
+
while ! $(syntax) && ! [ MATCH "^[$(ws)]*(#)" : $(line) ] && $($(var))
|
| 671 |
+
{
|
| 672 |
+
local m = [ MATCH "^[$(ws)]*(.*)$" : $(line) ] ;
|
| 673 |
+
if $(m)
|
| 674 |
+
{
|
| 675 |
+
syntax = $(m) ;
|
| 676 |
+
}
|
| 677 |
+
$(var) = $($(var)[2-]) ;
|
| 678 |
+
line = $($(var)[1]) ;
|
| 679 |
+
}
|
| 680 |
+
return $(syntax) ;
|
| 681 |
+
}
|
| 682 |
+
|
| 683 |
+
|
| 684 |
+
# Extract the next token, this is either a single Jam construct or a comment as
|
| 685 |
+
# a single token.
|
| 686 |
+
#
|
| 687 |
+
local rule extract-token (
|
| 688 |
+
var # The name of the variable to extract from.
|
| 689 |
+
)
|
| 690 |
+
{
|
| 691 |
+
local parts = ;
|
| 692 |
+
while ! $(parts)
|
| 693 |
+
{
|
| 694 |
+
parts = [ MATCH "^[$(ws)]*([^$(ws)]+)[$(ws)]*(.*)" : $($(var)[1]) ] ;
|
| 695 |
+
if ! $(parts)
|
| 696 |
+
{
|
| 697 |
+
$(var) = $($(var)[2-]) ;
|
| 698 |
+
}
|
| 699 |
+
}
|
| 700 |
+
local token = ;
|
| 701 |
+
if [ MATCH "^(#)" : $(parts[1]) ]
|
| 702 |
+
{
|
| 703 |
+
token = $(parts:J=" ") ;
|
| 704 |
+
$(var) = $($(var)[2-]) ;
|
| 705 |
+
}
|
| 706 |
+
else
|
| 707 |
+
{
|
| 708 |
+
token = $(parts[1]) ;
|
| 709 |
+
$(var) = $(parts[2-]:J=" ") $($(var)[2-]) ;
|
| 710 |
+
}
|
| 711 |
+
return $(token) ;
|
| 712 |
+
}
|
| 713 |
+
|
| 714 |
+
|
| 715 |
+
# Scan for a rule declaration as the next item in the variable.
|
| 716 |
+
#
|
| 717 |
+
local rule scan-rule (
|
| 718 |
+
syntax ? # The first part of the text which contains the rule declaration.
|
| 719 |
+
: var # The name of the variable to extract from.
|
| 720 |
+
)
|
| 721 |
+
{
|
| 722 |
+
local rule-parts =
|
| 723 |
+
[ MATCH "^[$(ws)]*(rule|local[$(ws)]*rule)[$(ws)]+([^$(ws)]+)[$(ws)]*(.*)" : $(syntax:J=" ") ] ;
|
| 724 |
+
if $(rule-parts[1])
|
| 725 |
+
{
|
| 726 |
+
# Mark as doc for rule.
|
| 727 |
+
local rule-name = $(rule-parts[2]) ;
|
| 728 |
+
if $(scope-name)
|
| 729 |
+
{
|
| 730 |
+
rule-name = $(scope-name).$(rule-name) ;
|
| 731 |
+
}
|
| 732 |
+
local is-local = [ MATCH "^(local).*" : $(rule-parts[1]) ] ;
|
| 733 |
+
if $(comment-block)
|
| 734 |
+
{
|
| 735 |
+
set-rule-doc $(rule-name) $(module-name) $(is-local) : $(comment-block) ;
|
| 736 |
+
}
|
| 737 |
+
# Parse args of rule.
|
| 738 |
+
$(var) = $(rule-parts[3-]) $($(var)) ;
|
| 739 |
+
set-rule-arguments-signature $(rule-name) $(module-name) : [ scan-rule-arguments $(var) ] ;
|
| 740 |
+
# Scan within this rules scope.
|
| 741 |
+
local scope-level = [ extract-token $(var) ] ;
|
| 742 |
+
local scope-name = $(rule-name) ;
|
| 743 |
+
while $(scope-level)
|
| 744 |
+
{
|
| 745 |
+
local comment-block = [ extract-comment $(var) ] ;
|
| 746 |
+
local syntax-block = [ extract-syntax $(var) ] ;
|
| 747 |
+
if [ scan-rule $(syntax-block) : $(var) ]
|
| 748 |
+
{
|
| 749 |
+
}
|
| 750 |
+
else if [ MATCH "^(\\{)" : $(syntax-block) ]
|
| 751 |
+
{
|
| 752 |
+
scope-level += "{" ;
|
| 753 |
+
}
|
| 754 |
+
else if [ MATCH "^[^\\}]*([\\}])[$(ws)]*$" : $(syntax-block) ]
|
| 755 |
+
{
|
| 756 |
+
scope-level = $(scope-level[2-]) ;
|
| 757 |
+
}
|
| 758 |
+
}
|
| 759 |
+
|
| 760 |
+
return true ;
|
| 761 |
+
}
|
| 762 |
+
}
|
| 763 |
+
|
| 764 |
+
|
| 765 |
+
# Scan the arguments of a rule.
|
| 766 |
+
#
|
| 767 |
+
local rule scan-rule-arguments (
|
| 768 |
+
var # The name of the variable to extract from.
|
| 769 |
+
)
|
| 770 |
+
{
|
| 771 |
+
local arg-syntax = ;
|
| 772 |
+
local token = [ extract-token $(var) ] ;
|
| 773 |
+
while $(token) != "(" && $(token) != "{"
|
| 774 |
+
{
|
| 775 |
+
token = [ extract-token $(var) ] ;
|
| 776 |
+
}
|
| 777 |
+
if $(token) != "{"
|
| 778 |
+
{
|
| 779 |
+
token = [ extract-token $(var) ] ;
|
| 780 |
+
}
|
| 781 |
+
local arg-signature = ;
|
| 782 |
+
while $(token) != ")" && $(token) != "{"
|
| 783 |
+
{
|
| 784 |
+
local arg-name = ;
|
| 785 |
+
local arg-qualifier = " " ;
|
| 786 |
+
local arg-doc = ;
|
| 787 |
+
if $(token) = ":"
|
| 788 |
+
{
|
| 789 |
+
arg-signature += $(token) ;
|
| 790 |
+
token = [ extract-token $(var) ] ;
|
| 791 |
+
}
|
| 792 |
+
arg-name = $(token) ;
|
| 793 |
+
arg-signature += $(token) ;
|
| 794 |
+
token = [ extract-token $(var) ] ;
|
| 795 |
+
if [ MATCH "^([\\*\\+\\?])" : $(token) ]
|
| 796 |
+
{
|
| 797 |
+
arg-qualifier = $(token) ;
|
| 798 |
+
arg-signature += $(token) ;
|
| 799 |
+
token = [ extract-token $(var) ] ;
|
| 800 |
+
}
|
| 801 |
+
if $(token) = ":"
|
| 802 |
+
{
|
| 803 |
+
arg-signature += $(token) ;
|
| 804 |
+
token = [ extract-token $(var) ] ;
|
| 805 |
+
}
|
| 806 |
+
if [ MATCH "^(#)" : $(token) ]
|
| 807 |
+
{
|
| 808 |
+
$(var) = $(token) $($(var)) ;
|
| 809 |
+
arg-doc = [ extract-comment $(var) ] ;
|
| 810 |
+
token = [ extract-token $(var) ] ;
|
| 811 |
+
}
|
| 812 |
+
set-argument-doc $(arg-name) $(arg-qualifier) $(rule-name) $(module-name) : $(arg-doc) ;
|
| 813 |
+
}
|
| 814 |
+
while $(token) != "{"
|
| 815 |
+
{
|
| 816 |
+
token = [ extract-token $(var) ] ;
|
| 817 |
+
}
|
| 818 |
+
$(var) = "{" $($(var)) ;
|
| 819 |
+
arg-signature ?= "" ;
|
| 820 |
+
return $(arg-signature) ;
|
| 821 |
+
}
|
| 822 |
+
|
| 823 |
+
|
| 824 |
+
# Scan for a variable declaration.
|
| 825 |
+
#
|
| 826 |
+
local rule scan-variable (
|
| 827 |
+
syntax ? # The first part of the text which contains the variable declaration.
|
| 828 |
+
: var # The name of the variable to extract from.
|
| 829 |
+
)
|
| 830 |
+
{
|
| 831 |
+
# [1] = name, [2] = value(s)
|
| 832 |
+
local var-parts =
|
| 833 |
+
[ MATCH "^[$(ws)]*([^$(ws)]+)[$(ws)]+([\\?\\=]*)[$(ws)]+([^\\;]*)\\;" : $(syntax) ] ;
|
| 834 |
+
if $(var-parts)
|
| 835 |
+
{
|
| 836 |
+
local value = [ MATCH "^(.*)[ ]$" : $(var-parts[3-]:J=" ") ] ;
|
| 837 |
+
local default-value = "" ;
|
| 838 |
+
local initial-valie = "" ;
|
| 839 |
+
if $(var-parts[2]) = "?="
|
| 840 |
+
{
|
| 841 |
+
default-value = $(value) ;
|
| 842 |
+
default-value ?= "(empty)" ;
|
| 843 |
+
}
|
| 844 |
+
else
|
| 845 |
+
{
|
| 846 |
+
initial-value = $(value) ;
|
| 847 |
+
initial-value ?= "(empty)" ;
|
| 848 |
+
}
|
| 849 |
+
if $(comment-block)
|
| 850 |
+
{
|
| 851 |
+
set-variable-doc $(var-parts[1]) $(default-value) $(initial-value) $(module-name) : $(comment-block) ;
|
| 852 |
+
}
|
| 853 |
+
return true ;
|
| 854 |
+
}
|
| 855 |
+
}
|
| 856 |
+
|
| 857 |
+
|
| 858 |
+
# Scan a class declaration.
|
| 859 |
+
#
|
| 860 |
+
local rule scan-class (
|
| 861 |
+
syntax ? # The syntax text for the class declaration.
|
| 862 |
+
)
|
| 863 |
+
{
|
| 864 |
+
# [1] = class?, [2] = name, [3] = superclass
|
| 865 |
+
local class-parts =
|
| 866 |
+
[ MATCH "^[$(ws)]*([^$(ws)]+)[$(ws)]+([^$(ws)]+)[$(ws)]+:*[$(ws)]*([^$(ws);]*)" : $(syntax) ] ;
|
| 867 |
+
if $(class-parts[1]) = "class" || $(class-parts[1]) = "class.class"
|
| 868 |
+
{
|
| 869 |
+
set-class-doc $(class-parts[2]) $(module-name) : $(class-parts[3]) ;
|
| 870 |
+
}
|
| 871 |
+
}
|
| 872 |
+
|
| 873 |
+
|
| 874 |
+
# Scan a module file for documentation comments. This also invokes any actions
|
| 875 |
+
# assigned to the module. The actions are the rules that do the actual output of
|
| 876 |
+
# the documentation. This rule is invoked as the header scan rule for the module
|
| 877 |
+
# file.
|
| 878 |
+
#
|
| 879 |
+
rule scan-module (
|
| 880 |
+
target # The module file.
|
| 881 |
+
: text * # The text in the file, one item per line.
|
| 882 |
+
: action * # Rule to call to output docs for the module.
|
| 883 |
+
)
|
| 884 |
+
{
|
| 885 |
+
if $(.option.debug) { ECHO "HELP:" scanning module target '$(target)' ; }
|
| 886 |
+
local module-name = $(target:B) ;
|
| 887 |
+
local module-documented = ;
|
| 888 |
+
local comment-block = ;
|
| 889 |
+
local syntax-block = ;
|
| 890 |
+
# This is a hack because we can not get the line of a file if it happens to
|
| 891 |
+
# not have a new-line termination.
|
| 892 |
+
text += "}" ;
|
| 893 |
+
while $(text)
|
| 894 |
+
{
|
| 895 |
+
comment-block = [ extract-comment text ] ;
|
| 896 |
+
syntax-block = [ extract-syntax text ] ;
|
| 897 |
+
if $(.option.debug)
|
| 898 |
+
{
|
| 899 |
+
ECHO "HELP:" comment block; '$(comment-block)' ;
|
| 900 |
+
ECHO "HELP:" syntax block; '$(syntax-block)' ;
|
| 901 |
+
}
|
| 902 |
+
if [ scan-rule $(syntax-block) : text ] { }
|
| 903 |
+
else if [ scan-variable $(syntax-block) : text ] { }
|
| 904 |
+
else if [ scan-class $(syntax-block) ] { }
|
| 905 |
+
else if [ MATCH .*([cC]opyright).* : $(comment-block:J=" ") ]
|
| 906 |
+
{
|
| 907 |
+
# mark as the copy for the module.
|
| 908 |
+
set-module-copyright $(module-name) : $(comment-block) ;
|
| 909 |
+
}
|
| 910 |
+
else if $(action[1]) in "print-help-project" "print-help-config"
|
| 911 |
+
&& ! $(jamfile<$(target)>.docs)
|
| 912 |
+
{
|
| 913 |
+
# special module docs for the project jamfile.
|
| 914 |
+
jamfile<$(target)>.docs = $(comment-block) ;
|
| 915 |
+
}
|
| 916 |
+
else if ! $(module-documented)
|
| 917 |
+
{
|
| 918 |
+
# document the module.
|
| 919 |
+
set-module-doc $(module-name) : $(comment-block) ;
|
| 920 |
+
module-documented = true ;
|
| 921 |
+
}
|
| 922 |
+
}
|
| 923 |
+
if $(action)
|
| 924 |
+
{
|
| 925 |
+
$(action[1]) $(module-name) : $(action[2-]) ;
|
| 926 |
+
}
|
| 927 |
+
}
|
| 928 |
+
|
| 929 |
+
|
| 930 |
+
# Import scan-module to global scope, so that it is available during header
|
| 931 |
+
# scanning phase.
|
| 932 |
+
#
|
| 933 |
+
IMPORT $(__name__) : scan-module : : doc.scan-module ;
|
| 934 |
+
|
| 935 |
+
|
| 936 |
+
# Read in a file using the SHELL builtin and return the individual lines as
|
| 937 |
+
# would be done for header scanning.
|
| 938 |
+
#
|
| 939 |
+
local rule read-file (
|
| 940 |
+
file # The file to read in.
|
| 941 |
+
)
|
| 942 |
+
{
|
| 943 |
+
file = [ path.native [ path.root [ path.make $(file) ] [ path.pwd ] ] ] ;
|
| 944 |
+
if ! $(.file<$(file)>.lines)
|
| 945 |
+
{
|
| 946 |
+
local content ;
|
| 947 |
+
switch [ modules.peek : OS ]
|
| 948 |
+
{
|
| 949 |
+
case NT :
|
| 950 |
+
content = [ SHELL "TYPE \"$(file)\"" ] ;
|
| 951 |
+
|
| 952 |
+
case * :
|
| 953 |
+
content = [ SHELL "cat \"$(file)\"" ] ;
|
| 954 |
+
}
|
| 955 |
+
local lines ;
|
| 956 |
+
local nl = "
|
| 957 |
+
" ;
|
| 958 |
+
local << = "([^$(nl)]*)[$(nl)](.*)" ;
|
| 959 |
+
local line+ = [ MATCH "$(<<)" : "$(content)" ] ;
|
| 960 |
+
while $(line+)
|
| 961 |
+
{
|
| 962 |
+
lines += $(line+[1]) ;
|
| 963 |
+
line+ = [ MATCH "$(<<)" : "$(line+[2])" ] ;
|
| 964 |
+
}
|
| 965 |
+
.file<$(file)>.lines = $(lines) ;
|
| 966 |
+
}
|
| 967 |
+
return $(.file<$(file)>.lines) ;
|
| 968 |
+
}
|
| 969 |
+
|
| 970 |
+
|
| 971 |
+
# Add a scan action to perform to generate the help documentation. The action
|
| 972 |
+
# rule is passed the name of the module as the first argument. The second
|
| 973 |
+
# argument(s) are optional and passed directly as specified here.
|
| 974 |
+
#
|
| 975 |
+
local rule do-scan (
|
| 976 |
+
modules + # The modules to scan and perform the action on.
|
| 977 |
+
: action * # The action rule, plus the secondary arguments to pass to the action rule.
|
| 978 |
+
)
|
| 979 |
+
{
|
| 980 |
+
if $(help-output) = text
|
| 981 |
+
{
|
| 982 |
+
print.output $(help-output-file).txt plain ;
|
| 983 |
+
ALWAYS $(help-output-file).txt ;
|
| 984 |
+
DEPENDS all : $(help-output-file).txt ;
|
| 985 |
+
}
|
| 986 |
+
if $(help-output) = html
|
| 987 |
+
{
|
| 988 |
+
print.output $(help-output-file).html html ;
|
| 989 |
+
ALWAYS $(help-output-file).html ;
|
| 990 |
+
DEPENDS all : $(help-output-file).html ;
|
| 991 |
+
}
|
| 992 |
+
for local module-file in $(modules[1--2])
|
| 993 |
+
{
|
| 994 |
+
scan-module $(module-file) : [ read-file $(module-file) ] ;
|
| 995 |
+
}
|
| 996 |
+
scan-module $(modules[-1]) : [ read-file $(modules[-1]) ] : $(action) ;
|
| 997 |
+
}
|
mosesdecoder/jam-files/boost-build/util/numbers.jam
ADDED
|
@@ -0,0 +1,218 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright 2001, 2002 Dave Abrahams
|
| 2 |
+
# Copyright 2002, 2003 Vladimir Prus
|
| 3 |
+
# Distributed under the Boost Software License, Version 1.0.
|
| 4 |
+
# (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
|
| 5 |
+
|
| 6 |
+
import errors ;
|
| 7 |
+
|
| 8 |
+
|
| 9 |
+
rule trim-leading-zeroes ( value )
|
| 10 |
+
{
|
| 11 |
+
return [ CALC $(value) + 0 ] ;
|
| 12 |
+
}
|
| 13 |
+
|
| 14 |
+
|
| 15 |
+
rule check ( numbers * )
|
| 16 |
+
{
|
| 17 |
+
for local n in $(numbers)
|
| 18 |
+
{
|
| 19 |
+
switch $(n)
|
| 20 |
+
{
|
| 21 |
+
case *[^0-9]* :
|
| 22 |
+
errors.error $(n) "in" $(numbers) : is not a number ;
|
| 23 |
+
}
|
| 24 |
+
}
|
| 25 |
+
}
|
| 26 |
+
|
| 27 |
+
|
| 28 |
+
rule increment ( number )
|
| 29 |
+
{
|
| 30 |
+
return [ CALC $(number) + 1 ] ;
|
| 31 |
+
}
|
| 32 |
+
|
| 33 |
+
|
| 34 |
+
rule decrement ( number )
|
| 35 |
+
{
|
| 36 |
+
return [ CALC $(number) - 1 ] ;
|
| 37 |
+
}
|
| 38 |
+
|
| 39 |
+
|
| 40 |
+
rule range ( start finish ? : step ? )
|
| 41 |
+
{
|
| 42 |
+
if ! $(finish)
|
| 43 |
+
{
|
| 44 |
+
finish = $(start) ;
|
| 45 |
+
start = 1 ;
|
| 46 |
+
}
|
| 47 |
+
step ?= 1 ;
|
| 48 |
+
|
| 49 |
+
check $(start) $(finish) $(step) ;
|
| 50 |
+
|
| 51 |
+
if $(finish) != 0
|
| 52 |
+
{
|
| 53 |
+
local result ;
|
| 54 |
+
while [ less $(start) $(finish) ] || $(start) = $(finish)
|
| 55 |
+
{
|
| 56 |
+
result += $(start) ;
|
| 57 |
+
start = [ CALC $(start) + $(step) ] ;
|
| 58 |
+
}
|
| 59 |
+
return $(result) ;
|
| 60 |
+
}
|
| 61 |
+
}
|
| 62 |
+
|
| 63 |
+
|
| 64 |
+
rule less ( n1 n2 )
|
| 65 |
+
{
|
| 66 |
+
switch [ CALC $(n2) - $(n1) ]
|
| 67 |
+
{
|
| 68 |
+
case [1-9]* : return true ;
|
| 69 |
+
}
|
| 70 |
+
}
|
| 71 |
+
|
| 72 |
+
|
| 73 |
+
rule log10 ( number )
|
| 74 |
+
{
|
| 75 |
+
switch $(number)
|
| 76 |
+
{
|
| 77 |
+
case *[^0-9]* : errors.error $(number) is not a number ;
|
| 78 |
+
case 0 : errors.error can't take log of zero ;
|
| 79 |
+
case [1-9] : return 0 ;
|
| 80 |
+
case [1-9]? : return 1 ;
|
| 81 |
+
case [1-9]?? : return 2 ;
|
| 82 |
+
case [1-9]??? : return 3 ;
|
| 83 |
+
case [1-9]???? : return 4 ;
|
| 84 |
+
case [1-9]????? : return 5 ;
|
| 85 |
+
case [1-9]?????? : return 6 ;
|
| 86 |
+
case [1-9]??????? : return 7 ;
|
| 87 |
+
case [1-9]???????? : return 8 ;
|
| 88 |
+
case [1-9]????????? : return 9 ;
|
| 89 |
+
case * :
|
| 90 |
+
{
|
| 91 |
+
import sequence ;
|
| 92 |
+
import string ;
|
| 93 |
+
local chars = [ string.chars $(number) ] ;
|
| 94 |
+
while $(chars[1]) = 0
|
| 95 |
+
{
|
| 96 |
+
chars = $(chars[2-]) ;
|
| 97 |
+
}
|
| 98 |
+
if ! $(chars)
|
| 99 |
+
{
|
| 100 |
+
errors.error can't take log of zero ;
|
| 101 |
+
}
|
| 102 |
+
else
|
| 103 |
+
{
|
| 104 |
+
return [ decrement [ sequence.length $(chars) ] ] ;
|
| 105 |
+
}
|
| 106 |
+
}
|
| 107 |
+
}
|
| 108 |
+
}
|
| 109 |
+
|
| 110 |
+
|
| 111 |
+
rule __test__ ( )
|
| 112 |
+
{
|
| 113 |
+
import assert ;
|
| 114 |
+
|
| 115 |
+
assert.result 1 : increment 0 ;
|
| 116 |
+
assert.result 2 : increment 1 ;
|
| 117 |
+
assert.result 1 : decrement 2 ;
|
| 118 |
+
assert.result 0 : decrement 1 ;
|
| 119 |
+
assert.result 50 : increment 49 ;
|
| 120 |
+
assert.result 49 : decrement 50 ;
|
| 121 |
+
assert.result 99 : increment 98 ;
|
| 122 |
+
assert.result 99 : decrement 100 ;
|
| 123 |
+
assert.result 100 : increment 99 ;
|
| 124 |
+
assert.result 999 : decrement 1000 ;
|
| 125 |
+
assert.result 1000 : increment 999 ;
|
| 126 |
+
|
| 127 |
+
assert.result 1 2 3 : range 3 ;
|
| 128 |
+
assert.result 1 2 3 4 5 6 7 8 9 10 11 12 : range 12 ;
|
| 129 |
+
assert.result 3 4 5 6 7 8 9 10 11 : range 3 11 ;
|
| 130 |
+
assert.result : range 0 ;
|
| 131 |
+
assert.result 1 4 7 10 : range 10 : 3 ;
|
| 132 |
+
assert.result 2 4 6 8 10 : range 2 10 : 2 ;
|
| 133 |
+
assert.result 25 50 75 100 : range 25 100 : 25 ;
|
| 134 |
+
|
| 135 |
+
assert.result 0 : trim-leading-zeroes 0 ;
|
| 136 |
+
assert.result 1234 : trim-leading-zeroes 1234 ;
|
| 137 |
+
assert.result 123456 : trim-leading-zeroes 0000123456 ;
|
| 138 |
+
assert.result 1000123456 : trim-leading-zeroes 1000123456 ;
|
| 139 |
+
assert.result 10000 : trim-leading-zeroes 10000 ;
|
| 140 |
+
assert.result 10000 : trim-leading-zeroes 00010000 ;
|
| 141 |
+
|
| 142 |
+
assert.true less 1 2 ;
|
| 143 |
+
assert.true less 1 12 ;
|
| 144 |
+
assert.true less 1 21 ;
|
| 145 |
+
assert.true less 005 217 ;
|
| 146 |
+
assert.false less 0 0 ;
|
| 147 |
+
assert.false less 03 3 ;
|
| 148 |
+
assert.false less 3 03 ;
|
| 149 |
+
assert.true less 005 217 ;
|
| 150 |
+
assert.true less 0005 217 ;
|
| 151 |
+
assert.true less 5 00217 ;
|
| 152 |
+
|
| 153 |
+
# TEMPORARY disabled, because nested "try"/"catch" do not work and I do no
|
| 154 |
+
# have the time to fix that right now.
|
| 155 |
+
if $(0)
|
| 156 |
+
{
|
| 157 |
+
try ;
|
| 158 |
+
{
|
| 159 |
+
decrement 0 ;
|
| 160 |
+
}
|
| 161 |
+
catch can't decrement zero! ;
|
| 162 |
+
|
| 163 |
+
try ;
|
| 164 |
+
{
|
| 165 |
+
check foo ;
|
| 166 |
+
}
|
| 167 |
+
catch : not a number ;
|
| 168 |
+
|
| 169 |
+
try ;
|
| 170 |
+
{
|
| 171 |
+
increment foo ;
|
| 172 |
+
}
|
| 173 |
+
catch : not a number ;
|
| 174 |
+
|
| 175 |
+
try ;
|
| 176 |
+
{
|
| 177 |
+
log10 0 ;
|
| 178 |
+
}
|
| 179 |
+
catch can't take log of zero ;
|
| 180 |
+
|
| 181 |
+
try ;
|
| 182 |
+
{
|
| 183 |
+
log10 000 ;
|
| 184 |
+
}
|
| 185 |
+
catch can't take log of zero ;
|
| 186 |
+
|
| 187 |
+
}
|
| 188 |
+
|
| 189 |
+
assert.result 0 : log10 1 ;
|
| 190 |
+
assert.result 0 : log10 9 ;
|
| 191 |
+
assert.result 1 : log10 10 ;
|
| 192 |
+
assert.result 1 : log10 99 ;
|
| 193 |
+
assert.result 2 : log10 100 ;
|
| 194 |
+
assert.result 2 : log10 101 ;
|
| 195 |
+
assert.result 2 : log10 125 ;
|
| 196 |
+
assert.result 2 : log10 999 ;
|
| 197 |
+
assert.result 3 : log10 1000 ;
|
| 198 |
+
assert.result 10 : log10 12345678901 ;
|
| 199 |
+
|
| 200 |
+
for local x in [ range 75 110 : 5 ]
|
| 201 |
+
{
|
| 202 |
+
for local y in [ range $(x) 111 : 3 ]
|
| 203 |
+
{
|
| 204 |
+
if $(x) != $(y)
|
| 205 |
+
{
|
| 206 |
+
assert.true less $(x) $(y) ;
|
| 207 |
+
}
|
| 208 |
+
}
|
| 209 |
+
}
|
| 210 |
+
|
| 211 |
+
for local x in [ range 90 110 : 2 ]
|
| 212 |
+
{
|
| 213 |
+
for local y in [ range 80 $(x) : 4 ]
|
| 214 |
+
{
|
| 215 |
+
assert.false less $(x) $(y) ;
|
| 216 |
+
}
|
| 217 |
+
}
|
| 218 |
+
}
|
mosesdecoder/jam-files/boost-build/util/regex.jam
ADDED
|
@@ -0,0 +1,193 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright 2001, 2002 Dave Abrahams
|
| 2 |
+
# Copyright 2003 Douglas Gregor
|
| 3 |
+
# Copyright 2003 Rene Rivera
|
| 4 |
+
# Copyright 2002, 2003, 2004, 2005 Vladimir Prus
|
| 5 |
+
# Distributed under the Boost Software License, Version 1.0.
|
| 6 |
+
# (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
|
| 7 |
+
|
| 8 |
+
#
|
| 9 |
+
# Returns a list of the following substrings:
|
| 10 |
+
# 1) from beginning till the first occurrence of 'separator' or till the end,
|
| 11 |
+
# 2) between each occurrence of 'separator' and the next occurrence,
|
| 12 |
+
# 3) from the last occurrence of 'separator' till the end.
|
| 13 |
+
# If no separator is present, the result will contain only one element.
|
| 14 |
+
#
|
| 15 |
+
|
| 16 |
+
rule split ( string separator )
|
| 17 |
+
{
|
| 18 |
+
local result ;
|
| 19 |
+
local s = $(string) ;
|
| 20 |
+
|
| 21 |
+
# Break pieaces off 's' until it has no separators left.
|
| 22 |
+
local match = 1 ;
|
| 23 |
+
while $(match)
|
| 24 |
+
{
|
| 25 |
+
match = [ MATCH ^(.*)($(separator))(.*) : $(s) ] ;
|
| 26 |
+
if $(match)
|
| 27 |
+
{
|
| 28 |
+
match += "" ; # in case 3rd item was empty - works around MATCH bug
|
| 29 |
+
result = $(match[3]) $(result) ;
|
| 30 |
+
s = $(match[1]) ;
|
| 31 |
+
}
|
| 32 |
+
}
|
| 33 |
+
# Combine the remaining part at the beginning, which does not have
|
| 34 |
+
# separators, with the pieces broken off. Note that the rule's signature
|
| 35 |
+
# does not allow the initial s to be empty.
|
| 36 |
+
return $(s) $(result) ;
|
| 37 |
+
}
|
| 38 |
+
|
| 39 |
+
|
| 40 |
+
# Returns the concatenated results of Applying regex.split to every element of
|
| 41 |
+
# the list using the separator pattern.
|
| 42 |
+
#
|
| 43 |
+
rule split-list ( list * : separator )
|
| 44 |
+
{
|
| 45 |
+
local result ;
|
| 46 |
+
for s in $(list)
|
| 47 |
+
{
|
| 48 |
+
result += [ split $(s) $(separator) ] ;
|
| 49 |
+
}
|
| 50 |
+
return $(result) ;
|
| 51 |
+
}
|
| 52 |
+
|
| 53 |
+
|
| 54 |
+
# Match string against pattern, and return the elements indicated by indices.
|
| 55 |
+
#
|
| 56 |
+
rule match ( pattern : string : indices * )
|
| 57 |
+
{
|
| 58 |
+
indices ?= 1 2 3 4 5 6 7 8 9 ;
|
| 59 |
+
local x = [ MATCH $(pattern) : $(string) ] ;
|
| 60 |
+
return $(x[$(indices)]) ;
|
| 61 |
+
}
|
| 62 |
+
|
| 63 |
+
|
| 64 |
+
# Matches all elements of 'list' agains the 'pattern' and returns a list of
|
| 65 |
+
# elements indicated by indices of all successful matches. If 'indices' is
|
| 66 |
+
# omitted returns a list of first paranthethised groups of all successful
|
| 67 |
+
# matches.
|
| 68 |
+
#
|
| 69 |
+
rule transform ( list * : pattern : indices * )
|
| 70 |
+
{
|
| 71 |
+
indices ?= 1 ;
|
| 72 |
+
local result ;
|
| 73 |
+
for local e in $(list)
|
| 74 |
+
{
|
| 75 |
+
local m = [ MATCH $(pattern) : $(e) ] ;
|
| 76 |
+
if $(m)
|
| 77 |
+
{
|
| 78 |
+
result += $(m[$(indices)]) ;
|
| 79 |
+
}
|
| 80 |
+
}
|
| 81 |
+
return $(result) ;
|
| 82 |
+
}
|
| 83 |
+
|
| 84 |
+
NATIVE_RULE regex : transform ;
|
| 85 |
+
|
| 86 |
+
|
| 87 |
+
# Escapes all of the characters in symbols using the escape symbol escape-symbol
|
| 88 |
+
# for the given string, and returns the escaped string.
|
| 89 |
+
#
|
| 90 |
+
rule escape ( string : symbols : escape-symbol )
|
| 91 |
+
{
|
| 92 |
+
local result = "" ;
|
| 93 |
+
local m = 1 ;
|
| 94 |
+
while $(m)
|
| 95 |
+
{
|
| 96 |
+
m = [ MATCH ^([^$(symbols)]*)([$(symbols)])(.*) : $(string) ] ;
|
| 97 |
+
if $(m)
|
| 98 |
+
{
|
| 99 |
+
m += "" ; # Supposedly a bug fix; borrowed from regex.split
|
| 100 |
+
result = "$(result)$(m[1])$(escape-symbol)$(m[2])" ;
|
| 101 |
+
string = $(m[3]) ;
|
| 102 |
+
}
|
| 103 |
+
}
|
| 104 |
+
string ?= "" ;
|
| 105 |
+
result = "$(result)$(string)" ;
|
| 106 |
+
return $(result) ;
|
| 107 |
+
}
|
| 108 |
+
|
| 109 |
+
|
| 110 |
+
# Replaces occurrences of a match string in a given string and returns the new
|
| 111 |
+
# string. The match string can be a regex expression.
|
| 112 |
+
#
|
| 113 |
+
rule replace (
|
| 114 |
+
string # The string to modify.
|
| 115 |
+
match # The characters to replace.
|
| 116 |
+
replacement # The string to replace with.
|
| 117 |
+
)
|
| 118 |
+
{
|
| 119 |
+
local result = "" ;
|
| 120 |
+
local parts = 1 ;
|
| 121 |
+
while $(parts)
|
| 122 |
+
{
|
| 123 |
+
parts = [ MATCH ^(.*)($(match))(.*) : $(string) ] ;
|
| 124 |
+
if $(parts)
|
| 125 |
+
{
|
| 126 |
+
parts += "" ;
|
| 127 |
+
result = "$(replacement)$(parts[3])$(result)" ;
|
| 128 |
+
string = $(parts[1]) ;
|
| 129 |
+
}
|
| 130 |
+
}
|
| 131 |
+
string ?= "" ;
|
| 132 |
+
result = "$(string)$(result)" ;
|
| 133 |
+
return $(result) ;
|
| 134 |
+
}
|
| 135 |
+
|
| 136 |
+
|
| 137 |
+
# Replaces occurrences of a match string in a given list of strings and returns
|
| 138 |
+
# a list of new strings. The match string can be a regex expression.
|
| 139 |
+
#
|
| 140 |
+
# list - the list of strings to modify.
|
| 141 |
+
# match - the search expression.
|
| 142 |
+
# replacement - the string to replace with.
|
| 143 |
+
#
|
| 144 |
+
rule replace-list ( list * : match : replacement )
|
| 145 |
+
{
|
| 146 |
+
local result ;
|
| 147 |
+
for local e in $(list)
|
| 148 |
+
{
|
| 149 |
+
result += [ replace $(e) $(match) $(replacement) ] ;
|
| 150 |
+
}
|
| 151 |
+
return $(result) ;
|
| 152 |
+
}
|
| 153 |
+
|
| 154 |
+
|
| 155 |
+
rule __test__ ( )
|
| 156 |
+
{
|
| 157 |
+
import assert ;
|
| 158 |
+
|
| 159 |
+
assert.result a b c : split "a/b/c" / ;
|
| 160 |
+
assert.result "" a b c : split "/a/b/c" / ;
|
| 161 |
+
assert.result "" "" a b c : split "//a/b/c" / ;
|
| 162 |
+
assert.result "" a "" b c : split "/a//b/c" / ;
|
| 163 |
+
assert.result "" a "" b c "" : split "/a//b/c/" / ;
|
| 164 |
+
assert.result "" a "" b c "" "" : split "/a//b/c//" / ;
|
| 165 |
+
|
| 166 |
+
assert.result a c b d
|
| 167 |
+
: match (.)(.)(.)(.) : abcd : 1 3 2 4 ;
|
| 168 |
+
|
| 169 |
+
assert.result a b c d
|
| 170 |
+
: match (.)(.)(.)(.) : abcd ;
|
| 171 |
+
|
| 172 |
+
assert.result ababab cddc
|
| 173 |
+
: match ((ab)*)([cd]+) : abababcddc : 1 3 ;
|
| 174 |
+
|
| 175 |
+
assert.result a.h c.h
|
| 176 |
+
: transform <a.h> \"b.h\" <c.h> : <(.*)> ;
|
| 177 |
+
|
| 178 |
+
assert.result a.h b.h c.h
|
| 179 |
+
: transform <a.h> \"b.h\" <c.h> : <([^>]*)>|\"([^\"]*)\" : 1 2 ;
|
| 180 |
+
|
| 181 |
+
assert.result "^<?xml version=\"1.0\"^>"
|
| 182 |
+
: escape "<?xml version=\"1.0\">" : "&|()<>^" : "^" ;
|
| 183 |
+
|
| 184 |
+
assert.result "<?xml version=\\\"1.0\\\">"
|
| 185 |
+
: escape "<?xml version=\"1.0\">" : "\\\"" : "\\" ;
|
| 186 |
+
|
| 187 |
+
assert.result "string string " : replace "string string " " " " " ;
|
| 188 |
+
assert.result " string string" : replace " string string" " " " " ;
|
| 189 |
+
assert.result "string string" : replace "string string" " " " " ;
|
| 190 |
+
assert.result "-" : replace "&" "&" "-" ;
|
| 191 |
+
|
| 192 |
+
assert.result "-" "a-b" : replace-list "&" "a&b" : "&" : "-" ;
|
| 193 |
+
}
|
mosesdecoder/jam-files/engine/build.bat
ADDED
|
@@ -0,0 +1,565 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
@ECHO OFF
|
| 2 |
+
|
| 3 |
+
REM ~ Copyright 2002-2007 Rene Rivera.
|
| 4 |
+
REM ~ Distributed under the Boost Software License, Version 1.0.
|
| 5 |
+
REM ~ (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
|
| 6 |
+
|
| 7 |
+
setlocal
|
| 8 |
+
goto Start
|
| 9 |
+
|
| 10 |
+
|
| 11 |
+
:Set_Error
|
| 12 |
+
color 00
|
| 13 |
+
goto :eof
|
| 14 |
+
|
| 15 |
+
|
| 16 |
+
:Clear_Error
|
| 17 |
+
ver >nul
|
| 18 |
+
goto :eof
|
| 19 |
+
|
| 20 |
+
|
| 21 |
+
:Error_Print
|
| 22 |
+
REM Output an error message and set the errorlevel to indicate failure.
|
| 23 |
+
setlocal
|
| 24 |
+
ECHO ###
|
| 25 |
+
ECHO ### %1
|
| 26 |
+
ECHO ###
|
| 27 |
+
ECHO ### You can specify the toolset as the argument, i.e.:
|
| 28 |
+
ECHO ### .\build.bat msvc
|
| 29 |
+
ECHO ###
|
| 30 |
+
ECHO ### Toolsets supported by this script are: borland, como, gcc, gcc-nocygwin,
|
| 31 |
+
ECHO ### intel-win32, metrowerks, mingw, msvc, vc7, vc8, vc9, vc10, vc11
|
| 32 |
+
ECHO ###
|
| 33 |
+
call :Set_Error
|
| 34 |
+
endlocal
|
| 35 |
+
goto :eof
|
| 36 |
+
|
| 37 |
+
|
| 38 |
+
:Test_Path
|
| 39 |
+
REM Tests for the given file(executable) presence in the directories in the PATH
|
| 40 |
+
REM environment variable. Additionaly sets FOUND_PATH to the path of the
|
| 41 |
+
REM found file.
|
| 42 |
+
call :Clear_Error
|
| 43 |
+
setlocal
|
| 44 |
+
set test=%~$PATH:1
|
| 45 |
+
endlocal
|
| 46 |
+
if not errorlevel 1 set FOUND_PATH=%~dp$PATH:1
|
| 47 |
+
goto :eof
|
| 48 |
+
|
| 49 |
+
|
| 50 |
+
:Test_Option
|
| 51 |
+
REM Tests whether the given string is in the form of an option: "--*"
|
| 52 |
+
call :Clear_Error
|
| 53 |
+
setlocal
|
| 54 |
+
set test=%1
|
| 55 |
+
if not defined test (
|
| 56 |
+
call :Set_Error
|
| 57 |
+
goto Test_Option_End
|
| 58 |
+
)
|
| 59 |
+
set test=###%test%###
|
| 60 |
+
set test=%test:"###=%
|
| 61 |
+
set test=%test:###"=%
|
| 62 |
+
set test=%test:###=%
|
| 63 |
+
if not "-" == "%test:~1,1%" call :Set_Error
|
| 64 |
+
:Test_Option_End
|
| 65 |
+
endlocal
|
| 66 |
+
goto :eof
|
| 67 |
+
|
| 68 |
+
|
| 69 |
+
:Test_Empty
|
| 70 |
+
REM Tests whether the given string is not empty
|
| 71 |
+
call :Clear_Error
|
| 72 |
+
setlocal
|
| 73 |
+
set test=%1
|
| 74 |
+
if not defined test (
|
| 75 |
+
call :Clear_Error
|
| 76 |
+
goto Test_Empty_End
|
| 77 |
+
)
|
| 78 |
+
set test=###%test%###
|
| 79 |
+
set test=%test:"###=%
|
| 80 |
+
set test=%test:###"=%
|
| 81 |
+
set test=%test:###=%
|
| 82 |
+
if not "" == "%test%" call :Set_Error
|
| 83 |
+
:Test_Empty_End
|
| 84 |
+
endlocal
|
| 85 |
+
goto :eof
|
| 86 |
+
|
| 87 |
+
|
| 88 |
+
:Call_If_Exists
|
| 89 |
+
if EXIST %1 call %*
|
| 90 |
+
goto :eof
|
| 91 |
+
|
| 92 |
+
|
| 93 |
+
:Guess_Toolset
|
| 94 |
+
REM Try and guess the toolset to bootstrap the build with...
|
| 95 |
+
REM Sets BOOST_JAM_TOOLSET to the first found toolset.
|
| 96 |
+
REM May also set BOOST_JAM_TOOLSET_ROOT to the
|
| 97 |
+
REM location of the found toolset.
|
| 98 |
+
|
| 99 |
+
call :Clear_Error
|
| 100 |
+
call :Test_Empty %ProgramFiles%
|
| 101 |
+
if not errorlevel 1 set ProgramFiles=C:\Program Files
|
| 102 |
+
|
| 103 |
+
call :Clear_Error
|
| 104 |
+
if NOT "_%VS110COMNTOOLS%_" == "__" (
|
| 105 |
+
set "BOOST_JAM_TOOLSET=vc11"
|
| 106 |
+
set "BOOST_JAM_TOOLSET_ROOT=%VS110COMNTOOLS%..\..\VC\"
|
| 107 |
+
goto :eof)
|
| 108 |
+
call :Clear_Error
|
| 109 |
+
if EXIST "%ProgramFiles%\Microsoft Visual Studio 11.0\VC\VCVARSALL.BAT" (
|
| 110 |
+
set "BOOST_JAM_TOOLSET=vc11"
|
| 111 |
+
set "BOOST_JAM_TOOLSET_ROOT=%ProgramFiles%\Microsoft Visual Studio 11.0\VC\"
|
| 112 |
+
goto :eof)
|
| 113 |
+
call :Clear_Error
|
| 114 |
+
if NOT "_%VS100COMNTOOLS%_" == "__" (
|
| 115 |
+
set "BOOST_JAM_TOOLSET=vc10"
|
| 116 |
+
set "BOOST_JAM_TOOLSET_ROOT=%VS100COMNTOOLS%..\..\VC\"
|
| 117 |
+
goto :eof)
|
| 118 |
+
call :Clear_Error
|
| 119 |
+
if EXIST "%ProgramFiles%\Microsoft Visual Studio 10.0\VC\VCVARSALL.BAT" (
|
| 120 |
+
set "BOOST_JAM_TOOLSET=vc10"
|
| 121 |
+
set "BOOST_JAM_TOOLSET_ROOT=%ProgramFiles%\Microsoft Visual Studio 10.0\VC\"
|
| 122 |
+
goto :eof)
|
| 123 |
+
call :Clear_Error
|
| 124 |
+
if NOT "_%VS90COMNTOOLS%_" == "__" (
|
| 125 |
+
set "BOOST_JAM_TOOLSET=vc9"
|
| 126 |
+
set "BOOST_JAM_TOOLSET_ROOT=%VS90COMNTOOLS%..\..\VC\"
|
| 127 |
+
goto :eof)
|
| 128 |
+
call :Clear_Error
|
| 129 |
+
if EXIST "%ProgramFiles%\Microsoft Visual Studio 9.0\VC\VCVARSALL.BAT" (
|
| 130 |
+
set "BOOST_JAM_TOOLSET=vc9"
|
| 131 |
+
set "BOOST_JAM_TOOLSET_ROOT=%ProgramFiles%\Microsoft Visual Studio 9.0\VC\"
|
| 132 |
+
goto :eof)
|
| 133 |
+
call :Clear_Error
|
| 134 |
+
if NOT "_%VS80COMNTOOLS%_" == "__" (
|
| 135 |
+
set "BOOST_JAM_TOOLSET=vc8"
|
| 136 |
+
set "BOOST_JAM_TOOLSET_ROOT=%VS80COMNTOOLS%..\..\VC\"
|
| 137 |
+
goto :eof)
|
| 138 |
+
call :Clear_Error
|
| 139 |
+
if EXIST "%ProgramFiles%\Microsoft Visual Studio 8\VC\VCVARSALL.BAT" (
|
| 140 |
+
set "BOOST_JAM_TOOLSET=vc8"
|
| 141 |
+
set "BOOST_JAM_TOOLSET_ROOT=%ProgramFiles%\Microsoft Visual Studio 8\VC\"
|
| 142 |
+
goto :eof)
|
| 143 |
+
call :Clear_Error
|
| 144 |
+
if NOT "_%VS71COMNTOOLS%_" == "__" (
|
| 145 |
+
set "BOOST_JAM_TOOLSET=vc7"
|
| 146 |
+
set "BOOST_JAM_TOOLSET_ROOT=%VS71COMNTOOLS%\..\..\VC7\"
|
| 147 |
+
goto :eof)
|
| 148 |
+
call :Clear_Error
|
| 149 |
+
if NOT "_%VCINSTALLDIR%_" == "__" (
|
| 150 |
+
REM %VCINSTALLDIR% is also set for VC9 (and probably VC8)
|
| 151 |
+
set "BOOST_JAM_TOOLSET=vc7"
|
| 152 |
+
set "BOOST_JAM_TOOLSET_ROOT=%VCINSTALLDIR%\VC7\"
|
| 153 |
+
goto :eof)
|
| 154 |
+
call :Clear_Error
|
| 155 |
+
if EXIST "%ProgramFiles%\Microsoft Visual Studio .NET 2003\VC7\bin\VCVARS32.BAT" (
|
| 156 |
+
set "BOOST_JAM_TOOLSET=vc7"
|
| 157 |
+
set "BOOST_JAM_TOOLSET_ROOT=%ProgramFiles%\Microsoft Visual Studio .NET 2003\VC7\"
|
| 158 |
+
goto :eof)
|
| 159 |
+
call :Clear_Error
|
| 160 |
+
if EXIST "%ProgramFiles%\Microsoft Visual Studio .NET\VC7\bin\VCVARS32.BAT" (
|
| 161 |
+
set "BOOST_JAM_TOOLSET=vc7"
|
| 162 |
+
set "BOOST_JAM_TOOLSET_ROOT=%ProgramFiles%\Microsoft Visual Studio .NET\VC7\"
|
| 163 |
+
goto :eof)
|
| 164 |
+
call :Clear_Error
|
| 165 |
+
if NOT "_%MSVCDir%_" == "__" (
|
| 166 |
+
set "BOOST_JAM_TOOLSET=msvc"
|
| 167 |
+
set "BOOST_JAM_TOOLSET_ROOT=%MSVCDir%\"
|
| 168 |
+
goto :eof)
|
| 169 |
+
call :Clear_Error
|
| 170 |
+
if EXIST "%ProgramFiles%\Microsoft Visual Studio\VC98\bin\VCVARS32.BAT" (
|
| 171 |
+
set "BOOST_JAM_TOOLSET=msvc"
|
| 172 |
+
set "BOOST_JAM_TOOLSET_ROOT=%ProgramFiles%\Microsoft Visual Studio\VC98\"
|
| 173 |
+
goto :eof)
|
| 174 |
+
call :Clear_Error
|
| 175 |
+
if EXIST "%ProgramFiles%\Microsoft Visual C++\VC98\bin\VCVARS32.BAT" (
|
| 176 |
+
set "BOOST_JAM_TOOLSET=msvc"
|
| 177 |
+
set "BOOST_JAM_TOOLSET_ROOT=%ProgramFiles%\Microsoft Visual C++\VC98\"
|
| 178 |
+
goto :eof)
|
| 179 |
+
call :Clear_Error
|
| 180 |
+
call :Test_Path cl.exe
|
| 181 |
+
if not errorlevel 1 (
|
| 182 |
+
set "BOOST_JAM_TOOLSET=msvc"
|
| 183 |
+
set "BOOST_JAM_TOOLSET_ROOT=%FOUND_PATH%..\"
|
| 184 |
+
goto :eof)
|
| 185 |
+
call :Clear_Error
|
| 186 |
+
call :Test_Path vcvars32.bat
|
| 187 |
+
if not errorlevel 1 (
|
| 188 |
+
set "BOOST_JAM_TOOLSET=msvc"
|
| 189 |
+
call "%FOUND_PATH%VCVARS32.BAT"
|
| 190 |
+
set "BOOST_JAM_TOOLSET_ROOT=%MSVCDir%\"
|
| 191 |
+
goto :eof)
|
| 192 |
+
call :Clear_Error
|
| 193 |
+
if EXIST "C:\Borland\BCC55\Bin\bcc32.exe" (
|
| 194 |
+
set "BOOST_JAM_TOOLSET=borland"
|
| 195 |
+
set "BOOST_JAM_TOOLSET_ROOT=C:\Borland\BCC55\"
|
| 196 |
+
goto :eof)
|
| 197 |
+
call :Clear_Error
|
| 198 |
+
call :Test_Path bcc32.exe
|
| 199 |
+
if not errorlevel 1 (
|
| 200 |
+
set "BOOST_JAM_TOOLSET=borland"
|
| 201 |
+
set "BOOST_JAM_TOOLSET_ROOT=%FOUND_PATH%..\"
|
| 202 |
+
goto :eof)
|
| 203 |
+
call :Clear_Error
|
| 204 |
+
call :Test_Path icl.exe
|
| 205 |
+
if not errorlevel 1 (
|
| 206 |
+
set "BOOST_JAM_TOOLSET=intel-win32"
|
| 207 |
+
set "BOOST_JAM_TOOLSET_ROOT=%FOUND_PATH%..\"
|
| 208 |
+
goto :eof)
|
| 209 |
+
call :Clear_Error
|
| 210 |
+
if EXIST "C:\MinGW\bin\gcc.exe" (
|
| 211 |
+
set "BOOST_JAM_TOOLSET=mingw"
|
| 212 |
+
set "BOOST_JAM_TOOLSET_ROOT=C:\MinGW\"
|
| 213 |
+
goto :eof)
|
| 214 |
+
call :Clear_Error
|
| 215 |
+
if NOT "_%CWFolder%_" == "__" (
|
| 216 |
+
set "BOOST_JAM_TOOLSET=metrowerks"
|
| 217 |
+
set "BOOST_JAM_TOOLSET_ROOT=%CWFolder%\"
|
| 218 |
+
goto :eof )
|
| 219 |
+
call :Clear_Error
|
| 220 |
+
call :Test_Path mwcc.exe
|
| 221 |
+
if not errorlevel 1 (
|
| 222 |
+
set "BOOST_JAM_TOOLSET=metrowerks"
|
| 223 |
+
set "BOOST_JAM_TOOLSET_ROOT=%FOUND_PATH%..\..\"
|
| 224 |
+
goto :eof)
|
| 225 |
+
call :Clear_Error
|
| 226 |
+
call :Error_Print "Could not find a suitable toolset."
|
| 227 |
+
goto :eof
|
| 228 |
+
|
| 229 |
+
|
| 230 |
+
:Guess_Yacc
|
| 231 |
+
REM Tries to find bison or yacc in common places so we can build the grammar.
|
| 232 |
+
call :Clear_Error
|
| 233 |
+
call :Test_Path yacc.exe
|
| 234 |
+
if not errorlevel 1 (
|
| 235 |
+
set "YACC=yacc -d"
|
| 236 |
+
goto :eof)
|
| 237 |
+
call :Clear_Error
|
| 238 |
+
call :Test_Path bison.exe
|
| 239 |
+
if not errorlevel 1 (
|
| 240 |
+
set "YACC=bison -d --yacc"
|
| 241 |
+
goto :eof)
|
| 242 |
+
call :Clear_Error
|
| 243 |
+
if EXIST "C:\Program Files\GnuWin32\bin\bison.exe" (
|
| 244 |
+
set "YACC=C:\Program Files\GnuWin32\bin\bison.exe" -d --yacc
|
| 245 |
+
goto :eof)
|
| 246 |
+
call :Clear_Error
|
| 247 |
+
call :Error_Print "Could not find Yacc to build the Jam grammar."
|
| 248 |
+
goto :eof
|
| 249 |
+
|
| 250 |
+
|
| 251 |
+
:Start
|
| 252 |
+
set BOOST_JAM_TOOLSET=
|
| 253 |
+
set BOOST_JAM_ARGS=
|
| 254 |
+
|
| 255 |
+
REM If no arguments guess the toolset;
|
| 256 |
+
REM or if first argument is an option guess the toolset;
|
| 257 |
+
REM otherwise the argument is the toolset to use.
|
| 258 |
+
call :Clear_Error
|
| 259 |
+
call :Test_Empty %1
|
| 260 |
+
if not errorlevel 1 (
|
| 261 |
+
call :Guess_Toolset
|
| 262 |
+
if not errorlevel 1 ( goto Setup_Toolset ) else ( goto Finish )
|
| 263 |
+
)
|
| 264 |
+
|
| 265 |
+
call :Clear_Error
|
| 266 |
+
call :Test_Option %1
|
| 267 |
+
if not errorlevel 1 (
|
| 268 |
+
call :Guess_Toolset
|
| 269 |
+
if not errorlevel 1 ( goto Setup_Toolset ) else ( goto Finish )
|
| 270 |
+
)
|
| 271 |
+
|
| 272 |
+
call :Clear_Error
|
| 273 |
+
set BOOST_JAM_TOOLSET=%1
|
| 274 |
+
shift
|
| 275 |
+
goto Setup_Toolset
|
| 276 |
+
|
| 277 |
+
|
| 278 |
+
:Setup_Toolset
|
| 279 |
+
REM Setup the toolset command and options. This bit of code
|
| 280 |
+
REM needs to be flexible enough to handle both when
|
| 281 |
+
REM the toolset was guessed at and found, or when the toolset
|
| 282 |
+
REM was indicated in the command arguments.
|
| 283 |
+
REM NOTE: The strange multiple "if ?? == _toolset_" tests are that way
|
| 284 |
+
REM because in BAT variables are subsituted only once during a single
|
| 285 |
+
REM command. A complete "if ... ( commands ) else ( commands )"
|
| 286 |
+
REM is a single command, even though it's in multiple lines here.
|
| 287 |
+
:Setup_Args
|
| 288 |
+
call :Clear_Error
|
| 289 |
+
call :Test_Empty %1
|
| 290 |
+
if not errorlevel 1 goto Config_Toolset
|
| 291 |
+
call :Clear_Error
|
| 292 |
+
call :Test_Option %1
|
| 293 |
+
if errorlevel 1 (
|
| 294 |
+
set BOOST_JAM_ARGS=%BOOST_JAM_ARGS% %1
|
| 295 |
+
shift
|
| 296 |
+
goto Setup_Args
|
| 297 |
+
)
|
| 298 |
+
:Config_Toolset
|
| 299 |
+
if NOT "_%BOOST_JAM_TOOLSET%_" == "_metrowerks_" goto Skip_METROWERKS
|
| 300 |
+
if NOT "_%CWFolder%_" == "__" (
|
| 301 |
+
set "BOOST_JAM_TOOLSET_ROOT=%CWFolder%\"
|
| 302 |
+
)
|
| 303 |
+
set "PATH=%BOOST_JAM_TOOLSET_ROOT%Other Metrowerks Tools\Command Line Tools;%PATH%"
|
| 304 |
+
set "BOOST_JAM_CC=mwcc -runtime ss -cwd include -DNT -lkernel32.lib -ladvapi32.lib -luser32.lib"
|
| 305 |
+
set "BOOST_JAM_OPT_JAM=-o bootstrap\jam0.exe"
|
| 306 |
+
set "BOOST_JAM_OPT_MKJAMBASE=-o bootstrap\mkjambase0.exe"
|
| 307 |
+
set "BOOST_JAM_OPT_YYACC=-o bootstrap\yyacc0.exe"
|
| 308 |
+
set "_known_=1"
|
| 309 |
+
:Skip_METROWERKS
|
| 310 |
+
if NOT "_%BOOST_JAM_TOOLSET%_" == "_msvc_" goto Skip_MSVC
|
| 311 |
+
if NOT "_%MSVCDir%_" == "__" (
|
| 312 |
+
set "BOOST_JAM_TOOLSET_ROOT=%MSVCDir%\"
|
| 313 |
+
)
|
| 314 |
+
call :Call_If_Exists "%BOOST_JAM_TOOLSET_ROOT%bin\VCVARS32.BAT"
|
| 315 |
+
if not "_%BOOST_JAM_TOOLSET_ROOT%_" == "__" (
|
| 316 |
+
set "PATH=%BOOST_JAM_TOOLSET_ROOT%bin;%PATH%"
|
| 317 |
+
)
|
| 318 |
+
set "BOOST_JAM_CC=cl /nologo /GZ /Zi /MLd /Fobootstrap/ /Fdbootstrap/ -DNT -DYYDEBUG kernel32.lib advapi32.lib user32.lib"
|
| 319 |
+
set "BOOST_JAM_OPT_JAM=/Febootstrap\jam0"
|
| 320 |
+
set "BOOST_JAM_OPT_MKJAMBASE=/Febootstrap\mkjambase0"
|
| 321 |
+
set "BOOST_JAM_OPT_YYACC=/Febootstrap\yyacc0"
|
| 322 |
+
set "_known_=1"
|
| 323 |
+
:Skip_MSVC
|
| 324 |
+
if NOT "_%BOOST_JAM_TOOLSET%_" == "_vc7_" goto Skip_VC7
|
| 325 |
+
if NOT "_%VS71COMNTOOLS%_" == "__" (
|
| 326 |
+
set "BOOST_JAM_TOOLSET_ROOT=%VS71COMNTOOLS%..\..\VC7\"
|
| 327 |
+
)
|
| 328 |
+
if "_%VCINSTALLDIR%_" == "__" call :Call_If_Exists "%BOOST_JAM_TOOLSET_ROOT%bin\VCVARS32.BAT"
|
| 329 |
+
if NOT "_%BOOST_JAM_TOOLSET_ROOT%_" == "__" (
|
| 330 |
+
if "_%VCINSTALLDIR%_" == "__" (
|
| 331 |
+
set "PATH=%BOOST_JAM_TOOLSET_ROOT%bin;%PATH%"
|
| 332 |
+
) )
|
| 333 |
+
set "BOOST_JAM_CC=cl /nologo /GZ /Zi /MLd /Fobootstrap/ /Fdbootstrap/ -DNT -DYYDEBUG kernel32.lib advapi32.lib user32.lib"
|
| 334 |
+
set "BOOST_JAM_OPT_JAM=/Febootstrap\jam0"
|
| 335 |
+
set "BOOST_JAM_OPT_MKJAMBASE=/Febootstrap\mkjambase0"
|
| 336 |
+
set "BOOST_JAM_OPT_YYACC=/Febootstrap\yyacc0"
|
| 337 |
+
set "_known_=1"
|
| 338 |
+
:Skip_VC7
|
| 339 |
+
if NOT "_%BOOST_JAM_TOOLSET%_" == "_vc8_" goto Skip_VC8
|
| 340 |
+
if NOT "_%VS80COMNTOOLS%_" == "__" (
|
| 341 |
+
set "BOOST_JAM_TOOLSET_ROOT=%VS80COMNTOOLS%..\..\VC\"
|
| 342 |
+
)
|
| 343 |
+
if "_%VCINSTALLDIR%_" == "__" call :Call_If_Exists "%BOOST_JAM_TOOLSET_ROOT%VCVARSALL.BAT" %BOOST_JAM_ARGS%
|
| 344 |
+
if NOT "_%BOOST_JAM_TOOLSET_ROOT%_" == "__" (
|
| 345 |
+
if "_%VCINSTALLDIR%_" == "__" (
|
| 346 |
+
set "PATH=%BOOST_JAM_TOOLSET_ROOT%bin;%PATH%"
|
| 347 |
+
) )
|
| 348 |
+
set "BOOST_JAM_CC=cl /nologo /RTC1 /Zi /MTd /Fobootstrap/ /Fdbootstrap/ -DNT -DYYDEBUG -wd4996 kernel32.lib advapi32.lib user32.lib"
|
| 349 |
+
set "BOOST_JAM_OPT_JAM=/Febootstrap\jam0"
|
| 350 |
+
set "BOOST_JAM_OPT_MKJAMBASE=/Febootstrap\mkjambase0"
|
| 351 |
+
set "BOOST_JAM_OPT_YYACC=/Febootstrap\yyacc0"
|
| 352 |
+
set "_known_=1"
|
| 353 |
+
:Skip_VC8
|
| 354 |
+
if NOT "_%BOOST_JAM_TOOLSET%_" == "_vc9_" goto Skip_VC9
|
| 355 |
+
if NOT "_%VS90COMNTOOLS%_" == "__" (
|
| 356 |
+
set "BOOST_JAM_TOOLSET_ROOT=%VS90COMNTOOLS%..\..\VC\"
|
| 357 |
+
)
|
| 358 |
+
if "_%VCINSTALLDIR%_" == "__" call :Call_If_Exists "%BOOST_JAM_TOOLSET_ROOT%VCVARSALL.BAT" %BOOST_JAM_ARGS%
|
| 359 |
+
if NOT "_%BOOST_JAM_TOOLSET_ROOT%_" == "__" (
|
| 360 |
+
if "_%VCINSTALLDIR%_" == "__" (
|
| 361 |
+
set "PATH=%BOOST_JAM_TOOLSET_ROOT%bin;%PATH%"
|
| 362 |
+
) )
|
| 363 |
+
set "BOOST_JAM_CC=cl /nologo /RTC1 /Zi /MTd /Fobootstrap/ /Fdbootstrap/ -DNT -DYYDEBUG -wd4996 kernel32.lib advapi32.lib user32.lib"
|
| 364 |
+
set "BOOST_JAM_OPT_JAM=/Febootstrap\jam0"
|
| 365 |
+
set "BOOST_JAM_OPT_MKJAMBASE=/Febootstrap\mkjambase0"
|
| 366 |
+
set "BOOST_JAM_OPT_YYACC=/Febootstrap\yyacc0"
|
| 367 |
+
set "_known_=1"
|
| 368 |
+
:Skip_VC9
|
| 369 |
+
if NOT "_%BOOST_JAM_TOOLSET%_" == "_vc10_" goto Skip_VC10
|
| 370 |
+
if NOT "_%VS100COMNTOOLS%_" == "__" (
|
| 371 |
+
set "BOOST_JAM_TOOLSET_ROOT=%VS100COMNTOOLS%..\..\VC\"
|
| 372 |
+
)
|
| 373 |
+
if "_%VCINSTALLDIR%_" == "__" call :Call_If_Exists "%BOOST_JAM_TOOLSET_ROOT%VCVARSALL.BAT" %BOOST_JAM_ARGS%
|
| 374 |
+
if NOT "_%BOOST_JAM_TOOLSET_ROOT%_" == "__" (
|
| 375 |
+
if "_%VCINSTALLDIR%_" == "__" (
|
| 376 |
+
set "PATH=%BOOST_JAM_TOOLSET_ROOT%bin;%PATH%"
|
| 377 |
+
) )
|
| 378 |
+
set "BOOST_JAM_CC=cl /nologo /RTC1 /Zi /MTd /Fobootstrap/ /Fdbootstrap/ -DNT -DYYDEBUG -wd4996 kernel32.lib advapi32.lib user32.lib"
|
| 379 |
+
set "BOOST_JAM_OPT_JAM=/Febootstrap\jam0"
|
| 380 |
+
set "BOOST_JAM_OPT_MKJAMBASE=/Febootstrap\mkjambase0"
|
| 381 |
+
set "BOOST_JAM_OPT_YYACC=/Febootstrap\yyacc0"
|
| 382 |
+
set "_known_=1"
|
| 383 |
+
:Skip_VC10
|
| 384 |
+
if NOT "_%BOOST_JAM_TOOLSET%_" == "_vc11_" goto Skip_VC11
|
| 385 |
+
if NOT "_%VS110COMNTOOLS%_" == "__" (
|
| 386 |
+
set "BOOST_JAM_TOOLSET_ROOT=%VS110COMNTOOLS%..\..\VC\"
|
| 387 |
+
)
|
| 388 |
+
if "_%VCINSTALLDIR%_" == "__" call :Call_If_Exists "%BOOST_JAM_TOOLSET_ROOT%VCVARSALL.BAT" %BOOST_JAM_ARGS%
|
| 389 |
+
if NOT "_%BOOST_JAM_TOOLSET_ROOT%_" == "__" (
|
| 390 |
+
if "_%VCINSTALLDIR%_" == "__" (
|
| 391 |
+
set "PATH=%BOOST_JAM_TOOLSET_ROOT%bin;%PATH%"
|
| 392 |
+
) )
|
| 393 |
+
set "BOOST_JAM_CC=cl /nologo /RTC1 /Zi /MTd /Fobootstrap/ /Fdbootstrap/ -DNT -DYYDEBUG -wd4996 kernel32.lib advapi32.lib user32.lib"
|
| 394 |
+
set "BOOST_JAM_OPT_JAM=/Febootstrap\jam0"
|
| 395 |
+
set "BOOST_JAM_OPT_MKJAMBASE=/Febootstrap\mkjambase0"
|
| 396 |
+
set "BOOST_JAM_OPT_YYACC=/Febootstrap\yyacc0"
|
| 397 |
+
set "_known_=1"
|
| 398 |
+
:Skip_VC11
|
| 399 |
+
if NOT "_%BOOST_JAM_TOOLSET%_" == "_borland_" goto Skip_BORLAND
|
| 400 |
+
if "_%BOOST_JAM_TOOLSET_ROOT%_" == "__" (
|
| 401 |
+
call :Test_Path bcc32.exe )
|
| 402 |
+
if "_%BOOST_JAM_TOOLSET_ROOT%_" == "__" (
|
| 403 |
+
if not errorlevel 1 (
|
| 404 |
+
set "BOOST_JAM_TOOLSET_ROOT=%FOUND_PATH%..\"
|
| 405 |
+
) )
|
| 406 |
+
if not "_%BOOST_JAM_TOOLSET_ROOT%_" == "__" (
|
| 407 |
+
set "PATH=%BOOST_JAM_TOOLSET_ROOT%Bin;%PATH%"
|
| 408 |
+
)
|
| 409 |
+
set "BOOST_JAM_CC=bcc32 -WC -w- -q -I%BOOST_JAM_TOOLSET_ROOT%Include -L%BOOST_JAM_TOOLSET_ROOT%Lib /DNT -nbootstrap"
|
| 410 |
+
set "BOOST_JAM_OPT_JAM=-ejam0"
|
| 411 |
+
set "BOOST_JAM_OPT_MKJAMBASE=-emkjambasejam0"
|
| 412 |
+
set "BOOST_JAM_OPT_YYACC=-eyyacc0"
|
| 413 |
+
set "_known_=1"
|
| 414 |
+
:Skip_BORLAND
|
| 415 |
+
if NOT "_%BOOST_JAM_TOOLSET%_" == "_como_" goto Skip_COMO
|
| 416 |
+
set "BOOST_JAM_CC=como -DNT"
|
| 417 |
+
set "BOOST_JAM_OPT_JAM=-o bootstrap\jam0.exe"
|
| 418 |
+
set "BOOST_JAM_OPT_MKJAMBASE=-o bootstrap\mkjambase0.exe"
|
| 419 |
+
set "BOOST_JAM_OPT_YYACC=-o bootstrap\yyacc0.exe"
|
| 420 |
+
set "_known_=1"
|
| 421 |
+
:Skip_COMO
|
| 422 |
+
if NOT "_%BOOST_JAM_TOOLSET%_" == "_gcc_" goto Skip_GCC
|
| 423 |
+
set "BOOST_JAM_CC=gcc -DNT"
|
| 424 |
+
set "BOOST_JAM_OPT_JAM=-o bootstrap\jam0.exe"
|
| 425 |
+
set "BOOST_JAM_OPT_MKJAMBASE=-o bootstrap\mkjambase0.exe"
|
| 426 |
+
set "BOOST_JAM_OPT_YYACC=-o bootstrap\yyacc0.exe"
|
| 427 |
+
set "_known_=1"
|
| 428 |
+
:Skip_GCC
|
| 429 |
+
if NOT "_%BOOST_JAM_TOOLSET%_" == "_gcc-nocygwin_" goto Skip_GCC_NOCYGWIN
|
| 430 |
+
set "BOOST_JAM_CC=gcc -DNT -mno-cygwin"
|
| 431 |
+
set "BOOST_JAM_OPT_JAM=-o bootstrap\jam0.exe"
|
| 432 |
+
set "BOOST_JAM_OPT_MKJAMBASE=-o bootstrap\mkjambase0.exe"
|
| 433 |
+
set "BOOST_JAM_OPT_YYACC=-o bootstrap\yyacc0.exe"
|
| 434 |
+
set "_known_=1"
|
| 435 |
+
:Skip_GCC_NOCYGWIN
|
| 436 |
+
if NOT "_%BOOST_JAM_TOOLSET%_" == "_intel-win32_" goto Skip_INTEL_WIN32
|
| 437 |
+
set "BOOST_JAM_CC=icl -DNT /nologo kernel32.lib advapi32.lib user32.lib"
|
| 438 |
+
set "BOOST_JAM_OPT_JAM=/Febootstrap\jam0"
|
| 439 |
+
set "BOOST_JAM_OPT_MKJAMBASE=/Febootstrap\mkjambase0"
|
| 440 |
+
set "BOOST_JAM_OPT_YYACC=/Febootstrap\yyacc0"
|
| 441 |
+
set "_known_=1"
|
| 442 |
+
:Skip_INTEL_WIN32
|
| 443 |
+
if NOT "_%BOOST_JAM_TOOLSET%_" == "_mingw_" goto Skip_MINGW
|
| 444 |
+
if not "_%BOOST_JAM_TOOLSET_ROOT%_" == "__" (
|
| 445 |
+
set "PATH=%BOOST_JAM_TOOLSET_ROOT%bin;%PATH%"
|
| 446 |
+
)
|
| 447 |
+
set "BOOST_JAM_CC=gcc -DNT"
|
| 448 |
+
set "BOOST_JAM_OPT_JAM=-o bootstrap\jam0.exe"
|
| 449 |
+
set "BOOST_JAM_OPT_MKJAMBASE=-o bootstrap\mkjambase0.exe"
|
| 450 |
+
set "BOOST_JAM_OPT_YYACC=-o bootstrap\yyacc0.exe"
|
| 451 |
+
set "_known_=1"
|
| 452 |
+
:Skip_MINGW
|
| 453 |
+
call :Clear_Error
|
| 454 |
+
if "_%_known_%_" == "__" (
|
| 455 |
+
call :Error_Print "Unknown toolset: %BOOST_JAM_TOOLSET%"
|
| 456 |
+
)
|
| 457 |
+
if errorlevel 1 goto Finish
|
| 458 |
+
|
| 459 |
+
echo ###
|
| 460 |
+
echo ### Using '%BOOST_JAM_TOOLSET%' toolset.
|
| 461 |
+
echo ###
|
| 462 |
+
|
| 463 |
+
set YYACC_SOURCES=yyacc.c
|
| 464 |
+
set MKJAMBASE_SOURCES=mkjambase.c
|
| 465 |
+
set BJAM_SOURCES=
|
| 466 |
+
set BJAM_SOURCES=%BJAM_SOURCES% command.c compile.c constants.c debug.c
|
| 467 |
+
set BJAM_SOURCES=%BJAM_SOURCES% execcmd.c execnt.c filent.c frames.c function.c
|
| 468 |
+
set BJAM_SOURCES=%BJAM_SOURCES% glob.c hash.c hdrmacro.c headers.c jam.c
|
| 469 |
+
set BJAM_SOURCES=%BJAM_SOURCES% jambase.c jamgram.c lists.c make.c make1.c
|
| 470 |
+
set BJAM_SOURCES=%BJAM_SOURCES% object.c option.c output.c parse.c pathnt.c
|
| 471 |
+
set BJAM_SOURCES=%BJAM_SOURCES% pathsys.c regexp.c rules.c scan.c search.c
|
| 472 |
+
set BJAM_SOURCES=%BJAM_SOURCES% subst.c timestamp.c variable.c modules.c
|
| 473 |
+
set BJAM_SOURCES=%BJAM_SOURCES% strings.c filesys.c builtins.c md5.c class.c
|
| 474 |
+
set BJAM_SOURCES=%BJAM_SOURCES% cwd.c w32_getreg.c native.c modules/set.c
|
| 475 |
+
set BJAM_SOURCES=%BJAM_SOURCES% modules/path.c modules/regex.c
|
| 476 |
+
set BJAM_SOURCES=%BJAM_SOURCES% modules/property-set.c modules/sequence.c
|
| 477 |
+
set BJAM_SOURCES=%BJAM_SOURCES% modules/order.c
|
| 478 |
+
|
| 479 |
+
set BJAM_UPDATE=
|
| 480 |
+
:Check_Update
|
| 481 |
+
call :Test_Empty %1
|
| 482 |
+
if not errorlevel 1 goto Check_Update_End
|
| 483 |
+
call :Clear_Error
|
| 484 |
+
setlocal
|
| 485 |
+
set test=%1
|
| 486 |
+
set test=###%test%###
|
| 487 |
+
set test=%test:"###=%
|
| 488 |
+
set test=%test:###"=%
|
| 489 |
+
set test=%test:###=%
|
| 490 |
+
if "%test%" == "--update" goto Found_Update
|
| 491 |
+
endlocal
|
| 492 |
+
shift
|
| 493 |
+
if not "_%BJAM_UPDATE%_" == "_update_" goto Check_Update
|
| 494 |
+
:Found_Update
|
| 495 |
+
endlocal
|
| 496 |
+
set BJAM_UPDATE=update
|
| 497 |
+
:Check_Update_End
|
| 498 |
+
if "_%BJAM_UPDATE%_" == "_update_" (
|
| 499 |
+
if not exist ".\bootstrap\jam0.exe" (
|
| 500 |
+
set BJAM_UPDATE=
|
| 501 |
+
)
|
| 502 |
+
)
|
| 503 |
+
|
| 504 |
+
@echo ON
|
| 505 |
+
@if "_%BJAM_UPDATE%_" == "_update_" goto Skip_Bootstrap
|
| 506 |
+
if exist bootstrap rd /S /Q bootstrap
|
| 507 |
+
md bootstrap
|
| 508 |
+
@if not exist jamgram.y goto Bootstrap_GrammarPrep
|
| 509 |
+
@if not exist jamgramtab.h goto Bootstrap_GrammarPrep
|
| 510 |
+
@goto Skip_GrammarPrep
|
| 511 |
+
:Bootstrap_GrammarPrep
|
| 512 |
+
%BOOST_JAM_CC% %BOOST_JAM_OPT_YYACC% %YYACC_SOURCES%
|
| 513 |
+
@if not exist ".\bootstrap\yyacc0.exe" goto Skip_GrammarPrep
|
| 514 |
+
.\bootstrap\yyacc0 jamgram.y jamgramtab.h jamgram.yy
|
| 515 |
+
:Skip_GrammarPrep
|
| 516 |
+
@if not exist jamgram.c goto Bootstrap_GrammarBuild
|
| 517 |
+
@if not exist jamgram.h goto Bootstrap_GrammarBuild
|
| 518 |
+
@goto Skip_GrammarBuild
|
| 519 |
+
:Bootstrap_GrammarBuild
|
| 520 |
+
@echo OFF
|
| 521 |
+
if "_%YACC%_" == "__" (
|
| 522 |
+
call :Guess_Yacc
|
| 523 |
+
)
|
| 524 |
+
if errorlevel 1 goto Finish
|
| 525 |
+
@echo ON
|
| 526 |
+
%YACC% jamgram.y
|
| 527 |
+
@if errorlevel 1 goto Finish
|
| 528 |
+
del /f jamgram.c
|
| 529 |
+
rename y.tab.c jamgram.c
|
| 530 |
+
del /f jamgram.h
|
| 531 |
+
rename y.tab.h jamgram.h
|
| 532 |
+
:Skip_GrammarBuild
|
| 533 |
+
@echo ON
|
| 534 |
+
@if exist jambase.c goto Skip_Jambase
|
| 535 |
+
%BOOST_JAM_CC% %BOOST_JAM_OPT_MKJAMBASE% %MKJAMBASE_SOURCES%
|
| 536 |
+
@if not exist ".\bootstrap\mkjambase0.exe" goto Skip_Jambase
|
| 537 |
+
.\bootstrap\mkjambase0 jambase.c Jambase
|
| 538 |
+
:Skip_Jambase
|
| 539 |
+
%BOOST_JAM_CC% %BOOST_JAM_OPT_JAM% %BJAM_SOURCES%
|
| 540 |
+
:Skip_Bootstrap
|
| 541 |
+
@if not exist ".\bootstrap\jam0.exe" goto Skip_Jam
|
| 542 |
+
@set args=%*
|
| 543 |
+
@echo OFF
|
| 544 |
+
:Set_Args
|
| 545 |
+
setlocal
|
| 546 |
+
call :Test_Empty %args%
|
| 547 |
+
if not errorlevel 1 goto Set_Args_End
|
| 548 |
+
set test=###%args:~0,2%###
|
| 549 |
+
set test=%test:"###=%
|
| 550 |
+
set test=%test:###"=%
|
| 551 |
+
set test=%test:###=%
|
| 552 |
+
set test=%test:~0,1%
|
| 553 |
+
if "-" == "%test%" goto Set_Args_End
|
| 554 |
+
endlocal
|
| 555 |
+
set args=%args:~1%
|
| 556 |
+
goto Set_Args
|
| 557 |
+
:Set_Args_End
|
| 558 |
+
@echo ON
|
| 559 |
+
@if "_%BJAM_UPDATE%_" == "_update_" goto Skip_Clean
|
| 560 |
+
.\bootstrap\jam0 -f build.jam --toolset=%BOOST_JAM_TOOLSET% "--toolset-root=%BOOST_JAM_TOOLSET_ROOT% " %args% clean
|
| 561 |
+
:Skip_Clean
|
| 562 |
+
.\bootstrap\jam0 -f build.jam --toolset=%BOOST_JAM_TOOLSET% "--toolset-root=%BOOST_JAM_TOOLSET_ROOT% " %args%
|
| 563 |
+
:Skip_Jam
|
| 564 |
+
|
| 565 |
+
:Finish
|
mosesdecoder/jam-files/engine/builtins.c
ADDED
|
@@ -0,0 +1,2354 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/*
|
| 2 |
+
* Copyright 1993-2002 Christopher Seiwald and Perforce Software, Inc.
|
| 3 |
+
*
|
| 4 |
+
* This file is part of Jam - see jam.c for Copyright information.
|
| 5 |
+
*/
|
| 6 |
+
|
| 7 |
+
#include "jam.h"
|
| 8 |
+
#include "builtins.h"
|
| 9 |
+
|
| 10 |
+
#include "compile.h"
|
| 11 |
+
#include "constants.h"
|
| 12 |
+
#include "cwd.h"
|
| 13 |
+
#include "filesys.h"
|
| 14 |
+
#include "frames.h"
|
| 15 |
+
#include "hash.h"
|
| 16 |
+
#include "hdrmacro.h"
|
| 17 |
+
#include "lists.h"
|
| 18 |
+
#include "make.h"
|
| 19 |
+
#include "md5.h"
|
| 20 |
+
#include "native.h"
|
| 21 |
+
#include "object.h"
|
| 22 |
+
#include "parse.h"
|
| 23 |
+
#include "pathsys.h"
|
| 24 |
+
#include "rules.h"
|
| 25 |
+
#include "strings.h"
|
| 26 |
+
#include "subst.h"
|
| 27 |
+
#include "timestamp.h"
|
| 28 |
+
#include "variable.h"
|
| 29 |
+
|
| 30 |
+
#include <ctype.h>
|
| 31 |
+
|
| 32 |
+
#if defined(USE_EXECUNIX)
|
| 33 |
+
# include <sys/types.h>
|
| 34 |
+
# include <sys/wait.h>
|
| 35 |
+
#else
|
| 36 |
+
/*
|
| 37 |
+
* NT does not have wait() and associated macros and uses the system() return
|
| 38 |
+
* value instead. Status code group are documented at:
|
| 39 |
+
* http://msdn.microsoft.com/en-gb/library/ff565436.aspx
|
| 40 |
+
*/
|
| 41 |
+
# define WIFEXITED(w) (((w) & 0XFFFFFF00) == 0)
|
| 42 |
+
# define WEXITSTATUS(w)(w)
|
| 43 |
+
#endif
|
| 44 |
+
|
| 45 |
+
/*
|
| 46 |
+
* builtins.c - builtin jam rules
|
| 47 |
+
*
|
| 48 |
+
* External routines:
|
| 49 |
+
* load_builtins() - define builtin rules
|
| 50 |
+
* unknown_rule() - reports an unknown rule occurrence to the
|
| 51 |
+
* user and exits
|
| 52 |
+
*
|
| 53 |
+
* Internal routines:
|
| 54 |
+
* append_if_exists() - if file exists, append it to the list
|
| 55 |
+
* builtin_calc() - CALC rule
|
| 56 |
+
* builtin_delete_module() - DELETE_MODULE ( MODULE ? )
|
| 57 |
+
* builtin_depends() - DEPENDS/INCLUDES rule
|
| 58 |
+
* builtin_echo() - ECHO rule
|
| 59 |
+
* builtin_exit() - EXIT rule
|
| 60 |
+
* builtin_export() - EXPORT ( MODULE ? : RULES * )
|
| 61 |
+
* builtin_flags() - NOCARE, NOTFILE, TEMPORARY rule
|
| 62 |
+
* builtin_glob() - GLOB rule
|
| 63 |
+
* builtin_glob_recursive() - ???
|
| 64 |
+
* builtin_hdrmacro() - ???
|
| 65 |
+
* builtin_import() - IMPORT rule
|
| 66 |
+
* builtin_match() - MATCH rule, regexp matching
|
| 67 |
+
* builtin_rebuilds() - REBUILDS rule
|
| 68 |
+
* builtin_rulenames() - RULENAMES ( MODULE ? )
|
| 69 |
+
* builtin_split_by_characters() - splits the given string into tokens
|
| 70 |
+
* builtin_varnames() - VARNAMES ( MODULE ? )
|
| 71 |
+
* get_source_line() - get a frame's file and line number
|
| 72 |
+
* information
|
| 73 |
+
*/
|
| 74 |
+
|
| 75 |
+
|
| 76 |
+
/*
|
| 77 |
+
* compile_builtin() - define builtin rules
|
| 78 |
+
*/
|
| 79 |
+
|
| 80 |
+
#define P0 (PARSE *)0
|
| 81 |
+
#define C0 (OBJECT *)0
|
| 82 |
+
|
| 83 |
+
#if defined( OS_NT ) || defined( OS_CYGWIN )
|
| 84 |
+
LIST * builtin_system_registry ( FRAME *, int );
|
| 85 |
+
LIST * builtin_system_registry_names( FRAME *, int );
|
| 86 |
+
#endif
|
| 87 |
+
|
| 88 |
+
int glob( char const * s, char const * c );
|
| 89 |
+
|
| 90 |
+
void backtrace ( FRAME * );
|
| 91 |
+
void backtrace_line ( FRAME * );
|
| 92 |
+
void print_source_line( FRAME * );
|
| 93 |
+
|
| 94 |
+
|
| 95 |
+
RULE * bind_builtin( char const * name_, LIST * (* f)( FRAME *, int flags ),
|
| 96 |
+
int flags, char const * * args )
|
| 97 |
+
{
|
| 98 |
+
FUNCTION * func;
|
| 99 |
+
RULE * result;
|
| 100 |
+
OBJECT * name = object_new( name_ );
|
| 101 |
+
|
| 102 |
+
func = function_builtin( f, flags, args );
|
| 103 |
+
|
| 104 |
+
result = new_rule_body( root_module(), name, func, 1 );
|
| 105 |
+
|
| 106 |
+
function_free( func );
|
| 107 |
+
|
| 108 |
+
object_free( name );
|
| 109 |
+
|
| 110 |
+
return result;
|
| 111 |
+
}
|
| 112 |
+
|
| 113 |
+
|
| 114 |
+
RULE * duplicate_rule( char const * name_, RULE * other )
|
| 115 |
+
{
|
| 116 |
+
OBJECT * name = object_new( name_ );
|
| 117 |
+
RULE * result = import_rule( other, root_module(), name );
|
| 118 |
+
object_free( name );
|
| 119 |
+
return result;
|
| 120 |
+
}
|
| 121 |
+
|
| 122 |
+
|
| 123 |
+
/*
|
| 124 |
+
* load_builtins() - define builtin rules
|
| 125 |
+
*/
|
| 126 |
+
|
| 127 |
+
void load_builtins()
|
| 128 |
+
{
|
| 129 |
+
duplicate_rule( "Always",
|
| 130 |
+
bind_builtin( "ALWAYS",
|
| 131 |
+
builtin_flags, T_FLAG_TOUCHED, 0 ) );
|
| 132 |
+
|
| 133 |
+
duplicate_rule( "Depends",
|
| 134 |
+
bind_builtin( "DEPENDS",
|
| 135 |
+
builtin_depends, 0, 0 ) );
|
| 136 |
+
|
| 137 |
+
duplicate_rule( "echo",
|
| 138 |
+
duplicate_rule( "Echo",
|
| 139 |
+
bind_builtin( "ECHO",
|
| 140 |
+
builtin_echo, 0, 0 ) ) );
|
| 141 |
+
|
| 142 |
+
{
|
| 143 |
+
char const * args[] = { "message", "*", ":", "result-value", "?", 0 };
|
| 144 |
+
duplicate_rule( "exit",
|
| 145 |
+
duplicate_rule( "Exit",
|
| 146 |
+
bind_builtin( "EXIT",
|
| 147 |
+
builtin_exit, 0, args ) ) );
|
| 148 |
+
}
|
| 149 |
+
|
| 150 |
+
{
|
| 151 |
+
char const * args[] = { "directories", "*", ":", "patterns", "*", ":",
|
| 152 |
+
"case-insensitive", "?", 0 };
|
| 153 |
+
duplicate_rule( "Glob",
|
| 154 |
+
bind_builtin( "GLOB", builtin_glob, 0, args ) );
|
| 155 |
+
}
|
| 156 |
+
|
| 157 |
+
{
|
| 158 |
+
char const * args[] = { "patterns", "*", 0 };
|
| 159 |
+
bind_builtin( "GLOB-RECURSIVELY",
|
| 160 |
+
builtin_glob_recursive, 0, args );
|
| 161 |
+
}
|
| 162 |
+
|
| 163 |
+
duplicate_rule( "Includes",
|
| 164 |
+
bind_builtin( "INCLUDES",
|
| 165 |
+
builtin_depends, 1, 0 ) );
|
| 166 |
+
|
| 167 |
+
{
|
| 168 |
+
char const * args[] = { "targets", "*", ":", "targets-to-rebuild", "*",
|
| 169 |
+
0 };
|
| 170 |
+
bind_builtin( "REBUILDS",
|
| 171 |
+
builtin_rebuilds, 0, args );
|
| 172 |
+
}
|
| 173 |
+
|
| 174 |
+
duplicate_rule( "Leaves",
|
| 175 |
+
bind_builtin( "LEAVES",
|
| 176 |
+
builtin_flags, T_FLAG_LEAVES, 0 ) );
|
| 177 |
+
|
| 178 |
+
duplicate_rule( "Match",
|
| 179 |
+
bind_builtin( "MATCH",
|
| 180 |
+
builtin_match, 0, 0 ) );
|
| 181 |
+
|
| 182 |
+
{
|
| 183 |
+
char const * args[] = { "string", ":", "delimiters", 0 };
|
| 184 |
+
bind_builtin( "SPLIT_BY_CHARACTERS",
|
| 185 |
+
builtin_split_by_characters, 0, args );
|
| 186 |
+
}
|
| 187 |
+
|
| 188 |
+
duplicate_rule( "NoCare",
|
| 189 |
+
bind_builtin( "NOCARE",
|
| 190 |
+
builtin_flags, T_FLAG_NOCARE, 0 ) );
|
| 191 |
+
|
| 192 |
+
duplicate_rule( "NOTIME",
|
| 193 |
+
duplicate_rule( "NotFile",
|
| 194 |
+
bind_builtin( "NOTFILE",
|
| 195 |
+
builtin_flags, T_FLAG_NOTFILE, 0 ) ) );
|
| 196 |
+
|
| 197 |
+
duplicate_rule( "NoUpdate",
|
| 198 |
+
bind_builtin( "NOUPDATE",
|
| 199 |
+
builtin_flags, T_FLAG_NOUPDATE, 0 ) );
|
| 200 |
+
|
| 201 |
+
duplicate_rule( "Temporary",
|
| 202 |
+
bind_builtin( "TEMPORARY",
|
| 203 |
+
builtin_flags, T_FLAG_TEMP, 0 ) );
|
| 204 |
+
|
| 205 |
+
bind_builtin( "ISFILE",
|
| 206 |
+
builtin_flags, T_FLAG_ISFILE, 0 );
|
| 207 |
+
|
| 208 |
+
duplicate_rule( "HdrMacro",
|
| 209 |
+
bind_builtin( "HDRMACRO",
|
| 210 |
+
builtin_hdrmacro, 0, 0 ) );
|
| 211 |
+
|
| 212 |
+
/* FAIL_EXPECTED is used to indicate that the result of a target build
|
| 213 |
+
* action should be inverted (ok <=> fail) this can be useful when
|
| 214 |
+
* performing test runs from Jamfiles.
|
| 215 |
+
*/
|
| 216 |
+
bind_builtin( "FAIL_EXPECTED",
|
| 217 |
+
builtin_flags, T_FLAG_FAIL_EXPECTED, 0 );
|
| 218 |
+
|
| 219 |
+
bind_builtin( "RMOLD",
|
| 220 |
+
builtin_flags, T_FLAG_RMOLD, 0 );
|
| 221 |
+
|
| 222 |
+
{
|
| 223 |
+
char const * args[] = { "targets", "*", 0 };
|
| 224 |
+
bind_builtin( "UPDATE",
|
| 225 |
+
builtin_update, 0, args );
|
| 226 |
+
}
|
| 227 |
+
|
| 228 |
+
{
|
| 229 |
+
char const * args[] = { "targets", "*",
|
| 230 |
+
":", "log", "?",
|
| 231 |
+
":", "ignore-minus-n", "?",
|
| 232 |
+
":", "ignore-minus-q", "?", 0 };
|
| 233 |
+
bind_builtin( "UPDATE_NOW",
|
| 234 |
+
builtin_update_now, 0, args );
|
| 235 |
+
}
|
| 236 |
+
|
| 237 |
+
{
|
| 238 |
+
char const * args[] = { "string", "pattern", "replacements", "+", 0 };
|
| 239 |
+
duplicate_rule( "subst",
|
| 240 |
+
bind_builtin( "SUBST",
|
| 241 |
+
builtin_subst, 0, args ) );
|
| 242 |
+
}
|
| 243 |
+
|
| 244 |
+
{
|
| 245 |
+
char const * args[] = { "module", "?", 0 };
|
| 246 |
+
bind_builtin( "RULENAMES",
|
| 247 |
+
builtin_rulenames, 0, args );
|
| 248 |
+
}
|
| 249 |
+
|
| 250 |
+
{
|
| 251 |
+
char const * args[] = { "module", "?", 0 };
|
| 252 |
+
bind_builtin( "VARNAMES",
|
| 253 |
+
builtin_varnames, 0, args );
|
| 254 |
+
}
|
| 255 |
+
|
| 256 |
+
{
|
| 257 |
+
char const * args[] = { "module", "?", 0 };
|
| 258 |
+
bind_builtin( "DELETE_MODULE",
|
| 259 |
+
builtin_delete_module, 0, args );
|
| 260 |
+
}
|
| 261 |
+
|
| 262 |
+
{
|
| 263 |
+
char const * args[] = { "source_module", "?",
|
| 264 |
+
":", "source_rules", "*",
|
| 265 |
+
":", "target_module", "?",
|
| 266 |
+
":", "target_rules", "*",
|
| 267 |
+
":", "localize", "?", 0 };
|
| 268 |
+
bind_builtin( "IMPORT",
|
| 269 |
+
builtin_import, 0, args );
|
| 270 |
+
}
|
| 271 |
+
|
| 272 |
+
{
|
| 273 |
+
char const * args[] = { "module", "?", ":", "rules", "*", 0 };
|
| 274 |
+
bind_builtin( "EXPORT",
|
| 275 |
+
builtin_export, 0, args );
|
| 276 |
+
}
|
| 277 |
+
|
| 278 |
+
{
|
| 279 |
+
char const * args[] = { "levels", "?", 0 };
|
| 280 |
+
bind_builtin( "CALLER_MODULE",
|
| 281 |
+
builtin_caller_module, 0, args );
|
| 282 |
+
}
|
| 283 |
+
|
| 284 |
+
{
|
| 285 |
+
char const * args[] = { "levels", "?", 0 };
|
| 286 |
+
bind_builtin( "BACKTRACE",
|
| 287 |
+
builtin_backtrace, 0, args );
|
| 288 |
+
}
|
| 289 |
+
|
| 290 |
+
{
|
| 291 |
+
char const * args[] = { 0 };
|
| 292 |
+
bind_builtin( "PWD",
|
| 293 |
+
builtin_pwd, 0, args );
|
| 294 |
+
}
|
| 295 |
+
|
| 296 |
+
{
|
| 297 |
+
char const * args[] = { "modules_to_import", "+",
|
| 298 |
+
":", "target_module", "?", 0 };
|
| 299 |
+
bind_builtin( "IMPORT_MODULE",
|
| 300 |
+
builtin_import_module, 0, args );
|
| 301 |
+
}
|
| 302 |
+
|
| 303 |
+
{
|
| 304 |
+
char const * args[] = { "module", "?", 0 };
|
| 305 |
+
bind_builtin( "IMPORTED_MODULES",
|
| 306 |
+
builtin_imported_modules, 0, args );
|
| 307 |
+
}
|
| 308 |
+
|
| 309 |
+
{
|
| 310 |
+
char const * args[] = { "instance_module", ":", "class_module", 0 };
|
| 311 |
+
bind_builtin( "INSTANCE",
|
| 312 |
+
builtin_instance, 0, args );
|
| 313 |
+
}
|
| 314 |
+
|
| 315 |
+
{
|
| 316 |
+
char const * args[] = { "sequence", "*", 0 };
|
| 317 |
+
bind_builtin( "SORT",
|
| 318 |
+
builtin_sort, 0, args );
|
| 319 |
+
}
|
| 320 |
+
|
| 321 |
+
{
|
| 322 |
+
char const * args[] = { "path_parts", "*", 0 };
|
| 323 |
+
bind_builtin( "NORMALIZE_PATH",
|
| 324 |
+
builtin_normalize_path, 0, args );
|
| 325 |
+
}
|
| 326 |
+
|
| 327 |
+
{
|
| 328 |
+
char const * args[] = { "args", "*", 0 };
|
| 329 |
+
bind_builtin( "CALC",
|
| 330 |
+
builtin_calc, 0, args );
|
| 331 |
+
}
|
| 332 |
+
|
| 333 |
+
{
|
| 334 |
+
char const * args[] = { "module", ":", "rule", 0 };
|
| 335 |
+
bind_builtin( "NATIVE_RULE",
|
| 336 |
+
builtin_native_rule, 0, args );
|
| 337 |
+
}
|
| 338 |
+
|
| 339 |
+
{
|
| 340 |
+
char const * args[] = { "module", ":", "rule", ":", "version", 0 };
|
| 341 |
+
bind_builtin( "HAS_NATIVE_RULE",
|
| 342 |
+
builtin_has_native_rule, 0, args );
|
| 343 |
+
}
|
| 344 |
+
|
| 345 |
+
{
|
| 346 |
+
char const * args[] = { "module", "*", 0 };
|
| 347 |
+
bind_builtin( "USER_MODULE",
|
| 348 |
+
builtin_user_module, 0, args );
|
| 349 |
+
}
|
| 350 |
+
|
| 351 |
+
{
|
| 352 |
+
char const * args[] = { 0 };
|
| 353 |
+
bind_builtin( "NEAREST_USER_LOCATION",
|
| 354 |
+
builtin_nearest_user_location, 0, args );
|
| 355 |
+
}
|
| 356 |
+
|
| 357 |
+
{
|
| 358 |
+
char const * args[] = { "file", 0 };
|
| 359 |
+
bind_builtin( "CHECK_IF_FILE",
|
| 360 |
+
builtin_check_if_file, 0, args );
|
| 361 |
+
}
|
| 362 |
+
|
| 363 |
+
#ifdef HAVE_PYTHON
|
| 364 |
+
{
|
| 365 |
+
char const * args[] = { "python-module",
|
| 366 |
+
":", "function",
|
| 367 |
+
":", "jam-module",
|
| 368 |
+
":", "rule-name", 0 };
|
| 369 |
+
bind_builtin( "PYTHON_IMPORT_RULE",
|
| 370 |
+
builtin_python_import_rule, 0, args );
|
| 371 |
+
}
|
| 372 |
+
#endif
|
| 373 |
+
|
| 374 |
+
# if defined( OS_NT ) || defined( OS_CYGWIN )
|
| 375 |
+
{
|
| 376 |
+
char const * args[] = { "key_path", ":", "data", "?", 0 };
|
| 377 |
+
bind_builtin( "W32_GETREG",
|
| 378 |
+
builtin_system_registry, 0, args );
|
| 379 |
+
}
|
| 380 |
+
|
| 381 |
+
{
|
| 382 |
+
char const * args[] = { "key_path", ":", "result-type", 0 };
|
| 383 |
+
bind_builtin( "W32_GETREGNAMES",
|
| 384 |
+
builtin_system_registry_names, 0, args );
|
| 385 |
+
}
|
| 386 |
+
# endif
|
| 387 |
+
|
| 388 |
+
{
|
| 389 |
+
char const * args[] = { "command", ":", "*", 0 };
|
| 390 |
+
duplicate_rule( "SHELL",
|
| 391 |
+
bind_builtin( "COMMAND",
|
| 392 |
+
builtin_shell, 0, args ) );
|
| 393 |
+
}
|
| 394 |
+
|
| 395 |
+
{
|
| 396 |
+
char const * args[] = { "string", 0 };
|
| 397 |
+
bind_builtin( "MD5",
|
| 398 |
+
builtin_md5, 0, args );
|
| 399 |
+
}
|
| 400 |
+
|
| 401 |
+
{
|
| 402 |
+
char const * args[] = { "name", ":", "mode", 0 };
|
| 403 |
+
bind_builtin( "FILE_OPEN",
|
| 404 |
+
builtin_file_open, 0, args );
|
| 405 |
+
}
|
| 406 |
+
|
| 407 |
+
{
|
| 408 |
+
char const * args[] = { "string", ":", "width", 0 };
|
| 409 |
+
bind_builtin( "PAD",
|
| 410 |
+
builtin_pad, 0, args );
|
| 411 |
+
}
|
| 412 |
+
|
| 413 |
+
{
|
| 414 |
+
char const * args[] = { "targets", "*", 0 };
|
| 415 |
+
bind_builtin( "PRECIOUS",
|
| 416 |
+
builtin_precious, 0, args );
|
| 417 |
+
}
|
| 418 |
+
|
| 419 |
+
{
|
| 420 |
+
char const * args [] = { 0 };
|
| 421 |
+
bind_builtin( "SELF_PATH", builtin_self_path, 0, args );
|
| 422 |
+
}
|
| 423 |
+
|
| 424 |
+
{
|
| 425 |
+
char const * args [] = { "path", 0 };
|
| 426 |
+
bind_builtin( "MAKEDIR", builtin_makedir, 0, args );
|
| 427 |
+
}
|
| 428 |
+
|
| 429 |
+
/* Initialize builtin modules. */
|
| 430 |
+
init_set();
|
| 431 |
+
init_path();
|
| 432 |
+
init_regex();
|
| 433 |
+
init_property_set();
|
| 434 |
+
init_sequence();
|
| 435 |
+
init_order();
|
| 436 |
+
}
|
| 437 |
+
|
| 438 |
+
|
| 439 |
+
/*
|
| 440 |
+
* builtin_calc() - CALC rule
|
| 441 |
+
*
|
| 442 |
+
* Performs simple mathematical operations on two arguments.
|
| 443 |
+
*/
|
| 444 |
+
|
| 445 |
+
LIST * builtin_calc( FRAME * frame, int flags )
|
| 446 |
+
{
|
| 447 |
+
LIST * arg = lol_get( frame->args, 0 );
|
| 448 |
+
|
| 449 |
+
LIST * result = L0;
|
| 450 |
+
long lhs_value;
|
| 451 |
+
long rhs_value;
|
| 452 |
+
long result_value;
|
| 453 |
+
char buffer[ 16 ];
|
| 454 |
+
char const * lhs;
|
| 455 |
+
char const * op;
|
| 456 |
+
char const * rhs;
|
| 457 |
+
LISTITER iter = list_begin( arg );
|
| 458 |
+
LISTITER const end = list_end( arg );
|
| 459 |
+
|
| 460 |
+
if ( iter == end ) return L0;
|
| 461 |
+
lhs = object_str( list_item( iter ) );
|
| 462 |
+
|
| 463 |
+
iter = list_next( iter );
|
| 464 |
+
if ( iter == end ) return L0;
|
| 465 |
+
op = object_str( list_item( iter ) );
|
| 466 |
+
|
| 467 |
+
iter = list_next( iter );
|
| 468 |
+
if ( iter == end ) return L0;
|
| 469 |
+
rhs = object_str( list_item( iter ) );
|
| 470 |
+
|
| 471 |
+
lhs_value = atoi( lhs );
|
| 472 |
+
rhs_value = atoi( rhs );
|
| 473 |
+
|
| 474 |
+
if ( !strcmp( "+", op ) )
|
| 475 |
+
result_value = lhs_value + rhs_value;
|
| 476 |
+
else if ( !strcmp( "-", op ) )
|
| 477 |
+
result_value = lhs_value - rhs_value;
|
| 478 |
+
else
|
| 479 |
+
return L0;
|
| 480 |
+
|
| 481 |
+
sprintf( buffer, "%ld", result_value );
|
| 482 |
+
result = list_push_back( result, object_new( buffer ) );
|
| 483 |
+
return result;
|
| 484 |
+
}
|
| 485 |
+
|
| 486 |
+
|
| 487 |
+
/*
|
| 488 |
+
* builtin_depends() - DEPENDS/INCLUDES rule
|
| 489 |
+
*
|
| 490 |
+
* The DEPENDS/INCLUDES builtin rule appends each of the listed sources on the
|
| 491 |
+
* dependency/includes list of each of the listed targets. It binds both the
|
| 492 |
+
* targets and sources as TARGETs.
|
| 493 |
+
*/
|
| 494 |
+
|
| 495 |
+
LIST * builtin_depends( FRAME * frame, int flags )
|
| 496 |
+
{
|
| 497 |
+
LIST * const targets = lol_get( frame->args, 0 );
|
| 498 |
+
LIST * const sources = lol_get( frame->args, 1 );
|
| 499 |
+
|
| 500 |
+
LISTITER iter = list_begin( targets );
|
| 501 |
+
LISTITER end = list_end( targets );
|
| 502 |
+
for ( ; iter != end; iter = list_next( iter ) )
|
| 503 |
+
{
|
| 504 |
+
TARGET * const t = bindtarget( list_item( iter ) );
|
| 505 |
+
|
| 506 |
+
if ( flags )
|
| 507 |
+
target_include_many( t, sources );
|
| 508 |
+
else
|
| 509 |
+
t->depends = targetlist( t->depends, sources );
|
| 510 |
+
}
|
| 511 |
+
|
| 512 |
+
/* Enter reverse links */
|
| 513 |
+
iter = list_begin( sources );
|
| 514 |
+
end = list_end( sources );
|
| 515 |
+
for ( ; iter != end; iter = list_next( iter ) )
|
| 516 |
+
{
|
| 517 |
+
TARGET * const s = bindtarget( list_item( iter ) );
|
| 518 |
+
if ( flags )
|
| 519 |
+
{
|
| 520 |
+
LISTITER t_iter = list_begin( targets );
|
| 521 |
+
LISTITER const t_end = list_end( targets );
|
| 522 |
+
for ( ; t_iter != t_end; t_iter = list_next( t_iter ) )
|
| 523 |
+
s->dependants = targetentry( s->dependants, bindtarget(
|
| 524 |
+
list_item( t_iter ) )->includes );
|
| 525 |
+
}
|
| 526 |
+
else
|
| 527 |
+
s->dependants = targetlist( s->dependants, targets );
|
| 528 |
+
}
|
| 529 |
+
|
| 530 |
+
return L0;
|
| 531 |
+
}
|
| 532 |
+
|
| 533 |
+
|
| 534 |
+
/*
|
| 535 |
+
* builtin_rebuilds() - REBUILDS rule
|
| 536 |
+
*
|
| 537 |
+
* Appends each of the rebuild-targets listed in its second argument to the
|
| 538 |
+
* rebuilds list for each of the targets listed in its first argument.
|
| 539 |
+
*/
|
| 540 |
+
|
| 541 |
+
LIST * builtin_rebuilds( FRAME * frame, int flags )
|
| 542 |
+
{
|
| 543 |
+
LIST * targets = lol_get( frame->args, 0 );
|
| 544 |
+
LIST * rebuilds = lol_get( frame->args, 1 );
|
| 545 |
+
LISTITER iter = list_begin( targets );
|
| 546 |
+
LISTITER const end = list_end( targets );
|
| 547 |
+
for ( ; iter != end; iter = list_next( iter ) )
|
| 548 |
+
{
|
| 549 |
+
TARGET * const t = bindtarget( list_item( iter ) );
|
| 550 |
+
t->rebuilds = targetlist( t->rebuilds, rebuilds );
|
| 551 |
+
}
|
| 552 |
+
return L0;
|
| 553 |
+
}
|
| 554 |
+
|
| 555 |
+
|
| 556 |
+
/*
|
| 557 |
+
* builtin_echo() - ECHO rule
|
| 558 |
+
*
|
| 559 |
+
* Echoes the targets to the user. No other actions are taken.
|
| 560 |
+
*/
|
| 561 |
+
|
| 562 |
+
LIST * builtin_echo( FRAME * frame, int flags )
|
| 563 |
+
{
|
| 564 |
+
list_print( lol_get( frame->args, 0 ) );
|
| 565 |
+
printf( "\n" );
|
| 566 |
+
fflush( stdout );
|
| 567 |
+
return L0;
|
| 568 |
+
}
|
| 569 |
+
|
| 570 |
+
|
| 571 |
+
/*
|
| 572 |
+
* builtin_exit() - EXIT rule
|
| 573 |
+
*
|
| 574 |
+
* Echoes the targets to the user and exits the program with a failure status.
|
| 575 |
+
*/
|
| 576 |
+
|
| 577 |
+
LIST * builtin_exit( FRAME * frame, int flags )
|
| 578 |
+
{
|
| 579 |
+
LIST * const code = lol_get( frame->args, 1 );
|
| 580 |
+
list_print( lol_get( frame->args, 0 ) );
|
| 581 |
+
printf( "\n" );
|
| 582 |
+
if ( !list_empty( code ) )
|
| 583 |
+
exit( atoi( object_str( list_front( code ) ) ) );
|
| 584 |
+
else
|
| 585 |
+
exit( EXITBAD ); /* yeech */
|
| 586 |
+
return L0;
|
| 587 |
+
}
|
| 588 |
+
|
| 589 |
+
|
| 590 |
+
/*
|
| 591 |
+
* builtin_flags() - NOCARE, NOTFILE, TEMPORARY rule
|
| 592 |
+
*
|
| 593 |
+
* Marks the target with the appropriate flag, for use by make0(). It binds each
|
| 594 |
+
* target as a TARGET.
|
| 595 |
+
*/
|
| 596 |
+
|
| 597 |
+
LIST * builtin_flags( FRAME * frame, int flags )
|
| 598 |
+
{
|
| 599 |
+
LIST * const targets = lol_get( frame->args, 0 );
|
| 600 |
+
LISTITER iter = list_begin( targets );
|
| 601 |
+
LISTITER const end = list_end( targets );
|
| 602 |
+
for ( ; iter != end; iter = list_next( iter ) )
|
| 603 |
+
bindtarget( list_item( iter ) )->flags |= flags;
|
| 604 |
+
return L0;
|
| 605 |
+
}
|
| 606 |
+
|
| 607 |
+
|
| 608 |
+
/*
|
| 609 |
+
* builtin_glob() - GLOB rule
|
| 610 |
+
*/
|
| 611 |
+
|
| 612 |
+
struct globbing
|
| 613 |
+
{
|
| 614 |
+
LIST * patterns;
|
| 615 |
+
LIST * results;
|
| 616 |
+
LIST * case_insensitive;
|
| 617 |
+
};
|
| 618 |
+
|
| 619 |
+
|
| 620 |
+
static void downcase_inplace( char * p )
|
| 621 |
+
{
|
| 622 |
+
for ( ; *p; ++p )
|
| 623 |
+
*p = tolower( *p );
|
| 624 |
+
}
|
| 625 |
+
|
| 626 |
+
|
| 627 |
+
static void builtin_glob_back( void * closure, OBJECT * file, int status,
|
| 628 |
+
timestamp const * const time )
|
| 629 |
+
{
|
| 630 |
+
PROFILE_ENTER( BUILTIN_GLOB_BACK );
|
| 631 |
+
|
| 632 |
+
struct globbing * const globbing = (struct globbing *)closure;
|
| 633 |
+
PATHNAME f;
|
| 634 |
+
string buf[ 1 ];
|
| 635 |
+
LISTITER iter;
|
| 636 |
+
LISTITER end;
|
| 637 |
+
|
| 638 |
+
/* Null out directory for matching. We wish we had file_dirscan() pass up a
|
| 639 |
+
* PATHNAME.
|
| 640 |
+
*/
|
| 641 |
+
path_parse( object_str( file ), &f );
|
| 642 |
+
f.f_dir.len = 0;
|
| 643 |
+
|
| 644 |
+
/* For globbing, we unconditionally ignore current and parent directory
|
| 645 |
+
* items. Since these items always exist, there is no reason why caller of
|
| 646 |
+
* GLOB would want to see them. We could also change file_dirscan(), but
|
| 647 |
+
* then paths with embedded "." and ".." would not work anywhere.
|
| 648 |
+
*/
|
| 649 |
+
if ( !strcmp( f.f_base.ptr, "." ) || !strcmp( f.f_base.ptr, ".." ) )
|
| 650 |
+
{
|
| 651 |
+
PROFILE_EXIT( BUILTIN_GLOB_BACK );
|
| 652 |
+
return;
|
| 653 |
+
}
|
| 654 |
+
|
| 655 |
+
string_new( buf );
|
| 656 |
+
path_build( &f, buf );
|
| 657 |
+
|
| 658 |
+
if ( globbing->case_insensitive )
|
| 659 |
+
downcase_inplace( buf->value );
|
| 660 |
+
|
| 661 |
+
iter = list_begin( globbing->patterns );
|
| 662 |
+
end = list_end( globbing->patterns );
|
| 663 |
+
for ( ; iter != end; iter = list_next( iter ) )
|
| 664 |
+
{
|
| 665 |
+
if ( !glob( object_str( list_item( iter ) ), buf->value ) )
|
| 666 |
+
{
|
| 667 |
+
globbing->results = list_push_back( globbing->results, object_copy(
|
| 668 |
+
file ) );
|
| 669 |
+
break;
|
| 670 |
+
}
|
| 671 |
+
}
|
| 672 |
+
|
| 673 |
+
string_free( buf );
|
| 674 |
+
|
| 675 |
+
PROFILE_EXIT( BUILTIN_GLOB_BACK );
|
| 676 |
+
}
|
| 677 |
+
|
| 678 |
+
|
| 679 |
+
static LIST * downcase_list( LIST * in )
|
| 680 |
+
{
|
| 681 |
+
LIST * result = L0;
|
| 682 |
+
LISTITER iter = list_begin( in );
|
| 683 |
+
LISTITER const end = list_end( in );
|
| 684 |
+
|
| 685 |
+
string s[ 1 ];
|
| 686 |
+
string_new( s );
|
| 687 |
+
|
| 688 |
+
for ( ; iter != end; iter = list_next( iter ) )
|
| 689 |
+
{
|
| 690 |
+
string_append( s, object_str( list_item( iter ) ) );
|
| 691 |
+
downcase_inplace( s->value );
|
| 692 |
+
result = list_push_back( result, object_new( s->value ) );
|
| 693 |
+
string_truncate( s, 0 );
|
| 694 |
+
}
|
| 695 |
+
|
| 696 |
+
string_free( s );
|
| 697 |
+
return result;
|
| 698 |
+
}
|
| 699 |
+
|
| 700 |
+
|
| 701 |
+
LIST * builtin_glob( FRAME * frame, int flags )
|
| 702 |
+
{
|
| 703 |
+
LIST * const l = lol_get( frame->args, 0 );
|
| 704 |
+
LIST * const r = lol_get( frame->args, 1 );
|
| 705 |
+
|
| 706 |
+
LISTITER iter;
|
| 707 |
+
LISTITER end;
|
| 708 |
+
struct globbing globbing;
|
| 709 |
+
|
| 710 |
+
globbing.results = L0;
|
| 711 |
+
globbing.patterns = r;
|
| 712 |
+
|
| 713 |
+
globbing.case_insensitive =
|
| 714 |
+
# if defined( OS_NT ) || defined( OS_CYGWIN )
|
| 715 |
+
l; /* Always case-insensitive if any files can be found. */
|
| 716 |
+
# else
|
| 717 |
+
lol_get( frame->args, 2 );
|
| 718 |
+
# endif
|
| 719 |
+
|
| 720 |
+
if ( globbing.case_insensitive )
|
| 721 |
+
globbing.patterns = downcase_list( r );
|
| 722 |
+
|
| 723 |
+
iter = list_begin( l );
|
| 724 |
+
end = list_end( l );
|
| 725 |
+
for ( ; iter != end; iter = list_next( iter ) )
|
| 726 |
+
file_dirscan( list_item( iter ), builtin_glob_back, &globbing );
|
| 727 |
+
|
| 728 |
+
if ( globbing.case_insensitive )
|
| 729 |
+
list_free( globbing.patterns );
|
| 730 |
+
|
| 731 |
+
return globbing.results;
|
| 732 |
+
}
|
| 733 |
+
|
| 734 |
+
|
| 735 |
+
static int has_wildcards( char const * const str )
|
| 736 |
+
{
|
| 737 |
+
return str[ strcspn( str, "[]*?" ) ] ? 1 : 0;
|
| 738 |
+
}
|
| 739 |
+
|
| 740 |
+
|
| 741 |
+
/*
|
| 742 |
+
* append_if_exists() - if file exists, append it to the list
|
| 743 |
+
*/
|
| 744 |
+
|
| 745 |
+
static LIST * append_if_exists( LIST * list, OBJECT * file )
|
| 746 |
+
{
|
| 747 |
+
return file_query( file )
|
| 748 |
+
? list_push_back( list, object_copy( file ) )
|
| 749 |
+
: list ;
|
| 750 |
+
}
|
| 751 |
+
|
| 752 |
+
|
| 753 |
+
LIST * glob1( OBJECT * dirname, OBJECT * pattern )
|
| 754 |
+
{
|
| 755 |
+
LIST * const plist = list_new( object_copy( pattern ) );
|
| 756 |
+
struct globbing globbing;
|
| 757 |
+
|
| 758 |
+
globbing.results = L0;
|
| 759 |
+
globbing.patterns = plist;
|
| 760 |
+
|
| 761 |
+
globbing.case_insensitive
|
| 762 |
+
# if defined( OS_NT ) || defined( OS_CYGWIN )
|
| 763 |
+
= plist; /* always case-insensitive if any files can be found */
|
| 764 |
+
# else
|
| 765 |
+
= L0;
|
| 766 |
+
# endif
|
| 767 |
+
|
| 768 |
+
if ( globbing.case_insensitive )
|
| 769 |
+
globbing.patterns = downcase_list( plist );
|
| 770 |
+
|
| 771 |
+
file_dirscan( dirname, builtin_glob_back, &globbing );
|
| 772 |
+
|
| 773 |
+
if ( globbing.case_insensitive )
|
| 774 |
+
list_free( globbing.patterns );
|
| 775 |
+
|
| 776 |
+
list_free( plist );
|
| 777 |
+
|
| 778 |
+
return globbing.results;
|
| 779 |
+
}
|
| 780 |
+
|
| 781 |
+
|
| 782 |
+
LIST * glob_recursive( char const * pattern )
|
| 783 |
+
{
|
| 784 |
+
LIST * result = L0;
|
| 785 |
+
|
| 786 |
+
/* Check if there's metacharacters in pattern */
|
| 787 |
+
if ( !has_wildcards( pattern ) )
|
| 788 |
+
{
|
| 789 |
+
/* No metacharacters. Check if the path exists. */
|
| 790 |
+
OBJECT * const p = object_new( pattern );
|
| 791 |
+
result = append_if_exists( result, p );
|
| 792 |
+
object_free( p );
|
| 793 |
+
}
|
| 794 |
+
else
|
| 795 |
+
{
|
| 796 |
+
/* Have metacharacters in the pattern. Split into dir/name. */
|
| 797 |
+
PATHNAME path[ 1 ];
|
| 798 |
+
path_parse( pattern, path );
|
| 799 |
+
|
| 800 |
+
if ( path->f_dir.ptr )
|
| 801 |
+
{
|
| 802 |
+
LIST * dirs = L0;
|
| 803 |
+
string dirname[ 1 ];
|
| 804 |
+
string basename[ 1 ];
|
| 805 |
+
string_new( dirname );
|
| 806 |
+
string_new( basename );
|
| 807 |
+
|
| 808 |
+
string_append_range( dirname, path->f_dir.ptr,
|
| 809 |
+
path->f_dir.ptr + path->f_dir.len );
|
| 810 |
+
|
| 811 |
+
path->f_grist.ptr = 0;
|
| 812 |
+
path->f_grist.len = 0;
|
| 813 |
+
path->f_dir.ptr = 0;
|
| 814 |
+
path->f_dir.len = 0;
|
| 815 |
+
path_build( path, basename );
|
| 816 |
+
|
| 817 |
+
dirs = has_wildcards( dirname->value )
|
| 818 |
+
? glob_recursive( dirname->value )
|
| 819 |
+
: list_push_back( dirs, object_new( dirname->value ) );
|
| 820 |
+
|
| 821 |
+
if ( has_wildcards( basename->value ) )
|
| 822 |
+
{
|
| 823 |
+
OBJECT * const b = object_new( basename->value );
|
| 824 |
+
LISTITER iter = list_begin( dirs );
|
| 825 |
+
LISTITER const end = list_end( dirs );
|
| 826 |
+
for ( ; iter != end; iter = list_next( iter ) )
|
| 827 |
+
result = list_append( result, glob1( list_item( iter ), b )
|
| 828 |
+
);
|
| 829 |
+
object_free( b );
|
| 830 |
+
}
|
| 831 |
+
else
|
| 832 |
+
{
|
| 833 |
+
LISTITER iter = list_begin( dirs );
|
| 834 |
+
LISTITER const end = list_end( dirs );
|
| 835 |
+
string file_string[ 1 ];
|
| 836 |
+
string_new( file_string );
|
| 837 |
+
|
| 838 |
+
/* No wildcard in basename. */
|
| 839 |
+
for ( ; iter != end; iter = list_next( iter ) )
|
| 840 |
+
{
|
| 841 |
+
OBJECT * p;
|
| 842 |
+
path->f_dir.ptr = object_str( list_item( iter ) );
|
| 843 |
+
path->f_dir.len = strlen( object_str( list_item( iter ) ) );
|
| 844 |
+
path_build( path, file_string );
|
| 845 |
+
|
| 846 |
+
p = object_new( file_string->value );
|
| 847 |
+
|
| 848 |
+
result = append_if_exists( result, p );
|
| 849 |
+
|
| 850 |
+
object_free( p );
|
| 851 |
+
|
| 852 |
+
string_truncate( file_string, 0 );
|
| 853 |
+
}
|
| 854 |
+
|
| 855 |
+
string_free( file_string );
|
| 856 |
+
}
|
| 857 |
+
|
| 858 |
+
string_free( dirname );
|
| 859 |
+
string_free( basename );
|
| 860 |
+
|
| 861 |
+
list_free( dirs );
|
| 862 |
+
}
|
| 863 |
+
else
|
| 864 |
+
{
|
| 865 |
+
/* No directory, just a pattern. */
|
| 866 |
+
OBJECT * const p = object_new( pattern );
|
| 867 |
+
result = list_append( result, glob1( constant_dot, p ) );
|
| 868 |
+
object_free( p );
|
| 869 |
+
}
|
| 870 |
+
}
|
| 871 |
+
|
| 872 |
+
return result;
|
| 873 |
+
}
|
| 874 |
+
|
| 875 |
+
|
| 876 |
+
/*
|
| 877 |
+
* builtin_glob_recursive() - ???
|
| 878 |
+
*/
|
| 879 |
+
|
| 880 |
+
LIST * builtin_glob_recursive( FRAME * frame, int flags )
|
| 881 |
+
{
|
| 882 |
+
LIST * result = L0;
|
| 883 |
+
LIST * const l = lol_get( frame->args, 0 );
|
| 884 |
+
LISTITER iter = list_begin( l );
|
| 885 |
+
LISTITER const end = list_end( l );
|
| 886 |
+
for ( ; iter != end; iter = list_next( iter ) )
|
| 887 |
+
result = list_append( result, glob_recursive( object_str( list_item(
|
| 888 |
+
iter ) ) ) );
|
| 889 |
+
return result;
|
| 890 |
+
}
|
| 891 |
+
|
| 892 |
+
|
| 893 |
+
/*
|
| 894 |
+
* builtin_match() - MATCH rule, regexp matching
|
| 895 |
+
*/
|
| 896 |
+
|
| 897 |
+
LIST * builtin_match( FRAME * frame, int flags )
|
| 898 |
+
{
|
| 899 |
+
LIST * l;
|
| 900 |
+
LIST * r;
|
| 901 |
+
LIST * result = L0;
|
| 902 |
+
LISTITER l_iter;
|
| 903 |
+
LISTITER l_end;
|
| 904 |
+
LISTITER r_iter;
|
| 905 |
+
LISTITER r_end;
|
| 906 |
+
|
| 907 |
+
string buf[ 1 ];
|
| 908 |
+
string_new( buf );
|
| 909 |
+
|
| 910 |
+
/* For each pattern */
|
| 911 |
+
|
| 912 |
+
l = lol_get( frame->args, 0 );
|
| 913 |
+
l_iter = list_begin( l );
|
| 914 |
+
l_end = list_end( l );
|
| 915 |
+
for ( ; l_iter != l_end; l_iter = list_next( l_iter ) )
|
| 916 |
+
{
|
| 917 |
+
/* Result is cached and intentionally never freed. */
|
| 918 |
+
regexp * re = regex_compile( list_item( l_iter ) );
|
| 919 |
+
|
| 920 |
+
/* For each string to match against. */
|
| 921 |
+
r = lol_get( frame->args, 1 );
|
| 922 |
+
r_iter = list_begin( r );
|
| 923 |
+
r_end = list_end( r );
|
| 924 |
+
for ( ; r_iter != r_end; r_iter = list_next( r_iter ) )
|
| 925 |
+
{
|
| 926 |
+
if ( regexec( re, object_str( list_item( r_iter ) ) ) )
|
| 927 |
+
{
|
| 928 |
+
int i;
|
| 929 |
+
int top;
|
| 930 |
+
|
| 931 |
+
/* Find highest parameter */
|
| 932 |
+
|
| 933 |
+
for ( top = NSUBEXP; top-- > 1; )
|
| 934 |
+
if ( re->startp[ top ] )
|
| 935 |
+
break;
|
| 936 |
+
|
| 937 |
+
/* And add all parameters up to highest onto list. */
|
| 938 |
+
/* Must have parameters to have results! */
|
| 939 |
+
for ( i = 1; i <= top; ++i )
|
| 940 |
+
{
|
| 941 |
+
string_append_range( buf, re->startp[ i ], re->endp[ i ] );
|
| 942 |
+
result = list_push_back( result, object_new( buf->value ) );
|
| 943 |
+
string_truncate( buf, 0 );
|
| 944 |
+
}
|
| 945 |
+
}
|
| 946 |
+
}
|
| 947 |
+
}
|
| 948 |
+
|
| 949 |
+
string_free( buf );
|
| 950 |
+
return result;
|
| 951 |
+
}
|
| 952 |
+
|
| 953 |
+
|
| 954 |
+
/*
|
| 955 |
+
* builtin_split_by_characters() - splits the given string into tokens
|
| 956 |
+
*/
|
| 957 |
+
|
| 958 |
+
LIST * builtin_split_by_characters( FRAME * frame, int flags )
|
| 959 |
+
{
|
| 960 |
+
LIST * l1 = lol_get( frame->args, 0 );
|
| 961 |
+
LIST * l2 = lol_get( frame->args, 1 );
|
| 962 |
+
|
| 963 |
+
LIST * result = L0;
|
| 964 |
+
|
| 965 |
+
string buf[ 1 ];
|
| 966 |
+
|
| 967 |
+
char const * delimiters = object_str( list_front( l2 ) );
|
| 968 |
+
char * t;
|
| 969 |
+
|
| 970 |
+
string_copy( buf, object_str( list_front( l1 ) ) );
|
| 971 |
+
|
| 972 |
+
t = strtok( buf->value, delimiters );
|
| 973 |
+
while ( t )
|
| 974 |
+
{
|
| 975 |
+
result = list_push_back( result, object_new( t ) );
|
| 976 |
+
t = strtok( NULL, delimiters );
|
| 977 |
+
}
|
| 978 |
+
|
| 979 |
+
string_free( buf );
|
| 980 |
+
|
| 981 |
+
return result;
|
| 982 |
+
}
|
| 983 |
+
|
| 984 |
+
|
| 985 |
+
/*
|
| 986 |
+
* builtin_hdrmacro() - ???
|
| 987 |
+
*/
|
| 988 |
+
|
| 989 |
+
LIST * builtin_hdrmacro( FRAME * frame, int flags )
|
| 990 |
+
{
|
| 991 |
+
LIST * const l = lol_get( frame->args, 0 );
|
| 992 |
+
LISTITER iter = list_begin( l );
|
| 993 |
+
LISTITER const end = list_end( l );
|
| 994 |
+
|
| 995 |
+
for ( ; iter != end; iter = list_next( iter ) )
|
| 996 |
+
{
|
| 997 |
+
TARGET * const t = bindtarget( list_item( iter ) );
|
| 998 |
+
|
| 999 |
+
/* Scan file for header filename macro definitions. */
|
| 1000 |
+
if ( DEBUG_HEADER )
|
| 1001 |
+
printf( "scanning '%s' for header file macro definitions\n",
|
| 1002 |
+
object_str( list_item( iter ) ) );
|
| 1003 |
+
|
| 1004 |
+
macro_headers( t );
|
| 1005 |
+
}
|
| 1006 |
+
|
| 1007 |
+
return L0;
|
| 1008 |
+
}
|
| 1009 |
+
|
| 1010 |
+
|
| 1011 |
+
/*
|
| 1012 |
+
* builtin_rulenames() - RULENAMES ( MODULE ? )
|
| 1013 |
+
*
|
| 1014 |
+
* Returns a list of the non-local rule names in the given MODULE. If MODULE is
|
| 1015 |
+
* not supplied, returns the list of rule names in the global module.
|
| 1016 |
+
*/
|
| 1017 |
+
|
| 1018 |
+
static void add_rule_name( void * r_, void * result_ )
|
| 1019 |
+
{
|
| 1020 |
+
RULE * const r = (RULE *)r_;
|
| 1021 |
+
LIST * * const result = (LIST * *)result_;
|
| 1022 |
+
if ( r->exported )
|
| 1023 |
+
*result = list_push_back( *result, object_copy( r->name ) );
|
| 1024 |
+
}
|
| 1025 |
+
|
| 1026 |
+
|
| 1027 |
+
LIST * builtin_rulenames( FRAME * frame, int flags )
|
| 1028 |
+
{
|
| 1029 |
+
LIST * arg0 = lol_get( frame->args, 0 );
|
| 1030 |
+
LIST * result = L0;
|
| 1031 |
+
module_t * const source_module = bindmodule( list_empty( arg0 )
|
| 1032 |
+
? 0
|
| 1033 |
+
: list_front( arg0 ) );
|
| 1034 |
+
|
| 1035 |
+
if ( source_module->rules )
|
| 1036 |
+
hashenumerate( source_module->rules, add_rule_name, &result );
|
| 1037 |
+
return result;
|
| 1038 |
+
}
|
| 1039 |
+
|
| 1040 |
+
|
| 1041 |
+
/*
|
| 1042 |
+
* builtin_varnames() - VARNAMES ( MODULE ? )
|
| 1043 |
+
*
|
| 1044 |
+
* Returns a list of the variable names in the given MODULE. If MODULE is not
|
| 1045 |
+
* supplied, returns the list of variable names in the global module.
|
| 1046 |
+
*/
|
| 1047 |
+
|
| 1048 |
+
/* helper function for builtin_varnames(), below. Used with hashenumerate, will
|
| 1049 |
+
* prepend the key of each element to the list
|
| 1050 |
+
*/
|
| 1051 |
+
static void add_hash_key( void * np, void * result_ )
|
| 1052 |
+
{
|
| 1053 |
+
LIST * * result = (LIST * *)result_;
|
| 1054 |
+
*result = list_push_back( *result, object_copy( *(OBJECT * *)np ) );
|
| 1055 |
+
}
|
| 1056 |
+
|
| 1057 |
+
|
| 1058 |
+
LIST * builtin_varnames( FRAME * frame, int flags )
|
| 1059 |
+
{
|
| 1060 |
+
LIST * arg0 = lol_get( frame->args, 0 );
|
| 1061 |
+
LIST * result = L0;
|
| 1062 |
+
module_t * source_module = bindmodule( list_empty( arg0 )
|
| 1063 |
+
? 0
|
| 1064 |
+
: list_front( arg0 ) );
|
| 1065 |
+
|
| 1066 |
+
struct hash * const vars = source_module->variables;
|
| 1067 |
+
if ( vars )
|
| 1068 |
+
hashenumerate( vars, add_hash_key, &result );
|
| 1069 |
+
return result;
|
| 1070 |
+
}
|
| 1071 |
+
|
| 1072 |
+
|
| 1073 |
+
/*
|
| 1074 |
+
* builtin_delete_module() - DELETE_MODULE ( MODULE ? )
|
| 1075 |
+
*
|
| 1076 |
+
* Clears all rules and variables from the given module.
|
| 1077 |
+
*/
|
| 1078 |
+
|
| 1079 |
+
LIST * builtin_delete_module( FRAME * frame, int flags )
|
| 1080 |
+
{
|
| 1081 |
+
LIST * const arg0 = lol_get( frame->args, 0 );
|
| 1082 |
+
module_t * const source_module = bindmodule( list_empty( arg0 ) ? 0 :
|
| 1083 |
+
list_front( arg0 ) );
|
| 1084 |
+
delete_module( source_module );
|
| 1085 |
+
return L0;
|
| 1086 |
+
}
|
| 1087 |
+
|
| 1088 |
+
|
| 1089 |
+
/*
|
| 1090 |
+
* unknown_rule() - reports an unknown rule occurrence to the user and exits
|
| 1091 |
+
*/
|
| 1092 |
+
|
| 1093 |
+
void unknown_rule( FRAME * frame, char const * key, module_t * module,
|
| 1094 |
+
OBJECT * rule_name )
|
| 1095 |
+
{
|
| 1096 |
+
backtrace_line( frame->prev );
|
| 1097 |
+
if ( key )
|
| 1098 |
+
printf("%s error", key);
|
| 1099 |
+
else
|
| 1100 |
+
printf("ERROR");
|
| 1101 |
+
printf( ": rule \"%s\" unknown in ", object_str( rule_name ) );
|
| 1102 |
+
if ( module->name )
|
| 1103 |
+
printf( "module \"%s\".\n", object_str( module->name ) );
|
| 1104 |
+
else
|
| 1105 |
+
printf( "root module.\n" );
|
| 1106 |
+
backtrace( frame->prev );
|
| 1107 |
+
exit( 1 );
|
| 1108 |
+
}
|
| 1109 |
+
|
| 1110 |
+
|
| 1111 |
+
/*
|
| 1112 |
+
* builtin_import() - IMPORT rule
|
| 1113 |
+
*
|
| 1114 |
+
* IMPORT
|
| 1115 |
+
* (
|
| 1116 |
+
* SOURCE_MODULE ? :
|
| 1117 |
+
* SOURCE_RULES * :
|
| 1118 |
+
* TARGET_MODULE ? :
|
| 1119 |
+
* TARGET_RULES * :
|
| 1120 |
+
* LOCALIZE ?
|
| 1121 |
+
* )
|
| 1122 |
+
*
|
| 1123 |
+
* Imports rules from the SOURCE_MODULE into the TARGET_MODULE as local rules.
|
| 1124 |
+
* If either SOURCE_MODULE or TARGET_MODULE is not supplied, it refers to the
|
| 1125 |
+
* global module. SOURCE_RULES specifies which rules from the SOURCE_MODULE to
|
| 1126 |
+
* import; TARGET_RULES specifies the names to give those rules in
|
| 1127 |
+
* TARGET_MODULE. If SOURCE_RULES contains a name that does not correspond to
|
| 1128 |
+
* a rule in SOURCE_MODULE, or if it contains a different number of items than
|
| 1129 |
+
* TARGET_RULES, an error is issued. If LOCALIZE is specified, the rules will be
|
| 1130 |
+
* executed in TARGET_MODULE, with corresponding access to its module local
|
| 1131 |
+
* variables.
|
| 1132 |
+
*/
|
| 1133 |
+
|
| 1134 |
+
LIST * builtin_import( FRAME * frame, int flags )
|
| 1135 |
+
{
|
| 1136 |
+
LIST * source_module_list = lol_get( frame->args, 0 );
|
| 1137 |
+
LIST * source_rules = lol_get( frame->args, 1 );
|
| 1138 |
+
LIST * target_module_list = lol_get( frame->args, 2 );
|
| 1139 |
+
LIST * target_rules = lol_get( frame->args, 3 );
|
| 1140 |
+
LIST * localize = lol_get( frame->args, 4 );
|
| 1141 |
+
|
| 1142 |
+
module_t * target_module = bindmodule( list_empty( target_module_list )
|
| 1143 |
+
? 0
|
| 1144 |
+
: list_front( target_module_list ) );
|
| 1145 |
+
module_t * source_module = bindmodule( list_empty( source_module_list )
|
| 1146 |
+
? 0
|
| 1147 |
+
: list_front( source_module_list ) );
|
| 1148 |
+
|
| 1149 |
+
LISTITER source_iter = list_begin( source_rules );
|
| 1150 |
+
LISTITER const source_end = list_end( source_rules );
|
| 1151 |
+
LISTITER target_iter = list_begin( target_rules );
|
| 1152 |
+
LISTITER const target_end = list_end( target_rules );
|
| 1153 |
+
|
| 1154 |
+
for ( ;
|
| 1155 |
+
source_iter != source_end && target_iter != target_end;
|
| 1156 |
+
source_iter = list_next( source_iter ),
|
| 1157 |
+
target_iter = list_next( target_iter ) )
|
| 1158 |
+
{
|
| 1159 |
+
RULE * r;
|
| 1160 |
+
RULE * imported;
|
| 1161 |
+
|
| 1162 |
+
if ( !source_module->rules || !(r = (RULE *)hash_find(
|
| 1163 |
+
source_module->rules, list_item( source_iter ) ) ) )
|
| 1164 |
+
unknown_rule( frame, "IMPORT", source_module, list_item( source_iter
|
| 1165 |
+
) );
|
| 1166 |
+
|
| 1167 |
+
imported = import_rule( r, target_module, list_item( target_iter ) );
|
| 1168 |
+
if ( !list_empty( localize ) )
|
| 1169 |
+
rule_localize( imported, target_module );
|
| 1170 |
+
/* This rule is really part of some other module. Just refer to it here,
|
| 1171 |
+
* but do not let it out.
|
| 1172 |
+
*/
|
| 1173 |
+
imported->exported = 0;
|
| 1174 |
+
}
|
| 1175 |
+
|
| 1176 |
+
if ( source_iter != source_end || target_iter != target_end )
|
| 1177 |
+
{
|
| 1178 |
+
backtrace_line( frame->prev );
|
| 1179 |
+
printf( "import error: length of source and target rule name lists "
|
| 1180 |
+
"don't match!\n" );
|
| 1181 |
+
printf( " source: " );
|
| 1182 |
+
list_print( source_rules );
|
| 1183 |
+
printf( "\n target: " );
|
| 1184 |
+
list_print( target_rules );
|
| 1185 |
+
printf( "\n" );
|
| 1186 |
+
backtrace( frame->prev );
|
| 1187 |
+
exit( 1 );
|
| 1188 |
+
}
|
| 1189 |
+
|
| 1190 |
+
return L0;
|
| 1191 |
+
}
|
| 1192 |
+
|
| 1193 |
+
|
| 1194 |
+
/*
|
| 1195 |
+
* builtin_export() - EXPORT ( MODULE ? : RULES * )
|
| 1196 |
+
*
|
| 1197 |
+
* The EXPORT rule marks RULES from the SOURCE_MODULE as non-local (and thus
|
| 1198 |
+
* exportable). If an element of RULES does not name a rule in MODULE, an error
|
| 1199 |
+
* is issued.
|
| 1200 |
+
*/
|
| 1201 |
+
|
| 1202 |
+
LIST * builtin_export( FRAME * frame, int flags )
|
| 1203 |
+
{
|
| 1204 |
+
LIST * const module_list = lol_get( frame->args, 0 );
|
| 1205 |
+
LIST * const rules = lol_get( frame->args, 1 );
|
| 1206 |
+
module_t * const m = bindmodule( list_empty( module_list ) ? 0 : list_front(
|
| 1207 |
+
module_list ) );
|
| 1208 |
+
|
| 1209 |
+
LISTITER iter = list_begin( rules );
|
| 1210 |
+
LISTITER const end = list_end( rules );
|
| 1211 |
+
for ( ; iter != end; iter = list_next( iter ) )
|
| 1212 |
+
{
|
| 1213 |
+
RULE * r;
|
| 1214 |
+
if ( !m->rules || !( r = (RULE *)hash_find( m->rules, list_item( iter )
|
| 1215 |
+
) ) )
|
| 1216 |
+
unknown_rule( frame, "EXPORT", m, list_item( iter ) );
|
| 1217 |
+
r->exported = 1;
|
| 1218 |
+
}
|
| 1219 |
+
return L0;
|
| 1220 |
+
}
|
| 1221 |
+
|
| 1222 |
+
|
| 1223 |
+
/*
|
| 1224 |
+
* get_source_line() - get a frame's file and line number information
|
| 1225 |
+
*
|
| 1226 |
+
* This is the execution traceback information to be indicated for in debug
|
| 1227 |
+
* output or an error backtrace.
|
| 1228 |
+
*/
|
| 1229 |
+
|
| 1230 |
+
static void get_source_line( FRAME * frame, char const * * file, int * line )
|
| 1231 |
+
{
|
| 1232 |
+
if ( frame->file )
|
| 1233 |
+
{
|
| 1234 |
+
char const * f = object_str( frame->file );
|
| 1235 |
+
int l = frame->line;
|
| 1236 |
+
if ( !strcmp( f, "+" ) )
|
| 1237 |
+
{
|
| 1238 |
+
f = "jambase.c";
|
| 1239 |
+
l += 3;
|
| 1240 |
+
}
|
| 1241 |
+
*file = f;
|
| 1242 |
+
*line = l;
|
| 1243 |
+
}
|
| 1244 |
+
else
|
| 1245 |
+
{
|
| 1246 |
+
*file = "(builtin)";
|
| 1247 |
+
*line = -1;
|
| 1248 |
+
}
|
| 1249 |
+
}
|
| 1250 |
+
|
| 1251 |
+
|
| 1252 |
+
void print_source_line( FRAME * frame )
|
| 1253 |
+
{
|
| 1254 |
+
char const * file;
|
| 1255 |
+
int line;
|
| 1256 |
+
get_source_line( frame, &file, &line );
|
| 1257 |
+
if ( line < 0 )
|
| 1258 |
+
printf( "(builtin):" );
|
| 1259 |
+
else
|
| 1260 |
+
printf( "%s:%d:", file, line );
|
| 1261 |
+
}
|
| 1262 |
+
|
| 1263 |
+
|
| 1264 |
+
/*
|
| 1265 |
+
* backtrace_line() - print a single line of error backtrace for the given
|
| 1266 |
+
* frame.
|
| 1267 |
+
*/
|
| 1268 |
+
|
| 1269 |
+
void backtrace_line( FRAME * frame )
|
| 1270 |
+
{
|
| 1271 |
+
if ( frame == 0 )
|
| 1272 |
+
{
|
| 1273 |
+
printf( "(no frame):" );
|
| 1274 |
+
}
|
| 1275 |
+
else
|
| 1276 |
+
{
|
| 1277 |
+
print_source_line( frame );
|
| 1278 |
+
printf( " in %s\n", frame->rulename );
|
| 1279 |
+
}
|
| 1280 |
+
}
|
| 1281 |
+
|
| 1282 |
+
|
| 1283 |
+
/*
|
| 1284 |
+
* backtrace() - Print the entire backtrace from the given frame to the Jambase
|
| 1285 |
+
* which invoked it.
|
| 1286 |
+
*/
|
| 1287 |
+
|
| 1288 |
+
void backtrace( FRAME * frame )
|
| 1289 |
+
{
|
| 1290 |
+
if ( !frame ) return;
|
| 1291 |
+
while ( ( frame = frame->prev ) )
|
| 1292 |
+
backtrace_line( frame );
|
| 1293 |
+
}
|
| 1294 |
+
|
| 1295 |
+
|
| 1296 |
+
/*
|
| 1297 |
+
* builtin_backtrace() - A Jam version of the backtrace function, taking no
|
| 1298 |
+
* arguments and returning a list of quadruples: FILENAME LINE MODULE. RULENAME
|
| 1299 |
+
* describing each frame. Note that the module-name is always followed by a
|
| 1300 |
+
* period.
|
| 1301 |
+
*/
|
| 1302 |
+
|
| 1303 |
+
LIST * builtin_backtrace( FRAME * frame, int flags )
|
| 1304 |
+
{
|
| 1305 |
+
LIST * const levels_arg = lol_get( frame->args, 0 );
|
| 1306 |
+
int levels = list_empty( levels_arg )
|
| 1307 |
+
? (int)( (unsigned int)(-1) >> 1 )
|
| 1308 |
+
: atoi( object_str( list_front( levels_arg ) ) );
|
| 1309 |
+
|
| 1310 |
+
LIST * result = L0;
|
| 1311 |
+
for ( ; ( frame = frame->prev ) && levels; --levels )
|
| 1312 |
+
{
|
| 1313 |
+
char const * file;
|
| 1314 |
+
int line;
|
| 1315 |
+
char buf[ 32 ];
|
| 1316 |
+
string module_name[ 1 ];
|
| 1317 |
+
get_source_line( frame, &file, &line );
|
| 1318 |
+
sprintf( buf, "%d", line );
|
| 1319 |
+
string_new( module_name );
|
| 1320 |
+
if ( frame->module->name )
|
| 1321 |
+
{
|
| 1322 |
+
string_append( module_name, object_str( frame->module->name ) );
|
| 1323 |
+
string_append( module_name, "." );
|
| 1324 |
+
}
|
| 1325 |
+
result = list_push_back( result, object_new( file ) );
|
| 1326 |
+
result = list_push_back( result, object_new( buf ) );
|
| 1327 |
+
result = list_push_back( result, object_new( module_name->value ) );
|
| 1328 |
+
result = list_push_back( result, object_new( frame->rulename ) );
|
| 1329 |
+
string_free( module_name );
|
| 1330 |
+
}
|
| 1331 |
+
return result;
|
| 1332 |
+
}
|
| 1333 |
+
|
| 1334 |
+
|
| 1335 |
+
/*
|
| 1336 |
+
* builtin_caller_module() - CALLER_MODULE ( levels ? )
|
| 1337 |
+
*
|
| 1338 |
+
* If levels is not supplied, returns the name of the module of the rule which
|
| 1339 |
+
* called the one calling this one. If levels is supplied, it is interpreted as
|
| 1340 |
+
* an integer specifying a number of additional levels of call stack to traverse
|
| 1341 |
+
* in order to locate the module in question. If no such module exists, returns
|
| 1342 |
+
* the empty list. Also returns the empty list when the module in question is
|
| 1343 |
+
* the global module. This rule is needed for implementing module import
|
| 1344 |
+
* behavior.
|
| 1345 |
+
*/
|
| 1346 |
+
|
| 1347 |
+
LIST * builtin_caller_module( FRAME * frame, int flags )
|
| 1348 |
+
{
|
| 1349 |
+
LIST * const levels_arg = lol_get( frame->args, 0 );
|
| 1350 |
+
int const levels = list_empty( levels_arg )
|
| 1351 |
+
? 0
|
| 1352 |
+
: atoi( object_str( list_front( levels_arg ) ) );
|
| 1353 |
+
|
| 1354 |
+
int i;
|
| 1355 |
+
for ( i = 0; ( i < levels + 2 ) && frame->prev; ++i )
|
| 1356 |
+
frame = frame->prev;
|
| 1357 |
+
|
| 1358 |
+
return frame->module == root_module()
|
| 1359 |
+
? L0
|
| 1360 |
+
: list_new( object_copy( frame->module->name ) );
|
| 1361 |
+
}
|
| 1362 |
+
|
| 1363 |
+
|
| 1364 |
+
/*
|
| 1365 |
+
* Return the current working directory.
|
| 1366 |
+
*
|
| 1367 |
+
* Usage: pwd = [ PWD ] ;
|
| 1368 |
+
*/
|
| 1369 |
+
|
| 1370 |
+
LIST * builtin_pwd( FRAME * frame, int flags )
|
| 1371 |
+
{
|
| 1372 |
+
return list_new( object_copy( cwd() ) );
|
| 1373 |
+
}
|
| 1374 |
+
|
| 1375 |
+
|
| 1376 |
+
/*
|
| 1377 |
+
* Adds targets to the list of target that jam will attempt to update.
|
| 1378 |
+
*/
|
| 1379 |
+
|
| 1380 |
+
LIST * builtin_update( FRAME * frame, int flags )
|
| 1381 |
+
{
|
| 1382 |
+
LIST * result = list_copy( targets_to_update() );
|
| 1383 |
+
LIST * arg1 = lol_get( frame->args, 0 );
|
| 1384 |
+
LISTITER iter = list_begin( arg1 ), end = list_end( arg1 );
|
| 1385 |
+
clear_targets_to_update();
|
| 1386 |
+
for ( ; iter != end; iter = list_next( iter ) )
|
| 1387 |
+
mark_target_for_updating( object_copy( list_item( iter ) ) );
|
| 1388 |
+
return result;
|
| 1389 |
+
}
|
| 1390 |
+
|
| 1391 |
+
extern int anyhow;
|
| 1392 |
+
int last_update_now_status;
|
| 1393 |
+
|
| 1394 |
+
/* Takes a list of target names and immediately updates them.
|
| 1395 |
+
*
|
| 1396 |
+
* Parameters:
|
| 1397 |
+
* 1. Target list.
|
| 1398 |
+
* 2. Optional file descriptor (converted to a string) for a log file where all
|
| 1399 |
+
* the related build output should be redirected.
|
| 1400 |
+
* 3. If specified, makes the build temporarily disable the -n option, i.e.
|
| 1401 |
+
* forces all needed out-of-date targets to be rebuilt.
|
| 1402 |
+
* 4. If specified, makes the build temporarily disable the -q option, i.e.
|
| 1403 |
+
* forces the build to continue even if one of the targets fails to build.
|
| 1404 |
+
*/
|
| 1405 |
+
LIST * builtin_update_now( FRAME * frame, int flags )
|
| 1406 |
+
{
|
| 1407 |
+
LIST * targets = lol_get( frame->args, 0 );
|
| 1408 |
+
LIST * log = lol_get( frame->args, 1 );
|
| 1409 |
+
LIST * force = lol_get( frame->args, 2 );
|
| 1410 |
+
LIST * continue_ = lol_get( frame->args, 3 );
|
| 1411 |
+
int status;
|
| 1412 |
+
int original_stdout = 0;
|
| 1413 |
+
int original_stderr = 0;
|
| 1414 |
+
int original_noexec = 0;
|
| 1415 |
+
int original_quitquick = 0;
|
| 1416 |
+
|
| 1417 |
+
if ( !list_empty( log ) )
|
| 1418 |
+
{
|
| 1419 |
+
/* Temporarily redirect stdout and stderr to the given log file. */
|
| 1420 |
+
int const fd = atoi( object_str( list_front( log ) ) );
|
| 1421 |
+
original_stdout = dup( 0 );
|
| 1422 |
+
original_stderr = dup( 1 );
|
| 1423 |
+
dup2( fd, 0 );
|
| 1424 |
+
dup2( fd, 1 );
|
| 1425 |
+
}
|
| 1426 |
+
|
| 1427 |
+
if ( !list_empty( force ) )
|
| 1428 |
+
{
|
| 1429 |
+
original_noexec = globs.noexec;
|
| 1430 |
+
globs.noexec = 0;
|
| 1431 |
+
}
|
| 1432 |
+
|
| 1433 |
+
if ( !list_empty( continue_ ) )
|
| 1434 |
+
{
|
| 1435 |
+
original_quitquick = globs.quitquick;
|
| 1436 |
+
globs.quitquick = 0;
|
| 1437 |
+
}
|
| 1438 |
+
|
| 1439 |
+
status = make( targets, anyhow );
|
| 1440 |
+
|
| 1441 |
+
if ( !list_empty( force ) )
|
| 1442 |
+
{
|
| 1443 |
+
globs.noexec = original_noexec;
|
| 1444 |
+
}
|
| 1445 |
+
|
| 1446 |
+
if ( !list_empty( continue_ ) )
|
| 1447 |
+
{
|
| 1448 |
+
globs.quitquick = original_quitquick;
|
| 1449 |
+
}
|
| 1450 |
+
|
| 1451 |
+
if ( !list_empty( log ) )
|
| 1452 |
+
{
|
| 1453 |
+
/* Flush whatever stdio might have buffered, while descriptions 0 and 1
|
| 1454 |
+
* still refer to the log file.
|
| 1455 |
+
*/
|
| 1456 |
+
fflush( stdout );
|
| 1457 |
+
fflush( stderr );
|
| 1458 |
+
dup2( original_stdout, 0 );
|
| 1459 |
+
dup2( original_stderr, 1 );
|
| 1460 |
+
close( original_stdout );
|
| 1461 |
+
close( original_stderr );
|
| 1462 |
+
}
|
| 1463 |
+
|
| 1464 |
+
last_update_now_status = status;
|
| 1465 |
+
|
| 1466 |
+
return status ? L0 : list_new( object_copy( constant_ok ) );
|
| 1467 |
+
}
|
| 1468 |
+
|
| 1469 |
+
|
| 1470 |
+
LIST * builtin_import_module( FRAME * frame, int flags )
|
| 1471 |
+
{
|
| 1472 |
+
LIST * const arg1 = lol_get( frame->args, 0 );
|
| 1473 |
+
LIST * const arg2 = lol_get( frame->args, 1 );
|
| 1474 |
+
module_t * const m = list_empty( arg2 )
|
| 1475 |
+
? root_module()
|
| 1476 |
+
: bindmodule( list_front( arg2 ) );
|
| 1477 |
+
import_module( arg1, m );
|
| 1478 |
+
return L0;
|
| 1479 |
+
}
|
| 1480 |
+
|
| 1481 |
+
|
| 1482 |
+
LIST * builtin_imported_modules( FRAME * frame, int flags )
|
| 1483 |
+
{
|
| 1484 |
+
LIST * const arg0 = lol_get( frame->args, 0 );
|
| 1485 |
+
OBJECT * const module = list_empty( arg0 ) ? 0 : list_front( arg0 );
|
| 1486 |
+
return imported_modules( bindmodule( module ) );
|
| 1487 |
+
}
|
| 1488 |
+
|
| 1489 |
+
|
| 1490 |
+
LIST * builtin_instance( FRAME * frame, int flags )
|
| 1491 |
+
{
|
| 1492 |
+
LIST * arg1 = lol_get( frame->args, 0 );
|
| 1493 |
+
LIST * arg2 = lol_get( frame->args, 1 );
|
| 1494 |
+
module_t * const instance = bindmodule( list_front( arg1 ) );
|
| 1495 |
+
module_t * const class_module = bindmodule( list_front( arg2 ) );
|
| 1496 |
+
instance->class_module = class_module;
|
| 1497 |
+
module_set_fixed_variables( instance, class_module->num_fixed_variables );
|
| 1498 |
+
return L0;
|
| 1499 |
+
}
|
| 1500 |
+
|
| 1501 |
+
|
| 1502 |
+
LIST * builtin_sort( FRAME * frame, int flags )
|
| 1503 |
+
{
|
| 1504 |
+
return list_sort( lol_get( frame->args, 0 ) );
|
| 1505 |
+
}
|
| 1506 |
+
|
| 1507 |
+
|
| 1508 |
+
LIST * builtin_normalize_path( FRAME * frame, int flags )
|
| 1509 |
+
{
|
| 1510 |
+
LIST * arg = lol_get( frame->args, 0 );
|
| 1511 |
+
|
| 1512 |
+
/* First, we iterate over all '/'-separated elements, starting from the end
|
| 1513 |
+
* of string. If we see a '..', we remove a preceeding path element. If we
|
| 1514 |
+
* see '.', we remove it. Removal is done by overwriting data using '\1'
|
| 1515 |
+
* characters. After the whole string has been processed, we do a second
|
| 1516 |
+
* pass, removing any entered '\1' characters.
|
| 1517 |
+
*/
|
| 1518 |
+
|
| 1519 |
+
string in[ 1 ];
|
| 1520 |
+
string out[ 1 ];
|
| 1521 |
+
/* Last character of the part of string still to be processed. */
|
| 1522 |
+
char * end;
|
| 1523 |
+
/* Working pointer. */
|
| 1524 |
+
char * current;
|
| 1525 |
+
/* Number of '..' elements seen and not processed yet. */
|
| 1526 |
+
int dotdots = 0;
|
| 1527 |
+
int rooted = 0;
|
| 1528 |
+
OBJECT * result = 0;
|
| 1529 |
+
LISTITER arg_iter = list_begin( arg );
|
| 1530 |
+
LISTITER arg_end = list_end( arg );
|
| 1531 |
+
|
| 1532 |
+
/* Make a copy of input: we should not change it. Prepend a '/' before it as
|
| 1533 |
+
* a guard for the algorithm later on and remember whether it was originally
|
| 1534 |
+
* rooted or not.
|
| 1535 |
+
*/
|
| 1536 |
+
string_new( in );
|
| 1537 |
+
string_push_back( in, '/' );
|
| 1538 |
+
for ( ; arg_iter != arg_end; arg_iter = list_next( arg_iter ) )
|
| 1539 |
+
{
|
| 1540 |
+
if ( object_str( list_item( arg_iter ) )[ 0 ] != '\0' )
|
| 1541 |
+
{
|
| 1542 |
+
if ( in->size == 1 )
|
| 1543 |
+
rooted = ( object_str( list_item( arg_iter ) )[ 0 ] == '/' ) ||
|
| 1544 |
+
( object_str( list_item( arg_iter ) )[ 0 ] == '\\' );
|
| 1545 |
+
else
|
| 1546 |
+
string_append( in, "/" );
|
| 1547 |
+
string_append( in, object_str( list_item( arg_iter ) ) );
|
| 1548 |
+
}
|
| 1549 |
+
}
|
| 1550 |
+
|
| 1551 |
+
/* Convert \ into /. On Windows, paths using / and \ are equivalent, and we
|
| 1552 |
+
* want this function to obtain a canonic representation.
|
| 1553 |
+
*/
|
| 1554 |
+
for ( current = in->value, end = in->value + in->size;
|
| 1555 |
+
current < end; ++current )
|
| 1556 |
+
if ( *current == '\\' )
|
| 1557 |
+
*current = '/';
|
| 1558 |
+
|
| 1559 |
+
/* Now we remove any extra path elements by overwriting them with '\1'
|
| 1560 |
+
* characters and cound how many more unused '..' path elements there are
|
| 1561 |
+
* remaining. Note that each remaining path element with always starts with
|
| 1562 |
+
* a '/' character.
|
| 1563 |
+
*/
|
| 1564 |
+
for ( end = in->value + in->size - 1; end >= in->value; )
|
| 1565 |
+
{
|
| 1566 |
+
/* Set 'current' to the next occurence of '/', which always exists. */
|
| 1567 |
+
for ( current = end; *current != '/'; --current );
|
| 1568 |
+
|
| 1569 |
+
if ( current == end )
|
| 1570 |
+
{
|
| 1571 |
+
/* Found a trailing or duplicate '/'. Remove it. */
|
| 1572 |
+
*current = '\1';
|
| 1573 |
+
}
|
| 1574 |
+
else if ( ( end - current == 1 ) && ( *( current + 1 ) == '.' ) )
|
| 1575 |
+
{
|
| 1576 |
+
/* Found '/.'. Remove them all. */
|
| 1577 |
+
*current = '\1';
|
| 1578 |
+
*(current + 1) = '\1';
|
| 1579 |
+
}
|
| 1580 |
+
else if ( ( end - current == 2 ) && ( *( current + 1 ) == '.' ) &&
|
| 1581 |
+
( *( current + 2 ) == '.' ) )
|
| 1582 |
+
{
|
| 1583 |
+
/* Found '/..'. Remove them all. */
|
| 1584 |
+
*current = '\1';
|
| 1585 |
+
*(current + 1) = '\1';
|
| 1586 |
+
*(current + 2) = '\1';
|
| 1587 |
+
++dotdots;
|
| 1588 |
+
}
|
| 1589 |
+
else if ( dotdots )
|
| 1590 |
+
{
|
| 1591 |
+
memset( current, '\1', end - current + 1 );
|
| 1592 |
+
--dotdots;
|
| 1593 |
+
}
|
| 1594 |
+
end = current - 1;
|
| 1595 |
+
}
|
| 1596 |
+
|
| 1597 |
+
string_new( out );
|
| 1598 |
+
|
| 1599 |
+
/* Now we know that we need to add exactly dotdots '..' path elements to the
|
| 1600 |
+
* front and that our string is either empty or has a '/' as its first
|
| 1601 |
+
* significant character. If we have any dotdots remaining then the passed
|
| 1602 |
+
* path must not have been rooted or else it is invalid we return an empty
|
| 1603 |
+
* list.
|
| 1604 |
+
*/
|
| 1605 |
+
if ( dotdots )
|
| 1606 |
+
{
|
| 1607 |
+
if ( rooted )
|
| 1608 |
+
{
|
| 1609 |
+
string_free( out );
|
| 1610 |
+
string_free( in );
|
| 1611 |
+
return L0;
|
| 1612 |
+
}
|
| 1613 |
+
do
|
| 1614 |
+
string_append( out, "/.." );
|
| 1615 |
+
while ( --dotdots );
|
| 1616 |
+
}
|
| 1617 |
+
|
| 1618 |
+
/* Now we actually remove all the path characters marked for removal. */
|
| 1619 |
+
for ( current = in->value; *current; ++current )
|
| 1620 |
+
if ( *current != '\1' )
|
| 1621 |
+
string_push_back( out, *current );
|
| 1622 |
+
|
| 1623 |
+
/* Here we know that our string contains no '\1' characters and is either
|
| 1624 |
+
* empty or has a '/' as its initial character. If the original path was not
|
| 1625 |
+
* rooted and we have a non-empty path we need to drop the initial '/'. If
|
| 1626 |
+
* the original path was rooted and we have an empty path we need to add
|
| 1627 |
+
* back the '/'.
|
| 1628 |
+
*/
|
| 1629 |
+
result = object_new( out->size
|
| 1630 |
+
? out->value + !rooted
|
| 1631 |
+
: ( rooted ? "/" : "." ) );
|
| 1632 |
+
|
| 1633 |
+
string_free( out );
|
| 1634 |
+
string_free( in );
|
| 1635 |
+
|
| 1636 |
+
return list_new( result );
|
| 1637 |
+
}
|
| 1638 |
+
|
| 1639 |
+
|
| 1640 |
+
LIST * builtin_native_rule( FRAME * frame, int flags )
|
| 1641 |
+
{
|
| 1642 |
+
LIST * module_name = lol_get( frame->args, 0 );
|
| 1643 |
+
LIST * rule_name = lol_get( frame->args, 1 );
|
| 1644 |
+
|
| 1645 |
+
module_t * module = bindmodule( list_front( module_name ) );
|
| 1646 |
+
|
| 1647 |
+
native_rule_t * np;
|
| 1648 |
+
if ( module->native_rules && (np = (native_rule_t *)hash_find(
|
| 1649 |
+
module->native_rules, list_front( rule_name ) ) ) )
|
| 1650 |
+
{
|
| 1651 |
+
new_rule_body( module, np->name, np->procedure, 1 );
|
| 1652 |
+
}
|
| 1653 |
+
else
|
| 1654 |
+
{
|
| 1655 |
+
backtrace_line( frame->prev );
|
| 1656 |
+
printf( "error: no native rule \"%s\" defined in module \"%s.\"\n",
|
| 1657 |
+
object_str( list_front( rule_name ) ), object_str( module->name ) );
|
| 1658 |
+
backtrace( frame->prev );
|
| 1659 |
+
exit( 1 );
|
| 1660 |
+
}
|
| 1661 |
+
return L0;
|
| 1662 |
+
}
|
| 1663 |
+
|
| 1664 |
+
|
| 1665 |
+
LIST * builtin_has_native_rule( FRAME * frame, int flags )
|
| 1666 |
+
{
|
| 1667 |
+
LIST * module_name = lol_get( frame->args, 0 );
|
| 1668 |
+
LIST * rule_name = lol_get( frame->args, 1 );
|
| 1669 |
+
LIST * version = lol_get( frame->args, 2 );
|
| 1670 |
+
|
| 1671 |
+
module_t * module = bindmodule( list_front( module_name ) );
|
| 1672 |
+
|
| 1673 |
+
native_rule_t * np;
|
| 1674 |
+
if ( module->native_rules && (np = (native_rule_t *)hash_find(
|
| 1675 |
+
module->native_rules, list_front( rule_name ) ) ) )
|
| 1676 |
+
{
|
| 1677 |
+
int expected_version = atoi( object_str( list_front( version ) ) );
|
| 1678 |
+
if ( np->version == expected_version )
|
| 1679 |
+
return list_new( object_copy( constant_true ) );
|
| 1680 |
+
}
|
| 1681 |
+
return L0;
|
| 1682 |
+
}
|
| 1683 |
+
|
| 1684 |
+
|
| 1685 |
+
LIST * builtin_user_module( FRAME * frame, int flags )
|
| 1686 |
+
{
|
| 1687 |
+
LIST * const module_name = lol_get( frame->args, 0 );
|
| 1688 |
+
LISTITER iter = list_begin( module_name );
|
| 1689 |
+
LISTITER const end = list_end( module_name );
|
| 1690 |
+
for ( ; iter != end; iter = list_next( iter ) )
|
| 1691 |
+
bindmodule( list_item( iter ) )->user_module = 1;
|
| 1692 |
+
return L0;
|
| 1693 |
+
}
|
| 1694 |
+
|
| 1695 |
+
|
| 1696 |
+
LIST * builtin_nearest_user_location( FRAME * frame, int flags )
|
| 1697 |
+
{
|
| 1698 |
+
FRAME * const nearest_user_frame = frame->module->user_module
|
| 1699 |
+
? frame
|
| 1700 |
+
: frame->prev_user;
|
| 1701 |
+
if ( !nearest_user_frame )
|
| 1702 |
+
return L0;
|
| 1703 |
+
|
| 1704 |
+
{
|
| 1705 |
+
LIST * result = L0;
|
| 1706 |
+
char const * file;
|
| 1707 |
+
int line;
|
| 1708 |
+
char buf[ 32 ];
|
| 1709 |
+
|
| 1710 |
+
get_source_line( nearest_user_frame, &file, &line );
|
| 1711 |
+
sprintf( buf, "%d", line );
|
| 1712 |
+
result = list_push_back( result, object_new( file ) );
|
| 1713 |
+
result = list_push_back( result, object_new( buf ) );
|
| 1714 |
+
return result;
|
| 1715 |
+
}
|
| 1716 |
+
}
|
| 1717 |
+
|
| 1718 |
+
|
| 1719 |
+
LIST * builtin_check_if_file( FRAME * frame, int flags )
|
| 1720 |
+
{
|
| 1721 |
+
LIST * const name = lol_get( frame->args, 0 );
|
| 1722 |
+
return file_is_file( list_front( name ) ) == 1
|
| 1723 |
+
? list_new( object_copy( constant_true ) )
|
| 1724 |
+
: L0;
|
| 1725 |
+
}
|
| 1726 |
+
|
| 1727 |
+
|
| 1728 |
+
LIST * builtin_md5( FRAME * frame, int flags )
|
| 1729 |
+
{
|
| 1730 |
+
LIST * l = lol_get( frame->args, 0 );
|
| 1731 |
+
char const * s = object_str( list_front( l ) );
|
| 1732 |
+
|
| 1733 |
+
md5_state_t state;
|
| 1734 |
+
md5_byte_t digest[ 16 ];
|
| 1735 |
+
char hex_output[ 16 * 2 + 1 ];
|
| 1736 |
+
|
| 1737 |
+
int di;
|
| 1738 |
+
|
| 1739 |
+
md5_init( &state );
|
| 1740 |
+
md5_append( &state, (md5_byte_t const *)s, strlen( s ) );
|
| 1741 |
+
md5_finish( &state, digest );
|
| 1742 |
+
|
| 1743 |
+
for ( di = 0; di < 16; ++di )
|
| 1744 |
+
sprintf( hex_output + di * 2, "%02x", digest[ di ] );
|
| 1745 |
+
|
| 1746 |
+
return list_new( object_new( hex_output ) );
|
| 1747 |
+
}
|
| 1748 |
+
|
| 1749 |
+
|
| 1750 |
+
LIST * builtin_file_open( FRAME * frame, int flags )
|
| 1751 |
+
{
|
| 1752 |
+
char const * name = object_str( list_front( lol_get( frame->args, 0 ) ) );
|
| 1753 |
+
char const * mode = object_str( list_front( lol_get( frame->args, 1 ) ) );
|
| 1754 |
+
int fd;
|
| 1755 |
+
char buffer[ sizeof( "4294967295" ) ];
|
| 1756 |
+
|
| 1757 |
+
if ( strcmp(mode, "w") == 0 )
|
| 1758 |
+
fd = open( name, O_WRONLY|O_CREAT|O_TRUNC, 0666 );
|
| 1759 |
+
else
|
| 1760 |
+
fd = open( name, O_RDONLY );
|
| 1761 |
+
|
| 1762 |
+
if ( fd != -1 )
|
| 1763 |
+
{
|
| 1764 |
+
sprintf( buffer, "%d", fd );
|
| 1765 |
+
return list_new( object_new( buffer ) );
|
| 1766 |
+
}
|
| 1767 |
+
return L0;
|
| 1768 |
+
}
|
| 1769 |
+
|
| 1770 |
+
|
| 1771 |
+
LIST * builtin_pad( FRAME * frame, int flags )
|
| 1772 |
+
{
|
| 1773 |
+
OBJECT * string = list_front( lol_get( frame->args, 0 ) );
|
| 1774 |
+
char const * width_s = object_str( list_front( lol_get( frame->args, 1 ) ) );
|
| 1775 |
+
|
| 1776 |
+
int current = strlen( object_str( string ) );
|
| 1777 |
+
int desired = atoi( width_s );
|
| 1778 |
+
if ( current >= desired )
|
| 1779 |
+
return list_new( object_copy( string ) );
|
| 1780 |
+
else
|
| 1781 |
+
{
|
| 1782 |
+
char * buffer = BJAM_MALLOC( desired + 1 );
|
| 1783 |
+
int i;
|
| 1784 |
+
LIST * result;
|
| 1785 |
+
|
| 1786 |
+
strcpy( buffer, object_str( string ) );
|
| 1787 |
+
for ( i = current; i < desired; ++i )
|
| 1788 |
+
buffer[ i ] = ' ';
|
| 1789 |
+
buffer[ desired ] = '\0';
|
| 1790 |
+
result = list_new( object_new( buffer ) );
|
| 1791 |
+
BJAM_FREE( buffer );
|
| 1792 |
+
return result;
|
| 1793 |
+
}
|
| 1794 |
+
}
|
| 1795 |
+
|
| 1796 |
+
|
| 1797 |
+
LIST * builtin_precious( FRAME * frame, int flags )
|
| 1798 |
+
{
|
| 1799 |
+
LIST * targets = lol_get( frame->args, 0 );
|
| 1800 |
+
LISTITER iter = list_begin( targets );
|
| 1801 |
+
LISTITER const end = list_end( targets );
|
| 1802 |
+
for ( ; iter != end; iter = list_next( iter ) )
|
| 1803 |
+
bindtarget( list_item( iter ) )->flags |= T_FLAG_PRECIOUS;
|
| 1804 |
+
return L0;
|
| 1805 |
+
}
|
| 1806 |
+
|
| 1807 |
+
|
| 1808 |
+
LIST * builtin_self_path( FRAME * frame, int flags )
|
| 1809 |
+
{
|
| 1810 |
+
extern char const * saved_argv0;
|
| 1811 |
+
char * p = executable_path( saved_argv0 );
|
| 1812 |
+
if ( p )
|
| 1813 |
+
{
|
| 1814 |
+
LIST * const result = list_new( object_new( p ) );
|
| 1815 |
+
free( p );
|
| 1816 |
+
return result;
|
| 1817 |
+
}
|
| 1818 |
+
return L0;
|
| 1819 |
+
}
|
| 1820 |
+
|
| 1821 |
+
|
| 1822 |
+
LIST * builtin_makedir( FRAME * frame, int flags )
|
| 1823 |
+
{
|
| 1824 |
+
LIST * const path = lol_get( frame->args, 0 );
|
| 1825 |
+
return file_mkdir( object_str( list_front( path ) ) )
|
| 1826 |
+
? L0
|
| 1827 |
+
: list_new( object_copy( list_front( path ) ) );
|
| 1828 |
+
}
|
| 1829 |
+
|
| 1830 |
+
|
| 1831 |
+
#ifdef HAVE_PYTHON
|
| 1832 |
+
|
| 1833 |
+
LIST * builtin_python_import_rule( FRAME * frame, int flags )
|
| 1834 |
+
{
|
| 1835 |
+
static int first_time = 1;
|
| 1836 |
+
char const * python_module = object_str( list_front( lol_get( frame->args,
|
| 1837 |
+
0 ) ) );
|
| 1838 |
+
char const * python_function = object_str( list_front( lol_get( frame->args,
|
| 1839 |
+
1 ) ) );
|
| 1840 |
+
OBJECT * jam_module = list_front( lol_get( frame->args, 2 ) );
|
| 1841 |
+
OBJECT * jam_rule = list_front( lol_get( frame->args, 3 ) );
|
| 1842 |
+
|
| 1843 |
+
PyObject * pName;
|
| 1844 |
+
PyObject * pModule;
|
| 1845 |
+
PyObject * pDict;
|
| 1846 |
+
PyObject * pFunc;
|
| 1847 |
+
|
| 1848 |
+
if ( first_time )
|
| 1849 |
+
{
|
| 1850 |
+
/* At the first invocation, we add the value of the global
|
| 1851 |
+
* EXTRA_PYTHONPATH to the sys.path Python variable.
|
| 1852 |
+
*/
|
| 1853 |
+
LIST * extra = 0;
|
| 1854 |
+
module_t * outer_module = frame->module;
|
| 1855 |
+
LISTITER iter, end;
|
| 1856 |
+
|
| 1857 |
+
first_time = 0;
|
| 1858 |
+
|
| 1859 |
+
extra = var_get( root_module(), constant_extra_pythonpath );
|
| 1860 |
+
|
| 1861 |
+
iter = list_begin( extra ), end = list_end( extra );
|
| 1862 |
+
for ( ; iter != end; iter = list_next( iter ) )
|
| 1863 |
+
{
|
| 1864 |
+
string buf[ 1 ];
|
| 1865 |
+
string_new( buf );
|
| 1866 |
+
string_append( buf, "import sys\nsys.path.append(\"" );
|
| 1867 |
+
string_append( buf, object_str( list_item( iter ) ) );
|
| 1868 |
+
string_append( buf, "\")\n" );
|
| 1869 |
+
PyRun_SimpleString( buf->value );
|
| 1870 |
+
string_free( buf );
|
| 1871 |
+
}
|
| 1872 |
+
}
|
| 1873 |
+
|
| 1874 |
+
pName = PyString_FromString( python_module );
|
| 1875 |
+
pModule = PyImport_Import( pName );
|
| 1876 |
+
Py_DECREF( pName );
|
| 1877 |
+
|
| 1878 |
+
if ( pModule != NULL )
|
| 1879 |
+
{
|
| 1880 |
+
pDict = PyModule_GetDict( pModule );
|
| 1881 |
+
pFunc = PyDict_GetItemString( pDict, python_function );
|
| 1882 |
+
|
| 1883 |
+
if ( pFunc && PyCallable_Check( pFunc ) )
|
| 1884 |
+
{
|
| 1885 |
+
module_t * m = bindmodule( jam_module );
|
| 1886 |
+
new_rule_body( m, jam_rule, function_python( pFunc, 0 ), 0 );
|
| 1887 |
+
}
|
| 1888 |
+
else
|
| 1889 |
+
{
|
| 1890 |
+
if ( PyErr_Occurred() )
|
| 1891 |
+
PyErr_Print();
|
| 1892 |
+
fprintf( stderr, "Cannot find function \"%s\"\n", python_function );
|
| 1893 |
+
}
|
| 1894 |
+
Py_DECREF( pModule );
|
| 1895 |
+
}
|
| 1896 |
+
else
|
| 1897 |
+
{
|
| 1898 |
+
PyErr_Print();
|
| 1899 |
+
fprintf( stderr, "Failed to load \"%s\"\n", python_module );
|
| 1900 |
+
}
|
| 1901 |
+
return L0;
|
| 1902 |
+
|
| 1903 |
+
}
|
| 1904 |
+
|
| 1905 |
+
#endif /* #ifdef HAVE_PYTHON */
|
| 1906 |
+
|
| 1907 |
+
|
| 1908 |
+
void lol_build( LOL * lol, char const * * elements )
|
| 1909 |
+
{
|
| 1910 |
+
LIST * l = L0;
|
| 1911 |
+
lol_init( lol );
|
| 1912 |
+
|
| 1913 |
+
while ( elements && *elements )
|
| 1914 |
+
{
|
| 1915 |
+
if ( !strcmp( *elements, ":" ) )
|
| 1916 |
+
{
|
| 1917 |
+
lol_add( lol, l );
|
| 1918 |
+
l = L0;
|
| 1919 |
+
}
|
| 1920 |
+
else
|
| 1921 |
+
{
|
| 1922 |
+
l = list_push_back( l, object_new( *elements ) );
|
| 1923 |
+
}
|
| 1924 |
+
++elements;
|
| 1925 |
+
}
|
| 1926 |
+
|
| 1927 |
+
if ( l != L0 )
|
| 1928 |
+
lol_add( lol, l );
|
| 1929 |
+
}
|
| 1930 |
+
|
| 1931 |
+
|
| 1932 |
+
#ifdef HAVE_PYTHON
|
| 1933 |
+
|
| 1934 |
+
/*
|
| 1935 |
+
* Calls the bjam rule specified by name passed in 'args'. The name is looked up
|
| 1936 |
+
* in the context of bjam's 'python_interface' module. Returns the list of
|
| 1937 |
+
* strings returned by the rule.
|
| 1938 |
+
*/
|
| 1939 |
+
|
| 1940 |
+
PyObject * bjam_call( PyObject * self, PyObject * args )
|
| 1941 |
+
{
|
| 1942 |
+
FRAME inner[ 1 ];
|
| 1943 |
+
LIST * result;
|
| 1944 |
+
PARSE * p;
|
| 1945 |
+
OBJECT * rulename;
|
| 1946 |
+
|
| 1947 |
+
/* Build up the list of arg lists. */
|
| 1948 |
+
frame_init( inner );
|
| 1949 |
+
inner->prev = 0;
|
| 1950 |
+
inner->prev_user = 0;
|
| 1951 |
+
inner->module = bindmodule( constant_python_interface );
|
| 1952 |
+
|
| 1953 |
+
/* Extract the rule name and arguments from 'args'. */
|
| 1954 |
+
|
| 1955 |
+
/* PyTuple_GetItem returns borrowed reference. */
|
| 1956 |
+
rulename = object_new( PyString_AsString( PyTuple_GetItem( args, 0 ) ) );
|
| 1957 |
+
{
|
| 1958 |
+
int i = 1;
|
| 1959 |
+
int size = PyTuple_Size( args );
|
| 1960 |
+
for ( ; i < size; ++i )
|
| 1961 |
+
{
|
| 1962 |
+
PyObject * a = PyTuple_GetItem( args, i );
|
| 1963 |
+
if ( PyString_Check( a ) )
|
| 1964 |
+
{
|
| 1965 |
+
lol_add( inner->args, list_new( object_new(
|
| 1966 |
+
PyString_AsString( a ) ) ) );
|
| 1967 |
+
}
|
| 1968 |
+
else if ( PySequence_Check( a ) )
|
| 1969 |
+
{
|
| 1970 |
+
LIST * l = 0;
|
| 1971 |
+
int s = PySequence_Size( a );
|
| 1972 |
+
int i = 0;
|
| 1973 |
+
for ( ; i < s; ++i )
|
| 1974 |
+
{
|
| 1975 |
+
/* PySequence_GetItem returns new reference. */
|
| 1976 |
+
PyObject * e = PySequence_GetItem( a, i );
|
| 1977 |
+
char * s = PyString_AsString( e );
|
| 1978 |
+
if ( !s )
|
| 1979 |
+
{
|
| 1980 |
+
printf( "Invalid parameter type passed from Python\n" );
|
| 1981 |
+
exit( 1 );
|
| 1982 |
+
}
|
| 1983 |
+
l = list_push_back( l, object_new( s ) );
|
| 1984 |
+
Py_DECREF( e );
|
| 1985 |
+
}
|
| 1986 |
+
lol_add( inner->args, l );
|
| 1987 |
+
}
|
| 1988 |
+
}
|
| 1989 |
+
}
|
| 1990 |
+
|
| 1991 |
+
result = evaluate_rule( bindrule( rulename, inner->module), rulename, inner );
|
| 1992 |
+
object_free( rulename );
|
| 1993 |
+
|
| 1994 |
+
frame_free( inner );
|
| 1995 |
+
|
| 1996 |
+
/* Convert the bjam list into a Python list result. */
|
| 1997 |
+
{
|
| 1998 |
+
PyObject * const pyResult = PyList_New( list_length( result ) );
|
| 1999 |
+
int i = 0;
|
| 2000 |
+
LISTITER iter = list_begin( result );
|
| 2001 |
+
LISTITER const end = list_end( result );
|
| 2002 |
+
for ( ; iter != end; iter = list_next( iter ) )
|
| 2003 |
+
{
|
| 2004 |
+
PyList_SetItem( pyResult, i, PyString_FromString( object_str(
|
| 2005 |
+
list_item( iter ) ) ) );
|
| 2006 |
+
i += 1;
|
| 2007 |
+
}
|
| 2008 |
+
list_free( result );
|
| 2009 |
+
return pyResult;
|
| 2010 |
+
}
|
| 2011 |
+
}
|
| 2012 |
+
|
| 2013 |
+
|
| 2014 |
+
/*
|
| 2015 |
+
* Accepts four arguments:
|
| 2016 |
+
* - module name
|
| 2017 |
+
* - rule name,
|
| 2018 |
+
* - Python callable.
|
| 2019 |
+
* - (optional) bjam language function signature.
|
| 2020 |
+
* Creates a bjam rule with the specified name in the specified module, which
|
| 2021 |
+
* will invoke the Python callable.
|
| 2022 |
+
*/
|
| 2023 |
+
|
| 2024 |
+
PyObject * bjam_import_rule( PyObject * self, PyObject * args )
|
| 2025 |
+
{
|
| 2026 |
+
char * module;
|
| 2027 |
+
char * rule;
|
| 2028 |
+
PyObject * func;
|
| 2029 |
+
PyObject * bjam_signature = NULL;
|
| 2030 |
+
module_t * m;
|
| 2031 |
+
RULE * r;
|
| 2032 |
+
OBJECT * module_name;
|
| 2033 |
+
OBJECT * rule_name;
|
| 2034 |
+
|
| 2035 |
+
if ( !PyArg_ParseTuple( args, "ssO|O:import_rule",
|
| 2036 |
+
&module, &rule, &func, &bjam_signature ) )
|
| 2037 |
+
return NULL;
|
| 2038 |
+
|
| 2039 |
+
if ( !PyCallable_Check( func ) )
|
| 2040 |
+
{
|
| 2041 |
+
PyErr_SetString( PyExc_RuntimeError, "Non-callable object passed to "
|
| 2042 |
+
"bjam.import_rule" );
|
| 2043 |
+
return NULL;
|
| 2044 |
+
}
|
| 2045 |
+
|
| 2046 |
+
module_name = *module ? object_new( module ) : 0;
|
| 2047 |
+
m = bindmodule( module_name );
|
| 2048 |
+
if ( module_name )
|
| 2049 |
+
object_free( module_name );
|
| 2050 |
+
rule_name = object_new( rule );
|
| 2051 |
+
new_rule_body( m, rule_name, function_python( func, bjam_signature ), 0 );
|
| 2052 |
+
object_free( rule_name );
|
| 2053 |
+
|
| 2054 |
+
Py_INCREF( Py_None );
|
| 2055 |
+
return Py_None;
|
| 2056 |
+
}
|
| 2057 |
+
|
| 2058 |
+
|
| 2059 |
+
/*
|
| 2060 |
+
* Accepts four arguments:
|
| 2061 |
+
* - an action name
|
| 2062 |
+
* - an action body
|
| 2063 |
+
* - a list of variable that will be bound inside the action
|
| 2064 |
+
* - integer flags.
|
| 2065 |
+
* Defines an action on bjam side.
|
| 2066 |
+
*/
|
| 2067 |
+
|
| 2068 |
+
PyObject * bjam_define_action( PyObject * self, PyObject * args )
|
| 2069 |
+
{
|
| 2070 |
+
char * name;
|
| 2071 |
+
char * body;
|
| 2072 |
+
module_t * m;
|
| 2073 |
+
PyObject * bindlist_python;
|
| 2074 |
+
int flags;
|
| 2075 |
+
LIST * bindlist = L0;
|
| 2076 |
+
int n;
|
| 2077 |
+
int i;
|
| 2078 |
+
OBJECT * name_str;
|
| 2079 |
+
FUNCTION * body_func;
|
| 2080 |
+
|
| 2081 |
+
if ( !PyArg_ParseTuple( args, "ssO!i:define_action", &name, &body,
|
| 2082 |
+
&PyList_Type, &bindlist_python, &flags ) )
|
| 2083 |
+
return NULL;
|
| 2084 |
+
|
| 2085 |
+
n = PyList_Size( bindlist_python );
|
| 2086 |
+
for ( i = 0; i < n; ++i )
|
| 2087 |
+
{
|
| 2088 |
+
PyObject * next = PyList_GetItem( bindlist_python, i );
|
| 2089 |
+
if ( !PyString_Check( next ) )
|
| 2090 |
+
{
|
| 2091 |
+
PyErr_SetString( PyExc_RuntimeError, "bind list has non-string "
|
| 2092 |
+
"type" );
|
| 2093 |
+
return NULL;
|
| 2094 |
+
}
|
| 2095 |
+
bindlist = list_push_back( bindlist, object_new( PyString_AsString( next
|
| 2096 |
+
) ) );
|
| 2097 |
+
}
|
| 2098 |
+
|
| 2099 |
+
name_str = object_new( name );
|
| 2100 |
+
body_func = function_compile_actions( body, constant_builtin, -1 );
|
| 2101 |
+
new_rule_actions( root_module(), name_str, body_func, bindlist, flags );
|
| 2102 |
+
function_free( body_func );
|
| 2103 |
+
object_free( name_str );
|
| 2104 |
+
|
| 2105 |
+
Py_INCREF( Py_None );
|
| 2106 |
+
return Py_None;
|
| 2107 |
+
}
|
| 2108 |
+
|
| 2109 |
+
|
| 2110 |
+
/*
|
| 2111 |
+
* Returns the value of a variable in root Jam module.
|
| 2112 |
+
*/
|
| 2113 |
+
|
| 2114 |
+
PyObject * bjam_variable( PyObject * self, PyObject * args )
|
| 2115 |
+
{
|
| 2116 |
+
char * name;
|
| 2117 |
+
LIST * value;
|
| 2118 |
+
PyObject * result;
|
| 2119 |
+
int i;
|
| 2120 |
+
OBJECT * varname;
|
| 2121 |
+
LISTITER iter;
|
| 2122 |
+
LISTITER end;
|
| 2123 |
+
|
| 2124 |
+
if ( !PyArg_ParseTuple( args, "s", &name ) )
|
| 2125 |
+
return NULL;
|
| 2126 |
+
|
| 2127 |
+
varname = object_new( name );
|
| 2128 |
+
value = var_get( root_module(), varname );
|
| 2129 |
+
object_free( varname );
|
| 2130 |
+
iter = list_begin( value );
|
| 2131 |
+
end = list_end( value );
|
| 2132 |
+
|
| 2133 |
+
result = PyList_New( list_length( value ) );
|
| 2134 |
+
for ( i = 0; iter != end; iter = list_next( iter ), ++i )
|
| 2135 |
+
PyList_SetItem( result, i, PyString_FromString( object_str( list_item(
|
| 2136 |
+
iter ) ) ) );
|
| 2137 |
+
|
| 2138 |
+
return result;
|
| 2139 |
+
}
|
| 2140 |
+
|
| 2141 |
+
|
| 2142 |
+
PyObject * bjam_backtrace( PyObject * self, PyObject * args )
|
| 2143 |
+
{
|
| 2144 |
+
PyObject * result = PyList_New( 0 );
|
| 2145 |
+
struct frame * f = frame_before_python_call;
|
| 2146 |
+
|
| 2147 |
+
for ( ; f = f->prev; )
|
| 2148 |
+
{
|
| 2149 |
+
PyObject * tuple = PyTuple_New( 4 );
|
| 2150 |
+
char const * file;
|
| 2151 |
+
int line;
|
| 2152 |
+
char buf[ 32 ];
|
| 2153 |
+
string module_name[ 1 ];
|
| 2154 |
+
|
| 2155 |
+
get_source_line( f, &file, &line );
|
| 2156 |
+
sprintf( buf, "%d", line );
|
| 2157 |
+
string_new( module_name );
|
| 2158 |
+
if ( f->module->name )
|
| 2159 |
+
{
|
| 2160 |
+
string_append( module_name, object_str( f->module->name ) );
|
| 2161 |
+
string_append( module_name, "." );
|
| 2162 |
+
}
|
| 2163 |
+
|
| 2164 |
+
/* PyTuple_SetItem steals reference. */
|
| 2165 |
+
PyTuple_SetItem( tuple, 0, PyString_FromString( file ) );
|
| 2166 |
+
PyTuple_SetItem( tuple, 1, PyString_FromString( buf ) );
|
| 2167 |
+
PyTuple_SetItem( tuple, 2, PyString_FromString( module_name->value ) );
|
| 2168 |
+
PyTuple_SetItem( tuple, 3, PyString_FromString( f->rulename ) );
|
| 2169 |
+
|
| 2170 |
+
string_free( module_name );
|
| 2171 |
+
|
| 2172 |
+
PyList_Append( result, tuple );
|
| 2173 |
+
Py_DECREF( tuple );
|
| 2174 |
+
}
|
| 2175 |
+
return result;
|
| 2176 |
+
}
|
| 2177 |
+
|
| 2178 |
+
PyObject * bjam_caller( PyObject * self, PyObject * args )
|
| 2179 |
+
{
|
| 2180 |
+
return PyString_FromString( frame_before_python_call->prev->module->name ?
|
| 2181 |
+
object_str( frame_before_python_call->prev->module->name ) : "" );
|
| 2182 |
+
}
|
| 2183 |
+
|
| 2184 |
+
#endif /* #ifdef HAVE_PYTHON */
|
| 2185 |
+
|
| 2186 |
+
|
| 2187 |
+
#ifdef HAVE_POPEN
|
| 2188 |
+
|
| 2189 |
+
#if defined(_MSC_VER) || defined(__BORLANDC__)
|
| 2190 |
+
#define popen windows_popen_wrapper
|
| 2191 |
+
#define pclose _pclose
|
| 2192 |
+
|
| 2193 |
+
/*
|
| 2194 |
+
* This wrapper is a workaround for a funny _popen() feature on Windows
|
| 2195 |
+
* where it eats external quotes in some cases. The bug seems to be related
|
| 2196 |
+
* to the quote stripping functionality used by the Windows cmd.exe
|
| 2197 |
+
* interpreter when its /S is not specified.
|
| 2198 |
+
*
|
| 2199 |
+
* Cleaned up quote from the cmd.exe help screen as displayed on Windows XP
|
| 2200 |
+
* SP3:
|
| 2201 |
+
*
|
| 2202 |
+
* 1. If all of the following conditions are met, then quote characters on
|
| 2203 |
+
* the command line are preserved:
|
| 2204 |
+
*
|
| 2205 |
+
* - no /S switch
|
| 2206 |
+
* - exactly two quote characters
|
| 2207 |
+
* - no special characters between the two quote characters, where
|
| 2208 |
+
* special is one of: &<>()@^|
|
| 2209 |
+
* - there are one or more whitespace characters between the two quote
|
| 2210 |
+
* characters
|
| 2211 |
+
* - the string between the two quote characters is the name of an
|
| 2212 |
+
* executable file.
|
| 2213 |
+
*
|
| 2214 |
+
* 2. Otherwise, old behavior is to see if the first character is a quote
|
| 2215 |
+
* character and if so, strip the leading character and remove the last
|
| 2216 |
+
* quote character on the command line, preserving any text after the
|
| 2217 |
+
* last quote character.
|
| 2218 |
+
*
|
| 2219 |
+
* This causes some commands containing quotes not to be executed correctly.
|
| 2220 |
+
* For example:
|
| 2221 |
+
*
|
| 2222 |
+
* "\Long folder name\aaa.exe" --name="Jurko" --no-surname
|
| 2223 |
+
*
|
| 2224 |
+
* would get its outermost quotes stripped and would be executed as:
|
| 2225 |
+
*
|
| 2226 |
+
* \Long folder name\aaa.exe" --name="Jurko --no-surname
|
| 2227 |
+
*
|
| 2228 |
+
* which would report an error about '\Long' not being a valid command.
|
| 2229 |
+
*
|
| 2230 |
+
* cmd.exe help seems to indicate it would be enough to add an extra space
|
| 2231 |
+
* character in front of the command to avoid this but this does not work,
|
| 2232 |
+
* most likely due to the shell first stripping all leading whitespace
|
| 2233 |
+
* characters from the command.
|
| 2234 |
+
*
|
| 2235 |
+
* Solution implemented here is to quote the whole command in case it
|
| 2236 |
+
* contains any quote characters. Note thought this will not work correctly
|
| 2237 |
+
* should Windows ever 'fix' this feature.
|
| 2238 |
+
* (03.06.2008.) (Jurko)
|
| 2239 |
+
*/
|
| 2240 |
+
static FILE * windows_popen_wrapper( char const * command,
|
| 2241 |
+
char const * mode )
|
| 2242 |
+
{
|
| 2243 |
+
int const extra_command_quotes_needed = !!strchr( command, '"' );
|
| 2244 |
+
string quoted_command;
|
| 2245 |
+
FILE * result;
|
| 2246 |
+
|
| 2247 |
+
if ( extra_command_quotes_needed )
|
| 2248 |
+
{
|
| 2249 |
+
string_new( "ed_command );
|
| 2250 |
+
string_append( "ed_command, "\"" );
|
| 2251 |
+
string_append( "ed_command, command );
|
| 2252 |
+
string_append( "ed_command, "\"" );
|
| 2253 |
+
command = quoted_command.value;
|
| 2254 |
+
}
|
| 2255 |
+
|
| 2256 |
+
result = _popen( command, "r" );
|
| 2257 |
+
|
| 2258 |
+
if ( extra_command_quotes_needed )
|
| 2259 |
+
string_free( "ed_command );
|
| 2260 |
+
|
| 2261 |
+
return result;
|
| 2262 |
+
}
|
| 2263 |
+
#endif /* defined(_MSC_VER) || defined(__BORLANDC__) */
|
| 2264 |
+
|
| 2265 |
+
|
| 2266 |
+
static char * rtrim( char * const s )
|
| 2267 |
+
{
|
| 2268 |
+
char * p = s;
|
| 2269 |
+
while ( *p ) ++p;
|
| 2270 |
+
for ( --p; p >= s && isspace( *p ); *p-- = 0 );
|
| 2271 |
+
return s;
|
| 2272 |
+
}
|
| 2273 |
+
|
| 2274 |
+
|
| 2275 |
+
LIST * builtin_shell( FRAME * frame, int flags )
|
| 2276 |
+
{
|
| 2277 |
+
LIST * command = lol_get( frame->args, 0 );
|
| 2278 |
+
LIST * result = L0;
|
| 2279 |
+
string s;
|
| 2280 |
+
int ret;
|
| 2281 |
+
char buffer[ 1024 ];
|
| 2282 |
+
FILE * p = NULL;
|
| 2283 |
+
int exit_status = -1;
|
| 2284 |
+
int exit_status_opt = 0;
|
| 2285 |
+
int no_output_opt = 0;
|
| 2286 |
+
int strip_eol_opt = 0;
|
| 2287 |
+
|
| 2288 |
+
/* Process the variable args options. */
|
| 2289 |
+
{
|
| 2290 |
+
int a = 1;
|
| 2291 |
+
LIST * arg = lol_get( frame->args, a );
|
| 2292 |
+
for ( ; !list_empty( arg ); arg = lol_get( frame->args, ++a ) )
|
| 2293 |
+
{
|
| 2294 |
+
if ( !strcmp( "exit-status", object_str( list_front( arg ) ) ) )
|
| 2295 |
+
exit_status_opt = 1;
|
| 2296 |
+
else if ( !strcmp( "no-output", object_str( list_front( arg ) ) ) )
|
| 2297 |
+
no_output_opt = 1;
|
| 2298 |
+
else if ( !strcmp("strip-eol", object_str( list_front( arg ) ) ) )
|
| 2299 |
+
strip_eol_opt = 1;
|
| 2300 |
+
}
|
| 2301 |
+
}
|
| 2302 |
+
|
| 2303 |
+
/* The following fflush() call seems to be indicated as a workaround for a
|
| 2304 |
+
* popen() bug on POSIX implementations related to synhronizing input
|
| 2305 |
+
* stream positions for the called and the calling process.
|
| 2306 |
+
*/
|
| 2307 |
+
fflush( NULL );
|
| 2308 |
+
|
| 2309 |
+
p = popen( object_str( list_front( command ) ), "r" );
|
| 2310 |
+
if ( p == NULL )
|
| 2311 |
+
return L0;
|
| 2312 |
+
|
| 2313 |
+
string_new( &s );
|
| 2314 |
+
|
| 2315 |
+
while ( ( ret = fread( buffer, sizeof( char ), sizeof( buffer ) - 1, p ) ) >
|
| 2316 |
+
0 )
|
| 2317 |
+
{
|
| 2318 |
+
buffer[ ret ] = 0;
|
| 2319 |
+
if ( !no_output_opt )
|
| 2320 |
+
{
|
| 2321 |
+
if ( strip_eol_opt )
|
| 2322 |
+
rtrim( buffer );
|
| 2323 |
+
string_append( &s, buffer );
|
| 2324 |
+
}
|
| 2325 |
+
}
|
| 2326 |
+
|
| 2327 |
+
exit_status = pclose( p );
|
| 2328 |
+
|
| 2329 |
+
/* The command output is returned first. */
|
| 2330 |
+
result = list_new( object_new( s.value ) );
|
| 2331 |
+
string_free( &s );
|
| 2332 |
+
|
| 2333 |
+
/* The command exit result next. */
|
| 2334 |
+
if ( exit_status_opt )
|
| 2335 |
+
{
|
| 2336 |
+
if ( WIFEXITED( exit_status ) )
|
| 2337 |
+
exit_status = WEXITSTATUS( exit_status );
|
| 2338 |
+
else
|
| 2339 |
+
exit_status = -1;
|
| 2340 |
+
sprintf( buffer, "%d", exit_status );
|
| 2341 |
+
result = list_push_back( result, object_new( buffer ) );
|
| 2342 |
+
}
|
| 2343 |
+
|
| 2344 |
+
return result;
|
| 2345 |
+
}
|
| 2346 |
+
|
| 2347 |
+
#else /* #ifdef HAVE_POPEN */
|
| 2348 |
+
|
| 2349 |
+
LIST * builtin_shell( FRAME * frame, int flags )
|
| 2350 |
+
{
|
| 2351 |
+
return L0;
|
| 2352 |
+
}
|
| 2353 |
+
|
| 2354 |
+
#endif /* #ifdef HAVE_POPEN */
|
mosesdecoder/jam-files/engine/builtins.h
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/*
|
| 2 |
+
* Copyright 1993-2002 Christopher Seiwald and Perforce Software, Inc.
|
| 3 |
+
*
|
| 4 |
+
* This file is part of Jam - see jam.c for Copyright information.
|
| 5 |
+
*/
|
| 6 |
+
|
| 7 |
+
#ifndef JAM_BUILTINS_H
|
| 8 |
+
# define JAM_BUILTINS_H
|
| 9 |
+
|
| 10 |
+
# include "frames.h"
|
| 11 |
+
|
| 12 |
+
/*
|
| 13 |
+
* builtins.h - compile parsed jam statements
|
| 14 |
+
*/
|
| 15 |
+
|
| 16 |
+
void load_builtins();
|
| 17 |
+
void init_set();
|
| 18 |
+
void init_path();
|
| 19 |
+
void init_regex();
|
| 20 |
+
void init_property_set();
|
| 21 |
+
void init_sequence();
|
| 22 |
+
void init_order();
|
| 23 |
+
|
| 24 |
+
void property_set_done();
|
| 25 |
+
|
| 26 |
+
LIST *builtin_calc( FRAME * frame, int flags );
|
| 27 |
+
LIST *builtin_depends( FRAME * frame, int flags );
|
| 28 |
+
LIST *builtin_rebuilds( FRAME * frame, int flags );
|
| 29 |
+
LIST *builtin_echo( FRAME * frame, int flags );
|
| 30 |
+
LIST *builtin_exit( FRAME * frame, int flags );
|
| 31 |
+
LIST *builtin_flags( FRAME * frame, int flags );
|
| 32 |
+
LIST *builtin_glob( FRAME * frame, int flags );
|
| 33 |
+
LIST *builtin_glob_recursive( FRAME * frame, int flags );
|
| 34 |
+
LIST *builtin_subst( FRAME * frame, int flags );
|
| 35 |
+
LIST *builtin_match( FRAME * frame, int flags );
|
| 36 |
+
LIST *builtin_split_by_characters( FRAME * frame, int flags );
|
| 37 |
+
LIST *builtin_hdrmacro( FRAME * frame, int flags );
|
| 38 |
+
LIST *builtin_rulenames( FRAME * frame, int flags );
|
| 39 |
+
LIST *builtin_varnames( FRAME * frame, int flags );
|
| 40 |
+
LIST *builtin_delete_module( FRAME * frame, int flags );
|
| 41 |
+
LIST *builtin_import( FRAME * frame, int flags );
|
| 42 |
+
LIST *builtin_export( FRAME * frame, int flags );
|
| 43 |
+
LIST *builtin_caller_module( FRAME * frame, int flags );
|
| 44 |
+
LIST *builtin_backtrace( FRAME * frame, int flags );
|
| 45 |
+
LIST *builtin_pwd( FRAME * frame, int flags );
|
| 46 |
+
LIST *builtin_update( FRAME * frame, int flags );
|
| 47 |
+
LIST *builtin_update_now( FRAME * frame, int flags );
|
| 48 |
+
LIST *builtin_import_module( FRAME * frame, int flags );
|
| 49 |
+
LIST *builtin_imported_modules( FRAME * frame, int flags );
|
| 50 |
+
LIST *builtin_instance( FRAME * frame, int flags );
|
| 51 |
+
LIST *builtin_sort( FRAME * frame, int flags );
|
| 52 |
+
LIST *builtin_normalize_path( FRAME * frame, int flags );
|
| 53 |
+
LIST *builtin_native_rule( FRAME * frame, int flags );
|
| 54 |
+
LIST *builtin_has_native_rule( FRAME * frame, int flags );
|
| 55 |
+
LIST *builtin_user_module( FRAME * frame, int flags );
|
| 56 |
+
LIST *builtin_nearest_user_location( FRAME * frame, int flags );
|
| 57 |
+
LIST *builtin_check_if_file( FRAME * frame, int flags );
|
| 58 |
+
LIST *builtin_python_import_rule( FRAME * frame, int flags );
|
| 59 |
+
LIST *builtin_shell( FRAME * frame, int flags );
|
| 60 |
+
LIST *builtin_md5( FRAME * frame, int flags );
|
| 61 |
+
LIST *builtin_file_open( FRAME * frame, int flags );
|
| 62 |
+
LIST *builtin_pad( FRAME * frame, int flags );
|
| 63 |
+
LIST *builtin_precious( FRAME * frame, int flags );
|
| 64 |
+
LIST *builtin_self_path( FRAME * frame, int flags );
|
| 65 |
+
LIST *builtin_makedir( FRAME * frame, int flags );
|
| 66 |
+
|
| 67 |
+
void backtrace( FRAME *frame );
|
| 68 |
+
extern int last_update_now_status;
|
| 69 |
+
|
| 70 |
+
#endif
|
mosesdecoder/jam-files/engine/bump_version.py
ADDED
|
@@ -0,0 +1,98 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/python
|
| 2 |
+
|
| 3 |
+
# This script is used to bump the bjam version. It takes a single argument, e.g
|
| 4 |
+
#
|
| 5 |
+
# ./bump_version.py 3.1.9
|
| 6 |
+
#
|
| 7 |
+
# and updates all the necessary files.
|
| 8 |
+
#
|
| 9 |
+
# Copyright 2006 Rene Rivera.
|
| 10 |
+
# Copyright 2005-2006 Vladimir Prus.
|
| 11 |
+
# Distributed under the Boost Software License, Version 1.0.
|
| 12 |
+
# (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
|
| 13 |
+
|
| 14 |
+
|
| 15 |
+
import os
|
| 16 |
+
import os.path
|
| 17 |
+
import re
|
| 18 |
+
import string
|
| 19 |
+
import sys
|
| 20 |
+
|
| 21 |
+
srcdir = os.path.abspath(os.path.dirname(__file__))
|
| 22 |
+
docdir = os.path.abspath(os.path.join(srcdir, "..", "doc"))
|
| 23 |
+
|
| 24 |
+
|
| 25 |
+
def edit(file, *replacements):
|
| 26 |
+
print(" '%s'..." % file)
|
| 27 |
+
f = open(file, 'r')
|
| 28 |
+
text = f.read()
|
| 29 |
+
f.close()
|
| 30 |
+
for (source, target) in replacements:
|
| 31 |
+
text, n = re.compile(source, re.MULTILINE).subn(target, text)
|
| 32 |
+
assert n > 0
|
| 33 |
+
f = open(file, 'w')
|
| 34 |
+
f.write(text)
|
| 35 |
+
f.close()
|
| 36 |
+
|
| 37 |
+
|
| 38 |
+
def make_edits(ver):
|
| 39 |
+
ver03 = (list(ver) + [0] * 3)[0:3]
|
| 40 |
+
ver02 = ver03[0:2]
|
| 41 |
+
|
| 42 |
+
join = lambda v, s : s.join(str(x) for x in v)
|
| 43 |
+
dotJoin = lambda v : join(v, ".")
|
| 44 |
+
|
| 45 |
+
print("Setting version to %s" % str(ver03))
|
| 46 |
+
|
| 47 |
+
edit(os.path.join(srcdir, "boost-jam.spec"),
|
| 48 |
+
('^(Version:) .*$', '\\1 %s' % dotJoin(ver03)))
|
| 49 |
+
|
| 50 |
+
edit(os.path.join(srcdir, "build.jam"),
|
| 51 |
+
('^(_VERSION_ =).* ;$', '\\1 %s ;' % join(ver03, " ")))
|
| 52 |
+
|
| 53 |
+
edit(os.path.join(docdir, "bjam.qbk"),
|
| 54 |
+
('(\[version).*(\])', '\\1: %s\\2' % dotJoin(ver03)),
|
| 55 |
+
('(\[def :version:).*(\])', '\\1 %s\\2' % dotJoin(ver03)))
|
| 56 |
+
|
| 57 |
+
edit(os.path.join(srcdir, "patchlevel.h"),
|
| 58 |
+
('^(#define VERSION_MAJOR) .*$', '\\1 %s' % ver03[0]),
|
| 59 |
+
('^(#define VERSION_MINOR) .*$', '\\1 %s' % ver03[1]),
|
| 60 |
+
('^(#define VERSION_PATCH) .*$', '\\1 %s' % ver03[2]),
|
| 61 |
+
('^(#define VERSION_MAJOR_SYM) .*$', '\\1 "%02d"' % ver03[0]),
|
| 62 |
+
('^(#define VERSION_MINOR_SYM) .*$', '\\1 "%02d"' % ver03[1]),
|
| 63 |
+
('^(#define VERSION_PATCH_SYM) .*$', '\\1 "%02d"' % ver03[2]),
|
| 64 |
+
('^(#define VERSION) .*$', '\\1 "%s"' % dotJoin(ver)),
|
| 65 |
+
('^(#define JAMVERSYM) .*$', '\\1 "JAMVERSION=%s"' % dotJoin(ver02)))
|
| 66 |
+
|
| 67 |
+
|
| 68 |
+
def main():
|
| 69 |
+
if len(sys.argv) < 2:
|
| 70 |
+
print("Expect new version as argument.")
|
| 71 |
+
sys.exit(1)
|
| 72 |
+
if len(sys.argv) > 3:
|
| 73 |
+
print("Too many arguments.")
|
| 74 |
+
sys.exit(1)
|
| 75 |
+
|
| 76 |
+
version = sys.argv[1].split(".")
|
| 77 |
+
if len(version) > 3:
|
| 78 |
+
print("Expect version argument in the format: <MAJOR>.<MINOR>.<PATCH>")
|
| 79 |
+
sys.exit(1)
|
| 80 |
+
|
| 81 |
+
try:
|
| 82 |
+
version = list(int(x) for x in version)
|
| 83 |
+
except ValueError:
|
| 84 |
+
print("Version values must be valid integers.")
|
| 85 |
+
sys.exit(1)
|
| 86 |
+
|
| 87 |
+
while version and version[-1] == 0:
|
| 88 |
+
version.pop()
|
| 89 |
+
|
| 90 |
+
if not version:
|
| 91 |
+
print("At least one of the version values must be positive.")
|
| 92 |
+
sys.exit()
|
| 93 |
+
|
| 94 |
+
make_edits(version)
|
| 95 |
+
|
| 96 |
+
|
| 97 |
+
if __name__ == '__main__':
|
| 98 |
+
main()
|
mosesdecoder/jam-files/engine/class.c
ADDED
|
@@ -0,0 +1,191 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/*
|
| 2 |
+
* Copyright Vladimir Prus 2003.
|
| 3 |
+
* Distributed under the Boost Software License, Version 1.0.
|
| 4 |
+
* (See accompanying file LICENSE_1_0.txt or copy at
|
| 5 |
+
* http://www.boost.org/LICENSE_1_0.txt)
|
| 6 |
+
*/
|
| 7 |
+
|
| 8 |
+
#include "class.h"
|
| 9 |
+
|
| 10 |
+
#include "constants.h"
|
| 11 |
+
#include "frames.h"
|
| 12 |
+
#include "hash.h"
|
| 13 |
+
#include "lists.h"
|
| 14 |
+
#include "object.h"
|
| 15 |
+
#include "rules.h"
|
| 16 |
+
#include "strings.h"
|
| 17 |
+
#include "variable.h"
|
| 18 |
+
|
| 19 |
+
#include <stdio.h>
|
| 20 |
+
#include <stdlib.h>
|
| 21 |
+
|
| 22 |
+
|
| 23 |
+
static struct hash * classes = 0;
|
| 24 |
+
|
| 25 |
+
|
| 26 |
+
static void check_defined( LIST * class_names )
|
| 27 |
+
{
|
| 28 |
+
LISTITER iter = list_begin( class_names );
|
| 29 |
+
LISTITER const end = list_end( class_names );
|
| 30 |
+
for ( ; iter != end; iter = list_next( iter ) )
|
| 31 |
+
{
|
| 32 |
+
if ( !hash_find( classes, list_item( iter ) ) )
|
| 33 |
+
{
|
| 34 |
+
printf( "Class %s is not defined\n", object_str( list_item( iter ) )
|
| 35 |
+
);
|
| 36 |
+
abort();
|
| 37 |
+
}
|
| 38 |
+
}
|
| 39 |
+
}
|
| 40 |
+
|
| 41 |
+
|
| 42 |
+
static OBJECT * class_module_name( OBJECT * declared_name )
|
| 43 |
+
{
|
| 44 |
+
string name[ 1 ];
|
| 45 |
+
OBJECT * result;
|
| 46 |
+
|
| 47 |
+
string_new( name );
|
| 48 |
+
string_append( name, "class@" );
|
| 49 |
+
string_append( name, object_str( declared_name ) );
|
| 50 |
+
|
| 51 |
+
result = object_new( name->value );
|
| 52 |
+
string_free( name );
|
| 53 |
+
|
| 54 |
+
return result;
|
| 55 |
+
}
|
| 56 |
+
|
| 57 |
+
|
| 58 |
+
struct import_base_data
|
| 59 |
+
{
|
| 60 |
+
OBJECT * base_name;
|
| 61 |
+
module_t * base_module;
|
| 62 |
+
module_t * class_module;
|
| 63 |
+
};
|
| 64 |
+
|
| 65 |
+
|
| 66 |
+
static void import_base_rule( void * r_, void * d_ )
|
| 67 |
+
{
|
| 68 |
+
RULE * r = (RULE *)r_;
|
| 69 |
+
RULE * ir1;
|
| 70 |
+
RULE * ir2;
|
| 71 |
+
struct import_base_data * d = (struct import_base_data *)d_;
|
| 72 |
+
OBJECT * qname;
|
| 73 |
+
|
| 74 |
+
string qualified_name[ 1 ];
|
| 75 |
+
string_new ( qualified_name );
|
| 76 |
+
string_append ( qualified_name, object_str( d->base_name ) );
|
| 77 |
+
string_push_back( qualified_name, '.' );
|
| 78 |
+
string_append ( qualified_name, object_str( r->name ) );
|
| 79 |
+
qname = object_new( qualified_name->value );
|
| 80 |
+
string_free( qualified_name );
|
| 81 |
+
|
| 82 |
+
ir1 = import_rule( r, d->class_module, r->name );
|
| 83 |
+
ir2 = import_rule( r, d->class_module, qname );
|
| 84 |
+
|
| 85 |
+
object_free( qname );
|
| 86 |
+
|
| 87 |
+
/* Copy 'exported' flag. */
|
| 88 |
+
ir1->exported = ir2->exported = r->exported;
|
| 89 |
+
|
| 90 |
+
/* If we are importing a class method, localize it. */
|
| 91 |
+
if ( ( r->module == d->base_module ) || ( r->module->class_module &&
|
| 92 |
+
( r->module->class_module == d->base_module ) ) )
|
| 93 |
+
{
|
| 94 |
+
rule_localize( ir1, d->class_module );
|
| 95 |
+
rule_localize( ir2, d->class_module );
|
| 96 |
+
}
|
| 97 |
+
}
|
| 98 |
+
|
| 99 |
+
|
| 100 |
+
/*
|
| 101 |
+
* For each exported rule 'n', declared in class module for base, imports that
|
| 102 |
+
* rule in 'class' as 'n' and as 'base.n'. Imported rules are localized and
|
| 103 |
+
* marked as exported.
|
| 104 |
+
*/
|
| 105 |
+
|
| 106 |
+
static void import_base_rules( module_t * class_, OBJECT * base )
|
| 107 |
+
{
|
| 108 |
+
OBJECT * module_name = class_module_name( base );
|
| 109 |
+
module_t * base_module = bindmodule( module_name );
|
| 110 |
+
LIST * imported;
|
| 111 |
+
struct import_base_data d;
|
| 112 |
+
d.base_name = base;
|
| 113 |
+
d.base_module = base_module;
|
| 114 |
+
d.class_module = class_;
|
| 115 |
+
object_free( module_name );
|
| 116 |
+
|
| 117 |
+
if ( base_module->rules )
|
| 118 |
+
hashenumerate( base_module->rules, import_base_rule, &d );
|
| 119 |
+
|
| 120 |
+
imported = imported_modules( base_module );
|
| 121 |
+
import_module( imported, class_ );
|
| 122 |
+
list_free( imported );
|
| 123 |
+
}
|
| 124 |
+
|
| 125 |
+
|
| 126 |
+
OBJECT * make_class_module( LIST * xname, LIST * bases, FRAME * frame )
|
| 127 |
+
{
|
| 128 |
+
OBJECT * name = class_module_name( list_front( xname ) );
|
| 129 |
+
OBJECT * * pp;
|
| 130 |
+
module_t * class_module = 0;
|
| 131 |
+
module_t * outer_module = frame->module;
|
| 132 |
+
int found;
|
| 133 |
+
|
| 134 |
+
if ( !classes )
|
| 135 |
+
classes = hashinit( sizeof( OBJECT * ), "classes" );
|
| 136 |
+
|
| 137 |
+
pp = (OBJECT * *)hash_insert( classes, list_front( xname ), &found );
|
| 138 |
+
if ( !found )
|
| 139 |
+
{
|
| 140 |
+
*pp = object_copy( list_front( xname ) );
|
| 141 |
+
}
|
| 142 |
+
else
|
| 143 |
+
{
|
| 144 |
+
printf( "Class %s already defined\n", object_str( list_front( xname ) )
|
| 145 |
+
);
|
| 146 |
+
abort();
|
| 147 |
+
}
|
| 148 |
+
check_defined( bases );
|
| 149 |
+
|
| 150 |
+
class_module = bindmodule( name );
|
| 151 |
+
|
| 152 |
+
{
|
| 153 |
+
/*
|
| 154 |
+
Initialize variables that Boost.Build inserts in every object.
|
| 155 |
+
We want to avoid creating the object's hash if it isn't needed.
|
| 156 |
+
*/
|
| 157 |
+
int num = class_module->num_fixed_variables;
|
| 158 |
+
module_add_fixed_var( class_module, constant_name, &num );
|
| 159 |
+
module_add_fixed_var( class_module, constant_class, &num );
|
| 160 |
+
module_set_fixed_variables( class_module, num );
|
| 161 |
+
}
|
| 162 |
+
|
| 163 |
+
var_set( class_module, constant_name, xname, VAR_SET );
|
| 164 |
+
var_set( class_module, constant_bases, bases, VAR_SET );
|
| 165 |
+
|
| 166 |
+
{
|
| 167 |
+
LISTITER iter = list_begin( bases );
|
| 168 |
+
LISTITER const end = list_end( bases );
|
| 169 |
+
for ( ; iter != end; iter = list_next( iter ) )
|
| 170 |
+
import_base_rules( class_module, list_item( iter ) );
|
| 171 |
+
}
|
| 172 |
+
|
| 173 |
+
return name;
|
| 174 |
+
}
|
| 175 |
+
|
| 176 |
+
|
| 177 |
+
static void free_class( void * xclass, void * data )
|
| 178 |
+
{
|
| 179 |
+
object_free( *(OBJECT * *)xclass );
|
| 180 |
+
}
|
| 181 |
+
|
| 182 |
+
|
| 183 |
+
void class_done( void )
|
| 184 |
+
{
|
| 185 |
+
if ( classes )
|
| 186 |
+
{
|
| 187 |
+
hashenumerate( classes, free_class, (void *)0 );
|
| 188 |
+
hashdone( classes );
|
| 189 |
+
classes = 0;
|
| 190 |
+
}
|
| 191 |
+
}
|
mosesdecoder/jam-files/engine/command.h
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/*
|
| 2 |
+
* Copyright 1994 Christopher Seiwald.
|
| 3 |
+
*
|
| 4 |
+
* This file is part of Jam - see jam.c for Copyright information.
|
| 5 |
+
*/
|
| 6 |
+
|
| 7 |
+
/*
|
| 8 |
+
* command.h - the CMD structure and routines to manipulate them
|
| 9 |
+
*
|
| 10 |
+
* Both ACTION and CMD contain a rule, targets, and sources. An
|
| 11 |
+
* ACTION describes a rule to be applied to the given targets and
|
| 12 |
+
* sources; a CMD is what actually gets executed by the shell. The
|
| 13 |
+
* differences are due to:
|
| 14 |
+
*
|
| 15 |
+
* ACTIONS must be combined if 'actions together' is given.
|
| 16 |
+
* ACTIONS must be split if 'actions piecemeal' is given.
|
| 17 |
+
* ACTIONS must have current sources omitted for 'actions updated'.
|
| 18 |
+
*
|
| 19 |
+
* The CMD datatype holds a single command that is to be executed
|
| 20 |
+
* against a target, and they can chain together to represent the
|
| 21 |
+
* full collection of commands used to update a target.
|
| 22 |
+
*
|
| 23 |
+
* Structures:
|
| 24 |
+
*
|
| 25 |
+
* CMD - an action, ready to be formatted into a buffer and executed.
|
| 26 |
+
*
|
| 27 |
+
* External routines:
|
| 28 |
+
*
|
| 29 |
+
* cmd_new() - return a new CMD or 0 if too many args.
|
| 30 |
+
* cmd_free() - delete CMD and its parts.
|
| 31 |
+
* cmd_next() - walk the CMD chain.
|
| 32 |
+
* cmd_release_targets_and_shell() - CMD forgets about its targets & shell.
|
| 33 |
+
*/
|
| 34 |
+
|
| 35 |
+
|
| 36 |
+
/*
|
| 37 |
+
* CMD - an action, ready to be formatted into a buffer and executed.
|
| 38 |
+
*/
|
| 39 |
+
|
| 40 |
+
#ifndef COMMAND_SW20111118_H
|
| 41 |
+
#define COMMAND_SW20111118_H
|
| 42 |
+
|
| 43 |
+
#include "lists.h"
|
| 44 |
+
#include "rules.h"
|
| 45 |
+
#include "strings.h"
|
| 46 |
+
|
| 47 |
+
|
| 48 |
+
typedef struct _cmd CMD;
|
| 49 |
+
struct _cmd
|
| 50 |
+
{
|
| 51 |
+
CMD * next;
|
| 52 |
+
RULE * rule; /* rule->actions contains shell script */
|
| 53 |
+
LIST * shell; /* $(JAMSHELL) value */
|
| 54 |
+
LOL args; /* LISTs for $(<), $(>) */
|
| 55 |
+
string buf[ 1 ]; /* actual commands */
|
| 56 |
+
int noop; /* no-op commands should be faked instead of executed */
|
| 57 |
+
};
|
| 58 |
+
|
| 59 |
+
CMD * cmd_new
|
| 60 |
+
(
|
| 61 |
+
RULE * rule, /* rule (referenced) */
|
| 62 |
+
LIST * targets, /* $(<) (ownership transferred) */
|
| 63 |
+
LIST * sources, /* $(>) (ownership transferred) */
|
| 64 |
+
LIST * shell /* $(JAMSHELL) (ownership transferred) */
|
| 65 |
+
);
|
| 66 |
+
|
| 67 |
+
void cmd_release_targets_and_shell( CMD * );
|
| 68 |
+
|
| 69 |
+
void cmd_free( CMD * );
|
| 70 |
+
|
| 71 |
+
#define cmd_next( c ) ((c)->next)
|
| 72 |
+
|
| 73 |
+
#endif
|
mosesdecoder/jam-files/engine/compile.h
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/*
|
| 2 |
+
* Copyright 1993, 2000 Christopher Seiwald.
|
| 3 |
+
*
|
| 4 |
+
* This file is part of Jam - see jam.c for Copyright information.
|
| 5 |
+
*/
|
| 6 |
+
|
| 7 |
+
/* This file is ALSO:
|
| 8 |
+
* Copyright 2001-2004 David Abrahams.
|
| 9 |
+
* Distributed under the Boost Software License, Version 1.0.
|
| 10 |
+
* (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
|
| 11 |
+
*/
|
| 12 |
+
|
| 13 |
+
/*
|
| 14 |
+
* compile.h - compile parsed jam statements
|
| 15 |
+
*/
|
| 16 |
+
|
| 17 |
+
#ifndef COMPILE_DWA20011022_H
|
| 18 |
+
#define COMPILE_DWA20011022_H
|
| 19 |
+
|
| 20 |
+
#include "frames.h"
|
| 21 |
+
#include "lists.h"
|
| 22 |
+
#include "object.h"
|
| 23 |
+
#include "rules.h"
|
| 24 |
+
|
| 25 |
+
void compile_builtins();
|
| 26 |
+
|
| 27 |
+
LIST * evaluate_rule( RULE * rule, OBJECT * rulename, FRAME * );
|
| 28 |
+
LIST * call_rule( OBJECT * rulename, FRAME * caller_frame, ... );
|
| 29 |
+
|
| 30 |
+
/* Flags for compile_set(), etc */
|
| 31 |
+
|
| 32 |
+
#define ASSIGN_SET 0x00 /* = assign variable */
|
| 33 |
+
#define ASSIGN_APPEND 0x01 /* += append variable */
|
| 34 |
+
#define ASSIGN_DEFAULT 0x02 /* set only if unset */
|
| 35 |
+
|
| 36 |
+
/* Flags for compile_setexec() */
|
| 37 |
+
|
| 38 |
+
#define EXEC_UPDATED 0x01 /* executes updated */
|
| 39 |
+
#define EXEC_TOGETHER 0x02 /* executes together */
|
| 40 |
+
#define EXEC_IGNORE 0x04 /* executes ignore */
|
| 41 |
+
#define EXEC_QUIETLY 0x08 /* executes quietly */
|
| 42 |
+
#define EXEC_PIECEMEAL 0x10 /* executes piecemeal */
|
| 43 |
+
#define EXEC_EXISTING 0x20 /* executes existing */
|
| 44 |
+
|
| 45 |
+
/* Conditions for compile_if() */
|
| 46 |
+
|
| 47 |
+
#define EXPR_NOT 0 /* ! cond */
|
| 48 |
+
#define EXPR_AND 1 /* cond && cond */
|
| 49 |
+
#define EXPR_OR 2 /* cond || cond */
|
| 50 |
+
#define EXPR_EXISTS 3 /* arg */
|
| 51 |
+
#define EXPR_EQUALS 4 /* arg = arg */
|
| 52 |
+
#define EXPR_NOTEQ 5 /* arg != arg */
|
| 53 |
+
#define EXPR_LESS 6 /* arg < arg */
|
| 54 |
+
#define EXPR_LESSEQ 7 /* arg <= arg */
|
| 55 |
+
#define EXPR_MORE 8 /* arg > arg */
|
| 56 |
+
#define EXPR_MOREEQ 9 /* arg >= arg */
|
| 57 |
+
#define EXPR_IN 10 /* arg in arg */
|
| 58 |
+
|
| 59 |
+
#endif
|
mosesdecoder/jam-files/engine/cwd.c
ADDED
|
@@ -0,0 +1,83 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/*
|
| 2 |
+
* Copyright 2002. Vladimir Prus
|
| 3 |
+
* Copyright 2005. Rene Rivera
|
| 4 |
+
* Distributed under the Boost Software License, Version 1.0.
|
| 5 |
+
* (See accompanying file LICENSE_1_0.txt or copy at
|
| 6 |
+
* http://www.boost.org/LICENSE_1_0.txt)
|
| 7 |
+
*/
|
| 8 |
+
|
| 9 |
+
#include "cwd.h"
|
| 10 |
+
|
| 11 |
+
#include "jam.h"
|
| 12 |
+
#include "mem.h"
|
| 13 |
+
#include "pathsys.h"
|
| 14 |
+
|
| 15 |
+
#include <assert.h>
|
| 16 |
+
#include <errno.h>
|
| 17 |
+
#include <limits.h>
|
| 18 |
+
|
| 19 |
+
/* MinGW on Windows declares PATH_MAX in limits.h */
|
| 20 |
+
#if defined( NT ) && !defined( __GNUC__ )
|
| 21 |
+
# include <direct.h>
|
| 22 |
+
# define PATH_MAX _MAX_PATH
|
| 23 |
+
#else
|
| 24 |
+
# include <unistd.h>
|
| 25 |
+
# if defined( __COMO__ )
|
| 26 |
+
# include <linux/limits.h>
|
| 27 |
+
# endif
|
| 28 |
+
#endif
|
| 29 |
+
|
| 30 |
+
#ifndef PATH_MAX
|
| 31 |
+
# define PATH_MAX 1024
|
| 32 |
+
#endif
|
| 33 |
+
|
| 34 |
+
|
| 35 |
+
static OBJECT * cwd_;
|
| 36 |
+
|
| 37 |
+
|
| 38 |
+
void cwd_init( void )
|
| 39 |
+
{
|
| 40 |
+
int buffer_size = PATH_MAX;
|
| 41 |
+
char * cwd_buffer = 0;
|
| 42 |
+
int error;
|
| 43 |
+
|
| 44 |
+
assert( !cwd_ );
|
| 45 |
+
|
| 46 |
+
do
|
| 47 |
+
{
|
| 48 |
+
char * const buffer = BJAM_MALLOC_RAW( buffer_size );
|
| 49 |
+
cwd_buffer = getcwd( buffer, buffer_size );
|
| 50 |
+
error = errno;
|
| 51 |
+
if ( cwd_buffer )
|
| 52 |
+
{
|
| 53 |
+
/* We store the path using its canonical/long/key format. */
|
| 54 |
+
OBJECT * const cwd = object_new( cwd_buffer );
|
| 55 |
+
cwd_ = path_as_key( cwd );
|
| 56 |
+
object_free( cwd );
|
| 57 |
+
}
|
| 58 |
+
buffer_size *= 2;
|
| 59 |
+
BJAM_FREE_RAW( buffer );
|
| 60 |
+
}
|
| 61 |
+
while ( !cwd_ && error == ERANGE );
|
| 62 |
+
|
| 63 |
+
if ( !cwd_ )
|
| 64 |
+
{
|
| 65 |
+
perror( "can not get current working directory" );
|
| 66 |
+
exit( EXITBAD );
|
| 67 |
+
}
|
| 68 |
+
}
|
| 69 |
+
|
| 70 |
+
|
| 71 |
+
OBJECT * cwd( void )
|
| 72 |
+
{
|
| 73 |
+
assert( cwd_ );
|
| 74 |
+
return cwd_;
|
| 75 |
+
}
|
| 76 |
+
|
| 77 |
+
|
| 78 |
+
void cwd_done( void )
|
| 79 |
+
{
|
| 80 |
+
assert( cwd_ );
|
| 81 |
+
object_free( cwd_ );
|
| 82 |
+
cwd_ = NULL;
|
| 83 |
+
}
|
mosesdecoder/jam-files/engine/filent.c
ADDED
|
@@ -0,0 +1,311 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/*
|
| 2 |
+
* Copyright 1993, 1995 Christopher Seiwald.
|
| 3 |
+
*
|
| 4 |
+
* This file is part of Jam - see jam.c for Copyright information.
|
| 5 |
+
*/
|
| 6 |
+
|
| 7 |
+
/* This file is ALSO:
|
| 8 |
+
* Copyright 2001-2004 David Abrahams.
|
| 9 |
+
* Copyright 2005 Rene Rivera.
|
| 10 |
+
* Distributed under the Boost Software License, Version 1.0.
|
| 11 |
+
* (See accompanying file LICENSE_1_0.txt or copy at
|
| 12 |
+
* http://www.boost.org/LICENSE_1_0.txt)
|
| 13 |
+
*/
|
| 14 |
+
|
| 15 |
+
/*
|
| 16 |
+
* filent.c - scan directories and archives on NT
|
| 17 |
+
*
|
| 18 |
+
* External routines:
|
| 19 |
+
* file_mkdir() - create a directory
|
| 20 |
+
* file_supported_fmt_resolution() - file modification timestamp resolution
|
| 21 |
+
*
|
| 22 |
+
* External routines called only via routines in filesys.c:
|
| 23 |
+
* file_collect_dir_content_() - collects directory content information
|
| 24 |
+
* file_dirscan_() - OS specific file_dirscan() implementation
|
| 25 |
+
* file_query_() - query information about a path from the OS
|
| 26 |
+
*/
|
| 27 |
+
|
| 28 |
+
#include "jam.h"
|
| 29 |
+
#ifdef OS_NT
|
| 30 |
+
#include "filesys.h"
|
| 31 |
+
|
| 32 |
+
#include "object.h"
|
| 33 |
+
#include "pathsys.h"
|
| 34 |
+
#include "strings.h"
|
| 35 |
+
|
| 36 |
+
#ifdef __BORLANDC__
|
| 37 |
+
# undef FILENAME /* cpp namespace collision */
|
| 38 |
+
#endif
|
| 39 |
+
|
| 40 |
+
#define WIN32_LEAN_AND_MEAN
|
| 41 |
+
#include <windows.h>
|
| 42 |
+
|
| 43 |
+
#include <assert.h>
|
| 44 |
+
#include <ctype.h>
|
| 45 |
+
#include <direct.h>
|
| 46 |
+
#include <io.h>
|
| 47 |
+
|
| 48 |
+
|
| 49 |
+
/*
|
| 50 |
+
* file_collect_dir_content_() - collects directory content information
|
| 51 |
+
*/
|
| 52 |
+
|
| 53 |
+
int file_collect_dir_content_( file_info_t * const d )
|
| 54 |
+
{
|
| 55 |
+
PATHNAME f;
|
| 56 |
+
string pathspec[ 1 ];
|
| 57 |
+
string pathname[ 1 ];
|
| 58 |
+
LIST * files = L0;
|
| 59 |
+
int d_length;
|
| 60 |
+
|
| 61 |
+
assert( d );
|
| 62 |
+
assert( d->is_dir );
|
| 63 |
+
assert( list_empty( d->files ) );
|
| 64 |
+
|
| 65 |
+
d_length = strlen( object_str( d->name ) );
|
| 66 |
+
|
| 67 |
+
memset( (char *)&f, '\0', sizeof( f ) );
|
| 68 |
+
f.f_dir.ptr = object_str( d->name );
|
| 69 |
+
f.f_dir.len = d_length;
|
| 70 |
+
|
| 71 |
+
/* Prepare file search specification for the FindXXX() Windows API. */
|
| 72 |
+
if ( !d_length )
|
| 73 |
+
string_copy( pathspec, ".\\*" );
|
| 74 |
+
else
|
| 75 |
+
{
|
| 76 |
+
/* We can not simply assume the given folder name will never include its
|
| 77 |
+
* trailing path separator or otherwise we would not support the Windows
|
| 78 |
+
* root folder specified without its drive letter, i.e. '\'.
|
| 79 |
+
*/
|
| 80 |
+
char const trailingChar = object_str( d->name )[ d_length - 1 ] ;
|
| 81 |
+
string_copy( pathspec, object_str( d->name ) );
|
| 82 |
+
if ( ( trailingChar != '\\' ) && ( trailingChar != '/' ) )
|
| 83 |
+
string_append( pathspec, "\\" );
|
| 84 |
+
string_append( pathspec, "*" );
|
| 85 |
+
}
|
| 86 |
+
|
| 87 |
+
/* The following code for collecting information about all files in a folder
|
| 88 |
+
* needs to be kept synchronized with how the file_query() operation is
|
| 89 |
+
* implemented (collects information about a single file).
|
| 90 |
+
*/
|
| 91 |
+
{
|
| 92 |
+
/* FIXME: Avoid duplicate FindXXX Windows API calls here and in the code
|
| 93 |
+
* determining a normalized path.
|
| 94 |
+
*/
|
| 95 |
+
WIN32_FIND_DATA finfo;
|
| 96 |
+
HANDLE const findHandle = FindFirstFileA( pathspec->value, &finfo );
|
| 97 |
+
if ( findHandle == INVALID_HANDLE_VALUE )
|
| 98 |
+
{
|
| 99 |
+
string_free( pathspec );
|
| 100 |
+
return -1;
|
| 101 |
+
}
|
| 102 |
+
|
| 103 |
+
string_new( pathname );
|
| 104 |
+
do
|
| 105 |
+
{
|
| 106 |
+
OBJECT * pathname_obj;
|
| 107 |
+
|
| 108 |
+
f.f_base.ptr = finfo.cFileName;
|
| 109 |
+
f.f_base.len = strlen( finfo.cFileName );
|
| 110 |
+
|
| 111 |
+
string_truncate( pathname, 0 );
|
| 112 |
+
path_build( &f, pathname );
|
| 113 |
+
|
| 114 |
+
pathname_obj = object_new( pathname->value );
|
| 115 |
+
path_register_key( pathname_obj );
|
| 116 |
+
files = list_push_back( files, pathname_obj );
|
| 117 |
+
{
|
| 118 |
+
int found;
|
| 119 |
+
file_info_t * const ff = file_info( pathname_obj, &found );
|
| 120 |
+
ff->is_dir = finfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
|
| 121 |
+
ff->is_file = !ff->is_dir;
|
| 122 |
+
ff->exists = 1;
|
| 123 |
+
timestamp_from_filetime( &ff->time, &finfo.ftLastWriteTime );
|
| 124 |
+
}
|
| 125 |
+
}
|
| 126 |
+
while ( FindNextFile( findHandle, &finfo ) );
|
| 127 |
+
|
| 128 |
+
FindClose( findHandle );
|
| 129 |
+
}
|
| 130 |
+
|
| 131 |
+
string_free( pathname );
|
| 132 |
+
string_free( pathspec );
|
| 133 |
+
|
| 134 |
+
d->files = files;
|
| 135 |
+
return 0;
|
| 136 |
+
}
|
| 137 |
+
|
| 138 |
+
|
| 139 |
+
/*
|
| 140 |
+
* file_dirscan_() - OS specific file_dirscan() implementation
|
| 141 |
+
*/
|
| 142 |
+
|
| 143 |
+
void file_dirscan_( file_info_t * const d, scanback func, void * closure )
|
| 144 |
+
{
|
| 145 |
+
assert( d );
|
| 146 |
+
assert( d->is_dir );
|
| 147 |
+
|
| 148 |
+
/* Special case \ or d:\ : enter it */
|
| 149 |
+
{
|
| 150 |
+
char const * const name = object_str( d->name );
|
| 151 |
+
if ( name[ 0 ] == '\\' && !name[ 1 ] )
|
| 152 |
+
{
|
| 153 |
+
(*func)( closure, d->name, 1 /* stat()'ed */, &d->time );
|
| 154 |
+
}
|
| 155 |
+
else if ( name[ 0 ] && name[ 1 ] == ':' && name[ 2 ] && !name[ 3 ] )
|
| 156 |
+
{
|
| 157 |
+
/* We have just entered a 3-letter drive name spelling (with a
|
| 158 |
+
* trailing slash), into the hash table. Now enter its two-letter
|
| 159 |
+
* variant, without the trailing slash, so that if we try to check
|
| 160 |
+
* whether "c:" exists, we hit it.
|
| 161 |
+
*
|
| 162 |
+
* Jam core has workarounds for that. Given:
|
| 163 |
+
* x = c:\whatever\foo ;
|
| 164 |
+
* p = $(x:D) ;
|
| 165 |
+
* p2 = $(p:D) ;
|
| 166 |
+
* There will be no trailing slash in $(p), but there will be one in
|
| 167 |
+
* $(p2). But, that seems rather fragile.
|
| 168 |
+
*/
|
| 169 |
+
OBJECT * const dir_no_slash = object_new_range( name, 2 );
|
| 170 |
+
(*func)( closure, d->name, 1 /* stat()'ed */, &d->time );
|
| 171 |
+
(*func)( closure, dir_no_slash, 1 /* stat()'ed */, &d->time );
|
| 172 |
+
object_free( dir_no_slash );
|
| 173 |
+
}
|
| 174 |
+
}
|
| 175 |
+
}
|
| 176 |
+
|
| 177 |
+
|
| 178 |
+
/*
|
| 179 |
+
* file_mkdir() - create a directory
|
| 180 |
+
*/
|
| 181 |
+
|
| 182 |
+
int file_mkdir( char const * const path )
|
| 183 |
+
{
|
| 184 |
+
return _mkdir( path );
|
| 185 |
+
}
|
| 186 |
+
|
| 187 |
+
|
| 188 |
+
/*
|
| 189 |
+
* file_query_() - query information about a path from the OS
|
| 190 |
+
*
|
| 191 |
+
* The following code for collecting information about a single file needs to be
|
| 192 |
+
* kept synchronized with how the file_collect_dir_content_() operation is
|
| 193 |
+
* implemented (collects information about all files in a folder).
|
| 194 |
+
*/
|
| 195 |
+
|
| 196 |
+
int try_file_query_root( file_info_t * const info )
|
| 197 |
+
{
|
| 198 |
+
WIN32_FILE_ATTRIBUTE_DATA fileData;
|
| 199 |
+
char buf[ 4 ];
|
| 200 |
+
char const * const pathstr = object_str( info->name );
|
| 201 |
+
if ( !pathstr[ 0 ] )
|
| 202 |
+
{
|
| 203 |
+
buf[ 0 ] = '.';
|
| 204 |
+
buf[ 1 ] = 0;
|
| 205 |
+
}
|
| 206 |
+
else if ( pathstr[ 0 ] == '\\' && ! pathstr[ 1 ] )
|
| 207 |
+
{
|
| 208 |
+
buf[ 0 ] = '\\';
|
| 209 |
+
buf[ 1 ] = '\0';
|
| 210 |
+
}
|
| 211 |
+
else if ( pathstr[ 1 ] == ':' )
|
| 212 |
+
{
|
| 213 |
+
if ( !pathstr[ 2 ] )
|
| 214 |
+
{
|
| 215 |
+
}
|
| 216 |
+
else if ( !pathstr[ 2 ] || ( pathstr[ 2 ] == '\\' && !pathstr[ 3 ] ) )
|
| 217 |
+
{
|
| 218 |
+
buf[ 0 ] = pathstr[ 0 ];
|
| 219 |
+
buf[ 1 ] = ':';
|
| 220 |
+
buf[ 2 ] = '\\';
|
| 221 |
+
buf[ 3 ] = '\0';
|
| 222 |
+
}
|
| 223 |
+
else
|
| 224 |
+
{
|
| 225 |
+
return 0;
|
| 226 |
+
}
|
| 227 |
+
}
|
| 228 |
+
else
|
| 229 |
+
{
|
| 230 |
+
return 0;
|
| 231 |
+
}
|
| 232 |
+
|
| 233 |
+
/* We have a root path */
|
| 234 |
+
if ( !GetFileAttributesExA( buf, GetFileExInfoStandard, &fileData ) )
|
| 235 |
+
{
|
| 236 |
+
info->is_dir = 0;
|
| 237 |
+
info->is_file = 0;
|
| 238 |
+
info->exists = 0;
|
| 239 |
+
timestamp_clear( &info->time );
|
| 240 |
+
}
|
| 241 |
+
else
|
| 242 |
+
{
|
| 243 |
+
info->is_dir = fileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
|
| 244 |
+
info->is_file = !info->is_dir;
|
| 245 |
+
info->exists = 1;
|
| 246 |
+
timestamp_from_filetime( &info->time, &fileData.ftLastWriteTime );
|
| 247 |
+
}
|
| 248 |
+
return 1;
|
| 249 |
+
}
|
| 250 |
+
|
| 251 |
+
void file_query_( file_info_t * const info )
|
| 252 |
+
{
|
| 253 |
+
char const * const pathstr = object_str( info->name );
|
| 254 |
+
const char * dir;
|
| 255 |
+
OBJECT * parent;
|
| 256 |
+
file_info_t * parent_info;
|
| 257 |
+
|
| 258 |
+
if ( try_file_query_root( info ) )
|
| 259 |
+
return;
|
| 260 |
+
|
| 261 |
+
if ( ( dir = strrchr( pathstr, '\\' ) ) )
|
| 262 |
+
{
|
| 263 |
+
parent = object_new_range( pathstr, dir - pathstr );
|
| 264 |
+
}
|
| 265 |
+
else
|
| 266 |
+
{
|
| 267 |
+
parent = object_copy( constant_empty );
|
| 268 |
+
}
|
| 269 |
+
parent_info = file_query( parent );
|
| 270 |
+
object_free( parent );
|
| 271 |
+
if ( !parent_info || !parent_info->is_dir )
|
| 272 |
+
{
|
| 273 |
+
info->is_dir = 0;
|
| 274 |
+
info->is_file = 0;
|
| 275 |
+
info->exists = 0;
|
| 276 |
+
timestamp_clear( &info->time );
|
| 277 |
+
}
|
| 278 |
+
else
|
| 279 |
+
{
|
| 280 |
+
info->is_dir = 0;
|
| 281 |
+
info->is_file = 0;
|
| 282 |
+
info->exists = 0;
|
| 283 |
+
timestamp_clear( &info->time );
|
| 284 |
+
if ( list_empty( parent_info->files ) )
|
| 285 |
+
file_collect_dir_content_( parent_info );
|
| 286 |
+
}
|
| 287 |
+
}
|
| 288 |
+
|
| 289 |
+
|
| 290 |
+
/*
|
| 291 |
+
* file_supported_fmt_resolution() - file modification timestamp resolution
|
| 292 |
+
*
|
| 293 |
+
* Returns the minimum file modification timestamp resolution supported by this
|
| 294 |
+
* Boost Jam implementation. File modification timestamp changes of less than
|
| 295 |
+
* the returned value might not be recognized.
|
| 296 |
+
*
|
| 297 |
+
* Does not take into consideration any OS or file system related restrictions.
|
| 298 |
+
*
|
| 299 |
+
* Return value 0 indicates that any value supported by the OS is also supported
|
| 300 |
+
* here.
|
| 301 |
+
*/
|
| 302 |
+
|
| 303 |
+
void file_supported_fmt_resolution( timestamp * const t )
|
| 304 |
+
{
|
| 305 |
+
/* On Windows we support nano-second file modification timestamp resolution,
|
| 306 |
+
* just the same as the Windows OS itself.
|
| 307 |
+
*/
|
| 308 |
+
timestamp_init( t, 0, 0 );
|
| 309 |
+
}
|
| 310 |
+
|
| 311 |
+
#endif /* OS_NT */
|
mosesdecoder/jam-files/engine/fileunix.c
ADDED
|
@@ -0,0 +1,180 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/*
|
| 2 |
+
* Copyright 1993-2002 Christopher Seiwald and Perforce Software, Inc.
|
| 3 |
+
*
|
| 4 |
+
* This file is part of Jam - see jam.c for Copyright information.
|
| 5 |
+
*/
|
| 6 |
+
|
| 7 |
+
/* This file is ALSO:
|
| 8 |
+
* Copyright 2001-2004 David Abrahams.
|
| 9 |
+
* Copyright 2005 Rene Rivera.
|
| 10 |
+
* Distributed under the Boost Software License, Version 1.0.
|
| 11 |
+
* (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
|
| 12 |
+
*/
|
| 13 |
+
|
| 14 |
+
/*
|
| 15 |
+
* fileunix.c - manipulate file names and scan directories on UNIX/AmigaOS
|
| 16 |
+
*
|
| 17 |
+
* External routines:
|
| 18 |
+
* file_mkdir() - create a directory
|
| 19 |
+
* file_supported_fmt_resolution() - file modification timestamp resolution
|
| 20 |
+
*
|
| 21 |
+
* External routines called only via routines in filesys.c:
|
| 22 |
+
* file_collect_dir_content_() - collects directory content information
|
| 23 |
+
* file_dirscan_() - OS specific file_dirscan() implementation
|
| 24 |
+
* file_query_() - query information about a path from the OS
|
| 25 |
+
*/
|
| 26 |
+
|
| 27 |
+
#include "jam.h"
|
| 28 |
+
#ifdef USE_FILEUNIX
|
| 29 |
+
#include "filesys.h"
|
| 30 |
+
|
| 31 |
+
#include "object.h"
|
| 32 |
+
#include "pathsys.h"
|
| 33 |
+
#include "strings.h"
|
| 34 |
+
|
| 35 |
+
#include <assert.h>
|
| 36 |
+
#include <stdio.h>
|
| 37 |
+
#include <sys/stat.h> /* needed for mkdir() */
|
| 38 |
+
|
| 39 |
+
#if defined( sun ) || defined( __sun ) || defined( linux )
|
| 40 |
+
# include <unistd.h> /* needed for read and close prototype */
|
| 41 |
+
#endif
|
| 42 |
+
|
| 43 |
+
#if defined( OS_SEQUENT ) || \
|
| 44 |
+
defined( OS_DGUX ) || \
|
| 45 |
+
defined( OS_SCO ) || \
|
| 46 |
+
defined( OS_ISC )
|
| 47 |
+
# define PORTAR 1
|
| 48 |
+
#endif
|
| 49 |
+
|
| 50 |
+
#if defined( OS_RHAPSODY ) || defined( OS_MACOSX ) || defined( OS_NEXT )
|
| 51 |
+
# include <sys/dir.h>
|
| 52 |
+
# include <unistd.h> /* need unistd for rhapsody's proper lseek */
|
| 53 |
+
# define STRUCT_DIRENT struct direct
|
| 54 |
+
#else
|
| 55 |
+
# include <dirent.h>
|
| 56 |
+
# define STRUCT_DIRENT struct dirent
|
| 57 |
+
#endif
|
| 58 |
+
|
| 59 |
+
/*
|
| 60 |
+
* file_collect_dir_content_() - collects directory content information
|
| 61 |
+
*/
|
| 62 |
+
|
| 63 |
+
int file_collect_dir_content_( file_info_t * const d )
|
| 64 |
+
{
|
| 65 |
+
LIST * files = L0;
|
| 66 |
+
PATHNAME f;
|
| 67 |
+
DIR * dd;
|
| 68 |
+
STRUCT_DIRENT * dirent;
|
| 69 |
+
string path[ 1 ];
|
| 70 |
+
char const * dirstr;
|
| 71 |
+
|
| 72 |
+
assert( d );
|
| 73 |
+
assert( d->is_dir );
|
| 74 |
+
assert( list_empty( d->files ) );
|
| 75 |
+
|
| 76 |
+
dirstr = object_str( d->name );
|
| 77 |
+
|
| 78 |
+
memset( (char *)&f, '\0', sizeof( f ) );
|
| 79 |
+
f.f_dir.ptr = dirstr;
|
| 80 |
+
f.f_dir.len = strlen( dirstr );
|
| 81 |
+
|
| 82 |
+
if ( !*dirstr ) dirstr = ".";
|
| 83 |
+
|
| 84 |
+
if ( !( dd = opendir( dirstr ) ) )
|
| 85 |
+
return -1;
|
| 86 |
+
|
| 87 |
+
string_new( path );
|
| 88 |
+
while ( ( dirent = readdir( dd ) ) )
|
| 89 |
+
{
|
| 90 |
+
OBJECT * name;
|
| 91 |
+
f.f_base.ptr = dirent->d_name
|
| 92 |
+
#ifdef old_sinix
|
| 93 |
+
- 2 /* Broken structure definition on sinix. */
|
| 94 |
+
#endif
|
| 95 |
+
;
|
| 96 |
+
f.f_base.len = strlen( f.f_base.ptr );
|
| 97 |
+
|
| 98 |
+
string_truncate( path, 0 );
|
| 99 |
+
path_build( &f, path );
|
| 100 |
+
name = object_new( path->value );
|
| 101 |
+
/* Immediately stat the file to preserve invariants. */
|
| 102 |
+
if ( file_query( name ) )
|
| 103 |
+
files = list_push_back( files, name );
|
| 104 |
+
else
|
| 105 |
+
object_free( name );
|
| 106 |
+
}
|
| 107 |
+
string_free( path );
|
| 108 |
+
|
| 109 |
+
closedir( dd );
|
| 110 |
+
|
| 111 |
+
d->files = files;
|
| 112 |
+
return 0;
|
| 113 |
+
}
|
| 114 |
+
|
| 115 |
+
|
| 116 |
+
/*
|
| 117 |
+
* file_dirscan_() - OS specific file_dirscan() implementation
|
| 118 |
+
*/
|
| 119 |
+
|
| 120 |
+
void file_dirscan_( file_info_t * const d, scanback func, void * closure )
|
| 121 |
+
{
|
| 122 |
+
assert( d );
|
| 123 |
+
assert( d->is_dir );
|
| 124 |
+
|
| 125 |
+
/* Special case / : enter it */
|
| 126 |
+
if ( !strcmp( object_str( d->name ), "/" ) )
|
| 127 |
+
(*func)( closure, d->name, 1 /* stat()'ed */, &d->time );
|
| 128 |
+
}
|
| 129 |
+
|
| 130 |
+
|
| 131 |
+
/*
|
| 132 |
+
* file_mkdir() - create a directory
|
| 133 |
+
*/
|
| 134 |
+
|
| 135 |
+
int file_mkdir( char const * const path )
|
| 136 |
+
{
|
| 137 |
+
#if defined(__MINGW32__)
|
| 138 |
+
/* MinGW's mkdir() takes only one argument: the path. */
|
| 139 |
+
mkdir(path);
|
| 140 |
+
#else
|
| 141 |
+
/* Explicit cast to remove const modifiers and avoid related compiler
|
| 142 |
+
* warnings displayed when using the intel compiler.
|
| 143 |
+
*/
|
| 144 |
+
return mkdir( (char *)path, 0777 );
|
| 145 |
+
#endif
|
| 146 |
+
}
|
| 147 |
+
|
| 148 |
+
|
| 149 |
+
/*
|
| 150 |
+
* file_query_() - query information about a path from the OS
|
| 151 |
+
*/
|
| 152 |
+
|
| 153 |
+
void file_query_( file_info_t * const info )
|
| 154 |
+
{
|
| 155 |
+
file_query_posix_( info );
|
| 156 |
+
}
|
| 157 |
+
|
| 158 |
+
|
| 159 |
+
/*
|
| 160 |
+
* file_supported_fmt_resolution() - file modification timestamp resolution
|
| 161 |
+
*
|
| 162 |
+
* Returns the minimum file modification timestamp resolution supported by this
|
| 163 |
+
* Boost Jam implementation. File modification timestamp changes of less than
|
| 164 |
+
* the returned value might not be recognized.
|
| 165 |
+
*
|
| 166 |
+
* Does not take into consideration any OS or file system related restrictions.
|
| 167 |
+
*
|
| 168 |
+
* Return value 0 indicates that any value supported by the OS is also supported
|
| 169 |
+
* here.
|
| 170 |
+
*/
|
| 171 |
+
|
| 172 |
+
void file_supported_fmt_resolution( timestamp * const t )
|
| 173 |
+
{
|
| 174 |
+
/* The current implementation does not support file modification timestamp
|
| 175 |
+
* resolution of less than one second.
|
| 176 |
+
*/
|
| 177 |
+
timestamp_init( t, 1, 0 );
|
| 178 |
+
}
|
| 179 |
+
|
| 180 |
+
#endif /* USE_FILEUNIX */
|
mosesdecoder/jam-files/engine/frames.c
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/*
|
| 2 |
+
* Copyright 2001-2004 David Abrahams.
|
| 3 |
+
* Distributed under the Boost Software License, Version 1.0.
|
| 4 |
+
* (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
|
| 5 |
+
*/
|
| 6 |
+
|
| 7 |
+
#include "jam.h"
|
| 8 |
+
#include "frames.h"
|
| 9 |
+
|
| 10 |
+
|
| 11 |
+
FRAME * frame_before_python_call;
|
| 12 |
+
|
| 13 |
+
|
| 14 |
+
void frame_init( FRAME * frame )
|
| 15 |
+
{
|
| 16 |
+
frame->prev = 0;
|
| 17 |
+
frame->prev_user = 0;
|
| 18 |
+
lol_init( frame->args );
|
| 19 |
+
frame->module = root_module();
|
| 20 |
+
frame->rulename = "module scope";
|
| 21 |
+
frame->file = 0;
|
| 22 |
+
frame->line = -1;
|
| 23 |
+
}
|
| 24 |
+
|
| 25 |
+
|
| 26 |
+
void frame_free( FRAME * frame )
|
| 27 |
+
{
|
| 28 |
+
lol_free( frame->args );
|
| 29 |
+
}
|
mosesdecoder/jam-files/engine/function.c
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
mosesdecoder/jam-files/engine/function.h
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/*
|
| 2 |
+
* Copyright 2011 Steven Watanabe
|
| 3 |
+
* Distributed under the Boost Software License, Version 1.0.
|
| 4 |
+
* (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
|
| 5 |
+
*/
|
| 6 |
+
|
| 7 |
+
#ifndef FUNCTION_SW20111123_H
|
| 8 |
+
#define FUNCTION_SW20111123_H
|
| 9 |
+
|
| 10 |
+
#include "object.h"
|
| 11 |
+
#include "frames.h"
|
| 12 |
+
#include "lists.h"
|
| 13 |
+
#include "parse.h"
|
| 14 |
+
#include "strings.h"
|
| 15 |
+
|
| 16 |
+
typedef struct _function FUNCTION;
|
| 17 |
+
typedef struct _stack STACK;
|
| 18 |
+
|
| 19 |
+
STACK * stack_global( void );
|
| 20 |
+
void stack_push( STACK * s, LIST * l );
|
| 21 |
+
LIST * stack_pop( STACK * s );
|
| 22 |
+
|
| 23 |
+
FUNCTION * function_compile( PARSE * parse );
|
| 24 |
+
FUNCTION * function_builtin( LIST * ( * func )( FRAME * frame, int flags ), int flags, const char * * args );
|
| 25 |
+
void function_refer( FUNCTION * );
|
| 26 |
+
void function_free( FUNCTION * );
|
| 27 |
+
OBJECT * function_rulename( FUNCTION * );
|
| 28 |
+
void function_set_rulename( FUNCTION *, OBJECT * );
|
| 29 |
+
void function_location( FUNCTION *, OBJECT * *, int * );
|
| 30 |
+
LIST * function_run( FUNCTION * function, FRAME * frame, STACK * s );
|
| 31 |
+
|
| 32 |
+
FUNCTION * function_compile_actions( const char * actions, OBJECT * file, int line );
|
| 33 |
+
void function_run_actions( FUNCTION * function, FRAME * frame, STACK * s, string * out );
|
| 34 |
+
|
| 35 |
+
FUNCTION * function_bind_variables( FUNCTION * f, module_t * module, int * counter );
|
| 36 |
+
FUNCTION * function_unbind_variables( FUNCTION * f );
|
| 37 |
+
|
| 38 |
+
void function_done( void );
|
| 39 |
+
|
| 40 |
+
#ifdef HAVE_PYTHON
|
| 41 |
+
|
| 42 |
+
FUNCTION * function_python( PyObject * function, PyObject * bjam_signature );
|
| 43 |
+
|
| 44 |
+
#endif
|
| 45 |
+
|
| 46 |
+
#endif
|
mosesdecoder/jam-files/engine/hash.h
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/*
|
| 2 |
+
* Copyright 1993, 1995 Christopher Seiwald.
|
| 3 |
+
*
|
| 4 |
+
* This file is part of Jam - see jam.c for Copyright information.
|
| 5 |
+
*/
|
| 6 |
+
|
| 7 |
+
/*
|
| 8 |
+
* hash.h - simple in-memory hashing routines
|
| 9 |
+
*/
|
| 10 |
+
|
| 11 |
+
#ifndef BOOST_JAM_HASH_H
|
| 12 |
+
#define BOOST_JAM_HASH_H
|
| 13 |
+
|
| 14 |
+
#include "object.h"
|
| 15 |
+
|
| 16 |
+
/*
|
| 17 |
+
* An opaque struct representing an item in the hash table. The first element of
|
| 18 |
+
* every struct stored in the table must be an OBJECT * which is treated as the
|
| 19 |
+
* key.
|
| 20 |
+
*/
|
| 21 |
+
typedef struct hashdata HASHDATA;
|
| 22 |
+
|
| 23 |
+
/*
|
| 24 |
+
* hashinit() - initialize a hash table, returning a handle.
|
| 25 |
+
*
|
| 26 |
+
* Parameters:
|
| 27 |
+
* datalen - item size
|
| 28 |
+
* name - used for debugging
|
| 29 |
+
*/
|
| 30 |
+
struct hash * hashinit( int datalen, char const * name );
|
| 31 |
+
|
| 32 |
+
/*
|
| 33 |
+
* hash_free() - free a hash table, given its handle
|
| 34 |
+
*/
|
| 35 |
+
void hash_free( struct hash * );
|
| 36 |
+
void hashdone( struct hash * );
|
| 37 |
+
|
| 38 |
+
/*
|
| 39 |
+
* hashenumerate() - call f(i, data) on each item, i in the hash table. The
|
| 40 |
+
* enumeration order is unspecified.
|
| 41 |
+
*/
|
| 42 |
+
void hashenumerate( struct hash *, void (* f)( void *, void * ), void * data );
|
| 43 |
+
|
| 44 |
+
/*
|
| 45 |
+
* hash_insert() - insert a new item in a hash table, or return an existing one.
|
| 46 |
+
*
|
| 47 |
+
* Preconditions:
|
| 48 |
+
* - hp must be a hash table created by hashinit()
|
| 49 |
+
* - key must be an object created by object_new()
|
| 50 |
+
*
|
| 51 |
+
* Postconditions:
|
| 52 |
+
* - if the key does not already exist in the hash table, *found == 0 and the
|
| 53 |
+
* result will be a pointer to an uninitialized item. The key of the new
|
| 54 |
+
* item must be set to a value equal to key before any further operations on
|
| 55 |
+
* the hash table except hashdone().
|
| 56 |
+
* - if the key is present then *found == 1 and the result is a pointer to the
|
| 57 |
+
* existing record.
|
| 58 |
+
*/
|
| 59 |
+
HASHDATA * hash_insert( struct hash *, OBJECT * key, int * found );
|
| 60 |
+
|
| 61 |
+
/*
|
| 62 |
+
* hash_find() - find a record in the table or NULL if none exists
|
| 63 |
+
*/
|
| 64 |
+
HASHDATA * hash_find( struct hash *, OBJECT * key );
|
| 65 |
+
|
| 66 |
+
struct hashstats {
|
| 67 |
+
int count;
|
| 68 |
+
int num_items;
|
| 69 |
+
int tab_size;
|
| 70 |
+
int item_size;
|
| 71 |
+
int sets;
|
| 72 |
+
int num_hashes;
|
| 73 |
+
};
|
| 74 |
+
|
| 75 |
+
void hashstats_init( struct hashstats * stats );
|
| 76 |
+
void hashstats_add( struct hashstats * stats, struct hash * );
|
| 77 |
+
void hashstats_print( struct hashstats * stats, char const * name );
|
| 78 |
+
|
| 79 |
+
#endif
|
mosesdecoder/jam-files/engine/hcache.c
ADDED
|
@@ -0,0 +1,519 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/*
|
| 2 |
+
* This file has been donated to Jam.
|
| 3 |
+
*/
|
| 4 |
+
|
| 5 |
+
/*
|
| 6 |
+
* Craig W. McPheeters, Alias|Wavefront.
|
| 7 |
+
*
|
| 8 |
+
* hcache.c hcache.h - handle cacheing of #includes in source files.
|
| 9 |
+
*
|
| 10 |
+
* Create a cache of files scanned for headers. When starting jam, look for the
|
| 11 |
+
* cache file and load it if present. When finished the binding phase, create a
|
| 12 |
+
* new header cache. The cache contains files, their timestamps and the header
|
| 13 |
+
* files found in their scan. During the binding phase of jam, look in the
|
| 14 |
+
* header cache first for the headers contained in a file. If the cache is
|
| 15 |
+
* present and valid, use its contents. This results in dramatic speedups with
|
| 16 |
+
* large projects (e.g. 3min -> 1min startup for one project.)
|
| 17 |
+
*
|
| 18 |
+
* External routines:
|
| 19 |
+
* hcache_init() - read and parse the local .jamdeps file.
|
| 20 |
+
* hcache_done() - write a new .jamdeps file.
|
| 21 |
+
* hcache() - return list of headers on target. Use cache or do a scan.
|
| 22 |
+
*
|
| 23 |
+
* The dependency file format is an ASCII file with 1 line per target. Each line
|
| 24 |
+
* has the following fields:
|
| 25 |
+
* @boundname@ timestamp_sec timestamp_nsec @file@ @file@ @file@ ...
|
| 26 |
+
*/
|
| 27 |
+
|
| 28 |
+
#ifdef OPT_HEADER_CACHE_EXT
|
| 29 |
+
|
| 30 |
+
#include "jam.h"
|
| 31 |
+
#include "hcache.h"
|
| 32 |
+
|
| 33 |
+
#include "hash.h"
|
| 34 |
+
#include "headers.h"
|
| 35 |
+
#include "lists.h"
|
| 36 |
+
#include "modules.h"
|
| 37 |
+
#include "object.h"
|
| 38 |
+
#include "parse.h"
|
| 39 |
+
#include "regexp.h"
|
| 40 |
+
#include "rules.h"
|
| 41 |
+
#include "search.h"
|
| 42 |
+
#include "timestamp.h"
|
| 43 |
+
#include "variable.h"
|
| 44 |
+
|
| 45 |
+
typedef struct hcachedata HCACHEDATA ;
|
| 46 |
+
|
| 47 |
+
struct hcachedata
|
| 48 |
+
{
|
| 49 |
+
OBJECT * boundname;
|
| 50 |
+
timestamp time;
|
| 51 |
+
LIST * includes;
|
| 52 |
+
LIST * hdrscan; /* the HDRSCAN value for this target */
|
| 53 |
+
int age; /* if too old, we will remove it from cache */
|
| 54 |
+
HCACHEDATA * next;
|
| 55 |
+
};
|
| 56 |
+
|
| 57 |
+
|
| 58 |
+
static struct hash * hcachehash = 0;
|
| 59 |
+
static HCACHEDATA * hcachelist = 0;
|
| 60 |
+
|
| 61 |
+
static int queries = 0;
|
| 62 |
+
static int hits = 0;
|
| 63 |
+
|
| 64 |
+
#define CACHE_FILE_VERSION "version 5"
|
| 65 |
+
#define CACHE_RECORD_HEADER "header"
|
| 66 |
+
#define CACHE_RECORD_END "end"
|
| 67 |
+
|
| 68 |
+
|
| 69 |
+
/*
|
| 70 |
+
* Return the name of the header cache file. May return NULL.
|
| 71 |
+
*
|
| 72 |
+
* The user sets this by setting the HCACHEFILE variable in a Jamfile. We cache
|
| 73 |
+
* the result so the user can not change the cache file during header scanning.
|
| 74 |
+
*/
|
| 75 |
+
|
| 76 |
+
static const char * cache_name( void )
|
| 77 |
+
{
|
| 78 |
+
static OBJECT * name = 0;
|
| 79 |
+
if ( !name )
|
| 80 |
+
{
|
| 81 |
+
LIST * const hcachevar = var_get( root_module(), constant_HCACHEFILE );
|
| 82 |
+
|
| 83 |
+
if ( !list_empty( hcachevar ) )
|
| 84 |
+
{
|
| 85 |
+
TARGET * const t = bindtarget( list_front( hcachevar ) );
|
| 86 |
+
|
| 87 |
+
pushsettings( root_module(), t->settings );
|
| 88 |
+
/* Do not expect the cache file to be generated, so pass 0 as the
|
| 89 |
+
* third argument to search. Expect the location to be specified via
|
| 90 |
+
* LOCATE, so pass 0 as the fourth arugment.
|
| 91 |
+
*/
|
| 92 |
+
object_free( t->boundname );
|
| 93 |
+
t->boundname = search( t->name, &t->time, 0, 0 );
|
| 94 |
+
popsettings( root_module(), t->settings );
|
| 95 |
+
|
| 96 |
+
name = object_copy( t->boundname );
|
| 97 |
+
}
|
| 98 |
+
}
|
| 99 |
+
return name ? object_str( name ) : 0;
|
| 100 |
+
}
|
| 101 |
+
|
| 102 |
+
|
| 103 |
+
/*
|
| 104 |
+
* Return the maximum age a cache entry can have before it is purged from the
|
| 105 |
+
* cache.
|
| 106 |
+
*/
|
| 107 |
+
|
| 108 |
+
static int cache_maxage( void )
|
| 109 |
+
{
|
| 110 |
+
int age = 100;
|
| 111 |
+
LIST * const var = var_get( root_module(), constant_HCACHEMAXAGE );
|
| 112 |
+
if ( !list_empty( var ) )
|
| 113 |
+
{
|
| 114 |
+
age = atoi( object_str( list_front( var ) ) );
|
| 115 |
+
if ( age < 0 )
|
| 116 |
+
age = 0;
|
| 117 |
+
}
|
| 118 |
+
return age;
|
| 119 |
+
}
|
| 120 |
+
|
| 121 |
+
|
| 122 |
+
/*
|
| 123 |
+
* Read a netstring. The caveat is that the string can not contain ASCII 0. The
|
| 124 |
+
* returned value is as returned by object_new().
|
| 125 |
+
*/
|
| 126 |
+
|
| 127 |
+
OBJECT * read_netstring( FILE * f )
|
| 128 |
+
{
|
| 129 |
+
unsigned long len;
|
| 130 |
+
static char * buf = NULL;
|
| 131 |
+
static unsigned long buf_len = 0;
|
| 132 |
+
|
| 133 |
+
if ( fscanf( f, " %9lu", &len ) != 1 )
|
| 134 |
+
return NULL;
|
| 135 |
+
if ( fgetc( f ) != (int)'\t' )
|
| 136 |
+
return NULL;
|
| 137 |
+
|
| 138 |
+
if ( len > 1024 * 64 )
|
| 139 |
+
return NULL; /* sanity check */
|
| 140 |
+
|
| 141 |
+
if ( len > buf_len )
|
| 142 |
+
{
|
| 143 |
+
unsigned long new_len = buf_len * 2;
|
| 144 |
+
if ( new_len < len )
|
| 145 |
+
new_len = len;
|
| 146 |
+
buf = (char *)BJAM_REALLOC( buf, new_len + 1 );
|
| 147 |
+
if ( buf )
|
| 148 |
+
buf_len = new_len;
|
| 149 |
+
}
|
| 150 |
+
|
| 151 |
+
if ( !buf )
|
| 152 |
+
return NULL;
|
| 153 |
+
|
| 154 |
+
if ( fread( buf, 1, len, f ) != len )
|
| 155 |
+
return NULL;
|
| 156 |
+
if ( fgetc( f ) != (int)'\n' )
|
| 157 |
+
return NULL;
|
| 158 |
+
|
| 159 |
+
buf[ len ] = 0;
|
| 160 |
+
return object_new( buf );
|
| 161 |
+
}
|
| 162 |
+
|
| 163 |
+
|
| 164 |
+
/*
|
| 165 |
+
* Write a netstring.
|
| 166 |
+
*/
|
| 167 |
+
|
| 168 |
+
void write_netstring( FILE * f, char const * s )
|
| 169 |
+
{
|
| 170 |
+
if ( !s )
|
| 171 |
+
s = "";
|
| 172 |
+
fprintf( f, "%lu\t%s\n", (long unsigned)strlen( s ), s );
|
| 173 |
+
}
|
| 174 |
+
|
| 175 |
+
|
| 176 |
+
void hcache_init()
|
| 177 |
+
{
|
| 178 |
+
FILE * f;
|
| 179 |
+
OBJECT * version = 0;
|
| 180 |
+
int header_count = 0;
|
| 181 |
+
const char * hcachename;
|
| 182 |
+
|
| 183 |
+
if ( hcachehash )
|
| 184 |
+
return;
|
| 185 |
+
|
| 186 |
+
hcachehash = hashinit( sizeof( HCACHEDATA ), "hcache" );
|
| 187 |
+
|
| 188 |
+
if ( !( hcachename = cache_name() ) )
|
| 189 |
+
return;
|
| 190 |
+
|
| 191 |
+
if ( !( f = fopen( hcachename, "rb" ) ) )
|
| 192 |
+
return;
|
| 193 |
+
|
| 194 |
+
version = read_netstring( f );
|
| 195 |
+
|
| 196 |
+
if ( !version || strcmp( object_str( version ), CACHE_FILE_VERSION ) )
|
| 197 |
+
goto bail;
|
| 198 |
+
|
| 199 |
+
while ( 1 )
|
| 200 |
+
{
|
| 201 |
+
HCACHEDATA cachedata;
|
| 202 |
+
HCACHEDATA * c;
|
| 203 |
+
OBJECT * record_type = 0;
|
| 204 |
+
OBJECT * time_secs_str = 0;
|
| 205 |
+
OBJECT * time_nsecs_str = 0;
|
| 206 |
+
OBJECT * age_str = 0;
|
| 207 |
+
OBJECT * includes_count_str = 0;
|
| 208 |
+
OBJECT * hdrscan_count_str = 0;
|
| 209 |
+
int i;
|
| 210 |
+
int count;
|
| 211 |
+
LIST * l;
|
| 212 |
+
int found;
|
| 213 |
+
|
| 214 |
+
cachedata.boundname = 0;
|
| 215 |
+
cachedata.includes = 0;
|
| 216 |
+
cachedata.hdrscan = 0;
|
| 217 |
+
|
| 218 |
+
record_type = read_netstring( f );
|
| 219 |
+
if ( !record_type )
|
| 220 |
+
{
|
| 221 |
+
fprintf( stderr, "invalid %s\n", hcachename );
|
| 222 |
+
goto cleanup;
|
| 223 |
+
}
|
| 224 |
+
if ( !strcmp( object_str( record_type ), CACHE_RECORD_END ) )
|
| 225 |
+
{
|
| 226 |
+
object_free( record_type );
|
| 227 |
+
break;
|
| 228 |
+
}
|
| 229 |
+
if ( strcmp( object_str( record_type ), CACHE_RECORD_HEADER ) )
|
| 230 |
+
{
|
| 231 |
+
fprintf( stderr, "invalid %s with record separator <%s>\n",
|
| 232 |
+
hcachename, record_type ? object_str( record_type ) : "<null>" );
|
| 233 |
+
goto cleanup;
|
| 234 |
+
}
|
| 235 |
+
|
| 236 |
+
cachedata.boundname = read_netstring( f );
|
| 237 |
+
time_secs_str = read_netstring( f );
|
| 238 |
+
time_nsecs_str = read_netstring( f );
|
| 239 |
+
age_str = read_netstring( f );
|
| 240 |
+
includes_count_str = read_netstring( f );
|
| 241 |
+
|
| 242 |
+
if ( !cachedata.boundname || !time_secs_str || !time_nsecs_str ||
|
| 243 |
+
!age_str || !includes_count_str )
|
| 244 |
+
{
|
| 245 |
+
fprintf( stderr, "invalid %s\n", hcachename );
|
| 246 |
+
goto cleanup;
|
| 247 |
+
}
|
| 248 |
+
|
| 249 |
+
timestamp_init( &cachedata.time, atoi( object_str( time_secs_str ) ),
|
| 250 |
+
atoi( object_str( time_nsecs_str ) ) );
|
| 251 |
+
cachedata.age = atoi( object_str( age_str ) ) + 1;
|
| 252 |
+
|
| 253 |
+
count = atoi( object_str( includes_count_str ) );
|
| 254 |
+
for ( l = L0, i = 0; i < count; ++i )
|
| 255 |
+
{
|
| 256 |
+
OBJECT * const s = read_netstring( f );
|
| 257 |
+
if ( !s )
|
| 258 |
+
{
|
| 259 |
+
fprintf( stderr, "invalid %s\n", hcachename );
|
| 260 |
+
list_free( l );
|
| 261 |
+
goto cleanup;
|
| 262 |
+
}
|
| 263 |
+
l = list_push_back( l, s );
|
| 264 |
+
}
|
| 265 |
+
cachedata.includes = l;
|
| 266 |
+
|
| 267 |
+
hdrscan_count_str = read_netstring( f );
|
| 268 |
+
if ( !hdrscan_count_str )
|
| 269 |
+
{
|
| 270 |
+
fprintf( stderr, "invalid %s\n", hcachename );
|
| 271 |
+
goto cleanup;
|
| 272 |
+
}
|
| 273 |
+
|
| 274 |
+
count = atoi( object_str( hdrscan_count_str ) );
|
| 275 |
+
for ( l = L0, i = 0; i < count; ++i )
|
| 276 |
+
{
|
| 277 |
+
OBJECT * const s = read_netstring( f );
|
| 278 |
+
if ( !s )
|
| 279 |
+
{
|
| 280 |
+
fprintf( stderr, "invalid %s\n", hcachename );
|
| 281 |
+
list_free( l );
|
| 282 |
+
goto cleanup;
|
| 283 |
+
}
|
| 284 |
+
l = list_push_back( l, s );
|
| 285 |
+
}
|
| 286 |
+
cachedata.hdrscan = l;
|
| 287 |
+
|
| 288 |
+
c = (HCACHEDATA *)hash_insert( hcachehash, cachedata.boundname, &found )
|
| 289 |
+
;
|
| 290 |
+
if ( !found )
|
| 291 |
+
{
|
| 292 |
+
c->boundname = cachedata.boundname;
|
| 293 |
+
c->includes = cachedata.includes;
|
| 294 |
+
c->hdrscan = cachedata.hdrscan;
|
| 295 |
+
c->age = cachedata.age;
|
| 296 |
+
timestamp_copy( &c->time, &cachedata.time );
|
| 297 |
+
}
|
| 298 |
+
else
|
| 299 |
+
{
|
| 300 |
+
fprintf( stderr, "can not insert header cache item, bailing on %s"
|
| 301 |
+
"\n", hcachename );
|
| 302 |
+
goto cleanup;
|
| 303 |
+
}
|
| 304 |
+
|
| 305 |
+
c->next = hcachelist;
|
| 306 |
+
hcachelist = c;
|
| 307 |
+
|
| 308 |
+
++header_count;
|
| 309 |
+
|
| 310 |
+
object_free( record_type );
|
| 311 |
+
object_free( time_secs_str );
|
| 312 |
+
object_free( time_nsecs_str );
|
| 313 |
+
object_free( age_str );
|
| 314 |
+
object_free( includes_count_str );
|
| 315 |
+
object_free( hdrscan_count_str );
|
| 316 |
+
continue;
|
| 317 |
+
|
| 318 |
+
cleanup:
|
| 319 |
+
|
| 320 |
+
if ( record_type ) object_free( record_type );
|
| 321 |
+
if ( time_secs_str ) object_free( time_secs_str );
|
| 322 |
+
if ( time_nsecs_str ) object_free( time_nsecs_str );
|
| 323 |
+
if ( age_str ) object_free( age_str );
|
| 324 |
+
if ( includes_count_str ) object_free( includes_count_str );
|
| 325 |
+
if ( hdrscan_count_str ) object_free( hdrscan_count_str );
|
| 326 |
+
|
| 327 |
+
if ( cachedata.boundname ) object_free( cachedata.boundname );
|
| 328 |
+
if ( cachedata.includes ) list_free( cachedata.includes );
|
| 329 |
+
if ( cachedata.hdrscan ) list_free( cachedata.hdrscan );
|
| 330 |
+
|
| 331 |
+
goto bail;
|
| 332 |
+
}
|
| 333 |
+
|
| 334 |
+
if ( DEBUG_HEADER )
|
| 335 |
+
printf( "hcache read from file %s\n", hcachename );
|
| 336 |
+
|
| 337 |
+
bail:
|
| 338 |
+
if ( version )
|
| 339 |
+
object_free( version );
|
| 340 |
+
fclose( f );
|
| 341 |
+
}
|
| 342 |
+
|
| 343 |
+
|
| 344 |
+
void hcache_done()
|
| 345 |
+
{
|
| 346 |
+
FILE * f;
|
| 347 |
+
HCACHEDATA * c;
|
| 348 |
+
int header_count = 0;
|
| 349 |
+
const char * hcachename;
|
| 350 |
+
int maxage;
|
| 351 |
+
|
| 352 |
+
if ( !hcachehash )
|
| 353 |
+
return;
|
| 354 |
+
|
| 355 |
+
if ( !( hcachename = cache_name() ) )
|
| 356 |
+
goto cleanup;
|
| 357 |
+
|
| 358 |
+
if ( !( f = fopen( hcachename, "wb" ) ) )
|
| 359 |
+
goto cleanup;
|
| 360 |
+
|
| 361 |
+
maxage = cache_maxage();
|
| 362 |
+
|
| 363 |
+
/* Print out the version. */
|
| 364 |
+
write_netstring( f, CACHE_FILE_VERSION );
|
| 365 |
+
|
| 366 |
+
c = hcachelist;
|
| 367 |
+
for ( c = hcachelist; c; c = c->next )
|
| 368 |
+
{
|
| 369 |
+
LISTITER iter;
|
| 370 |
+
LISTITER end;
|
| 371 |
+
char time_secs_str[ 30 ];
|
| 372 |
+
char time_nsecs_str[ 30 ];
|
| 373 |
+
char age_str[ 30 ];
|
| 374 |
+
char includes_count_str[ 30 ];
|
| 375 |
+
char hdrscan_count_str[ 30 ];
|
| 376 |
+
|
| 377 |
+
if ( maxage == 0 )
|
| 378 |
+
c->age = 0;
|
| 379 |
+
else if ( c->age > maxage )
|
| 380 |
+
continue;
|
| 381 |
+
|
| 382 |
+
sprintf( includes_count_str, "%lu", (long unsigned)list_length(
|
| 383 |
+
c->includes ) );
|
| 384 |
+
sprintf( hdrscan_count_str, "%lu", (long unsigned)list_length(
|
| 385 |
+
c->hdrscan ) );
|
| 386 |
+
sprintf( time_secs_str, "%lu", (long unsigned)c->time.secs );
|
| 387 |
+
sprintf( time_nsecs_str, "%lu", (long unsigned)c->time.nsecs );
|
| 388 |
+
sprintf( age_str, "%lu", (long unsigned)c->age );
|
| 389 |
+
|
| 390 |
+
write_netstring( f, CACHE_RECORD_HEADER );
|
| 391 |
+
write_netstring( f, object_str( c->boundname ) );
|
| 392 |
+
write_netstring( f, time_secs_str );
|
| 393 |
+
write_netstring( f, time_nsecs_str );
|
| 394 |
+
write_netstring( f, age_str );
|
| 395 |
+
write_netstring( f, includes_count_str );
|
| 396 |
+
for ( iter = list_begin( c->includes ), end = list_end( c->includes );
|
| 397 |
+
iter != end; iter = list_next( iter ) )
|
| 398 |
+
write_netstring( f, object_str( list_item( iter ) ) );
|
| 399 |
+
write_netstring( f, hdrscan_count_str );
|
| 400 |
+
for ( iter = list_begin( c->hdrscan ), end = list_end( c->hdrscan );
|
| 401 |
+
iter != end; iter = list_next( iter ) )
|
| 402 |
+
write_netstring( f, object_str( list_item( iter ) ) );
|
| 403 |
+
fputs( "\n", f );
|
| 404 |
+
++header_count;
|
| 405 |
+
}
|
| 406 |
+
write_netstring( f, CACHE_RECORD_END );
|
| 407 |
+
|
| 408 |
+
if ( DEBUG_HEADER )
|
| 409 |
+
printf( "hcache written to %s. %d dependencies, %.0f%% hit rate\n",
|
| 410 |
+
hcachename, header_count, queries ? 100.0 * hits / queries : 0 );
|
| 411 |
+
|
| 412 |
+
fclose ( f );
|
| 413 |
+
|
| 414 |
+
cleanup:
|
| 415 |
+
for ( c = hcachelist; c; c = c->next )
|
| 416 |
+
{
|
| 417 |
+
list_free( c->includes );
|
| 418 |
+
list_free( c->hdrscan );
|
| 419 |
+
object_free( c->boundname );
|
| 420 |
+
}
|
| 421 |
+
|
| 422 |
+
hcachelist = 0;
|
| 423 |
+
if ( hcachehash )
|
| 424 |
+
hashdone( hcachehash );
|
| 425 |
+
hcachehash = 0;
|
| 426 |
+
}
|
| 427 |
+
|
| 428 |
+
|
| 429 |
+
LIST * hcache( TARGET * t, int rec, regexp * re[], LIST * hdrscan )
|
| 430 |
+
{
|
| 431 |
+
HCACHEDATA * c;
|
| 432 |
+
|
| 433 |
+
++queries;
|
| 434 |
+
|
| 435 |
+
if ( ( c = (HCACHEDATA *)hash_find( hcachehash, t->boundname ) ) )
|
| 436 |
+
{
|
| 437 |
+
if ( !timestamp_cmp( &c->time, &t->time ) )
|
| 438 |
+
{
|
| 439 |
+
LIST * const l1 = hdrscan;
|
| 440 |
+
LIST * const l2 = c->hdrscan;
|
| 441 |
+
LISTITER iter1 = list_begin( l1 );
|
| 442 |
+
LISTITER const end1 = list_end( l1 );
|
| 443 |
+
LISTITER iter2 = list_begin( l2 );
|
| 444 |
+
LISTITER const end2 = list_end( l2 );
|
| 445 |
+
while ( iter1 != end1 && iter2 != end2 )
|
| 446 |
+
{
|
| 447 |
+
if ( !object_equal( list_item( iter1 ), list_item( iter2 ) ) )
|
| 448 |
+
iter1 = end1;
|
| 449 |
+
else
|
| 450 |
+
{
|
| 451 |
+
iter1 = list_next( iter1 );
|
| 452 |
+
iter2 = list_next( iter2 );
|
| 453 |
+
}
|
| 454 |
+
}
|
| 455 |
+
if ( iter1 != end1 || iter2 != end2 )
|
| 456 |
+
{
|
| 457 |
+
if ( DEBUG_HEADER )
|
| 458 |
+
{
|
| 459 |
+
printf( "HDRSCAN out of date in cache for %s\n",
|
| 460 |
+
object_str( t->boundname ) );
|
| 461 |
+
printf(" real : ");
|
| 462 |
+
list_print( hdrscan );
|
| 463 |
+
printf( "\n cached: " );
|
| 464 |
+
list_print( c->hdrscan );
|
| 465 |
+
printf( "\n" );
|
| 466 |
+
}
|
| 467 |
+
|
| 468 |
+
list_free( c->includes );
|
| 469 |
+
list_free( c->hdrscan );
|
| 470 |
+
c->includes = L0;
|
| 471 |
+
c->hdrscan = L0;
|
| 472 |
+
}
|
| 473 |
+
else
|
| 474 |
+
{
|
| 475 |
+
if ( DEBUG_HEADER )
|
| 476 |
+
printf( "using header cache for %s\n", object_str(
|
| 477 |
+
t->boundname ) );
|
| 478 |
+
c->age = 0;
|
| 479 |
+
++hits;
|
| 480 |
+
return list_copy( c->includes );
|
| 481 |
+
}
|
| 482 |
+
}
|
| 483 |
+
else
|
| 484 |
+
{
|
| 485 |
+
if ( DEBUG_HEADER )
|
| 486 |
+
printf ("header cache out of date for %s\n", object_str(
|
| 487 |
+
t->boundname ) );
|
| 488 |
+
list_free( c->includes );
|
| 489 |
+
list_free( c->hdrscan );
|
| 490 |
+
c->includes = L0;
|
| 491 |
+
c->hdrscan = L0;
|
| 492 |
+
}
|
| 493 |
+
}
|
| 494 |
+
else
|
| 495 |
+
{
|
| 496 |
+
int found;
|
| 497 |
+
c = (HCACHEDATA *)hash_insert( hcachehash, t->boundname, &found );
|
| 498 |
+
if ( !found )
|
| 499 |
+
{
|
| 500 |
+
c->boundname = object_copy( t->boundname );
|
| 501 |
+
c->next = hcachelist;
|
| 502 |
+
hcachelist = c;
|
| 503 |
+
}
|
| 504 |
+
}
|
| 505 |
+
|
| 506 |
+
/* 'c' points at the cache entry. Its out of date. */
|
| 507 |
+
{
|
| 508 |
+
LIST * const l = headers1( L0, t->boundname, rec, re );
|
| 509 |
+
|
| 510 |
+
timestamp_copy( &c->time, &t->time );
|
| 511 |
+
c->age = 0;
|
| 512 |
+
c->includes = list_copy( l );
|
| 513 |
+
c->hdrscan = list_copy( hdrscan );
|
| 514 |
+
|
| 515 |
+
return l;
|
| 516 |
+
}
|
| 517 |
+
}
|
| 518 |
+
|
| 519 |
+
#endif /* OPT_HEADER_CACHE_EXT */
|
mosesdecoder/jam-files/engine/hdrmacro.h
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/*
|
| 2 |
+
* Copyright 1993, 1995 Christopher Seiwald.
|
| 3 |
+
*
|
| 4 |
+
* This file is part of Jam - see jam.c for Copyright information.
|
| 5 |
+
*/
|
| 6 |
+
|
| 7 |
+
/*
|
| 8 |
+
* hdrmacro.h - parses header files for #define MACRO <filename> or
|
| 9 |
+
* #define MACRO "filename" definitions
|
| 10 |
+
*/
|
| 11 |
+
|
| 12 |
+
#ifndef HDRMACRO_SW20111118_H
|
| 13 |
+
#define HDRMACRO_SW20111118_H
|
| 14 |
+
|
| 15 |
+
#include "object.h"
|
| 16 |
+
#include "rules.h"
|
| 17 |
+
|
| 18 |
+
void macro_headers( TARGET * );
|
| 19 |
+
OBJECT * macro_header_get( OBJECT * macro_name );
|
| 20 |
+
|
| 21 |
+
#endif
|
mosesdecoder/jam-files/engine/headers.c
ADDED
|
@@ -0,0 +1,197 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/*
|
| 2 |
+
* Copyright 1993, 2000 Christopher Seiwald.
|
| 3 |
+
*
|
| 4 |
+
* This file is part of Jam - see jam.c for Copyright information.
|
| 5 |
+
*/
|
| 6 |
+
/* This file is ALSO:
|
| 7 |
+
* Copyright 2001-2004 David Abrahams.
|
| 8 |
+
* Distributed under the Boost Software License, Version 1.0.
|
| 9 |
+
* (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
|
| 10 |
+
*/
|
| 11 |
+
|
| 12 |
+
/*
|
| 13 |
+
* headers.c - handle #includes in source files
|
| 14 |
+
*
|
| 15 |
+
* Using regular expressions provided as the variable $(HDRSCAN), headers()
|
| 16 |
+
* searches a file for #include files and phonies up a rule invocation:
|
| 17 |
+
* $(HDRRULE) <target> : <include files> ;
|
| 18 |
+
*
|
| 19 |
+
* External routines:
|
| 20 |
+
* headers() - scan a target for include files and call HDRRULE
|
| 21 |
+
*
|
| 22 |
+
* Internal routines:
|
| 23 |
+
* headers1() - using regexp, scan a file and build include LIST
|
| 24 |
+
*/
|
| 25 |
+
|
| 26 |
+
#include "jam.h"
|
| 27 |
+
#include "headers.h"
|
| 28 |
+
|
| 29 |
+
#include "compile.h"
|
| 30 |
+
#include "hdrmacro.h"
|
| 31 |
+
#include "lists.h"
|
| 32 |
+
#include "modules.h"
|
| 33 |
+
#include "object.h"
|
| 34 |
+
#include "parse.h"
|
| 35 |
+
#include "rules.h"
|
| 36 |
+
#include "subst.h"
|
| 37 |
+
#include "variable.h"
|
| 38 |
+
|
| 39 |
+
#ifdef OPT_HEADER_CACHE_EXT
|
| 40 |
+
# include "hcache.h"
|
| 41 |
+
#endif
|
| 42 |
+
|
| 43 |
+
#ifndef OPT_HEADER_CACHE_EXT
|
| 44 |
+
static LIST * headers1( LIST *, OBJECT * file, int rec, regexp * re[] );
|
| 45 |
+
#endif
|
| 46 |
+
|
| 47 |
+
|
| 48 |
+
/*
|
| 49 |
+
* headers() - scan a target for include files and call HDRRULE
|
| 50 |
+
*/
|
| 51 |
+
|
| 52 |
+
#define MAXINC 10
|
| 53 |
+
|
| 54 |
+
void headers( TARGET * t )
|
| 55 |
+
{
|
| 56 |
+
LIST * hdrscan;
|
| 57 |
+
LIST * hdrrule;
|
| 58 |
+
#ifndef OPT_HEADER_CACHE_EXT
|
| 59 |
+
LIST * headlist = L0;
|
| 60 |
+
#endif
|
| 61 |
+
regexp * re[ MAXINC ];
|
| 62 |
+
int rec = 0;
|
| 63 |
+
LISTITER iter;
|
| 64 |
+
LISTITER end;
|
| 65 |
+
|
| 66 |
+
hdrscan = var_get( root_module(), constant_HDRSCAN );
|
| 67 |
+
if ( list_empty( hdrscan ) )
|
| 68 |
+
return;
|
| 69 |
+
|
| 70 |
+
hdrrule = var_get( root_module(), constant_HDRRULE );
|
| 71 |
+
if ( list_empty( hdrrule ) )
|
| 72 |
+
return;
|
| 73 |
+
|
| 74 |
+
if ( DEBUG_HEADER )
|
| 75 |
+
printf( "header scan %s\n", object_str( t->name ) );
|
| 76 |
+
|
| 77 |
+
/* Compile all regular expressions in HDRSCAN */
|
| 78 |
+
iter = list_begin( hdrscan );
|
| 79 |
+
end = list_end( hdrscan );
|
| 80 |
+
for ( ; ( rec < MAXINC ) && iter != end; iter = list_next( iter ) )
|
| 81 |
+
{
|
| 82 |
+
re[ rec++ ] = regex_compile( list_item( iter ) );
|
| 83 |
+
}
|
| 84 |
+
|
| 85 |
+
/* Doctor up call to HDRRULE rule */
|
| 86 |
+
/* Call headers1() to get LIST of included files. */
|
| 87 |
+
{
|
| 88 |
+
FRAME frame[ 1 ];
|
| 89 |
+
frame_init( frame );
|
| 90 |
+
lol_add( frame->args, list_new( object_copy( t->name ) ) );
|
| 91 |
+
#ifdef OPT_HEADER_CACHE_EXT
|
| 92 |
+
lol_add( frame->args, hcache( t, rec, re, hdrscan ) );
|
| 93 |
+
#else
|
| 94 |
+
lol_add( frame->args, headers1( headlist, t->boundname, rec, re ) );
|
| 95 |
+
#endif
|
| 96 |
+
|
| 97 |
+
if ( lol_get( frame->args, 1 ) )
|
| 98 |
+
{
|
| 99 |
+
OBJECT * rulename = list_front( hdrrule );
|
| 100 |
+
/* The third argument to HDRRULE is the bound name of $(<). */
|
| 101 |
+
lol_add( frame->args, list_new( object_copy( t->boundname ) ) );
|
| 102 |
+
list_free( evaluate_rule( bindrule( rulename, frame->module ), rulename, frame ) );
|
| 103 |
+
}
|
| 104 |
+
|
| 105 |
+
/* Clean up. */
|
| 106 |
+
frame_free( frame );
|
| 107 |
+
}
|
| 108 |
+
}
|
| 109 |
+
|
| 110 |
+
|
| 111 |
+
/*
|
| 112 |
+
* headers1() - using regexp, scan a file and build include LIST.
|
| 113 |
+
*/
|
| 114 |
+
|
| 115 |
+
#ifndef OPT_HEADER_CACHE_EXT
|
| 116 |
+
static
|
| 117 |
+
#endif
|
| 118 |
+
LIST * headers1( LIST * l, OBJECT * file, int rec, regexp * re[] )
|
| 119 |
+
{
|
| 120 |
+
FILE * f;
|
| 121 |
+
char buf[ 1024 ];
|
| 122 |
+
int i;
|
| 123 |
+
static regexp * re_macros = 0;
|
| 124 |
+
|
| 125 |
+
#ifdef OPT_IMPROVED_PATIENCE_EXT
|
| 126 |
+
static int count = 0;
|
| 127 |
+
++count;
|
| 128 |
+
if ( ( ( count == 100 ) || !( count % 1000 ) ) && DEBUG_MAKE )
|
| 129 |
+
{
|
| 130 |
+
printf( "...patience...\n" );
|
| 131 |
+
fflush( stdout );
|
| 132 |
+
}
|
| 133 |
+
#endif
|
| 134 |
+
|
| 135 |
+
/* The following regexp is used to detect cases where a file is included
|
| 136 |
+
* through a line like "#include MACRO".
|
| 137 |
+
*/
|
| 138 |
+
if ( re_macros == 0 )
|
| 139 |
+
{
|
| 140 |
+
OBJECT * const re_str = object_new(
|
| 141 |
+
"#[ \t]*include[ \t]*([A-Za-z][A-Za-z0-9_]*).*$" );
|
| 142 |
+
re_macros = regex_compile( re_str );
|
| 143 |
+
object_free( re_str );
|
| 144 |
+
}
|
| 145 |
+
|
| 146 |
+
if ( !( f = fopen( object_str( file ), "r" ) ) )
|
| 147 |
+
return l;
|
| 148 |
+
|
| 149 |
+
while ( fgets( buf, sizeof( buf ), f ) )
|
| 150 |
+
{
|
| 151 |
+
for ( i = 0; i < rec; ++i )
|
| 152 |
+
if ( regexec( re[ i ], buf ) && re[ i ]->startp[ 1 ] )
|
| 153 |
+
{
|
| 154 |
+
( (char *)re[ i ]->endp[ 1 ] )[ 0 ] = '\0';
|
| 155 |
+
if ( DEBUG_HEADER )
|
| 156 |
+
printf( "header found: %s\n", re[ i ]->startp[ 1 ] );
|
| 157 |
+
l = list_push_back( l, object_new( re[ i ]->startp[ 1 ] ) );
|
| 158 |
+
}
|
| 159 |
+
|
| 160 |
+
/* Special treatment for #include MACRO. */
|
| 161 |
+
if ( regexec( re_macros, buf ) && re_macros->startp[ 1 ] )
|
| 162 |
+
{
|
| 163 |
+
OBJECT * header_filename;
|
| 164 |
+
OBJECT * macro_name;
|
| 165 |
+
|
| 166 |
+
( (char *)re_macros->endp[ 1 ] )[ 0 ] = '\0';
|
| 167 |
+
|
| 168 |
+
if ( DEBUG_HEADER )
|
| 169 |
+
printf( "macro header found: %s", re_macros->startp[ 1 ] );
|
| 170 |
+
|
| 171 |
+
macro_name = object_new( re_macros->startp[ 1 ] );
|
| 172 |
+
header_filename = macro_header_get( macro_name );
|
| 173 |
+
object_free( macro_name );
|
| 174 |
+
if ( header_filename )
|
| 175 |
+
{
|
| 176 |
+
if ( DEBUG_HEADER )
|
| 177 |
+
printf( " resolved to '%s'\n", object_str( header_filename )
|
| 178 |
+
);
|
| 179 |
+
l = list_push_back( l, object_copy( header_filename ) );
|
| 180 |
+
}
|
| 181 |
+
else
|
| 182 |
+
{
|
| 183 |
+
if ( DEBUG_HEADER )
|
| 184 |
+
printf( " ignored !!\n" );
|
| 185 |
+
}
|
| 186 |
+
}
|
| 187 |
+
}
|
| 188 |
+
|
| 189 |
+
fclose( f );
|
| 190 |
+
return l;
|
| 191 |
+
}
|
| 192 |
+
|
| 193 |
+
|
| 194 |
+
void regerror( char const * s )
|
| 195 |
+
{
|
| 196 |
+
printf( "re error %s\n", s );
|
| 197 |
+
}
|
mosesdecoder/jam-files/engine/jam.c
ADDED
|
@@ -0,0 +1,656 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/*
|
| 2 |
+
* /+\
|
| 3 |
+
* +\ Copyright 1993-2002 Christopher Seiwald and Perforce Software, Inc.
|
| 4 |
+
* \+/
|
| 5 |
+
*
|
| 6 |
+
* This file is part of jam.
|
| 7 |
+
*
|
| 8 |
+
* License is hereby granted to use this software and distribute it freely, as
|
| 9 |
+
* long as this copyright notice is retained and modifications are clearly
|
| 10 |
+
* marked.
|
| 11 |
+
*
|
| 12 |
+
* ALL WARRANTIES ARE HEREBY DISCLAIMED.
|
| 13 |
+
*/
|
| 14 |
+
|
| 15 |
+
/* This file is ALSO:
|
| 16 |
+
* Copyright 2001-2004 David Abrahams.
|
| 17 |
+
* Distributed under the Boost Software License, Version 1.0.
|
| 18 |
+
* (See accompanying file LICENSE_1_0.txt or copy at
|
| 19 |
+
* http://www.boost.org/LICENSE_1_0.txt)
|
| 20 |
+
*/
|
| 21 |
+
|
| 22 |
+
/*
|
| 23 |
+
* jam.c - make redux
|
| 24 |
+
*
|
| 25 |
+
* See Jam.html for usage information.
|
| 26 |
+
*
|
| 27 |
+
* These comments document the code.
|
| 28 |
+
*
|
| 29 |
+
* The top half of the code is structured such:
|
| 30 |
+
*
|
| 31 |
+
* jam
|
| 32 |
+
* / | \
|
| 33 |
+
* +---+ | \
|
| 34 |
+
* / | \
|
| 35 |
+
* jamgram option \
|
| 36 |
+
* / | \ \
|
| 37 |
+
* / | \ \
|
| 38 |
+
* / | \ |
|
| 39 |
+
* scan | compile make
|
| 40 |
+
* | | / | \ / | \
|
| 41 |
+
* | | / | \ / | \
|
| 42 |
+
* | | / | \ / | \
|
| 43 |
+
* jambase parse | rules search make1
|
| 44 |
+
* | | | \
|
| 45 |
+
* | | | \
|
| 46 |
+
* | | | \
|
| 47 |
+
* builtins timestamp command execute
|
| 48 |
+
* |
|
| 49 |
+
* |
|
| 50 |
+
* |
|
| 51 |
+
* filesys
|
| 52 |
+
*
|
| 53 |
+
*
|
| 54 |
+
* The support routines are called by all of the above, but themselves are
|
| 55 |
+
* layered thus:
|
| 56 |
+
*
|
| 57 |
+
* variable|expand
|
| 58 |
+
* / | |
|
| 59 |
+
* / | |
|
| 60 |
+
* / | |
|
| 61 |
+
* lists | pathsys
|
| 62 |
+
* \ |
|
| 63 |
+
* \ hash
|
| 64 |
+
* \ |
|
| 65 |
+
* \ |
|
| 66 |
+
* \ |
|
| 67 |
+
* \ |
|
| 68 |
+
* \ |
|
| 69 |
+
* object
|
| 70 |
+
*
|
| 71 |
+
* Roughly, the modules are:
|
| 72 |
+
*
|
| 73 |
+
* builtins.c - jam's built-in rules
|
| 74 |
+
* command.c - maintain lists of commands
|
| 75 |
+
* compile.c - compile parsed jam statements
|
| 76 |
+
* exec*.c - execute a shell script on a specific OS
|
| 77 |
+
* file*.c - scan directories and archives on a specific OS
|
| 78 |
+
* hash.c - simple in-memory hashing routines
|
| 79 |
+
* hdrmacro.c - handle header file parsing for filename macro definitions
|
| 80 |
+
* headers.c - handle #includes in source files
|
| 81 |
+
* jambase.c - compilable copy of Jambase
|
| 82 |
+
* jamgram.y - jam grammar
|
| 83 |
+
* lists.c - maintain lists of strings
|
| 84 |
+
* make.c - bring a target up to date, once rules are in place
|
| 85 |
+
* make1.c - execute command to bring targets up to date
|
| 86 |
+
* object.c - string manipulation routines
|
| 87 |
+
* option.c - command line option processing
|
| 88 |
+
* parse.c - make and destroy parse trees as driven by the parser
|
| 89 |
+
* path*.c - manipulate file names on a specific OS
|
| 90 |
+
* hash.c - simple in-memory hashing routines
|
| 91 |
+
* regexp.c - Henry Spencer's regexp
|
| 92 |
+
* rules.c - access to RULEs, TARGETs, and ACTIONs
|
| 93 |
+
* scan.c - the jam yacc scanner
|
| 94 |
+
* search.c - find a target along $(SEARCH) or $(LOCATE)
|
| 95 |
+
* timestamp.c - get the timestamp of a file or archive member
|
| 96 |
+
* variable.c - handle jam multi-element variables
|
| 97 |
+
*/
|
| 98 |
+
|
| 99 |
+
|
| 100 |
+
#include "jam.h"
|
| 101 |
+
#include "patchlevel.h"
|
| 102 |
+
|
| 103 |
+
#include "builtins.h"
|
| 104 |
+
#include "class.h"
|
| 105 |
+
#include "compile.h"
|
| 106 |
+
#include "constants.h"
|
| 107 |
+
#include "filesys.h"
|
| 108 |
+
#include "function.h"
|
| 109 |
+
#include "hcache.h"
|
| 110 |
+
#include "lists.h"
|
| 111 |
+
#include "make.h"
|
| 112 |
+
#include "object.h"
|
| 113 |
+
#include "option.h"
|
| 114 |
+
#include "output.h"
|
| 115 |
+
#include "parse.h"
|
| 116 |
+
#include "cwd.h"
|
| 117 |
+
#include "rules.h"
|
| 118 |
+
#include "scan.h"
|
| 119 |
+
#include "search.h"
|
| 120 |
+
#include "strings.h"
|
| 121 |
+
#include "timestamp.h"
|
| 122 |
+
#include "variable.h"
|
| 123 |
+
|
| 124 |
+
/* Macintosh is "special" */
|
| 125 |
+
#ifdef OS_MAC
|
| 126 |
+
# include <QuickDraw.h>
|
| 127 |
+
#endif
|
| 128 |
+
|
| 129 |
+
/* And UNIX for this. */
|
| 130 |
+
#ifdef unix
|
| 131 |
+
# include <sys/utsname.h>
|
| 132 |
+
# include <signal.h>
|
| 133 |
+
#endif
|
| 134 |
+
|
| 135 |
+
struct globs globs =
|
| 136 |
+
{
|
| 137 |
+
0, /* noexec */
|
| 138 |
+
1, /* jobs */
|
| 139 |
+
0, /* quitquick */
|
| 140 |
+
0, /* newestfirst */
|
| 141 |
+
0, /* pipes action stdout and stderr merged to action output */
|
| 142 |
+
#ifdef OS_MAC
|
| 143 |
+
{ 0, 0 }, /* debug - suppress tracing output */
|
| 144 |
+
#else
|
| 145 |
+
{ 0, 1 }, /* debug ... */
|
| 146 |
+
#endif
|
| 147 |
+
0, /* output commands, not run them */
|
| 148 |
+
0, /* action timeout */
|
| 149 |
+
0 /* maximum buffer size zero is all output */
|
| 150 |
+
};
|
| 151 |
+
|
| 152 |
+
/* Symbols to be defined as true for use in Jambase. */
|
| 153 |
+
static char * othersyms[] = { OSMAJOR, OSMINOR, OSPLAT, JAMVERSYM, 0 };
|
| 154 |
+
|
| 155 |
+
|
| 156 |
+
/* Known for sure:
|
| 157 |
+
* mac needs arg_enviro
|
| 158 |
+
* OS2 needs extern environ
|
| 159 |
+
*/
|
| 160 |
+
|
| 161 |
+
#ifdef OS_MAC
|
| 162 |
+
# define use_environ arg_environ
|
| 163 |
+
# ifdef MPW
|
| 164 |
+
QDGlobals qd;
|
| 165 |
+
# endif
|
| 166 |
+
#endif
|
| 167 |
+
|
| 168 |
+
/* on Win32-LCC */
|
| 169 |
+
#if defined( OS_NT ) && defined( __LCC__ )
|
| 170 |
+
# define use_environ _environ
|
| 171 |
+
#endif
|
| 172 |
+
|
| 173 |
+
#if defined( __MWERKS__)
|
| 174 |
+
# define use_environ _environ
|
| 175 |
+
extern char * * _environ;
|
| 176 |
+
#endif
|
| 177 |
+
|
| 178 |
+
#ifndef use_environ
|
| 179 |
+
# define use_environ environ
|
| 180 |
+
# if !defined( __WATCOM__ ) && !defined( OS_OS2 ) && !defined( OS_NT )
|
| 181 |
+
extern char **environ;
|
| 182 |
+
# endif
|
| 183 |
+
#endif
|
| 184 |
+
|
| 185 |
+
#if YYDEBUG != 0
|
| 186 |
+
extern int yydebug;
|
| 187 |
+
#endif
|
| 188 |
+
|
| 189 |
+
#ifndef NDEBUG
|
| 190 |
+
static void run_unit_tests()
|
| 191 |
+
{
|
| 192 |
+
# if defined( USE_EXECNT )
|
| 193 |
+
extern void execnt_unit_test();
|
| 194 |
+
execnt_unit_test();
|
| 195 |
+
# endif
|
| 196 |
+
string_unit_test();
|
| 197 |
+
}
|
| 198 |
+
#endif
|
| 199 |
+
|
| 200 |
+
int anyhow = 0;
|
| 201 |
+
|
| 202 |
+
#ifdef HAVE_PYTHON
|
| 203 |
+
extern PyObject * bjam_call ( PyObject * self, PyObject * args );
|
| 204 |
+
extern PyObject * bjam_import_rule ( PyObject * self, PyObject * args );
|
| 205 |
+
extern PyObject * bjam_define_action( PyObject * self, PyObject * args );
|
| 206 |
+
extern PyObject * bjam_variable ( PyObject * self, PyObject * args );
|
| 207 |
+
extern PyObject * bjam_backtrace ( PyObject * self, PyObject * args );
|
| 208 |
+
extern PyObject * bjam_caller ( PyObject * self, PyObject * args );
|
| 209 |
+
#endif
|
| 210 |
+
|
| 211 |
+
void regex_done();
|
| 212 |
+
|
| 213 |
+
char const * saved_argv0;
|
| 214 |
+
|
| 215 |
+
int main( int argc, char * * argv, char * * arg_environ )
|
| 216 |
+
{
|
| 217 |
+
int n;
|
| 218 |
+
char * s;
|
| 219 |
+
struct bjam_option optv[ N_OPTS ];
|
| 220 |
+
char const * all = "all";
|
| 221 |
+
int status;
|
| 222 |
+
int arg_c = argc;
|
| 223 |
+
char * * arg_v = argv;
|
| 224 |
+
char const * progname = argv[ 0 ];
|
| 225 |
+
module_t * environ_module;
|
| 226 |
+
|
| 227 |
+
saved_argv0 = argv[ 0 ];
|
| 228 |
+
|
| 229 |
+
BJAM_MEM_INIT();
|
| 230 |
+
|
| 231 |
+
#ifdef OS_MAC
|
| 232 |
+
InitGraf( &qd.thePort );
|
| 233 |
+
#endif
|
| 234 |
+
|
| 235 |
+
--argc;
|
| 236 |
+
++argv;
|
| 237 |
+
|
| 238 |
+
if ( getoptions( argc, argv, "-:l:m:d:j:p:f:gs:t:ano:qv", optv ) < 0 )
|
| 239 |
+
{
|
| 240 |
+
printf( "\nusage: %s [ options ] targets...\n\n", progname );
|
| 241 |
+
|
| 242 |
+
printf( "-a Build all targets, even if they are current.\n" );
|
| 243 |
+
printf( "-dx Set the debug level to x (0-9).\n" );
|
| 244 |
+
printf( "-fx Read x instead of Jambase.\n" );
|
| 245 |
+
/* printf( "-g Build from newest sources first.\n" ); */
|
| 246 |
+
printf( "-jx Run up to x shell commands concurrently.\n" );
|
| 247 |
+
printf( "-lx Limit actions to x number of seconds after which they are stopped.\n" );
|
| 248 |
+
printf( "-mx Maximum target output saved (kb), default is to save all output.\n" );
|
| 249 |
+
printf( "-n Don't actually execute the updating actions.\n" );
|
| 250 |
+
printf( "-ox Write the updating actions to file x.\n" );
|
| 251 |
+
printf( "-px x=0, pipes action stdout and stderr merged into action output.\n" );
|
| 252 |
+
printf( "-q Quit quickly as soon as a target fails.\n" );
|
| 253 |
+
printf( "-sx=y Set variable x=y, overriding environment.\n" );
|
| 254 |
+
printf( "-tx Rebuild x, even if it is up-to-date.\n" );
|
| 255 |
+
printf( "-v Print the version of jam and exit.\n" );
|
| 256 |
+
printf( "--x Option is ignored.\n\n" );
|
| 257 |
+
|
| 258 |
+
exit( EXITBAD );
|
| 259 |
+
}
|
| 260 |
+
|
| 261 |
+
/* Version info. */
|
| 262 |
+
if ( ( s = getoptval( optv, 'v', 0 ) ) )
|
| 263 |
+
{
|
| 264 |
+
printf( "Boost.Jam Version %s. %s.\n", VERSION, OSMINOR );
|
| 265 |
+
printf( " Copyright 1993-2002 Christopher Seiwald and Perforce "
|
| 266 |
+
"Software, Inc.\n" );
|
| 267 |
+
printf( " Copyright 2001 David Turner.\n" );
|
| 268 |
+
printf( " Copyright 2001-2004 David Abrahams.\n" );
|
| 269 |
+
printf( " Copyright 2002-2008 Rene Rivera.\n" );
|
| 270 |
+
printf( " Copyright 2003-2008 Vladimir Prus.\n" );
|
| 271 |
+
return EXITOK;
|
| 272 |
+
}
|
| 273 |
+
|
| 274 |
+
/* Pick up interesting options. */
|
| 275 |
+
if ( ( s = getoptval( optv, 'n', 0 ) ) )
|
| 276 |
+
{
|
| 277 |
+
++globs.noexec;
|
| 278 |
+
globs.debug[ 2 ] = 1;
|
| 279 |
+
}
|
| 280 |
+
|
| 281 |
+
if ( ( s = getoptval( optv, 'p', 0 ) ) )
|
| 282 |
+
{
|
| 283 |
+
/* Undocumented -p3 (acts like both -p1 -p2) means separate pipe action
|
| 284 |
+
* stdout and stderr.
|
| 285 |
+
*/
|
| 286 |
+
globs.pipe_action = atoi( s );
|
| 287 |
+
if ( globs.pipe_action < 0 || 3 < globs.pipe_action )
|
| 288 |
+
{
|
| 289 |
+
printf( "Invalid pipe descriptor '%d', valid values are -p[0..3]."
|
| 290 |
+
"\n", globs.pipe_action );
|
| 291 |
+
exit( EXITBAD );
|
| 292 |
+
}
|
| 293 |
+
}
|
| 294 |
+
|
| 295 |
+
if ( ( s = getoptval( optv, 'q', 0 ) ) )
|
| 296 |
+
globs.quitquick = 1;
|
| 297 |
+
|
| 298 |
+
if ( ( s = getoptval( optv, 'a', 0 ) ) )
|
| 299 |
+
anyhow++;
|
| 300 |
+
|
| 301 |
+
if ( ( s = getoptval( optv, 'j', 0 ) ) )
|
| 302 |
+
{
|
| 303 |
+
globs.jobs = atoi( s );
|
| 304 |
+
if ( globs.jobs < 1 || globs.jobs > MAXJOBS )
|
| 305 |
+
{
|
| 306 |
+
printf( "Invalid value for the '-j' option, valid values are 1 "
|
| 307 |
+
"through %d.\n", MAXJOBS );
|
| 308 |
+
exit( EXITBAD );
|
| 309 |
+
}
|
| 310 |
+
}
|
| 311 |
+
|
| 312 |
+
if ( ( s = getoptval( optv, 'g', 0 ) ) )
|
| 313 |
+
globs.newestfirst = 1;
|
| 314 |
+
|
| 315 |
+
if ( ( s = getoptval( optv, 'l', 0 ) ) )
|
| 316 |
+
globs.timeout = atoi( s );
|
| 317 |
+
|
| 318 |
+
if ( ( s = getoptval( optv, 'm', 0 ) ) )
|
| 319 |
+
globs.max_buf = atoi( s ) * 1024; /* convert to kb */
|
| 320 |
+
|
| 321 |
+
/* Turn on/off debugging */
|
| 322 |
+
for ( n = 0; ( s = getoptval( optv, 'd', n ) ); ++n )
|
| 323 |
+
{
|
| 324 |
+
int i;
|
| 325 |
+
|
| 326 |
+
/* First -d, turn off defaults. */
|
| 327 |
+
if ( !n )
|
| 328 |
+
for ( i = 0; i < DEBUG_MAX; ++i )
|
| 329 |
+
globs.debug[i] = 0;
|
| 330 |
+
|
| 331 |
+
i = atoi( s );
|
| 332 |
+
|
| 333 |
+
if ( ( i < 0 ) || ( i >= DEBUG_MAX ) )
|
| 334 |
+
{
|
| 335 |
+
printf( "Invalid debug level '%s'.\n", s );
|
| 336 |
+
continue;
|
| 337 |
+
}
|
| 338 |
+
|
| 339 |
+
/* n turns on levels 1-n. */
|
| 340 |
+
/* +n turns on level n. */
|
| 341 |
+
if ( *s == '+' )
|
| 342 |
+
globs.debug[ i ] = 1;
|
| 343 |
+
else while ( i )
|
| 344 |
+
globs.debug[ i-- ] = 1;
|
| 345 |
+
}
|
| 346 |
+
|
| 347 |
+
constants_init();
|
| 348 |
+
cwd_init();
|
| 349 |
+
|
| 350 |
+
{
|
| 351 |
+
PROFILE_ENTER( MAIN );
|
| 352 |
+
|
| 353 |
+
#ifdef HAVE_PYTHON
|
| 354 |
+
{
|
| 355 |
+
PROFILE_ENTER( MAIN_PYTHON );
|
| 356 |
+
Py_Initialize();
|
| 357 |
+
{
|
| 358 |
+
static PyMethodDef BjamMethods[] = {
|
| 359 |
+
{"call", bjam_call, METH_VARARGS,
|
| 360 |
+
"Call the specified bjam rule."},
|
| 361 |
+
{"import_rule", bjam_import_rule, METH_VARARGS,
|
| 362 |
+
"Imports Python callable to bjam."},
|
| 363 |
+
{"define_action", bjam_define_action, METH_VARARGS,
|
| 364 |
+
"Defines a command line action."},
|
| 365 |
+
{"variable", bjam_variable, METH_VARARGS,
|
| 366 |
+
"Obtains a variable from bjam's global module."},
|
| 367 |
+
{"backtrace", bjam_backtrace, METH_VARARGS,
|
| 368 |
+
"Returns bjam backtrace from the last call into Python."},
|
| 369 |
+
{"caller", bjam_caller, METH_VARARGS,
|
| 370 |
+
"Returns the module from which the last call into Python is made."},
|
| 371 |
+
{NULL, NULL, 0, NULL}
|
| 372 |
+
};
|
| 373 |
+
|
| 374 |
+
Py_InitModule( "bjam", BjamMethods );
|
| 375 |
+
}
|
| 376 |
+
PROFILE_EXIT( MAIN_PYTHON );
|
| 377 |
+
}
|
| 378 |
+
#endif
|
| 379 |
+
|
| 380 |
+
#ifndef NDEBUG
|
| 381 |
+
run_unit_tests();
|
| 382 |
+
#endif
|
| 383 |
+
#if YYDEBUG != 0
|
| 384 |
+
if ( DEBUG_PARSE )
|
| 385 |
+
yydebug = 1;
|
| 386 |
+
#endif
|
| 387 |
+
|
| 388 |
+
/* Set JAMDATE. */
|
| 389 |
+
{
|
| 390 |
+
timestamp current;
|
| 391 |
+
timestamp_current( ¤t );
|
| 392 |
+
var_set( root_module(), constant_JAMDATE, list_new( outf_time(
|
| 393 |
+
¤t ) ), VAR_SET );
|
| 394 |
+
}
|
| 395 |
+
|
| 396 |
+
/* Set JAM_VERSION. */
|
| 397 |
+
var_set( root_module(), constant_JAM_VERSION,
|
| 398 |
+
list_push_back( list_push_back( list_new(
|
| 399 |
+
object_new( VERSION_MAJOR_SYM ) ),
|
| 400 |
+
object_new( VERSION_MINOR_SYM ) ),
|
| 401 |
+
object_new( VERSION_PATCH_SYM ) ),
|
| 402 |
+
VAR_SET );
|
| 403 |
+
|
| 404 |
+
/* Set JAMUNAME. */
|
| 405 |
+
#ifdef unix
|
| 406 |
+
{
|
| 407 |
+
struct utsname u;
|
| 408 |
+
|
| 409 |
+
if ( uname( &u ) >= 0 )
|
| 410 |
+
{
|
| 411 |
+
var_set( root_module(), constant_JAMUNAME,
|
| 412 |
+
list_push_back(
|
| 413 |
+
list_push_back(
|
| 414 |
+
list_push_back(
|
| 415 |
+
list_push_back(
|
| 416 |
+
list_new(
|
| 417 |
+
object_new( u.sysname ) ),
|
| 418 |
+
object_new( u.nodename ) ),
|
| 419 |
+
object_new( u.release ) ),
|
| 420 |
+
object_new( u.version ) ),
|
| 421 |
+
object_new( u.machine ) ), VAR_SET );
|
| 422 |
+
}
|
| 423 |
+
}
|
| 424 |
+
#endif /* unix */
|
| 425 |
+
|
| 426 |
+
/* Set JAM_TIMESTAMP_RESOLUTION. */
|
| 427 |
+
{
|
| 428 |
+
timestamp fmt_resolution[ 1 ];
|
| 429 |
+
file_supported_fmt_resolution( fmt_resolution );
|
| 430 |
+
var_set( root_module(), constant_JAM_TIMESTAMP_RESOLUTION, list_new(
|
| 431 |
+
object_new( timestamp_timestr( fmt_resolution ) ) ), VAR_SET );
|
| 432 |
+
}
|
| 433 |
+
|
| 434 |
+
/* Load up environment variables. */
|
| 435 |
+
|
| 436 |
+
/* First into the global module, with splitting, for backward
|
| 437 |
+
* compatibility.
|
| 438 |
+
*/
|
| 439 |
+
var_defines( root_module(), use_environ, 1 );
|
| 440 |
+
|
| 441 |
+
environ_module = bindmodule( constant_ENVIRON );
|
| 442 |
+
/* Then into .ENVIRON, without splitting. */
|
| 443 |
+
var_defines( environ_module, use_environ, 0 );
|
| 444 |
+
|
| 445 |
+
/*
|
| 446 |
+
* Jam defined variables OS & OSPLAT. We load them after environment, so
|
| 447 |
+
* that setting OS in environment does not change Jam's notion of the
|
| 448 |
+
* current platform.
|
| 449 |
+
*/
|
| 450 |
+
var_defines( root_module(), othersyms, 1 );
|
| 451 |
+
|
| 452 |
+
/* Load up variables set on command line. */
|
| 453 |
+
for ( n = 0; ( s = getoptval( optv, 's', n ) ); ++n )
|
| 454 |
+
{
|
| 455 |
+
char * symv[ 2 ];
|
| 456 |
+
symv[ 0 ] = s;
|
| 457 |
+
symv[ 1 ] = 0;
|
| 458 |
+
var_defines( root_module(), symv, 1 );
|
| 459 |
+
var_defines( environ_module, symv, 0 );
|
| 460 |
+
}
|
| 461 |
+
|
| 462 |
+
/* Set the ARGV to reflect the complete list of arguments of invocation.
|
| 463 |
+
*/
|
| 464 |
+
for ( n = 0; n < arg_c; ++n )
|
| 465 |
+
var_set( root_module(), constant_ARGV, list_new( object_new(
|
| 466 |
+
arg_v[ n ] ) ), VAR_APPEND );
|
| 467 |
+
|
| 468 |
+
/* Initialize built-in rules. */
|
| 469 |
+
load_builtins();
|
| 470 |
+
|
| 471 |
+
/* Add the targets in the command line to the update list. */
|
| 472 |
+
for ( n = 1; n < arg_c; ++n )
|
| 473 |
+
{
|
| 474 |
+
if ( arg_v[ n ][ 0 ] == '-' )
|
| 475 |
+
{
|
| 476 |
+
char * f = "-:l:d:j:f:gs:t:ano:qv";
|
| 477 |
+
for ( ; *f; ++f ) if ( *f == arg_v[ n ][ 1 ] ) break;
|
| 478 |
+
if ( ( f[ 1 ] == ':' ) && ( arg_v[ n ][ 2 ] == '\0' ) ) ++n;
|
| 479 |
+
}
|
| 480 |
+
else
|
| 481 |
+
{
|
| 482 |
+
OBJECT * const target = object_new( arg_v[ n ] );
|
| 483 |
+
mark_target_for_updating( target );
|
| 484 |
+
object_free( target );
|
| 485 |
+
}
|
| 486 |
+
}
|
| 487 |
+
|
| 488 |
+
if ( list_empty( targets_to_update() ) )
|
| 489 |
+
mark_target_for_updating( constant_all );
|
| 490 |
+
|
| 491 |
+
/* Parse ruleset. */
|
| 492 |
+
{
|
| 493 |
+
FRAME frame[ 1 ];
|
| 494 |
+
frame_init( frame );
|
| 495 |
+
for ( n = 0; ( s = getoptval( optv, 'f', n ) ); ++n )
|
| 496 |
+
{
|
| 497 |
+
OBJECT * const filename = object_new( s );
|
| 498 |
+
parse_file( filename, frame );
|
| 499 |
+
object_free( filename );
|
| 500 |
+
}
|
| 501 |
+
|
| 502 |
+
if ( !n )
|
| 503 |
+
parse_file( constant_plus, frame );
|
| 504 |
+
}
|
| 505 |
+
|
| 506 |
+
status = yyanyerrors();
|
| 507 |
+
|
| 508 |
+
/* Manually touch -t targets. */
|
| 509 |
+
for ( n = 0; ( s = getoptval( optv, 't', n ) ); ++n )
|
| 510 |
+
{
|
| 511 |
+
OBJECT * const target = object_new( s );
|
| 512 |
+
touch_target( target );
|
| 513 |
+
object_free( target );
|
| 514 |
+
}
|
| 515 |
+
|
| 516 |
+
/* If an output file is specified, set globs.cmdout to that. */
|
| 517 |
+
if ( ( s = getoptval( optv, 'o', 0 ) ) )
|
| 518 |
+
{
|
| 519 |
+
if ( !( globs.cmdout = fopen( s, "w" ) ) )
|
| 520 |
+
{
|
| 521 |
+
printf( "Failed to write to '%s'\n", s );
|
| 522 |
+
exit( EXITBAD );
|
| 523 |
+
}
|
| 524 |
+
++globs.noexec;
|
| 525 |
+
}
|
| 526 |
+
|
| 527 |
+
/* The build system may set the PARALLELISM variable to override -j
|
| 528 |
+
* options.
|
| 529 |
+
*/
|
| 530 |
+
{
|
| 531 |
+
LIST * const p = var_get( root_module(), constant_PARALLELISM );
|
| 532 |
+
if ( !list_empty( p ) )
|
| 533 |
+
{
|
| 534 |
+
int const j = atoi( object_str( list_front( p ) ) );
|
| 535 |
+
if ( j < 1 || j > MAXJOBS )
|
| 536 |
+
printf( "Invalid value of PARALLELISM: %s. Valid values "
|
| 537 |
+
"are 1 through %d.\n", object_str( list_front( p ) ),
|
| 538 |
+
MAXJOBS );
|
| 539 |
+
else
|
| 540 |
+
globs.jobs = j;
|
| 541 |
+
}
|
| 542 |
+
}
|
| 543 |
+
|
| 544 |
+
/* KEEP_GOING overrides -q option. */
|
| 545 |
+
{
|
| 546 |
+
LIST * const p = var_get( root_module(), constant_KEEP_GOING );
|
| 547 |
+
if ( !list_empty( p ) )
|
| 548 |
+
globs.quitquick = atoi( object_str( list_front( p ) ) ) ? 0 : 1;
|
| 549 |
+
}
|
| 550 |
+
|
| 551 |
+
/* Now make target. */
|
| 552 |
+
{
|
| 553 |
+
PROFILE_ENTER( MAIN_MAKE );
|
| 554 |
+
LIST * const targets = targets_to_update();
|
| 555 |
+
if ( !list_empty( targets ) )
|
| 556 |
+
status |= make( targets, anyhow );
|
| 557 |
+
else
|
| 558 |
+
status = last_update_now_status;
|
| 559 |
+
PROFILE_EXIT( MAIN_MAKE );
|
| 560 |
+
}
|
| 561 |
+
|
| 562 |
+
PROFILE_EXIT( MAIN );
|
| 563 |
+
}
|
| 564 |
+
|
| 565 |
+
if ( DEBUG_PROFILE )
|
| 566 |
+
profile_dump();
|
| 567 |
+
|
| 568 |
+
|
| 569 |
+
#ifdef OPT_HEADER_CACHE_EXT
|
| 570 |
+
hcache_done();
|
| 571 |
+
#endif
|
| 572 |
+
|
| 573 |
+
clear_targets_to_update();
|
| 574 |
+
|
| 575 |
+
/* Widely scattered cleanup. */
|
| 576 |
+
property_set_done();
|
| 577 |
+
file_done();
|
| 578 |
+
rules_done();
|
| 579 |
+
timestamp_done();
|
| 580 |
+
search_done();
|
| 581 |
+
class_done();
|
| 582 |
+
modules_done();
|
| 583 |
+
regex_done();
|
| 584 |
+
cwd_done();
|
| 585 |
+
path_done();
|
| 586 |
+
function_done();
|
| 587 |
+
list_done();
|
| 588 |
+
constants_done();
|
| 589 |
+
object_done();
|
| 590 |
+
|
| 591 |
+
/* Close cmdout. */
|
| 592 |
+
if ( globs.cmdout )
|
| 593 |
+
fclose( globs.cmdout );
|
| 594 |
+
|
| 595 |
+
#ifdef HAVE_PYTHON
|
| 596 |
+
Py_Finalize();
|
| 597 |
+
#endif
|
| 598 |
+
|
| 599 |
+
BJAM_MEM_CLOSE();
|
| 600 |
+
|
| 601 |
+
return status ? EXITBAD : EXITOK;
|
| 602 |
+
}
|
| 603 |
+
|
| 604 |
+
|
| 605 |
+
/*
|
| 606 |
+
* executable_path()
|
| 607 |
+
*/
|
| 608 |
+
|
| 609 |
+
#if defined(_WIN32)
|
| 610 |
+
# define WIN32_LEAN_AND_MEAN
|
| 611 |
+
# include <windows.h>
|
| 612 |
+
char * executable_path( char const * argv0 )
|
| 613 |
+
{
|
| 614 |
+
char buf[ 1024 ];
|
| 615 |
+
DWORD const ret = GetModuleFileName( NULL, buf, sizeof( buf ) );
|
| 616 |
+
return ( !ret || ret == sizeof( buf ) ) ? NULL : strdup( buf );
|
| 617 |
+
}
|
| 618 |
+
#elif defined(__APPLE__) /* Not tested */
|
| 619 |
+
# include <mach-o/dyld.h>
|
| 620 |
+
char *executable_path( char const * argv0 )
|
| 621 |
+
{
|
| 622 |
+
char buf[ 1024 ];
|
| 623 |
+
uint32_t size = sizeof( buf );
|
| 624 |
+
return _NSGetExecutablePath( buf, &size ) ? NULL : strdup( buf );
|
| 625 |
+
}
|
| 626 |
+
#elif defined(sun) || defined(__sun) /* Not tested */
|
| 627 |
+
# include <stdlib.h>
|
| 628 |
+
char * executable_path( char const * argv0 )
|
| 629 |
+
{
|
| 630 |
+
return strdup( getexecname() );
|
| 631 |
+
}
|
| 632 |
+
#elif defined(__FreeBSD__)
|
| 633 |
+
# include <sys/sysctl.h>
|
| 634 |
+
char * executable_path( char const * argv0 )
|
| 635 |
+
{
|
| 636 |
+
int mib[ 4 ] = { CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1 };
|
| 637 |
+
char buf[ 1024 ];
|
| 638 |
+
size_t size = sizeof( buf );
|
| 639 |
+
sysctl( mib, 4, buf, &size, NULL, 0 );
|
| 640 |
+
return ( !size || size == sizeof( buf ) ) ? NULL : strndup( buf, size );
|
| 641 |
+
}
|
| 642 |
+
#elif defined(__linux__)
|
| 643 |
+
# include <unistd.h>
|
| 644 |
+
char * executable_path( char const * argv0 )
|
| 645 |
+
{
|
| 646 |
+
char buf[ 1024 ];
|
| 647 |
+
ssize_t const ret = readlink( "/proc/self/exe", buf, sizeof( buf ) );
|
| 648 |
+
return ( !ret || ret == sizeof( buf ) ) ? NULL : strndup( buf, ret );
|
| 649 |
+
}
|
| 650 |
+
#else
|
| 651 |
+
char * executable_path( char const * argv0 )
|
| 652 |
+
{
|
| 653 |
+
/* If argv0 is an absolute path, assume it is the right absolute path. */
|
| 654 |
+
return argv0[ 0 ] == '/' ? strdup( argv0 ) : NULL;
|
| 655 |
+
}
|
| 656 |
+
#endif
|
mosesdecoder/jam-files/engine/jam.h
ADDED
|
@@ -0,0 +1,475 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/*
|
| 2 |
+
* Copyright 1993, 1995 Christopher Seiwald.
|
| 3 |
+
*
|
| 4 |
+
* This file is part of Jam - see jam.c for Copyright information.
|
| 5 |
+
*/
|
| 6 |
+
|
| 7 |
+
/* This file is ALSO:
|
| 8 |
+
* Copyright 2001-2004 David Abrahams.
|
| 9 |
+
* Distributed under the Boost Software License, Version 1.0.
|
| 10 |
+
* (See accompanying file LICENSE_1_0.txt or copy at
|
| 11 |
+
* http://www.boost.org/LICENSE_1_0.txt)
|
| 12 |
+
*/
|
| 13 |
+
|
| 14 |
+
/*
|
| 15 |
+
* jam.h - includes and globals for jam
|
| 16 |
+
*/
|
| 17 |
+
|
| 18 |
+
#ifndef JAM_H_VP_2003_08_01
|
| 19 |
+
#define JAM_H_VP_2003_08_01
|
| 20 |
+
|
| 21 |
+
#ifdef HAVE_PYTHON
|
| 22 |
+
#include <Python.h>
|
| 23 |
+
#endif
|
| 24 |
+
|
| 25 |
+
/* Assume popen support is available unless known otherwise. */
|
| 26 |
+
#define HAVE_POPEN 1
|
| 27 |
+
|
| 28 |
+
/*
|
| 29 |
+
* Windows NT
|
| 30 |
+
*/
|
| 31 |
+
|
| 32 |
+
#ifdef NT
|
| 33 |
+
|
| 34 |
+
#include <ctype.h>
|
| 35 |
+
#include <fcntl.h>
|
| 36 |
+
#include <malloc.h>
|
| 37 |
+
#ifndef __MWERKS__
|
| 38 |
+
#include <memory.h>
|
| 39 |
+
#endif
|
| 40 |
+
#include <stdio.h>
|
| 41 |
+
#include <stdlib.h>
|
| 42 |
+
#include <signal.h>
|
| 43 |
+
#include <string.h>
|
| 44 |
+
#include <time.h>
|
| 45 |
+
|
| 46 |
+
#define OSMAJOR "NT=true"
|
| 47 |
+
#define OSMINOR "OS=NT"
|
| 48 |
+
#define OS_NT
|
| 49 |
+
#define SPLITPATH ';'
|
| 50 |
+
#define MAXLINE (undefined__see_execnt_c) /* max chars per command line */
|
| 51 |
+
#define USE_EXECNT
|
| 52 |
+
#define PATH_DELIM '\\'
|
| 53 |
+
|
| 54 |
+
/* AS400 cross-compile from NT. */
|
| 55 |
+
|
| 56 |
+
#ifdef AS400
|
| 57 |
+
#undef OSMINOR
|
| 58 |
+
#undef OSMAJOR
|
| 59 |
+
#define OSMAJOR "AS400=true"
|
| 60 |
+
#define OSMINOR "OS=AS400"
|
| 61 |
+
#define OS_AS400
|
| 62 |
+
#endif
|
| 63 |
+
|
| 64 |
+
/* Metrowerks Standard Library on Windows. */
|
| 65 |
+
|
| 66 |
+
#ifdef __MSL__
|
| 67 |
+
#undef HAVE_POPEN
|
| 68 |
+
#endif
|
| 69 |
+
|
| 70 |
+
#endif /* #ifdef NT */
|
| 71 |
+
|
| 72 |
+
|
| 73 |
+
/*
|
| 74 |
+
* Windows MingW32
|
| 75 |
+
*/
|
| 76 |
+
|
| 77 |
+
#ifdef __MINGW32__
|
| 78 |
+
|
| 79 |
+
#include <fcntl.h>
|
| 80 |
+
#include <stdlib.h>
|
| 81 |
+
#include <stdio.h>
|
| 82 |
+
#include <ctype.h>
|
| 83 |
+
#include <malloc.h>
|
| 84 |
+
#include <memory.h>
|
| 85 |
+
#include <signal.h>
|
| 86 |
+
#include <string.h>
|
| 87 |
+
#include <time.h>
|
| 88 |
+
|
| 89 |
+
#define OSMAJOR "MINGW=true"
|
| 90 |
+
#define OSMINOR "OS=MINGW"
|
| 91 |
+
#define OS_NT
|
| 92 |
+
#define SPLITPATH ';'
|
| 93 |
+
#define MAXLINE 996 /* max chars per command line */
|
| 94 |
+
#define USE_EXECUNIX
|
| 95 |
+
#define PATH_DELIM '\\'
|
| 96 |
+
|
| 97 |
+
#endif /* #ifdef MINGW */
|
| 98 |
+
|
| 99 |
+
|
| 100 |
+
/*
|
| 101 |
+
* God fearing UNIX.
|
| 102 |
+
*/
|
| 103 |
+
|
| 104 |
+
#ifndef OSMINOR
|
| 105 |
+
|
| 106 |
+
#define OSMAJOR "UNIX=true"
|
| 107 |
+
#define USE_EXECUNIX
|
| 108 |
+
#define USE_FILEUNIX
|
| 109 |
+
#define PATH_DELIM '/'
|
| 110 |
+
|
| 111 |
+
#ifdef _AIX
|
| 112 |
+
#define unix
|
| 113 |
+
#define MAXLINE 23552 /* 24k - 1k, max chars per command line */
|
| 114 |
+
#define OSMINOR "OS=AIX"
|
| 115 |
+
#define OS_AIX
|
| 116 |
+
#define NO_VFORK
|
| 117 |
+
#endif
|
| 118 |
+
#ifdef AMIGA
|
| 119 |
+
#define OSMINOR "OS=AMIGA"
|
| 120 |
+
#define OS_AMIGA
|
| 121 |
+
#endif
|
| 122 |
+
#ifdef __BEOS__
|
| 123 |
+
#define unix
|
| 124 |
+
#define OSMINOR "OS=BEOS"
|
| 125 |
+
#define OS_BEOS
|
| 126 |
+
#define NO_VFORK
|
| 127 |
+
#endif
|
| 128 |
+
#ifdef __bsdi__
|
| 129 |
+
#define OSMINOR "OS=BSDI"
|
| 130 |
+
#define OS_BSDI
|
| 131 |
+
#endif
|
| 132 |
+
#if defined (COHERENT) && defined (_I386)
|
| 133 |
+
#define OSMINOR "OS=COHERENT"
|
| 134 |
+
#define OS_COHERENT
|
| 135 |
+
#define NO_VFORK
|
| 136 |
+
#endif
|
| 137 |
+
#if defined(__cygwin__) || defined(__CYGWIN__)
|
| 138 |
+
#define OSMINOR "OS=CYGWIN"
|
| 139 |
+
#define OS_CYGWIN
|
| 140 |
+
#endif
|
| 141 |
+
#if defined(__FreeBSD__) && !defined(__DragonFly__)
|
| 142 |
+
#define OSMINOR "OS=FREEBSD"
|
| 143 |
+
#define OS_FREEBSD
|
| 144 |
+
#endif
|
| 145 |
+
#ifdef __DragonFly__
|
| 146 |
+
#define OSMINOR "OS=DRAGONFLYBSD"
|
| 147 |
+
#define OS_DRAGONFLYBSD
|
| 148 |
+
#endif
|
| 149 |
+
#ifdef __DGUX__
|
| 150 |
+
#define OSMINOR "OS=DGUX"
|
| 151 |
+
#define OS_DGUX
|
| 152 |
+
#endif
|
| 153 |
+
#ifdef __hpux
|
| 154 |
+
#define OSMINOR "OS=HPUX"
|
| 155 |
+
#define OS_HPUX
|
| 156 |
+
#endif
|
| 157 |
+
#ifdef __OPENNT
|
| 158 |
+
#define unix
|
| 159 |
+
#define OSMINOR "OS=INTERIX"
|
| 160 |
+
#define OS_INTERIX
|
| 161 |
+
#define NO_VFORK
|
| 162 |
+
#endif
|
| 163 |
+
#ifdef __sgi
|
| 164 |
+
#define OSMINOR "OS=IRIX"
|
| 165 |
+
#define OS_IRIX
|
| 166 |
+
#define NO_VFORK
|
| 167 |
+
#endif
|
| 168 |
+
#ifdef __ISC
|
| 169 |
+
#define OSMINOR "OS=ISC"
|
| 170 |
+
#define OS_ISC
|
| 171 |
+
#define NO_VFORK
|
| 172 |
+
#endif
|
| 173 |
+
#ifdef linux
|
| 174 |
+
#define OSMINOR "OS=LINUX"
|
| 175 |
+
#define OS_LINUX
|
| 176 |
+
#endif
|
| 177 |
+
#ifdef __Lynx__
|
| 178 |
+
#define OSMINOR "OS=LYNX"
|
| 179 |
+
#define OS_LYNX
|
| 180 |
+
#define NO_VFORK
|
| 181 |
+
#define unix
|
| 182 |
+
#endif
|
| 183 |
+
#ifdef __MACHTEN__
|
| 184 |
+
#define OSMINOR "OS=MACHTEN"
|
| 185 |
+
#define OS_MACHTEN
|
| 186 |
+
#endif
|
| 187 |
+
#ifdef mpeix
|
| 188 |
+
#define unix
|
| 189 |
+
#define OSMINOR "OS=MPEIX"
|
| 190 |
+
#define OS_MPEIX
|
| 191 |
+
#define NO_VFORK
|
| 192 |
+
#endif
|
| 193 |
+
#ifdef __MVS__
|
| 194 |
+
#define unix
|
| 195 |
+
#define OSMINOR "OS=MVS"
|
| 196 |
+
#define OS_MVS
|
| 197 |
+
#endif
|
| 198 |
+
#ifdef _ATT4
|
| 199 |
+
#define OSMINOR "OS=NCR"
|
| 200 |
+
#define OS_NCR
|
| 201 |
+
#endif
|
| 202 |
+
#ifdef __NetBSD__
|
| 203 |
+
#define unix
|
| 204 |
+
#define OSMINOR "OS=NETBSD"
|
| 205 |
+
#define OS_NETBSD
|
| 206 |
+
#define NO_VFORK
|
| 207 |
+
#endif
|
| 208 |
+
#ifdef __QNX__
|
| 209 |
+
#define unix
|
| 210 |
+
#ifdef __QNXNTO__
|
| 211 |
+
#define OSMINOR "OS=QNXNTO"
|
| 212 |
+
#define OS_QNXNTO
|
| 213 |
+
#else
|
| 214 |
+
#define OSMINOR "OS=QNX"
|
| 215 |
+
#define OS_QNX
|
| 216 |
+
#define NO_VFORK
|
| 217 |
+
#define MAXLINE 996 /* max chars per command line */
|
| 218 |
+
#endif
|
| 219 |
+
#endif
|
| 220 |
+
#ifdef NeXT
|
| 221 |
+
#ifdef __APPLE__
|
| 222 |
+
#define OSMINOR "OS=RHAPSODY"
|
| 223 |
+
#define OS_RHAPSODY
|
| 224 |
+
#else
|
| 225 |
+
#define OSMINOR "OS=NEXT"
|
| 226 |
+
#define OS_NEXT
|
| 227 |
+
#endif
|
| 228 |
+
#endif
|
| 229 |
+
#ifdef __APPLE__
|
| 230 |
+
#define unix
|
| 231 |
+
#define OSMINOR "OS=MACOSX"
|
| 232 |
+
#define OS_MACOSX
|
| 233 |
+
#endif
|
| 234 |
+
#ifdef __osf__
|
| 235 |
+
#ifndef unix
|
| 236 |
+
#define unix
|
| 237 |
+
#endif
|
| 238 |
+
#define OSMINOR "OS=OSF"
|
| 239 |
+
#define OS_OSF
|
| 240 |
+
#endif
|
| 241 |
+
#ifdef _SEQUENT_
|
| 242 |
+
#define OSMINOR "OS=PTX"
|
| 243 |
+
#define OS_PTX
|
| 244 |
+
#endif
|
| 245 |
+
#ifdef M_XENIX
|
| 246 |
+
#define OSMINOR "OS=SCO"
|
| 247 |
+
#define OS_SCO
|
| 248 |
+
#define NO_VFORK
|
| 249 |
+
#endif
|
| 250 |
+
#ifdef sinix
|
| 251 |
+
#define unix
|
| 252 |
+
#define OSMINOR "OS=SINIX"
|
| 253 |
+
#define OS_SINIX
|
| 254 |
+
#endif
|
| 255 |
+
#ifdef sun
|
| 256 |
+
#if defined(__svr4__) || defined(__SVR4)
|
| 257 |
+
#define OSMINOR "OS=SOLARIS"
|
| 258 |
+
#define OS_SOLARIS
|
| 259 |
+
#else
|
| 260 |
+
#define OSMINOR "OS=SUNOS"
|
| 261 |
+
#define OS_SUNOS
|
| 262 |
+
#endif
|
| 263 |
+
#endif
|
| 264 |
+
#ifdef ultrix
|
| 265 |
+
#define OSMINOR "OS=ULTRIX"
|
| 266 |
+
#define OS_ULTRIX
|
| 267 |
+
#endif
|
| 268 |
+
#ifdef _UNICOS
|
| 269 |
+
#define OSMINOR "OS=UNICOS"
|
| 270 |
+
#define OS_UNICOS
|
| 271 |
+
#endif
|
| 272 |
+
#if defined(__USLC__) && !defined(M_XENIX)
|
| 273 |
+
#define OSMINOR "OS=UNIXWARE"
|
| 274 |
+
#define OS_UNIXWARE
|
| 275 |
+
#endif
|
| 276 |
+
#ifdef __OpenBSD__
|
| 277 |
+
#define OSMINOR "OS=OPENBSD"
|
| 278 |
+
#define OS_OPENBSD
|
| 279 |
+
#define unix
|
| 280 |
+
#endif
|
| 281 |
+
#if defined (__FreeBSD_kernel__) && !defined(__FreeBSD__)
|
| 282 |
+
#define OSMINOR "OS=KFREEBSD"
|
| 283 |
+
#define OS_KFREEBSD
|
| 284 |
+
#endif
|
| 285 |
+
#ifndef OSMINOR
|
| 286 |
+
#define OSMINOR "OS=UNKNOWN"
|
| 287 |
+
#endif
|
| 288 |
+
|
| 289 |
+
/* All the UNIX includes */
|
| 290 |
+
|
| 291 |
+
#include <sys/types.h>
|
| 292 |
+
|
| 293 |
+
#ifndef OS_MPEIX
|
| 294 |
+
#include <sys/file.h>
|
| 295 |
+
#endif
|
| 296 |
+
|
| 297 |
+
#include <fcntl.h>
|
| 298 |
+
#include <stdio.h>
|
| 299 |
+
#include <ctype.h>
|
| 300 |
+
#include <signal.h>
|
| 301 |
+
#include <string.h>
|
| 302 |
+
#include <time.h>
|
| 303 |
+
#include <unistd.h>
|
| 304 |
+
|
| 305 |
+
#ifndef OS_QNX
|
| 306 |
+
#include <memory.h>
|
| 307 |
+
#endif
|
| 308 |
+
|
| 309 |
+
#ifndef OS_ULTRIX
|
| 310 |
+
#include <stdlib.h>
|
| 311 |
+
#endif
|
| 312 |
+
|
| 313 |
+
#if !defined( OS_BSDI ) && \
|
| 314 |
+
!defined( OS_FREEBSD ) && \
|
| 315 |
+
!defined( OS_DRAGONFLYBSD ) && \
|
| 316 |
+
!defined( OS_NEXT ) && \
|
| 317 |
+
!defined( OS_MACHTEN ) && \
|
| 318 |
+
!defined( OS_MACOSX ) && \
|
| 319 |
+
!defined( OS_RHAPSODY ) && \
|
| 320 |
+
!defined( OS_MVS ) && \
|
| 321 |
+
!defined( OS_OPENBSD )
|
| 322 |
+
#include <malloc.h>
|
| 323 |
+
#endif
|
| 324 |
+
|
| 325 |
+
#endif /* #ifndef OSMINOR */
|
| 326 |
+
|
| 327 |
+
|
| 328 |
+
/*
|
| 329 |
+
* OSPLAT definitions - suppressed when it is a one-of-a-kind.
|
| 330 |
+
*/
|
| 331 |
+
|
| 332 |
+
#if defined( _M_PPC ) || \
|
| 333 |
+
defined( PPC ) || \
|
| 334 |
+
defined( ppc ) || \
|
| 335 |
+
defined( __powerpc__ ) || \
|
| 336 |
+
defined( __ppc__ )
|
| 337 |
+
#define OSPLAT "OSPLAT=PPC"
|
| 338 |
+
#endif
|
| 339 |
+
|
| 340 |
+
#if defined( _ALPHA_ ) || \
|
| 341 |
+
defined( __alpha__ )
|
| 342 |
+
#define OSPLAT "OSPLAT=AXP"
|
| 343 |
+
#endif
|
| 344 |
+
|
| 345 |
+
#if defined( _i386_ ) || \
|
| 346 |
+
defined( __i386__ ) || \
|
| 347 |
+
defined( __i386 ) || \
|
| 348 |
+
defined( _M_IX86 )
|
| 349 |
+
#define OSPLAT "OSPLAT=X86"
|
| 350 |
+
#endif
|
| 351 |
+
|
| 352 |
+
#if defined( __ia64__ ) || \
|
| 353 |
+
defined( __IA64__ ) || \
|
| 354 |
+
defined( __ia64 )
|
| 355 |
+
#define OSPLAT "OSPLAT=IA64"
|
| 356 |
+
#endif
|
| 357 |
+
|
| 358 |
+
#if defined( __x86_64__ ) || \
|
| 359 |
+
defined( __amd64__ ) || \
|
| 360 |
+
defined( _M_AMD64 )
|
| 361 |
+
#define OSPLAT "OSPLAT=X86_64"
|
| 362 |
+
#endif
|
| 363 |
+
|
| 364 |
+
#if defined( __sparc__ ) || \
|
| 365 |
+
defined( __sparc )
|
| 366 |
+
#define OSPLAT "OSPLAT=SPARC"
|
| 367 |
+
#endif
|
| 368 |
+
|
| 369 |
+
#ifdef __mips__
|
| 370 |
+
#define OSPLAT "OSPLAT=MIPS"
|
| 371 |
+
#endif
|
| 372 |
+
|
| 373 |
+
#ifdef __arm__
|
| 374 |
+
#define OSPLAT "OSPLAT=ARM"
|
| 375 |
+
#endif
|
| 376 |
+
|
| 377 |
+
#ifdef __s390__
|
| 378 |
+
#define OSPLAT "OSPLAT=390"
|
| 379 |
+
#endif
|
| 380 |
+
|
| 381 |
+
#ifdef __hppa
|
| 382 |
+
#define OSPLAT "OSPLAT=PARISC"
|
| 383 |
+
#endif
|
| 384 |
+
|
| 385 |
+
#ifndef OSPLAT
|
| 386 |
+
#define OSPLAT ""
|
| 387 |
+
#endif
|
| 388 |
+
|
| 389 |
+
|
| 390 |
+
/*
|
| 391 |
+
* Jam implementation misc.
|
| 392 |
+
*/
|
| 393 |
+
|
| 394 |
+
#ifndef MAXLINE
|
| 395 |
+
#define MAXLINE 102400 /* max chars per command line */
|
| 396 |
+
#endif
|
| 397 |
+
|
| 398 |
+
#ifndef EXITOK
|
| 399 |
+
#define EXITOK 0
|
| 400 |
+
#define EXITBAD 1
|
| 401 |
+
#endif
|
| 402 |
+
|
| 403 |
+
#ifndef SPLITPATH
|
| 404 |
+
#define SPLITPATH ':'
|
| 405 |
+
#endif
|
| 406 |
+
|
| 407 |
+
/* You probably do not need to muck with these. */
|
| 408 |
+
|
| 409 |
+
#define MAXSYM 1024 /* longest symbol in the environment */
|
| 410 |
+
#define MAXJPATH 1024 /* longest filename */
|
| 411 |
+
|
| 412 |
+
#define MAXJOBS 64 /* internally enforced -j limit */
|
| 413 |
+
#define MAXARGC 32 /* words in $(JAMSHELL) */
|
| 414 |
+
|
| 415 |
+
/* Jam private definitions below. */
|
| 416 |
+
|
| 417 |
+
#define DEBUG_MAX 14
|
| 418 |
+
|
| 419 |
+
|
| 420 |
+
struct globs
|
| 421 |
+
{
|
| 422 |
+
int noexec;
|
| 423 |
+
int jobs;
|
| 424 |
+
int quitquick;
|
| 425 |
+
int newestfirst; /* build newest sources first */
|
| 426 |
+
int pipe_action;
|
| 427 |
+
char debug[ DEBUG_MAX ];
|
| 428 |
+
FILE * cmdout; /* print cmds, not run them */
|
| 429 |
+
long timeout; /* number of seconds to limit actions to,
|
| 430 |
+
* default 0 for no limit.
|
| 431 |
+
*/
|
| 432 |
+
int dart; /* output build and test results formatted for
|
| 433 |
+
* Dart
|
| 434 |
+
*/
|
| 435 |
+
int max_buf; /* maximum amount of output saved from target
|
| 436 |
+
* (kb)
|
| 437 |
+
*/
|
| 438 |
+
};
|
| 439 |
+
|
| 440 |
+
extern struct globs globs;
|
| 441 |
+
|
| 442 |
+
#define DEBUG_MAKE ( globs.debug[ 1 ] ) /* show actions when executed */
|
| 443 |
+
#define DEBUG_MAKEQ ( globs.debug[ 2 ] ) /* show even quiet actions */
|
| 444 |
+
#define DEBUG_EXEC ( globs.debug[ 2 ] ) /* show text of actons */
|
| 445 |
+
#define DEBUG_MAKEPROG ( globs.debug[ 3 ] ) /* show make0 progress */
|
| 446 |
+
#define DEBUG_BIND ( globs.debug[ 3 ] ) /* show when files bound */
|
| 447 |
+
|
| 448 |
+
#define DEBUG_EXECCMD ( globs.debug[ 4 ] ) /* show execcmds()'s work */
|
| 449 |
+
|
| 450 |
+
#define DEBUG_COMPILE ( globs.debug[ 5 ] ) /* show rule invocations */
|
| 451 |
+
|
| 452 |
+
#define DEBUG_HEADER ( globs.debug[ 6 ] ) /* show result of header scan */
|
| 453 |
+
#define DEBUG_BINDSCAN ( globs.debug[ 6 ] ) /* show result of dir scan */
|
| 454 |
+
#define DEBUG_SEARCH ( globs.debug[ 6 ] ) /* show binding attempts */
|
| 455 |
+
|
| 456 |
+
#define DEBUG_VARSET ( globs.debug[ 7 ] ) /* show variable settings */
|
| 457 |
+
#define DEBUG_VARGET ( globs.debug[ 8 ] ) /* show variable fetches */
|
| 458 |
+
#define DEBUG_VAREXP ( globs.debug[ 8 ] ) /* show variable expansions */
|
| 459 |
+
#define DEBUG_IF ( globs.debug[ 8 ] ) /* show 'if' calculations */
|
| 460 |
+
#define DEBUG_LISTS ( globs.debug[ 9 ] ) /* show list manipulation */
|
| 461 |
+
#define DEBUG_SCAN ( globs.debug[ 9 ] ) /* show scanner tokens */
|
| 462 |
+
#define DEBUG_MEM ( globs.debug[ 9 ] ) /* show memory use */
|
| 463 |
+
|
| 464 |
+
#define DEBUG_PROFILE ( globs.debug[ 10 ] ) /* dump rule execution times */
|
| 465 |
+
#define DEBUG_PARSE ( globs.debug[ 11 ] ) /* debug parsing */
|
| 466 |
+
#define DEBUG_GRAPH ( globs.debug[ 12 ] ) /* debug dependencies */
|
| 467 |
+
#define DEBUG_FATE ( globs.debug[ 13 ] ) /* show fate changes in make0() */
|
| 468 |
+
|
| 469 |
+
/* Everyone gets the memory definitions. */
|
| 470 |
+
#include "mem.h"
|
| 471 |
+
|
| 472 |
+
/* They also get the profile functions. */
|
| 473 |
+
#include "debug.h"
|
| 474 |
+
|
| 475 |
+
#endif
|
mosesdecoder/jam-files/engine/jamgram.y
ADDED
|
@@ -0,0 +1,373 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
%token _BANG_t
|
| 2 |
+
%token _BANG_EQUALS_t
|
| 3 |
+
%token _AMPER_t
|
| 4 |
+
%token _AMPERAMPER_t
|
| 5 |
+
%token _LPAREN_t
|
| 6 |
+
%token _RPAREN_t
|
| 7 |
+
%token _PLUS_EQUALS_t
|
| 8 |
+
%token _COLON_t
|
| 9 |
+
%token _SEMIC_t
|
| 10 |
+
%token _LANGLE_t
|
| 11 |
+
%token _LANGLE_EQUALS_t
|
| 12 |
+
%token _EQUALS_t
|
| 13 |
+
%token _RANGLE_t
|
| 14 |
+
%token _RANGLE_EQUALS_t
|
| 15 |
+
%token _QUESTION_EQUALS_t
|
| 16 |
+
%token _LBRACKET_t
|
| 17 |
+
%token _RBRACKET_t
|
| 18 |
+
%token ACTIONS_t
|
| 19 |
+
%token BIND_t
|
| 20 |
+
%token CASE_t
|
| 21 |
+
%token CLASS_t
|
| 22 |
+
%token DEFAULT_t
|
| 23 |
+
%token ELSE_t
|
| 24 |
+
%token EXISTING_t
|
| 25 |
+
%token FOR_t
|
| 26 |
+
%token IF_t
|
| 27 |
+
%token IGNORE_t
|
| 28 |
+
%token IN_t
|
| 29 |
+
%token INCLUDE_t
|
| 30 |
+
%token LOCAL_t
|
| 31 |
+
%token MODULE_t
|
| 32 |
+
%token ON_t
|
| 33 |
+
%token PIECEMEAL_t
|
| 34 |
+
%token QUIETLY_t
|
| 35 |
+
%token RETURN_t
|
| 36 |
+
%token RULE_t
|
| 37 |
+
%token SWITCH_t
|
| 38 |
+
%token TOGETHER_t
|
| 39 |
+
%token UPDATED_t
|
| 40 |
+
%token WHILE_t
|
| 41 |
+
%token _LBRACE_t
|
| 42 |
+
%token _BAR_t
|
| 43 |
+
%token _BARBAR_t
|
| 44 |
+
%token _RBRACE_t
|
| 45 |
+
/*
|
| 46 |
+
* Copyright 1993, 2000 Christopher Seiwald.
|
| 47 |
+
*
|
| 48 |
+
* This file is part of Jam - see jam.c for Copyright information.
|
| 49 |
+
*/
|
| 50 |
+
|
| 51 |
+
/* This file is ALSO:
|
| 52 |
+
* Copyright 2001-2004 David Abrahams.
|
| 53 |
+
* Distributed under the Boost Software License, Version 1.0.
|
| 54 |
+
* (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
|
| 55 |
+
*/
|
| 56 |
+
|
| 57 |
+
/*
|
| 58 |
+
* jamgram.yy - jam grammar
|
| 59 |
+
*
|
| 60 |
+
* 04/13/94 (seiwald) - added shorthand L0 for null list pointer
|
| 61 |
+
* 06/01/94 (seiwald) - new 'actions existing' does existing sources
|
| 62 |
+
* 08/23/94 (seiwald) - Support for '+=' (append to variable)
|
| 63 |
+
* 08/31/94 (seiwald) - Allow ?= as alias for "default =".
|
| 64 |
+
* 09/15/94 (seiwald) - if conditionals take only single arguments, so
|
| 65 |
+
* that 'if foo == bar' gives syntax error (use =).
|
| 66 |
+
* 02/11/95 (seiwald) - when scanning arguments to rules, only treat
|
| 67 |
+
* punctuation keywords as keywords. All arg lists
|
| 68 |
+
* are terminated with punctuation keywords.
|
| 69 |
+
*
|
| 70 |
+
* 09/11/00 (seiwald) - Support for function calls:
|
| 71 |
+
*
|
| 72 |
+
* Rules now return lists (LIST *), rather than void.
|
| 73 |
+
*
|
| 74 |
+
* New "[ rule ]" syntax evals rule into a LIST.
|
| 75 |
+
*
|
| 76 |
+
* Lists are now generated by compile_list() and
|
| 77 |
+
* compile_append(), and any other rule that indirectly
|
| 78 |
+
* makes a list, rather than being built directly here,
|
| 79 |
+
* so that lists values can contain rule evaluations.
|
| 80 |
+
*
|
| 81 |
+
* New 'return' rule sets the return value, though
|
| 82 |
+
* other statements also may have return values.
|
| 83 |
+
*
|
| 84 |
+
* 'run' production split from 'block' production so
|
| 85 |
+
* that empty blocks can be handled separately.
|
| 86 |
+
*/
|
| 87 |
+
|
| 88 |
+
%token ARG STRING
|
| 89 |
+
|
| 90 |
+
%left _BARBAR_t _BAR_t
|
| 91 |
+
%left _AMPERAMPER_t _AMPER_t
|
| 92 |
+
%left _EQUALS_t _BANG_EQUALS_t IN_t
|
| 93 |
+
%left _LANGLE_t _LANGLE_EQUALS_t _RANGLE_t _RANGLE_EQUALS_t
|
| 94 |
+
%left _BANG_t
|
| 95 |
+
|
| 96 |
+
%{
|
| 97 |
+
#include "jam.h"
|
| 98 |
+
|
| 99 |
+
#include "lists.h"
|
| 100 |
+
#include "parse.h"
|
| 101 |
+
#include "scan.h"
|
| 102 |
+
#include "compile.h"
|
| 103 |
+
#include "object.h"
|
| 104 |
+
#include "rules.h"
|
| 105 |
+
|
| 106 |
+
# define YYMAXDEPTH 10000 /* for OSF and other less endowed yaccs */
|
| 107 |
+
|
| 108 |
+
# define F0 -1
|
| 109 |
+
# define P0 (PARSE *)0
|
| 110 |
+
# define S0 (OBJECT *)0
|
| 111 |
+
|
| 112 |
+
# define pappend( l,r ) parse_make( PARSE_APPEND,l,r,P0,S0,S0,0 )
|
| 113 |
+
# define peval( c,l,r ) parse_make( PARSE_EVAL,l,r,P0,S0,S0,c )
|
| 114 |
+
# define pfor( s,l,r,x ) parse_make( PARSE_FOREACH,l,r,P0,s,S0,x )
|
| 115 |
+
# define pif( l,r,t ) parse_make( PARSE_IF,l,r,t,S0,S0,0 )
|
| 116 |
+
# define pincl( l ) parse_make( PARSE_INCLUDE,l,P0,P0,S0,S0,0 )
|
| 117 |
+
# define plist( s ) parse_make( PARSE_LIST,P0,P0,P0,s,S0,0 )
|
| 118 |
+
# define plocal( l,r,t ) parse_make( PARSE_LOCAL,l,r,t,S0,S0,0 )
|
| 119 |
+
# define pmodule( l,r ) parse_make( PARSE_MODULE,l,r,P0,S0,S0,0 )
|
| 120 |
+
# define pclass( l,r ) parse_make( PARSE_CLASS,l,r,P0,S0,S0,0 )
|
| 121 |
+
# define pnull() parse_make( PARSE_NULL,P0,P0,P0,S0,S0,0 )
|
| 122 |
+
# define pon( l,r ) parse_make( PARSE_ON,l,r,P0,S0,S0,0 )
|
| 123 |
+
# define prule( s,p ) parse_make( PARSE_RULE,p,P0,P0,s,S0,0 )
|
| 124 |
+
# define prules( l,r ) parse_make( PARSE_RULES,l,r,P0,S0,S0,0 )
|
| 125 |
+
# define pset( l,r,a ) parse_make( PARSE_SET,l,r,P0,S0,S0,a )
|
| 126 |
+
# define pset1( l,r,t,a ) parse_make( PARSE_SETTINGS,l,r,t,S0,S0,a )
|
| 127 |
+
# define psetc( s,p,a,l ) parse_make( PARSE_SETCOMP,p,a,P0,s,S0,l )
|
| 128 |
+
# define psete( s,l,s1,f ) parse_make( PARSE_SETEXEC,l,P0,P0,s,s1,f )
|
| 129 |
+
# define pswitch( l,r ) parse_make( PARSE_SWITCH,l,r,P0,S0,S0,0 )
|
| 130 |
+
# define pwhile( l,r ) parse_make( PARSE_WHILE,l,r,P0,S0,S0,0 )
|
| 131 |
+
|
| 132 |
+
# define pnode( l,r ) parse_make( F0,l,r,P0,S0,S0,0 )
|
| 133 |
+
# define psnode( s,l ) parse_make( F0,l,P0,P0,s,S0,0 )
|
| 134 |
+
|
| 135 |
+
%}
|
| 136 |
+
|
| 137 |
+
%%
|
| 138 |
+
|
| 139 |
+
run : /* empty */
|
| 140 |
+
/* do nothing */
|
| 141 |
+
| rules
|
| 142 |
+
{ parse_save( $1.parse ); }
|
| 143 |
+
;
|
| 144 |
+
|
| 145 |
+
/*
|
| 146 |
+
* block - zero or more rules
|
| 147 |
+
* rules - one or more rules
|
| 148 |
+
* rule - any one of jam's rules
|
| 149 |
+
* right-recursive so rules execute in order.
|
| 150 |
+
*/
|
| 151 |
+
|
| 152 |
+
block : null
|
| 153 |
+
{ $$.parse = $1.parse; }
|
| 154 |
+
| rules
|
| 155 |
+
{ $$.parse = $1.parse; }
|
| 156 |
+
;
|
| 157 |
+
|
| 158 |
+
rules : rule
|
| 159 |
+
{ $$.parse = $1.parse; }
|
| 160 |
+
| rule rules
|
| 161 |
+
{ $$.parse = prules( $1.parse, $2.parse ); }
|
| 162 |
+
| LOCAL_t list assign_list_opt _SEMIC_t block
|
| 163 |
+
{ $$.parse = plocal( $2.parse, $3.parse, $5.parse ); }
|
| 164 |
+
;
|
| 165 |
+
|
| 166 |
+
null : /* empty */
|
| 167 |
+
{ $$.parse = pnull(); }
|
| 168 |
+
;
|
| 169 |
+
|
| 170 |
+
assign_list_opt : _EQUALS_t list
|
| 171 |
+
{ $$.parse = $2.parse; $$.number = ASSIGN_SET; }
|
| 172 |
+
| null
|
| 173 |
+
{ $$.parse = $1.parse; $$.number = ASSIGN_APPEND; }
|
| 174 |
+
;
|
| 175 |
+
|
| 176 |
+
arglist_opt : _LPAREN_t lol _RPAREN_t
|
| 177 |
+
{ $$.parse = $2.parse; }
|
| 178 |
+
|
|
| 179 |
+
{ $$.parse = P0; }
|
| 180 |
+
;
|
| 181 |
+
|
| 182 |
+
local_opt : LOCAL_t
|
| 183 |
+
{ $$.number = 1; }
|
| 184 |
+
| /* empty */
|
| 185 |
+
{ $$.number = 0; }
|
| 186 |
+
;
|
| 187 |
+
|
| 188 |
+
rule : _LBRACE_t block _RBRACE_t
|
| 189 |
+
{ $$.parse = $2.parse; }
|
| 190 |
+
| INCLUDE_t list _SEMIC_t
|
| 191 |
+
{ $$.parse = pincl( $2.parse ); }
|
| 192 |
+
| ARG lol _SEMIC_t
|
| 193 |
+
{ $$.parse = prule( $1.string, $2.parse ); }
|
| 194 |
+
| arg assign list _SEMIC_t
|
| 195 |
+
{ $$.parse = pset( $1.parse, $3.parse, $2.number ); }
|
| 196 |
+
| arg ON_t list assign list _SEMIC_t
|
| 197 |
+
{ $$.parse = pset1( $1.parse, $3.parse, $5.parse, $4.number ); }
|
| 198 |
+
| RETURN_t list _SEMIC_t
|
| 199 |
+
{ $$.parse = $2.parse; }
|
| 200 |
+
| FOR_t local_opt ARG IN_t list _LBRACE_t block _RBRACE_t
|
| 201 |
+
{ $$.parse = pfor( $3.string, $5.parse, $7.parse, $2.number ); }
|
| 202 |
+
| SWITCH_t list _LBRACE_t cases _RBRACE_t
|
| 203 |
+
{ $$.parse = pswitch( $2.parse, $4.parse ); }
|
| 204 |
+
| IF_t expr _LBRACE_t block _RBRACE_t
|
| 205 |
+
{ $$.parse = pif( $2.parse, $4.parse, pnull() ); }
|
| 206 |
+
| MODULE_t list _LBRACE_t block _RBRACE_t
|
| 207 |
+
{ $$.parse = pmodule( $2.parse, $4.parse ); }
|
| 208 |
+
| CLASS_t lol _LBRACE_t block _RBRACE_t
|
| 209 |
+
{ $$.parse = pclass( $2.parse, $4.parse ); }
|
| 210 |
+
| WHILE_t expr _LBRACE_t block _RBRACE_t
|
| 211 |
+
{ $$.parse = pwhile( $2.parse, $4.parse ); }
|
| 212 |
+
| IF_t expr _LBRACE_t block _RBRACE_t ELSE_t rule
|
| 213 |
+
{ $$.parse = pif( $2.parse, $4.parse, $7.parse ); }
|
| 214 |
+
| local_opt RULE_t ARG arglist_opt rule
|
| 215 |
+
{ $$.parse = psetc( $3.string, $5.parse, $4.parse, $1.number ); }
|
| 216 |
+
| ON_t arg rule
|
| 217 |
+
{ $$.parse = pon( $2.parse, $3.parse ); }
|
| 218 |
+
| ACTIONS_t eflags ARG bindlist _LBRACE_t
|
| 219 |
+
{ yymode( SCAN_STRING ); }
|
| 220 |
+
STRING
|
| 221 |
+
{ yymode( SCAN_NORMAL ); }
|
| 222 |
+
_RBRACE_t
|
| 223 |
+
{ $$.parse = psete( $3.string,$4.parse,$7.string,$2.number ); }
|
| 224 |
+
;
|
| 225 |
+
|
| 226 |
+
/*
|
| 227 |
+
* assign - = or +=
|
| 228 |
+
*/
|
| 229 |
+
|
| 230 |
+
assign : _EQUALS_t
|
| 231 |
+
{ $$.number = ASSIGN_SET; }
|
| 232 |
+
| _PLUS_EQUALS_t
|
| 233 |
+
{ $$.number = ASSIGN_APPEND; }
|
| 234 |
+
| _QUESTION_EQUALS_t
|
| 235 |
+
{ $$.number = ASSIGN_DEFAULT; }
|
| 236 |
+
| DEFAULT_t _EQUALS_t
|
| 237 |
+
{ $$.number = ASSIGN_DEFAULT; }
|
| 238 |
+
;
|
| 239 |
+
|
| 240 |
+
/*
|
| 241 |
+
* expr - an expression for if
|
| 242 |
+
*/
|
| 243 |
+
expr : arg
|
| 244 |
+
{ $$.parse = peval( EXPR_EXISTS, $1.parse, pnull() ); }
|
| 245 |
+
| expr _EQUALS_t expr
|
| 246 |
+
{ $$.parse = peval( EXPR_EQUALS, $1.parse, $3.parse ); }
|
| 247 |
+
| expr _BANG_EQUALS_t expr
|
| 248 |
+
{ $$.parse = peval( EXPR_NOTEQ, $1.parse, $3.parse ); }
|
| 249 |
+
| expr _LANGLE_t expr
|
| 250 |
+
{ $$.parse = peval( EXPR_LESS, $1.parse, $3.parse ); }
|
| 251 |
+
| expr _LANGLE_EQUALS_t expr
|
| 252 |
+
{ $$.parse = peval( EXPR_LESSEQ, $1.parse, $3.parse ); }
|
| 253 |
+
| expr _RANGLE_t expr
|
| 254 |
+
{ $$.parse = peval( EXPR_MORE, $1.parse, $3.parse ); }
|
| 255 |
+
| expr _RANGLE_EQUALS_t expr
|
| 256 |
+
{ $$.parse = peval( EXPR_MOREEQ, $1.parse, $3.parse ); }
|
| 257 |
+
| expr _AMPER_t expr
|
| 258 |
+
{ $$.parse = peval( EXPR_AND, $1.parse, $3.parse ); }
|
| 259 |
+
| expr _AMPERAMPER_t expr
|
| 260 |
+
{ $$.parse = peval( EXPR_AND, $1.parse, $3.parse ); }
|
| 261 |
+
| expr _BAR_t expr
|
| 262 |
+
{ $$.parse = peval( EXPR_OR, $1.parse, $3.parse ); }
|
| 263 |
+
| expr _BARBAR_t expr
|
| 264 |
+
{ $$.parse = peval( EXPR_OR, $1.parse, $3.parse ); }
|
| 265 |
+
| arg IN_t list
|
| 266 |
+
{ $$.parse = peval( EXPR_IN, $1.parse, $3.parse ); }
|
| 267 |
+
| _BANG_t expr
|
| 268 |
+
{ $$.parse = peval( EXPR_NOT, $2.parse, pnull() ); }
|
| 269 |
+
| _LPAREN_t expr _RPAREN_t
|
| 270 |
+
{ $$.parse = $2.parse; }
|
| 271 |
+
;
|
| 272 |
+
|
| 273 |
+
|
| 274 |
+
/*
|
| 275 |
+
* cases - action elements inside a 'switch'
|
| 276 |
+
* case - a single action element inside a 'switch'
|
| 277 |
+
* right-recursive rule so cases can be examined in order.
|
| 278 |
+
*/
|
| 279 |
+
|
| 280 |
+
cases : /* empty */
|
| 281 |
+
{ $$.parse = P0; }
|
| 282 |
+
| case cases
|
| 283 |
+
{ $$.parse = pnode( $1.parse, $2.parse ); }
|
| 284 |
+
;
|
| 285 |
+
|
| 286 |
+
case : CASE_t ARG _COLON_t block
|
| 287 |
+
{ $$.parse = psnode( $2.string, $4.parse ); }
|
| 288 |
+
;
|
| 289 |
+
|
| 290 |
+
/*
|
| 291 |
+
* lol - list of lists
|
| 292 |
+
* right-recursive rule so that lists can be added in order.
|
| 293 |
+
*/
|
| 294 |
+
|
| 295 |
+
lol : list
|
| 296 |
+
{ $$.parse = pnode( P0, $1.parse ); }
|
| 297 |
+
| list _COLON_t lol
|
| 298 |
+
{ $$.parse = pnode( $3.parse, $1.parse ); }
|
| 299 |
+
;
|
| 300 |
+
|
| 301 |
+
/*
|
| 302 |
+
* list - zero or more args in a LIST
|
| 303 |
+
* listp - list (in puncutation only mode)
|
| 304 |
+
* arg - one ARG or function call
|
| 305 |
+
*/
|
| 306 |
+
|
| 307 |
+
list : listp
|
| 308 |
+
{ $$.parse = $1.parse; yymode( SCAN_NORMAL ); }
|
| 309 |
+
;
|
| 310 |
+
|
| 311 |
+
listp : /* empty */
|
| 312 |
+
{ $$.parse = pnull(); yymode( SCAN_PUNCT ); }
|
| 313 |
+
| listp arg
|
| 314 |
+
{ $$.parse = pappend( $1.parse, $2.parse ); }
|
| 315 |
+
;
|
| 316 |
+
|
| 317 |
+
arg : ARG
|
| 318 |
+
{ $$.parse = plist( $1.string ); }
|
| 319 |
+
| _LBRACKET_t { yymode( SCAN_NORMAL ); } func _RBRACKET_t
|
| 320 |
+
{ $$.parse = $3.parse; }
|
| 321 |
+
;
|
| 322 |
+
|
| 323 |
+
/*
|
| 324 |
+
* func - a function call (inside [])
|
| 325 |
+
* This needs to be split cleanly out of 'rule'
|
| 326 |
+
*/
|
| 327 |
+
|
| 328 |
+
func : ARG lol
|
| 329 |
+
{ $$.parse = prule( $1.string, $2.parse ); }
|
| 330 |
+
| ON_t arg ARG lol
|
| 331 |
+
{ $$.parse = pon( $2.parse, prule( $3.string, $4.parse ) ); }
|
| 332 |
+
| ON_t arg RETURN_t list
|
| 333 |
+
{ $$.parse = pon( $2.parse, $4.parse ); }
|
| 334 |
+
;
|
| 335 |
+
|
| 336 |
+
|
| 337 |
+
/*
|
| 338 |
+
* eflags - zero or more modifiers to 'executes'
|
| 339 |
+
* eflag - a single modifier to 'executes'
|
| 340 |
+
*/
|
| 341 |
+
|
| 342 |
+
eflags : /* empty */
|
| 343 |
+
{ $$.number = 0; }
|
| 344 |
+
| eflags eflag
|
| 345 |
+
{ $$.number = $1.number | $2.number; }
|
| 346 |
+
;
|
| 347 |
+
|
| 348 |
+
eflag : UPDATED_t
|
| 349 |
+
{ $$.number = EXEC_UPDATED; }
|
| 350 |
+
| TOGETHER_t
|
| 351 |
+
{ $$.number = EXEC_TOGETHER; }
|
| 352 |
+
| IGNORE_t
|
| 353 |
+
{ $$.number = EXEC_IGNORE; }
|
| 354 |
+
| QUIETLY_t
|
| 355 |
+
{ $$.number = EXEC_QUIETLY; }
|
| 356 |
+
| PIECEMEAL_t
|
| 357 |
+
{ $$.number = EXEC_PIECEMEAL; }
|
| 358 |
+
| EXISTING_t
|
| 359 |
+
{ $$.number = EXEC_EXISTING; }
|
| 360 |
+
;
|
| 361 |
+
|
| 362 |
+
|
| 363 |
+
/*
|
| 364 |
+
* bindlist - list of variable to bind for an action
|
| 365 |
+
*/
|
| 366 |
+
|
| 367 |
+
bindlist : /* empty */
|
| 368 |
+
{ $$.parse = pnull(); }
|
| 369 |
+
| BIND_t list
|
| 370 |
+
{ $$.parse = $2.parse; }
|
| 371 |
+
;
|
| 372 |
+
|
| 373 |
+
|