sleepyhead111 commited on
Commit
27fb65a
·
verified ·
1 Parent(s): de68f2b

Add files using upload-large-folder tool

Browse files
This view is limited to 50 files because it contains too many changes.   See raw diff
Files changed (50) hide show
  1. mosesdecoder/contrib/combine-ptables/README.md +147 -0
  2. mosesdecoder/contrib/combine-ptables/combine-ptables.pl +449 -0
  3. mosesdecoder/contrib/m4m/Jamfile +12 -0
  4. mosesdecoder/contrib/m4m/Makefile +2 -0
  5. mosesdecoder/contrib/m4m/README +24 -0
  6. mosesdecoder/contrib/picaro/zh/README +4 -0
  7. mosesdecoder/contrib/picaro/zh/alternate.aln +1 -0
  8. mosesdecoder/contrib/picaro/zh/sample.aln +1 -0
  9. mosesdecoder/contrib/picaro/zh/sample.e +1 -0
  10. mosesdecoder/contrib/picaro/zh/sample.f +1 -0
  11. mosesdecoder/contrib/promix/test_data/esen.ep.model.filtered/phrase-table.0-0.1.1.binphr.srctree.wa +0 -0
  12. mosesdecoder/contrib/promix/test_data/esen.ep.model.filtered/phrase-table.0-0.1.1.binphr.srcvoc +8 -0
  13. mosesdecoder/contrib/promix/test_data/esen.ep.model.filtered/phrase-table.0-0.1.1.binphr.tgtvoc +0 -0
  14. mosesdecoder/contrib/promix/test_data/esen.nc.model.filtered/phrase-table.0-0.1.1 +0 -0
  15. mosesdecoder/contrib/server/Translation-web/src/conf/MANIFEST.MF +2 -0
  16. mosesdecoder/contrib/server/Translation-web/src/java/com/hpl/mt/Translate.java +129 -0
  17. mosesdecoder/contrib/server/Translation-web/web/META-INF/context.xml +2 -0
  18. mosesdecoder/contrib/server/Translation-web/web/WEB-INF/web.xml +16 -0
  19. mosesdecoder/contrib/server/Translation-web/web/css/common.css +22 -0
  20. mosesdecoder/contrib/server/Translation-web/web/lib/jquery-1.6.4.js +0 -0
  21. mosesdecoder/contrib/server/Translation-web/web/lib/jquery-ui-1.8.16.custom.js +0 -0
  22. mosesdecoder/jam-files/boost-build/tools/boostbook.jam +730 -0
  23. mosesdecoder/jam-files/boost-build/tools/como-linux.jam +103 -0
  24. mosesdecoder/jam-files/boost-build/tools/gfortran.jam +39 -0
  25. mosesdecoder/jam-files/boost-build/tools/message.jam +55 -0
  26. mosesdecoder/jam-files/boost-build/tools/pgi.jam +147 -0
  27. mosesdecoder/jam-files/boost-build/tools/quickbook-config.jam +44 -0
  28. mosesdecoder/jam-files/boost-build/tools/quickbook.jam +361 -0
  29. mosesdecoder/jam-files/boost-build/tools/stage.jam +524 -0
  30. mosesdecoder/jam-files/boost-build/tools/testing-aux.jam +210 -0
  31. mosesdecoder/jam-files/boost-build/tools/vacpp.jam +150 -0
  32. mosesdecoder/jam-files/boost-build/util/container.jam +339 -0
  33. mosesdecoder/jam-files/boost-build/util/indirect.jam +115 -0
  34. mosesdecoder/jam-files/boost-build/util/option.jam +109 -0
  35. mosesdecoder/jam-files/boost-build/util/os.jam +171 -0
  36. mosesdecoder/jam-files/boost-build/util/path.jam +934 -0
  37. mosesdecoder/jam-files/boost-build/util/print.jam +488 -0
  38. mosesdecoder/jam-files/boost-build/util/sequence.jam +335 -0
  39. mosesdecoder/jam-files/boost-build/util/set.jam +93 -0
  40. mosesdecoder/jam-files/boost-build/util/string.jam +189 -0
  41. mosesdecoder/jam-files/boost-build/util/utility.jam +235 -0
  42. mosesdecoder/moses/TranslationModel/CYKPlusParser/ChartRuleLookupManagerCYKPlus.h +67 -0
  43. mosesdecoder/moses/TranslationModel/CYKPlusParser/ChartRuleLookupManagerExample.cpp +107 -0
  44. mosesdecoder/moses/TranslationModel/CYKPlusParser/ChartRuleLookupManagerExample.h +57 -0
  45. mosesdecoder/moses/TranslationModel/CYKPlusParser/ChartRuleLookupManagerMemory.cpp +270 -0
  46. mosesdecoder/moses/TranslationModel/CYKPlusParser/CompletedRuleCollection.cpp +129 -0
  47. mosesdecoder/moses/TranslationModel/CYKPlusParser/DotChartInMemory.cpp +40 -0
  48. mosesdecoder/moses/TranslationModel/CYKPlusParser/DotChartOnDisk.cpp +57 -0
  49. mosesdecoder/moses/TranslationModel/CYKPlusParser/DotChartOnDisk.h +186 -0
  50. mosesdecoder/moses/TranslationModel/CompactPT/CanonicalHuffman.h +326 -0
mosesdecoder/contrib/combine-ptables/README.md ADDED
@@ -0,0 +1,147 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ `combine-ptables.pl`: fill-up and other techniques of translation models combination.
2
+
3
+ Author:
4
+ Arianna Bisazza bisazza[AT]fbk.eu
5
+
6
+ ABOUT
7
+ -----
8
+ This tool implements "fill-up" and other operations that are useful to combine translation and reordering tables.
9
+ In the "fill-up" approach, the weights of out-domain data sources are estimated directly by MERT along with the
10
+ other model weights.
11
+
12
+ This tool also supports linear interpolation, but weights must be provided by the user.
13
+ If you want to automatically estimate linear interpolation weights, use `contrib/tmcombine` instead.
14
+
15
+
16
+ REFERENCE
17
+ ---------
18
+ When using this script, please cite:
19
+ Arianna Bisazza, Nick Ruiz, and Marcello Federico. 2011.
20
+ "Fill-up versus Interpolation Methods for Phrase-based SMT Adaptation."
21
+ In International Workshop on Spoken Language Translation (IWSLT), San Francisco, CA.
22
+
23
+
24
+ FILL-UP
25
+ -------
26
+
27
+ This combination technique is useful when the relevance of the models is known a priori,
28
+ e.g. when one is trained on in-domain data and the others on out-of-domain data.
29
+
30
+ This mode preserves all the entries and scores coming from the first model, and adds
31
+ entries from the other models only if new.
32
+ If more than two tables are provided, each entry is taken only from the first table
33
+ that contains it.
34
+
35
+ Moreover, a binary feature is added for each additional table to denote the provenance
36
+ of an entry. For in-domain entries, the binary features are all set to 1 (=exp(0)).
37
+ Entries coming from the 2nd table will have the 1st binary feature set to 2.718 (=exp(1)).
38
+
39
+ This technique was proposed in the following works:
40
+
41
+ Preslav Nakov. 2008.
42
+ "Improving English-Spanish Statistical Machine Translation: Experiments in Domain
43
+ Adaptation, Sentence Paraphrasing, Tokenization, and Recasing."
44
+ In Workshop on Statistical Machine Translation.
45
+
46
+ Arianna Bisazza, Nick Ruiz, and Marcello Federico. 2011.
47
+ "Fill-up versus Interpolation Methods for Phrase-based SMT Adaptation."
48
+ In International Workshop on Spoken Language Translation (IWSLT), San Francisco, CA.
49
+
50
+ The latter paper contains details about the present implementation as well as an empirical
51
+ evaluation of fill-up against other combination techniques.
52
+ Reordering model fill-up, cascaded fill-up and pruning criteria are also discussed in the
53
+ same paper.
54
+
55
+ Among the findings of this paper, pruning new (out-of-domain) phrases with more than 4
56
+ source words appeared to be beneficial on the Arabic-English TED task when combining the
57
+ in-domain models with MultiUn models.
58
+ This corresponds to the option:
59
+ `--newSourceMaxLength=4`
60
+
61
+
62
+ BACKOFF
63
+ -------
64
+
65
+ This combination technique is a simplified version of the fill-up technique.
66
+ With respect to fill-up technique, the backoff technique does not add the
67
+ binary additional feature denoting the provenance of an entry.
68
+
69
+
70
+ LINEAR INTERPOLATION
71
+ --------------------
72
+
73
+ This combination technique consists in linearly combining the feature values coming
74
+ from all tables. The combination weights should be provided by the user, otherwise
75
+ uniform weights are assumed.
76
+ When a phrase pair is absent from a table, a constant value (epsilon) is assumed for
77
+ the corresponding feature values. You may want to set your own epsilon.
78
+
79
+ See [Bisazza et al. 2011] for an empirical comparison of uniformly weighted linear
80
+ interpolation against fill-up and decoding-time log-linear interpolation. In that paper,
81
+ epsilon was always set to 1e-06.
82
+
83
+
84
+ UNION
85
+ -----
86
+
87
+ This combination technique creates the union of all phrase pairs and assigns to each
88
+ of them the concatenation of all tables scores.
89
+
90
+
91
+ INTERSECTION
92
+ ------------
93
+
94
+ This combination technique creates the intersection of all phrase pairs: each phrase
95
+ pair that occurs in all phrase tables is output along with the feature vector taken
96
+ from the *first* table.
97
+ The intersection can be used to prune the reordering table in order to match the
98
+ entries of a corresponding pruned phrase table.
99
+
100
+
101
+ USAGE
102
+ -----
103
+
104
+ Get statistics about overlap of entries:
105
+ `combine-ptables.pl --mode=stats ptable1 ptable2 ... ptableN > ptables-overlap-stats`
106
+
107
+ Interpolate phrase tables...
108
+ - with uniform weights:
109
+ `combine-ptables.pl --mode=interp --phpenalty-at=4 ptable1 ptable2 ptable3 > interp-ptable.X`
110
+
111
+ - with custom weights:
112
+ `combine-ptables.pl --mode=interp --phpenalty-at=4 --weights=0.8,0.1,0.1 ptable1 ptable2 ptable3 > interp-ptable.Y`
113
+
114
+ - with custom epsilon:
115
+ `combine-ptables.pl --mode=interp --phpenalty-at=4 --epsilon=1e-05 ptable1 ptable2 ptable3 > interp-ptable.Z`
116
+
117
+
118
+ Fillup phrase tables...
119
+ - unpruned:
120
+ `combine-ptables.pl --mode=fillup ptable1 ptable2 ... ptableN > fillup-ptable`
121
+
122
+ - pruned (new phrases only with max. 4 source words):
123
+ `combine-ptables.pl --mode=fillup --newSourceMaxLength=4 ptable1 ptable2 ... ptableN > fillup-ptable`
124
+
125
+
126
+ Given a pruned phrase table, prune the corresponding reordering table:
127
+ `combine-ptables.pl --mode=intersect1 reotable1-unpruned ptable1-pruned > reotable1-pruned`
128
+
129
+
130
+ NOTES
131
+ -----
132
+
133
+ The script works only with textual (non-binarized) phrase or reordering tables
134
+ that were *previously sorted* with `LC_ALL=C sort`
135
+
136
+ The resulting combined tables are also textual and need to binarized normally.
137
+
138
+ The script combine-ptables.pl can be used on lexicalized reordering tables as well.
139
+
140
+ Input tables can be gzipped.
141
+
142
+ When integrating filled up models into a Moses system, remember to:
143
+ - specify the correct number of features (typically 6) under [ttable-file] in the configuration file `moses.ini`
144
+ - add a weight under [weight-t] in `moses.ini`
145
+ - if you binarize the models, provide the correct number of features to the command:
146
+ `$moses/bin/processPhraseTable -ttable 0 0 - -nscores $nbFeatures`
147
+
mosesdecoder/contrib/combine-ptables/combine-ptables.pl ADDED
@@ -0,0 +1,449 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #! /usr/bin/perl
2
+
3
+ #******************************************************************************
4
+ # Arianna Bisazza @ FBK-irst. March 2012
5
+ #******************************************************************************
6
+ # combine-ptables.pl : Combine Moses-style phrase tables, using different approaches
7
+
8
+
9
+ use strict;
10
+ use open ':utf8';
11
+ binmode STDIN, ':utf8';
12
+ binmode STDOUT, ':utf8';
13
+
14
+ use Getopt::Long "GetOptions";
15
+
16
+ sub main {
17
+ my $usage = "
18
+ USAGE
19
+ -----
20
+ combine-ptables.pl --mode=(interp|union|fillup|backoff|intersect1|stats) ptable1 ptable2 ... ptableN > combined-ptable
21
+ combine-ptables.pl --mode=intersect1 reotable-unpruned ptable-pruned > reotable-pruned
22
+ -----
23
+ #
24
+ # This scripts reads two or more *sorted* phrase tables and combines them in different modes.
25
+ #
26
+ # (Note: if present, word alignments are ignored).
27
+ #
28
+ # ----------------
29
+ # OPTIONS
30
+ # ----------------
31
+ #
32
+ # Required:
33
+ # --mode fillup: Each entry is taken only from the first table that contains it.
34
+ # A binary feature is added from each table except the first.
35
+ # backoff: Each entry is taken only from the first table that contains it.
36
+ # NO binary feature is added.
37
+ # interp: Linear interpolation.
38
+ # union: Union of entries, feature vectors are concatenated.
39
+ # intersect1: Intersection of entries, feature vectors taken from the first table.
40
+ # stats: Only compute some statistics about tables overlap. No table is produced.
41
+ #
42
+ # NOTE: if present, additional fields such as word alignment, phrase counts etc. are always
43
+ # taken from the first table.
44
+ #
45
+ # Generic options:
46
+ # --phpenalty=FLOAT Constant value for phrase penalty. Default is exp(1)=2.718
47
+ # --phpenalty-at=N The (N+1)th score of each table is considered as phrase penalty with a constant value.
48
+ # In 'interp' mode, the corresponding feature is not interpolated but simply set to the constant.
49
+ # In 'union' mode, the ph.penalty (constant) is output only once, after all the other scores.
50
+ # By default, no score is considered as phrase penalty.
51
+ #
52
+ #
53
+ # Options for 'fillup':
54
+ # --newSourceMaxLength=INT Don't include \"new\" source phrases if longer than INT words.
55
+ #
56
+ # Options for 'backoff':
57
+ # --newSourceMaxLength=INT Don't include \"new\" source phrases if longer than INT words.
58
+ #
59
+ # Options for 'interp':
60
+ # --weights=W1,W2,...WN Weights for interpolation. By default, uniform weights are applied.
61
+ # --epsilon=X Score to assume when a phrase pair is not contained in a table (in 'interp' and 'union' modes).
62
+ # Default epsilon is 1e-06.
63
+ #
64
+ # Options for 'union':
65
+ #
66
+ #
67
+ ";
68
+
69
+ my $combination_mode = '';
70
+ my $debug = '';
71
+ my $weights_str = '';
72
+ my $epsilon = 0.000001;
73
+ my $phPenalty = 2.718; # exp(1)
74
+ my $phPenalty_idx = -1;
75
+ my $delim= " ||| ";
76
+ my $delim_RE= ' \|\|\| ';
77
+ my $exp_one = 2.718;
78
+ my $exp_zero = 1;
79
+ my $newSourceMaxLength = -1;
80
+ my $help = '';
81
+
82
+ GetOptions ('debug' => \$debug,
83
+ 'mode=s' => \$combination_mode,
84
+ 'weights=s' => \$weights_str,
85
+ 'epsilon=f' => \$epsilon,
86
+ 'phpenalty=f' => \$phPenalty,
87
+ 'phpenalty-at=i' => \$phPenalty_idx,
88
+ 'newSourceMaxLength=i' => \$newSourceMaxLength,
89
+ 'help' => \$help);
90
+
91
+ if($help) { die "$usage\n\n"; }
92
+
93
+ if($combination_mode!~/(interp|union|fillup|backoff|intersect1|stats)/) {die "$usage\nUnknown combination mode!\n"};
94
+
95
+ if(@ARGV < 2) {die "$usage\n\n Please provide at least 2 tables to combine \n\n";}
96
+
97
+ print STDERR "
98
+ WARNING: Your phrase tables must be sorted (with LC_ALL=C) !!
99
+ ******************************
100
+ Combination mode is [$combination_mode]
101
+ ******************************
102
+ ";
103
+
104
+ my @tables = @ARGV;
105
+ my $nbtables = scalar(@tables);
106
+
107
+ ###########################################
108
+
109
+ # The newSourceMaxLength option requires reading all the first PT before starting the combination
110
+ my %sourcePhrasesPT1;
111
+ if((($combination_mode eq "fillup") || ($combination_mode eq "backoff")) && $newSourceMaxLength>-1) {
112
+ my $table1=$tables[0];
113
+ $table1 =~ s/(.*\.gz)\s*$/gzip -dc < $1|/;
114
+ open(TABLE1, "$table1") or die "Cannot open $table1: ($!)\n";
115
+ while(my $line=<TABLE1>) {
116
+ $line=~m/^(.*?)$delim_RE/;
117
+ $sourcePhrasesPT1{$1}++;
118
+ }
119
+ close(TABLE1);
120
+ }
121
+
122
+ my @table_files=();
123
+ foreach my $table (@tables) {
124
+ $table =~ s/(.*\.gz)\s*$/gzip -dc < $1|/;
125
+ #localize the file glob, so FILE is unique to the inner loop.
126
+ local *FILE;
127
+ open(FILE, "$table") or die "Cannot open $table: ($!)\n";
128
+ push(@table_files, *FILE);
129
+ }
130
+
131
+
132
+ # Read first line from all tables to find number of weights (and sanity checks)
133
+ my @read_ppairs=();
134
+ my $nbscores = &read_line_from_tables(\@table_files, \@read_ppairs);
135
+ print STDERR "Each phrase table contains $nbscores features.\n";
136
+
137
+ ###########################################
138
+
139
+ if($phPenalty_idx!=-1) {
140
+ if($phPenalty_idx<0 || $phPenalty_idx>=$nbscores) {
141
+ die "Invalid value for option phpenalty-at! Should be in the range [0,($nbscores-1)]\n\n";
142
+ }
143
+ else { print STDERR "Phrase penalty at index $phPenalty_idx\n"; }
144
+ }
145
+
146
+ #if($weights_str ne "") { die "Weights option NOT supported yet. Can only use uniform (1/nbscores)\n\n"; }
147
+ #my $unifw = 1/$nbtables;
148
+
149
+ my @weights=(); # Array of arrays each containing the feature weights for a phrase table
150
+ if($combination_mode eq "interp") {
151
+ my @table_level_weights=();
152
+ if($weights_str eq "") {
153
+ @table_level_weights= ((1/$nbtables) x $nbtables); # assuming uniform weights
154
+ }
155
+ else {
156
+ @table_level_weights= split(/,/, $weights_str);
157
+ if(scalar(@table_level_weights) != $nbtables) {
158
+ die "$usage\n Invalid string for option --weights! Must be a comma-separated list of floats, one per ph.table.\n";
159
+ }
160
+ }
161
+
162
+ for(my $i=0; $i<$nbtables; $i++) {
163
+ my @weights_pt = (($table_level_weights[$i]) x $nbscores);
164
+ if($phPenalty_idx!=-1) {
165
+ $weights_pt[$phPenalty_idx]=0;
166
+ }
167
+ print STDERR "WEIGHTS-PT_$i: ", join(" -- ", @weights_pt), "\n";
168
+ $weights[$i] = \@weights_pt;
169
+ }
170
+ print STDERR "EPSILON: $epsilon \n";
171
+ }
172
+
173
+
174
+ ###########################################
175
+
176
+ my @empty_ppair=("");
177
+ my @epsilons = (($epsilon) x $nbscores);
178
+ if($phPenalty_idx>-1) {
179
+ pop @epsilons;
180
+ }
181
+
182
+ my $nbPpairs_inAll=0;
183
+ my @nbPairs_found_only_in=((0) x $nbtables);
184
+ my $MINSCORE=1;
185
+
186
+ print STDERR "Working...\n\n";
187
+ while(1) {
188
+ my $min_ppair="";
189
+ my $reached_end_of_tables=1;
190
+ my @tablesContainingPpair=((0) x $nbtables);
191
+ for(my $i=0; $i<$nbtables; $i++) {
192
+ my $ppair=$read_ppairs[$i]->[0];
193
+ if($ppair ne "") {
194
+ $reached_end_of_tables=0;
195
+ if($min_ppair eq "" || $ppair lt $min_ppair) {
196
+ $min_ppair=$ppair;
197
+ @tablesContainingPpair=((0) x $nbtables);
198
+ $tablesContainingPpair[$i]=1;
199
+ }
200
+ elsif($ppair eq $min_ppair) {
201
+ $tablesContainingPpair[$i]=1;
202
+ }
203
+ }
204
+ }
205
+ last if($reached_end_of_tables);
206
+
207
+ ## Actual combination is performed here:
208
+ &combine_ppair(\@read_ppairs, \@tablesContainingPpair);
209
+
210
+ &read_line_from_tables(\@table_files, \@read_ppairs, \@tablesContainingPpair);
211
+
212
+ }
213
+
214
+ print STDERR "...done!\n";
215
+
216
+ print STDERR "The minimum score in all tables is $MINSCORE\n";
217
+
218
+ if($combination_mode eq "stats") {
219
+ my $tot_ppairs=0;
220
+ print "
221
+ # entries
222
+ found in all tables: $nbPpairs_inAll\n";
223
+
224
+ for(my $i=0; $i<$nbtables; $i++) {
225
+ print "found only in PT_$i: $nbPairs_found_only_in[$i]\n";
226
+ }
227
+
228
+ }
229
+
230
+ ####################################
231
+ sub combine_ppair(PPAIRS_REFARRAY, TABLE_INDICES_REFARRAY) {
232
+ my $ra_ppairs=shift; # 1st item: phrase-pair key (string);
233
+ # 2nd item: ref.array of scores;
234
+ # 3rd item: additional info (string, may be empty)
235
+
236
+ my $ra_toRead=shift; # Important: this says which phrase tables contain the ph.pair currently processed
237
+
238
+ my $ppair="";
239
+ my @scores=();
240
+ my $additional_info="";
241
+
242
+ my $to_print=1;
243
+
244
+ if($debug) {
245
+ print STDERR "combine_ppair:\n";
246
+ for(my $i=0; $i<$nbtables; $i++) {
247
+ if($ra_toRead->[$i]) {
248
+ print STDERR "ppair_$i= ", join (" // ", @{$ra_ppairs->[$i]}), "\n";
249
+ }
250
+ }
251
+ }
252
+
253
+ if($combination_mode eq "stats") {
254
+ $to_print=0;
255
+ my $found_in=-1;
256
+ my $nb_found=0;
257
+ for(my $i=0; $i<$nbtables; $i++) {
258
+ if($ra_toRead->[$i]) {
259
+ $found_in=$i;
260
+ $nb_found++;
261
+ }
262
+ }
263
+ if($nb_found==1) { $nbPairs_found_only_in[$found_in]++; }
264
+ elsif($nb_found==$nbtables) { $nbPpairs_inAll++; }
265
+ }
266
+ ### Fill-up + additional binary feature
267
+ elsif($combination_mode eq "fillup") {
268
+ my @bin_feats=(($exp_zero) x ($nbtables-1));
269
+ for(my $i=0; $i<$nbtables; $i++) {
270
+ if($ra_toRead->[$i]) {
271
+ $ppair= shift(@{$ra_ppairs->[$i]});
272
+ # pruning criteria are applied here:
273
+ if($i>0 && $newSourceMaxLength>-1) {
274
+ $ppair=~m/^(.*?)$delim_RE/;
275
+ if(scalar(split(/ +/, $1)) > $newSourceMaxLength &&
276
+ !defined($sourcePhrasesPT1{$1}))
277
+ { $to_print=0; }
278
+ }
279
+ # @scores= @{$ra_ppairs->[$i]};
280
+ @scores = @{shift(@{$ra_ppairs->[$i]})};
281
+ # binary feature for ph.pair provenance fires here
282
+ if($i>0) { $bin_feats[$i-1]=$exp_one; }
283
+ $additional_info=shift(@{$ra_ppairs->[$i]});
284
+ last;
285
+ }
286
+ }
287
+ push(@scores, @bin_feats);
288
+ }
289
+ ### Backoff
290
+ elsif($combination_mode eq "backoff") {
291
+ #my @bin_feats=(($exp_zero) x ($nbtables-1));
292
+ for(my $i=0; $i<$nbtables; $i++) {
293
+ if($ra_toRead->[$i]) {
294
+ $ppair= shift(@{$ra_ppairs->[$i]});
295
+ # pruning criteria are applied here:
296
+ if($i>0 && $newSourceMaxLength>-1) {
297
+ $ppair=~m/^(.*?)$delim_RE/;
298
+ if(scalar(split(/ +/, $1)) > $newSourceMaxLength &&
299
+ !defined($sourcePhrasesPT1{$1}))
300
+ { $to_print=0; }
301
+ }
302
+ @scores = @{shift(@{$ra_ppairs->[$i]})};
303
+ $additional_info=shift(@{$ra_ppairs->[$i]});
304
+ last;
305
+ }
306
+ }
307
+ }
308
+ ### Linear interpolation
309
+ elsif($combination_mode eq "interp") {
310
+ my $firstPpair=-1;
311
+ @scores=((0) x $nbscores);
312
+ for(my $i=0; $i<$nbtables; $i++) {
313
+ if($ra_toRead->[$i]) {
314
+ if($firstPpair==-1) { $firstPpair=$i; }
315
+ $ppair= shift(@{$ra_ppairs->[$i]});
316
+ my @scoresPT = @{shift(@{$ra_ppairs->[$i]})};
317
+ for(my $j=0; $j<$nbscores; $j++) {
318
+ # $scores[$j]+= $weights[$i]->[$j]* $ra_ppairs->[$i][$j];
319
+ $scores[$j]+= $weights[$i]->[$j]* $scoresPT[$j];
320
+ }
321
+ }
322
+ else {
323
+ for(my $j=0; $j<$nbscores; $j++) {
324
+ $scores[$j]+= $weights[$i]->[$j]* $epsilon;
325
+ }
326
+ }
327
+ if($phPenalty_idx!=-1) {
328
+ $scores[$phPenalty_idx]= $phPenalty;
329
+ }
330
+ }
331
+ if($debug) { print STDERR "..taking info from ptable_$firstPpair\n"; }
332
+ $additional_info= shift(@{$ra_ppairs->[$firstPpair]});
333
+ }
334
+ ### Union + feature concatenation
335
+ elsif($combination_mode eq "union") {
336
+ my $firstPpair=-1;
337
+ for(my $i=0; $i<$nbtables; $i++) {
338
+ if($ra_toRead->[$i]) {
339
+ if($firstPpair==-1) { $firstPpair=$i; }
340
+ $ppair= shift(@{$ra_ppairs->[$i]});
341
+ my @scoresPT= @{shift(@{$ra_ppairs->[$i]})};
342
+ if($phPenalty_idx!=-1) {
343
+ # splice(@{$ra_ppairs->[$i]}, $phPenalty_idx, 1);
344
+ splice(@scoresPT, $phPenalty_idx, 1);
345
+ }
346
+ # push(@scores, @{$ra_ppairs->[$i]});
347
+ push(@scores, @scoresPT);
348
+ }
349
+ else {
350
+ push(@scores, @epsilons);
351
+ }
352
+ }
353
+ if($phPenalty_idx!=-1) {
354
+ push(@scores, $phPenalty);
355
+ }
356
+ if($debug) { print STDERR "..taking info from ptable_$firstPpair\n"; }
357
+ $additional_info= shift(@{$ra_ppairs->[$firstPpair]});
358
+ }
359
+ ### Intersect + features from first table
360
+ elsif($combination_mode eq "intersect1") {
361
+ $to_print=0;
362
+ my $found_in_all=1;
363
+ for(my $i=0; $i<$nbtables; $i++) {
364
+ if(!$ra_toRead->[$i]) {
365
+ $found_in_all=0;
366
+ last;
367
+ }
368
+ }
369
+ if($found_in_all) {
370
+ $to_print=1;
371
+ $ppair= shift(@{$ra_ppairs->[0]});
372
+ # @scores= @{$ra_ppairs->[0]};
373
+ @scores= @{shift(@{$ra_ppairs->[0]})};
374
+ $additional_info= shift(@{$ra_ppairs->[0]});
375
+ }
376
+ }
377
+ else {
378
+ die "$usage\nUnknown combination mode!\n";
379
+ }
380
+
381
+
382
+ if($to_print) {
383
+ if($additional_info eq "") {
384
+ print $ppair, join(" ", @scores), "\n";
385
+ }else {
386
+ print $ppair, join(" ", @scores), $delim, $additional_info, "\n";
387
+ }
388
+ }
389
+ }
390
+
391
+ ####################################
392
+ # Read lines from all filehandles given in FILES_REFARRAY,
393
+ # or from the files whose indices are assigned 1 in the array TABLE_INDICES_REFARRAY
394
+ # Parse each of them as a phrase pair entry and stores it to the corresponding position of PPAIRS_REFARRAY
395
+ sub read_line_from_tables(FILES_REFARRAY, PPAIRS_REFARRAY, TABLE_INDICES_REFARRAY) {
396
+ my $ra_files=shift;
397
+ my $ra_ppairs=shift;
398
+
399
+ my $ra_toRead=shift;
400
+ my @toRead=((1) x $nbtables); # by default read from all files
401
+ if($ra_toRead ne "") {
402
+ @toRead=@$ra_toRead;
403
+ }
404
+
405
+ my $nbscores=-1;
406
+ my $key=""; my $additional_info="";
407
+ for(my $i=0; $i<$nbtables; $i++) {
408
+ next if($toRead[$i]==0);
409
+ my @ppair=();
410
+ my $file=$ra_files->[$i];
411
+ if(my $line = <$file>) {
412
+ chomp $line;
413
+ my @fields = split(/$delim_RE/, $line);
414
+ if(scalar(@fields)<3) {
415
+ die "Invalid phrase table entry:\n$line\n";
416
+ }
417
+ my @scores = split(/\s+/, $fields[2]);
418
+ foreach my $score (@scores) {
419
+ if($score<$MINSCORE) { $MINSCORE=$score; }
420
+ }
421
+ # Get nb of scores from the 1st table. Check that all tables provide the same nb of scores,
422
+ # unless mode is 'intersect' (then it doesn't matter as scores are taken only from 1st table)
423
+ if($nbscores==-1) {
424
+ $nbscores=scalar(@scores);
425
+ } elsif($nbscores!=scalar(@scores) && $combination_mode ne "intersect1") {
426
+ die "Wrong number of scores in table-$i! Should be $nbscores\n";
427
+ }
428
+ # Get additional fields if any (word aligment, phrase counts etc.)
429
+ if(scalar(@fields)>3) {
430
+ $additional_info=join($delim, splice(@fields,3));
431
+ #print STDOUT "additional_info:__{$additional_info}__\n";
432
+ }
433
+ my $key = "$fields[0]$delim$fields[1]$delim"; ## IMPORTANT: the | delimiter at the end of the phrase pair is crucial to preserve sorting!!
434
+ push(@ppair, $key, \@scores, $additional_info);
435
+ }
436
+ else {
437
+ push(@ppair, "");
438
+ }
439
+ $ra_ppairs->[$i]=\@ppair;
440
+ }
441
+
442
+ return $nbscores;
443
+ }
444
+
445
+ #########
446
+ }
447
+
448
+
449
+ &main;
mosesdecoder/contrib/m4m/Jamfile ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ external-lib bzip2 ;
2
+ external-lib zlib ;
3
+
4
+ exe merge-sorted :
5
+ util/merge-sorted.cc
6
+ $(TOP)/moses/TranslationModel/UG/mm//mm
7
+ $(TOP)/moses/TranslationModel/UG/generic//generic
8
+ $(TOP)//boost_iostreams
9
+ $(TOP)//boost_program_options
10
+ ;
11
+
12
+ install $(PREFIX)/bin : merge-sorted ;
mosesdecoder/contrib/m4m/Makefile ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ merge-sorted:
2
+ g++ -O3 -I ../.. util/merge-sorted.cc ../../moses/TranslationModel/UG/generic/file_io/ug_stream.cpp -o $@ -lboost_iostreams -lboost_program_options -lbz2 -lz
mosesdecoder/contrib/m4m/README ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ M4M - Makefiles for Moses
2
+
3
+ Makefiles for Moses (M4M) is a collection of make file modules designed to
4
+ facilitate building and experimenting with Moses MT systems. The long story is
5
+ in the paper (m4m.pdf).
6
+
7
+ You'll need the following additional tools (in your PATH):
8
+ - wget if you want to use m4m to download and install WMT data sets
9
+ - Gnu parallel: http://www.gnu.org/software/parallel/
10
+ - a word aligner (mgiza or fastalign or Berkeley Aligner)
11
+
12
+ ******************************************************************************
13
+ * MAKEFILES FOR MOSES IS STILL UNDER INTENSIVE DEVELOPMENT. *
14
+ * BEAR WITH ME WHILE BUGS ARE BEING FIXED AND FUNCTIONALITY IS ADDED. *
15
+ ******************************************************************************
16
+
17
+ KNOWN ISSUES:
18
+
19
+ - giza phrase table creation sometimes fails when make is run in
20
+ multi-threaded mode. Running make without the -j switch seems to work.
21
+
22
+
23
+
24
+ Ulrich Germann
mosesdecoder/contrib/picaro/zh/README ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ Chinese-English sample
2
+ sample.f Chinese text
3
+ sample.e English text
4
+ sample.a Alignment file with links in f-e format
mosesdecoder/contrib/picaro/zh/alternate.aln ADDED
@@ -0,0 +1 @@
 
 
1
+ 0-0 1-1 2-6 3-2 3-3 4-4 4-5 5-7
mosesdecoder/contrib/picaro/zh/sample.aln ADDED
@@ -0,0 +1 @@
 
 
1
+ 0-0 1-1 2-6 3-2 3-3 3-4 4-5 5-7
mosesdecoder/contrib/picaro/zh/sample.e ADDED
@@ -0,0 +1 @@
 
 
1
+ i want to go to china tomorrow .
mosesdecoder/contrib/picaro/zh/sample.f ADDED
@@ -0,0 +1 @@
 
 
1
+ 我 想 明天 去 中国 .
mosesdecoder/contrib/promix/test_data/esen.ep.model.filtered/phrase-table.0-0.1.1.binphr.srctree.wa ADDED
Binary file (672 Bytes). View file
 
mosesdecoder/contrib/promix/test_data/esen.ep.model.filtered/phrase-table.0-0.1.1.binphr.srcvoc ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ 7 del
2
+ 6 lados
3
+ 5 ambos
4
+ 4 en
5
+ 3 políticos
6
+ 2 los
7
+ 1 a
8
+ 0 Atlántico
mosesdecoder/contrib/promix/test_data/esen.ep.model.filtered/phrase-table.0-0.1.1.binphr.tgtvoc ADDED
The diff for this file is too large to render. See raw diff
 
mosesdecoder/contrib/promix/test_data/esen.nc.model.filtered/phrase-table.0-0.1.1 ADDED
The diff for this file is too large to render. See raw diff
 
mosesdecoder/contrib/server/Translation-web/src/conf/MANIFEST.MF ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ Manifest-Version: 1.0
2
+
mosesdecoder/contrib/server/Translation-web/src/java/com/hpl/mt/Translate.java ADDED
@@ -0,0 +1,129 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ package com.hpl.mt;
2
+
3
+ /*
4
+ * To change this template, choose Tools | Templates
5
+ * and open the template in the editor.
6
+ */
7
+
8
+ import java.io.IOException;
9
+ import java.io.PrintWriter;
10
+ import java.net.URL;
11
+ import java.util.HashMap;
12
+ import java.util.logging.Level;
13
+ import java.util.logging.Logger;
14
+ import javax.servlet.ServletException;
15
+ import javax.servlet.http.HttpServlet;
16
+ import javax.servlet.http.HttpServletRequest;
17
+ import javax.servlet.http.HttpServletResponse;
18
+ import org.apache.xmlrpc.XmlRpcException;
19
+ import org.apache.xmlrpc.client.XmlRpcClient;
20
+ import org.apache.xmlrpc.client.XmlRpcClientConfigImpl;
21
+
22
+ /**
23
+ *
24
+ * @author ulanov
25
+ */
26
+ public class Translate extends HttpServlet {
27
+
28
+ /**
29
+ * Processes requests for both HTTP
30
+ * <code>GET</code> and
31
+ * <code>POST</code> methods.
32
+ *
33
+ * @param request servlet request
34
+ * @param response servlet response
35
+ * @throws ServletException if a servlet-specific error occurs
36
+ * @throws IOException if an I/O error occurs
37
+ */
38
+ protected void processRequest(HttpServletRequest request, HttpServletResponse response)
39
+ throws ServletException, IOException {
40
+ response.setContentType("text/html;charset=UTF-8");
41
+ System.out.println("before" + request.getCharacterEncoding());
42
+ request.setCharacterEncoding("UTF-8");
43
+ System.out.println("after" + request.getCharacterEncoding());
44
+ PrintWriter out = response.getWriter();
45
+ try {
46
+ /*
47
+ * TODO output your page here. You may use following sample code.
48
+ */
49
+ // Create an instance of XmlRpcClient
50
+ String textToTranslate = request.getParameter("text");
51
+ XmlRpcClientConfigImpl config = new XmlRpcClientConfigImpl();
52
+ config.setServerURL(new URL("http://localhost:9008/RPC2"));
53
+ XmlRpcClient client = new XmlRpcClient();
54
+ client.setConfig(config);
55
+ // The XML-RPC data type used by mosesserver is <struct>. In Java, this data type can be represented using HashMap.
56
+ HashMap<String,String> mosesParams = new HashMap<String,String>();
57
+ mosesParams.put("text", textToTranslate);
58
+ mosesParams.put("align", "true");
59
+ mosesParams.put("report-all-factors", "true");
60
+ // The XmlRpcClient.execute method doesn't accept Hashmap (pParams). It's either Object[] or List.
61
+ Object[] params = new Object[] { null };
62
+ params[0] = mosesParams;
63
+ // Invoke the remote method "translate". The result is an Object, convert it to a HashMap.
64
+ HashMap result;
65
+ try {
66
+ result = (HashMap)client.execute("translate", params);
67
+ } catch (XmlRpcException ex) {
68
+ Logger.getLogger(Translate.class.getName()).log(Level.SEVERE, null, ex);
69
+ throw new IOException("XML-RPC failed");
70
+ }
71
+ // Print the returned results
72
+ String textTranslation = (String)result.get("text");
73
+ System.out.println("Input : "+textToTranslate);
74
+ System.out.println("Translation : "+textTranslation);
75
+ out.write(textTranslation);
76
+ if (result.get("align") != null){
77
+ Object[] aligns = (Object[])result.get("align");
78
+ System.out.println("Phrase alignments : [Source Start:Source End][Target Start]");
79
+ for ( Object element : aligns) {
80
+ HashMap align = (HashMap)element;
81
+ System.out.println("["+align.get("src-start")+":"+align.get("src-end")+"]["+align.get("tgt-start")+"]");
82
+ }
83
+ }
84
+ } finally {
85
+ out.close();
86
+ }
87
+ }
88
+
89
+ // <editor-fold defaultstate="collapsed" desc="HttpServlet methods. Click on the + sign on the left to edit the code.">
90
+ /**
91
+ * Handles the HTTP
92
+ * <code>GET</code> method.
93
+ *
94
+ * @param request servlet request
95
+ * @param response servlet response
96
+ * @throws ServletException if a servlet-specific error occurs
97
+ * @throws IOException if an I/O error occurs
98
+ */
99
+ @Override
100
+ protected void doGet(HttpServletRequest request, HttpServletResponse response)
101
+ throws ServletException, IOException {
102
+ processRequest(request, response);
103
+ }
104
+
105
+ /**
106
+ * Handles the HTTP
107
+ * <code>POST</code> method.
108
+ *
109
+ * @param request servlet request
110
+ * @param response servlet response
111
+ * @throws ServletException if a servlet-specific error occurs
112
+ * @throws IOException if an I/O error occurs
113
+ */
114
+ @Override
115
+ protected void doPost(HttpServletRequest request, HttpServletResponse response)
116
+ throws ServletException, IOException {
117
+ processRequest(request, response);
118
+ }
119
+
120
+ /**
121
+ * Returns a short description of the servlet.
122
+ *
123
+ * @return a String containing servlet description
124
+ */
125
+ @Override
126
+ public String getServletInfo() {
127
+ return "Short description";
128
+ }// </editor-fold>
129
+ }
mosesdecoder/contrib/server/Translation-web/web/META-INF/context.xml ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <Context antiJARLocking="true" path="/Translation"/>
mosesdecoder/contrib/server/Translation-web/web/WEB-INF/web.xml ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
3
+ <servlet>
4
+ <servlet-name>Translate</servlet-name>
5
+ <servlet-class>com.hpl.mt.Translate</servlet-class>
6
+ </servlet>
7
+ <servlet-mapping>
8
+ <servlet-name>Translate</servlet-name>
9
+ <url-pattern>/Translate</url-pattern>
10
+ </servlet-mapping>
11
+ <session-config>
12
+ <session-timeout>
13
+ 30
14
+ </session-timeout>
15
+ </session-config>
16
+ </web-app>
mosesdecoder/contrib/server/Translation-web/web/css/common.css ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ Document : common
3
+ Created on : Jul 31, 2012, 11:53:29 AM
4
+ Author : ulanov
5
+ Description:
6
+ Purpose of the stylesheet follows.
7
+ */
8
+
9
+ root {
10
+ display: block;
11
+ }
12
+
13
+ body {font-size:small; font-family: Verdana,Arial,sans-serif;height:auto; width: auto;}
14
+ span {font-size:medium;}
15
+
16
+ #north_tab {height: 10%; width: 100%; float: top;}
17
+ #south_tab {height: 80%; width: 100%; float: bottom;}
18
+
19
+ #input_text {height: 50%; width: 30%; margin-right: 10px; float: left;}
20
+ #output_text {height: 50%; width: 30%; margin-right: 10px; float: left;}
21
+
22
+ #translate {float: left; margin-right: 10px;}
mosesdecoder/contrib/server/Translation-web/web/lib/jquery-1.6.4.js ADDED
The diff for this file is too large to render. See raw diff
 
mosesdecoder/contrib/server/Translation-web/web/lib/jquery-ui-1.8.16.custom.js ADDED
The diff for this file is too large to render. See raw diff
 
mosesdecoder/jam-files/boost-build/tools/boostbook.jam ADDED
@@ -0,0 +1,730 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2003, 2004, 2005 Dave Abrahams
2
+ # Copyright 2003, 2004, 2005 Douglas Gregor
3
+ # Copyright 2005, 2006, 2007 Rene Rivera
4
+ # Copyright 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
+ # This module defines rules to handle generation of documentation
9
+ # from BoostBook sources.
10
+ #
11
+ # The type of output is controlled by the <format> feature which can
12
+ # have the following values::
13
+ #
14
+ # * html: Generates html documention. This is the default.
15
+ # * xhtml: Generates xhtml documentation
16
+ # * htmlhelp: Generates html help output.
17
+ # * onehtml: Generates a single html page.
18
+ # * man: Generates man pages.
19
+ # * pdf: Generates pdf documentation.
20
+ # * ps: Generates postscript output.
21
+ # * docbook: Generates docbook XML.
22
+ # * fo: Generates XSL formating objects.
23
+ # * tests: Extracts test cases from the boostbook XML.
24
+ #
25
+ # format is an implicit feature, so typing pdf on the command
26
+ # line (for example) is a short-cut for format=pdf.
27
+
28
+ import "class" : new ;
29
+ import common ;
30
+ import errors ;
31
+ import targets ;
32
+ import feature ;
33
+ import generators ;
34
+ import print ;
35
+ import property ;
36
+ import project ;
37
+ import property-set ;
38
+ import regex ;
39
+ import scanner ;
40
+ import sequence ;
41
+ import make ;
42
+ import os ;
43
+ import type ;
44
+ import modules path project ;
45
+ import build-system ;
46
+
47
+ import xsltproc : xslt xslt-dir ;
48
+
49
+ # Make this module into a project.
50
+ project.initialize $(__name__) ;
51
+ project boostbook ;
52
+
53
+
54
+ feature.feature format : html xhtml htmlhelp onehtml man pdf ps docbook fo tests
55
+ : incidental implicit composite propagated ;
56
+
57
+ type.register DTDXML : dtdxml ;
58
+ type.register XML : xml ;
59
+ type.register BOOSTBOOK : boostbook : XML ;
60
+ type.register DOCBOOK : docbook : XML ;
61
+ type.register FO : fo : XML ;
62
+ type.register PDF : pdf ;
63
+ type.register PS : ps ;
64
+ type.register XSLT : xsl : XML ;
65
+ type.register HTMLDIR ;
66
+ type.register XHTMLDIR ;
67
+ type.register HTMLHELP ;
68
+ type.register MANPAGES ;
69
+ type.register TESTS : tests ;
70
+ # Artificial target type, used to require invocation of top-level
71
+ # BoostBook generator.
72
+ type.register BOOSTBOOK_MAIN ;
73
+
74
+
75
+ # Initialize BoostBook support.
76
+ rule init (
77
+ docbook-xsl-dir ? # The DocBook XSL stylesheet directory. If not
78
+ # provided, we use DOCBOOK_XSL_DIR from the environment
79
+ # (if available) or look in standard locations.
80
+ # Otherwise, we let the XML processor load the
81
+ # stylesheets remotely.
82
+
83
+ : docbook-dtd-dir ? # The DocBook DTD directory. If not provided, we use
84
+ # DOCBOOK_DTD_DIR From the environment (if available) or
85
+ # look in standard locations. Otherwise, we let the XML
86
+ # processor load the DTD remotely.
87
+
88
+ : boostbook-dir ? # The BoostBook directory with the DTD and XSL subdirs.
89
+ )
90
+ {
91
+
92
+ if ! $(.initialized)
93
+ {
94
+ .initialized = true ;
95
+
96
+ check-boostbook-dir $(boostbook-dir) ;
97
+ find-tools $(docbook-xsl-dir) : $(docbook-dtd-dir) : $(boostbook-dir) ;
98
+
99
+ # Register generators only if we've were called via "using boostbook ; "
100
+ generators.register-standard boostbook.dtdxml-to-boostbook : DTDXML : XML ;
101
+ generators.register-standard boostbook.boostbook-to-docbook : XML : DOCBOOK ;
102
+ generators.register-standard boostbook.boostbook-to-tests : XML : TESTS ;
103
+ generators.register-standard boostbook.docbook-to-onehtml : DOCBOOK : HTML ;
104
+ generators.register-standard boostbook.docbook-to-htmldir : DOCBOOK : HTMLDIR ;
105
+ generators.register-standard boostbook.docbook-to-xhtmldir : DOCBOOK : XHTMLDIR ;
106
+ generators.register-standard boostbook.docbook-to-htmlhelp : DOCBOOK : HTMLHELP ;
107
+ generators.register-standard boostbook.docbook-to-manpages : DOCBOOK : MANPAGES ;
108
+ generators.register-standard boostbook.docbook-to-fo : DOCBOOK : FO ;
109
+
110
+ # The same about Jamfile main target rules.
111
+ IMPORT $(__name__) : boostbook : : boostbook ;
112
+ }
113
+ else
114
+ {
115
+ if $(docbook-xsl-dir)
116
+ {
117
+ modify-config ;
118
+ .docbook-xsl-dir = [ path.make $(docbook-xsl-dir) ] ;
119
+ check-docbook-xsl-dir ;
120
+ }
121
+ if $(docbook-dtd-dir)
122
+ {
123
+ modify-config ;
124
+ .docbook-dtd-dir = [ path.make $(docbook-dtd-dir) ] ;
125
+ check-docbook-dtd-dir ;
126
+ }
127
+ if $(boostbook-dir)
128
+ {
129
+ modify-config ;
130
+ check-boostbook-dir $(boostbook-dir) ;
131
+ local boostbook-xsl-dir = [ path.glob $(boostbook-dir) : xsl ] ;
132
+ local boostbook-dtd-dir = [ path.glob $(boostbook-dir) : dtd ] ;
133
+ .boostbook-xsl-dir = $(boostbook-xsl-dir[1]) ;
134
+ .boostbook-dtd-dir = $(boostbook-dtd-dir[1]) ;
135
+ check-boostbook-xsl-dir ;
136
+ check-boostbook-dtd-dir ;
137
+ }
138
+ }
139
+ }
140
+
141
+ rule lock-config ( )
142
+ {
143
+ if ! $(.initialized)
144
+ {
145
+ errors.user-error "BoostBook has not been configured." ;
146
+ }
147
+ if ! $(.config-locked)
148
+ {
149
+ .config-locked = true ;
150
+ }
151
+ }
152
+
153
+ rule modify-config ( )
154
+ {
155
+ if $(.config-locked)
156
+ {
157
+ errors.user-error "BoostBook configuration cannot be changed after it has been used." ;
158
+ }
159
+ }
160
+
161
+ rule find-boost-in-registry ( keys * )
162
+ {
163
+ local boost-root = ;
164
+ for local R in $(keys)
165
+ {
166
+ local installed-boost = [ W32_GETREG
167
+ "HKEY_LOCAL_MACHINE\\SOFTWARE\\$(R)"
168
+ : "InstallRoot" ] ;
169
+ if $(installed-boost)
170
+ {
171
+ boost-root += [ path.make $(installed-boost) ] ;
172
+ }
173
+ }
174
+ return $(boost-root) ;
175
+ }
176
+
177
+ rule check-docbook-xsl-dir ( )
178
+ {
179
+ if $(.docbook-xsl-dir)
180
+ {
181
+ if ! [ path.glob $(.docbook-xsl-dir) : common/common.xsl ]
182
+ {
183
+ errors.user-error "BoostBook: could not find docbook XSL stylesheets in:" [ path.native $(.docbook-xsl-dir) ] ;
184
+ }
185
+ else
186
+ {
187
+ if --debug-configuration in [ modules.peek : ARGV ]
188
+ {
189
+ ECHO "notice: BoostBook: found docbook XSL stylesheets in:" [ path.native $(.docbook-xsl-dir) ] ;
190
+ }
191
+ }
192
+ }
193
+ }
194
+
195
+ rule check-docbook-dtd-dir ( )
196
+ {
197
+ if $(.docbook-dtd-dir)
198
+ {
199
+ if ! [ path.glob $(.docbook-dtd-dir) : docbookx.dtd ]
200
+ {
201
+ errors.user-error "error: BoostBook: could not find docbook DTD in:" [ path.native $(.docbook-dtd-dir) ] ;
202
+ }
203
+ else
204
+ {
205
+ if --debug-configuration in [ modules.peek : ARGV ]
206
+ {
207
+ ECHO "notice: BoostBook: found docbook DTD in:" [ path.native $(.docbook-dtd-dir) ] ;
208
+ }
209
+ }
210
+ }
211
+ }
212
+
213
+ rule check-boostbook-xsl-dir ( )
214
+ {
215
+ if ! $(.boostbook-xsl-dir)
216
+ {
217
+ errors.user-error "error: BoostBook: could not find boostbook XSL stylesheets." ;
218
+ }
219
+ else if ! [ path.glob $(.boostbook-xsl-dir) : docbook.xsl ]
220
+ {
221
+ errors.user-error "error: BoostBook: could not find docbook XSL stylesheets in:" [ path.native $(.boostbook-xsl-dir) ] ;
222
+ }
223
+ else
224
+ {
225
+ if --debug-configuration in [ modules.peek : ARGV ]
226
+ {
227
+ ECHO "notice: BoostBook: found boostbook XSL stylesheets in:" [ path.native $(.boostbook-xsl-dir) ] ;
228
+ }
229
+ }
230
+ }
231
+
232
+ rule check-boostbook-dtd-dir ( )
233
+ {
234
+ if ! $(.boostbook-dtd-dir)
235
+ {
236
+ errors.user-error "error: BoostBook: could not find boostbook DTD." ;
237
+ }
238
+ else if ! [ path.glob $(.boostbook-dtd-dir) : boostbook.dtd ]
239
+ {
240
+ errors.user-error "error: BoostBook: could not find boostbook DTD in:" [ path.native $(.boostbook-dtd-dir) ] ;
241
+ }
242
+ else
243
+ {
244
+ if --debug-configuration in [ modules.peek : ARGV ]
245
+ {
246
+ ECHO "notice: BoostBook: found boostbook DTD in:" [ path.native $(.boostbook-dtd-dir) ] ;
247
+ }
248
+ }
249
+ }
250
+
251
+ rule check-boostbook-dir ( boostbook-dir ? )
252
+ {
253
+ if $(boostbook-dir) && ! [ path.glob $(boostbook-dir) : xsl ]
254
+ {
255
+ errors.user-error "error: BoostBook: could not find boostbook in:" [ path.native $(boostbook-dir) ] ;
256
+ }
257
+ }
258
+
259
+ rule find-tools ( docbook-xsl-dir ? : docbook-dtd-dir ? : boostbook-dir ? )
260
+ {
261
+ docbook-xsl-dir ?= [ modules.peek : DOCBOOK_XSL_DIR ] ;
262
+ docbook-dtd-dir ?= [ modules.peek : DOCBOOK_DTD_DIR ] ;
263
+ boostbook-dir ?= [ modules.peek : BOOSTBOOK_DIR ] ;
264
+
265
+ # Look for the boostbook stylesheets relative to BOOST_ROOT
266
+ # and Boost.Build.
267
+ local boost-build-root = [ path.make [ build-system.location ] ] ;
268
+ local boostbook-search-dirs = [ path.join $(boost-build-root) .. .. ] ;
269
+
270
+ local boost-root = [ modules.peek : BOOST_ROOT ] ;
271
+ if $(boost-root)
272
+ {
273
+ boostbook-search-dirs += [ path.join [ path.make $(boost-root) ] tools ] ;
274
+ }
275
+ boostbook-dir ?= [ path.glob $(boostbook-search-dirs) : boostbook* ] ;
276
+
277
+ # Try to find the tools in platform specific locations
278
+ if [ os.name ] = NT
279
+ {
280
+ # If installed by the Boost installer.
281
+ local boost-root = ;
282
+
283
+ local boost-installer-versions = snapshot cvs 1.33.0 ;
284
+ local boost-consulting-installer-versions = 1.33.1 1.34.0 1.34.1 ;
285
+ local boostpro-installer-versions =
286
+ 1.35.0 1.36.0 1.37.0 1.38.0 1.39.0 1.40.0 1.41.0 1.42.0
287
+ 1.43.0 1.44.0 1.45.0 1.46.0 1.47.0 1.48.0 1.49.0 1.50.0 ;
288
+
289
+ local old-installer-root = [ find-boost-in-registry Boost.org\\$(boost-installer-versions) ] ;
290
+
291
+ # Make sure that the most recent version is searched for first
292
+ boost-root += [ sequence.reverse
293
+ [ find-boost-in-registry
294
+ Boost-Consulting.com\\$(boost-consulting-installer-versions)
295
+ boostpro.com\\$(boostpro-installer-versions) ] ] ;
296
+
297
+ # Plausible locations.
298
+ local root = [ PWD ] ;
299
+ while $(root) != $(root:D) { root = $(root:D) ; }
300
+ root = [ path.make $(root) ] ;
301
+ local search-dirs = ;
302
+ local docbook-search-dirs = ;
303
+ for local p in $(boost-root) {
304
+ search-dirs += [ path.join $(p) tools ] ;
305
+ }
306
+ for local p in $(old-installer-root)
307
+ {
308
+ search-dirs += [ path.join $(p) share ] ;
309
+ docbook-search-dirs += [ path.join $(p) share ] ;
310
+ }
311
+ search-dirs += [ path.join $(root) Boost tools ] ;
312
+ search-dirs += [ path.join $(root) Boost share ] ;
313
+ docbook-search-dirs += [ path.join $(root) Boost share ] ;
314
+
315
+ docbook-xsl-dir ?= [ path.glob $(docbook-search-dirs) : docbook-xsl* ] ;
316
+ docbook-dtd-dir ?= [ path.glob $(docbook-search-dirs) : docbook-xml* ] ;
317
+ boostbook-dir ?= [ path.glob $(search-dirs) : boostbook* ] ;
318
+ }
319
+ else
320
+ {
321
+ # Plausible locations.
322
+
323
+ local share = /usr/local/share /usr/share /opt/share /opt/local/share ;
324
+ local dtd-versions = 4.2 ;
325
+
326
+ docbook-xsl-dir ?= [ path.glob $(share) : docbook-xsl* ] ;
327
+ docbook-xsl-dir ?= [ path.glob $(share)/sgml/docbook : xsl-stylesheets ] ;
328
+ docbook-xsl-dir ?= [ path.glob $(share)/xsl : docbook* ] ;
329
+
330
+ docbook-dtd-dir ?= [ path.glob $(share) : docbook-xml* ] ;
331
+ docbook-dtd-dir ?= [ path.glob $(share)/sgml/docbook : xml-dtd-$(dtd-versions)* ] ;
332
+ docbook-dtd-dir ?= [ path.glob $(share)/xml/docbook : $(dtd-versions) ] ;
333
+
334
+ boostbook-dir ?= [ path.glob $(share) : boostbook* ] ;
335
+
336
+ # Ubuntu Linux
337
+ docbook-xsl-dir ?= [ path.glob /usr/share/xml/docbook/stylesheet : nwalsh ] ;
338
+ docbook-dtd-dir ?= [ path.glob /usr/share/xml/docbook/schema/dtd : $(dtd-versions) ] ;
339
+
340
+ # SUSE
341
+ docbook-xsl-dir ?= [ path.glob /usr/share/xml/docbook/stylesheet/nwalsh : current ] ;
342
+ }
343
+
344
+ if $(docbook-xsl-dir)
345
+ {
346
+ .docbook-xsl-dir = [ path.make $(docbook-xsl-dir[1]) ] ;
347
+ }
348
+ if $(docbook-dtd-dir)
349
+ {
350
+ .docbook-dtd-dir = [ path.make $(docbook-dtd-dir[1]) ] ;
351
+ }
352
+
353
+ if --debug-configuration in [ modules.peek : ARGV ]
354
+ {
355
+ ECHO "notice: Boost.Book: searching XSL/DTD in" ;
356
+ ECHO "notice:" [ sequence.transform path.native : $(boostbook-dir) ] ;
357
+ }
358
+ local boostbook-xsl-dir ;
359
+ for local dir in $(boostbook-dir) {
360
+ boostbook-xsl-dir += [ path.glob $(dir) : xsl ] ;
361
+ }
362
+ local boostbook-dtd-dir ;
363
+ for local dir in $(boostbook-dir) {
364
+ boostbook-dtd-dir += [ path.glob $(dir) : dtd ] ;
365
+ }
366
+ .boostbook-xsl-dir = $(boostbook-xsl-dir[1]) ;
367
+ .boostbook-dtd-dir = $(boostbook-dtd-dir[1]) ;
368
+
369
+ check-docbook-xsl-dir ;
370
+ check-docbook-dtd-dir ;
371
+ check-boostbook-xsl-dir ;
372
+ check-boostbook-dtd-dir ;
373
+ }
374
+
375
+ rule xsl-dir
376
+ {
377
+ lock-config ;
378
+ return $(.boostbook-xsl-dir) ;
379
+ }
380
+
381
+ rule dtd-dir
382
+ {
383
+ lock-config ;
384
+ return $(.boostbook-dtd-dir) ;
385
+ }
386
+
387
+ rule docbook-xsl-dir
388
+ {
389
+ lock-config ;
390
+ return $(.docbook-xsl-dir) ;
391
+ }
392
+
393
+ rule docbook-dtd-dir
394
+ {
395
+ lock-config ;
396
+ return $(.docbook-dtd-dir) ;
397
+ }
398
+
399
+ rule dtdxml-to-boostbook ( target : source : properties * )
400
+ {
401
+ lock-config ;
402
+ xslt $(target) : $(source) "$(.boostbook-xsl-dir)/dtd/dtd2boostbook.xsl"
403
+ : $(properties) ;
404
+ }
405
+
406
+ rule boostbook-to-docbook ( target : source : properties * )
407
+ {
408
+ lock-config ;
409
+ local stylesheet = [ path.native $(.boostbook-xsl-dir)/docbook.xsl ] ;
410
+ xslt $(target) : $(source) $(stylesheet) : $(properties) ;
411
+ }
412
+
413
+ rule docbook-to-onehtml ( target : source : properties * )
414
+ {
415
+ lock-config ;
416
+ local stylesheet = [ path.native $(.boostbook-xsl-dir)/html-single.xsl ] ;
417
+ xslt $(target) : $(source) $(stylesheet) : $(properties) ;
418
+ }
419
+
420
+ rule docbook-to-htmldir ( target : source : properties * )
421
+ {
422
+ lock-config ;
423
+ local stylesheet = [ path.native $(.boostbook-xsl-dir)/html.xsl ] ;
424
+ xslt-dir $(target) : $(source) $(stylesheet) : $(properties) : html ;
425
+ }
426
+
427
+ rule docbook-to-xhtmldir ( target : source : properties * )
428
+ {
429
+ lock-config ;
430
+ local stylesheet = [ path.native $(.boostbook-xsl-dir)/xhtml.xsl ] ;
431
+ xslt-dir $(target) : $(source) $(stylesheet) : $(properties) : xhtml ;
432
+ }
433
+
434
+ rule docbook-to-htmlhelp ( target : source : properties * )
435
+ {
436
+ lock-config ;
437
+ local stylesheet = [ path.native $(.boostbook-xsl-dir)/html-help.xsl ] ;
438
+ xslt-dir $(target) : $(source) $(stylesheet) : $(properties) : htmlhelp ;
439
+ }
440
+
441
+ rule docbook-to-manpages ( target : source : properties * )
442
+ {
443
+ lock-config ;
444
+ local stylesheet = [ path.native $(.boostbook-xsl-dir)/manpages.xsl ] ;
445
+ xslt-dir $(target) : $(source) $(stylesheet) : $(properties) : man ;
446
+ }
447
+
448
+ rule docbook-to-fo ( target : source : properties * )
449
+ {
450
+ lock-config ;
451
+ local stylesheet = [ path.native $(.boostbook-xsl-dir)/fo.xsl ] ;
452
+ xslt $(target) : $(source) $(stylesheet) : $(properties) ;
453
+ }
454
+
455
+ rule format-catalog-path ( path )
456
+ {
457
+ local result = $(path) ;
458
+ if [ xsltproc.is-cygwin ]
459
+ {
460
+ if [ os.name ] = NT
461
+ {
462
+ drive = [ MATCH ^/(.):(.*)$ : $(path) ] ;
463
+ result = /cygdrive/$(drive[1])$(drive[2]) ;
464
+ }
465
+ }
466
+ else
467
+ {
468
+ if [ os.name ] = CYGWIN
469
+ {
470
+ local native-path = [ path.native $(path) ] ;
471
+ result = [ path.make $(native-path:W) ] ;
472
+ }
473
+ }
474
+ return [ regex.replace $(result) " " "%20" ] ;
475
+ }
476
+
477
+ rule generate-xml-catalog ( target : sources * : properties * )
478
+ {
479
+ print.output $(target) ;
480
+
481
+ # BoostBook DTD catalog entry
482
+ local boostbook-dtd-dir = [ boostbook.dtd-dir ] ;
483
+ if $(boostbook-dtd-dir)
484
+ {
485
+ boostbook-dtd-dir = [ format-catalog-path $(boostbook-dtd-dir) ] ;
486
+ }
487
+
488
+ print.text
489
+ "<?xml version=\"1.0\"?>"
490
+ "<!DOCTYPE catalog "
491
+ " PUBLIC \"-//OASIS/DTD Entity Resolution XML Catalog V1.0//EN\""
492
+ " \"http://www.oasis-open.org/committees/entity/release/1.0/catalog.dtd\">"
493
+ "<catalog xmlns=\"urn:oasis:names:tc:entity:xmlns:xml:catalog\">"
494
+ " <rewriteURI uriStartString=\"http://www.boost.org/tools/boostbook/dtd/\" rewritePrefix=\"file://$(boostbook-dtd-dir)/\"/>"
495
+ : true ;
496
+
497
+ local docbook-xsl-dir = [ boostbook.docbook-xsl-dir ] ;
498
+ if ! $(docbook-xsl-dir)
499
+ {
500
+ ECHO "BoostBook warning: no DocBook XSL directory specified." ;
501
+ ECHO " If you have the DocBook XSL stylesheets installed, please " ;
502
+ ECHO " set DOCBOOK_XSL_DIR to the stylesheet directory on either " ;
503
+ ECHO " the command line (via -sDOCBOOK_XSL_DIR=...) or in a " ;
504
+ ECHO " Boost.Jam configuration file. The DocBook XSL stylesheets " ;
505
+ ECHO " are available here: http://docbook.sourceforge.net/ " ;
506
+ ECHO " Stylesheets will be downloaded on-the-fly (very slow!) " ;
507
+ }
508
+ else
509
+ {
510
+ docbook-xsl-dir = [ format-catalog-path $(docbook-xsl-dir) ] ;
511
+ print.text " <rewriteURI uriStartString=\"http://docbook.sourceforge.net/release/xsl/current/\" rewritePrefix=\"file://$(docbook-xsl-dir)/\"/>" ;
512
+ }
513
+
514
+ local docbook-dtd-dir = [ boostbook.docbook-dtd-dir ] ;
515
+ if ! $(docbook-dtd-dir)
516
+ {
517
+ ECHO "BoostBook warning: no DocBook DTD directory specified." ;
518
+ ECHO " If you have the DocBook DTD installed, please set " ;
519
+ ECHO " DOCBOOK_DTD_DIR to the DTD directory on either " ;
520
+ ECHO " the command line (via -sDOCBOOK_DTD_DIR=...) or in a " ;
521
+ ECHO " Boost.Jam configuration file. The DocBook DTD is available " ;
522
+ ECHO " here: http://www.oasis-open.org/docbook/xml/4.2/index.shtml" ;
523
+ ECHO " The DTD will be downloaded on-the-fly (very slow!) " ;
524
+ }
525
+ else
526
+ {
527
+ docbook-dtd-dir = [ format-catalog-path $(docbook-dtd-dir) ] ;
528
+ print.text " <rewriteURI uriStartString=\"http://www.oasis-open.org/docbook/xml/4.2/\" rewritePrefix=\"file://$(docbook-dtd-dir)/\"/>" ;
529
+ }
530
+
531
+ print.text "</catalog>" ;
532
+ }
533
+
534
+ rule xml-catalog ( )
535
+ {
536
+ if ! $(.xml-catalog)
537
+ {
538
+ # The target is created as part of the root project. But ideally
539
+ # it would be created as part of the boostbook project. This is not
540
+ # current possible as such global projects don't inherit things like
541
+ # the build directory.
542
+
543
+ # Find the root project.
544
+ local root-project = [ project.current ] ;
545
+ root-project = [ $(root-project).project-module ] ;
546
+ while
547
+ [ project.attribute $(root-project) parent-module ] &&
548
+ [ project.attribute $(root-project) parent-module ] != user-config &&
549
+ [ project.attribute $(root-project) parent-module ] != project-config
550
+ {
551
+ root-project = [ project.attribute $(root-project) parent-module ] ;
552
+ }
553
+ .xml-catalog = [ new file-target boostbook_catalog
554
+ : XML
555
+ : [ project.target $(root-project) ]
556
+ : [ new action : boostbook.generate-xml-catalog ]
557
+ :
558
+ ] ;
559
+ .xml-catalog-file = [ $(.xml-catalog).path ] [ $(.xml-catalog).name ] ;
560
+ .xml-catalog-file = $(.xml-catalog-file:J=/) ;
561
+ }
562
+ return $(.xml-catalog) $(.xml-catalog-file) ;
563
+ }
564
+
565
+ class boostbook-generator : generator
566
+ {
567
+ import feature ;
568
+ import virtual-target ;
569
+ import generators ;
570
+ import boostbook ;
571
+
572
+
573
+ rule __init__ ( * : * )
574
+ {
575
+ generator.__init__ $(1) : $(2) : $(3) : $(4) : $(5) : $(6) : $(7) : $(8) : $(9) ;
576
+ }
577
+
578
+ rule run ( project name ? : property-set : sources * )
579
+ {
580
+ # Generate the catalog, but only once...
581
+ local global-catalog = [ boostbook.xml-catalog ] ;
582
+ local catalog = $(global-catalog[1]) ;
583
+ local catalog-file = $(global-catalog[2]) ;
584
+ local targets ;
585
+
586
+ # Add the catalog to the property set
587
+ property-set = [ $(property-set).add-raw <catalog>$(catalog-file) ] ;
588
+
589
+ local type = none ;
590
+ local manifest ;
591
+ local format = [ $(property-set).get <format> ] ;
592
+ switch $(format)
593
+ {
594
+ case html :
595
+ {
596
+ type = HTMLDIR ;
597
+ manifest = HTML.manifest ;
598
+ }
599
+ case xhtml :
600
+ {
601
+ type = XHTMLDIR ;
602
+ manifest = HTML.manifest ;
603
+ }
604
+ case htmlhelp :
605
+ {
606
+ type = HTMLHELP ;
607
+ manifest = HTML.manifest ;
608
+ }
609
+
610
+ case onehtml : type = HTML ;
611
+
612
+ case man :
613
+ {
614
+ type = MANPAGES ;
615
+ manifest = man.manifest ;
616
+ }
617
+
618
+ case docbook : type = DOCBOOK ;
619
+ case fo : type = FO ;
620
+ case pdf : type = PDF ;
621
+ case ps : type = PS ;
622
+ case tests : type = TESTS ;
623
+ }
624
+
625
+ if $(manifest)
626
+ {
627
+ # Create DOCBOOK file from BOOSTBOOK sources.
628
+ local base-target = [ generators.construct $(project)
629
+ : DOCBOOK : $(property-set) : $(sources) ] ;
630
+ base-target = $(base-target[2]) ;
631
+ $(base-target).depends $(catalog) ;
632
+
633
+ # Generate HTML/PDF/PS from DOCBOOK.
634
+ local target = [ generators.construct $(project) $(name)_$(manifest)
635
+ : $(type)
636
+ : [ $(property-set).add-raw
637
+ <xsl:param>manifest=$(name)_$(manifest) ]
638
+ : $(base-target) ] ;
639
+ local name = [ $(property-set).get <name> ] ;
640
+ name ?= $(format) ;
641
+ $(target[2]).set-path $(name) ;
642
+ $(target[2]).depends $(catalog) ;
643
+
644
+ targets += $(target[2]) ;
645
+ }
646
+ else {
647
+ local target = [ generators.construct $(project)
648
+ : $(type) : $(property-set) : $(sources) ] ;
649
+
650
+ if ! $(target)
651
+ {
652
+ errors.error "Cannot build documentation type '$(format)'" ;
653
+ }
654
+ else
655
+ {
656
+ $(target[2]).depends $(catalog) ;
657
+ targets += $(target[2]) ;
658
+ }
659
+ }
660
+
661
+ return $(targets) ;
662
+ }
663
+ }
664
+
665
+ generators.register [ new boostbook-generator boostbook.main : : BOOSTBOOK_MAIN ] ;
666
+
667
+ # Creates a boostbook target.
668
+ rule boostbook ( target-name : sources * : requirements * : default-build * )
669
+ {
670
+ local project = [ project.current ] ;
671
+
672
+ targets.main-target-alternative
673
+ [ new typed-target $(target-name) : $(project) : BOOSTBOOK_MAIN
674
+ : [ targets.main-target-sources $(sources) : $(target-name) ]
675
+ : [ targets.main-target-requirements $(requirements) : $(project) ]
676
+ : [ targets.main-target-default-build $(default-build) : $(project) ]
677
+ ] ;
678
+ }
679
+
680
+ #############################################################################
681
+ # Dependency scanners
682
+ #############################################################################
683
+ # XInclude scanner. Mostly stolen from c-scanner :)
684
+ # Note that this assumes an "xi" prefix for XIncludes. This isn't always the
685
+ # case for XML documents, but we'll assume it's true for anything we encounter.
686
+ class xinclude-scanner : scanner
687
+ {
688
+ import virtual-target ;
689
+ import path ;
690
+ import scanner ;
691
+
692
+ rule __init__ ( includes * )
693
+ {
694
+ scanner.__init__ ;
695
+ self.includes = $(includes) ;
696
+ }
697
+
698
+ rule pattern ( )
699
+ {
700
+ return "xi:include[ ]*href=\"([^\"]*)\"" ;
701
+ }
702
+
703
+ rule process ( target : matches * : binding )
704
+ {
705
+ local target_path = [ NORMALIZE_PATH $(binding:D) ] ;
706
+
707
+ NOCARE $(matches) ;
708
+ INCLUDES $(target) : $(matches) ;
709
+ SEARCH on $(matches) = $(target_path) $(self.includes:G=) ;
710
+
711
+ scanner.propagate $(__name__) : $(matches) : $(target) ;
712
+ }
713
+ }
714
+
715
+ scanner.register xinclude-scanner : xsl:path ;
716
+ type.set-scanner XML : xinclude-scanner ;
717
+
718
+ rule boostbook-to-tests ( target : source : properties * )
719
+ {
720
+ lock-config ;
721
+ local boost_root = [ modules.peek : BOOST_ROOT ] ;
722
+ local native-path =
723
+ [ path.native [ path.join $(.boostbook-xsl-dir) testing Jamfile ] ] ;
724
+ local stylesheet = $(native-path:S=.xsl) ;
725
+ xslt $(target) : $(source) $(stylesheet)
726
+ : $(properties) <xsl:param>boost.root=$(boost_root)
727
+ ;
728
+ }
729
+
730
+
mosesdecoder/jam-files/boost-build/tools/como-linux.jam ADDED
@@ -0,0 +1,103 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2004, 2005, 2006 Vladimir Prus
2
+ # Distributed under the Boost Software License, Version 1.0.
3
+ # (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
4
+
5
+ # The following #// line will be used by the regression test table generation
6
+ # program as the column heading for HTML tables. Must not include a version
7
+ # number.
8
+ #//<a href="http://www.comeaucomputing.com/">Comeau<br>C++</a>
9
+
10
+ import toolset ;
11
+ import feature ;
12
+ import toolset : flags ;
13
+ import common ;
14
+ import generators ;
15
+
16
+ import unix ;
17
+ import como ;
18
+
19
+ feature.extend-subfeature toolset como : platform : linux ;
20
+
21
+ toolset.inherit-generators como-linux
22
+ <toolset>como <toolset-como:platform>linux : unix ;
23
+ generators.override como-linux.prebuilt : builtin.lib-generator ;
24
+ generators.override como-linux.searched-lib-generator : searched-lib-generator ;
25
+ toolset.inherit-flags como-linux : unix ;
26
+ toolset.inherit-rules como-linux : gcc ;
27
+
28
+ generators.register-c-compiler como-linux.compile.c++ : CPP : OBJ
29
+ : <toolset>como <toolset-como:platform>linux ;
30
+ generators.register-c-compiler como-linux.compile.c : C : OBJ
31
+ : <toolset>como <toolset-como:platform>linux ;
32
+
33
+
34
+ rule init ( version ? : command * : options * )
35
+ {
36
+ local condition = [ common.check-init-parameters como-linux
37
+ : version $(version) ] ;
38
+
39
+ command = [ common.get-invocation-command como-linux : como
40
+ : $(command) ] ;
41
+
42
+ common.handle-options como-linux : $(condition) : $(command) : $(options) ;
43
+ }
44
+
45
+
46
+ flags como-linux C++FLAGS <exception-handling>off : --no_exceptions ;
47
+ flags como-linux C++FLAGS <exception-handling>on : --exceptions ;
48
+
49
+ flags como-linux CFLAGS <inlining>off : --no_inlining ;
50
+ flags como-linux CFLAGS <inlining>on <inlining>full : --inlining ;
51
+
52
+ flags como-linux CFLAGS <optimization>off : -O0 ;
53
+ flags como-linux CFLAGS <optimization>speed : -O3 ;
54
+ flags como-linux CFLAGS <optimization>space : -Os ;
55
+
56
+ flags como-linux CFLAGS <debug-symbols>on : -g ;
57
+ flags como-linux LINKFLAGS <debug-symbols>on : -g ;
58
+
59
+ flags como-linux FINDLIBS : m ;
60
+ flags como-linux FINDLIBS : rt ;
61
+
62
+ flags como-linux CFLAGS <cflags> ;
63
+ flags como-linux C++FLAGS <cxxflags> ;
64
+ flags como-linux DEFINES <define> ;
65
+ flags como-linux UNDEFS <undef> ;
66
+ flags como-linux HDRS <include> ;
67
+ flags como-linux STDHDRS <sysinclude> ;
68
+ flags como-linux LINKFLAGS <linkflags> ;
69
+ flags como-linux ARFLAGS <arflags> ;
70
+
71
+ flags como-linux.link LIBRARIES <library-file> ;
72
+ flags como-linux.link LINKPATH <library-path> ;
73
+ flags como-linux.link FINDLIBS-ST <find-static-library> ;
74
+ flags como-linux.link FINDLIBS-SA <find-shared-library> ;
75
+
76
+ flags como-linux.link RPATH <dll-path> ;
77
+ flags como-linux.link RPATH_LINK <xdll-path> ;
78
+
79
+
80
+ actions link bind LIBRARIES
81
+ {
82
+ $(CONFIG_COMMAND) $(LINKFLAGS) -o "$(<[1])" "$(>)" -L"$(LINKPATH)" -Wl,-R$(SPACE)-Wl,"$(RPATH)" -Wl,-rpath-link$(SPACE)-Wl,"$(RPATH_LINK)" "$(LIBRARIES)" "$(LIBRARIES)" -l$(FINDLIBS-SA) -l$(FINDLIBS-ST) 2>&1
83
+ }
84
+
85
+ actions link.dll bind LIBRARIES
86
+ {
87
+ $(CONFIG_COMMAND) $(LINKFLAGS) -shared -o "$(<[1])" "$(>)" -L"$(LINKPATH)" -Wl,-R$(SPACE)-Wl,"$(RPATH)" -Wl,-rpath-link$(SPACE)-Wl,"$(RPATH_LINK)" "$(LIBRARIES)" "$(LIBRARIES)" -l$(FINDLIBS-SA) -l$(FINDLIBS-ST) 2>&1
88
+ }
89
+
90
+ actions compile.c
91
+ {
92
+ $(CONFIG_COMMAND) -c --c99 --long_long -U$(UNDEFS) -D$(DEFINES) $(CFLAGS) -I"$(HDRS)" -I"$(STDHDRS)" -o "$(<)" "$(>)" 2>&1
93
+ }
94
+
95
+ actions compile.c++
96
+ {
97
+ $(CONFIG_COMMAND) -tused -c --long_long -U$(UNDEFS) -D$(DEFINES) $(CFLAGS) $(C++FLAGS) -I"$(HDRS)" -I"$(STDHDRS)" -o "$(<)" "$(>)" 2>&1
98
+ }
99
+
100
+ actions archive
101
+ {
102
+ ar rcu $(<) $(>)
103
+ }
mosesdecoder/jam-files/boost-build/tools/gfortran.jam ADDED
@@ -0,0 +1,39 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright (C) 2004 Toon Knapen
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 toolset : flags ;
8
+ import feature ;
9
+ import fortran ;
10
+
11
+ rule init ( version ? : command * : options * )
12
+ {
13
+ }
14
+
15
+ # Declare flags and action for compilation
16
+ flags gfortran OPTIONS <fflags> ;
17
+
18
+ flags gfortran OPTIONS <optimization>off : -O0 ;
19
+ flags gfortran OPTIONS <optimization>speed : -O3 ;
20
+ flags gfortran OPTIONS <optimization>space : -Os ;
21
+
22
+ flags gfortran OPTIONS <debug-symbols>on : -g ;
23
+ flags gfortran OPTIONS <profiling>on : -pg ;
24
+
25
+ flags gfortran OPTIONS <link>shared/<main-target-type>LIB : -fPIC ;
26
+
27
+ flags gfortran DEFINES <define> ;
28
+ flags gfortran INCLUDES <include> ;
29
+
30
+ rule compile.fortran
31
+ {
32
+ }
33
+
34
+ actions compile.fortran
35
+ {
36
+ gcc -Wall $(OPTIONS) -D$(DEFINES) -I$(INCLUDES) -c -o "$(<)" "$(>)"
37
+ }
38
+
39
+ generators.register-fortran-compiler gfortran.compile.fortran : FORTRAN FORTRAN90 : OBJ ;
mosesdecoder/jam-files/boost-build/tools/message.jam ADDED
@@ -0,0 +1,55 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2008 Vladimir Prus
2
+ # Distributed under the Boost Software License, Version 1.0.
3
+ # (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
4
+
5
+ # Defines main target type 'message', that prints a message when built for the
6
+ # first time.
7
+
8
+ import project ;
9
+ import "class" : new ;
10
+ import targets ;
11
+ import property-set ;
12
+
13
+ class message-target-class : basic-target
14
+ {
15
+ rule __init__ ( name-and-dir : project : * )
16
+ {
17
+ basic-target.__init__ $(name-and-dir) : $(project) ;
18
+ self.3 = $(3) ;
19
+ self.4 = $(4) ;
20
+ self.5 = $(5) ;
21
+ self.6 = $(6) ;
22
+ self.7 = $(7) ;
23
+ self.8 = $(8) ;
24
+ self.9 = $(9) ;
25
+ self.built = ;
26
+ }
27
+
28
+ rule construct ( name : source-targets * : property-set )
29
+ {
30
+ if ! $(self.built)
31
+ {
32
+ for i in 3 4 5 6 7 8 9
33
+ {
34
+ if $(self.$(i))
35
+ {
36
+ ECHO $(self.$(i)) ;
37
+ }
38
+ }
39
+ self.built = 1 ;
40
+ }
41
+
42
+ return [ property-set.empty ] ;
43
+ }
44
+ }
45
+
46
+
47
+ rule message ( name : * )
48
+ {
49
+ local project = [ project.current ] ;
50
+
51
+ targets.main-target-alternative
52
+ [ new message-target-class $(name) : $(project)
53
+ : $(2) : $(3) : $(4) : $(5) : $(6) : $(7) ] ;
54
+ }
55
+ IMPORT $(__name__) : message : : message ;
mosesdecoder/jam-files/boost-build/tools/pgi.jam ADDED
@@ -0,0 +1,147 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright Noel Belcourt 2007.
2
+ # Distributed under the Boost Software License, Version 1.0.
3
+ # (See accompanying file LICENSE_1_0.txt or copy at
4
+ # http://www.boost.org/LICENSE_1_0.txt)
5
+
6
+ import property ;
7
+ import generators ;
8
+ import os ;
9
+ import toolset : flags ;
10
+ import feature ;
11
+ import fortran ;
12
+ import type ;
13
+ import common ;
14
+ import gcc ;
15
+
16
+ feature.extend toolset : pgi ;
17
+ toolset.inherit pgi : unix ;
18
+ generators.override pgi.prebuilt : builtin.lib-generator ;
19
+ generators.override pgi.searched-lib-generator : searched-lib-generator ;
20
+
21
+ # Documentation and toolchain description located
22
+ # http://www.pgroup.com/resources/docs.htm
23
+
24
+ rule init ( version ? : command * : options * )
25
+ {
26
+ local condition = [ common.check-init-parameters pgi : version $(version) ] ;
27
+
28
+ local l_command = [ common.get-invocation-command pgi : pgCC : $(command) ] ;
29
+
30
+ common.handle-options pgi : $(condition) : $(l_command) : $(options) ;
31
+
32
+ command_c = $(command_c[1--2]) $(l_command[-1]:B=cc) ;
33
+
34
+ toolset.flags pgi CONFIG_C_COMMAND $(condition) : $(command_c) ;
35
+
36
+ flags pgi.compile DEFINES $(condition) :
37
+ [ feature.get-values <define> : $(options) ] : unchecked ;
38
+
39
+ # IOV_MAX support
40
+ flags pgi.compile DEFINES $(condition) : __need_IOV_MAX : unchecked ;
41
+
42
+ # set link flags
43
+ flags pgi.link FINDLIBS-ST : [
44
+ feature.get-values <find-static-library> : $(options) ] : unchecked ;
45
+
46
+ # always link lib rt to resolve clock_gettime()
47
+ flags pgi.link FINDLIBS-SA : rt [
48
+ feature.get-values <find-shared-library> : $(options) ] : unchecked ;
49
+
50
+ gcc.init-link-flags pgi gnu $(condition) ;
51
+ }
52
+
53
+ # Declare generators
54
+ generators.register-c-compiler pgi.compile.c : C : OBJ : <toolset>pgi ;
55
+ generators.register-c-compiler pgi.compile.c++ : CPP : OBJ : <toolset>pgi ;
56
+ generators.register-fortran-compiler pgi.compile.fortran : FORTRAN : OBJ : <toolset>pgi ;
57
+
58
+ # Declare flags and actions for compilation
59
+ flags pgi.compile OPTIONS : -Kieee ;
60
+ flags pgi.compile OPTIONS <link>shared : -fpic -fPIC ;
61
+ flags pgi.compile OPTIONS <debug-symbols>on : -gopt ;
62
+ flags pgi.compile OPTIONS <profiling>on : -xprofile=tcov ;
63
+ flags pgi.compile OPTIONS <optimization>speed : -fast -Mx,8,0x10000000 ;
64
+ flags pgi.compile OPTIONS <optimization>space : -xO2 -xspace ;
65
+ # flags pgi.compile OPTIONS <threading>multi : -mt ;
66
+
67
+ flags pgi.compile OPTIONS <warnings>off : -Minform=severe ;
68
+ flags pgi.compile OPTIONS <warnings>on : -Minform=warn ;
69
+
70
+ flags pgi.compile.c++ OPTIONS <inlining>off : -INLINE:none ;
71
+
72
+ flags pgi.compile OPTIONS <cflags> ;
73
+ flags pgi.compile.c++ OPTIONS <cxxflags> ;
74
+ flags pgi.compile DEFINES <define> ;
75
+ flags pgi.compile INCLUDES <include> ;
76
+
77
+ flags pgi.compile.fortran OPTIONS <fflags> ;
78
+
79
+ actions compile.c
80
+ {
81
+ "$(CONFIG_C_COMMAND)" $(OPTIONS) -D$(DEFINES) -I"$(INCLUDES)" -c -o "$(<)" "$(>)"
82
+ }
83
+
84
+ actions compile.c++
85
+ {
86
+ "$(CONFIG_COMMAND)" $(OPTIONS) -D$(DEFINES) -I"$(INCLUDES)" -c -o "$(<)" "$(>)"
87
+ }
88
+
89
+ actions compile.fortran
90
+ {
91
+ "$(CONFIG_F_COMMAND)" $(OPTIONS) -D$(DEFINES) -I"$(INCLUDES)" -c -o "$(<)" "$(>)"
92
+ }
93
+
94
+ # Declare flags and actions for linking
95
+ flags pgi.link OPTIONS <debug-symbols>on : -gopt ;
96
+ # Strip the binary when no debugging is needed
97
+ flags pgi.link OPTIONS <debug-symbols>off : -s ;
98
+ flags pgi.link OPTIONS <profiling>on : -xprofile=tcov ;
99
+ flags pgi.link OPTIONS <linkflags> ;
100
+ flags pgi.link OPTIONS <link>shared : -fpic -fPIC ;
101
+ flags pgi.link LINKPATH <library-path> ;
102
+ flags pgi.link FINDLIBS-ST <find-static-library> ;
103
+ flags pgi.link FINDLIBS-SA <find-shared-library> ;
104
+ flags pgi.link FINDLIBS-SA <threading>multi : pthread rt ;
105
+ flags pgi.link LIBRARIES <library-file> ;
106
+ flags pgi.link LINK-RUNTIME <runtime-link>static : static ;
107
+ flags pgi.link LINK-RUNTIME <runtime-link>shared : dynamic ;
108
+ flags pgi.link RPATH <dll-path> ;
109
+
110
+ # On gcc, there are separate options for dll path at runtime and
111
+ # link time. On Solaris, there's only one: -R, so we have to use
112
+ # it, even though it's bad idea.
113
+ flags pgi.link RPATH <xdll-path> ;
114
+
115
+ rule link ( targets * : sources * : properties * )
116
+ {
117
+ SPACE on $(targets) = " " ;
118
+ }
119
+
120
+ # reddish can only link statically and, somehow, the presence of -Bdynamic on the link line
121
+ # marks the executable as a dynamically linked exec even though no dynamic libraries are supplied.
122
+ # Yod on redstorm refuses to load an executable that is dynamically linked.
123
+ # removing the dynamic link options should get us where we need to be on redstorm.
124
+ # "$(CONFIG_COMMAND)" $(OPTIONS) -L"$(LINKPATH)" -R"$(RPATH)" -o "$(<)" "$(>)" "$(LIBRARIES)" -Bdynamic -l$(FINDLIBS-SA) -Bstatic -l$(FINDLIBS-ST) -B$(LINK-RUNTIME)
125
+ actions link bind LIBRARIES
126
+ {
127
+ "$(CONFIG_COMMAND)" $(OPTIONS) -L"$(LINKPATH)" -R"$(RPATH)" -o "$(<)" "$(>)" "$(LIBRARIES)" -Bstatic -l$(FINDLIBS-ST) -Bdynamic -l$(FINDLIBS-SA) -B$(LINK-RUNTIME)
128
+ }
129
+
130
+ # Slight mods for dlls
131
+ rule link.dll ( targets * : sources * : properties * )
132
+ {
133
+ SPACE on $(targets) = " " ;
134
+ }
135
+
136
+ # "$(CONFIG_COMMAND)" $(OPTIONS) -L"$(LINKPATH)" -R"$(RPATH)" -o "$(<)" -h$(<[1]:D=) -G "$(>)" "$(LIBRARIES)" -Bdynamic -l$(FINDLIBS-SA) -Bstatic -l$(FINDLIBS-ST) -B$(LINK-RUNTIME)
137
+
138
+ actions link.dll bind LIBRARIES
139
+ {
140
+ "$(CONFIG_COMMAND)" $(OPTIONS) -shared -L"$(LINKPATH)" -R"$(RPATH)" -o "$(<)" "$(>)" -Wl,-h -Wl,$(<[1]:D=) "$(LIBRARIES)" -Bdynamic -l$(FINDLIBS-SA) -Bstatic -l$(FINDLIBS-ST) -B$(LINK-RUNTIME)
141
+ }
142
+
143
+ actions updated together piecemeal pgi.archive
144
+ {
145
+ ar -rc$(ARFLAGS:E=) "$(<)" "$(>)"
146
+ }
147
+
mosesdecoder/jam-files/boost-build/tools/quickbook-config.jam ADDED
@@ -0,0 +1,44 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #~ Copyright 2005 Rene Rivera.
2
+ #~ Distributed under the Boost Software License, Version 1.0.
3
+ #~ (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
4
+
5
+ # Automatic configuration for BoostBook tools. To use, just import this module.
6
+
7
+ import os ;
8
+ import toolset : using ;
9
+
10
+ if [ os.name ] = NT
11
+ {
12
+ local boost-dir = ;
13
+ for local R in snapshot cvs 1.33.0
14
+ {
15
+ boost-dir += [ W32_GETREG
16
+ "HKEY_LOCAL_MACHINE\\SOFTWARE\\Boost.org\\$(R)"
17
+ : "InstallRoot" ] ;
18
+ }
19
+ local quickbook-path = [ GLOB "$(boost-dir)\\bin" "\\Boost\\bin" : quickbook.exe ] ;
20
+ quickbook-path = $(quickbook-path[1]) ;
21
+
22
+ if $(quickbook-path)
23
+ {
24
+ if --debug-configuration in [ modules.peek : ARGV ]
25
+ {
26
+ ECHO "notice:" using quickbook ":" $(quickbook-path) ;
27
+ }
28
+ using quickbook : $(quickbook-path) ;
29
+ }
30
+ }
31
+ else
32
+ {
33
+ local quickbook-path = [ GLOB "/usr/local/bin" "/usr/bin" "/opt/bin" : quickbook ] ;
34
+ quickbook-path = $(quickbook-path[1]) ;
35
+
36
+ if $(quickbook-path)
37
+ {
38
+ if --debug-configuration in [ modules.peek : ARGV ]
39
+ {
40
+ ECHO "notice:" using quickbook ":" $(quickbook-path) ;
41
+ }
42
+ using quickbook : $(quickbook-path) ;
43
+ }
44
+ }
mosesdecoder/jam-files/boost-build/tools/quickbook.jam ADDED
@@ -0,0 +1,361 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #
2
+ # Copyright (c) 2005 Jo�o Abecasis
3
+ # Copyright (c) 2005 Vladimir Prus
4
+ # Copyright (c) 2006 Rene Rivera
5
+ #
6
+ # Distributed under the Boost Software License, Version 1.0. (See
7
+ # accompanying file LICENSE_1_0.txt or copy at
8
+ # http://www.boost.org/LICENSE_1_0.txt)
9
+ #
10
+
11
+ # This toolset defines a generator to translate QuickBook to BoostBook. It can
12
+ # be used to generate nice (!) user documentation in different formats
13
+ # (pdf/html/...), from a single text file with simple markup.
14
+ #
15
+ # The toolset defines the QUICKBOOK type (file extension 'qbk') and
16
+ # a QUICKBOOK to XML (BOOSTBOOK) generator.
17
+ #
18
+ #
19
+ # ===========================================================================
20
+ # Q & A
21
+ # ===========================================================================
22
+ #
23
+ # If you don't know what this is all about, some Q & A will hopefully get you
24
+ # up to speed with QuickBook and this toolset.
25
+ #
26
+ #
27
+ # What is QuickBook ?
28
+ #
29
+ # QuickBook is a WikiWiki style documentation tool geared towards C++
30
+ # documentation using simple rules and markup for simple formatting tasks.
31
+ # QuickBook extends the WikiWiki concept. Like the WikiWiki, QuickBook
32
+ # documents are simple text files. A single QuickBook document can
33
+ # generate a fully linked set of nice HTML and PostScript/PDF documents
34
+ # complete with images and syntax-colorized source code.
35
+ #
36
+ #
37
+ # Where can I get QuickBook ?
38
+ #
39
+ # Quickbook can be found in Boost's repository, under the tools/quickbook
40
+ # directory it was added there on Jan 2005, some time after the release of
41
+ # Boost v1.32.0 and has been an integral part of the Boost distribution
42
+ # since v1.33.
43
+ #
44
+ # Here's a link to the SVN repository:
45
+ # https://svn.boost.org/svn/boost/trunk/tools/quickbook
46
+ #
47
+ # And to QuickBook's QuickBook-generated docs:
48
+ # http://www.boost.org/doc/libs/release/tools/quickbook/index.html
49
+ #
50
+ #
51
+ # How do I use QuickBook and this toolset in my projects ?
52
+ #
53
+ # The minimal example is:
54
+ #
55
+ # using boostbook ;
56
+ # import quickbook ;
57
+ #
58
+ # boostbook my_docs : my_docs_source.qbk ;
59
+ #
60
+ # where my_docs is a target name and my_docs_source.qbk is a QuickBook
61
+ # file. The documentation format to be generated is determined by the
62
+ # boostbook toolset. By default html documentation should be generated,
63
+ # but you should check BoostBook's docs to be sure.
64
+ #
65
+ #
66
+ # What do I need ?
67
+ #
68
+ # You should start by setting up the BoostBook toolset. Please refer to
69
+ # boostbook.jam and the BoostBook documentation for information on how to
70
+ # do this.
71
+ #
72
+ # A QuickBook executable is also needed. The toolset will generate this
73
+ # executable if it can find the QuickBook sources. The following
74
+ # directories will be searched:
75
+ #
76
+ # BOOST_ROOT/tools/quickbook/
77
+ # BOOST_BUILD_PATH/../../quickbook/
78
+ #
79
+ # (BOOST_ROOT and BOOST_BUILD_PATH are environment variables)
80
+ #
81
+ # If QuickBook sources are not found the toolset will then try to use
82
+ # the shell command 'quickbook'.
83
+ #
84
+ #
85
+ # How do I provide a custom QuickBook executable ?
86
+ #
87
+ # You may put the following in your user-config.jam or site-config.jam:
88
+ #
89
+ # using quickbook : /path/to/quickbook ;
90
+ #
91
+ # or, if 'quickbook' can be found in your PATH,
92
+ #
93
+ # using quickbook : quickbook ;
94
+ #
95
+ #
96
+ # For convenience three alternatives are tried to get a QuickBook executable:
97
+ #
98
+ # 1. If the user points us to the a QuickBook executable, that is used.
99
+ #
100
+ # 2. Otherwise, we search for the QuickBook sources and compile QuickBook
101
+ # using the default toolset.
102
+ #
103
+ # 3. As a last resort, we rely on the shell for finding 'quickbook'.
104
+ #
105
+
106
+ import boostbook ;
107
+ import "class" : new ;
108
+ import feature ;
109
+ import generators ;
110
+ import toolset ;
111
+ import type ;
112
+ import scanner ;
113
+ import project ;
114
+ import targets ;
115
+ import build-system ;
116
+ import path ;
117
+ import common ;
118
+ import errors ;
119
+
120
+ # The one and only QUICKBOOK type!
121
+ type.register QUICKBOOK : qbk ;
122
+
123
+ # <quickbook-binary> shell command to run QuickBook
124
+ # <quickbook-binary-dependencies> targets to build QuickBook from sources.
125
+ feature.feature <quickbook-binary> : : free ;
126
+ feature.feature <quickbook-binary-dependencies> : : free dependency ;
127
+ feature.feature <quickbook-define> : : free ;
128
+ feature.feature <quickbook-indent> : : free ;
129
+ feature.feature <quickbook-line-width> : : free ;
130
+
131
+
132
+ # quickbook-binary-generator handles generation of the QuickBook executable, by
133
+ # marking it as a dependency for QuickBook docs.
134
+ #
135
+ # If the user supplied the QuickBook command that will be used.
136
+ #
137
+ # Otherwise we search some sensible places for the QuickBook sources and compile
138
+ # from scratch using the default toolset.
139
+ #
140
+ # As a last resort we rely on the shell to find 'quickbook'.
141
+ #
142
+ class quickbook-binary-generator : generator
143
+ {
144
+ import modules path targets quickbook ;
145
+
146
+ rule run ( project name ? : property-set : sources * : multiple ? )
147
+ {
148
+ quickbook.freeze-config ;
149
+ # QuickBook invocation command and dependencies.
150
+ local quickbook-binary = [ modules.peek quickbook : .quickbook-binary ] ;
151
+ local quickbook-binary-dependencies ;
152
+
153
+ if ! $(quickbook-binary)
154
+ {
155
+ # If the QuickBook source directory was found, mark its main target
156
+ # as a dependency for the current project. Otherwise, try to find
157
+ # 'quickbook' in user's PATH
158
+ local quickbook-dir = [ modules.peek quickbook : .quickbook-dir ] ;
159
+ if $(quickbook-dir)
160
+ {
161
+ # Get the main-target in QuickBook directory.
162
+ local quickbook-main-target = [ targets.resolve-reference $(quickbook-dir) : $(project) ] ;
163
+
164
+ # The first element are actual targets, the second are
165
+ # properties found in target-id. We do not care about these
166
+ # since we have passed the id ourselves.
167
+ quickbook-main-target =
168
+ [ $(quickbook-main-target[1]).main-target quickbook ] ;
169
+
170
+ quickbook-binary-dependencies =
171
+ [ $(quickbook-main-target).generate [ $(property-set).propagated ] ] ;
172
+
173
+ # Ignore usage-requirements returned as first element.
174
+ quickbook-binary-dependencies = $(quickbook-binary-dependencies[2-]) ;
175
+
176
+ # Some toolsets generate extra targets (e.g. RSP). We must mark
177
+ # all targets as dependencies for the project, but we will only
178
+ # use the EXE target for quickbook-to-boostbook translation.
179
+ for local target in $(quickbook-binary-dependencies)
180
+ {
181
+ if [ $(target).type ] = EXE
182
+ {
183
+ quickbook-binary =
184
+ [ path.native
185
+ [ path.join
186
+ [ $(target).path ]
187
+ [ $(target).name ]
188
+ ]
189
+ ] ;
190
+ }
191
+ }
192
+ }
193
+ }
194
+
195
+ # Add $(quickbook-binary-dependencies) as a dependency of the current
196
+ # project and set it as the <quickbook-binary> feature for the
197
+ # quickbook-to-boostbook rule, below.
198
+ property-set = [ $(property-set).add-raw
199
+ <dependency>$(quickbook-binary-dependencies)
200
+ <quickbook-binary>$(quickbook-binary)
201
+ <quickbook-binary-dependencies>$(quickbook-binary-dependencies)
202
+ ] ;
203
+
204
+ return [ generator.run $(project) $(name) : $(property-set) : $(sources) : $(multiple) ] ;
205
+ }
206
+ }
207
+
208
+
209
+ # Define a scanner for tracking QBK include dependencies.
210
+ #
211
+ class qbk-scanner : common-scanner
212
+ {
213
+ rule pattern ( )
214
+ {
215
+ return "\\[[ ]*include[ ]+([^]]+)\\]"
216
+ "\\[[ ]*include:[a-zA-Z0-9_]+[ ]+([^]]+)\\]"
217
+ "\\[[ ]*import[ ]+([^]]+)\\]" ;
218
+ }
219
+ }
220
+
221
+
222
+ scanner.register qbk-scanner : include ;
223
+
224
+ type.set-scanner QUICKBOOK : qbk-scanner ;
225
+
226
+
227
+ # Initialization of toolset.
228
+ #
229
+ # Parameters:
230
+ # command ? -> path to QuickBook executable.
231
+ #
232
+ # When command is not supplied toolset will search for QuickBook directory and
233
+ # compile the executable from source. If that fails we still search the path for
234
+ # 'quickbook'.
235
+ #
236
+ rule init (
237
+ command ? # path to the QuickBook executable.
238
+ )
239
+ {
240
+ if $(command)
241
+ {
242
+ if $(.config-frozen)
243
+ {
244
+ errors.user-error "quickbook: configuration cannot be changed after it has been used." ;
245
+ }
246
+ .command = $(command) ;
247
+ }
248
+ }
249
+
250
+ rule freeze-config ( )
251
+ {
252
+ if ! $(.config-frozen)
253
+ {
254
+ .config-frozen = true ;
255
+
256
+ # QuickBook invocation command and dependencies.
257
+
258
+ .quickbook-binary = $(.command) ;
259
+
260
+ if $(.quickbook-binary)
261
+ {
262
+ # Use user-supplied command.
263
+ .quickbook-binary = [ common.get-invocation-command quickbook : quickbook : $(.quickbook-binary) ] ;
264
+ }
265
+ else
266
+ {
267
+ # Search for QuickBook sources in sensible places, like
268
+ # $(BOOST_ROOT)/tools/quickbook
269
+ # $(BOOST_BUILD_PATH)/../../quickbook
270
+
271
+ # And build quickbook executable from sources.
272
+
273
+ local boost-root = [ modules.peek : BOOST_ROOT ] ;
274
+ local boost-build-path = [ build-system.location ] ;
275
+
276
+ if $(boost-root)
277
+ {
278
+ .quickbook-dir += [ path.join $(boost-root) tools ] ;
279
+ }
280
+
281
+ if $(boost-build-path)
282
+ {
283
+ .quickbook-dir += $(boost-build-path)/../.. ;
284
+ }
285
+
286
+ .quickbook-dir = [ path.glob $(.quickbook-dir) : quickbook ] ;
287
+
288
+ # If the QuickBook source directory was found, mark its main target
289
+ # as a dependency for the current project. Otherwise, try to find
290
+ # 'quickbook' in user's PATH
291
+ if $(.quickbook-dir)
292
+ {
293
+ .quickbook-dir = [ path.make $(.quickbook-dir[1]) ] ;
294
+ }
295
+ else
296
+ {
297
+ ECHO "QuickBook warning: The path to the quickbook executable was" ;
298
+ ECHO " not provided. Additionally, couldn't find QuickBook" ;
299
+ ECHO " sources searching in" ;
300
+ ECHO " * BOOST_ROOT/tools/quickbook" ;
301
+ ECHO " * BOOST_BUILD_PATH/../../quickbook" ;
302
+ ECHO " Will now try to find a precompiled executable by searching" ;
303
+ ECHO " the PATH for 'quickbook'." ;
304
+ ECHO " To disable this warning in the future, or to completely" ;
305
+ ECHO " avoid compilation of quickbook, you can explicitly set the" ;
306
+ ECHO " path to a quickbook executable command in user-config.jam" ;
307
+ ECHO " or site-config.jam with the call" ;
308
+ ECHO " using quickbook : /path/to/quickbook ;" ;
309
+
310
+ # As a last resort, search for 'quickbook' command in path. Note
311
+ # that even if the 'quickbook' command is not found,
312
+ # get-invocation-command will still return 'quickbook' and might
313
+ # generate an error while generating the virtual-target.
314
+
315
+ .quickbook-binary = [ common.get-invocation-command quickbook : quickbook ] ;
316
+ }
317
+ }
318
+ }
319
+ }
320
+
321
+
322
+ generators.register [ new quickbook-binary-generator quickbook.quickbook-to-boostbook : QUICKBOOK : XML ] ;
323
+
324
+
325
+ # <quickbook-binary> shell command to run QuickBook
326
+ # <quickbook-binary-dependencies> targets to build QuickBook from sources.
327
+ toolset.flags quickbook.quickbook-to-boostbook QB-COMMAND <quickbook-binary> ;
328
+ toolset.flags quickbook.quickbook-to-boostbook QB-DEPENDENCIES <quickbook-binary-dependencies> ;
329
+ toolset.flags quickbook.quickbook-to-boostbook INCLUDES <include> ;
330
+ toolset.flags quickbook.quickbook-to-boostbook QB-DEFINES <quickbook-define> ;
331
+ toolset.flags quickbook.quickbook-to-boostbook QB-INDENT <quickbook-indent> ;
332
+ toolset.flags quickbook.quickbook-to-boostbook QB-LINE-WIDTH <quickbook-line-width> ;
333
+
334
+
335
+ rule quickbook-to-boostbook ( target : source : properties * )
336
+ {
337
+ # Signal dependency of quickbook sources on <quickbook-binary-dependencies>
338
+ # upon invocation of quickbook-to-boostbook.
339
+ DEPENDS $(target) : [ on $(target) return $(QB-DEPENDENCIES) ] ;
340
+ }
341
+
342
+
343
+ actions quickbook-to-boostbook
344
+ {
345
+ "$(QB-COMMAND)" -I"$(INCLUDES)" -D"$(QB-DEFINES)" --indent="$(QB-INDENT)" --linewidth="$(QB-LINE-WIDTH)" --output-file="$(1)" "$(2)"
346
+ }
347
+
348
+
349
+ # Declare a main target to convert a quickbook source into a boostbook XML file.
350
+ #
351
+ rule to-boostbook ( target-name : sources * : requirements * : default-build * )
352
+ {
353
+ local project = [ project.current ] ;
354
+
355
+ targets.main-target-alternative
356
+ [ new typed-target $(target-name) : $(project) : XML
357
+ : [ targets.main-target-sources $(sources) : $(target-name) ]
358
+ : [ targets.main-target-requirements $(requirements) : $(project) ]
359
+ : [ targets.main-target-default-build $(default-build) : $(project) ]
360
+ ] ;
361
+ }
mosesdecoder/jam-files/boost-build/tools/stage.jam ADDED
@@ -0,0 +1,524 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+ # This module defines the 'install' rule, used to copy a set of targets to a
8
+ # single location.
9
+
10
+ import targets ;
11
+ import "class" : new ;
12
+ import errors ;
13
+ import type ;
14
+ import generators ;
15
+ import feature ;
16
+ import project ;
17
+ import virtual-target ;
18
+ import path ;
19
+ import types/register ;
20
+
21
+
22
+ feature.feature <install-dependencies> : off on : incidental ;
23
+ feature.feature <install-type> : : free incidental ;
24
+ feature.feature <install-source-root> : : free path ;
25
+ feature.feature <so-version> : : free incidental ;
26
+
27
+ # If 'on', version symlinks for shared libraries will not be created. Affects
28
+ # Unix builds only.
29
+ feature.feature <install-no-version-symlinks> : on : optional incidental ;
30
+
31
+
32
+ class install-target-class : basic-target
33
+ {
34
+ import feature ;
35
+ import project ;
36
+ import type ;
37
+ import errors ;
38
+ import generators ;
39
+ import path ;
40
+ import stage ;
41
+ import "class" : new ;
42
+ import property ;
43
+ import property-set ;
44
+
45
+ rule __init__ ( name-and-dir : project : sources * : requirements * : default-build * )
46
+ {
47
+ basic-target.__init__ $(name-and-dir) : $(project) : $(sources) :
48
+ $(requirements) : $(default-build) ;
49
+ }
50
+
51
+ # If <location> is not set, sets it based on the project data.
52
+ #
53
+ rule update-location ( property-set )
54
+ {
55
+ local loc = [ $(property-set).get <location> ] ;
56
+ if ! $(loc)
57
+ {
58
+ loc = [ path.root $(self.name) [ $(self.project).get location ] ] ;
59
+ property-set = [ $(property-set).add-raw $(loc:G=<location>) ] ;
60
+ }
61
+
62
+ return $(property-set) ;
63
+ }
64
+
65
+ # Takes a target that is installed and a property set which is used when
66
+ # installing.
67
+ #
68
+ rule adjust-properties ( target : build-property-set )
69
+ {
70
+ local ps-raw ;
71
+ local a = [ $(target).action ] ;
72
+ if $(a)
73
+ {
74
+ local ps = [ $(a).properties ] ;
75
+ ps-raw = [ $(ps).raw ] ;
76
+
77
+ # Unless <hardcode-dll-paths>true is in properties, which can happen
78
+ # only if the user has explicitly requested it, nuke all <dll-path>
79
+ # properties.
80
+ if [ $(build-property-set).get <hardcode-dll-paths> ] != true
81
+ {
82
+ ps-raw = [ property.change $(ps-raw) : <dll-path> ] ;
83
+ }
84
+
85
+ # If any <dll-path> properties were specified for installing, add
86
+ # them.
87
+ local l = [ $(build-property-set).get <dll-path> ] ;
88
+ ps-raw += $(l:G=<dll-path>) ;
89
+
90
+ # Also copy <linkflags> feature from current build set, to be used
91
+ # for relinking.
92
+ local l = [ $(build-property-set).get <linkflags> ] ;
93
+ ps-raw += $(l:G=<linkflags>) ;
94
+
95
+ # Remove the <tag> feature on original targets.
96
+ ps-raw = [ property.change $(ps-raw) : <tag> ] ;
97
+
98
+ # And <location>. If stage target has another stage target in
99
+ # sources, then we shall get virtual targets with the <location>
100
+ # property set.
101
+ ps-raw = [ property.change $(ps-raw) : <location> ] ;
102
+ }
103
+
104
+ local d = [ $(build-property-set).get <dependency> ] ;
105
+ ps-raw += $(d:G=<dependency>) ;
106
+
107
+ local d = [ $(build-property-set).get <location> ] ;
108
+ ps-raw += $(d:G=<location>) ;
109
+
110
+ local ns = [ $(build-property-set).get <install-no-version-symlinks> ] ;
111
+ ps-raw += $(ns:G=<install-no-version-symlinks>) ;
112
+
113
+ local d = [ $(build-property-set).get <install-source-root> ] ;
114
+ # Make the path absolute: we shall use it to compute relative paths and
115
+ # making the path absolute will help.
116
+ if $(d)
117
+ {
118
+ d = [ path.root $(d) [ path.pwd ] ] ;
119
+ ps-raw += $(d:G=<install-source-root>) ;
120
+ }
121
+
122
+ if $(ps-raw)
123
+ {
124
+ return [ property-set.create $(ps-raw) ] ;
125
+ }
126
+ else
127
+ {
128
+ return [ property-set.empty ] ;
129
+ }
130
+ }
131
+
132
+ rule construct ( name : source-targets * : property-set )
133
+ {
134
+ source-targets = [ targets-to-stage $(source-targets) :
135
+ $(property-set) ] ;
136
+
137
+ property-set = [ update-location $(property-set) ] ;
138
+
139
+ local ename = [ $(property-set).get <name> ] ;
140
+
141
+ if $(ename) && $(source-targets[2])
142
+ {
143
+ errors.error "When <name> property is used in 'install', only one"
144
+ "source is allowed" ;
145
+ }
146
+
147
+ local result ;
148
+ for local i in $(source-targets)
149
+ {
150
+ local staged-targets ;
151
+
152
+ local new-properties = [ adjust-properties $(i) :
153
+ $(property-set) ] ;
154
+
155
+ # See if something special should be done when staging this type. It
156
+ # is indicated by the presence of a special "INSTALLED_" type.
157
+ local t = [ $(i).type ] ;
158
+ if $(t) && [ type.registered INSTALLED_$(t) ]
159
+ {
160
+ if $(ename)
161
+ {
162
+ errors.error "In 'install': <name> property specified with target that requires relinking." ;
163
+ }
164
+ else
165
+ {
166
+ local targets = [ generators.construct $(self.project)
167
+ $(name) : INSTALLED_$(t) : $(new-properties) : $(i) ] ;
168
+ staged-targets += $(targets[2-]) ;
169
+ }
170
+ }
171
+ else
172
+ {
173
+ staged-targets = [ stage.copy-file $(self.project) $(ename) :
174
+ $(i) : $(new-properties) ] ;
175
+ }
176
+
177
+ if ! $(staged-targets)
178
+ {
179
+ errors.error "Unable to generate staged version of " [ $(source).str ] ;
180
+ }
181
+
182
+ for t in $(staged-targets)
183
+ {
184
+ result += [ virtual-target.register $(t) ] ;
185
+ }
186
+ }
187
+
188
+ return [ property-set.empty ] $(result) ;
189
+ }
190
+
191
+ # Given the list of source targets explicitly passed to 'stage', returns the
192
+ # list of targets which must be staged.
193
+ #
194
+ rule targets-to-stage ( source-targets * : property-set )
195
+ {
196
+ local result ;
197
+
198
+ # Traverse the dependencies, if needed.
199
+ if [ $(property-set).get <install-dependencies> ] = "on"
200
+ {
201
+ source-targets = [ collect-targets $(source-targets) ] ;
202
+ }
203
+
204
+ # Filter the target types, if needed.
205
+ local included-types = [ $(property-set).get <install-type> ] ;
206
+ for local r in $(source-targets)
207
+ {
208
+ local ty = [ $(r).type ] ;
209
+ if $(ty)
210
+ {
211
+ # Do not stage searched libs.
212
+ if $(ty) != SEARCHED_LIB
213
+ {
214
+ if $(included-types)
215
+ {
216
+ if [ include-type $(ty) : $(included-types) ]
217
+ {
218
+ result += $(r) ;
219
+ }
220
+ }
221
+ else
222
+ {
223
+ result += $(r) ;
224
+ }
225
+ }
226
+ }
227
+ else if ! $(included-types)
228
+ {
229
+ # Don't install typeless target if there is an explicit list of
230
+ # allowed types.
231
+ result += $(r) ;
232
+ }
233
+ }
234
+
235
+ return $(result) ;
236
+ }
237
+
238
+ # CONSIDER: figure out why we can not use virtual-target.traverse here.
239
+ #
240
+ rule collect-targets ( targets * )
241
+ {
242
+ # Find subvariants
243
+ local s ;
244
+ for local t in $(targets)
245
+ {
246
+ s += [ $(t).creating-subvariant ] ;
247
+ }
248
+ s = [ sequence.unique $(s) ] ;
249
+
250
+ local result = [ new set ] ;
251
+ $(result).add $(targets) ;
252
+
253
+ for local i in $(s)
254
+ {
255
+ $(i).all-referenced-targets $(result) ;
256
+ }
257
+ local result2 ;
258
+ for local r in [ $(result).list ]
259
+ {
260
+ if $(r:G) != <use>
261
+ {
262
+ result2 += $(r:G=) ;
263
+ }
264
+ }
265
+ DELETE_MODULE $(result) ;
266
+ return [ sequence.unique $(result2) ] ;
267
+ }
268
+
269
+ # Returns true iff 'type' is subtype of some element of 'types-to-include'.
270
+ #
271
+ local rule include-type ( type : types-to-include * )
272
+ {
273
+ local found ;
274
+ while $(types-to-include) && ! $(found)
275
+ {
276
+ if [ type.is-subtype $(type) $(types-to-include[1]) ]
277
+ {
278
+ found = true ;
279
+ }
280
+ types-to-include = $(types-to-include[2-]) ;
281
+ }
282
+
283
+ return $(found) ;
284
+ }
285
+ }
286
+
287
+
288
+ # Creates a copy of target 'source'. The 'properties' object should have a
289
+ # <location> property which specifies where the target must be placed.
290
+ #
291
+ rule copy-file ( project name ? : source : properties )
292
+ {
293
+ name ?= [ $(source).name ] ;
294
+ local relative ;
295
+
296
+ local new-a = [ new non-scanning-action $(source) : common.copy :
297
+ $(properties) ] ;
298
+ local source-root = [ $(properties).get <install-source-root> ] ;
299
+ if $(source-root)
300
+ {
301
+ # Get the real path of the target. We probably need to strip relative
302
+ # path from the target name at construction.
303
+ local path = [ $(source).path ] ;
304
+ path = [ path.root $(name:D) $(path) ] ;
305
+ # Make the path absolute. Otherwise, it would be hard to compute the
306
+ # relative path. The 'source-root' is already absolute, see the
307
+ # 'adjust-properties' method above.
308
+ path = [ path.root $(path) [ path.pwd ] ] ;
309
+
310
+ relative = [ path.relative-to $(source-root) $(path) ] ;
311
+ }
312
+
313
+ # Note: Using $(name:D=$(relative)) might be faster here, but then we would
314
+ # need to explicitly check that relative is not ".", otherwise we might get
315
+ # paths like '<prefix>/boost/.', try to create it and mkdir would obviously
316
+ # fail.
317
+ name = [ path.join $(relative) $(name:D=) ] ;
318
+
319
+ return [ new file-target $(name) exact : [ $(source).type ] : $(project) :
320
+ $(new-a) ] ;
321
+ }
322
+
323
+
324
+ rule symlink ( name : project : source : properties )
325
+ {
326
+ local a = [ new action $(source) : symlink.ln : $(properties) ] ;
327
+ return [ new file-target $(name) exact : [ $(source).type ] : $(project) :
328
+ $(a) ] ;
329
+ }
330
+
331
+
332
+ rule relink-file ( project : source : property-set )
333
+ {
334
+ local action = [ $(source).action ] ;
335
+ local cloned-action = [ virtual-target.clone-action $(action) : $(project) :
336
+ "" : $(property-set) ] ;
337
+ return [ $(cloned-action).targets ] ;
338
+ }
339
+
340
+
341
+ # Declare installed version of the EXE type. Generator for this type will cause
342
+ # relinking to the new location.
343
+ type.register INSTALLED_EXE : : EXE ;
344
+
345
+
346
+ class installed-exe-generator : generator
347
+ {
348
+ import type ;
349
+ import property-set ;
350
+ import modules ;
351
+ import stage ;
352
+
353
+ rule __init__ ( )
354
+ {
355
+ generator.__init__ install-exe : EXE : INSTALLED_EXE ;
356
+ }
357
+
358
+ rule run ( project name ? : property-set : source : multiple ? )
359
+ {
360
+ local need-relink ;
361
+
362
+ if [ $(property-set).get <os> ] in NT CYGWIN ||
363
+ [ $(property-set).get <target-os> ] in windows cygwin
364
+ {
365
+ }
366
+ else
367
+ {
368
+ # See if the dll-path properties are not changed during
369
+ # install. If so, copy, don't relink.
370
+ local a = [ $(source).action ] ;
371
+ local p = [ $(a).properties ] ;
372
+ local original = [ $(p).get <dll-path> ] ;
373
+ local current = [ $(property-set).get <dll-path> ] ;
374
+
375
+ if $(current) != $(original)
376
+ {
377
+ need-relink = true ;
378
+ }
379
+ }
380
+
381
+
382
+ if $(need-relink)
383
+ {
384
+ return [ stage.relink-file $(project)
385
+ : $(source) : $(property-set) ] ;
386
+ }
387
+ else
388
+ {
389
+ return [ stage.copy-file $(project)
390
+ : $(source) : $(property-set) ] ;
391
+ }
392
+ }
393
+ }
394
+
395
+
396
+ generators.register [ new installed-exe-generator ] ;
397
+
398
+
399
+ # Installing a shared link on Unix might cause a creation of versioned symbolic
400
+ # links.
401
+ type.register INSTALLED_SHARED_LIB : : SHARED_LIB ;
402
+
403
+
404
+ class installed-shared-lib-generator : generator
405
+ {
406
+ import type ;
407
+ import property-set ;
408
+ import modules ;
409
+ import stage ;
410
+
411
+ rule __init__ ( )
412
+ {
413
+ generator.__init__ install-shared-lib : SHARED_LIB
414
+ : INSTALLED_SHARED_LIB ;
415
+ }
416
+
417
+ rule run ( project name ? : property-set : source : multiple ? )
418
+ {
419
+ if [ $(property-set).get <os> ] in NT CYGWIN ||
420
+ [ $(property-set).get <target-os> ] in windows cygwin
421
+ {
422
+ local copied = [ stage.copy-file $(project) : $(source) :
423
+ $(property-set) ] ;
424
+ return [ virtual-target.register $(copied) ] ;
425
+ }
426
+ else
427
+ {
428
+ local a = [ $(source).action ] ;
429
+ local copied ;
430
+ if ! $(a)
431
+ {
432
+ # Non-derived file, just copy.
433
+ copied = [ stage.copy-file $(project) : $(source) :
434
+ $(property-set) ] ;
435
+ }
436
+ else
437
+ {
438
+ local cp = [ $(a).properties ] ;
439
+ local current-dll-path = [ $(cp).get <dll-path> ] ;
440
+ local new-dll-path = [ $(property-set).get <dll-path> ] ;
441
+
442
+ if $(current-dll-path) != $(new-dll-path)
443
+ {
444
+ # Rpath changed, need to relink.
445
+ copied = [ stage.relink-file $(project) : $(source) :
446
+ $(property-set) ] ;
447
+ }
448
+ else
449
+ {
450
+ copied = [ stage.copy-file $(project) : $(source) :
451
+ $(property-set) ] ;
452
+ }
453
+ }
454
+
455
+ copied = [ virtual-target.register $(copied) ] ;
456
+
457
+ local result = $(copied) ;
458
+ # If the name is in the form NNN.XXX.YYY.ZZZ, where all 'X', 'Y' and
459
+ # 'Z' are numbers, we need to create NNN.XXX and NNN.XXX.YYY
460
+ # symbolic links.
461
+ local m = [ MATCH (.*)\\.([0123456789]+)\\.([0123456789]+)\\.([0123456789]+)$
462
+ : [ $(copied).name ] ] ;
463
+ if $(m)
464
+ {
465
+ # Symlink without version at all is used to make
466
+ # -lsome_library work.
467
+ result += [ stage.symlink $(m[1]) : $(project) : $(copied) :
468
+ $(property-set) ] ;
469
+
470
+ # Symlinks of some libfoo.N and libfoo.N.M are used so that
471
+ # library can found at runtime, if libfoo.N.M.X has soname of
472
+ # libfoo.N. That happens when the library makes some binary
473
+ # compatibility guarantees. If not, it is possible to skip those
474
+ # symlinks.
475
+ local suppress =
476
+ [ $(property-set).get <install-no-version-symlinks> ] ;
477
+
478
+ if $(suppress) != "on"
479
+ {
480
+ result += [ stage.symlink $(m[1]).$(m[2]) : $(project)
481
+ : $(copied) : $(property-set) ] ;
482
+ result += [ stage.symlink $(m[1]).$(m[2]).$(m[3]) : $(project)
483
+ : $(copied) : $(property-set) ] ;
484
+ }
485
+ }
486
+
487
+ return $(result) ;
488
+ }
489
+ }
490
+ }
491
+
492
+ generators.register [ new installed-shared-lib-generator ] ;
493
+
494
+
495
+ # Main target rule for 'install'.
496
+ #
497
+ rule install ( name : sources * : requirements * : default-build * )
498
+ {
499
+ local project = [ project.current ] ;
500
+
501
+ # Unless the user has explicitly asked us to hardcode dll paths, add
502
+ # <hardcode-dll-paths>false in requirements, to override default value.
503
+ if ! <hardcode-dll-paths>true in $(requirements)
504
+ {
505
+ requirements += <hardcode-dll-paths>false ;
506
+ }
507
+
508
+ if <tag> in $(requirements:G)
509
+ {
510
+ errors.user-error
511
+ "The <tag> property is not allowed for the 'install' rule" ;
512
+ }
513
+
514
+ targets.main-target-alternative
515
+ [ new install-target-class $(name) : $(project)
516
+ : [ targets.main-target-sources $(sources) : $(name) ]
517
+ : [ targets.main-target-requirements $(requirements) : $(project) ]
518
+ : [ targets.main-target-default-build $(default-build) : $(project) ]
519
+ ] ;
520
+ }
521
+
522
+
523
+ IMPORT $(__name__) : install : : install ;
524
+ IMPORT $(__name__) : install : : stage ;
mosesdecoder/jam-files/boost-build/tools/testing-aux.jam ADDED
@@ -0,0 +1,210 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # This module is imported by testing.py. The definitions here are
2
+ # too tricky to do in Python
3
+
4
+ # Causes the 'target' to exist after bjam invocation if and only if all the
5
+ # dependencies were successfully built.
6
+ #
7
+ rule expect-success ( target : dependency + : requirements * )
8
+ {
9
+ **passed** $(target) : $(sources) ;
10
+ }
11
+ IMPORT testing : expect-success : : testing.expect-success ;
12
+
13
+ # Causes the 'target' to exist after bjam invocation if and only if all some of
14
+ # the dependencies were not successfully built.
15
+ #
16
+ rule expect-failure ( target : dependency + : properties * )
17
+ {
18
+ local grist = [ MATCH ^<(.*)> : $(dependency:G) ] ;
19
+ local marker = $(dependency:G=$(grist)*fail) ;
20
+ (failed-as-expected) $(marker) ;
21
+ FAIL_EXPECTED $(dependency) ;
22
+ LOCATE on $(marker) = [ on $(dependency) return $(LOCATE) ] ;
23
+ RMOLD $(marker) ;
24
+ DEPENDS $(marker) : $(dependency) ;
25
+ DEPENDS $(target) : $(marker) ;
26
+ **passed** $(target) : $(marker) ;
27
+ }
28
+ IMPORT testing : expect-failure : : testing.expect-failure ;
29
+
30
+ # The rule/action combination used to report successful passing of a test.
31
+ #
32
+ rule **passed**
33
+ {
34
+ # Force deletion of the target, in case any dependencies failed to build.
35
+ RMOLD $(<) ;
36
+ }
37
+
38
+
39
+ # Used to create test files signifying passed tests.
40
+ #
41
+ actions **passed**
42
+ {
43
+ echo passed > "$(<)"
44
+ }
45
+
46
+
47
+ # Used to create replacement object files that do not get created during tests
48
+ # that are expected to fail.
49
+ #
50
+ actions (failed-as-expected)
51
+ {
52
+ echo failed as expected > "$(<)"
53
+ }
54
+
55
+ # Runs executable 'sources' and stores stdout in file 'target'. Unless
56
+ # --preserve-test-targets command line option has been specified, removes the
57
+ # executable. The 'target-to-remove' parameter controls what should be removed:
58
+ # - if 'none', does not remove anything, ever
59
+ # - if empty, removes 'source'
60
+ # - if non-empty and not 'none', contains a list of sources to remove.
61
+ #
62
+ rule capture-output ( target : source : properties * : targets-to-remove * )
63
+ {
64
+ output-file on $(target) = $(target:S=.output) ;
65
+ LOCATE on $(target:S=.output) = [ on $(target) return $(LOCATE) ] ;
66
+
67
+ # The INCLUDES kill a warning about independent target...
68
+ INCLUDES $(target) : $(target:S=.output) ;
69
+ # but it also puts .output into dependency graph, so we must tell jam it is
70
+ # OK if it cannot find the target or updating rule.
71
+ NOCARE $(target:S=.output) ;
72
+
73
+ # This has two-fold effect. First it adds input files to the dependendency
74
+ # graph, preventing a warning. Second, it causes input files to be bound
75
+ # before target is created. Therefore, they are bound using SEARCH setting
76
+ # on them and not LOCATE setting of $(target), as in other case (due to jam
77
+ # bug).
78
+ DEPENDS $(target) : [ on $(target) return $(INPUT_FILES) ] ;
79
+
80
+ if $(targets-to-remove) = none
81
+ {
82
+ targets-to-remove = ;
83
+ }
84
+ else if ! $(targets-to-remove)
85
+ {
86
+ targets-to-remove = $(source) ;
87
+ }
88
+
89
+ if [ on $(target) return $(REMOVE_TEST_TARGETS) ]
90
+ {
91
+ TEMPORARY $(targets-to-remove) ;
92
+ # Set a second action on target that will be executed after capture
93
+ # output action. The 'RmTemps' rule has the 'ignore' modifier so it is
94
+ # always considered succeeded. This is needed for 'run-fail' test. For
95
+ # that test the target will be marked with FAIL_EXPECTED, and without
96
+ # 'ignore' successful execution will be negated and be reported as
97
+ # failure. With 'ignore' we do not detect a case where removing files
98
+ # fails, but it is not likely to happen.
99
+ RmTemps $(target) : $(targets-to-remove) ;
100
+ }
101
+ }
102
+
103
+
104
+ if [ os.name ] = NT
105
+ {
106
+ .STATUS = %status% ;
107
+ .SET_STATUS = "set status=%ERRORLEVEL%" ;
108
+ .RUN_OUTPUT_NL = "echo." ;
109
+ .STATUS_0 = "%status% EQU 0 (" ;
110
+ .STATUS_NOT_0 = "%status% NEQ 0 (" ;
111
+ .VERBOSE = "%verbose% EQU 1 (" ;
112
+ .ENDIF = ")" ;
113
+ .SHELL_SET = "set " ;
114
+ .CATENATE = type ;
115
+ .CP = copy ;
116
+ }
117
+ else
118
+ {
119
+ .STATUS = "$status" ;
120
+ .SET_STATUS = "status=$?" ;
121
+ .RUN_OUTPUT_NL = "echo" ;
122
+ .STATUS_0 = "test $status -eq 0 ; then" ;
123
+ .STATUS_NOT_0 = "test $status -ne 0 ; then" ;
124
+ .VERBOSE = "test $verbose -eq 1 ; then" ;
125
+ .ENDIF = "fi" ;
126
+ .SHELL_SET = "" ;
127
+ .CATENATE = cat ;
128
+ .CP = cp ;
129
+ }
130
+
131
+
132
+ .VERBOSE_TEST = 0 ;
133
+ if --verbose-test in [ modules.peek : ARGV ]
134
+ {
135
+ .VERBOSE_TEST = 1 ;
136
+ }
137
+
138
+
139
+ .RM = [ common.rm-command ] ;
140
+
141
+
142
+ actions capture-output bind INPUT_FILES output-file
143
+ {
144
+ $(PATH_SETUP)
145
+ $(LAUNCHER) "$(>)" $(ARGS) "$(INPUT_FILES)" > "$(output-file)" 2>&1
146
+ $(.SET_STATUS)
147
+ $(.RUN_OUTPUT_NL) >> "$(output-file)"
148
+ echo EXIT STATUS: $(.STATUS) >> "$(output-file)"
149
+ if $(.STATUS_0)
150
+ $(.CP) "$(output-file)" "$(<)"
151
+ $(.ENDIF)
152
+ $(.SHELL_SET)verbose=$(.VERBOSE_TEST)
153
+ if $(.STATUS_NOT_0)
154
+ $(.SHELL_SET)verbose=1
155
+ $(.ENDIF)
156
+ if $(.VERBOSE)
157
+ echo ====== BEGIN OUTPUT ======
158
+ $(.CATENATE) "$(output-file)"
159
+ echo ====== END OUTPUT ======
160
+ $(.ENDIF)
161
+ exit $(.STATUS)
162
+ }
163
+
164
+ IMPORT testing : capture-output : : testing.capture-output ;
165
+
166
+
167
+ actions quietly updated ignore piecemeal together RmTemps
168
+ {
169
+ $(.RM) "$(>)"
170
+ }
171
+
172
+
173
+ .MAKE_FILE = [ common.file-creation-command ] ;
174
+
175
+ actions unit-test
176
+ {
177
+ $(PATH_SETUP)
178
+ $(LAUNCHER) $(>) $(ARGS) && $(.MAKE_FILE) $(<)
179
+ }
180
+
181
+ rule record-time ( target : source : start end user system )
182
+ {
183
+ local src-string = [$(source:G=:J=",")"] " ;
184
+ USER_TIME on $(target) += $(src-string)$(user) ;
185
+ SYSTEM_TIME on $(target) += $(src-string)$(system) ;
186
+ }
187
+
188
+ # Calling this rule requests that Boost Build time how long it taks to build the
189
+ # 'source' target and display the results both on the standard output and in the
190
+ # 'target' file.
191
+ #
192
+ rule time ( target : source : properties * )
193
+ {
194
+ # Set up rule for recording timing information.
195
+ __TIMING_RULE__ on $(source) = testing.record-time $(target) ;
196
+
197
+ # Make sure that the source is rebuilt any time we need to retrieve that
198
+ # information.
199
+ REBUILDS $(target) : $(source) ;
200
+ }
201
+
202
+
203
+ actions time
204
+ {
205
+ echo user: $(USER_TIME)
206
+ echo system: $(SYSTEM_TIME)
207
+
208
+ echo user: $(USER_TIME)" seconds" > "$(<)"
209
+ echo system: $(SYSTEM_TIME)" seconds" >> "$(<)"
210
+ }
mosesdecoder/jam-files/boost-build/tools/vacpp.jam ADDED
@@ -0,0 +1,150 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright Vladimir Prus 2004.
2
+ # Copyright Toon Knapen 2004.
3
+ # Distributed under the Boost Software License, Version 1.0.
4
+ # (See accompanying file LICENSE_1_0.txt
5
+ # or copy at http://www.boost.org/LICENSE_1_0.txt)
6
+
7
+ #
8
+ # Boost.Build V2 toolset for the IBM XL C++ compiler
9
+ #
10
+
11
+ import toolset : flags ;
12
+ import feature ;
13
+ import common ;
14
+ import generators ;
15
+ import os ;
16
+
17
+ feature.extend toolset : vacpp ;
18
+ toolset.inherit vacpp : unix ;
19
+ generators.override vacpp.prebuilt : builtin.prebuilt ;
20
+ generators.override vacpp.searched-lib-generator : searched-lib-generator ;
21
+
22
+ # Configure the vacpp toolset
23
+ rule init ( version ? : command * : options * )
24
+ {
25
+ local condition = [
26
+ common.check-init-parameters vacpp : version $(version) ] ;
27
+
28
+ command = [ common.get-invocation-command vacpp : xlC
29
+ : $(command) : "/usr/vacpp/bin/xlC" ] ;
30
+
31
+ common.handle-options vacpp : $(condition) : $(command) : $(options) ;
32
+ }
33
+
34
+ # Declare generators
35
+ generators.register-c-compiler vacpp.compile.c : C : OBJ : <toolset>vacpp ;
36
+ generators.register-c-compiler vacpp.compile.c++ : CPP : OBJ : <toolset>vacpp ;
37
+
38
+ # Allow C++ style comments in C files
39
+ flags vacpp CFLAGS : -qcpluscmt ;
40
+
41
+ # Declare flags
42
+ flags vacpp CFLAGS <optimization>off : -qNOOPTimize ;
43
+ flags vacpp CFLAGS <optimization>speed : -O3 -qstrict ;
44
+ flags vacpp CFLAGS <optimization>space : -O2 -qcompact ;
45
+
46
+ # Discretionary inlining (not recommended)
47
+ flags vacpp CFLAGS <inlining>off : -qnoinline ;
48
+ flags vacpp CFLAGS <inlining>on : -qinline ;
49
+ #flags vacpp CFLAGS <inlining>full : -qinline ;
50
+ flags vacpp CFLAGS <inlining>full : ;
51
+
52
+ # Exception handling
53
+ flags vacpp C++FLAGS <exception-handling>off : -qnoeh ;
54
+ flags vacpp C++FLAGS <exception-handling>on : -qeh ;
55
+
56
+ # Run-time Type Identification
57
+ flags vacpp C++FLAGS <rtti>off : -qnortti ;
58
+ flags vacpp C++FLAGS <rtti>on : -qrtti ;
59
+
60
+ # Enable 64-bit memory addressing model
61
+ flags vacpp CFLAGS <address-model>64 : -q64 ;
62
+ flags vacpp LINKFLAGS <address-model>64 : -q64 ;
63
+ flags vacpp ARFLAGS <target-os>aix/<address-model>64 : -X 64 ;
64
+
65
+ # Use absolute path when generating debug information
66
+ flags vacpp CFLAGS <debug-symbols>on : -g -qfullpath ;
67
+ flags vacpp LINKFLAGS <debug-symbols>on : -g -qfullpath ;
68
+ flags vacpp LINKFLAGS <debug-symbols>off : -s ;
69
+
70
+ if [ os.name ] = AIX
71
+ {
72
+ flags vacpp.compile C++FLAGS : -qfuncsect ;
73
+
74
+ # The -bnoipath strips the prepending (relative) path of libraries from
75
+ # the loader section in the target library or executable. Hence, during
76
+ # load-time LIBPATH (identical to LD_LIBRARY_PATH) or a hard-coded
77
+ # -blibpath (*similar* to -lrpath/-lrpath-link) is searched. Without
78
+ # this option, the prepending (relative) path + library name is
79
+ # hard-coded in the loader section, causing *only* this path to be
80
+ # searched during load-time. Note that the AIX linker does not have an
81
+ # -soname equivalent, this is as close as it gets.
82
+ #
83
+ # The above options are definately for AIX 5.x, and most likely also for
84
+ # AIX 4.x and AIX 6.x. For details about the AIX linker see:
85
+ # http://download.boulder.ibm.com/ibmdl/pub/software/dw/aix/es-aix_ll.pdf
86
+ #
87
+ flags vacpp.link LINKFLAGS <link>shared : -bnoipath ;
88
+
89
+ # Run-time linking
90
+ flags vacpp.link EXE-LINKFLAGS <link>shared : -brtl ;
91
+ }
92
+ else
93
+ {
94
+ # Linux PPC
95
+ flags vacpp.compile CFLAGS <link>shared : -qpic=large ;
96
+ flags vacpp FINDLIBS : rt ;
97
+ }
98
+
99
+ # Profiling
100
+ flags vacpp CFLAGS <profiling>on : -pg ;
101
+ flags vacpp LINKFLAGS <profiling>on : -pg ;
102
+
103
+ flags vacpp.compile OPTIONS <cflags> ;
104
+ flags vacpp.compile.c++ OPTIONS <cxxflags> ;
105
+ flags vacpp DEFINES <define> ;
106
+ flags vacpp UNDEFS <undef> ;
107
+ flags vacpp HDRS <include> ;
108
+ flags vacpp STDHDRS <sysinclude> ;
109
+ flags vacpp.link OPTIONS <linkflags> ;
110
+ flags vacpp ARFLAGS <arflags> ;
111
+
112
+ flags vacpp LIBPATH <library-path> ;
113
+ flags vacpp NEEDLIBS <library-file> ;
114
+ flags vacpp FINDLIBS <find-shared-library> ;
115
+ flags vacpp FINDLIBS <find-static-library> ;
116
+
117
+ # Select the compiler name according to the threading model.
118
+ flags vacpp VA_C_COMPILER <threading>single : xlc ;
119
+ flags vacpp VA_C_COMPILER <threading>multi : xlc_r ;
120
+ flags vacpp VA_CXX_COMPILER <threading>single : xlC ;
121
+ flags vacpp VA_CXX_COMPILER <threading>multi : xlC_r ;
122
+
123
+ SPACE = " " ;
124
+
125
+ flags vacpp.link.dll HAVE_SONAME <target-os>linux : "" ;
126
+
127
+ actions vacpp.link bind NEEDLIBS
128
+ {
129
+ $(VA_CXX_COMPILER) $(EXE-LINKFLAGS) $(LINKFLAGS) -o "$(<[1])" -L$(LIBPATH) -L$(STDLIBPATH) "$(>)" "$(NEEDLIBS)" "$(NEEDLIBS)" -l$(FINDLIBS) $(OPTIONS) $(USER_OPTIONS)
130
+ }
131
+
132
+ actions vacpp.link.dll bind NEEDLIBS
133
+ {
134
+ xlC_r -G $(LINKFLAGS) -o "$(<[1])" $(HAVE_SONAME)-Wl,-soname$(SPACE)-Wl,$(<[-1]:D=) -L$(LIBPATH) -L$(STDLIBPATH) "$(>)" "$(NEEDLIBS)" "$(NEEDLIBS)" -l$(FINDLIBS) $(OPTIONS) $(USER_OPTIONS)
135
+ }
136
+
137
+ actions vacpp.compile.c
138
+ {
139
+ $(VA_C_COMPILER) -c $(OPTIONS) $(USER_OPTIONS) -I$(BOOST_ROOT) -U$(UNDEFS) -D$(DEFINES) $(CFLAGS) -I"$(HDRS)" -I"$(STDHDRS)" -o "$(<)" "$(>)"
140
+ }
141
+
142
+ actions vacpp.compile.c++
143
+ {
144
+ $(VA_CXX_COMPILER) -c $(OPTIONS) $(USER_OPTIONS) -I$(BOOST_ROOT) -U$(UNDEFS) -D$(DEFINES) $(CFLAGS) $(C++FLAGS) -I"$(HDRS)" -I"$(STDHDRS)" -o "$(<)" "$(>)"
145
+ }
146
+
147
+ actions updated together piecemeal vacpp.archive
148
+ {
149
+ ar $(ARFLAGS) ru "$(<)" "$(>)"
150
+ }
mosesdecoder/jam-files/boost-build/util/container.jam ADDED
@@ -0,0 +1,339 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2003 Dave Abrahams
2
+ # Copyright 2002, 2003 Rene Rivera
3
+ # Copyright 2002, 2003, 2004 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
+ # Various container classes.
8
+
9
+ # Base for container objects. This lets us construct recursive structures. That
10
+ # is containers with containers in them, specifically so we can tell literal
11
+ # values from node values.
12
+ #
13
+ class node
14
+ {
15
+ rule __init__ (
16
+ value ? # Optional value to set node to initially.
17
+ )
18
+ {
19
+ self.value = $(value) ;
20
+ }
21
+
22
+ # Set the value of this node, passing nothing will clear it.
23
+ #
24
+ rule set ( value * )
25
+ {
26
+ self.value = $(value) ;
27
+ }
28
+
29
+ # Get the value of this node.
30
+ #
31
+ rule get ( )
32
+ {
33
+ return $(self.value) ;
34
+ }
35
+ }
36
+
37
+
38
+ # A simple vector. Interface mimics the C++ std::vector and std::list, with the
39
+ # exception that indices are one (1) based to follow Jam standard.
40
+ #
41
+ # TODO: Possibly add assertion checks.
42
+ #
43
+ class vector : node
44
+ {
45
+ import numbers ;
46
+ import utility ;
47
+ import sequence ;
48
+
49
+ rule __init__ (
50
+ values * # Initial contents of vector.
51
+ )
52
+ {
53
+ node.__init__ ;
54
+ self.value = $(values) ;
55
+ }
56
+
57
+ # Get the value of the first element.
58
+ #
59
+ rule front ( )
60
+ {
61
+ return $(self.value[1]) ;
62
+ }
63
+
64
+ # Get the value of the last element.
65
+ #
66
+ rule back ( )
67
+ {
68
+ return $(self.value[-1]) ;
69
+ }
70
+
71
+ # Get the value of the element at the given index, one based. Access to
72
+ # elements of recursive structures is supported directly. Specifying
73
+ # additional index values recursively accesses the elements as containers.
74
+ # For example: [ $(v).at 1 : 2 ] would retrieve the second element of our
75
+ # first element, assuming the first element is a container.
76
+ #
77
+ rule at (
78
+ index # The element index, one based.
79
+ : * # Additional indices to access recursively.
80
+ )
81
+ {
82
+ local r = $(self.value[$(index)]) ;
83
+ if $(2)
84
+ {
85
+ r = [ $(r).at $(2) : $(3) : $(4) : $(5) : $(6) : $(7) : $(8) : $(9) ] ;
86
+ }
87
+ return $(r) ;
88
+ }
89
+
90
+ # Get the value contained in the given element. This has the same
91
+ # functionality and interface as "at" but in addition gets the value of the
92
+ # referenced element, assuming it is a "node".
93
+ #
94
+ rule get-at (
95
+ index # The element index, one based.
96
+ : * # Additional indices to access recursively.
97
+ )
98
+ {
99
+ local r = $(self.value[$(index)]) ;
100
+ if $(2)
101
+ {
102
+ r = [ $(r).at $(2) : $(3) : $(4) : $(5) : $(6) : $(7) : $(8) : $(9) ] ;
103
+ }
104
+ return [ $(r).get ] ;
105
+ }
106
+
107
+ # Insert the given value into the front of the vector pushing the rest of
108
+ # the elements back.
109
+ #
110
+ rule push-front (
111
+ value # Value to become first element.
112
+ )
113
+ {
114
+ self.value = $(value) $(self.value) ;
115
+ }
116
+
117
+ # Remove the front element from the vector. Does not return the value. No
118
+ # effect if vector is empty.
119
+ #
120
+ rule pop-front ( )
121
+ {
122
+ self.value = $(self.value[2-]) ;
123
+ }
124
+
125
+ # Add the given value at the end of the vector.
126
+ #
127
+ rule push-back (
128
+ value # Value to become back element.
129
+ )
130
+ {
131
+ self.value += $(value) ;
132
+ }
133
+
134
+ # Remove the back element from the vector. Does not return the value. No
135
+ # effect if vector is empty.
136
+ #
137
+ rule pop-back ( )
138
+ {
139
+ self.value = $(self.value[1--2]) ;
140
+ }
141
+
142
+ # Insert the given value at the given index, one based. The values at and to
143
+ # the right of the index are pushed back to make room for the new value.
144
+ # If the index is passed the end of the vector the element is added to the
145
+ # end.
146
+ #
147
+ rule insert (
148
+ index # The index to insert at, one based.
149
+ : value # The value to insert.
150
+ )
151
+ {
152
+ local left = $(self.value[1-$(index)]) ;
153
+ local right = $(self.value[$(index)-]) ;
154
+ if $(right)-is-not-empty
155
+ {
156
+ left = $(left[1--2]) ;
157
+ }
158
+ self.value = $(left) $(value) $(right) ;
159
+ }
160
+
161
+ # Remove one or more elements from the vector. The range is inclusive, and
162
+ # not specifying an end is equivalent to the [start, start] range.
163
+ #
164
+ rule erase (
165
+ start # Index of first element to remove.
166
+ end ? # Optional, index of last element to remove.
167
+ )
168
+ {
169
+ end ?= $(start) ;
170
+ local left = $(self.value[1-$(start)]) ;
171
+ left = $(left[1--2]) ;
172
+ local right = $(self.value[$(end)-]) ;
173
+ right = $(right[2-]) ;
174
+ self.value = $(left) $(right) ;
175
+ }
176
+
177
+ # Remove all elements from the vector.
178
+ #
179
+ rule clear ( )
180
+ {
181
+ self.value = ;
182
+ }
183
+
184
+ # The number of elements in the vector.
185
+ #
186
+ rule size ( )
187
+ {
188
+ return [ sequence.length $(self.value) ] ;
189
+ }
190
+
191
+ # Returns "true" if there are NO elements in the vector, empty otherwise.
192
+ #
193
+ rule empty ( )
194
+ {
195
+ if ! $(self.value)-is-not-empty
196
+ {
197
+ return true ;
198
+ }
199
+ }
200
+
201
+ # Returns the textual representation of content.
202
+ #
203
+ rule str ( )
204
+ {
205
+ return "[" [ sequence.transform utility.str : $(self.value) ] "]" ;
206
+ }
207
+
208
+ # Sorts the vector inplace, calling 'utility.less' for comparisons.
209
+ #
210
+ rule sort ( )
211
+ {
212
+ self.value = [ sequence.insertion-sort $(self.value) : utility.less ] ;
213
+ }
214
+
215
+ # Returns true if content is equal to the content of other vector. Uses
216
+ # 'utility.equal' for comparison.
217
+ #
218
+ rule equal ( another )
219
+ {
220
+ local mismatch ;
221
+ local size = [ size ] ;
222
+ if $(size) = [ $(another).size ]
223
+ {
224
+ for local i in [ numbers.range 1 $(size) ]
225
+ {
226
+ if ! [ utility.equal [ at $(i) ] [ $(another).at $(i) ] ]
227
+ {
228
+ mismatch = true ;
229
+ }
230
+ }
231
+ }
232
+ else
233
+ {
234
+ mismatch = true ;
235
+ }
236
+
237
+ if ! $(mismatch)
238
+ {
239
+ return true ;
240
+ }
241
+ }
242
+ }
243
+
244
+
245
+ rule __test__ ( )
246
+ {
247
+ import assert ;
248
+ import "class" : new ;
249
+
250
+ local v1 = [ new vector ] ;
251
+ assert.true $(v1).equal $(v1) ;
252
+ assert.true $(v1).empty ;
253
+ assert.result 0 : $(v1).size ;
254
+ assert.result "[" "]" : $(v1).str ;
255
+ $(v1).push-back b ;
256
+ $(v1).push-front a ;
257
+ assert.result "[" a b "]" : $(v1).str ;
258
+ assert.result a : $(v1).front ;
259
+ assert.result b : $(v1).back ;
260
+ $(v1).insert 2 : d ;
261
+ $(v1).insert 2 : c ;
262
+ $(v1).insert 4 : f ;
263
+ $(v1).insert 4 : e ;
264
+ $(v1).pop-back ;
265
+ assert.result 5 : $(v1).size ;
266
+ assert.result d : $(v1).at 3 ;
267
+ $(v1).pop-front ;
268
+ assert.result c : $(v1).front ;
269
+ assert.false $(v1).empty ;
270
+ $(v1).erase 3 4 ;
271
+ assert.result 2 : $(v1).size ;
272
+
273
+ local v2 = [ new vector q w e r t y ] ;
274
+ assert.result 6 : $(v2).size ;
275
+ $(v1).push-back $(v2) ;
276
+ assert.result 3 : $(v1).size ;
277
+ local v2-alias = [ $(v1).back ] ;
278
+ assert.result e : $(v2-alias).at 3 ;
279
+ $(v1).clear ;
280
+ assert.true $(v1).empty ;
281
+ assert.false $(v2-alias).empty ;
282
+ $(v2).pop-back ;
283
+ assert.result t : $(v2-alias).back ;
284
+
285
+ local v3 = [ new vector ] ;
286
+ $(v3).push-back [ new vector 1 2 3 4 5 ] ;
287
+ $(v3).push-back [ new vector a b c ] ;
288
+ assert.result "[" "[" 1 2 3 4 5 "]" "[" a b c "]" "]" : $(v3).str ;
289
+ $(v3).push-back [ new vector [ new vector x y z ] [ new vector 7 8 9 ] ] ;
290
+ assert.result 1 : $(v3).at 1 : 1 ;
291
+ assert.result b : $(v3).at 2 : 2 ;
292
+ assert.result a b c : $(v3).get-at 2 ;
293
+ assert.result 7 8 9 : $(v3).get-at 3 : 2 ;
294
+
295
+ local v4 = [ new vector 4 3 6 ] ;
296
+ $(v4).sort ;
297
+ assert.result 3 4 6 : $(v4).get ;
298
+ assert.false $(v4).equal $(v3) ;
299
+
300
+ local v5 = [ new vector 3 4 6 ] ;
301
+ assert.true $(v4).equal $(v5) ;
302
+ # Check that vectors of different sizes are considered non-equal.
303
+ $(v5).pop-back ;
304
+ assert.false $(v4).equal $(v5) ;
305
+
306
+ local v6 = [ new vector [ new vector 1 2 3 ] ] ;
307
+ assert.true $(v6).equal [ new vector [ new vector 1 2 3 ] ] ;
308
+
309
+ local v7 = [ new vector 111 222 333 ] ;
310
+ assert.true $(v7).equal $(v7) ;
311
+ $(v7).insert 4 : 444 ;
312
+ assert.result 111 222 333 444 : $(v7).get ;
313
+ $(v7).insert 999 : xxx ;
314
+ assert.result 111 222 333 444 xxx : $(v7).get ;
315
+
316
+ local v8 = [ new vector "" "" "" ] ;
317
+ assert.true $(v8).equal $(v8) ;
318
+ assert.false $(v8).empty ;
319
+ assert.result 3 : $(v8).size ;
320
+ assert.result "" : $(v8).at 1 ;
321
+ assert.result "" : $(v8).at 2 ;
322
+ assert.result "" : $(v8).at 3 ;
323
+ assert.result : $(v8).at 4 ;
324
+ $(v8).insert 2 : 222 ;
325
+ assert.result 4 : $(v8).size ;
326
+ assert.result "" 222 "" "" : $(v8).get ;
327
+ $(v8).insert 999 : "" ;
328
+ assert.result 5 : $(v8).size ;
329
+ assert.result "" 222 "" "" "" : $(v8).get ;
330
+ $(v8).insert 999 : xxx ;
331
+ assert.result 6 : $(v8).size ;
332
+ assert.result "" 222 "" "" "" xxx : $(v8).get ;
333
+
334
+ # Regression test for a bug causing vector.equal to compare only the first
335
+ # and the last element in the given vectors.
336
+ local v9 = [ new vector 111 xxx 222 ] ;
337
+ local v10 = [ new vector 111 yyy 222 ] ;
338
+ assert.false $(v9).equal $(v10) ;
339
+ }
mosesdecoder/jam-files/boost-build/util/indirect.jam ADDED
@@ -0,0 +1,115 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2003 Dave Abrahams
2
+ # Copyright 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 modules ;
7
+ import numbers ;
8
+
9
+
10
+ # The pattern that indirect rules must match: module%rule
11
+ .pattern = ^([^%]*)%([^%]+)$ ;
12
+
13
+
14
+ #
15
+ # Type checking rules.
16
+ #
17
+ local rule indirect-rule ( x )
18
+ {
19
+ if ! [ MATCH $(.pattern) : $(x) ]
20
+ {
21
+ return "expected a string of the form module%rule, but got \""$(x)"\" for argument" ;
22
+ }
23
+ }
24
+
25
+
26
+ # Make an indirect rule which calls the given rule. If context is supplied it is
27
+ # expected to be the module in which to invoke the rule by the 'call' rule
28
+ # below. Otherwise, the rule will be invoked in the module of this rule's
29
+ # caller.
30
+ #
31
+ rule make ( rulename bound-args * : context ? )
32
+ {
33
+ context ?= [ CALLER_MODULE ] ;
34
+ context ?= "" ;
35
+ return $(context)%$(rulename) $(bound-args) ;
36
+ }
37
+
38
+
39
+ # Make an indirect rule which calls the given rule. 'rulename' may be a
40
+ # qualified rule; if so it is returned unchanged. Otherwise, if frames is not
41
+ # supplied, the result will be invoked (by 'call', below) in the module of the
42
+ # caller. Otherwise, frames > 1 specifies additional call frames to back up in
43
+ # order to find the module context.
44
+ #
45
+ rule make-qualified ( rulename bound-args * : frames ? )
46
+ {
47
+ if [ MATCH $(.pattern) : $(rulename) ]
48
+ {
49
+ return $(rulename) $(bound-args) ;
50
+ }
51
+ else
52
+ {
53
+ frames ?= 1 ;
54
+ # If the rule name includes a Jamfile module, grab it.
55
+ local module-context = [ MATCH ^(Jamfile<[^>]*>)\\..* : $(rulename) ] ;
56
+
57
+ if ! $(module-context)
58
+ {
59
+ # Take the first dot-separated element as module name. This disallows
60
+ # module names with dots, but allows rule names with dots.
61
+ module-context = [ MATCH ^([^.]*)\\..* : $(rulename) ] ;
62
+ }
63
+ module-context ?= [ CALLER_MODULE $(frames) ] ;
64
+ return [ make $(rulename) $(bound-args) : $(module-context) ] ;
65
+ }
66
+ }
67
+
68
+
69
+ # Returns the module name in which the given indirect rule will be invoked.
70
+ #
71
+ rule get-module ( [indirect-rule] x )
72
+ {
73
+ local m = [ MATCH $(.pattern) : $(x) ] ;
74
+ if ! $(m[1])
75
+ {
76
+ m = ;
77
+ }
78
+ return $(m[1]) ;
79
+ }
80
+
81
+
82
+ # Returns the rulename that will be called when x is invoked.
83
+ #
84
+ rule get-rule ( [indirect-rule] x )
85
+ {
86
+ local m = [ MATCH $(.pattern) : $(x) ] ;
87
+ return $(m[2]) ;
88
+ }
89
+
90
+
91
+ # Invoke the given indirect-rule.
92
+ #
93
+ rule call ( [indirect-rule] r args * : * )
94
+ {
95
+ return [ modules.call-in [ get-module $(r) ] : [ get-rule $(r) ] $(args)
96
+ : $(2) : $(3) : $(4) : $(5) : $(6) : $(7) : $(8) : $(9) ] ;
97
+ }
98
+
99
+
100
+ rule __test__
101
+ {
102
+ import assert ;
103
+
104
+ rule foo-barr! ( x )
105
+ {
106
+ assert.equal $(x) : x ;
107
+ }
108
+
109
+ assert.equal [ get-rule [ make foo-barr! ] ] : foo-barr! ;
110
+ assert.equal [ get-module [ make foo-barr! ] ] : [ CALLER_MODULE ] ;
111
+
112
+ call [ make foo-barr! ] x ;
113
+ call [ make foo-barr! x ] ;
114
+ call [ make foo-barr! : [ CALLER_MODULE ] ] x ;
115
+ }
mosesdecoder/jam-files/boost-build/util/option.jam ADDED
@@ -0,0 +1,109 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright (c) 2005 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 modules ;
8
+
9
+ # Set a value for a named option, to be used when not overridden on the command
10
+ # line.
11
+ rule set ( name : value ? )
12
+ {
13
+ .option.$(name) = $(value) ;
14
+ }
15
+
16
+ rule get ( name : default-value ? : implied-value ? )
17
+ {
18
+ local m = [ MATCH --$(name)=(.*) : [ modules.peek : ARGV ] ] ;
19
+ if $(m)
20
+ {
21
+ return $(m[1]) ;
22
+ }
23
+ else
24
+ {
25
+ m = [ MATCH (--$(name)) : [ modules.peek : ARGV ] ] ;
26
+ if $(m) && $(implied-value)
27
+ {
28
+ return $(implied-value) ;
29
+ }
30
+ else if $(.option.$(name))
31
+ {
32
+ return $(.option.$(name)) ;
33
+ }
34
+ else
35
+ {
36
+ return $(default-value) ;
37
+ }
38
+ }
39
+ }
40
+
41
+
42
+ # Check command-line args as soon as possible. For each option try to load
43
+ # module named after option. Is that succeeds, invoke 'process' rule in the
44
+ # module. The rule may return "true" to indicate that the regular build process
45
+ # should not be attempted.
46
+ #
47
+ # Options take the general form of: --<name>[=<value>] [<value>]
48
+ #
49
+ rule process ( )
50
+ {
51
+ local ARGV = [ modules.peek : ARGV ] ;
52
+ local BOOST_BUILD_PATH = [ modules.peek : BOOST_BUILD_PATH ] ;
53
+
54
+ local dont-build ;
55
+ local args = $(ARGV) ;
56
+ while $(args)
57
+ {
58
+ local arg = [ MATCH ^--(.*) : $(args[1]) ] ;
59
+ while $(args[2-]) && ! $(arg)
60
+ {
61
+ args = $(args[2-]) ;
62
+ arg = [ MATCH ^--(.*) : $(args[1]) ] ;
63
+ }
64
+ args = $(args[2-]) ;
65
+
66
+ if $(arg)
67
+ {
68
+ local split = [ MATCH ^(([^-=]+)[^=]*)(=?)(.*)$ : $(arg) ] ;
69
+ local full-name = $(split[1]) ;
70
+ local prefix = $(split[2]) ;
71
+ local values ;
72
+
73
+ if $(split[3])
74
+ {
75
+ values = $(split[4]) ;
76
+ }
77
+ if $(args) && ! [ MATCH ^(--).* : $(args[1]) ]
78
+ {
79
+ values += $(args[1]) ;
80
+ args = $(args[2-]) ;
81
+ }
82
+
83
+ # Jook in options subdirectories of BOOST_BUILD_PATH for modules
84
+ # matching the full option name and then its prefix.
85
+ local plugin-dir = options ;
86
+ local option-files = [ GLOB $(plugin-dir:D=$(BOOST_BUILD_PATH)) :
87
+ $(full-name).jam $(prefix).jam ] ;
88
+
89
+ if $(option-files)
90
+ {
91
+ # Load the file into a module named for the option.
92
+ local f = $(option-files[1]) ;
93
+ local module-name = --$(f:D=:S=) ;
94
+ modules.load $(module-name) : $(f:D=) : $(f:D) ;
95
+
96
+ # If there is a process rule, call it with the full option name
97
+ # and its value (if any). If there was no "=" in the option, the
98
+ # value will be empty.
99
+ if process in [ RULENAMES $(module-name) ]
100
+ {
101
+ dont-build += [ modules.call-in $(module-name) : process
102
+ --$(full-name) : $(values) ] ;
103
+ }
104
+ }
105
+ }
106
+ }
107
+
108
+ return $(dont-build) ;
109
+ }
mosesdecoder/jam-files/boost-build/util/os.jam ADDED
@@ -0,0 +1,171 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2001, 2002, 2003, 2005 Dave Abrahams
2
+ # Copyright 2006 Rene Rivera
3
+ # Copyright 2003, 2005 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 modules ;
8
+ import string ;
9
+
10
+
11
+ # Return the value(s) of the given environment variable(s) at the time bjam was
12
+ # invoked.
13
+ rule environ ( variable-names + )
14
+ {
15
+ return [ modules.peek .ENVIRON : $(variable-names) ] ;
16
+ }
17
+
18
+ .name = [ modules.peek : OS ] ;
19
+ .platform = [ modules.peek : OSPLAT ] ;
20
+ .version = [ modules.peek : OSVER ] ;
21
+
22
+
23
+ local rule constant ( c : os ? )
24
+ {
25
+ os ?= $(.name) ;
26
+ # First look for a platform-specific name, then the general value.
27
+ local variables = .$(c)-$(os) .$(c) ;
28
+ local result = $($(variables)) ;
29
+ return $(result[1]) ;
30
+ }
31
+
32
+ rule get-constant ( os ? )
33
+ {
34
+ # Find the name of the constant being accessed, which is equal to the name
35
+ # used to invoke us.
36
+ local bt = [ BACKTRACE 1 ] ;
37
+ local rulename = [ MATCH ([^.]*)$ : $(bt[4]) ] ;
38
+ return [ constant $(rulename) : $(os) ] ;
39
+ }
40
+
41
+
42
+ # export all the common constants
43
+ .constants = name platform version shared-library-path-variable path-separator executable-path-variable executable-suffix ;
44
+ for local constant in $(.constants)
45
+ {
46
+ IMPORT $(__name__) : get-constant : $(__name__) : $(constant) ;
47
+ }
48
+ EXPORT $(__name__) : $(.constants) ;
49
+
50
+ .executable-path-variable-NT = PATH ;
51
+ # On Windows the case and capitalization of PATH is not always predictable, so
52
+ # let's find out what variable name was really set.
53
+ if $(.name) = NT
54
+ {
55
+ for local n in [ VARNAMES .ENVIRON ]
56
+ {
57
+ if $(n:L) = path
58
+ {
59
+ .executable-path-variable-NT = $(n) ;
60
+ }
61
+ }
62
+ }
63
+
64
+ # Specific constants for various platforms. There's no need to define any
65
+ # constant whose value would be the same as the default, below.
66
+ .shared-library-path-variable-NT = $(.executable-path-variable-NT) ;
67
+ .path-separator-NT = ";" ;
68
+ .expand-variable-prefix-NT = % ;
69
+ .expand-variable-suffix-NT = % ;
70
+ .executable-suffix-NT = .exe ;
71
+
72
+ .shared-library-path-variable-CYGWIN = PATH ;
73
+
74
+ .shared-library-path-variable-MACOSX = DYLD_LIBRARY_PATH ;
75
+
76
+ .shared-library-path-variable-AIX = LIBPATH ;
77
+
78
+ # Default constants
79
+ .shared-library-path-variable = LD_LIBRARY_PATH ;
80
+ .path-separator = ":" ;
81
+ .expand-variable-prefix = $ ;
82
+ .expand-variable-suffix = "" ;
83
+ .executable-path-variable = PATH ;
84
+ .executable-suffix = "" ;
85
+
86
+
87
+ # Return a list of the directories in the PATH. Yes, that information is (sort
88
+ # of) available in the global module, but jam code can change those values, and
89
+ # it isn't always clear what case/capitalization to use when looking. This rule
90
+ # is a more reliable way to get there.
91
+ rule executable-path ( )
92
+ {
93
+ return [ string.words [ environ [ constant executable-path-variable ] ]
94
+ : [ constant path-separator ] ] ;
95
+ }
96
+
97
+
98
+ # Initialize the list of home directories for the current user depending on the
99
+ # OS.
100
+ if $(.name) = NT
101
+ {
102
+ local home = [ environ HOMEDRIVE HOMEPATH ] ;
103
+ .home-directories = $(home[1])$(home[2]) [ environ HOME ] [ environ USERPROFILE ] ;
104
+ }
105
+ else
106
+ {
107
+ .home-directories = [ environ HOME ] ;
108
+ }
109
+
110
+
111
+ # Can't use 'constant' mechanism because it only returns 1-element values.
112
+ rule home-directories ( )
113
+ {
114
+ return $(.home-directories) ;
115
+ }
116
+
117
+
118
+ # Return the string needed to represent the expansion of the named shell
119
+ # variable.
120
+ rule expand-variable ( variable )
121
+ {
122
+ local prefix = [ constant expand-variable-prefix ] ;
123
+ local suffix = [ constant expand-variable-suffix ] ;
124
+ return $(prefix)$(variable)$(suffix) ;
125
+ }
126
+
127
+
128
+ # Returns true if running on windows, whether in cygwin or not.
129
+ rule on-windows ( )
130
+ {
131
+ local result ;
132
+ if [ modules.peek : NT ]
133
+ {
134
+ result = true ;
135
+ }
136
+ else if [ modules.peek : UNIX ]
137
+ {
138
+ switch [ modules.peek : JAMUNAME ]
139
+ {
140
+ case CYGWIN* :
141
+ {
142
+ result = true ;
143
+ }
144
+ }
145
+ }
146
+ return $(result) ;
147
+ }
148
+
149
+
150
+ if ! [ on-windows ]
151
+ {
152
+ .on-unix = 1 ;
153
+ }
154
+
155
+
156
+ rule on-unix
157
+ {
158
+ return $(.on-unix) ;
159
+ }
160
+
161
+
162
+ rule __test__
163
+ {
164
+ import assert ;
165
+ if ! ( --quiet in [ modules.peek : ARGV ] )
166
+ {
167
+ ECHO os: name= [ name ] ;
168
+ ECHO os: version= [ version ] ;
169
+ }
170
+ assert.true name ;
171
+ }
mosesdecoder/jam-files/boost-build/util/path.jam ADDED
@@ -0,0 +1,934 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright Vladimir Prus 2002-2006.
2
+ # Copyright Dave Abrahams 2003-2004.
3
+ # Copyright Rene Rivera 2003-2006.
4
+ #
5
+ # Distributed under the Boost Software License, Version 1.0.
6
+ # (See accompanying file LICENSE_1_0.txt or copy at
7
+ # http://www.boost.org/LICENSE_1_0.txt)
8
+
9
+ # Performs various path manipulations. Paths are always in a 'normalized'
10
+ # representation. In it, a path may be either:
11
+ #
12
+ # - '.', or
13
+ #
14
+ # - ['/'] [ ( '..' '/' )* (token '/')* token ]
15
+ #
16
+ # In plain english, path can be rooted, '..' elements are allowed only at the
17
+ # beginning, and it never ends in slash, except for path consisting of slash
18
+ # only.
19
+
20
+ import errors ;
21
+ import modules ;
22
+ import regex ;
23
+ import sequence ;
24
+ import set ;
25
+ import version ;
26
+
27
+
28
+ os = [ modules.peek : OS ] ;
29
+ if [ modules.peek : UNIX ]
30
+ {
31
+ local uname = [ modules.peek : JAMUNAME ] ;
32
+ switch $(uname)
33
+ {
34
+ case CYGWIN* : os = CYGWIN ;
35
+ case * : os = UNIX ;
36
+ }
37
+ }
38
+
39
+
40
+ # Converts the native path into normalized form.
41
+ #
42
+ rule make ( native )
43
+ {
44
+ return [ make-$(os) $(native) ] ;
45
+ }
46
+
47
+
48
+ # Builds native representation of the path.
49
+ #
50
+ rule native ( path )
51
+ {
52
+ return [ native-$(os) $(path) ] ;
53
+ }
54
+
55
+
56
+ # Tests if a path is rooted.
57
+ #
58
+ rule is-rooted ( path )
59
+ {
60
+ return [ MATCH "^(/)" : $(path) ] ;
61
+ }
62
+
63
+
64
+ # Tests if a path has a parent.
65
+ #
66
+ rule has-parent ( path )
67
+ {
68
+ if $(path) != /
69
+ {
70
+ return 1 ;
71
+ }
72
+ else
73
+ {
74
+ return ;
75
+ }
76
+ }
77
+
78
+
79
+ # Returns the path without any directory components.
80
+ #
81
+ rule basename ( path )
82
+ {
83
+ return [ MATCH "([^/]+)$" : $(path) ] ;
84
+ }
85
+
86
+
87
+ # Returns parent directory of the path. If no parent exists, error is issued.
88
+ #
89
+ rule parent ( path )
90
+ {
91
+ if [ has-parent $(path) ]
92
+ {
93
+ if $(path) = .
94
+ {
95
+ return .. ;
96
+ }
97
+ else
98
+ {
99
+ # Strip everything at the end of path up to and including the last
100
+ # slash.
101
+ local result = [ regex.match "((.*)/)?([^/]+)" : $(path) : 2 3 ] ;
102
+
103
+ # Did we strip what we shouldn't?
104
+ if $(result[2]) = ".."
105
+ {
106
+ return $(path)/.. ;
107
+ }
108
+ else
109
+ {
110
+ if ! $(result[1])
111
+ {
112
+ if [ is-rooted $(path) ]
113
+ {
114
+ result = / ;
115
+ }
116
+ else
117
+ {
118
+ result = . ;
119
+ }
120
+ }
121
+ return $(result[1]) ;
122
+ }
123
+ }
124
+ }
125
+ else
126
+ {
127
+ errors.error "Path '$(path)' has no parent" ;
128
+ }
129
+ }
130
+
131
+
132
+ # Returns path2 such that "[ join path path2 ] = .". The path may not contain
133
+ # ".." element or be rooted.
134
+ #
135
+ rule reverse ( path )
136
+ {
137
+ if $(path) = .
138
+ {
139
+ return $(path) ;
140
+ }
141
+ else
142
+ {
143
+ local tokens = [ regex.split $(path) "/" ] ;
144
+ local tokens2 ;
145
+ for local i in $(tokens)
146
+ {
147
+ tokens2 += .. ;
148
+ }
149
+ return [ sequence.join $(tokens2) : "/" ] ;
150
+ }
151
+ }
152
+
153
+
154
+ # Concatenates the passed path elements. Generates an error if any element other
155
+ # than the first one is rooted. Skips any empty or undefined path elements.
156
+ #
157
+ rule join ( elements + )
158
+ {
159
+ if ! $(elements[2-])
160
+ {
161
+ return $(elements[1]) ;
162
+ }
163
+ else
164
+ {
165
+ for local e in $(elements[2-])
166
+ {
167
+ if [ is-rooted $(e) ]
168
+ {
169
+ errors.error only the first element may be rooted ;
170
+ }
171
+ }
172
+ if [ version.check-jam-version 3 1 17 ]
173
+ {
174
+ return [ NORMALIZE_PATH "$(elements)" ] ;
175
+ }
176
+ else
177
+ {
178
+ # Boost Jam prior to version 3.1.17 had problems with its
179
+ # NORMALIZE_PATH rule in case you passed it a leading backslash
180
+ # instead of a slash, in some cases when you sent it an empty
181
+ # initial path element and possibly some others. At least some of
182
+ # those cases were being hit and relied upon when calling this rule
183
+ # from the path.make-NT rule.
184
+ if ! $(elements[1]) && $(elements[2])
185
+ {
186
+ return [ NORMALIZE_PATH "/" "$(elements[2-])" ] ;
187
+ }
188
+ else
189
+ {
190
+ return [ NORMALIZE_PATH "$(elements)" ] ;
191
+ }
192
+ }
193
+ }
194
+ }
195
+
196
+
197
+ # If 'path' is relative, it is rooted at 'root'. Otherwise, it is unchanged.
198
+ #
199
+ rule root ( path root )
200
+ {
201
+ if [ is-rooted $(path) ]
202
+ {
203
+ return $(path) ;
204
+ }
205
+ else
206
+ {
207
+ return [ join $(root) $(path) ] ;
208
+ }
209
+ }
210
+
211
+
212
+ # Returns the current working directory.
213
+ #
214
+ rule pwd ( )
215
+ {
216
+ if ! $(.pwd)
217
+ {
218
+ .pwd = [ make [ PWD ] ] ;
219
+ }
220
+ return $(.pwd) ;
221
+ }
222
+
223
+
224
+ # Returns the list of files matching the given pattern in the specified
225
+ # directory. Both directories and patterns are supplied as portable paths. Each
226
+ # pattern should be non-absolute path, and can't contain "." or ".." elements.
227
+ # Each slash separated element of pattern can contain the following special
228
+ # characters:
229
+ # - '?', which match any character
230
+ # - '*', which matches arbitrary number of characters.
231
+ # A file $(d)/e1/e2/e3 (where 'd' is in $(dirs)) matches pattern p1/p2/p3 if and
232
+ # only if e1 matches p1, e2 matches p2 and so on.
233
+ #
234
+ # For example:
235
+ # [ glob . : *.cpp ]
236
+ # [ glob . : */build/Jamfile ]
237
+ #
238
+ rule glob ( dirs * : patterns + : exclude-patterns * )
239
+ {
240
+ local result ;
241
+ local real-patterns ;
242
+ local real-exclude-patterns ;
243
+ for local d in $(dirs)
244
+ {
245
+ for local p in $(patterns)
246
+ {
247
+ local pattern = [ path.root $(p) $(d) ] ;
248
+ real-patterns += [ path.native $(pattern) ] ;
249
+ }
250
+
251
+ for local p in $(exclude-patterns)
252
+ {
253
+ local pattern = [ path.root $(p) $(d) ] ;
254
+ real-exclude-patterns += [ path.native $(pattern) ] ;
255
+ }
256
+ }
257
+
258
+ local inc = [ GLOB-RECURSIVELY $(real-patterns) ] ;
259
+ inc = [ sequence.transform NORMALIZE_PATH : $(inc) ] ;
260
+ local exc = [ GLOB-RECURSIVELY $(real-exclude-patterns) ] ;
261
+ exc = [ sequence.transform NORMALIZE_PATH : $(exc) ] ;
262
+
263
+ return [ sequence.transform path.make : [ set.difference $(inc) : $(exc) ] ]
264
+ ;
265
+ }
266
+
267
+
268
+ # Recursive version of GLOB. Builds the glob of files while also searching in
269
+ # the subdirectories of the given roots. An optional set of exclusion patterns
270
+ # will filter out the matching entries from the result. The exclusions also
271
+ # apply to the subdirectory scanning, such that directories that match the
272
+ # exclusion patterns will not be searched.
273
+ #
274
+ rule glob-tree ( roots * : patterns + : exclude-patterns * )
275
+ {
276
+ return [ sequence.transform path.make : [ .glob-tree [ sequence.transform
277
+ path.native : $(roots) ] : $(patterns) : $(exclude-patterns) ] ] ;
278
+ }
279
+
280
+
281
+ local rule .glob-tree ( roots * : patterns * : exclude-patterns * )
282
+ {
283
+ local excluded ;
284
+ if $(exclude-patterns)
285
+ {
286
+ excluded = [ GLOB $(roots) : $(exclude-patterns) ] ;
287
+ }
288
+ local result = [ set.difference [ GLOB $(roots) : $(patterns) ] :
289
+ $(excluded) ] ;
290
+ local subdirs ;
291
+ for local d in [ set.difference [ GLOB $(roots) : * ] : $(excluded) ]
292
+ {
293
+ if ! ( $(d:D=) in . .. ) && ! [ CHECK_IF_FILE $(d) ]
294
+ {
295
+ subdirs += $(d) ;
296
+ }
297
+ }
298
+ if $(subdirs)
299
+ {
300
+ result += [ .glob-tree $(subdirs) : $(patterns) : $(exclude-patterns) ]
301
+ ;
302
+ }
303
+ return $(result) ;
304
+ }
305
+
306
+
307
+ # Returns true is the specified file exists.
308
+ #
309
+ rule exists ( file )
310
+ {
311
+ return [ path.glob $(file:D) : $(file:D=) ] ;
312
+ }
313
+ NATIVE_RULE path : exists ;
314
+
315
+
316
+ # Find out the absolute name of path and returns the list of all the parents,
317
+ # starting with the immediate one. Parents are returned as relative names. If
318
+ # 'upper_limit' is specified, directories above it will be pruned.
319
+ #
320
+ rule all-parents ( path : upper_limit ? : cwd ? )
321
+ {
322
+ cwd ?= [ pwd ] ;
323
+ local path_ele = [ regex.split [ root $(path) $(cwd) ] "/" ] ;
324
+
325
+ if ! $(upper_limit)
326
+ {
327
+ upper_limit = / ;
328
+ }
329
+ local upper_ele = [ regex.split [ root $(upper_limit) $(cwd) ] "/" ] ;
330
+
331
+ # Leave only elements in 'path_ele' below 'upper_ele'.
332
+ while $(path_ele) && ( $(upper_ele[1]) = $(path_ele[1]) )
333
+ {
334
+ upper_ele = $(upper_ele[2-]) ;
335
+ path_ele = $(path_ele[2-]) ;
336
+ }
337
+
338
+ # Have all upper elements been removed ?
339
+ if $(upper_ele)
340
+ {
341
+ errors.error "$(upper_limit) is not prefix of $(path)" ;
342
+ }
343
+
344
+ # Create the relative paths to parents, number of elements in 'path_ele'.
345
+ local result ;
346
+ for local i in $(path_ele)
347
+ {
348
+ path = [ parent $(path) ] ;
349
+ result += $(path) ;
350
+ }
351
+ return $(result) ;
352
+ }
353
+
354
+
355
+ # Search for 'pattern' in parent directories of 'dir', up till and including
356
+ # 'upper_limit', if it is specified, or till the filesystem root otherwise.
357
+ #
358
+ rule glob-in-parents ( dir : patterns + : upper-limit ? )
359
+ {
360
+ local result ;
361
+ local parent-dirs = [ all-parents $(dir) : $(upper-limit) ] ;
362
+
363
+ while $(parent-dirs) && ! $(result)
364
+ {
365
+ result = [ glob $(parent-dirs[1]) : $(patterns) ] ;
366
+ parent-dirs = $(parent-dirs[2-]) ;
367
+ }
368
+ return $(result) ;
369
+ }
370
+
371
+
372
+ # Assuming 'child' is a subdirectory of 'parent', return the relative path from
373
+ # 'parent' to 'child'.
374
+ #
375
+ rule relative ( child parent : no-error ? )
376
+ {
377
+ local not-a-child ;
378
+ if $(parent) = "."
379
+ {
380
+ return $(child) ;
381
+ }
382
+ else
383
+ {
384
+ local split1 = [ regex.split $(parent) / ] ;
385
+ local split2 = [ regex.split $(child) / ] ;
386
+
387
+ while $(split1)
388
+ {
389
+ if $(split1[1]) = $(split2[1])
390
+ {
391
+ split1 = $(split1[2-]) ;
392
+ split2 = $(split2[2-]) ;
393
+ }
394
+ else
395
+ {
396
+ not-a-child = true ;
397
+ split1 = ;
398
+ }
399
+ }
400
+ if $(split2)
401
+ {
402
+ if $(not-a-child)
403
+ {
404
+ if $(no-error)
405
+ {
406
+ return not-a-child ;
407
+ }
408
+ else
409
+ {
410
+ errors.error $(child) is not a subdir of $(parent) ;
411
+ }
412
+ }
413
+ else
414
+ {
415
+ return [ join $(split2) ] ;
416
+ }
417
+ }
418
+ else
419
+ {
420
+ return "." ;
421
+ }
422
+ }
423
+ }
424
+
425
+
426
+ # Returns the minimal path to path2 that is relative path1.
427
+ #
428
+ rule relative-to ( path1 path2 )
429
+ {
430
+ local root_1 = [ regex.split [ reverse $(path1) ] / ] ;
431
+ local split1 = [ regex.split $(path1) / ] ;
432
+ local split2 = [ regex.split $(path2) / ] ;
433
+
434
+ while $(split1) && $(root_1)
435
+ {
436
+ if $(split1[1]) = $(split2[1])
437
+ {
438
+ root_1 = $(root_1[2-]) ;
439
+ split1 = $(split1[2-]) ;
440
+ split2 = $(split2[2-]) ;
441
+ }
442
+ else
443
+ {
444
+ split1 = ;
445
+ }
446
+ }
447
+ return [ join . $(root_1) $(split2) ] ;
448
+ }
449
+
450
+
451
+ # Returns the list of paths which are used by the operating system for looking
452
+ # up programs.
453
+ #
454
+ rule programs-path ( )
455
+ {
456
+ local result ;
457
+ local raw = [ modules.peek : PATH Path path ] ;
458
+ for local p in $(raw)
459
+ {
460
+ if $(p)
461
+ {
462
+ result += [ path.make $(p) ] ;
463
+ }
464
+ }
465
+ return $(result) ;
466
+ }
467
+
468
+ rule makedirs ( path )
469
+ {
470
+ local result = true ;
471
+ local native = [ native $(path) ] ;
472
+ if ! [ exists $(native) ]
473
+ {
474
+ if [ makedirs [ parent $(path) ] ]
475
+ {
476
+ if ! [ MAKEDIR $(native) ]
477
+ {
478
+ errors.error "Could not create directory '$(path)'" ;
479
+ result = ;
480
+ }
481
+ }
482
+ }
483
+ return $(result) ;
484
+ }
485
+
486
+ # Converts native Windows paths into our internal canonic path representation.
487
+ # Supports 'invalid' paths containing multiple successive path separator
488
+ # characters.
489
+ #
490
+ # TODO: Check and if needed add support for Windows 'X:file' path format where
491
+ # the file is located in the current folder on drive X.
492
+ #
493
+ rule make-NT ( native )
494
+ {
495
+ local result ;
496
+
497
+ if [ version.check-jam-version 3 1 17 ]
498
+ {
499
+ result = [ NORMALIZE_PATH $(native) ] ;
500
+ }
501
+ else
502
+ {
503
+ # This old implementation is really fragile due to a not so clear way
504
+ # NORMALIZE_PATH rule worked in Boost.Jam versions prior to 3.1.17. E.g.
505
+ # path.join would mostly ignore empty path elements but would root the
506
+ # joined path in case the initial two path elements were empty or some
507
+ # similar accidental wierdness.
508
+ result = [ path.join [ regex.split $(native) "[/\\]" ] ] ;
509
+ }
510
+
511
+ # We need to add an extra '/' in front in case this is a rooted Windows path
512
+ # starting with a drive letter and not a path separator character since the
513
+ # builtin NORMALIZE_PATH rule has no knowledge of this leading drive letter
514
+ # and treats it as a regular folder name.
515
+ if [ regex.match "(^.:)" : $(native) ]
516
+ {
517
+ result = /$(result) ;
518
+ }
519
+
520
+ return $(result) ;
521
+ }
522
+
523
+
524
+ rule native-NT ( path )
525
+ {
526
+ local result ;
527
+ if [ is-rooted $(path) ] && ! [ regex.match "^/(.:)" : $(path) ]
528
+ {
529
+ result = $(path) ;
530
+ }
531
+ else
532
+ {
533
+ result = [ MATCH "^/?(.*)" : $(path) ] ;
534
+ }
535
+ result = [ sequence.join [ regex.split $(result) "/" ] : "\\" ] ;
536
+ return $(result) ;
537
+ }
538
+
539
+
540
+ rule make-UNIX ( native )
541
+ {
542
+ # VP: I have no idea now 'native' can be empty here! But it can!
543
+ if ! $(native)
544
+ {
545
+ errors.error "Empty path passed to 'make-UNIX'" ;
546
+ }
547
+ else
548
+ {
549
+ return [ NORMALIZE_PATH $(native:T) ] ;
550
+ }
551
+ }
552
+
553
+
554
+ rule native-UNIX ( path )
555
+ {
556
+ return $(path) ;
557
+ }
558
+
559
+
560
+ rule make-CYGWIN ( path )
561
+ {
562
+ return [ make-NT $(path) ] ;
563
+ }
564
+
565
+
566
+ rule native-CYGWIN ( path )
567
+ {
568
+ local result = $(path) ;
569
+ if [ regex.match "(^/.:)" : $(path) ] # Windows absolute path.
570
+ {
571
+ result = [ MATCH "^/?(.*)" : $(path) ] ; # Remove leading '/'.
572
+ }
573
+ return [ native-UNIX $(result) ] ;
574
+ }
575
+
576
+
577
+ # split-path-VMS: splits input native path into device dir file (each part is
578
+ # optional).
579
+ #
580
+ # example:
581
+ #
582
+ # dev:[dir]file.c => dev: [dir] file.c
583
+ #
584
+ rule split-path-VMS ( native )
585
+ {
586
+ local matches = [ MATCH ([a-zA-Z0-9_-]+:)?(\\[[^\]]*\\])?(.*)?$ : $(native) ] ;
587
+ local device = $(matches[1]) ;
588
+ local dir = $(matches[2]) ;
589
+ local file = $(matches[3]) ;
590
+
591
+ return $(device) $(dir) $(file) ;
592
+ }
593
+
594
+
595
+ # Converts a native VMS path into a portable path spec.
596
+ #
597
+ # Does not handle current-device absolute paths such as "[dir]File.c" as it is
598
+ # not clear how to represent them in the portable path notation.
599
+ #
600
+ # Adds a trailing dot (".") to the file part if no extension is present (helps
601
+ # when converting it back into native path).
602
+ #
603
+ rule make-VMS ( native )
604
+ {
605
+ if [ MATCH ^(\\[[a-zA-Z0-9]) : $(native) ]
606
+ {
607
+ errors.error "Can't handle default-device absolute paths: " $(native) ;
608
+ }
609
+
610
+ local parts = [ split-path-VMS $(native) ] ;
611
+ local device = $(parts[1]) ;
612
+ local dir = $(parts[2]) ;
613
+ local file = $(parts[3]) ;
614
+ local elems ;
615
+
616
+ if $(device)
617
+ {
618
+ #
619
+ # rooted
620
+ #
621
+ elems = /$(device) ;
622
+ }
623
+
624
+ if $(dir) = "[]"
625
+ {
626
+ #
627
+ # Special case: current directory
628
+ #
629
+ elems = $(elems) "." ;
630
+ }
631
+ else if $(dir)
632
+ {
633
+ dir = [ regex.replace $(dir) "\\[|\\]" "" ] ;
634
+ local dir_parts = [ regex.split $(dir) \\. ] ;
635
+
636
+ if $(dir_parts[1]) = ""
637
+ {
638
+ #
639
+ # Relative path
640
+ #
641
+ dir_parts = $(dir_parts[2--1]) ;
642
+ }
643
+
644
+ #
645
+ # replace "parent-directory" parts (- => ..)
646
+ #
647
+ dir_parts = [ regex.replace-list $(dir_parts) : - : .. ] ;
648
+
649
+ elems = $(elems) $(dir_parts) ;
650
+ }
651
+
652
+ if $(file)
653
+ {
654
+ if ! [ MATCH (\\.) : $(file) ]
655
+ {
656
+ #
657
+ # Always add "." to end of non-extension file.
658
+ #
659
+ file = $(file). ;
660
+ }
661
+ elems = $(elems) $(file) ;
662
+ }
663
+
664
+ local portable = [ path.join $(elems) ] ;
665
+
666
+ return $(portable) ;
667
+ }
668
+
669
+
670
+ # Converts a portable path spec into a native VMS path.
671
+ #
672
+ # Relies on having at least one dot (".") included in the file name to be able
673
+ # to differentiate it from the directory part.
674
+ #
675
+ rule native-VMS ( path )
676
+ {
677
+ local device = "" ;
678
+ local dir = $(path) ;
679
+ local file = "" ;
680
+ local native ;
681
+ local split ;
682
+
683
+ #
684
+ # Has device ?
685
+ #
686
+ if [ is-rooted $(dir) ]
687
+ {
688
+ split = [ MATCH ^/([^:]+:)/?(.*) : $(dir) ] ;
689
+ device = $(split[1]) ;
690
+ dir = $(split[2]) ;
691
+ }
692
+
693
+ #
694
+ # Has file ?
695
+ #
696
+ # This is no exact science, just guess work:
697
+ #
698
+ # If the last part of the current path spec
699
+ # includes some chars, followed by a dot,
700
+ # optionally followed by more chars -
701
+ # then it is a file (keep your fingers crossed).
702
+ #
703
+ split = [ regex.split $(dir) / ] ;
704
+ local maybe_file = $(split[-1]) ;
705
+
706
+ if [ MATCH ^([^.]+\\..*) : $(maybe_file) ]
707
+ {
708
+ file = $(maybe_file) ;
709
+ dir = [ sequence.join $(split[1--2]) : / ] ;
710
+ }
711
+
712
+ #
713
+ # Has dir spec ?
714
+ #
715
+ if $(dir) = "."
716
+ {
717
+ dir = "[]" ;
718
+ }
719
+ else if $(dir)
720
+ {
721
+ dir = [ regex.replace $(dir) \\.\\. - ] ;
722
+ dir = [ regex.replace $(dir) / . ] ;
723
+
724
+ if $(device) = ""
725
+ {
726
+ #
727
+ # Relative directory
728
+ #
729
+ dir = "."$(dir) ;
730
+ }
731
+ dir = "["$(dir)"]" ;
732
+ }
733
+
734
+ native = [ sequence.join $(device) $(dir) $(file) ] ;
735
+
736
+ return $(native) ;
737
+ }
738
+
739
+
740
+ rule __test__ ( )
741
+ {
742
+ import assert ;
743
+ import errors : try catch ;
744
+
745
+ assert.true is-rooted "/" ;
746
+ assert.true is-rooted "/foo" ;
747
+ assert.true is-rooted "/foo/bar" ;
748
+ assert.result : is-rooted "." ;
749
+ assert.result : is-rooted "foo" ;
750
+ assert.result : is-rooted "foo/bar" ;
751
+
752
+ assert.true has-parent "foo" ;
753
+ assert.true has-parent "foo/bar" ;
754
+ assert.true has-parent "." ;
755
+ assert.result : has-parent "/" ;
756
+
757
+ assert.result "." : basename "." ;
758
+ assert.result ".." : basename ".." ;
759
+ assert.result "foo" : basename "foo" ;
760
+ assert.result "foo" : basename "bar/foo" ;
761
+ assert.result "foo" : basename "gaz/bar/foo" ;
762
+ assert.result "foo" : basename "/gaz/bar/foo" ;
763
+
764
+ assert.result "." : parent "foo" ;
765
+ assert.result "/" : parent "/foo" ;
766
+ assert.result "foo/bar" : parent "foo/bar/giz" ;
767
+ assert.result ".." : parent "." ;
768
+ assert.result ".." : parent "../foo" ;
769
+ assert.result "../../foo" : parent "../../foo/bar" ;
770
+
771
+ assert.result "." : reverse "." ;
772
+ assert.result ".." : reverse "foo" ;
773
+ assert.result "../../.." : reverse "foo/bar/giz" ;
774
+
775
+ assert.result "foo" : join "foo" ;
776
+ assert.result "/foo" : join "/" "foo" ;
777
+ assert.result "foo/bar" : join "foo" "bar" ;
778
+ assert.result "foo/bar" : join "foo/giz" "../bar" ;
779
+ assert.result "foo/giz" : join "foo/bar/baz" "../../giz" ;
780
+ assert.result ".." : join "." ".." ;
781
+ assert.result ".." : join "foo" "../.." ;
782
+ assert.result "../.." : join "../foo" "../.." ;
783
+ assert.result "/foo" : join "/bar" "../foo" ;
784
+ assert.result "foo/giz" : join "foo/giz" "." ;
785
+ assert.result "." : join lib2 ".." ;
786
+ assert.result "/" : join "/a" ".." ;
787
+
788
+ assert.result /a/b : join /a/b/c .. ;
789
+
790
+ assert.result "foo/bar/giz" : join "foo" "bar" "giz" ;
791
+ assert.result "giz" : join "foo" ".." "giz" ;
792
+ assert.result "foo/giz" : join "foo" "." "giz" ;
793
+
794
+ try ;
795
+ {
796
+ join "a" "/b" ;
797
+ }
798
+ catch only first element may be rooted ;
799
+
800
+ local CWD = "/home/ghost/build" ;
801
+ assert.result : all-parents . : . : $(CWD) ;
802
+ assert.result . .. ../.. ../../.. : all-parents "Jamfile" : "" : $(CWD) ;
803
+ assert.result foo . .. ../.. ../../.. : all-parents "foo/Jamfile" : "" : $(CWD) ;
804
+ assert.result ../Work .. ../.. ../../.. : all-parents "../Work/Jamfile" : "" : $(CWD) ;
805
+
806
+ local CWD = "/home/ghost" ;
807
+ assert.result . .. : all-parents "Jamfile" : "/home" : $(CWD) ;
808
+ assert.result . : all-parents "Jamfile" : "/home/ghost" : $(CWD) ;
809
+
810
+ assert.result "c/d" : relative "a/b/c/d" "a/b" ;
811
+ assert.result "foo" : relative "foo" "." ;
812
+
813
+ local save-os = [ modules.peek path : os ] ;
814
+ modules.poke path : os : NT ;
815
+
816
+ assert.result "foo/bar/giz" : make "foo/bar/giz" ;
817
+ assert.result "foo/bar/giz" : make "foo\\bar\\giz" ;
818
+ assert.result "foo" : make "foo/" ;
819
+ assert.result "foo" : make "foo\\" ;
820
+ assert.result "foo" : make "foo/." ;
821
+ assert.result "foo" : make "foo/bar/.." ;
822
+ assert.result "foo" : make "foo/bar/../" ;
823
+ assert.result "foo" : make "foo/bar/..\\" ;
824
+ assert.result "foo/bar" : make "foo/././././bar" ;
825
+ assert.result "/foo" : make "\\foo" ;
826
+ assert.result "/D:/My Documents" : make "D:\\My Documents" ;
827
+ assert.result "/c:/boost/tools/build/new/project.jam" : make "c:\\boost\\tools\\build\\test\\..\\new\\project.jam" ;
828
+
829
+ # Test processing 'invalid' paths containing multiple successive path
830
+ # separators.
831
+ assert.result "foo" : make "foo//" ;
832
+ assert.result "foo" : make "foo///" ;
833
+ assert.result "foo" : make "foo\\\\" ;
834
+ assert.result "foo" : make "foo\\\\\\" ;
835
+ assert.result "/foo" : make "//foo" ;
836
+ assert.result "/foo" : make "///foo" ;
837
+ assert.result "/foo" : make "\\\\foo" ;
838
+ assert.result "/foo" : make "\\\\\\foo" ;
839
+ assert.result "/foo" : make "\\/\\/foo" ;
840
+ assert.result "foo/bar" : make "foo//\\//\\\\bar//\\//\\\\\\//\\//\\\\" ;
841
+ assert.result "foo" : make "foo/bar//.." ;
842
+ assert.result "foo/bar" : make "foo/bar/giz//.." ;
843
+ assert.result "foo/giz" : make "foo//\\//\\\\bar///\\\\//\\\\////\\/..///giz\\//\\\\\\//\\//\\\\" ;
844
+ assert.result "../../../foo" : make "..///.//..///.//..////foo///" ;
845
+
846
+ # Test processing 'invalid' rooted paths with too many '..' path elements
847
+ # that would place them before the root.
848
+ assert.result : make "/.." ;
849
+ assert.result : make "/../" ;
850
+ assert.result : make "/../." ;
851
+ assert.result : make "/.././" ;
852
+ assert.result : make "/foo/../bar/giz/.././././../../." ;
853
+ assert.result : make "/foo/../bar/giz/.././././../.././" ;
854
+ assert.result : make "//foo/../bar/giz/.././././../../." ;
855
+ assert.result : make "//foo/../bar/giz/.././././../.././" ;
856
+ assert.result : make "\\\\foo/../bar/giz/.././././../../." ;
857
+ assert.result : make "\\\\foo/../bar/giz/.././././../.././" ;
858
+ assert.result : make "/..///.//..///.//..////foo///" ;
859
+
860
+ assert.result "foo\\bar\\giz" : native "foo/bar/giz" ;
861
+ assert.result "foo" : native "foo" ;
862
+ assert.result "\\foo" : native "/foo" ;
863
+ assert.result "D:\\My Documents\\Work" : native "/D:/My Documents/Work" ;
864
+
865
+ modules.poke path : os : UNIX ;
866
+
867
+ assert.result "foo/bar/giz" : make "foo/bar/giz" ;
868
+ assert.result "/sub1" : make "/sub1/." ;
869
+ assert.result "/sub1" : make "/sub1/sub2/.." ;
870
+ assert.result "sub1" : make "sub1/." ;
871
+ assert.result "sub1" : make "sub1/sub2/.." ;
872
+ assert.result "/foo/bar" : native "/foo/bar" ;
873
+
874
+ modules.poke path : os : VMS ;
875
+
876
+ #
877
+ # Don't really need to poke os before these
878
+ #
879
+ assert.result "disk:" "[dir]" "file" : split-path-VMS "disk:[dir]file" ;
880
+ assert.result "disk:" "[dir]" "" : split-path-VMS "disk:[dir]" ;
881
+ assert.result "disk:" "" "" : split-path-VMS "disk:" ;
882
+ assert.result "disk:" "" "file" : split-path-VMS "disk:file" ;
883
+ assert.result "" "[dir]" "file" : split-path-VMS "[dir]file" ;
884
+ assert.result "" "[dir]" "" : split-path-VMS "[dir]" ;
885
+ assert.result "" "" "file" : split-path-VMS "file" ;
886
+ assert.result "" "" "" : split-path-VMS "" ;
887
+
888
+ #
889
+ # Special case: current directory
890
+ #
891
+ assert.result "" "[]" "" : split-path-VMS "[]" ;
892
+ assert.result "disk:" "[]" "" : split-path-VMS "disk:[]" ;
893
+ assert.result "" "[]" "file" : split-path-VMS "[]file" ;
894
+ assert.result "disk:" "[]" "file" : split-path-VMS "disk:[]file" ;
895
+
896
+ #
897
+ # Make portable paths
898
+ #
899
+ assert.result "/disk:" : make "disk:" ;
900
+ assert.result "foo/bar/giz" : make "[.foo.bar.giz]" ;
901
+ assert.result "foo" : make "[.foo]" ;
902
+ assert.result "foo" : make "[.foo.bar.-]" ;
903
+ assert.result ".." : make "[.-]" ;
904
+ assert.result ".." : make "[-]" ;
905
+ assert.result "." : make "[]" ;
906
+ assert.result "giz.h" : make "giz.h" ;
907
+ assert.result "foo/bar/giz.h" : make "[.foo.bar]giz.h" ;
908
+ assert.result "/disk:/my_docs" : make "disk:[my_docs]" ;
909
+ assert.result "/disk:/boost/tools/build/new/project.jam" : make "disk:[boost.tools.build.test.-.new]project.jam" ;
910
+
911
+ #
912
+ # Special case (adds '.' to end of file w/o extension to
913
+ # disambiguate from directory in portable path spec).
914
+ #
915
+ assert.result "Jamfile." : make "Jamfile" ;
916
+ assert.result "dir/Jamfile." : make "[.dir]Jamfile" ;
917
+ assert.result "/disk:/dir/Jamfile." : make "disk:[dir]Jamfile" ;
918
+
919
+ #
920
+ # Make native paths
921
+ #
922
+ assert.result "disk:" : native "/disk:" ;
923
+ assert.result "[.foo.bar.giz]" : native "foo/bar/giz" ;
924
+ assert.result "[.foo]" : native "foo" ;
925
+ assert.result "[.-]" : native ".." ;
926
+ assert.result "[.foo.-]" : native "foo/.." ;
927
+ assert.result "[]" : native "." ;
928
+ assert.result "disk:[my_docs.work]" : native "/disk:/my_docs/work" ;
929
+ assert.result "giz.h" : native "giz.h" ;
930
+ assert.result "disk:Jamfile." : native "/disk:Jamfile." ;
931
+ assert.result "disk:[my_docs.work]Jamfile." : native "/disk:/my_docs/work/Jamfile." ;
932
+
933
+ modules.poke path : os : $(save-os) ;
934
+ }
mosesdecoder/jam-files/boost-build/util/print.jam ADDED
@@ -0,0 +1,488 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2003 Douglas Gregor
2
+ # Copyright 2002, 2003, 2005 Rene Rivera
3
+ # Copyright 2002, 2003, 2004, 2005 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
+ # Utilities for generating format independent output. Using these
8
+ # will help in generation of documentation in at minimum plain/console
9
+ # and html.
10
+
11
+ import modules ;
12
+ import numbers ;
13
+ import string ;
14
+ import regex ;
15
+ import "class" ;
16
+ import scanner ;
17
+ import path ;
18
+
19
+ # The current output target. Defaults to console.
20
+ output-target = console ;
21
+
22
+ # The current output type. Defaults to plain. Other possible values are "html".
23
+ output-type = plain ;
24
+
25
+ # Whitespace.
26
+ .whitespace = [ string.whitespace ] ;
27
+
28
+
29
+ # Set the target and type of output to generate. This sets both the destination
30
+ # output and the type of docs to generate to that output. The target can be
31
+ # either a file or "console" for echoing to the console. If the type of output
32
+ # is not specified it defaults to plain text.
33
+ #
34
+ rule output (
35
+ target # The target file or device; file or "console".
36
+ type ? # The type of output; "plain" or "html".
37
+ )
38
+ {
39
+ type ?= plain ;
40
+ if $(output-target) != $(target)
41
+ {
42
+ output-target = $(target) ;
43
+ output-type = $(type) ;
44
+ if $(output-type) = html
45
+ {
46
+ text
47
+ "<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">"
48
+ "<html>"
49
+ "<head>"
50
+ "</head>"
51
+ "<body link=\"#0000ff\" vlink=\"#800080\">"
52
+ : true
53
+ : prefix ;
54
+ text
55
+ "</body>"
56
+ "</html>"
57
+ :
58
+ : suffix ;
59
+ }
60
+ }
61
+ }
62
+
63
+
64
+ # Generate a section with a description. The type of output can be controlled by
65
+ # the value of the 'output-type' variable.
66
+ #
67
+ rule section (
68
+ name # The name of the section.
69
+ description * # A number of description lines.
70
+ )
71
+ {
72
+ if $(output-type) = plain
73
+ {
74
+ lines [ split-at-words $(name): ] ;
75
+ lines ;
76
+ }
77
+ else if $(output-type) = html
78
+ {
79
+ name = [ escape-html $(name) ] ;
80
+ text <h3>$(name)</h3> <p> ;
81
+ }
82
+ local pre = ;
83
+ while $(description)
84
+ {
85
+ local paragraph = ;
86
+ while $(description) && [ string.is-whitespace $(description[1]) ] { description = $(description[2-]) ; }
87
+ if $(pre)
88
+ {
89
+ while $(description) && (
90
+ $(pre) = " $(description[1])" ||
91
+ ( $(pre) < [ string.chars [ MATCH "^([$(.whitespace)]*)" : " $(description[1])" ] ] )
92
+ )
93
+ { paragraph += $(description[1]) ; description = $(description[2-]) ; }
94
+ while [ string.is-whitespace $(paragraph[-1]) ] { paragraph = $(paragraph[1--2]) ; }
95
+ pre = ;
96
+ if $(output-type) = plain
97
+ {
98
+ lines $(paragraph) "" : " " " " ;
99
+ }
100
+ else if $(output-type) = html
101
+ {
102
+ text <blockquote> ;
103
+ lines $(paragraph) ;
104
+ text </blockquote> ;
105
+ }
106
+ }
107
+ else
108
+ {
109
+ while $(description) && ! [ string.is-whitespace $(description[1]) ]
110
+ { paragraph += $(description[1]) ; description = $(description[2-]) ; }
111
+ if $(paragraph[1]) = :: && ! $(paragraph[2])
112
+ {
113
+ pre = " " ;
114
+ }
115
+ if $(paragraph[1]) = ::
116
+ {
117
+ if $(output-type) = plain
118
+ {
119
+ lines $(paragraph[2-]) "" : " " " " ;
120
+ lines ;
121
+ }
122
+ else if $(output-type) = html
123
+ {
124
+ text <blockquote> ;
125
+ lines $(paragraph[2-]) ;
126
+ text </blockquote> ;
127
+ }
128
+ }
129
+ else
130
+ {
131
+ local p = [ MATCH "(.*)(::)$" : $(paragraph[-1]) ] ;
132
+ local pws = [ MATCH "([ ]*)$" : $(p[1]) ] ;
133
+ p = [ MATCH "(.*)($(pws))($(p[2]))$" : $(paragraph[-1]) ] ;
134
+ if $(p[3]) = ::
135
+ {
136
+ pre = [ string.chars [ MATCH "^([$(.whitespace)]*)" : " $(p[1])" ] ] ;
137
+ if ! $(p[2]) || $(p[2]) = "" { paragraph = $(paragraph[1--2]) $(p[1]): ; }
138
+ else { paragraph = $(paragraph[1--2]) $(p[1]) ; }
139
+ if $(output-type) = plain
140
+ {
141
+ lines [ split-at-words " " $(paragraph) ] : " " " " ;
142
+ lines ;
143
+ }
144
+ else if $(output-type) = html
145
+ {
146
+ text </p> <p> [ escape-html $(paragraph) ] ;
147
+ }
148
+ }
149
+ else
150
+ {
151
+ if $(output-type) = plain
152
+ {
153
+ lines [ split-at-words " " $(paragraph) ] : " " " " ;
154
+ lines ;
155
+ }
156
+ else if $(output-type) = html
157
+ {
158
+ text </p> <p> [ escape-html $(paragraph) ] ;
159
+ }
160
+ }
161
+ }
162
+ }
163
+ }
164
+ if $(output-type) = html
165
+ {
166
+ text </p> ;
167
+ }
168
+ }
169
+
170
+
171
+ # Generate the start of a list of items. The type of output can be controlled by
172
+ # the value of the 'output-type' variable.
173
+ #
174
+ rule list-start ( )
175
+ {
176
+ if $(output-type) = plain
177
+ {
178
+ }
179
+ else if $(output-type) = html
180
+ {
181
+ text <ul> ;
182
+ }
183
+ }
184
+
185
+
186
+ # Generate an item in a list. The type of output can be controlled by the value
187
+ # of the 'output-type' variable.
188
+ #
189
+ rule list-item (
190
+ item + # The item to list.
191
+ )
192
+ {
193
+ if $(output-type) = plain
194
+ {
195
+ lines [ split-at-words "*" $(item) ] : " " " " ;
196
+ }
197
+ else if $(output-type) = html
198
+ {
199
+ text <li> [ escape-html $(item) ] </li> ;
200
+ }
201
+ }
202
+
203
+
204
+ # Generate the end of a list of items. The type of output can be controlled by
205
+ # the value of the 'output-type' variable.
206
+ #
207
+ rule list-end ( )
208
+ {
209
+ if $(output-type) = plain
210
+ {
211
+ lines ;
212
+ }
213
+ else if $(output-type) = html
214
+ {
215
+ text </ul> ;
216
+ }
217
+ }
218
+
219
+
220
+ # Split the given text into separate lines, word-wrapping to a margin. The
221
+ # default margin is 78 characters.
222
+ #
223
+ rule split-at-words (
224
+ text + # The text to split.
225
+ : margin ? # An optional margin, default is 78.
226
+ )
227
+ {
228
+ local lines = ;
229
+ text = [ string.words $(text:J=" ") ] ;
230
+ text = $(text:J=" ") ;
231
+ margin ?= 78 ;
232
+ local char-match-1 = ".?" ;
233
+ local char-match = "" ;
234
+ while $(margin) != 0
235
+ {
236
+ char-match = $(char-match)$(char-match-1) ;
237
+ margin = [ numbers.decrement $(margin) ] ;
238
+ }
239
+ while $(text)
240
+ {
241
+ local s = "" ;
242
+ local t = "" ;
243
+ # divide s into the first X characters and the rest
244
+ s = [ MATCH "^($(char-match))(.*)" : $(text) ] ;
245
+
246
+ if $(s[2])
247
+ {
248
+ # split the first half at a space
249
+ t = [ MATCH "^(.*)[\\ ]([^\\ ]*)$" : $(s[1]) ] ;
250
+ }
251
+ else
252
+ {
253
+ t = $(s) ;
254
+ }
255
+
256
+ if ! $(t[2])
257
+ {
258
+ t += "" ;
259
+ }
260
+
261
+ text = $(t[2])$(s[2]) ;
262
+ lines += $(t[1]) ;
263
+ }
264
+ return $(lines) ;
265
+ }
266
+
267
+
268
+ # Generate a set of fixed lines. Each single item passed in is output on a
269
+ # separate line. For console this just echos each line, but for html this will
270
+ # split them with <br>.
271
+ #
272
+ rule lines (
273
+ text * # The lines of text.
274
+ : indent ? # Optional indentation prepended to each line after the first one.
275
+ outdent ? # Optional indentation to prepend to the first line.
276
+ )
277
+ {
278
+ text ?= "" ;
279
+ indent ?= "" ;
280
+ outdent ?= "" ;
281
+ if $(output-type) = plain
282
+ {
283
+ text $(outdent)$(text[1]) $(indent)$(text[2-]) ;
284
+ }
285
+ else if $(output-type) = html
286
+ {
287
+ local indent-chars = [ string.chars $(indent) ] ;
288
+ indent = "" ;
289
+ for local c in $(indent-chars)
290
+ {
291
+ if $(c) = " " { c = "&nbsp;" ; }
292
+ else if $(c) = " " { c = "&nbsp;&nbsp;&nbsp;&nbsp;" ; }
293
+ indent = $(indent)$(c) ;
294
+ }
295
+ local html-text = [ escape-html $(text) : "&nbsp;" ] ;
296
+ text $(html-text[1])<br> $(indent)$(html-text[2-])<br> ;
297
+ }
298
+ }
299
+
300
+
301
+ # Output text directly to the current target. When doing output to a file, one
302
+ # can indicate if the text should be output to "prefix" it, as the "body"
303
+ # (default), or "suffix" of the file. This is independant of the actual
304
+ # execution order of the text rule. This rule invokes a singular action, one
305
+ # action only once, which does the build of the file. Therefore actions on the
306
+ # target outside of this rule will happen entirely before and/or after all
307
+ # output using this rule.
308
+ #
309
+ rule text (
310
+ strings * # The strings of text to output.
311
+ : overwrite ? # true to overwrite the output (if it is a file)
312
+ : prefix-body-suffix ? # Indication to output prefix, body, or suffix (for a file).
313
+ )
314
+ {
315
+ prefix-body-suffix ?= body ;
316
+ if $(output-target) = console
317
+ {
318
+ if ! $(strings)
319
+ {
320
+ ECHO ;
321
+ }
322
+ else
323
+ {
324
+ for local s in $(strings)
325
+ {
326
+ ECHO $(s) ;
327
+ }
328
+ }
329
+ }
330
+ if ! $($(output-target).did-action)
331
+ {
332
+ $(output-target).did-action = yes ;
333
+ $(output-target).text-prefix = ;
334
+ $(output-target).text-body = ;
335
+ $(output-target).text-suffix = ;
336
+
337
+ nl on $(output-target) = "
338
+ " ;
339
+ text-redirect on $(output-target) = ">>" ;
340
+ if $(overwrite)
341
+ {
342
+ text-redirect on $(output-target) = ">" ;
343
+ }
344
+ text-content on $(output-target) = ;
345
+
346
+ text-action $(output-target) ;
347
+
348
+ if $(overwrite) && $(output-target) != console
349
+ {
350
+ check-for-update $(output-target) ;
351
+ }
352
+ }
353
+ $(output-target).text-$(prefix-body-suffix) += $(strings) ;
354
+ text-content on $(output-target) =
355
+ $($(output-target).text-prefix)
356
+ $($(output-target).text-body)
357
+ $($(output-target).text-suffix) ;
358
+ }
359
+
360
+
361
+ # Outputs the text to the current targets, after word-wrapping it.
362
+ #
363
+ rule wrapped-text ( text + )
364
+ {
365
+ local lines = [ split-at-words $(text) ] ;
366
+ text $(lines) ;
367
+ }
368
+
369
+
370
+ # Escapes text into html/xml printable equivalents. Does not know about tags and
371
+ # therefore tags fed into this will also be escaped. Currently escapes space,
372
+ # "<", ">", and "&".
373
+ #
374
+ rule escape-html (
375
+ text + # The text to escape.
376
+ : space ? # What to replace spaces with, defaults to " ".
377
+ )
378
+ {
379
+ local html-text = ;
380
+ while $(text)
381
+ {
382
+ local html = $(text[1]) ;
383
+ text = $(text[2-]) ;
384
+ html = [ regex.replace $(html) "&" "&amp;" ] ;
385
+ html = [ regex.replace $(html) "<" "&lt;" ] ;
386
+ html = [ regex.replace $(html) ">" "&gt;" ] ;
387
+ if $(space)
388
+ {
389
+ html = [ regex.replace $(html) " " "$(space)" ] ;
390
+ }
391
+ html-text += $(html) ;
392
+ }
393
+ return $(html-text) ;
394
+ }
395
+
396
+
397
+ # Outputs the text strings collected by the text rule to the output file.
398
+ #
399
+ actions quietly text-action
400
+ {
401
+ @($(STDOUT):E=$(text-content:J=$(nl))) $(text-redirect) "$(<)"
402
+ }
403
+
404
+
405
+ rule get-scanner ( )
406
+ {
407
+ if ! $(.scanner)
408
+ {
409
+ .scanner = [ class.new print-scanner ] ;
410
+ }
411
+ return $(.scanner) ;
412
+ }
413
+
414
+
415
+ # The following code to update print targets when their contents
416
+ # change is a horrible hack. It basically creates a target which
417
+ # binds to this file (print.jam) and installs a scanner on it
418
+ # which reads the target and compares its contents to the new
419
+ # contents that we're writing.
420
+ #
421
+ rule check-for-update ( target )
422
+ {
423
+ local scanner = [ get-scanner ] ;
424
+ local file = [ path.native [ modules.binding $(__name__) ] ] ;
425
+ local g = [ MATCH <(.*)> : $(target:G) ] ;
426
+ local dependency-target = $(__file__:G=$(g:E=)-$(target:G=)-$(scanner)) ;
427
+ DEPENDS $(target) : $(dependency-target) ;
428
+ SEARCH on $(dependency-target) = $(file:D) ;
429
+ ISFILE $(dependency-target) ;
430
+ NOUPDATE $(dependency-target) ;
431
+ base on $(dependency-target) = $(target) ;
432
+ scanner.install $(scanner) : $(dependency-target) none ;
433
+ return $(dependency-target) ;
434
+ }
435
+
436
+
437
+ class print-scanner : scanner
438
+ {
439
+ import path ;
440
+ import os ;
441
+
442
+ rule pattern ( )
443
+ {
444
+ return "(One match...)" ;
445
+ }
446
+
447
+ rule process ( target : matches * : binding )
448
+ {
449
+ local base = [ on $(target) return $(base) ] ;
450
+ local nl = [ on $(base) return $(nl) ] ;
451
+ local text-content = [ on $(base) return $(text-content) ] ;
452
+ local dir = [ on $(base) return $(LOCATE) ] ;
453
+ if $(dir)
454
+ {
455
+ dir = [ path.make $(dir) ] ;
456
+ }
457
+ local file = [ path.native [ path.join $(dir) $(base:G=) ] ] ;
458
+ local actual-content ;
459
+ if [ os.name ] = NT
460
+ {
461
+ actual-content = [ SHELL "type \"$(file)\" 2>nul" ] ;
462
+ }
463
+ else
464
+ {
465
+ actual-content = [ SHELL "cat \"$(file)\" 2>/dev/null" ] ;
466
+ }
467
+ if $(text-content:J=$(nl)) != $(actual-content)
468
+ {
469
+ ALWAYS $(base) ;
470
+ }
471
+ }
472
+ }
473
+
474
+
475
+ rule __test__ ( )
476
+ {
477
+ import assert ;
478
+
479
+ assert.result one two three : split-at-words one two three : 5 ;
480
+ assert.result "one two" three : split-at-words one two three : 8 ;
481
+ assert.result "one two" three : split-at-words one two three : 9 ;
482
+ assert.result "one two three" : split-at-words one two three ;
483
+
484
+ # VP, 2004-12-03 The following test fails for some reason, so commenting it
485
+ # out.
486
+ #assert.result "one&nbsp;two&nbsp;three" "&amp;&lt;&gt;" :
487
+ # escape-html "one two three" "&<>" ;
488
+ }
mosesdecoder/jam-files/boost-build/util/sequence.jam ADDED
@@ -0,0 +1,335 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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 assert ;
8
+ import numbers ;
9
+ import modules ;
10
+
11
+
12
+ # Note that algorithms in this module execute largely in the caller's module
13
+ # namespace, so that local rules can be used as function objects. Also note that
14
+ # most predicates can be multi-element lists. In that case, all but the first
15
+ # element are prepended to the first argument which is passed to the rule named
16
+ # by the first element.
17
+
18
+
19
+ # Return the elements e of $(sequence) for which [ $(predicate) e ] has a
20
+ # non-null value.
21
+ #
22
+ rule filter ( predicate + : sequence * )
23
+ {
24
+ local caller = [ CALLER_MODULE ] ;
25
+ local result ;
26
+
27
+ for local e in $(sequence)
28
+ {
29
+ if [ modules.call-in $(caller) : $(predicate) $(e) ]
30
+ {
31
+ result += $(e) ;
32
+ }
33
+ }
34
+ return $(result) ;
35
+ }
36
+
37
+
38
+ # Return a new sequence consisting of [ $(function) $(e) ] for each element e of
39
+ # $(sequence).
40
+ #
41
+ rule transform ( function + : sequence * )
42
+ {
43
+ local caller = [ CALLER_MODULE ] ;
44
+ local result ;
45
+
46
+ for local e in $(sequence)
47
+ {
48
+ result += [ modules.call-in $(caller) : $(function) $(e) ] ;
49
+ }
50
+ return $(result) ;
51
+ }
52
+
53
+
54
+ rule reverse ( s * )
55
+ {
56
+ local r ;
57
+ for local x in $(s)
58
+ {
59
+ r = $(x) $(r) ;
60
+ }
61
+ return $(r) ;
62
+ }
63
+
64
+
65
+ rule less ( a b )
66
+ {
67
+ if $(a) < $(b)
68
+ {
69
+ return true ;
70
+ }
71
+ }
72
+
73
+
74
+ # Insertion-sort s using the BinaryPredicate ordered.
75
+ #
76
+ rule insertion-sort ( s * : ordered * )
77
+ {
78
+ if ! $(ordered)
79
+ {
80
+ return [ SORT $(s) ] ;
81
+ }
82
+ else
83
+ {
84
+ local caller = [ CALLER_MODULE ] ;
85
+ ordered ?= sequence.less ;
86
+ local result = $(s[1]) ;
87
+ if $(ordered) = sequence.less
88
+ {
89
+ local head tail ;
90
+ for local x in $(s[2-])
91
+ {
92
+ head = ;
93
+ tail = $(result) ;
94
+ while $(tail) && ( $(tail[1]) < $(x) )
95
+ {
96
+ head += $(tail[1]) ;
97
+ tail = $(tail[2-]) ;
98
+ }
99
+ result = $(head) $(x) $(tail) ;
100
+ }
101
+ }
102
+ else
103
+ {
104
+ for local x in $(s[2-])
105
+ {
106
+ local head tail ;
107
+ tail = $(result) ;
108
+ while $(tail) && [ modules.call-in $(caller) : $(ordered) $(tail[1]) $(x) ]
109
+ {
110
+ head += $(tail[1]) ;
111
+ tail = $(tail[2-]) ;
112
+ }
113
+ result = $(head) $(x) $(tail) ;
114
+ }
115
+ }
116
+
117
+ return $(result) ;
118
+ }
119
+ }
120
+
121
+
122
+ # Merge two ordered sequences using the BinaryPredicate ordered.
123
+ #
124
+ rule merge ( s1 * : s2 * : ordered * )
125
+ {
126
+ ordered ?= sequence.less ;
127
+ local result__ ;
128
+ local caller = [ CALLER_MODULE ] ;
129
+
130
+ while $(s1) && $(s2)
131
+ {
132
+ if [ modules.call-in $(caller) : $(ordered) $(s1[1]) $(s2[1]) ]
133
+ {
134
+ result__ += $(s1[1]) ;
135
+ s1 = $(s1[2-]) ;
136
+ }
137
+ else if [ modules.call-in $(caller) : $(ordered) $(s2[1]) $(s1[1]) ]
138
+ {
139
+ result__ += $(s2[1]) ;
140
+ s2 = $(s2[2-]) ;
141
+ }
142
+ else
143
+ {
144
+ s2 = $(s2[2-]) ;
145
+ }
146
+
147
+ }
148
+ result__ += $(s1) ;
149
+ result__ += $(s2) ;
150
+
151
+ return $(result__) ;
152
+ }
153
+
154
+
155
+ # Join the elements of s into one long string. If joint is supplied, it is used
156
+ # as a separator.
157
+ #
158
+ rule join ( s * : joint ? )
159
+ {
160
+ joint ?= "" ;
161
+ return $(s:J=$(joint)) ;
162
+ }
163
+
164
+
165
+ # Find the length of any sequence.
166
+ #
167
+ rule length ( s * )
168
+ {
169
+ local result = 0 ;
170
+ for local i in $(s)
171
+ {
172
+ result = [ CALC $(result) + 1 ] ;
173
+ }
174
+ return $(result) ;
175
+ }
176
+
177
+
178
+ rule unique ( list * : stable ? )
179
+ {
180
+ local result ;
181
+ local prev ;
182
+ if $(stable)
183
+ {
184
+ for local f in $(list)
185
+ {
186
+ if ! $(f) in $(result)
187
+ {
188
+ result += $(f) ;
189
+ }
190
+ }
191
+ }
192
+ else
193
+ {
194
+ for local i in [ SORT $(list) ]
195
+ {
196
+ if $(i) != $(prev)
197
+ {
198
+ result += $(i) ;
199
+ }
200
+ prev = $(i) ;
201
+ }
202
+ }
203
+ return $(result) ;
204
+ }
205
+
206
+
207
+ # Returns the maximum number in 'elements'. Uses 'ordered' for comparisons or
208
+ # 'numbers.less' if none is provided.
209
+ #
210
+ rule max-element ( elements + : ordered ? )
211
+ {
212
+ ordered ?= numbers.less ;
213
+
214
+ local max = $(elements[1]) ;
215
+ for local e in $(elements[2-])
216
+ {
217
+ if [ $(ordered) $(max) $(e) ]
218
+ {
219
+ max = $(e) ;
220
+ }
221
+ }
222
+ return $(max) ;
223
+ }
224
+
225
+
226
+ # Returns all of 'elements' for which corresponding element in parallel list
227
+ # 'rank' is equal to the maximum value in 'rank'.
228
+ #
229
+ rule select-highest-ranked ( elements * : ranks * )
230
+ {
231
+ if $(elements)
232
+ {
233
+ local max-rank = [ max-element $(ranks) ] ;
234
+ local result ;
235
+ while $(elements)
236
+ {
237
+ if $(ranks[1]) = $(max-rank)
238
+ {
239
+ result += $(elements[1]) ;
240
+ }
241
+ elements = $(elements[2-]) ;
242
+ ranks = $(ranks[2-]) ;
243
+ }
244
+ return $(result) ;
245
+ }
246
+ }
247
+ NATIVE_RULE sequence : select-highest-ranked ;
248
+
249
+
250
+ rule __test__ ( )
251
+ {
252
+ # Use a unique module so we can test the use of local rules.
253
+ module sequence.__test__
254
+ {
255
+ import assert ;
256
+ import sequence ;
257
+
258
+ local rule is-even ( n )
259
+ {
260
+ if $(n) in 0 2 4 6 8
261
+ {
262
+ return true ;
263
+ }
264
+ }
265
+
266
+ assert.result 4 6 4 2 8 : sequence.filter is-even : 1 4 6 3 4 7 2 3 8 ;
267
+
268
+ # Test that argument binding works.
269
+ local rule is-equal-test ( x y )
270
+ {
271
+ if $(x) = $(y)
272
+ {
273
+ return true ;
274
+ }
275
+ }
276
+
277
+ assert.result 3 3 3 : sequence.filter is-equal-test 3 : 1 2 3 4 3 5 3 5 7 ;
278
+
279
+ local rule append-x ( n )
280
+ {
281
+ return $(n)x ;
282
+ }
283
+
284
+ assert.result 1x 2x 3x : sequence.transform append-x : 1 2 3 ;
285
+
286
+ local rule repeat2 ( x )
287
+ {
288
+ return $(x) $(x) ;
289
+ }
290
+
291
+ assert.result 1 1 2 2 3 3 : sequence.transform repeat2 : 1 2 3 ;
292
+
293
+ local rule test-greater ( a b )
294
+ {
295
+ if $(a) > $(b)
296
+ {
297
+ return true ;
298
+ }
299
+ }
300
+ assert.result 1 2 3 4 5 6 7 8 9 : sequence.insertion-sort 9 6 5 3 8 7 1 2 4 ;
301
+ assert.result 9 8 7 6 5 4 3 2 1 : sequence.insertion-sort 9 6 5 3 8 7 1 2 4 : test-greater ;
302
+ assert.result 1 2 3 4 5 6 : sequence.merge 1 3 5 : 2 4 6 ;
303
+ assert.result 6 5 4 3 2 1 : sequence.merge 5 3 1 : 6 4 2 : test-greater ;
304
+ assert.result 1 2 3 : sequence.merge 1 2 3 : ;
305
+ assert.result 1 : sequence.merge 1 : 1 ;
306
+
307
+ assert.result foo-bar-baz : sequence.join foo bar baz : - ;
308
+ assert.result substandard : sequence.join sub stan dard ;
309
+ assert.result 3.0.1 : sequence.join 3.0.1 : - ;
310
+
311
+ assert.result 0 : sequence.length ;
312
+ assert.result 3 : sequence.length a b c ;
313
+ assert.result 17 : sequence.length 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 ;
314
+
315
+ assert.result 1 : sequence.length a ;
316
+ assert.result 10 : sequence.length a b c d e f g h i j ;
317
+ assert.result 11 : sequence.length a b c d e f g h i j k ;
318
+ assert.result 12 : sequence.length a b c d e f g h i j k l ;
319
+
320
+ local p2 = x ;
321
+ for local i in 1 2 3 4 5 6 7 8
322
+ {
323
+ p2 = $(p2) $(p2) ;
324
+ }
325
+ assert.result 256 : sequence.length $(p2) ;
326
+
327
+ assert.result 1 2 3 4 5 : sequence.unique 1 2 3 2 4 3 3 5 5 5 ;
328
+
329
+ assert.result 5 : sequence.max-element 1 3 5 0 4 ;
330
+
331
+ assert.result e-3 h-3 : sequence.select-highest-ranked e-1 e-3 h-3 m-2 : 1 3 3 2 ;
332
+
333
+ assert.result 7 6 5 4 3 2 1 : sequence.reverse 1 2 3 4 5 6 7 ;
334
+ }
335
+ }
mosesdecoder/jam-files/boost-build/util/set.jam ADDED
@@ -0,0 +1,93 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2001, 2002 Dave Abrahams
2
+ # Copyright 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
+ class set
7
+ {
8
+ rule __init__ ( )
9
+ {
10
+ }
11
+
12
+ rule add ( elements * )
13
+ {
14
+ for local e in $(elements)
15
+ {
16
+ if ! $($(e))
17
+ {
18
+ $(e) = 1 ;
19
+ self.result += $(e) ;
20
+ }
21
+ }
22
+ }
23
+
24
+ rule contains ( element )
25
+ {
26
+ return $($(element)) ;
27
+ }
28
+
29
+ rule list ( )
30
+ {
31
+ return $(self.result) ;
32
+ }
33
+ }
34
+
35
+
36
+
37
+ # Returns the elements of set1 that are not in set2.
38
+ #
39
+ rule difference ( set1 * : set2 * )
40
+ {
41
+ local result = ;
42
+ for local element in $(set1)
43
+ {
44
+ if ! ( $(element) in $(set2) )
45
+ {
46
+ result += $(element) ;
47
+ }
48
+ }
49
+ return $(result) ;
50
+ }
51
+
52
+ NATIVE_RULE set : difference ;
53
+
54
+
55
+ # Removes all the items appearing in both set1 & set2.
56
+ #
57
+ rule intersection ( set1 * : set2 * )
58
+ {
59
+ local result ;
60
+ for local v in $(set1)
61
+ {
62
+ if $(v) in $(set2)
63
+ {
64
+ result += $(v) ;
65
+ }
66
+ }
67
+ return $(result) ;
68
+ }
69
+
70
+
71
+ # Returns whether set1 & set2 contain the same elements. Note that this ignores
72
+ # any element ordering differences as well as any element duplication.
73
+ #
74
+ rule equal ( set1 * : set2 * )
75
+ {
76
+ if $(set1) in $(set2) && ( $(set2) in $(set1) )
77
+ {
78
+ return true ;
79
+ }
80
+ }
81
+
82
+
83
+ rule __test__ ( )
84
+ {
85
+ import assert ;
86
+
87
+ assert.result 0 1 4 6 8 9 : difference 0 1 2 3 4 5 6 7 8 9 : 2 3 5 7 ;
88
+ assert.result 2 5 7 : intersection 0 1 2 4 5 6 7 8 9 : 2 3 5 7 ;
89
+
90
+ assert.true equal : ;
91
+ assert.true equal 1 1 2 3 : 3 2 2 1 ;
92
+ assert.false equal 2 3 : 3 2 2 1 ;
93
+ }
mosesdecoder/jam-files/boost-build/util/string.jam ADDED
@@ -0,0 +1,189 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2002 Dave Abrahams
2
+ # Copyright 2002, 2003 Rene Rivera
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 regex ;
7
+
8
+
9
+ # Characters considered whitespace, as a list.
10
+ .whitespace-chars = " " " " "
11
+ " ;
12
+
13
+ # Characters considered whitespace, as a single string.
14
+ .whitespace = $(.whitespace-chars:J="") ;
15
+
16
+
17
+ # Returns the canonical set of whitespace characters, as a list.
18
+ #
19
+ rule whitespace-chars ( )
20
+ {
21
+ return $(.whitespace-chars) ;
22
+ }
23
+
24
+
25
+ # Returns the canonical set of whitespace characters, as a single string.
26
+ #
27
+ rule whitespace ( )
28
+ {
29
+ return $(.whitespace) ;
30
+ }
31
+
32
+
33
+ # Splits the given string into a list of strings composed of each character of
34
+ # the string in sequence.
35
+ #
36
+ rule chars (
37
+ string # The string to split.
38
+ )
39
+ {
40
+ local result ;
41
+ while $(string)
42
+ {
43
+ local s = [ MATCH (.?)(.?)(.?)(.?)(.?)(.?)(.?)(.?)(.*) : $(string) ] ;
44
+ string = $(s[9]) ;
45
+ result += $(s[1-8]) ;
46
+ }
47
+
48
+ # Trim off empty strings.
49
+ while $(result[1]) && ! $(result[-1])
50
+ {
51
+ result = $(result[1--2]) ;
52
+ }
53
+
54
+ return $(result) ;
55
+ }
56
+
57
+
58
+ # Apply a set of standard transformations to string to produce an abbreviation
59
+ # no more than 5 characters long.
60
+ #
61
+ rule abbreviate ( string )
62
+ {
63
+ local r = $(.abbreviated-$(string)) ;
64
+ if $(r)
65
+ {
66
+ return $(r) ;
67
+ }
68
+ # Anything less than 4 characters gets no abbreviation.
69
+ else if ! [ MATCH (....) : $(string) ]
70
+ {
71
+ .abbreviated-$(string) = $(string) ;
72
+ return $(string) ;
73
+ }
74
+ else
75
+ {
76
+ # Separate the initial letter in case it's a vowel.
77
+ local s1 = [ MATCH ^(.)(.*) : $(string) ] ;
78
+
79
+ # Drop trailing "ing".
80
+ local s2 = [ MATCH ^(.*)ing$ : $(s1[2]) ] ;
81
+ s2 ?= $(s1[2]) ;
82
+
83
+ # Reduce all doubled characters to one.
84
+ local last = "" ;
85
+ for local c in [ chars $(s2) ]
86
+ {
87
+ if $(c) != $(last)
88
+ {
89
+ r += $(c) ;
90
+ last = $(c) ;
91
+ }
92
+ }
93
+ s2 = $(r:J="") ;
94
+
95
+ # Chop all vowels out of the remainder.
96
+ s2 = [ regex.replace $(s2) [AEIOUaeiou] "" ] ;
97
+
98
+ # Shorten remaining consonants to 4 characters.
99
+ s2 = [ MATCH ^(.?.?.?.?) : $(s2) ] ;
100
+
101
+ # Glue the initial character back on to the front.
102
+ s2 = $(s1[1])$(s2) ;
103
+
104
+ .abbreviated-$(string) = $(s2) ;
105
+ return $(s2) ;
106
+ }
107
+ }
108
+
109
+
110
+ # Concatenates the given strings, inserting the given separator between each
111
+ # string.
112
+ #
113
+ rule join (
114
+ strings * # The strings to join.
115
+ : separator ? # The optional separator.
116
+ )
117
+ {
118
+ separator ?= "" ;
119
+ return $(strings:J=$(separator)) ;
120
+ }
121
+
122
+
123
+ # Split a string into whitespace separated words.
124
+ #
125
+ rule words (
126
+ string # The string to split.
127
+ : whitespace * # Optional, characters to consider as whitespace.
128
+ )
129
+ {
130
+ whitespace = $(whitespace:J="") ;
131
+ whitespace ?= $(.whitespace) ;
132
+ local w = ;
133
+ while $(string)
134
+ {
135
+ string = [ MATCH "^[$(whitespace)]*([^$(whitespace)]*)(.*)" : $(string) ] ;
136
+ if $(string[1]) && $(string[1]) != ""
137
+ {
138
+ w += $(string[1]) ;
139
+ }
140
+ string = $(string[2]) ;
141
+ }
142
+ return $(w) ;
143
+ }
144
+
145
+
146
+ # Check that the given string is composed entirely of whitespace.
147
+ #
148
+ rule is-whitespace (
149
+ string ? # The string to test.
150
+ )
151
+ {
152
+ if ! $(string) { return true ; }
153
+ else if $(string) = "" { return true ; }
154
+ else if [ MATCH "^([$(.whitespace)]+)$" : $(string) ] { return true ; }
155
+ else { return ; }
156
+ }
157
+
158
+ rule __test__ ( )
159
+ {
160
+ import assert ;
161
+ assert.result a b c : chars abc ;
162
+
163
+ assert.result rntm : abbreviate runtime ;
164
+ assert.result ovrld : abbreviate overload ;
165
+ assert.result dbg : abbreviate debugging ;
166
+ assert.result async : abbreviate asynchronous ;
167
+ assert.result pop : abbreviate pop ;
168
+ assert.result aaa : abbreviate aaa ;
169
+ assert.result qck : abbreviate quack ;
170
+ assert.result sttc : abbreviate static ;
171
+
172
+ # Check boundary cases.
173
+ assert.result a : chars a ;
174
+ assert.result : chars "" ;
175
+ assert.result a b c d e f g h : chars abcdefgh ;
176
+ assert.result a b c d e f g h i : chars abcdefghi ;
177
+ assert.result a b c d e f g h i j : chars abcdefghij ;
178
+ assert.result a b c d e f g h i j k : chars abcdefghijk ;
179
+
180
+ assert.result a//b/c/d : join a "" b c d : / ;
181
+ assert.result abcd : join a "" b c d ;
182
+
183
+ assert.result a b c : words "a b c" ;
184
+
185
+ assert.true is-whitespace " " ;
186
+ assert.false is-whitespace " a b c " ;
187
+ assert.true is-whitespace "" ;
188
+ assert.true is-whitespace ;
189
+ }
mosesdecoder/jam-files/boost-build/util/utility.jam ADDED
@@ -0,0 +1,235 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2001, 2002 Dave Abrahams
2
+ # Copyright 2002, 2003, 2004, 2005 Vladimir Prus
3
+ # Copyright 2008 Jurko Gospodnetic
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 "class" : is-instance ;
8
+ import errors ;
9
+
10
+
11
+ # For all elements of 'list' which do not already have 'suffix', add 'suffix'.
12
+ #
13
+ rule apply-default-suffix ( suffix : list * )
14
+ {
15
+ local result ;
16
+ for local i in $(list)
17
+ {
18
+ if $(i:S) = $(suffix)
19
+ {
20
+ result += $(i) ;
21
+ }
22
+ else
23
+ {
24
+ result += $(i)$(suffix) ;
25
+ }
26
+ }
27
+ return $(result) ;
28
+ }
29
+
30
+
31
+ # If 'name' contains a dot, returns the part before the last dot. If 'name'
32
+ # contains no dot, returns it unmodified.
33
+ #
34
+ rule basename ( name )
35
+ {
36
+ if $(name:S)
37
+ {
38
+ name = $(name:B) ;
39
+ }
40
+ return $(name) ;
41
+ }
42
+
43
+
44
+ # Return the file of the caller of the rule that called caller-file.
45
+ #
46
+ rule caller-file ( )
47
+ {
48
+ local bt = [ BACKTRACE ] ;
49
+ return $(bt[9]) ;
50
+ }
51
+
52
+
53
+ # Tests if 'a' is equal to 'b'. If 'a' is a class instance, calls its 'equal'
54
+ # method. Uses ordinary jam's comparison otherwise.
55
+ #
56
+ rule equal ( a b )
57
+ {
58
+ if [ is-instance $(a) ]
59
+ {
60
+ return [ $(a).equal $(b) ] ;
61
+ }
62
+ else
63
+ {
64
+ if $(a) = $(b)
65
+ {
66
+ return true ;
67
+ }
68
+ }
69
+ }
70
+
71
+
72
+ # Tests if 'a' is less than 'b'. If 'a' is a class instance, calls its 'less'
73
+ # method. Uses ordinary jam's comparison otherwise.
74
+ #
75
+ rule less ( a b )
76
+ {
77
+ if [ is-instance $(a) ]
78
+ {
79
+ return [ $(a).less $(b) ] ;
80
+ }
81
+ else
82
+ {
83
+ if $(a) < $(b)
84
+ {
85
+ return true ;
86
+ }
87
+ }
88
+ }
89
+
90
+
91
+ # Returns the textual representation of argument. If it is a class instance,
92
+ # class its 'str' method. Otherwise, returns the argument.
93
+ #
94
+ rule str ( value )
95
+ {
96
+ if [ is-instance $(value) ]
97
+ {
98
+ return [ $(value).str ] ;
99
+ }
100
+ else
101
+ {
102
+ return $(value) ;
103
+ }
104
+ }
105
+
106
+
107
+ # Accepts a list of gristed values and returns them ungristed. Reports an error
108
+ # in case any of the passed parameters is not gristed, i.e. surrounded in angle
109
+ # brackets < and >.
110
+ #
111
+ rule ungrist ( names * )
112
+ {
113
+ local result ;
114
+ for local name in $(names)
115
+ {
116
+ local stripped = [ MATCH ^<(.*)>$ : $(name) ] ;
117
+ if ! $(stripped)
118
+ {
119
+ errors.error "in ungrist $(names) : $(name) is not of the form <.*>" ;
120
+ }
121
+ result += $(stripped) ;
122
+ }
123
+ return $(result) ;
124
+ }
125
+
126
+
127
+ # If the passed value is quoted, unquotes it. Otherwise returns the value
128
+ # unchanged.
129
+ #
130
+ rule unquote ( value ? )
131
+ {
132
+ local match-result = [ MATCH ^(\")(.*)(\")$ : $(value) ] ;
133
+ if $(match-result)
134
+ {
135
+ return $(match-result[2]) ;
136
+ }
137
+ else
138
+ {
139
+ return $(value) ;
140
+ }
141
+ }
142
+
143
+
144
+ rule __test__ ( )
145
+ {
146
+ import assert ;
147
+ import "class" : new ;
148
+ import errors : try catch ;
149
+
150
+ assert.result 123 : str 123 ;
151
+
152
+ class test-class__
153
+ {
154
+ rule __init__ ( ) { }
155
+ rule str ( ) { return "str-test-class" ; }
156
+ rule less ( a ) { return "yes, of course!" ; }
157
+ rule equal ( a ) { return "not sure" ; }
158
+ }
159
+
160
+ assert.result "str-test-class" : str [ new test-class__ ] ;
161
+ assert.true less 1 2 ;
162
+ assert.false less 2 1 ;
163
+ assert.result "yes, of course!" : less [ new test-class__ ] 1 ;
164
+ assert.true equal 1 1 ;
165
+ assert.false equal 1 2 ;
166
+ assert.result "not sure" : equal [ new test-class__ ] 1 ;
167
+
168
+ assert.result foo.lib foo.lib : apply-default-suffix .lib : foo.lib foo.lib
169
+ ;
170
+
171
+ assert.result foo : basename foo ;
172
+ assert.result foo : basename foo.so ;
173
+ assert.result foo.so : basename foo.so.1 ;
174
+
175
+ assert.result : unquote ;
176
+ assert.result "" : unquote "" ;
177
+ assert.result foo : unquote foo ;
178
+ assert.result \"foo : unquote \"foo ;
179
+ assert.result foo\" : unquote foo\" ;
180
+ assert.result foo : unquote \"foo\" ;
181
+ assert.result \"foo\" : unquote \"\"foo\"\" ;
182
+
183
+ assert.result : ungrist ;
184
+ assert.result foo : ungrist <foo> ;
185
+ assert.result <foo> : ungrist <<foo>> ;
186
+ assert.result foo bar : ungrist <foo> <bar> ;
187
+
188
+ try ;
189
+ {
190
+ ungrist "" ;
191
+ }
192
+ catch "in ungrist : is not of the form <.*>" ;
193
+
194
+ try ;
195
+ {
196
+ ungrist <> ;
197
+ }
198
+ catch "in ungrist <> : <> is not of the form <.*>" ;
199
+
200
+ try ;
201
+ {
202
+ ungrist foo ;
203
+ }
204
+ catch "in ungrist foo : foo is not of the form <.*>" ;
205
+
206
+ try ;
207
+ {
208
+ ungrist <foo ;
209
+ }
210
+ catch "in ungrist <foo : <foo is not of the form <.*>" ;
211
+
212
+ try ;
213
+ {
214
+ ungrist foo> ;
215
+ }
216
+ catch "in ungrist foo> : foo> is not of the form <.*>" ;
217
+
218
+ try ;
219
+ {
220
+ ungrist foo bar ;
221
+ }
222
+ catch "in ungrist foo : foo is not of the form <.*>" ;
223
+
224
+ try ;
225
+ {
226
+ ungrist foo <bar> ;
227
+ }
228
+ catch "in ungrist foo : foo is not of the form <.*>" ;
229
+
230
+ try ;
231
+ {
232
+ ungrist <foo> bar ;
233
+ }
234
+ catch "in ungrist bar : bar is not of the form <.*>" ;
235
+ }
mosesdecoder/moses/TranslationModel/CYKPlusParser/ChartRuleLookupManagerCYKPlus.h ADDED
@@ -0,0 +1,67 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /***********************************************************************
2
+ Moses - statistical machine translation system
3
+ Copyright (C) 2006-2012 University of Edinburgh
4
+
5
+ This library is free software; you can redistribute it and/or
6
+ modify it under the terms of the GNU Lesser General Public
7
+ License as published by the Free Software Foundation; either
8
+ version 2.1 of the License, or (at your option) any later version.
9
+
10
+ This library is distributed in the hope that it will be useful,
11
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
+ Lesser General Public License for more details.
14
+
15
+ You should have received a copy of the GNU Lesser General Public
16
+ License along with this library; if not, write to the Free Software
17
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18
+ ***********************************************************************/
19
+
20
+ #pragma once
21
+ #ifndef moses_ChartRuleLookupManagerCYKPlus_h
22
+ #define moses_ChartRuleLookupManagerCYKPlus_h
23
+
24
+ #include "moses/ChartRuleLookupManager.h"
25
+ #include "moses/StackVec.h"
26
+
27
+ namespace Moses
28
+ {
29
+
30
+ class DottedRule;
31
+ class TargetPhraseCollection;
32
+ class Range;
33
+
34
+ /** @todo what is this?
35
+ */
36
+ class ChartRuleLookupManagerCYKPlus : public ChartRuleLookupManager
37
+ {
38
+ public:
39
+ ChartRuleLookupManagerCYKPlus(const ChartParser &parser,
40
+ const ChartCellCollectionBase &cellColl)
41
+ : ChartRuleLookupManager(parser, cellColl) {}
42
+
43
+ protected:
44
+ void AddCompletedRule(
45
+ const DottedRule &dottedRule,
46
+ const TargetPhraseCollection &tpc,
47
+ const Range &range,
48
+ ChartParserCallback &outColl);
49
+
50
+ StackVec m_stackVec;
51
+ };
52
+
53
+ // struct that caches cellLabel, its end position and score for quicker lookup
54
+ struct ChartCellCache {
55
+ ChartCellCache(size_t endPos, const ChartCellLabel* cellLabel, float score)
56
+ : endPos(endPos)
57
+ , cellLabel(cellLabel)
58
+ , score(score) {}
59
+
60
+ size_t endPos;
61
+ const ChartCellLabel* cellLabel;
62
+ float score;
63
+ };
64
+
65
+ } // namespace Moses
66
+
67
+ #endif
mosesdecoder/moses/TranslationModel/CYKPlusParser/ChartRuleLookupManagerExample.cpp ADDED
@@ -0,0 +1,107 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /***********************************************************************
2
+ Moses - factored phrase-based language decoder
3
+ Copyright (C) 2011 University of Edinburgh
4
+
5
+ This library is free software; you can redistribute it and/or
6
+ modify it under the terms of the GNU Lesser General Public
7
+ License as published by the Free Software Foundation; either
8
+ version 2.1 of the License, or (at your option) any later version.
9
+
10
+ This library is distributed in the hope that it will be useful,
11
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
+ Lesser General Public License for more details.
14
+
15
+ You should have received a copy of the GNU Lesser General Public
16
+ License along with this library; if not, write to the Free Software
17
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18
+ ***********************************************************************/
19
+
20
+ #include <iostream>
21
+ #include "ChartRuleLookupManagerExample.h"
22
+ #include "DotChartInMemory.h"
23
+
24
+ #include "moses/Util.h"
25
+ #include "moses/ChartParser.h"
26
+ #include "moses/InputType.h"
27
+ #include "moses/ChartParserCallback.h"
28
+ #include "moses/StaticData.h"
29
+ #include "moses/NonTerminal.h"
30
+ #include "moses/ChartCellCollection.h"
31
+ #include "moses/TranslationModel/PhraseDictionaryMemory.h"
32
+ #include "moses/TranslationModel/ExamplePT.h"
33
+
34
+ using namespace std;
35
+
36
+ namespace Moses
37
+ {
38
+
39
+ ChartRuleLookupManagerExample::ChartRuleLookupManagerExample(
40
+ const ChartParser &parser,
41
+ const ChartCellCollectionBase &cellColl,
42
+ const ExamplePT &skeletonPt)
43
+ : ChartRuleLookupManager(parser, cellColl)
44
+ , m_skeletonPT(skeletonPt)
45
+ {
46
+ cerr << "starting ChartRuleLookupManagerExample" << endl;
47
+ }
48
+
49
+ ChartRuleLookupManagerExample::~ChartRuleLookupManagerExample()
50
+ {
51
+ // RemoveAllInColl(m_tpColl);
52
+ }
53
+
54
+ void ChartRuleLookupManagerExample::GetChartRuleCollection(
55
+ const InputPath &inputPath,
56
+ size_t last,
57
+ ChartParserCallback &outColl)
58
+ {
59
+ //m_tpColl.push_back(TargetPhraseCollection());
60
+ //TargetPhraseCollection &tpColl = m_tpColl.back();
61
+ TargetPhraseCollection::shared_ptr tpColl(new TargetPhraseCollection);
62
+ m_tpColl.push_back(tpColl);
63
+
64
+ const Range &range = inputPath.GetWordsRange();
65
+
66
+ if (range.GetNumWordsCovered() == 1) {
67
+ const ChartCellLabel &sourceWordLabel = GetSourceAt(range.GetStartPos());
68
+ const Word &sourceWord = sourceWordLabel.GetLabel();
69
+ TargetPhrase *tp = CreateTargetPhrase(sourceWord);
70
+ tpColl->Add(tp);
71
+ }
72
+
73
+ outColl.Add(*tpColl, m_stackVec, range);
74
+ }
75
+
76
+ TargetPhrase *
77
+ ChartRuleLookupManagerExample::
78
+ CreateTargetPhrase(const Word &sourceWord) const
79
+ {
80
+ // create a target phrase from the 1st word of the source, prefix with 'ChartManagerExample:'
81
+ string str = sourceWord.GetFactor(0)->GetString().as_string();
82
+ str = "ChartManagerExample:" + str;
83
+
84
+ TargetPhrase *tp = new TargetPhrase(&m_skeletonPT);
85
+ Word &word = tp->AddWord();
86
+ word.CreateFromString(Output, m_skeletonPT.GetOutput(), str, false);
87
+
88
+ // create hiero-style non-terminal for LHS
89
+ Word *targetLHS = new Word();
90
+ targetLHS->CreateFromString(Output, m_skeletonPT.GetOutput(), "X", true);
91
+ tp->SetTargetLHS(targetLHS);
92
+
93
+ // word alignement
94
+ tp->SetAlignmentInfo("0-0");
95
+
96
+ // score for this phrase table
97
+ vector<float> scores(m_skeletonPT.GetNumScoreComponents(), 1.3);
98
+ tp->GetScoreBreakdown().PlusEquals(&m_skeletonPT, scores);
99
+
100
+ // score of all other ff when this rule is being loaded
101
+ Phrase sourcePhrase;
102
+ sourcePhrase.AddWord(sourceWord);
103
+ //tp->Evaluate(sourcePhrase, m_skeletonPT.GetFeaturesToApply());
104
+
105
+ return tp;
106
+ }
107
+ } // namespace Moses
mosesdecoder/moses/TranslationModel/CYKPlusParser/ChartRuleLookupManagerExample.h ADDED
@@ -0,0 +1,57 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /***********************************************************************
2
+ Moses - factored phrase-based language decoder
3
+ Copyright (C) 2011 University of Edinburgh
4
+
5
+ This library is free software; you can redistribute it and/or
6
+ modify it under the terms of the GNU Lesser General Public
7
+ License as published by the Free Software Foundation; either
8
+ version 2.1 of the License, or (at your option) any later version.
9
+
10
+ This library is distributed in the hope that it will be useful,
11
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
+ Lesser General Public License for more details.
14
+
15
+ You should have received a copy of the GNU Lesser General Public
16
+ License along with this library; if not, write to the Free Software
17
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18
+ ***********************************************************************/
19
+
20
+ #pragma once
21
+
22
+ #include <vector>
23
+ #include "moses/ChartRuleLookupManager.h"
24
+ #include "moses/StackVec.h"
25
+
26
+ namespace Moses
27
+ {
28
+ class TargetPhraseCollection;
29
+ class ChartParserCallback;
30
+ class DottedRuleColl;
31
+ class Range;
32
+ class ExamplePT;
33
+
34
+ class ChartRuleLookupManagerExample : public ChartRuleLookupManager
35
+ {
36
+ public:
37
+ ChartRuleLookupManagerExample(const ChartParser &parser,
38
+ const ChartCellCollectionBase &cellColl,
39
+ const ExamplePT &skeletonPt);
40
+
41
+ ~ChartRuleLookupManagerExample();
42
+
43
+ virtual void GetChartRuleCollection(
44
+ const InputPath &inputPath,
45
+ size_t last,
46
+ ChartParserCallback &outColl);
47
+
48
+ private:
49
+ TargetPhrase *CreateTargetPhrase(const Word &sourceWord) const;
50
+
51
+ StackVec m_stackVec;
52
+ std::vector<TargetPhraseCollection::shared_ptr > m_tpColl;
53
+ const ExamplePT &m_skeletonPT;
54
+ };
55
+
56
+ } // namespace Moses
57
+
mosesdecoder/moses/TranslationModel/CYKPlusParser/ChartRuleLookupManagerMemory.cpp ADDED
@@ -0,0 +1,270 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /***********************************************************************
2
+ Moses - factored phrase-based language decoder
3
+ Copyright (C) 2011 University of Edinburgh
4
+
5
+ This library is free software; you can redistribute it and/or
6
+ modify it under the terms of the GNU Lesser General Public
7
+ License as published by the Free Software Foundation; either
8
+ version 2.1 of the License, or (at your option) any later version.
9
+
10
+ This library is distributed in the hope that it will be useful,
11
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
+ Lesser General Public License for more details.
14
+
15
+ You should have received a copy of the GNU Lesser General Public
16
+ License along with this library; if not, write to the Free Software
17
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18
+ ***********************************************************************/
19
+
20
+ #include <iostream>
21
+ #include "ChartRuleLookupManagerMemory.h"
22
+
23
+ #include "moses/ChartParser.h"
24
+ #include "moses/InputType.h"
25
+ #include "moses/Terminal.h"
26
+ #include "moses/ChartParserCallback.h"
27
+ #include "moses/StaticData.h"
28
+ #include "moses/NonTerminal.h"
29
+ #include "moses/ChartCellCollection.h"
30
+ #include "moses/FactorCollection.h"
31
+ #include "moses/TranslationModel/PhraseDictionaryMemory.h"
32
+
33
+ using namespace std;
34
+
35
+ namespace Moses
36
+ {
37
+
38
+ ChartRuleLookupManagerMemory::ChartRuleLookupManagerMemory(
39
+ const ChartParser &parser,
40
+ const ChartCellCollectionBase &cellColl,
41
+ const PhraseDictionaryMemory &ruleTable)
42
+ : ChartRuleLookupManagerCYKPlus(parser, cellColl)
43
+ , m_ruleTable(ruleTable)
44
+ , m_softMatchingMap(StaticData::Instance().GetSoftMatches())
45
+ {
46
+
47
+ size_t sourceSize = parser.GetSize();
48
+ size_t ruleLimit = parser.options()->syntax.rule_limit;
49
+ m_completedRules.resize(sourceSize, CompletedRuleCollection(ruleLimit));
50
+
51
+ m_isSoftMatching = !m_softMatchingMap.empty();
52
+ }
53
+
54
+ void ChartRuleLookupManagerMemory::GetChartRuleCollection(
55
+ const InputPath &inputPath,
56
+ size_t lastPos,
57
+ ChartParserCallback &outColl)
58
+ {
59
+ const Range &range = inputPath.GetWordsRange();
60
+ size_t startPos = range.GetStartPos();
61
+ size_t absEndPos = range.GetEndPos();
62
+
63
+ m_lastPos = lastPos;
64
+ m_stackVec.clear();
65
+ m_stackScores.clear();
66
+ m_outColl = &outColl;
67
+ m_unaryPos = absEndPos-1; // rules ending in this position are unary and should not be added to collection
68
+
69
+ // create/update data structure to quickly look up all chart cells that match start position and label.
70
+ UpdateCompressedMatrix(startPos, absEndPos, lastPos);
71
+
72
+ const PhraseDictionaryNodeMemory &rootNode = m_ruleTable.GetRootNode();
73
+
74
+ // all rules starting with terminal
75
+ if (startPos == absEndPos) {
76
+ GetTerminalExtension(&rootNode, startPos);
77
+ }
78
+ // all rules starting with nonterminal
79
+ else if (absEndPos > startPos) {
80
+ GetNonTerminalExtension(&rootNode, startPos);
81
+ }
82
+
83
+ // copy temporarily stored rules to out collection
84
+ CompletedRuleCollection & rules = m_completedRules[absEndPos];
85
+ for (vector<CompletedRule*>::const_iterator iter = rules.begin(); iter != rules.end(); ++iter) {
86
+ outColl.Add((*iter)->GetTPC(), (*iter)->GetStackVector(), range);
87
+ }
88
+
89
+ rules.Clear();
90
+
91
+ }
92
+
93
+ // Create/update compressed matrix that stores all valid ChartCellLabels for a given start position and label.
94
+ void ChartRuleLookupManagerMemory::UpdateCompressedMatrix(size_t startPos,
95
+ size_t origEndPos,
96
+ size_t lastPos)
97
+ {
98
+
99
+ std::vector<size_t> endPosVec;
100
+ size_t numNonTerms = FactorCollection::Instance().GetNumNonTerminals();
101
+ m_compressedMatrixVec.resize(lastPos+1);
102
+
103
+ // we only need to update cell at [startPos, origEndPos-1] for initial lookup
104
+ if (startPos < origEndPos) {
105
+ endPosVec.push_back(origEndPos-1);
106
+ }
107
+
108
+ // update all cells starting from startPos+1 for lookup of rule extensions
109
+ else if (startPos == origEndPos) {
110
+ startPos++;
111
+ for (size_t endPos = startPos; endPos <= lastPos; endPos++) {
112
+ endPosVec.push_back(endPos);
113
+ }
114
+ //re-use data structure for cells with later start position, but remove chart cells that would break max-chart-span
115
+ for (size_t pos = startPos+1; pos <= lastPos; pos++) {
116
+ CompressedMatrix & cellMatrix = m_compressedMatrixVec[pos];
117
+ cellMatrix.resize(numNonTerms);
118
+ for (size_t i = 0; i < numNonTerms; i++) {
119
+ if (!cellMatrix[i].empty() && cellMatrix[i].back().endPos > lastPos) {
120
+ cellMatrix[i].pop_back();
121
+ }
122
+ }
123
+ }
124
+ }
125
+
126
+ if (startPos > lastPos) {
127
+ return;
128
+ }
129
+
130
+ // populate compressed matrix with all chart cells that start at current start position
131
+ CompressedMatrix & cellMatrix = m_compressedMatrixVec[startPos];
132
+ cellMatrix.clear();
133
+ cellMatrix.resize(numNonTerms);
134
+ for (std::vector<size_t>::iterator p = endPosVec.begin(); p != endPosVec.end(); ++p) {
135
+
136
+ size_t endPos = *p;
137
+ // target non-terminal labels for the span
138
+ const ChartCellLabelSet &targetNonTerms = GetTargetLabelSet(startPos, endPos);
139
+
140
+ if (targetNonTerms.GetSize() == 0) {
141
+ continue;
142
+ }
143
+
144
+ #if !defined(UNLABELLED_SOURCE)
145
+ // source non-terminal labels for the span
146
+ const InputPath &inputPath = GetParser().GetInputPath(startPos, endPos);
147
+
148
+ // can this ever be true? Moses seems to pad the non-terminal set of the input with [X]
149
+ if (inputPath.GetNonTerminalSet().size() == 0) {
150
+ continue;
151
+ }
152
+ #endif
153
+
154
+ for (size_t i = 0; i < numNonTerms; i++) {
155
+ const ChartCellLabel *cellLabel = targetNonTerms.Find(i);
156
+ if (cellLabel != NULL) {
157
+ float score = cellLabel->GetBestScore(m_outColl);
158
+ cellMatrix[i].push_back(ChartCellCache(endPos, cellLabel, score));
159
+ }
160
+ }
161
+ }
162
+ }
163
+
164
+ // if a (partial) rule matches, add it to list completed rules (if non-unary and non-empty), and try find expansions that have this partial rule as prefix.
165
+ void ChartRuleLookupManagerMemory::AddAndExtend(
166
+ const PhraseDictionaryNodeMemory *node,
167
+ size_t endPos)
168
+ {
169
+
170
+ TargetPhraseCollection::shared_ptr tpc = node->GetTargetPhraseCollection();
171
+ // add target phrase collection (except if rule is empty or a unary non-terminal rule)
172
+ if (!tpc->IsEmpty() && (m_stackVec.empty() || endPos != m_unaryPos)) {
173
+ m_completedRules[endPos].Add(*tpc, m_stackVec, m_stackScores, *m_outColl);
174
+ }
175
+
176
+ // get all further extensions of rule (until reaching end of sentence or max-chart-span)
177
+ if (endPos < m_lastPos) {
178
+ if (!node->GetTerminalMap().empty()) {
179
+ GetTerminalExtension(node, endPos+1);
180
+ }
181
+ if (!node->GetNonTerminalMap().empty()) {
182
+ GetNonTerminalExtension(node, endPos+1);
183
+ }
184
+ }
185
+ }
186
+
187
+
188
+ // search all possible terminal extensions of a partial rule (pointed at by node) at a given position
189
+ // recursively try to expand partial rules into full rules up to m_lastPos.
190
+ void ChartRuleLookupManagerMemory::GetTerminalExtension(
191
+ const PhraseDictionaryNodeMemory *node,
192
+ size_t pos)
193
+ {
194
+
195
+ const Word &sourceWord = GetSourceAt(pos).GetLabel();
196
+ const PhraseDictionaryNodeMemory::TerminalMap & terminals = node->GetTerminalMap();
197
+
198
+ // if node has small number of terminal edges, test word equality for each.
199
+ if (terminals.size() < 5) {
200
+ for (PhraseDictionaryNodeMemory::TerminalMap::const_iterator iter = terminals.begin(); iter != terminals.end(); ++iter) {
201
+ const Word & word = iter->first;
202
+ if (TerminalEqualityPred()(word, sourceWord)) {
203
+ const PhraseDictionaryNodeMemory *child = & iter->second;
204
+ AddAndExtend(child, pos);
205
+ break;
206
+ }
207
+ }
208
+ }
209
+ // else, do hash lookup
210
+ else {
211
+ const PhraseDictionaryNodeMemory *child = node->GetChild(sourceWord);
212
+ if (child != NULL) {
213
+ AddAndExtend(child, pos);
214
+ }
215
+ }
216
+ }
217
+
218
+ // search all nonterminal possible nonterminal extensions of a partial rule (pointed at by node) for a variable span (starting from startPos).
219
+ // recursively try to expand partial rules into full rules up to m_lastPos.
220
+ void ChartRuleLookupManagerMemory::GetNonTerminalExtension(
221
+ const PhraseDictionaryNodeMemory *node,
222
+ size_t startPos)
223
+ {
224
+
225
+ const CompressedMatrix &compressedMatrix = m_compressedMatrixVec[startPos];
226
+
227
+ // non-terminal labels in phrase dictionary node
228
+ const PhraseDictionaryNodeMemory::NonTerminalMap & nonTermMap = node->GetNonTerminalMap();
229
+
230
+ // make room for back pointer
231
+ m_stackVec.push_back(NULL);
232
+ m_stackScores.push_back(0);
233
+
234
+ // loop over possible expansions of the rule
235
+ PhraseDictionaryNodeMemory::NonTerminalMap::const_iterator p;
236
+ PhraseDictionaryNodeMemory::NonTerminalMap::const_iterator end = nonTermMap.end();
237
+ for (p = nonTermMap.begin(); p != end; ++p) {
238
+ // does it match possible source and target non-terminals?
239
+ #if defined(UNLABELLED_SOURCE)
240
+ const Word &targetNonTerm = p->first;
241
+ #else
242
+ const Word &targetNonTerm = p->first.second;
243
+ #endif
244
+ const PhraseDictionaryNodeMemory *child = &p->second;
245
+ //soft matching of NTs
246
+ if (m_isSoftMatching && !m_softMatchingMap[targetNonTerm[0]->GetId()].empty()) {
247
+ const std::vector<Word>& softMatches = m_softMatchingMap[targetNonTerm[0]->GetId()];
248
+ for (std::vector<Word>::const_iterator softMatch = softMatches.begin(); softMatch != softMatches.end(); ++softMatch) {
249
+ const CompressedColumn &matches = compressedMatrix[(*softMatch)[0]->GetId()];
250
+ for (CompressedColumn::const_iterator match = matches.begin(); match != matches.end(); ++match) {
251
+ m_stackVec.back() = match->cellLabel;
252
+ m_stackScores.back() = match->score;
253
+ AddAndExtend(child, match->endPos);
254
+ }
255
+ }
256
+ } // end of soft matches lookup
257
+
258
+ const CompressedColumn &matches = compressedMatrix[targetNonTerm[0]->GetId()];
259
+ for (CompressedColumn::const_iterator match = matches.begin(); match != matches.end(); ++match) {
260
+ m_stackVec.back() = match->cellLabel;
261
+ m_stackScores.back() = match->score;
262
+ AddAndExtend(child, match->endPos);
263
+ }
264
+ }
265
+ // remove last back pointer
266
+ m_stackVec.pop_back();
267
+ m_stackScores.pop_back();
268
+ }
269
+
270
+ } // namespace Moses
mosesdecoder/moses/TranslationModel/CYKPlusParser/CompletedRuleCollection.cpp ADDED
@@ -0,0 +1,129 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /***********************************************************************
2
+ Moses - factored phrase-based language decoder
3
+ Copyright (C) 2014 University of Edinburgh
4
+
5
+ This library is free software; you can redistribute it and/or
6
+ modify it under the terms of the GNU Lesser General Public
7
+ License as published by the Free Software Foundation; either
8
+ version 2.1 of the License, or (at your option) any later version.
9
+
10
+ This library is distributed in the hope that it will be useful,
11
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
+ Lesser General Public License for more details.
14
+
15
+ You should have received a copy of the GNU Lesser General Public
16
+ License along with this library; if not, write to the Free Software
17
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18
+ ***********************************************************************/
19
+
20
+ #include <iostream>
21
+ #include "CompletedRuleCollection.h"
22
+
23
+ #include "moses/StaticData.h"
24
+
25
+ using namespace std;
26
+
27
+ namespace Moses
28
+ {
29
+
30
+ CompletedRuleCollection::CompletedRuleCollection(size_t rule_limit)
31
+ : m_ruleLimit(rule_limit)
32
+ {
33
+ m_scoreThreshold = numeric_limits<float>::infinity();
34
+ }
35
+
36
+ CompletedRuleCollection::~CompletedRuleCollection()
37
+ {
38
+ Clear();
39
+ }
40
+
41
+ // copies some functionality (pruning) from ChartTranslationOptionList::Add
42
+ void CompletedRuleCollection::Add(const TargetPhraseCollection &tpc,
43
+ const StackVec &stackVec,
44
+ const ChartParserCallback &outColl)
45
+ {
46
+ if (tpc.IsEmpty()) {
47
+ return;
48
+ }
49
+
50
+ const TargetPhrase &targetPhrase = **(tpc.begin());
51
+ float score = targetPhrase.GetFutureScore();
52
+ for (StackVec::const_iterator p = stackVec.begin(); p != stackVec.end(); ++p) {
53
+ float stackScore = (*p)->GetBestScore(&outColl);
54
+ score += stackScore;
55
+ }
56
+
57
+ // If the rule limit has already been reached then don't add the option
58
+ // unless it is better than at least one existing option.
59
+ if (m_ruleLimit && m_collection.size() > m_ruleLimit && score < m_scoreThreshold) {
60
+ return;
61
+ }
62
+
63
+ CompletedRule *completedRule = new CompletedRule(tpc, stackVec, score);
64
+ m_collection.push_back(completedRule);
65
+
66
+ // If the rule limit hasn't been exceeded then update the threshold.
67
+ if (!m_ruleLimit || m_collection.size() <= m_ruleLimit) {
68
+ m_scoreThreshold = (score < m_scoreThreshold) ? score : m_scoreThreshold;
69
+ }
70
+
71
+ // Prune if bursting
72
+ if (m_ruleLimit && m_collection.size() == m_ruleLimit * 2) {
73
+ NTH_ELEMENT4(m_collection.begin(),
74
+ m_collection.begin() + m_ruleLimit - 1,
75
+ m_collection.end(),
76
+ CompletedRuleOrdered());
77
+ m_scoreThreshold = m_collection[m_ruleLimit-1]->GetScoreEstimate();
78
+ for (size_t i = 0 + m_ruleLimit; i < m_collection.size(); i++) {
79
+ delete m_collection[i];
80
+
81
+ }
82
+ m_collection.resize(m_ruleLimit);
83
+ }
84
+ }
85
+
86
+
87
+ // copies some functionality (pruning) from ChartTranslationOptionList::Add
88
+ void CompletedRuleCollection::Add(const TargetPhraseCollection &tpc,
89
+ const StackVec &stackVec,
90
+ const std::vector<float> &stackScores,
91
+ const ChartParserCallback &outColl)
92
+ {
93
+ if (tpc.IsEmpty()) {
94
+ return;
95
+ }
96
+
97
+ const TargetPhrase &targetPhrase = **(tpc.begin());
98
+ float score = std::accumulate(stackScores.begin(), stackScores.end(), targetPhrase.GetFutureScore());
99
+
100
+ // If the rule limit has already been reached then don't add the option
101
+ // unless it is better than at least one existing option.
102
+ if (m_collection.size() > m_ruleLimit && score < m_scoreThreshold) {
103
+ return;
104
+ }
105
+
106
+ CompletedRule *completedRule = new CompletedRule(tpc, stackVec, score);
107
+ m_collection.push_back(completedRule);
108
+
109
+ // If the rule limit hasn't been exceeded then update the threshold.
110
+ if (m_collection.size() <= m_ruleLimit) {
111
+ m_scoreThreshold = (score < m_scoreThreshold) ? score : m_scoreThreshold;
112
+ }
113
+
114
+ // Prune if bursting
115
+ if (m_collection.size() == m_ruleLimit * 2) {
116
+ NTH_ELEMENT4(m_collection.begin(),
117
+ m_collection.begin() + m_ruleLimit - 1,
118
+ m_collection.end(),
119
+ CompletedRuleOrdered());
120
+ m_scoreThreshold = m_collection[m_ruleLimit-1]->GetScoreEstimate();
121
+ for (size_t i = 0 + m_ruleLimit; i < m_collection.size(); i++) {
122
+ delete m_collection[i];
123
+
124
+ }
125
+ m_collection.resize(m_ruleLimit);
126
+ }
127
+ }
128
+
129
+ }
mosesdecoder/moses/TranslationModel/CYKPlusParser/DotChartInMemory.cpp ADDED
@@ -0,0 +1,40 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /***********************************************************************
2
+ Moses - statistical machine translation system
3
+ Copyright (C) 2006-2011 University of Edinburgh
4
+
5
+ This library is free software; you can redistribute it and/or
6
+ modify it under the terms of the GNU Lesser General Public
7
+ License as published by the Free Software Foundation; either
8
+ version 2.1 of the License, or (at your option) any later version.
9
+
10
+ This library is distributed in the hope that it will be useful,
11
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
+ Lesser General Public License for more details.
14
+
15
+ You should have received a copy of the GNU Lesser General Public
16
+ License along with this library; if not, write to the Free Software
17
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18
+ ***********************************************************************/
19
+
20
+ #include "DotChartInMemory.h"
21
+
22
+ #include "moses/Util.h"
23
+
24
+ #include <algorithm>
25
+
26
+ namespace Moses
27
+ {
28
+
29
+ DottedRuleColl::~DottedRuleColl()
30
+ {
31
+ #ifdef USE_BOOST_POOL
32
+ // Do nothing. DottedRule objects are stored in object pools owned by
33
+ // the sentence-specific ChartRuleLookupManagers.
34
+ #else
35
+ std::for_each(m_coll.begin(), m_coll.end(),
36
+ RemoveAllInColl<CollType::value_type>);
37
+ #endif
38
+ }
39
+
40
+ }
mosesdecoder/moses/TranslationModel/CYKPlusParser/DotChartOnDisk.cpp ADDED
@@ -0,0 +1,57 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // $Id$
2
+ /***********************************************************************
3
+ Moses - factored phrase-based language decoder
4
+ Copyright (C) 2010 Hieu Hoang
5
+
6
+ This library is free software; you can redistribute it and/or
7
+ modify it under the terms of the GNU Lesser General Public
8
+ License as published by the Free Software Foundation; either
9
+ version 2.1 of the License, or (at your option) any later version.
10
+
11
+ This library is distributed in the hope that it will be useful,
12
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14
+ Lesser General Public License for more details.
15
+
16
+ You should have received a copy of the GNU Lesser General Public
17
+ License along with this library; if not, write to the Free Software
18
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19
+ ***********************************************************************/
20
+ #include <algorithm>
21
+ #include "DotChartOnDisk.h"
22
+ #include "moses/Util.h"
23
+ #include "OnDiskPt/PhraseNode.h"
24
+
25
+ using namespace std;
26
+
27
+ namespace Moses
28
+ {
29
+ DottedRuleStackOnDisk::DottedRuleStackOnDisk(size_t size)
30
+ :m_coll(size)
31
+ {
32
+ for (size_t ind = 0; ind < size; ++ind) {
33
+ m_coll[ind] = new DottedRuleCollOnDisk();
34
+ }
35
+ }
36
+
37
+ DottedRuleStackOnDisk::~DottedRuleStackOnDisk()
38
+ {
39
+ RemoveAllInColl(m_coll);
40
+ RemoveAllInColl(m_savedNode);
41
+ }
42
+
43
+ class SavedNodesOderer
44
+ {
45
+ public:
46
+ bool operator()(const SavedNodeOnDisk* a, const SavedNodeOnDisk* b) const {
47
+ bool ret = a->GetDottedRule().GetLastNode().GetCount(0) > b->GetDottedRule().GetLastNode().GetCount(0);
48
+ return ret;
49
+ }
50
+ };
51
+
52
+ void DottedRuleStackOnDisk::SortSavedNodes()
53
+ {
54
+ sort(m_savedNode.begin(), m_savedNode.end(), SavedNodesOderer());
55
+ }
56
+
57
+ };
mosesdecoder/moses/TranslationModel/CYKPlusParser/DotChartOnDisk.h ADDED
@@ -0,0 +1,186 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // $Id$
2
+ /***********************************************************************
3
+ Moses - factored phrase-based language decoder
4
+ Copyright (C) 2010 Hieu Hoang
5
+
6
+ This library is free software; you can redistribute it and/or
7
+ modify it under the terms of the GNU Lesser General Public
8
+ License as published by the Free Software Foundation; either
9
+ version 2.1 of the License, or (at your option) any later version.
10
+
11
+ This library is distributed in the hope that it will be useful,
12
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14
+ Lesser General Public License for more details.
15
+
16
+ You should have received a copy of the GNU Lesser General Public
17
+ License along with this library; if not, write to the Free Software
18
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19
+ ***********************************************************************/
20
+ #pragma once
21
+
22
+ #include <vector>
23
+ #include "DotChart.h"
24
+
25
+ namespace OnDiskPt
26
+ {
27
+ class PhraseNode;
28
+ }
29
+
30
+ namespace Moses
31
+ {
32
+
33
+ /** @todo what is this?
34
+ */
35
+ class DottedRuleOnDisk : public DottedRule
36
+ {
37
+ public:
38
+ // used only to init dot stack.
39
+ explicit DottedRuleOnDisk(const OnDiskPt::PhraseNode &lastNode)
40
+ : DottedRule()
41
+ , m_lastNode(lastNode)
42
+ , m_done(false) {}
43
+
44
+ DottedRuleOnDisk(const OnDiskPt::PhraseNode &lastNode,
45
+ const ChartCellLabel &cellLabel,
46
+ const DottedRuleOnDisk &prev)
47
+ : DottedRule(cellLabel, prev)
48
+ , m_lastNode(lastNode)
49
+ , m_done(false) {}
50
+
51
+ const OnDiskPt::PhraseNode &GetLastNode() const {
52
+ return m_lastNode;
53
+ }
54
+
55
+ bool Done() const {
56
+ return m_done;
57
+ }
58
+ void Done(bool value) const {
59
+ m_done = value;
60
+ }
61
+
62
+ private:
63
+ const OnDiskPt::PhraseNode &m_lastNode;
64
+ mutable bool m_done;
65
+ };
66
+
67
+ class DottedRuleCollOnDisk
68
+ {
69
+ protected:
70
+ typedef std::vector<const DottedRuleOnDisk*> CollType;
71
+ CollType m_coll;
72
+
73
+ public:
74
+ typedef CollType::iterator iterator;
75
+ typedef CollType::const_iterator const_iterator;
76
+
77
+ const_iterator begin() const {
78
+ return m_coll.begin();
79
+ }
80
+ const_iterator end() const {
81
+ return m_coll.end();
82
+ }
83
+ iterator begin() {
84
+ return m_coll.begin();
85
+ }
86
+ iterator end() {
87
+ return m_coll.end();
88
+ }
89
+
90
+ const DottedRuleOnDisk &Get(size_t ind) const {
91
+ return *m_coll[ind];
92
+ }
93
+
94
+ void Add(const DottedRuleOnDisk *dottedRule) {
95
+ m_coll.push_back(dottedRule);
96
+ }
97
+ void Delete(size_t ind) {
98
+ //delete m_coll[ind];
99
+ m_coll.erase(m_coll.begin() + ind);
100
+ }
101
+
102
+ size_t GetSize() const {
103
+ return m_coll.size();
104
+ }
105
+
106
+ };
107
+
108
+ class SavedNodeOnDisk
109
+ {
110
+ const DottedRuleOnDisk *m_dottedRule;
111
+
112
+ public:
113
+ SavedNodeOnDisk(const DottedRuleOnDisk *dottedRule)
114
+ :m_dottedRule(dottedRule) {
115
+ UTIL_THROW_IF2(m_dottedRule == NULL, "Dotted rule is null");
116
+ }
117
+
118
+ ~SavedNodeOnDisk() {
119
+ delete m_dottedRule;
120
+ }
121
+
122
+ const DottedRuleOnDisk &GetDottedRule() const {
123
+ return *m_dottedRule;
124
+ }
125
+ };
126
+
127
+ class DottedRuleStackOnDisk
128
+ {
129
+ // coll of coll of processed rules
130
+ public:
131
+ typedef std::vector<SavedNodeOnDisk*> SavedNodeColl;
132
+
133
+ protected:
134
+ typedef std::vector<DottedRuleCollOnDisk*> CollType;
135
+ CollType m_coll;
136
+
137
+ SavedNodeColl m_savedNode;
138
+
139
+ public:
140
+ typedef CollType::iterator iterator;
141
+ typedef CollType::const_iterator const_iterator;
142
+
143
+ const_iterator begin() const {
144
+ return m_coll.begin();
145
+ }
146
+ const_iterator end() const {
147
+ return m_coll.end();
148
+ }
149
+ iterator begin() {
150
+ return m_coll.begin();
151
+ }
152
+ iterator end() {
153
+ return m_coll.end();
154
+ }
155
+
156
+ DottedRuleStackOnDisk(size_t size);
157
+ ~DottedRuleStackOnDisk();
158
+
159
+ const DottedRuleCollOnDisk &Get(size_t pos) const {
160
+ return *m_coll[pos];
161
+ }
162
+ DottedRuleCollOnDisk &Get(size_t pos) {
163
+ return *m_coll[pos];
164
+ }
165
+
166
+ const DottedRuleCollOnDisk &back() const {
167
+ return *m_coll.back();
168
+ }
169
+
170
+ void Add(size_t pos, const DottedRuleOnDisk *dottedRule) {
171
+ UTIL_THROW_IF2(dottedRule == NULL, "Dotted rule is null");
172
+
173
+ m_coll[pos]->Add(dottedRule);
174
+ m_savedNode.push_back(new SavedNodeOnDisk(dottedRule));
175
+ }
176
+
177
+ const SavedNodeColl &GetSavedNodeColl() const {
178
+ return m_savedNode;
179
+ }
180
+
181
+ void SortSavedNodes();
182
+
183
+ };
184
+
185
+ }
186
+
mosesdecoder/moses/TranslationModel/CompactPT/CanonicalHuffman.h ADDED
@@ -0,0 +1,326 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // $Id$
2
+ // vim:tabstop=2
3
+ /***********************************************************************
4
+ Moses - factored phrase-based language decoder
5
+ Copyright (C) 2006 University of Edinburgh
6
+
7
+ This library is free software; you can redistribute it and/or
8
+ modify it under the terms of the GNU Lesser General Public
9
+ License as published by the Free Software Foundation; either
10
+ version 2.1 of the License, or (at your option) any later version.
11
+
12
+ This library is distributed in the hope that it will be useful,
13
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15
+ Lesser General Public License for more details.
16
+
17
+ You should have received a copy of the GNU Lesser General Public
18
+ License along with this library; if not, write to the Free Software
19
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20
+ ***********************************************************************/
21
+
22
+ #ifndef moses_CanonicalHuffman_h
23
+ #define moses_CanonicalHuffman_h
24
+
25
+ #include <string>
26
+ #include <algorithm>
27
+ #include <boost/dynamic_bitset.hpp>
28
+ #include <boost/unordered_map.hpp>
29
+
30
+ #include "ThrowingFwrite.h"
31
+
32
+ namespace Moses
33
+ {
34
+
35
+ template <typename Data>
36
+ class CanonicalHuffman
37
+ {
38
+ private:
39
+ std::vector<Data> m_symbols;
40
+ std::vector<size_t> m_firstCodes;
41
+ std::vector<size_t> m_lengthIndex;
42
+
43
+ typedef boost::unordered_map<Data, boost::dynamic_bitset<> > EncodeMap;
44
+ EncodeMap m_encodeMap;
45
+
46
+ struct MinHeapSorter {
47
+ std::vector<size_t>& m_vec;
48
+
49
+ MinHeapSorter(std::vector<size_t>& vec) : m_vec(vec) { }
50
+
51
+ bool operator()(size_t a, size_t b) {
52
+ return m_vec[a] > m_vec[b];
53
+ }
54
+ };
55
+
56
+ template <class Iterator>
57
+ void CalcLengths(Iterator begin, Iterator end, std::vector<size_t>& lengths) {
58
+ size_t n = std::distance(begin, end);
59
+ std::vector<size_t> A(2 * n, 0);
60
+
61
+ m_symbols.resize(n);
62
+ size_t i = 0;
63
+ for(Iterator it = begin; it != end; it++) {
64
+ m_symbols[i] = it->first;
65
+
66
+ A[i] = n + i;
67
+ A[n + i] = it->second;
68
+ i++;
69
+ }
70
+
71
+ if(n == 1) {
72
+ lengths.push_back(1);
73
+ return;
74
+ }
75
+
76
+ MinHeapSorter hs(A);
77
+ std::make_heap(A.begin(), A.begin() + n, hs);
78
+
79
+ // marked volatile to prevent the intel compiler from generating bad code
80
+ volatile size_t h = n;
81
+ volatile size_t m1, m2;
82
+ while(h > 1) {
83
+ m1 = A[0];
84
+ std::pop_heap(A.begin(), A.begin() + h, hs);
85
+
86
+ h--;
87
+
88
+ m2 = A[0];
89
+ std::pop_heap(A.begin(), A.begin() + h, hs);
90
+
91
+ A[h] = A[m1] + A[m2];
92
+ A[h-1] = h;
93
+ A[m1] = A[m2] = h;
94
+
95
+ std::push_heap(A.begin(), A.begin() + h, hs);
96
+ }
97
+
98
+ A[1] = 0;
99
+ for(size_t i = 2; i < 2*n; i++)
100
+ A[i] = A[A[i]] + 1;
101
+
102
+ lengths.resize(n);
103
+ for(size_t i = 0; i < n; i++)
104
+ lengths[i] = A[i + n];
105
+ }
106
+
107
+ void CalcCodes(std::vector<size_t>& lengths) {
108
+ std::vector<size_t> numLength;
109
+ for(std::vector<size_t>::iterator it = lengths.begin();
110
+ it != lengths.end(); it++) {
111
+ size_t length = *it;
112
+ if(numLength.size() <= length)
113
+ numLength.resize(length + 1, 0);
114
+ numLength[length]++;
115
+ }
116
+
117
+ m_lengthIndex.resize(numLength.size());
118
+ m_lengthIndex[0] = 0;
119
+ for(size_t l = 1; l < numLength.size(); l++)
120
+ m_lengthIndex[l] = m_lengthIndex[l - 1] + numLength[l - 1];
121
+
122
+ size_t maxLength = numLength.size() - 1;
123
+
124
+ m_firstCodes.resize(maxLength + 1, 0);
125
+ for(size_t l = maxLength - 1; l > 0; l--)
126
+ m_firstCodes[l] = (m_firstCodes[l + 1] + numLength[l + 1]) / 2;
127
+
128
+ std::vector<Data> t_symbols;
129
+ t_symbols.resize(lengths.size());
130
+
131
+ std::vector<size_t> nextCode = m_firstCodes;
132
+ for(size_t i = 0; i < lengths.size(); i++) {
133
+ Data data = m_symbols[i];
134
+ size_t length = lengths[i];
135
+
136
+ size_t pos = m_lengthIndex[length]
137
+ + (nextCode[length] - m_firstCodes[length]);
138
+ t_symbols[pos] = data;
139
+
140
+ nextCode[length] = nextCode[length] + 1;
141
+ }
142
+
143
+ m_symbols.swap(t_symbols);
144
+ }
145
+
146
+ void CreateCodeMap() {
147
+ for(size_t l = 1; l < m_lengthIndex.size(); l++) {
148
+ size_t intCode = m_firstCodes[l];
149
+ size_t num = ((l+1 < m_lengthIndex.size()) ? m_lengthIndex[l+1]
150
+ : m_symbols.size()) - m_lengthIndex[l];
151
+
152
+ for(size_t i = 0; i < num; i++) {
153
+ Data data = m_symbols[m_lengthIndex[l] + i];
154
+ boost::dynamic_bitset<> bitCode(l, intCode);
155
+ m_encodeMap[data] = bitCode;
156
+ intCode++;
157
+ }
158
+ }
159
+ }
160
+
161
+ const boost::dynamic_bitset<>& Encode(Data data) const {
162
+ typename EncodeMap::const_iterator it = m_encodeMap.find(data);
163
+ UTIL_THROW_IF2(it == m_encodeMap.end(), "Cannot find symbol in encoding map");
164
+ return it->second;
165
+ }
166
+
167
+ template <class BitWrapper>
168
+ void PutCode(BitWrapper& bitWrapper, const boost::dynamic_bitset<>& code) {
169
+ for(int j = code.size()-1; j >= 0; j--)
170
+ bitWrapper.Put(code[j]);
171
+ }
172
+
173
+ public:
174
+
175
+ template <class Iterator>
176
+ CanonicalHuffman(Iterator begin, Iterator end, bool forEncoding = true) {
177
+ std::vector<size_t> lengths;
178
+ CalcLengths(begin, end, lengths);
179
+ CalcCodes(lengths);
180
+
181
+ if(forEncoding)
182
+ CreateCodeMap();
183
+ }
184
+
185
+ CanonicalHuffman(std::FILE* pFile, bool forEncoding = false) {
186
+ Load(pFile);
187
+
188
+ if(forEncoding)
189
+ CreateCodeMap();
190
+ }
191
+
192
+ template <class BitWrapper>
193
+ void Put(BitWrapper& bitWrapper, Data data) {
194
+ PutCode(bitWrapper, Encode(data));
195
+ }
196
+
197
+ template <class BitWrapper>
198
+ Data Read(BitWrapper& bitWrapper) {
199
+ if(bitWrapper.TellFromEnd()) {
200
+ size_t intCode = bitWrapper.Read();
201
+ size_t len = 1;
202
+ while(intCode < m_firstCodes[len]) {
203
+ intCode = 2 * intCode + bitWrapper.Read();
204
+ len++;
205
+ }
206
+ return m_symbols[m_lengthIndex[len] + (intCode - m_firstCodes[len])];
207
+ }
208
+ return Data();
209
+ }
210
+
211
+ size_t Load(std::FILE* pFile) {
212
+ size_t start = std::ftell(pFile);
213
+ size_t read = 0;
214
+
215
+ size_t size;
216
+ read += std::fread(&size, sizeof(size_t), 1, pFile);
217
+ m_symbols.resize(size);
218
+ read += std::fread(&m_symbols[0], sizeof(Data), size, pFile);
219
+
220
+ read += std::fread(&size, sizeof(size_t), 1, pFile);
221
+ m_firstCodes.resize(size);
222
+ read += std::fread(&m_firstCodes[0], sizeof(size_t), size, pFile);
223
+
224
+ read += std::fread(&size, sizeof(size_t), 1, pFile);
225
+ m_lengthIndex.resize(size);
226
+ read += std::fread(&m_lengthIndex[0], sizeof(size_t), size, pFile);
227
+
228
+ return std::ftell(pFile) - start;
229
+ }
230
+
231
+ size_t Save(std::FILE* pFile) {
232
+ size_t start = std::ftell(pFile);
233
+
234
+ size_t size = m_symbols.size();
235
+ ThrowingFwrite(&size, sizeof(size_t), 1, pFile);
236
+ ThrowingFwrite(&m_symbols[0], sizeof(Data), size, pFile);
237
+
238
+ size = m_firstCodes.size();
239
+ ThrowingFwrite(&size, sizeof(size_t), 1, pFile);
240
+ ThrowingFwrite(&m_firstCodes[0], sizeof(size_t), size, pFile);
241
+
242
+ size = m_lengthIndex.size();
243
+ ThrowingFwrite(&size, sizeof(size_t), 1, pFile);
244
+ ThrowingFwrite(&m_lengthIndex[0], sizeof(size_t), size, pFile);
245
+
246
+ return std::ftell(pFile) - start;
247
+ }
248
+ };
249
+
250
+ template <class Container = std::string>
251
+ class BitWrapper
252
+ {
253
+ private:
254
+ Container& m_data;
255
+
256
+ typename Container::iterator m_iterator;
257
+ typename Container::value_type m_currentValue;
258
+
259
+ size_t m_valueBits;
260
+ typename Container::value_type m_mask;
261
+ size_t m_bitPos;
262
+
263
+ public:
264
+
265
+ BitWrapper(Container &data)
266
+ : m_data(data), m_iterator(m_data.begin()), m_currentValue(0),
267
+ m_valueBits(sizeof(typename Container::value_type) * 8),
268
+ m_mask(1), m_bitPos(0) { }
269
+
270
+ bool Read() {
271
+ if(m_bitPos % m_valueBits == 0) {
272
+ if(m_iterator != m_data.end())
273
+ m_currentValue = *m_iterator++;
274
+ } else
275
+ m_currentValue = m_currentValue >> 1;
276
+
277
+ m_bitPos++;
278
+ return (m_currentValue & m_mask);
279
+ }
280
+
281
+ void Put(bool bit) {
282
+ if(m_bitPos % m_valueBits == 0)
283
+ m_data.push_back(0);
284
+
285
+ if(bit)
286
+ m_data[m_data.size()-1] |= m_mask << (m_bitPos % m_valueBits);
287
+
288
+ m_bitPos++;
289
+ }
290
+
291
+ size_t Tell() {
292
+ return m_bitPos;
293
+ }
294
+
295
+ size_t TellFromEnd() {
296
+ if(m_data.size() * m_valueBits < m_bitPos)
297
+ return 0;
298
+ return m_data.size() * m_valueBits - m_bitPos;
299
+ }
300
+
301
+ void Seek(size_t bitPos) {
302
+ m_bitPos = bitPos;
303
+ m_iterator = m_data.begin() + int((m_bitPos-1)/m_valueBits);
304
+ m_currentValue = (*m_iterator) >> ((m_bitPos-1) % m_valueBits);
305
+ m_iterator++;
306
+ }
307
+
308
+ void SeekFromEnd(size_t bitPosFromEnd) {
309
+ size_t bitPos = m_data.size() * m_valueBits - bitPosFromEnd;
310
+ Seek(bitPos);
311
+ }
312
+
313
+ void Reset() {
314
+ m_iterator = m_data.begin();
315
+ m_currentValue = 0;
316
+ m_bitPos = 0;
317
+ }
318
+
319
+ Container& GetContainer() {
320
+ return m_data;
321
+ }
322
+ };
323
+
324
+ }
325
+
326
+ #endif