summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorHari Khalsa <hkhalsa@10gen.com>2012-10-24 17:40:42 -0400
committerHari Khalsa <hkhalsa@10gen.com>2012-10-29 09:28:18 -0400
commit325b42be26c6dda8965f2d6b9b7b64b381f5bd61 (patch)
treedb4db08805b0b1722e10cba723f5ea2dd9e88ca7 /src
parent1bd2fc12ef9de5b705dc1d127d02c397441c77e8 (diff)
downloadmongo-325b42be26c6dda8965f2d6b9b7b64b381f5bd61.tar.gz
SERVER-2874 Import S2 the flags library it depends on, add GeoJSON parsing
SERVER-2874 make the S2 stuff compile on mac/windows
Diffstat (limited to 'src')
-rw-r--r--src/mongo/SConscript10
-rw-r--r--src/mongo/db/geo/geojsonparser.cpp190
-rw-r--r--src/mongo/db/geo/geojsonparser.h44
-rw-r--r--src/mongo/db/geo/geojsonparser_test.cpp106
-rw-r--r--src/third_party/SConscript5
-rwxr-xr-xsrc/third_party/gflags-2.0/AUTHORS2
-rwxr-xr-xsrc/third_party/gflags-2.0/COPYING28
-rwxr-xr-xsrc/third_party/gflags-2.0/ChangeLog195
-rwxr-xr-xsrc/third_party/gflags-2.0/INSTALL237
-rwxr-xr-xsrc/third_party/gflags-2.0/Makefile1216
-rwxr-xr-xsrc/third_party/gflags-2.0/Makefile.am213
-rwxr-xr-xsrc/third_party/gflags-2.0/Makefile.in1216
-rwxr-xr-xsrc/third_party/gflags-2.0/NEWS158
-rwxr-xr-xsrc/third_party/gflags-2.0/README9
-rwxr-xr-xsrc/third_party/gflags-2.0/README_windows.txt26
-rwxr-xr-xsrc/third_party/gflags-2.0/SConscript16
-rwxr-xr-xsrc/third_party/gflags-2.0/aclocal.m4890
-rwxr-xr-xsrc/third_party/gflags-2.0/autogen.sh29
-rwxr-xr-xsrc/third_party/gflags-2.0/config.guess1526
-rwxr-xr-xsrc/third_party/gflags-2.0/config.status2288
-rwxr-xr-xsrc/third_party/gflags-2.0/config.sub1658
-rwxr-xr-xsrc/third_party/gflags-2.0/configure20626
-rwxr-xr-xsrc/third_party/gflags-2.0/configure.ac131
-rwxr-xr-xsrc/third_party/gflags-2.0/depcomp589
-rwxr-xr-xsrc/third_party/gflags-2.0/doc/designstyle.css115
-rwxr-xr-xsrc/third_party/gflags-2.0/doc/gflags.html546
-rwxr-xr-xsrc/third_party/gflags-2.0/gflags.sln32
-rwxr-xr-xsrc/third_party/gflags-2.0/install-sh519
-rwxr-xr-xsrc/third_party/gflags-2.0/libtool9060
-rwxr-xr-xsrc/third_party/gflags-2.0/ltmain.sh8413
-rwxr-xr-xsrc/third_party/gflags-2.0/m4/ac_have_attribute.m416
-rwxr-xr-xsrc/third_party/gflags-2.0/m4/acx_pthread.m4397
-rwxr-xr-xsrc/third_party/gflags-2.0/m4/google_namespace.m442
-rwxr-xr-xsrc/third_party/gflags-2.0/m4/libtool.m47377
-rwxr-xr-xsrc/third_party/gflags-2.0/m4/ltoptions.m4368
-rwxr-xr-xsrc/third_party/gflags-2.0/m4/ltsugar.m4123
-rwxr-xr-xsrc/third_party/gflags-2.0/m4/ltversion.m423
-rwxr-xr-xsrc/third_party/gflags-2.0/m4/lt~obsolete.m492
-rwxr-xr-xsrc/third_party/gflags-2.0/m4/namespaces.m415
-rwxr-xr-xsrc/third_party/gflags-2.0/m4/stl_namespace.m425
-rwxr-xr-xsrc/third_party/gflags-2.0/makelog77
-rwxr-xr-xsrc/third_party/gflags-2.0/missing367
-rwxr-xr-xsrc/third_party/gflags-2.0/packages/deb.sh74
-rwxr-xr-xsrc/third_party/gflags-2.0/packages/deb/changelog135
-rwxr-xr-xsrc/third_party/gflags-2.0/packages/deb/compat1
-rwxr-xr-xsrc/third_party/gflags-2.0/packages/deb/control25
-rwxr-xr-xsrc/third_party/gflags-2.0/packages/deb/copyright35
-rwxr-xr-xsrc/third_party/gflags-2.0/packages/deb/docs8
-rwxr-xr-xsrc/third_party/gflags-2.0/packages/deb/libgflags-dev.dirs5
-rwxr-xr-xsrc/third_party/gflags-2.0/packages/deb/libgflags-dev.install12
-rwxr-xr-xsrc/third_party/gflags-2.0/packages/deb/libgflags0.dirs2
-rwxr-xr-xsrc/third_party/gflags-2.0/packages/deb/libgflags0.install4
-rwxr-xr-xsrc/third_party/gflags-2.0/packages/deb/rules117
-rwxr-xr-xsrc/third_party/gflags-2.0/packages/rpm.sh86
-rwxr-xr-xsrc/third_party/gflags-2.0/packages/rpm/rpm.spec81
-rwxr-xr-xsrc/third_party/gflags-2.0/src/config.h115
-rwxr-xr-xsrc/third_party/gflags-2.0/src/config.h.in106
-rwxr-xr-xsrc/third_party/gflags-2.0/src/config_for_unittests.h63
-rwxr-xr-xsrc/third_party/gflags-2.0/src/gflags.cc1971
-rwxr-xr-xsrc/third_party/gflags-2.0/src/gflags/gflags.h569
-rwxr-xr-xsrc/third_party/gflags-2.0/src/gflags/gflags.h.in565
-rwxr-xr-xsrc/third_party/gflags-2.0/src/gflags/gflags_completions.h130
-rwxr-xr-xsrc/third_party/gflags-2.0/src/gflags/gflags_completions.h.in130
-rwxr-xr-xsrc/third_party/gflags-2.0/src/gflags/gflags_declare.h112
-rwxr-xr-xsrc/third_party/gflags-2.0/src/gflags/gflags_declare.h.in112
-rwxr-xr-xsrc/third_party/gflags-2.0/src/gflags_completions.cc768
-rwxr-xr-xsrc/third_party/gflags-2.0/src/gflags_completions.sh117
-rwxr-xr-xsrc/third_party/gflags-2.0/src/gflags_nc.cc68
-rwxr-xr-xsrc/third_party/gflags-2.0/src/gflags_reporting.cc447
-rwxr-xr-xsrc/third_party/gflags-2.0/src/gflags_strip_flags_test.cc61
-rwxr-xr-xsrc/third_party/gflags-2.0/src/gflags_strip_flags_test.sh80
-rwxr-xr-xsrc/third_party/gflags-2.0/src/gflags_unittest.cc1539
-rwxr-xr-xsrc/third_party/gflags-2.0/src/gflags_unittest.sh237
-rwxr-xr-xsrc/third_party/gflags-2.0/src/gflags_unittest_flagfile2
-rwxr-xr-xsrc/third_party/gflags-2.0/src/google/gflags.h34
-rwxr-xr-xsrc/third_party/gflags-2.0/src/google/gflags_completions.h34
-rwxr-xr-xsrc/third_party/gflags-2.0/src/mutex.h356
-rwxr-xr-xsrc/third_party/gflags-2.0/src/solaris/libstdc++.la51
-rwxr-xr-xsrc/third_party/gflags-2.0/src/stamp-h11
-rwxr-xr-xsrc/third_party/gflags-2.0/src/util.h333
-rwxr-xr-xsrc/third_party/gflags-2.0/src/windows/config.h139
-rwxr-xr-xsrc/third_party/gflags-2.0/src/windows/gflags/gflags.h569
-rwxr-xr-xsrc/third_party/gflags-2.0/src/windows/gflags/gflags_completions.h132
-rwxr-xr-xsrc/third_party/gflags-2.0/src/windows/gflags/gflags_declare.h114
-rwxr-xr-xsrc/third_party/gflags-2.0/src/windows/port.cc62
-rwxr-xr-xsrc/third_party/gflags-2.0/src/windows/port.h111
-rwxr-xr-xsrc/third_party/gflags-2.0/vsprojects/gflags_unittest/gflags_unittest.vcproj159
-rwxr-xr-xsrc/third_party/gflags-2.0/vsprojects/libgflags/libgflags.vcproj211
-rw-r--r--src/third_party/s2/LICENSE-2.0.txt202
-rw-r--r--src/third_party/s2/Makefile223
-rw-r--r--src/third_party/s2/SConscript56
-rwxr-xr-xsrc/third_party/s2/base/SConscript16
-rwxr-xr-xsrc/third_party/s2/base/basictypes.h103
-rwxr-xr-xsrc/third_party/s2/base/casts.h396
-rwxr-xr-xsrc/third_party/s2/base/commandlineflags.h19
-rw-r--r--src/third_party/s2/base/definer.h17
-rwxr-xr-xsrc/third_party/s2/base/docid.h340
-rwxr-xr-xsrc/third_party/s2/base/int128.cc19
-rwxr-xr-xsrc/third_party/s2/base/int128.h239
-rwxr-xr-xsrc/third_party/s2/base/integral_types.h107
-rwxr-xr-xsrc/third_party/s2/base/logging.cc38
-rwxr-xr-xsrc/third_party/s2/base/logging.h99
-rwxr-xr-xsrc/third_party/s2/base/macros.h263
-rwxr-xr-xsrc/third_party/s2/base/port.h1081
-rwxr-xr-xsrc/third_party/s2/base/scoped_ptr.h427
-rwxr-xr-xsrc/third_party/s2/base/stl_decl.h34
-rwxr-xr-xsrc/third_party/s2/base/stl_decl_msvc.h134
-rwxr-xr-xsrc/third_party/s2/base/stl_decl_osx.h88
-rwxr-xr-xsrc/third_party/s2/base/stringprintf.cc79
-rwxr-xr-xsrc/third_party/s2/base/stringprintf.h42
-rwxr-xr-xsrc/third_party/s2/base/strtoint.cc48
-rwxr-xr-xsrc/third_party/s2/base/strtoint.h93
-rwxr-xr-xsrc/third_party/s2/base/template_util.h98
-rwxr-xr-xsrc/third_party/s2/base/type_traits.h285
-rwxr-xr-xsrc/third_party/s2/pywraps2_test.py51
-rw-r--r--src/third_party/s2/r1interval.h186
-rw-r--r--src/third_party/s2/r1interval_test.cc109
-rw-r--r--src/third_party/s2/s1angle.cc41
-rw-r--r--src/third_party/s2/s1angle.h207
-rw-r--r--src/third_party/s2/s1angle_test.cc173
-rw-r--r--src/third_party/s2/s1interval.cc250
-rw-r--r--src/third_party/s2/s1interval.h224
-rw-r--r--src/third_party/s2/s1interval_test.cc371
-rw-r--r--src/third_party/s2/s2.cc773
-rw-r--r--src/third_party/s2/s2.h867
-rw-r--r--src/third_party/s2/s2.swig120
-rw-r--r--src/third_party/s2/s2_test.cc743
-rw-r--r--src/third_party/s2/s2cap.cc262
-rw-r--r--src/third_party/s2/s2cap.h175
-rw-r--r--src/third_party/s2/s2cap_test.cc253
-rw-r--r--src/third_party/s2/s2cell.cc223
-rw-r--r--src/third_party/s2/s2cell.h143
-rw-r--r--src/third_party/s2/s2cell_test.cc382
-rw-r--r--src/third_party/s2/s2cellid.cc536
-rw-r--r--src/third_party/s2/s2cellid.h518
-rw-r--r--src/third_party/s2/s2cellid_test.cc477
-rw-r--r--src/third_party/s2/s2cellunion.cc454
-rw-r--r--src/third_party/s2/s2cellunion.h207
-rw-r--r--src/third_party/s2/s2cellunion_test.cc449
-rw-r--r--src/third_party/s2/s2edgeindex.cc450
-rw-r--r--src/third_party/s2/s2edgeindex.h258
-rw-r--r--src/third_party/s2/s2edgeindex_test.cc388
-rw-r--r--src/third_party/s2/s2edgeutil.cc448
-rw-r--r--src/third_party/s2/s2edgeutil.h336
-rw-r--r--src/third_party/s2/s2edgeutil_test.cc651
-rw-r--r--src/third_party/s2/s2latlng.cc71
-rw-r--r--src/third_party/s2/s2latlng.h191
-rw-r--r--src/third_party/s2/s2latlng_test.cc136
-rw-r--r--src/third_party/s2/s2latlngrect.cc591
-rw-r--r--src/third_party/s2/s2latlngrect.h320
-rw-r--r--src/third_party/s2/s2latlngrect_test.cc720
-rw-r--r--src/third_party/s2/s2loop.cc818
-rw-r--r--src/third_party/s2/s2loop.h431
-rw-r--r--src/third_party/s2/s2loop_test.cc767
-rw-r--r--src/third_party/s2/s2pointregion.cc52
-rw-r--r--src/third_party/s2/s2pointregion.h47
-rw-r--r--src/third_party/s2/s2pointregion_test.cc50
-rw-r--r--src/third_party/s2/s2polygon.cc1228
-rw-r--r--src/third_party/s2/s2polygon.h311
-rw-r--r--src/third_party/s2/s2polygon_test.cc1226
-rw-r--r--src/third_party/s2/s2polygonbuilder.cc574
-rw-r--r--src/third_party/s2/s2polygonbuilder.h318
-rw-r--r--src/third_party/s2/s2polygonbuilder_test.cc555
-rw-r--r--src/third_party/s2/s2polyline.cc578
-rw-r--r--src/third_party/s2/s2polyline.h194
-rw-r--r--src/third_party/s2/s2polyline_test.cc462
-rw-r--r--src/third_party/s2/s2r2rect.cc152
-rw-r--r--src/third_party/s2/s2r2rect.h205
-rw-r--r--src/third_party/s2/s2r2rect_test.cc272
-rw-r--r--src/third_party/s2/s2region.cc10
-rw-r--r--src/third_party/s2/s2region.h101
-rw-r--r--src/third_party/s2/s2regioncoverer.cc359
-rw-r--r--src/third_party/s2/s2regioncoverer.h211
-rw-r--r--src/third_party/s2/s2regioncoverer_test.cc290
-rw-r--r--src/third_party/s2/s2regionintersection.cc84
-rw-r--r--src/third_party/s2/s2regionintersection.h69
-rw-r--r--src/third_party/s2/s2regionunion.cc90
-rw-r--r--src/third_party/s2/s2regionunion.h72
-rw-r--r--src/third_party/s2/s2regionunion_test.cc65
-rw-r--r--src/third_party/s2/s2testing.cc313
-rw-r--r--src/third_party/s2/s2testing.h154
-rwxr-xr-xsrc/third_party/s2/strings/SConscript17
-rwxr-xr-xsrc/third_party/s2/strings/ascii_ctype.cc86
-rwxr-xr-xsrc/third_party/s2/strings/ascii_ctype.h95
-rwxr-xr-xsrc/third_party/s2/strings/split.cc504
-rwxr-xr-xsrc/third_party/s2/strings/split.h177
-rwxr-xr-xsrc/third_party/s2/strings/stringprintf.cc52
-rwxr-xr-xsrc/third_party/s2/strings/stringprintf.h40
-rwxr-xr-xsrc/third_party/s2/strings/strutil.cc526
-rwxr-xr-xsrc/third_party/s2/strings/strutil.h325
-rwxr-xr-xsrc/third_party/s2/util/coding/SConscript15
-rwxr-xr-xsrc/third_party/s2/util/coding/coder.cc107
-rwxr-xr-xsrc/third_party/s2/util/coding/coder.h444
-rwxr-xr-xsrc/third_party/s2/util/coding/varint.cc264
-rwxr-xr-xsrc/third_party/s2/util/coding/varint.h508
-rwxr-xr-xsrc/third_party/s2/util/endian/endian.h191
-rwxr-xr-xsrc/third_party/s2/util/hash/hash_jenkins_lookup2.h153
-rwxr-xr-xsrc/third_party/s2/util/math/SConscript13
-rwxr-xr-xsrc/third_party/s2/util/math/exactfloat/exactfloat.cc749
-rwxr-xr-xsrc/third_party/s2/util/math/exactfloat/exactfloat.h605
-rwxr-xr-xsrc/third_party/s2/util/math/mathlimits.cc81
-rwxr-xr-xsrc/third_party/s2/util/math/mathlimits.h238
-rwxr-xr-xsrc/third_party/s2/util/math/mathutil.cc232
-rwxr-xr-xsrc/third_party/s2/util/math/mathutil.h749
-rwxr-xr-xsrc/third_party/s2/util/math/matrix3x3-inl.h576
-rwxr-xr-xsrc/third_party/s2/util/math/matrix3x3.h26
-rwxr-xr-xsrc/third_party/s2/util/math/vector2-inl.h361
-rwxr-xr-xsrc/third_party/s2/util/math/vector2.h189
-rwxr-xr-xsrc/third_party/s2/util/math/vector3-inl.h428
-rwxr-xr-xsrc/third_party/s2/util/math/vector3.h189
-rwxr-xr-xsrc/third_party/s2/util/math/vector4-inl.h432
-rwxr-xr-xsrc/third_party/s2/util/math/vector4.h178
212 files changed, 105003 insertions, 3 deletions
diff --git a/src/mongo/SConscript b/src/mongo/SConscript
index a50edb98f81..9076475920d 100644
--- a/src/mongo/SConscript
+++ b/src/mongo/SConscript
@@ -395,14 +395,20 @@ serverOnlyFiles += [ "s/d_logic.cpp",
env.StaticLibrary("defaultversion", "s/default_version.cpp")
-env.StaticLibrary("geometry", [ "db/geo/hash.cpp", "db/geo/shapes.cpp" ], LIBDEPS = [ "bson" ])
+env.StaticLibrary("geometry", [ "db/geo/hash.cpp", "db/geo/shapes.cpp", ], LIBDEPS = [ "bson" ])
+env.StaticLibrary("geojson", [ "db/geo/geojsonparser.cpp", ],
+ LIBDEPS = [ "bson",
+ '$BUILD_DIR/third_party/gflags-2.0/gflags',
+ '$BUILD_DIR/third_party/s2/s2' ])
-env.CppUnitTest("hash_test", [ "db/geo/hash_test.cpp" ], LIBDEPS = ["geometry"],)
+env.CppUnitTest("hash_test", [ "db/geo/hash_test.cpp" ], LIBDEPS = ["geometry" ])
+env.CppUnitTest("geojsonparser_test", [ "db/geo/geojsonparser_test.cpp" ], LIBDEPS = ["geojson"])
env.StaticLibrary("serveronly", serverOnlyFiles,
LIBDEPS=["coreshard",
"dbcmdline",
"defaultversion",
+ "geojson",
"geometry",
'$BUILD_DIR/third_party/shim_snappy'])
diff --git a/src/mongo/db/geo/geojsonparser.cpp b/src/mongo/db/geo/geojsonparser.cpp
new file mode 100644
index 00000000000..147aa043865
--- /dev/null
+++ b/src/mongo/db/geo/geojsonparser.cpp
@@ -0,0 +1,190 @@
+/**
+* Copyright (C) 2012 10gen Inc.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Affero General Public License, version 3,
+* as published by the Free Software Foundation.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU Affero General Public License for more details.
+*
+* You should have received a copy of the GNU Affero General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <string>
+#include <vector>
+#include "mongo/db/jsobj.h"
+#include "mongo/db/geo/geojsonparser.h"
+#include "third_party/s2/s2.h"
+#include "third_party/s2/s2latlng.h"
+#include "third_party/s2/s2loop.h"
+#include "third_party/s2/s2polygon.h"
+#include "third_party/s2/s2polygonbuilder.h"
+#include "third_party/s2/s2polyline.h"
+
+// TODO(hk): Modify S2 library to make DCHECKS work like fassert.
+
+namespace mongo {
+ // This field must be present, and...
+ static const string GEOJSON_TYPE = "type";
+ // Have one of these three values:
+ static const string GEOJSON_TYPE_POINT = "Point";
+ static const string GEOJSON_TYPE_LINESTRING = "LineString";
+ static const string GEOJSON_TYPE_POLYGON = "Polygon";
+ // This field must also be present. The value depends on the type.
+ static const string GEOJSON_COORDINATES = "coordinates";
+
+ //// Utility functions used by GeoJSONParser functions below.
+ static S2Point latLngToPoint(const vector<BSONElement>& coordElt) {
+ return S2LatLng::FromDegrees(coordElt[1].Number(),
+ coordElt[0].Number()).Normalized().ToPoint();
+ }
+
+ static void parsePoints(const vector<BSONElement>& coordElt, vector<S2Point>* out) {
+ for (size_t i = 0; i < coordElt.size(); ++i) {
+ const vector<BSONElement>& pointElt = coordElt[i].Array();
+ if (pointElt.empty()) { continue; }
+ out->push_back(latLngToPoint(pointElt));
+ }
+ }
+
+ static bool isArrayOfCoordinates(const vector<BSONElement>& coordinateArray) {
+ for (size_t i = 0; i < coordinateArray.size(); ++i) {
+ // Each coordinate should be an array
+ if (Array != coordinateArray[i].type()) { return false; }
+ // ...of two
+ const vector<BSONElement> &thisCoord = coordinateArray[i].Array();
+ if (2 != thisCoord.size()) { return false; }
+ // ...numbers.
+ for (size_t j = 0; j < thisCoord.size(); ++j) {
+ if (!thisCoord[j].isNumber()) { return false; }
+ }
+ }
+ return true;
+ }
+
+ // Coordinates looks like [[0,0],[5,0],[5,5],[0,5],[0,0]]
+ static bool isLoopClosed(const vector<BSONElement>& coordinates) {
+ double x1, y1, x2, y2;
+ x1 = coordinates[0].Array()[0].Number();
+ y1 = coordinates[0].Array()[1].Number();
+ x2 = coordinates[coordinates.size() - 1].Array()[0].Number();
+ y2 = coordinates[coordinates.size() - 1].Array()[1].Number();
+ // TODO(hk): maybe use fuzzier comparison?
+ return x1 == x2 && y1 == y2;
+ }
+
+ //// What we publicly export
+ bool GeoJSONParser::isPoint(const BSONObj& obj) {
+ BSONElement type = obj.getFieldDotted(GEOJSON_TYPE);
+ if (type.eoo() || (String != type.type())) { return false; }
+ if (GEOJSON_TYPE_POINT != type.String()) { return false; }
+
+ BSONElement coordElt = obj.getFieldDotted(GEOJSON_COORDINATES);
+ if (coordElt.eoo() || (Array != coordElt.type())) { return false; }
+
+ const vector<BSONElement>& coordinates = coordElt.Array();
+ if (coordinates.size() != 2) { return false; }
+ return coordinates[0].isNumber() && coordinates[1].isNumber();
+ }
+
+ void GeoJSONParser::parsePoint(const BSONObj& obj, S2Point* out) {
+ const vector<BSONElement>& coords = obj.getFieldDotted(GEOJSON_COORDINATES).Array();
+ *out = latLngToPoint(coords);
+ }
+
+ bool GeoJSONParser::isLineString(const BSONObj& obj) {
+ BSONElement type = obj.getFieldDotted(GEOJSON_TYPE);
+ if (type.eoo() || (String != type.type())) { return false; }
+ if (GEOJSON_TYPE_LINESTRING != type.String()) { return false; }
+
+ BSONElement coordElt = obj.getFieldDotted(GEOJSON_COORDINATES);
+ if (coordElt.eoo() || (Array != coordElt.type())) { return false; }
+
+ const vector<BSONElement>& coordinateArray = coordElt.Array();
+ if (coordinateArray.size() < 2) { return false; }
+ return isArrayOfCoordinates(coordinateArray);
+ }
+
+ void GeoJSONParser::parseLineString(const BSONObj& obj, S2Polyline* out) {
+ vector<S2Point> vertices;
+ parsePoints(obj.getFieldDotted(GEOJSON_COORDINATES).Array(), &vertices);
+ out->Init(vertices);
+ }
+
+ bool GeoJSONParser::isPolygon(const BSONObj& obj) {
+ BSONElement type = obj.getFieldDotted(GEOJSON_TYPE);
+ if (type.eoo() || (String != type.type())) { return false; }
+ if (GEOJSON_TYPE_POLYGON != type.String()) { return false; }
+
+ BSONElement coordElt = obj.getFieldDotted(GEOJSON_COORDINATES);
+ if (coordElt.eoo() || (Array != coordElt.type())) { return false; }
+
+ const vector<BSONElement>& coordinates = coordElt.Array();
+ // Must be at least one element, the outer shell
+ if (coordinates.empty()) { return false; }
+ // Verify that the shell is a bunch'a coordinates.
+ for (size_t i = 0; i < coordinates.size(); ++i) {
+ if (Array != coordinates[i].type()) { return false; }
+ const vector<BSONElement>& thisLoop = coordinates[i].Array();
+ // A triangle is the simplest 2d shape, and we repeat a vertex, so, 4.
+ if (thisLoop.size() < 4) { return false; }
+ if (!isArrayOfCoordinates(thisLoop)) { return false; }
+ if (!isLoopClosed(thisLoop)) { return false; }
+ }
+ return true;
+ }
+
+ void fixOrientationTo(vector<S2Point>* points, const bool wantClockwise) {
+ const vector<S2Point>& pointsRef = *points;
+ massert(0, "Don't have enough points in S2 orientation fixing to work with", 4 <= points->size());
+ double sum = 0;
+ // Sum the area under the curve...well really, it's twice the area.
+ for (size_t i = 0; i < pointsRef.size(); ++i) {
+ S2Point a = pointsRef[i];
+ S2Point b = pointsRef[(i + 1) % pointsRef.size()];
+ sum += (b[1] - a[1]) * (b[0] - a[0]);
+ }
+ // If sum > 0, clockwise
+ // If sum < 0, counter-clockwise
+ bool isClockwise = sum > 0;
+ if (isClockwise != wantClockwise) {
+ vector<S2Point> reversed(pointsRef.rbegin(), pointsRef.rend());
+ *points = reversed;
+ }
+ uassert(0, "Couldn't fix the orientation of a loop!", 0);
+ }
+
+ void GeoJSONParser::parsePolygon(const BSONObj& obj, S2Polygon* out) {
+ const vector<BSONElement>& coordinates =
+ obj.getFieldDotted(GEOJSON_COORDINATES).Array();
+
+ const vector<BSONElement>& exteriorRing = coordinates[0].Array();
+ vector<S2Point> exteriorVertices;
+ parsePoints(exteriorRing, &exteriorVertices);
+
+ // The exterior ring must be counter-clockwise. We fix it up for the user.
+ fixOrientationTo(&exteriorVertices, false);
+
+ S2PolygonBuilderOptions polyOptions;
+ polyOptions.set_validate(true);
+ S2PolygonBuilder polyBuilder(polyOptions);
+ S2Loop exteriorLoop(exteriorVertices);
+ polyBuilder.AddLoop(&exteriorLoop);
+
+ // Subsequent arrays of coordinates are interior rings/holes.
+ for (size_t i = 1; i < coordinates.size(); ++i) {
+ vector<S2Point> holePoints;
+ parsePoints(coordinates[i].Array(), &holePoints);
+ // Interior rings are clockwise.
+ fixOrientationTo(&holePoints, true);
+ S2Loop holeLoop(holePoints);
+ polyBuilder.AddLoop(&holeLoop);
+ }
+
+ polyBuilder.AssemblePolygon(out, NULL);
+ }
+} // namespace mongo
diff --git a/src/mongo/db/geo/geojsonparser.h b/src/mongo/db/geo/geojsonparser.h
new file mode 100644
index 00000000000..f7b81986d4b
--- /dev/null
+++ b/src/mongo/db/geo/geojsonparser.h
@@ -0,0 +1,44 @@
+/**
+* Copyright (C) 2008-2012 10gen Inc.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Affero General Public License, version 3,
+* as published by the Free Software Foundation.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU Affero General Public License for more details.
+*
+* You should have received a copy of the GNU Affero General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#pragma once
+
+#include "mongo/db/jsobj.h"
+#include <vector>
+#include "third_party/s2/s2.h"
+
+class S2Polyline;
+class S2Polygon;
+
+namespace mongo {
+ // This class parses a subset of GeoJSON and creates S2 shapes from it.
+ // See http://geojson.org/geojson-spec.html for the spec.
+ //
+ // We assume that if you're trying to parse something, you know it's valid.
+ // This means don't call parsePoint(x) unless you're sure isPoint(x).
+ // Perhaps there should just be parsePoint that returns bool and calls isPoint itself?
+ class GeoJSONParser {
+ public:
+ static bool isPoint(const BSONObj &obj);
+ static void parsePoint(const BSONObj &obj, S2Point *out);
+
+ static bool isLineString(const BSONObj &obj);
+ static void parseLineString(const BSONObj &obj, S2Polyline *out);
+
+ static bool isPolygon(const BSONObj &obj);
+ static void parsePolygon(const BSONObj &obj, S2Polygon *out);
+ };
+} // namespace mongo
diff --git a/src/mongo/db/geo/geojsonparser_test.cpp b/src/mongo/db/geo/geojsonparser_test.cpp
new file mode 100644
index 00000000000..7739e2e8994
--- /dev/null
+++ b/src/mongo/db/geo/geojsonparser_test.cpp
@@ -0,0 +1,106 @@
+/**
+ * Copyright (C) 2012 10gen Inc.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/**
+ * This file contains tests for mongo/db/geo/geojson_parser.cpp.
+ */
+
+#include <string>
+#include <sstream>
+
+#include "mongo/db/geo/geojsonparser.h"
+#include "mongo/db/json.h"
+#include "mongo/unittest/unittest.h"
+#include "mongo/util/assert_util.h"
+
+#include "third_party/s2/s2.h"
+#include "third_party/s2/s2polygon.h"
+#include "third_party/s2/s2polyline.h"
+
+//using std::string;
+//using std::stringstream;
+using mongo::GeoJSONParser;
+using mongo::fromjson;
+
+namespace {
+ TEST(GeoJSONParser, isValidPoint) {
+ ASSERT_TRUE(GeoJSONParser::isPoint(fromjson("{'type':'Point', 'coordinates': [40, 5]}")));
+ ASSERT_TRUE(GeoJSONParser::isPoint(fromjson("{'type':'Point', 'coordinates': [-40.3, -5.0]}")));
+
+ ASSERT_FALSE(GeoJSONParser::isPoint(fromjson("{'typo':'Point', 'coordinates': [40, -5]}")));
+ ASSERT_FALSE(GeoJSONParser::isPoint(fromjson("{'type':'Point', 'coordhats': [40, -5]}")));
+ ASSERT_FALSE(GeoJSONParser::isPoint(fromjson("{'type':['Point'], 'coordinates': [40, -5]}")));
+ ASSERT_FALSE(GeoJSONParser::isPoint(fromjson("{'type':'Point', 'coordinates': 40}")));
+ ASSERT_FALSE(GeoJSONParser::isPoint(fromjson("{'type':'Point', 'coordinates': [40, -5, 7]}")));
+ }
+
+ TEST(GeoJSONParser, isValidLineString) {
+ ASSERT_TRUE(GeoJSONParser::isLineString(fromjson("{'type':'LineString', 'coordinates':[[1,2], [3,4]]}")));
+ ASSERT_TRUE(GeoJSONParser::isLineString(fromjson("{'type':'LineString', 'coordinates':[[1,2], [3,4], [5,6]]}")));
+
+ ASSERT_FALSE(GeoJSONParser::isLineString(fromjson("{'type':'LineString', 'coordinates':[[1,2]]}")));
+ ASSERT_FALSE(GeoJSONParser::isLineString(fromjson("{'type':'LineString', 'coordinates':[['chicken','little']]}")));
+ ASSERT_FALSE(GeoJSONParser::isLineString(fromjson("{'type':'LineString', 'coordinates':[1,2, 3, 4]}")));
+ ASSERT_FALSE(GeoJSONParser::isLineString(fromjson("{'type':'LineString', 'coordinates':[[1,2, 3], [3,4, 5], [5,6]]}")));
+ }
+
+ TEST(GeoJSONParser, isValidPolygon) {
+ ASSERT_TRUE(GeoJSONParser::isPolygon(fromjson("{'type':'Polygon', 'coordinates':[ [[0,0],[5,0],[5,5],[0,5],[0,0]] ]}")));
+ // And one with a hole.
+ ASSERT_TRUE(GeoJSONParser::isPolygon(fromjson("{'type':'Polygon', 'coordinates':[ [[0,0],[5,0],[5,5],[0,5],[0,0]],"
+ " [[1,1],[4,1],[4,4],[1,4],[1,1]] ]}")));
+ // First point must be the same as the last.
+ ASSERT_FALSE(GeoJSONParser::isPolygon(fromjson("{'type':'Polygon', 'coordinates':[ [[1,2],[3,4],[5,6]] ]}")));
+ }
+
+ TEST(GeoJSONParser, parsePoint) {
+ S2Point point;
+ GeoJSONParser::parsePoint(fromjson("{'type':'Point', 'coordinates': [40, 5]}"), &point);
+ GeoJSONParser::parsePoint(fromjson("{'type':'Point', 'coordinates': [-40.3, -5.0]}"), &point);
+ }
+
+ TEST(GeoJSONParser, parseLineString) {
+ S2Polyline polyline;
+ GeoJSONParser::parseLineString(fromjson("{'type':'LineString', 'coordinates':[[1,2], [3,4]]}"), &polyline);
+ GeoJSONParser::parseLineString(fromjson("{'type':'LineString', 'coordinates':[[1,2], [3,4], [5,6]]}"), &polyline);
+ }
+
+ TEST(GeoJSONParser, parsePolygon) {
+ S2Point point;
+ GeoJSONParser::parsePoint(fromjson("{'type':'Point', 'coordinates': [2, 2]}"), &point);
+
+ S2Polygon polygonA;
+ GeoJSONParser::parsePolygon(fromjson("{'type':'Polygon', 'coordinates':[ [[0,0],[5,0],[5,5],[0,5],[0,0]] ]}"), &polygonA);
+ ASSERT_TRUE(polygonA.Contains(point));
+
+ S2Polygon polygonB;
+ GeoJSONParser::parsePolygon(fromjson("{'type':'Polygon', 'coordinates':[ [[0,0],[5,0],[5,5],[0,5],[0,0]],"
+ " [[1,1],[1,4],[4,4],[4,1],[1,1]] ]}"), &polygonB);
+ // We removed this in the loop.
+ ASSERT_FALSE(polygonB.Contains(point));
+
+ // Now we reverse the orientations and verify that the code fixes it up (outer loop must be CCW, inner CW).
+ S2Polygon polygonC;
+ GeoJSONParser::parsePolygon(fromjson("{'type':'Polygon', 'coordinates':[ [[0,0],[0,5],[5,5],[5,0],[0,0]] ]}"), &polygonC);
+ ASSERT_TRUE(polygonC.Contains(point));
+
+ S2Polygon polygonD;
+ GeoJSONParser::parsePolygon(fromjson("{'type':'Polygon', 'coordinates':[ [[0,0],[0,5],[5,5],[5,0],[0,0]],"
+ " [[1,1],[1,4],[4,4],[4,1],[1,1]] ]}"), &polygonD);
+ // Also removed in the loop.
+ ASSERT_FALSE(polygonD.Contains(point));
+ }
+}
diff --git a/src/third_party/SConscript b/src/third_party/SConscript
index 5a535710222..99b16250023 100644
--- a/src/third_party/SConscript
+++ b/src/third_party/SConscript
@@ -1,10 +1,13 @@
# -*- mode: python -*-
-Import( "env use_system_version_of_library windows" )
+Import("env use_system_version_of_library windows darwin")
env.SConscript( [
"murmurhash3/SConscript",
+ "gflags-2.0/SConscript",
+ "s2/SConscript",
] )
+env.Append(CPPPATH='$BUILD_DIR/third_party/s2')
if use_system_version_of_library("pcre"):
env.StaticLibrary( "pcrecpp", ['shim_pcrecpp.cc'],
diff --git a/src/third_party/gflags-2.0/AUTHORS b/src/third_party/gflags-2.0/AUTHORS
new file mode 100755
index 00000000000..887918bd00e
--- /dev/null
+++ b/src/third_party/gflags-2.0/AUTHORS
@@ -0,0 +1,2 @@
+google-gflags@googlegroups.com
+
diff --git a/src/third_party/gflags-2.0/COPYING b/src/third_party/gflags-2.0/COPYING
new file mode 100755
index 00000000000..d15b0c24134
--- /dev/null
+++ b/src/third_party/gflags-2.0/COPYING
@@ -0,0 +1,28 @@
+Copyright (c) 2006, Google Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+ * Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+copyright notice, this list of conditions and the following disclaimer
+in the documentation and/or other materials provided with the
+distribution.
+ * Neither the name of Google Inc. nor the names of its
+contributors may be used to endorse or promote products derived from
+this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/src/third_party/gflags-2.0/ChangeLog b/src/third_party/gflags-2.0/ChangeLog
new file mode 100755
index 00000000000..f9ef9350984
--- /dev/null
+++ b/src/third_party/gflags-2.0/ChangeLog
@@ -0,0 +1,195 @@
+Wed Jan 25 15:09:14 2012 Google Inc. <google-gflags@googlegroups.com>
+
+ * gflags: version 2.0
+ * Changed the 'official' gflags email in setup.py/etc
+ * Renamed google-gflags.sln to gflags.sln
+ * Changed copyright text to reflect Google's relinquished ownership
+
+Tue Dec 20 19:48:57 2011 Google Inc. <opensource@google.com>
+
+ * google-gflags: version 1.7
+ * Add CommandLineFlagInfo::flag_ptr pointing to current storage (musji)
+ * PORTING: flush after writing to stderr, needed on cygwin
+ * PORTING: Clean up the GFLAGS_DLL_DECL stuff better
+ * Fix a bug in StringPrintf() that affected large strings (csilvers)
+ * Die at configure-time when g++ isn't installed
+
+Fri Jul 29 19:05:21 2011 Google Inc. <opensource@google.com>
+
+ * google-gflags: version 1.6
+ * BUGFIX: Fix a bug where we were leaving out a required $(top_srcdir)
+ * Fix definition of clstring (jyrki)
+ * Split up flag declares into its own file (jyrki)
+ * Add --version support (csilvers)
+ * Update the README for gflags with static libs
+ * Update acx_pthread.m4 for nostdlib
+ * Change ReparseCommandLineFlags to return void (csilvers)
+ * Some doc typofixes and example augmentation (various)
+
+Mon Jan 24 16:11:35 2011 Google Inc. <opensource@google.com>
+
+ * google-gflags: version 1.5
+ * Better reporting of current vs default value (handler)
+ * Add API for cleaning up of memory at program-exit (jmarantz)
+ * Fix macros to work inside namespaces (csilvers)
+ * Use our own string typedef in case string is redefined (csilvers)
+ * Updated to autoconf 2.65
+
+Wed Oct 13 17:40:12 2010 Google Inc. <opensource@google.com>
+
+ * google-gflags: version 1.4
+ * Add a check to prevent passing 0 to DEFINE_string (jorg)
+ * Reduce compile (.o) size (jyrki)
+ * Some small changes to quiet debug compiles (alexk)
+ * PORTING: better support static linking on windows (csilvers)
+ * DOCUMENTATION: change default values, use validators, etc.
+ * Update the NEWS file to be non-empty
+ * Add pkg-config (.pc) files for libgflags and libgflags_nothreads
+
+Mon Jan 4 18:09:30 2010 Google Inc. <opensource@google.com>
+
+ * google-gflags: version 1.3
+ * PORTABILITY: can now build and run tests under MSVC (csilvers)
+ * Remove the python gflags code, which is now its own package (tansell)
+ * Clarify that "last flag wins" in the docs (csilvers)
+ * Comment danger of using GetAllFlags in validators (wojtekm)
+ * PORTABILITY: Some fixes necessary for c++0x (mboerger)
+ * Makefile fix: $(srcdir) -> $(top_srcdir) in one place (csilvres)
+ * INSTALL: autotools to autoconf v2.64 + automake v1.11 (csilvers)
+
+Thu Sep 10 12:53:04 2009 Google Inc. <opensource@google.com>
+
+ * google-gflags: version 1.2
+ * PORTABILITY: can now build and run tests under mingw (csilvers)
+ * Using a string arg for a bool flag is a compile-time error (rbayardo)
+ * Add --helpxml to gflags.py (salcianu)
+ * Protect against a hypothetical global d'tor mutex problem (csilvers)
+ * BUGFIX: can now define a flag after 'using namespace google' (hamaji)
+
+Tue Apr 14 12:35:25 2009 Google Inc. <opensource@google.com>
+
+ * google-gflags: version 1.1
+ * Add both foo and nofoo for boolean flags, with --undefok (andychu)
+ * Better document how validators work (wojtekm)
+ * Improve binary-detection for bash-completion (mtamsky)
+ * Python: Add a concept of "key flags", used with --help (salcianu)
+ * Python: Robustify flag_values (salcianu)
+ * Python: Add a new DEFINE_bool alias (keir, andrewliu)
+ * Python: Do module introspection based on module name (dsturtevant)
+ * Fix autoconf a bit better, especially on windows and solaris (ajenjo)
+ * BUG FIX: gflags_nothreads was linking against the wrong lib (ajenjo)
+ * BUG FIX: threads-detection failed on FreeBSD; replace it (ajenjo)
+ * PORTABILITY: Quiet an internal compiler error with SUSE 10 (csilvers)
+ * PORTABILITY: Update deb.sh for more recenty debuilds (csilvers)
+ * PORTABILITY: #include more headers to satify new gcc's (csilvers)
+ * INSTALL: Updated to autoconf 2.61 and libtool 1.5.26 (csilvers)
+
+Fri Oct 3 15:16:46 2008 Google Inc. <opensource@google.com>
+
+ * google-gflags: version 1.0
+ * Add a missing newline to an error string (bcmills)
+ * (otherwise exactly the same as gflags 1.0rc2)
+
+Thu Sep 18 12:58:05 2008 Google Inc. <opensource@google.com>
+
+ * google-gflags: version 1.0rc2
+ * Report current flag values in --helpxml (hdn)
+ * Fix compilation troubles with gcc 4.3.3 (simonb)
+ * BUG FIX: I was missing a std:: in DECLARE_string (csilvers)
+ * BUG FIX: Clarify in docs how to specify --bool flags (csilvers)
+ * BUG FIX: Fix --helpshort for source files not in a subdir (csilvers)
+ * BUG FIX: Fix python unittest for 64-bit builds (bcmills)
+
+Tue Aug 19 16:15:48 2008
+
+ * google-gflags: version 1.0rc1
+ * Move #include files from google/ to gflags/ (csilvers)
+ * Small optimizations to reduce binary (library) size (jyrki)
+ * BUGFIX: forgot a std:: in one of the .h files (csilvers)
+ * Speed up locking by making sure calls are inlined (ajenjo)
+ * 64-BIT COMPATIBILITY: Use %PRId64 instead of %lld (csilvers)
+ * PORTABILITY: fix Makefile to work with Cygwin (ajenjo)
+ * PORTABILITY: fix code to compile under Visual Studio (ajenjo)
+ * PORTABILITY: fix code to compile under Solaris 10 with CC (csilvers)
+
+Mon Jul 21 23:01:38 2008 Google Inc. <opensource@google.com>
+
+ * google-gflags: version 0.9
+ * Add the ability to validate a command-line flag (csilvers)
+ * Add completion support for commandline flags in bash (daven)
+ * Add -W compile flags to Makefile, when using gcc (csilvers)
+ * Allow helpstring to be NULL (cristianoc)
+ * Improved documentation of classes in the .cc file (csilvers)
+ * Fix python bug with AppendFlagValues + shortnames (jjtswan)
+ * Use bool instead of int for boolean flags in gflags.py (bcmills)
+ * Simplify the way we declare flags, now more foolproof (csilvers)
+ * Better error messages when bool flags collide (colohan)
+ * Only evaluate DEFINE_foo macro args once (csilvers)
+
+Wed Mar 26 15:20:18 2008 Google Inc. <opensource@google.com>
+
+ * google-gflags: version 0.8
+ * Export DescribeOneFlag() in the API
+ * Add support for automatic line wrapping at 80 cols for gflags.py
+ * Bugfix: do not treat an isolated "-" the same as an isolated "--"
+ * Update rpm spec to point to Google Code rather than sourceforge (!)
+ * Improve documentation (including documenting thread-safety)
+ * Improve #include hygiene
+ * Improve testing
+
+Thu Oct 18 11:33:20 2007 Google Inc. <opensource@google.com>
+
+ * google-gflags: version 0.7
+ * Deal even more correctly with libpthread not linked in (csilvers)
+ * Add STRIP_LOG, an improved DO_NOT_SHOW_COMMANDLINE_HELP (sioffe)
+ * Be more accurate printing default flag values in --help (dsturtevant)
+ * Reduce .o file size a bit by using shorter namespace names (jeff)
+ * Use relative install path, so 'setup.py --home' works (csilvers)
+ * Notice when a boolean flag has a non-boolean default (bnmouli)
+ * Broaden --helpshort to match foo-main.cc and foo_main.cc (hendrie)
+ * Fix "no modules match" message for --helpshort, etc (hendrie)
+
+Wed Aug 15 07:35:51 2007 Google Inc. <opensource@google.com>
+
+ * google-gflags: version 0.6
+ * Deal correctly with case that libpthread is not linked in (csilvers)
+ * Update Makefile/tests so we pass "make distcheck" (csilvers)
+ * Document and test that last assignment to a flag wins (wan)
+
+Tue Jun 12 15:23:42 2007 Google Inc. <opensource@google.com>
+
+ * google-gflags: version 0.5
+ * Include all m4 macros in the distribution (csilvers)
+ * Python: Fix broken data_files field in setup.py (sidlon)
+ * Python: better string serliaizing and unparsing (abo, csimmons)
+ * Fix checks for NaN and inf to work with Mac OS X (csilvers)
+
+Thu Apr 19 15:15:07 2007 Google Inc. <opensource@google.com>
+
+ * google-gflags: version 0.4
+ * Remove is_default from GetCommandLineFlagInfo (csilvers)
+ * Portability fixes: includes, strtoll, gcc4.3 errors (csilvers)
+ * A few doc typo cleanups (csilvers)
+
+Wed Mar 28 12:15:56 2007 Google Inc. <opensource@google.com>
+
+ * google-gflags: version 0.3
+ * python portability fix: use popen instead of subprocess (csilvers)
+ * Add is_default to CommandLineFlagInfo (pchien)
+ * Make docs a bit prettier (csilvers)
+ * Actually include the python files in the distribution! :-/ (csilvers)
+
+Mon Jan 22 15:33:06 2007 Google Inc. <opensource@google.com>
+
+ * google-gflags: version 0.2
+ * added support for python commandlineflags, as well as c++
+ * gflags2man, a script to turn flags into a man page (dchristian)
+
+Wed Dec 13 12:37:19 2006 Google Inc. <opensource@google.com>
+
+ * google-gflags: initial release:
+ The gflags package contains a library that implements commandline
+ flags processing. As such it's a replacement for getopt(). It
+ has increased flexibility, including built-in support for C++
+ types like string, and the ability to define flags in the source
+ file in which they're used.
diff --git a/src/third_party/gflags-2.0/INSTALL b/src/third_party/gflags-2.0/INSTALL
new file mode 100755
index 00000000000..d3c5b40a940
--- /dev/null
+++ b/src/third_party/gflags-2.0/INSTALL
@@ -0,0 +1,237 @@
+Installation Instructions
+*************************
+
+Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005,
+2006, 2007 Free Software Foundation, Inc.
+
+This file is free documentation; the Free Software Foundation gives
+unlimited permission to copy, distribute and modify it.
+
+Basic Installation
+==================
+
+Briefly, the shell commands `./configure; make; make install' should
+configure, build, and install this package. The following
+more-detailed instructions are generic; see the `README' file for
+instructions specific to this package.
+
+ The `configure' shell script attempts to guess correct values for
+various system-dependent variables used during compilation. It uses
+those values to create a `Makefile' in each directory of the package.
+It may also create one or more `.h' files containing system-dependent
+definitions. Finally, it creates a shell script `config.status' that
+you can run in the future to recreate the current configuration, and a
+file `config.log' containing compiler output (useful mainly for
+debugging `configure').
+
+ It can also use an optional file (typically called `config.cache'
+and enabled with `--cache-file=config.cache' or simply `-C') that saves
+the results of its tests to speed up reconfiguring. Caching is
+disabled by default to prevent problems with accidental use of stale
+cache files.
+
+ If you need to do unusual things to compile the package, please try
+to figure out how `configure' could check whether to do them, and mail
+diffs or instructions to the address given in the `README' so they can
+be considered for the next release. If you are using the cache, and at
+some point `config.cache' contains results you don't want to keep, you
+may remove or edit it.
+
+ The file `configure.ac' (or `configure.in') is used to create
+`configure' by a program called `autoconf'. You need `configure.ac' if
+you want to change it or regenerate `configure' using a newer version
+of `autoconf'.
+
+The simplest way to compile this package is:
+
+ 1. `cd' to the directory containing the package's source code and type
+ `./configure' to configure the package for your system.
+
+ Running `configure' might take a while. While running, it prints
+ some messages telling which features it is checking for.
+
+ 2. Type `make' to compile the package.
+
+ 3. Optionally, type `make check' to run any self-tests that come with
+ the package.
+
+ 4. Type `make install' to install the programs and any data files and
+ documentation.
+
+ 5. You can remove the program binaries and object files from the
+ source code directory by typing `make clean'. To also remove the
+ files that `configure' created (so you can compile the package for
+ a different kind of computer), type `make distclean'. There is
+ also a `make maintainer-clean' target, but that is intended mainly
+ for the package's developers. If you use it, you may have to get
+ all sorts of other programs in order to regenerate files that came
+ with the distribution.
+
+ 6. Often, you can also type `make uninstall' to remove the installed
+ files again.
+
+Compilers and Options
+=====================
+
+Some systems require unusual options for compilation or linking that the
+`configure' script does not know about. Run `./configure --help' for
+details on some of the pertinent environment variables.
+
+ You can give `configure' initial values for configuration parameters
+by setting variables in the command line or in the environment. Here
+is an example:
+
+ ./configure CC=c99 CFLAGS=-g LIBS=-lposix
+
+ *Note Defining Variables::, for more details.
+
+Compiling For Multiple Architectures
+====================================
+
+You can compile the package for more than one kind of computer at the
+same time, by placing the object files for each architecture in their
+own directory. To do this, you can use GNU `make'. `cd' to the
+directory where you want the object files and executables to go and run
+the `configure' script. `configure' automatically checks for the
+source code in the directory that `configure' is in and in `..'.
+
+ With a non-GNU `make', it is safer to compile the package for one
+architecture at a time in the source code directory. After you have
+installed the package for one architecture, use `make distclean' before
+reconfiguring for another architecture.
+
+Installation Names
+==================
+
+By default, `make install' installs the package's commands under
+`/usr/local/bin', include files under `/usr/local/include', etc. You
+can specify an installation prefix other than `/usr/local' by giving
+`configure' the option `--prefix=PREFIX'.
+
+ You can specify separate installation prefixes for
+architecture-specific files and architecture-independent files. If you
+pass the option `--exec-prefix=PREFIX' to `configure', the package uses
+PREFIX as the prefix for installing programs and libraries.
+Documentation and other data files still use the regular prefix.
+
+ In addition, if you use an unusual directory layout you can give
+options like `--bindir=DIR' to specify different values for particular
+kinds of files. Run `configure --help' for a list of the directories
+you can set and what kinds of files go in them.
+
+ If the package supports it, you can cause programs to be installed
+with an extra prefix or suffix on their names by giving `configure' the
+option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
+
+Optional Features
+=================
+
+Some packages pay attention to `--enable-FEATURE' options to
+`configure', where FEATURE indicates an optional part of the package.
+They may also pay attention to `--with-PACKAGE' options, where PACKAGE
+is something like `gnu-as' or `x' (for the X Window System). The
+`README' should mention any `--enable-' and `--with-' options that the
+package recognizes.
+
+ For packages that use the X Window System, `configure' can usually
+find the X include and library files automatically, but if it doesn't,
+you can use the `configure' options `--x-includes=DIR' and
+`--x-libraries=DIR' to specify their locations.
+
+Specifying the System Type
+==========================
+
+There may be some features `configure' cannot figure out automatically,
+but needs to determine by the type of machine the package will run on.
+Usually, assuming the package is built to be run on the _same_
+architectures, `configure' can figure that out, but if it prints a
+message saying it cannot guess the machine type, give it the
+`--build=TYPE' option. TYPE can either be a short name for the system
+type, such as `sun4', or a canonical name which has the form:
+
+ CPU-COMPANY-SYSTEM
+
+where SYSTEM can have one of these forms:
+
+ OS KERNEL-OS
+
+ See the file `config.sub' for the possible values of each field. If
+`config.sub' isn't included in this package, then this package doesn't
+need to know the machine type.
+
+ If you are _building_ compiler tools for cross-compiling, you should
+use the option `--target=TYPE' to select the type of system they will
+produce code for.
+
+ If you want to _use_ a cross compiler, that generates code for a
+platform different from the build platform, you should specify the
+"host" platform (i.e., that on which the generated programs will
+eventually be run) with `--host=TYPE'.
+
+Sharing Defaults
+================
+
+If you want to set default values for `configure' scripts to share, you
+can create a site shell script called `config.site' that gives default
+values for variables like `CC', `cache_file', and `prefix'.
+`configure' looks for `PREFIX/share/config.site' if it exists, then
+`PREFIX/etc/config.site' if it exists. Or, you can set the
+`CONFIG_SITE' environment variable to the location of the site script.
+A warning: not all `configure' scripts look for a site script.
+
+Defining Variables
+==================
+
+Variables not defined in a site shell script can be set in the
+environment passed to `configure'. However, some packages may run
+configure again during the build, and the customized values of these
+variables may be lost. In order to avoid this problem, you should set
+them in the `configure' command line, using `VAR=value'. For example:
+
+ ./configure CC=/usr/local2/bin/gcc
+
+causes the specified `gcc' to be used as the C compiler (unless it is
+overridden in the site shell script).
+
+Unfortunately, this technique does not work for `CONFIG_SHELL' due to
+an Autoconf bug. Until the bug is fixed you can use this workaround:
+
+ CONFIG_SHELL=/bin/bash /bin/bash ./configure CONFIG_SHELL=/bin/bash
+
+`configure' Invocation
+======================
+
+`configure' recognizes the following options to control how it operates.
+
+`--help'
+`-h'
+ Print a summary of the options to `configure', and exit.
+
+`--version'
+`-V'
+ Print the version of Autoconf used to generate the `configure'
+ script, and exit.
+
+`--cache-file=FILE'
+ Enable the cache: use and save the results of the tests in FILE,
+ traditionally `config.cache'. FILE defaults to `/dev/null' to
+ disable caching.
+
+`--config-cache'
+`-C'
+ Alias for `--cache-file=config.cache'.
+
+`--quiet'
+`--silent'
+`-q'
+ Do not print messages saying which checks are being made. To
+ suppress all normal output, redirect it to `/dev/null' (any error
+ messages will still be shown).
+
+`--srcdir=DIR'
+ Look for the package's source code in directory DIR. Usually
+ `configure' can determine that directory automatically.
+
+`configure' also accepts some other, not widely useful, options. Run
+`configure --help' for more details.
+
diff --git a/src/third_party/gflags-2.0/Makefile b/src/third_party/gflags-2.0/Makefile
new file mode 100755
index 00000000000..84465fd5d76
--- /dev/null
+++ b/src/third_party/gflags-2.0/Makefile
@@ -0,0 +1,1216 @@
+# Makefile.in generated by automake 1.10.1 from Makefile.am.
+# Makefile. Generated from Makefile.in by configure.
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+
+
+
+
+
+
+
+pkgdatadir = $(datadir)/gflags
+pkglibdir = $(libdir)/gflags
+pkgincludedir = $(includedir)/gflags
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = i386-apple-darwin12.2.0
+host_triplet = i386-apple-darwin12.2.0
+
+# These are good warnings to turn on by default,
+am__append_1 = -Wall -Wwrite-strings -Woverloaded-virtual -Wno-sign-compare
+TESTS = gflags_unittest$(EXEEXT) gflags_nothreads_unittest$(EXEEXT) \
+ gflags_unittest2$(EXEEXT) gflags_unittest3$(EXEEXT) \
+ gflags_strip_flags_test$(EXEEXT)
+noinst_PROGRAMS = $(am__EXEEXT_1)
+subdir = .
+DIST_COMMON = README $(am__configure_deps) $(dist_doc_DATA) \
+ $(dist_noinst_DATA) $(gflagsinclude_HEADERS) \
+ $(googleinclude_HEADERS) $(srcdir)/Makefile.am \
+ $(srcdir)/Makefile.in $(top_srcdir)/configure \
+ $(top_srcdir)/src/config.h.in \
+ $(top_srcdir)/src/gflags/gflags.h.in \
+ $(top_srcdir)/src/gflags/gflags_completions.h.in \
+ $(top_srcdir)/src/gflags/gflags_declare.h.in AUTHORS COPYING \
+ ChangeLog INSTALL NEWS config.guess config.sub depcomp \
+ install-sh ltmain.sh missing
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/ac_have_attribute.m4 \
+ $(top_srcdir)/m4/acx_pthread.m4 \
+ $(top_srcdir)/m4/google_namespace.m4 \
+ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
+ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
+ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/namespaces.m4 \
+ $(top_srcdir)/m4/stl_namespace.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \
+ configure.lineno config.status.lineno
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/src/config.h
+CONFIG_CLEAN_FILES = src/gflags/gflags.h src/gflags/gflags_declare.h \
+ src/gflags/gflags_completions.h
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = `echo $$p | sed -e 's|^.*/||'`;
+am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(bindir)" \
+ "$(DESTDIR)$(docdir)" "$(DESTDIR)$(pkgconfigdir)" \
+ "$(DESTDIR)$(gflagsincludedir)" \
+ "$(DESTDIR)$(googleincludedir)"
+libLTLIBRARIES_INSTALL = $(INSTALL)
+LTLIBRARIES = $(lib_LTLIBRARIES)
+am__DEPENDENCIES_1 =
+libgflags_la_DEPENDENCIES = $(am__DEPENDENCIES_1)
+am__objects_1 =
+am__objects_2 = $(am__objects_1) libgflags_la-gflags.lo \
+ libgflags_la-gflags_reporting.lo \
+ libgflags_la-gflags_completions.lo
+am_libgflags_la_OBJECTS = $(am__objects_2)
+libgflags_la_OBJECTS = $(am_libgflags_la_OBJECTS)
+libgflags_la_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(libgflags_la_CXXFLAGS) \
+ $(CXXFLAGS) $(libgflags_la_LDFLAGS) $(LDFLAGS) -o $@
+libgflags_nothreads_la_LIBADD =
+am__objects_3 = $(am__objects_1) libgflags_nothreads_la-gflags.lo \
+ libgflags_nothreads_la-gflags_reporting.lo \
+ libgflags_nothreads_la-gflags_completions.lo
+am_libgflags_nothreads_la_OBJECTS = $(am__objects_3)
+libgflags_nothreads_la_OBJECTS = $(am_libgflags_nothreads_la_OBJECTS)
+libgflags_nothreads_la_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
+ $(libgflags_nothreads_la_CXXFLAGS) $(CXXFLAGS) \
+ $(libgflags_nothreads_la_LDFLAGS) $(LDFLAGS) -o $@
+am__EXEEXT_1 = gflags_unittest$(EXEEXT) \
+ gflags_nothreads_unittest$(EXEEXT) gflags_unittest2$(EXEEXT) \
+ gflags_unittest3$(EXEEXT) gflags_strip_flags_test$(EXEEXT)
+PROGRAMS = $(noinst_PROGRAMS)
+am__objects_4 = $(am__objects_1) gflags_unittest.$(OBJEXT)
+am_gflags_nothreads_unittest_OBJECTS = $(am__objects_4)
+gflags_nothreads_unittest_OBJECTS = \
+ $(am_gflags_nothreads_unittest_OBJECTS)
+gflags_nothreads_unittest_DEPENDENCIES = libgflags_nothreads.la
+am_gflags_strip_flags_test_OBJECTS = $(am__objects_1) \
+ gflags_strip_flags_test-gflags_strip_flags_test.$(OBJEXT)
+gflags_strip_flags_test_OBJECTS = \
+ $(am_gflags_strip_flags_test_OBJECTS)
+gflags_strip_flags_test_DEPENDENCIES = libgflags.la
+gflags_strip_flags_test_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
+ $(gflags_strip_flags_test_CXXFLAGS) $(CXXFLAGS) \
+ $(gflags_strip_flags_test_LDFLAGS) $(LDFLAGS) -o $@
+am_gflags_unittest_OBJECTS = $(am__objects_1) \
+ gflags_unittest-gflags_unittest.$(OBJEXT)
+gflags_unittest_OBJECTS = $(am_gflags_unittest_OBJECTS)
+gflags_unittest_DEPENDENCIES = libgflags.la
+gflags_unittest_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
+ $(gflags_unittest_CXXFLAGS) $(CXXFLAGS) \
+ $(gflags_unittest_LDFLAGS) $(LDFLAGS) -o $@
+am_gflags_unittest2_OBJECTS = $(am__objects_1) \
+ gflags_unittest-main.$(OBJEXT)
+gflags_unittest2_OBJECTS = $(am_gflags_unittest2_OBJECTS)
+gflags_unittest2_DEPENDENCIES = libgflags_nothreads.la
+am_gflags_unittest3_OBJECTS = $(am__objects_1) \
+ gflags_unittest_main.$(OBJEXT)
+gflags_unittest3_OBJECTS = $(am_gflags_unittest3_OBJECTS)
+gflags_unittest3_DEPENDENCIES = libgflags_nothreads.la
+binSCRIPT_INSTALL = $(INSTALL_SCRIPT)
+SCRIPTS = $(bin_SCRIPTS) $(noinst_SCRIPTS)
+DEFAULT_INCLUDES = -I. -I$(top_builddir)/src
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
+LTCXXCOMPILE = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
+CXXLD = $(CXX)
+CXXLINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \
+ $(LDFLAGS) -o $@
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
+ $(LDFLAGS) -o $@
+SOURCES = $(libgflags_la_SOURCES) $(libgflags_nothreads_la_SOURCES) \
+ $(gflags_nothreads_unittest_SOURCES) \
+ $(gflags_strip_flags_test_SOURCES) $(gflags_unittest_SOURCES) \
+ $(gflags_unittest2_SOURCES) $(gflags_unittest3_SOURCES)
+DIST_SOURCES = $(libgflags_la_SOURCES) \
+ $(libgflags_nothreads_la_SOURCES) \
+ $(gflags_nothreads_unittest_SOURCES) \
+ $(gflags_strip_flags_test_SOURCES) $(gflags_unittest_SOURCES) \
+ $(gflags_unittest2_SOURCES) $(gflags_unittest3_SOURCES)
+dist_docDATA_INSTALL = $(INSTALL_DATA)
+pkgconfigDATA_INSTALL = $(INSTALL_DATA)
+DATA = $(dist_doc_DATA) $(dist_noinst_DATA) $(pkgconfig_DATA)
+gflagsincludeHEADERS_INSTALL = $(INSTALL_HEADER)
+googleincludeHEADERS_INSTALL = $(INSTALL_HEADER)
+HEADERS = $(gflagsinclude_HEADERS) $(googleinclude_HEADERS)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+distdir = $(PACKAGE)-$(VERSION)
+top_distdir = $(distdir)
+am__remove_distdir = \
+ { test ! -d $(distdir) \
+ || { find $(distdir) -type d ! -perm -200 -exec chmod u+w {} ';' \
+ && rm -fr $(distdir); }; }
+DIST_ARCHIVES = $(distdir).tar.gz $(distdir).zip
+GZIP_ENV = --best
+distuninstallcheck_listfiles = find . -type f -print
+distcleancheck_listfiles = find . -type f -print
+ACLOCAL = ${SHELL} /Users/hk/mongo/src/third_party/gflags-2.0/missing --run aclocal-1.10
+AMTAR = ${SHELL} /Users/hk/mongo/src/third_party/gflags-2.0/missing --run tar
+AR = ar
+AUTOCONF = ${SHELL} /Users/hk/mongo/src/third_party/gflags-2.0/missing --run autoconf
+AUTOHEADER = ${SHELL} /Users/hk/mongo/src/third_party/gflags-2.0/missing --run autoheader
+AUTOMAKE = ${SHELL} /Users/hk/mongo/src/third_party/gflags-2.0/missing --run automake-1.10
+AWK = awk
+CC = gcc
+CCDEPMODE = depmode=gcc3
+CFLAGS = -g -O2
+CPP = gcc -E
+CPPFLAGS =
+CXX = g++
+CXXCPP = g++ -E
+CXXDEPMODE = depmode=gcc3
+CXXFLAGS = -g -O2
+CYGPATH_W = echo
+DEFS = -DHAVE_CONFIG_H
+DEPDIR = .deps
+DSYMUTIL = dsymutil
+DUMPBIN =
+ECHO_C = \c
+ECHO_N =
+ECHO_T =
+EGREP = /usr/bin/grep -E
+EXEEXT =
+FGREP = /usr/bin/grep -F
+GREP = /usr/bin/grep
+INSTALL = /usr/bin/install -c
+INSTALL_DATA = ${INSTALL} -m 644
+INSTALL_PROGRAM = ${INSTALL}
+INSTALL_SCRIPT = ${INSTALL}
+INSTALL_STRIP_PROGRAM = $(install_sh) -c -s
+LD = /usr/llvm-gcc-4.2/libexec/gcc/i686-apple-darwin11/4.2.1/ld
+LDFLAGS =
+LIBOBJS =
+LIBS =
+LIBSTDCXX_LA_LINKER_FLAG =
+LIBTOOL = $(SHELL) $(top_builddir)/libtool
+LIBTOOL_DEPS = ./ltmain.sh
+LIPO = lipo
+LN_S = ln -s
+LTLIBOBJS =
+MAKEINFO = ${SHELL} /Users/hk/mongo/src/third_party/gflags-2.0/missing --run makeinfo
+MKDIR_P = ./install-sh -c -d
+NM = /usr/bin/nm
+NMEDIT = nmedit
+OBJDUMP = false
+OBJEXT = o
+OTOOL = otool
+OTOOL64 = :
+PACKAGE = gflags
+PACKAGE_BUGREPORT = google-gflags@googlegroups.com
+PACKAGE_NAME = gflags
+PACKAGE_STRING = gflags 2.0
+PACKAGE_TARNAME = gflags
+PACKAGE_VERSION = 2.0
+PATH_SEPARATOR = :
+PTHREAD_CC = gcc
+PTHREAD_CFLAGS = -D_THREAD_SAFE
+PTHREAD_LIBS =
+RANLIB = ranlib
+SED = /usr/bin/sed
+SET_MAKE =
+SHELL = /bin/sh
+SO_VERSION = 3:0:1
+STRIP = strip
+TEST_TMPDIR = /tmp/gflags
+VERSION = 2.0
+abs_builddir = /Users/hk/mongo/src/third_party/gflags-2.0
+abs_srcdir = /Users/hk/mongo/src/third_party/gflags-2.0
+abs_top_builddir = /Users/hk/mongo/src/third_party/gflags-2.0
+abs_top_srcdir = /Users/hk/mongo/src/third_party/gflags-2.0
+ac_ct_CC = gcc
+ac_ct_CXX = g++
+ac_ct_DUMPBIN =
+ac_cv___attribute__unused = __attribute__ ((unused))
+ac_cv_have___int16 = 0
+ac_cv_have_inttypes_h = 1
+ac_cv_have_stdint_h = 1
+ac_cv_have_systypes_h = 1
+ac_cv_have_u_int16_t = 1
+ac_cv_have_uint16_t = 1
+ac_google_end_namespace = }
+ac_google_namespace = ::google
+ac_google_start_namespace = namespace google {
+acx_pthread_config =
+am__include = include
+am__leading_dot = .
+am__quote =
+am__tar = ${AMTAR} chof - "$$tardir"
+am__untar = ${AMTAR} xf -
+bindir = ${exec_prefix}/bin
+build = i386-apple-darwin12.2.0
+build_alias =
+build_cpu = i386
+build_os = darwin12.2.0
+build_vendor = apple
+builddir = .
+datadir = ${datarootdir}
+datarootdir = ${prefix}/share
+docdir = $(prefix)/share/doc/$(PACKAGE)-$(VERSION)
+dvidir = ${docdir}
+exec_prefix = ${prefix}
+host = i386-apple-darwin12.2.0
+host_alias =
+host_cpu = i386
+host_os = darwin12.2.0
+host_vendor = apple
+htmldir = ${docdir}
+includedir = ${prefix}/include
+infodir = ${datarootdir}/info
+install_sh = $(SHELL) /Users/hk/mongo/src/third_party/gflags-2.0/install-sh
+libdir = ${exec_prefix}/lib
+libexecdir = ${exec_prefix}/libexec
+localedir = ${datarootdir}/locale
+localstatedir = ${prefix}/var
+lt_ECHO = /bin/echo
+mandir = ${datarootdir}/man
+mkdir_p = $(top_builddir)/./install-sh -c -d
+oldincludedir = /usr/include
+pdfdir = ${docdir}
+prefix = /usr/local
+program_transform_name = s,x,x,
+psdir = ${docdir}
+sbindir = ${exec_prefix}/sbin
+sharedstatedir = ${prefix}/com
+srcdir = .
+sysconfdir = ${prefix}/etc
+target_alias =
+top_build_prefix =
+top_builddir = .
+top_srcdir = .
+
+# Make sure that when we re-make ./configure, we get the macros we need
+ACLOCAL_AMFLAGS = -I m4
+
+# This is so we can #include <gflags/foo>
+AM_CPPFLAGS = -I$(top_srcdir)/src
+
+# This is mostly based on configure options
+AM_CXXFLAGS = $(am__append_1)
+
+# The -no-undefined flag allows libtool to generate shared libraries for
+# Cygwin and MinGW. LIBSTDCXX_LA_LINKER_FLAG is used to fix a Solaris bug.
+AM_LDFLAGS = -no-undefined $(LIBSTDCXX_LA_LINKER_FLAG)
+gflagsincludedir = $(includedir)/gflags
+gflagsinclude_HEADERS = src/gflags/gflags.h src/gflags/gflags_declare.h \
+ src/gflags/gflags_completions.h
+
+
+# This is for backwards compatibility only.
+googleincludedir = $(includedir)/google
+googleinclude_HEADERS = src/google/gflags.h src/google/gflags_completions.h
+bin_SCRIPTS = src/gflags_completions.sh
+dist_doc_DATA = AUTHORS COPYING ChangeLog INSTALL NEWS README \
+ README_windows.txt doc/designstyle.css doc/gflags.html
+
+lib_LTLIBRARIES = libgflags.la libgflags_nothreads.la
+WINDOWS_PROJECTS = gflags.sln vsprojects/libgflags/libgflags.vcproj \
+ vsprojects/gflags_unittest/gflags_unittest.vcproj
+TESTS_ENVIRONMENT = SRCDIR="$(top_srcdir)"
+
+# Some buggy sh's ignore "" instead of treating it as a positional
+# parameter. Since we use "" in this script, we prefer bash if we
+# can. If there's no bash, we fall back to sh.
+
+# These are negative-compilation tests. We want to make sure these
+# erroneous use of the flags macros correctly fail to compile.
+# Again, we just bother testing with the no-threads version of the library.
+
+# This one, on the other hand, should succeed.
+check_SCRIPTS = gflags_unittest_sh gflags_strip_flags_test_sh \
+ gflags_nc_test1 gflags_nc_test2 gflags_nc_test3 \
+ gflags_nc_test4
+# Every time you add a unittest to check_SCRIPTS, add it here too
+noinst_SCRIPTS = src/gflags_unittest.sh src/gflags_strip_flags_test.sh
+# Used for auto-generated source files
+CLEANFILES = src/gflags_unittest-main.cc src/gflags_unittest_main.cc \
+ $(pkgconfig_DATA)
+GFLAGS_SOURCES = $(gflagsinclude_HEADERS) src/mutex.h src/util.h \
+ src/gflags.cc src/gflags_reporting.cc \
+ src/gflags_completions.cc
+
+libgflags_la_SOURCES = $(GFLAGS_SOURCES)
+libgflags_la_CXXFLAGS = $(PTHREAD_CFLAGS) -DNDEBUG
+# -version-info gets passed to libtool
+libgflags_la_LDFLAGS = $(PTHREAD_CFLAGS) -version-info 3:0:1
+libgflags_la_LIBADD = $(PTHREAD_LIBS)
+libgflags_nothreads_la_SOURCES = $(GFLAGS_SOURCES)
+libgflags_nothreads_la_CXXFLAGS = -DNDEBUG -DNO_THREADS
+libgflags_nothreads_la_LDFLAGS = -version-info 3:0:1
+gflags_unittest_SOURCES = $(gflagsinclude_HEADERS) \
+ src/config_for_unittests.h \
+ src/gflags_unittest.cc
+
+gflags_unittest_CXXFLAGS = $(PTHREAD_CFLAGS)
+gflags_unittest_LDFLAGS = $(PTHREAD_CFLAGS)
+gflags_unittest_LDADD = libgflags.la
+gflags_nothreads_unittest_SOURCES = $(gflags_unittest_SOURCES)
+gflags_nothreads_unittest_LDADD = libgflags_nothreads.la
+gflags_unittest2_SOURCES = $(gflagsinclude_HEADERS) \
+ src/gflags_unittest-main.cc
+
+gflags_unittest2_LDADD = libgflags_nothreads.la
+gflags_unittest3_SOURCES = $(gflagsinclude_HEADERS) \
+ src/gflags_unittest_main.cc
+
+gflags_unittest3_LDADD = libgflags_nothreads.la
+
+# This file isn't covered under any rule that would cause it to be distributed.
+dist_noinst_DATA = src/gflags_unittest_flagfile src/gflags_nc.cc
+gflags_strip_flags_test_SOURCES = $(gflagsinclude_HEADERS) \
+ src/config_for_unittests.h \
+ src/gflags_strip_flags_test.cc
+
+gflags_strip_flags_test_CXXFLAGS = $(PTHREAD_CFLAGS)
+gflags_strip_flags_test_LDFLAGS = $(PTHREAD_CFLAGS)
+gflags_strip_flags_test_LDADD = libgflags.la
+
+# http://linux.die.net/man/1/pkg-config, http://pkg-config.freedesktop.org/wiki
+pkgconfigdir = $(libdir)/pkgconfig
+pkgconfig_DATA = lib${PACKAGE}.pc lib${PACKAGE}_nothreads.pc
+EXTRA_DIST = packages/rpm.sh packages/rpm/rpm.spec packages/deb.sh packages/deb \
+ libtool $(SCRIPTS) \
+ src/windows/config.h src/windows/port.h src/windows/port.cc \
+ src/windows/gflags/gflags.h src/windows/gflags/gflags_declare.h \
+ src/windows/gflags/gflags_completions.h \
+ $(WINDOWS_PROJECTS) \
+ src/solaris/libstdc++.la
+
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .cc .lo .o .obj
+am--refresh:
+ @:
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ echo ' cd $(srcdir) && $(AUTOMAKE) --gnu '; \
+ cd $(srcdir) && $(AUTOMAKE) --gnu \
+ && exit 0; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --gnu Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ echo ' $(SHELL) ./config.status'; \
+ $(SHELL) ./config.status;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ $(SHELL) ./config.status --recheck
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(srcdir) && $(AUTOCONF)
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS)
+
+src/config.h: src/stamp-h1
+ @if test ! -f $@; then \
+ rm -f src/stamp-h1; \
+ $(MAKE) $(AM_MAKEFLAGS) src/stamp-h1; \
+ else :; fi
+
+src/stamp-h1: $(top_srcdir)/src/config.h.in $(top_builddir)/config.status
+ @rm -f src/stamp-h1
+ cd $(top_builddir) && $(SHELL) ./config.status src/config.h
+$(top_srcdir)/src/config.h.in: $(am__configure_deps)
+ cd $(top_srcdir) && $(AUTOHEADER)
+ rm -f src/stamp-h1
+ touch $@
+
+distclean-hdr:
+ -rm -f src/config.h src/stamp-h1
+src/gflags/gflags.h: $(top_builddir)/config.status $(top_srcdir)/src/gflags/gflags.h.in
+ cd $(top_builddir) && $(SHELL) ./config.status $@
+src/gflags/gflags_declare.h: $(top_builddir)/config.status $(top_srcdir)/src/gflags/gflags_declare.h.in
+ cd $(top_builddir) && $(SHELL) ./config.status $@
+src/gflags/gflags_completions.h: $(top_builddir)/config.status $(top_srcdir)/src/gflags/gflags_completions.h.in
+ cd $(top_builddir) && $(SHELL) ./config.status $@
+install-libLTLIBRARIES: $(lib_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ test -z "$(libdir)" || $(MKDIR_P) "$(DESTDIR)$(libdir)"
+ @list='$(lib_LTLIBRARIES)'; for p in $$list; do \
+ if test -f $$p; then \
+ f=$(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) '$$p' '$(DESTDIR)$(libdir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) "$$p" "$(DESTDIR)$(libdir)/$$f"; \
+ else :; fi; \
+ done
+
+uninstall-libLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(lib_LTLIBRARIES)'; for p in $$list; do \
+ p=$(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$p'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$p"; \
+ done
+
+clean-libLTLIBRARIES:
+ -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)
+ @list='$(lib_LTLIBRARIES)'; for p in $$list; do \
+ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
+ test "$$dir" != "$$p" || dir=.; \
+ echo "rm -f \"$${dir}/so_locations\""; \
+ rm -f "$${dir}/so_locations"; \
+ done
+libgflags.la: $(libgflags_la_OBJECTS) $(libgflags_la_DEPENDENCIES)
+ $(libgflags_la_LINK) -rpath $(libdir) $(libgflags_la_OBJECTS) $(libgflags_la_LIBADD) $(LIBS)
+libgflags_nothreads.la: $(libgflags_nothreads_la_OBJECTS) $(libgflags_nothreads_la_DEPENDENCIES)
+ $(libgflags_nothreads_la_LINK) -rpath $(libdir) $(libgflags_nothreads_la_OBJECTS) $(libgflags_nothreads_la_LIBADD) $(LIBS)
+
+clean-noinstPROGRAMS:
+ @list='$(noinst_PROGRAMS)'; for p in $$list; do \
+ f=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
+ echo " rm -f $$p $$f"; \
+ rm -f $$p $$f ; \
+ done
+gflags_nothreads_unittest$(EXEEXT): $(gflags_nothreads_unittest_OBJECTS) $(gflags_nothreads_unittest_DEPENDENCIES)
+ @rm -f gflags_nothreads_unittest$(EXEEXT)
+ $(CXXLINK) $(gflags_nothreads_unittest_OBJECTS) $(gflags_nothreads_unittest_LDADD) $(LIBS)
+gflags_strip_flags_test$(EXEEXT): $(gflags_strip_flags_test_OBJECTS) $(gflags_strip_flags_test_DEPENDENCIES)
+ @rm -f gflags_strip_flags_test$(EXEEXT)
+ $(gflags_strip_flags_test_LINK) $(gflags_strip_flags_test_OBJECTS) $(gflags_strip_flags_test_LDADD) $(LIBS)
+gflags_unittest$(EXEEXT): $(gflags_unittest_OBJECTS) $(gflags_unittest_DEPENDENCIES)
+ @rm -f gflags_unittest$(EXEEXT)
+ $(gflags_unittest_LINK) $(gflags_unittest_OBJECTS) $(gflags_unittest_LDADD) $(LIBS)
+gflags_unittest2$(EXEEXT): $(gflags_unittest2_OBJECTS) $(gflags_unittest2_DEPENDENCIES)
+ @rm -f gflags_unittest2$(EXEEXT)
+ $(CXXLINK) $(gflags_unittest2_OBJECTS) $(gflags_unittest2_LDADD) $(LIBS)
+gflags_unittest3$(EXEEXT): $(gflags_unittest3_OBJECTS) $(gflags_unittest3_DEPENDENCIES)
+ @rm -f gflags_unittest3$(EXEEXT)
+ $(CXXLINK) $(gflags_unittest3_OBJECTS) $(gflags_unittest3_LDADD) $(LIBS)
+install-binSCRIPTS: $(bin_SCRIPTS)
+ @$(NORMAL_INSTALL)
+ test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)"
+ @list='$(bin_SCRIPTS)'; for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ if test -f $$d$$p; then \
+ f=`echo "$$p" | sed 's|^.*/||;$(transform)'`; \
+ echo " $(binSCRIPT_INSTALL) '$$d$$p' '$(DESTDIR)$(bindir)/$$f'"; \
+ $(binSCRIPT_INSTALL) "$$d$$p" "$(DESTDIR)$(bindir)/$$f"; \
+ else :; fi; \
+ done
+
+uninstall-binSCRIPTS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(bin_SCRIPTS)'; for p in $$list; do \
+ f=`echo "$$p" | sed 's|^.*/||;$(transform)'`; \
+ echo " rm -f '$(DESTDIR)$(bindir)/$$f'"; \
+ rm -f "$(DESTDIR)$(bindir)/$$f"; \
+ done
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+include ./$(DEPDIR)/gflags_strip_flags_test-gflags_strip_flags_test.Po
+include ./$(DEPDIR)/gflags_unittest-gflags_unittest.Po
+include ./$(DEPDIR)/gflags_unittest-main.Po
+include ./$(DEPDIR)/gflags_unittest.Po
+include ./$(DEPDIR)/gflags_unittest_main.Po
+include ./$(DEPDIR)/libgflags_la-gflags.Plo
+include ./$(DEPDIR)/libgflags_la-gflags_completions.Plo
+include ./$(DEPDIR)/libgflags_la-gflags_reporting.Plo
+include ./$(DEPDIR)/libgflags_nothreads_la-gflags.Plo
+include ./$(DEPDIR)/libgflags_nothreads_la-gflags_completions.Plo
+include ./$(DEPDIR)/libgflags_nothreads_la-gflags_reporting.Plo
+
+.cc.o:
+ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+# source='$<' object='$@' libtool=no \
+# DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \
+# $(CXXCOMPILE) -c -o $@ $<
+
+.cc.obj:
+ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+# source='$<' object='$@' libtool=no \
+# DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \
+# $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.cc.lo:
+ $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+# source='$<' object='$@' libtool=yes \
+# DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \
+# $(LTCXXCOMPILE) -c -o $@ $<
+
+libgflags_la-gflags.lo: src/gflags.cc
+ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgflags_la_CXXFLAGS) $(CXXFLAGS) -MT libgflags_la-gflags.lo -MD -MP -MF $(DEPDIR)/libgflags_la-gflags.Tpo -c -o libgflags_la-gflags.lo `test -f 'src/gflags.cc' || echo '$(srcdir)/'`src/gflags.cc
+ mv -f $(DEPDIR)/libgflags_la-gflags.Tpo $(DEPDIR)/libgflags_la-gflags.Plo
+# source='src/gflags.cc' object='libgflags_la-gflags.lo' libtool=yes \
+# DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \
+# $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgflags_la_CXXFLAGS) $(CXXFLAGS) -c -o libgflags_la-gflags.lo `test -f 'src/gflags.cc' || echo '$(srcdir)/'`src/gflags.cc
+
+libgflags_la-gflags_reporting.lo: src/gflags_reporting.cc
+ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgflags_la_CXXFLAGS) $(CXXFLAGS) -MT libgflags_la-gflags_reporting.lo -MD -MP -MF $(DEPDIR)/libgflags_la-gflags_reporting.Tpo -c -o libgflags_la-gflags_reporting.lo `test -f 'src/gflags_reporting.cc' || echo '$(srcdir)/'`src/gflags_reporting.cc
+ mv -f $(DEPDIR)/libgflags_la-gflags_reporting.Tpo $(DEPDIR)/libgflags_la-gflags_reporting.Plo
+# source='src/gflags_reporting.cc' object='libgflags_la-gflags_reporting.lo' libtool=yes \
+# DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \
+# $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgflags_la_CXXFLAGS) $(CXXFLAGS) -c -o libgflags_la-gflags_reporting.lo `test -f 'src/gflags_reporting.cc' || echo '$(srcdir)/'`src/gflags_reporting.cc
+
+libgflags_la-gflags_completions.lo: src/gflags_completions.cc
+ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgflags_la_CXXFLAGS) $(CXXFLAGS) -MT libgflags_la-gflags_completions.lo -MD -MP -MF $(DEPDIR)/libgflags_la-gflags_completions.Tpo -c -o libgflags_la-gflags_completions.lo `test -f 'src/gflags_completions.cc' || echo '$(srcdir)/'`src/gflags_completions.cc
+ mv -f $(DEPDIR)/libgflags_la-gflags_completions.Tpo $(DEPDIR)/libgflags_la-gflags_completions.Plo
+# source='src/gflags_completions.cc' object='libgflags_la-gflags_completions.lo' libtool=yes \
+# DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \
+# $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgflags_la_CXXFLAGS) $(CXXFLAGS) -c -o libgflags_la-gflags_completions.lo `test -f 'src/gflags_completions.cc' || echo '$(srcdir)/'`src/gflags_completions.cc
+
+libgflags_nothreads_la-gflags.lo: src/gflags.cc
+ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgflags_nothreads_la_CXXFLAGS) $(CXXFLAGS) -MT libgflags_nothreads_la-gflags.lo -MD -MP -MF $(DEPDIR)/libgflags_nothreads_la-gflags.Tpo -c -o libgflags_nothreads_la-gflags.lo `test -f 'src/gflags.cc' || echo '$(srcdir)/'`src/gflags.cc
+ mv -f $(DEPDIR)/libgflags_nothreads_la-gflags.Tpo $(DEPDIR)/libgflags_nothreads_la-gflags.Plo
+# source='src/gflags.cc' object='libgflags_nothreads_la-gflags.lo' libtool=yes \
+# DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \
+# $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgflags_nothreads_la_CXXFLAGS) $(CXXFLAGS) -c -o libgflags_nothreads_la-gflags.lo `test -f 'src/gflags.cc' || echo '$(srcdir)/'`src/gflags.cc
+
+libgflags_nothreads_la-gflags_reporting.lo: src/gflags_reporting.cc
+ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgflags_nothreads_la_CXXFLAGS) $(CXXFLAGS) -MT libgflags_nothreads_la-gflags_reporting.lo -MD -MP -MF $(DEPDIR)/libgflags_nothreads_la-gflags_reporting.Tpo -c -o libgflags_nothreads_la-gflags_reporting.lo `test -f 'src/gflags_reporting.cc' || echo '$(srcdir)/'`src/gflags_reporting.cc
+ mv -f $(DEPDIR)/libgflags_nothreads_la-gflags_reporting.Tpo $(DEPDIR)/libgflags_nothreads_la-gflags_reporting.Plo
+# source='src/gflags_reporting.cc' object='libgflags_nothreads_la-gflags_reporting.lo' libtool=yes \
+# DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \
+# $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgflags_nothreads_la_CXXFLAGS) $(CXXFLAGS) -c -o libgflags_nothreads_la-gflags_reporting.lo `test -f 'src/gflags_reporting.cc' || echo '$(srcdir)/'`src/gflags_reporting.cc
+
+libgflags_nothreads_la-gflags_completions.lo: src/gflags_completions.cc
+ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgflags_nothreads_la_CXXFLAGS) $(CXXFLAGS) -MT libgflags_nothreads_la-gflags_completions.lo -MD -MP -MF $(DEPDIR)/libgflags_nothreads_la-gflags_completions.Tpo -c -o libgflags_nothreads_la-gflags_completions.lo `test -f 'src/gflags_completions.cc' || echo '$(srcdir)/'`src/gflags_completions.cc
+ mv -f $(DEPDIR)/libgflags_nothreads_la-gflags_completions.Tpo $(DEPDIR)/libgflags_nothreads_la-gflags_completions.Plo
+# source='src/gflags_completions.cc' object='libgflags_nothreads_la-gflags_completions.lo' libtool=yes \
+# DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \
+# $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgflags_nothreads_la_CXXFLAGS) $(CXXFLAGS) -c -o libgflags_nothreads_la-gflags_completions.lo `test -f 'src/gflags_completions.cc' || echo '$(srcdir)/'`src/gflags_completions.cc
+
+gflags_unittest.o: src/gflags_unittest.cc
+ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT gflags_unittest.o -MD -MP -MF $(DEPDIR)/gflags_unittest.Tpo -c -o gflags_unittest.o `test -f 'src/gflags_unittest.cc' || echo '$(srcdir)/'`src/gflags_unittest.cc
+ mv -f $(DEPDIR)/gflags_unittest.Tpo $(DEPDIR)/gflags_unittest.Po
+# source='src/gflags_unittest.cc' object='gflags_unittest.o' libtool=no \
+# DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \
+# $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o gflags_unittest.o `test -f 'src/gflags_unittest.cc' || echo '$(srcdir)/'`src/gflags_unittest.cc
+
+gflags_unittest.obj: src/gflags_unittest.cc
+ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT gflags_unittest.obj -MD -MP -MF $(DEPDIR)/gflags_unittest.Tpo -c -o gflags_unittest.obj `if test -f 'src/gflags_unittest.cc'; then $(CYGPATH_W) 'src/gflags_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/src/gflags_unittest.cc'; fi`
+ mv -f $(DEPDIR)/gflags_unittest.Tpo $(DEPDIR)/gflags_unittest.Po
+# source='src/gflags_unittest.cc' object='gflags_unittest.obj' libtool=no \
+# DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \
+# $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o gflags_unittest.obj `if test -f 'src/gflags_unittest.cc'; then $(CYGPATH_W) 'src/gflags_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/src/gflags_unittest.cc'; fi`
+
+gflags_strip_flags_test-gflags_strip_flags_test.o: src/gflags_strip_flags_test.cc
+ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gflags_strip_flags_test_CXXFLAGS) $(CXXFLAGS) -MT gflags_strip_flags_test-gflags_strip_flags_test.o -MD -MP -MF $(DEPDIR)/gflags_strip_flags_test-gflags_strip_flags_test.Tpo -c -o gflags_strip_flags_test-gflags_strip_flags_test.o `test -f 'src/gflags_strip_flags_test.cc' || echo '$(srcdir)/'`src/gflags_strip_flags_test.cc
+ mv -f $(DEPDIR)/gflags_strip_flags_test-gflags_strip_flags_test.Tpo $(DEPDIR)/gflags_strip_flags_test-gflags_strip_flags_test.Po
+# source='src/gflags_strip_flags_test.cc' object='gflags_strip_flags_test-gflags_strip_flags_test.o' libtool=no \
+# DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \
+# $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gflags_strip_flags_test_CXXFLAGS) $(CXXFLAGS) -c -o gflags_strip_flags_test-gflags_strip_flags_test.o `test -f 'src/gflags_strip_flags_test.cc' || echo '$(srcdir)/'`src/gflags_strip_flags_test.cc
+
+gflags_strip_flags_test-gflags_strip_flags_test.obj: src/gflags_strip_flags_test.cc
+ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gflags_strip_flags_test_CXXFLAGS) $(CXXFLAGS) -MT gflags_strip_flags_test-gflags_strip_flags_test.obj -MD -MP -MF $(DEPDIR)/gflags_strip_flags_test-gflags_strip_flags_test.Tpo -c -o gflags_strip_flags_test-gflags_strip_flags_test.obj `if test -f 'src/gflags_strip_flags_test.cc'; then $(CYGPATH_W) 'src/gflags_strip_flags_test.cc'; else $(CYGPATH_W) '$(srcdir)/src/gflags_strip_flags_test.cc'; fi`
+ mv -f $(DEPDIR)/gflags_strip_flags_test-gflags_strip_flags_test.Tpo $(DEPDIR)/gflags_strip_flags_test-gflags_strip_flags_test.Po
+# source='src/gflags_strip_flags_test.cc' object='gflags_strip_flags_test-gflags_strip_flags_test.obj' libtool=no \
+# DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \
+# $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gflags_strip_flags_test_CXXFLAGS) $(CXXFLAGS) -c -o gflags_strip_flags_test-gflags_strip_flags_test.obj `if test -f 'src/gflags_strip_flags_test.cc'; then $(CYGPATH_W) 'src/gflags_strip_flags_test.cc'; else $(CYGPATH_W) '$(srcdir)/src/gflags_strip_flags_test.cc'; fi`
+
+gflags_unittest-gflags_unittest.o: src/gflags_unittest.cc
+ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gflags_unittest_CXXFLAGS) $(CXXFLAGS) -MT gflags_unittest-gflags_unittest.o -MD -MP -MF $(DEPDIR)/gflags_unittest-gflags_unittest.Tpo -c -o gflags_unittest-gflags_unittest.o `test -f 'src/gflags_unittest.cc' || echo '$(srcdir)/'`src/gflags_unittest.cc
+ mv -f $(DEPDIR)/gflags_unittest-gflags_unittest.Tpo $(DEPDIR)/gflags_unittest-gflags_unittest.Po
+# source='src/gflags_unittest.cc' object='gflags_unittest-gflags_unittest.o' libtool=no \
+# DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \
+# $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gflags_unittest_CXXFLAGS) $(CXXFLAGS) -c -o gflags_unittest-gflags_unittest.o `test -f 'src/gflags_unittest.cc' || echo '$(srcdir)/'`src/gflags_unittest.cc
+
+gflags_unittest-gflags_unittest.obj: src/gflags_unittest.cc
+ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gflags_unittest_CXXFLAGS) $(CXXFLAGS) -MT gflags_unittest-gflags_unittest.obj -MD -MP -MF $(DEPDIR)/gflags_unittest-gflags_unittest.Tpo -c -o gflags_unittest-gflags_unittest.obj `if test -f 'src/gflags_unittest.cc'; then $(CYGPATH_W) 'src/gflags_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/src/gflags_unittest.cc'; fi`
+ mv -f $(DEPDIR)/gflags_unittest-gflags_unittest.Tpo $(DEPDIR)/gflags_unittest-gflags_unittest.Po
+# source='src/gflags_unittest.cc' object='gflags_unittest-gflags_unittest.obj' libtool=no \
+# DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \
+# $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gflags_unittest_CXXFLAGS) $(CXXFLAGS) -c -o gflags_unittest-gflags_unittest.obj `if test -f 'src/gflags_unittest.cc'; then $(CYGPATH_W) 'src/gflags_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/src/gflags_unittest.cc'; fi`
+
+gflags_unittest-main.o: src/gflags_unittest-main.cc
+ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT gflags_unittest-main.o -MD -MP -MF $(DEPDIR)/gflags_unittest-main.Tpo -c -o gflags_unittest-main.o `test -f 'src/gflags_unittest-main.cc' || echo '$(srcdir)/'`src/gflags_unittest-main.cc
+ mv -f $(DEPDIR)/gflags_unittest-main.Tpo $(DEPDIR)/gflags_unittest-main.Po
+# source='src/gflags_unittest-main.cc' object='gflags_unittest-main.o' libtool=no \
+# DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \
+# $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o gflags_unittest-main.o `test -f 'src/gflags_unittest-main.cc' || echo '$(srcdir)/'`src/gflags_unittest-main.cc
+
+gflags_unittest-main.obj: src/gflags_unittest-main.cc
+ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT gflags_unittest-main.obj -MD -MP -MF $(DEPDIR)/gflags_unittest-main.Tpo -c -o gflags_unittest-main.obj `if test -f 'src/gflags_unittest-main.cc'; then $(CYGPATH_W) 'src/gflags_unittest-main.cc'; else $(CYGPATH_W) '$(srcdir)/src/gflags_unittest-main.cc'; fi`
+ mv -f $(DEPDIR)/gflags_unittest-main.Tpo $(DEPDIR)/gflags_unittest-main.Po
+# source='src/gflags_unittest-main.cc' object='gflags_unittest-main.obj' libtool=no \
+# DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \
+# $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o gflags_unittest-main.obj `if test -f 'src/gflags_unittest-main.cc'; then $(CYGPATH_W) 'src/gflags_unittest-main.cc'; else $(CYGPATH_W) '$(srcdir)/src/gflags_unittest-main.cc'; fi`
+
+gflags_unittest_main.o: src/gflags_unittest_main.cc
+ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT gflags_unittest_main.o -MD -MP -MF $(DEPDIR)/gflags_unittest_main.Tpo -c -o gflags_unittest_main.o `test -f 'src/gflags_unittest_main.cc' || echo '$(srcdir)/'`src/gflags_unittest_main.cc
+ mv -f $(DEPDIR)/gflags_unittest_main.Tpo $(DEPDIR)/gflags_unittest_main.Po
+# source='src/gflags_unittest_main.cc' object='gflags_unittest_main.o' libtool=no \
+# DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \
+# $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o gflags_unittest_main.o `test -f 'src/gflags_unittest_main.cc' || echo '$(srcdir)/'`src/gflags_unittest_main.cc
+
+gflags_unittest_main.obj: src/gflags_unittest_main.cc
+ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT gflags_unittest_main.obj -MD -MP -MF $(DEPDIR)/gflags_unittest_main.Tpo -c -o gflags_unittest_main.obj `if test -f 'src/gflags_unittest_main.cc'; then $(CYGPATH_W) 'src/gflags_unittest_main.cc'; else $(CYGPATH_W) '$(srcdir)/src/gflags_unittest_main.cc'; fi`
+ mv -f $(DEPDIR)/gflags_unittest_main.Tpo $(DEPDIR)/gflags_unittest_main.Po
+# source='src/gflags_unittest_main.cc' object='gflags_unittest_main.obj' libtool=no \
+# DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \
+# $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o gflags_unittest_main.obj `if test -f 'src/gflags_unittest_main.cc'; then $(CYGPATH_W) 'src/gflags_unittest_main.cc'; else $(CYGPATH_W) '$(srcdir)/src/gflags_unittest_main.cc'; fi`
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+distclean-libtool:
+ -rm -f libtool
+install-dist_docDATA: $(dist_doc_DATA)
+ @$(NORMAL_INSTALL)
+ test -z "$(docdir)" || $(MKDIR_P) "$(DESTDIR)$(docdir)"
+ @list='$(dist_doc_DATA)'; for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ f=$(am__strip_dir) \
+ echo " $(dist_docDATA_INSTALL) '$$d$$p' '$(DESTDIR)$(docdir)/$$f'"; \
+ $(dist_docDATA_INSTALL) "$$d$$p" "$(DESTDIR)$(docdir)/$$f"; \
+ done
+
+uninstall-dist_docDATA:
+ @$(NORMAL_UNINSTALL)
+ @list='$(dist_doc_DATA)'; for p in $$list; do \
+ f=$(am__strip_dir) \
+ echo " rm -f '$(DESTDIR)$(docdir)/$$f'"; \
+ rm -f "$(DESTDIR)$(docdir)/$$f"; \
+ done
+install-pkgconfigDATA: $(pkgconfig_DATA)
+ @$(NORMAL_INSTALL)
+ test -z "$(pkgconfigdir)" || $(MKDIR_P) "$(DESTDIR)$(pkgconfigdir)"
+ @list='$(pkgconfig_DATA)'; for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ f=$(am__strip_dir) \
+ echo " $(pkgconfigDATA_INSTALL) '$$d$$p' '$(DESTDIR)$(pkgconfigdir)/$$f'"; \
+ $(pkgconfigDATA_INSTALL) "$$d$$p" "$(DESTDIR)$(pkgconfigdir)/$$f"; \
+ done
+
+uninstall-pkgconfigDATA:
+ @$(NORMAL_UNINSTALL)
+ @list='$(pkgconfig_DATA)'; for p in $$list; do \
+ f=$(am__strip_dir) \
+ echo " rm -f '$(DESTDIR)$(pkgconfigdir)/$$f'"; \
+ rm -f "$(DESTDIR)$(pkgconfigdir)/$$f"; \
+ done
+install-gflagsincludeHEADERS: $(gflagsinclude_HEADERS)
+ @$(NORMAL_INSTALL)
+ test -z "$(gflagsincludedir)" || $(MKDIR_P) "$(DESTDIR)$(gflagsincludedir)"
+ @list='$(gflagsinclude_HEADERS)'; for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ f=$(am__strip_dir) \
+ echo " $(gflagsincludeHEADERS_INSTALL) '$$d$$p' '$(DESTDIR)$(gflagsincludedir)/$$f'"; \
+ $(gflagsincludeHEADERS_INSTALL) "$$d$$p" "$(DESTDIR)$(gflagsincludedir)/$$f"; \
+ done
+
+uninstall-gflagsincludeHEADERS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(gflagsinclude_HEADERS)'; for p in $$list; do \
+ f=$(am__strip_dir) \
+ echo " rm -f '$(DESTDIR)$(gflagsincludedir)/$$f'"; \
+ rm -f "$(DESTDIR)$(gflagsincludedir)/$$f"; \
+ done
+install-googleincludeHEADERS: $(googleinclude_HEADERS)
+ @$(NORMAL_INSTALL)
+ test -z "$(googleincludedir)" || $(MKDIR_P) "$(DESTDIR)$(googleincludedir)"
+ @list='$(googleinclude_HEADERS)'; for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ f=$(am__strip_dir) \
+ echo " $(googleincludeHEADERS_INSTALL) '$$d$$p' '$(DESTDIR)$(googleincludedir)/$$f'"; \
+ $(googleincludeHEADERS_INSTALL) "$$d$$p" "$(DESTDIR)$(googleincludedir)/$$f"; \
+ done
+
+uninstall-googleincludeHEADERS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(googleinclude_HEADERS)'; for p in $$list; do \
+ f=$(am__strip_dir) \
+ echo " rm -f '$(DESTDIR)$(googleincludedir)/$$f'"; \
+ rm -f "$(DESTDIR)$(googleincludedir)/$$f"; \
+ done
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$tags $$unique; \
+ fi
+ctags: CTAGS
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ test -z "$(CTAGS_ARGS)$$tags$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$tags $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && cd $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) $$here
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+check-TESTS: $(TESTS)
+ @failed=0; all=0; xfail=0; xpass=0; skip=0; ws='[ ]'; \
+ srcdir=$(srcdir); export srcdir; \
+ list=' $(TESTS) '; \
+ if test -n "$$list"; then \
+ for tst in $$list; do \
+ if test -f ./$$tst; then dir=./; \
+ elif test -f $$tst; then dir=; \
+ else dir="$(srcdir)/"; fi; \
+ if $(TESTS_ENVIRONMENT) $${dir}$$tst; then \
+ all=`expr $$all + 1`; \
+ case " $(XFAIL_TESTS) " in \
+ *$$ws$$tst$$ws*) \
+ xpass=`expr $$xpass + 1`; \
+ failed=`expr $$failed + 1`; \
+ echo "XPASS: $$tst"; \
+ ;; \
+ *) \
+ echo "PASS: $$tst"; \
+ ;; \
+ esac; \
+ elif test $$? -ne 77; then \
+ all=`expr $$all + 1`; \
+ case " $(XFAIL_TESTS) " in \
+ *$$ws$$tst$$ws*) \
+ xfail=`expr $$xfail + 1`; \
+ echo "XFAIL: $$tst"; \
+ ;; \
+ *) \
+ failed=`expr $$failed + 1`; \
+ echo "FAIL: $$tst"; \
+ ;; \
+ esac; \
+ else \
+ skip=`expr $$skip + 1`; \
+ echo "SKIP: $$tst"; \
+ fi; \
+ done; \
+ if test "$$failed" -eq 0; then \
+ if test "$$xfail" -eq 0; then \
+ banner="All $$all tests passed"; \
+ else \
+ banner="All $$all tests behaved as expected ($$xfail expected failures)"; \
+ fi; \
+ else \
+ if test "$$xpass" -eq 0; then \
+ banner="$$failed of $$all tests failed"; \
+ else \
+ banner="$$failed of $$all tests did not behave as expected ($$xpass unexpected passes)"; \
+ fi; \
+ fi; \
+ dashes="$$banner"; \
+ skipped=""; \
+ if test "$$skip" -ne 0; then \
+ skipped="($$skip tests were not run)"; \
+ test `echo "$$skipped" | wc -c` -le `echo "$$banner" | wc -c` || \
+ dashes="$$skipped"; \
+ fi; \
+ report=""; \
+ if test "$$failed" -ne 0 && test -n "$(PACKAGE_BUGREPORT)"; then \
+ report="Please report to $(PACKAGE_BUGREPORT)"; \
+ test `echo "$$report" | wc -c` -le `echo "$$banner" | wc -c` || \
+ dashes="$$report"; \
+ fi; \
+ dashes=`echo "$$dashes" | sed s/./=/g`; \
+ echo "$$dashes"; \
+ echo "$$banner"; \
+ test -z "$$skipped" || echo "$$skipped"; \
+ test -z "$$report" || echo "$$report"; \
+ echo "$$dashes"; \
+ test "$$failed" -eq 0; \
+ else :; fi
+
+distdir: $(DISTFILES)
+ $(am__remove_distdir)
+ test -d $(distdir) || mkdir $(distdir)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+ fi; \
+ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+ else \
+ test -f $(distdir)/$$file \
+ || cp -p $$d/$$file $(distdir)/$$file \
+ || exit 1; \
+ fi; \
+ done
+ -find $(distdir) -type d ! -perm -777 -exec chmod a+rwx {} \; -o \
+ ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \
+ ! -type d ! -perm -400 -exec chmod a+r {} \; -o \
+ ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \
+ || chmod -R a+r $(distdir)
+dist-gzip: distdir
+ tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
+ $(am__remove_distdir)
+
+dist-bzip2: distdir
+ tardir=$(distdir) && $(am__tar) | bzip2 -9 -c >$(distdir).tar.bz2
+ $(am__remove_distdir)
+
+dist-lzma: distdir
+ tardir=$(distdir) && $(am__tar) | lzma -9 -c >$(distdir).tar.lzma
+ $(am__remove_distdir)
+
+dist-tarZ: distdir
+ tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z
+ $(am__remove_distdir)
+
+dist-shar: distdir
+ shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz
+ $(am__remove_distdir)
+dist-zip: distdir
+ -rm -f $(distdir).zip
+ zip -rq $(distdir).zip $(distdir)
+ $(am__remove_distdir)
+
+dist dist-all: distdir
+ tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
+ -rm -f $(distdir).zip
+ zip -rq $(distdir).zip $(distdir)
+ $(am__remove_distdir)
+
+# This target untars the dist file and tries a VPATH configuration. Then
+# it guarantees that the distribution is self-contained by making another
+# tarfile.
+distcheck: dist
+ case '$(DIST_ARCHIVES)' in \
+ *.tar.gz*) \
+ GZIP=$(GZIP_ENV) gunzip -c $(distdir).tar.gz | $(am__untar) ;;\
+ *.tar.bz2*) \
+ bunzip2 -c $(distdir).tar.bz2 | $(am__untar) ;;\
+ *.tar.lzma*) \
+ unlzma -c $(distdir).tar.lzma | $(am__untar) ;;\
+ *.tar.Z*) \
+ uncompress -c $(distdir).tar.Z | $(am__untar) ;;\
+ *.shar.gz*) \
+ GZIP=$(GZIP_ENV) gunzip -c $(distdir).shar.gz | unshar ;;\
+ *.zip*) \
+ unzip $(distdir).zip ;;\
+ esac
+ chmod -R a-w $(distdir); chmod a+w $(distdir)
+ mkdir $(distdir)/_build
+ mkdir $(distdir)/_inst
+ chmod a-w $(distdir)
+ dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \
+ && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \
+ && cd $(distdir)/_build \
+ && ../configure --srcdir=.. --prefix="$$dc_install_base" \
+ $(DISTCHECK_CONFIGURE_FLAGS) \
+ && $(MAKE) $(AM_MAKEFLAGS) \
+ && $(MAKE) $(AM_MAKEFLAGS) dvi \
+ && $(MAKE) $(AM_MAKEFLAGS) check \
+ && $(MAKE) $(AM_MAKEFLAGS) install \
+ && $(MAKE) $(AM_MAKEFLAGS) installcheck \
+ && $(MAKE) $(AM_MAKEFLAGS) uninstall \
+ && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \
+ distuninstallcheck \
+ && chmod -R a-w "$$dc_install_base" \
+ && ({ \
+ (cd ../.. && umask 077 && mkdir "$$dc_destdir") \
+ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \
+ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \
+ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \
+ distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \
+ } || { rm -rf "$$dc_destdir"; exit 1; }) \
+ && rm -rf "$$dc_destdir" \
+ && $(MAKE) $(AM_MAKEFLAGS) dist \
+ && rm -rf $(DIST_ARCHIVES) \
+ && $(MAKE) $(AM_MAKEFLAGS) distcleancheck
+ $(am__remove_distdir)
+ @(echo "$(distdir) archives ready for distribution: "; \
+ list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \
+ sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x'
+distuninstallcheck:
+ @cd $(distuninstallcheck_dir) \
+ && test `$(distuninstallcheck_listfiles) | wc -l` -le 1 \
+ || { echo "ERROR: files left after uninstall:" ; \
+ if test -n "$(DESTDIR)"; then \
+ echo " (check DESTDIR support)"; \
+ fi ; \
+ $(distuninstallcheck_listfiles) ; \
+ exit 1; } >&2
+distcleancheck: distclean
+ @if test '$(srcdir)' = . ; then \
+ echo "ERROR: distcleancheck can only run from a VPATH build" ; \
+ exit 1 ; \
+ fi
+ @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \
+ || { echo "ERROR: files left in build directory after distclean:" ; \
+ $(distcleancheck_listfiles) ; \
+ exit 1; } >&2
+check-am: all-am
+ $(MAKE) $(AM_MAKEFLAGS) $(check_SCRIPTS)
+ $(MAKE) $(AM_MAKEFLAGS) check-TESTS
+check: check-am
+all-am: Makefile $(LTLIBRARIES) $(PROGRAMS) $(SCRIPTS) $(DATA) \
+ $(HEADERS)
+installdirs:
+ for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(bindir)" "$(DESTDIR)$(docdir)" "$(DESTDIR)$(pkgconfigdir)" "$(DESTDIR)$(gflagsincludedir)" "$(DESTDIR)$(googleincludedir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+ -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \
+ clean-noinstPROGRAMS mostlyclean-am
+
+distclean: distclean-am
+ -rm -f $(am__CONFIG_DISTCLEAN_FILES)
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-hdr distclean-libtool distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+info: info-am
+
+info-am:
+
+install-data-am: install-dist_docDATA install-gflagsincludeHEADERS \
+ install-googleincludeHEADERS install-pkgconfigDATA
+
+install-dvi: install-dvi-am
+
+install-exec-am: install-binSCRIPTS install-libLTLIBRARIES
+
+install-html: install-html-am
+
+install-info: install-info-am
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-ps: install-ps-am
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -f $(am__CONFIG_DISTCLEAN_FILES)
+ -rm -rf $(top_srcdir)/autom4te.cache
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-binSCRIPTS uninstall-dist_docDATA \
+ uninstall-gflagsincludeHEADERS uninstall-googleincludeHEADERS \
+ uninstall-libLTLIBRARIES uninstall-pkgconfigDATA
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS all all-am am--refresh check check-TESTS check-am \
+ clean clean-generic clean-libLTLIBRARIES clean-libtool \
+ clean-noinstPROGRAMS ctags dist dist-all dist-bzip2 dist-gzip \
+ dist-lzma dist-shar dist-tarZ dist-zip distcheck distclean \
+ distclean-compile distclean-generic distclean-hdr \
+ distclean-libtool distclean-tags distcleancheck distdir \
+ distuninstallcheck dvi dvi-am html html-am info info-am \
+ install install-am install-binSCRIPTS install-data \
+ install-data-am install-dist_docDATA install-dvi \
+ install-dvi-am install-exec install-exec-am \
+ install-gflagsincludeHEADERS install-googleincludeHEADERS \
+ install-html install-html-am install-info install-info-am \
+ install-libLTLIBRARIES install-man install-pdf install-pdf-am \
+ install-pkgconfigDATA install-ps install-ps-am install-strip \
+ installcheck installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ tags uninstall uninstall-am uninstall-binSCRIPTS \
+ uninstall-dist_docDATA uninstall-gflagsincludeHEADERS \
+ uninstall-googleincludeHEADERS uninstall-libLTLIBRARIES \
+ uninstall-pkgconfigDATA
+
+src/gflags_unittest-main.cc: src/gflags_unittest.cc
+ rm -f src/gflags_unittest-main.cc
+ cp -p $(top_srcdir)/src/gflags_unittest.cc src/gflags_unittest-main.cc
+src/gflags_unittest_main.cc: src/gflags_unittest.cc
+ rm -f src/gflags_unittest_main.cc
+ cp -p $(top_srcdir)/src/gflags_unittest.cc src/gflags_unittest_main.cc
+gflags_unittest_sh: gflags_unittest$(EXEEXT) \
+ gflags_unittest2$(EXEEXT) \
+ gflags_unittest3$(EXEEXT)
+ bash --version >/dev/null 2>&1 && export SH=bash || export SH=sh; \
+ $$SH "$(top_srcdir)/src/gflags_unittest.sh" \
+ "`pwd`/gflags_unittest" "$(top_srcdir)" "/tmp/gflags"
+gflags_strip_flags_test_sh: gflags_strip_flags_test$(EXEEXT)
+ sh "$(top_srcdir)/src/gflags_strip_flags_test.sh" \
+ "`pwd`/gflags_strip_flags_test$(EXEEXT)"
+gflags_nc_test1: $(gflagsinclude_HEADERS) src/gflags_nc.cc
+ if $(CXX) -DTEST_SWAPPED_ARGS $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o gflags_nc_test1.o $(srcdir)/src/gflags_nc.cc; then echo "Compile succeeded but should have failed"; exit 1; else echo "Compile failed, like it was supposed to"; fi
+gflags_nc_test2: $(gflagsinclude_HEADERS) src/gflags_nc.cc
+ if $(CXX) -DTEST_INT_INSTEAD_OF_BOOL $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o gflags_nc_test2.o $(srcdir)/src/gflags_nc.cc; then echo "Compile succeeded but should have failed"; exit 1; else echo "Compile failed, like it was supposed to"; fi
+gflags_nc_test3: $(gflagsinclude_HEADERS) src/gflags_nc.cc
+ if $(CXX) -DTEST_BOOL_IN_QUOTES $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o gflags_nc_test3.o $(srcdir)/src/gflags_nc.cc; then echo "Compile succeeded but should have failed"; exit 1; else echo "Compile failed, like it was supposed to"; fi
+gflags_nc_test4: $(gflagsinclude_HEADERS) src/gflags_nc.cc
+ $(CXX) -DSANITY $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o gflags_nc_test4.o $(srcdir)/src/gflags_nc.cc
+
+rpm: dist-gzip packages/rpm.sh packages/rpm/rpm.spec
+ @cd packages && ./rpm.sh ${PACKAGE} ${VERSION}
+
+deb: dist-gzip packages/deb.sh packages/deb/*
+ @cd packages && ./deb.sh ${PACKAGE} ${VERSION}
+
+# I get the description and URL lines from the rpm spec. I use sed to
+# try to rewrite exec_prefix, libdir, and includedir in terms of
+# prefix, if possible.
+lib${PACKAGE}.pc: Makefile packages/rpm/rpm.spec
+ echo 'prefix=$(prefix)' > "$@".tmp
+ echo 'exec_prefix='`echo '$(exec_prefix)' | sed 's@^$(prefix)@$${prefix}@'` >> "$@".tmp
+ echo 'libdir='`echo '$(libdir)' | sed 's@^$(exec_prefix)@$${exec_prefix}@'` >> "$@".tmp
+ echo 'includedir='`echo '$(includedir)' | sed 's@^$(prefix)@$${prefix}@'` >> "$@".tmp
+ echo '' >> "$@".tmp
+ echo 'Name: $(PACKAGE)' >> "$@".tmp
+ echo 'Version: $(VERSION)' >> "$@".tmp
+ -grep '^Summary:' $(top_srcdir)/packages/rpm/rpm.spec | sed s/^Summary:/Description:/ | head -n1 >> "$@".tmp
+ -grep '^URL: ' $(top_srcdir)/packages/rpm/rpm.spec >> "$@".tmp
+ echo 'Requires:' >> "$@".tmp
+ echo 'Libs: -L$${libdir} -l$(PACKAGE)' >> "$@".tmp
+ echo 'Libs.private: $(PTHREAD_CFLAGS) $(PTHREAD_LIBS)' >> "$@".tmp
+ echo 'Cflags: -I$${includedir}' >> "$@".tmp
+ mv -f "$@".tmp "$@"
+
+# The nothreads version is mostly the same
+lib${PACKAGE}_nothreads.pc: lib${PACKAGE}.pc
+ grep -v Libs.private lib${PACKAGE}.pc | sed s/-l$(PACKAGE)/-l$(PACKAGE)_nothreads/ > "$@"
+
+libtool: $(LIBTOOL_DEPS)
+ $(SHELL) ./config.status --recheck
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/src/third_party/gflags-2.0/Makefile.am b/src/third_party/gflags-2.0/Makefile.am
new file mode 100755
index 00000000000..c976d4531b3
--- /dev/null
+++ b/src/third_party/gflags-2.0/Makefile.am
@@ -0,0 +1,213 @@
+## Process this file with automake to produce Makefile.in
+
+# Make sure that when we re-make ./configure, we get the macros we need
+ACLOCAL_AMFLAGS = -I m4
+
+# This is so we can #include <gflags/foo>
+AM_CPPFLAGS = -I$(top_srcdir)/src
+
+# This is mostly based on configure options
+AM_CXXFLAGS =
+
+# These are good warnings to turn on by default,
+if GCC
+AM_CXXFLAGS += -Wall -Wwrite-strings -Woverloaded-virtual -Wno-sign-compare
+endif
+
+# The -no-undefined flag allows libtool to generate shared libraries for
+# Cygwin and MinGW. LIBSTDCXX_LA_LINKER_FLAG is used to fix a Solaris bug.
+AM_LDFLAGS = -no-undefined $(LIBSTDCXX_LA_LINKER_FLAG)
+
+gflagsincludedir = $(includedir)/gflags
+## The .h files you want to install (that is, .h files that people
+## who install this package can include in their own applications.)
+gflagsinclude_HEADERS = src/gflags/gflags.h src/gflags/gflags_declare.h \
+ src/gflags/gflags_completions.h
+
+# This is for backwards compatibility only.
+googleincludedir = $(includedir)/google
+googleinclude_HEADERS = src/google/gflags.h src/google/gflags_completions.h
+
+bin_SCRIPTS = src/gflags_completions.sh
+
+docdir = $(prefix)/share/doc/$(PACKAGE)-$(VERSION)
+## This is for HTML and other documentation you want to install.
+## Add your documentation files (in doc/) in addition to these
+## top-level boilerplate files. Also add a TODO file if you have one.
+dist_doc_DATA = AUTHORS COPYING ChangeLog INSTALL NEWS README \
+ README_windows.txt doc/designstyle.css doc/gflags.html
+
+## The libraries (.so's) you want to install
+lib_LTLIBRARIES =
+## The location of the windows project file for each binary we make
+WINDOWS_PROJECTS = gflags.sln
+
+## unittests you want to run when people type 'make check'.
+## TESTS is for binary unittests, check_SCRIPTS for script-based unittests.
+## TESTS_ENVIRONMENT sets environment variables for when you run unittest,
+## but it only seems to take effect for *binary* unittests (argh!)
+TESTS =
+TESTS_ENVIRONMENT = SRCDIR="$(top_srcdir)"
+check_SCRIPTS =
+# Every time you add a unittest to check_SCRIPTS, add it here too
+noinst_SCRIPTS =
+# Used for auto-generated source files
+CLEANFILES =
+
+## vvvv RULES TO MAKE THE LIBRARIES, BINARIES, AND UNITTESTS
+
+GFLAGS_SOURCES = $(gflagsinclude_HEADERS) src/mutex.h src/util.h \
+ src/gflags.cc src/gflags_reporting.cc \
+ src/gflags_completions.cc
+
+lib_LTLIBRARIES += libgflags.la
+WINDOWS_PROJECTS += vsprojects/libgflags/libgflags.vcproj
+libgflags_la_SOURCES = $(GFLAGS_SOURCES)
+libgflags_la_CXXFLAGS = $(PTHREAD_CFLAGS) -DNDEBUG
+# -version-info gets passed to libtool
+libgflags_la_LDFLAGS = $(PTHREAD_CFLAGS) -version-info @SO_VERSION@
+libgflags_la_LIBADD = $(PTHREAD_LIBS)
+
+lib_LTLIBRARIES += libgflags_nothreads.la
+libgflags_nothreads_la_SOURCES = $(GFLAGS_SOURCES)
+libgflags_nothreads_la_CXXFLAGS = -DNDEBUG -DNO_THREADS
+libgflags_nothreads_la_LDFLAGS = -version-info @SO_VERSION@
+
+TESTS += gflags_unittest
+WINDOWS_PROJECTS += vsprojects/gflags_unittest/gflags_unittest.vcproj
+gflags_unittest_SOURCES = $(gflagsinclude_HEADERS) \
+ src/config_for_unittests.h \
+ src/gflags_unittest.cc
+gflags_unittest_CXXFLAGS = $(PTHREAD_CFLAGS)
+gflags_unittest_LDFLAGS = $(PTHREAD_CFLAGS)
+gflags_unittest_LDADD = libgflags.la
+
+# Also make sure this works when we don't link in pthreads
+TESTS += gflags_nothreads_unittest
+gflags_nothreads_unittest_SOURCES = $(gflags_unittest_SOURCES)
+gflags_nothreads_unittest_LDADD = libgflags_nothreads.la
+
+# We also want to test that things work properly when the file that
+# holds main() has a name ending with -main or _main. To keep the
+# Makefile small :-), we test the no-threads version of these.
+TESTS += gflags_unittest2
+gflags_unittest2_SOURCES = $(gflagsinclude_HEADERS) \
+ src/gflags_unittest-main.cc
+gflags_unittest2_LDADD = libgflags_nothreads.la
+src/gflags_unittest-main.cc: src/gflags_unittest.cc
+ rm -f src/gflags_unittest-main.cc
+ cp -p $(top_srcdir)/src/gflags_unittest.cc src/gflags_unittest-main.cc
+CLEANFILES += src/gflags_unittest-main.cc
+
+TESTS += gflags_unittest3
+gflags_unittest3_SOURCES = $(gflagsinclude_HEADERS) \
+ src/gflags_unittest_main.cc
+gflags_unittest3_LDADD = libgflags_nothreads.la
+src/gflags_unittest_main.cc: src/gflags_unittest.cc
+ rm -f src/gflags_unittest_main.cc
+ cp -p $(top_srcdir)/src/gflags_unittest.cc src/gflags_unittest_main.cc
+CLEANFILES += src/gflags_unittest_main.cc
+
+# Some buggy sh's ignore "" instead of treating it as a positional
+# parameter. Since we use "" in this script, we prefer bash if we
+# can. If there's no bash, we fall back to sh.
+check_SCRIPTS += gflags_unittest_sh
+noinst_SCRIPTS += src/gflags_unittest.sh
+dist_noinst_DATA = src/gflags_unittest_flagfile
+gflags_unittest_sh: gflags_unittest$(EXEEXT) \
+ gflags_unittest2$(EXEEXT) \
+ gflags_unittest3$(EXEEXT)
+ bash --version >/dev/null 2>&1 && export SH=bash || export SH=sh; \
+ $$SH "$(top_srcdir)/src/gflags_unittest.sh" \
+ "`pwd`/gflags_unittest" "$(top_srcdir)" "@TEST_TMPDIR@"
+
+# Test the STRIP_FLAGS #define.
+TESTS += gflags_strip_flags_test
+gflags_strip_flags_test_SOURCES = $(gflagsinclude_HEADERS) \
+ src/config_for_unittests.h \
+ src/gflags_strip_flags_test.cc
+gflags_strip_flags_test_CXXFLAGS = $(PTHREAD_CFLAGS)
+gflags_strip_flags_test_LDFLAGS = $(PTHREAD_CFLAGS)
+gflags_strip_flags_test_LDADD = libgflags.la
+
+check_SCRIPTS += gflags_strip_flags_test_sh
+noinst_SCRIPTS += src/gflags_strip_flags_test.sh
+gflags_strip_flags_test_sh: gflags_strip_flags_test$(EXEEXT)
+ sh "$(top_srcdir)/src/gflags_strip_flags_test.sh" \
+ "`pwd`/gflags_strip_flags_test$(EXEEXT)"
+
+# These are negative-compilation tests. We want to make sure these
+# erroneous use of the flags macros correctly fail to compile.
+# Again, we just bother testing with the no-threads version of the library.
+check_SCRIPTS += gflags_nc_test1
+gflags_nc_test1: $(gflagsinclude_HEADERS) src/gflags_nc.cc
+ if $(CXX) -DTEST_SWAPPED_ARGS $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o gflags_nc_test1.o $(srcdir)/src/gflags_nc.cc; then echo "Compile succeeded but should have failed"; exit 1; else echo "Compile failed, like it was supposed to"; fi
+
+check_SCRIPTS += gflags_nc_test2
+gflags_nc_test2: $(gflagsinclude_HEADERS) src/gflags_nc.cc
+ if $(CXX) -DTEST_INT_INSTEAD_OF_BOOL $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o gflags_nc_test2.o $(srcdir)/src/gflags_nc.cc; then echo "Compile succeeded but should have failed"; exit 1; else echo "Compile failed, like it was supposed to"; fi
+
+check_SCRIPTS += gflags_nc_test3
+gflags_nc_test3: $(gflagsinclude_HEADERS) src/gflags_nc.cc
+ if $(CXX) -DTEST_BOOL_IN_QUOTES $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o gflags_nc_test3.o $(srcdir)/src/gflags_nc.cc; then echo "Compile succeeded but should have failed"; exit 1; else echo "Compile failed, like it was supposed to"; fi
+
+# This one, on the other hand, should succeed.
+check_SCRIPTS += gflags_nc_test4
+gflags_nc_test4: $(gflagsinclude_HEADERS) src/gflags_nc.cc
+ $(CXX) -DSANITY $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o gflags_nc_test4.o $(srcdir)/src/gflags_nc.cc
+
+# This file isn't covered under any rule that would cause it to be distributed.
+dist_noinst_DATA += src/gflags_nc.cc
+
+
+## ^^^^ END OF RULES TO MAKE THE LIBRARIES, BINARIES, AND UNITTESTS
+
+
+## This should always include $(TESTS), but may also include other
+## binaries that you compile but don't want automatically installed.
+noinst_PROGRAMS = $(TESTS)
+
+rpm: dist-gzip packages/rpm.sh packages/rpm/rpm.spec
+ @cd packages && ./rpm.sh ${PACKAGE} ${VERSION}
+
+deb: dist-gzip packages/deb.sh packages/deb/*
+ @cd packages && ./deb.sh ${PACKAGE} ${VERSION}
+
+# http://linux.die.net/man/1/pkg-config, http://pkg-config.freedesktop.org/wiki
+pkgconfigdir = $(libdir)/pkgconfig
+pkgconfig_DATA = lib${PACKAGE}.pc lib${PACKAGE}_nothreads.pc
+CLEANFILES += $(pkgconfig_DATA)
+
+# I get the description and URL lines from the rpm spec. I use sed to
+# try to rewrite exec_prefix, libdir, and includedir in terms of
+# prefix, if possible.
+lib${PACKAGE}.pc: Makefile packages/rpm/rpm.spec
+ echo 'prefix=$(prefix)' > "$@".tmp
+ echo 'exec_prefix='`echo '$(exec_prefix)' | sed 's@^$(prefix)@$${prefix}@'` >> "$@".tmp
+ echo 'libdir='`echo '$(libdir)' | sed 's@^$(exec_prefix)@$${exec_prefix}@'` >> "$@".tmp
+ echo 'includedir='`echo '$(includedir)' | sed 's@^$(prefix)@$${prefix}@'` >> "$@".tmp
+ echo '' >> "$@".tmp
+ echo 'Name: $(PACKAGE)' >> "$@".tmp
+ echo 'Version: $(VERSION)' >> "$@".tmp
+ -grep '^Summary:' $(top_srcdir)/packages/rpm/rpm.spec | sed s/^Summary:/Description:/ | head -n1 >> "$@".tmp
+ -grep '^URL: ' $(top_srcdir)/packages/rpm/rpm.spec >> "$@".tmp
+ echo 'Requires:' >> "$@".tmp
+ echo 'Libs: -L$${libdir} -l$(PACKAGE)' >> "$@".tmp
+ echo 'Libs.private: $(PTHREAD_CFLAGS) $(PTHREAD_LIBS)' >> "$@".tmp
+ echo 'Cflags: -I$${includedir}' >> "$@".tmp
+ mv -f "$@".tmp "$@"
+
+# The nothreads version is mostly the same
+lib${PACKAGE}_nothreads.pc: lib${PACKAGE}.pc
+ grep -v Libs.private lib${PACKAGE}.pc | sed s/-l$(PACKAGE)/-l$(PACKAGE)_nothreads/ > "$@"
+
+libtool: $(LIBTOOL_DEPS)
+ $(SHELL) ./config.status --recheck
+
+EXTRA_DIST = packages/rpm.sh packages/rpm/rpm.spec packages/deb.sh packages/deb \
+ libtool $(SCRIPTS) \
+ src/windows/config.h src/windows/port.h src/windows/port.cc \
+ src/windows/gflags/gflags.h src/windows/gflags/gflags_declare.h \
+ src/windows/gflags/gflags_completions.h \
+ $(WINDOWS_PROJECTS) \
+ src/solaris/libstdc++.la
diff --git a/src/third_party/gflags-2.0/Makefile.in b/src/third_party/gflags-2.0/Makefile.in
new file mode 100755
index 00000000000..70a58e915ba
--- /dev/null
+++ b/src/third_party/gflags-2.0/Makefile.in
@@ -0,0 +1,1216 @@
+# Makefile.in generated by automake 1.10.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+
+
+
+
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+
+# These are good warnings to turn on by default,
+@GCC_TRUE@am__append_1 = -Wall -Wwrite-strings -Woverloaded-virtual -Wno-sign-compare
+TESTS = gflags_unittest$(EXEEXT) gflags_nothreads_unittest$(EXEEXT) \
+ gflags_unittest2$(EXEEXT) gflags_unittest3$(EXEEXT) \
+ gflags_strip_flags_test$(EXEEXT)
+noinst_PROGRAMS = $(am__EXEEXT_1)
+subdir = .
+DIST_COMMON = README $(am__configure_deps) $(dist_doc_DATA) \
+ $(dist_noinst_DATA) $(gflagsinclude_HEADERS) \
+ $(googleinclude_HEADERS) $(srcdir)/Makefile.am \
+ $(srcdir)/Makefile.in $(top_srcdir)/configure \
+ $(top_srcdir)/src/config.h.in \
+ $(top_srcdir)/src/gflags/gflags.h.in \
+ $(top_srcdir)/src/gflags/gflags_completions.h.in \
+ $(top_srcdir)/src/gflags/gflags_declare.h.in AUTHORS COPYING \
+ ChangeLog INSTALL NEWS config.guess config.sub depcomp \
+ install-sh ltmain.sh missing
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/ac_have_attribute.m4 \
+ $(top_srcdir)/m4/acx_pthread.m4 \
+ $(top_srcdir)/m4/google_namespace.m4 \
+ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
+ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
+ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/namespaces.m4 \
+ $(top_srcdir)/m4/stl_namespace.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \
+ configure.lineno config.status.lineno
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/src/config.h
+CONFIG_CLEAN_FILES = src/gflags/gflags.h src/gflags/gflags_declare.h \
+ src/gflags/gflags_completions.h
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = `echo $$p | sed -e 's|^.*/||'`;
+am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(bindir)" \
+ "$(DESTDIR)$(docdir)" "$(DESTDIR)$(pkgconfigdir)" \
+ "$(DESTDIR)$(gflagsincludedir)" \
+ "$(DESTDIR)$(googleincludedir)"
+libLTLIBRARIES_INSTALL = $(INSTALL)
+LTLIBRARIES = $(lib_LTLIBRARIES)
+am__DEPENDENCIES_1 =
+libgflags_la_DEPENDENCIES = $(am__DEPENDENCIES_1)
+am__objects_1 =
+am__objects_2 = $(am__objects_1) libgflags_la-gflags.lo \
+ libgflags_la-gflags_reporting.lo \
+ libgflags_la-gflags_completions.lo
+am_libgflags_la_OBJECTS = $(am__objects_2)
+libgflags_la_OBJECTS = $(am_libgflags_la_OBJECTS)
+libgflags_la_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(libgflags_la_CXXFLAGS) \
+ $(CXXFLAGS) $(libgflags_la_LDFLAGS) $(LDFLAGS) -o $@
+libgflags_nothreads_la_LIBADD =
+am__objects_3 = $(am__objects_1) libgflags_nothreads_la-gflags.lo \
+ libgflags_nothreads_la-gflags_reporting.lo \
+ libgflags_nothreads_la-gflags_completions.lo
+am_libgflags_nothreads_la_OBJECTS = $(am__objects_3)
+libgflags_nothreads_la_OBJECTS = $(am_libgflags_nothreads_la_OBJECTS)
+libgflags_nothreads_la_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
+ $(libgflags_nothreads_la_CXXFLAGS) $(CXXFLAGS) \
+ $(libgflags_nothreads_la_LDFLAGS) $(LDFLAGS) -o $@
+am__EXEEXT_1 = gflags_unittest$(EXEEXT) \
+ gflags_nothreads_unittest$(EXEEXT) gflags_unittest2$(EXEEXT) \
+ gflags_unittest3$(EXEEXT) gflags_strip_flags_test$(EXEEXT)
+PROGRAMS = $(noinst_PROGRAMS)
+am__objects_4 = $(am__objects_1) gflags_unittest.$(OBJEXT)
+am_gflags_nothreads_unittest_OBJECTS = $(am__objects_4)
+gflags_nothreads_unittest_OBJECTS = \
+ $(am_gflags_nothreads_unittest_OBJECTS)
+gflags_nothreads_unittest_DEPENDENCIES = libgflags_nothreads.la
+am_gflags_strip_flags_test_OBJECTS = $(am__objects_1) \
+ gflags_strip_flags_test-gflags_strip_flags_test.$(OBJEXT)
+gflags_strip_flags_test_OBJECTS = \
+ $(am_gflags_strip_flags_test_OBJECTS)
+gflags_strip_flags_test_DEPENDENCIES = libgflags.la
+gflags_strip_flags_test_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
+ $(gflags_strip_flags_test_CXXFLAGS) $(CXXFLAGS) \
+ $(gflags_strip_flags_test_LDFLAGS) $(LDFLAGS) -o $@
+am_gflags_unittest_OBJECTS = $(am__objects_1) \
+ gflags_unittest-gflags_unittest.$(OBJEXT)
+gflags_unittest_OBJECTS = $(am_gflags_unittest_OBJECTS)
+gflags_unittest_DEPENDENCIES = libgflags.la
+gflags_unittest_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
+ $(gflags_unittest_CXXFLAGS) $(CXXFLAGS) \
+ $(gflags_unittest_LDFLAGS) $(LDFLAGS) -o $@
+am_gflags_unittest2_OBJECTS = $(am__objects_1) \
+ gflags_unittest-main.$(OBJEXT)
+gflags_unittest2_OBJECTS = $(am_gflags_unittest2_OBJECTS)
+gflags_unittest2_DEPENDENCIES = libgflags_nothreads.la
+am_gflags_unittest3_OBJECTS = $(am__objects_1) \
+ gflags_unittest_main.$(OBJEXT)
+gflags_unittest3_OBJECTS = $(am_gflags_unittest3_OBJECTS)
+gflags_unittest3_DEPENDENCIES = libgflags_nothreads.la
+binSCRIPT_INSTALL = $(INSTALL_SCRIPT)
+SCRIPTS = $(bin_SCRIPTS) $(noinst_SCRIPTS)
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/src
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
+LTCXXCOMPILE = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
+CXXLD = $(CXX)
+CXXLINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \
+ $(LDFLAGS) -o $@
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
+ $(LDFLAGS) -o $@
+SOURCES = $(libgflags_la_SOURCES) $(libgflags_nothreads_la_SOURCES) \
+ $(gflags_nothreads_unittest_SOURCES) \
+ $(gflags_strip_flags_test_SOURCES) $(gflags_unittest_SOURCES) \
+ $(gflags_unittest2_SOURCES) $(gflags_unittest3_SOURCES)
+DIST_SOURCES = $(libgflags_la_SOURCES) \
+ $(libgflags_nothreads_la_SOURCES) \
+ $(gflags_nothreads_unittest_SOURCES) \
+ $(gflags_strip_flags_test_SOURCES) $(gflags_unittest_SOURCES) \
+ $(gflags_unittest2_SOURCES) $(gflags_unittest3_SOURCES)
+dist_docDATA_INSTALL = $(INSTALL_DATA)
+pkgconfigDATA_INSTALL = $(INSTALL_DATA)
+DATA = $(dist_doc_DATA) $(dist_noinst_DATA) $(pkgconfig_DATA)
+gflagsincludeHEADERS_INSTALL = $(INSTALL_HEADER)
+googleincludeHEADERS_INSTALL = $(INSTALL_HEADER)
+HEADERS = $(gflagsinclude_HEADERS) $(googleinclude_HEADERS)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+distdir = $(PACKAGE)-$(VERSION)
+top_distdir = $(distdir)
+am__remove_distdir = \
+ { test ! -d $(distdir) \
+ || { find $(distdir) -type d ! -perm -200 -exec chmod u+w {} ';' \
+ && rm -fr $(distdir); }; }
+DIST_ARCHIVES = $(distdir).tar.gz $(distdir).zip
+GZIP_ENV = --best
+distuninstallcheck_listfiles = find . -type f -print
+distcleancheck_listfiles = find . -type f -print
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBSTDCXX_LA_LINKER_FLAG = @LIBSTDCXX_LA_LINKER_FLAG@
+LIBTOOL = @LIBTOOL@
+LIBTOOL_DEPS = @LIBTOOL_DEPS@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PTHREAD_CC = @PTHREAD_CC@
+PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
+PTHREAD_LIBS = @PTHREAD_LIBS@
+RANLIB = @RANLIB@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SO_VERSION = @SO_VERSION@
+STRIP = @STRIP@
+TEST_TMPDIR = @TEST_TMPDIR@
+VERSION = @VERSION@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+ac_cv___attribute__unused = @ac_cv___attribute__unused@
+ac_cv_have___int16 = @ac_cv_have___int16@
+ac_cv_have_inttypes_h = @ac_cv_have_inttypes_h@
+ac_cv_have_stdint_h = @ac_cv_have_stdint_h@
+ac_cv_have_systypes_h = @ac_cv_have_systypes_h@
+ac_cv_have_u_int16_t = @ac_cv_have_u_int16_t@
+ac_cv_have_uint16_t = @ac_cv_have_uint16_t@
+ac_google_end_namespace = @ac_google_end_namespace@
+ac_google_namespace = @ac_google_namespace@
+ac_google_start_namespace = @ac_google_start_namespace@
+acx_pthread_config = @acx_pthread_config@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = $(prefix)/share/doc/$(PACKAGE)-$(VERSION)
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+lt_ECHO = @lt_ECHO@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+
+# Make sure that when we re-make ./configure, we get the macros we need
+ACLOCAL_AMFLAGS = -I m4
+
+# This is so we can #include <gflags/foo>
+AM_CPPFLAGS = -I$(top_srcdir)/src
+
+# This is mostly based on configure options
+AM_CXXFLAGS = $(am__append_1)
+
+# The -no-undefined flag allows libtool to generate shared libraries for
+# Cygwin and MinGW. LIBSTDCXX_LA_LINKER_FLAG is used to fix a Solaris bug.
+AM_LDFLAGS = -no-undefined $(LIBSTDCXX_LA_LINKER_FLAG)
+gflagsincludedir = $(includedir)/gflags
+gflagsinclude_HEADERS = src/gflags/gflags.h src/gflags/gflags_declare.h \
+ src/gflags/gflags_completions.h
+
+
+# This is for backwards compatibility only.
+googleincludedir = $(includedir)/google
+googleinclude_HEADERS = src/google/gflags.h src/google/gflags_completions.h
+bin_SCRIPTS = src/gflags_completions.sh
+dist_doc_DATA = AUTHORS COPYING ChangeLog INSTALL NEWS README \
+ README_windows.txt doc/designstyle.css doc/gflags.html
+
+lib_LTLIBRARIES = libgflags.la libgflags_nothreads.la
+WINDOWS_PROJECTS = gflags.sln vsprojects/libgflags/libgflags.vcproj \
+ vsprojects/gflags_unittest/gflags_unittest.vcproj
+TESTS_ENVIRONMENT = SRCDIR="$(top_srcdir)"
+
+# Some buggy sh's ignore "" instead of treating it as a positional
+# parameter. Since we use "" in this script, we prefer bash if we
+# can. If there's no bash, we fall back to sh.
+
+# These are negative-compilation tests. We want to make sure these
+# erroneous use of the flags macros correctly fail to compile.
+# Again, we just bother testing with the no-threads version of the library.
+
+# This one, on the other hand, should succeed.
+check_SCRIPTS = gflags_unittest_sh gflags_strip_flags_test_sh \
+ gflags_nc_test1 gflags_nc_test2 gflags_nc_test3 \
+ gflags_nc_test4
+# Every time you add a unittest to check_SCRIPTS, add it here too
+noinst_SCRIPTS = src/gflags_unittest.sh src/gflags_strip_flags_test.sh
+# Used for auto-generated source files
+CLEANFILES = src/gflags_unittest-main.cc src/gflags_unittest_main.cc \
+ $(pkgconfig_DATA)
+GFLAGS_SOURCES = $(gflagsinclude_HEADERS) src/mutex.h src/util.h \
+ src/gflags.cc src/gflags_reporting.cc \
+ src/gflags_completions.cc
+
+libgflags_la_SOURCES = $(GFLAGS_SOURCES)
+libgflags_la_CXXFLAGS = $(PTHREAD_CFLAGS) -DNDEBUG
+# -version-info gets passed to libtool
+libgflags_la_LDFLAGS = $(PTHREAD_CFLAGS) -version-info @SO_VERSION@
+libgflags_la_LIBADD = $(PTHREAD_LIBS)
+libgflags_nothreads_la_SOURCES = $(GFLAGS_SOURCES)
+libgflags_nothreads_la_CXXFLAGS = -DNDEBUG -DNO_THREADS
+libgflags_nothreads_la_LDFLAGS = -version-info @SO_VERSION@
+gflags_unittest_SOURCES = $(gflagsinclude_HEADERS) \
+ src/config_for_unittests.h \
+ src/gflags_unittest.cc
+
+gflags_unittest_CXXFLAGS = $(PTHREAD_CFLAGS)
+gflags_unittest_LDFLAGS = $(PTHREAD_CFLAGS)
+gflags_unittest_LDADD = libgflags.la
+gflags_nothreads_unittest_SOURCES = $(gflags_unittest_SOURCES)
+gflags_nothreads_unittest_LDADD = libgflags_nothreads.la
+gflags_unittest2_SOURCES = $(gflagsinclude_HEADERS) \
+ src/gflags_unittest-main.cc
+
+gflags_unittest2_LDADD = libgflags_nothreads.la
+gflags_unittest3_SOURCES = $(gflagsinclude_HEADERS) \
+ src/gflags_unittest_main.cc
+
+gflags_unittest3_LDADD = libgflags_nothreads.la
+
+# This file isn't covered under any rule that would cause it to be distributed.
+dist_noinst_DATA = src/gflags_unittest_flagfile src/gflags_nc.cc
+gflags_strip_flags_test_SOURCES = $(gflagsinclude_HEADERS) \
+ src/config_for_unittests.h \
+ src/gflags_strip_flags_test.cc
+
+gflags_strip_flags_test_CXXFLAGS = $(PTHREAD_CFLAGS)
+gflags_strip_flags_test_LDFLAGS = $(PTHREAD_CFLAGS)
+gflags_strip_flags_test_LDADD = libgflags.la
+
+# http://linux.die.net/man/1/pkg-config, http://pkg-config.freedesktop.org/wiki
+pkgconfigdir = $(libdir)/pkgconfig
+pkgconfig_DATA = lib${PACKAGE}.pc lib${PACKAGE}_nothreads.pc
+EXTRA_DIST = packages/rpm.sh packages/rpm/rpm.spec packages/deb.sh packages/deb \
+ libtool $(SCRIPTS) \
+ src/windows/config.h src/windows/port.h src/windows/port.cc \
+ src/windows/gflags/gflags.h src/windows/gflags/gflags_declare.h \
+ src/windows/gflags/gflags_completions.h \
+ $(WINDOWS_PROJECTS) \
+ src/solaris/libstdc++.la
+
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .cc .lo .o .obj
+am--refresh:
+ @:
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ echo ' cd $(srcdir) && $(AUTOMAKE) --gnu '; \
+ cd $(srcdir) && $(AUTOMAKE) --gnu \
+ && exit 0; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --gnu Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ echo ' $(SHELL) ./config.status'; \
+ $(SHELL) ./config.status;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ $(SHELL) ./config.status --recheck
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(srcdir) && $(AUTOCONF)
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS)
+
+src/config.h: src/stamp-h1
+ @if test ! -f $@; then \
+ rm -f src/stamp-h1; \
+ $(MAKE) $(AM_MAKEFLAGS) src/stamp-h1; \
+ else :; fi
+
+src/stamp-h1: $(top_srcdir)/src/config.h.in $(top_builddir)/config.status
+ @rm -f src/stamp-h1
+ cd $(top_builddir) && $(SHELL) ./config.status src/config.h
+$(top_srcdir)/src/config.h.in: $(am__configure_deps)
+ cd $(top_srcdir) && $(AUTOHEADER)
+ rm -f src/stamp-h1
+ touch $@
+
+distclean-hdr:
+ -rm -f src/config.h src/stamp-h1
+src/gflags/gflags.h: $(top_builddir)/config.status $(top_srcdir)/src/gflags/gflags.h.in
+ cd $(top_builddir) && $(SHELL) ./config.status $@
+src/gflags/gflags_declare.h: $(top_builddir)/config.status $(top_srcdir)/src/gflags/gflags_declare.h.in
+ cd $(top_builddir) && $(SHELL) ./config.status $@
+src/gflags/gflags_completions.h: $(top_builddir)/config.status $(top_srcdir)/src/gflags/gflags_completions.h.in
+ cd $(top_builddir) && $(SHELL) ./config.status $@
+install-libLTLIBRARIES: $(lib_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ test -z "$(libdir)" || $(MKDIR_P) "$(DESTDIR)$(libdir)"
+ @list='$(lib_LTLIBRARIES)'; for p in $$list; do \
+ if test -f $$p; then \
+ f=$(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) '$$p' '$(DESTDIR)$(libdir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) "$$p" "$(DESTDIR)$(libdir)/$$f"; \
+ else :; fi; \
+ done
+
+uninstall-libLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(lib_LTLIBRARIES)'; for p in $$list; do \
+ p=$(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$p'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$p"; \
+ done
+
+clean-libLTLIBRARIES:
+ -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)
+ @list='$(lib_LTLIBRARIES)'; for p in $$list; do \
+ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
+ test "$$dir" != "$$p" || dir=.; \
+ echo "rm -f \"$${dir}/so_locations\""; \
+ rm -f "$${dir}/so_locations"; \
+ done
+libgflags.la: $(libgflags_la_OBJECTS) $(libgflags_la_DEPENDENCIES)
+ $(libgflags_la_LINK) -rpath $(libdir) $(libgflags_la_OBJECTS) $(libgflags_la_LIBADD) $(LIBS)
+libgflags_nothreads.la: $(libgflags_nothreads_la_OBJECTS) $(libgflags_nothreads_la_DEPENDENCIES)
+ $(libgflags_nothreads_la_LINK) -rpath $(libdir) $(libgflags_nothreads_la_OBJECTS) $(libgflags_nothreads_la_LIBADD) $(LIBS)
+
+clean-noinstPROGRAMS:
+ @list='$(noinst_PROGRAMS)'; for p in $$list; do \
+ f=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
+ echo " rm -f $$p $$f"; \
+ rm -f $$p $$f ; \
+ done
+gflags_nothreads_unittest$(EXEEXT): $(gflags_nothreads_unittest_OBJECTS) $(gflags_nothreads_unittest_DEPENDENCIES)
+ @rm -f gflags_nothreads_unittest$(EXEEXT)
+ $(CXXLINK) $(gflags_nothreads_unittest_OBJECTS) $(gflags_nothreads_unittest_LDADD) $(LIBS)
+gflags_strip_flags_test$(EXEEXT): $(gflags_strip_flags_test_OBJECTS) $(gflags_strip_flags_test_DEPENDENCIES)
+ @rm -f gflags_strip_flags_test$(EXEEXT)
+ $(gflags_strip_flags_test_LINK) $(gflags_strip_flags_test_OBJECTS) $(gflags_strip_flags_test_LDADD) $(LIBS)
+gflags_unittest$(EXEEXT): $(gflags_unittest_OBJECTS) $(gflags_unittest_DEPENDENCIES)
+ @rm -f gflags_unittest$(EXEEXT)
+ $(gflags_unittest_LINK) $(gflags_unittest_OBJECTS) $(gflags_unittest_LDADD) $(LIBS)
+gflags_unittest2$(EXEEXT): $(gflags_unittest2_OBJECTS) $(gflags_unittest2_DEPENDENCIES)
+ @rm -f gflags_unittest2$(EXEEXT)
+ $(CXXLINK) $(gflags_unittest2_OBJECTS) $(gflags_unittest2_LDADD) $(LIBS)
+gflags_unittest3$(EXEEXT): $(gflags_unittest3_OBJECTS) $(gflags_unittest3_DEPENDENCIES)
+ @rm -f gflags_unittest3$(EXEEXT)
+ $(CXXLINK) $(gflags_unittest3_OBJECTS) $(gflags_unittest3_LDADD) $(LIBS)
+install-binSCRIPTS: $(bin_SCRIPTS)
+ @$(NORMAL_INSTALL)
+ test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)"
+ @list='$(bin_SCRIPTS)'; for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ if test -f $$d$$p; then \
+ f=`echo "$$p" | sed 's|^.*/||;$(transform)'`; \
+ echo " $(binSCRIPT_INSTALL) '$$d$$p' '$(DESTDIR)$(bindir)/$$f'"; \
+ $(binSCRIPT_INSTALL) "$$d$$p" "$(DESTDIR)$(bindir)/$$f"; \
+ else :; fi; \
+ done
+
+uninstall-binSCRIPTS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(bin_SCRIPTS)'; for p in $$list; do \
+ f=`echo "$$p" | sed 's|^.*/||;$(transform)'`; \
+ echo " rm -f '$(DESTDIR)$(bindir)/$$f'"; \
+ rm -f "$(DESTDIR)$(bindir)/$$f"; \
+ done
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gflags_strip_flags_test-gflags_strip_flags_test.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gflags_unittest-gflags_unittest.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gflags_unittest-main.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gflags_unittest.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gflags_unittest_main.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgflags_la-gflags.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgflags_la-gflags_completions.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgflags_la-gflags_reporting.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgflags_nothreads_la-gflags.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgflags_nothreads_la-gflags_completions.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgflags_nothreads_la-gflags_reporting.Plo@am__quote@
+
+.cc.o:
+@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $<
+
+.cc.obj:
+@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.cc.lo:
+@am__fastdepCXX_TRUE@ $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(LTCXXCOMPILE) -c -o $@ $<
+
+libgflags_la-gflags.lo: src/gflags.cc
+@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgflags_la_CXXFLAGS) $(CXXFLAGS) -MT libgflags_la-gflags.lo -MD -MP -MF $(DEPDIR)/libgflags_la-gflags.Tpo -c -o libgflags_la-gflags.lo `test -f 'src/gflags.cc' || echo '$(srcdir)/'`src/gflags.cc
+@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/libgflags_la-gflags.Tpo $(DEPDIR)/libgflags_la-gflags.Plo
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/gflags.cc' object='libgflags_la-gflags.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgflags_la_CXXFLAGS) $(CXXFLAGS) -c -o libgflags_la-gflags.lo `test -f 'src/gflags.cc' || echo '$(srcdir)/'`src/gflags.cc
+
+libgflags_la-gflags_reporting.lo: src/gflags_reporting.cc
+@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgflags_la_CXXFLAGS) $(CXXFLAGS) -MT libgflags_la-gflags_reporting.lo -MD -MP -MF $(DEPDIR)/libgflags_la-gflags_reporting.Tpo -c -o libgflags_la-gflags_reporting.lo `test -f 'src/gflags_reporting.cc' || echo '$(srcdir)/'`src/gflags_reporting.cc
+@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/libgflags_la-gflags_reporting.Tpo $(DEPDIR)/libgflags_la-gflags_reporting.Plo
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/gflags_reporting.cc' object='libgflags_la-gflags_reporting.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgflags_la_CXXFLAGS) $(CXXFLAGS) -c -o libgflags_la-gflags_reporting.lo `test -f 'src/gflags_reporting.cc' || echo '$(srcdir)/'`src/gflags_reporting.cc
+
+libgflags_la-gflags_completions.lo: src/gflags_completions.cc
+@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgflags_la_CXXFLAGS) $(CXXFLAGS) -MT libgflags_la-gflags_completions.lo -MD -MP -MF $(DEPDIR)/libgflags_la-gflags_completions.Tpo -c -o libgflags_la-gflags_completions.lo `test -f 'src/gflags_completions.cc' || echo '$(srcdir)/'`src/gflags_completions.cc
+@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/libgflags_la-gflags_completions.Tpo $(DEPDIR)/libgflags_la-gflags_completions.Plo
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/gflags_completions.cc' object='libgflags_la-gflags_completions.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgflags_la_CXXFLAGS) $(CXXFLAGS) -c -o libgflags_la-gflags_completions.lo `test -f 'src/gflags_completions.cc' || echo '$(srcdir)/'`src/gflags_completions.cc
+
+libgflags_nothreads_la-gflags.lo: src/gflags.cc
+@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgflags_nothreads_la_CXXFLAGS) $(CXXFLAGS) -MT libgflags_nothreads_la-gflags.lo -MD -MP -MF $(DEPDIR)/libgflags_nothreads_la-gflags.Tpo -c -o libgflags_nothreads_la-gflags.lo `test -f 'src/gflags.cc' || echo '$(srcdir)/'`src/gflags.cc
+@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/libgflags_nothreads_la-gflags.Tpo $(DEPDIR)/libgflags_nothreads_la-gflags.Plo
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/gflags.cc' object='libgflags_nothreads_la-gflags.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgflags_nothreads_la_CXXFLAGS) $(CXXFLAGS) -c -o libgflags_nothreads_la-gflags.lo `test -f 'src/gflags.cc' || echo '$(srcdir)/'`src/gflags.cc
+
+libgflags_nothreads_la-gflags_reporting.lo: src/gflags_reporting.cc
+@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgflags_nothreads_la_CXXFLAGS) $(CXXFLAGS) -MT libgflags_nothreads_la-gflags_reporting.lo -MD -MP -MF $(DEPDIR)/libgflags_nothreads_la-gflags_reporting.Tpo -c -o libgflags_nothreads_la-gflags_reporting.lo `test -f 'src/gflags_reporting.cc' || echo '$(srcdir)/'`src/gflags_reporting.cc
+@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/libgflags_nothreads_la-gflags_reporting.Tpo $(DEPDIR)/libgflags_nothreads_la-gflags_reporting.Plo
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/gflags_reporting.cc' object='libgflags_nothreads_la-gflags_reporting.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgflags_nothreads_la_CXXFLAGS) $(CXXFLAGS) -c -o libgflags_nothreads_la-gflags_reporting.lo `test -f 'src/gflags_reporting.cc' || echo '$(srcdir)/'`src/gflags_reporting.cc
+
+libgflags_nothreads_la-gflags_completions.lo: src/gflags_completions.cc
+@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgflags_nothreads_la_CXXFLAGS) $(CXXFLAGS) -MT libgflags_nothreads_la-gflags_completions.lo -MD -MP -MF $(DEPDIR)/libgflags_nothreads_la-gflags_completions.Tpo -c -o libgflags_nothreads_la-gflags_completions.lo `test -f 'src/gflags_completions.cc' || echo '$(srcdir)/'`src/gflags_completions.cc
+@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/libgflags_nothreads_la-gflags_completions.Tpo $(DEPDIR)/libgflags_nothreads_la-gflags_completions.Plo
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/gflags_completions.cc' object='libgflags_nothreads_la-gflags_completions.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgflags_nothreads_la_CXXFLAGS) $(CXXFLAGS) -c -o libgflags_nothreads_la-gflags_completions.lo `test -f 'src/gflags_completions.cc' || echo '$(srcdir)/'`src/gflags_completions.cc
+
+gflags_unittest.o: src/gflags_unittest.cc
+@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT gflags_unittest.o -MD -MP -MF $(DEPDIR)/gflags_unittest.Tpo -c -o gflags_unittest.o `test -f 'src/gflags_unittest.cc' || echo '$(srcdir)/'`src/gflags_unittest.cc
+@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/gflags_unittest.Tpo $(DEPDIR)/gflags_unittest.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/gflags_unittest.cc' object='gflags_unittest.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o gflags_unittest.o `test -f 'src/gflags_unittest.cc' || echo '$(srcdir)/'`src/gflags_unittest.cc
+
+gflags_unittest.obj: src/gflags_unittest.cc
+@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT gflags_unittest.obj -MD -MP -MF $(DEPDIR)/gflags_unittest.Tpo -c -o gflags_unittest.obj `if test -f 'src/gflags_unittest.cc'; then $(CYGPATH_W) 'src/gflags_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/src/gflags_unittest.cc'; fi`
+@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/gflags_unittest.Tpo $(DEPDIR)/gflags_unittest.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/gflags_unittest.cc' object='gflags_unittest.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o gflags_unittest.obj `if test -f 'src/gflags_unittest.cc'; then $(CYGPATH_W) 'src/gflags_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/src/gflags_unittest.cc'; fi`
+
+gflags_strip_flags_test-gflags_strip_flags_test.o: src/gflags_strip_flags_test.cc
+@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gflags_strip_flags_test_CXXFLAGS) $(CXXFLAGS) -MT gflags_strip_flags_test-gflags_strip_flags_test.o -MD -MP -MF $(DEPDIR)/gflags_strip_flags_test-gflags_strip_flags_test.Tpo -c -o gflags_strip_flags_test-gflags_strip_flags_test.o `test -f 'src/gflags_strip_flags_test.cc' || echo '$(srcdir)/'`src/gflags_strip_flags_test.cc
+@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/gflags_strip_flags_test-gflags_strip_flags_test.Tpo $(DEPDIR)/gflags_strip_flags_test-gflags_strip_flags_test.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/gflags_strip_flags_test.cc' object='gflags_strip_flags_test-gflags_strip_flags_test.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gflags_strip_flags_test_CXXFLAGS) $(CXXFLAGS) -c -o gflags_strip_flags_test-gflags_strip_flags_test.o `test -f 'src/gflags_strip_flags_test.cc' || echo '$(srcdir)/'`src/gflags_strip_flags_test.cc
+
+gflags_strip_flags_test-gflags_strip_flags_test.obj: src/gflags_strip_flags_test.cc
+@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gflags_strip_flags_test_CXXFLAGS) $(CXXFLAGS) -MT gflags_strip_flags_test-gflags_strip_flags_test.obj -MD -MP -MF $(DEPDIR)/gflags_strip_flags_test-gflags_strip_flags_test.Tpo -c -o gflags_strip_flags_test-gflags_strip_flags_test.obj `if test -f 'src/gflags_strip_flags_test.cc'; then $(CYGPATH_W) 'src/gflags_strip_flags_test.cc'; else $(CYGPATH_W) '$(srcdir)/src/gflags_strip_flags_test.cc'; fi`
+@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/gflags_strip_flags_test-gflags_strip_flags_test.Tpo $(DEPDIR)/gflags_strip_flags_test-gflags_strip_flags_test.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/gflags_strip_flags_test.cc' object='gflags_strip_flags_test-gflags_strip_flags_test.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gflags_strip_flags_test_CXXFLAGS) $(CXXFLAGS) -c -o gflags_strip_flags_test-gflags_strip_flags_test.obj `if test -f 'src/gflags_strip_flags_test.cc'; then $(CYGPATH_W) 'src/gflags_strip_flags_test.cc'; else $(CYGPATH_W) '$(srcdir)/src/gflags_strip_flags_test.cc'; fi`
+
+gflags_unittest-gflags_unittest.o: src/gflags_unittest.cc
+@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gflags_unittest_CXXFLAGS) $(CXXFLAGS) -MT gflags_unittest-gflags_unittest.o -MD -MP -MF $(DEPDIR)/gflags_unittest-gflags_unittest.Tpo -c -o gflags_unittest-gflags_unittest.o `test -f 'src/gflags_unittest.cc' || echo '$(srcdir)/'`src/gflags_unittest.cc
+@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/gflags_unittest-gflags_unittest.Tpo $(DEPDIR)/gflags_unittest-gflags_unittest.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/gflags_unittest.cc' object='gflags_unittest-gflags_unittest.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gflags_unittest_CXXFLAGS) $(CXXFLAGS) -c -o gflags_unittest-gflags_unittest.o `test -f 'src/gflags_unittest.cc' || echo '$(srcdir)/'`src/gflags_unittest.cc
+
+gflags_unittest-gflags_unittest.obj: src/gflags_unittest.cc
+@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gflags_unittest_CXXFLAGS) $(CXXFLAGS) -MT gflags_unittest-gflags_unittest.obj -MD -MP -MF $(DEPDIR)/gflags_unittest-gflags_unittest.Tpo -c -o gflags_unittest-gflags_unittest.obj `if test -f 'src/gflags_unittest.cc'; then $(CYGPATH_W) 'src/gflags_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/src/gflags_unittest.cc'; fi`
+@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/gflags_unittest-gflags_unittest.Tpo $(DEPDIR)/gflags_unittest-gflags_unittest.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/gflags_unittest.cc' object='gflags_unittest-gflags_unittest.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gflags_unittest_CXXFLAGS) $(CXXFLAGS) -c -o gflags_unittest-gflags_unittest.obj `if test -f 'src/gflags_unittest.cc'; then $(CYGPATH_W) 'src/gflags_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/src/gflags_unittest.cc'; fi`
+
+gflags_unittest-main.o: src/gflags_unittest-main.cc
+@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT gflags_unittest-main.o -MD -MP -MF $(DEPDIR)/gflags_unittest-main.Tpo -c -o gflags_unittest-main.o `test -f 'src/gflags_unittest-main.cc' || echo '$(srcdir)/'`src/gflags_unittest-main.cc
+@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/gflags_unittest-main.Tpo $(DEPDIR)/gflags_unittest-main.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/gflags_unittest-main.cc' object='gflags_unittest-main.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o gflags_unittest-main.o `test -f 'src/gflags_unittest-main.cc' || echo '$(srcdir)/'`src/gflags_unittest-main.cc
+
+gflags_unittest-main.obj: src/gflags_unittest-main.cc
+@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT gflags_unittest-main.obj -MD -MP -MF $(DEPDIR)/gflags_unittest-main.Tpo -c -o gflags_unittest-main.obj `if test -f 'src/gflags_unittest-main.cc'; then $(CYGPATH_W) 'src/gflags_unittest-main.cc'; else $(CYGPATH_W) '$(srcdir)/src/gflags_unittest-main.cc'; fi`
+@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/gflags_unittest-main.Tpo $(DEPDIR)/gflags_unittest-main.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/gflags_unittest-main.cc' object='gflags_unittest-main.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o gflags_unittest-main.obj `if test -f 'src/gflags_unittest-main.cc'; then $(CYGPATH_W) 'src/gflags_unittest-main.cc'; else $(CYGPATH_W) '$(srcdir)/src/gflags_unittest-main.cc'; fi`
+
+gflags_unittest_main.o: src/gflags_unittest_main.cc
+@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT gflags_unittest_main.o -MD -MP -MF $(DEPDIR)/gflags_unittest_main.Tpo -c -o gflags_unittest_main.o `test -f 'src/gflags_unittest_main.cc' || echo '$(srcdir)/'`src/gflags_unittest_main.cc
+@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/gflags_unittest_main.Tpo $(DEPDIR)/gflags_unittest_main.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/gflags_unittest_main.cc' object='gflags_unittest_main.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o gflags_unittest_main.o `test -f 'src/gflags_unittest_main.cc' || echo '$(srcdir)/'`src/gflags_unittest_main.cc
+
+gflags_unittest_main.obj: src/gflags_unittest_main.cc
+@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT gflags_unittest_main.obj -MD -MP -MF $(DEPDIR)/gflags_unittest_main.Tpo -c -o gflags_unittest_main.obj `if test -f 'src/gflags_unittest_main.cc'; then $(CYGPATH_W) 'src/gflags_unittest_main.cc'; else $(CYGPATH_W) '$(srcdir)/src/gflags_unittest_main.cc'; fi`
+@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/gflags_unittest_main.Tpo $(DEPDIR)/gflags_unittest_main.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/gflags_unittest_main.cc' object='gflags_unittest_main.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o gflags_unittest_main.obj `if test -f 'src/gflags_unittest_main.cc'; then $(CYGPATH_W) 'src/gflags_unittest_main.cc'; else $(CYGPATH_W) '$(srcdir)/src/gflags_unittest_main.cc'; fi`
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+distclean-libtool:
+ -rm -f libtool
+install-dist_docDATA: $(dist_doc_DATA)
+ @$(NORMAL_INSTALL)
+ test -z "$(docdir)" || $(MKDIR_P) "$(DESTDIR)$(docdir)"
+ @list='$(dist_doc_DATA)'; for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ f=$(am__strip_dir) \
+ echo " $(dist_docDATA_INSTALL) '$$d$$p' '$(DESTDIR)$(docdir)/$$f'"; \
+ $(dist_docDATA_INSTALL) "$$d$$p" "$(DESTDIR)$(docdir)/$$f"; \
+ done
+
+uninstall-dist_docDATA:
+ @$(NORMAL_UNINSTALL)
+ @list='$(dist_doc_DATA)'; for p in $$list; do \
+ f=$(am__strip_dir) \
+ echo " rm -f '$(DESTDIR)$(docdir)/$$f'"; \
+ rm -f "$(DESTDIR)$(docdir)/$$f"; \
+ done
+install-pkgconfigDATA: $(pkgconfig_DATA)
+ @$(NORMAL_INSTALL)
+ test -z "$(pkgconfigdir)" || $(MKDIR_P) "$(DESTDIR)$(pkgconfigdir)"
+ @list='$(pkgconfig_DATA)'; for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ f=$(am__strip_dir) \
+ echo " $(pkgconfigDATA_INSTALL) '$$d$$p' '$(DESTDIR)$(pkgconfigdir)/$$f'"; \
+ $(pkgconfigDATA_INSTALL) "$$d$$p" "$(DESTDIR)$(pkgconfigdir)/$$f"; \
+ done
+
+uninstall-pkgconfigDATA:
+ @$(NORMAL_UNINSTALL)
+ @list='$(pkgconfig_DATA)'; for p in $$list; do \
+ f=$(am__strip_dir) \
+ echo " rm -f '$(DESTDIR)$(pkgconfigdir)/$$f'"; \
+ rm -f "$(DESTDIR)$(pkgconfigdir)/$$f"; \
+ done
+install-gflagsincludeHEADERS: $(gflagsinclude_HEADERS)
+ @$(NORMAL_INSTALL)
+ test -z "$(gflagsincludedir)" || $(MKDIR_P) "$(DESTDIR)$(gflagsincludedir)"
+ @list='$(gflagsinclude_HEADERS)'; for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ f=$(am__strip_dir) \
+ echo " $(gflagsincludeHEADERS_INSTALL) '$$d$$p' '$(DESTDIR)$(gflagsincludedir)/$$f'"; \
+ $(gflagsincludeHEADERS_INSTALL) "$$d$$p" "$(DESTDIR)$(gflagsincludedir)/$$f"; \
+ done
+
+uninstall-gflagsincludeHEADERS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(gflagsinclude_HEADERS)'; for p in $$list; do \
+ f=$(am__strip_dir) \
+ echo " rm -f '$(DESTDIR)$(gflagsincludedir)/$$f'"; \
+ rm -f "$(DESTDIR)$(gflagsincludedir)/$$f"; \
+ done
+install-googleincludeHEADERS: $(googleinclude_HEADERS)
+ @$(NORMAL_INSTALL)
+ test -z "$(googleincludedir)" || $(MKDIR_P) "$(DESTDIR)$(googleincludedir)"
+ @list='$(googleinclude_HEADERS)'; for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ f=$(am__strip_dir) \
+ echo " $(googleincludeHEADERS_INSTALL) '$$d$$p' '$(DESTDIR)$(googleincludedir)/$$f'"; \
+ $(googleincludeHEADERS_INSTALL) "$$d$$p" "$(DESTDIR)$(googleincludedir)/$$f"; \
+ done
+
+uninstall-googleincludeHEADERS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(googleinclude_HEADERS)'; for p in $$list; do \
+ f=$(am__strip_dir) \
+ echo " rm -f '$(DESTDIR)$(googleincludedir)/$$f'"; \
+ rm -f "$(DESTDIR)$(googleincludedir)/$$f"; \
+ done
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$tags $$unique; \
+ fi
+ctags: CTAGS
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ test -z "$(CTAGS_ARGS)$$tags$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$tags $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && cd $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) $$here
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+check-TESTS: $(TESTS)
+ @failed=0; all=0; xfail=0; xpass=0; skip=0; ws='[ ]'; \
+ srcdir=$(srcdir); export srcdir; \
+ list=' $(TESTS) '; \
+ if test -n "$$list"; then \
+ for tst in $$list; do \
+ if test -f ./$$tst; then dir=./; \
+ elif test -f $$tst; then dir=; \
+ else dir="$(srcdir)/"; fi; \
+ if $(TESTS_ENVIRONMENT) $${dir}$$tst; then \
+ all=`expr $$all + 1`; \
+ case " $(XFAIL_TESTS) " in \
+ *$$ws$$tst$$ws*) \
+ xpass=`expr $$xpass + 1`; \
+ failed=`expr $$failed + 1`; \
+ echo "XPASS: $$tst"; \
+ ;; \
+ *) \
+ echo "PASS: $$tst"; \
+ ;; \
+ esac; \
+ elif test $$? -ne 77; then \
+ all=`expr $$all + 1`; \
+ case " $(XFAIL_TESTS) " in \
+ *$$ws$$tst$$ws*) \
+ xfail=`expr $$xfail + 1`; \
+ echo "XFAIL: $$tst"; \
+ ;; \
+ *) \
+ failed=`expr $$failed + 1`; \
+ echo "FAIL: $$tst"; \
+ ;; \
+ esac; \
+ else \
+ skip=`expr $$skip + 1`; \
+ echo "SKIP: $$tst"; \
+ fi; \
+ done; \
+ if test "$$failed" -eq 0; then \
+ if test "$$xfail" -eq 0; then \
+ banner="All $$all tests passed"; \
+ else \
+ banner="All $$all tests behaved as expected ($$xfail expected failures)"; \
+ fi; \
+ else \
+ if test "$$xpass" -eq 0; then \
+ banner="$$failed of $$all tests failed"; \
+ else \
+ banner="$$failed of $$all tests did not behave as expected ($$xpass unexpected passes)"; \
+ fi; \
+ fi; \
+ dashes="$$banner"; \
+ skipped=""; \
+ if test "$$skip" -ne 0; then \
+ skipped="($$skip tests were not run)"; \
+ test `echo "$$skipped" | wc -c` -le `echo "$$banner" | wc -c` || \
+ dashes="$$skipped"; \
+ fi; \
+ report=""; \
+ if test "$$failed" -ne 0 && test -n "$(PACKAGE_BUGREPORT)"; then \
+ report="Please report to $(PACKAGE_BUGREPORT)"; \
+ test `echo "$$report" | wc -c` -le `echo "$$banner" | wc -c` || \
+ dashes="$$report"; \
+ fi; \
+ dashes=`echo "$$dashes" | sed s/./=/g`; \
+ echo "$$dashes"; \
+ echo "$$banner"; \
+ test -z "$$skipped" || echo "$$skipped"; \
+ test -z "$$report" || echo "$$report"; \
+ echo "$$dashes"; \
+ test "$$failed" -eq 0; \
+ else :; fi
+
+distdir: $(DISTFILES)
+ $(am__remove_distdir)
+ test -d $(distdir) || mkdir $(distdir)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+ fi; \
+ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+ else \
+ test -f $(distdir)/$$file \
+ || cp -p $$d/$$file $(distdir)/$$file \
+ || exit 1; \
+ fi; \
+ done
+ -find $(distdir) -type d ! -perm -777 -exec chmod a+rwx {} \; -o \
+ ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \
+ ! -type d ! -perm -400 -exec chmod a+r {} \; -o \
+ ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \
+ || chmod -R a+r $(distdir)
+dist-gzip: distdir
+ tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
+ $(am__remove_distdir)
+
+dist-bzip2: distdir
+ tardir=$(distdir) && $(am__tar) | bzip2 -9 -c >$(distdir).tar.bz2
+ $(am__remove_distdir)
+
+dist-lzma: distdir
+ tardir=$(distdir) && $(am__tar) | lzma -9 -c >$(distdir).tar.lzma
+ $(am__remove_distdir)
+
+dist-tarZ: distdir
+ tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z
+ $(am__remove_distdir)
+
+dist-shar: distdir
+ shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz
+ $(am__remove_distdir)
+dist-zip: distdir
+ -rm -f $(distdir).zip
+ zip -rq $(distdir).zip $(distdir)
+ $(am__remove_distdir)
+
+dist dist-all: distdir
+ tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
+ -rm -f $(distdir).zip
+ zip -rq $(distdir).zip $(distdir)
+ $(am__remove_distdir)
+
+# This target untars the dist file and tries a VPATH configuration. Then
+# it guarantees that the distribution is self-contained by making another
+# tarfile.
+distcheck: dist
+ case '$(DIST_ARCHIVES)' in \
+ *.tar.gz*) \
+ GZIP=$(GZIP_ENV) gunzip -c $(distdir).tar.gz | $(am__untar) ;;\
+ *.tar.bz2*) \
+ bunzip2 -c $(distdir).tar.bz2 | $(am__untar) ;;\
+ *.tar.lzma*) \
+ unlzma -c $(distdir).tar.lzma | $(am__untar) ;;\
+ *.tar.Z*) \
+ uncompress -c $(distdir).tar.Z | $(am__untar) ;;\
+ *.shar.gz*) \
+ GZIP=$(GZIP_ENV) gunzip -c $(distdir).shar.gz | unshar ;;\
+ *.zip*) \
+ unzip $(distdir).zip ;;\
+ esac
+ chmod -R a-w $(distdir); chmod a+w $(distdir)
+ mkdir $(distdir)/_build
+ mkdir $(distdir)/_inst
+ chmod a-w $(distdir)
+ dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \
+ && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \
+ && cd $(distdir)/_build \
+ && ../configure --srcdir=.. --prefix="$$dc_install_base" \
+ $(DISTCHECK_CONFIGURE_FLAGS) \
+ && $(MAKE) $(AM_MAKEFLAGS) \
+ && $(MAKE) $(AM_MAKEFLAGS) dvi \
+ && $(MAKE) $(AM_MAKEFLAGS) check \
+ && $(MAKE) $(AM_MAKEFLAGS) install \
+ && $(MAKE) $(AM_MAKEFLAGS) installcheck \
+ && $(MAKE) $(AM_MAKEFLAGS) uninstall \
+ && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \
+ distuninstallcheck \
+ && chmod -R a-w "$$dc_install_base" \
+ && ({ \
+ (cd ../.. && umask 077 && mkdir "$$dc_destdir") \
+ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \
+ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \
+ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \
+ distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \
+ } || { rm -rf "$$dc_destdir"; exit 1; }) \
+ && rm -rf "$$dc_destdir" \
+ && $(MAKE) $(AM_MAKEFLAGS) dist \
+ && rm -rf $(DIST_ARCHIVES) \
+ && $(MAKE) $(AM_MAKEFLAGS) distcleancheck
+ $(am__remove_distdir)
+ @(echo "$(distdir) archives ready for distribution: "; \
+ list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \
+ sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x'
+distuninstallcheck:
+ @cd $(distuninstallcheck_dir) \
+ && test `$(distuninstallcheck_listfiles) | wc -l` -le 1 \
+ || { echo "ERROR: files left after uninstall:" ; \
+ if test -n "$(DESTDIR)"; then \
+ echo " (check DESTDIR support)"; \
+ fi ; \
+ $(distuninstallcheck_listfiles) ; \
+ exit 1; } >&2
+distcleancheck: distclean
+ @if test '$(srcdir)' = . ; then \
+ echo "ERROR: distcleancheck can only run from a VPATH build" ; \
+ exit 1 ; \
+ fi
+ @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \
+ || { echo "ERROR: files left in build directory after distclean:" ; \
+ $(distcleancheck_listfiles) ; \
+ exit 1; } >&2
+check-am: all-am
+ $(MAKE) $(AM_MAKEFLAGS) $(check_SCRIPTS)
+ $(MAKE) $(AM_MAKEFLAGS) check-TESTS
+check: check-am
+all-am: Makefile $(LTLIBRARIES) $(PROGRAMS) $(SCRIPTS) $(DATA) \
+ $(HEADERS)
+installdirs:
+ for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(bindir)" "$(DESTDIR)$(docdir)" "$(DESTDIR)$(pkgconfigdir)" "$(DESTDIR)$(gflagsincludedir)" "$(DESTDIR)$(googleincludedir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+ -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \
+ clean-noinstPROGRAMS mostlyclean-am
+
+distclean: distclean-am
+ -rm -f $(am__CONFIG_DISTCLEAN_FILES)
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-hdr distclean-libtool distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+info: info-am
+
+info-am:
+
+install-data-am: install-dist_docDATA install-gflagsincludeHEADERS \
+ install-googleincludeHEADERS install-pkgconfigDATA
+
+install-dvi: install-dvi-am
+
+install-exec-am: install-binSCRIPTS install-libLTLIBRARIES
+
+install-html: install-html-am
+
+install-info: install-info-am
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-ps: install-ps-am
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -f $(am__CONFIG_DISTCLEAN_FILES)
+ -rm -rf $(top_srcdir)/autom4te.cache
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-binSCRIPTS uninstall-dist_docDATA \
+ uninstall-gflagsincludeHEADERS uninstall-googleincludeHEADERS \
+ uninstall-libLTLIBRARIES uninstall-pkgconfigDATA
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS all all-am am--refresh check check-TESTS check-am \
+ clean clean-generic clean-libLTLIBRARIES clean-libtool \
+ clean-noinstPROGRAMS ctags dist dist-all dist-bzip2 dist-gzip \
+ dist-lzma dist-shar dist-tarZ dist-zip distcheck distclean \
+ distclean-compile distclean-generic distclean-hdr \
+ distclean-libtool distclean-tags distcleancheck distdir \
+ distuninstallcheck dvi dvi-am html html-am info info-am \
+ install install-am install-binSCRIPTS install-data \
+ install-data-am install-dist_docDATA install-dvi \
+ install-dvi-am install-exec install-exec-am \
+ install-gflagsincludeHEADERS install-googleincludeHEADERS \
+ install-html install-html-am install-info install-info-am \
+ install-libLTLIBRARIES install-man install-pdf install-pdf-am \
+ install-pkgconfigDATA install-ps install-ps-am install-strip \
+ installcheck installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ tags uninstall uninstall-am uninstall-binSCRIPTS \
+ uninstall-dist_docDATA uninstall-gflagsincludeHEADERS \
+ uninstall-googleincludeHEADERS uninstall-libLTLIBRARIES \
+ uninstall-pkgconfigDATA
+
+src/gflags_unittest-main.cc: src/gflags_unittest.cc
+ rm -f src/gflags_unittest-main.cc
+ cp -p $(top_srcdir)/src/gflags_unittest.cc src/gflags_unittest-main.cc
+src/gflags_unittest_main.cc: src/gflags_unittest.cc
+ rm -f src/gflags_unittest_main.cc
+ cp -p $(top_srcdir)/src/gflags_unittest.cc src/gflags_unittest_main.cc
+gflags_unittest_sh: gflags_unittest$(EXEEXT) \
+ gflags_unittest2$(EXEEXT) \
+ gflags_unittest3$(EXEEXT)
+ bash --version >/dev/null 2>&1 && export SH=bash || export SH=sh; \
+ $$SH "$(top_srcdir)/src/gflags_unittest.sh" \
+ "`pwd`/gflags_unittest" "$(top_srcdir)" "@TEST_TMPDIR@"
+gflags_strip_flags_test_sh: gflags_strip_flags_test$(EXEEXT)
+ sh "$(top_srcdir)/src/gflags_strip_flags_test.sh" \
+ "`pwd`/gflags_strip_flags_test$(EXEEXT)"
+gflags_nc_test1: $(gflagsinclude_HEADERS) src/gflags_nc.cc
+ if $(CXX) -DTEST_SWAPPED_ARGS $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o gflags_nc_test1.o $(srcdir)/src/gflags_nc.cc; then echo "Compile succeeded but should have failed"; exit 1; else echo "Compile failed, like it was supposed to"; fi
+gflags_nc_test2: $(gflagsinclude_HEADERS) src/gflags_nc.cc
+ if $(CXX) -DTEST_INT_INSTEAD_OF_BOOL $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o gflags_nc_test2.o $(srcdir)/src/gflags_nc.cc; then echo "Compile succeeded but should have failed"; exit 1; else echo "Compile failed, like it was supposed to"; fi
+gflags_nc_test3: $(gflagsinclude_HEADERS) src/gflags_nc.cc
+ if $(CXX) -DTEST_BOOL_IN_QUOTES $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o gflags_nc_test3.o $(srcdir)/src/gflags_nc.cc; then echo "Compile succeeded but should have failed"; exit 1; else echo "Compile failed, like it was supposed to"; fi
+gflags_nc_test4: $(gflagsinclude_HEADERS) src/gflags_nc.cc
+ $(CXX) -DSANITY $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o gflags_nc_test4.o $(srcdir)/src/gflags_nc.cc
+
+rpm: dist-gzip packages/rpm.sh packages/rpm/rpm.spec
+ @cd packages && ./rpm.sh ${PACKAGE} ${VERSION}
+
+deb: dist-gzip packages/deb.sh packages/deb/*
+ @cd packages && ./deb.sh ${PACKAGE} ${VERSION}
+
+# I get the description and URL lines from the rpm spec. I use sed to
+# try to rewrite exec_prefix, libdir, and includedir in terms of
+# prefix, if possible.
+lib${PACKAGE}.pc: Makefile packages/rpm/rpm.spec
+ echo 'prefix=$(prefix)' > "$@".tmp
+ echo 'exec_prefix='`echo '$(exec_prefix)' | sed 's@^$(prefix)@$${prefix}@'` >> "$@".tmp
+ echo 'libdir='`echo '$(libdir)' | sed 's@^$(exec_prefix)@$${exec_prefix}@'` >> "$@".tmp
+ echo 'includedir='`echo '$(includedir)' | sed 's@^$(prefix)@$${prefix}@'` >> "$@".tmp
+ echo '' >> "$@".tmp
+ echo 'Name: $(PACKAGE)' >> "$@".tmp
+ echo 'Version: $(VERSION)' >> "$@".tmp
+ -grep '^Summary:' $(top_srcdir)/packages/rpm/rpm.spec | sed s/^Summary:/Description:/ | head -n1 >> "$@".tmp
+ -grep '^URL: ' $(top_srcdir)/packages/rpm/rpm.spec >> "$@".tmp
+ echo 'Requires:' >> "$@".tmp
+ echo 'Libs: -L$${libdir} -l$(PACKAGE)' >> "$@".tmp
+ echo 'Libs.private: $(PTHREAD_CFLAGS) $(PTHREAD_LIBS)' >> "$@".tmp
+ echo 'Cflags: -I$${includedir}' >> "$@".tmp
+ mv -f "$@".tmp "$@"
+
+# The nothreads version is mostly the same
+lib${PACKAGE}_nothreads.pc: lib${PACKAGE}.pc
+ grep -v Libs.private lib${PACKAGE}.pc | sed s/-l$(PACKAGE)/-l$(PACKAGE)_nothreads/ > "$@"
+
+libtool: $(LIBTOOL_DEPS)
+ $(SHELL) ./config.status --recheck
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/src/third_party/gflags-2.0/NEWS b/src/third_party/gflags-2.0/NEWS
new file mode 100755
index 00000000000..ffc0127d91e
--- /dev/null
+++ b/src/third_party/gflags-2.0/NEWS
@@ -0,0 +1,158 @@
+== 25 January 2012 ==
+
+I've just released gflags 2.0.
+
+The `google-gflags` project has been renamed to `gflags`. I
+(csilvers) am stepping down as maintainer, to be replaced by Andreas
+Schuh. Welcome to the team, Andreas! I've seen the energy you have
+around gflags and the ideas you have for the project going forward,
+and look forward to having you on the team.
+
+I bumped the major version number up to 2 to reflect the new community
+ownership of the project. All the
+[http://gflags.googlecode.com/svn/tags/gflags-2.0/ChangeLog changes]
+are related to the renaming. There are no functional changes from
+gflags 1.7. In particular, I've kept the code in the namespace
+`google`, though in a future version it should be renamed to `gflags`.
+I've also kept the `/usr/local/include/google/` subdirectory as
+synonym of `/usr/local/include/gflags/`, though the former name has
+been obsolete for some time now.
+
+
+=== 18 January 2011 ===
+
+The `google-gflags` Google Code page has been renamed to
+`gflags`, in preparation for the project being renamed to
+`gflags`. In the coming weeks, I'll be stepping down as
+maintainer for the gflags project, and as part of that Google is
+relinquishing ownership of the project; it will now be entirely
+community run. The name change reflects that shift.
+
+
+=== 20 December 2011 ===
+
+I've just released gflags 1.7. This is a minor release; the major
+change is that `CommandLineFlagInfo` now exports the address in memory
+where the flag is located. There has also been a bugfix involving
+very long --help strings, and some other minor
+[http://code.google.com/p/google-gflags/source/browse/tags/gflags-1.7/ChangeLog changes].
+
+=== 29 July 2011 ===
+
+I've just released gflags 1.6. The major new feature in this release
+is support for setting version info, so that --version does something
+useful.
+
+One minor change has required bumping the library number:
+`ReparseCommandlineFlags` now returns `void` instead of `int` (the int
+return value was always meaningless). Though I doubt anyone ever used
+this (meaningless) return value, technically it's a change to the ABI
+that requires a version bump. A bit sad.
+
+There's also a procedural change with this release: I've changed the
+internal tools used to integrate Google-supplied patches for gflags
+into the opensource release. These new tools should result in more
+frequent updates with better change descriptions. They will also
+result in future `ChangeLog` entries being much more verbose (for better
+or for worse).
+
+See the
+[http://code.google.com/p/google-gflags/source/browse/tags/gflags-1.6/ChangeLog ChangeLog]
+for a full list of changes for this release.
+
+=== 24 January 2011 ===
+
+I've just released gflags 1.5. This release has only minor changes
+from 1.4, including some slightly better reporting in --help, and
+an new memory-cleanup function that can help when running gflags-using
+libraries under valgrind. The major change is to fix up the macros
+(`DEFINE_bool` and the like) to work more reliably inside namespaces.
+
+If you have not had a problem with these macros, and don't need any of
+the other changes described, there is no need to upgrade. See the
+[http://code.google.com/p/google-gflags/source/browse/tags/gflags-1.5/ChangeLog ChangeLog]
+for a full list of changes for this release.
+
+=== 11 October 2010 ===
+
+I've just released gflags 1.4. This release has only minor changes
+from 1.3, including some documentation tweaks and some work to make
+the library smaller. If 1.3 is working well for you, there's no
+particular reason to upgrade.
+
+=== 4 January 2010 ===
+
+I've just released gflags 1.3. gflags now compiles under MSVC, and
+all tests pass. I *really* never thought non-unix-y Windows folks
+would want gflags, but at least some of them do.
+
+The major news, though, is that I've separated out the python package
+into its own library, [http://code.google.com/p/python-gflags python-gflags].
+If you're interested in the Python version of gflags, that's the place to
+get it now.
+
+=== 10 September 2009 ==
+
+I've just released gflags 1.2. The major change from gflags 1.1 is it
+now compiles under MinGW (as well as cygwin), and all tests pass. I
+never thought Windows folks would want unix-style command-line flags,
+since they're so different from the Windows style, but I guess I was
+wrong!
+
+The other changes are minor, such as support for --htmlxml in the
+python version of gflags.
+
+=== 15 April 2009 ===
+
+I've just released gflags 1.1. It has only minor changes fdrom gflags
+1.0 (see the
+[http://code.google.com/p/google-gflags/source/browse/tags/gflags-1.1/ChangeLog ChangeLog]
+for details). The major change is that I moved to a new
+system for creating .deb and .rpm files. This allows me to create
+x86_64 deb and rpm files.
+
+In the process of moving to this new system, I noticed an
+inconsistency: the tar.gz and .rpm files created libraries named
+libgflags.so, but the deb file created libgoogle-gflags.so. I have
+fixed the deb file to create libraries like the others. I'm no expert
+in debian packaging, but I believe this has caused the package name to
+change as well. Please let me know (at
+[mailto:google-gflags@googlegroups.com
+google-gflags@googlegroups.com]) if this causes problems for you --
+especially if you know of a fix! I would be happy to change the deb
+packages to add symlinks from the old library name to the new
+(libgoogle-gflags.so -> libgflags.so), but that is beyond my knowledge
+of how to make .debs.
+
+If you've tried to install a .rpm or .deb and it doesn't work for you,
+let me know. I'm excited to finally have 64-bit package files, but
+there may still be some wrinkles in the new system to iron out.
+
+===1 October 2008===
+
+gflags 1.0rc2 was out for a few weeks without any issues, so gflags
+1.0 is now released. This is much like gflags 0.9. The major change
+is that the .h files have been moved from `/usr/include/google` to
+`/usr/include/gflags`. While I have backwards-compatibility
+forwarding headeds in place, please rewrite existing code to say
+{{{
+ #include <gflags/gflags.h>
+}}}
+instead of
+{{{
+ #include <google/gflags.h>
+}}}
+
+I've kept the default namespace to google. You can still change with
+with the appropriate flag to the configure script (`./configure
+--help` to see the flags). If you have feedback as to whether the
+default namespace should change to gflags, which would be a
+non-backwards-compatible change, send mail to
+`google-gflags@googlegroups.com`!
+
+Version 1.0 also has some neat new features, like support for bash
+commandline-completion of help flags. See the
+[http://code.google.com/p/google-gflags/source/browse/tags/gflags-1.0rc2/ChangeLog
+ChangeLog] for more details.
+
+If I don't hear any bad news for a few weeks, I'll release 1.0-final.
diff --git a/src/third_party/gflags-2.0/README b/src/third_party/gflags-2.0/README
new file mode 100755
index 00000000000..74229821b81
--- /dev/null
+++ b/src/third_party/gflags-2.0/README
@@ -0,0 +1,9 @@
+This repository contains a C++ of the Google commandline flags module.
+Documentation for the C++ implementation is in doc/. The python version of
+gflags is now shipped seperately as it is completely independent of this
+module.
+
+See INSTALL for (generic) installation instructions for C++: basically
+ ./configure && make && make install
+
+See README_windows.txt for instructions on using under windows.
diff --git a/src/third_party/gflags-2.0/README_windows.txt b/src/third_party/gflags-2.0/README_windows.txt
new file mode 100755
index 00000000000..ffb06bb5e1c
--- /dev/null
+++ b/src/third_party/gflags-2.0/README_windows.txt
@@ -0,0 +1,26 @@
+You can compile this under Windows, if you want. The solution file
+(for VC 7.1 and later) is in this directory.
+
+I've been told the following steps work to compile this under win64:
+ 1) Open the provided solution file
+ 2) Click on the Win32 target (on the right of Debug/Release)
+ 3) Choose Configuration Manager
+ 4) In Active Solution Platforms, choose New...
+ 5) In "Type of select the new platform", choose x64.
+ In "Copy settings from:" choose Win32.
+ 6) Ok and then Close
+
+I don't know very much about how to install DLLs on Windows, so you'll
+have to figure out that part for yourself. If you choose to just
+re-use the existing .sln, make sure you set the IncludeDir's
+appropriately! Look at the properties for libgflags.dll.
+
+You can also create a static library of gflags. To do this, add
+ /D GFLAGS_DLL_DECL= /D GFLAGS_DLL_DECLARE_FLAG= /D GFLAGS_DLL_DEFINE_FLAG=
+to the compile line of every gflags .cc file.
+
+If you create a static library that *uses* flags (that is, DEFINEs or
+DECLAREs flags), you will need to add the following to every .cc file
+that defines or declares a flag (it's safe to add them to every .cc
+file in your project):
+ /D GFLAGS_DLL_DECLARE_FLAG= /D GFLAGS_DLL_DEFINE_FLAG=
diff --git a/src/third_party/gflags-2.0/SConscript b/src/third_party/gflags-2.0/SConscript
new file mode 100755
index 00000000000..ba0f04c9ff9
--- /dev/null
+++ b/src/third_party/gflags-2.0/SConscript
@@ -0,0 +1,16 @@
+# -*- mode: python -*-
+
+Import("env windows linux darwin solaris")
+
+env = env.Clone()
+
+# Sigh. "config.h" is a very popular include and we want ours to be
+# the one used.
+env.Append(CCFLAGS=['-Isrc/third_party/gflags-2.0/src'])
+
+env.StaticLibrary(
+ "gflags",
+ [ "src/gflags.cc",
+ #"src/gflags_completions.cc",
+ #"src/gflags_reporting.cc",
+ ])
diff --git a/src/third_party/gflags-2.0/aclocal.m4 b/src/third_party/gflags-2.0/aclocal.m4
new file mode 100755
index 00000000000..f2af944e1b2
--- /dev/null
+++ b/src/third_party/gflags-2.0/aclocal.m4
@@ -0,0 +1,890 @@
+# generated automatically by aclocal 1.10.1 -*- Autoconf -*-
+
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
+# 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+m4_ifndef([AC_AUTOCONF_VERSION],
+ [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
+m4_if(AC_AUTOCONF_VERSION, [2.62],,
+[m4_warning([this file was generated for autoconf 2.62.
+You have another version of autoconf. It may work, but is not guaranteed to.
+If you have problems, you may need to regenerate the build system entirely.
+To do so, use the procedure documented by the package, typically `autoreconf'.])])
+
+# Copyright (C) 2002, 2003, 2005, 2006, 2007 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_AUTOMAKE_VERSION(VERSION)
+# ----------------------------
+# Automake X.Y traces this macro to ensure aclocal.m4 has been
+# generated from the m4 files accompanying Automake X.Y.
+# (This private macro should not be called outside this file.)
+AC_DEFUN([AM_AUTOMAKE_VERSION],
+[am__api_version='1.10'
+dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to
+dnl require some minimum version. Point them to the right macro.
+m4_if([$1], [1.10.1], [],
+ [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl
+])
+
+# _AM_AUTOCONF_VERSION(VERSION)
+# -----------------------------
+# aclocal traces this macro to find the Autoconf version.
+# This is a private macro too. Using m4_define simplifies
+# the logic in aclocal, which can simply ignore this definition.
+m4_define([_AM_AUTOCONF_VERSION], [])
+
+# AM_SET_CURRENT_AUTOMAKE_VERSION
+# -------------------------------
+# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced.
+# This function is AC_REQUIREd by AC_INIT_AUTOMAKE.
+AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
+[AM_AUTOMAKE_VERSION([1.10.1])dnl
+m4_ifndef([AC_AUTOCONF_VERSION],
+ [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
+_AM_AUTOCONF_VERSION(AC_AUTOCONF_VERSION)])
+
+# AM_AUX_DIR_EXPAND -*- Autoconf -*-
+
+# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets
+# $ac_aux_dir to `$srcdir/foo'. In other projects, it is set to
+# `$srcdir', `$srcdir/..', or `$srcdir/../..'.
+#
+# Of course, Automake must honor this variable whenever it calls a
+# tool from the auxiliary directory. The problem is that $srcdir (and
+# therefore $ac_aux_dir as well) can be either absolute or relative,
+# depending on how configure is run. This is pretty annoying, since
+# it makes $ac_aux_dir quite unusable in subdirectories: in the top
+# source directory, any form will work fine, but in subdirectories a
+# relative path needs to be adjusted first.
+#
+# $ac_aux_dir/missing
+# fails when called from a subdirectory if $ac_aux_dir is relative
+# $top_srcdir/$ac_aux_dir/missing
+# fails if $ac_aux_dir is absolute,
+# fails when called from a subdirectory in a VPATH build with
+# a relative $ac_aux_dir
+#
+# The reason of the latter failure is that $top_srcdir and $ac_aux_dir
+# are both prefixed by $srcdir. In an in-source build this is usually
+# harmless because $srcdir is `.', but things will broke when you
+# start a VPATH build or use an absolute $srcdir.
+#
+# So we could use something similar to $top_srcdir/$ac_aux_dir/missing,
+# iff we strip the leading $srcdir from $ac_aux_dir. That would be:
+# am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"`
+# and then we would define $MISSING as
+# MISSING="\${SHELL} $am_aux_dir/missing"
+# This will work as long as MISSING is not called from configure, because
+# unfortunately $(top_srcdir) has no meaning in configure.
+# However there are other variables, like CC, which are often used in
+# configure, and could therefore not use this "fixed" $ac_aux_dir.
+#
+# Another solution, used here, is to always expand $ac_aux_dir to an
+# absolute PATH. The drawback is that using absolute paths prevent a
+# configured tree to be moved without reconfiguration.
+
+AC_DEFUN([AM_AUX_DIR_EXPAND],
+[dnl Rely on autoconf to set up CDPATH properly.
+AC_PREREQ([2.50])dnl
+# expand $ac_aux_dir to an absolute path
+am_aux_dir=`cd $ac_aux_dir && pwd`
+])
+
+# AM_CONDITIONAL -*- Autoconf -*-
+
+# Copyright (C) 1997, 2000, 2001, 2003, 2004, 2005, 2006
+# Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 8
+
+# AM_CONDITIONAL(NAME, SHELL-CONDITION)
+# -------------------------------------
+# Define a conditional.
+AC_DEFUN([AM_CONDITIONAL],
+[AC_PREREQ(2.52)dnl
+ ifelse([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])],
+ [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl
+AC_SUBST([$1_TRUE])dnl
+AC_SUBST([$1_FALSE])dnl
+_AM_SUBST_NOTMAKE([$1_TRUE])dnl
+_AM_SUBST_NOTMAKE([$1_FALSE])dnl
+if $2; then
+ $1_TRUE=
+ $1_FALSE='#'
+else
+ $1_TRUE='#'
+ $1_FALSE=
+fi
+AC_CONFIG_COMMANDS_PRE(
+[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then
+ AC_MSG_ERROR([[conditional "$1" was never defined.
+Usually this means the macro was only invoked conditionally.]])
+fi])])
+
+# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
+# Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 9
+
+# There are a few dirty hacks below to avoid letting `AC_PROG_CC' be
+# written in clear, in which case automake, when reading aclocal.m4,
+# will think it sees a *use*, and therefore will trigger all it's
+# C support machinery. Also note that it means that autoscan, seeing
+# CC etc. in the Makefile, will ask for an AC_PROG_CC use...
+
+
+# _AM_DEPENDENCIES(NAME)
+# ----------------------
+# See how the compiler implements dependency checking.
+# NAME is "CC", "CXX", "GCJ", or "OBJC".
+# We try a few techniques and use that to set a single cache variable.
+#
+# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was
+# modified to invoke _AM_DEPENDENCIES(CC); we would have a circular
+# dependency, and given that the user is not expected to run this macro,
+# just rely on AC_PROG_CC.
+AC_DEFUN([_AM_DEPENDENCIES],
+[AC_REQUIRE([AM_SET_DEPDIR])dnl
+AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl
+AC_REQUIRE([AM_MAKE_INCLUDE])dnl
+AC_REQUIRE([AM_DEP_TRACK])dnl
+
+ifelse([$1], CC, [depcc="$CC" am_compiler_list=],
+ [$1], CXX, [depcc="$CXX" am_compiler_list=],
+ [$1], OBJC, [depcc="$OBJC" am_compiler_list='gcc3 gcc'],
+ [$1], UPC, [depcc="$UPC" am_compiler_list=],
+ [$1], GCJ, [depcc="$GCJ" am_compiler_list='gcc3 gcc'],
+ [depcc="$$1" am_compiler_list=])
+
+AC_CACHE_CHECK([dependency style of $depcc],
+ [am_cv_$1_dependencies_compiler_type],
+[if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then
+ # We make a subdir and do the tests there. Otherwise we can end up
+ # making bogus files that we don't know about and never remove. For
+ # instance it was reported that on HP-UX the gcc test will end up
+ # making a dummy file named `D' -- because `-MD' means `put the output
+ # in D'.
+ mkdir conftest.dir
+ # Copy depcomp to subdir because otherwise we won't find it if we're
+ # using a relative directory.
+ cp "$am_depcomp" conftest.dir
+ cd conftest.dir
+ # We will build objects and dependencies in a subdirectory because
+ # it helps to detect inapplicable dependency modes. For instance
+ # both Tru64's cc and ICC support -MD to output dependencies as a
+ # side effect of compilation, but ICC will put the dependencies in
+ # the current directory while Tru64 will put them in the object
+ # directory.
+ mkdir sub
+
+ am_cv_$1_dependencies_compiler_type=none
+ if test "$am_compiler_list" = ""; then
+ am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp`
+ fi
+ for depmode in $am_compiler_list; do
+ # Setup a source with many dependencies, because some compilers
+ # like to wrap large dependency lists on column 80 (with \), and
+ # we should not choose a depcomp mode which is confused by this.
+ #
+ # We need to recreate these files for each test, as the compiler may
+ # overwrite some of them when testing with obscure command lines.
+ # This happens at least with the AIX C compiler.
+ : > sub/conftest.c
+ for i in 1 2 3 4 5 6; do
+ echo '#include "conftst'$i'.h"' >> sub/conftest.c
+ # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with
+ # Solaris 8's {/usr,}/bin/sh.
+ touch sub/conftst$i.h
+ done
+ echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
+
+ case $depmode in
+ nosideeffect)
+ # after this tag, mechanisms are not by side-effect, so they'll
+ # only be used when explicitly requested
+ if test "x$enable_dependency_tracking" = xyes; then
+ continue
+ else
+ break
+ fi
+ ;;
+ none) break ;;
+ esac
+ # We check with `-c' and `-o' for the sake of the "dashmstdout"
+ # mode. It turns out that the SunPro C++ compiler does not properly
+ # handle `-M -o', and we need to detect this.
+ if depmode=$depmode \
+ source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \
+ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \
+ $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c \
+ >/dev/null 2>conftest.err &&
+ grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 &&
+ grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 &&
+ grep sub/conftest.${OBJEXT-o} sub/conftest.Po > /dev/null 2>&1 &&
+ ${MAKE-make} -s -f confmf > /dev/null 2>&1; then
+ # icc doesn't choke on unknown options, it will just issue warnings
+ # or remarks (even with -Werror). So we grep stderr for any message
+ # that says an option was ignored or not supported.
+ # When given -MP, icc 7.0 and 7.1 complain thusly:
+ # icc: Command line warning: ignoring option '-M'; no argument required
+ # The diagnosis changed in icc 8.0:
+ # icc: Command line remark: option '-MP' not supported
+ if (grep 'ignoring option' conftest.err ||
+ grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else
+ am_cv_$1_dependencies_compiler_type=$depmode
+ break
+ fi
+ fi
+ done
+
+ cd ..
+ rm -rf conftest.dir
+else
+ am_cv_$1_dependencies_compiler_type=none
+fi
+])
+AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type])
+AM_CONDITIONAL([am__fastdep$1], [
+ test "x$enable_dependency_tracking" != xno \
+ && test "$am_cv_$1_dependencies_compiler_type" = gcc3])
+])
+
+
+# AM_SET_DEPDIR
+# -------------
+# Choose a directory name for dependency files.
+# This macro is AC_REQUIREd in _AM_DEPENDENCIES
+AC_DEFUN([AM_SET_DEPDIR],
+[AC_REQUIRE([AM_SET_LEADING_DOT])dnl
+AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl
+])
+
+
+# AM_DEP_TRACK
+# ------------
+AC_DEFUN([AM_DEP_TRACK],
+[AC_ARG_ENABLE(dependency-tracking,
+[ --disable-dependency-tracking speeds up one-time build
+ --enable-dependency-tracking do not reject slow dependency extractors])
+if test "x$enable_dependency_tracking" != xno; then
+ am_depcomp="$ac_aux_dir/depcomp"
+ AMDEPBACKSLASH='\'
+fi
+AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno])
+AC_SUBST([AMDEPBACKSLASH])dnl
+_AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl
+])
+
+# Generate code to set up dependency tracking. -*- Autoconf -*-
+
+# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
+# Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+#serial 3
+
+# _AM_OUTPUT_DEPENDENCY_COMMANDS
+# ------------------------------
+AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS],
+[for mf in $CONFIG_FILES; do
+ # Strip MF so we end up with the name of the file.
+ mf=`echo "$mf" | sed -e 's/:.*$//'`
+ # Check whether this is an Automake generated Makefile or not.
+ # We used to match only the files named `Makefile.in', but
+ # some people rename them; so instead we look at the file content.
+ # Grep'ing the first line is not enough: some people post-process
+ # each Makefile.in and add a new line on top of each file to say so.
+ # Grep'ing the whole file is not good either: AIX grep has a line
+ # limit of 2048, but all sed's we know have understand at least 4000.
+ if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then
+ dirpart=`AS_DIRNAME("$mf")`
+ else
+ continue
+ fi
+ # Extract the definition of DEPDIR, am__include, and am__quote
+ # from the Makefile without running `make'.
+ DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"`
+ test -z "$DEPDIR" && continue
+ am__include=`sed -n 's/^am__include = //p' < "$mf"`
+ test -z "am__include" && continue
+ am__quote=`sed -n 's/^am__quote = //p' < "$mf"`
+ # When using ansi2knr, U may be empty or an underscore; expand it
+ U=`sed -n 's/^U = //p' < "$mf"`
+ # Find all dependency output files, they are included files with
+ # $(DEPDIR) in their names. We invoke sed twice because it is the
+ # simplest approach to changing $(DEPDIR) to its actual value in the
+ # expansion.
+ for file in `sed -n "
+ s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \
+ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do
+ # Make sure the directory exists.
+ test -f "$dirpart/$file" && continue
+ fdir=`AS_DIRNAME(["$file"])`
+ AS_MKDIR_P([$dirpart/$fdir])
+ # echo "creating $dirpart/$file"
+ echo '# dummy' > "$dirpart/$file"
+ done
+done
+])# _AM_OUTPUT_DEPENDENCY_COMMANDS
+
+
+# AM_OUTPUT_DEPENDENCY_COMMANDS
+# -----------------------------
+# This macro should only be invoked once -- use via AC_REQUIRE.
+#
+# This code is only required when automatic dependency tracking
+# is enabled. FIXME. This creates each `.P' file that we will
+# need in order to bootstrap the dependency handling code.
+AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS],
+[AC_CONFIG_COMMANDS([depfiles],
+ [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS],
+ [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"])
+])
+
+# Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005
+# Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 8
+
+# AM_CONFIG_HEADER is obsolete. It has been replaced by AC_CONFIG_HEADERS.
+AU_DEFUN([AM_CONFIG_HEADER], [AC_CONFIG_HEADERS($@)])
+
+# Do all the work for Automake. -*- Autoconf -*-
+
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
+# 2005, 2006, 2008 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 13
+
+# This macro actually does too much. Some checks are only needed if
+# your package does certain things. But this isn't really a big deal.
+
+# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE])
+# AM_INIT_AUTOMAKE([OPTIONS])
+# -----------------------------------------------
+# The call with PACKAGE and VERSION arguments is the old style
+# call (pre autoconf-2.50), which is being phased out. PACKAGE
+# and VERSION should now be passed to AC_INIT and removed from
+# the call to AM_INIT_AUTOMAKE.
+# We support both call styles for the transition. After
+# the next Automake release, Autoconf can make the AC_INIT
+# arguments mandatory, and then we can depend on a new Autoconf
+# release and drop the old call support.
+AC_DEFUN([AM_INIT_AUTOMAKE],
+[AC_PREREQ([2.60])dnl
+dnl Autoconf wants to disallow AM_ names. We explicitly allow
+dnl the ones we care about.
+m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl
+AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl
+AC_REQUIRE([AC_PROG_INSTALL])dnl
+if test "`cd $srcdir && pwd`" != "`pwd`"; then
+ # Use -I$(srcdir) only when $(srcdir) != ., so that make's output
+ # is not polluted with repeated "-I."
+ AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl
+ # test to see if srcdir already configured
+ if test -f $srcdir/config.status; then
+ AC_MSG_ERROR([source directory already configured; run "make distclean" there first])
+ fi
+fi
+
+# test whether we have cygpath
+if test -z "$CYGPATH_W"; then
+ if (cygpath --version) >/dev/null 2>/dev/null; then
+ CYGPATH_W='cygpath -w'
+ else
+ CYGPATH_W=echo
+ fi
+fi
+AC_SUBST([CYGPATH_W])
+
+# Define the identity of the package.
+dnl Distinguish between old-style and new-style calls.
+m4_ifval([$2],
+[m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl
+ AC_SUBST([PACKAGE], [$1])dnl
+ AC_SUBST([VERSION], [$2])],
+[_AM_SET_OPTIONS([$1])dnl
+dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT.
+m4_if(m4_ifdef([AC_PACKAGE_NAME], 1)m4_ifdef([AC_PACKAGE_VERSION], 1), 11,,
+ [m4_fatal([AC_INIT should be called with package and version arguments])])dnl
+ AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl
+ AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl
+
+_AM_IF_OPTION([no-define],,
+[AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package])
+ AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])])dnl
+
+# Some tools Automake needs.
+AC_REQUIRE([AM_SANITY_CHECK])dnl
+AC_REQUIRE([AC_ARG_PROGRAM])dnl
+AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version})
+AM_MISSING_PROG(AUTOCONF, autoconf)
+AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version})
+AM_MISSING_PROG(AUTOHEADER, autoheader)
+AM_MISSING_PROG(MAKEINFO, makeinfo)
+AM_PROG_INSTALL_SH
+AM_PROG_INSTALL_STRIP
+AC_REQUIRE([AM_PROG_MKDIR_P])dnl
+# We need awk for the "check" target. The system "awk" is bad on
+# some platforms.
+AC_REQUIRE([AC_PROG_AWK])dnl
+AC_REQUIRE([AC_PROG_MAKE_SET])dnl
+AC_REQUIRE([AM_SET_LEADING_DOT])dnl
+_AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])],
+ [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])],
+ [_AM_PROG_TAR([v7])])])
+_AM_IF_OPTION([no-dependencies],,
+[AC_PROVIDE_IFELSE([AC_PROG_CC],
+ [_AM_DEPENDENCIES(CC)],
+ [define([AC_PROG_CC],
+ defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl
+AC_PROVIDE_IFELSE([AC_PROG_CXX],
+ [_AM_DEPENDENCIES(CXX)],
+ [define([AC_PROG_CXX],
+ defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl
+AC_PROVIDE_IFELSE([AC_PROG_OBJC],
+ [_AM_DEPENDENCIES(OBJC)],
+ [define([AC_PROG_OBJC],
+ defn([AC_PROG_OBJC])[_AM_DEPENDENCIES(OBJC)])])dnl
+])
+])
+
+
+# When config.status generates a header, we must update the stamp-h file.
+# This file resides in the same directory as the config header
+# that is generated. The stamp files are numbered to have different names.
+
+# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the
+# loop where config.status creates the headers, so we can generate
+# our stamp files there.
+AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK],
+[# Compute $1's index in $config_headers.
+_am_arg=$1
+_am_stamp_count=1
+for _am_header in $config_headers :; do
+ case $_am_header in
+ $_am_arg | $_am_arg:* )
+ break ;;
+ * )
+ _am_stamp_count=`expr $_am_stamp_count + 1` ;;
+ esac
+done
+echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count])
+
+# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_PROG_INSTALL_SH
+# ------------------
+# Define $install_sh.
+AC_DEFUN([AM_PROG_INSTALL_SH],
+[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
+install_sh=${install_sh-"\$(SHELL) $am_aux_dir/install-sh"}
+AC_SUBST(install_sh)])
+
+# Copyright (C) 2003, 2005 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 2
+
+# Check whether the underlying file-system supports filenames
+# with a leading dot. For instance MS-DOS doesn't.
+AC_DEFUN([AM_SET_LEADING_DOT],
+[rm -rf .tst 2>/dev/null
+mkdir .tst 2>/dev/null
+if test -d .tst; then
+ am__leading_dot=.
+else
+ am__leading_dot=_
+fi
+rmdir .tst 2>/dev/null
+AC_SUBST([am__leading_dot])])
+
+# Check to see how 'make' treats includes. -*- Autoconf -*-
+
+# Copyright (C) 2001, 2002, 2003, 2005 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 3
+
+# AM_MAKE_INCLUDE()
+# -----------------
+# Check to see how make treats includes.
+AC_DEFUN([AM_MAKE_INCLUDE],
+[am_make=${MAKE-make}
+cat > confinc << 'END'
+am__doit:
+ @echo done
+.PHONY: am__doit
+END
+# If we don't find an include directive, just comment out the code.
+AC_MSG_CHECKING([for style of include used by $am_make])
+am__include="#"
+am__quote=
+_am_result=none
+# First try GNU make style include.
+echo "include confinc" > confmf
+# We grep out `Entering directory' and `Leaving directory'
+# messages which can occur if `w' ends up in MAKEFLAGS.
+# In particular we don't look at `^make:' because GNU make might
+# be invoked under some other name (usually "gmake"), in which
+# case it prints its new name instead of `make'.
+if test "`$am_make -s -f confmf 2> /dev/null | grep -v 'ing directory'`" = "done"; then
+ am__include=include
+ am__quote=
+ _am_result=GNU
+fi
+# Now try BSD make style include.
+if test "$am__include" = "#"; then
+ echo '.include "confinc"' > confmf
+ if test "`$am_make -s -f confmf 2> /dev/null`" = "done"; then
+ am__include=.include
+ am__quote="\""
+ _am_result=BSD
+ fi
+fi
+AC_SUBST([am__include])
+AC_SUBST([am__quote])
+AC_MSG_RESULT([$_am_result])
+rm -f confinc confmf
+])
+
+# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*-
+
+# Copyright (C) 1997, 1999, 2000, 2001, 2003, 2004, 2005
+# Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 5
+
+# AM_MISSING_PROG(NAME, PROGRAM)
+# ------------------------------
+AC_DEFUN([AM_MISSING_PROG],
+[AC_REQUIRE([AM_MISSING_HAS_RUN])
+$1=${$1-"${am_missing_run}$2"}
+AC_SUBST($1)])
+
+
+# AM_MISSING_HAS_RUN
+# ------------------
+# Define MISSING if not defined so far and test if it supports --run.
+# If it does, set am_missing_run to use it, otherwise, to nothing.
+AC_DEFUN([AM_MISSING_HAS_RUN],
+[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
+AC_REQUIRE_AUX_FILE([missing])dnl
+test x"${MISSING+set}" = xset || MISSING="\${SHELL} $am_aux_dir/missing"
+# Use eval to expand $SHELL
+if eval "$MISSING --run true"; then
+ am_missing_run="$MISSING --run "
+else
+ am_missing_run=
+ AC_MSG_WARN([`missing' script is too old or missing])
+fi
+])
+
+# Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_PROG_MKDIR_P
+# ---------------
+# Check for `mkdir -p'.
+AC_DEFUN([AM_PROG_MKDIR_P],
+[AC_PREREQ([2.60])dnl
+AC_REQUIRE([AC_PROG_MKDIR_P])dnl
+dnl Automake 1.8 to 1.9.6 used to define mkdir_p. We now use MKDIR_P,
+dnl while keeping a definition of mkdir_p for backward compatibility.
+dnl @MKDIR_P@ is magic: AC_OUTPUT adjusts its value for each Makefile.
+dnl However we cannot define mkdir_p as $(MKDIR_P) for the sake of
+dnl Makefile.ins that do not define MKDIR_P, so we do our own
+dnl adjustment using top_builddir (which is defined more often than
+dnl MKDIR_P).
+AC_SUBST([mkdir_p], ["$MKDIR_P"])dnl
+case $mkdir_p in
+ [[\\/$]]* | ?:[[\\/]]*) ;;
+ */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;;
+esac
+])
+
+# Helper functions for option handling. -*- Autoconf -*-
+
+# Copyright (C) 2001, 2002, 2003, 2005 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 3
+
+# _AM_MANGLE_OPTION(NAME)
+# -----------------------
+AC_DEFUN([_AM_MANGLE_OPTION],
+[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])])
+
+# _AM_SET_OPTION(NAME)
+# ------------------------------
+# Set option NAME. Presently that only means defining a flag for this option.
+AC_DEFUN([_AM_SET_OPTION],
+[m4_define(_AM_MANGLE_OPTION([$1]), 1)])
+
+# _AM_SET_OPTIONS(OPTIONS)
+# ----------------------------------
+# OPTIONS is a space-separated list of Automake options.
+AC_DEFUN([_AM_SET_OPTIONS],
+[AC_FOREACH([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])])
+
+# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET])
+# -------------------------------------------
+# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise.
+AC_DEFUN([_AM_IF_OPTION],
+[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])])
+
+# Check to make sure that the build environment is sane. -*- Autoconf -*-
+
+# Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005
+# Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 4
+
+# AM_SANITY_CHECK
+# ---------------
+AC_DEFUN([AM_SANITY_CHECK],
+[AC_MSG_CHECKING([whether build environment is sane])
+# Just in case
+sleep 1
+echo timestamp > conftest.file
+# Do `set' in a subshell so we don't clobber the current shell's
+# arguments. Must try -L first in case configure is actually a
+# symlink; some systems play weird games with the mod time of symlinks
+# (eg FreeBSD returns the mod time of the symlink's containing
+# directory).
+if (
+ set X `ls -Lt $srcdir/configure conftest.file 2> /dev/null`
+ if test "$[*]" = "X"; then
+ # -L didn't work.
+ set X `ls -t $srcdir/configure conftest.file`
+ fi
+ rm -f conftest.file
+ if test "$[*]" != "X $srcdir/configure conftest.file" \
+ && test "$[*]" != "X conftest.file $srcdir/configure"; then
+
+ # If neither matched, then we have a broken ls. This can happen
+ # if, for instance, CONFIG_SHELL is bash and it inherits a
+ # broken ls alias from the environment. This has actually
+ # happened. Such a system could not be considered "sane".
+ AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken
+alias in your environment])
+ fi
+
+ test "$[2]" = conftest.file
+ )
+then
+ # Ok.
+ :
+else
+ AC_MSG_ERROR([newly created file is older than distributed files!
+Check your system clock])
+fi
+AC_MSG_RESULT(yes)])
+
+# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_PROG_INSTALL_STRIP
+# ---------------------
+# One issue with vendor `install' (even GNU) is that you can't
+# specify the program used to strip binaries. This is especially
+# annoying in cross-compiling environments, where the build's strip
+# is unlikely to handle the host's binaries.
+# Fortunately install-sh will honor a STRIPPROG variable, so we
+# always use install-sh in `make install-strip', and initialize
+# STRIPPROG with the value of the STRIP variable (set by the user).
+AC_DEFUN([AM_PROG_INSTALL_STRIP],
+[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl
+# Installed binaries are usually stripped using `strip' when the user
+# run `make install-strip'. However `strip' might not be the right
+# tool to use in cross-compilation environments, therefore Automake
+# will honor the `STRIP' environment variable to overrule this program.
+dnl Don't test for $cross_compiling = yes, because it might be `maybe'.
+if test "$cross_compiling" != no; then
+ AC_CHECK_TOOL([STRIP], [strip], :)
+fi
+INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s"
+AC_SUBST([INSTALL_STRIP_PROGRAM])])
+
+# Copyright (C) 2006 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# _AM_SUBST_NOTMAKE(VARIABLE)
+# ---------------------------
+# Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in.
+# This macro is traced by Automake.
+AC_DEFUN([_AM_SUBST_NOTMAKE])
+
+# Check how to create a tarball. -*- Autoconf -*-
+
+# Copyright (C) 2004, 2005 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 2
+
+# _AM_PROG_TAR(FORMAT)
+# --------------------
+# Check how to create a tarball in format FORMAT.
+# FORMAT should be one of `v7', `ustar', or `pax'.
+#
+# Substitute a variable $(am__tar) that is a command
+# writing to stdout a FORMAT-tarball containing the directory
+# $tardir.
+# tardir=directory && $(am__tar) > result.tar
+#
+# Substitute a variable $(am__untar) that extract such
+# a tarball read from stdin.
+# $(am__untar) < result.tar
+AC_DEFUN([_AM_PROG_TAR],
+[# Always define AMTAR for backward compatibility.
+AM_MISSING_PROG([AMTAR], [tar])
+m4_if([$1], [v7],
+ [am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'],
+ [m4_case([$1], [ustar],, [pax],,
+ [m4_fatal([Unknown tar format])])
+AC_MSG_CHECKING([how to create a $1 tar archive])
+# Loop over all known methods to create a tar archive until one works.
+_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none'
+_am_tools=${am_cv_prog_tar_$1-$_am_tools}
+# Do not fold the above two line into one, because Tru64 sh and
+# Solaris sh will not grok spaces in the rhs of `-'.
+for _am_tool in $_am_tools
+do
+ case $_am_tool in
+ gnutar)
+ for _am_tar in tar gnutar gtar;
+ do
+ AM_RUN_LOG([$_am_tar --version]) && break
+ done
+ am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"'
+ am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"'
+ am__untar="$_am_tar -xf -"
+ ;;
+ plaintar)
+ # Must skip GNU tar: if it does not support --format= it doesn't create
+ # ustar tarball either.
+ (tar --version) >/dev/null 2>&1 && continue
+ am__tar='tar chf - "$$tardir"'
+ am__tar_='tar chf - "$tardir"'
+ am__untar='tar xf -'
+ ;;
+ pax)
+ am__tar='pax -L -x $1 -w "$$tardir"'
+ am__tar_='pax -L -x $1 -w "$tardir"'
+ am__untar='pax -r'
+ ;;
+ cpio)
+ am__tar='find "$$tardir" -print | cpio -o -H $1 -L'
+ am__tar_='find "$tardir" -print | cpio -o -H $1 -L'
+ am__untar='cpio -i -H $1 -d'
+ ;;
+ none)
+ am__tar=false
+ am__tar_=false
+ am__untar=false
+ ;;
+ esac
+
+ # If the value was cached, stop now. We just wanted to have am__tar
+ # and am__untar set.
+ test -n "${am_cv_prog_tar_$1}" && break
+
+ # tar/untar a dummy directory, and stop if the command works
+ rm -rf conftest.dir
+ mkdir conftest.dir
+ echo GrepMe > conftest.dir/file
+ AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar])
+ rm -rf conftest.dir
+ if test -s conftest.tar; then
+ AM_RUN_LOG([$am__untar <conftest.tar])
+ grep GrepMe conftest.dir/file >/dev/null 2>&1 && break
+ fi
+done
+rm -rf conftest.dir
+
+AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool])
+AC_MSG_RESULT([$am_cv_prog_tar_$1])])
+AC_SUBST([am__tar])
+AC_SUBST([am__untar])
+]) # _AM_PROG_TAR
+
+m4_include([m4/ac_have_attribute.m4])
+m4_include([m4/acx_pthread.m4])
+m4_include([m4/google_namespace.m4])
+m4_include([m4/libtool.m4])
+m4_include([m4/ltoptions.m4])
+m4_include([m4/ltsugar.m4])
+m4_include([m4/ltversion.m4])
+m4_include([m4/lt~obsolete.m4])
+m4_include([m4/namespaces.m4])
+m4_include([m4/stl_namespace.m4])
diff --git a/src/third_party/gflags-2.0/autogen.sh b/src/third_party/gflags-2.0/autogen.sh
new file mode 100755
index 00000000000..3268bc94de8
--- /dev/null
+++ b/src/third_party/gflags-2.0/autogen.sh
@@ -0,0 +1,29 @@
+#!/bin/sh
+
+# Before using, you should figure out all the .m4 macros that your
+# configure.m4 script needs and make sure they exist in the m4/
+# directory.
+#
+# These are the files that this script might edit:
+# aclocal.m4 configure Makefile.in src/config.h.in \
+# depcomp config.guess config.sub install-sh missing mkinstalldirs \
+#
+# Here's a command you can run to see what files aclocal will import:
+# aclocal -I ../autoconf --output=- | sed -n 's/^m4_include..\([^]]*\).*/\1/p'
+
+# Because libtoolize isn't in the hermetic build, autogen doesn't run it.
+# However, it should be run manually periodically to update these files:
+# in .: ltmain.sh
+# in m4: libtool.m4 ltoptions.m4 ltsugar.m4 ltversion.m4 lt~obsolete.m4
+
+set -ex
+rm -rf autom4te.cache
+
+aclocal --force -I m4
+#grep -q LIBTOOL configure.ac && libtoolize -c -f
+autoconf -f -W all,no-obsolete
+autoheader -f -W all
+automake -a -c -f -W all
+
+rm -rf autom4te.cache
+exit 0
diff --git a/src/third_party/gflags-2.0/config.guess b/src/third_party/gflags-2.0/config.guess
new file mode 100755
index 00000000000..ca2a03ca4f1
--- /dev/null
+++ b/src/third_party/gflags-2.0/config.guess
@@ -0,0 +1,1526 @@
+#! /bin/sh
+# Attempt to guess a canonical system name.
+# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
+# Free Software Foundation, Inc.
+
+timestamp='2008-01-08'
+
+# This file is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
+# 02110-1301, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+
+# Originally written by Per Bothner <per@bothner.com>.
+# Please send patches to <config-patches@gnu.org>. Submit a context
+# diff and a properly formatted ChangeLog entry.
+#
+# This script attempts to guess a canonical system name similar to
+# config.sub. If it succeeds, it prints the system name on stdout, and
+# exits with 0. Otherwise, it exits with 1.
+#
+# The plan is that this can be called by configure scripts if you
+# don't specify an explicit build system type.
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION]
+
+Output the configuration name of the system \`$me' is run on.
+
+Operation modes:
+ -h, --help print this help, then exit
+ -t, --time-stamp print date of last modification, then exit
+ -v, --version print version number, then exit
+
+Report bugs and patches to <config-patches@gnu.org>."
+
+version="\
+GNU config.guess ($timestamp)
+
+Originally written by Per Bothner.
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
+2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+
+This is free software; see the source for copying conditions. There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+
+help="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+ case $1 in
+ --time-stamp | --time* | -t )
+ echo "$timestamp" ; exit ;;
+ --version | -v )
+ echo "$version" ; exit ;;
+ --help | --h* | -h )
+ echo "$usage"; exit ;;
+ -- ) # Stop option processing
+ shift; break ;;
+ - ) # Use stdin as input.
+ break ;;
+ -* )
+ echo "$me: invalid option $1$help" >&2
+ exit 1 ;;
+ * )
+ break ;;
+ esac
+done
+
+if test $# != 0; then
+ echo "$me: too many arguments$help" >&2
+ exit 1
+fi
+
+trap 'exit 1' 1 2 15
+
+# CC_FOR_BUILD -- compiler used by this script. Note that the use of a
+# compiler to aid in system detection is discouraged as it requires
+# temporary files to be created and, as you can see below, it is a
+# headache to deal with in a portable fashion.
+
+# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still
+# use `HOST_CC' if defined, but it is deprecated.
+
+# Portable tmp directory creation inspired by the Autoconf team.
+
+set_cc_for_build='
+trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ;
+trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ;
+: ${TMPDIR=/tmp} ;
+ { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } ||
+ { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } ||
+ { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } ||
+ { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ;
+dummy=$tmp/dummy ;
+tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ;
+case $CC_FOR_BUILD,$HOST_CC,$CC in
+ ,,) echo "int x;" > $dummy.c ;
+ for c in cc gcc c89 c99 ; do
+ if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then
+ CC_FOR_BUILD="$c"; break ;
+ fi ;
+ done ;
+ if test x"$CC_FOR_BUILD" = x ; then
+ CC_FOR_BUILD=no_compiler_found ;
+ fi
+ ;;
+ ,,*) CC_FOR_BUILD=$CC ;;
+ ,*,*) CC_FOR_BUILD=$HOST_CC ;;
+esac ; set_cc_for_build= ;'
+
+# This is needed to find uname on a Pyramid OSx when run in the BSD universe.
+# (ghazi@noc.rutgers.edu 1994-08-24)
+if (test -f /.attbin/uname) >/dev/null 2>&1 ; then
+ PATH=$PATH:/.attbin ; export PATH
+fi
+
+UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown
+UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
+UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown
+UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
+
+# Note: order is significant - the case branches are not exclusive.
+
+case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
+ *:NetBSD:*:*)
+ # NetBSD (nbsd) targets should (where applicable) match one or
+ # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*,
+ # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently
+ # switched to ELF, *-*-netbsd* would select the old
+ # object file format. This provides both forward
+ # compatibility and a consistent mechanism for selecting the
+ # object file format.
+ #
+ # Note: NetBSD doesn't particularly care about the vendor
+ # portion of the name. We always set it to "unknown".
+ sysctl="sysctl -n hw.machine_arch"
+ UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \
+ /usr/sbin/$sysctl 2>/dev/null || echo unknown)`
+ case "${UNAME_MACHINE_ARCH}" in
+ armeb) machine=armeb-unknown ;;
+ arm*) machine=arm-unknown ;;
+ sh3el) machine=shl-unknown ;;
+ sh3eb) machine=sh-unknown ;;
+ sh5el) machine=sh5le-unknown ;;
+ *) machine=${UNAME_MACHINE_ARCH}-unknown ;;
+ esac
+ # The Operating System including object format, if it has switched
+ # to ELF recently, or will in the future.
+ case "${UNAME_MACHINE_ARCH}" in
+ arm*|i386|m68k|ns32k|sh3*|sparc|vax)
+ eval $set_cc_for_build
+ if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
+ | grep __ELF__ >/dev/null
+ then
+ # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout).
+ # Return netbsd for either. FIX?
+ os=netbsd
+ else
+ os=netbsdelf
+ fi
+ ;;
+ *)
+ os=netbsd
+ ;;
+ esac
+ # The OS release
+ # Debian GNU/NetBSD machines have a different userland, and
+ # thus, need a distinct triplet. However, they do not need
+ # kernel version information, so it can be replaced with a
+ # suitable tag, in the style of linux-gnu.
+ case "${UNAME_VERSION}" in
+ Debian*)
+ release='-gnu'
+ ;;
+ *)
+ release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
+ ;;
+ esac
+ # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:
+ # contains redundant information, the shorter form:
+ # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
+ echo "${machine}-${os}${release}"
+ exit ;;
+ *:OpenBSD:*:*)
+ UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'`
+ echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE}
+ exit ;;
+ *:ekkoBSD:*:*)
+ echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE}
+ exit ;;
+ *:SolidBSD:*:*)
+ echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE}
+ exit ;;
+ macppc:MirBSD:*:*)
+ echo powerpc-unknown-mirbsd${UNAME_RELEASE}
+ exit ;;
+ *:MirBSD:*:*)
+ echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE}
+ exit ;;
+ alpha:OSF1:*:*)
+ case $UNAME_RELEASE in
+ *4.0)
+ UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
+ ;;
+ *5.*)
+ UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'`
+ ;;
+ esac
+ # According to Compaq, /usr/sbin/psrinfo has been available on
+ # OSF/1 and Tru64 systems produced since 1995. I hope that
+ # covers most systems running today. This code pipes the CPU
+ # types through head -n 1, so we only detect the type of CPU 0.
+ ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1`
+ case "$ALPHA_CPU_TYPE" in
+ "EV4 (21064)")
+ UNAME_MACHINE="alpha" ;;
+ "EV4.5 (21064)")
+ UNAME_MACHINE="alpha" ;;
+ "LCA4 (21066/21068)")
+ UNAME_MACHINE="alpha" ;;
+ "EV5 (21164)")
+ UNAME_MACHINE="alphaev5" ;;
+ "EV5.6 (21164A)")
+ UNAME_MACHINE="alphaev56" ;;
+ "EV5.6 (21164PC)")
+ UNAME_MACHINE="alphapca56" ;;
+ "EV5.7 (21164PC)")
+ UNAME_MACHINE="alphapca57" ;;
+ "EV6 (21264)")
+ UNAME_MACHINE="alphaev6" ;;
+ "EV6.7 (21264A)")
+ UNAME_MACHINE="alphaev67" ;;
+ "EV6.8CB (21264C)")
+ UNAME_MACHINE="alphaev68" ;;
+ "EV6.8AL (21264B)")
+ UNAME_MACHINE="alphaev68" ;;
+ "EV6.8CX (21264D)")
+ UNAME_MACHINE="alphaev68" ;;
+ "EV6.9A (21264/EV69A)")
+ UNAME_MACHINE="alphaev69" ;;
+ "EV7 (21364)")
+ UNAME_MACHINE="alphaev7" ;;
+ "EV7.9 (21364A)")
+ UNAME_MACHINE="alphaev79" ;;
+ esac
+ # A Pn.n version is a patched version.
+ # A Vn.n version is a released version.
+ # A Tn.n version is a released field test version.
+ # A Xn.n version is an unreleased experimental baselevel.
+ # 1.2 uses "1.2" for uname -r.
+ echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+ exit ;;
+ Alpha\ *:Windows_NT*:*)
+ # How do we know it's Interix rather than the generic POSIX subsystem?
+ # Should we change UNAME_MACHINE based on the output of uname instead
+ # of the specific Alpha model?
+ echo alpha-pc-interix
+ exit ;;
+ 21064:Windows_NT:50:3)
+ echo alpha-dec-winnt3.5
+ exit ;;
+ Amiga*:UNIX_System_V:4.0:*)
+ echo m68k-unknown-sysv4
+ exit ;;
+ *:[Aa]miga[Oo][Ss]:*:*)
+ echo ${UNAME_MACHINE}-unknown-amigaos
+ exit ;;
+ *:[Mm]orph[Oo][Ss]:*:*)
+ echo ${UNAME_MACHINE}-unknown-morphos
+ exit ;;
+ *:OS/390:*:*)
+ echo i370-ibm-openedition
+ exit ;;
+ *:z/VM:*:*)
+ echo s390-ibm-zvmoe
+ exit ;;
+ *:OS400:*:*)
+ echo powerpc-ibm-os400
+ exit ;;
+ arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
+ echo arm-acorn-riscix${UNAME_RELEASE}
+ exit ;;
+ arm:riscos:*:*|arm:RISCOS:*:*)
+ echo arm-unknown-riscos
+ exit ;;
+ SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*)
+ echo hppa1.1-hitachi-hiuxmpp
+ exit ;;
+ Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*)
+ # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE.
+ if test "`(/bin/universe) 2>/dev/null`" = att ; then
+ echo pyramid-pyramid-sysv3
+ else
+ echo pyramid-pyramid-bsd
+ fi
+ exit ;;
+ NILE*:*:*:dcosx)
+ echo pyramid-pyramid-svr4
+ exit ;;
+ DRS?6000:unix:4.0:6*)
+ echo sparc-icl-nx6
+ exit ;;
+ DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*)
+ case `/usr/bin/uname -p` in
+ sparc) echo sparc-icl-nx7; exit ;;
+ esac ;;
+ sun4H:SunOS:5.*:*)
+ echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit ;;
+ sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
+ echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit ;;
+ i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*)
+ echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit ;;
+ sun4*:SunOS:6*:*)
+ # According to config.sub, this is the proper way to canonicalize
+ # SunOS6. Hard to guess exactly what SunOS6 will be like, but
+ # it's likely to be more like Solaris than SunOS4.
+ echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit ;;
+ sun4*:SunOS:*:*)
+ case "`/usr/bin/arch -k`" in
+ Series*|S4*)
+ UNAME_RELEASE=`uname -v`
+ ;;
+ esac
+ # Japanese Language versions have a version number like `4.1.3-JL'.
+ echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'`
+ exit ;;
+ sun3*:SunOS:*:*)
+ echo m68k-sun-sunos${UNAME_RELEASE}
+ exit ;;
+ sun*:*:4.2BSD:*)
+ UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
+ test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3
+ case "`/bin/arch`" in
+ sun3)
+ echo m68k-sun-sunos${UNAME_RELEASE}
+ ;;
+ sun4)
+ echo sparc-sun-sunos${UNAME_RELEASE}
+ ;;
+ esac
+ exit ;;
+ aushp:SunOS:*:*)
+ echo sparc-auspex-sunos${UNAME_RELEASE}
+ exit ;;
+ # The situation for MiNT is a little confusing. The machine name
+ # can be virtually everything (everything which is not
+ # "atarist" or "atariste" at least should have a processor
+ # > m68000). The system name ranges from "MiNT" over "FreeMiNT"
+ # to the lowercase version "mint" (or "freemint"). Finally
+ # the system name "TOS" denotes a system which is actually not
+ # MiNT. But MiNT is downward compatible to TOS, so this should
+ # be no problem.
+ atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
+ echo m68k-atari-mint${UNAME_RELEASE}
+ exit ;;
+ atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
+ echo m68k-atari-mint${UNAME_RELEASE}
+ exit ;;
+ *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
+ echo m68k-atari-mint${UNAME_RELEASE}
+ exit ;;
+ milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
+ echo m68k-milan-mint${UNAME_RELEASE}
+ exit ;;
+ hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
+ echo m68k-hades-mint${UNAME_RELEASE}
+ exit ;;
+ *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
+ echo m68k-unknown-mint${UNAME_RELEASE}
+ exit ;;
+ m68k:machten:*:*)
+ echo m68k-apple-machten${UNAME_RELEASE}
+ exit ;;
+ powerpc:machten:*:*)
+ echo powerpc-apple-machten${UNAME_RELEASE}
+ exit ;;
+ RISC*:Mach:*:*)
+ echo mips-dec-mach_bsd4.3
+ exit ;;
+ RISC*:ULTRIX:*:*)
+ echo mips-dec-ultrix${UNAME_RELEASE}
+ exit ;;
+ VAX*:ULTRIX*:*:*)
+ echo vax-dec-ultrix${UNAME_RELEASE}
+ exit ;;
+ 2020:CLIX:*:* | 2430:CLIX:*:*)
+ echo clipper-intergraph-clix${UNAME_RELEASE}
+ exit ;;
+ mips:*:*:UMIPS | mips:*:*:RISCos)
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+#ifdef __cplusplus
+#include <stdio.h> /* for printf() prototype */
+ int main (int argc, char *argv[]) {
+#else
+ int main (argc, argv) int argc; char *argv[]; {
+#endif
+ #if defined (host_mips) && defined (MIPSEB)
+ #if defined (SYSTYPE_SYSV)
+ printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0);
+ #endif
+ #if defined (SYSTYPE_SVR4)
+ printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0);
+ #endif
+ #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD)
+ printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0);
+ #endif
+ #endif
+ exit (-1);
+ }
+EOF
+ $CC_FOR_BUILD -o $dummy $dummy.c &&
+ dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` &&
+ SYSTEM_NAME=`$dummy $dummyarg` &&
+ { echo "$SYSTEM_NAME"; exit; }
+ echo mips-mips-riscos${UNAME_RELEASE}
+ exit ;;
+ Motorola:PowerMAX_OS:*:*)
+ echo powerpc-motorola-powermax
+ exit ;;
+ Motorola:*:4.3:PL8-*)
+ echo powerpc-harris-powermax
+ exit ;;
+ Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*)
+ echo powerpc-harris-powermax
+ exit ;;
+ Night_Hawk:Power_UNIX:*:*)
+ echo powerpc-harris-powerunix
+ exit ;;
+ m88k:CX/UX:7*:*)
+ echo m88k-harris-cxux7
+ exit ;;
+ m88k:*:4*:R4*)
+ echo m88k-motorola-sysv4
+ exit ;;
+ m88k:*:3*:R3*)
+ echo m88k-motorola-sysv3
+ exit ;;
+ AViiON:dgux:*:*)
+ # DG/UX returns AViiON for all architectures
+ UNAME_PROCESSOR=`/usr/bin/uname -p`
+ if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ]
+ then
+ if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \
+ [ ${TARGET_BINARY_INTERFACE}x = x ]
+ then
+ echo m88k-dg-dgux${UNAME_RELEASE}
+ else
+ echo m88k-dg-dguxbcs${UNAME_RELEASE}
+ fi
+ else
+ echo i586-dg-dgux${UNAME_RELEASE}
+ fi
+ exit ;;
+ M88*:DolphinOS:*:*) # DolphinOS (SVR3)
+ echo m88k-dolphin-sysv3
+ exit ;;
+ M88*:*:R3*:*)
+ # Delta 88k system running SVR3
+ echo m88k-motorola-sysv3
+ exit ;;
+ XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3)
+ echo m88k-tektronix-sysv3
+ exit ;;
+ Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD)
+ echo m68k-tektronix-bsd
+ exit ;;
+ *:IRIX*:*:*)
+ echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'`
+ exit ;;
+ ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
+ echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id
+ exit ;; # Note that: echo "'`uname -s`'" gives 'AIX '
+ i*86:AIX:*:*)
+ echo i386-ibm-aix
+ exit ;;
+ ia64:AIX:*:*)
+ if [ -x /usr/bin/oslevel ] ; then
+ IBM_REV=`/usr/bin/oslevel`
+ else
+ IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+ fi
+ echo ${UNAME_MACHINE}-ibm-aix${IBM_REV}
+ exit ;;
+ *:AIX:2:3)
+ if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+ #include <sys/systemcfg.h>
+
+ main()
+ {
+ if (!__power_pc())
+ exit(1);
+ puts("powerpc-ibm-aix3.2.5");
+ exit(0);
+ }
+EOF
+ if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy`
+ then
+ echo "$SYSTEM_NAME"
+ else
+ echo rs6000-ibm-aix3.2.5
+ fi
+ elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then
+ echo rs6000-ibm-aix3.2.4
+ else
+ echo rs6000-ibm-aix3.2
+ fi
+ exit ;;
+ *:AIX:*:[456])
+ IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
+ if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
+ IBM_ARCH=rs6000
+ else
+ IBM_ARCH=powerpc
+ fi
+ if [ -x /usr/bin/oslevel ] ; then
+ IBM_REV=`/usr/bin/oslevel`
+ else
+ IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+ fi
+ echo ${IBM_ARCH}-ibm-aix${IBM_REV}
+ exit ;;
+ *:AIX:*:*)
+ echo rs6000-ibm-aix
+ exit ;;
+ ibmrt:4.4BSD:*|romp-ibm:BSD:*)
+ echo romp-ibm-bsd4.4
+ exit ;;
+ ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and
+ echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to
+ exit ;; # report: romp-ibm BSD 4.3
+ *:BOSX:*:*)
+ echo rs6000-bull-bosx
+ exit ;;
+ DPX/2?00:B.O.S.:*:*)
+ echo m68k-bull-sysv3
+ exit ;;
+ 9000/[34]??:4.3bsd:1.*:*)
+ echo m68k-hp-bsd
+ exit ;;
+ hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)
+ echo m68k-hp-bsd4.4
+ exit ;;
+ 9000/[34678]??:HP-UX:*:*)
+ HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+ case "${UNAME_MACHINE}" in
+ 9000/31? ) HP_ARCH=m68000 ;;
+ 9000/[34]?? ) HP_ARCH=m68k ;;
+ 9000/[678][0-9][0-9])
+ if [ -x /usr/bin/getconf ]; then
+ sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
+ sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
+ case "${sc_cpu_version}" in
+ 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
+ 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
+ 532) # CPU_PA_RISC2_0
+ case "${sc_kernel_bits}" in
+ 32) HP_ARCH="hppa2.0n" ;;
+ 64) HP_ARCH="hppa2.0w" ;;
+ '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20
+ esac ;;
+ esac
+ fi
+ if [ "${HP_ARCH}" = "" ]; then
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+
+ #define _HPUX_SOURCE
+ #include <stdlib.h>
+ #include <unistd.h>
+
+ int main ()
+ {
+ #if defined(_SC_KERNEL_BITS)
+ long bits = sysconf(_SC_KERNEL_BITS);
+ #endif
+ long cpu = sysconf (_SC_CPU_VERSION);
+
+ switch (cpu)
+ {
+ case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
+ case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
+ case CPU_PA_RISC2_0:
+ #if defined(_SC_KERNEL_BITS)
+ switch (bits)
+ {
+ case 64: puts ("hppa2.0w"); break;
+ case 32: puts ("hppa2.0n"); break;
+ default: puts ("hppa2.0"); break;
+ } break;
+ #else /* !defined(_SC_KERNEL_BITS) */
+ puts ("hppa2.0"); break;
+ #endif
+ default: puts ("hppa1.0"); break;
+ }
+ exit (0);
+ }
+EOF
+ (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy`
+ test -z "$HP_ARCH" && HP_ARCH=hppa
+ fi ;;
+ esac
+ if [ ${HP_ARCH} = "hppa2.0w" ]
+ then
+ eval $set_cc_for_build
+
+ # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating
+ # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler
+ # generating 64-bit code. GNU and HP use different nomenclature:
+ #
+ # $ CC_FOR_BUILD=cc ./config.guess
+ # => hppa2.0w-hp-hpux11.23
+ # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess
+ # => hppa64-hp-hpux11.23
+
+ if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) |
+ grep __LP64__ >/dev/null
+ then
+ HP_ARCH="hppa2.0w"
+ else
+ HP_ARCH="hppa64"
+ fi
+ fi
+ echo ${HP_ARCH}-hp-hpux${HPUX_REV}
+ exit ;;
+ ia64:HP-UX:*:*)
+ HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+ echo ia64-hp-hpux${HPUX_REV}
+ exit ;;
+ 3050*:HI-UX:*:*)
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+ #include <unistd.h>
+ int
+ main ()
+ {
+ long cpu = sysconf (_SC_CPU_VERSION);
+ /* The order matters, because CPU_IS_HP_MC68K erroneously returns
+ true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct
+ results, however. */
+ if (CPU_IS_PA_RISC (cpu))
+ {
+ switch (cpu)
+ {
+ case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break;
+ case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break;
+ case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break;
+ default: puts ("hppa-hitachi-hiuxwe2"); break;
+ }
+ }
+ else if (CPU_IS_HP_MC68K (cpu))
+ puts ("m68k-hitachi-hiuxwe2");
+ else puts ("unknown-hitachi-hiuxwe2");
+ exit (0);
+ }
+EOF
+ $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` &&
+ { echo "$SYSTEM_NAME"; exit; }
+ echo unknown-hitachi-hiuxwe2
+ exit ;;
+ 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )
+ echo hppa1.1-hp-bsd
+ exit ;;
+ 9000/8??:4.3bsd:*:*)
+ echo hppa1.0-hp-bsd
+ exit ;;
+ *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*)
+ echo hppa1.0-hp-mpeix
+ exit ;;
+ hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* )
+ echo hppa1.1-hp-osf
+ exit ;;
+ hp8??:OSF1:*:*)
+ echo hppa1.0-hp-osf
+ exit ;;
+ i*86:OSF1:*:*)
+ if [ -x /usr/sbin/sysversion ] ; then
+ echo ${UNAME_MACHINE}-unknown-osf1mk
+ else
+ echo ${UNAME_MACHINE}-unknown-osf1
+ fi
+ exit ;;
+ parisc*:Lites*:*:*)
+ echo hppa1.1-hp-lites
+ exit ;;
+ C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
+ echo c1-convex-bsd
+ exit ;;
+ C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
+ if getsysinfo -f scalar_acc
+ then echo c32-convex-bsd
+ else echo c2-convex-bsd
+ fi
+ exit ;;
+ C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
+ echo c34-convex-bsd
+ exit ;;
+ C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
+ echo c38-convex-bsd
+ exit ;;
+ C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
+ echo c4-convex-bsd
+ exit ;;
+ CRAY*Y-MP:*:*:*)
+ echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit ;;
+ CRAY*[A-Z]90:*:*:*)
+ echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \
+ | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \
+ -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \
+ -e 's/\.[^.]*$/.X/'
+ exit ;;
+ CRAY*TS:*:*:*)
+ echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit ;;
+ CRAY*T3E:*:*:*)
+ echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit ;;
+ CRAY*SV1:*:*:*)
+ echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit ;;
+ *:UNICOS/mp:*:*)
+ echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit ;;
+ F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
+ FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+ FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+ FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
+ echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+ exit ;;
+ 5000:UNIX_System_V:4.*:*)
+ FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+ FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'`
+ echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+ exit ;;
+ i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
+ echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
+ exit ;;
+ sparc*:BSD/OS:*:*)
+ echo sparc-unknown-bsdi${UNAME_RELEASE}
+ exit ;;
+ *:BSD/OS:*:*)
+ echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
+ exit ;;
+ *:FreeBSD:*:*)
+ case ${UNAME_MACHINE} in
+ pc98)
+ echo i386-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+ amd64)
+ echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+ *)
+ echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+ esac
+ exit ;;
+ i*:CYGWIN*:*)
+ echo ${UNAME_MACHINE}-pc-cygwin
+ exit ;;
+ *:MINGW*:*)
+ echo ${UNAME_MACHINE}-pc-mingw32
+ exit ;;
+ i*:windows32*:*)
+ # uname -m includes "-pc" on this system.
+ echo ${UNAME_MACHINE}-mingw32
+ exit ;;
+ i*:PW*:*)
+ echo ${UNAME_MACHINE}-pc-pw32
+ exit ;;
+ *:Interix*:[3456]*)
+ case ${UNAME_MACHINE} in
+ x86)
+ echo i586-pc-interix${UNAME_RELEASE}
+ exit ;;
+ EM64T | authenticamd)
+ echo x86_64-unknown-interix${UNAME_RELEASE}
+ exit ;;
+ IA64)
+ echo ia64-unknown-interix${UNAME_RELEASE}
+ exit ;;
+ esac ;;
+ [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*)
+ echo i${UNAME_MACHINE}-pc-mks
+ exit ;;
+ i*:Windows_NT*:* | Pentium*:Windows_NT*:*)
+ # How do we know it's Interix rather than the generic POSIX subsystem?
+ # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we
+ # UNAME_MACHINE based on the output of uname instead of i386?
+ echo i586-pc-interix
+ exit ;;
+ i*:UWIN*:*)
+ echo ${UNAME_MACHINE}-pc-uwin
+ exit ;;
+ amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*)
+ echo x86_64-unknown-cygwin
+ exit ;;
+ p*:CYGWIN*:*)
+ echo powerpcle-unknown-cygwin
+ exit ;;
+ prep*:SunOS:5.*:*)
+ echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit ;;
+ *:GNU:*:*)
+ # the GNU system
+ echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
+ exit ;;
+ *:GNU/*:*:*)
+ # other systems with GNU libc and userland
+ echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu
+ exit ;;
+ i*86:Minix:*:*)
+ echo ${UNAME_MACHINE}-pc-minix
+ exit ;;
+ arm*:Linux:*:*)
+ eval $set_cc_for_build
+ if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \
+ | grep -q __ARM_EABI__
+ then
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ else
+ echo ${UNAME_MACHINE}-unknown-linux-gnueabi
+ fi
+ exit ;;
+ avr32*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit ;;
+ cris:Linux:*:*)
+ echo cris-axis-linux-gnu
+ exit ;;
+ crisv32:Linux:*:*)
+ echo crisv32-axis-linux-gnu
+ exit ;;
+ frv:Linux:*:*)
+ echo frv-unknown-linux-gnu
+ exit ;;
+ ia64:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit ;;
+ m32r*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit ;;
+ m68*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit ;;
+ mips:Linux:*:*)
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+ #undef CPU
+ #undef mips
+ #undef mipsel
+ #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
+ CPU=mipsel
+ #else
+ #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
+ CPU=mips
+ #else
+ CPU=
+ #endif
+ #endif
+EOF
+ eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n '
+ /^CPU/{
+ s: ::g
+ p
+ }'`"
+ test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; }
+ ;;
+ mips64:Linux:*:*)
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+ #undef CPU
+ #undef mips64
+ #undef mips64el
+ #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
+ CPU=mips64el
+ #else
+ #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
+ CPU=mips64
+ #else
+ CPU=
+ #endif
+ #endif
+EOF
+ eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n '
+ /^CPU/{
+ s: ::g
+ p
+ }'`"
+ test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; }
+ ;;
+ or32:Linux:*:*)
+ echo or32-unknown-linux-gnu
+ exit ;;
+ ppc:Linux:*:*)
+ echo powerpc-unknown-linux-gnu
+ exit ;;
+ ppc64:Linux:*:*)
+ echo powerpc64-unknown-linux-gnu
+ exit ;;
+ alpha:Linux:*:*)
+ case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
+ EV5) UNAME_MACHINE=alphaev5 ;;
+ EV56) UNAME_MACHINE=alphaev56 ;;
+ PCA56) UNAME_MACHINE=alphapca56 ;;
+ PCA57) UNAME_MACHINE=alphapca56 ;;
+ EV6) UNAME_MACHINE=alphaev6 ;;
+ EV67) UNAME_MACHINE=alphaev67 ;;
+ EV68*) UNAME_MACHINE=alphaev68 ;;
+ esac
+ objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null
+ if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi
+ echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC}
+ exit ;;
+ parisc:Linux:*:* | hppa:Linux:*:*)
+ # Look for CPU level
+ case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
+ PA7*) echo hppa1.1-unknown-linux-gnu ;;
+ PA8*) echo hppa2.0-unknown-linux-gnu ;;
+ *) echo hppa-unknown-linux-gnu ;;
+ esac
+ exit ;;
+ parisc64:Linux:*:* | hppa64:Linux:*:*)
+ echo hppa64-unknown-linux-gnu
+ exit ;;
+ s390:Linux:*:* | s390x:Linux:*:*)
+ echo ${UNAME_MACHINE}-ibm-linux
+ exit ;;
+ sh64*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit ;;
+ sh*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit ;;
+ sparc:Linux:*:* | sparc64:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit ;;
+ vax:Linux:*:*)
+ echo ${UNAME_MACHINE}-dec-linux-gnu
+ exit ;;
+ x86_64:Linux:*:*)
+ echo x86_64-unknown-linux-gnu
+ exit ;;
+ xtensa*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit ;;
+ i*86:Linux:*:*)
+ # The BFD linker knows what the default object file format is, so
+ # first see if it will tell us. cd to the root directory to prevent
+ # problems with other programs or directories called `ld' in the path.
+ # Set LC_ALL=C to ensure ld outputs messages in English.
+ ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \
+ | sed -ne '/supported targets:/!d
+ s/[ ][ ]*/ /g
+ s/.*supported targets: *//
+ s/ .*//
+ p'`
+ case "$ld_supported_targets" in
+ elf32-i386)
+ TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu"
+ ;;
+ a.out-i386-linux)
+ echo "${UNAME_MACHINE}-pc-linux-gnuaout"
+ exit ;;
+ coff-i386)
+ echo "${UNAME_MACHINE}-pc-linux-gnucoff"
+ exit ;;
+ "")
+ # Either a pre-BFD a.out linker (linux-gnuoldld) or
+ # one that does not give us useful --help.
+ echo "${UNAME_MACHINE}-pc-linux-gnuoldld"
+ exit ;;
+ esac
+ # Determine whether the default compiler is a.out or elf
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+ #include <features.h>
+ #ifdef __ELF__
+ # ifdef __GLIBC__
+ # if __GLIBC__ >= 2
+ LIBC=gnu
+ # else
+ LIBC=gnulibc1
+ # endif
+ # else
+ LIBC=gnulibc1
+ # endif
+ #else
+ #if defined(__INTEL_COMPILER) || defined(__PGI) || defined(__SUNPRO_C) || defined(__SUNPRO_CC)
+ LIBC=gnu
+ #else
+ LIBC=gnuaout
+ #endif
+ #endif
+ #ifdef __dietlibc__
+ LIBC=dietlibc
+ #endif
+EOF
+ eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n '
+ /^LIBC/{
+ s: ::g
+ p
+ }'`"
+ test x"${LIBC}" != x && {
+ echo "${UNAME_MACHINE}-pc-linux-${LIBC}"
+ exit
+ }
+ test x"${TENTATIVE}" != x && { echo "${TENTATIVE}"; exit; }
+ ;;
+ i*86:DYNIX/ptx:4*:*)
+ # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
+ # earlier versions are messed up and put the nodename in both
+ # sysname and nodename.
+ echo i386-sequent-sysv4
+ exit ;;
+ i*86:UNIX_SV:4.2MP:2.*)
+ # Unixware is an offshoot of SVR4, but it has its own version
+ # number series starting with 2...
+ # I am not positive that other SVR4 systems won't match this,
+ # I just have to hope. -- rms.
+ # Use sysv4.2uw... so that sysv4* matches it.
+ echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
+ exit ;;
+ i*86:OS/2:*:*)
+ # If we were able to find `uname', then EMX Unix compatibility
+ # is probably installed.
+ echo ${UNAME_MACHINE}-pc-os2-emx
+ exit ;;
+ i*86:XTS-300:*:STOP)
+ echo ${UNAME_MACHINE}-unknown-stop
+ exit ;;
+ i*86:atheos:*:*)
+ echo ${UNAME_MACHINE}-unknown-atheos
+ exit ;;
+ i*86:syllable:*:*)
+ echo ${UNAME_MACHINE}-pc-syllable
+ exit ;;
+ i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*)
+ echo i386-unknown-lynxos${UNAME_RELEASE}
+ exit ;;
+ i*86:*DOS:*:*)
+ echo ${UNAME_MACHINE}-pc-msdosdjgpp
+ exit ;;
+ i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*)
+ UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'`
+ if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
+ echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL}
+ else
+ echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL}
+ fi
+ exit ;;
+ i*86:*:5:[678]*)
+ # UnixWare 7.x, OpenUNIX and OpenServer 6.
+ case `/bin/uname -X | grep "^Machine"` in
+ *486*) UNAME_MACHINE=i486 ;;
+ *Pentium) UNAME_MACHINE=i586 ;;
+ *Pent*|*Celeron) UNAME_MACHINE=i686 ;;
+ esac
+ echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION}
+ exit ;;
+ i*86:*:3.2:*)
+ if test -f /usr/options/cb.name; then
+ UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
+ echo ${UNAME_MACHINE}-pc-isc$UNAME_REL
+ elif /bin/uname -X 2>/dev/null >/dev/null ; then
+ UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')`
+ (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486
+ (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \
+ && UNAME_MACHINE=i586
+ (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \
+ && UNAME_MACHINE=i686
+ (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \
+ && UNAME_MACHINE=i686
+ echo ${UNAME_MACHINE}-pc-sco$UNAME_REL
+ else
+ echo ${UNAME_MACHINE}-pc-sysv32
+ fi
+ exit ;;
+ pc:*:*:*)
+ # Left here for compatibility:
+ # uname -m prints for DJGPP always 'pc', but it prints nothing about
+ # the processor, so we play safe by assuming i386.
+ echo i386-pc-msdosdjgpp
+ exit ;;
+ Intel:Mach:3*:*)
+ echo i386-pc-mach3
+ exit ;;
+ paragon:*:*:*)
+ echo i860-intel-osf1
+ exit ;;
+ i860:*:4.*:*) # i860-SVR4
+ if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then
+ echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4
+ else # Add other i860-SVR4 vendors below as they are discovered.
+ echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4
+ fi
+ exit ;;
+ mini*:CTIX:SYS*5:*)
+ # "miniframe"
+ echo m68010-convergent-sysv
+ exit ;;
+ mc68k:UNIX:SYSTEM5:3.51m)
+ echo m68k-convergent-sysv
+ exit ;;
+ M680?0:D-NIX:5.3:*)
+ echo m68k-diab-dnix
+ exit ;;
+ M68*:*:R3V[5678]*:*)
+ test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;;
+ 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0)
+ OS_REL=''
+ test -r /etc/.relid \
+ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
+ /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+ && { echo i486-ncr-sysv4.3${OS_REL}; exit; }
+ /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
+ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
+ 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
+ /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+ && { echo i486-ncr-sysv4; exit; } ;;
+ m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)
+ echo m68k-unknown-lynxos${UNAME_RELEASE}
+ exit ;;
+ mc68030:UNIX_System_V:4.*:*)
+ echo m68k-atari-sysv4
+ exit ;;
+ TSUNAMI:LynxOS:2.*:*)
+ echo sparc-unknown-lynxos${UNAME_RELEASE}
+ exit ;;
+ rs6000:LynxOS:2.*:*)
+ echo rs6000-unknown-lynxos${UNAME_RELEASE}
+ exit ;;
+ PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*)
+ echo powerpc-unknown-lynxos${UNAME_RELEASE}
+ exit ;;
+ SM[BE]S:UNIX_SV:*:*)
+ echo mips-dde-sysv${UNAME_RELEASE}
+ exit ;;
+ RM*:ReliantUNIX-*:*:*)
+ echo mips-sni-sysv4
+ exit ;;
+ RM*:SINIX-*:*:*)
+ echo mips-sni-sysv4
+ exit ;;
+ *:SINIX-*:*:*)
+ if uname -p 2>/dev/null >/dev/null ; then
+ UNAME_MACHINE=`(uname -p) 2>/dev/null`
+ echo ${UNAME_MACHINE}-sni-sysv4
+ else
+ echo ns32k-sni-sysv
+ fi
+ exit ;;
+ PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
+ # says <Richard.M.Bartel@ccMail.Census.GOV>
+ echo i586-unisys-sysv4
+ exit ;;
+ *:UNIX_System_V:4*:FTX*)
+ # From Gerald Hewes <hewes@openmarket.com>.
+ # How about differentiating between stratus architectures? -djm
+ echo hppa1.1-stratus-sysv4
+ exit ;;
+ *:*:*:FTX*)
+ # From seanf@swdc.stratus.com.
+ echo i860-stratus-sysv4
+ exit ;;
+ i*86:VOS:*:*)
+ # From Paul.Green@stratus.com.
+ echo ${UNAME_MACHINE}-stratus-vos
+ exit ;;
+ *:VOS:*:*)
+ # From Paul.Green@stratus.com.
+ echo hppa1.1-stratus-vos
+ exit ;;
+ mc68*:A/UX:*:*)
+ echo m68k-apple-aux${UNAME_RELEASE}
+ exit ;;
+ news*:NEWS-OS:6*:*)
+ echo mips-sony-newsos6
+ exit ;;
+ R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
+ if [ -d /usr/nec ]; then
+ echo mips-nec-sysv${UNAME_RELEASE}
+ else
+ echo mips-unknown-sysv${UNAME_RELEASE}
+ fi
+ exit ;;
+ BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only.
+ echo powerpc-be-beos
+ exit ;;
+ BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only.
+ echo powerpc-apple-beos
+ exit ;;
+ BePC:BeOS:*:*) # BeOS running on Intel PC compatible.
+ echo i586-pc-beos
+ exit ;;
+ SX-4:SUPER-UX:*:*)
+ echo sx4-nec-superux${UNAME_RELEASE}
+ exit ;;
+ SX-5:SUPER-UX:*:*)
+ echo sx5-nec-superux${UNAME_RELEASE}
+ exit ;;
+ SX-6:SUPER-UX:*:*)
+ echo sx6-nec-superux${UNAME_RELEASE}
+ exit ;;
+ SX-7:SUPER-UX:*:*)
+ echo sx7-nec-superux${UNAME_RELEASE}
+ exit ;;
+ SX-8:SUPER-UX:*:*)
+ echo sx8-nec-superux${UNAME_RELEASE}
+ exit ;;
+ SX-8R:SUPER-UX:*:*)
+ echo sx8r-nec-superux${UNAME_RELEASE}
+ exit ;;
+ Power*:Rhapsody:*:*)
+ echo powerpc-apple-rhapsody${UNAME_RELEASE}
+ exit ;;
+ *:Rhapsody:*:*)
+ echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE}
+ exit ;;
+ *:Darwin:*:*)
+ UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown
+ case $UNAME_PROCESSOR in
+ unknown) UNAME_PROCESSOR=powerpc ;;
+ esac
+ echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}
+ exit ;;
+ *:procnto*:*:* | *:QNX:[0123456789]*:*)
+ UNAME_PROCESSOR=`uname -p`
+ if test "$UNAME_PROCESSOR" = "x86"; then
+ UNAME_PROCESSOR=i386
+ UNAME_MACHINE=pc
+ fi
+ echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE}
+ exit ;;
+ *:QNX:*:4*)
+ echo i386-pc-qnx
+ exit ;;
+ NSE-?:NONSTOP_KERNEL:*:*)
+ echo nse-tandem-nsk${UNAME_RELEASE}
+ exit ;;
+ NSR-?:NONSTOP_KERNEL:*:*)
+ echo nsr-tandem-nsk${UNAME_RELEASE}
+ exit ;;
+ *:NonStop-UX:*:*)
+ echo mips-compaq-nonstopux
+ exit ;;
+ BS2000:POSIX*:*:*)
+ echo bs2000-siemens-sysv
+ exit ;;
+ DS/*:UNIX_System_V:*:*)
+ echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE}
+ exit ;;
+ *:Plan9:*:*)
+ # "uname -m" is not consistent, so use $cputype instead. 386
+ # is converted to i386 for consistency with other x86
+ # operating systems.
+ if test "$cputype" = "386"; then
+ UNAME_MACHINE=i386
+ else
+ UNAME_MACHINE="$cputype"
+ fi
+ echo ${UNAME_MACHINE}-unknown-plan9
+ exit ;;
+ *:TOPS-10:*:*)
+ echo pdp10-unknown-tops10
+ exit ;;
+ *:TENEX:*:*)
+ echo pdp10-unknown-tenex
+ exit ;;
+ KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*)
+ echo pdp10-dec-tops20
+ exit ;;
+ XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*)
+ echo pdp10-xkl-tops20
+ exit ;;
+ *:TOPS-20:*:*)
+ echo pdp10-unknown-tops20
+ exit ;;
+ *:ITS:*:*)
+ echo pdp10-unknown-its
+ exit ;;
+ SEI:*:*:SEIUX)
+ echo mips-sei-seiux${UNAME_RELEASE}
+ exit ;;
+ *:DragonFly:*:*)
+ echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
+ exit ;;
+ *:*VMS:*:*)
+ UNAME_MACHINE=`(uname -p) 2>/dev/null`
+ case "${UNAME_MACHINE}" in
+ A*) echo alpha-dec-vms ; exit ;;
+ I*) echo ia64-dec-vms ; exit ;;
+ V*) echo vax-dec-vms ; exit ;;
+ esac ;;
+ *:XENIX:*:SysV)
+ echo i386-pc-xenix
+ exit ;;
+ i*86:skyos:*:*)
+ echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//'
+ exit ;;
+ i*86:rdos:*:*)
+ echo ${UNAME_MACHINE}-pc-rdos
+ exit ;;
+esac
+
+#echo '(No uname command or uname output not recognized.)' 1>&2
+#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2
+
+eval $set_cc_for_build
+cat >$dummy.c <<EOF
+#ifdef _SEQUENT_
+# include <sys/types.h>
+# include <sys/utsname.h>
+#endif
+main ()
+{
+#if defined (sony)
+#if defined (MIPSEB)
+ /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed,
+ I don't know.... */
+ printf ("mips-sony-bsd\n"); exit (0);
+#else
+#include <sys/param.h>
+ printf ("m68k-sony-newsos%s\n",
+#ifdef NEWSOS4
+ "4"
+#else
+ ""
+#endif
+ ); exit (0);
+#endif
+#endif
+
+#if defined (__arm) && defined (__acorn) && defined (__unix)
+ printf ("arm-acorn-riscix\n"); exit (0);
+#endif
+
+#if defined (hp300) && !defined (hpux)
+ printf ("m68k-hp-bsd\n"); exit (0);
+#endif
+
+#if defined (NeXT)
+#if !defined (__ARCHITECTURE__)
+#define __ARCHITECTURE__ "m68k"
+#endif
+ int version;
+ version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`;
+ if (version < 4)
+ printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version);
+ else
+ printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version);
+ exit (0);
+#endif
+
+#if defined (MULTIMAX) || defined (n16)
+#if defined (UMAXV)
+ printf ("ns32k-encore-sysv\n"); exit (0);
+#else
+#if defined (CMU)
+ printf ("ns32k-encore-mach\n"); exit (0);
+#else
+ printf ("ns32k-encore-bsd\n"); exit (0);
+#endif
+#endif
+#endif
+
+#if defined (__386BSD__)
+ printf ("i386-pc-bsd\n"); exit (0);
+#endif
+
+#if defined (sequent)
+#if defined (i386)
+ printf ("i386-sequent-dynix\n"); exit (0);
+#endif
+#if defined (ns32000)
+ printf ("ns32k-sequent-dynix\n"); exit (0);
+#endif
+#endif
+
+#if defined (_SEQUENT_)
+ struct utsname un;
+
+ uname(&un);
+
+ if (strncmp(un.version, "V2", 2) == 0) {
+ printf ("i386-sequent-ptx2\n"); exit (0);
+ }
+ if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */
+ printf ("i386-sequent-ptx1\n"); exit (0);
+ }
+ printf ("i386-sequent-ptx\n"); exit (0);
+
+#endif
+
+#if defined (vax)
+# if !defined (ultrix)
+# include <sys/param.h>
+# if defined (BSD)
+# if BSD == 43
+ printf ("vax-dec-bsd4.3\n"); exit (0);
+# else
+# if BSD == 199006
+ printf ("vax-dec-bsd4.3reno\n"); exit (0);
+# else
+ printf ("vax-dec-bsd\n"); exit (0);
+# endif
+# endif
+# else
+ printf ("vax-dec-bsd\n"); exit (0);
+# endif
+# else
+ printf ("vax-dec-ultrix\n"); exit (0);
+# endif
+#endif
+
+#if defined (alliant) && defined (i860)
+ printf ("i860-alliant-bsd\n"); exit (0);
+#endif
+
+ exit (1);
+}
+EOF
+
+$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` &&
+ { echo "$SYSTEM_NAME"; exit; }
+
+# Apollos put the system type in the environment.
+
+test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; }
+
+# Convex versions that predate uname can use getsysinfo(1)
+
+if [ -x /usr/convex/getsysinfo ]
+then
+ case `getsysinfo -f cpu_type` in
+ c1*)
+ echo c1-convex-bsd
+ exit ;;
+ c2*)
+ if getsysinfo -f scalar_acc
+ then echo c32-convex-bsd
+ else echo c2-convex-bsd
+ fi
+ exit ;;
+ c34*)
+ echo c34-convex-bsd
+ exit ;;
+ c38*)
+ echo c38-convex-bsd
+ exit ;;
+ c4*)
+ echo c4-convex-bsd
+ exit ;;
+ esac
+fi
+
+cat >&2 <<EOF
+$0: unable to guess system type
+
+This script, last modified $timestamp, has failed to recognize
+the operating system you are using. It is advised that you
+download the most up to date version of the config scripts from
+
+ http://savannah.gnu.org/cgi-bin/viewcvs/*checkout*/config/config/config.guess
+and
+ http://savannah.gnu.org/cgi-bin/viewcvs/*checkout*/config/config/config.sub
+
+If the version you run ($0) is already up to date, please
+send the following data and any information you think might be
+pertinent to <config-patches@gnu.org> in order to provide the needed
+information to handle your system.
+
+config.guess timestamp = $timestamp
+
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null`
+/bin/uname -X = `(/bin/uname -X) 2>/dev/null`
+
+hostinfo = `(hostinfo) 2>/dev/null`
+/bin/universe = `(/bin/universe) 2>/dev/null`
+/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null`
+/bin/arch = `(/bin/arch) 2>/dev/null`
+/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null`
+
+UNAME_MACHINE = ${UNAME_MACHINE}
+UNAME_RELEASE = ${UNAME_RELEASE}
+UNAME_SYSTEM = ${UNAME_SYSTEM}
+UNAME_VERSION = ${UNAME_VERSION}
+EOF
+
+exit 1
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:
diff --git a/src/third_party/gflags-2.0/config.status b/src/third_party/gflags-2.0/config.status
new file mode 100755
index 00000000000..1145a38106e
--- /dev/null
+++ b/src/third_party/gflags-2.0/config.status
@@ -0,0 +1,2288 @@
+#! /bin/sh
+# Generated by configure.
+# Run this file to recreate the current configuration.
+# Compiler output produced by configure, useful for debugging
+# configure, is in config.log if it exists.
+
+debug=false
+ac_cs_recheck=false
+ac_cs_silent=false
+SHELL=${CONFIG_SHELL-/bin/sh}
+## --------------------- ##
+## M4sh Initialization. ##
+## --------------------- ##
+
+# Be more Bourne compatible
+DUALCASE=1; export DUALCASE # for MKS sh
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+ emulate sh
+ NULLCMD=:
+ # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '${1+"$@"}'='"$@"'
+ setopt NO_GLOB_SUBST
+else
+ case `(set -o) 2>/dev/null` in
+ *posix*) set -o posix ;;
+esac
+
+fi
+
+
+
+
+# PATH needs CR
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+as_nl='
+'
+export as_nl
+# Printing a long string crashes Solaris 7 /usr/bin/printf.
+as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
+if (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
+ as_echo='printf %s\n'
+ as_echo_n='printf %s'
+else
+ if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
+ as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
+ as_echo_n='/usr/ucb/echo -n'
+ else
+ as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
+ as_echo_n_body='eval
+ arg=$1;
+ case $arg in
+ *"$as_nl"*)
+ expr "X$arg" : "X\\(.*\\)$as_nl";
+ arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
+ esac;
+ expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
+ '
+ export as_echo_n_body
+ as_echo_n='sh -c $as_echo_n_body as_echo'
+ fi
+ export as_echo_body
+ as_echo='sh -c $as_echo_body as_echo'
+fi
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+ PATH_SEPARATOR=:
+ (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
+ (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
+ PATH_SEPARATOR=';'
+ }
+fi
+
+# Support unset when possible.
+if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+ as_unset=unset
+else
+ as_unset=false
+fi
+
+
+# IFS
+# We need space, tab and new line, in precisely that order. Quoting is
+# there to prevent editors from complaining about space-tab.
+# (If _AS_PATH_WALK were called with IFS unset, it would disable word
+# splitting by setting IFS to empty value.)
+IFS=" "" $as_nl"
+
+# Find who we are. Look in the path if we contain no directory separator.
+case $0 in
+ *[\\/]* ) as_myself=$0 ;;
+ *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+done
+IFS=$as_save_IFS
+
+ ;;
+esac
+# We did not find ourselves, most probably we were run as `sh COMMAND'
+# in which case we are not to be found in the path.
+if test "x$as_myself" = x; then
+ as_myself=$0
+fi
+if test ! -f "$as_myself"; then
+ $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+ { (exit 1); exit 1; }
+fi
+
+# Work around bugs in pre-3.0 UWIN ksh.
+for as_var in ENV MAIL MAILPATH
+do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var
+done
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+LC_ALL=C
+export LC_ALL
+LANGUAGE=C
+export LANGUAGE
+
+# Required to use basename.
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+ test "X`expr 00001 : '.*\(...\)'`" = X001; then
+ as_expr=expr
+else
+ as_expr=false
+fi
+
+if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
+ as_basename=basename
+else
+ as_basename=false
+fi
+
+
+# Name of the executable.
+as_me=`$as_basename -- "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+ X"$0" : 'X\(//\)$' \| \
+ X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X/"$0" |
+ sed '/^.*\/\([^/][^/]*\)\/*$/{
+ s//\1/
+ q
+ }
+ /^X\/\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\/\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+
+# CDPATH.
+$as_unset CDPATH
+
+
+
+ as_lineno_1=$LINENO
+ as_lineno_2=$LINENO
+ test "x$as_lineno_1" != "x$as_lineno_2" &&
+ test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || {
+
+ # Create $as_me.lineno as a copy of $as_myself, but with $LINENO
+ # uniformly replaced by the line number. The first 'sed' inserts a
+ # line-number line after each line using $LINENO; the second 'sed'
+ # does the real work. The second script uses 'N' to pair each
+ # line-number line with the line containing $LINENO, and appends
+ # trailing '-' during substitution so that $LINENO is not a special
+ # case at line end.
+ # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the
+ # scripts with optimization help from Paolo Bonzini. Blame Lee
+ # E. McMahon (1931-1989) for sed's syntax. :-)
+ sed -n '
+ p
+ /[$]LINENO/=
+ ' <$as_myself |
+ sed '
+ s/[$]LINENO.*/&-/
+ t lineno
+ b
+ :lineno
+ N
+ :loop
+ s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/
+ t loop
+ s/-\n.*//
+ ' >$as_me.lineno &&
+ chmod +x "$as_me.lineno" ||
+ { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2
+ { (exit 1); exit 1; }; }
+
+ # Don't try to exec as it changes $[0], causing all sort of problems
+ # (the dirname of $[0] is not the place where we might find the
+ # original and so on. Autoconf is especially sensitive to this).
+ . "./$as_me.lineno"
+ # Exit status is that of the last command.
+ exit
+}
+
+
+if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
+ as_dirname=dirname
+else
+ as_dirname=false
+fi
+
+ECHO_C= ECHO_N= ECHO_T=
+case `echo -n x` in
+-n*)
+ case `echo 'x\c'` in
+ *c*) ECHO_T=' ';; # ECHO_T is single tab character.
+ *) ECHO_C='\c';;
+ esac;;
+*)
+ ECHO_N='-n';;
+esac
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+ test "X`expr 00001 : '.*\(...\)'`" = X001; then
+ as_expr=expr
+else
+ as_expr=false
+fi
+
+rm -f conf$$ conf$$.exe conf$$.file
+if test -d conf$$.dir; then
+ rm -f conf$$.dir/conf$$.file
+else
+ rm -f conf$$.dir
+ mkdir conf$$.dir 2>/dev/null
+fi
+if (echo >conf$$.file) 2>/dev/null; then
+ if ln -s conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s='ln -s'
+ # ... but there are two gotchas:
+ # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
+ # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
+ # In both cases, we have to default to `cp -p'.
+ ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+ as_ln_s='cp -p'
+ elif ln conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s=ln
+ else
+ as_ln_s='cp -p'
+ fi
+else
+ as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
+rmdir conf$$.dir 2>/dev/null
+
+if mkdir -p . 2>/dev/null; then
+ as_mkdir_p=:
+else
+ test -d ./-p && rmdir ./-p
+ as_mkdir_p=false
+fi
+
+if test -x / >/dev/null 2>&1; then
+ as_test_x='test -x'
+else
+ if ls -dL / >/dev/null 2>&1; then
+ as_ls_L_option=L
+ else
+ as_ls_L_option=
+ fi
+ as_test_x='
+ eval sh -c '\''
+ if test -d "$1"; then
+ test -d "$1/.";
+ else
+ case $1 in
+ -*)set "./$1";;
+ esac;
+ case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in
+ ???[sx]*):;;*)false;;esac;fi
+ '\'' sh
+ '
+fi
+as_executable_p=$as_test_x
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+exec 6>&1
+
+# Save the log message, to keep $[0] and so on meaningful, and to
+# report actual input values of CONFIG_FILES etc. instead of their
+# values after options handling.
+ac_log="
+This file was extended by gflags $as_me 2.0, which was
+generated by GNU Autoconf 2.62. Invocation command line was
+
+ CONFIG_FILES = $CONFIG_FILES
+ CONFIG_HEADERS = $CONFIG_HEADERS
+ CONFIG_LINKS = $CONFIG_LINKS
+ CONFIG_COMMANDS = $CONFIG_COMMANDS
+ $ $0 $@
+
+on `(hostname || uname -n) 2>/dev/null | sed 1q`
+"
+
+# Files that config.status was made for.
+config_files=" Makefile src/gflags/gflags.h src/gflags/gflags_declare.h src/gflags/gflags_completions.h"
+config_headers=" src/config.h"
+config_commands=" depfiles libtool"
+
+ac_cs_usage="\
+\`$as_me' instantiates files from templates according to the
+current configuration.
+
+Usage: $0 [OPTIONS] [FILE]...
+
+ -h, --help print this help, then exit
+ -V, --version print version number and configuration settings, then exit
+ -q, --quiet do not print progress messages
+ -d, --debug don't remove temporary files
+ --recheck update $as_me by reconfiguring in the same conditions
+ --file=FILE[:TEMPLATE]
+ instantiate the configuration file FILE
+ --header=FILE[:TEMPLATE]
+ instantiate the configuration header FILE
+
+Configuration files:
+$config_files
+
+Configuration headers:
+$config_headers
+
+Configuration commands:
+$config_commands
+
+Report bugs to <bug-autoconf@gnu.org>."
+
+ac_cs_version="\
+gflags config.status 2.0
+configured by ./configure, generated by GNU Autoconf 2.62,
+ with options \"\"
+
+Copyright (C) 2008 Free Software Foundation, Inc.
+This config.status script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it."
+
+ac_pwd='/Users/hk/mongo/src/third_party/gflags-2.0'
+srcdir='.'
+INSTALL='/usr/bin/install -c'
+MKDIR_P='./install-sh -c -d'
+AWK='awk'
+test -n "$AWK" || AWK=awk
+# The default lists apply if the user does not specify any file.
+ac_need_defaults=:
+while test $# != 0
+do
+ case $1 in
+ --*=*)
+ ac_option=`expr "X$1" : 'X\([^=]*\)='`
+ ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'`
+ ac_shift=:
+ ;;
+ *)
+ ac_option=$1
+ ac_optarg=$2
+ ac_shift=shift
+ ;;
+ esac
+
+ case $ac_option in
+ # Handling of the options.
+ -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+ ac_cs_recheck=: ;;
+ --version | --versio | --versi | --vers | --ver | --ve | --v | -V )
+ $as_echo "$ac_cs_version"; exit ;;
+ --debug | --debu | --deb | --de | --d | -d )
+ debug=: ;;
+ --file | --fil | --fi | --f )
+ $ac_shift
+ case $ac_optarg in
+ *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
+ esac
+ CONFIG_FILES="$CONFIG_FILES '$ac_optarg'"
+ ac_need_defaults=false;;
+ --header | --heade | --head | --hea )
+ $ac_shift
+ case $ac_optarg in
+ *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
+ esac
+ CONFIG_HEADERS="$CONFIG_HEADERS '$ac_optarg'"
+ ac_need_defaults=false;;
+ --he | --h)
+ # Conflict between --help and --header
+ { $as_echo "$as_me: error: ambiguous option: $1
+Try \`$0 --help' for more information." >&2
+ { (exit 1); exit 1; }; };;
+ --help | --hel | -h )
+ $as_echo "$ac_cs_usage"; exit ;;
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil | --si | --s)
+ ac_cs_silent=: ;;
+
+ # This is an error.
+ -*) { $as_echo "$as_me: error: unrecognized option: $1
+Try \`$0 --help' for more information." >&2
+ { (exit 1); exit 1; }; } ;;
+
+ *) ac_config_targets="$ac_config_targets $1"
+ ac_need_defaults=false ;;
+
+ esac
+ shift
+done
+
+ac_configure_extra_args=
+
+if $ac_cs_silent; then
+ exec 6>/dev/null
+ ac_configure_extra_args="$ac_configure_extra_args --silent"
+fi
+
+if $ac_cs_recheck; then
+ set X '/bin/sh' './configure' $ac_configure_extra_args --no-create --no-recursion
+ shift
+ $as_echo "running CONFIG_SHELL=/bin/sh $*" >&6
+ CONFIG_SHELL='/bin/sh'
+ export CONFIG_SHELL
+ exec "$@"
+fi
+
+exec 5>>config.log
+{
+ echo
+ sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
+## Running $as_me. ##
+_ASBOX
+ $as_echo "$ac_log"
+} >&5
+
+#
+# INIT-COMMANDS
+#
+AMDEP_TRUE="" ac_aux_dir="."
+
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+sed_quote_subst='s/\(["`$\\]\)/\\\1/g'
+double_quote_subst='s/\(["`\\]\)/\\\1/g'
+delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g'
+enable_fast_install='needless'
+macro_version='2.2.6b'
+macro_revision='1.3017'
+enable_shared='yes'
+enable_static='yes'
+pic_mode='default'
+host_alias=''
+host='i386-apple-darwin12.2.0'
+host_os='darwin12.2.0'
+build_alias=''
+build='i386-apple-darwin12.2.0'
+build_os='darwin12.2.0'
+SED='/usr/bin/sed'
+Xsed='/usr/bin/sed -e 1s/^X//'
+GREP='/usr/bin/grep'
+EGREP='/usr/bin/grep -E'
+FGREP='/usr/bin/grep -F'
+LD='/usr/llvm-gcc-4.2/libexec/gcc/i686-apple-darwin11/4.2.1/ld'
+NM='/usr/bin/nm'
+LN_S='ln -s'
+max_cmd_len='196608'
+ac_objext='o'
+exeext=''
+lt_unset='unset'
+lt_SP2NL='tr \040 \012'
+lt_NL2SP='tr \015\012 \040\040'
+reload_flag=' -r'
+reload_cmds='$LTCC $LTCFLAGS -nostdlib ${wl}-r -o $output$reload_objs'
+OBJDUMP='false'
+deplibs_check_method='pass_all'
+file_magic_cmd='$MAGIC_CMD'
+AR='ar'
+AR_FLAGS='cru'
+STRIP='strip'
+RANLIB='ranlib'
+old_postinstall_cmds='chmod 644 $oldlib~$RANLIB $oldlib'
+old_postuninstall_cmds=''
+old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs~$RANLIB $oldlib'
+CC='gcc'
+CFLAGS='-g -O2'
+compiler='g++'
+GCC='yes'
+lt_cv_sys_global_symbol_pipe='sed -n -e '\''s/^.*[ ]\([BCDEGRST][BCDEGRST]*\)[ ][ ]*_\([_A-Za-z][_A-Za-z0-9]*\)$/\1 _\2 \2/p'\'''
+lt_cv_sys_global_symbol_to_cdecl='sed -n -e '\''s/^T .* \(.*\)$/extern int \1();/p'\'' -e '\''s/^[BCDEGRST]* .* \(.*\)$/extern char \1;/p'\'''
+lt_cv_sys_global_symbol_to_c_name_address='sed -n -e '\''s/^: \([^ ]*\) $/ {\"\1\", (void *) 0},/p'\'' -e '\''s/^[BCDEGRST]* \([^ ]*\) \([^ ]*\)$/ {"\2", (void *) \&\2},/p'\'''
+lt_cv_sys_global_symbol_to_c_name_address_lib_prefix='sed -n -e '\''s/^: \([^ ]*\) $/ {\"\1\", (void *) 0},/p'\'' -e '\''s/^[BCDEGRST]* \([^ ]*\) \(lib[^ ]*\)$/ {"\2", (void *) \&\2},/p'\'' -e '\''s/^[BCDEGRST]* \([^ ]*\) \([^ ]*\)$/ {"lib\2", (void *) \&\2},/p'\'''
+objdir='.libs'
+SHELL='/bin/sh'
+ECHO='/bin/echo'
+MAGIC_CMD='file'
+lt_prog_compiler_no_builtin_flag=' -fno-builtin'
+lt_prog_compiler_wl='-Wl,'
+lt_prog_compiler_pic=' -fno-common -DPIC'
+lt_prog_compiler_static=''
+lt_cv_prog_compiler_c_o='yes'
+need_locks='no'
+DSYMUTIL='dsymutil'
+NMEDIT='nmedit'
+LIPO='lipo'
+OTOOL='otool'
+OTOOL64=':'
+libext='a'
+shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`'
+extract_expsyms_cmds=''
+archive_cmds_need_lc='no'
+enable_shared_with_static_runtimes='no'
+export_dynamic_flag_spec=''
+whole_archive_flag_spec=''
+compiler_needs_object='no'
+old_archive_from_new_cmds=''
+old_archive_from_expsyms_cmds=''
+archive_cmds='$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring $single_module~$DSYMUTIL $lib || :'
+archive_expsym_cmds='sed '\''s,^,_,'\'' < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring $single_module ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym~$DSYMUTIL $lib || :'
+module_cmds='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs $compiler_flags~$DSYMUTIL $lib || :'
+module_expsym_cmds='sed -e '\''s,^,_,'\'' < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs $compiler_flags ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym~$DSYMUTIL $lib || :'
+with_gnu_ld='no'
+allow_undefined_flag='${wl}-undefined ${wl}dynamic_lookup'
+no_undefined_flag=''
+hardcode_libdir_flag_spec=''
+hardcode_libdir_flag_spec_ld=''
+hardcode_libdir_separator=''
+hardcode_direct='no'
+hardcode_direct_absolute='no'
+hardcode_minus_L='no'
+hardcode_shlibpath_var='unsupported'
+hardcode_automatic='yes'
+inherit_rpath='no'
+link_all_deplibs='yes'
+fix_srcfile_path=''
+always_export_symbols='no'
+export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+exclude_expsyms='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'
+include_expsyms=''
+prelink_cmds=''
+file_list_spec=''
+variables_saved_for_relink='PATH DYLD_LIBRARY_PATH GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH'
+need_lib_prefix='no'
+need_version='no'
+version_type='darwin'
+runpath_var=''
+shlibpath_var='DYLD_LIBRARY_PATH'
+shlibpath_overrides_runpath='yes'
+libname_spec='lib$name'
+library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext'
+soname_spec='${libname}${release}${major}$shared_ext'
+postinstall_cmds=''
+postuninstall_cmds=''
+finish_cmds=''
+finish_eval=''
+hardcode_into_libs='no'
+sys_lib_search_path_spec='/usr/llvm-gcc-4.2/lib/gcc/i686-apple-darwin11/4.2.1/x86_64 /usr/lib /usr/llvm-gcc-4.2/lib/gcc /usr/llvm-gcc-4.2/lib /usr/local/lib'
+sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib'
+hardcode_action='immediate'
+enable_dlopen='unknown'
+enable_dlopen_self='unknown'
+enable_dlopen_self_static='unknown'
+old_striplib='strip -S'
+striplib='strip -x'
+compiler_lib_search_dirs=''
+predep_objects=''
+postdep_objects=''
+predeps=''
+postdeps=''
+compiler_lib_search_path=''
+LD_CXX='/usr/llvm-gcc-4.2/libexec/gcc/i686-apple-darwin11/4.2.1/ld'
+old_archive_cmds_CXX='$AR $AR_FLAGS $oldlib$oldobjs~$RANLIB $oldlib'
+compiler_CXX='g++'
+GCC_CXX='yes'
+lt_prog_compiler_no_builtin_flag_CXX=' -fno-builtin'
+lt_prog_compiler_wl_CXX='-Wl,'
+lt_prog_compiler_pic_CXX=' -fno-common -DPIC'
+lt_prog_compiler_static_CXX=''
+lt_cv_prog_compiler_c_o_CXX='yes'
+archive_cmds_need_lc_CXX='no'
+enable_shared_with_static_runtimes_CXX='no'
+export_dynamic_flag_spec_CXX=''
+whole_archive_flag_spec_CXX=''
+compiler_needs_object_CXX='no'
+old_archive_from_new_cmds_CXX=''
+old_archive_from_expsyms_cmds_CXX=''
+archive_cmds_CXX='$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring $single_module~$DSYMUTIL $lib || :'
+archive_expsym_cmds_CXX='sed '\''s,^,_,'\'' < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring $single_module ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym~$DSYMUTIL $lib || :'
+module_cmds_CXX='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs $compiler_flags~$DSYMUTIL $lib || :'
+module_expsym_cmds_CXX='sed -e '\''s,^,_,'\'' < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs $compiler_flags ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym~$DSYMUTIL $lib || :'
+with_gnu_ld_CXX='no'
+allow_undefined_flag_CXX='${wl}-undefined ${wl}dynamic_lookup'
+no_undefined_flag_CXX=''
+hardcode_libdir_flag_spec_CXX=''
+hardcode_libdir_flag_spec_ld_CXX=''
+hardcode_libdir_separator_CXX=''
+hardcode_direct_CXX='no'
+hardcode_direct_absolute_CXX='no'
+hardcode_minus_L_CXX='no'
+hardcode_shlibpath_var_CXX='unsupported'
+hardcode_automatic_CXX='yes'
+inherit_rpath_CXX='no'
+link_all_deplibs_CXX='yes'
+fix_srcfile_path_CXX=''
+always_export_symbols_CXX='no'
+export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+exclude_expsyms_CXX='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'
+include_expsyms_CXX=''
+prelink_cmds_CXX=''
+file_list_spec_CXX=''
+hardcode_action_CXX='immediate'
+compiler_lib_search_dirs_CXX=''
+predep_objects_CXX=''
+postdep_objects_CXX=''
+predeps_CXX=''
+postdeps_CXX=''
+compiler_lib_search_path_CXX=''
+
+LTCC='gcc'
+LTCFLAGS='-g -O2'
+compiler='gcc'
+
+# Quote evaled strings.
+for var in SED GREP EGREP FGREP LD NM LN_S lt_SP2NL lt_NL2SP reload_flag OBJDUMP deplibs_check_method file_magic_cmd AR AR_FLAGS STRIP RANLIB CC CFLAGS compiler lt_cv_sys_global_symbol_pipe lt_cv_sys_global_symbol_to_cdecl lt_cv_sys_global_symbol_to_c_name_address lt_cv_sys_global_symbol_to_c_name_address_lib_prefix SHELL ECHO lt_prog_compiler_no_builtin_flag lt_prog_compiler_wl lt_prog_compiler_pic lt_prog_compiler_static lt_cv_prog_compiler_c_o need_locks DSYMUTIL NMEDIT LIPO OTOOL OTOOL64 shrext_cmds export_dynamic_flag_spec whole_archive_flag_spec compiler_needs_object with_gnu_ld allow_undefined_flag no_undefined_flag hardcode_libdir_flag_spec hardcode_libdir_flag_spec_ld hardcode_libdir_separator fix_srcfile_path exclude_expsyms include_expsyms file_list_spec variables_saved_for_relink libname_spec library_names_spec soname_spec finish_eval old_striplib striplib compiler_lib_search_dirs predep_objects postdep_objects predeps postdeps compiler_lib_search_path LD_CXX compiler_CXX lt_prog_compiler_no_builtin_flag_CXX lt_prog_compiler_wl_CXX lt_prog_compiler_pic_CXX lt_prog_compiler_static_CXX lt_cv_prog_compiler_c_o_CXX export_dynamic_flag_spec_CXX whole_archive_flag_spec_CXX compiler_needs_object_CXX with_gnu_ld_CXX allow_undefined_flag_CXX no_undefined_flag_CXX hardcode_libdir_flag_spec_CXX hardcode_libdir_flag_spec_ld_CXX hardcode_libdir_separator_CXX fix_srcfile_path_CXX exclude_expsyms_CXX include_expsyms_CXX file_list_spec_CXX compiler_lib_search_dirs_CXX predep_objects_CXX postdep_objects_CXX predeps_CXX postdeps_CXX compiler_lib_search_path_CXX; do
+ case `eval \\$ECHO "X\\$$var"` in
+ *[\\\`\"\$]*)
+ eval "lt_$var=\\\"\`\$ECHO \"X\$$var\" | \$Xsed -e \"\$sed_quote_subst\"\`\\\""
+ ;;
+ *)
+ eval "lt_$var=\\\"\$$var\\\""
+ ;;
+ esac
+done
+
+# Double-quote double-evaled strings.
+for var in reload_cmds old_postinstall_cmds old_postuninstall_cmds old_archive_cmds extract_expsyms_cmds old_archive_from_new_cmds old_archive_from_expsyms_cmds archive_cmds archive_expsym_cmds module_cmds module_expsym_cmds export_symbols_cmds prelink_cmds postinstall_cmds postuninstall_cmds finish_cmds sys_lib_search_path_spec sys_lib_dlsearch_path_spec old_archive_cmds_CXX old_archive_from_new_cmds_CXX old_archive_from_expsyms_cmds_CXX archive_cmds_CXX archive_expsym_cmds_CXX module_cmds_CXX module_expsym_cmds_CXX export_symbols_cmds_CXX prelink_cmds_CXX; do
+ case `eval \\$ECHO "X\\$$var"` in
+ *[\\\`\"\$]*)
+ eval "lt_$var=\\\"\`\$ECHO \"X\$$var\" | \$Xsed -e \"\$double_quote_subst\" -e \"\$sed_quote_subst\" -e \"\$delay_variable_subst\"\`\\\""
+ ;;
+ *)
+ eval "lt_$var=\\\"\$$var\\\""
+ ;;
+ esac
+done
+
+# Fix-up fallback echo if it was mangled by the above quoting rules.
+case $lt_ECHO in
+*'\$0 --fallback-echo"') lt_ECHO=`$ECHO "X$lt_ECHO" | $Xsed -e 's/\\\\\\\$0 --fallback-echo"$/$0 --fallback-echo"/'`
+ ;;
+esac
+
+ac_aux_dir='.'
+xsi_shell='yes'
+lt_shell_append='yes'
+
+# See if we are running on zsh, and set the options which allow our
+# commands through without removal of \ escapes INIT.
+if test -n "${ZSH_VERSION+set}" ; then
+ setopt NO_GLOB_SUBST
+fi
+
+
+ PACKAGE='gflags'
+ VERSION='2.0'
+ TIMESTAMP=''
+ RM='rm -f'
+ ofile='libtool'
+
+
+
+
+
+
+
+# Handling of arguments.
+for ac_config_target in $ac_config_targets
+do
+ case $ac_config_target in
+ "src/config.h") CONFIG_HEADERS="$CONFIG_HEADERS src/config.h" ;;
+ "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;;
+ "libtool") CONFIG_COMMANDS="$CONFIG_COMMANDS libtool" ;;
+ "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;;
+ "src/gflags/gflags.h") CONFIG_FILES="$CONFIG_FILES src/gflags/gflags.h" ;;
+ "src/gflags/gflags_declare.h") CONFIG_FILES="$CONFIG_FILES src/gflags/gflags_declare.h" ;;
+ "src/gflags/gflags_completions.h") CONFIG_FILES="$CONFIG_FILES src/gflags/gflags_completions.h" ;;
+
+ *) { { $as_echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5
+$as_echo "$as_me: error: invalid argument: $ac_config_target" >&2;}
+ { (exit 1); exit 1; }; };;
+ esac
+done
+
+
+# If the user did not use the arguments to specify the items to instantiate,
+# then the envvar interface is used. Set only those that are not.
+# We use the long form for the default assignment because of an extremely
+# bizarre bug on SunOS 4.1.3.
+if $ac_need_defaults; then
+ test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files
+ test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers
+ test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands
+fi
+
+# Have a temporary directory for convenience. Make it in the build tree
+# simply because there is no reason against having it here, and in addition,
+# creating and moving files from /tmp can sometimes cause problems.
+# Hook for its removal unless debugging.
+# Note that there is a small window in which the directory will not be cleaned:
+# after its creation but before its name has been assigned to `$tmp'.
+$debug ||
+{
+ tmp=
+ trap 'exit_status=$?
+ { test -z "$tmp" || test ! -d "$tmp" || rm -fr "$tmp"; } && exit $exit_status
+' 0
+ trap '{ (exit 1); exit 1; }' 1 2 13 15
+}
+# Create a (secure) tmp directory for tmp files.
+
+{
+ tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` &&
+ test -n "$tmp" && test -d "$tmp"
+} ||
+{
+ tmp=./conf$$-$RANDOM
+ (umask 077 && mkdir "$tmp")
+} ||
+{
+ $as_echo "$as_me: cannot create a temporary directory in ." >&2
+ { (exit 1); exit 1; }
+}
+
+# Set up the scripts for CONFIG_FILES section.
+# No need to generate them if there are no CONFIG_FILES.
+# This happens for instance with `./config.status config.h'.
+if test -n "$CONFIG_FILES"; then
+
+
+ac_cr=' '
+ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' </dev/null 2>/dev/null`
+if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then
+ ac_cs_awk_cr='\\r'
+else
+ ac_cs_awk_cr=$ac_cr
+fi
+
+echo 'BEGIN {' >"$tmp/subs1.awk" &&
+cat >>"$tmp/subs1.awk" <<\_ACAWK &&
+S["SHELL"]="/bin/sh"
+S["PATH_SEPARATOR"]=":"
+S["PACKAGE_NAME"]="gflags"
+S["PACKAGE_TARNAME"]="gflags"
+S["PACKAGE_VERSION"]="2.0"
+S["PACKAGE_STRING"]="gflags 2.0"
+S["PACKAGE_BUGREPORT"]="google-gflags@googlegroups.com"
+S["exec_prefix"]="${prefix}"
+S["prefix"]="/usr/local"
+S["program_transform_name"]="s,x,x,"
+S["bindir"]="${exec_prefix}/bin"
+S["sbindir"]="${exec_prefix}/sbin"
+S["libexecdir"]="${exec_prefix}/libexec"
+S["datarootdir"]="${prefix}/share"
+S["datadir"]="${datarootdir}"
+S["sysconfdir"]="${prefix}/etc"
+S["sharedstatedir"]="${prefix}/com"
+S["localstatedir"]="${prefix}/var"
+S["includedir"]="${prefix}/include"
+S["oldincludedir"]="/usr/include"
+S["docdir"]="${datarootdir}/doc/${PACKAGE_TARNAME}"
+S["infodir"]="${datarootdir}/info"
+S["htmldir"]="${docdir}"
+S["dvidir"]="${docdir}"
+S["pdfdir"]="${docdir}"
+S["psdir"]="${docdir}"
+S["libdir"]="${exec_prefix}/lib"
+S["localedir"]="${datarootdir}/locale"
+S["mandir"]="${datarootdir}/man"
+S["DEFS"]="-DHAVE_CONFIG_H"
+S["ECHO_C"]="\\c"
+S["ECHO_N"]=""
+S["ECHO_T"]=""
+S["LIBS"]=""
+S["build_alias"]=""
+S["host_alias"]=""
+S["target_alias"]=""
+S["INSTALL_PROGRAM"]="${INSTALL}"
+S["INSTALL_SCRIPT"]="${INSTALL}"
+S["INSTALL_DATA"]="${INSTALL} -m 644"
+S["am__isrc"]=""
+S["CYGPATH_W"]="echo"
+S["PACKAGE"]="gflags"
+S["VERSION"]="2.0"
+S["ACLOCAL"]="${SHELL} /Users/hk/mongo/src/third_party/gflags-2.0/missing --run aclocal-1.10"
+S["AUTOCONF"]="${SHELL} /Users/hk/mongo/src/third_party/gflags-2.0/missing --run autoconf"
+S["AUTOMAKE"]="${SHELL} /Users/hk/mongo/src/third_party/gflags-2.0/missing --run automake-1.10"
+S["AUTOHEADER"]="${SHELL} /Users/hk/mongo/src/third_party/gflags-2.0/missing --run autoheader"
+S["MAKEINFO"]="${SHELL} /Users/hk/mongo/src/third_party/gflags-2.0/missing --run makeinfo"
+S["install_sh"]="$(SHELL) /Users/hk/mongo/src/third_party/gflags-2.0/install-sh"
+S["STRIP"]="strip"
+S["INSTALL_STRIP_PROGRAM"]="$(install_sh) -c -s"
+S["MKDIR_P"]="./install-sh -c -d"
+S["mkdir_p"]="$(top_builddir)/./install-sh -c -d"
+S["AWK"]="awk"
+S["SET_MAKE"]=""
+S["am__leading_dot"]="."
+S["AMTAR"]="${SHELL} /Users/hk/mongo/src/third_party/gflags-2.0/missing --run tar"
+S["am__tar"]="${AMTAR} chof - \"$$tardir\""
+S["am__untar"]="${AMTAR} xf -"
+S["CXX"]="g++"
+S["CXXFLAGS"]="-g -O2"
+S["LDFLAGS"]=""
+S["CPPFLAGS"]=""
+S["ac_ct_CXX"]="g++"
+S["EXEEXT"]=""
+S["OBJEXT"]="o"
+S["DEPDIR"]=".deps"
+S["am__include"]="include"
+S["am__quote"]=""
+S["AMDEP_TRUE"]=""
+S["AMDEP_FALSE"]="#"
+S["AMDEPBACKSLASH"]="\\"
+S["CXXDEPMODE"]="depmode=gcc3"
+S["am__fastdepCXX_TRUE"]=""
+S["am__fastdepCXX_FALSE"]="#"
+S["CC"]="gcc"
+S["CFLAGS"]="-g -O2"
+S["ac_ct_CC"]="gcc"
+S["CCDEPMODE"]="depmode=gcc3"
+S["am__fastdepCC_TRUE"]=""
+S["am__fastdepCC_FALSE"]="#"
+S["CPP"]="gcc -E"
+S["GCC_TRUE"]=""
+S["GCC_FALSE"]="#"
+S["build"]="i386-apple-darwin12.2.0"
+S["build_cpu"]="i386"
+S["build_vendor"]="apple"
+S["build_os"]="darwin12.2.0"
+S["host"]="i386-apple-darwin12.2.0"
+S["host_cpu"]="i386"
+S["host_vendor"]="apple"
+S["host_os"]="darwin12.2.0"
+S["TEST_TMPDIR"]="/tmp/gflags"
+S["LIBTOOL"]="$(SHELL) $(top_builddir)/libtool"
+S["SED"]="/usr/bin/sed"
+S["GREP"]="/usr/bin/grep"
+S["EGREP"]="/usr/bin/grep -E"
+S["FGREP"]="/usr/bin/grep -F"
+S["LD"]="/usr/llvm-gcc-4.2/libexec/gcc/i686-apple-darwin11/4.2.1/ld"
+S["DUMPBIN"]=""
+S["ac_ct_DUMPBIN"]=""
+S["NM"]="/usr/bin/nm"
+S["LN_S"]="ln -s"
+S["OBJDUMP"]="false"
+S["AR"]="ar"
+S["RANLIB"]="ranlib"
+S["lt_ECHO"]="/bin/echo"
+S["DSYMUTIL"]="dsymutil"
+S["NMEDIT"]="nmedit"
+S["LIPO"]="lipo"
+S["OTOOL"]="otool"
+S["OTOOL64"]=":"
+S["CXXCPP"]="g++ -E"
+S["LIBTOOL_DEPS"]="./ltmain.sh"
+S["SO_VERSION"]="3:0:1"
+S["acx_pthread_config"]=""
+S["PTHREAD_CC"]="gcc"
+S["PTHREAD_LIBS"]=""
+S["PTHREAD_CFLAGS"]="-D_THREAD_SAFE "
+S["LIBSTDCXX_LA_LINKER_FLAG"]=""
+S["ac_google_start_namespace"]="namespace google {"
+S["ac_google_end_namespace"]="}"
+S["ac_google_namespace"]="::google"
+S["ac_cv___attribute__unused"]="__attribute__ ((unused))"
+S["ac_cv_have_stdint_h"]="1"
+S["ac_cv_have_systypes_h"]="1"
+S["ac_cv_have_inttypes_h"]="1"
+S["ac_cv_have_uint16_t"]="1"
+S["ac_cv_have_u_int16_t"]="1"
+S["ac_cv_have___int16"]="0"
+S["LIBOBJS"]=""
+S["LTLIBOBJS"]=""
+_ACAWK
+cat >>"$tmp/subs1.awk" <<_ACAWK &&
+ for (key in S) S_is_set[key] = 1
+ FS = ""
+
+}
+{
+ line = $ 0
+ nfields = split(line, field, "@")
+ substed = 0
+ len = length(field[1])
+ for (i = 2; i < nfields; i++) {
+ key = field[i]
+ keylen = length(key)
+ if (S_is_set[key]) {
+ value = S[key]
+ line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3)
+ len += length(value) + length(field[++i])
+ substed = 1
+ } else
+ len += 1 + keylen
+ }
+
+ print line
+}
+
+_ACAWK
+if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then
+ sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g"
+else
+ cat
+fi < "$tmp/subs1.awk" > "$tmp/subs.awk" \
+ || { { $as_echo "$as_me:$LINENO: error: could not setup config files machinery" >&5
+$as_echo "$as_me: error: could not setup config files machinery" >&2;}
+ { (exit 1); exit 1; }; }
+fi # test -n "$CONFIG_FILES"
+
+# Set up the scripts for CONFIG_HEADERS section.
+# No need to generate them if there are no CONFIG_HEADERS.
+# This happens for instance with `./config.status Makefile'.
+if test -n "$CONFIG_HEADERS"; then
+cat >"$tmp/defines.awk" <<\_ACAWK ||
+BEGIN {
+D["PACKAGE_NAME"]=" \"gflags\""
+D["PACKAGE_TARNAME"]=" \"gflags\""
+D["PACKAGE_VERSION"]=" \"2.0\""
+D["PACKAGE_STRING"]=" \"gflags 2.0\""
+D["PACKAGE_BUGREPORT"]=" \"google-gflags@googlegroups.com\""
+D["PACKAGE"]=" \"gflags\""
+D["VERSION"]=" \"2.0\""
+D["STDC_HEADERS"]=" 1"
+D["HAVE_SYS_TYPES_H"]=" 1"
+D["HAVE_SYS_STAT_H"]=" 1"
+D["HAVE_STDLIB_H"]=" 1"
+D["HAVE_STRING_H"]=" 1"
+D["HAVE_MEMORY_H"]=" 1"
+D["HAVE_STRINGS_H"]=" 1"
+D["HAVE_INTTYPES_H"]=" 1"
+D["HAVE_STDINT_H"]=" 1"
+D["HAVE_UNISTD_H"]=" 1"
+D["HAVE_DLFCN_H"]=" 1"
+D["LT_OBJDIR"]=" \".libs/\""
+D["STDC_HEADERS"]=" 1"
+D["HAVE_FNMATCH_H"]=" 1"
+D["HAVE_SYS_STAT_H"]=" 1"
+D["HAVE_UNISTD_H"]=" 1"
+D["HAVE_STRTOLL"]=" 1"
+D["HAVE_STRTOQ"]=" 1"
+D["HAVE___ATTRIBUTE__"]=" 1"
+D["HAVE_PTHREAD"]=" 1"
+D["HAVE_NAMESPACES"]=" 1"
+D["STL_NAMESPACE"]=" std"
+D["GOOGLE_NAMESPACE"]=" ::google"
+D["_START_GOOGLE_NAMESPACE_"]=" namespace google {"
+D["_END_GOOGLE_NAMESPACE_"]=" }"
+D["GFLAGS_DLL_DECL"]=" /**/"
+ for (key in D) D_is_set[key] = 1
+ FS = ""
+}
+/^[\t ]*#[\t ]*(define|undef)[\t ]+[_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ][_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789]*([\t (]|$)/ {
+ line = $ 0
+ split(line, arg, " ")
+ if (arg[1] == "#") {
+ defundef = arg[2]
+ mac1 = arg[3]
+ } else {
+ defundef = substr(arg[1], 2)
+ mac1 = arg[2]
+ }
+ split(mac1, mac2, "(") #)
+ macro = mac2[1]
+ if (D_is_set[macro]) {
+ # Preserve the white space surrounding the "#".
+ prefix = substr(line, 1, index(line, defundef) - 1)
+ print prefix "define", macro P[macro] D[macro]
+ next
+ } else {
+ # Replace #undef with comments. This is necessary, for example,
+ # in the case of _POSIX_SOURCE, which is predefined and required
+ # on some systems where configure will not decide to define it.
+ if (defundef == "undef") {
+ print "/*", line, "*/"
+ next
+ }
+ }
+}
+{ print }
+_ACAWK
+ { { $as_echo "$as_me:$LINENO: error: could not setup config headers machinery" >&5
+$as_echo "$as_me: error: could not setup config headers machinery" >&2;}
+ { (exit 1); exit 1; }; }
+fi # test -n "$CONFIG_HEADERS"
+
+
+eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS :C $CONFIG_COMMANDS"
+shift
+for ac_tag
+do
+ case $ac_tag in
+ :[FHLC]) ac_mode=$ac_tag; continue;;
+ esac
+ case $ac_mode$ac_tag in
+ :[FHL]*:*);;
+ :L* | :C*:*) { { $as_echo "$as_me:$LINENO: error: Invalid tag $ac_tag." >&5
+$as_echo "$as_me: error: Invalid tag $ac_tag." >&2;}
+ { (exit 1); exit 1; }; };;
+ :[FH]-) ac_tag=-:-;;
+ :[FH]*) ac_tag=$ac_tag:$ac_tag.in;;
+ esac
+ ac_save_IFS=$IFS
+ IFS=:
+ set x $ac_tag
+ IFS=$ac_save_IFS
+ shift
+ ac_file=$1
+ shift
+
+ case $ac_mode in
+ :L) ac_source=$1;;
+ :[FH])
+ ac_file_inputs=
+ for ac_f
+ do
+ case $ac_f in
+ -) ac_f="$tmp/stdin";;
+ *) # Look for the file first in the build tree, then in the source tree
+ # (if the path is not absolute). The absolute path cannot be DOS-style,
+ # because $ac_f cannot contain `:'.
+ test -f "$ac_f" ||
+ case $ac_f in
+ [\\/$]*) false;;
+ *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";;
+ esac ||
+ { { $as_echo "$as_me:$LINENO: error: cannot find input file: $ac_f" >&5
+$as_echo "$as_me: error: cannot find input file: $ac_f" >&2;}
+ { (exit 1); exit 1; }; };;
+ esac
+ case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac
+ ac_file_inputs="$ac_file_inputs '$ac_f'"
+ done
+
+ # Let's still pretend it is `configure' which instantiates (i.e., don't
+ # use $as_me), people would be surprised to read:
+ # /* config.h. Generated by config.status. */
+ configure_input='Generated from '`
+ $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g'
+ `' by configure.'
+ if test x"$ac_file" != x-; then
+ configure_input="$ac_file. $configure_input"
+ { $as_echo "$as_me:$LINENO: creating $ac_file" >&5
+$as_echo "$as_me: creating $ac_file" >&6;}
+ fi
+ # Neutralize special characters interpreted by sed in replacement strings.
+ case $configure_input in #(
+ *\&* | *\|* | *\\* )
+ ac_sed_conf_input=`$as_echo "$configure_input" |
+ sed 's/[\\\\&|]/\\\\&/g'`;; #(
+ *) ac_sed_conf_input=$configure_input;;
+ esac
+
+ case $ac_tag in
+ *:-:* | *:-) cat >"$tmp/stdin" \
+ || { { $as_echo "$as_me:$LINENO: error: could not create $ac_file" >&5
+$as_echo "$as_me: error: could not create $ac_file" >&2;}
+ { (exit 1); exit 1; }; } ;;
+ esac
+ ;;
+ esac
+
+ ac_dir=`$as_dirname -- "$ac_file" ||
+$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$ac_file" : 'X\(//\)[^/]' \| \
+ X"$ac_file" : 'X\(//\)$' \| \
+ X"$ac_file" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$ac_file" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ { as_dir="$ac_dir"
+ case $as_dir in #(
+ -*) as_dir=./$as_dir;;
+ esac
+ test -d "$as_dir" || { $as_mkdir_p && mkdir -p "$as_dir"; } || {
+ as_dirs=
+ while :; do
+ case $as_dir in #(
+ *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
+ *) as_qdir=$as_dir;;
+ esac
+ as_dirs="'$as_qdir' $as_dirs"
+ as_dir=`$as_dirname -- "$as_dir" ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$as_dir" : 'X\(//\)[^/]' \| \
+ X"$as_dir" : 'X\(//\)$' \| \
+ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_dir" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ test -d "$as_dir" && break
+ done
+ test -z "$as_dirs" || eval "mkdir $as_dirs"
+ } || test -d "$as_dir" || { { $as_echo "$as_me:$LINENO: error: cannot create directory $as_dir" >&5
+$as_echo "$as_me: error: cannot create directory $as_dir" >&2;}
+ { (exit 1); exit 1; }; }; }
+ ac_builddir=.
+
+case "$ac_dir" in
+.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
+*)
+ ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
+ # A ".." for each directory in $ac_dir_suffix.
+ ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
+ case $ac_top_builddir_sub in
+ "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
+ *) ac_top_build_prefix=$ac_top_builddir_sub/ ;;
+ esac ;;
+esac
+ac_abs_top_builddir=$ac_pwd
+ac_abs_builddir=$ac_pwd$ac_dir_suffix
+# for backward compatibility:
+ac_top_builddir=$ac_top_build_prefix
+
+case $srcdir in
+ .) # We are building in place.
+ ac_srcdir=.
+ ac_top_srcdir=$ac_top_builddir_sub
+ ac_abs_top_srcdir=$ac_pwd ;;
+ [\\/]* | ?:[\\/]* ) # Absolute name.
+ ac_srcdir=$srcdir$ac_dir_suffix;
+ ac_top_srcdir=$srcdir
+ ac_abs_top_srcdir=$srcdir ;;
+ *) # Relative name.
+ ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
+ ac_top_srcdir=$ac_top_build_prefix$srcdir
+ ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
+esac
+ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
+
+
+ case $ac_mode in
+ :F)
+ #
+ # CONFIG_FILE
+ #
+
+ case $INSTALL in
+ [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;;
+ *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;;
+ esac
+ ac_MKDIR_P=$MKDIR_P
+ case $MKDIR_P in
+ [\\/$]* | ?:[\\/]* ) ;;
+ */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;;
+ esac
+# If the template does not know about datarootdir, expand it.
+# FIXME: This hack should be removed a few years after 2.60.
+ac_datarootdir_hack=; ac_datarootdir_seen=
+
+ac_sed_dataroot='
+/datarootdir/ {
+ p
+ q
+}
+/@datadir@/p
+/@docdir@/p
+/@infodir@/p
+/@localedir@/p
+/@mandir@/p
+'
+case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in
+*datarootdir*) ac_datarootdir_seen=yes;;
+*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*)
+ { $as_echo "$as_me:$LINENO: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5
+$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;}
+ ac_datarootdir_hack='
+ s&@datadir@&${datarootdir}&g
+ s&@docdir@&${datarootdir}/doc/${PACKAGE_TARNAME}&g
+ s&@infodir@&${datarootdir}/info&g
+ s&@localedir@&${datarootdir}/locale&g
+ s&@mandir@&${datarootdir}/man&g
+ s&\${datarootdir}&${prefix}/share&g' ;;
+esac
+ac_sed_extra="/^[ ]*VPATH[ ]*=/{
+s/:*\$(srcdir):*/:/
+s/:*\${srcdir}:*/:/
+s/:*@srcdir@:*/:/
+s/^\([^=]*=[ ]*\):*/\1/
+s/:*$//
+s/^[^=]*=[ ]*$//
+}
+
+:t
+/@[a-zA-Z_][a-zA-Z_0-9]*@/!b
+s|@configure_input@|$ac_sed_conf_input|;t t
+s&@top_builddir@&$ac_top_builddir_sub&;t t
+s&@top_build_prefix@&$ac_top_build_prefix&;t t
+s&@srcdir@&$ac_srcdir&;t t
+s&@abs_srcdir@&$ac_abs_srcdir&;t t
+s&@top_srcdir@&$ac_top_srcdir&;t t
+s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t
+s&@builddir@&$ac_builddir&;t t
+s&@abs_builddir@&$ac_abs_builddir&;t t
+s&@abs_top_builddir@&$ac_abs_top_builddir&;t t
+s&@INSTALL@&$ac_INSTALL&;t t
+s&@MKDIR_P@&$ac_MKDIR_P&;t t
+$ac_datarootdir_hack
+"
+eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$tmp/subs.awk" >$tmp/out \
+ || { { $as_echo "$as_me:$LINENO: error: could not create $ac_file" >&5
+$as_echo "$as_me: error: could not create $ac_file" >&2;}
+ { (exit 1); exit 1; }; }
+
+test -z "$ac_datarootdir_hack$ac_datarootdir_seen" &&
+ { ac_out=`sed -n '/\${datarootdir}/p' "$tmp/out"`; test -n "$ac_out"; } &&
+ { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' "$tmp/out"`; test -z "$ac_out"; } &&
+ { $as_echo "$as_me:$LINENO: WARNING: $ac_file contains a reference to the variable \`datarootdir'
+which seems to be undefined. Please make sure it is defined." >&5
+$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir'
+which seems to be undefined. Please make sure it is defined." >&2;}
+
+ rm -f "$tmp/stdin"
+ case $ac_file in
+ -) cat "$tmp/out" && rm -f "$tmp/out";;
+ *) rm -f "$ac_file" && mv "$tmp/out" "$ac_file";;
+ esac \
+ || { { $as_echo "$as_me:$LINENO: error: could not create $ac_file" >&5
+$as_echo "$as_me: error: could not create $ac_file" >&2;}
+ { (exit 1); exit 1; }; }
+ ;;
+ :H)
+ #
+ # CONFIG_HEADER
+ #
+ if test x"$ac_file" != x-; then
+ {
+ $as_echo "/* $configure_input */" \
+ && eval '$AWK -f "$tmp/defines.awk"' "$ac_file_inputs"
+ } >"$tmp/config.h" \
+ || { { $as_echo "$as_me:$LINENO: error: could not create $ac_file" >&5
+$as_echo "$as_me: error: could not create $ac_file" >&2;}
+ { (exit 1); exit 1; }; }
+ if diff "$ac_file" "$tmp/config.h" >/dev/null 2>&1; then
+ { $as_echo "$as_me:$LINENO: $ac_file is unchanged" >&5
+$as_echo "$as_me: $ac_file is unchanged" >&6;}
+ else
+ rm -f "$ac_file"
+ mv "$tmp/config.h" "$ac_file" \
+ || { { $as_echo "$as_me:$LINENO: error: could not create $ac_file" >&5
+$as_echo "$as_me: error: could not create $ac_file" >&2;}
+ { (exit 1); exit 1; }; }
+ fi
+ else
+ $as_echo "/* $configure_input */" \
+ && eval '$AWK -f "$tmp/defines.awk"' "$ac_file_inputs" \
+ || { { $as_echo "$as_me:$LINENO: error: could not create -" >&5
+$as_echo "$as_me: error: could not create -" >&2;}
+ { (exit 1); exit 1; }; }
+ fi
+# Compute "$ac_file"'s index in $config_headers.
+_am_arg="$ac_file"
+_am_stamp_count=1
+for _am_header in $config_headers :; do
+ case $_am_header in
+ $_am_arg | $_am_arg:* )
+ break ;;
+ * )
+ _am_stamp_count=`expr $_am_stamp_count + 1` ;;
+ esac
+done
+echo "timestamp for $_am_arg" >`$as_dirname -- "$_am_arg" ||
+$as_expr X"$_am_arg" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$_am_arg" : 'X\(//\)[^/]' \| \
+ X"$_am_arg" : 'X\(//\)$' \| \
+ X"$_am_arg" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$_am_arg" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`/stamp-h$_am_stamp_count
+ ;;
+
+ :C) { $as_echo "$as_me:$LINENO: executing $ac_file commands" >&5
+$as_echo "$as_me: executing $ac_file commands" >&6;}
+ ;;
+ esac
+
+
+ case $ac_file$ac_mode in
+ "depfiles":C) test x"$AMDEP_TRUE" != x"" || for mf in $CONFIG_FILES; do
+ # Strip MF so we end up with the name of the file.
+ mf=`echo "$mf" | sed -e 's/:.*$//'`
+ # Check whether this is an Automake generated Makefile or not.
+ # We used to match only the files named `Makefile.in', but
+ # some people rename them; so instead we look at the file content.
+ # Grep'ing the first line is not enough: some people post-process
+ # each Makefile.in and add a new line on top of each file to say so.
+ # Grep'ing the whole file is not good either: AIX grep has a line
+ # limit of 2048, but all sed's we know have understand at least 4000.
+ if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then
+ dirpart=`$as_dirname -- "$mf" ||
+$as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$mf" : 'X\(//\)[^/]' \| \
+ X"$mf" : 'X\(//\)$' \| \
+ X"$mf" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$mf" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ else
+ continue
+ fi
+ # Extract the definition of DEPDIR, am__include, and am__quote
+ # from the Makefile without running `make'.
+ DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"`
+ test -z "$DEPDIR" && continue
+ am__include=`sed -n 's/^am__include = //p' < "$mf"`
+ test -z "am__include" && continue
+ am__quote=`sed -n 's/^am__quote = //p' < "$mf"`
+ # When using ansi2knr, U may be empty or an underscore; expand it
+ U=`sed -n 's/^U = //p' < "$mf"`
+ # Find all dependency output files, they are included files with
+ # $(DEPDIR) in their names. We invoke sed twice because it is the
+ # simplest approach to changing $(DEPDIR) to its actual value in the
+ # expansion.
+ for file in `sed -n "
+ s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \
+ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do
+ # Make sure the directory exists.
+ test -f "$dirpart/$file" && continue
+ fdir=`$as_dirname -- "$file" ||
+$as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$file" : 'X\(//\)[^/]' \| \
+ X"$file" : 'X\(//\)$' \| \
+ X"$file" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$file" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ { as_dir=$dirpart/$fdir
+ case $as_dir in #(
+ -*) as_dir=./$as_dir;;
+ esac
+ test -d "$as_dir" || { $as_mkdir_p && mkdir -p "$as_dir"; } || {
+ as_dirs=
+ while :; do
+ case $as_dir in #(
+ *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
+ *) as_qdir=$as_dir;;
+ esac
+ as_dirs="'$as_qdir' $as_dirs"
+ as_dir=`$as_dirname -- "$as_dir" ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$as_dir" : 'X\(//\)[^/]' \| \
+ X"$as_dir" : 'X\(//\)$' \| \
+ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_dir" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ test -d "$as_dir" && break
+ done
+ test -z "$as_dirs" || eval "mkdir $as_dirs"
+ } || test -d "$as_dir" || { { $as_echo "$as_me:$LINENO: error: cannot create directory $as_dir" >&5
+$as_echo "$as_me: error: cannot create directory $as_dir" >&2;}
+ { (exit 1); exit 1; }; }; }
+ # echo "creating $dirpart/$file"
+ echo '# dummy' > "$dirpart/$file"
+ done
+done
+ ;;
+ "libtool":C)
+
+ # See if we are running on zsh, and set the options which allow our
+ # commands through without removal of \ escapes.
+ if test -n "${ZSH_VERSION+set}" ; then
+ setopt NO_GLOB_SUBST
+ fi
+
+ cfgfile="${ofile}T"
+ trap "$RM \"$cfgfile\"; exit 1" 1 2 15
+ $RM "$cfgfile"
+
+ cat <<_LT_EOF >> "$cfgfile"
+#! $SHELL
+
+# `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services.
+# Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $VERSION
+# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+# NOTE: Changes made to this file will be lost: look at ltmain.sh.
+#
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005,
+# 2006, 2007, 2008 Free Software Foundation, Inc.
+# Written by Gordon Matzigkeit, 1996
+#
+# This file is part of GNU Libtool.
+#
+# GNU Libtool is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# As a special exception to the GNU General Public License,
+# if you distribute this file as part of a program or library that
+# is built using GNU Libtool, you may include this file under the
+# same distribution terms that you use for the rest of that program.
+#
+# GNU Libtool is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Libtool; see the file COPYING. If not, a copy
+# can be downloaded from http://www.gnu.org/licenses/gpl.html, or
+# obtained by writing to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+
+# The names of the tagged configurations supported by this script.
+available_tags="CXX "
+
+# ### BEGIN LIBTOOL CONFIG
+
+# Whether or not to optimize for fast installation.
+fast_install=$enable_fast_install
+
+# Which release of libtool.m4 was used?
+macro_version=$macro_version
+macro_revision=$macro_revision
+
+# Whether or not to build shared libraries.
+build_libtool_libs=$enable_shared
+
+# Whether or not to build static libraries.
+build_old_libs=$enable_static
+
+# What type of objects to build.
+pic_mode=$pic_mode
+
+# The host system.
+host_alias=$host_alias
+host=$host
+host_os=$host_os
+
+# The build system.
+build_alias=$build_alias
+build=$build
+build_os=$build_os
+
+# A sed program that does not truncate output.
+SED=$lt_SED
+
+# Sed that helps us avoid accidentally triggering echo(1) options like -n.
+Xsed="\$SED -e 1s/^X//"
+
+# A grep program that handles long lines.
+GREP=$lt_GREP
+
+# An ERE matcher.
+EGREP=$lt_EGREP
+
+# A literal string matcher.
+FGREP=$lt_FGREP
+
+# A BSD- or MS-compatible name lister.
+NM=$lt_NM
+
+# Whether we need soft or hard links.
+LN_S=$lt_LN_S
+
+# What is the maximum length of a command?
+max_cmd_len=$max_cmd_len
+
+# Object file suffix (normally "o").
+objext=$ac_objext
+
+# Executable file suffix (normally "").
+exeext=$exeext
+
+# whether the shell understands "unset".
+lt_unset=$lt_unset
+
+# turn spaces into newlines.
+SP2NL=$lt_lt_SP2NL
+
+# turn newlines into spaces.
+NL2SP=$lt_lt_NL2SP
+
+# How to create reloadable object files.
+reload_flag=$lt_reload_flag
+reload_cmds=$lt_reload_cmds
+
+# An object symbol dumper.
+OBJDUMP=$lt_OBJDUMP
+
+# Method to check whether dependent libraries are shared objects.
+deplibs_check_method=$lt_deplibs_check_method
+
+# Command to use when deplibs_check_method == "file_magic".
+file_magic_cmd=$lt_file_magic_cmd
+
+# The archiver.
+AR=$lt_AR
+AR_FLAGS=$lt_AR_FLAGS
+
+# A symbol stripping program.
+STRIP=$lt_STRIP
+
+# Commands used to install an old-style archive.
+RANLIB=$lt_RANLIB
+old_postinstall_cmds=$lt_old_postinstall_cmds
+old_postuninstall_cmds=$lt_old_postuninstall_cmds
+
+# A C compiler.
+LTCC=$lt_CC
+
+# LTCC compiler flags.
+LTCFLAGS=$lt_CFLAGS
+
+# Take the output of nm and produce a listing of raw symbols and C names.
+global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe
+
+# Transform the output of nm in a proper C declaration.
+global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl
+
+# Transform the output of nm in a C name address pair.
+global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address
+
+# Transform the output of nm in a C name address pair when lib prefix is needed.
+global_symbol_to_c_name_address_lib_prefix=$lt_lt_cv_sys_global_symbol_to_c_name_address_lib_prefix
+
+# The name of the directory that contains temporary libtool files.
+objdir=$objdir
+
+# Shell to use when invoking shell scripts.
+SHELL=$lt_SHELL
+
+# An echo program that does not interpret backslashes.
+ECHO=$lt_ECHO
+
+# Used to examine libraries when file_magic_cmd begins with "file".
+MAGIC_CMD=$MAGIC_CMD
+
+# Must we lock files when doing compilation?
+need_locks=$lt_need_locks
+
+# Tool to manipulate archived DWARF debug symbol files on Mac OS X.
+DSYMUTIL=$lt_DSYMUTIL
+
+# Tool to change global to local symbols on Mac OS X.
+NMEDIT=$lt_NMEDIT
+
+# Tool to manipulate fat objects and archives on Mac OS X.
+LIPO=$lt_LIPO
+
+# ldd/readelf like tool for Mach-O binaries on Mac OS X.
+OTOOL=$lt_OTOOL
+
+# ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4.
+OTOOL64=$lt_OTOOL64
+
+# Old archive suffix (normally "a").
+libext=$libext
+
+# Shared library suffix (normally ".so").
+shrext_cmds=$lt_shrext_cmds
+
+# The commands to extract the exported symbol list from a shared archive.
+extract_expsyms_cmds=$lt_extract_expsyms_cmds
+
+# Variables whose values should be saved in libtool wrapper scripts and
+# restored at link time.
+variables_saved_for_relink=$lt_variables_saved_for_relink
+
+# Do we need the "lib" prefix for modules?
+need_lib_prefix=$need_lib_prefix
+
+# Do we need a version for libraries?
+need_version=$need_version
+
+# Library versioning type.
+version_type=$version_type
+
+# Shared library runtime path variable.
+runpath_var=$runpath_var
+
+# Shared library path variable.
+shlibpath_var=$shlibpath_var
+
+# Is shlibpath searched before the hard-coded library search path?
+shlibpath_overrides_runpath=$shlibpath_overrides_runpath
+
+# Format of library name prefix.
+libname_spec=$lt_libname_spec
+
+# List of archive names. First name is the real one, the rest are links.
+# The last name is the one that the linker finds with -lNAME
+library_names_spec=$lt_library_names_spec
+
+# The coded name of the library, if different from the real name.
+soname_spec=$lt_soname_spec
+
+# Command to use after installation of a shared archive.
+postinstall_cmds=$lt_postinstall_cmds
+
+# Command to use after uninstallation of a shared archive.
+postuninstall_cmds=$lt_postuninstall_cmds
+
+# Commands used to finish a libtool library installation in a directory.
+finish_cmds=$lt_finish_cmds
+
+# As "finish_cmds", except a single script fragment to be evaled but
+# not shown.
+finish_eval=$lt_finish_eval
+
+# Whether we should hardcode library paths into libraries.
+hardcode_into_libs=$hardcode_into_libs
+
+# Compile-time system search path for libraries.
+sys_lib_search_path_spec=$lt_sys_lib_search_path_spec
+
+# Run-time system search path for libraries.
+sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec
+
+# Whether dlopen is supported.
+dlopen_support=$enable_dlopen
+
+# Whether dlopen of programs is supported.
+dlopen_self=$enable_dlopen_self
+
+# Whether dlopen of statically linked programs is supported.
+dlopen_self_static=$enable_dlopen_self_static
+
+# Commands to strip libraries.
+old_striplib=$lt_old_striplib
+striplib=$lt_striplib
+
+
+# The linker used to build libraries.
+LD=$lt_LD
+
+# Commands used to build an old-style archive.
+old_archive_cmds=$lt_old_archive_cmds
+
+# A language specific compiler.
+CC=$lt_compiler
+
+# Is the compiler the GNU compiler?
+with_gcc=$GCC
+
+# Compiler flag to turn off builtin functions.
+no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag
+
+# How to pass a linker flag through the compiler.
+wl=$lt_lt_prog_compiler_wl
+
+# Additional compiler flags for building library objects.
+pic_flag=$lt_lt_prog_compiler_pic
+
+# Compiler flag to prevent dynamic linking.
+link_static_flag=$lt_lt_prog_compiler_static
+
+# Does compiler simultaneously support -c and -o options?
+compiler_c_o=$lt_lt_cv_prog_compiler_c_o
+
+# Whether or not to add -lc for building shared libraries.
+build_libtool_need_lc=$archive_cmds_need_lc
+
+# Whether or not to disallow shared libs when runtime libs are static.
+allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes
+
+# Compiler flag to allow reflexive dlopens.
+export_dynamic_flag_spec=$lt_export_dynamic_flag_spec
+
+# Compiler flag to generate shared objects directly from archives.
+whole_archive_flag_spec=$lt_whole_archive_flag_spec
+
+# Whether the compiler copes with passing no objects directly.
+compiler_needs_object=$lt_compiler_needs_object
+
+# Create an old-style archive from a shared archive.
+old_archive_from_new_cmds=$lt_old_archive_from_new_cmds
+
+# Create a temporary old-style archive to link instead of a shared archive.
+old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds
+
+# Commands used to build a shared archive.
+archive_cmds=$lt_archive_cmds
+archive_expsym_cmds=$lt_archive_expsym_cmds
+
+# Commands used to build a loadable module if different from building
+# a shared archive.
+module_cmds=$lt_module_cmds
+module_expsym_cmds=$lt_module_expsym_cmds
+
+# Whether we are building with GNU ld or not.
+with_gnu_ld=$lt_with_gnu_ld
+
+# Flag that allows shared libraries with undefined symbols to be built.
+allow_undefined_flag=$lt_allow_undefined_flag
+
+# Flag that enforces no undefined symbols.
+no_undefined_flag=$lt_no_undefined_flag
+
+# Flag to hardcode \$libdir into a binary during linking.
+# This must work even if \$libdir does not exist
+hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec
+
+# If ld is used when linking, flag to hardcode \$libdir into a binary
+# during linking. This must work even if \$libdir does not exist.
+hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld
+
+# Whether we need a single "-rpath" flag with a separated argument.
+hardcode_libdir_separator=$lt_hardcode_libdir_separator
+
+# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes
+# DIR into the resulting binary.
+hardcode_direct=$hardcode_direct
+
+# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes
+# DIR into the resulting binary and the resulting library dependency is
+# "absolute",i.e impossible to change by setting \${shlibpath_var} if the
+# library is relocated.
+hardcode_direct_absolute=$hardcode_direct_absolute
+
+# Set to "yes" if using the -LDIR flag during linking hardcodes DIR
+# into the resulting binary.
+hardcode_minus_L=$hardcode_minus_L
+
+# Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR
+# into the resulting binary.
+hardcode_shlibpath_var=$hardcode_shlibpath_var
+
+# Set to "yes" if building a shared library automatically hardcodes DIR
+# into the library and all subsequent libraries and executables linked
+# against it.
+hardcode_automatic=$hardcode_automatic
+
+# Set to yes if linker adds runtime paths of dependent libraries
+# to runtime path list.
+inherit_rpath=$inherit_rpath
+
+# Whether libtool must link a program against all its dependency libraries.
+link_all_deplibs=$link_all_deplibs
+
+# Fix the shell variable \$srcfile for the compiler.
+fix_srcfile_path=$lt_fix_srcfile_path
+
+# Set to "yes" if exported symbols are required.
+always_export_symbols=$always_export_symbols
+
+# The commands to list exported symbols.
+export_symbols_cmds=$lt_export_symbols_cmds
+
+# Symbols that should not be listed in the preloaded symbols.
+exclude_expsyms=$lt_exclude_expsyms
+
+# Symbols that must always be exported.
+include_expsyms=$lt_include_expsyms
+
+# Commands necessary for linking programs (against libraries) with templates.
+prelink_cmds=$lt_prelink_cmds
+
+# Specify filename containing input files.
+file_list_spec=$lt_file_list_spec
+
+# How to hardcode a shared library path into an executable.
+hardcode_action=$hardcode_action
+
+# The directories searched by this compiler when creating a shared library.
+compiler_lib_search_dirs=$lt_compiler_lib_search_dirs
+
+# Dependencies to place before and after the objects being linked to
+# create a shared library.
+predep_objects=$lt_predep_objects
+postdep_objects=$lt_postdep_objects
+predeps=$lt_predeps
+postdeps=$lt_postdeps
+
+# The library search path used internally by the compiler when linking
+# a shared library.
+compiler_lib_search_path=$lt_compiler_lib_search_path
+
+# ### END LIBTOOL CONFIG
+
+_LT_EOF
+
+ case $host_os in
+ aix3*)
+ cat <<\_LT_EOF >> "$cfgfile"
+# AIX sometimes has problems with the GCC collect2 program. For some
+# reason, if we set the COLLECT_NAMES environment variable, the problems
+# vanish in a puff of smoke.
+if test "X${COLLECT_NAMES+set}" != Xset; then
+ COLLECT_NAMES=
+ export COLLECT_NAMES
+fi
+_LT_EOF
+ ;;
+ esac
+
+
+ltmain="$ac_aux_dir/ltmain.sh"
+
+
+ # We use sed instead of cat because bash on DJGPP gets confused if
+ # if finds mixed CR/LF and LF-only lines. Since sed operates in
+ # text mode, it properly converts lines to CR/LF. This bash problem
+ # is reportedly fixed, but why not run on old versions too?
+ sed '/^# Generated shell functions inserted here/q' "$ltmain" >> "$cfgfile" \
+ || (rm -f "$cfgfile"; exit 1)
+
+ case $xsi_shell in
+ yes)
+ cat << \_LT_EOF >> "$cfgfile"
+
+# func_dirname file append nondir_replacement
+# Compute the dirname of FILE. If nonempty, add APPEND to the result,
+# otherwise set result to NONDIR_REPLACEMENT.
+func_dirname ()
+{
+ case ${1} in
+ */*) func_dirname_result="${1%/*}${2}" ;;
+ * ) func_dirname_result="${3}" ;;
+ esac
+}
+
+# func_basename file
+func_basename ()
+{
+ func_basename_result="${1##*/}"
+}
+
+# func_dirname_and_basename file append nondir_replacement
+# perform func_basename and func_dirname in a single function
+# call:
+# dirname: Compute the dirname of FILE. If nonempty,
+# add APPEND to the result, otherwise set result
+# to NONDIR_REPLACEMENT.
+# value returned in "$func_dirname_result"
+# basename: Compute filename of FILE.
+# value retuned in "$func_basename_result"
+# Implementation must be kept synchronized with func_dirname
+# and func_basename. For efficiency, we do not delegate to
+# those functions but instead duplicate the functionality here.
+func_dirname_and_basename ()
+{
+ case ${1} in
+ */*) func_dirname_result="${1%/*}${2}" ;;
+ * ) func_dirname_result="${3}" ;;
+ esac
+ func_basename_result="${1##*/}"
+}
+
+# func_stripname prefix suffix name
+# strip PREFIX and SUFFIX off of NAME.
+# PREFIX and SUFFIX must not contain globbing or regex special
+# characters, hashes, percent signs, but SUFFIX may contain a leading
+# dot (in which case that matches only a dot).
+func_stripname ()
+{
+ # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are
+ # positional parameters, so assign one to ordinary parameter first.
+ func_stripname_result=${3}
+ func_stripname_result=${func_stripname_result#"${1}"}
+ func_stripname_result=${func_stripname_result%"${2}"}
+}
+
+# func_opt_split
+func_opt_split ()
+{
+ func_opt_split_opt=${1%%=*}
+ func_opt_split_arg=${1#*=}
+}
+
+# func_lo2o object
+func_lo2o ()
+{
+ case ${1} in
+ *.lo) func_lo2o_result=${1%.lo}.${objext} ;;
+ *) func_lo2o_result=${1} ;;
+ esac
+}
+
+# func_xform libobj-or-source
+func_xform ()
+{
+ func_xform_result=${1%.*}.lo
+}
+
+# func_arith arithmetic-term...
+func_arith ()
+{
+ func_arith_result=$(( $* ))
+}
+
+# func_len string
+# STRING may not start with a hyphen.
+func_len ()
+{
+ func_len_result=${#1}
+}
+
+_LT_EOF
+ ;;
+ *) # Bourne compatible functions.
+ cat << \_LT_EOF >> "$cfgfile"
+
+# func_dirname file append nondir_replacement
+# Compute the dirname of FILE. If nonempty, add APPEND to the result,
+# otherwise set result to NONDIR_REPLACEMENT.
+func_dirname ()
+{
+ # Extract subdirectory from the argument.
+ func_dirname_result=`$ECHO "X${1}" | $Xsed -e "$dirname"`
+ if test "X$func_dirname_result" = "X${1}"; then
+ func_dirname_result="${3}"
+ else
+ func_dirname_result="$func_dirname_result${2}"
+ fi
+}
+
+# func_basename file
+func_basename ()
+{
+ func_basename_result=`$ECHO "X${1}" | $Xsed -e "$basename"`
+}
+
+
+# func_stripname prefix suffix name
+# strip PREFIX and SUFFIX off of NAME.
+# PREFIX and SUFFIX must not contain globbing or regex special
+# characters, hashes, percent signs, but SUFFIX may contain a leading
+# dot (in which case that matches only a dot).
+# func_strip_suffix prefix name
+func_stripname ()
+{
+ case ${2} in
+ .*) func_stripname_result=`$ECHO "X${3}" \
+ | $Xsed -e "s%^${1}%%" -e "s%\\\\${2}\$%%"`;;
+ *) func_stripname_result=`$ECHO "X${3}" \
+ | $Xsed -e "s%^${1}%%" -e "s%${2}\$%%"`;;
+ esac
+}
+
+# sed scripts:
+my_sed_long_opt='1s/^\(-[^=]*\)=.*/\1/;q'
+my_sed_long_arg='1s/^-[^=]*=//'
+
+# func_opt_split
+func_opt_split ()
+{
+ func_opt_split_opt=`$ECHO "X${1}" | $Xsed -e "$my_sed_long_opt"`
+ func_opt_split_arg=`$ECHO "X${1}" | $Xsed -e "$my_sed_long_arg"`
+}
+
+# func_lo2o object
+func_lo2o ()
+{
+ func_lo2o_result=`$ECHO "X${1}" | $Xsed -e "$lo2o"`
+}
+
+# func_xform libobj-or-source
+func_xform ()
+{
+ func_xform_result=`$ECHO "X${1}" | $Xsed -e 's/\.[^.]*$/.lo/'`
+}
+
+# func_arith arithmetic-term...
+func_arith ()
+{
+ func_arith_result=`expr "$@"`
+}
+
+# func_len string
+# STRING may not start with a hyphen.
+func_len ()
+{
+ func_len_result=`expr "$1" : ".*" 2>/dev/null || echo $max_cmd_len`
+}
+
+_LT_EOF
+esac
+
+case $lt_shell_append in
+ yes)
+ cat << \_LT_EOF >> "$cfgfile"
+
+# func_append var value
+# Append VALUE to the end of shell variable VAR.
+func_append ()
+{
+ eval "$1+=\$2"
+}
+_LT_EOF
+ ;;
+ *)
+ cat << \_LT_EOF >> "$cfgfile"
+
+# func_append var value
+# Append VALUE to the end of shell variable VAR.
+func_append ()
+{
+ eval "$1=\$$1\$2"
+}
+
+_LT_EOF
+ ;;
+ esac
+
+
+ sed -n '/^# Generated shell functions inserted here/,$p' "$ltmain" >> "$cfgfile" \
+ || (rm -f "$cfgfile"; exit 1)
+
+ mv -f "$cfgfile" "$ofile" ||
+ (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile")
+ chmod +x "$ofile"
+
+
+ cat <<_LT_EOF >> "$ofile"
+
+# ### BEGIN LIBTOOL TAG CONFIG: CXX
+
+# The linker used to build libraries.
+LD=$lt_LD_CXX
+
+# Commands used to build an old-style archive.
+old_archive_cmds=$lt_old_archive_cmds_CXX
+
+# A language specific compiler.
+CC=$lt_compiler_CXX
+
+# Is the compiler the GNU compiler?
+with_gcc=$GCC_CXX
+
+# Compiler flag to turn off builtin functions.
+no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag_CXX
+
+# How to pass a linker flag through the compiler.
+wl=$lt_lt_prog_compiler_wl_CXX
+
+# Additional compiler flags for building library objects.
+pic_flag=$lt_lt_prog_compiler_pic_CXX
+
+# Compiler flag to prevent dynamic linking.
+link_static_flag=$lt_lt_prog_compiler_static_CXX
+
+# Does compiler simultaneously support -c and -o options?
+compiler_c_o=$lt_lt_cv_prog_compiler_c_o_CXX
+
+# Whether or not to add -lc for building shared libraries.
+build_libtool_need_lc=$archive_cmds_need_lc_CXX
+
+# Whether or not to disallow shared libs when runtime libs are static.
+allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes_CXX
+
+# Compiler flag to allow reflexive dlopens.
+export_dynamic_flag_spec=$lt_export_dynamic_flag_spec_CXX
+
+# Compiler flag to generate shared objects directly from archives.
+whole_archive_flag_spec=$lt_whole_archive_flag_spec_CXX
+
+# Whether the compiler copes with passing no objects directly.
+compiler_needs_object=$lt_compiler_needs_object_CXX
+
+# Create an old-style archive from a shared archive.
+old_archive_from_new_cmds=$lt_old_archive_from_new_cmds_CXX
+
+# Create a temporary old-style archive to link instead of a shared archive.
+old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds_CXX
+
+# Commands used to build a shared archive.
+archive_cmds=$lt_archive_cmds_CXX
+archive_expsym_cmds=$lt_archive_expsym_cmds_CXX
+
+# Commands used to build a loadable module if different from building
+# a shared archive.
+module_cmds=$lt_module_cmds_CXX
+module_expsym_cmds=$lt_module_expsym_cmds_CXX
+
+# Whether we are building with GNU ld or not.
+with_gnu_ld=$lt_with_gnu_ld_CXX
+
+# Flag that allows shared libraries with undefined symbols to be built.
+allow_undefined_flag=$lt_allow_undefined_flag_CXX
+
+# Flag that enforces no undefined symbols.
+no_undefined_flag=$lt_no_undefined_flag_CXX
+
+# Flag to hardcode \$libdir into a binary during linking.
+# This must work even if \$libdir does not exist
+hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec_CXX
+
+# If ld is used when linking, flag to hardcode \$libdir into a binary
+# during linking. This must work even if \$libdir does not exist.
+hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld_CXX
+
+# Whether we need a single "-rpath" flag with a separated argument.
+hardcode_libdir_separator=$lt_hardcode_libdir_separator_CXX
+
+# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes
+# DIR into the resulting binary.
+hardcode_direct=$hardcode_direct_CXX
+
+# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes
+# DIR into the resulting binary and the resulting library dependency is
+# "absolute",i.e impossible to change by setting \${shlibpath_var} if the
+# library is relocated.
+hardcode_direct_absolute=$hardcode_direct_absolute_CXX
+
+# Set to "yes" if using the -LDIR flag during linking hardcodes DIR
+# into the resulting binary.
+hardcode_minus_L=$hardcode_minus_L_CXX
+
+# Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR
+# into the resulting binary.
+hardcode_shlibpath_var=$hardcode_shlibpath_var_CXX
+
+# Set to "yes" if building a shared library automatically hardcodes DIR
+# into the library and all subsequent libraries and executables linked
+# against it.
+hardcode_automatic=$hardcode_automatic_CXX
+
+# Set to yes if linker adds runtime paths of dependent libraries
+# to runtime path list.
+inherit_rpath=$inherit_rpath_CXX
+
+# Whether libtool must link a program against all its dependency libraries.
+link_all_deplibs=$link_all_deplibs_CXX
+
+# Fix the shell variable \$srcfile for the compiler.
+fix_srcfile_path=$lt_fix_srcfile_path_CXX
+
+# Set to "yes" if exported symbols are required.
+always_export_symbols=$always_export_symbols_CXX
+
+# The commands to list exported symbols.
+export_symbols_cmds=$lt_export_symbols_cmds_CXX
+
+# Symbols that should not be listed in the preloaded symbols.
+exclude_expsyms=$lt_exclude_expsyms_CXX
+
+# Symbols that must always be exported.
+include_expsyms=$lt_include_expsyms_CXX
+
+# Commands necessary for linking programs (against libraries) with templates.
+prelink_cmds=$lt_prelink_cmds_CXX
+
+# Specify filename containing input files.
+file_list_spec=$lt_file_list_spec_CXX
+
+# How to hardcode a shared library path into an executable.
+hardcode_action=$hardcode_action_CXX
+
+# The directories searched by this compiler when creating a shared library.
+compiler_lib_search_dirs=$lt_compiler_lib_search_dirs_CXX
+
+# Dependencies to place before and after the objects being linked to
+# create a shared library.
+predep_objects=$lt_predep_objects_CXX
+postdep_objects=$lt_postdep_objects_CXX
+predeps=$lt_predeps_CXX
+postdeps=$lt_postdeps_CXX
+
+# The library search path used internally by the compiler when linking
+# a shared library.
+compiler_lib_search_path=$lt_compiler_lib_search_path_CXX
+
+# ### END LIBTOOL TAG CONFIG: CXX
+_LT_EOF
+
+ ;;
+
+ esac
+done # for ac_tag
+
+
+{ (exit 0); exit 0; }
diff --git a/src/third_party/gflags-2.0/config.sub b/src/third_party/gflags-2.0/config.sub
new file mode 100755
index 00000000000..6759825a5b7
--- /dev/null
+++ b/src/third_party/gflags-2.0/config.sub
@@ -0,0 +1,1658 @@
+#! /bin/sh
+# Configuration validation subroutine script.
+# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
+# Free Software Foundation, Inc.
+
+timestamp='2008-01-16'
+
+# This file is (in principle) common to ALL GNU software.
+# The presence of a machine in this file suggests that SOME GNU software
+# can handle that machine. It does not imply ALL GNU software can.
+#
+# This file is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
+# 02110-1301, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+
+# Please send patches to <config-patches@gnu.org>. Submit a context
+# diff and a properly formatted ChangeLog entry.
+#
+# Configuration subroutine to validate and canonicalize a configuration type.
+# Supply the specified configuration type as an argument.
+# If it is invalid, we print an error message on stderr and exit with code 1.
+# Otherwise, we print the canonical config type on stdout and succeed.
+
+# This file is supposed to be the same for all GNU packages
+# and recognize all the CPU types, system types and aliases
+# that are meaningful with *any* GNU software.
+# Each package is responsible for reporting which valid configurations
+# it does not support. The user should be able to distinguish
+# a failure to support a valid configuration from a meaningless
+# configuration.
+
+# The goal of this file is to map all the various variations of a given
+# machine specification into a single specification in the form:
+# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
+# or in some cases, the newer four-part form:
+# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
+# It is wrong to echo any other type of specification.
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION] CPU-MFR-OPSYS
+ $0 [OPTION] ALIAS
+
+Canonicalize a configuration name.
+
+Operation modes:
+ -h, --help print this help, then exit
+ -t, --time-stamp print date of last modification, then exit
+ -v, --version print version number, then exit
+
+Report bugs and patches to <config-patches@gnu.org>."
+
+version="\
+GNU config.sub ($timestamp)
+
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
+2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+
+This is free software; see the source for copying conditions. There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+
+help="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+ case $1 in
+ --time-stamp | --time* | -t )
+ echo "$timestamp" ; exit ;;
+ --version | -v )
+ echo "$version" ; exit ;;
+ --help | --h* | -h )
+ echo "$usage"; exit ;;
+ -- ) # Stop option processing
+ shift; break ;;
+ - ) # Use stdin as input.
+ break ;;
+ -* )
+ echo "$me: invalid option $1$help"
+ exit 1 ;;
+
+ *local*)
+ # First pass through any local machine types.
+ echo $1
+ exit ;;
+
+ * )
+ break ;;
+ esac
+done
+
+case $# in
+ 0) echo "$me: missing argument$help" >&2
+ exit 1;;
+ 1) ;;
+ *) echo "$me: too many arguments$help" >&2
+ exit 1;;
+esac
+
+# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
+# Here we must recognize all the valid KERNEL-OS combinations.
+maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
+case $maybe_os in
+ nto-qnx* | linux-gnu* | linux-dietlibc | linux-newlib* | linux-uclibc* | \
+ uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | \
+ storm-chaos* | os2-emx* | rtmk-nova*)
+ os=-$maybe_os
+ basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
+ ;;
+ *)
+ basic_machine=`echo $1 | sed 's/-[^-]*$//'`
+ if [ $basic_machine != $1 ]
+ then os=`echo $1 | sed 's/.*-/-/'`
+ else os=; fi
+ ;;
+esac
+
+### Let's recognize common machines as not being operating systems so
+### that things like config.sub decstation-3100 work. We also
+### recognize some manufacturers as not being operating systems, so we
+### can provide default operating systems below.
+case $os in
+ -sun*os*)
+ # Prevent following clause from handling this invalid input.
+ ;;
+ -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \
+ -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \
+ -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \
+ -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
+ -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
+ -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
+ -apple | -axis | -knuth | -cray)
+ os=
+ basic_machine=$1
+ ;;
+ -sim | -cisco | -oki | -wec | -winbond)
+ os=
+ basic_machine=$1
+ ;;
+ -scout)
+ ;;
+ -wrs)
+ os=-vxworks
+ basic_machine=$1
+ ;;
+ -chorusos*)
+ os=-chorusos
+ basic_machine=$1
+ ;;
+ -chorusrdb)
+ os=-chorusrdb
+ basic_machine=$1
+ ;;
+ -hiux*)
+ os=-hiuxwe2
+ ;;
+ -sco6)
+ os=-sco5v6
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco5)
+ os=-sco3.2v5
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco4)
+ os=-sco3.2v4
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco3.2.[4-9]*)
+ os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco3.2v[4-9]*)
+ # Don't forget version if it is 3.2v4 or newer.
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco5v6*)
+ # Don't forget version if it is 3.2v4 or newer.
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco*)
+ os=-sco3.2v2
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -udk*)
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -isc)
+ os=-isc2.2
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -clix*)
+ basic_machine=clipper-intergraph
+ ;;
+ -isc*)
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -lynx*)
+ os=-lynxos
+ ;;
+ -ptx*)
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'`
+ ;;
+ -windowsnt*)
+ os=`echo $os | sed -e 's/windowsnt/winnt/'`
+ ;;
+ -psos*)
+ os=-psos
+ ;;
+ -mint | -mint[0-9]*)
+ basic_machine=m68k-atari
+ os=-mint
+ ;;
+esac
+
+# Decode aliases for certain CPU-COMPANY combinations.
+case $basic_machine in
+ # Recognize the basic CPU types without company name.
+ # Some are omitted here because they have special meanings below.
+ 1750a | 580 \
+ | a29k \
+ | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
+ | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
+ | am33_2.0 \
+ | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \
+ | bfin \
+ | c4x | clipper \
+ | d10v | d30v | dlx | dsp16xx \
+ | fido | fr30 | frv \
+ | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
+ | i370 | i860 | i960 | ia64 \
+ | ip2k | iq2000 \
+ | m32c | m32r | m32rle | m68000 | m68k | m88k \
+ | maxq | mb | microblaze | mcore | mep \
+ | mips | mipsbe | mipseb | mipsel | mipsle \
+ | mips16 \
+ | mips64 | mips64el \
+ | mips64vr | mips64vrel \
+ | mips64orion | mips64orionel \
+ | mips64vr4100 | mips64vr4100el \
+ | mips64vr4300 | mips64vr4300el \
+ | mips64vr5000 | mips64vr5000el \
+ | mips64vr5900 | mips64vr5900el \
+ | mipsisa32 | mipsisa32el \
+ | mipsisa32r2 | mipsisa32r2el \
+ | mipsisa64 | mipsisa64el \
+ | mipsisa64r2 | mipsisa64r2el \
+ | mipsisa64sb1 | mipsisa64sb1el \
+ | mipsisa64sr71k | mipsisa64sr71kel \
+ | mipstx39 | mipstx39el \
+ | mn10200 | mn10300 \
+ | mt \
+ | msp430 \
+ | nios | nios2 \
+ | ns16k | ns32k \
+ | or32 \
+ | pdp10 | pdp11 | pj | pjl \
+ | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \
+ | pyramid \
+ | score \
+ | sh | sh[1234] | sh[24]a | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
+ | sh64 | sh64le \
+ | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \
+ | sparcv8 | sparcv9 | sparcv9b | sparcv9v \
+ | spu | strongarm \
+ | tahoe | thumb | tic4x | tic80 | tron \
+ | v850 | v850e \
+ | we32k \
+ | x86 | xc16x | xscale | xscalee[bl] | xstormy16 | xtensa \
+ | z8k)
+ basic_machine=$basic_machine-unknown
+ ;;
+ m6811 | m68hc11 | m6812 | m68hc12)
+ # Motorola 68HC11/12.
+ basic_machine=$basic_machine-unknown
+ os=-none
+ ;;
+ m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k)
+ ;;
+ ms1)
+ basic_machine=mt-unknown
+ ;;
+
+ # We use `pc' rather than `unknown'
+ # because (1) that's what they normally are, and
+ # (2) the word "unknown" tends to confuse beginning users.
+ i*86 | x86_64)
+ basic_machine=$basic_machine-pc
+ ;;
+ # Object if more than one company name word.
+ *-*-*)
+ echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+ exit 1
+ ;;
+ # Recognize the basic CPU types with company name.
+ 580-* \
+ | a29k-* \
+ | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
+ | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
+ | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \
+ | arm-* | armbe-* | armle-* | armeb-* | armv*-* \
+ | avr-* | avr32-* \
+ | bfin-* | bs2000-* \
+ | c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \
+ | clipper-* | craynv-* | cydra-* \
+ | d10v-* | d30v-* | dlx-* \
+ | elxsi-* \
+ | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \
+ | h8300-* | h8500-* \
+ | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
+ | i*86-* | i860-* | i960-* | ia64-* \
+ | ip2k-* | iq2000-* \
+ | m32c-* | m32r-* | m32rle-* \
+ | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
+ | m88110-* | m88k-* | maxq-* | mcore-* \
+ | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
+ | mips16-* \
+ | mips64-* | mips64el-* \
+ | mips64vr-* | mips64vrel-* \
+ | mips64orion-* | mips64orionel-* \
+ | mips64vr4100-* | mips64vr4100el-* \
+ | mips64vr4300-* | mips64vr4300el-* \
+ | mips64vr5000-* | mips64vr5000el-* \
+ | mips64vr5900-* | mips64vr5900el-* \
+ | mipsisa32-* | mipsisa32el-* \
+ | mipsisa32r2-* | mipsisa32r2el-* \
+ | mipsisa64-* | mipsisa64el-* \
+ | mipsisa64r2-* | mipsisa64r2el-* \
+ | mipsisa64sb1-* | mipsisa64sb1el-* \
+ | mipsisa64sr71k-* | mipsisa64sr71kel-* \
+ | mipstx39-* | mipstx39el-* \
+ | mmix-* \
+ | mt-* \
+ | msp430-* \
+ | nios-* | nios2-* \
+ | none-* | np1-* | ns16k-* | ns32k-* \
+ | orion-* \
+ | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
+ | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \
+ | pyramid-* \
+ | romp-* | rs6000-* \
+ | sh-* | sh[1234]-* | sh[24]a-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \
+ | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
+ | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \
+ | sparclite-* \
+ | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | strongarm-* | sv1-* | sx?-* \
+ | tahoe-* | thumb-* \
+ | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
+ | tron-* \
+ | v850-* | v850e-* | vax-* \
+ | we32k-* \
+ | x86-* | x86_64-* | xc16x-* | xps100-* | xscale-* | xscalee[bl]-* \
+ | xstormy16-* | xtensa*-* \
+ | ymp-* \
+ | z8k-*)
+ ;;
+ # Recognize the basic CPU types without company name, with glob match.
+ xtensa*)
+ basic_machine=$basic_machine-unknown
+ ;;
+ # Recognize the various machine names and aliases which stand
+ # for a CPU type and a company and sometimes even an OS.
+ 386bsd)
+ basic_machine=i386-unknown
+ os=-bsd
+ ;;
+ 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
+ basic_machine=m68000-att
+ ;;
+ 3b*)
+ basic_machine=we32k-att
+ ;;
+ a29khif)
+ basic_machine=a29k-amd
+ os=-udi
+ ;;
+ abacus)
+ basic_machine=abacus-unknown
+ ;;
+ adobe68k)
+ basic_machine=m68010-adobe
+ os=-scout
+ ;;
+ alliant | fx80)
+ basic_machine=fx80-alliant
+ ;;
+ altos | altos3068)
+ basic_machine=m68k-altos
+ ;;
+ am29k)
+ basic_machine=a29k-none
+ os=-bsd
+ ;;
+ amd64)
+ basic_machine=x86_64-pc
+ ;;
+ amd64-*)
+ basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ amdahl)
+ basic_machine=580-amdahl
+ os=-sysv
+ ;;
+ amiga | amiga-*)
+ basic_machine=m68k-unknown
+ ;;
+ amigaos | amigados)
+ basic_machine=m68k-unknown
+ os=-amigaos
+ ;;
+ amigaunix | amix)
+ basic_machine=m68k-unknown
+ os=-sysv4
+ ;;
+ apollo68)
+ basic_machine=m68k-apollo
+ os=-sysv
+ ;;
+ apollo68bsd)
+ basic_machine=m68k-apollo
+ os=-bsd
+ ;;
+ aux)
+ basic_machine=m68k-apple
+ os=-aux
+ ;;
+ balance)
+ basic_machine=ns32k-sequent
+ os=-dynix
+ ;;
+ blackfin)
+ basic_machine=bfin-unknown
+ os=-linux
+ ;;
+ blackfin-*)
+ basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'`
+ os=-linux
+ ;;
+ c90)
+ basic_machine=c90-cray
+ os=-unicos
+ ;;
+ convex-c1)
+ basic_machine=c1-convex
+ os=-bsd
+ ;;
+ convex-c2)
+ basic_machine=c2-convex
+ os=-bsd
+ ;;
+ convex-c32)
+ basic_machine=c32-convex
+ os=-bsd
+ ;;
+ convex-c34)
+ basic_machine=c34-convex
+ os=-bsd
+ ;;
+ convex-c38)
+ basic_machine=c38-convex
+ os=-bsd
+ ;;
+ cray | j90)
+ basic_machine=j90-cray
+ os=-unicos
+ ;;
+ craynv)
+ basic_machine=craynv-cray
+ os=-unicosmp
+ ;;
+ cr16)
+ basic_machine=cr16-unknown
+ os=-elf
+ ;;
+ crds | unos)
+ basic_machine=m68k-crds
+ ;;
+ crisv32 | crisv32-* | etraxfs*)
+ basic_machine=crisv32-axis
+ ;;
+ cris | cris-* | etrax*)
+ basic_machine=cris-axis
+ ;;
+ crx)
+ basic_machine=crx-unknown
+ os=-elf
+ ;;
+ da30 | da30-*)
+ basic_machine=m68k-da30
+ ;;
+ decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)
+ basic_machine=mips-dec
+ ;;
+ decsystem10* | dec10*)
+ basic_machine=pdp10-dec
+ os=-tops10
+ ;;
+ decsystem20* | dec20*)
+ basic_machine=pdp10-dec
+ os=-tops20
+ ;;
+ delta | 3300 | motorola-3300 | motorola-delta \
+ | 3300-motorola | delta-motorola)
+ basic_machine=m68k-motorola
+ ;;
+ delta88)
+ basic_machine=m88k-motorola
+ os=-sysv3
+ ;;
+ djgpp)
+ basic_machine=i586-pc
+ os=-msdosdjgpp
+ ;;
+ dpx20 | dpx20-*)
+ basic_machine=rs6000-bull
+ os=-bosx
+ ;;
+ dpx2* | dpx2*-bull)
+ basic_machine=m68k-bull
+ os=-sysv3
+ ;;
+ ebmon29k)
+ basic_machine=a29k-amd
+ os=-ebmon
+ ;;
+ elxsi)
+ basic_machine=elxsi-elxsi
+ os=-bsd
+ ;;
+ encore | umax | mmax)
+ basic_machine=ns32k-encore
+ ;;
+ es1800 | OSE68k | ose68k | ose | OSE)
+ basic_machine=m68k-ericsson
+ os=-ose
+ ;;
+ fx2800)
+ basic_machine=i860-alliant
+ ;;
+ genix)
+ basic_machine=ns32k-ns
+ ;;
+ gmicro)
+ basic_machine=tron-gmicro
+ os=-sysv
+ ;;
+ go32)
+ basic_machine=i386-pc
+ os=-go32
+ ;;
+ h3050r* | hiux*)
+ basic_machine=hppa1.1-hitachi
+ os=-hiuxwe2
+ ;;
+ h8300hms)
+ basic_machine=h8300-hitachi
+ os=-hms
+ ;;
+ h8300xray)
+ basic_machine=h8300-hitachi
+ os=-xray
+ ;;
+ h8500hms)
+ basic_machine=h8500-hitachi
+ os=-hms
+ ;;
+ harris)
+ basic_machine=m88k-harris
+ os=-sysv3
+ ;;
+ hp300-*)
+ basic_machine=m68k-hp
+ ;;
+ hp300bsd)
+ basic_machine=m68k-hp
+ os=-bsd
+ ;;
+ hp300hpux)
+ basic_machine=m68k-hp
+ os=-hpux
+ ;;
+ hp3k9[0-9][0-9] | hp9[0-9][0-9])
+ basic_machine=hppa1.0-hp
+ ;;
+ hp9k2[0-9][0-9] | hp9k31[0-9])
+ basic_machine=m68000-hp
+ ;;
+ hp9k3[2-9][0-9])
+ basic_machine=m68k-hp
+ ;;
+ hp9k6[0-9][0-9] | hp6[0-9][0-9])
+ basic_machine=hppa1.0-hp
+ ;;
+ hp9k7[0-79][0-9] | hp7[0-79][0-9])
+ basic_machine=hppa1.1-hp
+ ;;
+ hp9k78[0-9] | hp78[0-9])
+ # FIXME: really hppa2.0-hp
+ basic_machine=hppa1.1-hp
+ ;;
+ hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893)
+ # FIXME: really hppa2.0-hp
+ basic_machine=hppa1.1-hp
+ ;;
+ hp9k8[0-9][13679] | hp8[0-9][13679])
+ basic_machine=hppa1.1-hp
+ ;;
+ hp9k8[0-9][0-9] | hp8[0-9][0-9])
+ basic_machine=hppa1.0-hp
+ ;;
+ hppa-next)
+ os=-nextstep3
+ ;;
+ hppaosf)
+ basic_machine=hppa1.1-hp
+ os=-osf
+ ;;
+ hppro)
+ basic_machine=hppa1.1-hp
+ os=-proelf
+ ;;
+ i370-ibm* | ibm*)
+ basic_machine=i370-ibm
+ ;;
+# I'm not sure what "Sysv32" means. Should this be sysv3.2?
+ i*86v32)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ os=-sysv32
+ ;;
+ i*86v4*)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ os=-sysv4
+ ;;
+ i*86v)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ os=-sysv
+ ;;
+ i*86sol2)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ os=-solaris2
+ ;;
+ i386mach)
+ basic_machine=i386-mach
+ os=-mach
+ ;;
+ i386-vsta | vsta)
+ basic_machine=i386-unknown
+ os=-vsta
+ ;;
+ iris | iris4d)
+ basic_machine=mips-sgi
+ case $os in
+ -irix*)
+ ;;
+ *)
+ os=-irix4
+ ;;
+ esac
+ ;;
+ isi68 | isi)
+ basic_machine=m68k-isi
+ os=-sysv
+ ;;
+ m68knommu)
+ basic_machine=m68k-unknown
+ os=-linux
+ ;;
+ m68knommu-*)
+ basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'`
+ os=-linux
+ ;;
+ m88k-omron*)
+ basic_machine=m88k-omron
+ ;;
+ magnum | m3230)
+ basic_machine=mips-mips
+ os=-sysv
+ ;;
+ merlin)
+ basic_machine=ns32k-utek
+ os=-sysv
+ ;;
+ mingw32)
+ basic_machine=i386-pc
+ os=-mingw32
+ ;;
+ mingw32ce)
+ basic_machine=arm-unknown
+ os=-mingw32ce
+ ;;
+ miniframe)
+ basic_machine=m68000-convergent
+ ;;
+ *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*)
+ basic_machine=m68k-atari
+ os=-mint
+ ;;
+ mips3*-*)
+ basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
+ ;;
+ mips3*)
+ basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
+ ;;
+ monitor)
+ basic_machine=m68k-rom68k
+ os=-coff
+ ;;
+ morphos)
+ basic_machine=powerpc-unknown
+ os=-morphos
+ ;;
+ msdos)
+ basic_machine=i386-pc
+ os=-msdos
+ ;;
+ ms1-*)
+ basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'`
+ ;;
+ mvs)
+ basic_machine=i370-ibm
+ os=-mvs
+ ;;
+ ncr3000)
+ basic_machine=i486-ncr
+ os=-sysv4
+ ;;
+ netbsd386)
+ basic_machine=i386-unknown
+ os=-netbsd
+ ;;
+ netwinder)
+ basic_machine=armv4l-rebel
+ os=-linux
+ ;;
+ news | news700 | news800 | news900)
+ basic_machine=m68k-sony
+ os=-newsos
+ ;;
+ news1000)
+ basic_machine=m68030-sony
+ os=-newsos
+ ;;
+ news-3600 | risc-news)
+ basic_machine=mips-sony
+ os=-newsos
+ ;;
+ necv70)
+ basic_machine=v70-nec
+ os=-sysv
+ ;;
+ next | m*-next )
+ basic_machine=m68k-next
+ case $os in
+ -nextstep* )
+ ;;
+ -ns2*)
+ os=-nextstep2
+ ;;
+ *)
+ os=-nextstep3
+ ;;
+ esac
+ ;;
+ nh3000)
+ basic_machine=m68k-harris
+ os=-cxux
+ ;;
+ nh[45]000)
+ basic_machine=m88k-harris
+ os=-cxux
+ ;;
+ nindy960)
+ basic_machine=i960-intel
+ os=-nindy
+ ;;
+ mon960)
+ basic_machine=i960-intel
+ os=-mon960
+ ;;
+ nonstopux)
+ basic_machine=mips-compaq
+ os=-nonstopux
+ ;;
+ np1)
+ basic_machine=np1-gould
+ ;;
+ nsr-tandem)
+ basic_machine=nsr-tandem
+ ;;
+ op50n-* | op60c-*)
+ basic_machine=hppa1.1-oki
+ os=-proelf
+ ;;
+ openrisc | openrisc-*)
+ basic_machine=or32-unknown
+ ;;
+ os400)
+ basic_machine=powerpc-ibm
+ os=-os400
+ ;;
+ OSE68000 | ose68000)
+ basic_machine=m68000-ericsson
+ os=-ose
+ ;;
+ os68k)
+ basic_machine=m68k-none
+ os=-os68k
+ ;;
+ pa-hitachi)
+ basic_machine=hppa1.1-hitachi
+ os=-hiuxwe2
+ ;;
+ paragon)
+ basic_machine=i860-intel
+ os=-osf
+ ;;
+ parisc)
+ basic_machine=hppa-unknown
+ os=-linux
+ ;;
+ parisc-*)
+ basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'`
+ os=-linux
+ ;;
+ pbd)
+ basic_machine=sparc-tti
+ ;;
+ pbb)
+ basic_machine=m68k-tti
+ ;;
+ pc532 | pc532-*)
+ basic_machine=ns32k-pc532
+ ;;
+ pc98)
+ basic_machine=i386-pc
+ ;;
+ pc98-*)
+ basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pentium | p5 | k5 | k6 | nexgen | viac3)
+ basic_machine=i586-pc
+ ;;
+ pentiumpro | p6 | 6x86 | athlon | athlon_*)
+ basic_machine=i686-pc
+ ;;
+ pentiumii | pentium2 | pentiumiii | pentium3)
+ basic_machine=i686-pc
+ ;;
+ pentium4)
+ basic_machine=i786-pc
+ ;;
+ pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
+ basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pentiumpro-* | p6-* | 6x86-* | athlon-*)
+ basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*)
+ basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pentium4-*)
+ basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pn)
+ basic_machine=pn-gould
+ ;;
+ power) basic_machine=power-ibm
+ ;;
+ ppc) basic_machine=powerpc-unknown
+ ;;
+ ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ ppcle | powerpclittle | ppc-le | powerpc-little)
+ basic_machine=powerpcle-unknown
+ ;;
+ ppcle-* | powerpclittle-*)
+ basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ ppc64) basic_machine=powerpc64-unknown
+ ;;
+ ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ ppc64le | powerpc64little | ppc64-le | powerpc64-little)
+ basic_machine=powerpc64le-unknown
+ ;;
+ ppc64le-* | powerpc64little-*)
+ basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ ps2)
+ basic_machine=i386-ibm
+ ;;
+ pw32)
+ basic_machine=i586-unknown
+ os=-pw32
+ ;;
+ rdos)
+ basic_machine=i386-pc
+ os=-rdos
+ ;;
+ rom68k)
+ basic_machine=m68k-rom68k
+ os=-coff
+ ;;
+ rm[46]00)
+ basic_machine=mips-siemens
+ ;;
+ rtpc | rtpc-*)
+ basic_machine=romp-ibm
+ ;;
+ s390 | s390-*)
+ basic_machine=s390-ibm
+ ;;
+ s390x | s390x-*)
+ basic_machine=s390x-ibm
+ ;;
+ sa29200)
+ basic_machine=a29k-amd
+ os=-udi
+ ;;
+ sb1)
+ basic_machine=mipsisa64sb1-unknown
+ ;;
+ sb1el)
+ basic_machine=mipsisa64sb1el-unknown
+ ;;
+ sde)
+ basic_machine=mipsisa32-sde
+ os=-elf
+ ;;
+ sei)
+ basic_machine=mips-sei
+ os=-seiux
+ ;;
+ sequent)
+ basic_machine=i386-sequent
+ ;;
+ sh)
+ basic_machine=sh-hitachi
+ os=-hms
+ ;;
+ sh5el)
+ basic_machine=sh5le-unknown
+ ;;
+ sh64)
+ basic_machine=sh64-unknown
+ ;;
+ sparclite-wrs | simso-wrs)
+ basic_machine=sparclite-wrs
+ os=-vxworks
+ ;;
+ sps7)
+ basic_machine=m68k-bull
+ os=-sysv2
+ ;;
+ spur)
+ basic_machine=spur-unknown
+ ;;
+ st2000)
+ basic_machine=m68k-tandem
+ ;;
+ stratus)
+ basic_machine=i860-stratus
+ os=-sysv4
+ ;;
+ sun2)
+ basic_machine=m68000-sun
+ ;;
+ sun2os3)
+ basic_machine=m68000-sun
+ os=-sunos3
+ ;;
+ sun2os4)
+ basic_machine=m68000-sun
+ os=-sunos4
+ ;;
+ sun3os3)
+ basic_machine=m68k-sun
+ os=-sunos3
+ ;;
+ sun3os4)
+ basic_machine=m68k-sun
+ os=-sunos4
+ ;;
+ sun4os3)
+ basic_machine=sparc-sun
+ os=-sunos3
+ ;;
+ sun4os4)
+ basic_machine=sparc-sun
+ os=-sunos4
+ ;;
+ sun4sol2)
+ basic_machine=sparc-sun
+ os=-solaris2
+ ;;
+ sun3 | sun3-*)
+ basic_machine=m68k-sun
+ ;;
+ sun4)
+ basic_machine=sparc-sun
+ ;;
+ sun386 | sun386i | roadrunner)
+ basic_machine=i386-sun
+ ;;
+ sv1)
+ basic_machine=sv1-cray
+ os=-unicos
+ ;;
+ symmetry)
+ basic_machine=i386-sequent
+ os=-dynix
+ ;;
+ t3e)
+ basic_machine=alphaev5-cray
+ os=-unicos
+ ;;
+ t90)
+ basic_machine=t90-cray
+ os=-unicos
+ ;;
+ tic54x | c54x*)
+ basic_machine=tic54x-unknown
+ os=-coff
+ ;;
+ tic55x | c55x*)
+ basic_machine=tic55x-unknown
+ os=-coff
+ ;;
+ tic6x | c6x*)
+ basic_machine=tic6x-unknown
+ os=-coff
+ ;;
+ tile*)
+ basic_machine=tile-unknown
+ os=-linux-gnu
+ ;;
+ tx39)
+ basic_machine=mipstx39-unknown
+ ;;
+ tx39el)
+ basic_machine=mipstx39el-unknown
+ ;;
+ toad1)
+ basic_machine=pdp10-xkl
+ os=-tops20
+ ;;
+ tower | tower-32)
+ basic_machine=m68k-ncr
+ ;;
+ tpf)
+ basic_machine=s390x-ibm
+ os=-tpf
+ ;;
+ udi29k)
+ basic_machine=a29k-amd
+ os=-udi
+ ;;
+ ultra3)
+ basic_machine=a29k-nyu
+ os=-sym1
+ ;;
+ v810 | necv810)
+ basic_machine=v810-nec
+ os=-none
+ ;;
+ vaxv)
+ basic_machine=vax-dec
+ os=-sysv
+ ;;
+ vms)
+ basic_machine=vax-dec
+ os=-vms
+ ;;
+ vpp*|vx|vx-*)
+ basic_machine=f301-fujitsu
+ ;;
+ vxworks960)
+ basic_machine=i960-wrs
+ os=-vxworks
+ ;;
+ vxworks68)
+ basic_machine=m68k-wrs
+ os=-vxworks
+ ;;
+ vxworks29k)
+ basic_machine=a29k-wrs
+ os=-vxworks
+ ;;
+ w65*)
+ basic_machine=w65-wdc
+ os=-none
+ ;;
+ w89k-*)
+ basic_machine=hppa1.1-winbond
+ os=-proelf
+ ;;
+ xbox)
+ basic_machine=i686-pc
+ os=-mingw32
+ ;;
+ xps | xps100)
+ basic_machine=xps100-honeywell
+ ;;
+ ymp)
+ basic_machine=ymp-cray
+ os=-unicos
+ ;;
+ z8k-*-coff)
+ basic_machine=z8k-unknown
+ os=-sim
+ ;;
+ none)
+ basic_machine=none-none
+ os=-none
+ ;;
+
+# Here we handle the default manufacturer of certain CPU types. It is in
+# some cases the only manufacturer, in others, it is the most popular.
+ w89k)
+ basic_machine=hppa1.1-winbond
+ ;;
+ op50n)
+ basic_machine=hppa1.1-oki
+ ;;
+ op60c)
+ basic_machine=hppa1.1-oki
+ ;;
+ romp)
+ basic_machine=romp-ibm
+ ;;
+ mmix)
+ basic_machine=mmix-knuth
+ ;;
+ rs6000)
+ basic_machine=rs6000-ibm
+ ;;
+ vax)
+ basic_machine=vax-dec
+ ;;
+ pdp10)
+ # there are many clones, so DEC is not a safe bet
+ basic_machine=pdp10-unknown
+ ;;
+ pdp11)
+ basic_machine=pdp11-dec
+ ;;
+ we32k)
+ basic_machine=we32k-att
+ ;;
+ sh[1234] | sh[24]a | sh[34]eb | sh[1234]le | sh[23]ele)
+ basic_machine=sh-unknown
+ ;;
+ sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v)
+ basic_machine=sparc-sun
+ ;;
+ cydra)
+ basic_machine=cydra-cydrome
+ ;;
+ orion)
+ basic_machine=orion-highlevel
+ ;;
+ orion105)
+ basic_machine=clipper-highlevel
+ ;;
+ mac | mpw | mac-mpw)
+ basic_machine=m68k-apple
+ ;;
+ pmac | pmac-mpw)
+ basic_machine=powerpc-apple
+ ;;
+ *-unknown)
+ # Make sure to match an already-canonicalized machine name.
+ ;;
+ *)
+ echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+ exit 1
+ ;;
+esac
+
+# Here we canonicalize certain aliases for manufacturers.
+case $basic_machine in
+ *-digital*)
+ basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'`
+ ;;
+ *-commodore*)
+ basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'`
+ ;;
+ *)
+ ;;
+esac
+
+# Decode manufacturer-specific aliases for certain operating systems.
+
+if [ x"$os" != x"" ]
+then
+case $os in
+ # First match some system type aliases
+ # that might get confused with valid system types.
+ # -solaris* is a basic system type, with this one exception.
+ -solaris1 | -solaris1.*)
+ os=`echo $os | sed -e 's|solaris1|sunos4|'`
+ ;;
+ -solaris)
+ os=-solaris2
+ ;;
+ -svr4*)
+ os=-sysv4
+ ;;
+ -unixware*)
+ os=-sysv4.2uw
+ ;;
+ -gnu/linux*)
+ os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
+ ;;
+ # First accept the basic system types.
+ # The portable systems comes first.
+ # Each alternative MUST END IN A *, to match a version number.
+ # -sysv* is not here because it comes later, after sysvr4.
+ -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
+ | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\
+ | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \
+ | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
+ | -aos* \
+ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
+ | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
+ | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \
+ | -openbsd* | -solidbsd* \
+ | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
+ | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
+ | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
+ | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
+ | -chorusos* | -chorusrdb* \
+ | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
+ | -mingw32* | -linux-gnu* | -linux-newlib* | -linux-uclibc* \
+ | -uxpv* | -beos* | -mpeix* | -udk* \
+ | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
+ | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
+ | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
+ | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
+ | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
+ | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
+ | -skyos* | -haiku* | -rdos* | -toppers* | -drops*)
+ # Remember, each alternative MUST END IN *, to match a version number.
+ ;;
+ -qnx*)
+ case $basic_machine in
+ x86-* | i*86-*)
+ ;;
+ *)
+ os=-nto$os
+ ;;
+ esac
+ ;;
+ -nto-qnx*)
+ ;;
+ -nto*)
+ os=`echo $os | sed -e 's|nto|nto-qnx|'`
+ ;;
+ -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \
+ | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \
+ | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*)
+ ;;
+ -mac*)
+ os=`echo $os | sed -e 's|mac|macos|'`
+ ;;
+ -linux-dietlibc)
+ os=-linux-dietlibc
+ ;;
+ -linux*)
+ os=`echo $os | sed -e 's|linux|linux-gnu|'`
+ ;;
+ -sunos5*)
+ os=`echo $os | sed -e 's|sunos5|solaris2|'`
+ ;;
+ -sunos6*)
+ os=`echo $os | sed -e 's|sunos6|solaris3|'`
+ ;;
+ -opened*)
+ os=-openedition
+ ;;
+ -os400*)
+ os=-os400
+ ;;
+ -wince*)
+ os=-wince
+ ;;
+ -osfrose*)
+ os=-osfrose
+ ;;
+ -osf*)
+ os=-osf
+ ;;
+ -utek*)
+ os=-bsd
+ ;;
+ -dynix*)
+ os=-bsd
+ ;;
+ -acis*)
+ os=-aos
+ ;;
+ -atheos*)
+ os=-atheos
+ ;;
+ -syllable*)
+ os=-syllable
+ ;;
+ -386bsd)
+ os=-bsd
+ ;;
+ -ctix* | -uts*)
+ os=-sysv
+ ;;
+ -nova*)
+ os=-rtmk-nova
+ ;;
+ -ns2 )
+ os=-nextstep2
+ ;;
+ -nsk*)
+ os=-nsk
+ ;;
+ # Preserve the version number of sinix5.
+ -sinix5.*)
+ os=`echo $os | sed -e 's|sinix|sysv|'`
+ ;;
+ -sinix*)
+ os=-sysv4
+ ;;
+ -tpf*)
+ os=-tpf
+ ;;
+ -triton*)
+ os=-sysv3
+ ;;
+ -oss*)
+ os=-sysv3
+ ;;
+ -svr4)
+ os=-sysv4
+ ;;
+ -svr3)
+ os=-sysv3
+ ;;
+ -sysvr4)
+ os=-sysv4
+ ;;
+ # This must come after -sysvr4.
+ -sysv*)
+ ;;
+ -ose*)
+ os=-ose
+ ;;
+ -es1800*)
+ os=-ose
+ ;;
+ -xenix)
+ os=-xenix
+ ;;
+ -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+ os=-mint
+ ;;
+ -aros*)
+ os=-aros
+ ;;
+ -kaos*)
+ os=-kaos
+ ;;
+ -zvmoe)
+ os=-zvmoe
+ ;;
+ -none)
+ ;;
+ *)
+ # Get rid of the `-' at the beginning of $os.
+ os=`echo $os | sed 's/[^-]*-//'`
+ echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2
+ exit 1
+ ;;
+esac
+else
+
+# Here we handle the default operating systems that come with various machines.
+# The value should be what the vendor currently ships out the door with their
+# machine or put another way, the most popular os provided with the machine.
+
+# Note that if you're going to try to match "-MANUFACTURER" here (say,
+# "-sun"), then you have to tell the case statement up towards the top
+# that MANUFACTURER isn't an operating system. Otherwise, code above
+# will signal an error saying that MANUFACTURER isn't an operating
+# system, and we'll never get to this point.
+
+case $basic_machine in
+ score-*)
+ os=-elf
+ ;;
+ spu-*)
+ os=-elf
+ ;;
+ *-acorn)
+ os=-riscix1.2
+ ;;
+ arm*-rebel)
+ os=-linux
+ ;;
+ arm*-semi)
+ os=-aout
+ ;;
+ c4x-* | tic4x-*)
+ os=-coff
+ ;;
+ # This must come before the *-dec entry.
+ pdp10-*)
+ os=-tops20
+ ;;
+ pdp11-*)
+ os=-none
+ ;;
+ *-dec | vax-*)
+ os=-ultrix4.2
+ ;;
+ m68*-apollo)
+ os=-domain
+ ;;
+ i386-sun)
+ os=-sunos4.0.2
+ ;;
+ m68000-sun)
+ os=-sunos3
+ # This also exists in the configure program, but was not the
+ # default.
+ # os=-sunos4
+ ;;
+ m68*-cisco)
+ os=-aout
+ ;;
+ mep-*)
+ os=-elf
+ ;;
+ mips*-cisco)
+ os=-elf
+ ;;
+ mips*-*)
+ os=-elf
+ ;;
+ or32-*)
+ os=-coff
+ ;;
+ *-tti) # must be before sparc entry or we get the wrong os.
+ os=-sysv3
+ ;;
+ sparc-* | *-sun)
+ os=-sunos4.1.1
+ ;;
+ *-be)
+ os=-beos
+ ;;
+ *-haiku)
+ os=-haiku
+ ;;
+ *-ibm)
+ os=-aix
+ ;;
+ *-knuth)
+ os=-mmixware
+ ;;
+ *-wec)
+ os=-proelf
+ ;;
+ *-winbond)
+ os=-proelf
+ ;;
+ *-oki)
+ os=-proelf
+ ;;
+ *-hp)
+ os=-hpux
+ ;;
+ *-hitachi)
+ os=-hiux
+ ;;
+ i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent)
+ os=-sysv
+ ;;
+ *-cbm)
+ os=-amigaos
+ ;;
+ *-dg)
+ os=-dgux
+ ;;
+ *-dolphin)
+ os=-sysv3
+ ;;
+ m68k-ccur)
+ os=-rtu
+ ;;
+ m88k-omron*)
+ os=-luna
+ ;;
+ *-next )
+ os=-nextstep
+ ;;
+ *-sequent)
+ os=-ptx
+ ;;
+ *-crds)
+ os=-unos
+ ;;
+ *-ns)
+ os=-genix
+ ;;
+ i370-*)
+ os=-mvs
+ ;;
+ *-next)
+ os=-nextstep3
+ ;;
+ *-gould)
+ os=-sysv
+ ;;
+ *-highlevel)
+ os=-bsd
+ ;;
+ *-encore)
+ os=-bsd
+ ;;
+ *-sgi)
+ os=-irix
+ ;;
+ *-siemens)
+ os=-sysv4
+ ;;
+ *-masscomp)
+ os=-rtu
+ ;;
+ f30[01]-fujitsu | f700-fujitsu)
+ os=-uxpv
+ ;;
+ *-rom68k)
+ os=-coff
+ ;;
+ *-*bug)
+ os=-coff
+ ;;
+ *-apple)
+ os=-macos
+ ;;
+ *-atari*)
+ os=-mint
+ ;;
+ *)
+ os=-none
+ ;;
+esac
+fi
+
+# Here we handle the case where we know the os, and the CPU type, but not the
+# manufacturer. We pick the logical manufacturer.
+vendor=unknown
+case $basic_machine in
+ *-unknown)
+ case $os in
+ -riscix*)
+ vendor=acorn
+ ;;
+ -sunos*)
+ vendor=sun
+ ;;
+ -aix*)
+ vendor=ibm
+ ;;
+ -beos*)
+ vendor=be
+ ;;
+ -hpux*)
+ vendor=hp
+ ;;
+ -mpeix*)
+ vendor=hp
+ ;;
+ -hiux*)
+ vendor=hitachi
+ ;;
+ -unos*)
+ vendor=crds
+ ;;
+ -dgux*)
+ vendor=dg
+ ;;
+ -luna*)
+ vendor=omron
+ ;;
+ -genix*)
+ vendor=ns
+ ;;
+ -mvs* | -opened*)
+ vendor=ibm
+ ;;
+ -os400*)
+ vendor=ibm
+ ;;
+ -ptx*)
+ vendor=sequent
+ ;;
+ -tpf*)
+ vendor=ibm
+ ;;
+ -vxsim* | -vxworks* | -windiss*)
+ vendor=wrs
+ ;;
+ -aux*)
+ vendor=apple
+ ;;
+ -hms*)
+ vendor=hitachi
+ ;;
+ -mpw* | -macos*)
+ vendor=apple
+ ;;
+ -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+ vendor=atari
+ ;;
+ -vos*)
+ vendor=stratus
+ ;;
+ esac
+ basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
+ ;;
+esac
+
+echo $basic_machine$os
+exit
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:
diff --git a/src/third_party/gflags-2.0/configure b/src/third_party/gflags-2.0/configure
new file mode 100755
index 00000000000..b5d0afcf7d1
--- /dev/null
+++ b/src/third_party/gflags-2.0/configure
@@ -0,0 +1,20626 @@
+#! /bin/sh
+# Guess values for system-dependent variables and create Makefiles.
+# Generated by GNU Autoconf 2.62 for gflags 2.0.
+#
+# Report bugs to <google-gflags@googlegroups.com>.
+#
+# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
+# 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+## --------------------- ##
+## M4sh Initialization. ##
+## --------------------- ##
+
+# Be more Bourne compatible
+DUALCASE=1; export DUALCASE # for MKS sh
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+ emulate sh
+ NULLCMD=:
+ # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '${1+"$@"}'='"$@"'
+ setopt NO_GLOB_SUBST
+else
+ case `(set -o) 2>/dev/null` in
+ *posix*) set -o posix ;;
+esac
+
+fi
+
+
+
+
+# PATH needs CR
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+as_nl='
+'
+export as_nl
+# Printing a long string crashes Solaris 7 /usr/bin/printf.
+as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
+if (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
+ as_echo='printf %s\n'
+ as_echo_n='printf %s'
+else
+ if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
+ as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
+ as_echo_n='/usr/ucb/echo -n'
+ else
+ as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
+ as_echo_n_body='eval
+ arg=$1;
+ case $arg in
+ *"$as_nl"*)
+ expr "X$arg" : "X\\(.*\\)$as_nl";
+ arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
+ esac;
+ expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
+ '
+ export as_echo_n_body
+ as_echo_n='sh -c $as_echo_n_body as_echo'
+ fi
+ export as_echo_body
+ as_echo='sh -c $as_echo_body as_echo'
+fi
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+ PATH_SEPARATOR=:
+ (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
+ (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
+ PATH_SEPARATOR=';'
+ }
+fi
+
+# Support unset when possible.
+if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+ as_unset=unset
+else
+ as_unset=false
+fi
+
+
+# IFS
+# We need space, tab and new line, in precisely that order. Quoting is
+# there to prevent editors from complaining about space-tab.
+# (If _AS_PATH_WALK were called with IFS unset, it would disable word
+# splitting by setting IFS to empty value.)
+IFS=" "" $as_nl"
+
+# Find who we are. Look in the path if we contain no directory separator.
+case $0 in
+ *[\\/]* ) as_myself=$0 ;;
+ *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+done
+IFS=$as_save_IFS
+
+ ;;
+esac
+# We did not find ourselves, most probably we were run as `sh COMMAND'
+# in which case we are not to be found in the path.
+if test "x$as_myself" = x; then
+ as_myself=$0
+fi
+if test ! -f "$as_myself"; then
+ $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+ { (exit 1); exit 1; }
+fi
+
+# Work around bugs in pre-3.0 UWIN ksh.
+for as_var in ENV MAIL MAILPATH
+do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var
+done
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+LC_ALL=C
+export LC_ALL
+LANGUAGE=C
+export LANGUAGE
+
+# Required to use basename.
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+ test "X`expr 00001 : '.*\(...\)'`" = X001; then
+ as_expr=expr
+else
+ as_expr=false
+fi
+
+if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
+ as_basename=basename
+else
+ as_basename=false
+fi
+
+
+# Name of the executable.
+as_me=`$as_basename -- "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+ X"$0" : 'X\(//\)$' \| \
+ X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X/"$0" |
+ sed '/^.*\/\([^/][^/]*\)\/*$/{
+ s//\1/
+ q
+ }
+ /^X\/\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\/\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+
+# CDPATH.
+$as_unset CDPATH
+
+
+if test "x$CONFIG_SHELL" = x; then
+ if (eval ":") 2>/dev/null; then
+ as_have_required=yes
+else
+ as_have_required=no
+fi
+
+ if test $as_have_required = yes && (eval ":
+(as_func_return () {
+ (exit \$1)
+}
+as_func_success () {
+ as_func_return 0
+}
+as_func_failure () {
+ as_func_return 1
+}
+as_func_ret_success () {
+ return 0
+}
+as_func_ret_failure () {
+ return 1
+}
+
+exitcode=0
+if as_func_success; then
+ :
+else
+ exitcode=1
+ echo as_func_success failed.
+fi
+
+if as_func_failure; then
+ exitcode=1
+ echo as_func_failure succeeded.
+fi
+
+if as_func_ret_success; then
+ :
+else
+ exitcode=1
+ echo as_func_ret_success failed.
+fi
+
+if as_func_ret_failure; then
+ exitcode=1
+ echo as_func_ret_failure succeeded.
+fi
+
+if ( set x; as_func_ret_success y && test x = \"\$1\" ); then
+ :
+else
+ exitcode=1
+ echo positional parameters were not saved.
+fi
+
+test \$exitcode = 0) || { (exit 1); exit 1; }
+
+(
+ as_lineno_1=\$LINENO
+ as_lineno_2=\$LINENO
+ test \"x\$as_lineno_1\" != \"x\$as_lineno_2\" &&
+ test \"x\`expr \$as_lineno_1 + 1\`\" = \"x\$as_lineno_2\") || { (exit 1); exit 1; }
+") 2> /dev/null; then
+ :
+else
+ as_candidate_shells=
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ case $as_dir in
+ /*)
+ for as_base in sh bash ksh sh5; do
+ as_candidate_shells="$as_candidate_shells $as_dir/$as_base"
+ done;;
+ esac
+done
+IFS=$as_save_IFS
+
+
+ for as_shell in $as_candidate_shells $SHELL; do
+ # Try only shells that exist, to save several forks.
+ if { test -f "$as_shell" || test -f "$as_shell.exe"; } &&
+ { ("$as_shell") 2> /dev/null <<\_ASEOF
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+ emulate sh
+ NULLCMD=:
+ # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '${1+"$@"}'='"$@"'
+ setopt NO_GLOB_SUBST
+else
+ case `(set -o) 2>/dev/null` in
+ *posix*) set -o posix ;;
+esac
+
+fi
+
+
+:
+_ASEOF
+}; then
+ CONFIG_SHELL=$as_shell
+ as_have_required=yes
+ if { "$as_shell" 2> /dev/null <<\_ASEOF
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+ emulate sh
+ NULLCMD=:
+ # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '${1+"$@"}'='"$@"'
+ setopt NO_GLOB_SUBST
+else
+ case `(set -o) 2>/dev/null` in
+ *posix*) set -o posix ;;
+esac
+
+fi
+
+
+:
+(as_func_return () {
+ (exit $1)
+}
+as_func_success () {
+ as_func_return 0
+}
+as_func_failure () {
+ as_func_return 1
+}
+as_func_ret_success () {
+ return 0
+}
+as_func_ret_failure () {
+ return 1
+}
+
+exitcode=0
+if as_func_success; then
+ :
+else
+ exitcode=1
+ echo as_func_success failed.
+fi
+
+if as_func_failure; then
+ exitcode=1
+ echo as_func_failure succeeded.
+fi
+
+if as_func_ret_success; then
+ :
+else
+ exitcode=1
+ echo as_func_ret_success failed.
+fi
+
+if as_func_ret_failure; then
+ exitcode=1
+ echo as_func_ret_failure succeeded.
+fi
+
+if ( set x; as_func_ret_success y && test x = "$1" ); then
+ :
+else
+ exitcode=1
+ echo positional parameters were not saved.
+fi
+
+test $exitcode = 0) || { (exit 1); exit 1; }
+
+(
+ as_lineno_1=$LINENO
+ as_lineno_2=$LINENO
+ test "x$as_lineno_1" != "x$as_lineno_2" &&
+ test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2") || { (exit 1); exit 1; }
+
+_ASEOF
+}; then
+ break
+fi
+
+fi
+
+ done
+
+ if test "x$CONFIG_SHELL" != x; then
+ for as_var in BASH_ENV ENV
+ do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var
+ done
+ export CONFIG_SHELL
+ exec "$CONFIG_SHELL" "$as_myself" ${1+"$@"}
+fi
+
+
+ if test $as_have_required = no; then
+ echo This script requires a shell more modern than all the
+ echo shells that I found on your system. Please install a
+ echo modern shell, or manually run the script under such a
+ echo shell if you do have one.
+ { (exit 1); exit 1; }
+fi
+
+
+fi
+
+fi
+
+
+
+(eval "as_func_return () {
+ (exit \$1)
+}
+as_func_success () {
+ as_func_return 0
+}
+as_func_failure () {
+ as_func_return 1
+}
+as_func_ret_success () {
+ return 0
+}
+as_func_ret_failure () {
+ return 1
+}
+
+exitcode=0
+if as_func_success; then
+ :
+else
+ exitcode=1
+ echo as_func_success failed.
+fi
+
+if as_func_failure; then
+ exitcode=1
+ echo as_func_failure succeeded.
+fi
+
+if as_func_ret_success; then
+ :
+else
+ exitcode=1
+ echo as_func_ret_success failed.
+fi
+
+if as_func_ret_failure; then
+ exitcode=1
+ echo as_func_ret_failure succeeded.
+fi
+
+if ( set x; as_func_ret_success y && test x = \"\$1\" ); then
+ :
+else
+ exitcode=1
+ echo positional parameters were not saved.
+fi
+
+test \$exitcode = 0") || {
+ echo No shell found that supports shell functions.
+ echo Please tell bug-autoconf@gnu.org about your system,
+ echo including any error possibly output before this message.
+ echo This can help us improve future autoconf versions.
+ echo Configuration will now proceed without shell functions.
+}
+
+
+
+ as_lineno_1=$LINENO
+ as_lineno_2=$LINENO
+ test "x$as_lineno_1" != "x$as_lineno_2" &&
+ test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || {
+
+ # Create $as_me.lineno as a copy of $as_myself, but with $LINENO
+ # uniformly replaced by the line number. The first 'sed' inserts a
+ # line-number line after each line using $LINENO; the second 'sed'
+ # does the real work. The second script uses 'N' to pair each
+ # line-number line with the line containing $LINENO, and appends
+ # trailing '-' during substitution so that $LINENO is not a special
+ # case at line end.
+ # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the
+ # scripts with optimization help from Paolo Bonzini. Blame Lee
+ # E. McMahon (1931-1989) for sed's syntax. :-)
+ sed -n '
+ p
+ /[$]LINENO/=
+ ' <$as_myself |
+ sed '
+ s/[$]LINENO.*/&-/
+ t lineno
+ b
+ :lineno
+ N
+ :loop
+ s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/
+ t loop
+ s/-\n.*//
+ ' >$as_me.lineno &&
+ chmod +x "$as_me.lineno" ||
+ { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2
+ { (exit 1); exit 1; }; }
+
+ # Don't try to exec as it changes $[0], causing all sort of problems
+ # (the dirname of $[0] is not the place where we might find the
+ # original and so on. Autoconf is especially sensitive to this).
+ . "./$as_me.lineno"
+ # Exit status is that of the last command.
+ exit
+}
+
+
+if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
+ as_dirname=dirname
+else
+ as_dirname=false
+fi
+
+ECHO_C= ECHO_N= ECHO_T=
+case `echo -n x` in
+-n*)
+ case `echo 'x\c'` in
+ *c*) ECHO_T=' ';; # ECHO_T is single tab character.
+ *) ECHO_C='\c';;
+ esac;;
+*)
+ ECHO_N='-n';;
+esac
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+ test "X`expr 00001 : '.*\(...\)'`" = X001; then
+ as_expr=expr
+else
+ as_expr=false
+fi
+
+rm -f conf$$ conf$$.exe conf$$.file
+if test -d conf$$.dir; then
+ rm -f conf$$.dir/conf$$.file
+else
+ rm -f conf$$.dir
+ mkdir conf$$.dir 2>/dev/null
+fi
+if (echo >conf$$.file) 2>/dev/null; then
+ if ln -s conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s='ln -s'
+ # ... but there are two gotchas:
+ # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
+ # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
+ # In both cases, we have to default to `cp -p'.
+ ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+ as_ln_s='cp -p'
+ elif ln conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s=ln
+ else
+ as_ln_s='cp -p'
+ fi
+else
+ as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
+rmdir conf$$.dir 2>/dev/null
+
+if mkdir -p . 2>/dev/null; then
+ as_mkdir_p=:
+else
+ test -d ./-p && rmdir ./-p
+ as_mkdir_p=false
+fi
+
+if test -x / >/dev/null 2>&1; then
+ as_test_x='test -x'
+else
+ if ls -dL / >/dev/null 2>&1; then
+ as_ls_L_option=L
+ else
+ as_ls_L_option=
+ fi
+ as_test_x='
+ eval sh -c '\''
+ if test -d "$1"; then
+ test -d "$1/.";
+ else
+ case $1 in
+ -*)set "./$1";;
+ esac;
+ case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in
+ ???[sx]*):;;*)false;;esac;fi
+ '\'' sh
+ '
+fi
+as_executable_p=$as_test_x
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+
+
+# Check that we are running under the correct shell.
+SHELL=${CONFIG_SHELL-/bin/sh}
+
+case X$lt_ECHO in
+X*--fallback-echo)
+ # Remove one level of quotation (which was required for Make).
+ ECHO=`echo "$lt_ECHO" | sed 's,\\\\\$\\$0,'$0','`
+ ;;
+esac
+
+ECHO=${lt_ECHO-echo}
+if test "X$1" = X--no-reexec; then
+ # Discard the --no-reexec flag, and continue.
+ shift
+elif test "X$1" = X--fallback-echo; then
+ # Avoid inline document here, it may be left over
+ :
+elif test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' ; then
+ # Yippee, $ECHO works!
+ :
+else
+ # Restart under the correct shell.
+ exec $SHELL "$0" --no-reexec ${1+"$@"}
+fi
+
+if test "X$1" = X--fallback-echo; then
+ # used as fallback echo
+ shift
+ cat <<_LT_EOF
+$*
+_LT_EOF
+ exit 0
+fi
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+if test -z "$lt_ECHO"; then
+ if test "X${echo_test_string+set}" != Xset; then
+ # find a string as large as possible, as long as the shell can cope with it
+ for cmd in 'sed 50q "$0"' 'sed 20q "$0"' 'sed 10q "$0"' 'sed 2q "$0"' 'echo test'; do
+ # expected sizes: less than 2Kb, 1Kb, 512 bytes, 16 bytes, ...
+ if { echo_test_string=`eval $cmd`; } 2>/dev/null &&
+ { test "X$echo_test_string" = "X$echo_test_string"; } 2>/dev/null
+ then
+ break
+ fi
+ done
+ fi
+
+ if test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' &&
+ echo_testing_string=`{ $ECHO "$echo_test_string"; } 2>/dev/null` &&
+ test "X$echo_testing_string" = "X$echo_test_string"; then
+ :
+ else
+ # The Solaris, AIX, and Digital Unix default echo programs unquote
+ # backslashes. This makes it impossible to quote backslashes using
+ # echo "$something" | sed 's/\\/\\\\/g'
+ #
+ # So, first we look for a working echo in the user's PATH.
+
+ lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+ for dir in $PATH /usr/ucb; do
+ IFS="$lt_save_ifs"
+ if (test -f $dir/echo || test -f $dir/echo$ac_exeext) &&
+ test "X`($dir/echo '\t') 2>/dev/null`" = 'X\t' &&
+ echo_testing_string=`($dir/echo "$echo_test_string") 2>/dev/null` &&
+ test "X$echo_testing_string" = "X$echo_test_string"; then
+ ECHO="$dir/echo"
+ break
+ fi
+ done
+ IFS="$lt_save_ifs"
+
+ if test "X$ECHO" = Xecho; then
+ # We didn't find a better echo, so look for alternatives.
+ if test "X`{ print -r '\t'; } 2>/dev/null`" = 'X\t' &&
+ echo_testing_string=`{ print -r "$echo_test_string"; } 2>/dev/null` &&
+ test "X$echo_testing_string" = "X$echo_test_string"; then
+ # This shell has a builtin print -r that does the trick.
+ ECHO='print -r'
+ elif { test -f /bin/ksh || test -f /bin/ksh$ac_exeext; } &&
+ test "X$CONFIG_SHELL" != X/bin/ksh; then
+ # If we have ksh, try running configure again with it.
+ ORIGINAL_CONFIG_SHELL=${CONFIG_SHELL-/bin/sh}
+ export ORIGINAL_CONFIG_SHELL
+ CONFIG_SHELL=/bin/ksh
+ export CONFIG_SHELL
+ exec $CONFIG_SHELL "$0" --no-reexec ${1+"$@"}
+ else
+ # Try using printf.
+ ECHO='printf %s\n'
+ if test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' &&
+ echo_testing_string=`{ $ECHO "$echo_test_string"; } 2>/dev/null` &&
+ test "X$echo_testing_string" = "X$echo_test_string"; then
+ # Cool, printf works
+ :
+ elif echo_testing_string=`($ORIGINAL_CONFIG_SHELL "$0" --fallback-echo '\t') 2>/dev/null` &&
+ test "X$echo_testing_string" = 'X\t' &&
+ echo_testing_string=`($ORIGINAL_CONFIG_SHELL "$0" --fallback-echo "$echo_test_string") 2>/dev/null` &&
+ test "X$echo_testing_string" = "X$echo_test_string"; then
+ CONFIG_SHELL=$ORIGINAL_CONFIG_SHELL
+ export CONFIG_SHELL
+ SHELL="$CONFIG_SHELL"
+ export SHELL
+ ECHO="$CONFIG_SHELL $0 --fallback-echo"
+ elif echo_testing_string=`($CONFIG_SHELL "$0" --fallback-echo '\t') 2>/dev/null` &&
+ test "X$echo_testing_string" = 'X\t' &&
+ echo_testing_string=`($CONFIG_SHELL "$0" --fallback-echo "$echo_test_string") 2>/dev/null` &&
+ test "X$echo_testing_string" = "X$echo_test_string"; then
+ ECHO="$CONFIG_SHELL $0 --fallback-echo"
+ else
+ # maybe with a smaller string...
+ prev=:
+
+ for cmd in 'echo test' 'sed 2q "$0"' 'sed 10q "$0"' 'sed 20q "$0"' 'sed 50q "$0"'; do
+ if { test "X$echo_test_string" = "X`eval $cmd`"; } 2>/dev/null
+ then
+ break
+ fi
+ prev="$cmd"
+ done
+
+ if test "$prev" != 'sed 50q "$0"'; then
+ echo_test_string=`eval $prev`
+ export echo_test_string
+ exec ${ORIGINAL_CONFIG_SHELL-${CONFIG_SHELL-/bin/sh}} "$0" ${1+"$@"}
+ else
+ # Oops. We lost completely, so just stick with echo.
+ ECHO=echo
+ fi
+ fi
+ fi
+ fi
+ fi
+fi
+
+# Copy echo and quote the copy suitably for passing to libtool from
+# the Makefile, instead of quoting the original, which is used later.
+lt_ECHO=$ECHO
+if test "X$lt_ECHO" = "X$CONFIG_SHELL $0 --fallback-echo"; then
+ lt_ECHO="$CONFIG_SHELL \\\$\$0 --fallback-echo"
+fi
+
+
+
+
+exec 7<&0 </dev/null 6>&1
+
+# Name of the host.
+# hostname on some systems (SVR3.2, Linux) returns a bogus exit status,
+# so uname gets run too.
+ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q`
+
+#
+# Initializations.
+#
+ac_default_prefix=/usr/local
+ac_clean_files=
+ac_config_libobj_dir=.
+LIBOBJS=
+cross_compiling=no
+subdirs=
+MFLAGS=
+MAKEFLAGS=
+SHELL=${CONFIG_SHELL-/bin/sh}
+
+# Identity of this package.
+PACKAGE_NAME='gflags'
+PACKAGE_TARNAME='gflags'
+PACKAGE_VERSION='2.0'
+PACKAGE_STRING='gflags 2.0'
+PACKAGE_BUGREPORT='google-gflags@googlegroups.com'
+
+ac_unique_file="README"
+# Factoring default headers for most tests.
+ac_includes_default="\
+#include <stdio.h>
+#ifdef HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+# include <sys/stat.h>
+#endif
+#ifdef STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# ifdef HAVE_STDLIB_H
+# include <stdlib.h>
+# endif
+#endif
+#ifdef HAVE_STRING_H
+# if !defined STDC_HEADERS && defined HAVE_MEMORY_H
+# include <memory.h>
+# endif
+# include <string.h>
+#endif
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif
+#ifdef HAVE_INTTYPES_H
+# include <inttypes.h>
+#endif
+#ifdef HAVE_STDINT_H
+# include <stdint.h>
+#endif
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif"
+
+ac_subst_vars='SHELL
+PATH_SEPARATOR
+PACKAGE_NAME
+PACKAGE_TARNAME
+PACKAGE_VERSION
+PACKAGE_STRING
+PACKAGE_BUGREPORT
+exec_prefix
+prefix
+program_transform_name
+bindir
+sbindir
+libexecdir
+datarootdir
+datadir
+sysconfdir
+sharedstatedir
+localstatedir
+includedir
+oldincludedir
+docdir
+infodir
+htmldir
+dvidir
+pdfdir
+psdir
+libdir
+localedir
+mandir
+DEFS
+ECHO_C
+ECHO_N
+ECHO_T
+LIBS
+build_alias
+host_alias
+target_alias
+INSTALL_PROGRAM
+INSTALL_SCRIPT
+INSTALL_DATA
+am__isrc
+CYGPATH_W
+PACKAGE
+VERSION
+ACLOCAL
+AUTOCONF
+AUTOMAKE
+AUTOHEADER
+MAKEINFO
+install_sh
+STRIP
+INSTALL_STRIP_PROGRAM
+MKDIR_P
+mkdir_p
+AWK
+SET_MAKE
+am__leading_dot
+AMTAR
+am__tar
+am__untar
+CXX
+CXXFLAGS
+LDFLAGS
+CPPFLAGS
+ac_ct_CXX
+EXEEXT
+OBJEXT
+DEPDIR
+am__include
+am__quote
+AMDEP_TRUE
+AMDEP_FALSE
+AMDEPBACKSLASH
+CXXDEPMODE
+am__fastdepCXX_TRUE
+am__fastdepCXX_FALSE
+CC
+CFLAGS
+ac_ct_CC
+CCDEPMODE
+am__fastdepCC_TRUE
+am__fastdepCC_FALSE
+CPP
+GCC_TRUE
+GCC_FALSE
+build
+build_cpu
+build_vendor
+build_os
+host
+host_cpu
+host_vendor
+host_os
+TEST_TMPDIR
+LIBTOOL
+SED
+GREP
+EGREP
+FGREP
+LD
+DUMPBIN
+ac_ct_DUMPBIN
+NM
+LN_S
+OBJDUMP
+AR
+RANLIB
+lt_ECHO
+DSYMUTIL
+NMEDIT
+LIPO
+OTOOL
+OTOOL64
+CXXCPP
+LIBTOOL_DEPS
+SO_VERSION
+acx_pthread_config
+PTHREAD_CC
+PTHREAD_LIBS
+PTHREAD_CFLAGS
+LIBSTDCXX_LA_LINKER_FLAG
+ac_google_start_namespace
+ac_google_end_namespace
+ac_google_namespace
+ac_cv___attribute__unused
+ac_cv_have_stdint_h
+ac_cv_have_systypes_h
+ac_cv_have_inttypes_h
+ac_cv_have_uint16_t
+ac_cv_have_u_int16_t
+ac_cv_have___int16
+LIBOBJS
+LTLIBOBJS'
+ac_subst_files=''
+ac_user_opts='
+enable_option_checking
+enable_dependency_tracking
+enable_fast_install
+enable_shared
+enable_static
+with_pic
+with_gnu_ld
+enable_libtool_lock
+enable_namespace
+'
+ ac_precious_vars='build_alias
+host_alias
+target_alias
+CXX
+CXXFLAGS
+LDFLAGS
+LIBS
+CPPFLAGS
+CCC
+CC
+CFLAGS
+CPP
+CXXCPP'
+
+
+# Initialize some variables set by options.
+ac_init_help=
+ac_init_version=false
+ac_unrecognized_opts=
+ac_unrecognized_sep=
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+cache_file=/dev/null
+exec_prefix=NONE
+no_create=
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+verbose=
+x_includes=NONE
+x_libraries=NONE
+
+# Installation directory options.
+# These are left unexpanded so users can "make install exec_prefix=/foo"
+# and all the variables that are supposed to be based on exec_prefix
+# by default will actually change.
+# Use braces instead of parens because sh, perl, etc. also accept them.
+# (The list follows the same order as the GNU Coding Standards.)
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datarootdir='${prefix}/share'
+datadir='${datarootdir}'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+docdir='${datarootdir}/doc/${PACKAGE_TARNAME}'
+infodir='${datarootdir}/info'
+htmldir='${docdir}'
+dvidir='${docdir}'
+pdfdir='${docdir}'
+psdir='${docdir}'
+libdir='${exec_prefix}/lib'
+localedir='${datarootdir}/locale'
+mandir='${datarootdir}/man'
+
+ac_prev=
+ac_dashdash=
+for ac_option
+do
+ # If the previous option needs an argument, assign it.
+ if test -n "$ac_prev"; then
+ eval $ac_prev=\$ac_option
+ ac_prev=
+ continue
+ fi
+
+ case $ac_option in
+ *=*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;;
+ *) ac_optarg=yes ;;
+ esac
+
+ # Accept the important Cygnus configure options, so we can diagnose typos.
+
+ case $ac_dashdash$ac_option in
+ --)
+ ac_dashdash=yes ;;
+
+ -bindir | --bindir | --bindi | --bind | --bin | --bi)
+ ac_prev=bindir ;;
+ -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+ bindir=$ac_optarg ;;
+
+ -build | --build | --buil | --bui | --bu)
+ ac_prev=build_alias ;;
+ -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+ build_alias=$ac_optarg ;;
+
+ -cache-file | --cache-file | --cache-fil | --cache-fi \
+ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+ ac_prev=cache_file ;;
+ -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+ cache_file=$ac_optarg ;;
+
+ --config-cache | -C)
+ cache_file=config.cache ;;
+
+ -datadir | --datadir | --datadi | --datad)
+ ac_prev=datadir ;;
+ -datadir=* | --datadir=* | --datadi=* | --datad=*)
+ datadir=$ac_optarg ;;
+
+ -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \
+ | --dataroo | --dataro | --datar)
+ ac_prev=datarootdir ;;
+ -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \
+ | --dataroot=* | --dataroo=* | --dataro=* | --datar=*)
+ datarootdir=$ac_optarg ;;
+
+ -disable-* | --disable-*)
+ ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+ { $as_echo "$as_me: error: invalid feature name: $ac_useropt" >&2
+ { (exit 1); exit 1; }; }
+ ac_useropt_orig=$ac_useropt
+ ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+ case $ac_user_opts in
+ *"
+"enable_$ac_useropt"
+"*) ;;
+ *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig"
+ ac_unrecognized_sep=', ';;
+ esac
+ eval enable_$ac_useropt=no ;;
+
+ -docdir | --docdir | --docdi | --doc | --do)
+ ac_prev=docdir ;;
+ -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*)
+ docdir=$ac_optarg ;;
+
+ -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv)
+ ac_prev=dvidir ;;
+ -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*)
+ dvidir=$ac_optarg ;;
+
+ -enable-* | --enable-*)
+ ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+ { $as_echo "$as_me: error: invalid feature name: $ac_useropt" >&2
+ { (exit 1); exit 1; }; }
+ ac_useropt_orig=$ac_useropt
+ ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+ case $ac_user_opts in
+ *"
+"enable_$ac_useropt"
+"*) ;;
+ *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig"
+ ac_unrecognized_sep=', ';;
+ esac
+ eval enable_$ac_useropt=\$ac_optarg ;;
+
+ -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+ | --exec | --exe | --ex)
+ ac_prev=exec_prefix ;;
+ -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+ | --exec=* | --exe=* | --ex=*)
+ exec_prefix=$ac_optarg ;;
+
+ -gas | --gas | --ga | --g)
+ # Obsolete; use --with-gas.
+ with_gas=yes ;;
+
+ -help | --help | --hel | --he | -h)
+ ac_init_help=long ;;
+ -help=r* | --help=r* | --hel=r* | --he=r* | -hr*)
+ ac_init_help=recursive ;;
+ -help=s* | --help=s* | --hel=s* | --he=s* | -hs*)
+ ac_init_help=short ;;
+
+ -host | --host | --hos | --ho)
+ ac_prev=host_alias ;;
+ -host=* | --host=* | --hos=* | --ho=*)
+ host_alias=$ac_optarg ;;
+
+ -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht)
+ ac_prev=htmldir ;;
+ -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \
+ | --ht=*)
+ htmldir=$ac_optarg ;;
+
+ -includedir | --includedir | --includedi | --included | --include \
+ | --includ | --inclu | --incl | --inc)
+ ac_prev=includedir ;;
+ -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+ | --includ=* | --inclu=* | --incl=* | --inc=*)
+ includedir=$ac_optarg ;;
+
+ -infodir | --infodir | --infodi | --infod | --info | --inf)
+ ac_prev=infodir ;;
+ -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+ infodir=$ac_optarg ;;
+
+ -libdir | --libdir | --libdi | --libd)
+ ac_prev=libdir ;;
+ -libdir=* | --libdir=* | --libdi=* | --libd=*)
+ libdir=$ac_optarg ;;
+
+ -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+ | --libexe | --libex | --libe)
+ ac_prev=libexecdir ;;
+ -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+ | --libexe=* | --libex=* | --libe=*)
+ libexecdir=$ac_optarg ;;
+
+ -localedir | --localedir | --localedi | --localed | --locale)
+ ac_prev=localedir ;;
+ -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*)
+ localedir=$ac_optarg ;;
+
+ -localstatedir | --localstatedir | --localstatedi | --localstated \
+ | --localstate | --localstat | --localsta | --localst | --locals)
+ ac_prev=localstatedir ;;
+ -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+ | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*)
+ localstatedir=$ac_optarg ;;
+
+ -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+ ac_prev=mandir ;;
+ -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+ mandir=$ac_optarg ;;
+
+ -nfp | --nfp | --nf)
+ # Obsolete; use --without-fp.
+ with_fp=no ;;
+
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c | -n)
+ no_create=yes ;;
+
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+ no_recursion=yes ;;
+
+ -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+ | --oldin | --oldi | --old | --ol | --o)
+ ac_prev=oldincludedir ;;
+ -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+ oldincludedir=$ac_optarg ;;
+
+ -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+ ac_prev=prefix ;;
+ -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+ prefix=$ac_optarg ;;
+
+ -program-prefix | --program-prefix | --program-prefi | --program-pref \
+ | --program-pre | --program-pr | --program-p)
+ ac_prev=program_prefix ;;
+ -program-prefix=* | --program-prefix=* | --program-prefi=* \
+ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+ program_prefix=$ac_optarg ;;
+
+ -program-suffix | --program-suffix | --program-suffi | --program-suff \
+ | --program-suf | --program-su | --program-s)
+ ac_prev=program_suffix ;;
+ -program-suffix=* | --program-suffix=* | --program-suffi=* \
+ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+ program_suffix=$ac_optarg ;;
+
+ -program-transform-name | --program-transform-name \
+ | --program-transform-nam | --program-transform-na \
+ | --program-transform-n | --program-transform- \
+ | --program-transform | --program-transfor \
+ | --program-transfo | --program-transf \
+ | --program-trans | --program-tran \
+ | --progr-tra | --program-tr | --program-t)
+ ac_prev=program_transform_name ;;
+ -program-transform-name=* | --program-transform-name=* \
+ | --program-transform-nam=* | --program-transform-na=* \
+ | --program-transform-n=* | --program-transform-=* \
+ | --program-transform=* | --program-transfor=* \
+ | --program-transfo=* | --program-transf=* \
+ | --program-trans=* | --program-tran=* \
+ | --progr-tra=* | --program-tr=* | --program-t=*)
+ program_transform_name=$ac_optarg ;;
+
+ -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd)
+ ac_prev=pdfdir ;;
+ -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*)
+ pdfdir=$ac_optarg ;;
+
+ -psdir | --psdir | --psdi | --psd | --ps)
+ ac_prev=psdir ;;
+ -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*)
+ psdir=$ac_optarg ;;
+
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil)
+ silent=yes ;;
+
+ -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+ ac_prev=sbindir ;;
+ -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+ | --sbi=* | --sb=*)
+ sbindir=$ac_optarg ;;
+
+ -sharedstatedir | --sharedstatedir | --sharedstatedi \
+ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+ | --sharedst | --shareds | --shared | --share | --shar \
+ | --sha | --sh)
+ ac_prev=sharedstatedir ;;
+ -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+ | --sha=* | --sh=*)
+ sharedstatedir=$ac_optarg ;;
+
+ -site | --site | --sit)
+ ac_prev=site ;;
+ -site=* | --site=* | --sit=*)
+ site=$ac_optarg ;;
+
+ -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+ ac_prev=srcdir ;;
+ -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+ srcdir=$ac_optarg ;;
+
+ -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+ | --syscon | --sysco | --sysc | --sys | --sy)
+ ac_prev=sysconfdir ;;
+ -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+ sysconfdir=$ac_optarg ;;
+
+ -target | --target | --targe | --targ | --tar | --ta | --t)
+ ac_prev=target_alias ;;
+ -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+ target_alias=$ac_optarg ;;
+
+ -v | -verbose | --verbose | --verbos | --verbo | --verb)
+ verbose=yes ;;
+
+ -version | --version | --versio | --versi | --vers | -V)
+ ac_init_version=: ;;
+
+ -with-* | --with-*)
+ ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+ { $as_echo "$as_me: error: invalid package name: $ac_useropt" >&2
+ { (exit 1); exit 1; }; }
+ ac_useropt_orig=$ac_useropt
+ ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+ case $ac_user_opts in
+ *"
+"with_$ac_useropt"
+"*) ;;
+ *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig"
+ ac_unrecognized_sep=', ';;
+ esac
+ eval with_$ac_useropt=\$ac_optarg ;;
+
+ -without-* | --without-*)
+ ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+ { $as_echo "$as_me: error: invalid package name: $ac_useropt" >&2
+ { (exit 1); exit 1; }; }
+ ac_useropt_orig=$ac_useropt
+ ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+ case $ac_user_opts in
+ *"
+"with_$ac_useropt"
+"*) ;;
+ *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig"
+ ac_unrecognized_sep=', ';;
+ esac
+ eval with_$ac_useropt=no ;;
+
+ --x)
+ # Obsolete; use --with-x.
+ with_x=yes ;;
+
+ -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+ | --x-incl | --x-inc | --x-in | --x-i)
+ ac_prev=x_includes ;;
+ -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+ x_includes=$ac_optarg ;;
+
+ -x-libraries | --x-libraries | --x-librarie | --x-librari \
+ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+ ac_prev=x_libraries ;;
+ -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+ x_libraries=$ac_optarg ;;
+
+ -*) { $as_echo "$as_me: error: unrecognized option: $ac_option
+Try \`$0 --help' for more information." >&2
+ { (exit 1); exit 1; }; }
+ ;;
+
+ *=*)
+ ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null &&
+ { $as_echo "$as_me: error: invalid variable name: $ac_envvar" >&2
+ { (exit 1); exit 1; }; }
+ eval $ac_envvar=\$ac_optarg
+ export $ac_envvar ;;
+
+ *)
+ # FIXME: should be removed in autoconf 3.0.
+ $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2
+ expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null &&
+ $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2
+ : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}
+ ;;
+
+ esac
+done
+
+if test -n "$ac_prev"; then
+ ac_option=--`echo $ac_prev | sed 's/_/-/g'`
+ { $as_echo "$as_me: error: missing argument to $ac_option" >&2
+ { (exit 1); exit 1; }; }
+fi
+
+if test -n "$ac_unrecognized_opts"; then
+ case $enable_option_checking in
+ no) ;;
+ fatal) { $as_echo "$as_me: error: Unrecognized options: $ac_unrecognized_opts" >&2
+ { (exit 1); exit 1; }; } ;;
+ *) $as_echo "$as_me: WARNING: Unrecognized options: $ac_unrecognized_opts" >&2 ;;
+ esac
+fi
+
+# Check all directory arguments for consistency.
+for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \
+ datadir sysconfdir sharedstatedir localstatedir includedir \
+ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
+ libdir localedir mandir
+do
+ eval ac_val=\$$ac_var
+ # Remove trailing slashes.
+ case $ac_val in
+ */ )
+ ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'`
+ eval $ac_var=\$ac_val;;
+ esac
+ # Be sure to have absolute directory names.
+ case $ac_val in
+ [\\/$]* | ?:[\\/]* ) continue;;
+ NONE | '' ) case $ac_var in *prefix ) continue;; esac;;
+ esac
+ { $as_echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2
+ { (exit 1); exit 1; }; }
+done
+
+# There might be people who depend on the old broken behavior: `$host'
+# used to hold the argument of --host etc.
+# FIXME: To remove some day.
+build=$build_alias
+host=$host_alias
+target=$target_alias
+
+# FIXME: To remove some day.
+if test "x$host_alias" != x; then
+ if test "x$build_alias" = x; then
+ cross_compiling=maybe
+ $as_echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host.
+ If a cross compiler is detected then cross compile mode will be used." >&2
+ elif test "x$build_alias" != "x$host_alias"; then
+ cross_compiling=yes
+ fi
+fi
+
+ac_tool_prefix=
+test -n "$host_alias" && ac_tool_prefix=$host_alias-
+
+test "$silent" = yes && exec 6>/dev/null
+
+
+ac_pwd=`pwd` && test -n "$ac_pwd" &&
+ac_ls_di=`ls -di .` &&
+ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` ||
+ { $as_echo "$as_me: error: Working directory cannot be determined" >&2
+ { (exit 1); exit 1; }; }
+test "X$ac_ls_di" = "X$ac_pwd_ls_di" ||
+ { $as_echo "$as_me: error: pwd does not report name of working directory" >&2
+ { (exit 1); exit 1; }; }
+
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+ ac_srcdir_defaulted=yes
+ # Try the directory containing this script, then the parent directory.
+ ac_confdir=`$as_dirname -- "$as_myself" ||
+$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$as_myself" : 'X\(//\)[^/]' \| \
+ X"$as_myself" : 'X\(//\)$' \| \
+ X"$as_myself" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_myself" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ srcdir=$ac_confdir
+ if test ! -r "$srcdir/$ac_unique_file"; then
+ srcdir=..
+ fi
+else
+ ac_srcdir_defaulted=no
+fi
+if test ! -r "$srcdir/$ac_unique_file"; then
+ test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .."
+ { $as_echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2
+ { (exit 1); exit 1; }; }
+fi
+ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work"
+ac_abs_confdir=`(
+ cd "$srcdir" && test -r "./$ac_unique_file" || { $as_echo "$as_me: error: $ac_msg" >&2
+ { (exit 1); exit 1; }; }
+ pwd)`
+# When building in place, set srcdir=.
+if test "$ac_abs_confdir" = "$ac_pwd"; then
+ srcdir=.
+fi
+# Remove unnecessary trailing slashes from srcdir.
+# Double slashes in file names in object file debugging info
+# mess up M-x gdb in Emacs.
+case $srcdir in
+*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;;
+esac
+for ac_var in $ac_precious_vars; do
+ eval ac_env_${ac_var}_set=\${${ac_var}+set}
+ eval ac_env_${ac_var}_value=\$${ac_var}
+ eval ac_cv_env_${ac_var}_set=\${${ac_var}+set}
+ eval ac_cv_env_${ac_var}_value=\$${ac_var}
+done
+
+#
+# Report the --help message.
+#
+if test "$ac_init_help" = "long"; then
+ # Omit some internal or obsolete options to make the list less imposing.
+ # This message is too long to be a string in the A/UX 3.1 sh.
+ cat <<_ACEOF
+\`configure' configures gflags 2.0 to adapt to many kinds of systems.
+
+Usage: $0 [OPTION]... [VAR=VALUE]...
+
+To assign environment variables (e.g., CC, CFLAGS...), specify them as
+VAR=VALUE. See below for descriptions of some of the useful variables.
+
+Defaults for the options are specified in brackets.
+
+Configuration:
+ -h, --help display this help and exit
+ --help=short display options specific to this package
+ --help=recursive display the short help of all the included packages
+ -V, --version display version information and exit
+ -q, --quiet, --silent do not print \`checking...' messages
+ --cache-file=FILE cache test results in FILE [disabled]
+ -C, --config-cache alias for \`--cache-file=config.cache'
+ -n, --no-create do not create output files
+ --srcdir=DIR find the sources in DIR [configure dir or \`..']
+
+Installation directories:
+ --prefix=PREFIX install architecture-independent files in PREFIX
+ [$ac_default_prefix]
+ --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX
+ [PREFIX]
+
+By default, \`make install' will install all the files in
+\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify
+an installation prefix other than \`$ac_default_prefix' using \`--prefix',
+for instance \`--prefix=\$HOME'.
+
+For better control, use the options below.
+
+Fine tuning of the installation directories:
+ --bindir=DIR user executables [EPREFIX/bin]
+ --sbindir=DIR system admin executables [EPREFIX/sbin]
+ --libexecdir=DIR program executables [EPREFIX/libexec]
+ --sysconfdir=DIR read-only single-machine data [PREFIX/etc]
+ --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com]
+ --localstatedir=DIR modifiable single-machine data [PREFIX/var]
+ --libdir=DIR object code libraries [EPREFIX/lib]
+ --includedir=DIR C header files [PREFIX/include]
+ --oldincludedir=DIR C header files for non-gcc [/usr/include]
+ --datarootdir=DIR read-only arch.-independent data root [PREFIX/share]
+ --datadir=DIR read-only architecture-independent data [DATAROOTDIR]
+ --infodir=DIR info documentation [DATAROOTDIR/info]
+ --localedir=DIR locale-dependent data [DATAROOTDIR/locale]
+ --mandir=DIR man documentation [DATAROOTDIR/man]
+ --docdir=DIR documentation root [DATAROOTDIR/doc/gflags]
+ --htmldir=DIR html documentation [DOCDIR]
+ --dvidir=DIR dvi documentation [DOCDIR]
+ --pdfdir=DIR pdf documentation [DOCDIR]
+ --psdir=DIR ps documentation [DOCDIR]
+_ACEOF
+
+ cat <<\_ACEOF
+
+Program names:
+ --program-prefix=PREFIX prepend PREFIX to installed program names
+ --program-suffix=SUFFIX append SUFFIX to installed program names
+ --program-transform-name=PROGRAM run sed PROGRAM on installed program names
+
+System types:
+ --build=BUILD configure for building on BUILD [guessed]
+ --host=HOST cross-compile to build programs to run on HOST [BUILD]
+_ACEOF
+fi
+
+if test -n "$ac_init_help"; then
+ case $ac_init_help in
+ short | recursive ) echo "Configuration of gflags 2.0:";;
+ esac
+ cat <<\_ACEOF
+
+Optional Features:
+ --disable-option-checking ignore unrecognized --enable/--with options
+ --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
+ --enable-FEATURE[=ARG] include FEATURE [ARG=yes]
+ --disable-dependency-tracking speeds up one-time build
+ --enable-dependency-tracking do not reject slow dependency extractors
+ --enable-fast-install[=PKGS]
+ optimize for fast installation [default=no]
+ --enable-shared[=PKGS] build shared libraries [default=yes]
+ --enable-static[=PKGS] build static libraries [default=yes]
+ --disable-libtool-lock avoid locking (might break parallel builds)
+ --enable-namespace=FOO to define these Google
+ classes in the FOO namespace. --disable-namespace
+ to define them in the global namespace. Default
+ is to define them in namespace google.
+
+Optional Packages:
+ --with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
+ --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
+ --with-pic try to use only PIC/non-PIC objects [default=use
+ both]
+ --with-gnu-ld assume the C compiler uses GNU ld [default=no]
+
+Some influential environment variables:
+ CXX C++ compiler command
+ CXXFLAGS C++ compiler flags
+ LDFLAGS linker flags, e.g. -L<lib dir> if you have libraries in a
+ nonstandard directory <lib dir>
+ LIBS libraries to pass to the linker, e.g. -l<library>
+ CPPFLAGS C/C++/Objective C preprocessor flags, e.g. -I<include dir> if
+ you have headers in a nonstandard directory <include dir>
+ CC C compiler command
+ CFLAGS C compiler flags
+ CPP C preprocessor
+ CXXCPP C++ preprocessor
+
+Use these variables to override the choices made by `configure' or to help
+it to find libraries and programs with nonstandard names/locations.
+
+Report bugs to <google-gflags@googlegroups.com>.
+_ACEOF
+ac_status=$?
+fi
+
+if test "$ac_init_help" = "recursive"; then
+ # If there are subdirs, report their specific --help.
+ for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue
+ test -d "$ac_dir" ||
+ { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } ||
+ continue
+ ac_builddir=.
+
+case "$ac_dir" in
+.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
+*)
+ ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
+ # A ".." for each directory in $ac_dir_suffix.
+ ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
+ case $ac_top_builddir_sub in
+ "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
+ *) ac_top_build_prefix=$ac_top_builddir_sub/ ;;
+ esac ;;
+esac
+ac_abs_top_builddir=$ac_pwd
+ac_abs_builddir=$ac_pwd$ac_dir_suffix
+# for backward compatibility:
+ac_top_builddir=$ac_top_build_prefix
+
+case $srcdir in
+ .) # We are building in place.
+ ac_srcdir=.
+ ac_top_srcdir=$ac_top_builddir_sub
+ ac_abs_top_srcdir=$ac_pwd ;;
+ [\\/]* | ?:[\\/]* ) # Absolute name.
+ ac_srcdir=$srcdir$ac_dir_suffix;
+ ac_top_srcdir=$srcdir
+ ac_abs_top_srcdir=$srcdir ;;
+ *) # Relative name.
+ ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
+ ac_top_srcdir=$ac_top_build_prefix$srcdir
+ ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
+esac
+ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
+
+ cd "$ac_dir" || { ac_status=$?; continue; }
+ # Check for guested configure.
+ if test -f "$ac_srcdir/configure.gnu"; then
+ echo &&
+ $SHELL "$ac_srcdir/configure.gnu" --help=recursive
+ elif test -f "$ac_srcdir/configure"; then
+ echo &&
+ $SHELL "$ac_srcdir/configure" --help=recursive
+ else
+ $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
+ fi || ac_status=$?
+ cd "$ac_pwd" || { ac_status=$?; break; }
+ done
+fi
+
+test -n "$ac_init_help" && exit $ac_status
+if $ac_init_version; then
+ cat <<\_ACEOF
+gflags configure 2.0
+generated by GNU Autoconf 2.62
+
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
+2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+This configure script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it.
+_ACEOF
+ exit
+fi
+cat >config.log <<_ACEOF
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+
+It was created by gflags $as_me 2.0, which was
+generated by GNU Autoconf 2.62. Invocation command line was
+
+ $ $0 $@
+
+_ACEOF
+exec 5>>config.log
+{
+cat <<_ASUNAME
+## --------- ##
+## Platform. ##
+## --------- ##
+
+hostname = `(hostname || uname -n) 2>/dev/null | sed 1q`
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown`
+/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown`
+
+/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown`
+/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown`
+/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown`
+/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown`
+/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown`
+/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown`
+
+_ASUNAME
+
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ $as_echo "PATH: $as_dir"
+done
+IFS=$as_save_IFS
+
+} >&5
+
+cat >&5 <<_ACEOF
+
+
+## ----------- ##
+## Core tests. ##
+## ----------- ##
+
+_ACEOF
+
+
+# Keep a trace of the command line.
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Strip out --silent because we don't want to record it for future runs.
+# Also quote any args containing shell meta-characters.
+# Make two passes to allow for proper duplicate-argument suppression.
+ac_configure_args=
+ac_configure_args0=
+ac_configure_args1=
+ac_must_keep_next=false
+for ac_pass in 1 2
+do
+ for ac_arg
+ do
+ case $ac_arg in
+ -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;;
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil)
+ continue ;;
+ *\'*)
+ ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
+ esac
+ case $ac_pass in
+ 1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;;
+ 2)
+ ac_configure_args1="$ac_configure_args1 '$ac_arg'"
+ if test $ac_must_keep_next = true; then
+ ac_must_keep_next=false # Got value, back to normal.
+ else
+ case $ac_arg in
+ *=* | --config-cache | -C | -disable-* | --disable-* \
+ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \
+ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \
+ | -with-* | --with-* | -without-* | --without-* | --x)
+ case "$ac_configure_args0 " in
+ "$ac_configure_args1"*" '$ac_arg' "* ) continue ;;
+ esac
+ ;;
+ -* ) ac_must_keep_next=true ;;
+ esac
+ fi
+ ac_configure_args="$ac_configure_args '$ac_arg'"
+ ;;
+ esac
+ done
+done
+$as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; }
+$as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; }
+
+# When interrupted or exit'd, cleanup temporary files, and complete
+# config.log. We remove comments because anyway the quotes in there
+# would cause problems or look ugly.
+# WARNING: Use '\'' to represent an apostrophe within the trap.
+# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug.
+trap 'exit_status=$?
+ # Save into config.log some information that might help in debugging.
+ {
+ echo
+
+ cat <<\_ASBOX
+## ---------------- ##
+## Cache variables. ##
+## ---------------- ##
+_ASBOX
+ echo
+ # The following way of writing the cache mishandles newlines in values,
+(
+ for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do
+ eval ac_val=\$$ac_var
+ case $ac_val in #(
+ *${as_nl}*)
+ case $ac_var in #(
+ *_cv_*) { $as_echo "$as_me:$LINENO: WARNING: Cache variable $ac_var contains a newline." >&5
+$as_echo "$as_me: WARNING: Cache variable $ac_var contains a newline." >&2;} ;;
+ esac
+ case $ac_var in #(
+ _ | IFS | as_nl) ;; #(
+ BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(
+ *) $as_unset $ac_var ;;
+ esac ;;
+ esac
+ done
+ (set) 2>&1 |
+ case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #(
+ *${as_nl}ac_space=\ *)
+ sed -n \
+ "s/'\''/'\''\\\\'\'''\''/g;
+ s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p"
+ ;; #(
+ *)
+ sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
+ ;;
+ esac |
+ sort
+)
+ echo
+
+ cat <<\_ASBOX
+## ----------------- ##
+## Output variables. ##
+## ----------------- ##
+_ASBOX
+ echo
+ for ac_var in $ac_subst_vars
+ do
+ eval ac_val=\$$ac_var
+ case $ac_val in
+ *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
+ esac
+ $as_echo "$ac_var='\''$ac_val'\''"
+ done | sort
+ echo
+
+ if test -n "$ac_subst_files"; then
+ cat <<\_ASBOX
+## ------------------- ##
+## File substitutions. ##
+## ------------------- ##
+_ASBOX
+ echo
+ for ac_var in $ac_subst_files
+ do
+ eval ac_val=\$$ac_var
+ case $ac_val in
+ *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
+ esac
+ $as_echo "$ac_var='\''$ac_val'\''"
+ done | sort
+ echo
+ fi
+
+ if test -s confdefs.h; then
+ cat <<\_ASBOX
+## ----------- ##
+## confdefs.h. ##
+## ----------- ##
+_ASBOX
+ echo
+ cat confdefs.h
+ echo
+ fi
+ test "$ac_signal" != 0 &&
+ $as_echo "$as_me: caught signal $ac_signal"
+ $as_echo "$as_me: exit $exit_status"
+ } >&5
+ rm -f core *.core core.conftest.* &&
+ rm -f -r conftest* confdefs* conf$$* $ac_clean_files &&
+ exit $exit_status
+' 0
+for ac_signal in 1 2 13 15; do
+ trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal
+done
+ac_signal=0
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -f -r conftest* confdefs.h
+
+# Predefined preprocessor variables.
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_NAME "$PACKAGE_NAME"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_TARNAME "$PACKAGE_TARNAME"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_VERSION "$PACKAGE_VERSION"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_STRING "$PACKAGE_STRING"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT"
+_ACEOF
+
+
+# Let the site file select an alternate cache file if it wants to.
+# Prefer an explicitly selected file to automatically selected ones.
+ac_site_file1=NONE
+ac_site_file2=NONE
+if test -n "$CONFIG_SITE"; then
+ ac_site_file1=$CONFIG_SITE
+elif test "x$prefix" != xNONE; then
+ ac_site_file1=$prefix/share/config.site
+ ac_site_file2=$prefix/etc/config.site
+else
+ ac_site_file1=$ac_default_prefix/share/config.site
+ ac_site_file2=$ac_default_prefix/etc/config.site
+fi
+for ac_site_file in "$ac_site_file1" "$ac_site_file2"
+do
+ test "x$ac_site_file" = xNONE && continue
+ if test -r "$ac_site_file"; then
+ { $as_echo "$as_me:$LINENO: loading site script $ac_site_file" >&5
+$as_echo "$as_me: loading site script $ac_site_file" >&6;}
+ sed 's/^/| /' "$ac_site_file" >&5
+ . "$ac_site_file"
+ fi
+done
+
+if test -r "$cache_file"; then
+ # Some versions of bash will fail to source /dev/null (special
+ # files actually), so we avoid doing that.
+ if test -f "$cache_file"; then
+ { $as_echo "$as_me:$LINENO: loading cache $cache_file" >&5
+$as_echo "$as_me: loading cache $cache_file" >&6;}
+ case $cache_file in
+ [\\/]* | ?:[\\/]* ) . "$cache_file";;
+ *) . "./$cache_file";;
+ esac
+ fi
+else
+ { $as_echo "$as_me:$LINENO: creating cache $cache_file" >&5
+$as_echo "$as_me: creating cache $cache_file" >&6;}
+ >$cache_file
+fi
+
+# Check that the precious variables saved in the cache have kept the same
+# value.
+ac_cache_corrupted=false
+for ac_var in $ac_precious_vars; do
+ eval ac_old_set=\$ac_cv_env_${ac_var}_set
+ eval ac_new_set=\$ac_env_${ac_var}_set
+ eval ac_old_val=\$ac_cv_env_${ac_var}_value
+ eval ac_new_val=\$ac_env_${ac_var}_value
+ case $ac_old_set,$ac_new_set in
+ set,)
+ { $as_echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
+$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}
+ ac_cache_corrupted=: ;;
+ ,set)
+ { $as_echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5
+$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;}
+ ac_cache_corrupted=: ;;
+ ,);;
+ *)
+ if test "x$ac_old_val" != "x$ac_new_val"; then
+ # differences in whitespace do not lead to failure.
+ ac_old_val_w=`echo x $ac_old_val`
+ ac_new_val_w=`echo x $ac_new_val`
+ if test "$ac_old_val_w" != "$ac_new_val_w"; then
+ { $as_echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5
+$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
+ ac_cache_corrupted=:
+ else
+ { $as_echo "$as_me:$LINENO: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5
+$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;}
+ eval $ac_var=\$ac_old_val
+ fi
+ { $as_echo "$as_me:$LINENO: former value: \`$ac_old_val'" >&5
+$as_echo "$as_me: former value: \`$ac_old_val'" >&2;}
+ { $as_echo "$as_me:$LINENO: current value: \`$ac_new_val'" >&5
+$as_echo "$as_me: current value: \`$ac_new_val'" >&2;}
+ fi;;
+ esac
+ # Pass precious variables to config.status.
+ if test "$ac_new_set" = set; then
+ case $ac_new_val in
+ *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
+ *) ac_arg=$ac_var=$ac_new_val ;;
+ esac
+ case " $ac_configure_args " in
+ *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy.
+ *) ac_configure_args="$ac_configure_args '$ac_arg'" ;;
+ esac
+ fi
+done
+if $ac_cache_corrupted; then
+ { $as_echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5
+$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;}
+ { { $as_echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5
+$as_echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;}
+ { (exit 1); exit 1; }; }
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+# Update this value for every release! (A:B:C will map to foo.so.(A-C).C.B)
+# http://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html
+SO_VERSION=3:0:1
+
+# The argument here is just something that should be in the current directory
+# (for sanity checking)
+
+
+am__api_version='1.10'
+
+ac_aux_dir=
+for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do
+ if test -f "$ac_dir/install-sh"; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install-sh -c"
+ break
+ elif test -f "$ac_dir/install.sh"; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install.sh -c"
+ break
+ elif test -f "$ac_dir/shtool"; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/shtool install -c"
+ break
+ fi
+done
+if test -z "$ac_aux_dir"; then
+ { { $as_echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" >&5
+$as_echo "$as_me: error: cannot find install-sh or install.sh in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" >&2;}
+ { (exit 1); exit 1; }; }
+fi
+
+# These three variables are undocumented and unsupported,
+# and are intended to be withdrawn in a future Autoconf release.
+# They can cause serious problems if a builder's source tree is in a directory
+# whose full name contains unusual characters.
+ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var.
+ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var.
+ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var.
+
+
+# Find a good install program. We prefer a C program (faster),
+# so one script is as good as another. But avoid the broken or
+# incompatible versions:
+# SysV /etc/install, /usr/sbin/install
+# SunOS /usr/etc/install
+# IRIX /sbin/install
+# AIX /bin/install
+# AmigaOS /C/install, which installs bootblocks on floppy discs
+# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
+# AFS /usr/afsws/bin/install, which mishandles nonexistent args
+# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
+# OS/2's system install, which has a completely different semantic
+# ./install, which can be erroneously created by make from ./install.sh.
+# Reject install programs that cannot install multiple files.
+{ $as_echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5
+$as_echo_n "checking for a BSD-compatible install... " >&6; }
+if test -z "$INSTALL"; then
+if test "${ac_cv_path_install+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ # Account for people who put trailing slashes in PATH elements.
+case $as_dir/ in
+ ./ | .// | /cC/* | \
+ /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \
+ ?:\\/os2\\/install\\/* | ?:\\/OS2\\/INSTALL\\/* | \
+ /usr/ucb/* ) ;;
+ *)
+ # OSF1 and SCO ODT 3.0 have their own names for install.
+ # Don't use installbsd from OSF since it installs stuff as root
+ # by default.
+ for ac_prog in ginstall scoinst install; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; }; then
+ if test $ac_prog = install &&
+ grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+ # AIX install. It has an incompatible calling convention.
+ :
+ elif test $ac_prog = install &&
+ grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+ # program-specific install script used by HP pwplus--don't use.
+ :
+ else
+ rm -rf conftest.one conftest.two conftest.dir
+ echo one > conftest.one
+ echo two > conftest.two
+ mkdir conftest.dir
+ if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" &&
+ test -s conftest.one && test -s conftest.two &&
+ test -s conftest.dir/conftest.one &&
+ test -s conftest.dir/conftest.two
+ then
+ ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c"
+ break 3
+ fi
+ fi
+ fi
+ done
+ done
+ ;;
+esac
+
+done
+IFS=$as_save_IFS
+
+rm -rf conftest.one conftest.two conftest.dir
+
+fi
+ if test "${ac_cv_path_install+set}" = set; then
+ INSTALL=$ac_cv_path_install
+ else
+ # As a last resort, use the slow shell script. Don't cache a
+ # value for INSTALL within a source directory, because that will
+ # break other packages using the cache if that directory is
+ # removed, or if the value is a relative name.
+ INSTALL=$ac_install_sh
+ fi
+fi
+{ $as_echo "$as_me:$LINENO: result: $INSTALL" >&5
+$as_echo "$INSTALL" >&6; }
+
+# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
+# It thinks the first close brace ends the variable substitution.
+test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
+
+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}'
+
+test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+{ $as_echo "$as_me:$LINENO: checking whether build environment is sane" >&5
+$as_echo_n "checking whether build environment is sane... " >&6; }
+# Just in case
+sleep 1
+echo timestamp > conftest.file
+# Do `set' in a subshell so we don't clobber the current shell's
+# arguments. Must try -L first in case configure is actually a
+# symlink; some systems play weird games with the mod time of symlinks
+# (eg FreeBSD returns the mod time of the symlink's containing
+# directory).
+if (
+ set X `ls -Lt $srcdir/configure conftest.file 2> /dev/null`
+ if test "$*" = "X"; then
+ # -L didn't work.
+ set X `ls -t $srcdir/configure conftest.file`
+ fi
+ rm -f conftest.file
+ if test "$*" != "X $srcdir/configure conftest.file" \
+ && test "$*" != "X conftest.file $srcdir/configure"; then
+
+ # If neither matched, then we have a broken ls. This can happen
+ # if, for instance, CONFIG_SHELL is bash and it inherits a
+ # broken ls alias from the environment. This has actually
+ # happened. Such a system could not be considered "sane".
+ { { $as_echo "$as_me:$LINENO: error: ls -t appears to fail. Make sure there is not a broken
+alias in your environment" >&5
+$as_echo "$as_me: error: ls -t appears to fail. Make sure there is not a broken
+alias in your environment" >&2;}
+ { (exit 1); exit 1; }; }
+ fi
+
+ test "$2" = conftest.file
+ )
+then
+ # Ok.
+ :
+else
+ { { $as_echo "$as_me:$LINENO: error: newly created file is older than distributed files!
+Check your system clock" >&5
+$as_echo "$as_me: error: newly created file is older than distributed files!
+Check your system clock" >&2;}
+ { (exit 1); exit 1; }; }
+fi
+{ $as_echo "$as_me:$LINENO: result: yes" >&5
+$as_echo "yes" >&6; }
+test "$program_prefix" != NONE &&
+ program_transform_name="s&^&$program_prefix&;$program_transform_name"
+# Use a double $ so make ignores it.
+test "$program_suffix" != NONE &&
+ program_transform_name="s&\$&$program_suffix&;$program_transform_name"
+# Double any \ or $.
+# By default was `s,x,x', remove it if useless.
+ac_script='s/[\\$]/&&/g;s/;s,x,x,$//'
+program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"`
+
+# expand $ac_aux_dir to an absolute path
+am_aux_dir=`cd $ac_aux_dir && pwd`
+
+test x"${MISSING+set}" = xset || MISSING="\${SHELL} $am_aux_dir/missing"
+# Use eval to expand $SHELL
+if eval "$MISSING --run true"; then
+ am_missing_run="$MISSING --run "
+else
+ am_missing_run=
+ { $as_echo "$as_me:$LINENO: WARNING: \`missing' script is too old or missing" >&5
+$as_echo "$as_me: WARNING: \`missing' script is too old or missing" >&2;}
+fi
+
+{ $as_echo "$as_me:$LINENO: checking for a thread-safe mkdir -p" >&5
+$as_echo_n "checking for a thread-safe mkdir -p... " >&6; }
+if test -z "$MKDIR_P"; then
+ if test "${ac_cv_path_mkdir+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_prog in mkdir gmkdir; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; } || continue
+ case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #(
+ 'mkdir (GNU coreutils) '* | \
+ 'mkdir (coreutils) '* | \
+ 'mkdir (fileutils) '4.1*)
+ ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext
+ break 3;;
+ esac
+ done
+ done
+done
+IFS=$as_save_IFS
+
+fi
+
+ if test "${ac_cv_path_mkdir+set}" = set; then
+ MKDIR_P="$ac_cv_path_mkdir -p"
+ else
+ # As a last resort, use the slow shell script. Don't cache a
+ # value for MKDIR_P within a source directory, because that will
+ # break other packages using the cache if that directory is
+ # removed, or if the value is a relative name.
+ test -d ./--version && rmdir ./--version
+ MKDIR_P="$ac_install_sh -d"
+ fi
+fi
+{ $as_echo "$as_me:$LINENO: result: $MKDIR_P" >&5
+$as_echo "$MKDIR_P" >&6; }
+
+mkdir_p="$MKDIR_P"
+case $mkdir_p in
+ [\\/$]* | ?:[\\/]*) ;;
+ */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;;
+esac
+
+for ac_prog in gawk mawk nawk awk
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_AWK+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$AWK"; then
+ ac_cv_prog_AWK="$AWK" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_AWK="$ac_prog"
+ $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+AWK=$ac_cv_prog_AWK
+if test -n "$AWK"; then
+ { $as_echo "$as_me:$LINENO: result: $AWK" >&5
+$as_echo "$AWK" >&6; }
+else
+ { $as_echo "$as_me:$LINENO: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$AWK" && break
+done
+
+{ $as_echo "$as_me:$LINENO: checking whether ${MAKE-make} sets \$(MAKE)" >&5
+$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; }
+set x ${MAKE-make}
+ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'`
+if { as_var=ac_cv_prog_make_${ac_make}_set; eval "test \"\${$as_var+set}\" = set"; }; then
+ $as_echo_n "(cached) " >&6
+else
+ cat >conftest.make <<\_ACEOF
+SHELL = /bin/sh
+all:
+ @echo '@@@%%%=$(MAKE)=@@@%%%'
+_ACEOF
+# GNU make sometimes prints "make[1]: Entering...", which would confuse us.
+case `${MAKE-make} -f conftest.make 2>/dev/null` in
+ *@@@%%%=?*=@@@%%%*)
+ eval ac_cv_prog_make_${ac_make}_set=yes;;
+ *)
+ eval ac_cv_prog_make_${ac_make}_set=no;;
+esac
+rm -f conftest.make
+fi
+if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then
+ { $as_echo "$as_me:$LINENO: result: yes" >&5
+$as_echo "yes" >&6; }
+ SET_MAKE=
+else
+ { $as_echo "$as_me:$LINENO: result: no" >&5
+$as_echo "no" >&6; }
+ SET_MAKE="MAKE=${MAKE-make}"
+fi
+
+rm -rf .tst 2>/dev/null
+mkdir .tst 2>/dev/null
+if test -d .tst; then
+ am__leading_dot=.
+else
+ am__leading_dot=_
+fi
+rmdir .tst 2>/dev/null
+
+if test "`cd $srcdir && pwd`" != "`pwd`"; then
+ # Use -I$(srcdir) only when $(srcdir) != ., so that make's output
+ # is not polluted with repeated "-I."
+ am__isrc=' -I$(srcdir)'
+ # test to see if srcdir already configured
+ if test -f $srcdir/config.status; then
+ { { $as_echo "$as_me:$LINENO: error: source directory already configured; run \"make distclean\" there first" >&5
+$as_echo "$as_me: error: source directory already configured; run \"make distclean\" there first" >&2;}
+ { (exit 1); exit 1; }; }
+ fi
+fi
+
+# test whether we have cygpath
+if test -z "$CYGPATH_W"; then
+ if (cygpath --version) >/dev/null 2>/dev/null; then
+ CYGPATH_W='cygpath -w'
+ else
+ CYGPATH_W=echo
+ fi
+fi
+
+
+# Define the identity of the package.
+ PACKAGE='gflags'
+ VERSION='2.0'
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE "$PACKAGE"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define VERSION "$VERSION"
+_ACEOF
+
+# Some tools Automake needs.
+
+ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"}
+
+
+AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"}
+
+
+AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"}
+
+
+AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"}
+
+
+MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"}
+
+install_sh=${install_sh-"\$(SHELL) $am_aux_dir/install-sh"}
+
+# Installed binaries are usually stripped using `strip' when the user
+# run `make install-strip'. However `strip' might not be the right
+# tool to use in cross-compilation environments, therefore Automake
+# will honor the `STRIP' environment variable to overrule this program.
+if test "$cross_compiling" != no; then
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args.
+set dummy ${ac_tool_prefix}strip; ac_word=$2
+{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_STRIP+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$STRIP"; then
+ ac_cv_prog_STRIP="$STRIP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_STRIP="${ac_tool_prefix}strip"
+ $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+STRIP=$ac_cv_prog_STRIP
+if test -n "$STRIP"; then
+ { $as_echo "$as_me:$LINENO: result: $STRIP" >&5
+$as_echo "$STRIP" >&6; }
+else
+ { $as_echo "$as_me:$LINENO: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_STRIP"; then
+ ac_ct_STRIP=$STRIP
+ # Extract the first word of "strip", so it can be a program name with args.
+set dummy strip; ac_word=$2
+{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_STRIP+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_STRIP"; then
+ ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_ac_ct_STRIP="strip"
+ $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP
+if test -n "$ac_ct_STRIP"; then
+ { $as_echo "$as_me:$LINENO: result: $ac_ct_STRIP" >&5
+$as_echo "$ac_ct_STRIP" >&6; }
+else
+ { $as_echo "$as_me:$LINENO: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_STRIP" = x; then
+ STRIP=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools
+whose name does not start with the host triplet. If you think this
+configuration is useful to you, please write to autoconf@gnu.org." >&5
+$as_echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools
+whose name does not start with the host triplet. If you think this
+configuration is useful to you, please write to autoconf@gnu.org." >&2;}
+ac_tool_warned=yes ;;
+esac
+ STRIP=$ac_ct_STRIP
+ fi
+else
+ STRIP="$ac_cv_prog_STRIP"
+fi
+
+fi
+INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s"
+
+# We need awk for the "check" target. The system "awk" is bad on
+# some platforms.
+# Always define AMTAR for backward compatibility.
+
+AMTAR=${AMTAR-"${am_missing_run}tar"}
+
+am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'
+
+
+
+
+
+ac_config_headers="$ac_config_headers src/config.h"
+
+
+# Checks for programs.
+ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+if test -z "$CXX"; then
+ if test -n "$CCC"; then
+ CXX=$CCC
+ else
+ if test -n "$ac_tool_prefix"; then
+ for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC
+ do
+ # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_CXX+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CXX"; then
+ ac_cv_prog_CXX="$CXX" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_CXX="$ac_tool_prefix$ac_prog"
+ $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+CXX=$ac_cv_prog_CXX
+if test -n "$CXX"; then
+ { $as_echo "$as_me:$LINENO: result: $CXX" >&5
+$as_echo "$CXX" >&6; }
+else
+ { $as_echo "$as_me:$LINENO: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$CXX" && break
+ done
+fi
+if test -z "$CXX"; then
+ ac_ct_CXX=$CXX
+ for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_CXX+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_CXX"; then
+ ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_ac_ct_CXX="$ac_prog"
+ $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CXX=$ac_cv_prog_ac_ct_CXX
+if test -n "$ac_ct_CXX"; then
+ { $as_echo "$as_me:$LINENO: result: $ac_ct_CXX" >&5
+$as_echo "$ac_ct_CXX" >&6; }
+else
+ { $as_echo "$as_me:$LINENO: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$ac_ct_CXX" && break
+done
+
+ if test "x$ac_ct_CXX" = x; then
+ CXX="g++"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools
+whose name does not start with the host triplet. If you think this
+configuration is useful to you, please write to autoconf@gnu.org." >&5
+$as_echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools
+whose name does not start with the host triplet. If you think this
+configuration is useful to you, please write to autoconf@gnu.org." >&2;}
+ac_tool_warned=yes ;;
+esac
+ CXX=$ac_ct_CXX
+ fi
+fi
+
+ fi
+fi
+# Provide some information about the compiler.
+$as_echo "$as_me:$LINENO: checking for C++ compiler version" >&5
+set X $ac_compile
+ac_compiler=$2
+{ (ac_try="$ac_compiler --version >&5"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compiler --version >&5") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }
+{ (ac_try="$ac_compiler -v >&5"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compiler -v >&5") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }
+{ (ac_try="$ac_compiler -V >&5"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compiler -V >&5") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }
+
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out"
+# Try to create an executable without -o first, disregard a.out.
+# It will help us diagnose broken compilers, and finding out an intuition
+# of exeext.
+{ $as_echo "$as_me:$LINENO: checking for C++ compiler default output file name" >&5
+$as_echo_n "checking for C++ compiler default output file name... " >&6; }
+ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
+
+# The possible output files:
+ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*"
+
+ac_rmfiles=
+for ac_file in $ac_files
+do
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;
+ * ) ac_rmfiles="$ac_rmfiles $ac_file";;
+ esac
+done
+rm -f $ac_rmfiles
+
+if { (ac_try="$ac_link_default"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_link_default") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; then
+ # Autoconf-2.13 could set the ac_cv_exeext variable to `no'.
+# So ignore a value of `no', otherwise this would lead to `EXEEXT = no'
+# in a Makefile. We should not override ac_cv_exeext if it was cached,
+# so that the user can short-circuit this test for compilers unknown to
+# Autoconf.
+for ac_file in $ac_files ''
+do
+ test -f "$ac_file" || continue
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj )
+ ;;
+ [ab].out )
+ # We found the default executable, but exeext='' is most
+ # certainly right.
+ break;;
+ *.* )
+ if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no;
+ then :; else
+ ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+ fi
+ # We set ac_cv_exeext here because the later test for it is not
+ # safe: cross compilers may not add the suffix if given an `-o'
+ # argument, so we may need to know it at that point already.
+ # Even if this section looks crufty: it has the advantage of
+ # actually working.
+ break;;
+ * )
+ break;;
+ esac
+done
+test "$ac_cv_exeext" = no && ac_cv_exeext=
+
+else
+ ac_file=''
+fi
+
+{ $as_echo "$as_me:$LINENO: result: $ac_file" >&5
+$as_echo "$ac_file" >&6; }
+if test -z "$ac_file"; then
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { $as_echo "$as_me:$LINENO: error: C++ compiler cannot create executables
+See \`config.log' for more details." >&5
+$as_echo "$as_me: error: C++ compiler cannot create executables
+See \`config.log' for more details." >&2;}
+ { (exit 77); exit 77; }; }
+fi
+
+ac_exeext=$ac_cv_exeext
+
+# Check that the compiler produces executables we can run. If not, either
+# the compiler is broken, or we cross compile.
+{ $as_echo "$as_me:$LINENO: checking whether the C++ compiler works" >&5
+$as_echo_n "checking whether the C++ compiler works... " >&6; }
+# FIXME: These cross compiler hacks should be removed for Autoconf 3.0
+# If not cross compiling, check that we can run a simple program.
+if test "$cross_compiling" != yes; then
+ if { ac_try='./$ac_file'
+ { (case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_try") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ cross_compiling=no
+ else
+ if test "$cross_compiling" = maybe; then
+ cross_compiling=yes
+ else
+ { { $as_echo "$as_me:$LINENO: error: cannot run C++ compiled programs.
+If you meant to cross compile, use \`--host'.
+See \`config.log' for more details." >&5
+$as_echo "$as_me: error: cannot run C++ compiled programs.
+If you meant to cross compile, use \`--host'.
+See \`config.log' for more details." >&2;}
+ { (exit 1); exit 1; }; }
+ fi
+ fi
+fi
+{ $as_echo "$as_me:$LINENO: result: yes" >&5
+$as_echo "yes" >&6; }
+
+rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out
+ac_clean_files=$ac_clean_files_save
+# Check that the compiler produces executables we can run. If not, either
+# the compiler is broken, or we cross compile.
+{ $as_echo "$as_me:$LINENO: checking whether we are cross compiling" >&5
+$as_echo_n "checking whether we are cross compiling... " >&6; }
+{ $as_echo "$as_me:$LINENO: result: $cross_compiling" >&5
+$as_echo "$cross_compiling" >&6; }
+
+{ $as_echo "$as_me:$LINENO: checking for suffix of executables" >&5
+$as_echo_n "checking for suffix of executables... " >&6; }
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_link") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; then
+ # If both `conftest.exe' and `conftest' are `present' (well, observable)
+# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will
+# work properly (i.e., refer to `conftest.exe'), while it won't with
+# `rm'.
+for ac_file in conftest.exe conftest conftest.*; do
+ test -f "$ac_file" || continue
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;
+ *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+ break;;
+ * ) break;;
+ esac
+done
+else
+ { { $as_echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details." >&5
+$as_echo "$as_me: error: cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+
+rm -f conftest$ac_cv_exeext
+{ $as_echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5
+$as_echo "$ac_cv_exeext" >&6; }
+
+rm -f conftest.$ac_ext
+EXEEXT=$ac_cv_exeext
+ac_exeext=$EXEEXT
+{ $as_echo "$as_me:$LINENO: checking for suffix of object files" >&5
+$as_echo_n "checking for suffix of object files... " >&6; }
+if test "${ac_cv_objext+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.o conftest.obj
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compile") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; then
+ for ac_file in conftest.o conftest.obj conftest.*; do
+ test -f "$ac_file" || continue;
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;;
+ *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'`
+ break;;
+ esac
+done
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { $as_echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile
+See \`config.log' for more details." >&5
+$as_echo "$as_me: error: cannot compute suffix of object files: cannot compile
+See \`config.log' for more details." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+
+rm -f conftest.$ac_cv_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:$LINENO: result: $ac_cv_objext" >&5
+$as_echo "$ac_cv_objext" >&6; }
+OBJEXT=$ac_cv_objext
+ac_objext=$OBJEXT
+{ $as_echo "$as_me:$LINENO: checking whether we are using the GNU C++ compiler" >&5
+$as_echo_n "checking whether we are using the GNU C++ compiler... " >&6; }
+if test "${ac_cv_cxx_compiler_gnu+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+#ifndef __GNUC__
+ choke me
+#endif
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_cxx_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ ac_compiler_gnu=yes
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_compiler_gnu=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_cv_cxx_compiler_gnu=$ac_compiler_gnu
+
+fi
+{ $as_echo "$as_me:$LINENO: result: $ac_cv_cxx_compiler_gnu" >&5
+$as_echo "$ac_cv_cxx_compiler_gnu" >&6; }
+if test $ac_compiler_gnu = yes; then
+ GXX=yes
+else
+ GXX=
+fi
+ac_test_CXXFLAGS=${CXXFLAGS+set}
+ac_save_CXXFLAGS=$CXXFLAGS
+{ $as_echo "$as_me:$LINENO: checking whether $CXX accepts -g" >&5
+$as_echo_n "checking whether $CXX accepts -g... " >&6; }
+if test "${ac_cv_prog_cxx_g+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ ac_save_cxx_werror_flag=$ac_cxx_werror_flag
+ ac_cxx_werror_flag=yes
+ ac_cv_prog_cxx_g=no
+ CXXFLAGS="-g"
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_cxx_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ ac_cv_prog_cxx_g=yes
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ CXXFLAGS=""
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_cxx_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ :
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_cxx_werror_flag=$ac_save_cxx_werror_flag
+ CXXFLAGS="-g"
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_cxx_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ ac_cv_prog_cxx_g=yes
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_cxx_werror_flag=$ac_save_cxx_werror_flag
+fi
+{ $as_echo "$as_me:$LINENO: result: $ac_cv_prog_cxx_g" >&5
+$as_echo "$ac_cv_prog_cxx_g" >&6; }
+if test "$ac_test_CXXFLAGS" = set; then
+ CXXFLAGS=$ac_save_CXXFLAGS
+elif test $ac_cv_prog_cxx_g = yes; then
+ if test "$GXX" = yes; then
+ CXXFLAGS="-g -O2"
+ else
+ CXXFLAGS="-g"
+ fi
+else
+ if test "$GXX" = yes; then
+ CXXFLAGS="-O2"
+ else
+ CXXFLAGS=
+ fi
+fi
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+DEPDIR="${am__leading_dot}deps"
+
+ac_config_commands="$ac_config_commands depfiles"
+
+
+am_make=${MAKE-make}
+cat > confinc << 'END'
+am__doit:
+ @echo done
+.PHONY: am__doit
+END
+# If we don't find an include directive, just comment out the code.
+{ $as_echo "$as_me:$LINENO: checking for style of include used by $am_make" >&5
+$as_echo_n "checking for style of include used by $am_make... " >&6; }
+am__include="#"
+am__quote=
+_am_result=none
+# First try GNU make style include.
+echo "include confinc" > confmf
+# We grep out `Entering directory' and `Leaving directory'
+# messages which can occur if `w' ends up in MAKEFLAGS.
+# In particular we don't look at `^make:' because GNU make might
+# be invoked under some other name (usually "gmake"), in which
+# case it prints its new name instead of `make'.
+if test "`$am_make -s -f confmf 2> /dev/null | grep -v 'ing directory'`" = "done"; then
+ am__include=include
+ am__quote=
+ _am_result=GNU
+fi
+# Now try BSD make style include.
+if test "$am__include" = "#"; then
+ echo '.include "confinc"' > confmf
+ if test "`$am_make -s -f confmf 2> /dev/null`" = "done"; then
+ am__include=.include
+ am__quote="\""
+ _am_result=BSD
+ fi
+fi
+
+
+{ $as_echo "$as_me:$LINENO: result: $_am_result" >&5
+$as_echo "$_am_result" >&6; }
+rm -f confinc confmf
+
+# Check whether --enable-dependency-tracking was given.
+if test "${enable_dependency_tracking+set}" = set; then
+ enableval=$enable_dependency_tracking;
+fi
+
+if test "x$enable_dependency_tracking" != xno; then
+ am_depcomp="$ac_aux_dir/depcomp"
+ AMDEPBACKSLASH='\'
+fi
+ if test "x$enable_dependency_tracking" != xno; then
+ AMDEP_TRUE=
+ AMDEP_FALSE='#'
+else
+ AMDEP_TRUE='#'
+ AMDEP_FALSE=
+fi
+
+
+
+depcc="$CXX" am_compiler_list=
+
+{ $as_echo "$as_me:$LINENO: checking dependency style of $depcc" >&5
+$as_echo_n "checking dependency style of $depcc... " >&6; }
+if test "${am_cv_CXX_dependencies_compiler_type+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then
+ # We make a subdir and do the tests there. Otherwise we can end up
+ # making bogus files that we don't know about and never remove. For
+ # instance it was reported that on HP-UX the gcc test will end up
+ # making a dummy file named `D' -- because `-MD' means `put the output
+ # in D'.
+ mkdir conftest.dir
+ # Copy depcomp to subdir because otherwise we won't find it if we're
+ # using a relative directory.
+ cp "$am_depcomp" conftest.dir
+ cd conftest.dir
+ # We will build objects and dependencies in a subdirectory because
+ # it helps to detect inapplicable dependency modes. For instance
+ # both Tru64's cc and ICC support -MD to output dependencies as a
+ # side effect of compilation, but ICC will put the dependencies in
+ # the current directory while Tru64 will put them in the object
+ # directory.
+ mkdir sub
+
+ am_cv_CXX_dependencies_compiler_type=none
+ if test "$am_compiler_list" = ""; then
+ am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp`
+ fi
+ for depmode in $am_compiler_list; do
+ # Setup a source with many dependencies, because some compilers
+ # like to wrap large dependency lists on column 80 (with \), and
+ # we should not choose a depcomp mode which is confused by this.
+ #
+ # We need to recreate these files for each test, as the compiler may
+ # overwrite some of them when testing with obscure command lines.
+ # This happens at least with the AIX C compiler.
+ : > sub/conftest.c
+ for i in 1 2 3 4 5 6; do
+ echo '#include "conftst'$i'.h"' >> sub/conftest.c
+ # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with
+ # Solaris 8's {/usr,}/bin/sh.
+ touch sub/conftst$i.h
+ done
+ echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
+
+ case $depmode in
+ nosideeffect)
+ # after this tag, mechanisms are not by side-effect, so they'll
+ # only be used when explicitly requested
+ if test "x$enable_dependency_tracking" = xyes; then
+ continue
+ else
+ break
+ fi
+ ;;
+ none) break ;;
+ esac
+ # We check with `-c' and `-o' for the sake of the "dashmstdout"
+ # mode. It turns out that the SunPro C++ compiler does not properly
+ # handle `-M -o', and we need to detect this.
+ if depmode=$depmode \
+ source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \
+ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \
+ $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c \
+ >/dev/null 2>conftest.err &&
+ grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 &&
+ grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 &&
+ grep sub/conftest.${OBJEXT-o} sub/conftest.Po > /dev/null 2>&1 &&
+ ${MAKE-make} -s -f confmf > /dev/null 2>&1; then
+ # icc doesn't choke on unknown options, it will just issue warnings
+ # or remarks (even with -Werror). So we grep stderr for any message
+ # that says an option was ignored or not supported.
+ # When given -MP, icc 7.0 and 7.1 complain thusly:
+ # icc: Command line warning: ignoring option '-M'; no argument required
+ # The diagnosis changed in icc 8.0:
+ # icc: Command line remark: option '-MP' not supported
+ if (grep 'ignoring option' conftest.err ||
+ grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else
+ am_cv_CXX_dependencies_compiler_type=$depmode
+ break
+ fi
+ fi
+ done
+
+ cd ..
+ rm -rf conftest.dir
+else
+ am_cv_CXX_dependencies_compiler_type=none
+fi
+
+fi
+{ $as_echo "$as_me:$LINENO: result: $am_cv_CXX_dependencies_compiler_type" >&5
+$as_echo "$am_cv_CXX_dependencies_compiler_type" >&6; }
+CXXDEPMODE=depmode=$am_cv_CXX_dependencies_compiler_type
+
+ if
+ test "x$enable_dependency_tracking" != xno \
+ && test "$am_cv_CXX_dependencies_compiler_type" = gcc3; then
+ am__fastdepCXX_TRUE=
+ am__fastdepCXX_FALSE='#'
+else
+ am__fastdepCXX_TRUE='#'
+ am__fastdepCXX_FALSE=
+fi
+
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}gcc; ac_word=$2
+{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_CC+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_CC="${ac_tool_prefix}gcc"
+ $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { $as_echo "$as_me:$LINENO: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+ { $as_echo "$as_me:$LINENO: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_CC"; then
+ ac_ct_CC=$CC
+ # Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_CC"; then
+ ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_ac_ct_CC="gcc"
+ $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+ { $as_echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
+$as_echo "$ac_ct_CC" >&6; }
+else
+ { $as_echo "$as_me:$LINENO: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_CC" = x; then
+ CC=""
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools
+whose name does not start with the host triplet. If you think this
+configuration is useful to you, please write to autoconf@gnu.org." >&5
+$as_echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools
+whose name does not start with the host triplet. If you think this
+configuration is useful to you, please write to autoconf@gnu.org." >&2;}
+ac_tool_warned=yes ;;
+esac
+ CC=$ac_ct_CC
+ fi
+else
+ CC="$ac_cv_prog_CC"
+fi
+
+if test -z "$CC"; then
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}cc; ac_word=$2
+{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_CC+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_CC="${ac_tool_prefix}cc"
+ $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { $as_echo "$as_me:$LINENO: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+ { $as_echo "$as_me:$LINENO: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ fi
+fi
+if test -z "$CC"; then
+ # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_CC+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ ac_prog_rejected=no
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
+ ac_prog_rejected=yes
+ continue
+ fi
+ ac_cv_prog_CC="cc"
+ $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+IFS=$as_save_IFS
+
+if test $ac_prog_rejected = yes; then
+ # We found a bogon in the path, so make sure we never use it.
+ set dummy $ac_cv_prog_CC
+ shift
+ if test $# != 0; then
+ # We chose a different compiler from the bogus one.
+ # However, it has the same basename, so the bogon will be chosen
+ # first if we set CC to just the basename; use the full file name.
+ shift
+ ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@"
+ fi
+fi
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { $as_echo "$as_me:$LINENO: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+ { $as_echo "$as_me:$LINENO: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$CC"; then
+ if test -n "$ac_tool_prefix"; then
+ for ac_prog in cl.exe
+ do
+ # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_CC+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
+ $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { $as_echo "$as_me:$LINENO: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+ { $as_echo "$as_me:$LINENO: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$CC" && break
+ done
+fi
+if test -z "$CC"; then
+ ac_ct_CC=$CC
+ for ac_prog in cl.exe
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_CC"; then
+ ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_ac_ct_CC="$ac_prog"
+ $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+ { $as_echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
+$as_echo "$ac_ct_CC" >&6; }
+else
+ { $as_echo "$as_me:$LINENO: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$ac_ct_CC" && break
+done
+
+ if test "x$ac_ct_CC" = x; then
+ CC=""
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools
+whose name does not start with the host triplet. If you think this
+configuration is useful to you, please write to autoconf@gnu.org." >&5
+$as_echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools
+whose name does not start with the host triplet. If you think this
+configuration is useful to you, please write to autoconf@gnu.org." >&2;}
+ac_tool_warned=yes ;;
+esac
+ CC=$ac_ct_CC
+ fi
+fi
+
+fi
+
+
+test -z "$CC" && { { $as_echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH
+See \`config.log' for more details." >&5
+$as_echo "$as_me: error: no acceptable C compiler found in \$PATH
+See \`config.log' for more details." >&2;}
+ { (exit 1); exit 1; }; }
+
+# Provide some information about the compiler.
+$as_echo "$as_me:$LINENO: checking for C compiler version" >&5
+set X $ac_compile
+ac_compiler=$2
+{ (ac_try="$ac_compiler --version >&5"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compiler --version >&5") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }
+{ (ac_try="$ac_compiler -v >&5"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compiler -v >&5") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }
+{ (ac_try="$ac_compiler -V >&5"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compiler -V >&5") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }
+
+{ $as_echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5
+$as_echo_n "checking whether we are using the GNU C compiler... " >&6; }
+if test "${ac_cv_c_compiler_gnu+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+#ifndef __GNUC__
+ choke me
+#endif
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ ac_compiler_gnu=yes
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_compiler_gnu=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_cv_c_compiler_gnu=$ac_compiler_gnu
+
+fi
+{ $as_echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5
+$as_echo "$ac_cv_c_compiler_gnu" >&6; }
+if test $ac_compiler_gnu = yes; then
+ GCC=yes
+else
+ GCC=
+fi
+ac_test_CFLAGS=${CFLAGS+set}
+ac_save_CFLAGS=$CFLAGS
+{ $as_echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5
+$as_echo_n "checking whether $CC accepts -g... " >&6; }
+if test "${ac_cv_prog_cc_g+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ ac_save_c_werror_flag=$ac_c_werror_flag
+ ac_c_werror_flag=yes
+ ac_cv_prog_cc_g=no
+ CFLAGS="-g"
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ ac_cv_prog_cc_g=yes
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ CFLAGS=""
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ :
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_c_werror_flag=$ac_save_c_werror_flag
+ CFLAGS="-g"
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ ac_cv_prog_cc_g=yes
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_c_werror_flag=$ac_save_c_werror_flag
+fi
+{ $as_echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5
+$as_echo "$ac_cv_prog_cc_g" >&6; }
+if test "$ac_test_CFLAGS" = set; then
+ CFLAGS=$ac_save_CFLAGS
+elif test $ac_cv_prog_cc_g = yes; then
+ if test "$GCC" = yes; then
+ CFLAGS="-g -O2"
+ else
+ CFLAGS="-g"
+ fi
+else
+ if test "$GCC" = yes; then
+ CFLAGS="-O2"
+ else
+ CFLAGS=
+ fi
+fi
+{ $as_echo "$as_me:$LINENO: checking for $CC option to accept ISO C89" >&5
+$as_echo_n "checking for $CC option to accept ISO C89... " >&6; }
+if test "${ac_cv_prog_cc_c89+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ ac_cv_prog_cc_c89=no
+ac_save_CC=$CC
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <stdarg.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */
+struct buf { int x; };
+FILE * (*rcsopen) (struct buf *, struct stat *, int);
+static char *e (p, i)
+ char **p;
+ int i;
+{
+ return p[i];
+}
+static char *f (char * (*g) (char **, int), char **p, ...)
+{
+ char *s;
+ va_list v;
+ va_start (v,p);
+ s = g (p, va_arg (v,int));
+ va_end (v);
+ return s;
+}
+
+/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has
+ function prototypes and stuff, but not '\xHH' hex character constants.
+ These don't provoke an error unfortunately, instead are silently treated
+ as 'x'. The following induces an error, until -std is added to get
+ proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an
+ array size at least. It's necessary to write '\x00'==0 to get something
+ that's true only with -std. */
+int osf4_cc_array ['\x00' == 0 ? 1 : -1];
+
+/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters
+ inside strings and character constants. */
+#define FOO(x) 'x'
+int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1];
+
+int test (int i, double x);
+struct s1 {int (*f) (int a);};
+struct s2 {int (*f) (double a);};
+int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
+int argc;
+char **argv;
+int
+main ()
+{
+return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1];
+ ;
+ return 0;
+}
+_ACEOF
+for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \
+ -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
+do
+ CC="$ac_save_CC $ac_arg"
+ rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ ac_cv_prog_cc_c89=$ac_arg
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+fi
+
+rm -f core conftest.err conftest.$ac_objext
+ test "x$ac_cv_prog_cc_c89" != "xno" && break
+done
+rm -f conftest.$ac_ext
+CC=$ac_save_CC
+
+fi
+# AC_CACHE_VAL
+case "x$ac_cv_prog_cc_c89" in
+ x)
+ { $as_echo "$as_me:$LINENO: result: none needed" >&5
+$as_echo "none needed" >&6; } ;;
+ xno)
+ { $as_echo "$as_me:$LINENO: result: unsupported" >&5
+$as_echo "unsupported" >&6; } ;;
+ *)
+ CC="$CC $ac_cv_prog_cc_c89"
+ { $as_echo "$as_me:$LINENO: result: $ac_cv_prog_cc_c89" >&5
+$as_echo "$ac_cv_prog_cc_c89" >&6; } ;;
+esac
+
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+depcc="$CC" am_compiler_list=
+
+{ $as_echo "$as_me:$LINENO: checking dependency style of $depcc" >&5
+$as_echo_n "checking dependency style of $depcc... " >&6; }
+if test "${am_cv_CC_dependencies_compiler_type+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then
+ # We make a subdir and do the tests there. Otherwise we can end up
+ # making bogus files that we don't know about and never remove. For
+ # instance it was reported that on HP-UX the gcc test will end up
+ # making a dummy file named `D' -- because `-MD' means `put the output
+ # in D'.
+ mkdir conftest.dir
+ # Copy depcomp to subdir because otherwise we won't find it if we're
+ # using a relative directory.
+ cp "$am_depcomp" conftest.dir
+ cd conftest.dir
+ # We will build objects and dependencies in a subdirectory because
+ # it helps to detect inapplicable dependency modes. For instance
+ # both Tru64's cc and ICC support -MD to output dependencies as a
+ # side effect of compilation, but ICC will put the dependencies in
+ # the current directory while Tru64 will put them in the object
+ # directory.
+ mkdir sub
+
+ am_cv_CC_dependencies_compiler_type=none
+ if test "$am_compiler_list" = ""; then
+ am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp`
+ fi
+ for depmode in $am_compiler_list; do
+ # Setup a source with many dependencies, because some compilers
+ # like to wrap large dependency lists on column 80 (with \), and
+ # we should not choose a depcomp mode which is confused by this.
+ #
+ # We need to recreate these files for each test, as the compiler may
+ # overwrite some of them when testing with obscure command lines.
+ # This happens at least with the AIX C compiler.
+ : > sub/conftest.c
+ for i in 1 2 3 4 5 6; do
+ echo '#include "conftst'$i'.h"' >> sub/conftest.c
+ # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with
+ # Solaris 8's {/usr,}/bin/sh.
+ touch sub/conftst$i.h
+ done
+ echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
+
+ case $depmode in
+ nosideeffect)
+ # after this tag, mechanisms are not by side-effect, so they'll
+ # only be used when explicitly requested
+ if test "x$enable_dependency_tracking" = xyes; then
+ continue
+ else
+ break
+ fi
+ ;;
+ none) break ;;
+ esac
+ # We check with `-c' and `-o' for the sake of the "dashmstdout"
+ # mode. It turns out that the SunPro C++ compiler does not properly
+ # handle `-M -o', and we need to detect this.
+ if depmode=$depmode \
+ source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \
+ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \
+ $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c \
+ >/dev/null 2>conftest.err &&
+ grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 &&
+ grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 &&
+ grep sub/conftest.${OBJEXT-o} sub/conftest.Po > /dev/null 2>&1 &&
+ ${MAKE-make} -s -f confmf > /dev/null 2>&1; then
+ # icc doesn't choke on unknown options, it will just issue warnings
+ # or remarks (even with -Werror). So we grep stderr for any message
+ # that says an option was ignored or not supported.
+ # When given -MP, icc 7.0 and 7.1 complain thusly:
+ # icc: Command line warning: ignoring option '-M'; no argument required
+ # The diagnosis changed in icc 8.0:
+ # icc: Command line remark: option '-MP' not supported
+ if (grep 'ignoring option' conftest.err ||
+ grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else
+ am_cv_CC_dependencies_compiler_type=$depmode
+ break
+ fi
+ fi
+ done
+
+ cd ..
+ rm -rf conftest.dir
+else
+ am_cv_CC_dependencies_compiler_type=none
+fi
+
+fi
+{ $as_echo "$as_me:$LINENO: result: $am_cv_CC_dependencies_compiler_type" >&5
+$as_echo "$am_cv_CC_dependencies_compiler_type" >&6; }
+CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type
+
+ if
+ test "x$enable_dependency_tracking" != xno \
+ && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then
+ am__fastdepCC_TRUE=
+ am__fastdepCC_FALSE='#'
+else
+ am__fastdepCC_TRUE='#'
+ am__fastdepCC_FALSE=
+fi
+
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+{ $as_echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5
+$as_echo_n "checking how to run the C preprocessor... " >&6; }
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+ CPP=
+fi
+if test -z "$CPP"; then
+ if test "${ac_cv_prog_CPP+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ # Double quotes because CPP needs to be expanded
+ for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp"
+ do
+ ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+ # Use a header file that comes with gcc, so configuring glibc
+ # with a fresh cross-compiler works.
+ # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ # <limits.h> exists even on freestanding compilers.
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp. "Syntax error" is here to catch this case.
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+ Syntax error
+_ACEOF
+if { (ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null && {
+ test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ }; then
+ :
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ # Broken: fails on valid input.
+continue
+fi
+
+rm -f conftest.err conftest.$ac_ext
+
+ # OK, works on sane cases. Now check whether nonexistent headers
+ # can be detected and how.
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <ac_nonexistent.h>
+_ACEOF
+if { (ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null && {
+ test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ }; then
+ # Broken: success on invalid input.
+continue
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+
+rm -f conftest.err conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then
+ break
+fi
+
+ done
+ ac_cv_prog_CPP=$CPP
+
+fi
+ CPP=$ac_cv_prog_CPP
+else
+ ac_cv_prog_CPP=$CPP
+fi
+{ $as_echo "$as_me:$LINENO: result: $CPP" >&5
+$as_echo "$CPP" >&6; }
+ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+ # Use a header file that comes with gcc, so configuring glibc
+ # with a fresh cross-compiler works.
+ # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ # <limits.h> exists even on freestanding compilers.
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp. "Syntax error" is here to catch this case.
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+ Syntax error
+_ACEOF
+if { (ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null && {
+ test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ }; then
+ :
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ # Broken: fails on valid input.
+continue
+fi
+
+rm -f conftest.err conftest.$ac_ext
+
+ # OK, works on sane cases. Now check whether nonexistent headers
+ # can be detected and how.
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <ac_nonexistent.h>
+_ACEOF
+if { (ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null && {
+ test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ }; then
+ # Broken: success on invalid input.
+continue
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+
+rm -f conftest.err conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then
+ :
+else
+ { { $as_echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details." >&5
+$as_echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+ if test "$GCC" = yes; then
+ GCC_TRUE=
+ GCC_FALSE='#'
+else
+ GCC_TRUE='#'
+ GCC_FALSE=
+fi
+ # let the Makefile know if we're gcc
+# Make sure we can run config.sub.
+$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 ||
+ { { $as_echo "$as_me:$LINENO: error: cannot run $SHELL $ac_aux_dir/config.sub" >&5
+$as_echo "$as_me: error: cannot run $SHELL $ac_aux_dir/config.sub" >&2;}
+ { (exit 1); exit 1; }; }
+
+{ $as_echo "$as_me:$LINENO: checking build system type" >&5
+$as_echo_n "checking build system type... " >&6; }
+if test "${ac_cv_build+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ ac_build_alias=$build_alias
+test "x$ac_build_alias" = x &&
+ ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"`
+test "x$ac_build_alias" = x &&
+ { { $as_echo "$as_me:$LINENO: error: cannot guess build type; you must specify one" >&5
+$as_echo "$as_me: error: cannot guess build type; you must specify one" >&2;}
+ { (exit 1); exit 1; }; }
+ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` ||
+ { { $as_echo "$as_me:$LINENO: error: $SHELL $ac_aux_dir/config.sub $ac_build_alias failed" >&5
+$as_echo "$as_me: error: $SHELL $ac_aux_dir/config.sub $ac_build_alias failed" >&2;}
+ { (exit 1); exit 1; }; }
+
+fi
+{ $as_echo "$as_me:$LINENO: result: $ac_cv_build" >&5
+$as_echo "$ac_cv_build" >&6; }
+case $ac_cv_build in
+*-*-*) ;;
+*) { { $as_echo "$as_me:$LINENO: error: invalid value of canonical build" >&5
+$as_echo "$as_me: error: invalid value of canonical build" >&2;}
+ { (exit 1); exit 1; }; };;
+esac
+build=$ac_cv_build
+ac_save_IFS=$IFS; IFS='-'
+set x $ac_cv_build
+shift
+build_cpu=$1
+build_vendor=$2
+shift; shift
+# Remember, the first character of IFS is used to create $*,
+# except with old shells:
+build_os=$*
+IFS=$ac_save_IFS
+case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac
+
+
+{ $as_echo "$as_me:$LINENO: checking host system type" >&5
+$as_echo_n "checking host system type... " >&6; }
+if test "${ac_cv_host+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ if test "x$host_alias" = x; then
+ ac_cv_host=$ac_cv_build
+else
+ ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` ||
+ { { $as_echo "$as_me:$LINENO: error: $SHELL $ac_aux_dir/config.sub $host_alias failed" >&5
+$as_echo "$as_me: error: $SHELL $ac_aux_dir/config.sub $host_alias failed" >&2;}
+ { (exit 1); exit 1; }; }
+fi
+
+fi
+{ $as_echo "$as_me:$LINENO: result: $ac_cv_host" >&5
+$as_echo "$ac_cv_host" >&6; }
+case $ac_cv_host in
+*-*-*) ;;
+*) { { $as_echo "$as_me:$LINENO: error: invalid value of canonical host" >&5
+$as_echo "$as_me: error: invalid value of canonical host" >&2;}
+ { (exit 1); exit 1; }; };;
+esac
+host=$ac_cv_host
+ac_save_IFS=$IFS; IFS='-'
+set x $ac_cv_host
+shift
+host_cpu=$1
+host_vendor=$2
+shift; shift
+# Remember, the first character of IFS is used to create $*,
+# except with old shells:
+host_os=$*
+IFS=$ac_save_IFS
+case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac
+
+
+
+# MinGW uses autoconf, but also needs the windows shim routines
+# (since it doesn't have its own support for, say, pthreads).
+# This requires us to #include a special header file, and also to
+# link in some windows versions of .o's instead of the unix versions.
+
+
+# Populate $host_cpu, $host_os, etc.
+{ $as_echo "$as_me:$LINENO: checking host system type" >&5
+$as_echo_n "checking host system type... " >&6; }
+if test "${ac_cv_host+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ if test "x$host_alias" = x; then
+ ac_cv_host=$ac_cv_build
+else
+ ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` ||
+ { { $as_echo "$as_me:$LINENO: error: $SHELL $ac_aux_dir/config.sub $host_alias failed" >&5
+$as_echo "$as_me: error: $SHELL $ac_aux_dir/config.sub $host_alias failed" >&2;}
+ { (exit 1); exit 1; }; }
+fi
+
+fi
+{ $as_echo "$as_me:$LINENO: result: $ac_cv_host" >&5
+$as_echo "$ac_cv_host" >&6; }
+case $ac_cv_host in
+*-*-*) ;;
+*) { { $as_echo "$as_me:$LINENO: error: invalid value of canonical host" >&5
+$as_echo "$as_me: error: invalid value of canonical host" >&2;}
+ { (exit 1); exit 1; }; };;
+esac
+host=$ac_cv_host
+ac_save_IFS=$IFS; IFS='-'
+set x $ac_cv_host
+shift
+host_cpu=$1
+host_vendor=$2
+shift; shift
+# Remember, the first character of IFS is used to create $*,
+# except with old shells:
+host_os=$*
+IFS=$ac_save_IFS
+case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac
+
+
+case $host_os in
+ *mingw*)
+ # Disabling fast install keeps libtool from creating wrapper scripts
+ # around the executables it builds. Such scripts have caused failures on
+ # MinGW. Using this option means an extra link step is executed during
+ # "make install".
+ # Check whether --enable-fast-install was given.
+if test "${enable_fast_install+set}" = set; then
+ enableval=$enable_fast_install; p=${PACKAGE-default}
+ case $enableval in
+ yes) enable_fast_install=yes ;;
+ no) enable_fast_install=no ;;
+ *)
+ enable_fast_install=no
+ # Look at the argument we got. We use all the common list separators.
+ lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+ for pkg in $enableval; do
+ IFS="$lt_save_ifs"
+ if test "X$pkg" = "X$p"; then
+ enable_fast_install=yes
+ fi
+ done
+ IFS="$lt_save_ifs"
+ ;;
+ esac
+else
+ enable_fast_install=no
+fi
+
+
+
+
+
+
+
+
+
+ # /tmp is a mount-point in mingw, and hard to use. use cwd instead
+ TEST_TMPDIR=gflags_testdir
+ ;;
+ *)
+ # Check whether --enable-fast-install was given.
+if test "${enable_fast_install+set}" = set; then
+ enableval=$enable_fast_install; p=${PACKAGE-default}
+ case $enableval in
+ yes) enable_fast_install=yes ;;
+ no) enable_fast_install=no ;;
+ *)
+ enable_fast_install=no
+ # Look at the argument we got. We use all the common list separators.
+ lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+ for pkg in $enableval; do
+ IFS="$lt_save_ifs"
+ if test "X$pkg" = "X$p"; then
+ enable_fast_install=yes
+ fi
+ done
+ IFS="$lt_save_ifs"
+ ;;
+ esac
+else
+ enable_fast_install=yes
+fi
+
+
+
+
+
+
+ TEST_TMPDIR=/tmp/gflags
+ ;;
+esac
+
+
+# Uncomment this if you'll be exporting libraries (.so's)
+case `pwd` in
+ *\ * | *\ *)
+ { $as_echo "$as_me:$LINENO: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&5
+$as_echo "$as_me: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&2;} ;;
+esac
+
+
+
+macro_version='2.2.6b'
+macro_revision='1.3017'
+
+
+
+
+
+
+
+
+
+
+
+
+
+ltmain="$ac_aux_dir/ltmain.sh"
+
+{ $as_echo "$as_me:$LINENO: checking for a sed that does not truncate output" >&5
+$as_echo_n "checking for a sed that does not truncate output... " >&6; }
+if test "${ac_cv_path_SED+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/
+ for ac_i in 1 2 3 4 5 6 7; do
+ ac_script="$ac_script$as_nl$ac_script"
+ done
+ echo "$ac_script" 2>/dev/null | sed 99q >conftest.sed
+ $as_unset ac_script || ac_script=
+ if test -z "$SED"; then
+ ac_path_SED_found=false
+ # Loop through the user's path and test for each of PROGNAME-LIST
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_prog in sed gsed; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ ac_path_SED="$as_dir/$ac_prog$ac_exec_ext"
+ { test -f "$ac_path_SED" && $as_test_x "$ac_path_SED"; } || continue
+# Check for GNU ac_path_SED and select it if it is found.
+ # Check for GNU $ac_path_SED
+case `"$ac_path_SED" --version 2>&1` in
+*GNU*)
+ ac_cv_path_SED="$ac_path_SED" ac_path_SED_found=:;;
+*)
+ ac_count=0
+ $as_echo_n 0123456789 >"conftest.in"
+ while :
+ do
+ cat "conftest.in" "conftest.in" >"conftest.tmp"
+ mv "conftest.tmp" "conftest.in"
+ cp "conftest.in" "conftest.nl"
+ $as_echo '' >> "conftest.nl"
+ "$ac_path_SED" -f conftest.sed < "conftest.nl" >"conftest.out" 2>/dev/null || break
+ diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+ ac_count=`expr $ac_count + 1`
+ if test $ac_count -gt ${ac_path_SED_max-0}; then
+ # Best one so far, save it but keep looking for a better one
+ ac_cv_path_SED="$ac_path_SED"
+ ac_path_SED_max=$ac_count
+ fi
+ # 10*(2^10) chars as input seems more than enough
+ test $ac_count -gt 10 && break
+ done
+ rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+ $ac_path_SED_found && break 3
+ done
+ done
+done
+IFS=$as_save_IFS
+ if test -z "$ac_cv_path_SED"; then
+ { { $as_echo "$as_me:$LINENO: error: no acceptable sed could be found in \$PATH" >&5
+$as_echo "$as_me: error: no acceptable sed could be found in \$PATH" >&2;}
+ { (exit 1); exit 1; }; }
+ fi
+else
+ ac_cv_path_SED=$SED
+fi
+
+fi
+{ $as_echo "$as_me:$LINENO: result: $ac_cv_path_SED" >&5
+$as_echo "$ac_cv_path_SED" >&6; }
+ SED="$ac_cv_path_SED"
+ rm -f conftest.sed
+
+test -z "$SED" && SED=sed
+Xsed="$SED -e 1s/^X//"
+
+
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:$LINENO: checking for grep that handles long lines and -e" >&5
+$as_echo_n "checking for grep that handles long lines and -e... " >&6; }
+if test "${ac_cv_path_GREP+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ if test -z "$GREP"; then
+ ac_path_GREP_found=false
+ # Loop through the user's path and test for each of PROGNAME-LIST
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_prog in grep ggrep; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext"
+ { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue
+# Check for GNU ac_path_GREP and select it if it is found.
+ # Check for GNU $ac_path_GREP
+case `"$ac_path_GREP" --version 2>&1` in
+*GNU*)
+ ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;;
+*)
+ ac_count=0
+ $as_echo_n 0123456789 >"conftest.in"
+ while :
+ do
+ cat "conftest.in" "conftest.in" >"conftest.tmp"
+ mv "conftest.tmp" "conftest.in"
+ cp "conftest.in" "conftest.nl"
+ $as_echo 'GREP' >> "conftest.nl"
+ "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break
+ diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+ ac_count=`expr $ac_count + 1`
+ if test $ac_count -gt ${ac_path_GREP_max-0}; then
+ # Best one so far, save it but keep looking for a better one
+ ac_cv_path_GREP="$ac_path_GREP"
+ ac_path_GREP_max=$ac_count
+ fi
+ # 10*(2^10) chars as input seems more than enough
+ test $ac_count -gt 10 && break
+ done
+ rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+ $ac_path_GREP_found && break 3
+ done
+ done
+done
+IFS=$as_save_IFS
+ if test -z "$ac_cv_path_GREP"; then
+ { { $as_echo "$as_me:$LINENO: error: no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&5
+$as_echo "$as_me: error: no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&2;}
+ { (exit 1); exit 1; }; }
+ fi
+else
+ ac_cv_path_GREP=$GREP
+fi
+
+fi
+{ $as_echo "$as_me:$LINENO: result: $ac_cv_path_GREP" >&5
+$as_echo "$ac_cv_path_GREP" >&6; }
+ GREP="$ac_cv_path_GREP"
+
+
+{ $as_echo "$as_me:$LINENO: checking for egrep" >&5
+$as_echo_n "checking for egrep... " >&6; }
+if test "${ac_cv_path_EGREP+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ if echo a | $GREP -E '(a|b)' >/dev/null 2>&1
+ then ac_cv_path_EGREP="$GREP -E"
+ else
+ if test -z "$EGREP"; then
+ ac_path_EGREP_found=false
+ # Loop through the user's path and test for each of PROGNAME-LIST
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_prog in egrep; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext"
+ { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue
+# Check for GNU ac_path_EGREP and select it if it is found.
+ # Check for GNU $ac_path_EGREP
+case `"$ac_path_EGREP" --version 2>&1` in
+*GNU*)
+ ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;;
+*)
+ ac_count=0
+ $as_echo_n 0123456789 >"conftest.in"
+ while :
+ do
+ cat "conftest.in" "conftest.in" >"conftest.tmp"
+ mv "conftest.tmp" "conftest.in"
+ cp "conftest.in" "conftest.nl"
+ $as_echo 'EGREP' >> "conftest.nl"
+ "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break
+ diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+ ac_count=`expr $ac_count + 1`
+ if test $ac_count -gt ${ac_path_EGREP_max-0}; then
+ # Best one so far, save it but keep looking for a better one
+ ac_cv_path_EGREP="$ac_path_EGREP"
+ ac_path_EGREP_max=$ac_count
+ fi
+ # 10*(2^10) chars as input seems more than enough
+ test $ac_count -gt 10 && break
+ done
+ rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+ $ac_path_EGREP_found && break 3
+ done
+ done
+done
+IFS=$as_save_IFS
+ if test -z "$ac_cv_path_EGREP"; then
+ { { $as_echo "$as_me:$LINENO: error: no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&5
+$as_echo "$as_me: error: no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&2;}
+ { (exit 1); exit 1; }; }
+ fi
+else
+ ac_cv_path_EGREP=$EGREP
+fi
+
+ fi
+fi
+{ $as_echo "$as_me:$LINENO: result: $ac_cv_path_EGREP" >&5
+$as_echo "$ac_cv_path_EGREP" >&6; }
+ EGREP="$ac_cv_path_EGREP"
+
+
+{ $as_echo "$as_me:$LINENO: checking for fgrep" >&5
+$as_echo_n "checking for fgrep... " >&6; }
+if test "${ac_cv_path_FGREP+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ if echo 'ab*c' | $GREP -F 'ab*c' >/dev/null 2>&1
+ then ac_cv_path_FGREP="$GREP -F"
+ else
+ if test -z "$FGREP"; then
+ ac_path_FGREP_found=false
+ # Loop through the user's path and test for each of PROGNAME-LIST
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_prog in fgrep; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ ac_path_FGREP="$as_dir/$ac_prog$ac_exec_ext"
+ { test -f "$ac_path_FGREP" && $as_test_x "$ac_path_FGREP"; } || continue
+# Check for GNU ac_path_FGREP and select it if it is found.
+ # Check for GNU $ac_path_FGREP
+case `"$ac_path_FGREP" --version 2>&1` in
+*GNU*)
+ ac_cv_path_FGREP="$ac_path_FGREP" ac_path_FGREP_found=:;;
+*)
+ ac_count=0
+ $as_echo_n 0123456789 >"conftest.in"
+ while :
+ do
+ cat "conftest.in" "conftest.in" >"conftest.tmp"
+ mv "conftest.tmp" "conftest.in"
+ cp "conftest.in" "conftest.nl"
+ $as_echo 'FGREP' >> "conftest.nl"
+ "$ac_path_FGREP" FGREP < "conftest.nl" >"conftest.out" 2>/dev/null || break
+ diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+ ac_count=`expr $ac_count + 1`
+ if test $ac_count -gt ${ac_path_FGREP_max-0}; then
+ # Best one so far, save it but keep looking for a better one
+ ac_cv_path_FGREP="$ac_path_FGREP"
+ ac_path_FGREP_max=$ac_count
+ fi
+ # 10*(2^10) chars as input seems more than enough
+ test $ac_count -gt 10 && break
+ done
+ rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+ $ac_path_FGREP_found && break 3
+ done
+ done
+done
+IFS=$as_save_IFS
+ if test -z "$ac_cv_path_FGREP"; then
+ { { $as_echo "$as_me:$LINENO: error: no acceptable fgrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&5
+$as_echo "$as_me: error: no acceptable fgrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&2;}
+ { (exit 1); exit 1; }; }
+ fi
+else
+ ac_cv_path_FGREP=$FGREP
+fi
+
+ fi
+fi
+{ $as_echo "$as_me:$LINENO: result: $ac_cv_path_FGREP" >&5
+$as_echo "$ac_cv_path_FGREP" >&6; }
+ FGREP="$ac_cv_path_FGREP"
+
+
+test -z "$GREP" && GREP=grep
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# Check whether --with-gnu-ld was given.
+if test "${with_gnu_ld+set}" = set; then
+ withval=$with_gnu_ld; test "$withval" = no || with_gnu_ld=yes
+else
+ with_gnu_ld=no
+fi
+
+ac_prog=ld
+if test "$GCC" = yes; then
+ # Check if gcc -print-prog-name=ld gives a path.
+ { $as_echo "$as_me:$LINENO: checking for ld used by $CC" >&5
+$as_echo_n "checking for ld used by $CC... " >&6; }
+ case $host in
+ *-*-mingw*)
+ # gcc leaves a trailing carriage return which upsets mingw
+ ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
+ *)
+ ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;
+ esac
+ case $ac_prog in
+ # Accept absolute paths.
+ [\\/]* | ?:[\\/]*)
+ re_direlt='/[^/][^/]*/\.\./'
+ # Canonicalize the pathname of ld
+ ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'`
+ while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do
+ ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"`
+ done
+ test -z "$LD" && LD="$ac_prog"
+ ;;
+ "")
+ # If it fails, then pretend we aren't using GCC.
+ ac_prog=ld
+ ;;
+ *)
+ # If it is relative, then search for the first ld in PATH.
+ with_gnu_ld=unknown
+ ;;
+ esac
+elif test "$with_gnu_ld" = yes; then
+ { $as_echo "$as_me:$LINENO: checking for GNU ld" >&5
+$as_echo_n "checking for GNU ld... " >&6; }
+else
+ { $as_echo "$as_me:$LINENO: checking for non-GNU ld" >&5
+$as_echo_n "checking for non-GNU ld... " >&6; }
+fi
+if test "${lt_cv_path_LD+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ if test -z "$LD"; then
+ lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+ for ac_dir in $PATH; do
+ IFS="$lt_save_ifs"
+ test -z "$ac_dir" && ac_dir=.
+ if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
+ lt_cv_path_LD="$ac_dir/$ac_prog"
+ # Check to see if the program is GNU ld. I'd rather use --version,
+ # but apparently some variants of GNU ld only accept -v.
+ # Break only if it was the GNU/non-GNU ld that we prefer.
+ case `"$lt_cv_path_LD" -v 2>&1 </dev/null` in
+ *GNU* | *'with BFD'*)
+ test "$with_gnu_ld" != no && break
+ ;;
+ *)
+ test "$with_gnu_ld" != yes && break
+ ;;
+ esac
+ fi
+ done
+ IFS="$lt_save_ifs"
+else
+ lt_cv_path_LD="$LD" # Let the user override the test with a path.
+fi
+fi
+
+LD="$lt_cv_path_LD"
+if test -n "$LD"; then
+ { $as_echo "$as_me:$LINENO: result: $LD" >&5
+$as_echo "$LD" >&6; }
+else
+ { $as_echo "$as_me:$LINENO: result: no" >&5
+$as_echo "no" >&6; }
+fi
+test -z "$LD" && { { $as_echo "$as_me:$LINENO: error: no acceptable ld found in \$PATH" >&5
+$as_echo "$as_me: error: no acceptable ld found in \$PATH" >&2;}
+ { (exit 1); exit 1; }; }
+{ $as_echo "$as_me:$LINENO: checking if the linker ($LD) is GNU ld" >&5
+$as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; }
+if test "${lt_cv_prog_gnu_ld+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ # I'd rather use --version here, but apparently some GNU lds only accept -v.
+case `$LD -v 2>&1 </dev/null` in
+*GNU* | *'with BFD'*)
+ lt_cv_prog_gnu_ld=yes
+ ;;
+*)
+ lt_cv_prog_gnu_ld=no
+ ;;
+esac
+fi
+{ $as_echo "$as_me:$LINENO: result: $lt_cv_prog_gnu_ld" >&5
+$as_echo "$lt_cv_prog_gnu_ld" >&6; }
+with_gnu_ld=$lt_cv_prog_gnu_ld
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:$LINENO: checking for BSD- or MS-compatible name lister (nm)" >&5
+$as_echo_n "checking for BSD- or MS-compatible name lister (nm)... " >&6; }
+if test "${lt_cv_path_NM+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$NM"; then
+ # Let the user override the test.
+ lt_cv_path_NM="$NM"
+else
+ lt_nm_to_check="${ac_tool_prefix}nm"
+ if test -n "$ac_tool_prefix" && test "$build" = "$host"; then
+ lt_nm_to_check="$lt_nm_to_check nm"
+ fi
+ for lt_tmp_nm in $lt_nm_to_check; do
+ lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+ for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do
+ IFS="$lt_save_ifs"
+ test -z "$ac_dir" && ac_dir=.
+ tmp_nm="$ac_dir/$lt_tmp_nm"
+ if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then
+ # Check to see if the nm accepts a BSD-compat flag.
+ # Adding the `sed 1q' prevents false positives on HP-UX, which says:
+ # nm: unknown option "B" ignored
+ # Tru64's nm complains that /dev/null is an invalid object file
+ case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in
+ */dev/null* | *'Invalid file or object type'*)
+ lt_cv_path_NM="$tmp_nm -B"
+ break
+ ;;
+ *)
+ case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in
+ */dev/null*)
+ lt_cv_path_NM="$tmp_nm -p"
+ break
+ ;;
+ *)
+ lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but
+ continue # so that we can try to find one that supports BSD flags
+ ;;
+ esac
+ ;;
+ esac
+ fi
+ done
+ IFS="$lt_save_ifs"
+ done
+ : ${lt_cv_path_NM=no}
+fi
+fi
+{ $as_echo "$as_me:$LINENO: result: $lt_cv_path_NM" >&5
+$as_echo "$lt_cv_path_NM" >&6; }
+if test "$lt_cv_path_NM" != "no"; then
+ NM="$lt_cv_path_NM"
+else
+ # Didn't find any BSD compatible name lister, look for dumpbin.
+ if test -n "$ac_tool_prefix"; then
+ for ac_prog in "dumpbin -symbols" "link -dump -symbols"
+ do
+ # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_DUMPBIN+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$DUMPBIN"; then
+ ac_cv_prog_DUMPBIN="$DUMPBIN" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_DUMPBIN="$ac_tool_prefix$ac_prog"
+ $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+DUMPBIN=$ac_cv_prog_DUMPBIN
+if test -n "$DUMPBIN"; then
+ { $as_echo "$as_me:$LINENO: result: $DUMPBIN" >&5
+$as_echo "$DUMPBIN" >&6; }
+else
+ { $as_echo "$as_me:$LINENO: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$DUMPBIN" && break
+ done
+fi
+if test -z "$DUMPBIN"; then
+ ac_ct_DUMPBIN=$DUMPBIN
+ for ac_prog in "dumpbin -symbols" "link -dump -symbols"
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_DUMPBIN+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_DUMPBIN"; then
+ ac_cv_prog_ac_ct_DUMPBIN="$ac_ct_DUMPBIN" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_ac_ct_DUMPBIN="$ac_prog"
+ $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_DUMPBIN=$ac_cv_prog_ac_ct_DUMPBIN
+if test -n "$ac_ct_DUMPBIN"; then
+ { $as_echo "$as_me:$LINENO: result: $ac_ct_DUMPBIN" >&5
+$as_echo "$ac_ct_DUMPBIN" >&6; }
+else
+ { $as_echo "$as_me:$LINENO: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$ac_ct_DUMPBIN" && break
+done
+
+ if test "x$ac_ct_DUMPBIN" = x; then
+ DUMPBIN=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools
+whose name does not start with the host triplet. If you think this
+configuration is useful to you, please write to autoconf@gnu.org." >&5
+$as_echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools
+whose name does not start with the host triplet. If you think this
+configuration is useful to you, please write to autoconf@gnu.org." >&2;}
+ac_tool_warned=yes ;;
+esac
+ DUMPBIN=$ac_ct_DUMPBIN
+ fi
+fi
+
+
+ if test "$DUMPBIN" != ":"; then
+ NM="$DUMPBIN"
+ fi
+fi
+test -z "$NM" && NM=nm
+
+
+
+
+
+
+{ $as_echo "$as_me:$LINENO: checking the name lister ($NM) interface" >&5
+$as_echo_n "checking the name lister ($NM) interface... " >&6; }
+if test "${lt_cv_nm_interface+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_nm_interface="BSD nm"
+ echo "int some_variable = 0;" > conftest.$ac_ext
+ (eval echo "\"\$as_me:5214: $ac_compile\"" >&5)
+ (eval "$ac_compile" 2>conftest.err)
+ cat conftest.err >&5
+ (eval echo "\"\$as_me:5217: $NM \\\"conftest.$ac_objext\\\"\"" >&5)
+ (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out)
+ cat conftest.err >&5
+ (eval echo "\"\$as_me:5220: output\"" >&5)
+ cat conftest.out >&5
+ if $GREP 'External.*some_variable' conftest.out > /dev/null; then
+ lt_cv_nm_interface="MS dumpbin"
+ fi
+ rm -f conftest*
+fi
+{ $as_echo "$as_me:$LINENO: result: $lt_cv_nm_interface" >&5
+$as_echo "$lt_cv_nm_interface" >&6; }
+
+{ $as_echo "$as_me:$LINENO: checking whether ln -s works" >&5
+$as_echo_n "checking whether ln -s works... " >&6; }
+LN_S=$as_ln_s
+if test "$LN_S" = "ln -s"; then
+ { $as_echo "$as_me:$LINENO: result: yes" >&5
+$as_echo "yes" >&6; }
+else
+ { $as_echo "$as_me:$LINENO: result: no, using $LN_S" >&5
+$as_echo "no, using $LN_S" >&6; }
+fi
+
+# find the maximum length of command line arguments
+{ $as_echo "$as_me:$LINENO: checking the maximum length of command line arguments" >&5
+$as_echo_n "checking the maximum length of command line arguments... " >&6; }
+if test "${lt_cv_sys_max_cmd_len+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ i=0
+ teststring="ABCD"
+
+ case $build_os in
+ msdosdjgpp*)
+ # On DJGPP, this test can blow up pretty badly due to problems in libc
+ # (any single argument exceeding 2000 bytes causes a buffer overrun
+ # during glob expansion). Even if it were fixed, the result of this
+ # check would be larger than it should be.
+ lt_cv_sys_max_cmd_len=12288; # 12K is about right
+ ;;
+
+ gnu*)
+ # Under GNU Hurd, this test is not required because there is
+ # no limit to the length of command line arguments.
+ # Libtool will interpret -1 as no limit whatsoever
+ lt_cv_sys_max_cmd_len=-1;
+ ;;
+
+ cygwin* | mingw* | cegcc*)
+ # On Win9x/ME, this test blows up -- it succeeds, but takes
+ # about 5 minutes as the teststring grows exponentially.
+ # Worse, since 9x/ME are not pre-emptively multitasking,
+ # you end up with a "frozen" computer, even though with patience
+ # the test eventually succeeds (with a max line length of 256k).
+ # Instead, let's just punt: use the minimum linelength reported by
+ # all of the supported platforms: 8192 (on NT/2K/XP).
+ lt_cv_sys_max_cmd_len=8192;
+ ;;
+
+ amigaos*)
+ # On AmigaOS with pdksh, this test takes hours, literally.
+ # So we just punt and use a minimum line length of 8192.
+ lt_cv_sys_max_cmd_len=8192;
+ ;;
+
+ netbsd* | freebsd* | openbsd* | darwin* | dragonfly*)
+ # This has been around since 386BSD, at least. Likely further.
+ if test -x /sbin/sysctl; then
+ lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax`
+ elif test -x /usr/sbin/sysctl; then
+ lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax`
+ else
+ lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs
+ fi
+ # And add a safety zone
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4`
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3`
+ ;;
+
+ interix*)
+ # We know the value 262144 and hardcode it with a safety zone (like BSD)
+ lt_cv_sys_max_cmd_len=196608
+ ;;
+
+ osf*)
+ # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure
+ # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not
+ # nice to cause kernel panics so lets avoid the loop below.
+ # First set a reasonable default.
+ lt_cv_sys_max_cmd_len=16384
+ #
+ if test -x /sbin/sysconfig; then
+ case `/sbin/sysconfig -q proc exec_disable_arg_limit` in
+ *1*) lt_cv_sys_max_cmd_len=-1 ;;
+ esac
+ fi
+ ;;
+ sco3.2v5*)
+ lt_cv_sys_max_cmd_len=102400
+ ;;
+ sysv5* | sco5v6* | sysv4.2uw2*)
+ kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null`
+ if test -n "$kargmax"; then
+ lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[ ]//'`
+ else
+ lt_cv_sys_max_cmd_len=32768
+ fi
+ ;;
+ *)
+ lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null`
+ if test -n "$lt_cv_sys_max_cmd_len"; then
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4`
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3`
+ else
+ # Make teststring a little bigger before we do anything with it.
+ # a 1K string should be a reasonable start.
+ for i in 1 2 3 4 5 6 7 8 ; do
+ teststring=$teststring$teststring
+ done
+ SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}}
+ # If test is not a shell built-in, we'll probably end up computing a
+ # maximum length that is only half of the actual maximum length, but
+ # we can't tell.
+ while { test "X"`$SHELL $0 --fallback-echo "X$teststring$teststring" 2>/dev/null` \
+ = "XX$teststring$teststring"; } >/dev/null 2>&1 &&
+ test $i != 17 # 1/2 MB should be enough
+ do
+ i=`expr $i + 1`
+ teststring=$teststring$teststring
+ done
+ # Only check the string length outside the loop.
+ lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1`
+ teststring=
+ # Add a significant safety factor because C++ compilers can tack on
+ # massive amounts of additional arguments before passing them to the
+ # linker. It appears as though 1/2 is a usable value.
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2`
+ fi
+ ;;
+ esac
+
+fi
+
+if test -n $lt_cv_sys_max_cmd_len ; then
+ { $as_echo "$as_me:$LINENO: result: $lt_cv_sys_max_cmd_len" >&5
+$as_echo "$lt_cv_sys_max_cmd_len" >&6; }
+else
+ { $as_echo "$as_me:$LINENO: result: none" >&5
+$as_echo "none" >&6; }
+fi
+max_cmd_len=$lt_cv_sys_max_cmd_len
+
+
+
+
+
+
+: ${CP="cp -f"}
+: ${MV="mv -f"}
+: ${RM="rm -f"}
+
+{ $as_echo "$as_me:$LINENO: checking whether the shell understands some XSI constructs" >&5
+$as_echo_n "checking whether the shell understands some XSI constructs... " >&6; }
+# Try some XSI features
+xsi_shell=no
+( _lt_dummy="a/b/c"
+ test "${_lt_dummy##*/},${_lt_dummy%/*},"${_lt_dummy%"$_lt_dummy"}, \
+ = c,a/b,, \
+ && eval 'test $(( 1 + 1 )) -eq 2 \
+ && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \
+ && xsi_shell=yes
+{ $as_echo "$as_me:$LINENO: result: $xsi_shell" >&5
+$as_echo "$xsi_shell" >&6; }
+
+
+{ $as_echo "$as_me:$LINENO: checking whether the shell understands \"+=\"" >&5
+$as_echo_n "checking whether the shell understands \"+=\"... " >&6; }
+lt_shell_append=no
+( foo=bar; set foo baz; eval "$1+=\$2" && test "$foo" = barbaz ) \
+ >/dev/null 2>&1 \
+ && lt_shell_append=yes
+{ $as_echo "$as_me:$LINENO: result: $lt_shell_append" >&5
+$as_echo "$lt_shell_append" >&6; }
+
+
+if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+ lt_unset=unset
+else
+ lt_unset=false
+fi
+
+
+
+
+
+# test EBCDIC or ASCII
+case `echo X|tr X '\101'` in
+ A) # ASCII based system
+ # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr
+ lt_SP2NL='tr \040 \012'
+ lt_NL2SP='tr \015\012 \040\040'
+ ;;
+ *) # EBCDIC based system
+ lt_SP2NL='tr \100 \n'
+ lt_NL2SP='tr \r\n \100\100'
+ ;;
+esac
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:$LINENO: checking for $LD option to reload object files" >&5
+$as_echo_n "checking for $LD option to reload object files... " >&6; }
+if test "${lt_cv_ld_reload_flag+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_ld_reload_flag='-r'
+fi
+{ $as_echo "$as_me:$LINENO: result: $lt_cv_ld_reload_flag" >&5
+$as_echo "$lt_cv_ld_reload_flag" >&6; }
+reload_flag=$lt_cv_ld_reload_flag
+case $reload_flag in
+"" | " "*) ;;
+*) reload_flag=" $reload_flag" ;;
+esac
+reload_cmds='$LD$reload_flag -o $output$reload_objs'
+case $host_os in
+ darwin*)
+ if test "$GCC" = yes; then
+ reload_cmds='$LTCC $LTCFLAGS -nostdlib ${wl}-r -o $output$reload_objs'
+ else
+ reload_cmds='$LD$reload_flag -o $output$reload_objs'
+ fi
+ ;;
+esac
+
+
+
+
+
+
+
+
+
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args.
+set dummy ${ac_tool_prefix}objdump; ac_word=$2
+{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_OBJDUMP+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$OBJDUMP"; then
+ ac_cv_prog_OBJDUMP="$OBJDUMP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump"
+ $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+OBJDUMP=$ac_cv_prog_OBJDUMP
+if test -n "$OBJDUMP"; then
+ { $as_echo "$as_me:$LINENO: result: $OBJDUMP" >&5
+$as_echo "$OBJDUMP" >&6; }
+else
+ { $as_echo "$as_me:$LINENO: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_OBJDUMP"; then
+ ac_ct_OBJDUMP=$OBJDUMP
+ # Extract the first word of "objdump", so it can be a program name with args.
+set dummy objdump; ac_word=$2
+{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_OBJDUMP+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_OBJDUMP"; then
+ ac_cv_prog_ac_ct_OBJDUMP="$ac_ct_OBJDUMP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_ac_ct_OBJDUMP="objdump"
+ $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_OBJDUMP=$ac_cv_prog_ac_ct_OBJDUMP
+if test -n "$ac_ct_OBJDUMP"; then
+ { $as_echo "$as_me:$LINENO: result: $ac_ct_OBJDUMP" >&5
+$as_echo "$ac_ct_OBJDUMP" >&6; }
+else
+ { $as_echo "$as_me:$LINENO: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_OBJDUMP" = x; then
+ OBJDUMP="false"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools
+whose name does not start with the host triplet. If you think this
+configuration is useful to you, please write to autoconf@gnu.org." >&5
+$as_echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools
+whose name does not start with the host triplet. If you think this
+configuration is useful to you, please write to autoconf@gnu.org." >&2;}
+ac_tool_warned=yes ;;
+esac
+ OBJDUMP=$ac_ct_OBJDUMP
+ fi
+else
+ OBJDUMP="$ac_cv_prog_OBJDUMP"
+fi
+
+test -z "$OBJDUMP" && OBJDUMP=objdump
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:$LINENO: checking how to recognize dependent libraries" >&5
+$as_echo_n "checking how to recognize dependent libraries... " >&6; }
+if test "${lt_cv_deplibs_check_method+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_file_magic_cmd='$MAGIC_CMD'
+lt_cv_file_magic_test_file=
+lt_cv_deplibs_check_method='unknown'
+# Need to set the preceding variable on all platforms that support
+# interlibrary dependencies.
+# 'none' -- dependencies not supported.
+# `unknown' -- same as none, but documents that we really don't know.
+# 'pass_all' -- all dependencies passed with no checks.
+# 'test_compile' -- check by making test program.
+# 'file_magic [[regex]]' -- check by looking for files in library path
+# which responds to the $file_magic_cmd with a given extended regex.
+# If you have `file' or equivalent on your system and you're not sure
+# whether `pass_all' will *always* work, you probably want this one.
+
+case $host_os in
+aix[4-9]*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+beos*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+bsdi[45]*)
+ lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)'
+ lt_cv_file_magic_cmd='/usr/bin/file -L'
+ lt_cv_file_magic_test_file=/shlib/libc.so
+ ;;
+
+cygwin*)
+ # func_win32_libid is a shell function defined in ltmain.sh
+ lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
+ lt_cv_file_magic_cmd='func_win32_libid'
+ ;;
+
+mingw* | pw32*)
+ # Base MSYS/MinGW do not provide the 'file' command needed by
+ # func_win32_libid shell function, so use a weaker test based on 'objdump',
+ # unless we find 'file', for example because we are cross-compiling.
+ if ( file / ) >/dev/null 2>&1; then
+ lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
+ lt_cv_file_magic_cmd='func_win32_libid'
+ else
+ lt_cv_deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?'
+ lt_cv_file_magic_cmd='$OBJDUMP -f'
+ fi
+ ;;
+
+cegcc)
+ # use the weaker test based on 'objdump'. See mingw*.
+ lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?'
+ lt_cv_file_magic_cmd='$OBJDUMP -f'
+ ;;
+
+darwin* | rhapsody*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+freebsd* | dragonfly*)
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then
+ case $host_cpu in
+ i*86 )
+ # Not sure whether the presence of OpenBSD here was a mistake.
+ # Let's accept both of them until this is cleared up.
+ lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[3-9]86 (compact )?demand paged shared library'
+ lt_cv_file_magic_cmd=/usr/bin/file
+ lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*`
+ ;;
+ esac
+ else
+ lt_cv_deplibs_check_method=pass_all
+ fi
+ ;;
+
+gnu*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+hpux10.20* | hpux11*)
+ lt_cv_file_magic_cmd=/usr/bin/file
+ case $host_cpu in
+ ia64*)
+ lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - IA64'
+ lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so
+ ;;
+ hppa*64*)
+ lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - PA-RISC [0-9].[0-9]'
+ lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl
+ ;;
+ *)
+ lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9].[0-9]) shared library'
+ lt_cv_file_magic_test_file=/usr/lib/libc.sl
+ ;;
+ esac
+ ;;
+
+interix[3-9]*)
+ # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here
+ lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|\.a)$'
+ ;;
+
+irix5* | irix6* | nonstopux*)
+ case $LD in
+ *-32|*"-32 ") libmagic=32-bit;;
+ *-n32|*"-n32 ") libmagic=N32;;
+ *-64|*"-64 ") libmagic=64-bit;;
+ *) libmagic=never-match;;
+ esac
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+# This must be Linux ELF.
+linux* | k*bsd*-gnu | kopensolaris*-gnu)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+netbsd* | netbsdelf*-gnu)
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then
+ lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$'
+ else
+ lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|_pic\.a)$'
+ fi
+ ;;
+
+newos6*)
+ lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)'
+ lt_cv_file_magic_cmd=/usr/bin/file
+ lt_cv_file_magic_test_file=/usr/lib/libnls.so
+ ;;
+
+*nto* | *qnx*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+openbsd*)
+ if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+ lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|\.so|_pic\.a)$'
+ else
+ lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$'
+ fi
+ ;;
+
+osf3* | osf4* | osf5*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+rdos*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+solaris*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+sysv4 | sysv4.3*)
+ case $host_vendor in
+ motorola)
+ lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]'
+ lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*`
+ ;;
+ ncr)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+ sequent)
+ lt_cv_file_magic_cmd='/bin/file'
+ lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )'
+ ;;
+ sni)
+ lt_cv_file_magic_cmd='/bin/file'
+ lt_cv_deplibs_check_method="file_magic ELF [0-9][0-9]*-bit [LM]SB dynamic lib"
+ lt_cv_file_magic_test_file=/lib/libc.so
+ ;;
+ siemens)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+ pc)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+ esac
+ ;;
+
+tpf*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+esac
+
+fi
+{ $as_echo "$as_me:$LINENO: result: $lt_cv_deplibs_check_method" >&5
+$as_echo "$lt_cv_deplibs_check_method" >&6; }
+file_magic_cmd=$lt_cv_file_magic_cmd
+deplibs_check_method=$lt_cv_deplibs_check_method
+test -z "$deplibs_check_method" && deplibs_check_method=unknown
+
+
+
+
+
+
+
+
+
+
+
+
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}ar", so it can be a program name with args.
+set dummy ${ac_tool_prefix}ar; ac_word=$2
+{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_AR+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$AR"; then
+ ac_cv_prog_AR="$AR" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_AR="${ac_tool_prefix}ar"
+ $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+AR=$ac_cv_prog_AR
+if test -n "$AR"; then
+ { $as_echo "$as_me:$LINENO: result: $AR" >&5
+$as_echo "$AR" >&6; }
+else
+ { $as_echo "$as_me:$LINENO: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_AR"; then
+ ac_ct_AR=$AR
+ # Extract the first word of "ar", so it can be a program name with args.
+set dummy ar; ac_word=$2
+{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_AR+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_AR"; then
+ ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_ac_ct_AR="ar"
+ $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_AR=$ac_cv_prog_ac_ct_AR
+if test -n "$ac_ct_AR"; then
+ { $as_echo "$as_me:$LINENO: result: $ac_ct_AR" >&5
+$as_echo "$ac_ct_AR" >&6; }
+else
+ { $as_echo "$as_me:$LINENO: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_AR" = x; then
+ AR="false"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools
+whose name does not start with the host triplet. If you think this
+configuration is useful to you, please write to autoconf@gnu.org." >&5
+$as_echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools
+whose name does not start with the host triplet. If you think this
+configuration is useful to you, please write to autoconf@gnu.org." >&2;}
+ac_tool_warned=yes ;;
+esac
+ AR=$ac_ct_AR
+ fi
+else
+ AR="$ac_cv_prog_AR"
+fi
+
+test -z "$AR" && AR=ar
+test -z "$AR_FLAGS" && AR_FLAGS=cru
+
+
+
+
+
+
+
+
+
+
+
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args.
+set dummy ${ac_tool_prefix}strip; ac_word=$2
+{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_STRIP+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$STRIP"; then
+ ac_cv_prog_STRIP="$STRIP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_STRIP="${ac_tool_prefix}strip"
+ $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+STRIP=$ac_cv_prog_STRIP
+if test -n "$STRIP"; then
+ { $as_echo "$as_me:$LINENO: result: $STRIP" >&5
+$as_echo "$STRIP" >&6; }
+else
+ { $as_echo "$as_me:$LINENO: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_STRIP"; then
+ ac_ct_STRIP=$STRIP
+ # Extract the first word of "strip", so it can be a program name with args.
+set dummy strip; ac_word=$2
+{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_STRIP+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_STRIP"; then
+ ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_ac_ct_STRIP="strip"
+ $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP
+if test -n "$ac_ct_STRIP"; then
+ { $as_echo "$as_me:$LINENO: result: $ac_ct_STRIP" >&5
+$as_echo "$ac_ct_STRIP" >&6; }
+else
+ { $as_echo "$as_me:$LINENO: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_STRIP" = x; then
+ STRIP=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools
+whose name does not start with the host triplet. If you think this
+configuration is useful to you, please write to autoconf@gnu.org." >&5
+$as_echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools
+whose name does not start with the host triplet. If you think this
+configuration is useful to you, please write to autoconf@gnu.org." >&2;}
+ac_tool_warned=yes ;;
+esac
+ STRIP=$ac_ct_STRIP
+ fi
+else
+ STRIP="$ac_cv_prog_STRIP"
+fi
+
+test -z "$STRIP" && STRIP=:
+
+
+
+
+
+
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args.
+set dummy ${ac_tool_prefix}ranlib; ac_word=$2
+{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_RANLIB+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$RANLIB"; then
+ ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib"
+ $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+RANLIB=$ac_cv_prog_RANLIB
+if test -n "$RANLIB"; then
+ { $as_echo "$as_me:$LINENO: result: $RANLIB" >&5
+$as_echo "$RANLIB" >&6; }
+else
+ { $as_echo "$as_me:$LINENO: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_RANLIB"; then
+ ac_ct_RANLIB=$RANLIB
+ # Extract the first word of "ranlib", so it can be a program name with args.
+set dummy ranlib; ac_word=$2
+{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_RANLIB"; then
+ ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_ac_ct_RANLIB="ranlib"
+ $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB
+if test -n "$ac_ct_RANLIB"; then
+ { $as_echo "$as_me:$LINENO: result: $ac_ct_RANLIB" >&5
+$as_echo "$ac_ct_RANLIB" >&6; }
+else
+ { $as_echo "$as_me:$LINENO: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_RANLIB" = x; then
+ RANLIB=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools
+whose name does not start with the host triplet. If you think this
+configuration is useful to you, please write to autoconf@gnu.org." >&5
+$as_echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools
+whose name does not start with the host triplet. If you think this
+configuration is useful to you, please write to autoconf@gnu.org." >&2;}
+ac_tool_warned=yes ;;
+esac
+ RANLIB=$ac_ct_RANLIB
+ fi
+else
+ RANLIB="$ac_cv_prog_RANLIB"
+fi
+
+test -z "$RANLIB" && RANLIB=:
+
+
+
+
+
+
+# Determine commands to create old-style static archives.
+old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs'
+old_postinstall_cmds='chmod 644 $oldlib'
+old_postuninstall_cmds=
+
+if test -n "$RANLIB"; then
+ case $host_os in
+ openbsd*)
+ old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$oldlib"
+ ;;
+ *)
+ old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$oldlib"
+ ;;
+ esac
+ old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib"
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# If no C compiler was specified, use CC.
+LTCC=${LTCC-"$CC"}
+
+# If no C compiler flags were specified, use CFLAGS.
+LTCFLAGS=${LTCFLAGS-"$CFLAGS"}
+
+# Allow CC to be a program name with arguments.
+compiler=$CC
+
+
+# Check for command to grab the raw symbol name followed by C symbol from nm.
+{ $as_echo "$as_me:$LINENO: checking command to parse $NM output from $compiler object" >&5
+$as_echo_n "checking command to parse $NM output from $compiler object... " >&6; }
+if test "${lt_cv_sys_global_symbol_pipe+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+
+# These are sane defaults that work on at least a few old systems.
+# [They come from Ultrix. What could be older than Ultrix?!! ;)]
+
+# Character class describing NM global symbol codes.
+symcode='[BCDEGRST]'
+
+# Regexp to match symbols that can be accessed directly from C.
+sympat='\([_A-Za-z][_A-Za-z0-9]*\)'
+
+# Define system-specific variables.
+case $host_os in
+aix*)
+ symcode='[BCDT]'
+ ;;
+cygwin* | mingw* | pw32* | cegcc*)
+ symcode='[ABCDGISTW]'
+ ;;
+hpux*)
+ if test "$host_cpu" = ia64; then
+ symcode='[ABCDEGRST]'
+ fi
+ ;;
+irix* | nonstopux*)
+ symcode='[BCDEGRST]'
+ ;;
+osf*)
+ symcode='[BCDEGQRST]'
+ ;;
+solaris*)
+ symcode='[BDRT]'
+ ;;
+sco3.2v5*)
+ symcode='[DT]'
+ ;;
+sysv4.2uw2*)
+ symcode='[DT]'
+ ;;
+sysv5* | sco5v6* | unixware* | OpenUNIX*)
+ symcode='[ABDT]'
+ ;;
+sysv4)
+ symcode='[DFNSTU]'
+ ;;
+esac
+
+# If we're using GNU nm, then use its standard symbol codes.
+case `$NM -V 2>&1` in
+*GNU* | *'with BFD'*)
+ symcode='[ABCDGIRSTW]' ;;
+esac
+
+# Transform an extracted symbol line into a proper C declaration.
+# Some systems (esp. on ia64) link data and code symbols differently,
+# so use this general approach.
+lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'"
+
+# Transform an extracted symbol line into symbol name and symbol address
+lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\) $/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"\2\", (void *) \&\2},/p'"
+lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([^ ]*\) $/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \(lib[^ ]*\)$/ {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"lib\2\", (void *) \&\2},/p'"
+
+# Handle CRLF in mingw tool chain
+opt_cr=
+case $build_os in
+mingw*)
+ opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp
+ ;;
+esac
+
+# Try without a prefix underscore, then with it.
+for ac_symprfx in "" "_"; do
+
+ # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol.
+ symxfrm="\\1 $ac_symprfx\\2 \\2"
+
+ # Write the raw and C identifiers.
+ if test "$lt_cv_nm_interface" = "MS dumpbin"; then
+ # Fake it for dumpbin and say T for any non-static function
+ # and D for any global variable.
+ # Also find C++ and __fastcall symbols from MSVC++,
+ # which start with @ or ?.
+ lt_cv_sys_global_symbol_pipe="$AWK '"\
+" {last_section=section; section=\$ 3};"\
+" /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\
+" \$ 0!~/External *\|/{next};"\
+" / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\
+" {if(hide[section]) next};"\
+" {f=0}; \$ 0~/\(\).*\|/{f=1}; {printf f ? \"T \" : \"D \"};"\
+" {split(\$ 0, a, /\||\r/); split(a[2], s)};"\
+" s[1]~/^[@?]/{print s[1], s[1]; next};"\
+" s[1]~prfx {split(s[1],t,\"@\"); print t[1], substr(t[1],length(prfx))}"\
+" ' prfx=^$ac_symprfx"
+ else
+ lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[ ]\($symcode$symcode*\)[ ][ ]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'"
+ fi
+
+ # Check to see that the pipe works correctly.
+ pipe_works=no
+
+ rm -f conftest*
+ cat > conftest.$ac_ext <<_LT_EOF
+#ifdef __cplusplus
+extern "C" {
+#endif
+char nm_test_var;
+void nm_test_func(void);
+void nm_test_func(void){}
+#ifdef __cplusplus
+}
+#endif
+int main(){nm_test_var='a';nm_test_func();return(0);}
+_LT_EOF
+
+ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; then
+ # Now try to grab the symbols.
+ nlist=conftest.nm
+ if { (eval echo "$as_me:$LINENO: \"$NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $nlist\"") >&5
+ (eval $NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $nlist) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && test -s "$nlist"; then
+ # Try sorting and uniquifying the output.
+ if sort "$nlist" | uniq > "$nlist"T; then
+ mv -f "$nlist"T "$nlist"
+ else
+ rm -f "$nlist"T
+ fi
+
+ # Make sure that we snagged all the symbols we need.
+ if $GREP ' nm_test_var$' "$nlist" >/dev/null; then
+ if $GREP ' nm_test_func$' "$nlist" >/dev/null; then
+ cat <<_LT_EOF > conftest.$ac_ext
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+_LT_EOF
+ # Now generate the symbol file.
+ eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext'
+
+ cat <<_LT_EOF >> conftest.$ac_ext
+
+/* The mapping between symbol names and symbols. */
+const struct {
+ const char *name;
+ void *address;
+}
+lt__PROGRAM__LTX_preloaded_symbols[] =
+{
+ { "@PROGRAM@", (void *) 0 },
+_LT_EOF
+ $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (void *) \&\2},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext
+ cat <<\_LT_EOF >> conftest.$ac_ext
+ {0, (void *) 0}
+};
+
+/* This works around a problem in FreeBSD linker */
+#ifdef FREEBSD_WORKAROUND
+static const void *lt_preloaded_setup() {
+ return lt__PROGRAM__LTX_preloaded_symbols;
+}
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+_LT_EOF
+ # Now try linking the two files.
+ mv conftest.$ac_objext conftstm.$ac_objext
+ lt_save_LIBS="$LIBS"
+ lt_save_CFLAGS="$CFLAGS"
+ LIBS="conftstm.$ac_objext"
+ CFLAGS="$CFLAGS$lt_prog_compiler_no_builtin_flag"
+ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && test -s conftest${ac_exeext}; then
+ pipe_works=yes
+ fi
+ LIBS="$lt_save_LIBS"
+ CFLAGS="$lt_save_CFLAGS"
+ else
+ echo "cannot find nm_test_func in $nlist" >&5
+ fi
+ else
+ echo "cannot find nm_test_var in $nlist" >&5
+ fi
+ else
+ echo "cannot run $lt_cv_sys_global_symbol_pipe" >&5
+ fi
+ else
+ echo "$progname: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ fi
+ rm -rf conftest* conftst*
+
+ # Do not use the global_symbol_pipe unless it works.
+ if test "$pipe_works" = yes; then
+ break
+ else
+ lt_cv_sys_global_symbol_pipe=
+ fi
+done
+
+fi
+
+if test -z "$lt_cv_sys_global_symbol_pipe"; then
+ lt_cv_sys_global_symbol_to_cdecl=
+fi
+if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then
+ { $as_echo "$as_me:$LINENO: result: failed" >&5
+$as_echo "failed" >&6; }
+else
+ { $as_echo "$as_me:$LINENO: result: ok" >&5
+$as_echo "ok" >&6; }
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# Check whether --enable-libtool-lock was given.
+if test "${enable_libtool_lock+set}" = set; then
+ enableval=$enable_libtool_lock;
+fi
+
+test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes
+
+# Some flags need to be propagated to the compiler or linker for good
+# libtool support.
+case $host in
+ia64-*-hpux*)
+ # Find out which ABI we are using.
+ echo 'int i;' > conftest.$ac_ext
+ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; then
+ case `/usr/bin/file conftest.$ac_objext` in
+ *ELF-32*)
+ HPUX_IA64_MODE="32"
+ ;;
+ *ELF-64*)
+ HPUX_IA64_MODE="64"
+ ;;
+ esac
+ fi
+ rm -rf conftest*
+ ;;
+*-*-irix6*)
+ # Find out which ABI we are using.
+ echo '#line 6442 "configure"' > conftest.$ac_ext
+ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; then
+ if test "$lt_cv_prog_gnu_ld" = yes; then
+ case `/usr/bin/file conftest.$ac_objext` in
+ *32-bit*)
+ LD="${LD-ld} -melf32bsmip"
+ ;;
+ *N32*)
+ LD="${LD-ld} -melf32bmipn32"
+ ;;
+ *64-bit*)
+ LD="${LD-ld} -melf64bmip"
+ ;;
+ esac
+ else
+ case `/usr/bin/file conftest.$ac_objext` in
+ *32-bit*)
+ LD="${LD-ld} -32"
+ ;;
+ *N32*)
+ LD="${LD-ld} -n32"
+ ;;
+ *64-bit*)
+ LD="${LD-ld} -64"
+ ;;
+ esac
+ fi
+ fi
+ rm -rf conftest*
+ ;;
+
+x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \
+s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
+ # Find out which ABI we are using.
+ echo 'int i;' > conftest.$ac_ext
+ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; then
+ case `/usr/bin/file conftest.o` in
+ *32-bit*)
+ case $host in
+ x86_64-*kfreebsd*-gnu)
+ LD="${LD-ld} -m elf_i386_fbsd"
+ ;;
+ x86_64-*linux*)
+ LD="${LD-ld} -m elf_i386"
+ ;;
+ ppc64-*linux*|powerpc64-*linux*)
+ LD="${LD-ld} -m elf32ppclinux"
+ ;;
+ s390x-*linux*)
+ LD="${LD-ld} -m elf_s390"
+ ;;
+ sparc64-*linux*)
+ LD="${LD-ld} -m elf32_sparc"
+ ;;
+ esac
+ ;;
+ *64-bit*)
+ case $host in
+ x86_64-*kfreebsd*-gnu)
+ LD="${LD-ld} -m elf_x86_64_fbsd"
+ ;;
+ x86_64-*linux*)
+ LD="${LD-ld} -m elf_x86_64"
+ ;;
+ ppc*-*linux*|powerpc*-*linux*)
+ LD="${LD-ld} -m elf64ppc"
+ ;;
+ s390*-*linux*|s390*-*tpf*)
+ LD="${LD-ld} -m elf64_s390"
+ ;;
+ sparc*-*linux*)
+ LD="${LD-ld} -m elf64_sparc"
+ ;;
+ esac
+ ;;
+ esac
+ fi
+ rm -rf conftest*
+ ;;
+
+*-*-sco3.2v5*)
+ # On SCO OpenServer 5, we need -belf to get full-featured binaries.
+ SAVE_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS -belf"
+ { $as_echo "$as_me:$LINENO: checking whether the C compiler needs -belf" >&5
+$as_echo_n "checking whether the C compiler needs -belf... " >&6; }
+if test "${lt_cv_cc_needs_belf+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_link") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest$ac_exeext && {
+ test "$cross_compiling" = yes ||
+ $as_test_x conftest$ac_exeext
+ }; then
+ lt_cv_cc_needs_belf=yes
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ lt_cv_cc_needs_belf=no
+fi
+
+rm -rf conftest.dSYM
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+ conftest$ac_exeext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+fi
+{ $as_echo "$as_me:$LINENO: result: $lt_cv_cc_needs_belf" >&5
+$as_echo "$lt_cv_cc_needs_belf" >&6; }
+ if test x"$lt_cv_cc_needs_belf" != x"yes"; then
+ # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf
+ CFLAGS="$SAVE_CFLAGS"
+ fi
+ ;;
+sparc*-*solaris*)
+ # Find out which ABI we are using.
+ echo 'int i;' > conftest.$ac_ext
+ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; then
+ case `/usr/bin/file conftest.o` in
+ *64-bit*)
+ case $lt_cv_prog_gnu_ld in
+ yes*) LD="${LD-ld} -m elf64_sparc" ;;
+ *)
+ if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then
+ LD="${LD-ld} -64"
+ fi
+ ;;
+ esac
+ ;;
+ esac
+ fi
+ rm -rf conftest*
+ ;;
+esac
+
+need_locks="$enable_libtool_lock"
+
+
+ case $host_os in
+ rhapsody* | darwin*)
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}dsymutil", so it can be a program name with args.
+set dummy ${ac_tool_prefix}dsymutil; ac_word=$2
+{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_DSYMUTIL+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$DSYMUTIL"; then
+ ac_cv_prog_DSYMUTIL="$DSYMUTIL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_DSYMUTIL="${ac_tool_prefix}dsymutil"
+ $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+DSYMUTIL=$ac_cv_prog_DSYMUTIL
+if test -n "$DSYMUTIL"; then
+ { $as_echo "$as_me:$LINENO: result: $DSYMUTIL" >&5
+$as_echo "$DSYMUTIL" >&6; }
+else
+ { $as_echo "$as_me:$LINENO: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_DSYMUTIL"; then
+ ac_ct_DSYMUTIL=$DSYMUTIL
+ # Extract the first word of "dsymutil", so it can be a program name with args.
+set dummy dsymutil; ac_word=$2
+{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_DSYMUTIL+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_DSYMUTIL"; then
+ ac_cv_prog_ac_ct_DSYMUTIL="$ac_ct_DSYMUTIL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_ac_ct_DSYMUTIL="dsymutil"
+ $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_DSYMUTIL=$ac_cv_prog_ac_ct_DSYMUTIL
+if test -n "$ac_ct_DSYMUTIL"; then
+ { $as_echo "$as_me:$LINENO: result: $ac_ct_DSYMUTIL" >&5
+$as_echo "$ac_ct_DSYMUTIL" >&6; }
+else
+ { $as_echo "$as_me:$LINENO: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_DSYMUTIL" = x; then
+ DSYMUTIL=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools
+whose name does not start with the host triplet. If you think this
+configuration is useful to you, please write to autoconf@gnu.org." >&5
+$as_echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools
+whose name does not start with the host triplet. If you think this
+configuration is useful to you, please write to autoconf@gnu.org." >&2;}
+ac_tool_warned=yes ;;
+esac
+ DSYMUTIL=$ac_ct_DSYMUTIL
+ fi
+else
+ DSYMUTIL="$ac_cv_prog_DSYMUTIL"
+fi
+
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}nmedit", so it can be a program name with args.
+set dummy ${ac_tool_prefix}nmedit; ac_word=$2
+{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_NMEDIT+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$NMEDIT"; then
+ ac_cv_prog_NMEDIT="$NMEDIT" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_NMEDIT="${ac_tool_prefix}nmedit"
+ $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+NMEDIT=$ac_cv_prog_NMEDIT
+if test -n "$NMEDIT"; then
+ { $as_echo "$as_me:$LINENO: result: $NMEDIT" >&5
+$as_echo "$NMEDIT" >&6; }
+else
+ { $as_echo "$as_me:$LINENO: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_NMEDIT"; then
+ ac_ct_NMEDIT=$NMEDIT
+ # Extract the first word of "nmedit", so it can be a program name with args.
+set dummy nmedit; ac_word=$2
+{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_NMEDIT+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_NMEDIT"; then
+ ac_cv_prog_ac_ct_NMEDIT="$ac_ct_NMEDIT" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_ac_ct_NMEDIT="nmedit"
+ $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_NMEDIT=$ac_cv_prog_ac_ct_NMEDIT
+if test -n "$ac_ct_NMEDIT"; then
+ { $as_echo "$as_me:$LINENO: result: $ac_ct_NMEDIT" >&5
+$as_echo "$ac_ct_NMEDIT" >&6; }
+else
+ { $as_echo "$as_me:$LINENO: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_NMEDIT" = x; then
+ NMEDIT=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools
+whose name does not start with the host triplet. If you think this
+configuration is useful to you, please write to autoconf@gnu.org." >&5
+$as_echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools
+whose name does not start with the host triplet. If you think this
+configuration is useful to you, please write to autoconf@gnu.org." >&2;}
+ac_tool_warned=yes ;;
+esac
+ NMEDIT=$ac_ct_NMEDIT
+ fi
+else
+ NMEDIT="$ac_cv_prog_NMEDIT"
+fi
+
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}lipo", so it can be a program name with args.
+set dummy ${ac_tool_prefix}lipo; ac_word=$2
+{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_LIPO+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$LIPO"; then
+ ac_cv_prog_LIPO="$LIPO" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_LIPO="${ac_tool_prefix}lipo"
+ $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+LIPO=$ac_cv_prog_LIPO
+if test -n "$LIPO"; then
+ { $as_echo "$as_me:$LINENO: result: $LIPO" >&5
+$as_echo "$LIPO" >&6; }
+else
+ { $as_echo "$as_me:$LINENO: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_LIPO"; then
+ ac_ct_LIPO=$LIPO
+ # Extract the first word of "lipo", so it can be a program name with args.
+set dummy lipo; ac_word=$2
+{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_LIPO+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_LIPO"; then
+ ac_cv_prog_ac_ct_LIPO="$ac_ct_LIPO" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_ac_ct_LIPO="lipo"
+ $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_LIPO=$ac_cv_prog_ac_ct_LIPO
+if test -n "$ac_ct_LIPO"; then
+ { $as_echo "$as_me:$LINENO: result: $ac_ct_LIPO" >&5
+$as_echo "$ac_ct_LIPO" >&6; }
+else
+ { $as_echo "$as_me:$LINENO: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_LIPO" = x; then
+ LIPO=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools
+whose name does not start with the host triplet. If you think this
+configuration is useful to you, please write to autoconf@gnu.org." >&5
+$as_echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools
+whose name does not start with the host triplet. If you think this
+configuration is useful to you, please write to autoconf@gnu.org." >&2;}
+ac_tool_warned=yes ;;
+esac
+ LIPO=$ac_ct_LIPO
+ fi
+else
+ LIPO="$ac_cv_prog_LIPO"
+fi
+
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}otool", so it can be a program name with args.
+set dummy ${ac_tool_prefix}otool; ac_word=$2
+{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_OTOOL+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$OTOOL"; then
+ ac_cv_prog_OTOOL="$OTOOL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_OTOOL="${ac_tool_prefix}otool"
+ $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+OTOOL=$ac_cv_prog_OTOOL
+if test -n "$OTOOL"; then
+ { $as_echo "$as_me:$LINENO: result: $OTOOL" >&5
+$as_echo "$OTOOL" >&6; }
+else
+ { $as_echo "$as_me:$LINENO: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_OTOOL"; then
+ ac_ct_OTOOL=$OTOOL
+ # Extract the first word of "otool", so it can be a program name with args.
+set dummy otool; ac_word=$2
+{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_OTOOL+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_OTOOL"; then
+ ac_cv_prog_ac_ct_OTOOL="$ac_ct_OTOOL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_ac_ct_OTOOL="otool"
+ $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_OTOOL=$ac_cv_prog_ac_ct_OTOOL
+if test -n "$ac_ct_OTOOL"; then
+ { $as_echo "$as_me:$LINENO: result: $ac_ct_OTOOL" >&5
+$as_echo "$ac_ct_OTOOL" >&6; }
+else
+ { $as_echo "$as_me:$LINENO: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_OTOOL" = x; then
+ OTOOL=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools
+whose name does not start with the host triplet. If you think this
+configuration is useful to you, please write to autoconf@gnu.org." >&5
+$as_echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools
+whose name does not start with the host triplet. If you think this
+configuration is useful to you, please write to autoconf@gnu.org." >&2;}
+ac_tool_warned=yes ;;
+esac
+ OTOOL=$ac_ct_OTOOL
+ fi
+else
+ OTOOL="$ac_cv_prog_OTOOL"
+fi
+
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}otool64", so it can be a program name with args.
+set dummy ${ac_tool_prefix}otool64; ac_word=$2
+{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_OTOOL64+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$OTOOL64"; then
+ ac_cv_prog_OTOOL64="$OTOOL64" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_OTOOL64="${ac_tool_prefix}otool64"
+ $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+OTOOL64=$ac_cv_prog_OTOOL64
+if test -n "$OTOOL64"; then
+ { $as_echo "$as_me:$LINENO: result: $OTOOL64" >&5
+$as_echo "$OTOOL64" >&6; }
+else
+ { $as_echo "$as_me:$LINENO: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_OTOOL64"; then
+ ac_ct_OTOOL64=$OTOOL64
+ # Extract the first word of "otool64", so it can be a program name with args.
+set dummy otool64; ac_word=$2
+{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_OTOOL64+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_OTOOL64"; then
+ ac_cv_prog_ac_ct_OTOOL64="$ac_ct_OTOOL64" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_ac_ct_OTOOL64="otool64"
+ $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_OTOOL64=$ac_cv_prog_ac_ct_OTOOL64
+if test -n "$ac_ct_OTOOL64"; then
+ { $as_echo "$as_me:$LINENO: result: $ac_ct_OTOOL64" >&5
+$as_echo "$ac_ct_OTOOL64" >&6; }
+else
+ { $as_echo "$as_me:$LINENO: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_OTOOL64" = x; then
+ OTOOL64=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools
+whose name does not start with the host triplet. If you think this
+configuration is useful to you, please write to autoconf@gnu.org." >&5
+$as_echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools
+whose name does not start with the host triplet. If you think this
+configuration is useful to you, please write to autoconf@gnu.org." >&2;}
+ac_tool_warned=yes ;;
+esac
+ OTOOL64=$ac_ct_OTOOL64
+ fi
+else
+ OTOOL64="$ac_cv_prog_OTOOL64"
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ { $as_echo "$as_me:$LINENO: checking for -single_module linker flag" >&5
+$as_echo_n "checking for -single_module linker flag... " >&6; }
+if test "${lt_cv_apple_cc_single_mod+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_apple_cc_single_mod=no
+ if test -z "${LT_MULTI_MODULE}"; then
+ # By default we will add the -single_module flag. You can override
+ # by either setting the environment variable LT_MULTI_MODULE
+ # non-empty at configure time, or by adding -multi_module to the
+ # link flags.
+ rm -rf libconftest.dylib*
+ echo "int foo(void){return 1;}" > conftest.c
+ echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \
+-dynamiclib -Wl,-single_module conftest.c" >&5
+ $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \
+ -dynamiclib -Wl,-single_module conftest.c 2>conftest.err
+ _lt_result=$?
+ if test -f libconftest.dylib && test ! -s conftest.err && test $_lt_result = 0; then
+ lt_cv_apple_cc_single_mod=yes
+ else
+ cat conftest.err >&5
+ fi
+ rm -rf libconftest.dylib*
+ rm -f conftest.*
+ fi
+fi
+{ $as_echo "$as_me:$LINENO: result: $lt_cv_apple_cc_single_mod" >&5
+$as_echo "$lt_cv_apple_cc_single_mod" >&6; }
+ { $as_echo "$as_me:$LINENO: checking for -exported_symbols_list linker flag" >&5
+$as_echo_n "checking for -exported_symbols_list linker flag... " >&6; }
+if test "${lt_cv_ld_exported_symbols_list+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_ld_exported_symbols_list=no
+ save_LDFLAGS=$LDFLAGS
+ echo "_main" > conftest.sym
+ LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym"
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_link") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest$ac_exeext && {
+ test "$cross_compiling" = yes ||
+ $as_test_x conftest$ac_exeext
+ }; then
+ lt_cv_ld_exported_symbols_list=yes
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ lt_cv_ld_exported_symbols_list=no
+fi
+
+rm -rf conftest.dSYM
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+ conftest$ac_exeext conftest.$ac_ext
+ LDFLAGS="$save_LDFLAGS"
+
+fi
+{ $as_echo "$as_me:$LINENO: result: $lt_cv_ld_exported_symbols_list" >&5
+$as_echo "$lt_cv_ld_exported_symbols_list" >&6; }
+ case $host_os in
+ rhapsody* | darwin1.[012])
+ _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;;
+ darwin1.*)
+ _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;;
+ darwin*) # darwin 5.x on
+ # if running on 10.5 or later, the deployment target defaults
+ # to the OS version, if on x86, and 10.4, the deployment
+ # target defaults to 10.4. Don't you love it?
+ case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in
+ 10.0,*86*-darwin8*|10.0,*-darwin[91]*)
+ _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;;
+ 10.[012]*)
+ _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;;
+ 10.*)
+ _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;;
+ esac
+ ;;
+ esac
+ if test "$lt_cv_apple_cc_single_mod" = "yes"; then
+ _lt_dar_single_mod='$single_module'
+ fi
+ if test "$lt_cv_ld_exported_symbols_list" = "yes"; then
+ _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym'
+ else
+ _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}'
+ fi
+ if test "$DSYMUTIL" != ":"; then
+ _lt_dsymutil='~$DSYMUTIL $lib || :'
+ else
+ _lt_dsymutil=
+ fi
+ ;;
+ esac
+
+
+{ $as_echo "$as_me:$LINENO: checking for ANSI C header files" >&5
+$as_echo_n "checking for ANSI C header files... " >&6; }
+if test "${ac_cv_header_stdc+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ ac_cv_header_stdc=yes
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_cv_header_stdc=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+if test $ac_cv_header_stdc = yes; then
+ # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <string.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "memchr" >/dev/null 2>&1; then
+ :
+else
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <stdlib.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "free" >/dev/null 2>&1; then
+ :
+else
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+ if test "$cross_compiling" = yes; then
+ :
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <ctype.h>
+#include <stdlib.h>
+#if ((' ' & 0x0FF) == 0x020)
+# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#else
+# define ISLOWER(c) \
+ (('a' <= (c) && (c) <= 'i') \
+ || ('j' <= (c) && (c) <= 'r') \
+ || ('s' <= (c) && (c) <= 'z'))
+# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
+#endif
+
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int
+main ()
+{
+ int i;
+ for (i = 0; i < 256; i++)
+ if (XOR (islower (i), ISLOWER (i))
+ || toupper (i) != TOUPPER (i))
+ return 2;
+ return 0;
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_link") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+ { (case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_try") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ :
+else
+ $as_echo "$as_me: program exited with status $ac_status" >&5
+$as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+ac_cv_header_stdc=no
+fi
+rm -rf conftest.dSYM
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+
+
+fi
+fi
+{ $as_echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5
+$as_echo "$ac_cv_header_stdc" >&6; }
+if test $ac_cv_header_stdc = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define STDC_HEADERS 1
+_ACEOF
+
+fi
+
+# On IRIX 5.3, sys/types and inttypes.h are conflicting.
+
+
+
+
+
+
+
+
+
+for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \
+ inttypes.h stdint.h unistd.h
+do
+as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+{ $as_echo "$as_me:$LINENO: checking for $ac_header" >&5
+$as_echo_n "checking for $ac_header... " >&6; }
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+ $as_echo_n "(cached) " >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ eval "$as_ac_Header=yes"
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ eval "$as_ac_Header=no"
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+ac_res=`eval 'as_val=${'$as_ac_Header'}
+ $as_echo "$as_val"'`
+ { $as_echo "$as_me:$LINENO: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+if test `eval 'as_val=${'$as_ac_Header'}
+ $as_echo "$as_val"'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+
+for ac_header in dlfcn.h
+do
+as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+{ $as_echo "$as_me:$LINENO: checking for $ac_header" >&5
+$as_echo_n "checking for $ac_header... " >&6; }
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+ $as_echo_n "(cached) " >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ eval "$as_ac_Header=yes"
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ eval "$as_ac_Header=no"
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+ac_res=`eval 'as_val=${'$as_ac_Header'}
+ $as_echo "$as_val"'`
+ { $as_echo "$as_me:$LINENO: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+if test `eval 'as_val=${'$as_ac_Header'}
+ $as_echo "$as_val"'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+
+ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+if test -z "$CXX"; then
+ if test -n "$CCC"; then
+ CXX=$CCC
+ else
+ if test -n "$ac_tool_prefix"; then
+ for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC
+ do
+ # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_CXX+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CXX"; then
+ ac_cv_prog_CXX="$CXX" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_CXX="$ac_tool_prefix$ac_prog"
+ $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+CXX=$ac_cv_prog_CXX
+if test -n "$CXX"; then
+ { $as_echo "$as_me:$LINENO: result: $CXX" >&5
+$as_echo "$CXX" >&6; }
+else
+ { $as_echo "$as_me:$LINENO: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$CXX" && break
+ done
+fi
+if test -z "$CXX"; then
+ ac_ct_CXX=$CXX
+ for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_CXX+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_CXX"; then
+ ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_ac_ct_CXX="$ac_prog"
+ $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CXX=$ac_cv_prog_ac_ct_CXX
+if test -n "$ac_ct_CXX"; then
+ { $as_echo "$as_me:$LINENO: result: $ac_ct_CXX" >&5
+$as_echo "$ac_ct_CXX" >&6; }
+else
+ { $as_echo "$as_me:$LINENO: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$ac_ct_CXX" && break
+done
+
+ if test "x$ac_ct_CXX" = x; then
+ CXX="g++"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools
+whose name does not start with the host triplet. If you think this
+configuration is useful to you, please write to autoconf@gnu.org." >&5
+$as_echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools
+whose name does not start with the host triplet. If you think this
+configuration is useful to you, please write to autoconf@gnu.org." >&2;}
+ac_tool_warned=yes ;;
+esac
+ CXX=$ac_ct_CXX
+ fi
+fi
+
+ fi
+fi
+# Provide some information about the compiler.
+$as_echo "$as_me:$LINENO: checking for C++ compiler version" >&5
+set X $ac_compile
+ac_compiler=$2
+{ (ac_try="$ac_compiler --version >&5"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compiler --version >&5") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }
+{ (ac_try="$ac_compiler -v >&5"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compiler -v >&5") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }
+{ (ac_try="$ac_compiler -V >&5"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compiler -V >&5") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }
+
+{ $as_echo "$as_me:$LINENO: checking whether we are using the GNU C++ compiler" >&5
+$as_echo_n "checking whether we are using the GNU C++ compiler... " >&6; }
+if test "${ac_cv_cxx_compiler_gnu+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+#ifndef __GNUC__
+ choke me
+#endif
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_cxx_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ ac_compiler_gnu=yes
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_compiler_gnu=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_cv_cxx_compiler_gnu=$ac_compiler_gnu
+
+fi
+{ $as_echo "$as_me:$LINENO: result: $ac_cv_cxx_compiler_gnu" >&5
+$as_echo "$ac_cv_cxx_compiler_gnu" >&6; }
+if test $ac_compiler_gnu = yes; then
+ GXX=yes
+else
+ GXX=
+fi
+ac_test_CXXFLAGS=${CXXFLAGS+set}
+ac_save_CXXFLAGS=$CXXFLAGS
+{ $as_echo "$as_me:$LINENO: checking whether $CXX accepts -g" >&5
+$as_echo_n "checking whether $CXX accepts -g... " >&6; }
+if test "${ac_cv_prog_cxx_g+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ ac_save_cxx_werror_flag=$ac_cxx_werror_flag
+ ac_cxx_werror_flag=yes
+ ac_cv_prog_cxx_g=no
+ CXXFLAGS="-g"
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_cxx_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ ac_cv_prog_cxx_g=yes
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ CXXFLAGS=""
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_cxx_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ :
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_cxx_werror_flag=$ac_save_cxx_werror_flag
+ CXXFLAGS="-g"
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_cxx_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ ac_cv_prog_cxx_g=yes
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_cxx_werror_flag=$ac_save_cxx_werror_flag
+fi
+{ $as_echo "$as_me:$LINENO: result: $ac_cv_prog_cxx_g" >&5
+$as_echo "$ac_cv_prog_cxx_g" >&6; }
+if test "$ac_test_CXXFLAGS" = set; then
+ CXXFLAGS=$ac_save_CXXFLAGS
+elif test $ac_cv_prog_cxx_g = yes; then
+ if test "$GXX" = yes; then
+ CXXFLAGS="-g -O2"
+ else
+ CXXFLAGS="-g"
+ fi
+else
+ if test "$GXX" = yes; then
+ CXXFLAGS="-O2"
+ else
+ CXXFLAGS=
+ fi
+fi
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+depcc="$CXX" am_compiler_list=
+
+{ $as_echo "$as_me:$LINENO: checking dependency style of $depcc" >&5
+$as_echo_n "checking dependency style of $depcc... " >&6; }
+if test "${am_cv_CXX_dependencies_compiler_type+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then
+ # We make a subdir and do the tests there. Otherwise we can end up
+ # making bogus files that we don't know about and never remove. For
+ # instance it was reported that on HP-UX the gcc test will end up
+ # making a dummy file named `D' -- because `-MD' means `put the output
+ # in D'.
+ mkdir conftest.dir
+ # Copy depcomp to subdir because otherwise we won't find it if we're
+ # using a relative directory.
+ cp "$am_depcomp" conftest.dir
+ cd conftest.dir
+ # We will build objects and dependencies in a subdirectory because
+ # it helps to detect inapplicable dependency modes. For instance
+ # both Tru64's cc and ICC support -MD to output dependencies as a
+ # side effect of compilation, but ICC will put the dependencies in
+ # the current directory while Tru64 will put them in the object
+ # directory.
+ mkdir sub
+
+ am_cv_CXX_dependencies_compiler_type=none
+ if test "$am_compiler_list" = ""; then
+ am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp`
+ fi
+ for depmode in $am_compiler_list; do
+ # Setup a source with many dependencies, because some compilers
+ # like to wrap large dependency lists on column 80 (with \), and
+ # we should not choose a depcomp mode which is confused by this.
+ #
+ # We need to recreate these files for each test, as the compiler may
+ # overwrite some of them when testing with obscure command lines.
+ # This happens at least with the AIX C compiler.
+ : > sub/conftest.c
+ for i in 1 2 3 4 5 6; do
+ echo '#include "conftst'$i'.h"' >> sub/conftest.c
+ # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with
+ # Solaris 8's {/usr,}/bin/sh.
+ touch sub/conftst$i.h
+ done
+ echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
+
+ case $depmode in
+ nosideeffect)
+ # after this tag, mechanisms are not by side-effect, so they'll
+ # only be used when explicitly requested
+ if test "x$enable_dependency_tracking" = xyes; then
+ continue
+ else
+ break
+ fi
+ ;;
+ none) break ;;
+ esac
+ # We check with `-c' and `-o' for the sake of the "dashmstdout"
+ # mode. It turns out that the SunPro C++ compiler does not properly
+ # handle `-M -o', and we need to detect this.
+ if depmode=$depmode \
+ source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \
+ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \
+ $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c \
+ >/dev/null 2>conftest.err &&
+ grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 &&
+ grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 &&
+ grep sub/conftest.${OBJEXT-o} sub/conftest.Po > /dev/null 2>&1 &&
+ ${MAKE-make} -s -f confmf > /dev/null 2>&1; then
+ # icc doesn't choke on unknown options, it will just issue warnings
+ # or remarks (even with -Werror). So we grep stderr for any message
+ # that says an option was ignored or not supported.
+ # When given -MP, icc 7.0 and 7.1 complain thusly:
+ # icc: Command line warning: ignoring option '-M'; no argument required
+ # The diagnosis changed in icc 8.0:
+ # icc: Command line remark: option '-MP' not supported
+ if (grep 'ignoring option' conftest.err ||
+ grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else
+ am_cv_CXX_dependencies_compiler_type=$depmode
+ break
+ fi
+ fi
+ done
+
+ cd ..
+ rm -rf conftest.dir
+else
+ am_cv_CXX_dependencies_compiler_type=none
+fi
+
+fi
+{ $as_echo "$as_me:$LINENO: result: $am_cv_CXX_dependencies_compiler_type" >&5
+$as_echo "$am_cv_CXX_dependencies_compiler_type" >&6; }
+CXXDEPMODE=depmode=$am_cv_CXX_dependencies_compiler_type
+
+ if
+ test "x$enable_dependency_tracking" != xno \
+ && test "$am_cv_CXX_dependencies_compiler_type" = gcc3; then
+ am__fastdepCXX_TRUE=
+ am__fastdepCXX_FALSE='#'
+else
+ am__fastdepCXX_TRUE='#'
+ am__fastdepCXX_FALSE=
+fi
+
+
+if test -n "$CXX" && ( test "X$CXX" != "Xno" &&
+ ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) ||
+ (test "X$CXX" != "Xg++"))) ; then
+ ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+{ $as_echo "$as_me:$LINENO: checking how to run the C++ preprocessor" >&5
+$as_echo_n "checking how to run the C++ preprocessor... " >&6; }
+if test -z "$CXXCPP"; then
+ if test "${ac_cv_prog_CXXCPP+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ # Double quotes because CXXCPP needs to be expanded
+ for CXXCPP in "$CXX -E" "/lib/cpp"
+ do
+ ac_preproc_ok=false
+for ac_cxx_preproc_warn_flag in '' yes
+do
+ # Use a header file that comes with gcc, so configuring glibc
+ # with a fresh cross-compiler works.
+ # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ # <limits.h> exists even on freestanding compilers.
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp. "Syntax error" is here to catch this case.
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+ Syntax error
+_ACEOF
+if { (ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null && {
+ test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" ||
+ test ! -s conftest.err
+ }; then
+ :
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ # Broken: fails on valid input.
+continue
+fi
+
+rm -f conftest.err conftest.$ac_ext
+
+ # OK, works on sane cases. Now check whether nonexistent headers
+ # can be detected and how.
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <ac_nonexistent.h>
+_ACEOF
+if { (ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null && {
+ test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" ||
+ test ! -s conftest.err
+ }; then
+ # Broken: success on invalid input.
+continue
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+
+rm -f conftest.err conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then
+ break
+fi
+
+ done
+ ac_cv_prog_CXXCPP=$CXXCPP
+
+fi
+ CXXCPP=$ac_cv_prog_CXXCPP
+else
+ ac_cv_prog_CXXCPP=$CXXCPP
+fi
+{ $as_echo "$as_me:$LINENO: result: $CXXCPP" >&5
+$as_echo "$CXXCPP" >&6; }
+ac_preproc_ok=false
+for ac_cxx_preproc_warn_flag in '' yes
+do
+ # Use a header file that comes with gcc, so configuring glibc
+ # with a fresh cross-compiler works.
+ # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ # <limits.h> exists even on freestanding compilers.
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp. "Syntax error" is here to catch this case.
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+ Syntax error
+_ACEOF
+if { (ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null && {
+ test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" ||
+ test ! -s conftest.err
+ }; then
+ :
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ # Broken: fails on valid input.
+continue
+fi
+
+rm -f conftest.err conftest.$ac_ext
+
+ # OK, works on sane cases. Now check whether nonexistent headers
+ # can be detected and how.
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <ac_nonexistent.h>
+_ACEOF
+if { (ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null && {
+ test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" ||
+ test ! -s conftest.err
+ }; then
+ # Broken: success on invalid input.
+continue
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+
+rm -f conftest.err conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then
+ :
+else
+ _lt_caught_CXX_error=yes
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+else
+ _lt_caught_CXX_error=yes
+fi
+
+
+
+
+
+# Set options
+
+
+
+ enable_dlopen=no
+
+
+ enable_win32_dll=no
+
+
+ # Check whether --enable-shared was given.
+if test "${enable_shared+set}" = set; then
+ enableval=$enable_shared; p=${PACKAGE-default}
+ case $enableval in
+ yes) enable_shared=yes ;;
+ no) enable_shared=no ;;
+ *)
+ enable_shared=no
+ # Look at the argument we got. We use all the common list separators.
+ lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+ for pkg in $enableval; do
+ IFS="$lt_save_ifs"
+ if test "X$pkg" = "X$p"; then
+ enable_shared=yes
+ fi
+ done
+ IFS="$lt_save_ifs"
+ ;;
+ esac
+else
+ enable_shared=yes
+fi
+
+
+
+
+
+
+
+
+
+ # Check whether --enable-static was given.
+if test "${enable_static+set}" = set; then
+ enableval=$enable_static; p=${PACKAGE-default}
+ case $enableval in
+ yes) enable_static=yes ;;
+ no) enable_static=no ;;
+ *)
+ enable_static=no
+ # Look at the argument we got. We use all the common list separators.
+ lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+ for pkg in $enableval; do
+ IFS="$lt_save_ifs"
+ if test "X$pkg" = "X$p"; then
+ enable_static=yes
+ fi
+ done
+ IFS="$lt_save_ifs"
+ ;;
+ esac
+else
+ enable_static=yes
+fi
+
+
+
+
+
+
+
+
+
+
+# Check whether --with-pic was given.
+if test "${with_pic+set}" = set; then
+ withval=$with_pic; pic_mode="$withval"
+else
+ pic_mode=default
+fi
+
+
+test -z "$pic_mode" && pic_mode=default
+
+
+
+
+
+
+
+
+
+
+
+# This can be used to rebuild libtool when needed
+LIBTOOL_DEPS="$ltmain"
+
+# Always use our own libtool.
+LIBTOOL='$(SHELL) $(top_builddir)/libtool'
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+test -z "$LN_S" && LN_S="ln -s"
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+if test -n "${ZSH_VERSION+set}" ; then
+ setopt NO_GLOB_SUBST
+fi
+
+{ $as_echo "$as_me:$LINENO: checking for objdir" >&5
+$as_echo_n "checking for objdir... " >&6; }
+if test "${lt_cv_objdir+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ rm -f .libs 2>/dev/null
+mkdir .libs 2>/dev/null
+if test -d .libs; then
+ lt_cv_objdir=.libs
+else
+ # MS-DOS does not allow filenames that begin with a dot.
+ lt_cv_objdir=_libs
+fi
+rmdir .libs 2>/dev/null
+fi
+{ $as_echo "$as_me:$LINENO: result: $lt_cv_objdir" >&5
+$as_echo "$lt_cv_objdir" >&6; }
+objdir=$lt_cv_objdir
+
+
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define LT_OBJDIR "$lt_cv_objdir/"
+_ACEOF
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+case $host_os in
+aix3*)
+ # AIX sometimes has problems with the GCC collect2 program. For some
+ # reason, if we set the COLLECT_NAMES environment variable, the problems
+ # vanish in a puff of smoke.
+ if test "X${COLLECT_NAMES+set}" != Xset; then
+ COLLECT_NAMES=
+ export COLLECT_NAMES
+ fi
+ ;;
+esac
+
+# Sed substitution that helps us do robust quoting. It backslashifies
+# metacharacters that are still active within double-quoted strings.
+sed_quote_subst='s/\(["`$\\]\)/\\\1/g'
+
+# Same as above, but do not quote variable references.
+double_quote_subst='s/\(["`\\]\)/\\\1/g'
+
+# Sed substitution to delay expansion of an escaped shell variable in a
+# double_quote_subst'ed string.
+delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g'
+
+# Sed substitution to delay expansion of an escaped single quote.
+delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g'
+
+# Sed substitution to avoid accidental globbing in evaled expressions
+no_glob_subst='s/\*/\\\*/g'
+
+# Global variables:
+ofile=libtool
+can_build_shared=yes
+
+# All known linkers require a `.a' archive for static linking (except MSVC,
+# which needs '.lib').
+libext=a
+
+with_gnu_ld="$lt_cv_prog_gnu_ld"
+
+old_CC="$CC"
+old_CFLAGS="$CFLAGS"
+
+# Set sane defaults for various variables
+test -z "$CC" && CC=cc
+test -z "$LTCC" && LTCC=$CC
+test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS
+test -z "$LD" && LD=ld
+test -z "$ac_objext" && ac_objext=o
+
+for cc_temp in $compiler""; do
+ case $cc_temp in
+ compile | *[\\/]compile | ccache | *[\\/]ccache ) ;;
+ distcc | *[\\/]distcc | purify | *[\\/]purify ) ;;
+ \-*) ;;
+ *) break;;
+ esac
+done
+cc_basename=`$ECHO "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"`
+
+
+# Only perform the check for file, if the check method requires it
+test -z "$MAGIC_CMD" && MAGIC_CMD=file
+case $deplibs_check_method in
+file_magic*)
+ if test "$file_magic_cmd" = '$MAGIC_CMD'; then
+ { $as_echo "$as_me:$LINENO: checking for ${ac_tool_prefix}file" >&5
+$as_echo_n "checking for ${ac_tool_prefix}file... " >&6; }
+if test "${lt_cv_path_MAGIC_CMD+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ case $MAGIC_CMD in
+[\\/*] | ?:[\\/]*)
+ lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path.
+ ;;
+*)
+ lt_save_MAGIC_CMD="$MAGIC_CMD"
+ lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+ ac_dummy="/usr/bin$PATH_SEPARATOR$PATH"
+ for ac_dir in $ac_dummy; do
+ IFS="$lt_save_ifs"
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/${ac_tool_prefix}file; then
+ lt_cv_path_MAGIC_CMD="$ac_dir/${ac_tool_prefix}file"
+ if test -n "$file_magic_test_file"; then
+ case $deplibs_check_method in
+ "file_magic "*)
+ file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"`
+ MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+ if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
+ $EGREP "$file_magic_regex" > /dev/null; then
+ :
+ else
+ cat <<_LT_EOF 1>&2
+
+*** Warning: the command libtool uses to detect shared libraries,
+*** $file_magic_cmd, produces output that libtool cannot recognize.
+*** The result is that libtool may fail to recognize shared libraries
+*** as such. This will affect the creation of libtool libraries that
+*** depend on shared libraries, but programs linked with such libtool
+*** libraries will work regardless of this problem. Nevertheless, you
+*** may want to report the problem to your system manager and/or to
+*** bug-libtool@gnu.org
+
+_LT_EOF
+ fi ;;
+ esac
+ fi
+ break
+ fi
+ done
+ IFS="$lt_save_ifs"
+ MAGIC_CMD="$lt_save_MAGIC_CMD"
+ ;;
+esac
+fi
+
+MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+if test -n "$MAGIC_CMD"; then
+ { $as_echo "$as_me:$LINENO: result: $MAGIC_CMD" >&5
+$as_echo "$MAGIC_CMD" >&6; }
+else
+ { $as_echo "$as_me:$LINENO: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+
+
+
+if test -z "$lt_cv_path_MAGIC_CMD"; then
+ if test -n "$ac_tool_prefix"; then
+ { $as_echo "$as_me:$LINENO: checking for file" >&5
+$as_echo_n "checking for file... " >&6; }
+if test "${lt_cv_path_MAGIC_CMD+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ case $MAGIC_CMD in
+[\\/*] | ?:[\\/]*)
+ lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path.
+ ;;
+*)
+ lt_save_MAGIC_CMD="$MAGIC_CMD"
+ lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+ ac_dummy="/usr/bin$PATH_SEPARATOR$PATH"
+ for ac_dir in $ac_dummy; do
+ IFS="$lt_save_ifs"
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/file; then
+ lt_cv_path_MAGIC_CMD="$ac_dir/file"
+ if test -n "$file_magic_test_file"; then
+ case $deplibs_check_method in
+ "file_magic "*)
+ file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"`
+ MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+ if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
+ $EGREP "$file_magic_regex" > /dev/null; then
+ :
+ else
+ cat <<_LT_EOF 1>&2
+
+*** Warning: the command libtool uses to detect shared libraries,
+*** $file_magic_cmd, produces output that libtool cannot recognize.
+*** The result is that libtool may fail to recognize shared libraries
+*** as such. This will affect the creation of libtool libraries that
+*** depend on shared libraries, but programs linked with such libtool
+*** libraries will work regardless of this problem. Nevertheless, you
+*** may want to report the problem to your system manager and/or to
+*** bug-libtool@gnu.org
+
+_LT_EOF
+ fi ;;
+ esac
+ fi
+ break
+ fi
+ done
+ IFS="$lt_save_ifs"
+ MAGIC_CMD="$lt_save_MAGIC_CMD"
+ ;;
+esac
+fi
+
+MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+if test -n "$MAGIC_CMD"; then
+ { $as_echo "$as_me:$LINENO: result: $MAGIC_CMD" >&5
+$as_echo "$MAGIC_CMD" >&6; }
+else
+ { $as_echo "$as_me:$LINENO: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ else
+ MAGIC_CMD=:
+ fi
+fi
+
+ fi
+ ;;
+esac
+
+# Use C for the default configuration in the libtool script
+
+lt_save_CC="$CC"
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+# Source file extension for C test sources.
+ac_ext=c
+
+# Object file extension for compiled C test sources.
+objext=o
+objext=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code="int some_variable = 0;"
+
+# Code to be used in simple link tests
+lt_simple_link_test_code='int main(){return(0);}'
+
+
+
+
+
+
+
+# If no C compiler was specified, use CC.
+LTCC=${LTCC-"$CC"}
+
+# If no C compiler flags were specified, use CFLAGS.
+LTCFLAGS=${LTCFLAGS-"$CFLAGS"}
+
+# Allow CC to be a program name with arguments.
+compiler=$CC
+
+# Save the default compiler, since it gets overwritten when the other
+# tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP.
+compiler_DEFAULT=$CC
+
+# save warnings/boilerplate of simple test code
+ac_outfile=conftest.$ac_objext
+echo "$lt_simple_compile_test_code" >conftest.$ac_ext
+eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_compiler_boilerplate=`cat conftest.err`
+$RM conftest*
+
+ac_outfile=conftest.$ac_objext
+echo "$lt_simple_link_test_code" >conftest.$ac_ext
+eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_linker_boilerplate=`cat conftest.err`
+$RM -r conftest*
+
+
+## CAVEAT EMPTOR:
+## There is no encapsulation within the following macros, do not change
+## the running order or otherwise move them around unless you know exactly
+## what you are doing...
+if test -n "$compiler"; then
+
+lt_prog_compiler_no_builtin_flag=
+
+if test "$GCC" = yes; then
+ lt_prog_compiler_no_builtin_flag=' -fno-builtin'
+
+ { $as_echo "$as_me:$LINENO: checking if $compiler supports -fno-rtti -fno-exceptions" >&5
+$as_echo_n "checking if $compiler supports -fno-rtti -fno-exceptions... " >&6; }
+if test "${lt_cv_prog_compiler_rtti_exceptions+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_prog_compiler_rtti_exceptions=no
+ ac_outfile=conftest.$ac_objext
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+ lt_compiler_flag="-fno-rtti -fno-exceptions"
+ # Insert the option either (1) after the last *FLAGS variable, or
+ # (2) before a word containing "conftest.", or (3) at the end.
+ # Note that $ac_compile itself does not contain backslashes and begins
+ # with a dollar sign (not a hyphen), so the echo should work correctly.
+ # The option is referenced via a variable to avoid confusing sed.
+ lt_compile=`echo "$ac_compile" | $SED \
+ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+ -e 's:$: $lt_compiler_flag:'`
+ (eval echo "\"\$as_me:8773: $lt_compile\"" >&5)
+ (eval "$lt_compile" 2>conftest.err)
+ ac_status=$?
+ cat conftest.err >&5
+ echo "$as_me:8777: \$? = $ac_status" >&5
+ if (exit $ac_status) && test -s "$ac_outfile"; then
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings other than the usual output.
+ $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp
+ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+ if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
+ lt_cv_prog_compiler_rtti_exceptions=yes
+ fi
+ fi
+ $RM conftest*
+
+fi
+{ $as_echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_rtti_exceptions" >&5
+$as_echo "$lt_cv_prog_compiler_rtti_exceptions" >&6; }
+
+if test x"$lt_cv_prog_compiler_rtti_exceptions" = xyes; then
+ lt_prog_compiler_no_builtin_flag="$lt_prog_compiler_no_builtin_flag -fno-rtti -fno-exceptions"
+else
+ :
+fi
+
+fi
+
+
+
+
+
+
+ lt_prog_compiler_wl=
+lt_prog_compiler_pic=
+lt_prog_compiler_static=
+
+{ $as_echo "$as_me:$LINENO: checking for $compiler option to produce PIC" >&5
+$as_echo_n "checking for $compiler option to produce PIC... " >&6; }
+
+ if test "$GCC" = yes; then
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_static='-static'
+
+ case $host_os in
+ aix*)
+ # All AIX code is PIC.
+ if test "$host_cpu" = ia64; then
+ # AIX 5 now supports IA64 processor
+ lt_prog_compiler_static='-Bstatic'
+ fi
+ ;;
+
+ amigaos*)
+ case $host_cpu in
+ powerpc)
+ # see comment about AmigaOS4 .so support
+ lt_prog_compiler_pic='-fPIC'
+ ;;
+ m68k)
+ # FIXME: we need at least 68020 code to build shared libraries, but
+ # adding the `-m68020' flag to GCC prevents building anything better,
+ # like `-m68040'.
+ lt_prog_compiler_pic='-m68020 -resident32 -malways-restore-a4'
+ ;;
+ esac
+ ;;
+
+ beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
+ # PIC is the default for these OSes.
+ ;;
+
+ mingw* | cygwin* | pw32* | os2* | cegcc*)
+ # This hack is so that the source file can tell whether it is being
+ # built for inclusion in a dll (and should export symbols for example).
+ # Although the cygwin gcc ignores -fPIC, still need this for old-style
+ # (--disable-auto-import) libraries
+ lt_prog_compiler_pic='-DDLL_EXPORT'
+ ;;
+
+ darwin* | rhapsody*)
+ # PIC is the default on this platform
+ # Common symbols not allowed in MH_DYLIB files
+ lt_prog_compiler_pic='-fno-common'
+ ;;
+
+ hpux*)
+ # PIC is the default for 64-bit PA HP-UX, but not for 32-bit
+ # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag
+ # sets the default TLS model and affects inlining.
+ case $host_cpu in
+ hppa*64*)
+ # +Z the default
+ ;;
+ *)
+ lt_prog_compiler_pic='-fPIC'
+ ;;
+ esac
+ ;;
+
+ interix[3-9]*)
+ # Interix 3.x gcc -fpic/-fPIC options generate broken code.
+ # Instead, we relocate shared libraries at runtime.
+ ;;
+
+ msdosdjgpp*)
+ # Just because we use GCC doesn't mean we suddenly get shared libraries
+ # on systems that don't support them.
+ lt_prog_compiler_can_build_shared=no
+ enable_shared=no
+ ;;
+
+ *nto* | *qnx*)
+ # QNX uses GNU C++, but need to define -shared option too, otherwise
+ # it will coredump.
+ lt_prog_compiler_pic='-fPIC -shared'
+ ;;
+
+ sysv4*MP*)
+ if test -d /usr/nec; then
+ lt_prog_compiler_pic=-Kconform_pic
+ fi
+ ;;
+
+ *)
+ lt_prog_compiler_pic='-fPIC'
+ ;;
+ esac
+ else
+ # PORTME Check for flag to pass linker flags through the system compiler.
+ case $host_os in
+ aix*)
+ lt_prog_compiler_wl='-Wl,'
+ if test "$host_cpu" = ia64; then
+ # AIX 5 now supports IA64 processor
+ lt_prog_compiler_static='-Bstatic'
+ else
+ lt_prog_compiler_static='-bnso -bI:/lib/syscalls.exp'
+ fi
+ ;;
+
+ mingw* | cygwin* | pw32* | os2* | cegcc*)
+ # This hack is so that the source file can tell whether it is being
+ # built for inclusion in a dll (and should export symbols for example).
+ lt_prog_compiler_pic='-DDLL_EXPORT'
+ ;;
+
+ hpux9* | hpux10* | hpux11*)
+ lt_prog_compiler_wl='-Wl,'
+ # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
+ # not for PA HP-UX.
+ case $host_cpu in
+ hppa*64*|ia64*)
+ # +Z the default
+ ;;
+ *)
+ lt_prog_compiler_pic='+Z'
+ ;;
+ esac
+ # Is there a better lt_prog_compiler_static that works with the bundled CC?
+ lt_prog_compiler_static='${wl}-a ${wl}archive'
+ ;;
+
+ irix5* | irix6* | nonstopux*)
+ lt_prog_compiler_wl='-Wl,'
+ # PIC (with -KPIC) is the default.
+ lt_prog_compiler_static='-non_shared'
+ ;;
+
+ linux* | k*bsd*-gnu | kopensolaris*-gnu)
+ case $cc_basename in
+ # old Intel for x86_64 which still supported -KPIC.
+ ecc*)
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='-KPIC'
+ lt_prog_compiler_static='-static'
+ ;;
+ # icc used to be incompatible with GCC.
+ # ICC 10 doesn't accept -KPIC any more.
+ icc* | ifort*)
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='-fPIC'
+ lt_prog_compiler_static='-static'
+ ;;
+ # Lahey Fortran 8.1.
+ lf95*)
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='--shared'
+ lt_prog_compiler_static='--static'
+ ;;
+ pgcc* | pgf77* | pgf90* | pgf95*)
+ # Portland Group compilers (*not* the Pentium gcc compiler,
+ # which looks to be a dead project)
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='-fpic'
+ lt_prog_compiler_static='-Bstatic'
+ ;;
+ ccc*)
+ lt_prog_compiler_wl='-Wl,'
+ # All Alpha code is PIC.
+ lt_prog_compiler_static='-non_shared'
+ ;;
+ xl*)
+ # IBM XL C 8.0/Fortran 10.1 on PPC
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='-qpic'
+ lt_prog_compiler_static='-qstaticlink'
+ ;;
+ *)
+ case `$CC -V 2>&1 | sed 5q` in
+ *Sun\ C*)
+ # Sun C 5.9
+ lt_prog_compiler_pic='-KPIC'
+ lt_prog_compiler_static='-Bstatic'
+ lt_prog_compiler_wl='-Wl,'
+ ;;
+ *Sun\ F*)
+ # Sun Fortran 8.3 passes all unrecognized flags to the linker
+ lt_prog_compiler_pic='-KPIC'
+ lt_prog_compiler_static='-Bstatic'
+ lt_prog_compiler_wl=''
+ ;;
+ esac
+ ;;
+ esac
+ ;;
+
+ newsos6)
+ lt_prog_compiler_pic='-KPIC'
+ lt_prog_compiler_static='-Bstatic'
+ ;;
+
+ *nto* | *qnx*)
+ # QNX uses GNU C++, but need to define -shared option too, otherwise
+ # it will coredump.
+ lt_prog_compiler_pic='-fPIC -shared'
+ ;;
+
+ osf3* | osf4* | osf5*)
+ lt_prog_compiler_wl='-Wl,'
+ # All OSF/1 code is PIC.
+ lt_prog_compiler_static='-non_shared'
+ ;;
+
+ rdos*)
+ lt_prog_compiler_static='-non_shared'
+ ;;
+
+ solaris*)
+ lt_prog_compiler_pic='-KPIC'
+ lt_prog_compiler_static='-Bstatic'
+ case $cc_basename in
+ f77* | f90* | f95*)
+ lt_prog_compiler_wl='-Qoption ld ';;
+ *)
+ lt_prog_compiler_wl='-Wl,';;
+ esac
+ ;;
+
+ sunos4*)
+ lt_prog_compiler_wl='-Qoption ld '
+ lt_prog_compiler_pic='-PIC'
+ lt_prog_compiler_static='-Bstatic'
+ ;;
+
+ sysv4 | sysv4.2uw2* | sysv4.3*)
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='-KPIC'
+ lt_prog_compiler_static='-Bstatic'
+ ;;
+
+ sysv4*MP*)
+ if test -d /usr/nec ;then
+ lt_prog_compiler_pic='-Kconform_pic'
+ lt_prog_compiler_static='-Bstatic'
+ fi
+ ;;
+
+ sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='-KPIC'
+ lt_prog_compiler_static='-Bstatic'
+ ;;
+
+ unicos*)
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_can_build_shared=no
+ ;;
+
+ uts4*)
+ lt_prog_compiler_pic='-pic'
+ lt_prog_compiler_static='-Bstatic'
+ ;;
+
+ *)
+ lt_prog_compiler_can_build_shared=no
+ ;;
+ esac
+ fi
+
+case $host_os in
+ # For platforms which do not support PIC, -DPIC is meaningless:
+ *djgpp*)
+ lt_prog_compiler_pic=
+ ;;
+ *)
+ lt_prog_compiler_pic="$lt_prog_compiler_pic -DPIC"
+ ;;
+esac
+{ $as_echo "$as_me:$LINENO: result: $lt_prog_compiler_pic" >&5
+$as_echo "$lt_prog_compiler_pic" >&6; }
+
+
+
+
+
+
+#
+# Check to make sure the PIC flag actually works.
+#
+if test -n "$lt_prog_compiler_pic"; then
+ { $as_echo "$as_me:$LINENO: checking if $compiler PIC flag $lt_prog_compiler_pic works" >&5
+$as_echo_n "checking if $compiler PIC flag $lt_prog_compiler_pic works... " >&6; }
+if test "${lt_cv_prog_compiler_pic_works+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_prog_compiler_pic_works=no
+ ac_outfile=conftest.$ac_objext
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+ lt_compiler_flag="$lt_prog_compiler_pic -DPIC"
+ # Insert the option either (1) after the last *FLAGS variable, or
+ # (2) before a word containing "conftest.", or (3) at the end.
+ # Note that $ac_compile itself does not contain backslashes and begins
+ # with a dollar sign (not a hyphen), so the echo should work correctly.
+ # The option is referenced via a variable to avoid confusing sed.
+ lt_compile=`echo "$ac_compile" | $SED \
+ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+ -e 's:$: $lt_compiler_flag:'`
+ (eval echo "\"\$as_me:9112: $lt_compile\"" >&5)
+ (eval "$lt_compile" 2>conftest.err)
+ ac_status=$?
+ cat conftest.err >&5
+ echo "$as_me:9116: \$? = $ac_status" >&5
+ if (exit $ac_status) && test -s "$ac_outfile"; then
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings other than the usual output.
+ $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp
+ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+ if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
+ lt_cv_prog_compiler_pic_works=yes
+ fi
+ fi
+ $RM conftest*
+
+fi
+{ $as_echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_pic_works" >&5
+$as_echo "$lt_cv_prog_compiler_pic_works" >&6; }
+
+if test x"$lt_cv_prog_compiler_pic_works" = xyes; then
+ case $lt_prog_compiler_pic in
+ "" | " "*) ;;
+ *) lt_prog_compiler_pic=" $lt_prog_compiler_pic" ;;
+ esac
+else
+ lt_prog_compiler_pic=
+ lt_prog_compiler_can_build_shared=no
+fi
+
+fi
+
+
+
+
+
+
+#
+# Check to make sure the static flag actually works.
+#
+wl=$lt_prog_compiler_wl eval lt_tmp_static_flag=\"$lt_prog_compiler_static\"
+{ $as_echo "$as_me:$LINENO: checking if $compiler static flag $lt_tmp_static_flag works" >&5
+$as_echo_n "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; }
+if test "${lt_cv_prog_compiler_static_works+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_prog_compiler_static_works=no
+ save_LDFLAGS="$LDFLAGS"
+ LDFLAGS="$LDFLAGS $lt_tmp_static_flag"
+ echo "$lt_simple_link_test_code" > conftest.$ac_ext
+ if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then
+ # The linker can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ if test -s conftest.err; then
+ # Append any errors to the config.log.
+ cat conftest.err 1>&5
+ $ECHO "X$_lt_linker_boilerplate" | $Xsed -e '/^$/d' > conftest.exp
+ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+ if diff conftest.exp conftest.er2 >/dev/null; then
+ lt_cv_prog_compiler_static_works=yes
+ fi
+ else
+ lt_cv_prog_compiler_static_works=yes
+ fi
+ fi
+ $RM -r conftest*
+ LDFLAGS="$save_LDFLAGS"
+
+fi
+{ $as_echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_static_works" >&5
+$as_echo "$lt_cv_prog_compiler_static_works" >&6; }
+
+if test x"$lt_cv_prog_compiler_static_works" = xyes; then
+ :
+else
+ lt_prog_compiler_static=
+fi
+
+
+
+
+
+
+
+ { $as_echo "$as_me:$LINENO: checking if $compiler supports -c -o file.$ac_objext" >&5
+$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; }
+if test "${lt_cv_prog_compiler_c_o+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_prog_compiler_c_o=no
+ $RM -r conftest 2>/dev/null
+ mkdir conftest
+ cd conftest
+ mkdir out
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+ lt_compiler_flag="-o out/conftest2.$ac_objext"
+ # Insert the option either (1) after the last *FLAGS variable, or
+ # (2) before a word containing "conftest.", or (3) at the end.
+ # Note that $ac_compile itself does not contain backslashes and begins
+ # with a dollar sign (not a hyphen), so the echo should work correctly.
+ lt_compile=`echo "$ac_compile" | $SED \
+ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+ -e 's:$: $lt_compiler_flag:'`
+ (eval echo "\"\$as_me:9217: $lt_compile\"" >&5)
+ (eval "$lt_compile" 2>out/conftest.err)
+ ac_status=$?
+ cat out/conftest.err >&5
+ echo "$as_me:9221: \$? = $ac_status" >&5
+ if (exit $ac_status) && test -s out/conftest2.$ac_objext
+ then
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp
+ $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
+ if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
+ lt_cv_prog_compiler_c_o=yes
+ fi
+ fi
+ chmod u+w . 2>&5
+ $RM conftest*
+ # SGI C++ compiler will create directory out/ii_files/ for
+ # template instantiation
+ test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files
+ $RM out/* && rmdir out
+ cd ..
+ $RM -r conftest
+ $RM conftest*
+
+fi
+{ $as_echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_c_o" >&5
+$as_echo "$lt_cv_prog_compiler_c_o" >&6; }
+
+
+
+
+
+
+ { $as_echo "$as_me:$LINENO: checking if $compiler supports -c -o file.$ac_objext" >&5
+$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; }
+if test "${lt_cv_prog_compiler_c_o+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_prog_compiler_c_o=no
+ $RM -r conftest 2>/dev/null
+ mkdir conftest
+ cd conftest
+ mkdir out
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+ lt_compiler_flag="-o out/conftest2.$ac_objext"
+ # Insert the option either (1) after the last *FLAGS variable, or
+ # (2) before a word containing "conftest.", or (3) at the end.
+ # Note that $ac_compile itself does not contain backslashes and begins
+ # with a dollar sign (not a hyphen), so the echo should work correctly.
+ lt_compile=`echo "$ac_compile" | $SED \
+ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+ -e 's:$: $lt_compiler_flag:'`
+ (eval echo "\"\$as_me:9272: $lt_compile\"" >&5)
+ (eval "$lt_compile" 2>out/conftest.err)
+ ac_status=$?
+ cat out/conftest.err >&5
+ echo "$as_me:9276: \$? = $ac_status" >&5
+ if (exit $ac_status) && test -s out/conftest2.$ac_objext
+ then
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp
+ $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
+ if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
+ lt_cv_prog_compiler_c_o=yes
+ fi
+ fi
+ chmod u+w . 2>&5
+ $RM conftest*
+ # SGI C++ compiler will create directory out/ii_files/ for
+ # template instantiation
+ test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files
+ $RM out/* && rmdir out
+ cd ..
+ $RM -r conftest
+ $RM conftest*
+
+fi
+{ $as_echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_c_o" >&5
+$as_echo "$lt_cv_prog_compiler_c_o" >&6; }
+
+
+
+
+hard_links="nottested"
+if test "$lt_cv_prog_compiler_c_o" = no && test "$need_locks" != no; then
+ # do not overwrite the value of need_locks provided by the user
+ { $as_echo "$as_me:$LINENO: checking if we can lock with hard links" >&5
+$as_echo_n "checking if we can lock with hard links... " >&6; }
+ hard_links=yes
+ $RM conftest*
+ ln conftest.a conftest.b 2>/dev/null && hard_links=no
+ touch conftest.a
+ ln conftest.a conftest.b 2>&5 || hard_links=no
+ ln conftest.a conftest.b 2>/dev/null && hard_links=no
+ { $as_echo "$as_me:$LINENO: result: $hard_links" >&5
+$as_echo "$hard_links" >&6; }
+ if test "$hard_links" = no; then
+ { $as_echo "$as_me:$LINENO: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5
+$as_echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;}
+ need_locks=warn
+ fi
+else
+ need_locks=no
+fi
+
+
+
+
+
+
+ { $as_echo "$as_me:$LINENO: checking whether the $compiler linker ($LD) supports shared libraries" >&5
+$as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; }
+
+ runpath_var=
+ allow_undefined_flag=
+ always_export_symbols=no
+ archive_cmds=
+ archive_expsym_cmds=
+ compiler_needs_object=no
+ enable_shared_with_static_runtimes=no
+ export_dynamic_flag_spec=
+ export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+ hardcode_automatic=no
+ hardcode_direct=no
+ hardcode_direct_absolute=no
+ hardcode_libdir_flag_spec=
+ hardcode_libdir_flag_spec_ld=
+ hardcode_libdir_separator=
+ hardcode_minus_L=no
+ hardcode_shlibpath_var=unsupported
+ inherit_rpath=no
+ link_all_deplibs=unknown
+ module_cmds=
+ module_expsym_cmds=
+ old_archive_from_new_cmds=
+ old_archive_from_expsyms_cmds=
+ thread_safe_flag_spec=
+ whole_archive_flag_spec=
+ # include_expsyms should be a list of space-separated symbols to be *always*
+ # included in the symbol list
+ include_expsyms=
+ # exclude_expsyms can be an extended regexp of symbols to exclude
+ # it will be wrapped by ` (' and `)$', so one must not match beginning or
+ # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc',
+ # as well as any symbol that contains `d'.
+ exclude_expsyms='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'
+ # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out
+ # platforms (ab)use it in PIC code, but their linkers get confused if
+ # the symbol is explicitly referenced. Since portable code cannot
+ # rely on this symbol name, it's probably fine to never include it in
+ # preloaded symbol tables.
+ # Exclude shared library initialization/finalization symbols.
+ extract_expsyms_cmds=
+
+ case $host_os in
+ cygwin* | mingw* | pw32* | cegcc*)
+ # FIXME: the MSVC++ port hasn't been tested in a loooong time
+ # When not using gcc, we currently assume that we are using
+ # Microsoft Visual C++.
+ if test "$GCC" != yes; then
+ with_gnu_ld=no
+ fi
+ ;;
+ interix*)
+ # we just hope/assume this is gcc and not c89 (= MSVC++)
+ with_gnu_ld=yes
+ ;;
+ openbsd*)
+ with_gnu_ld=no
+ ;;
+ linux* | k*bsd*-gnu)
+ link_all_deplibs=no
+ ;;
+ esac
+
+ ld_shlibs=yes
+ if test "$with_gnu_ld" = yes; then
+ # If archive_cmds runs LD, not CC, wlarc should be empty
+ wlarc='${wl}'
+
+ # Set some defaults for GNU ld with shared library support. These
+ # are reset later if shared libraries are not supported. Putting them
+ # here allows them to be overridden if necessary.
+ runpath_var=LD_RUN_PATH
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+ export_dynamic_flag_spec='${wl}--export-dynamic'
+ # ancient GNU ld didn't support --whole-archive et. al.
+ if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then
+ whole_archive_flag_spec="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+ else
+ whole_archive_flag_spec=
+ fi
+ supports_anon_versioning=no
+ case `$LD -v 2>&1` in
+ *GNU\ gold*) supports_anon_versioning=yes ;;
+ *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11
+ *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ...
+ *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ...
+ *\ 2.11.*) ;; # other 2.11 versions
+ *) supports_anon_versioning=yes ;;
+ esac
+
+ # See if GNU ld supports shared libraries.
+ case $host_os in
+ aix[3-9]*)
+ # On AIX/PPC, the GNU linker is very broken
+ if test "$host_cpu" != ia64; then
+ ld_shlibs=no
+ cat <<_LT_EOF 1>&2
+
+*** Warning: the GNU linker, at least up to release 2.9.1, is reported
+*** to be unable to reliably create shared libraries on AIX.
+*** Therefore, libtool is disabling shared libraries support. If you
+*** really care for shared libraries, you may want to modify your PATH
+*** so that a non-GNU linker is found, and then restart.
+
+_LT_EOF
+ fi
+ ;;
+
+ amigaos*)
+ case $host_cpu in
+ powerpc)
+ # see comment about AmigaOS4 .so support
+ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ archive_expsym_cmds=''
+ ;;
+ m68k)
+ archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_minus_L=yes
+ ;;
+ esac
+ ;;
+
+ beos*)
+ if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ allow_undefined_flag=unsupported
+ # Joseph Beckenbach <jrb3@best.com> says some releases of gcc
+ # support --undefined. This deserves some investigation. FIXME
+ archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ else
+ ld_shlibs=no
+ fi
+ ;;
+
+ cygwin* | mingw* | pw32* | cegcc*)
+ # _LT_TAGVAR(hardcode_libdir_flag_spec, ) is actually meaningless,
+ # as there is no search path for DLLs.
+ hardcode_libdir_flag_spec='-L$libdir'
+ allow_undefined_flag=unsupported
+ always_export_symbols=no
+ enable_shared_with_static_runtimes=yes
+ export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/'\'' | $SED -e '\''/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols'
+
+ if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then
+ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+ # If the export-symbols file already is a .def file (1st line
+ # is EXPORTS), use it as is; otherwise, prepend...
+ archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+ cp $export_symbols $output_objdir/$soname.def;
+ else
+ echo EXPORTS > $output_objdir/$soname.def;
+ cat $export_symbols >> $output_objdir/$soname.def;
+ fi~
+ $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+ else
+ ld_shlibs=no
+ fi
+ ;;
+
+ interix[3-9]*)
+ hardcode_direct=no
+ hardcode_shlibpath_var=no
+ hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
+ export_dynamic_flag_spec='${wl}-E'
+ # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.
+ # Instead, shared libraries are loaded at an image base (0x10000000 by
+ # default) and relocated if they conflict, which is a slow very memory
+ # consuming and fragmenting process. To avoid this, we pick a random,
+ # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
+ # time. Moving up from 0x10000000 also allows more sbrk(2) space.
+ archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+ archive_expsym_cmds='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+ ;;
+
+ gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu)
+ tmp_diet=no
+ if test "$host_os" = linux-dietlibc; then
+ case $cc_basename in
+ diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn)
+ esac
+ fi
+ if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \
+ && test "$tmp_diet" = no
+ then
+ tmp_addflag=
+ tmp_sharedflag='-shared'
+ case $cc_basename,$host_cpu in
+ pgcc*) # Portland Group C compiler
+ whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive'
+ tmp_addflag=' $pic_flag'
+ ;;
+ pgf77* | pgf90* | pgf95*) # Portland Group f77 and f90 compilers
+ whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive'
+ tmp_addflag=' $pic_flag -Mnomain' ;;
+ ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64
+ tmp_addflag=' -i_dynamic' ;;
+ efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64
+ tmp_addflag=' -i_dynamic -nofor_main' ;;
+ ifc* | ifort*) # Intel Fortran compiler
+ tmp_addflag=' -nofor_main' ;;
+ lf95*) # Lahey Fortran 8.1
+ whole_archive_flag_spec=
+ tmp_sharedflag='--shared' ;;
+ xl[cC]*) # IBM XL C 8.0 on PPC (deal with xlf below)
+ tmp_sharedflag='-qmkshrobj'
+ tmp_addflag= ;;
+ esac
+ case `$CC -V 2>&1 | sed 5q` in
+ *Sun\ C*) # Sun C 5.9
+ whole_archive_flag_spec='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive'
+ compiler_needs_object=yes
+ tmp_sharedflag='-G' ;;
+ *Sun\ F*) # Sun Fortran 8.3
+ tmp_sharedflag='-G' ;;
+ esac
+ archive_cmds='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+
+ if test "x$supports_anon_versioning" = xyes; then
+ archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~
+ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+ echo "local: *; };" >> $output_objdir/$libname.ver~
+ $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib'
+ fi
+
+ case $cc_basename in
+ xlf*)
+ # IBM XL Fortran 10.1 on PPC cannot create shared libs itself
+ whole_archive_flag_spec='--whole-archive$convenience --no-whole-archive'
+ hardcode_libdir_flag_spec=
+ hardcode_libdir_flag_spec_ld='-rpath $libdir'
+ archive_cmds='$LD -shared $libobjs $deplibs $compiler_flags -soname $soname -o $lib'
+ if test "x$supports_anon_versioning" = xyes; then
+ archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~
+ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+ echo "local: *; };" >> $output_objdir/$libname.ver~
+ $LD -shared $libobjs $deplibs $compiler_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib'
+ fi
+ ;;
+ esac
+ else
+ ld_shlibs=no
+ fi
+ ;;
+
+ netbsd* | netbsdelf*-gnu)
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+ archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib'
+ wlarc=
+ else
+ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ fi
+ ;;
+
+ solaris*)
+ if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then
+ ld_shlibs=no
+ cat <<_LT_EOF 1>&2
+
+*** Warning: The releases 2.8.* of the GNU linker cannot reliably
+*** create shared libraries on Solaris systems. Therefore, libtool
+*** is disabling shared libraries support. We urge you to upgrade GNU
+*** binutils to release 2.9.1 or newer. Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+_LT_EOF
+ elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ else
+ ld_shlibs=no
+ fi
+ ;;
+
+ sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*)
+ case `$LD -v 2>&1` in
+ *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*)
+ ld_shlibs=no
+ cat <<_LT_EOF 1>&2
+
+*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not
+*** reliably create shared libraries on SCO systems. Therefore, libtool
+*** is disabling shared libraries support. We urge you to upgrade GNU
+*** binutils to release 2.16.91.0.3 or newer. Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+_LT_EOF
+ ;;
+ *)
+ # For security reasons, it is highly recommended that you always
+ # use absolute paths for naming shared libraries, and exclude the
+ # DT_RUNPATH tag from executables and libraries. But doing so
+ # requires that you compile everything twice, which is a pain.
+ if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ else
+ ld_shlibs=no
+ fi
+ ;;
+ esac
+ ;;
+
+ sunos4*)
+ archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+ wlarc=
+ hardcode_direct=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ *)
+ if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ else
+ ld_shlibs=no
+ fi
+ ;;
+ esac
+
+ if test "$ld_shlibs" = no; then
+ runpath_var=
+ hardcode_libdir_flag_spec=
+ export_dynamic_flag_spec=
+ whole_archive_flag_spec=
+ fi
+ else
+ # PORTME fill in a description of your system's linker (not GNU ld)
+ case $host_os in
+ aix3*)
+ allow_undefined_flag=unsupported
+ always_export_symbols=yes
+ archive_expsym_cmds='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname'
+ # Note: this linker hardcodes the directories in LIBPATH if there
+ # are no directories specified by -L.
+ hardcode_minus_L=yes
+ if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then
+ # Neither direct hardcoding nor static linking is supported with a
+ # broken collect2.
+ hardcode_direct=unsupported
+ fi
+ ;;
+
+ aix[4-9]*)
+ if test "$host_cpu" = ia64; then
+ # On IA64, the linker does run time linking by default, so we don't
+ # have to do anything special.
+ aix_use_runtimelinking=no
+ exp_sym_flag='-Bexport'
+ no_entry_flag=""
+ else
+ # If we're using GNU nm, then we don't want the "-C" option.
+ # -C means demangle to AIX nm, but means don't demangle with GNU nm
+ if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
+ export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
+ else
+ export_symbols_cmds='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
+ fi
+ aix_use_runtimelinking=no
+
+ # Test if we are trying to use run time linking or normal
+ # AIX style linking. If -brtl is somewhere in LDFLAGS, we
+ # need to do runtime linking.
+ case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*)
+ for ld_flag in $LDFLAGS; do
+ if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then
+ aix_use_runtimelinking=yes
+ break
+ fi
+ done
+ ;;
+ esac
+
+ exp_sym_flag='-bexport'
+ no_entry_flag='-bnoentry'
+ fi
+
+ # When large executables or shared objects are built, AIX ld can
+ # have problems creating the table of contents. If linking a library
+ # or program results in "error TOC overflow" add -mminimal-toc to
+ # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not
+ # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.
+
+ archive_cmds=''
+ hardcode_direct=yes
+ hardcode_direct_absolute=yes
+ hardcode_libdir_separator=':'
+ link_all_deplibs=yes
+ file_list_spec='${wl}-f,'
+
+ if test "$GCC" = yes; then
+ case $host_os in aix4.[012]|aix4.[012].*)
+ # We only want to do this on AIX 4.2 and lower, the check
+ # below for broken collect2 doesn't work under 4.3+
+ collect2name=`${CC} -print-prog-name=collect2`
+ if test -f "$collect2name" &&
+ strings "$collect2name" | $GREP resolve_lib_name >/dev/null
+ then
+ # We have reworked collect2
+ :
+ else
+ # We have old collect2
+ hardcode_direct=unsupported
+ # It fails to find uninstalled libraries when the uninstalled
+ # path is not listed in the libpath. Setting hardcode_minus_L
+ # to unsupported forces relinking
+ hardcode_minus_L=yes
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_libdir_separator=
+ fi
+ ;;
+ esac
+ shared_flag='-shared'
+ if test "$aix_use_runtimelinking" = yes; then
+ shared_flag="$shared_flag "'${wl}-G'
+ fi
+ link_all_deplibs=no
+ else
+ # not using gcc
+ if test "$host_cpu" = ia64; then
+ # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
+ # chokes on -Wl,-G. The following line is correct:
+ shared_flag='-G'
+ else
+ if test "$aix_use_runtimelinking" = yes; then
+ shared_flag='${wl}-G'
+ else
+ shared_flag='${wl}-bM:SRE'
+ fi
+ fi
+ fi
+
+ export_dynamic_flag_spec='${wl}-bexpall'
+ # It seems that -bexpall does not export symbols beginning with
+ # underscore (_), so it is better to generate a list of symbols to export.
+ always_export_symbols=yes
+ if test "$aix_use_runtimelinking" = yes; then
+ # Warning - without using the other runtime loading flags (-brtl),
+ # -berok will link without error, but may produce a broken library.
+ allow_undefined_flag='-berok'
+ # Determine the default libpath from the value encoded in an
+ # empty executable.
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_link") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest$ac_exeext && {
+ test "$cross_compiling" = yes ||
+ $as_test_x conftest$ac_exeext
+ }; then
+
+lt_aix_libpath_sed='
+ /Import File Strings/,/^$/ {
+ /^0/ {
+ s/^0 *\(.*\)$/\1/
+ p
+ }
+ }'
+aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+# Check for a 64-bit object if we didn't find anything.
+if test -z "$aix_libpath"; then
+ aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+fi
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+fi
+
+rm -rf conftest.dSYM
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+ conftest$ac_exeext conftest.$ac_ext
+if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
+
+ hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath"
+ archive_expsym_cmds='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then $ECHO "X${wl}${allow_undefined_flag}" | $Xsed; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag"
+ else
+ if test "$host_cpu" = ia64; then
+ hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib'
+ allow_undefined_flag="-z nodefs"
+ archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols"
+ else
+ # Determine the default libpath from the value encoded in an
+ # empty executable.
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_link") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest$ac_exeext && {
+ test "$cross_compiling" = yes ||
+ $as_test_x conftest$ac_exeext
+ }; then
+
+lt_aix_libpath_sed='
+ /Import File Strings/,/^$/ {
+ /^0/ {
+ s/^0 *\(.*\)$/\1/
+ p
+ }
+ }'
+aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+# Check for a 64-bit object if we didn't find anything.
+if test -z "$aix_libpath"; then
+ aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+fi
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+fi
+
+rm -rf conftest.dSYM
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+ conftest$ac_exeext conftest.$ac_ext
+if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
+
+ hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath"
+ # Warning - without using the other run time loading flags,
+ # -berok will link without error, but may produce a broken library.
+ no_undefined_flag=' ${wl}-bernotok'
+ allow_undefined_flag=' ${wl}-berok'
+ # Exported symbols can be pulled into shared objects from archives
+ whole_archive_flag_spec='$convenience'
+ archive_cmds_need_lc=yes
+ # This is similar to how AIX traditionally builds its shared libraries.
+ archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
+ fi
+ fi
+ ;;
+
+ amigaos*)
+ case $host_cpu in
+ powerpc)
+ # see comment about AmigaOS4 .so support
+ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ archive_expsym_cmds=''
+ ;;
+ m68k)
+ archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_minus_L=yes
+ ;;
+ esac
+ ;;
+
+ bsdi[45]*)
+ export_dynamic_flag_spec=-rdynamic
+ ;;
+
+ cygwin* | mingw* | pw32* | cegcc*)
+ # When not using gcc, we currently assume that we are using
+ # Microsoft Visual C++.
+ # hardcode_libdir_flag_spec is actually meaningless, as there is
+ # no search path for DLLs.
+ hardcode_libdir_flag_spec=' '
+ allow_undefined_flag=unsupported
+ # Tell ltmain to make .lib files, not .a files.
+ libext=lib
+ # Tell ltmain to make .dll files, not .so files.
+ shrext_cmds=".dll"
+ # FIXME: Setting linknames here is a bad hack.
+ archive_cmds='$CC -o $lib $libobjs $compiler_flags `$ECHO "X$deplibs" | $Xsed -e '\''s/ -lc$//'\''` -link -dll~linknames='
+ # The linker will automatically build a .lib file if we build a DLL.
+ old_archive_from_new_cmds='true'
+ # FIXME: Should let the user specify the lib program.
+ old_archive_cmds='lib -OUT:$oldlib$oldobjs$old_deplibs'
+ fix_srcfile_path='`cygpath -w "$srcfile"`'
+ enable_shared_with_static_runtimes=yes
+ ;;
+
+ darwin* | rhapsody*)
+
+
+ archive_cmds_need_lc=no
+ hardcode_direct=no
+ hardcode_automatic=yes
+ hardcode_shlibpath_var=unsupported
+ whole_archive_flag_spec=''
+ link_all_deplibs=yes
+ allow_undefined_flag="$_lt_dar_allow_undefined"
+ case $cc_basename in
+ ifort*) _lt_dar_can_shared=yes ;;
+ *) _lt_dar_can_shared=$GCC ;;
+ esac
+ if test "$_lt_dar_can_shared" = "yes"; then
+ output_verbose_link_cmd=echo
+ archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}"
+ module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}"
+ archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}"
+ module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}"
+
+ else
+ ld_shlibs=no
+ fi
+
+ ;;
+
+ dgux*)
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_shlibpath_var=no
+ ;;
+
+ freebsd1*)
+ ld_shlibs=no
+ ;;
+
+ # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor
+ # support. Future versions do this automatically, but an explicit c++rt0.o
+ # does not break anything, and helps significantly (at the cost of a little
+ # extra space).
+ freebsd2.2*)
+ archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o'
+ hardcode_libdir_flag_spec='-R$libdir'
+ hardcode_direct=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ # Unfortunately, older versions of FreeBSD 2 do not have this feature.
+ freebsd2*)
+ archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_direct=yes
+ hardcode_minus_L=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ # FreeBSD 3 and greater uses gcc -shared to do shared libraries.
+ freebsd* | dragonfly*)
+ archive_cmds='$CC -shared -o $lib $libobjs $deplibs $compiler_flags'
+ hardcode_libdir_flag_spec='-R$libdir'
+ hardcode_direct=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ hpux9*)
+ if test "$GCC" = yes; then
+ archive_cmds='$RM $output_objdir/$soname~$CC -shared -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+ else
+ archive_cmds='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+ fi
+ hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
+ hardcode_libdir_separator=:
+ hardcode_direct=yes
+
+ # hardcode_minus_L: Not really in the search PATH,
+ # but as the default location of the library.
+ hardcode_minus_L=yes
+ export_dynamic_flag_spec='${wl}-E'
+ ;;
+
+ hpux10*)
+ if test "$GCC" = yes -a "$with_gnu_ld" = no; then
+ archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+ else
+ archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'
+ fi
+ if test "$with_gnu_ld" = no; then
+ hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
+ hardcode_libdir_flag_spec_ld='+b $libdir'
+ hardcode_libdir_separator=:
+ hardcode_direct=yes
+ hardcode_direct_absolute=yes
+ export_dynamic_flag_spec='${wl}-E'
+ # hardcode_minus_L: Not really in the search PATH,
+ # but as the default location of the library.
+ hardcode_minus_L=yes
+ fi
+ ;;
+
+ hpux11*)
+ if test "$GCC" = yes -a "$with_gnu_ld" = no; then
+ case $host_cpu in
+ hppa*64*)
+ archive_cmds='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ ia64*)
+ archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ *)
+ archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ esac
+ else
+ case $host_cpu in
+ hppa*64*)
+ archive_cmds='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ ia64*)
+ archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ *)
+ archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ esac
+ fi
+ if test "$with_gnu_ld" = no; then
+ hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
+ hardcode_libdir_separator=:
+
+ case $host_cpu in
+ hppa*64*|ia64*)
+ hardcode_direct=no
+ hardcode_shlibpath_var=no
+ ;;
+ *)
+ hardcode_direct=yes
+ hardcode_direct_absolute=yes
+ export_dynamic_flag_spec='${wl}-E'
+
+ # hardcode_minus_L: Not really in the search PATH,
+ # but as the default location of the library.
+ hardcode_minus_L=yes
+ ;;
+ esac
+ fi
+ ;;
+
+ irix5* | irix6* | nonstopux*)
+ if test "$GCC" = yes; then
+ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ # Try to use the -exported_symbol ld option, if it does not
+ # work, assume that -exports_file does not work either and
+ # implicitly export all symbols.
+ save_LDFLAGS="$LDFLAGS"
+ LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null"
+ cat >conftest.$ac_ext <<_ACEOF
+int foo(void) {}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_link") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest$ac_exeext && {
+ test "$cross_compiling" = yes ||
+ $as_test_x conftest$ac_exeext
+ }; then
+ archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib'
+
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+fi
+
+rm -rf conftest.dSYM
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+ conftest$ac_exeext conftest.$ac_ext
+ LDFLAGS="$save_LDFLAGS"
+ else
+ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib'
+ archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib'
+ fi
+ archive_cmds_need_lc='no'
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+ hardcode_libdir_separator=:
+ inherit_rpath=yes
+ link_all_deplibs=yes
+ ;;
+
+ netbsd* | netbsdelf*-gnu)
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+ archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out
+ else
+ archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF
+ fi
+ hardcode_libdir_flag_spec='-R$libdir'
+ hardcode_direct=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ newsos6)
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_direct=yes
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+ hardcode_libdir_separator=:
+ hardcode_shlibpath_var=no
+ ;;
+
+ *nto* | *qnx*)
+ ;;
+
+ openbsd*)
+ if test -f /usr/libexec/ld.so; then
+ hardcode_direct=yes
+ hardcode_shlibpath_var=no
+ hardcode_direct_absolute=yes
+ if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+ archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols'
+ hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
+ export_dynamic_flag_spec='${wl}-E'
+ else
+ case $host_os in
+ openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*)
+ archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_libdir_flag_spec='-R$libdir'
+ ;;
+ *)
+ archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+ hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
+ ;;
+ esac
+ fi
+ else
+ ld_shlibs=no
+ fi
+ ;;
+
+ os2*)
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_minus_L=yes
+ allow_undefined_flag=unsupported
+ archive_cmds='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~$ECHO DATA >> $output_objdir/$libname.def~$ECHO " SINGLE NONSHARED" >> $output_objdir/$libname.def~$ECHO EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def'
+ old_archive_from_new_cmds='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def'
+ ;;
+
+ osf3*)
+ if test "$GCC" = yes; then
+ allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*'
+ archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ else
+ allow_undefined_flag=' -expect_unresolved \*'
+ archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib'
+ fi
+ archive_cmds_need_lc='no'
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+ hardcode_libdir_separator=:
+ ;;
+
+ osf4* | osf5*) # as osf3* with the addition of -msym flag
+ if test "$GCC" = yes; then
+ allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*'
+ archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+ else
+ allow_undefined_flag=' -expect_unresolved \*'
+ archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib'
+ archive_expsym_cmds='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~
+ $CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp'
+
+ # Both c and cxx compiler support -rpath directly
+ hardcode_libdir_flag_spec='-rpath $libdir'
+ fi
+ archive_cmds_need_lc='no'
+ hardcode_libdir_separator=:
+ ;;
+
+ solaris*)
+ no_undefined_flag=' -z defs'
+ if test "$GCC" = yes; then
+ wlarc='${wl}'
+ archive_cmds='$CC -shared ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $CC -shared ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
+ else
+ case `$CC -V 2>&1` in
+ *"Compilers 5.0"*)
+ wlarc=''
+ archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp'
+ ;;
+ *)
+ wlarc='${wl}'
+ archive_cmds='$CC -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $CC -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
+ ;;
+ esac
+ fi
+ hardcode_libdir_flag_spec='-R$libdir'
+ hardcode_shlibpath_var=no
+ case $host_os in
+ solaris2.[0-5] | solaris2.[0-5].*) ;;
+ *)
+ # The compiler driver will combine and reorder linker options,
+ # but understands `-z linker_flag'. GCC discards it without `$wl',
+ # but is careful enough not to reorder.
+ # Supported since Solaris 2.6 (maybe 2.5.1?)
+ if test "$GCC" = yes; then
+ whole_archive_flag_spec='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract'
+ else
+ whole_archive_flag_spec='-z allextract$convenience -z defaultextract'
+ fi
+ ;;
+ esac
+ link_all_deplibs=yes
+ ;;
+
+ sunos4*)
+ if test "x$host_vendor" = xsequent; then
+ # Use $CC to link under sequent, because it throws in some extra .o
+ # files that make .init and .fini sections work.
+ archive_cmds='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags'
+ else
+ archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags'
+ fi
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_direct=yes
+ hardcode_minus_L=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ sysv4)
+ case $host_vendor in
+ sni)
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_direct=yes # is this really true???
+ ;;
+ siemens)
+ ## LD is ld it makes a PLAMLIB
+ ## CC just makes a GrossModule.
+ archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags'
+ reload_cmds='$CC -r -o $output$reload_objs'
+ hardcode_direct=no
+ ;;
+ motorola)
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_direct=no #Motorola manual says yes, but my tests say they lie
+ ;;
+ esac
+ runpath_var='LD_RUN_PATH'
+ hardcode_shlibpath_var=no
+ ;;
+
+ sysv4.3*)
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_shlibpath_var=no
+ export_dynamic_flag_spec='-Bexport'
+ ;;
+
+ sysv4*MP*)
+ if test -d /usr/nec; then
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_shlibpath_var=no
+ runpath_var=LD_RUN_PATH
+ hardcode_runpath_var=yes
+ ld_shlibs=yes
+ fi
+ ;;
+
+ sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*)
+ no_undefined_flag='${wl}-z,text'
+ archive_cmds_need_lc=no
+ hardcode_shlibpath_var=no
+ runpath_var='LD_RUN_PATH'
+
+ if test "$GCC" = yes; then
+ archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ else
+ archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ fi
+ ;;
+
+ sysv5* | sco3.2v5* | sco5v6*)
+ # Note: We can NOT use -z defs as we might desire, because we do not
+ # link with -lc, and that would cause any symbols used from libc to
+ # always be unresolved, which means just about no library would
+ # ever link correctly. If we're not using GNU ld we use -z text
+ # though, which does catch some bad symbols but isn't as heavy-handed
+ # as -z defs.
+ no_undefined_flag='${wl}-z,text'
+ allow_undefined_flag='${wl}-z,nodefs'
+ archive_cmds_need_lc=no
+ hardcode_shlibpath_var=no
+ hardcode_libdir_flag_spec='${wl}-R,$libdir'
+ hardcode_libdir_separator=':'
+ link_all_deplibs=yes
+ export_dynamic_flag_spec='${wl}-Bexport'
+ runpath_var='LD_RUN_PATH'
+
+ if test "$GCC" = yes; then
+ archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ else
+ archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ fi
+ ;;
+
+ uts4*)
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_shlibpath_var=no
+ ;;
+
+ *)
+ ld_shlibs=no
+ ;;
+ esac
+
+ if test x$host_vendor = xsni; then
+ case $host in
+ sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
+ export_dynamic_flag_spec='${wl}-Blargedynsym'
+ ;;
+ esac
+ fi
+ fi
+
+{ $as_echo "$as_me:$LINENO: result: $ld_shlibs" >&5
+$as_echo "$ld_shlibs" >&6; }
+test "$ld_shlibs" = no && can_build_shared=no
+
+with_gnu_ld=$with_gnu_ld
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+#
+# Do we need to explicitly link libc?
+#
+case "x$archive_cmds_need_lc" in
+x|xyes)
+ # Assume -lc should be added
+ archive_cmds_need_lc=yes
+
+ if test "$enable_shared" = yes && test "$GCC" = yes; then
+ case $archive_cmds in
+ *'~'*)
+ # FIXME: we may have to deal with multi-command sequences.
+ ;;
+ '$CC '*)
+ # Test whether the compiler implicitly links with -lc since on some
+ # systems, -lgcc has to come before -lc. If gcc already passes -lc
+ # to ld, don't add -lc before -lgcc.
+ { $as_echo "$as_me:$LINENO: checking whether -lc should be explicitly linked in" >&5
+$as_echo_n "checking whether -lc should be explicitly linked in... " >&6; }
+ $RM conftest*
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } 2>conftest.err; then
+ soname=conftest
+ lib=conftest
+ libobjs=conftest.$ac_objext
+ deplibs=
+ wl=$lt_prog_compiler_wl
+ pic_flag=$lt_prog_compiler_pic
+ compiler_flags=-v
+ linker_flags=-v
+ verstring=
+ output_objdir=.
+ libname=conftest
+ lt_save_allow_undefined_flag=$allow_undefined_flag
+ allow_undefined_flag=
+ if { (eval echo "$as_me:$LINENO: \"$archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\"") >&5
+ (eval $archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }
+ then
+ archive_cmds_need_lc=no
+ else
+ archive_cmds_need_lc=yes
+ fi
+ allow_undefined_flag=$lt_save_allow_undefined_flag
+ else
+ cat conftest.err 1>&5
+ fi
+ $RM conftest*
+ { $as_echo "$as_me:$LINENO: result: $archive_cmds_need_lc" >&5
+$as_echo "$archive_cmds_need_lc" >&6; }
+ ;;
+ esac
+ fi
+ ;;
+esac
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ { $as_echo "$as_me:$LINENO: checking dynamic linker characteristics" >&5
+$as_echo_n "checking dynamic linker characteristics... " >&6; }
+
+if test "$GCC" = yes; then
+ case $host_os in
+ darwin*) lt_awk_arg="/^libraries:/,/LR/" ;;
+ *) lt_awk_arg="/^libraries:/" ;;
+ esac
+ lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e "s,=/,/,g"`
+ if $ECHO "$lt_search_path_spec" | $GREP ';' >/dev/null ; then
+ # if the path contains ";" then we assume it to be the separator
+ # otherwise default to the standard path separator (i.e. ":") - it is
+ # assumed that no part of a normal pathname contains ";" but that should
+ # okay in the real world where ";" in dirpaths is itself problematic.
+ lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED -e 's/;/ /g'`
+ else
+ lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
+ fi
+ # Ok, now we have the path, separated by spaces, we can step through it
+ # and add multilib dir if necessary.
+ lt_tmp_lt_search_path_spec=
+ lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null`
+ for lt_sys_path in $lt_search_path_spec; do
+ if test -d "$lt_sys_path/$lt_multi_os_dir"; then
+ lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir"
+ else
+ test -d "$lt_sys_path" && \
+ lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path"
+ fi
+ done
+ lt_search_path_spec=`$ECHO $lt_tmp_lt_search_path_spec | awk '
+BEGIN {RS=" "; FS="/|\n";} {
+ lt_foo="";
+ lt_count=0;
+ for (lt_i = NF; lt_i > 0; lt_i--) {
+ if ($lt_i != "" && $lt_i != ".") {
+ if ($lt_i == "..") {
+ lt_count++;
+ } else {
+ if (lt_count == 0) {
+ lt_foo="/" $lt_i lt_foo;
+ } else {
+ lt_count--;
+ }
+ }
+ }
+ }
+ if (lt_foo != "") { lt_freq[lt_foo]++; }
+ if (lt_freq[lt_foo] == 1) { print lt_foo; }
+}'`
+ sys_lib_search_path_spec=`$ECHO $lt_search_path_spec`
+else
+ sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib"
+fi
+library_names_spec=
+libname_spec='lib$name'
+soname_spec=
+shrext_cmds=".so"
+postinstall_cmds=
+postuninstall_cmds=
+finish_cmds=
+finish_eval=
+shlibpath_var=
+shlibpath_overrides_runpath=unknown
+version_type=none
+dynamic_linker="$host_os ld.so"
+sys_lib_dlsearch_path_spec="/lib /usr/lib"
+need_lib_prefix=unknown
+hardcode_into_libs=no
+
+# when you set need_version to no, make sure it does not cause -set_version
+# flags to be left without arguments
+need_version=unknown
+
+case $host_os in
+aix3*)
+ version_type=linux
+ library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a'
+ shlibpath_var=LIBPATH
+
+ # AIX 3 has no versioning support, so we append a major version to the name.
+ soname_spec='${libname}${release}${shared_ext}$major'
+ ;;
+
+aix[4-9]*)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ hardcode_into_libs=yes
+ if test "$host_cpu" = ia64; then
+ # AIX 5 supports IA64
+ library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}'
+ shlibpath_var=LD_LIBRARY_PATH
+ else
+ # With GCC up to 2.95.x, collect2 would create an import file
+ # for dependence libraries. The import file would start with
+ # the line `#! .'. This would cause the generated library to
+ # depend on `.', always an invalid library. This was fixed in
+ # development snapshots of GCC prior to 3.0.
+ case $host_os in
+ aix4 | aix4.[01] | aix4.[01].*)
+ if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)'
+ echo ' yes '
+ echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then
+ :
+ else
+ can_build_shared=no
+ fi
+ ;;
+ esac
+ # AIX (on Power*) has no versioning support, so currently we can not hardcode correct
+ # soname into executable. Probably we can add versioning support to
+ # collect2, so additional links can be useful in future.
+ if test "$aix_use_runtimelinking" = yes; then
+ # If using run time linking (on AIX 4.2 or later) use lib<name>.so
+ # instead of lib<name>.a to let people know that these are not
+ # typical AIX shared libraries.
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ else
+ # We preserve .a as extension for shared libraries through AIX4.2
+ # and later when we are not doing run time linking.
+ library_names_spec='${libname}${release}.a $libname.a'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ fi
+ shlibpath_var=LIBPATH
+ fi
+ ;;
+
+amigaos*)
+ case $host_cpu in
+ powerpc)
+ # Since July 2007 AmigaOS4 officially supports .so libraries.
+ # When compiling the executable, add -use-dynld -Lsobjs: to the compileline.
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ ;;
+ m68k)
+ library_names_spec='$libname.ixlibrary $libname.a'
+ # Create ${libname}_ixlibrary.a entries in /sys/libs.
+ finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$ECHO "X$lib" | $Xsed -e '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done'
+ ;;
+ esac
+ ;;
+
+beos*)
+ library_names_spec='${libname}${shared_ext}'
+ dynamic_linker="$host_os ld.so"
+ shlibpath_var=LIBRARY_PATH
+ ;;
+
+bsdi[45]*)
+ version_type=linux
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib"
+ sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib"
+ # the default ld.so.conf also contains /usr/contrib/lib and
+ # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow
+ # libtool to hard-code these into programs
+ ;;
+
+cygwin* | mingw* | pw32* | cegcc*)
+ version_type=windows
+ shrext_cmds=".dll"
+ need_version=no
+ need_lib_prefix=no
+
+ case $GCC,$host_os in
+ yes,cygwin* | yes,mingw* | yes,pw32* | yes,cegcc*)
+ library_names_spec='$libname.dll.a'
+ # DLL is installed to $(libdir)/../bin by postinstall_cmds
+ postinstall_cmds='base_file=`basename \${file}`~
+ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~
+ dldir=$destdir/`dirname \$dlpath`~
+ test -d \$dldir || mkdir -p \$dldir~
+ $install_prog $dir/$dlname \$dldir/$dlname~
+ chmod a+x \$dldir/$dlname~
+ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then
+ eval '\''$striplib \$dldir/$dlname'\'' || exit \$?;
+ fi'
+ postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
+ dlpath=$dir/\$dldll~
+ $RM \$dlpath'
+ shlibpath_overrides_runpath=yes
+
+ case $host_os in
+ cygwin*)
+ # Cygwin DLLs use 'cyg' prefix rather than 'lib'
+ soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+ sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib"
+ ;;
+ mingw* | cegcc*)
+ # MinGW DLLs use traditional 'lib' prefix
+ soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+ sys_lib_search_path_spec=`$CC -print-search-dirs | $GREP "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"`
+ if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then
+ # It is most probably a Windows format PATH printed by
+ # mingw gcc, but we are running on Cygwin. Gcc prints its search
+ # path with ; separators, and with drive letters. We can handle the
+ # drive letters (cygwin fileutils understands them), so leave them,
+ # especially as we might pass files found there to a mingw objdump,
+ # which wouldn't understand a cygwinified path. Ahh.
+ sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`
+ else
+ sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
+ fi
+ ;;
+ pw32*)
+ # pw32 DLLs use 'pw' prefix rather than 'lib'
+ library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+ ;;
+ esac
+ ;;
+
+ *)
+ library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib'
+ ;;
+ esac
+ dynamic_linker='Win32 ld.exe'
+ # FIXME: first we should search . and the directory the executable is in
+ shlibpath_var=PATH
+ ;;
+
+darwin* | rhapsody*)
+ dynamic_linker="$host_os dyld"
+ version_type=darwin
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext'
+ soname_spec='${libname}${release}${major}$shared_ext'
+ shlibpath_overrides_runpath=yes
+ shlibpath_var=DYLD_LIBRARY_PATH
+ shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`'
+
+ sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib"
+ sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib'
+ ;;
+
+dgux*)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ ;;
+
+freebsd1*)
+ dynamic_linker=no
+ ;;
+
+freebsd* | dragonfly*)
+ # DragonFly does not have aout. When/if they implement a new
+ # versioning mechanism, adjust this.
+ if test -x /usr/bin/objformat; then
+ objformat=`/usr/bin/objformat`
+ else
+ case $host_os in
+ freebsd[123]*) objformat=aout ;;
+ *) objformat=elf ;;
+ esac
+ fi
+ version_type=freebsd-$objformat
+ case $version_type in
+ freebsd-elf*)
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
+ need_version=no
+ need_lib_prefix=no
+ ;;
+ freebsd-*)
+ library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix'
+ need_version=yes
+ ;;
+ esac
+ shlibpath_var=LD_LIBRARY_PATH
+ case $host_os in
+ freebsd2*)
+ shlibpath_overrides_runpath=yes
+ ;;
+ freebsd3.[01]* | freebsdelf3.[01]*)
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ ;;
+ freebsd3.[2-9]* | freebsdelf3.[2-9]* | \
+ freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1)
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ ;;
+ *) # from 4.6 on, and DragonFly
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ ;;
+ esac
+ ;;
+
+gnu*)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ hardcode_into_libs=yes
+ ;;
+
+hpux9* | hpux10* | hpux11*)
+ # Give a soname corresponding to the major version so that dld.sl refuses to
+ # link against other versions.
+ version_type=sunos
+ need_lib_prefix=no
+ need_version=no
+ case $host_cpu in
+ ia64*)
+ shrext_cmds='.so'
+ hardcode_into_libs=yes
+ dynamic_linker="$host_os dld.so"
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ if test "X$HPUX_IA64_MODE" = X32; then
+ sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib"
+ else
+ sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64"
+ fi
+ sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+ ;;
+ hppa*64*)
+ shrext_cmds='.sl'
+ hardcode_into_libs=yes
+ dynamic_linker="$host_os dld.sl"
+ shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH
+ shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64"
+ sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+ ;;
+ *)
+ shrext_cmds='.sl'
+ dynamic_linker="$host_os dld.sl"
+ shlibpath_var=SHLIB_PATH
+ shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ ;;
+ esac
+ # HP-UX runs *really* slowly unless shared libraries are mode 555.
+ postinstall_cmds='chmod 555 $lib'
+ ;;
+
+interix[3-9]*)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ ;;
+
+irix5* | irix6* | nonstopux*)
+ case $host_os in
+ nonstopux*) version_type=nonstopux ;;
+ *)
+ if test "$lt_cv_prog_gnu_ld" = yes; then
+ version_type=linux
+ else
+ version_type=irix
+ fi ;;
+ esac
+ need_lib_prefix=no
+ need_version=no
+ soname_spec='${libname}${release}${shared_ext}$major'
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}'
+ case $host_os in
+ irix5* | nonstopux*)
+ libsuff= shlibsuff=
+ ;;
+ *)
+ case $LD in # libtool.m4 will add one of these switches to LD
+ *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ")
+ libsuff= shlibsuff= libmagic=32-bit;;
+ *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ")
+ libsuff=32 shlibsuff=N32 libmagic=N32;;
+ *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ")
+ libsuff=64 shlibsuff=64 libmagic=64-bit;;
+ *) libsuff= shlibsuff= libmagic=never-match;;
+ esac
+ ;;
+ esac
+ shlibpath_var=LD_LIBRARY${shlibsuff}_PATH
+ shlibpath_overrides_runpath=no
+ sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}"
+ sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}"
+ hardcode_into_libs=yes
+ ;;
+
+# No shared lib support for Linux oldld, aout, or coff.
+linux*oldld* | linux*aout* | linux*coff*)
+ dynamic_linker=no
+ ;;
+
+# This must be Linux ELF.
+linux* | k*bsd*-gnu | kopensolaris*-gnu)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ # Some binutils ld are patched to set DT_RUNPATH
+ save_LDFLAGS=$LDFLAGS
+ save_libdir=$libdir
+ eval "libdir=/foo; wl=\"$lt_prog_compiler_wl\"; \
+ LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec\""
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_link") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest$ac_exeext && {
+ test "$cross_compiling" = yes ||
+ $as_test_x conftest$ac_exeext
+ }; then
+ if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then
+ shlibpath_overrides_runpath=yes
+fi
+
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+fi
+
+rm -rf conftest.dSYM
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+ conftest$ac_exeext conftest.$ac_ext
+ LDFLAGS=$save_LDFLAGS
+ libdir=$save_libdir
+
+ # This implies no fast_install, which is unacceptable.
+ # Some rework will be needed to allow for fast_install
+ # before this can be enabled.
+ hardcode_into_libs=yes
+
+ # Append ld.so.conf contents to the search path
+ if test -f /etc/ld.so.conf; then
+ lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '`
+ sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra"
+ fi
+
+ # We used to test for /lib/ld.so.1 and disable shared libraries on
+ # powerpc, because MkLinux only supported shared libraries with the
+ # GNU dynamic linker. Since this was broken with cross compilers,
+ # most powerpc-linux boxes support dynamic linking these days and
+ # people can always --disable-shared, the test was removed, and we
+ # assume the GNU/Linux dynamic linker is in use.
+ dynamic_linker='GNU/Linux ld.so'
+ ;;
+
+netbsdelf*-gnu)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ dynamic_linker='NetBSD ld.elf_so'
+ ;;
+
+netbsd*)
+ version_type=sunos
+ need_lib_prefix=no
+ need_version=no
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+ dynamic_linker='NetBSD (a.out) ld.so'
+ else
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ dynamic_linker='NetBSD ld.elf_so'
+ fi
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ ;;
+
+newsos6)
+ version_type=linux
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ ;;
+
+*nto* | *qnx*)
+ version_type=qnx
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ dynamic_linker='ldqnx.so'
+ ;;
+
+openbsd*)
+ version_type=sunos
+ sys_lib_dlsearch_path_spec="/usr/lib"
+ need_lib_prefix=no
+ # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs.
+ case $host_os in
+ openbsd3.3 | openbsd3.3.*) need_version=yes ;;
+ *) need_version=no ;;
+ esac
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+ case $host_os in
+ openbsd2.[89] | openbsd2.[89].*)
+ shlibpath_overrides_runpath=no
+ ;;
+ *)
+ shlibpath_overrides_runpath=yes
+ ;;
+ esac
+ else
+ shlibpath_overrides_runpath=yes
+ fi
+ ;;
+
+os2*)
+ libname_spec='$name'
+ shrext_cmds=".dll"
+ need_lib_prefix=no
+ library_names_spec='$libname${shared_ext} $libname.a'
+ dynamic_linker='OS/2 ld.exe'
+ shlibpath_var=LIBPATH
+ ;;
+
+osf3* | osf4* | osf5*)
+ version_type=osf
+ need_lib_prefix=no
+ need_version=no
+ soname_spec='${libname}${release}${shared_ext}$major'
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ shlibpath_var=LD_LIBRARY_PATH
+ sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib"
+ sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec"
+ ;;
+
+rdos*)
+ dynamic_linker=no
+ ;;
+
+solaris*)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ # ldd complains unless libraries are executable
+ postinstall_cmds='chmod +x $lib'
+ ;;
+
+sunos4*)
+ version_type=sunos
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+ finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ if test "$with_gnu_ld" = yes; then
+ need_lib_prefix=no
+ fi
+ need_version=yes
+ ;;
+
+sysv4 | sysv4.3*)
+ version_type=linux
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ case $host_vendor in
+ sni)
+ shlibpath_overrides_runpath=no
+ need_lib_prefix=no
+ runpath_var=LD_RUN_PATH
+ ;;
+ siemens)
+ need_lib_prefix=no
+ ;;
+ motorola)
+ need_lib_prefix=no
+ need_version=no
+ shlibpath_overrides_runpath=no
+ sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib'
+ ;;
+ esac
+ ;;
+
+sysv4*MP*)
+ if test -d /usr/nec ;then
+ version_type=linux
+ library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}'
+ soname_spec='$libname${shared_ext}.$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ fi
+ ;;
+
+sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+ version_type=freebsd-elf
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ if test "$with_gnu_ld" = yes; then
+ sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib'
+ else
+ sys_lib_search_path_spec='/usr/ccs/lib /usr/lib'
+ case $host_os in
+ sco3.2v5*)
+ sys_lib_search_path_spec="$sys_lib_search_path_spec /lib"
+ ;;
+ esac
+ fi
+ sys_lib_dlsearch_path_spec='/usr/lib'
+ ;;
+
+tpf*)
+ # TPF is a cross-target only. Preferred cross-host = GNU/Linux.
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ ;;
+
+uts4*)
+ version_type=linux
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ ;;
+
+*)
+ dynamic_linker=no
+ ;;
+esac
+{ $as_echo "$as_me:$LINENO: result: $dynamic_linker" >&5
+$as_echo "$dynamic_linker" >&6; }
+test "$dynamic_linker" = no && can_build_shared=no
+
+variables_saved_for_relink="PATH $shlibpath_var $runpath_var"
+if test "$GCC" = yes; then
+ variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH"
+fi
+
+if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then
+ sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec"
+fi
+if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then
+ sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec"
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ { $as_echo "$as_me:$LINENO: checking how to hardcode library paths into programs" >&5
+$as_echo_n "checking how to hardcode library paths into programs... " >&6; }
+hardcode_action=
+if test -n "$hardcode_libdir_flag_spec" ||
+ test -n "$runpath_var" ||
+ test "X$hardcode_automatic" = "Xyes" ; then
+
+ # We can hardcode non-existent directories.
+ if test "$hardcode_direct" != no &&
+ # If the only mechanism to avoid hardcoding is shlibpath_var, we
+ # have to relink, otherwise we might link with an installed library
+ # when we should be linking with a yet-to-be-installed one
+ ## test "$_LT_TAGVAR(hardcode_shlibpath_var, )" != no &&
+ test "$hardcode_minus_L" != no; then
+ # Linking always hardcodes the temporary library directory.
+ hardcode_action=relink
+ else
+ # We can link without hardcoding, and we can hardcode nonexisting dirs.
+ hardcode_action=immediate
+ fi
+else
+ # We cannot hardcode anything, or else we can only hardcode existing
+ # directories.
+ hardcode_action=unsupported
+fi
+{ $as_echo "$as_me:$LINENO: result: $hardcode_action" >&5
+$as_echo "$hardcode_action" >&6; }
+
+if test "$hardcode_action" = relink ||
+ test "$inherit_rpath" = yes; then
+ # Fast installation is not supported
+ enable_fast_install=no
+elif test "$shlibpath_overrides_runpath" = yes ||
+ test "$enable_shared" = no; then
+ # Fast installation is not necessary
+ enable_fast_install=needless
+fi
+
+
+
+
+
+
+ if test "x$enable_dlopen" != xyes; then
+ enable_dlopen=unknown
+ enable_dlopen_self=unknown
+ enable_dlopen_self_static=unknown
+else
+ lt_cv_dlopen=no
+ lt_cv_dlopen_libs=
+
+ case $host_os in
+ beos*)
+ lt_cv_dlopen="load_add_on"
+ lt_cv_dlopen_libs=
+ lt_cv_dlopen_self=yes
+ ;;
+
+ mingw* | pw32* | cegcc*)
+ lt_cv_dlopen="LoadLibrary"
+ lt_cv_dlopen_libs=
+ ;;
+
+ cygwin*)
+ lt_cv_dlopen="dlopen"
+ lt_cv_dlopen_libs=
+ ;;
+
+ darwin*)
+ # if libdl is installed we need to link against it
+ { $as_echo "$as_me:$LINENO: checking for dlopen in -ldl" >&5
+$as_echo_n "checking for dlopen in -ldl... " >&6; }
+if test "${ac_cv_lib_dl_dlopen+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldl $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dlopen ();
+int
+main ()
+{
+return dlopen ();
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_link") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest$ac_exeext && {
+ test "$cross_compiling" = yes ||
+ $as_test_x conftest$ac_exeext
+ }; then
+ ac_cv_lib_dl_dlopen=yes
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_cv_lib_dl_dlopen=no
+fi
+
+rm -rf conftest.dSYM
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:$LINENO: result: $ac_cv_lib_dl_dlopen" >&5
+$as_echo "$ac_cv_lib_dl_dlopen" >&6; }
+if test $ac_cv_lib_dl_dlopen = yes; then
+ lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"
+else
+
+ lt_cv_dlopen="dyld"
+ lt_cv_dlopen_libs=
+ lt_cv_dlopen_self=yes
+
+fi
+
+ ;;
+
+ *)
+ { $as_echo "$as_me:$LINENO: checking for shl_load" >&5
+$as_echo_n "checking for shl_load... " >&6; }
+if test "${ac_cv_func_shl_load+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+/* Define shl_load to an innocuous variant, in case <limits.h> declares shl_load.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define shl_load innocuous_shl_load
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char shl_load (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef shl_load
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char shl_load ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined __stub_shl_load || defined __stub___shl_load
+choke me
+#endif
+
+int
+main ()
+{
+return shl_load ();
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_link") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest$ac_exeext && {
+ test "$cross_compiling" = yes ||
+ $as_test_x conftest$ac_exeext
+ }; then
+ ac_cv_func_shl_load=yes
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_cv_func_shl_load=no
+fi
+
+rm -rf conftest.dSYM
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:$LINENO: result: $ac_cv_func_shl_load" >&5
+$as_echo "$ac_cv_func_shl_load" >&6; }
+if test $ac_cv_func_shl_load = yes; then
+ lt_cv_dlopen="shl_load"
+else
+ { $as_echo "$as_me:$LINENO: checking for shl_load in -ldld" >&5
+$as_echo_n "checking for shl_load in -ldld... " >&6; }
+if test "${ac_cv_lib_dld_shl_load+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldld $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char shl_load ();
+int
+main ()
+{
+return shl_load ();
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_link") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest$ac_exeext && {
+ test "$cross_compiling" = yes ||
+ $as_test_x conftest$ac_exeext
+ }; then
+ ac_cv_lib_dld_shl_load=yes
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_cv_lib_dld_shl_load=no
+fi
+
+rm -rf conftest.dSYM
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:$LINENO: result: $ac_cv_lib_dld_shl_load" >&5
+$as_echo "$ac_cv_lib_dld_shl_load" >&6; }
+if test $ac_cv_lib_dld_shl_load = yes; then
+ lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld"
+else
+ { $as_echo "$as_me:$LINENO: checking for dlopen" >&5
+$as_echo_n "checking for dlopen... " >&6; }
+if test "${ac_cv_func_dlopen+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+/* Define dlopen to an innocuous variant, in case <limits.h> declares dlopen.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define dlopen innocuous_dlopen
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char dlopen (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef dlopen
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dlopen ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined __stub_dlopen || defined __stub___dlopen
+choke me
+#endif
+
+int
+main ()
+{
+return dlopen ();
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_link") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest$ac_exeext && {
+ test "$cross_compiling" = yes ||
+ $as_test_x conftest$ac_exeext
+ }; then
+ ac_cv_func_dlopen=yes
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_cv_func_dlopen=no
+fi
+
+rm -rf conftest.dSYM
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:$LINENO: result: $ac_cv_func_dlopen" >&5
+$as_echo "$ac_cv_func_dlopen" >&6; }
+if test $ac_cv_func_dlopen = yes; then
+ lt_cv_dlopen="dlopen"
+else
+ { $as_echo "$as_me:$LINENO: checking for dlopen in -ldl" >&5
+$as_echo_n "checking for dlopen in -ldl... " >&6; }
+if test "${ac_cv_lib_dl_dlopen+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldl $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dlopen ();
+int
+main ()
+{
+return dlopen ();
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_link") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest$ac_exeext && {
+ test "$cross_compiling" = yes ||
+ $as_test_x conftest$ac_exeext
+ }; then
+ ac_cv_lib_dl_dlopen=yes
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_cv_lib_dl_dlopen=no
+fi
+
+rm -rf conftest.dSYM
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:$LINENO: result: $ac_cv_lib_dl_dlopen" >&5
+$as_echo "$ac_cv_lib_dl_dlopen" >&6; }
+if test $ac_cv_lib_dl_dlopen = yes; then
+ lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"
+else
+ { $as_echo "$as_me:$LINENO: checking for dlopen in -lsvld" >&5
+$as_echo_n "checking for dlopen in -lsvld... " >&6; }
+if test "${ac_cv_lib_svld_dlopen+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lsvld $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dlopen ();
+int
+main ()
+{
+return dlopen ();
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_link") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest$ac_exeext && {
+ test "$cross_compiling" = yes ||
+ $as_test_x conftest$ac_exeext
+ }; then
+ ac_cv_lib_svld_dlopen=yes
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_cv_lib_svld_dlopen=no
+fi
+
+rm -rf conftest.dSYM
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:$LINENO: result: $ac_cv_lib_svld_dlopen" >&5
+$as_echo "$ac_cv_lib_svld_dlopen" >&6; }
+if test $ac_cv_lib_svld_dlopen = yes; then
+ lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"
+else
+ { $as_echo "$as_me:$LINENO: checking for dld_link in -ldld" >&5
+$as_echo_n "checking for dld_link in -ldld... " >&6; }
+if test "${ac_cv_lib_dld_dld_link+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldld $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dld_link ();
+int
+main ()
+{
+return dld_link ();
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_link") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest$ac_exeext && {
+ test "$cross_compiling" = yes ||
+ $as_test_x conftest$ac_exeext
+ }; then
+ ac_cv_lib_dld_dld_link=yes
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_cv_lib_dld_dld_link=no
+fi
+
+rm -rf conftest.dSYM
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:$LINENO: result: $ac_cv_lib_dld_dld_link" >&5
+$as_echo "$ac_cv_lib_dld_dld_link" >&6; }
+if test $ac_cv_lib_dld_dld_link = yes; then
+ lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld"
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+ ;;
+ esac
+
+ if test "x$lt_cv_dlopen" != xno; then
+ enable_dlopen=yes
+ else
+ enable_dlopen=no
+ fi
+
+ case $lt_cv_dlopen in
+ dlopen)
+ save_CPPFLAGS="$CPPFLAGS"
+ test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H"
+
+ save_LDFLAGS="$LDFLAGS"
+ wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\"
+
+ save_LIBS="$LIBS"
+ LIBS="$lt_cv_dlopen_libs $LIBS"
+
+ { $as_echo "$as_me:$LINENO: checking whether a program can dlopen itself" >&5
+$as_echo_n "checking whether a program can dlopen itself... " >&6; }
+if test "${lt_cv_dlopen_self+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ if test "$cross_compiling" = yes; then :
+ lt_cv_dlopen_self=cross
+else
+ lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
+ lt_status=$lt_dlunknown
+ cat > conftest.$ac_ext <<_LT_EOF
+#line 12089 "configure"
+#include "confdefs.h"
+
+#if HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
+#include <stdio.h>
+
+#ifdef RTLD_GLOBAL
+# define LT_DLGLOBAL RTLD_GLOBAL
+#else
+# ifdef DL_GLOBAL
+# define LT_DLGLOBAL DL_GLOBAL
+# else
+# define LT_DLGLOBAL 0
+# endif
+#endif
+
+/* We may have to define LT_DLLAZY_OR_NOW in the command line if we
+ find out it does not work in some platform. */
+#ifndef LT_DLLAZY_OR_NOW
+# ifdef RTLD_LAZY
+# define LT_DLLAZY_OR_NOW RTLD_LAZY
+# else
+# ifdef DL_LAZY
+# define LT_DLLAZY_OR_NOW DL_LAZY
+# else
+# ifdef RTLD_NOW
+# define LT_DLLAZY_OR_NOW RTLD_NOW
+# else
+# ifdef DL_NOW
+# define LT_DLLAZY_OR_NOW DL_NOW
+# else
+# define LT_DLLAZY_OR_NOW 0
+# endif
+# endif
+# endif
+# endif
+#endif
+
+void fnord() { int i=42;}
+int main ()
+{
+ void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
+ int status = $lt_dlunknown;
+
+ if (self)
+ {
+ if (dlsym (self,"fnord")) status = $lt_dlno_uscore;
+ else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore;
+ /* dlclose (self); */
+ }
+ else
+ puts (dlerror ());
+
+ return status;
+}
+_LT_EOF
+ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && test -s conftest${ac_exeext} 2>/dev/null; then
+ (./conftest; exit; ) >&5 2>/dev/null
+ lt_status=$?
+ case x$lt_status in
+ x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;;
+ x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;;
+ x$lt_dlunknown|x*) lt_cv_dlopen_self=no ;;
+ esac
+ else :
+ # compilation failed
+ lt_cv_dlopen_self=no
+ fi
+fi
+rm -fr conftest*
+
+
+fi
+{ $as_echo "$as_me:$LINENO: result: $lt_cv_dlopen_self" >&5
+$as_echo "$lt_cv_dlopen_self" >&6; }
+
+ if test "x$lt_cv_dlopen_self" = xyes; then
+ wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\"
+ { $as_echo "$as_me:$LINENO: checking whether a statically linked program can dlopen itself" >&5
+$as_echo_n "checking whether a statically linked program can dlopen itself... " >&6; }
+if test "${lt_cv_dlopen_self_static+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ if test "$cross_compiling" = yes; then :
+ lt_cv_dlopen_self_static=cross
+else
+ lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
+ lt_status=$lt_dlunknown
+ cat > conftest.$ac_ext <<_LT_EOF
+#line 12185 "configure"
+#include "confdefs.h"
+
+#if HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
+#include <stdio.h>
+
+#ifdef RTLD_GLOBAL
+# define LT_DLGLOBAL RTLD_GLOBAL
+#else
+# ifdef DL_GLOBAL
+# define LT_DLGLOBAL DL_GLOBAL
+# else
+# define LT_DLGLOBAL 0
+# endif
+#endif
+
+/* We may have to define LT_DLLAZY_OR_NOW in the command line if we
+ find out it does not work in some platform. */
+#ifndef LT_DLLAZY_OR_NOW
+# ifdef RTLD_LAZY
+# define LT_DLLAZY_OR_NOW RTLD_LAZY
+# else
+# ifdef DL_LAZY
+# define LT_DLLAZY_OR_NOW DL_LAZY
+# else
+# ifdef RTLD_NOW
+# define LT_DLLAZY_OR_NOW RTLD_NOW
+# else
+# ifdef DL_NOW
+# define LT_DLLAZY_OR_NOW DL_NOW
+# else
+# define LT_DLLAZY_OR_NOW 0
+# endif
+# endif
+# endif
+# endif
+#endif
+
+void fnord() { int i=42;}
+int main ()
+{
+ void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
+ int status = $lt_dlunknown;
+
+ if (self)
+ {
+ if (dlsym (self,"fnord")) status = $lt_dlno_uscore;
+ else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore;
+ /* dlclose (self); */
+ }
+ else
+ puts (dlerror ());
+
+ return status;
+}
+_LT_EOF
+ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && test -s conftest${ac_exeext} 2>/dev/null; then
+ (./conftest; exit; ) >&5 2>/dev/null
+ lt_status=$?
+ case x$lt_status in
+ x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;;
+ x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;;
+ x$lt_dlunknown|x*) lt_cv_dlopen_self_static=no ;;
+ esac
+ else :
+ # compilation failed
+ lt_cv_dlopen_self_static=no
+ fi
+fi
+rm -fr conftest*
+
+
+fi
+{ $as_echo "$as_me:$LINENO: result: $lt_cv_dlopen_self_static" >&5
+$as_echo "$lt_cv_dlopen_self_static" >&6; }
+ fi
+
+ CPPFLAGS="$save_CPPFLAGS"
+ LDFLAGS="$save_LDFLAGS"
+ LIBS="$save_LIBS"
+ ;;
+ esac
+
+ case $lt_cv_dlopen_self in
+ yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;;
+ *) enable_dlopen_self=unknown ;;
+ esac
+
+ case $lt_cv_dlopen_self_static in
+ yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;;
+ *) enable_dlopen_self_static=unknown ;;
+ esac
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+striplib=
+old_striplib=
+{ $as_echo "$as_me:$LINENO: checking whether stripping libraries is possible" >&5
+$as_echo_n "checking whether stripping libraries is possible... " >&6; }
+if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then
+ test -z "$old_striplib" && old_striplib="$STRIP --strip-debug"
+ test -z "$striplib" && striplib="$STRIP --strip-unneeded"
+ { $as_echo "$as_me:$LINENO: result: yes" >&5
+$as_echo "yes" >&6; }
+else
+# FIXME - insert some real tests, host_os isn't really good enough
+ case $host_os in
+ darwin*)
+ if test -n "$STRIP" ; then
+ striplib="$STRIP -x"
+ old_striplib="$STRIP -S"
+ { $as_echo "$as_me:$LINENO: result: yes" >&5
+$as_echo "yes" >&6; }
+ else
+ { $as_echo "$as_me:$LINENO: result: no" >&5
+$as_echo "no" >&6; }
+ fi
+ ;;
+ *)
+ { $as_echo "$as_me:$LINENO: result: no" >&5
+$as_echo "no" >&6; }
+ ;;
+ esac
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+ # Report which library types will actually be built
+ { $as_echo "$as_me:$LINENO: checking if libtool supports shared libraries" >&5
+$as_echo_n "checking if libtool supports shared libraries... " >&6; }
+ { $as_echo "$as_me:$LINENO: result: $can_build_shared" >&5
+$as_echo "$can_build_shared" >&6; }
+
+ { $as_echo "$as_me:$LINENO: checking whether to build shared libraries" >&5
+$as_echo_n "checking whether to build shared libraries... " >&6; }
+ test "$can_build_shared" = "no" && enable_shared=no
+
+ # On AIX, shared libraries and static libraries use the same namespace, and
+ # are all built from PIC.
+ case $host_os in
+ aix3*)
+ test "$enable_shared" = yes && enable_static=no
+ if test -n "$RANLIB"; then
+ archive_cmds="$archive_cmds~\$RANLIB \$lib"
+ postinstall_cmds='$RANLIB $lib'
+ fi
+ ;;
+
+ aix[4-9]*)
+ if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then
+ test "$enable_shared" = yes && enable_static=no
+ fi
+ ;;
+ esac
+ { $as_echo "$as_me:$LINENO: result: $enable_shared" >&5
+$as_echo "$enable_shared" >&6; }
+
+ { $as_echo "$as_me:$LINENO: checking whether to build static libraries" >&5
+$as_echo_n "checking whether to build static libraries... " >&6; }
+ # Make sure either enable_shared or enable_static is yes.
+ test "$enable_shared" = yes || enable_static=yes
+ { $as_echo "$as_me:$LINENO: result: $enable_static" >&5
+$as_echo "$enable_static" >&6; }
+
+
+
+
+fi
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+CC="$lt_save_CC"
+
+
+ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+archive_cmds_need_lc_CXX=no
+allow_undefined_flag_CXX=
+always_export_symbols_CXX=no
+archive_expsym_cmds_CXX=
+compiler_needs_object_CXX=no
+export_dynamic_flag_spec_CXX=
+hardcode_direct_CXX=no
+hardcode_direct_absolute_CXX=no
+hardcode_libdir_flag_spec_CXX=
+hardcode_libdir_flag_spec_ld_CXX=
+hardcode_libdir_separator_CXX=
+hardcode_minus_L_CXX=no
+hardcode_shlibpath_var_CXX=unsupported
+hardcode_automatic_CXX=no
+inherit_rpath_CXX=no
+module_cmds_CXX=
+module_expsym_cmds_CXX=
+link_all_deplibs_CXX=unknown
+old_archive_cmds_CXX=$old_archive_cmds
+no_undefined_flag_CXX=
+whole_archive_flag_spec_CXX=
+enable_shared_with_static_runtimes_CXX=no
+
+# Source file extension for C++ test sources.
+ac_ext=cpp
+
+# Object file extension for compiled C++ test sources.
+objext=o
+objext_CXX=$objext
+
+# No sense in running all these tests if we already determined that
+# the CXX compiler isn't working. Some variables (like enable_shared)
+# are currently assumed to apply to all compilers on this platform,
+# and will be corrupted by setting them based on a non-working compiler.
+if test "$_lt_caught_CXX_error" != yes; then
+ # Code to be used in simple compile tests
+ lt_simple_compile_test_code="int some_variable = 0;"
+
+ # Code to be used in simple link tests
+ lt_simple_link_test_code='int main(int, char *[]) { return(0); }'
+
+ # ltmain only uses $CC for tagged configurations so make sure $CC is set.
+
+
+
+
+
+
+# If no C compiler was specified, use CC.
+LTCC=${LTCC-"$CC"}
+
+# If no C compiler flags were specified, use CFLAGS.
+LTCFLAGS=${LTCFLAGS-"$CFLAGS"}
+
+# Allow CC to be a program name with arguments.
+compiler=$CC
+
+
+ # save warnings/boilerplate of simple test code
+ ac_outfile=conftest.$ac_objext
+echo "$lt_simple_compile_test_code" >conftest.$ac_ext
+eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_compiler_boilerplate=`cat conftest.err`
+$RM conftest*
+
+ ac_outfile=conftest.$ac_objext
+echo "$lt_simple_link_test_code" >conftest.$ac_ext
+eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_linker_boilerplate=`cat conftest.err`
+$RM -r conftest*
+
+
+ # Allow CC to be a program name with arguments.
+ lt_save_CC=$CC
+ lt_save_LD=$LD
+ lt_save_GCC=$GCC
+ GCC=$GXX
+ lt_save_with_gnu_ld=$with_gnu_ld
+ lt_save_path_LD=$lt_cv_path_LD
+ if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then
+ lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx
+ else
+ $as_unset lt_cv_prog_gnu_ld
+ fi
+ if test -n "${lt_cv_path_LDCXX+set}"; then
+ lt_cv_path_LD=$lt_cv_path_LDCXX
+ else
+ $as_unset lt_cv_path_LD
+ fi
+ test -z "${LDCXX+set}" || LD=$LDCXX
+ CC=${CXX-"c++"}
+ compiler=$CC
+ compiler_CXX=$CC
+ for cc_temp in $compiler""; do
+ case $cc_temp in
+ compile | *[\\/]compile | ccache | *[\\/]ccache ) ;;
+ distcc | *[\\/]distcc | purify | *[\\/]purify ) ;;
+ \-*) ;;
+ *) break;;
+ esac
+done
+cc_basename=`$ECHO "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"`
+
+
+ if test -n "$compiler"; then
+ # We don't want -fno-exception when compiling C++ code, so set the
+ # no_builtin_flag separately
+ if test "$GXX" = yes; then
+ lt_prog_compiler_no_builtin_flag_CXX=' -fno-builtin'
+ else
+ lt_prog_compiler_no_builtin_flag_CXX=
+ fi
+
+ if test "$GXX" = yes; then
+ # Set up default GNU C++ configuration
+
+
+
+# Check whether --with-gnu-ld was given.
+if test "${with_gnu_ld+set}" = set; then
+ withval=$with_gnu_ld; test "$withval" = no || with_gnu_ld=yes
+else
+ with_gnu_ld=no
+fi
+
+ac_prog=ld
+if test "$GCC" = yes; then
+ # Check if gcc -print-prog-name=ld gives a path.
+ { $as_echo "$as_me:$LINENO: checking for ld used by $CC" >&5
+$as_echo_n "checking for ld used by $CC... " >&6; }
+ case $host in
+ *-*-mingw*)
+ # gcc leaves a trailing carriage return which upsets mingw
+ ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
+ *)
+ ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;
+ esac
+ case $ac_prog in
+ # Accept absolute paths.
+ [\\/]* | ?:[\\/]*)
+ re_direlt='/[^/][^/]*/\.\./'
+ # Canonicalize the pathname of ld
+ ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'`
+ while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do
+ ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"`
+ done
+ test -z "$LD" && LD="$ac_prog"
+ ;;
+ "")
+ # If it fails, then pretend we aren't using GCC.
+ ac_prog=ld
+ ;;
+ *)
+ # If it is relative, then search for the first ld in PATH.
+ with_gnu_ld=unknown
+ ;;
+ esac
+elif test "$with_gnu_ld" = yes; then
+ { $as_echo "$as_me:$LINENO: checking for GNU ld" >&5
+$as_echo_n "checking for GNU ld... " >&6; }
+else
+ { $as_echo "$as_me:$LINENO: checking for non-GNU ld" >&5
+$as_echo_n "checking for non-GNU ld... " >&6; }
+fi
+if test "${lt_cv_path_LD+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ if test -z "$LD"; then
+ lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+ for ac_dir in $PATH; do
+ IFS="$lt_save_ifs"
+ test -z "$ac_dir" && ac_dir=.
+ if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
+ lt_cv_path_LD="$ac_dir/$ac_prog"
+ # Check to see if the program is GNU ld. I'd rather use --version,
+ # but apparently some variants of GNU ld only accept -v.
+ # Break only if it was the GNU/non-GNU ld that we prefer.
+ case `"$lt_cv_path_LD" -v 2>&1 </dev/null` in
+ *GNU* | *'with BFD'*)
+ test "$with_gnu_ld" != no && break
+ ;;
+ *)
+ test "$with_gnu_ld" != yes && break
+ ;;
+ esac
+ fi
+ done
+ IFS="$lt_save_ifs"
+else
+ lt_cv_path_LD="$LD" # Let the user override the test with a path.
+fi
+fi
+
+LD="$lt_cv_path_LD"
+if test -n "$LD"; then
+ { $as_echo "$as_me:$LINENO: result: $LD" >&5
+$as_echo "$LD" >&6; }
+else
+ { $as_echo "$as_me:$LINENO: result: no" >&5
+$as_echo "no" >&6; }
+fi
+test -z "$LD" && { { $as_echo "$as_me:$LINENO: error: no acceptable ld found in \$PATH" >&5
+$as_echo "$as_me: error: no acceptable ld found in \$PATH" >&2;}
+ { (exit 1); exit 1; }; }
+{ $as_echo "$as_me:$LINENO: checking if the linker ($LD) is GNU ld" >&5
+$as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; }
+if test "${lt_cv_prog_gnu_ld+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ # I'd rather use --version here, but apparently some GNU lds only accept -v.
+case `$LD -v 2>&1 </dev/null` in
+*GNU* | *'with BFD'*)
+ lt_cv_prog_gnu_ld=yes
+ ;;
+*)
+ lt_cv_prog_gnu_ld=no
+ ;;
+esac
+fi
+{ $as_echo "$as_me:$LINENO: result: $lt_cv_prog_gnu_ld" >&5
+$as_echo "$lt_cv_prog_gnu_ld" >&6; }
+with_gnu_ld=$lt_cv_prog_gnu_ld
+
+
+
+
+
+
+
+ # Check if GNU C++ uses GNU ld as the underlying linker, since the
+ # archiving commands below assume that GNU ld is being used.
+ if test "$with_gnu_ld" = yes; then
+ archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ archive_expsym_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+
+ hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir'
+ export_dynamic_flag_spec_CXX='${wl}--export-dynamic'
+
+ # If archive_cmds runs LD, not CC, wlarc should be empty
+ # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to
+ # investigate it a little bit more. (MM)
+ wlarc='${wl}'
+
+ # ancient GNU ld didn't support --whole-archive et. al.
+ if eval "`$CC -print-prog-name=ld` --help 2>&1" |
+ $GREP 'no-whole-archive' > /dev/null; then
+ whole_archive_flag_spec_CXX="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+ else
+ whole_archive_flag_spec_CXX=
+ fi
+ else
+ with_gnu_ld=no
+ wlarc=
+
+ # A generic and very simple default shared library creation
+ # command for GNU C++ for the case where it uses the native
+ # linker, instead of GNU ld. If possible, this setting should
+ # overridden to take advantage of the native linker features on
+ # the platform it is being used on.
+ archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib'
+ fi
+
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "\-L"'
+
+ else
+ GXX=no
+ with_gnu_ld=no
+ wlarc=
+ fi
+
+ # PORTME: fill in a description of your system's C++ link characteristics
+ { $as_echo "$as_me:$LINENO: checking whether the $compiler linker ($LD) supports shared libraries" >&5
+$as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; }
+ ld_shlibs_CXX=yes
+ case $host_os in
+ aix3*)
+ # FIXME: insert proper C++ library support
+ ld_shlibs_CXX=no
+ ;;
+ aix[4-9]*)
+ if test "$host_cpu" = ia64; then
+ # On IA64, the linker does run time linking by default, so we don't
+ # have to do anything special.
+ aix_use_runtimelinking=no
+ exp_sym_flag='-Bexport'
+ no_entry_flag=""
+ else
+ aix_use_runtimelinking=no
+
+ # Test if we are trying to use run time linking or normal
+ # AIX style linking. If -brtl is somewhere in LDFLAGS, we
+ # need to do runtime linking.
+ case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*)
+ for ld_flag in $LDFLAGS; do
+ case $ld_flag in
+ *-brtl*)
+ aix_use_runtimelinking=yes
+ break
+ ;;
+ esac
+ done
+ ;;
+ esac
+
+ exp_sym_flag='-bexport'
+ no_entry_flag='-bnoentry'
+ fi
+
+ # When large executables or shared objects are built, AIX ld can
+ # have problems creating the table of contents. If linking a library
+ # or program results in "error TOC overflow" add -mminimal-toc to
+ # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not
+ # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.
+
+ archive_cmds_CXX=''
+ hardcode_direct_CXX=yes
+ hardcode_direct_absolute_CXX=yes
+ hardcode_libdir_separator_CXX=':'
+ link_all_deplibs_CXX=yes
+ file_list_spec_CXX='${wl}-f,'
+
+ if test "$GXX" = yes; then
+ case $host_os in aix4.[012]|aix4.[012].*)
+ # We only want to do this on AIX 4.2 and lower, the check
+ # below for broken collect2 doesn't work under 4.3+
+ collect2name=`${CC} -print-prog-name=collect2`
+ if test -f "$collect2name" &&
+ strings "$collect2name" | $GREP resolve_lib_name >/dev/null
+ then
+ # We have reworked collect2
+ :
+ else
+ # We have old collect2
+ hardcode_direct_CXX=unsupported
+ # It fails to find uninstalled libraries when the uninstalled
+ # path is not listed in the libpath. Setting hardcode_minus_L
+ # to unsupported forces relinking
+ hardcode_minus_L_CXX=yes
+ hardcode_libdir_flag_spec_CXX='-L$libdir'
+ hardcode_libdir_separator_CXX=
+ fi
+ esac
+ shared_flag='-shared'
+ if test "$aix_use_runtimelinking" = yes; then
+ shared_flag="$shared_flag "'${wl}-G'
+ fi
+ else
+ # not using gcc
+ if test "$host_cpu" = ia64; then
+ # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
+ # chokes on -Wl,-G. The following line is correct:
+ shared_flag='-G'
+ else
+ if test "$aix_use_runtimelinking" = yes; then
+ shared_flag='${wl}-G'
+ else
+ shared_flag='${wl}-bM:SRE'
+ fi
+ fi
+ fi
+
+ export_dynamic_flag_spec_CXX='${wl}-bexpall'
+ # It seems that -bexpall does not export symbols beginning with
+ # underscore (_), so it is better to generate a list of symbols to
+ # export.
+ always_export_symbols_CXX=yes
+ if test "$aix_use_runtimelinking" = yes; then
+ # Warning - without using the other runtime loading flags (-brtl),
+ # -berok will link without error, but may produce a broken library.
+ allow_undefined_flag_CXX='-berok'
+ # Determine the default libpath from the value encoded in an empty
+ # executable.
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_link") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_cxx_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest$ac_exeext && {
+ test "$cross_compiling" = yes ||
+ $as_test_x conftest$ac_exeext
+ }; then
+
+lt_aix_libpath_sed='
+ /Import File Strings/,/^$/ {
+ /^0/ {
+ s/^0 *\(.*\)$/\1/
+ p
+ }
+ }'
+aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+# Check for a 64-bit object if we didn't find anything.
+if test -z "$aix_libpath"; then
+ aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+fi
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+fi
+
+rm -rf conftest.dSYM
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+ conftest$ac_exeext conftest.$ac_ext
+if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
+
+ hardcode_libdir_flag_spec_CXX='${wl}-blibpath:$libdir:'"$aix_libpath"
+
+ archive_expsym_cmds_CXX='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then $ECHO "X${wl}${allow_undefined_flag}" | $Xsed; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag"
+ else
+ if test "$host_cpu" = ia64; then
+ hardcode_libdir_flag_spec_CXX='${wl}-R $libdir:/usr/lib:/lib'
+ allow_undefined_flag_CXX="-z nodefs"
+ archive_expsym_cmds_CXX="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols"
+ else
+ # Determine the default libpath from the value encoded in an
+ # empty executable.
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_link") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_cxx_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest$ac_exeext && {
+ test "$cross_compiling" = yes ||
+ $as_test_x conftest$ac_exeext
+ }; then
+
+lt_aix_libpath_sed='
+ /Import File Strings/,/^$/ {
+ /^0/ {
+ s/^0 *\(.*\)$/\1/
+ p
+ }
+ }'
+aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+# Check for a 64-bit object if we didn't find anything.
+if test -z "$aix_libpath"; then
+ aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+fi
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+fi
+
+rm -rf conftest.dSYM
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+ conftest$ac_exeext conftest.$ac_ext
+if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
+
+ hardcode_libdir_flag_spec_CXX='${wl}-blibpath:$libdir:'"$aix_libpath"
+ # Warning - without using the other run time loading flags,
+ # -berok will link without error, but may produce a broken library.
+ no_undefined_flag_CXX=' ${wl}-bernotok'
+ allow_undefined_flag_CXX=' ${wl}-berok'
+ # Exported symbols can be pulled into shared objects from archives
+ whole_archive_flag_spec_CXX='$convenience'
+ archive_cmds_need_lc_CXX=yes
+ # This is similar to how AIX traditionally builds its shared
+ # libraries.
+ archive_expsym_cmds_CXX="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
+ fi
+ fi
+ ;;
+
+ beos*)
+ if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ allow_undefined_flag_CXX=unsupported
+ # Joseph Beckenbach <jrb3@best.com> says some releases of gcc
+ # support --undefined. This deserves some investigation. FIXME
+ archive_cmds_CXX='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ else
+ ld_shlibs_CXX=no
+ fi
+ ;;
+
+ chorus*)
+ case $cc_basename in
+ *)
+ # FIXME: insert proper C++ library support
+ ld_shlibs_CXX=no
+ ;;
+ esac
+ ;;
+
+ cygwin* | mingw* | pw32* | cegcc*)
+ # _LT_TAGVAR(hardcode_libdir_flag_spec, CXX) is actually meaningless,
+ # as there is no search path for DLLs.
+ hardcode_libdir_flag_spec_CXX='-L$libdir'
+ allow_undefined_flag_CXX=unsupported
+ always_export_symbols_CXX=no
+ enable_shared_with_static_runtimes_CXX=yes
+
+ if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then
+ archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+ # If the export-symbols file already is a .def file (1st line
+ # is EXPORTS), use it as is; otherwise, prepend...
+ archive_expsym_cmds_CXX='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+ cp $export_symbols $output_objdir/$soname.def;
+ else
+ echo EXPORTS > $output_objdir/$soname.def;
+ cat $export_symbols >> $output_objdir/$soname.def;
+ fi~
+ $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+ else
+ ld_shlibs_CXX=no
+ fi
+ ;;
+ darwin* | rhapsody*)
+
+
+ archive_cmds_need_lc_CXX=no
+ hardcode_direct_CXX=no
+ hardcode_automatic_CXX=yes
+ hardcode_shlibpath_var_CXX=unsupported
+ whole_archive_flag_spec_CXX=''
+ link_all_deplibs_CXX=yes
+ allow_undefined_flag_CXX="$_lt_dar_allow_undefined"
+ case $cc_basename in
+ ifort*) _lt_dar_can_shared=yes ;;
+ *) _lt_dar_can_shared=$GCC ;;
+ esac
+ if test "$_lt_dar_can_shared" = "yes"; then
+ output_verbose_link_cmd=echo
+ archive_cmds_CXX="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}"
+ module_cmds_CXX="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}"
+ archive_expsym_cmds_CXX="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}"
+ module_expsym_cmds_CXX="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}"
+ if test "$lt_cv_apple_cc_single_mod" != "yes"; then
+ archive_cmds_CXX="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dsymutil}"
+ archive_expsym_cmds_CXX="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dar_export_syms}${_lt_dsymutil}"
+ fi
+
+ else
+ ld_shlibs_CXX=no
+ fi
+
+ ;;
+
+ dgux*)
+ case $cc_basename in
+ ec++*)
+ # FIXME: insert proper C++ library support
+ ld_shlibs_CXX=no
+ ;;
+ ghcx*)
+ # Green Hills C++ Compiler
+ # FIXME: insert proper C++ library support
+ ld_shlibs_CXX=no
+ ;;
+ *)
+ # FIXME: insert proper C++ library support
+ ld_shlibs_CXX=no
+ ;;
+ esac
+ ;;
+
+ freebsd[12]*)
+ # C++ shared libraries reported to be fairly broken before
+ # switch to ELF
+ ld_shlibs_CXX=no
+ ;;
+
+ freebsd-elf*)
+ archive_cmds_need_lc_CXX=no
+ ;;
+
+ freebsd* | dragonfly*)
+ # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF
+ # conventions
+ ld_shlibs_CXX=yes
+ ;;
+
+ gnu*)
+ ;;
+
+ hpux9*)
+ hardcode_libdir_flag_spec_CXX='${wl}+b ${wl}$libdir'
+ hardcode_libdir_separator_CXX=:
+ export_dynamic_flag_spec_CXX='${wl}-E'
+ hardcode_direct_CXX=yes
+ hardcode_minus_L_CXX=yes # Not in the search PATH,
+ # but as the default
+ # location of the library.
+
+ case $cc_basename in
+ CC*)
+ # FIXME: insert proper C++ library support
+ ld_shlibs_CXX=no
+ ;;
+ aCC*)
+ archive_cmds_CXX='$RM $output_objdir/$soname~$CC -b ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ #
+ # There doesn't appear to be a way to prevent this compiler from
+ # explicitly linking system object files so we need to strip them
+ # from the output so that they don't get included in the library
+ # dependencies.
+ output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed'
+ ;;
+ *)
+ if test "$GXX" = yes; then
+ archive_cmds_CXX='$RM $output_objdir/$soname~$CC -shared -nostdlib -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+ else
+ # FIXME: insert proper C++ library support
+ ld_shlibs_CXX=no
+ fi
+ ;;
+ esac
+ ;;
+
+ hpux10*|hpux11*)
+ if test $with_gnu_ld = no; then
+ hardcode_libdir_flag_spec_CXX='${wl}+b ${wl}$libdir'
+ hardcode_libdir_separator_CXX=:
+
+ case $host_cpu in
+ hppa*64*|ia64*)
+ ;;
+ *)
+ export_dynamic_flag_spec_CXX='${wl}-E'
+ ;;
+ esac
+ fi
+ case $host_cpu in
+ hppa*64*|ia64*)
+ hardcode_direct_CXX=no
+ hardcode_shlibpath_var_CXX=no
+ ;;
+ *)
+ hardcode_direct_CXX=yes
+ hardcode_direct_absolute_CXX=yes
+ hardcode_minus_L_CXX=yes # Not in the search PATH,
+ # but as the default
+ # location of the library.
+ ;;
+ esac
+
+ case $cc_basename in
+ CC*)
+ # FIXME: insert proper C++ library support
+ ld_shlibs_CXX=no
+ ;;
+ aCC*)
+ case $host_cpu in
+ hppa*64*)
+ archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ ;;
+ ia64*)
+ archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ ;;
+ *)
+ archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ ;;
+ esac
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ #
+ # There doesn't appear to be a way to prevent this compiler from
+ # explicitly linking system object files so we need to strip them
+ # from the output so that they don't get included in the library
+ # dependencies.
+ output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed'
+ ;;
+ *)
+ if test "$GXX" = yes; then
+ if test $with_gnu_ld = no; then
+ case $host_cpu in
+ hppa*64*)
+ archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ ;;
+ ia64*)
+ archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ ;;
+ *)
+ archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ ;;
+ esac
+ fi
+ else
+ # FIXME: insert proper C++ library support
+ ld_shlibs_CXX=no
+ fi
+ ;;
+ esac
+ ;;
+
+ interix[3-9]*)
+ hardcode_direct_CXX=no
+ hardcode_shlibpath_var_CXX=no
+ hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir'
+ export_dynamic_flag_spec_CXX='${wl}-E'
+ # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.
+ # Instead, shared libraries are loaded at an image base (0x10000000 by
+ # default) and relocated if they conflict, which is a slow very memory
+ # consuming and fragmenting process. To avoid this, we pick a random,
+ # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
+ # time. Moving up from 0x10000000 also allows more sbrk(2) space.
+ archive_cmds_CXX='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+ archive_expsym_cmds_CXX='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+ ;;
+ irix5* | irix6*)
+ case $cc_basename in
+ CC*)
+ # SGI C++
+ archive_cmds_CXX='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib'
+
+ # Archives containing C++ object files must be created using
+ # "CC -ar", where "CC" is the IRIX C++ compiler. This is
+ # necessary to make sure instantiated templates are included
+ # in the archive.
+ old_archive_cmds_CXX='$CC -ar -WR,-u -o $oldlib $oldobjs'
+ ;;
+ *)
+ if test "$GXX" = yes; then
+ if test "$with_gnu_ld" = no; then
+ archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ else
+ archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` -o $lib'
+ fi
+ fi
+ link_all_deplibs_CXX=yes
+ ;;
+ esac
+ hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir'
+ hardcode_libdir_separator_CXX=:
+ inherit_rpath_CXX=yes
+ ;;
+
+ linux* | k*bsd*-gnu | kopensolaris*-gnu)
+ case $cc_basename in
+ KCC*)
+ # Kuck and Associates, Inc. (KAI) C++ Compiler
+
+ # KCC will only create a shared library if the output file
+ # ends with ".so" (or ".sl" for HP-UX), so rename the library
+ # to its proper name (with version) after linking.
+ archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib'
+ archive_expsym_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib ${wl}-retain-symbols-file,$export_symbols; mv \$templib $lib'
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ #
+ # There doesn't appear to be a way to prevent this compiler from
+ # explicitly linking system object files so we need to strip them
+ # from the output so that they don't get included in the library
+ # dependencies.
+ output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed'
+
+ hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir'
+ export_dynamic_flag_spec_CXX='${wl}--export-dynamic'
+
+ # Archives containing C++ object files must be created using
+ # "CC -Bstatic", where "CC" is the KAI C++ compiler.
+ old_archive_cmds_CXX='$CC -Bstatic -o $oldlib $oldobjs'
+ ;;
+ icpc* | ecpc* )
+ # Intel C++
+ with_gnu_ld=yes
+ # version 8.0 and above of icpc choke on multiply defined symbols
+ # if we add $predep_objects and $postdep_objects, however 7.1 and
+ # earlier do not add the objects themselves.
+ case `$CC -V 2>&1` in
+ *"Version 7."*)
+ archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ ;;
+ *) # Version 8.0 or newer
+ tmp_idyn=
+ case $host_cpu in
+ ia64*) tmp_idyn=' -i_dynamic';;
+ esac
+ archive_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ archive_expsym_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ ;;
+ esac
+ archive_cmds_need_lc_CXX=no
+ hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir'
+ export_dynamic_flag_spec_CXX='${wl}--export-dynamic'
+ whole_archive_flag_spec_CXX='${wl}--whole-archive$convenience ${wl}--no-whole-archive'
+ ;;
+ pgCC* | pgcpp*)
+ # Portland Group C++ compiler
+ case `$CC -V` in
+ *pgCC\ [1-5]* | *pgcpp\ [1-5]*)
+ prelink_cmds_CXX='tpldir=Template.dir~
+ rm -rf $tpldir~
+ $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~
+ compile_command="$compile_command `find $tpldir -name \*.o | $NL2SP`"'
+ old_archive_cmds_CXX='tpldir=Template.dir~
+ rm -rf $tpldir~
+ $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~
+ $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | $NL2SP`~
+ $RANLIB $oldlib'
+ archive_cmds_CXX='tpldir=Template.dir~
+ rm -rf $tpldir~
+ $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~
+ $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib'
+ archive_expsym_cmds_CXX='tpldir=Template.dir~
+ rm -rf $tpldir~
+ $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~
+ $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib'
+ ;;
+ *) # Version 6 will use weak symbols
+ archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib'
+ archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib'
+ ;;
+ esac
+
+ hardcode_libdir_flag_spec_CXX='${wl}--rpath ${wl}$libdir'
+ export_dynamic_flag_spec_CXX='${wl}--export-dynamic'
+ whole_archive_flag_spec_CXX='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive'
+ ;;
+ cxx*)
+ # Compaq C++
+ archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib ${wl}-retain-symbols-file $wl$export_symbols'
+
+ runpath_var=LD_RUN_PATH
+ hardcode_libdir_flag_spec_CXX='-rpath $libdir'
+ hardcode_libdir_separator_CXX=:
+
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ #
+ # There doesn't appear to be a way to prevent this compiler from
+ # explicitly linking system object files so we need to strip them
+ # from the output so that they don't get included in the library
+ # dependencies.
+ output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`$ECHO "X$templist" | $Xsed -e "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed'
+ ;;
+ xl*)
+ # IBM XL 8.0 on PPC, with GNU ld
+ hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir'
+ export_dynamic_flag_spec_CXX='${wl}--export-dynamic'
+ archive_cmds_CXX='$CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ if test "x$supports_anon_versioning" = xyes; then
+ archive_expsym_cmds_CXX='echo "{ global:" > $output_objdir/$libname.ver~
+ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+ echo "local: *; };" >> $output_objdir/$libname.ver~
+ $CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib'
+ fi
+ ;;
+ *)
+ case `$CC -V 2>&1 | sed 5q` in
+ *Sun\ C*)
+ # Sun C++ 5.9
+ no_undefined_flag_CXX=' -zdefs'
+ archive_cmds_CXX='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ archive_expsym_cmds_CXX='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file ${wl}$export_symbols'
+ hardcode_libdir_flag_spec_CXX='-R$libdir'
+ whole_archive_flag_spec_CXX='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive'
+ compiler_needs_object_CXX=yes
+
+ # Not sure whether something based on
+ # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1
+ # would be better.
+ output_verbose_link_cmd='echo'
+
+ # Archives containing C++ object files must be created using
+ # "CC -xar", where "CC" is the Sun C++ compiler. This is
+ # necessary to make sure instantiated templates are included
+ # in the archive.
+ old_archive_cmds_CXX='$CC -xar -o $oldlib $oldobjs'
+ ;;
+ esac
+ ;;
+ esac
+ ;;
+
+ lynxos*)
+ # FIXME: insert proper C++ library support
+ ld_shlibs_CXX=no
+ ;;
+
+ m88k*)
+ # FIXME: insert proper C++ library support
+ ld_shlibs_CXX=no
+ ;;
+
+ mvs*)
+ case $cc_basename in
+ cxx*)
+ # FIXME: insert proper C++ library support
+ ld_shlibs_CXX=no
+ ;;
+ *)
+ # FIXME: insert proper C++ library support
+ ld_shlibs_CXX=no
+ ;;
+ esac
+ ;;
+
+ netbsd*)
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+ archive_cmds_CXX='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags'
+ wlarc=
+ hardcode_libdir_flag_spec_CXX='-R$libdir'
+ hardcode_direct_CXX=yes
+ hardcode_shlibpath_var_CXX=no
+ fi
+ # Workaround some broken pre-1.5 toolchains
+ output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"'
+ ;;
+
+ *nto* | *qnx*)
+ ld_shlibs_CXX=yes
+ ;;
+
+ openbsd2*)
+ # C++ shared libraries are fairly broken
+ ld_shlibs_CXX=no
+ ;;
+
+ openbsd*)
+ if test -f /usr/libexec/ld.so; then
+ hardcode_direct_CXX=yes
+ hardcode_shlibpath_var_CXX=no
+ hardcode_direct_absolute_CXX=yes
+ archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib'
+ hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir'
+ if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+ archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib'
+ export_dynamic_flag_spec_CXX='${wl}-E'
+ whole_archive_flag_spec_CXX="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+ fi
+ output_verbose_link_cmd=echo
+ else
+ ld_shlibs_CXX=no
+ fi
+ ;;
+
+ osf3* | osf4* | osf5*)
+ case $cc_basename in
+ KCC*)
+ # Kuck and Associates, Inc. (KAI) C++ Compiler
+
+ # KCC will only create a shared library if the output file
+ # ends with ".so" (or ".sl" for HP-UX), so rename the library
+ # to its proper name (with version) after linking.
+ archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib'
+
+ hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir'
+ hardcode_libdir_separator_CXX=:
+
+ # Archives containing C++ object files must be created using
+ # the KAI C++ compiler.
+ case $host in
+ osf3*) old_archive_cmds_CXX='$CC -Bstatic -o $oldlib $oldobjs' ;;
+ *) old_archive_cmds_CXX='$CC -o $oldlib $oldobjs' ;;
+ esac
+ ;;
+ RCC*)
+ # Rational C++ 2.4.1
+ # FIXME: insert proper C++ library support
+ ld_shlibs_CXX=no
+ ;;
+ cxx*)
+ case $host in
+ osf3*)
+ allow_undefined_flag_CXX=' ${wl}-expect_unresolved ${wl}\*'
+ archive_cmds_CXX='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && $ECHO "X${wl}-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib'
+ hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir'
+ ;;
+ *)
+ allow_undefined_flag_CXX=' -expect_unresolved \*'
+ archive_cmds_CXX='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib'
+ archive_expsym_cmds_CXX='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~
+ echo "-hidden">> $lib.exp~
+ $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname ${wl}-input ${wl}$lib.exp `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib~
+ $RM $lib.exp'
+ hardcode_libdir_flag_spec_CXX='-rpath $libdir'
+ ;;
+ esac
+
+ hardcode_libdir_separator_CXX=:
+
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ #
+ # There doesn't appear to be a way to prevent this compiler from
+ # explicitly linking system object files so we need to strip them
+ # from the output so that they don't get included in the library
+ # dependencies.
+ output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`$ECHO "X$templist" | $Xsed -e "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed'
+ ;;
+ *)
+ if test "$GXX" = yes && test "$with_gnu_ld" = no; then
+ allow_undefined_flag_CXX=' ${wl}-expect_unresolved ${wl}\*'
+ case $host in
+ osf3*)
+ archive_cmds_CXX='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ ;;
+ *)
+ archive_cmds_CXX='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ ;;
+ esac
+
+ hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir'
+ hardcode_libdir_separator_CXX=:
+
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "\-L"'
+
+ else
+ # FIXME: insert proper C++ library support
+ ld_shlibs_CXX=no
+ fi
+ ;;
+ esac
+ ;;
+
+ psos*)
+ # FIXME: insert proper C++ library support
+ ld_shlibs_CXX=no
+ ;;
+
+ sunos4*)
+ case $cc_basename in
+ CC*)
+ # Sun C++ 4.x
+ # FIXME: insert proper C++ library support
+ ld_shlibs_CXX=no
+ ;;
+ lcc*)
+ # Lucid
+ # FIXME: insert proper C++ library support
+ ld_shlibs_CXX=no
+ ;;
+ *)
+ # FIXME: insert proper C++ library support
+ ld_shlibs_CXX=no
+ ;;
+ esac
+ ;;
+
+ solaris*)
+ case $cc_basename in
+ CC*)
+ # Sun C++ 4.2, 5.x and Centerline C++
+ archive_cmds_need_lc_CXX=yes
+ no_undefined_flag_CXX=' -zdefs'
+ archive_cmds_CXX='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $CC -G${allow_undefined_flag} ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
+
+ hardcode_libdir_flag_spec_CXX='-R$libdir'
+ hardcode_shlibpath_var_CXX=no
+ case $host_os in
+ solaris2.[0-5] | solaris2.[0-5].*) ;;
+ *)
+ # The compiler driver will combine and reorder linker options,
+ # but understands `-z linker_flag'.
+ # Supported since Solaris 2.6 (maybe 2.5.1?)
+ whole_archive_flag_spec_CXX='-z allextract$convenience -z defaultextract'
+ ;;
+ esac
+ link_all_deplibs_CXX=yes
+
+ output_verbose_link_cmd='echo'
+
+ # Archives containing C++ object files must be created using
+ # "CC -xar", where "CC" is the Sun C++ compiler. This is
+ # necessary to make sure instantiated templates are included
+ # in the archive.
+ old_archive_cmds_CXX='$CC -xar -o $oldlib $oldobjs'
+ ;;
+ gcx*)
+ # Green Hills C++ Compiler
+ archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
+
+ # The C++ compiler must be used to create the archive.
+ old_archive_cmds_CXX='$CC $LDFLAGS -archive -o $oldlib $oldobjs'
+ ;;
+ *)
+ # GNU C++ compiler with Solaris linker
+ if test "$GXX" = yes && test "$with_gnu_ld" = no; then
+ no_undefined_flag_CXX=' ${wl}-z ${wl}defs'
+ if $CC --version | $GREP -v '^2\.7' > /dev/null; then
+ archive_cmds_CXX='$CC -shared -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
+ archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $CC -shared -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
+
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "\-L"'
+ else
+ # g++ 2.7 appears to require `-G' NOT `-shared' on this
+ # platform.
+ archive_cmds_CXX='$CC -G -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
+ archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $CC -G -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
+
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP "\-L"'
+ fi
+
+ hardcode_libdir_flag_spec_CXX='${wl}-R $wl$libdir'
+ case $host_os in
+ solaris2.[0-5] | solaris2.[0-5].*) ;;
+ *)
+ whole_archive_flag_spec_CXX='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract'
+ ;;
+ esac
+ fi
+ ;;
+ esac
+ ;;
+
+ sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*)
+ no_undefined_flag_CXX='${wl}-z,text'
+ archive_cmds_need_lc_CXX=no
+ hardcode_shlibpath_var_CXX=no
+ runpath_var='LD_RUN_PATH'
+
+ case $cc_basename in
+ CC*)
+ archive_cmds_CXX='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds_CXX='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ *)
+ archive_cmds_CXX='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds_CXX='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ esac
+ ;;
+
+ sysv5* | sco3.2v5* | sco5v6*)
+ # Note: We can NOT use -z defs as we might desire, because we do not
+ # link with -lc, and that would cause any symbols used from libc to
+ # always be unresolved, which means just about no library would
+ # ever link correctly. If we're not using GNU ld we use -z text
+ # though, which does catch some bad symbols but isn't as heavy-handed
+ # as -z defs.
+ no_undefined_flag_CXX='${wl}-z,text'
+ allow_undefined_flag_CXX='${wl}-z,nodefs'
+ archive_cmds_need_lc_CXX=no
+ hardcode_shlibpath_var_CXX=no
+ hardcode_libdir_flag_spec_CXX='${wl}-R,$libdir'
+ hardcode_libdir_separator_CXX=':'
+ link_all_deplibs_CXX=yes
+ export_dynamic_flag_spec_CXX='${wl}-Bexport'
+ runpath_var='LD_RUN_PATH'
+
+ case $cc_basename in
+ CC*)
+ archive_cmds_CXX='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds_CXX='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ *)
+ archive_cmds_CXX='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds_CXX='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ esac
+ ;;
+
+ tandem*)
+ case $cc_basename in
+ NCC*)
+ # NonStop-UX NCC 3.20
+ # FIXME: insert proper C++ library support
+ ld_shlibs_CXX=no
+ ;;
+ *)
+ # FIXME: insert proper C++ library support
+ ld_shlibs_CXX=no
+ ;;
+ esac
+ ;;
+
+ vxworks*)
+ # FIXME: insert proper C++ library support
+ ld_shlibs_CXX=no
+ ;;
+
+ *)
+ # FIXME: insert proper C++ library support
+ ld_shlibs_CXX=no
+ ;;
+ esac
+
+ { $as_echo "$as_me:$LINENO: result: $ld_shlibs_CXX" >&5
+$as_echo "$ld_shlibs_CXX" >&6; }
+ test "$ld_shlibs_CXX" = no && can_build_shared=no
+
+ GCC_CXX="$GXX"
+ LD_CXX="$LD"
+
+ ## CAVEAT EMPTOR:
+ ## There is no encapsulation within the following macros, do not change
+ ## the running order or otherwise move them around unless you know exactly
+ ## what you are doing...
+ # Dependencies to place before and after the object being linked:
+predep_objects_CXX=
+postdep_objects_CXX=
+predeps_CXX=
+postdeps_CXX=
+compiler_lib_search_path_CXX=
+
+cat > conftest.$ac_ext <<_LT_EOF
+class Foo
+{
+public:
+ Foo (void) { a = 0; }
+private:
+ int a;
+};
+_LT_EOF
+
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; then
+ # Parse the compiler output and extract the necessary
+ # objects, libraries and library flags.
+
+ # Sentinel used to keep track of whether or not we are before
+ # the conftest object file.
+ pre_test_object_deps_done=no
+
+ for p in `eval "$output_verbose_link_cmd"`; do
+ case $p in
+
+ -L* | -R* | -l*)
+ # Some compilers place space between "-{L,R}" and the path.
+ # Remove the space.
+ if test $p = "-L" ||
+ test $p = "-R"; then
+ prev=$p
+ continue
+ else
+ prev=
+ fi
+
+ if test "$pre_test_object_deps_done" = no; then
+ case $p in
+ -L* | -R*)
+ # Internal compiler library paths should come after those
+ # provided the user. The postdeps already come after the
+ # user supplied libs so there is no need to process them.
+ if test -z "$compiler_lib_search_path_CXX"; then
+ compiler_lib_search_path_CXX="${prev}${p}"
+ else
+ compiler_lib_search_path_CXX="${compiler_lib_search_path_CXX} ${prev}${p}"
+ fi
+ ;;
+ # The "-l" case would never come before the object being
+ # linked, so don't bother handling this case.
+ esac
+ else
+ if test -z "$postdeps_CXX"; then
+ postdeps_CXX="${prev}${p}"
+ else
+ postdeps_CXX="${postdeps_CXX} ${prev}${p}"
+ fi
+ fi
+ ;;
+
+ *.$objext)
+ # This assumes that the test object file only shows up
+ # once in the compiler output.
+ if test "$p" = "conftest.$objext"; then
+ pre_test_object_deps_done=yes
+ continue
+ fi
+
+ if test "$pre_test_object_deps_done" = no; then
+ if test -z "$predep_objects_CXX"; then
+ predep_objects_CXX="$p"
+ else
+ predep_objects_CXX="$predep_objects_CXX $p"
+ fi
+ else
+ if test -z "$postdep_objects_CXX"; then
+ postdep_objects_CXX="$p"
+ else
+ postdep_objects_CXX="$postdep_objects_CXX $p"
+ fi
+ fi
+ ;;
+
+ *) ;; # Ignore the rest.
+
+ esac
+ done
+
+ # Clean up.
+ rm -f a.out a.exe
+else
+ echo "libtool.m4: error: problem compiling CXX test program"
+fi
+
+$RM -f confest.$objext
+
+# PORTME: override above test on systems where it is broken
+case $host_os in
+interix[3-9]*)
+ # Interix 3.5 installs completely hosed .la files for C++, so rather than
+ # hack all around it, let's just trust "g++" to DTRT.
+ predep_objects_CXX=
+ postdep_objects_CXX=
+ postdeps_CXX=
+ ;;
+
+linux*)
+ case `$CC -V 2>&1 | sed 5q` in
+ *Sun\ C*)
+ # Sun C++ 5.9
+
+ # The more standards-conforming stlport4 library is
+ # incompatible with the Cstd library. Avoid specifying
+ # it if it's in CXXFLAGS. Ignore libCrun as
+ # -library=stlport4 depends on it.
+ case " $CXX $CXXFLAGS " in
+ *" -library=stlport4 "*)
+ solaris_use_stlport4=yes
+ ;;
+ esac
+
+ if test "$solaris_use_stlport4" != yes; then
+ postdeps_CXX='-library=Cstd -library=Crun'
+ fi
+ ;;
+ esac
+ ;;
+
+solaris*)
+ case $cc_basename in
+ CC*)
+ # The more standards-conforming stlport4 library is
+ # incompatible with the Cstd library. Avoid specifying
+ # it if it's in CXXFLAGS. Ignore libCrun as
+ # -library=stlport4 depends on it.
+ case " $CXX $CXXFLAGS " in
+ *" -library=stlport4 "*)
+ solaris_use_stlport4=yes
+ ;;
+ esac
+
+ # Adding this requires a known-good setup of shared libraries for
+ # Sun compiler versions before 5.6, else PIC objects from an old
+ # archive will be linked into the output, leading to subtle bugs.
+ if test "$solaris_use_stlport4" != yes; then
+ postdeps_CXX='-library=Cstd -library=Crun'
+ fi
+ ;;
+ esac
+ ;;
+esac
+
+
+case " $postdeps_CXX " in
+*" -lc "*) archive_cmds_need_lc_CXX=no ;;
+esac
+ compiler_lib_search_dirs_CXX=
+if test -n "${compiler_lib_search_path_CXX}"; then
+ compiler_lib_search_dirs_CXX=`echo " ${compiler_lib_search_path_CXX}" | ${SED} -e 's! -L! !g' -e 's!^ !!'`
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ lt_prog_compiler_wl_CXX=
+lt_prog_compiler_pic_CXX=
+lt_prog_compiler_static_CXX=
+
+{ $as_echo "$as_me:$LINENO: checking for $compiler option to produce PIC" >&5
+$as_echo_n "checking for $compiler option to produce PIC... " >&6; }
+
+ # C++ specific cases for pic, static, wl, etc.
+ if test "$GXX" = yes; then
+ lt_prog_compiler_wl_CXX='-Wl,'
+ lt_prog_compiler_static_CXX='-static'
+
+ case $host_os in
+ aix*)
+ # All AIX code is PIC.
+ if test "$host_cpu" = ia64; then
+ # AIX 5 now supports IA64 processor
+ lt_prog_compiler_static_CXX='-Bstatic'
+ fi
+ ;;
+
+ amigaos*)
+ case $host_cpu in
+ powerpc)
+ # see comment about AmigaOS4 .so support
+ lt_prog_compiler_pic_CXX='-fPIC'
+ ;;
+ m68k)
+ # FIXME: we need at least 68020 code to build shared libraries, but
+ # adding the `-m68020' flag to GCC prevents building anything better,
+ # like `-m68040'.
+ lt_prog_compiler_pic_CXX='-m68020 -resident32 -malways-restore-a4'
+ ;;
+ esac
+ ;;
+
+ beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
+ # PIC is the default for these OSes.
+ ;;
+ mingw* | cygwin* | os2* | pw32* | cegcc*)
+ # This hack is so that the source file can tell whether it is being
+ # built for inclusion in a dll (and should export symbols for example).
+ # Although the cygwin gcc ignores -fPIC, still need this for old-style
+ # (--disable-auto-import) libraries
+ lt_prog_compiler_pic_CXX='-DDLL_EXPORT'
+ ;;
+ darwin* | rhapsody*)
+ # PIC is the default on this platform
+ # Common symbols not allowed in MH_DYLIB files
+ lt_prog_compiler_pic_CXX='-fno-common'
+ ;;
+ *djgpp*)
+ # DJGPP does not support shared libraries at all
+ lt_prog_compiler_pic_CXX=
+ ;;
+ interix[3-9]*)
+ # Interix 3.x gcc -fpic/-fPIC options generate broken code.
+ # Instead, we relocate shared libraries at runtime.
+ ;;
+ sysv4*MP*)
+ if test -d /usr/nec; then
+ lt_prog_compiler_pic_CXX=-Kconform_pic
+ fi
+ ;;
+ hpux*)
+ # PIC is the default for 64-bit PA HP-UX, but not for 32-bit
+ # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag
+ # sets the default TLS model and affects inlining.
+ case $host_cpu in
+ hppa*64*)
+ ;;
+ *)
+ lt_prog_compiler_pic_CXX='-fPIC'
+ ;;
+ esac
+ ;;
+ *qnx* | *nto*)
+ # QNX uses GNU C++, but need to define -shared option too, otherwise
+ # it will coredump.
+ lt_prog_compiler_pic_CXX='-fPIC -shared'
+ ;;
+ *)
+ lt_prog_compiler_pic_CXX='-fPIC'
+ ;;
+ esac
+ else
+ case $host_os in
+ aix[4-9]*)
+ # All AIX code is PIC.
+ if test "$host_cpu" = ia64; then
+ # AIX 5 now supports IA64 processor
+ lt_prog_compiler_static_CXX='-Bstatic'
+ else
+ lt_prog_compiler_static_CXX='-bnso -bI:/lib/syscalls.exp'
+ fi
+ ;;
+ chorus*)
+ case $cc_basename in
+ cxch68*)
+ # Green Hills C++ Compiler
+ # _LT_TAGVAR(lt_prog_compiler_static, CXX)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a"
+ ;;
+ esac
+ ;;
+ dgux*)
+ case $cc_basename in
+ ec++*)
+ lt_prog_compiler_pic_CXX='-KPIC'
+ ;;
+ ghcx*)
+ # Green Hills C++ Compiler
+ lt_prog_compiler_pic_CXX='-pic'
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ freebsd* | dragonfly*)
+ # FreeBSD uses GNU C++
+ ;;
+ hpux9* | hpux10* | hpux11*)
+ case $cc_basename in
+ CC*)
+ lt_prog_compiler_wl_CXX='-Wl,'
+ lt_prog_compiler_static_CXX='${wl}-a ${wl}archive'
+ if test "$host_cpu" != ia64; then
+ lt_prog_compiler_pic_CXX='+Z'
+ fi
+ ;;
+ aCC*)
+ lt_prog_compiler_wl_CXX='-Wl,'
+ lt_prog_compiler_static_CXX='${wl}-a ${wl}archive'
+ case $host_cpu in
+ hppa*64*|ia64*)
+ # +Z the default
+ ;;
+ *)
+ lt_prog_compiler_pic_CXX='+Z'
+ ;;
+ esac
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ interix*)
+ # This is c89, which is MS Visual C++ (no shared libs)
+ # Anyone wants to do a port?
+ ;;
+ irix5* | irix6* | nonstopux*)
+ case $cc_basename in
+ CC*)
+ lt_prog_compiler_wl_CXX='-Wl,'
+ lt_prog_compiler_static_CXX='-non_shared'
+ # CC pic flag -KPIC is the default.
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ linux* | k*bsd*-gnu | kopensolaris*-gnu)
+ case $cc_basename in
+ KCC*)
+ # KAI C++ Compiler
+ lt_prog_compiler_wl_CXX='--backend -Wl,'
+ lt_prog_compiler_pic_CXX='-fPIC'
+ ;;
+ ecpc* )
+ # old Intel C++ for x86_64 which still supported -KPIC.
+ lt_prog_compiler_wl_CXX='-Wl,'
+ lt_prog_compiler_pic_CXX='-KPIC'
+ lt_prog_compiler_static_CXX='-static'
+ ;;
+ icpc* )
+ # Intel C++, used to be incompatible with GCC.
+ # ICC 10 doesn't accept -KPIC any more.
+ lt_prog_compiler_wl_CXX='-Wl,'
+ lt_prog_compiler_pic_CXX='-fPIC'
+ lt_prog_compiler_static_CXX='-static'
+ ;;
+ pgCC* | pgcpp*)
+ # Portland Group C++ compiler
+ lt_prog_compiler_wl_CXX='-Wl,'
+ lt_prog_compiler_pic_CXX='-fpic'
+ lt_prog_compiler_static_CXX='-Bstatic'
+ ;;
+ cxx*)
+ # Compaq C++
+ # Make sure the PIC flag is empty. It appears that all Alpha
+ # Linux and Compaq Tru64 Unix objects are PIC.
+ lt_prog_compiler_pic_CXX=
+ lt_prog_compiler_static_CXX='-non_shared'
+ ;;
+ xlc* | xlC*)
+ # IBM XL 8.0 on PPC
+ lt_prog_compiler_wl_CXX='-Wl,'
+ lt_prog_compiler_pic_CXX='-qpic'
+ lt_prog_compiler_static_CXX='-qstaticlink'
+ ;;
+ *)
+ case `$CC -V 2>&1 | sed 5q` in
+ *Sun\ C*)
+ # Sun C++ 5.9
+ lt_prog_compiler_pic_CXX='-KPIC'
+ lt_prog_compiler_static_CXX='-Bstatic'
+ lt_prog_compiler_wl_CXX='-Qoption ld '
+ ;;
+ esac
+ ;;
+ esac
+ ;;
+ lynxos*)
+ ;;
+ m88k*)
+ ;;
+ mvs*)
+ case $cc_basename in
+ cxx*)
+ lt_prog_compiler_pic_CXX='-W c,exportall'
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ netbsd* | netbsdelf*-gnu)
+ ;;
+ *qnx* | *nto*)
+ # QNX uses GNU C++, but need to define -shared option too, otherwise
+ # it will coredump.
+ lt_prog_compiler_pic_CXX='-fPIC -shared'
+ ;;
+ osf3* | osf4* | osf5*)
+ case $cc_basename in
+ KCC*)
+ lt_prog_compiler_wl_CXX='--backend -Wl,'
+ ;;
+ RCC*)
+ # Rational C++ 2.4.1
+ lt_prog_compiler_pic_CXX='-pic'
+ ;;
+ cxx*)
+ # Digital/Compaq C++
+ lt_prog_compiler_wl_CXX='-Wl,'
+ # Make sure the PIC flag is empty. It appears that all Alpha
+ # Linux and Compaq Tru64 Unix objects are PIC.
+ lt_prog_compiler_pic_CXX=
+ lt_prog_compiler_static_CXX='-non_shared'
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ psos*)
+ ;;
+ solaris*)
+ case $cc_basename in
+ CC*)
+ # Sun C++ 4.2, 5.x and Centerline C++
+ lt_prog_compiler_pic_CXX='-KPIC'
+ lt_prog_compiler_static_CXX='-Bstatic'
+ lt_prog_compiler_wl_CXX='-Qoption ld '
+ ;;
+ gcx*)
+ # Green Hills C++ Compiler
+ lt_prog_compiler_pic_CXX='-PIC'
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ sunos4*)
+ case $cc_basename in
+ CC*)
+ # Sun C++ 4.x
+ lt_prog_compiler_pic_CXX='-pic'
+ lt_prog_compiler_static_CXX='-Bstatic'
+ ;;
+ lcc*)
+ # Lucid
+ lt_prog_compiler_pic_CXX='-pic'
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
+ case $cc_basename in
+ CC*)
+ lt_prog_compiler_wl_CXX='-Wl,'
+ lt_prog_compiler_pic_CXX='-KPIC'
+ lt_prog_compiler_static_CXX='-Bstatic'
+ ;;
+ esac
+ ;;
+ tandem*)
+ case $cc_basename in
+ NCC*)
+ # NonStop-UX NCC 3.20
+ lt_prog_compiler_pic_CXX='-KPIC'
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ vxworks*)
+ ;;
+ *)
+ lt_prog_compiler_can_build_shared_CXX=no
+ ;;
+ esac
+ fi
+
+case $host_os in
+ # For platforms which do not support PIC, -DPIC is meaningless:
+ *djgpp*)
+ lt_prog_compiler_pic_CXX=
+ ;;
+ *)
+ lt_prog_compiler_pic_CXX="$lt_prog_compiler_pic_CXX -DPIC"
+ ;;
+esac
+{ $as_echo "$as_me:$LINENO: result: $lt_prog_compiler_pic_CXX" >&5
+$as_echo "$lt_prog_compiler_pic_CXX" >&6; }
+
+
+
+#
+# Check to make sure the PIC flag actually works.
+#
+if test -n "$lt_prog_compiler_pic_CXX"; then
+ { $as_echo "$as_me:$LINENO: checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works" >&5
+$as_echo_n "checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works... " >&6; }
+if test "${lt_cv_prog_compiler_pic_works_CXX+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_prog_compiler_pic_works_CXX=no
+ ac_outfile=conftest.$ac_objext
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+ lt_compiler_flag="$lt_prog_compiler_pic_CXX -DPIC"
+ # Insert the option either (1) after the last *FLAGS variable, or
+ # (2) before a word containing "conftest.", or (3) at the end.
+ # Note that $ac_compile itself does not contain backslashes and begins
+ # with a dollar sign (not a hyphen), so the echo should work correctly.
+ # The option is referenced via a variable to avoid confusing sed.
+ lt_compile=`echo "$ac_compile" | $SED \
+ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+ -e 's:$: $lt_compiler_flag:'`
+ (eval echo "\"\$as_me:14205: $lt_compile\"" >&5)
+ (eval "$lt_compile" 2>conftest.err)
+ ac_status=$?
+ cat conftest.err >&5
+ echo "$as_me:14209: \$? = $ac_status" >&5
+ if (exit $ac_status) && test -s "$ac_outfile"; then
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings other than the usual output.
+ $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp
+ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+ if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
+ lt_cv_prog_compiler_pic_works_CXX=yes
+ fi
+ fi
+ $RM conftest*
+
+fi
+{ $as_echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_pic_works_CXX" >&5
+$as_echo "$lt_cv_prog_compiler_pic_works_CXX" >&6; }
+
+if test x"$lt_cv_prog_compiler_pic_works_CXX" = xyes; then
+ case $lt_prog_compiler_pic_CXX in
+ "" | " "*) ;;
+ *) lt_prog_compiler_pic_CXX=" $lt_prog_compiler_pic_CXX" ;;
+ esac
+else
+ lt_prog_compiler_pic_CXX=
+ lt_prog_compiler_can_build_shared_CXX=no
+fi
+
+fi
+
+
+
+#
+# Check to make sure the static flag actually works.
+#
+wl=$lt_prog_compiler_wl_CXX eval lt_tmp_static_flag=\"$lt_prog_compiler_static_CXX\"
+{ $as_echo "$as_me:$LINENO: checking if $compiler static flag $lt_tmp_static_flag works" >&5
+$as_echo_n "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; }
+if test "${lt_cv_prog_compiler_static_works_CXX+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_prog_compiler_static_works_CXX=no
+ save_LDFLAGS="$LDFLAGS"
+ LDFLAGS="$LDFLAGS $lt_tmp_static_flag"
+ echo "$lt_simple_link_test_code" > conftest.$ac_ext
+ if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then
+ # The linker can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ if test -s conftest.err; then
+ # Append any errors to the config.log.
+ cat conftest.err 1>&5
+ $ECHO "X$_lt_linker_boilerplate" | $Xsed -e '/^$/d' > conftest.exp
+ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+ if diff conftest.exp conftest.er2 >/dev/null; then
+ lt_cv_prog_compiler_static_works_CXX=yes
+ fi
+ else
+ lt_cv_prog_compiler_static_works_CXX=yes
+ fi
+ fi
+ $RM -r conftest*
+ LDFLAGS="$save_LDFLAGS"
+
+fi
+{ $as_echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_static_works_CXX" >&5
+$as_echo "$lt_cv_prog_compiler_static_works_CXX" >&6; }
+
+if test x"$lt_cv_prog_compiler_static_works_CXX" = xyes; then
+ :
+else
+ lt_prog_compiler_static_CXX=
+fi
+
+
+
+
+ { $as_echo "$as_me:$LINENO: checking if $compiler supports -c -o file.$ac_objext" >&5
+$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; }
+if test "${lt_cv_prog_compiler_c_o_CXX+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_prog_compiler_c_o_CXX=no
+ $RM -r conftest 2>/dev/null
+ mkdir conftest
+ cd conftest
+ mkdir out
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+ lt_compiler_flag="-o out/conftest2.$ac_objext"
+ # Insert the option either (1) after the last *FLAGS variable, or
+ # (2) before a word containing "conftest.", or (3) at the end.
+ # Note that $ac_compile itself does not contain backslashes and begins
+ # with a dollar sign (not a hyphen), so the echo should work correctly.
+ lt_compile=`echo "$ac_compile" | $SED \
+ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+ -e 's:$: $lt_compiler_flag:'`
+ (eval echo "\"\$as_me:14304: $lt_compile\"" >&5)
+ (eval "$lt_compile" 2>out/conftest.err)
+ ac_status=$?
+ cat out/conftest.err >&5
+ echo "$as_me:14308: \$? = $ac_status" >&5
+ if (exit $ac_status) && test -s out/conftest2.$ac_objext
+ then
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp
+ $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
+ if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
+ lt_cv_prog_compiler_c_o_CXX=yes
+ fi
+ fi
+ chmod u+w . 2>&5
+ $RM conftest*
+ # SGI C++ compiler will create directory out/ii_files/ for
+ # template instantiation
+ test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files
+ $RM out/* && rmdir out
+ cd ..
+ $RM -r conftest
+ $RM conftest*
+
+fi
+{ $as_echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_c_o_CXX" >&5
+$as_echo "$lt_cv_prog_compiler_c_o_CXX" >&6; }
+
+
+
+ { $as_echo "$as_me:$LINENO: checking if $compiler supports -c -o file.$ac_objext" >&5
+$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; }
+if test "${lt_cv_prog_compiler_c_o_CXX+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_prog_compiler_c_o_CXX=no
+ $RM -r conftest 2>/dev/null
+ mkdir conftest
+ cd conftest
+ mkdir out
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+ lt_compiler_flag="-o out/conftest2.$ac_objext"
+ # Insert the option either (1) after the last *FLAGS variable, or
+ # (2) before a word containing "conftest.", or (3) at the end.
+ # Note that $ac_compile itself does not contain backslashes and begins
+ # with a dollar sign (not a hyphen), so the echo should work correctly.
+ lt_compile=`echo "$ac_compile" | $SED \
+ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+ -e 's:$: $lt_compiler_flag:'`
+ (eval echo "\"\$as_me:14356: $lt_compile\"" >&5)
+ (eval "$lt_compile" 2>out/conftest.err)
+ ac_status=$?
+ cat out/conftest.err >&5
+ echo "$as_me:14360: \$? = $ac_status" >&5
+ if (exit $ac_status) && test -s out/conftest2.$ac_objext
+ then
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp
+ $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
+ if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
+ lt_cv_prog_compiler_c_o_CXX=yes
+ fi
+ fi
+ chmod u+w . 2>&5
+ $RM conftest*
+ # SGI C++ compiler will create directory out/ii_files/ for
+ # template instantiation
+ test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files
+ $RM out/* && rmdir out
+ cd ..
+ $RM -r conftest
+ $RM conftest*
+
+fi
+{ $as_echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_c_o_CXX" >&5
+$as_echo "$lt_cv_prog_compiler_c_o_CXX" >&6; }
+
+
+
+
+hard_links="nottested"
+if test "$lt_cv_prog_compiler_c_o_CXX" = no && test "$need_locks" != no; then
+ # do not overwrite the value of need_locks provided by the user
+ { $as_echo "$as_me:$LINENO: checking if we can lock with hard links" >&5
+$as_echo_n "checking if we can lock with hard links... " >&6; }
+ hard_links=yes
+ $RM conftest*
+ ln conftest.a conftest.b 2>/dev/null && hard_links=no
+ touch conftest.a
+ ln conftest.a conftest.b 2>&5 || hard_links=no
+ ln conftest.a conftest.b 2>/dev/null && hard_links=no
+ { $as_echo "$as_me:$LINENO: result: $hard_links" >&5
+$as_echo "$hard_links" >&6; }
+ if test "$hard_links" = no; then
+ { $as_echo "$as_me:$LINENO: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5
+$as_echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;}
+ need_locks=warn
+ fi
+else
+ need_locks=no
+fi
+
+
+
+ { $as_echo "$as_me:$LINENO: checking whether the $compiler linker ($LD) supports shared libraries" >&5
+$as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; }
+
+ export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+ case $host_os in
+ aix[4-9]*)
+ # If we're using GNU nm, then we don't want the "-C" option.
+ # -C means demangle to AIX nm, but means don't demangle with GNU nm
+ if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
+ export_symbols_cmds_CXX='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
+ else
+ export_symbols_cmds_CXX='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
+ fi
+ ;;
+ pw32*)
+ export_symbols_cmds_CXX="$ltdll_cmds"
+ ;;
+ cygwin* | mingw* | cegcc*)
+ export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;/^.*[ ]__nm__/s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols'
+ ;;
+ linux* | k*bsd*-gnu)
+ link_all_deplibs_CXX=no
+ ;;
+ *)
+ export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+ ;;
+ esac
+ exclude_expsyms_CXX='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'
+
+{ $as_echo "$as_me:$LINENO: result: $ld_shlibs_CXX" >&5
+$as_echo "$ld_shlibs_CXX" >&6; }
+test "$ld_shlibs_CXX" = no && can_build_shared=no
+
+with_gnu_ld_CXX=$with_gnu_ld
+
+
+
+
+
+
+#
+# Do we need to explicitly link libc?
+#
+case "x$archive_cmds_need_lc_CXX" in
+x|xyes)
+ # Assume -lc should be added
+ archive_cmds_need_lc_CXX=yes
+
+ if test "$enable_shared" = yes && test "$GCC" = yes; then
+ case $archive_cmds_CXX in
+ *'~'*)
+ # FIXME: we may have to deal with multi-command sequences.
+ ;;
+ '$CC '*)
+ # Test whether the compiler implicitly links with -lc since on some
+ # systems, -lgcc has to come before -lc. If gcc already passes -lc
+ # to ld, don't add -lc before -lgcc.
+ { $as_echo "$as_me:$LINENO: checking whether -lc should be explicitly linked in" >&5
+$as_echo_n "checking whether -lc should be explicitly linked in... " >&6; }
+ $RM conftest*
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } 2>conftest.err; then
+ soname=conftest
+ lib=conftest
+ libobjs=conftest.$ac_objext
+ deplibs=
+ wl=$lt_prog_compiler_wl_CXX
+ pic_flag=$lt_prog_compiler_pic_CXX
+ compiler_flags=-v
+ linker_flags=-v
+ verstring=
+ output_objdir=.
+ libname=conftest
+ lt_save_allow_undefined_flag=$allow_undefined_flag_CXX
+ allow_undefined_flag_CXX=
+ if { (eval echo "$as_me:$LINENO: \"$archive_cmds_CXX 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\"") >&5
+ (eval $archive_cmds_CXX 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }
+ then
+ archive_cmds_need_lc_CXX=no
+ else
+ archive_cmds_need_lc_CXX=yes
+ fi
+ allow_undefined_flag_CXX=$lt_save_allow_undefined_flag
+ else
+ cat conftest.err 1>&5
+ fi
+ $RM conftest*
+ { $as_echo "$as_me:$LINENO: result: $archive_cmds_need_lc_CXX" >&5
+$as_echo "$archive_cmds_need_lc_CXX" >&6; }
+ ;;
+ esac
+ fi
+ ;;
+esac
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ { $as_echo "$as_me:$LINENO: checking dynamic linker characteristics" >&5
+$as_echo_n "checking dynamic linker characteristics... " >&6; }
+
+library_names_spec=
+libname_spec='lib$name'
+soname_spec=
+shrext_cmds=".so"
+postinstall_cmds=
+postuninstall_cmds=
+finish_cmds=
+finish_eval=
+shlibpath_var=
+shlibpath_overrides_runpath=unknown
+version_type=none
+dynamic_linker="$host_os ld.so"
+sys_lib_dlsearch_path_spec="/lib /usr/lib"
+need_lib_prefix=unknown
+hardcode_into_libs=no
+
+# when you set need_version to no, make sure it does not cause -set_version
+# flags to be left without arguments
+need_version=unknown
+
+case $host_os in
+aix3*)
+ version_type=linux
+ library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a'
+ shlibpath_var=LIBPATH
+
+ # AIX 3 has no versioning support, so we append a major version to the name.
+ soname_spec='${libname}${release}${shared_ext}$major'
+ ;;
+
+aix[4-9]*)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ hardcode_into_libs=yes
+ if test "$host_cpu" = ia64; then
+ # AIX 5 supports IA64
+ library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}'
+ shlibpath_var=LD_LIBRARY_PATH
+ else
+ # With GCC up to 2.95.x, collect2 would create an import file
+ # for dependence libraries. The import file would start with
+ # the line `#! .'. This would cause the generated library to
+ # depend on `.', always an invalid library. This was fixed in
+ # development snapshots of GCC prior to 3.0.
+ case $host_os in
+ aix4 | aix4.[01] | aix4.[01].*)
+ if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)'
+ echo ' yes '
+ echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then
+ :
+ else
+ can_build_shared=no
+ fi
+ ;;
+ esac
+ # AIX (on Power*) has no versioning support, so currently we can not hardcode correct
+ # soname into executable. Probably we can add versioning support to
+ # collect2, so additional links can be useful in future.
+ if test "$aix_use_runtimelinking" = yes; then
+ # If using run time linking (on AIX 4.2 or later) use lib<name>.so
+ # instead of lib<name>.a to let people know that these are not
+ # typical AIX shared libraries.
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ else
+ # We preserve .a as extension for shared libraries through AIX4.2
+ # and later when we are not doing run time linking.
+ library_names_spec='${libname}${release}.a $libname.a'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ fi
+ shlibpath_var=LIBPATH
+ fi
+ ;;
+
+amigaos*)
+ case $host_cpu in
+ powerpc)
+ # Since July 2007 AmigaOS4 officially supports .so libraries.
+ # When compiling the executable, add -use-dynld -Lsobjs: to the compileline.
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ ;;
+ m68k)
+ library_names_spec='$libname.ixlibrary $libname.a'
+ # Create ${libname}_ixlibrary.a entries in /sys/libs.
+ finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$ECHO "X$lib" | $Xsed -e '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done'
+ ;;
+ esac
+ ;;
+
+beos*)
+ library_names_spec='${libname}${shared_ext}'
+ dynamic_linker="$host_os ld.so"
+ shlibpath_var=LIBRARY_PATH
+ ;;
+
+bsdi[45]*)
+ version_type=linux
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib"
+ sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib"
+ # the default ld.so.conf also contains /usr/contrib/lib and
+ # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow
+ # libtool to hard-code these into programs
+ ;;
+
+cygwin* | mingw* | pw32* | cegcc*)
+ version_type=windows
+ shrext_cmds=".dll"
+ need_version=no
+ need_lib_prefix=no
+
+ case $GCC,$host_os in
+ yes,cygwin* | yes,mingw* | yes,pw32* | yes,cegcc*)
+ library_names_spec='$libname.dll.a'
+ # DLL is installed to $(libdir)/../bin by postinstall_cmds
+ postinstall_cmds='base_file=`basename \${file}`~
+ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~
+ dldir=$destdir/`dirname \$dlpath`~
+ test -d \$dldir || mkdir -p \$dldir~
+ $install_prog $dir/$dlname \$dldir/$dlname~
+ chmod a+x \$dldir/$dlname~
+ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then
+ eval '\''$striplib \$dldir/$dlname'\'' || exit \$?;
+ fi'
+ postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
+ dlpath=$dir/\$dldll~
+ $RM \$dlpath'
+ shlibpath_overrides_runpath=yes
+
+ case $host_os in
+ cygwin*)
+ # Cygwin DLLs use 'cyg' prefix rather than 'lib'
+ soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+ sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib"
+ ;;
+ mingw* | cegcc*)
+ # MinGW DLLs use traditional 'lib' prefix
+ soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+ sys_lib_search_path_spec=`$CC -print-search-dirs | $GREP "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"`
+ if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then
+ # It is most probably a Windows format PATH printed by
+ # mingw gcc, but we are running on Cygwin. Gcc prints its search
+ # path with ; separators, and with drive letters. We can handle the
+ # drive letters (cygwin fileutils understands them), so leave them,
+ # especially as we might pass files found there to a mingw objdump,
+ # which wouldn't understand a cygwinified path. Ahh.
+ sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`
+ else
+ sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
+ fi
+ ;;
+ pw32*)
+ # pw32 DLLs use 'pw' prefix rather than 'lib'
+ library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+ ;;
+ esac
+ ;;
+
+ *)
+ library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib'
+ ;;
+ esac
+ dynamic_linker='Win32 ld.exe'
+ # FIXME: first we should search . and the directory the executable is in
+ shlibpath_var=PATH
+ ;;
+
+darwin* | rhapsody*)
+ dynamic_linker="$host_os dyld"
+ version_type=darwin
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext'
+ soname_spec='${libname}${release}${major}$shared_ext'
+ shlibpath_overrides_runpath=yes
+ shlibpath_var=DYLD_LIBRARY_PATH
+ shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`'
+
+ sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib'
+ ;;
+
+dgux*)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ ;;
+
+freebsd1*)
+ dynamic_linker=no
+ ;;
+
+freebsd* | dragonfly*)
+ # DragonFly does not have aout. When/if they implement a new
+ # versioning mechanism, adjust this.
+ if test -x /usr/bin/objformat; then
+ objformat=`/usr/bin/objformat`
+ else
+ case $host_os in
+ freebsd[123]*) objformat=aout ;;
+ *) objformat=elf ;;
+ esac
+ fi
+ version_type=freebsd-$objformat
+ case $version_type in
+ freebsd-elf*)
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
+ need_version=no
+ need_lib_prefix=no
+ ;;
+ freebsd-*)
+ library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix'
+ need_version=yes
+ ;;
+ esac
+ shlibpath_var=LD_LIBRARY_PATH
+ case $host_os in
+ freebsd2*)
+ shlibpath_overrides_runpath=yes
+ ;;
+ freebsd3.[01]* | freebsdelf3.[01]*)
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ ;;
+ freebsd3.[2-9]* | freebsdelf3.[2-9]* | \
+ freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1)
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ ;;
+ *) # from 4.6 on, and DragonFly
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ ;;
+ esac
+ ;;
+
+gnu*)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ hardcode_into_libs=yes
+ ;;
+
+hpux9* | hpux10* | hpux11*)
+ # Give a soname corresponding to the major version so that dld.sl refuses to
+ # link against other versions.
+ version_type=sunos
+ need_lib_prefix=no
+ need_version=no
+ case $host_cpu in
+ ia64*)
+ shrext_cmds='.so'
+ hardcode_into_libs=yes
+ dynamic_linker="$host_os dld.so"
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ if test "X$HPUX_IA64_MODE" = X32; then
+ sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib"
+ else
+ sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64"
+ fi
+ sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+ ;;
+ hppa*64*)
+ shrext_cmds='.sl'
+ hardcode_into_libs=yes
+ dynamic_linker="$host_os dld.sl"
+ shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH
+ shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64"
+ sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+ ;;
+ *)
+ shrext_cmds='.sl'
+ dynamic_linker="$host_os dld.sl"
+ shlibpath_var=SHLIB_PATH
+ shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ ;;
+ esac
+ # HP-UX runs *really* slowly unless shared libraries are mode 555.
+ postinstall_cmds='chmod 555 $lib'
+ ;;
+
+interix[3-9]*)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ ;;
+
+irix5* | irix6* | nonstopux*)
+ case $host_os in
+ nonstopux*) version_type=nonstopux ;;
+ *)
+ if test "$lt_cv_prog_gnu_ld" = yes; then
+ version_type=linux
+ else
+ version_type=irix
+ fi ;;
+ esac
+ need_lib_prefix=no
+ need_version=no
+ soname_spec='${libname}${release}${shared_ext}$major'
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}'
+ case $host_os in
+ irix5* | nonstopux*)
+ libsuff= shlibsuff=
+ ;;
+ *)
+ case $LD in # libtool.m4 will add one of these switches to LD
+ *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ")
+ libsuff= shlibsuff= libmagic=32-bit;;
+ *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ")
+ libsuff=32 shlibsuff=N32 libmagic=N32;;
+ *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ")
+ libsuff=64 shlibsuff=64 libmagic=64-bit;;
+ *) libsuff= shlibsuff= libmagic=never-match;;
+ esac
+ ;;
+ esac
+ shlibpath_var=LD_LIBRARY${shlibsuff}_PATH
+ shlibpath_overrides_runpath=no
+ sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}"
+ sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}"
+ hardcode_into_libs=yes
+ ;;
+
+# No shared lib support for Linux oldld, aout, or coff.
+linux*oldld* | linux*aout* | linux*coff*)
+ dynamic_linker=no
+ ;;
+
+# This must be Linux ELF.
+linux* | k*bsd*-gnu | kopensolaris*-gnu)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ # Some binutils ld are patched to set DT_RUNPATH
+ save_LDFLAGS=$LDFLAGS
+ save_libdir=$libdir
+ eval "libdir=/foo; wl=\"$lt_prog_compiler_wl_CXX\"; \
+ LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec_CXX\""
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_link") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_cxx_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest$ac_exeext && {
+ test "$cross_compiling" = yes ||
+ $as_test_x conftest$ac_exeext
+ }; then
+ if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then
+ shlibpath_overrides_runpath=yes
+fi
+
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+fi
+
+rm -rf conftest.dSYM
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+ conftest$ac_exeext conftest.$ac_ext
+ LDFLAGS=$save_LDFLAGS
+ libdir=$save_libdir
+
+ # This implies no fast_install, which is unacceptable.
+ # Some rework will be needed to allow for fast_install
+ # before this can be enabled.
+ hardcode_into_libs=yes
+
+ # Append ld.so.conf contents to the search path
+ if test -f /etc/ld.so.conf; then
+ lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '`
+ sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra"
+ fi
+
+ # We used to test for /lib/ld.so.1 and disable shared libraries on
+ # powerpc, because MkLinux only supported shared libraries with the
+ # GNU dynamic linker. Since this was broken with cross compilers,
+ # most powerpc-linux boxes support dynamic linking these days and
+ # people can always --disable-shared, the test was removed, and we
+ # assume the GNU/Linux dynamic linker is in use.
+ dynamic_linker='GNU/Linux ld.so'
+ ;;
+
+netbsdelf*-gnu)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ dynamic_linker='NetBSD ld.elf_so'
+ ;;
+
+netbsd*)
+ version_type=sunos
+ need_lib_prefix=no
+ need_version=no
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+ dynamic_linker='NetBSD (a.out) ld.so'
+ else
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ dynamic_linker='NetBSD ld.elf_so'
+ fi
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ ;;
+
+newsos6)
+ version_type=linux
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ ;;
+
+*nto* | *qnx*)
+ version_type=qnx
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ dynamic_linker='ldqnx.so'
+ ;;
+
+openbsd*)
+ version_type=sunos
+ sys_lib_dlsearch_path_spec="/usr/lib"
+ need_lib_prefix=no
+ # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs.
+ case $host_os in
+ openbsd3.3 | openbsd3.3.*) need_version=yes ;;
+ *) need_version=no ;;
+ esac
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+ case $host_os in
+ openbsd2.[89] | openbsd2.[89].*)
+ shlibpath_overrides_runpath=no
+ ;;
+ *)
+ shlibpath_overrides_runpath=yes
+ ;;
+ esac
+ else
+ shlibpath_overrides_runpath=yes
+ fi
+ ;;
+
+os2*)
+ libname_spec='$name'
+ shrext_cmds=".dll"
+ need_lib_prefix=no
+ library_names_spec='$libname${shared_ext} $libname.a'
+ dynamic_linker='OS/2 ld.exe'
+ shlibpath_var=LIBPATH
+ ;;
+
+osf3* | osf4* | osf5*)
+ version_type=osf
+ need_lib_prefix=no
+ need_version=no
+ soname_spec='${libname}${release}${shared_ext}$major'
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ shlibpath_var=LD_LIBRARY_PATH
+ sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib"
+ sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec"
+ ;;
+
+rdos*)
+ dynamic_linker=no
+ ;;
+
+solaris*)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ # ldd complains unless libraries are executable
+ postinstall_cmds='chmod +x $lib'
+ ;;
+
+sunos4*)
+ version_type=sunos
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+ finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ if test "$with_gnu_ld" = yes; then
+ need_lib_prefix=no
+ fi
+ need_version=yes
+ ;;
+
+sysv4 | sysv4.3*)
+ version_type=linux
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ case $host_vendor in
+ sni)
+ shlibpath_overrides_runpath=no
+ need_lib_prefix=no
+ runpath_var=LD_RUN_PATH
+ ;;
+ siemens)
+ need_lib_prefix=no
+ ;;
+ motorola)
+ need_lib_prefix=no
+ need_version=no
+ shlibpath_overrides_runpath=no
+ sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib'
+ ;;
+ esac
+ ;;
+
+sysv4*MP*)
+ if test -d /usr/nec ;then
+ version_type=linux
+ library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}'
+ soname_spec='$libname${shared_ext}.$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ fi
+ ;;
+
+sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+ version_type=freebsd-elf
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ if test "$with_gnu_ld" = yes; then
+ sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib'
+ else
+ sys_lib_search_path_spec='/usr/ccs/lib /usr/lib'
+ case $host_os in
+ sco3.2v5*)
+ sys_lib_search_path_spec="$sys_lib_search_path_spec /lib"
+ ;;
+ esac
+ fi
+ sys_lib_dlsearch_path_spec='/usr/lib'
+ ;;
+
+tpf*)
+ # TPF is a cross-target only. Preferred cross-host = GNU/Linux.
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ ;;
+
+uts4*)
+ version_type=linux
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ ;;
+
+*)
+ dynamic_linker=no
+ ;;
+esac
+{ $as_echo "$as_me:$LINENO: result: $dynamic_linker" >&5
+$as_echo "$dynamic_linker" >&6; }
+test "$dynamic_linker" = no && can_build_shared=no
+
+variables_saved_for_relink="PATH $shlibpath_var $runpath_var"
+if test "$GCC" = yes; then
+ variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH"
+fi
+
+if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then
+ sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec"
+fi
+if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then
+ sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec"
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ { $as_echo "$as_me:$LINENO: checking how to hardcode library paths into programs" >&5
+$as_echo_n "checking how to hardcode library paths into programs... " >&6; }
+hardcode_action_CXX=
+if test -n "$hardcode_libdir_flag_spec_CXX" ||
+ test -n "$runpath_var_CXX" ||
+ test "X$hardcode_automatic_CXX" = "Xyes" ; then
+
+ # We can hardcode non-existent directories.
+ if test "$hardcode_direct_CXX" != no &&
+ # If the only mechanism to avoid hardcoding is shlibpath_var, we
+ # have to relink, otherwise we might link with an installed library
+ # when we should be linking with a yet-to-be-installed one
+ ## test "$_LT_TAGVAR(hardcode_shlibpath_var, CXX)" != no &&
+ test "$hardcode_minus_L_CXX" != no; then
+ # Linking always hardcodes the temporary library directory.
+ hardcode_action_CXX=relink
+ else
+ # We can link without hardcoding, and we can hardcode nonexisting dirs.
+ hardcode_action_CXX=immediate
+ fi
+else
+ # We cannot hardcode anything, or else we can only hardcode existing
+ # directories.
+ hardcode_action_CXX=unsupported
+fi
+{ $as_echo "$as_me:$LINENO: result: $hardcode_action_CXX" >&5
+$as_echo "$hardcode_action_CXX" >&6; }
+
+if test "$hardcode_action_CXX" = relink ||
+ test "$inherit_rpath_CXX" = yes; then
+ # Fast installation is not supported
+ enable_fast_install=no
+elif test "$shlibpath_overrides_runpath" = yes ||
+ test "$enable_shared" = no; then
+ # Fast installation is not necessary
+ enable_fast_install=needless
+fi
+
+
+
+
+
+
+
+ fi # test -n "$compiler"
+
+ CC=$lt_save_CC
+ LDCXX=$LD
+ LD=$lt_save_LD
+ GCC=$lt_save_GCC
+ with_gnu_ld=$lt_save_with_gnu_ld
+ lt_cv_path_LDCXX=$lt_cv_path_LD
+ lt_cv_path_LD=$lt_save_path_LD
+ lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld
+ lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld
+fi # test "$_lt_caught_CXX_error" != yes
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ac_config_commands="$ac_config_commands libtool"
+
+
+
+
+# Only expand once:
+
+
+
+
+
+# Check whether some low-level functions/files are available
+{ $as_echo "$as_me:$LINENO: checking for ANSI C header files" >&5
+$as_echo_n "checking for ANSI C header files... " >&6; }
+if test "${ac_cv_header_stdc+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ ac_cv_header_stdc=yes
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_cv_header_stdc=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+if test $ac_cv_header_stdc = yes; then
+ # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <string.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "memchr" >/dev/null 2>&1; then
+ :
+else
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <stdlib.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "free" >/dev/null 2>&1; then
+ :
+else
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+ if test "$cross_compiling" = yes; then
+ :
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <ctype.h>
+#include <stdlib.h>
+#if ((' ' & 0x0FF) == 0x020)
+# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#else
+# define ISLOWER(c) \
+ (('a' <= (c) && (c) <= 'i') \
+ || ('j' <= (c) && (c) <= 'r') \
+ || ('s' <= (c) && (c) <= 'z'))
+# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
+#endif
+
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int
+main ()
+{
+ int i;
+ for (i = 0; i < 256; i++)
+ if (XOR (islower (i), ISLOWER (i))
+ || toupper (i) != TOUPPER (i))
+ return 2;
+ return 0;
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_link") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+ { (case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_try") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ :
+else
+ $as_echo "$as_me: program exited with status $ac_status" >&5
+$as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+ac_cv_header_stdc=no
+fi
+rm -rf conftest.dSYM
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+
+
+fi
+fi
+{ $as_echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5
+$as_echo "$ac_cv_header_stdc" >&6; }
+if test $ac_cv_header_stdc = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define STDC_HEADERS 1
+_ACEOF
+
+fi
+
+
+# These are tested for by AC_HEADER_STDC, but I check again to set the var
+if test "${ac_cv_header_stdint_h+set}" = set; then
+ { $as_echo "$as_me:$LINENO: checking for stdint.h" >&5
+$as_echo_n "checking for stdint.h... " >&6; }
+if test "${ac_cv_header_stdint_h+set}" = set; then
+ $as_echo_n "(cached) " >&6
+fi
+{ $as_echo "$as_me:$LINENO: result: $ac_cv_header_stdint_h" >&5
+$as_echo "$ac_cv_header_stdint_h" >&6; }
+else
+ # Is the header compilable?
+{ $as_echo "$as_me:$LINENO: checking stdint.h usability" >&5
+$as_echo_n "checking stdint.h usability... " >&6; }
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+#include <stdint.h>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ ac_header_compiler=yes
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_header_compiler=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+{ $as_echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+$as_echo "$ac_header_compiler" >&6; }
+
+# Is the header present?
+{ $as_echo "$as_me:$LINENO: checking stdint.h presence" >&5
+$as_echo_n "checking stdint.h presence... " >&6; }
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <stdint.h>
+_ACEOF
+if { (ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null && {
+ test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ }; then
+ ac_header_preproc=yes
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_header_preproc=no
+fi
+
+rm -f conftest.err conftest.$ac_ext
+{ $as_echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+$as_echo "$ac_header_preproc" >&6; }
+
+# So? What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+ yes:no: )
+ { $as_echo "$as_me:$LINENO: WARNING: stdint.h: accepted by the compiler, rejected by the preprocessor!" >&5
+$as_echo "$as_me: WARNING: stdint.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+ { $as_echo "$as_me:$LINENO: WARNING: stdint.h: proceeding with the compiler's result" >&5
+$as_echo "$as_me: WARNING: stdint.h: proceeding with the compiler's result" >&2;}
+ ac_header_preproc=yes
+ ;;
+ no:yes:* )
+ { $as_echo "$as_me:$LINENO: WARNING: stdint.h: present but cannot be compiled" >&5
+$as_echo "$as_me: WARNING: stdint.h: present but cannot be compiled" >&2;}
+ { $as_echo "$as_me:$LINENO: WARNING: stdint.h: check for missing prerequisite headers?" >&5
+$as_echo "$as_me: WARNING: stdint.h: check for missing prerequisite headers?" >&2;}
+ { $as_echo "$as_me:$LINENO: WARNING: stdint.h: see the Autoconf documentation" >&5
+$as_echo "$as_me: WARNING: stdint.h: see the Autoconf documentation" >&2;}
+ { $as_echo "$as_me:$LINENO: WARNING: stdint.h: section \"Present But Cannot Be Compiled\"" >&5
+$as_echo "$as_me: WARNING: stdint.h: section \"Present But Cannot Be Compiled\"" >&2;}
+ { $as_echo "$as_me:$LINENO: WARNING: stdint.h: proceeding with the preprocessor's result" >&5
+$as_echo "$as_me: WARNING: stdint.h: proceeding with the preprocessor's result" >&2;}
+ { $as_echo "$as_me:$LINENO: WARNING: stdint.h: in the future, the compiler will take precedence" >&5
+$as_echo "$as_me: WARNING: stdint.h: in the future, the compiler will take precedence" >&2;}
+ ( cat <<\_ASBOX
+## --------------------------------------------- ##
+## Report this to google-gflags@googlegroups.com ##
+## --------------------------------------------- ##
+_ASBOX
+ ) | sed "s/^/$as_me: WARNING: /" >&2
+ ;;
+esac
+{ $as_echo "$as_me:$LINENO: checking for stdint.h" >&5
+$as_echo_n "checking for stdint.h... " >&6; }
+if test "${ac_cv_header_stdint_h+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ ac_cv_header_stdint_h=$ac_header_preproc
+fi
+{ $as_echo "$as_me:$LINENO: result: $ac_cv_header_stdint_h" >&5
+$as_echo "$ac_cv_header_stdint_h" >&6; }
+
+fi
+if test $ac_cv_header_stdint_h = yes; then
+ ac_cv_have_stdint_h=1
+else
+ ac_cv_have_stdint_h=0
+fi
+
+
+if test "${ac_cv_header_sys_types_h+set}" = set; then
+ { $as_echo "$as_me:$LINENO: checking for sys/types.h" >&5
+$as_echo_n "checking for sys/types.h... " >&6; }
+if test "${ac_cv_header_sys_types_h+set}" = set; then
+ $as_echo_n "(cached) " >&6
+fi
+{ $as_echo "$as_me:$LINENO: result: $ac_cv_header_sys_types_h" >&5
+$as_echo "$ac_cv_header_sys_types_h" >&6; }
+else
+ # Is the header compilable?
+{ $as_echo "$as_me:$LINENO: checking sys/types.h usability" >&5
+$as_echo_n "checking sys/types.h usability... " >&6; }
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+#include <sys/types.h>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ ac_header_compiler=yes
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_header_compiler=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+{ $as_echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+$as_echo "$ac_header_compiler" >&6; }
+
+# Is the header present?
+{ $as_echo "$as_me:$LINENO: checking sys/types.h presence" >&5
+$as_echo_n "checking sys/types.h presence... " >&6; }
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <sys/types.h>
+_ACEOF
+if { (ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null && {
+ test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ }; then
+ ac_header_preproc=yes
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_header_preproc=no
+fi
+
+rm -f conftest.err conftest.$ac_ext
+{ $as_echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+$as_echo "$ac_header_preproc" >&6; }
+
+# So? What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+ yes:no: )
+ { $as_echo "$as_me:$LINENO: WARNING: sys/types.h: accepted by the compiler, rejected by the preprocessor!" >&5
+$as_echo "$as_me: WARNING: sys/types.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+ { $as_echo "$as_me:$LINENO: WARNING: sys/types.h: proceeding with the compiler's result" >&5
+$as_echo "$as_me: WARNING: sys/types.h: proceeding with the compiler's result" >&2;}
+ ac_header_preproc=yes
+ ;;
+ no:yes:* )
+ { $as_echo "$as_me:$LINENO: WARNING: sys/types.h: present but cannot be compiled" >&5
+$as_echo "$as_me: WARNING: sys/types.h: present but cannot be compiled" >&2;}
+ { $as_echo "$as_me:$LINENO: WARNING: sys/types.h: check for missing prerequisite headers?" >&5
+$as_echo "$as_me: WARNING: sys/types.h: check for missing prerequisite headers?" >&2;}
+ { $as_echo "$as_me:$LINENO: WARNING: sys/types.h: see the Autoconf documentation" >&5
+$as_echo "$as_me: WARNING: sys/types.h: see the Autoconf documentation" >&2;}
+ { $as_echo "$as_me:$LINENO: WARNING: sys/types.h: section \"Present But Cannot Be Compiled\"" >&5
+$as_echo "$as_me: WARNING: sys/types.h: section \"Present But Cannot Be Compiled\"" >&2;}
+ { $as_echo "$as_me:$LINENO: WARNING: sys/types.h: proceeding with the preprocessor's result" >&5
+$as_echo "$as_me: WARNING: sys/types.h: proceeding with the preprocessor's result" >&2;}
+ { $as_echo "$as_me:$LINENO: WARNING: sys/types.h: in the future, the compiler will take precedence" >&5
+$as_echo "$as_me: WARNING: sys/types.h: in the future, the compiler will take precedence" >&2;}
+ ( cat <<\_ASBOX
+## --------------------------------------------- ##
+## Report this to google-gflags@googlegroups.com ##
+## --------------------------------------------- ##
+_ASBOX
+ ) | sed "s/^/$as_me: WARNING: /" >&2
+ ;;
+esac
+{ $as_echo "$as_me:$LINENO: checking for sys/types.h" >&5
+$as_echo_n "checking for sys/types.h... " >&6; }
+if test "${ac_cv_header_sys_types_h+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ ac_cv_header_sys_types_h=$ac_header_preproc
+fi
+{ $as_echo "$as_me:$LINENO: result: $ac_cv_header_sys_types_h" >&5
+$as_echo "$ac_cv_header_sys_types_h" >&6; }
+
+fi
+if test $ac_cv_header_sys_types_h = yes; then
+ ac_cv_have_systypes_h=1
+else
+ ac_cv_have_systypes_h=0
+fi
+
+
+if test "${ac_cv_header_inttypes_h+set}" = set; then
+ { $as_echo "$as_me:$LINENO: checking for inttypes.h" >&5
+$as_echo_n "checking for inttypes.h... " >&6; }
+if test "${ac_cv_header_inttypes_h+set}" = set; then
+ $as_echo_n "(cached) " >&6
+fi
+{ $as_echo "$as_me:$LINENO: result: $ac_cv_header_inttypes_h" >&5
+$as_echo "$ac_cv_header_inttypes_h" >&6; }
+else
+ # Is the header compilable?
+{ $as_echo "$as_me:$LINENO: checking inttypes.h usability" >&5
+$as_echo_n "checking inttypes.h usability... " >&6; }
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+#include <inttypes.h>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ ac_header_compiler=yes
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_header_compiler=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+{ $as_echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+$as_echo "$ac_header_compiler" >&6; }
+
+# Is the header present?
+{ $as_echo "$as_me:$LINENO: checking inttypes.h presence" >&5
+$as_echo_n "checking inttypes.h presence... " >&6; }
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <inttypes.h>
+_ACEOF
+if { (ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null && {
+ test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ }; then
+ ac_header_preproc=yes
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_header_preproc=no
+fi
+
+rm -f conftest.err conftest.$ac_ext
+{ $as_echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+$as_echo "$ac_header_preproc" >&6; }
+
+# So? What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+ yes:no: )
+ { $as_echo "$as_me:$LINENO: WARNING: inttypes.h: accepted by the compiler, rejected by the preprocessor!" >&5
+$as_echo "$as_me: WARNING: inttypes.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+ { $as_echo "$as_me:$LINENO: WARNING: inttypes.h: proceeding with the compiler's result" >&5
+$as_echo "$as_me: WARNING: inttypes.h: proceeding with the compiler's result" >&2;}
+ ac_header_preproc=yes
+ ;;
+ no:yes:* )
+ { $as_echo "$as_me:$LINENO: WARNING: inttypes.h: present but cannot be compiled" >&5
+$as_echo "$as_me: WARNING: inttypes.h: present but cannot be compiled" >&2;}
+ { $as_echo "$as_me:$LINENO: WARNING: inttypes.h: check for missing prerequisite headers?" >&5
+$as_echo "$as_me: WARNING: inttypes.h: check for missing prerequisite headers?" >&2;}
+ { $as_echo "$as_me:$LINENO: WARNING: inttypes.h: see the Autoconf documentation" >&5
+$as_echo "$as_me: WARNING: inttypes.h: see the Autoconf documentation" >&2;}
+ { $as_echo "$as_me:$LINENO: WARNING: inttypes.h: section \"Present But Cannot Be Compiled\"" >&5
+$as_echo "$as_me: WARNING: inttypes.h: section \"Present But Cannot Be Compiled\"" >&2;}
+ { $as_echo "$as_me:$LINENO: WARNING: inttypes.h: proceeding with the preprocessor's result" >&5
+$as_echo "$as_me: WARNING: inttypes.h: proceeding with the preprocessor's result" >&2;}
+ { $as_echo "$as_me:$LINENO: WARNING: inttypes.h: in the future, the compiler will take precedence" >&5
+$as_echo "$as_me: WARNING: inttypes.h: in the future, the compiler will take precedence" >&2;}
+ ( cat <<\_ASBOX
+## --------------------------------------------- ##
+## Report this to google-gflags@googlegroups.com ##
+## --------------------------------------------- ##
+_ASBOX
+ ) | sed "s/^/$as_me: WARNING: /" >&2
+ ;;
+esac
+{ $as_echo "$as_me:$LINENO: checking for inttypes.h" >&5
+$as_echo_n "checking for inttypes.h... " >&6; }
+if test "${ac_cv_header_inttypes_h+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ ac_cv_header_inttypes_h=$ac_header_preproc
+fi
+{ $as_echo "$as_me:$LINENO: result: $ac_cv_header_inttypes_h" >&5
+$as_echo "$ac_cv_header_inttypes_h" >&6; }
+
+fi
+if test $ac_cv_header_inttypes_h = yes; then
+ ac_cv_have_inttypes_h=1
+else
+ ac_cv_have_inttypes_h=0
+fi
+
+
+
+for ac_header in fnmatch.h
+do
+as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+ { $as_echo "$as_me:$LINENO: checking for $ac_header" >&5
+$as_echo_n "checking for $ac_header... " >&6; }
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+ $as_echo_n "(cached) " >&6
+fi
+ac_res=`eval 'as_val=${'$as_ac_Header'}
+ $as_echo "$as_val"'`
+ { $as_echo "$as_me:$LINENO: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+else
+ # Is the header compilable?
+{ $as_echo "$as_me:$LINENO: checking $ac_header usability" >&5
+$as_echo_n "checking $ac_header usability... " >&6; }
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ ac_header_compiler=yes
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_header_compiler=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+{ $as_echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+$as_echo "$ac_header_compiler" >&6; }
+
+# Is the header present?
+{ $as_echo "$as_me:$LINENO: checking $ac_header presence" >&5
+$as_echo_n "checking $ac_header presence... " >&6; }
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <$ac_header>
+_ACEOF
+if { (ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null && {
+ test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ }; then
+ ac_header_preproc=yes
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_header_preproc=no
+fi
+
+rm -f conftest.err conftest.$ac_ext
+{ $as_echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+$as_echo "$ac_header_preproc" >&6; }
+
+# So? What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+ yes:no: )
+ { $as_echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
+$as_echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
+ { $as_echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
+$as_echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
+ ac_header_preproc=yes
+ ;;
+ no:yes:* )
+ { $as_echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
+$as_echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
+ { $as_echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5
+$as_echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;}
+ { $as_echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
+$as_echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
+ { $as_echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5
+$as_echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;}
+ { $as_echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
+$as_echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
+ { $as_echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
+$as_echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
+ ( cat <<\_ASBOX
+## --------------------------------------------- ##
+## Report this to google-gflags@googlegroups.com ##
+## --------------------------------------------- ##
+_ASBOX
+ ) | sed "s/^/$as_me: WARNING: /" >&2
+ ;;
+esac
+{ $as_echo "$as_me:$LINENO: checking for $ac_header" >&5
+$as_echo_n "checking for $ac_header... " >&6; }
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+ $as_echo_n "(cached) " >&6
+else
+ eval "$as_ac_Header=\$ac_header_preproc"
+fi
+ac_res=`eval 'as_val=${'$as_ac_Header'}
+ $as_echo "$as_val"'`
+ { $as_echo "$as_me:$LINENO: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+
+fi
+if test `eval 'as_val=${'$as_ac_Header'}
+ $as_echo "$as_val"'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+for ac_header in sys/stat.h
+do
+as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+ { $as_echo "$as_me:$LINENO: checking for $ac_header" >&5
+$as_echo_n "checking for $ac_header... " >&6; }
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+ $as_echo_n "(cached) " >&6
+fi
+ac_res=`eval 'as_val=${'$as_ac_Header'}
+ $as_echo "$as_val"'`
+ { $as_echo "$as_me:$LINENO: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+else
+ # Is the header compilable?
+{ $as_echo "$as_me:$LINENO: checking $ac_header usability" >&5
+$as_echo_n "checking $ac_header usability... " >&6; }
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ ac_header_compiler=yes
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_header_compiler=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+{ $as_echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+$as_echo "$ac_header_compiler" >&6; }
+
+# Is the header present?
+{ $as_echo "$as_me:$LINENO: checking $ac_header presence" >&5
+$as_echo_n "checking $ac_header presence... " >&6; }
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <$ac_header>
+_ACEOF
+if { (ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null && {
+ test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ }; then
+ ac_header_preproc=yes
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_header_preproc=no
+fi
+
+rm -f conftest.err conftest.$ac_ext
+{ $as_echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+$as_echo "$ac_header_preproc" >&6; }
+
+# So? What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+ yes:no: )
+ { $as_echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
+$as_echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
+ { $as_echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
+$as_echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
+ ac_header_preproc=yes
+ ;;
+ no:yes:* )
+ { $as_echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
+$as_echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
+ { $as_echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5
+$as_echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;}
+ { $as_echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
+$as_echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
+ { $as_echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5
+$as_echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;}
+ { $as_echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
+$as_echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
+ { $as_echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
+$as_echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
+ ( cat <<\_ASBOX
+## --------------------------------------------- ##
+## Report this to google-gflags@googlegroups.com ##
+## --------------------------------------------- ##
+_ASBOX
+ ) | sed "s/^/$as_me: WARNING: /" >&2
+ ;;
+esac
+{ $as_echo "$as_me:$LINENO: checking for $ac_header" >&5
+$as_echo_n "checking for $ac_header... " >&6; }
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+ $as_echo_n "(cached) " >&6
+else
+ eval "$as_ac_Header=\$ac_header_preproc"
+fi
+ac_res=`eval 'as_val=${'$as_ac_Header'}
+ $as_echo "$as_val"'`
+ { $as_echo "$as_me:$LINENO: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+
+fi
+if test `eval 'as_val=${'$as_ac_Header'}
+ $as_echo "$as_val"'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+for ac_header in unistd.h
+do
+as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+ { $as_echo "$as_me:$LINENO: checking for $ac_header" >&5
+$as_echo_n "checking for $ac_header... " >&6; }
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+ $as_echo_n "(cached) " >&6
+fi
+ac_res=`eval 'as_val=${'$as_ac_Header'}
+ $as_echo "$as_val"'`
+ { $as_echo "$as_me:$LINENO: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+else
+ # Is the header compilable?
+{ $as_echo "$as_me:$LINENO: checking $ac_header usability" >&5
+$as_echo_n "checking $ac_header usability... " >&6; }
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ ac_header_compiler=yes
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_header_compiler=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+{ $as_echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+$as_echo "$ac_header_compiler" >&6; }
+
+# Is the header present?
+{ $as_echo "$as_me:$LINENO: checking $ac_header presence" >&5
+$as_echo_n "checking $ac_header presence... " >&6; }
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <$ac_header>
+_ACEOF
+if { (ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null && {
+ test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ }; then
+ ac_header_preproc=yes
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_header_preproc=no
+fi
+
+rm -f conftest.err conftest.$ac_ext
+{ $as_echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+$as_echo "$ac_header_preproc" >&6; }
+
+# So? What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+ yes:no: )
+ { $as_echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
+$as_echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
+ { $as_echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
+$as_echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
+ ac_header_preproc=yes
+ ;;
+ no:yes:* )
+ { $as_echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
+$as_echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
+ { $as_echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5
+$as_echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;}
+ { $as_echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
+$as_echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
+ { $as_echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5
+$as_echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;}
+ { $as_echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
+$as_echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
+ { $as_echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
+$as_echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
+ ( cat <<\_ASBOX
+## --------------------------------------------- ##
+## Report this to google-gflags@googlegroups.com ##
+## --------------------------------------------- ##
+_ASBOX
+ ) | sed "s/^/$as_me: WARNING: /" >&2
+ ;;
+esac
+{ $as_echo "$as_me:$LINENO: checking for $ac_header" >&5
+$as_echo_n "checking for $ac_header... " >&6; }
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+ $as_echo_n "(cached) " >&6
+else
+ eval "$as_ac_Header=\$ac_header_preproc"
+fi
+ac_res=`eval 'as_val=${'$as_ac_Header'}
+ $as_echo "$as_val"'`
+ { $as_echo "$as_me:$LINENO: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+
+fi
+if test `eval 'as_val=${'$as_ac_Header'}
+ $as_echo "$as_val"'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+# These are the types I need. We look for them in either stdint.h,
+# sys/types.h, or inttypes.h, all of which are part of the default-includes.
+{ $as_echo "$as_me:$LINENO: checking for uint16_t" >&5
+$as_echo_n "checking for uint16_t... " >&6; }
+if test "${ac_cv_type_uint16_t+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ ac_cv_type_uint16_t=no
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+int
+main ()
+{
+if (sizeof (uint16_t))
+ return 0;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+int
+main ()
+{
+if (sizeof ((uint16_t)))
+ return 0;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ :
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_cv_type_uint16_t=yes
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:$LINENO: result: $ac_cv_type_uint16_t" >&5
+$as_echo "$ac_cv_type_uint16_t" >&6; }
+if test $ac_cv_type_uint16_t = yes; then
+ ac_cv_have_uint16_t=1
+else
+ ac_cv_have_uint16_t=0
+fi
+
+{ $as_echo "$as_me:$LINENO: checking for u_int16_t" >&5
+$as_echo_n "checking for u_int16_t... " >&6; }
+if test "${ac_cv_type_u_int16_t+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ ac_cv_type_u_int16_t=no
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+int
+main ()
+{
+if (sizeof (u_int16_t))
+ return 0;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+int
+main ()
+{
+if (sizeof ((u_int16_t)))
+ return 0;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ :
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_cv_type_u_int16_t=yes
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:$LINENO: result: $ac_cv_type_u_int16_t" >&5
+$as_echo "$ac_cv_type_u_int16_t" >&6; }
+if test $ac_cv_type_u_int16_t = yes; then
+ ac_cv_have_u_int16_t=1
+else
+ ac_cv_have_u_int16_t=0
+fi
+
+{ $as_echo "$as_me:$LINENO: checking for __int16" >&5
+$as_echo_n "checking for __int16... " >&6; }
+if test "${ac_cv_type___int16+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ ac_cv_type___int16=no
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+int
+main ()
+{
+if (sizeof (__int16))
+ return 0;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+int
+main ()
+{
+if (sizeof ((__int16)))
+ return 0;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ :
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_cv_type___int16=yes
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:$LINENO: result: $ac_cv_type___int16" >&5
+$as_echo "$ac_cv_type___int16" >&6; }
+if test $ac_cv_type___int16 = yes; then
+ ac_cv_have___int16=1
+else
+ ac_cv_have___int16=0
+fi
+
+
+
+
+for ac_func in strtoll strtoq
+do
+as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+{ $as_echo "$as_me:$LINENO: checking for $ac_func" >&5
+$as_echo_n "checking for $ac_func... " >&6; }
+if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then
+ $as_echo_n "(cached) " >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined __stub_$ac_func || defined __stub___$ac_func
+choke me
+#endif
+
+int
+main ()
+{
+return $ac_func ();
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_link") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest$ac_exeext && {
+ test "$cross_compiling" = yes ||
+ $as_test_x conftest$ac_exeext
+ }; then
+ eval "$as_ac_var=yes"
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ eval "$as_ac_var=no"
+fi
+
+rm -rf conftest.dSYM
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+ac_res=`eval 'as_val=${'$as_ac_var'}
+ $as_echo "$as_val"'`
+ { $as_echo "$as_me:$LINENO: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+if test `eval 'as_val=${'$as_ac_var'}
+ $as_echo "$as_val"'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+
+
+ { $as_echo "$as_me:$LINENO: checking for __attribute__" >&5
+$as_echo_n "checking for __attribute__... " >&6; }
+ if test "${ac_cv___attribute__+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <stdlib.h>
+ static void foo(void) __attribute__ ((unused));
+ void foo(void) { exit(1); }
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ ac_cv___attribute__=yes
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_cv___attribute__=no
+
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+ if test "$ac_cv___attribute__" = "yes"; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE___ATTRIBUTE__ 1
+_ACEOF
+
+ fi
+ { $as_echo "$as_me:$LINENO: result: $ac_cv___attribute__" >&5
+$as_echo "$ac_cv___attribute__" >&6; }
+
+# We only care about __attribute__ ((unused))
+if test x"$ac_cv___attribute__" = x"yes"; then
+ ac_cv___attribute__unused="__attribute__ ((unused))"
+else
+ ac_cv___attribute__unused=
+fi
+
+
+
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+acx_pthread_ok=no
+
+# We used to check for pthread.h first, but this fails if pthread.h
+# requires special compiler flags (e.g. on True64 or Sequent).
+# It gets checked for in the link test anyway.
+
+# First of all, check if the user has set any of the PTHREAD_LIBS,
+# etcetera environment variables, and if threads linking works using
+# them:
+if test x"$PTHREAD_LIBS$PTHREAD_CFLAGS" != x; then
+ save_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+ save_LIBS="$LIBS"
+ LIBS="$PTHREAD_LIBS $LIBS"
+ { $as_echo "$as_me:$LINENO: checking for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS" >&5
+$as_echo_n "checking for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS... " >&6; }
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char pthread_join ();
+int
+main ()
+{
+return pthread_join ();
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_link") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest$ac_exeext && {
+ test "$cross_compiling" = yes ||
+ $as_test_x conftest$ac_exeext
+ }; then
+ acx_pthread_ok=yes
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+fi
+
+rm -rf conftest.dSYM
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+ conftest$ac_exeext conftest.$ac_ext
+ { $as_echo "$as_me:$LINENO: result: $acx_pthread_ok" >&5
+$as_echo "$acx_pthread_ok" >&6; }
+ if test x"$acx_pthread_ok" = xno; then
+ PTHREAD_LIBS=""
+ PTHREAD_CFLAGS=""
+ fi
+ LIBS="$save_LIBS"
+ CFLAGS="$save_CFLAGS"
+fi
+
+# We must check for the threads library under a number of different
+# names; the ordering is very important because some systems
+# (e.g. DEC) have both -lpthread and -lpthreads, where one of the
+# libraries is broken (non-POSIX).
+
+# Create a list of thread flags to try. Items starting with a "-" are
+# C compiler flags, and other items are library names, except for "none"
+# which indicates that we try without any flags at all, and "pthread-config"
+# which is a program returning the flags for the Pth emulation library.
+
+acx_pthread_flags="pthreads none -Kthread -kthread lthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config"
+
+# The ordering *is* (sometimes) important. Some notes on the
+# individual items follow:
+
+# pthreads: AIX (must check this before -lpthread)
+# none: in case threads are in libc; should be tried before -Kthread and
+# other compiler flags to prevent continual compiler warnings
+# -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h)
+# -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able)
+# lthread: LinuxThreads port on FreeBSD (also preferred to -pthread)
+# -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads)
+# -pthreads: Solaris/gcc
+# -mthreads: Mingw32/gcc, Lynx/gcc
+# -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it
+# doesn't hurt to check since this sometimes defines pthreads too;
+# also defines -D_REENTRANT)
+# ... -mt is also the pthreads flag for HP/aCC
+# pthread: Linux, etcetera
+# --thread-safe: KAI C++
+# pthread-config: use pthread-config program (for GNU Pth library)
+
+case "${host_cpu}-${host_os}" in
+ *solaris*)
+
+ # On Solaris (at least, for some versions), libc contains stubbed
+ # (non-functional) versions of the pthreads routines, so link-based
+ # tests will erroneously succeed. (We need to link with -pthreads/-mt/
+ # -lpthread.) (The stubs are missing pthread_cleanup_push, or rather
+ # a function called by this macro, so we could check for that, but
+ # who knows whether they'll stub that too in a future libc.) So,
+ # we'll just look for -pthreads and -lpthread first:
+
+ acx_pthread_flags="-pthreads pthread -mt -pthread $acx_pthread_flags"
+ ;;
+esac
+
+if test x"$acx_pthread_ok" = xno; then
+for flag in $acx_pthread_flags; do
+
+ case $flag in
+ none)
+ { $as_echo "$as_me:$LINENO: checking whether pthreads work without any flags" >&5
+$as_echo_n "checking whether pthreads work without any flags... " >&6; }
+ ;;
+
+ -*)
+ { $as_echo "$as_me:$LINENO: checking whether pthreads work with $flag" >&5
+$as_echo_n "checking whether pthreads work with $flag... " >&6; }
+ PTHREAD_CFLAGS="$flag"
+ ;;
+
+ pthread-config)
+ # Extract the first word of "pthread-config", so it can be a program name with args.
+set dummy pthread-config; ac_word=$2
+{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_acx_pthread_config+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$acx_pthread_config"; then
+ ac_cv_prog_acx_pthread_config="$acx_pthread_config" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_acx_pthread_config="yes"
+ $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+IFS=$as_save_IFS
+
+ test -z "$ac_cv_prog_acx_pthread_config" && ac_cv_prog_acx_pthread_config="no"
+fi
+fi
+acx_pthread_config=$ac_cv_prog_acx_pthread_config
+if test -n "$acx_pthread_config"; then
+ { $as_echo "$as_me:$LINENO: result: $acx_pthread_config" >&5
+$as_echo "$acx_pthread_config" >&6; }
+else
+ { $as_echo "$as_me:$LINENO: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ if test x"$acx_pthread_config" = xno; then continue; fi
+ PTHREAD_CFLAGS="`pthread-config --cflags`"
+ PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`"
+ ;;
+
+ *)
+ { $as_echo "$as_me:$LINENO: checking for the pthreads library -l$flag" >&5
+$as_echo_n "checking for the pthreads library -l$flag... " >&6; }
+ PTHREAD_LIBS="-l$flag"
+ ;;
+ esac
+
+ save_LIBS="$LIBS"
+ save_CFLAGS="$CFLAGS"
+ LIBS="$PTHREAD_LIBS $LIBS"
+ CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+
+ # Check for various functions. We must include pthread.h,
+ # since some functions may be macros. (On the Sequent, we
+ # need a special flag -Kthread to make this header compile.)
+ # We check for pthread_join because it is in -lpthread on IRIX
+ # while pthread_create is in libc. We check for pthread_attr_init
+ # due to DEC craziness with -lpthreads. We check for
+ # pthread_cleanup_push because it is one of the few pthread
+ # functions on Solaris that doesn't have a non-functional libc stub.
+ # We try pthread_create on general principles.
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <pthread.h>
+int
+main ()
+{
+pthread_t th; pthread_join(th, 0);
+ pthread_attr_init(0); pthread_cleanup_push(0, 0);
+ pthread_create(0,0,0,0); pthread_cleanup_pop(0);
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_link") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest$ac_exeext && {
+ test "$cross_compiling" = yes ||
+ $as_test_x conftest$ac_exeext
+ }; then
+ acx_pthread_ok=yes
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+fi
+
+rm -rf conftest.dSYM
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+ conftest$ac_exeext conftest.$ac_ext
+
+ LIBS="$save_LIBS"
+ CFLAGS="$save_CFLAGS"
+
+ { $as_echo "$as_me:$LINENO: result: $acx_pthread_ok" >&5
+$as_echo "$acx_pthread_ok" >&6; }
+ if test "x$acx_pthread_ok" = xyes; then
+ break;
+ fi
+
+ PTHREAD_LIBS=""
+ PTHREAD_CFLAGS=""
+done
+fi
+
+# Various other checks:
+if test "x$acx_pthread_ok" = xyes; then
+ save_LIBS="$LIBS"
+ LIBS="$PTHREAD_LIBS $LIBS"
+ save_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+
+ # Detect AIX lossage: JOINABLE attribute is called UNDETACHED.
+ { $as_echo "$as_me:$LINENO: checking for joinable pthread attribute" >&5
+$as_echo_n "checking for joinable pthread attribute... " >&6; }
+ attr_name=unknown
+ for attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <pthread.h>
+int
+main ()
+{
+int attr=$attr; return attr;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_link") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest$ac_exeext && {
+ test "$cross_compiling" = yes ||
+ $as_test_x conftest$ac_exeext
+ }; then
+ attr_name=$attr; break
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+fi
+
+rm -rf conftest.dSYM
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+ conftest$ac_exeext conftest.$ac_ext
+ done
+ { $as_echo "$as_me:$LINENO: result: $attr_name" >&5
+$as_echo "$attr_name" >&6; }
+ if test "$attr_name" != PTHREAD_CREATE_JOINABLE; then
+
+cat >>confdefs.h <<_ACEOF
+#define PTHREAD_CREATE_JOINABLE $attr_name
+_ACEOF
+
+ fi
+
+ { $as_echo "$as_me:$LINENO: checking if more special flags are required for pthreads" >&5
+$as_echo_n "checking if more special flags are required for pthreads... " >&6; }
+ flag=no
+ case "${host_cpu}-${host_os}" in
+ *-aix* | *-freebsd* | *-darwin*) flag="-D_THREAD_SAFE";;
+ *solaris* | *-osf* | *-hpux*) flag="-D_REENTRANT";;
+ esac
+ { $as_echo "$as_me:$LINENO: result: ${flag}" >&5
+$as_echo "${flag}" >&6; }
+ if test "x$flag" != xno; then
+ PTHREAD_CFLAGS="$flag $PTHREAD_CFLAGS"
+ fi
+
+ LIBS="$save_LIBS"
+ CFLAGS="$save_CFLAGS"
+ # More AIX lossage: must compile with xlc_r or cc_r
+ if test x"$GCC" != xyes; then
+ for ac_prog in xlc_r cc_r
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_PTHREAD_CC+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$PTHREAD_CC"; then
+ ac_cv_prog_PTHREAD_CC="$PTHREAD_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_PTHREAD_CC="$ac_prog"
+ $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+PTHREAD_CC=$ac_cv_prog_PTHREAD_CC
+if test -n "$PTHREAD_CC"; then
+ { $as_echo "$as_me:$LINENO: result: $PTHREAD_CC" >&5
+$as_echo "$PTHREAD_CC" >&6; }
+else
+ { $as_echo "$as_me:$LINENO: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$PTHREAD_CC" && break
+done
+test -n "$PTHREAD_CC" || PTHREAD_CC="${CC}"
+
+ else
+ PTHREAD_CC=$CC
+ fi
+
+ # The next part tries to detect GCC inconsistency with -shared on some
+ # architectures and systems. The problem is that in certain
+ # configurations, when -shared is specified, GCC "forgets" to
+ # internally use various flags which are still necessary.
+
+ #
+ # Prepare the flags
+ #
+ save_CFLAGS="$CFLAGS"
+ save_LIBS="$LIBS"
+ save_CC="$CC"
+
+ # Try with the flags determined by the earlier checks.
+ #
+ # -Wl,-z,defs forces link-time symbol resolution, so that the
+ # linking checks with -shared actually have any value
+ #
+ # FIXME: -fPIC is required for -shared on many architectures,
+ # so we specify it here, but the right way would probably be to
+ # properly detect whether it is actually required.
+ CFLAGS="-shared -fPIC -Wl,-z,defs $CFLAGS $PTHREAD_CFLAGS"
+ LIBS="$PTHREAD_LIBS $LIBS"
+ CC="$PTHREAD_CC"
+
+ # In order not to create several levels of indentation, we test
+ # the value of "$done" until we find the cure or run out of ideas.
+ done="no"
+
+ # First, make sure the CFLAGS we added are actually accepted by our
+ # compiler. If not (and OS X's ld, for instance, does not accept -z),
+ # then we can't do this test.
+ if test x"$done" = xno; then
+ { $as_echo "$as_me:$LINENO: checking whether to check for GCC pthread/shared inconsistencies" >&5
+$as_echo_n "checking whether to check for GCC pthread/shared inconsistencies... " >&6; }
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_link") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest$ac_exeext && {
+ test "$cross_compiling" = yes ||
+ $as_test_x conftest$ac_exeext
+ }; then
+ :
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ done=yes
+fi
+
+rm -rf conftest.dSYM
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+ conftest$ac_exeext conftest.$ac_ext
+
+ if test "x$done" = xyes ; then
+ { $as_echo "$as_me:$LINENO: result: no" >&5
+$as_echo "no" >&6; }
+ else
+ { $as_echo "$as_me:$LINENO: result: yes" >&5
+$as_echo "yes" >&6; }
+ fi
+ fi
+
+ if test x"$done" = xno; then
+ { $as_echo "$as_me:$LINENO: checking whether -pthread is sufficient with -shared" >&5
+$as_echo_n "checking whether -pthread is sufficient with -shared... " >&6; }
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <pthread.h>
+int
+main ()
+{
+pthread_t th; pthread_join(th, 0);
+ pthread_attr_init(0); pthread_cleanup_push(0, 0);
+ pthread_create(0,0,0,0); pthread_cleanup_pop(0);
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_link") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest$ac_exeext && {
+ test "$cross_compiling" = yes ||
+ $as_test_x conftest$ac_exeext
+ }; then
+ done=yes
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+fi
+
+rm -rf conftest.dSYM
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+ conftest$ac_exeext conftest.$ac_ext
+
+ if test "x$done" = xyes; then
+ { $as_echo "$as_me:$LINENO: result: yes" >&5
+$as_echo "yes" >&6; }
+ else
+ { $as_echo "$as_me:$LINENO: result: no" >&5
+$as_echo "no" >&6; }
+ fi
+ fi
+
+ #
+ # Linux gcc on some architectures such as mips/mipsel forgets
+ # about -lpthread
+ #
+ if test x"$done" = xno; then
+ { $as_echo "$as_me:$LINENO: checking whether -lpthread fixes that" >&5
+$as_echo_n "checking whether -lpthread fixes that... " >&6; }
+ LIBS="-lpthread $PTHREAD_LIBS $save_LIBS"
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <pthread.h>
+int
+main ()
+{
+pthread_t th; pthread_join(th, 0);
+ pthread_attr_init(0); pthread_cleanup_push(0, 0);
+ pthread_create(0,0,0,0); pthread_cleanup_pop(0);
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_link") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest$ac_exeext && {
+ test "$cross_compiling" = yes ||
+ $as_test_x conftest$ac_exeext
+ }; then
+ done=yes
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+fi
+
+rm -rf conftest.dSYM
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+ conftest$ac_exeext conftest.$ac_ext
+
+ if test "x$done" = xyes; then
+ { $as_echo "$as_me:$LINENO: result: yes" >&5
+$as_echo "yes" >&6; }
+ PTHREAD_LIBS="-lpthread $PTHREAD_LIBS"
+ else
+ { $as_echo "$as_me:$LINENO: result: no" >&5
+$as_echo "no" >&6; }
+ fi
+ fi
+ #
+ # FreeBSD 4.10 gcc forgets to use -lc_r instead of -lc
+ #
+ if test x"$done" = xno; then
+ { $as_echo "$as_me:$LINENO: checking whether -lc_r fixes that" >&5
+$as_echo_n "checking whether -lc_r fixes that... " >&6; }
+ LIBS="-lc_r $PTHREAD_LIBS $save_LIBS"
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <pthread.h>
+int
+main ()
+{
+pthread_t th; pthread_join(th, 0);
+ pthread_attr_init(0); pthread_cleanup_push(0, 0);
+ pthread_create(0,0,0,0); pthread_cleanup_pop(0);
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_link") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest$ac_exeext && {
+ test "$cross_compiling" = yes ||
+ $as_test_x conftest$ac_exeext
+ }; then
+ done=yes
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+fi
+
+rm -rf conftest.dSYM
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+ conftest$ac_exeext conftest.$ac_ext
+
+ if test "x$done" = xyes; then
+ { $as_echo "$as_me:$LINENO: result: yes" >&5
+$as_echo "yes" >&6; }
+ PTHREAD_LIBS="-lc_r $PTHREAD_LIBS"
+ else
+ { $as_echo "$as_me:$LINENO: result: no" >&5
+$as_echo "no" >&6; }
+ fi
+ fi
+ if test x"$done" = xno; then
+ # OK, we have run out of ideas
+ { $as_echo "$as_me:$LINENO: WARNING: Impossible to determine how to use pthreads with shared libraries" >&5
+$as_echo "$as_me: WARNING: Impossible to determine how to use pthreads with shared libraries" >&2;}
+
+ # so it's not safe to assume that we may use pthreads
+ acx_pthread_ok=no
+ fi
+
+ { $as_echo "$as_me:$LINENO: checking whether what we have so far is sufficient with -nostdlib" >&5
+$as_echo_n "checking whether what we have so far is sufficient with -nostdlib... " >&6; }
+ CFLAGS="-nostdlib $CFLAGS"
+ # we need c with nostdlib
+ LIBS="$LIBS -lc"
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <pthread.h>
+int
+main ()
+{
+pthread_t th; pthread_join(th, 0);
+ pthread_attr_init(0); pthread_cleanup_push(0, 0);
+ pthread_create(0,0,0,0); pthread_cleanup_pop(0);
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_link") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest$ac_exeext && {
+ test "$cross_compiling" = yes ||
+ $as_test_x conftest$ac_exeext
+ }; then
+ done=yes
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ done=no
+fi
+
+rm -rf conftest.dSYM
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+ conftest$ac_exeext conftest.$ac_ext
+
+ if test "x$done" = xyes; then
+ { $as_echo "$as_me:$LINENO: result: yes" >&5
+$as_echo "yes" >&6; }
+ else
+ { $as_echo "$as_me:$LINENO: result: no" >&5
+$as_echo "no" >&6; }
+ fi
+
+ if test x"$done" = xno; then
+ { $as_echo "$as_me:$LINENO: checking whether -lpthread saves the day" >&5
+$as_echo_n "checking whether -lpthread saves the day... " >&6; }
+ LIBS="-lpthread $LIBS"
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <pthread.h>
+int
+main ()
+{
+pthread_t th; pthread_join(th, 0);
+ pthread_attr_init(0); pthread_cleanup_push(0, 0);
+ pthread_create(0,0,0,0); pthread_cleanup_pop(0);
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_link") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest$ac_exeext && {
+ test "$cross_compiling" = yes ||
+ $as_test_x conftest$ac_exeext
+ }; then
+ done=yes
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ done=no
+fi
+
+rm -rf conftest.dSYM
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+ conftest$ac_exeext conftest.$ac_ext
+
+ if test "x$done" = xyes; then
+ { $as_echo "$as_me:$LINENO: result: yes" >&5
+$as_echo "yes" >&6; }
+ PTHREAD_LIBS="$PTHREAD_LIBS -lpthread"
+ else
+ { $as_echo "$as_me:$LINENO: result: no" >&5
+$as_echo "no" >&6; }
+ { $as_echo "$as_me:$LINENO: WARNING: Impossible to determine how to use pthreads with shared libraries and -nostdlib" >&5
+$as_echo "$as_me: WARNING: Impossible to determine how to use pthreads with shared libraries and -nostdlib" >&2;}
+ fi
+ fi
+
+ CFLAGS="$save_CFLAGS"
+ LIBS="$save_LIBS"
+ CC="$save_CC"
+else
+ PTHREAD_CC="$CC"
+fi
+
+
+
+
+
+# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND:
+if test x"$acx_pthread_ok" = xyes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_PTHREAD 1
+_ACEOF
+
+ :
+else
+ acx_pthread_ok=no
+
+fi
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+
+# Find out what namespace 'normal' STL code lives in, and also what namespace
+# the user wants our classes to be defined in
+{ $as_echo "$as_me:$LINENO: checking whether the compiler implements namespaces" >&5
+$as_echo_n "checking whether the compiler implements namespaces... " >&6; }
+if test "${ac_cv_cxx_namespaces+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+
+ ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+namespace Outer {
+ namespace Inner { int i = 0; }}
+int
+main ()
+{
+using namespace Outer::Inner; return i;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_cxx_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ ac_cv_cxx_namespaces=yes
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_cv_cxx_namespaces=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+fi
+{ $as_echo "$as_me:$LINENO: result: $ac_cv_cxx_namespaces" >&5
+$as_echo "$ac_cv_cxx_namespaces" >&6; }
+ if test "$ac_cv_cxx_namespaces" = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_NAMESPACES 1
+_ACEOF
+
+ fi
+{ $as_echo "$as_me:$LINENO: checking what namespace STL code is in" >&5
+$as_echo_n "checking what namespace STL code is in... " >&6; }
+if test "${ac_cv_cxx_stl_namespace+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+
+
+ ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <vector>
+int
+main ()
+{
+vector<int> t; return 0;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_cxx_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ ac_cv_cxx_stl_namespace=none
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <vector>
+int
+main ()
+{
+std::vector<int> t; return 0;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_cxx_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ ac_cv_cxx_stl_namespace=std
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+fi
+{ $as_echo "$as_me:$LINENO: result: $ac_cv_cxx_stl_namespace" >&5
+$as_echo "$ac_cv_cxx_stl_namespace" >&6; }
+ if test "$ac_cv_cxx_stl_namespace" = none; then
+
+cat >>confdefs.h <<\_ACEOF
+#define STL_NAMESPACE /**/
+_ACEOF
+
+ fi
+ if test "$ac_cv_cxx_stl_namespace" = std; then
+
+cat >>confdefs.h <<\_ACEOF
+#define STL_NAMESPACE std
+_ACEOF
+
+ fi
+
+# TODO(csilvers): this should be renamed to gflags.
+google_namespace_default=google
+ # Check whether --enable-namespace was given.
+if test "${enable_namespace+set}" = set; then
+ enableval=$enable_namespace; case "$enableval" in
+ yes) google_namespace="$google_namespace_default" ;;
+ no) google_namespace="" ;;
+ *) google_namespace="$enableval" ;;
+ esac
+else
+ google_namespace="$google_namespace_default"
+fi
+
+ if test -n "$google_namespace"; then
+ ac_google_namespace="::$google_namespace"
+ ac_google_start_namespace="namespace $google_namespace {"
+ ac_google_end_namespace="}"
+ else
+ ac_google_namespace=""
+ ac_google_start_namespace=""
+ ac_google_end_namespace=""
+ fi
+
+cat >>confdefs.h <<_ACEOF
+#define GOOGLE_NAMESPACE $ac_google_namespace
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define _START_GOOGLE_NAMESPACE_ $ac_google_start_namespace
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define _END_GOOGLE_NAMESPACE_ $ac_google_end_namespace
+_ACEOF
+
+
+
+# Solaris 10 6/06 has a bug where /usr/sfw/lib/libstdc++.la is empty.
+# If so, we replace it with our own version.
+LIBSTDCXX_LA_LINKER_FLAG=
+if test -f /usr/sfw/lib/libstdc++.la && ! test -s /usr/sfw/lib/libstdc++.la
+then
+ LIBSTDCXX_LA_LINKER_FLAG='-L$(top_srcdir)/src/solaris'
+fi
+
+
+# These are what's needed by gflags.h.in
+
+
+
+
+
+
+
+
+
+
+
+## Check out ../autoconf/ for other macros you can call to do useful stuff
+
+# For windows, this has a non-trivial value (__declspec(export)), but any
+# system that uses configure wants this to be the empty string.
+
+cat >>confdefs.h <<\_ACEOF
+#define GFLAGS_DLL_DECL /**/
+_ACEOF
+
+
+# Write generated configuration file, and also .h files
+ac_config_files="$ac_config_files Makefile src/gflags/gflags.h src/gflags/gflags_declare.h src/gflags/gflags_completions.h"
+
+cat >confcache <<\_ACEOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs, see configure's option --config-cache.
+# It is not useful on other systems. If it contains results you don't
+# want to keep, you may remove or edit it.
+#
+# config.status only pays attention to the cache file if you give it
+# the --recheck option to rerun configure.
+#
+# `ac_cv_env_foo' variables (set or unset) will be overridden when
+# loading this file, other *unset* `ac_cv_foo' will be assigned the
+# following values.
+
+_ACEOF
+
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, we kill variables containing newlines.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(
+ for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do
+ eval ac_val=\$$ac_var
+ case $ac_val in #(
+ *${as_nl}*)
+ case $ac_var in #(
+ *_cv_*) { $as_echo "$as_me:$LINENO: WARNING: Cache variable $ac_var contains a newline." >&5
+$as_echo "$as_me: WARNING: Cache variable $ac_var contains a newline." >&2;} ;;
+ esac
+ case $ac_var in #(
+ _ | IFS | as_nl) ;; #(
+ BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(
+ *) $as_unset $ac_var ;;
+ esac ;;
+ esac
+ done
+
+ (set) 2>&1 |
+ case $as_nl`(ac_space=' '; set) 2>&1` in #(
+ *${as_nl}ac_space=\ *)
+ # `set' does not quote correctly, so add quotes (double-quote
+ # substitution turns \\\\ into \\, and sed turns \\ into \).
+ sed -n \
+ "s/'/'\\\\''/g;
+ s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"
+ ;; #(
+ *)
+ # `set' quotes correctly as required by POSIX, so do not add quotes.
+ sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
+ ;;
+ esac |
+ sort
+) |
+ sed '
+ /^ac_cv_env_/b end
+ t clear
+ :clear
+ s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/
+ t end
+ s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
+ :end' >>confcache
+if diff "$cache_file" confcache >/dev/null 2>&1; then :; else
+ if test -w "$cache_file"; then
+ test "x$cache_file" != "x/dev/null" &&
+ { $as_echo "$as_me:$LINENO: updating cache $cache_file" >&5
+$as_echo "$as_me: updating cache $cache_file" >&6;}
+ cat confcache >$cache_file
+ else
+ { $as_echo "$as_me:$LINENO: not updating unwritable cache $cache_file" >&5
+$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;}
+ fi
+fi
+rm -f confcache
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+DEFS=-DHAVE_CONFIG_H
+
+ac_libobjs=
+ac_ltlibobjs=
+for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue
+ # 1. Remove the extension, and $U if already installed.
+ ac_script='s/\$U\././;s/\.o$//;s/\.obj$//'
+ ac_i=`$as_echo "$ac_i" | sed "$ac_script"`
+ # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR
+ # will be set to the directory where LIBOBJS objects are built.
+ ac_libobjs="$ac_libobjs \${LIBOBJDIR}$ac_i\$U.$ac_objext"
+ ac_ltlibobjs="$ac_ltlibobjs \${LIBOBJDIR}$ac_i"'$U.lo'
+done
+LIBOBJS=$ac_libobjs
+
+LTLIBOBJS=$ac_ltlibobjs
+
+
+if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then
+ { { $as_echo "$as_me:$LINENO: error: conditional \"AMDEP\" was never defined.
+Usually this means the macro was only invoked conditionally." >&5
+$as_echo "$as_me: error: conditional \"AMDEP\" was never defined.
+Usually this means the macro was only invoked conditionally." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+if test -z "${am__fastdepCXX_TRUE}" && test -z "${am__fastdepCXX_FALSE}"; then
+ { { $as_echo "$as_me:$LINENO: error: conditional \"am__fastdepCXX\" was never defined.
+Usually this means the macro was only invoked conditionally." >&5
+$as_echo "$as_me: error: conditional \"am__fastdepCXX\" was never defined.
+Usually this means the macro was only invoked conditionally." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then
+ { { $as_echo "$as_me:$LINENO: error: conditional \"am__fastdepCC\" was never defined.
+Usually this means the macro was only invoked conditionally." >&5
+$as_echo "$as_me: error: conditional \"am__fastdepCC\" was never defined.
+Usually this means the macro was only invoked conditionally." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+if test -z "${GCC_TRUE}" && test -z "${GCC_FALSE}"; then
+ { { $as_echo "$as_me:$LINENO: error: conditional \"GCC\" was never defined.
+Usually this means the macro was only invoked conditionally." >&5
+$as_echo "$as_me: error: conditional \"GCC\" was never defined.
+Usually this means the macro was only invoked conditionally." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+if test -z "${am__fastdepCXX_TRUE}" && test -z "${am__fastdepCXX_FALSE}"; then
+ { { $as_echo "$as_me:$LINENO: error: conditional \"am__fastdepCXX\" was never defined.
+Usually this means the macro was only invoked conditionally." >&5
+$as_echo "$as_me: error: conditional \"am__fastdepCXX\" was never defined.
+Usually this means the macro was only invoked conditionally." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+
+: ${CONFIG_STATUS=./config.status}
+ac_write_fail=0
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files $CONFIG_STATUS"
+{ $as_echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5
+$as_echo "$as_me: creating $CONFIG_STATUS" >&6;}
+cat >$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+#! $SHELL
+# Generated by $as_me.
+# Run this file to recreate the current configuration.
+# Compiler output produced by configure, useful for debugging
+# configure, is in config.log if it exists.
+
+debug=false
+ac_cs_recheck=false
+ac_cs_silent=false
+SHELL=\${CONFIG_SHELL-$SHELL}
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+## --------------------- ##
+## M4sh Initialization. ##
+## --------------------- ##
+
+# Be more Bourne compatible
+DUALCASE=1; export DUALCASE # for MKS sh
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+ emulate sh
+ NULLCMD=:
+ # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '${1+"$@"}'='"$@"'
+ setopt NO_GLOB_SUBST
+else
+ case `(set -o) 2>/dev/null` in
+ *posix*) set -o posix ;;
+esac
+
+fi
+
+
+
+
+# PATH needs CR
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+as_nl='
+'
+export as_nl
+# Printing a long string crashes Solaris 7 /usr/bin/printf.
+as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
+if (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
+ as_echo='printf %s\n'
+ as_echo_n='printf %s'
+else
+ if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
+ as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
+ as_echo_n='/usr/ucb/echo -n'
+ else
+ as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
+ as_echo_n_body='eval
+ arg=$1;
+ case $arg in
+ *"$as_nl"*)
+ expr "X$arg" : "X\\(.*\\)$as_nl";
+ arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
+ esac;
+ expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
+ '
+ export as_echo_n_body
+ as_echo_n='sh -c $as_echo_n_body as_echo'
+ fi
+ export as_echo_body
+ as_echo='sh -c $as_echo_body as_echo'
+fi
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+ PATH_SEPARATOR=:
+ (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
+ (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
+ PATH_SEPARATOR=';'
+ }
+fi
+
+# Support unset when possible.
+if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+ as_unset=unset
+else
+ as_unset=false
+fi
+
+
+# IFS
+# We need space, tab and new line, in precisely that order. Quoting is
+# there to prevent editors from complaining about space-tab.
+# (If _AS_PATH_WALK were called with IFS unset, it would disable word
+# splitting by setting IFS to empty value.)
+IFS=" "" $as_nl"
+
+# Find who we are. Look in the path if we contain no directory separator.
+case $0 in
+ *[\\/]* ) as_myself=$0 ;;
+ *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+done
+IFS=$as_save_IFS
+
+ ;;
+esac
+# We did not find ourselves, most probably we were run as `sh COMMAND'
+# in which case we are not to be found in the path.
+if test "x$as_myself" = x; then
+ as_myself=$0
+fi
+if test ! -f "$as_myself"; then
+ $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+ { (exit 1); exit 1; }
+fi
+
+# Work around bugs in pre-3.0 UWIN ksh.
+for as_var in ENV MAIL MAILPATH
+do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var
+done
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+LC_ALL=C
+export LC_ALL
+LANGUAGE=C
+export LANGUAGE
+
+# Required to use basename.
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+ test "X`expr 00001 : '.*\(...\)'`" = X001; then
+ as_expr=expr
+else
+ as_expr=false
+fi
+
+if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
+ as_basename=basename
+else
+ as_basename=false
+fi
+
+
+# Name of the executable.
+as_me=`$as_basename -- "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+ X"$0" : 'X\(//\)$' \| \
+ X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X/"$0" |
+ sed '/^.*\/\([^/][^/]*\)\/*$/{
+ s//\1/
+ q
+ }
+ /^X\/\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\/\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+
+# CDPATH.
+$as_unset CDPATH
+
+
+
+ as_lineno_1=$LINENO
+ as_lineno_2=$LINENO
+ test "x$as_lineno_1" != "x$as_lineno_2" &&
+ test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || {
+
+ # Create $as_me.lineno as a copy of $as_myself, but with $LINENO
+ # uniformly replaced by the line number. The first 'sed' inserts a
+ # line-number line after each line using $LINENO; the second 'sed'
+ # does the real work. The second script uses 'N' to pair each
+ # line-number line with the line containing $LINENO, and appends
+ # trailing '-' during substitution so that $LINENO is not a special
+ # case at line end.
+ # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the
+ # scripts with optimization help from Paolo Bonzini. Blame Lee
+ # E. McMahon (1931-1989) for sed's syntax. :-)
+ sed -n '
+ p
+ /[$]LINENO/=
+ ' <$as_myself |
+ sed '
+ s/[$]LINENO.*/&-/
+ t lineno
+ b
+ :lineno
+ N
+ :loop
+ s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/
+ t loop
+ s/-\n.*//
+ ' >$as_me.lineno &&
+ chmod +x "$as_me.lineno" ||
+ { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2
+ { (exit 1); exit 1; }; }
+
+ # Don't try to exec as it changes $[0], causing all sort of problems
+ # (the dirname of $[0] is not the place where we might find the
+ # original and so on. Autoconf is especially sensitive to this).
+ . "./$as_me.lineno"
+ # Exit status is that of the last command.
+ exit
+}
+
+
+if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
+ as_dirname=dirname
+else
+ as_dirname=false
+fi
+
+ECHO_C= ECHO_N= ECHO_T=
+case `echo -n x` in
+-n*)
+ case `echo 'x\c'` in
+ *c*) ECHO_T=' ';; # ECHO_T is single tab character.
+ *) ECHO_C='\c';;
+ esac;;
+*)
+ ECHO_N='-n';;
+esac
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+ test "X`expr 00001 : '.*\(...\)'`" = X001; then
+ as_expr=expr
+else
+ as_expr=false
+fi
+
+rm -f conf$$ conf$$.exe conf$$.file
+if test -d conf$$.dir; then
+ rm -f conf$$.dir/conf$$.file
+else
+ rm -f conf$$.dir
+ mkdir conf$$.dir 2>/dev/null
+fi
+if (echo >conf$$.file) 2>/dev/null; then
+ if ln -s conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s='ln -s'
+ # ... but there are two gotchas:
+ # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
+ # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
+ # In both cases, we have to default to `cp -p'.
+ ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+ as_ln_s='cp -p'
+ elif ln conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s=ln
+ else
+ as_ln_s='cp -p'
+ fi
+else
+ as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
+rmdir conf$$.dir 2>/dev/null
+
+if mkdir -p . 2>/dev/null; then
+ as_mkdir_p=:
+else
+ test -d ./-p && rmdir ./-p
+ as_mkdir_p=false
+fi
+
+if test -x / >/dev/null 2>&1; then
+ as_test_x='test -x'
+else
+ if ls -dL / >/dev/null 2>&1; then
+ as_ls_L_option=L
+ else
+ as_ls_L_option=
+ fi
+ as_test_x='
+ eval sh -c '\''
+ if test -d "$1"; then
+ test -d "$1/.";
+ else
+ case $1 in
+ -*)set "./$1";;
+ esac;
+ case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in
+ ???[sx]*):;;*)false;;esac;fi
+ '\'' sh
+ '
+fi
+as_executable_p=$as_test_x
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+exec 6>&1
+
+# Save the log message, to keep $[0] and so on meaningful, and to
+# report actual input values of CONFIG_FILES etc. instead of their
+# values after options handling.
+ac_log="
+This file was extended by gflags $as_me 2.0, which was
+generated by GNU Autoconf 2.62. Invocation command line was
+
+ CONFIG_FILES = $CONFIG_FILES
+ CONFIG_HEADERS = $CONFIG_HEADERS
+ CONFIG_LINKS = $CONFIG_LINKS
+ CONFIG_COMMANDS = $CONFIG_COMMANDS
+ $ $0 $@
+
+on `(hostname || uname -n) 2>/dev/null | sed 1q`
+"
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+# Files that config.status was made for.
+config_files="$ac_config_files"
+config_headers="$ac_config_headers"
+config_commands="$ac_config_commands"
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+ac_cs_usage="\
+\`$as_me' instantiates files from templates according to the
+current configuration.
+
+Usage: $0 [OPTIONS] [FILE]...
+
+ -h, --help print this help, then exit
+ -V, --version print version number and configuration settings, then exit
+ -q, --quiet do not print progress messages
+ -d, --debug don't remove temporary files
+ --recheck update $as_me by reconfiguring in the same conditions
+ --file=FILE[:TEMPLATE]
+ instantiate the configuration file FILE
+ --header=FILE[:TEMPLATE]
+ instantiate the configuration header FILE
+
+Configuration files:
+$config_files
+
+Configuration headers:
+$config_headers
+
+Configuration commands:
+$config_commands
+
+Report bugs to <bug-autoconf@gnu.org>."
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ac_cs_version="\\
+gflags config.status 2.0
+configured by $0, generated by GNU Autoconf 2.62,
+ with options \\"`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\"
+
+Copyright (C) 2008 Free Software Foundation, Inc.
+This config.status script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it."
+
+ac_pwd='$ac_pwd'
+srcdir='$srcdir'
+INSTALL='$INSTALL'
+MKDIR_P='$MKDIR_P'
+AWK='$AWK'
+test -n "\$AWK" || AWK=awk
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# The default lists apply if the user does not specify any file.
+ac_need_defaults=:
+while test $# != 0
+do
+ case $1 in
+ --*=*)
+ ac_option=`expr "X$1" : 'X\([^=]*\)='`
+ ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'`
+ ac_shift=:
+ ;;
+ *)
+ ac_option=$1
+ ac_optarg=$2
+ ac_shift=shift
+ ;;
+ esac
+
+ case $ac_option in
+ # Handling of the options.
+ -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+ ac_cs_recheck=: ;;
+ --version | --versio | --versi | --vers | --ver | --ve | --v | -V )
+ $as_echo "$ac_cs_version"; exit ;;
+ --debug | --debu | --deb | --de | --d | -d )
+ debug=: ;;
+ --file | --fil | --fi | --f )
+ $ac_shift
+ case $ac_optarg in
+ *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
+ esac
+ CONFIG_FILES="$CONFIG_FILES '$ac_optarg'"
+ ac_need_defaults=false;;
+ --header | --heade | --head | --hea )
+ $ac_shift
+ case $ac_optarg in
+ *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
+ esac
+ CONFIG_HEADERS="$CONFIG_HEADERS '$ac_optarg'"
+ ac_need_defaults=false;;
+ --he | --h)
+ # Conflict between --help and --header
+ { $as_echo "$as_me: error: ambiguous option: $1
+Try \`$0 --help' for more information." >&2
+ { (exit 1); exit 1; }; };;
+ --help | --hel | -h )
+ $as_echo "$ac_cs_usage"; exit ;;
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil | --si | --s)
+ ac_cs_silent=: ;;
+
+ # This is an error.
+ -*) { $as_echo "$as_me: error: unrecognized option: $1
+Try \`$0 --help' for more information." >&2
+ { (exit 1); exit 1; }; } ;;
+
+ *) ac_config_targets="$ac_config_targets $1"
+ ac_need_defaults=false ;;
+
+ esac
+ shift
+done
+
+ac_configure_extra_args=
+
+if $ac_cs_silent; then
+ exec 6>/dev/null
+ ac_configure_extra_args="$ac_configure_extra_args --silent"
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+if \$ac_cs_recheck; then
+ set X '$SHELL' '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
+ shift
+ \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6
+ CONFIG_SHELL='$SHELL'
+ export CONFIG_SHELL
+ exec "\$@"
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+exec 5>>config.log
+{
+ echo
+ sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
+## Running $as_me. ##
+_ASBOX
+ $as_echo "$ac_log"
+} >&5
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+#
+# INIT-COMMANDS
+#
+AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"
+
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+sed_quote_subst='$sed_quote_subst'
+double_quote_subst='$double_quote_subst'
+delay_variable_subst='$delay_variable_subst'
+enable_fast_install='`$ECHO "X$enable_fast_install" | $Xsed -e "$delay_single_quote_subst"`'
+macro_version='`$ECHO "X$macro_version" | $Xsed -e "$delay_single_quote_subst"`'
+macro_revision='`$ECHO "X$macro_revision" | $Xsed -e "$delay_single_quote_subst"`'
+enable_shared='`$ECHO "X$enable_shared" | $Xsed -e "$delay_single_quote_subst"`'
+enable_static='`$ECHO "X$enable_static" | $Xsed -e "$delay_single_quote_subst"`'
+pic_mode='`$ECHO "X$pic_mode" | $Xsed -e "$delay_single_quote_subst"`'
+host_alias='`$ECHO "X$host_alias" | $Xsed -e "$delay_single_quote_subst"`'
+host='`$ECHO "X$host" | $Xsed -e "$delay_single_quote_subst"`'
+host_os='`$ECHO "X$host_os" | $Xsed -e "$delay_single_quote_subst"`'
+build_alias='`$ECHO "X$build_alias" | $Xsed -e "$delay_single_quote_subst"`'
+build='`$ECHO "X$build" | $Xsed -e "$delay_single_quote_subst"`'
+build_os='`$ECHO "X$build_os" | $Xsed -e "$delay_single_quote_subst"`'
+SED='`$ECHO "X$SED" | $Xsed -e "$delay_single_quote_subst"`'
+Xsed='`$ECHO "X$Xsed" | $Xsed -e "$delay_single_quote_subst"`'
+GREP='`$ECHO "X$GREP" | $Xsed -e "$delay_single_quote_subst"`'
+EGREP='`$ECHO "X$EGREP" | $Xsed -e "$delay_single_quote_subst"`'
+FGREP='`$ECHO "X$FGREP" | $Xsed -e "$delay_single_quote_subst"`'
+LD='`$ECHO "X$LD" | $Xsed -e "$delay_single_quote_subst"`'
+NM='`$ECHO "X$NM" | $Xsed -e "$delay_single_quote_subst"`'
+LN_S='`$ECHO "X$LN_S" | $Xsed -e "$delay_single_quote_subst"`'
+max_cmd_len='`$ECHO "X$max_cmd_len" | $Xsed -e "$delay_single_quote_subst"`'
+ac_objext='`$ECHO "X$ac_objext" | $Xsed -e "$delay_single_quote_subst"`'
+exeext='`$ECHO "X$exeext" | $Xsed -e "$delay_single_quote_subst"`'
+lt_unset='`$ECHO "X$lt_unset" | $Xsed -e "$delay_single_quote_subst"`'
+lt_SP2NL='`$ECHO "X$lt_SP2NL" | $Xsed -e "$delay_single_quote_subst"`'
+lt_NL2SP='`$ECHO "X$lt_NL2SP" | $Xsed -e "$delay_single_quote_subst"`'
+reload_flag='`$ECHO "X$reload_flag" | $Xsed -e "$delay_single_quote_subst"`'
+reload_cmds='`$ECHO "X$reload_cmds" | $Xsed -e "$delay_single_quote_subst"`'
+OBJDUMP='`$ECHO "X$OBJDUMP" | $Xsed -e "$delay_single_quote_subst"`'
+deplibs_check_method='`$ECHO "X$deplibs_check_method" | $Xsed -e "$delay_single_quote_subst"`'
+file_magic_cmd='`$ECHO "X$file_magic_cmd" | $Xsed -e "$delay_single_quote_subst"`'
+AR='`$ECHO "X$AR" | $Xsed -e "$delay_single_quote_subst"`'
+AR_FLAGS='`$ECHO "X$AR_FLAGS" | $Xsed -e "$delay_single_quote_subst"`'
+STRIP='`$ECHO "X$STRIP" | $Xsed -e "$delay_single_quote_subst"`'
+RANLIB='`$ECHO "X$RANLIB" | $Xsed -e "$delay_single_quote_subst"`'
+old_postinstall_cmds='`$ECHO "X$old_postinstall_cmds" | $Xsed -e "$delay_single_quote_subst"`'
+old_postuninstall_cmds='`$ECHO "X$old_postuninstall_cmds" | $Xsed -e "$delay_single_quote_subst"`'
+old_archive_cmds='`$ECHO "X$old_archive_cmds" | $Xsed -e "$delay_single_quote_subst"`'
+CC='`$ECHO "X$CC" | $Xsed -e "$delay_single_quote_subst"`'
+CFLAGS='`$ECHO "X$CFLAGS" | $Xsed -e "$delay_single_quote_subst"`'
+compiler='`$ECHO "X$compiler" | $Xsed -e "$delay_single_quote_subst"`'
+GCC='`$ECHO "X$GCC" | $Xsed -e "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_pipe='`$ECHO "X$lt_cv_sys_global_symbol_pipe" | $Xsed -e "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_to_cdecl='`$ECHO "X$lt_cv_sys_global_symbol_to_cdecl" | $Xsed -e "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_to_c_name_address='`$ECHO "X$lt_cv_sys_global_symbol_to_c_name_address" | $Xsed -e "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_to_c_name_address_lib_prefix='`$ECHO "X$lt_cv_sys_global_symbol_to_c_name_address_lib_prefix" | $Xsed -e "$delay_single_quote_subst"`'
+objdir='`$ECHO "X$objdir" | $Xsed -e "$delay_single_quote_subst"`'
+SHELL='`$ECHO "X$SHELL" | $Xsed -e "$delay_single_quote_subst"`'
+ECHO='`$ECHO "X$ECHO" | $Xsed -e "$delay_single_quote_subst"`'
+MAGIC_CMD='`$ECHO "X$MAGIC_CMD" | $Xsed -e "$delay_single_quote_subst"`'
+lt_prog_compiler_no_builtin_flag='`$ECHO "X$lt_prog_compiler_no_builtin_flag" | $Xsed -e "$delay_single_quote_subst"`'
+lt_prog_compiler_wl='`$ECHO "X$lt_prog_compiler_wl" | $Xsed -e "$delay_single_quote_subst"`'
+lt_prog_compiler_pic='`$ECHO "X$lt_prog_compiler_pic" | $Xsed -e "$delay_single_quote_subst"`'
+lt_prog_compiler_static='`$ECHO "X$lt_prog_compiler_static" | $Xsed -e "$delay_single_quote_subst"`'
+lt_cv_prog_compiler_c_o='`$ECHO "X$lt_cv_prog_compiler_c_o" | $Xsed -e "$delay_single_quote_subst"`'
+need_locks='`$ECHO "X$need_locks" | $Xsed -e "$delay_single_quote_subst"`'
+DSYMUTIL='`$ECHO "X$DSYMUTIL" | $Xsed -e "$delay_single_quote_subst"`'
+NMEDIT='`$ECHO "X$NMEDIT" | $Xsed -e "$delay_single_quote_subst"`'
+LIPO='`$ECHO "X$LIPO" | $Xsed -e "$delay_single_quote_subst"`'
+OTOOL='`$ECHO "X$OTOOL" | $Xsed -e "$delay_single_quote_subst"`'
+OTOOL64='`$ECHO "X$OTOOL64" | $Xsed -e "$delay_single_quote_subst"`'
+libext='`$ECHO "X$libext" | $Xsed -e "$delay_single_quote_subst"`'
+shrext_cmds='`$ECHO "X$shrext_cmds" | $Xsed -e "$delay_single_quote_subst"`'
+extract_expsyms_cmds='`$ECHO "X$extract_expsyms_cmds" | $Xsed -e "$delay_single_quote_subst"`'
+archive_cmds_need_lc='`$ECHO "X$archive_cmds_need_lc" | $Xsed -e "$delay_single_quote_subst"`'
+enable_shared_with_static_runtimes='`$ECHO "X$enable_shared_with_static_runtimes" | $Xsed -e "$delay_single_quote_subst"`'
+export_dynamic_flag_spec='`$ECHO "X$export_dynamic_flag_spec" | $Xsed -e "$delay_single_quote_subst"`'
+whole_archive_flag_spec='`$ECHO "X$whole_archive_flag_spec" | $Xsed -e "$delay_single_quote_subst"`'
+compiler_needs_object='`$ECHO "X$compiler_needs_object" | $Xsed -e "$delay_single_quote_subst"`'
+old_archive_from_new_cmds='`$ECHO "X$old_archive_from_new_cmds" | $Xsed -e "$delay_single_quote_subst"`'
+old_archive_from_expsyms_cmds='`$ECHO "X$old_archive_from_expsyms_cmds" | $Xsed -e "$delay_single_quote_subst"`'
+archive_cmds='`$ECHO "X$archive_cmds" | $Xsed -e "$delay_single_quote_subst"`'
+archive_expsym_cmds='`$ECHO "X$archive_expsym_cmds" | $Xsed -e "$delay_single_quote_subst"`'
+module_cmds='`$ECHO "X$module_cmds" | $Xsed -e "$delay_single_quote_subst"`'
+module_expsym_cmds='`$ECHO "X$module_expsym_cmds" | $Xsed -e "$delay_single_quote_subst"`'
+with_gnu_ld='`$ECHO "X$with_gnu_ld" | $Xsed -e "$delay_single_quote_subst"`'
+allow_undefined_flag='`$ECHO "X$allow_undefined_flag" | $Xsed -e "$delay_single_quote_subst"`'
+no_undefined_flag='`$ECHO "X$no_undefined_flag" | $Xsed -e "$delay_single_quote_subst"`'
+hardcode_libdir_flag_spec='`$ECHO "X$hardcode_libdir_flag_spec" | $Xsed -e "$delay_single_quote_subst"`'
+hardcode_libdir_flag_spec_ld='`$ECHO "X$hardcode_libdir_flag_spec_ld" | $Xsed -e "$delay_single_quote_subst"`'
+hardcode_libdir_separator='`$ECHO "X$hardcode_libdir_separator" | $Xsed -e "$delay_single_quote_subst"`'
+hardcode_direct='`$ECHO "X$hardcode_direct" | $Xsed -e "$delay_single_quote_subst"`'
+hardcode_direct_absolute='`$ECHO "X$hardcode_direct_absolute" | $Xsed -e "$delay_single_quote_subst"`'
+hardcode_minus_L='`$ECHO "X$hardcode_minus_L" | $Xsed -e "$delay_single_quote_subst"`'
+hardcode_shlibpath_var='`$ECHO "X$hardcode_shlibpath_var" | $Xsed -e "$delay_single_quote_subst"`'
+hardcode_automatic='`$ECHO "X$hardcode_automatic" | $Xsed -e "$delay_single_quote_subst"`'
+inherit_rpath='`$ECHO "X$inherit_rpath" | $Xsed -e "$delay_single_quote_subst"`'
+link_all_deplibs='`$ECHO "X$link_all_deplibs" | $Xsed -e "$delay_single_quote_subst"`'
+fix_srcfile_path='`$ECHO "X$fix_srcfile_path" | $Xsed -e "$delay_single_quote_subst"`'
+always_export_symbols='`$ECHO "X$always_export_symbols" | $Xsed -e "$delay_single_quote_subst"`'
+export_symbols_cmds='`$ECHO "X$export_symbols_cmds" | $Xsed -e "$delay_single_quote_subst"`'
+exclude_expsyms='`$ECHO "X$exclude_expsyms" | $Xsed -e "$delay_single_quote_subst"`'
+include_expsyms='`$ECHO "X$include_expsyms" | $Xsed -e "$delay_single_quote_subst"`'
+prelink_cmds='`$ECHO "X$prelink_cmds" | $Xsed -e "$delay_single_quote_subst"`'
+file_list_spec='`$ECHO "X$file_list_spec" | $Xsed -e "$delay_single_quote_subst"`'
+variables_saved_for_relink='`$ECHO "X$variables_saved_for_relink" | $Xsed -e "$delay_single_quote_subst"`'
+need_lib_prefix='`$ECHO "X$need_lib_prefix" | $Xsed -e "$delay_single_quote_subst"`'
+need_version='`$ECHO "X$need_version" | $Xsed -e "$delay_single_quote_subst"`'
+version_type='`$ECHO "X$version_type" | $Xsed -e "$delay_single_quote_subst"`'
+runpath_var='`$ECHO "X$runpath_var" | $Xsed -e "$delay_single_quote_subst"`'
+shlibpath_var='`$ECHO "X$shlibpath_var" | $Xsed -e "$delay_single_quote_subst"`'
+shlibpath_overrides_runpath='`$ECHO "X$shlibpath_overrides_runpath" | $Xsed -e "$delay_single_quote_subst"`'
+libname_spec='`$ECHO "X$libname_spec" | $Xsed -e "$delay_single_quote_subst"`'
+library_names_spec='`$ECHO "X$library_names_spec" | $Xsed -e "$delay_single_quote_subst"`'
+soname_spec='`$ECHO "X$soname_spec" | $Xsed -e "$delay_single_quote_subst"`'
+postinstall_cmds='`$ECHO "X$postinstall_cmds" | $Xsed -e "$delay_single_quote_subst"`'
+postuninstall_cmds='`$ECHO "X$postuninstall_cmds" | $Xsed -e "$delay_single_quote_subst"`'
+finish_cmds='`$ECHO "X$finish_cmds" | $Xsed -e "$delay_single_quote_subst"`'
+finish_eval='`$ECHO "X$finish_eval" | $Xsed -e "$delay_single_quote_subst"`'
+hardcode_into_libs='`$ECHO "X$hardcode_into_libs" | $Xsed -e "$delay_single_quote_subst"`'
+sys_lib_search_path_spec='`$ECHO "X$sys_lib_search_path_spec" | $Xsed -e "$delay_single_quote_subst"`'
+sys_lib_dlsearch_path_spec='`$ECHO "X$sys_lib_dlsearch_path_spec" | $Xsed -e "$delay_single_quote_subst"`'
+hardcode_action='`$ECHO "X$hardcode_action" | $Xsed -e "$delay_single_quote_subst"`'
+enable_dlopen='`$ECHO "X$enable_dlopen" | $Xsed -e "$delay_single_quote_subst"`'
+enable_dlopen_self='`$ECHO "X$enable_dlopen_self" | $Xsed -e "$delay_single_quote_subst"`'
+enable_dlopen_self_static='`$ECHO "X$enable_dlopen_self_static" | $Xsed -e "$delay_single_quote_subst"`'
+old_striplib='`$ECHO "X$old_striplib" | $Xsed -e "$delay_single_quote_subst"`'
+striplib='`$ECHO "X$striplib" | $Xsed -e "$delay_single_quote_subst"`'
+compiler_lib_search_dirs='`$ECHO "X$compiler_lib_search_dirs" | $Xsed -e "$delay_single_quote_subst"`'
+predep_objects='`$ECHO "X$predep_objects" | $Xsed -e "$delay_single_quote_subst"`'
+postdep_objects='`$ECHO "X$postdep_objects" | $Xsed -e "$delay_single_quote_subst"`'
+predeps='`$ECHO "X$predeps" | $Xsed -e "$delay_single_quote_subst"`'
+postdeps='`$ECHO "X$postdeps" | $Xsed -e "$delay_single_quote_subst"`'
+compiler_lib_search_path='`$ECHO "X$compiler_lib_search_path" | $Xsed -e "$delay_single_quote_subst"`'
+LD_CXX='`$ECHO "X$LD_CXX" | $Xsed -e "$delay_single_quote_subst"`'
+old_archive_cmds_CXX='`$ECHO "X$old_archive_cmds_CXX" | $Xsed -e "$delay_single_quote_subst"`'
+compiler_CXX='`$ECHO "X$compiler_CXX" | $Xsed -e "$delay_single_quote_subst"`'
+GCC_CXX='`$ECHO "X$GCC_CXX" | $Xsed -e "$delay_single_quote_subst"`'
+lt_prog_compiler_no_builtin_flag_CXX='`$ECHO "X$lt_prog_compiler_no_builtin_flag_CXX" | $Xsed -e "$delay_single_quote_subst"`'
+lt_prog_compiler_wl_CXX='`$ECHO "X$lt_prog_compiler_wl_CXX" | $Xsed -e "$delay_single_quote_subst"`'
+lt_prog_compiler_pic_CXX='`$ECHO "X$lt_prog_compiler_pic_CXX" | $Xsed -e "$delay_single_quote_subst"`'
+lt_prog_compiler_static_CXX='`$ECHO "X$lt_prog_compiler_static_CXX" | $Xsed -e "$delay_single_quote_subst"`'
+lt_cv_prog_compiler_c_o_CXX='`$ECHO "X$lt_cv_prog_compiler_c_o_CXX" | $Xsed -e "$delay_single_quote_subst"`'
+archive_cmds_need_lc_CXX='`$ECHO "X$archive_cmds_need_lc_CXX" | $Xsed -e "$delay_single_quote_subst"`'
+enable_shared_with_static_runtimes_CXX='`$ECHO "X$enable_shared_with_static_runtimes_CXX" | $Xsed -e "$delay_single_quote_subst"`'
+export_dynamic_flag_spec_CXX='`$ECHO "X$export_dynamic_flag_spec_CXX" | $Xsed -e "$delay_single_quote_subst"`'
+whole_archive_flag_spec_CXX='`$ECHO "X$whole_archive_flag_spec_CXX" | $Xsed -e "$delay_single_quote_subst"`'
+compiler_needs_object_CXX='`$ECHO "X$compiler_needs_object_CXX" | $Xsed -e "$delay_single_quote_subst"`'
+old_archive_from_new_cmds_CXX='`$ECHO "X$old_archive_from_new_cmds_CXX" | $Xsed -e "$delay_single_quote_subst"`'
+old_archive_from_expsyms_cmds_CXX='`$ECHO "X$old_archive_from_expsyms_cmds_CXX" | $Xsed -e "$delay_single_quote_subst"`'
+archive_cmds_CXX='`$ECHO "X$archive_cmds_CXX" | $Xsed -e "$delay_single_quote_subst"`'
+archive_expsym_cmds_CXX='`$ECHO "X$archive_expsym_cmds_CXX" | $Xsed -e "$delay_single_quote_subst"`'
+module_cmds_CXX='`$ECHO "X$module_cmds_CXX" | $Xsed -e "$delay_single_quote_subst"`'
+module_expsym_cmds_CXX='`$ECHO "X$module_expsym_cmds_CXX" | $Xsed -e "$delay_single_quote_subst"`'
+with_gnu_ld_CXX='`$ECHO "X$with_gnu_ld_CXX" | $Xsed -e "$delay_single_quote_subst"`'
+allow_undefined_flag_CXX='`$ECHO "X$allow_undefined_flag_CXX" | $Xsed -e "$delay_single_quote_subst"`'
+no_undefined_flag_CXX='`$ECHO "X$no_undefined_flag_CXX" | $Xsed -e "$delay_single_quote_subst"`'
+hardcode_libdir_flag_spec_CXX='`$ECHO "X$hardcode_libdir_flag_spec_CXX" | $Xsed -e "$delay_single_quote_subst"`'
+hardcode_libdir_flag_spec_ld_CXX='`$ECHO "X$hardcode_libdir_flag_spec_ld_CXX" | $Xsed -e "$delay_single_quote_subst"`'
+hardcode_libdir_separator_CXX='`$ECHO "X$hardcode_libdir_separator_CXX" | $Xsed -e "$delay_single_quote_subst"`'
+hardcode_direct_CXX='`$ECHO "X$hardcode_direct_CXX" | $Xsed -e "$delay_single_quote_subst"`'
+hardcode_direct_absolute_CXX='`$ECHO "X$hardcode_direct_absolute_CXX" | $Xsed -e "$delay_single_quote_subst"`'
+hardcode_minus_L_CXX='`$ECHO "X$hardcode_minus_L_CXX" | $Xsed -e "$delay_single_quote_subst"`'
+hardcode_shlibpath_var_CXX='`$ECHO "X$hardcode_shlibpath_var_CXX" | $Xsed -e "$delay_single_quote_subst"`'
+hardcode_automatic_CXX='`$ECHO "X$hardcode_automatic_CXX" | $Xsed -e "$delay_single_quote_subst"`'
+inherit_rpath_CXX='`$ECHO "X$inherit_rpath_CXX" | $Xsed -e "$delay_single_quote_subst"`'
+link_all_deplibs_CXX='`$ECHO "X$link_all_deplibs_CXX" | $Xsed -e "$delay_single_quote_subst"`'
+fix_srcfile_path_CXX='`$ECHO "X$fix_srcfile_path_CXX" | $Xsed -e "$delay_single_quote_subst"`'
+always_export_symbols_CXX='`$ECHO "X$always_export_symbols_CXX" | $Xsed -e "$delay_single_quote_subst"`'
+export_symbols_cmds_CXX='`$ECHO "X$export_symbols_cmds_CXX" | $Xsed -e "$delay_single_quote_subst"`'
+exclude_expsyms_CXX='`$ECHO "X$exclude_expsyms_CXX" | $Xsed -e "$delay_single_quote_subst"`'
+include_expsyms_CXX='`$ECHO "X$include_expsyms_CXX" | $Xsed -e "$delay_single_quote_subst"`'
+prelink_cmds_CXX='`$ECHO "X$prelink_cmds_CXX" | $Xsed -e "$delay_single_quote_subst"`'
+file_list_spec_CXX='`$ECHO "X$file_list_spec_CXX" | $Xsed -e "$delay_single_quote_subst"`'
+hardcode_action_CXX='`$ECHO "X$hardcode_action_CXX" | $Xsed -e "$delay_single_quote_subst"`'
+compiler_lib_search_dirs_CXX='`$ECHO "X$compiler_lib_search_dirs_CXX" | $Xsed -e "$delay_single_quote_subst"`'
+predep_objects_CXX='`$ECHO "X$predep_objects_CXX" | $Xsed -e "$delay_single_quote_subst"`'
+postdep_objects_CXX='`$ECHO "X$postdep_objects_CXX" | $Xsed -e "$delay_single_quote_subst"`'
+predeps_CXX='`$ECHO "X$predeps_CXX" | $Xsed -e "$delay_single_quote_subst"`'
+postdeps_CXX='`$ECHO "X$postdeps_CXX" | $Xsed -e "$delay_single_quote_subst"`'
+compiler_lib_search_path_CXX='`$ECHO "X$compiler_lib_search_path_CXX" | $Xsed -e "$delay_single_quote_subst"`'
+
+LTCC='$LTCC'
+LTCFLAGS='$LTCFLAGS'
+compiler='$compiler_DEFAULT'
+
+# Quote evaled strings.
+for var in SED \
+GREP \
+EGREP \
+FGREP \
+LD \
+NM \
+LN_S \
+lt_SP2NL \
+lt_NL2SP \
+reload_flag \
+OBJDUMP \
+deplibs_check_method \
+file_magic_cmd \
+AR \
+AR_FLAGS \
+STRIP \
+RANLIB \
+CC \
+CFLAGS \
+compiler \
+lt_cv_sys_global_symbol_pipe \
+lt_cv_sys_global_symbol_to_cdecl \
+lt_cv_sys_global_symbol_to_c_name_address \
+lt_cv_sys_global_symbol_to_c_name_address_lib_prefix \
+SHELL \
+ECHO \
+lt_prog_compiler_no_builtin_flag \
+lt_prog_compiler_wl \
+lt_prog_compiler_pic \
+lt_prog_compiler_static \
+lt_cv_prog_compiler_c_o \
+need_locks \
+DSYMUTIL \
+NMEDIT \
+LIPO \
+OTOOL \
+OTOOL64 \
+shrext_cmds \
+export_dynamic_flag_spec \
+whole_archive_flag_spec \
+compiler_needs_object \
+with_gnu_ld \
+allow_undefined_flag \
+no_undefined_flag \
+hardcode_libdir_flag_spec \
+hardcode_libdir_flag_spec_ld \
+hardcode_libdir_separator \
+fix_srcfile_path \
+exclude_expsyms \
+include_expsyms \
+file_list_spec \
+variables_saved_for_relink \
+libname_spec \
+library_names_spec \
+soname_spec \
+finish_eval \
+old_striplib \
+striplib \
+compiler_lib_search_dirs \
+predep_objects \
+postdep_objects \
+predeps \
+postdeps \
+compiler_lib_search_path \
+LD_CXX \
+compiler_CXX \
+lt_prog_compiler_no_builtin_flag_CXX \
+lt_prog_compiler_wl_CXX \
+lt_prog_compiler_pic_CXX \
+lt_prog_compiler_static_CXX \
+lt_cv_prog_compiler_c_o_CXX \
+export_dynamic_flag_spec_CXX \
+whole_archive_flag_spec_CXX \
+compiler_needs_object_CXX \
+with_gnu_ld_CXX \
+allow_undefined_flag_CXX \
+no_undefined_flag_CXX \
+hardcode_libdir_flag_spec_CXX \
+hardcode_libdir_flag_spec_ld_CXX \
+hardcode_libdir_separator_CXX \
+fix_srcfile_path_CXX \
+exclude_expsyms_CXX \
+include_expsyms_CXX \
+file_list_spec_CXX \
+compiler_lib_search_dirs_CXX \
+predep_objects_CXX \
+postdep_objects_CXX \
+predeps_CXX \
+postdeps_CXX \
+compiler_lib_search_path_CXX; do
+ case \`eval \\\\\$ECHO "X\\\\\$\$var"\` in
+ *[\\\\\\\`\\"\\\$]*)
+ eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"X\\\$\$var\\" | \\\$Xsed -e \\"\\\$sed_quote_subst\\"\\\`\\\\\\""
+ ;;
+ *)
+ eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\""
+ ;;
+ esac
+done
+
+# Double-quote double-evaled strings.
+for var in reload_cmds \
+old_postinstall_cmds \
+old_postuninstall_cmds \
+old_archive_cmds \
+extract_expsyms_cmds \
+old_archive_from_new_cmds \
+old_archive_from_expsyms_cmds \
+archive_cmds \
+archive_expsym_cmds \
+module_cmds \
+module_expsym_cmds \
+export_symbols_cmds \
+prelink_cmds \
+postinstall_cmds \
+postuninstall_cmds \
+finish_cmds \
+sys_lib_search_path_spec \
+sys_lib_dlsearch_path_spec \
+old_archive_cmds_CXX \
+old_archive_from_new_cmds_CXX \
+old_archive_from_expsyms_cmds_CXX \
+archive_cmds_CXX \
+archive_expsym_cmds_CXX \
+module_cmds_CXX \
+module_expsym_cmds_CXX \
+export_symbols_cmds_CXX \
+prelink_cmds_CXX; do
+ case \`eval \\\\\$ECHO "X\\\\\$\$var"\` in
+ *[\\\\\\\`\\"\\\$]*)
+ eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"X\\\$\$var\\" | \\\$Xsed -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\""
+ ;;
+ *)
+ eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\""
+ ;;
+ esac
+done
+
+# Fix-up fallback echo if it was mangled by the above quoting rules.
+case \$lt_ECHO in
+*'\\\$0 --fallback-echo"') lt_ECHO=\`\$ECHO "X\$lt_ECHO" | \$Xsed -e 's/\\\\\\\\\\\\\\\$0 --fallback-echo"\$/\$0 --fallback-echo"/'\`
+ ;;
+esac
+
+ac_aux_dir='$ac_aux_dir'
+xsi_shell='$xsi_shell'
+lt_shell_append='$lt_shell_append'
+
+# See if we are running on zsh, and set the options which allow our
+# commands through without removal of \ escapes INIT.
+if test -n "\${ZSH_VERSION+set}" ; then
+ setopt NO_GLOB_SUBST
+fi
+
+
+ PACKAGE='$PACKAGE'
+ VERSION='$VERSION'
+ TIMESTAMP='$TIMESTAMP'
+ RM='$RM'
+ ofile='$ofile'
+
+
+
+
+
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+
+# Handling of arguments.
+for ac_config_target in $ac_config_targets
+do
+ case $ac_config_target in
+ "src/config.h") CONFIG_HEADERS="$CONFIG_HEADERS src/config.h" ;;
+ "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;;
+ "libtool") CONFIG_COMMANDS="$CONFIG_COMMANDS libtool" ;;
+ "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;;
+ "src/gflags/gflags.h") CONFIG_FILES="$CONFIG_FILES src/gflags/gflags.h" ;;
+ "src/gflags/gflags_declare.h") CONFIG_FILES="$CONFIG_FILES src/gflags/gflags_declare.h" ;;
+ "src/gflags/gflags_completions.h") CONFIG_FILES="$CONFIG_FILES src/gflags/gflags_completions.h" ;;
+
+ *) { { $as_echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5
+$as_echo "$as_me: error: invalid argument: $ac_config_target" >&2;}
+ { (exit 1); exit 1; }; };;
+ esac
+done
+
+
+# If the user did not use the arguments to specify the items to instantiate,
+# then the envvar interface is used. Set only those that are not.
+# We use the long form for the default assignment because of an extremely
+# bizarre bug on SunOS 4.1.3.
+if $ac_need_defaults; then
+ test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files
+ test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers
+ test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands
+fi
+
+# Have a temporary directory for convenience. Make it in the build tree
+# simply because there is no reason against having it here, and in addition,
+# creating and moving files from /tmp can sometimes cause problems.
+# Hook for its removal unless debugging.
+# Note that there is a small window in which the directory will not be cleaned:
+# after its creation but before its name has been assigned to `$tmp'.
+$debug ||
+{
+ tmp=
+ trap 'exit_status=$?
+ { test -z "$tmp" || test ! -d "$tmp" || rm -fr "$tmp"; } && exit $exit_status
+' 0
+ trap '{ (exit 1); exit 1; }' 1 2 13 15
+}
+# Create a (secure) tmp directory for tmp files.
+
+{
+ tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` &&
+ test -n "$tmp" && test -d "$tmp"
+} ||
+{
+ tmp=./conf$$-$RANDOM
+ (umask 077 && mkdir "$tmp")
+} ||
+{
+ $as_echo "$as_me: cannot create a temporary directory in ." >&2
+ { (exit 1); exit 1; }
+}
+
+# Set up the scripts for CONFIG_FILES section.
+# No need to generate them if there are no CONFIG_FILES.
+# This happens for instance with `./config.status config.h'.
+if test -n "$CONFIG_FILES"; then
+
+
+ac_cr=' '
+ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' </dev/null 2>/dev/null`
+if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then
+ ac_cs_awk_cr='\\r'
+else
+ ac_cs_awk_cr=$ac_cr
+fi
+
+echo 'BEGIN {' >"$tmp/subs1.awk" &&
+_ACEOF
+
+
+{
+ echo "cat >conf$$subs.awk <<_ACEOF" &&
+ echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' &&
+ echo "_ACEOF"
+} >conf$$subs.sh ||
+ { { $as_echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5
+$as_echo "$as_me: error: could not make $CONFIG_STATUS" >&2;}
+ { (exit 1); exit 1; }; }
+ac_delim_num=`echo "$ac_subst_vars" | grep -c '$'`
+ac_delim='%!_!# '
+for ac_last_try in false false false false false :; do
+ . ./conf$$subs.sh ||
+ { { $as_echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5
+$as_echo "$as_me: error: could not make $CONFIG_STATUS" >&2;}
+ { (exit 1); exit 1; }; }
+
+ if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` = $ac_delim_num; then
+ break
+ elif $ac_last_try; then
+ { { $as_echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5
+$as_echo "$as_me: error: could not make $CONFIG_STATUS" >&2;}
+ { (exit 1); exit 1; }; }
+ else
+ ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
+ fi
+done
+rm -f conf$$subs.sh
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+cat >>"\$tmp/subs1.awk" <<\\_ACAWK &&
+_ACEOF
+sed -n '
+h
+s/^/S["/; s/!.*/"]=/
+p
+g
+s/^[^!]*!//
+:repl
+t repl
+s/'"$ac_delim"'$//
+t delim
+:nl
+h
+s/\(.\{148\}\).*/\1/
+t more1
+s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/
+p
+n
+b repl
+:more1
+s/["\\]/\\&/g; s/^/"/; s/$/"\\/
+p
+g
+s/.\{148\}//
+t nl
+:delim
+h
+s/\(.\{148\}\).*/\1/
+t more2
+s/["\\]/\\&/g; s/^/"/; s/$/"/
+p
+b
+:more2
+s/["\\]/\\&/g; s/^/"/; s/$/"\\/
+p
+g
+s/.\{148\}//
+t delim
+' <conf$$subs.awk | sed '
+/^[^""]/{
+ N
+ s/\n//
+}
+' >>$CONFIG_STATUS || ac_write_fail=1
+rm -f conf$$subs.awk
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+_ACAWK
+cat >>"\$tmp/subs1.awk" <<_ACAWK &&
+ for (key in S) S_is_set[key] = 1
+ FS = ""
+
+}
+{
+ line = $ 0
+ nfields = split(line, field, "@")
+ substed = 0
+ len = length(field[1])
+ for (i = 2; i < nfields; i++) {
+ key = field[i]
+ keylen = length(key)
+ if (S_is_set[key]) {
+ value = S[key]
+ line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3)
+ len += length(value) + length(field[++i])
+ substed = 1
+ } else
+ len += 1 + keylen
+ }
+
+ print line
+}
+
+_ACAWK
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then
+ sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g"
+else
+ cat
+fi < "$tmp/subs1.awk" > "$tmp/subs.awk" \
+ || { { $as_echo "$as_me:$LINENO: error: could not setup config files machinery" >&5
+$as_echo "$as_me: error: could not setup config files machinery" >&2;}
+ { (exit 1); exit 1; }; }
+_ACEOF
+
+# VPATH may cause trouble with some makes, so we remove $(srcdir),
+# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and
+# trailing colons and then remove the whole line if VPATH becomes empty
+# (actually we leave an empty line to preserve line numbers).
+if test "x$srcdir" = x.; then
+ ac_vpsub='/^[ ]*VPATH[ ]*=/{
+s/:*\$(srcdir):*/:/
+s/:*\${srcdir}:*/:/
+s/:*@srcdir@:*/:/
+s/^\([^=]*=[ ]*\):*/\1/
+s/:*$//
+s/^[^=]*=[ ]*$//
+}'
+fi
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+fi # test -n "$CONFIG_FILES"
+
+# Set up the scripts for CONFIG_HEADERS section.
+# No need to generate them if there are no CONFIG_HEADERS.
+# This happens for instance with `./config.status Makefile'.
+if test -n "$CONFIG_HEADERS"; then
+cat >"$tmp/defines.awk" <<\_ACAWK ||
+BEGIN {
+_ACEOF
+
+# Transform confdefs.h into an awk script `defines.awk', embedded as
+# here-document in config.status, that substitutes the proper values into
+# config.h.in to produce config.h.
+
+# Create a delimiter string that does not exist in confdefs.h, to ease
+# handling of long lines.
+ac_delim='%!_!# '
+for ac_last_try in false false :; do
+ ac_t=`sed -n "/$ac_delim/p" confdefs.h`
+ if test -z "$ac_t"; then
+ break
+ elif $ac_last_try; then
+ { { $as_echo "$as_me:$LINENO: error: could not make $CONFIG_HEADERS" >&5
+$as_echo "$as_me: error: could not make $CONFIG_HEADERS" >&2;}
+ { (exit 1); exit 1; }; }
+ else
+ ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
+ fi
+done
+
+# For the awk script, D is an array of macro values keyed by name,
+# likewise P contains macro parameters if any. Preserve backslash
+# newline sequences.
+
+ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]*
+sed -n '
+s/.\{148\}/&'"$ac_delim"'/g
+t rset
+:rset
+s/^[ ]*#[ ]*define[ ][ ]*/ /
+t def
+d
+:def
+s/\\$//
+t bsnl
+s/["\\]/\\&/g
+s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\
+D["\1"]=" \3"/p
+s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p
+d
+:bsnl
+s/["\\]/\\&/g
+s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\
+D["\1"]=" \3\\\\\\n"\\/p
+t cont
+s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p
+t cont
+d
+:cont
+n
+s/.\{148\}/&'"$ac_delim"'/g
+t clear
+:clear
+s/\\$//
+t bsnlc
+s/["\\]/\\&/g; s/^/"/; s/$/"/p
+d
+:bsnlc
+s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p
+b cont
+' <confdefs.h | sed '
+s/'"$ac_delim"'/"\\\
+"/g' >>$CONFIG_STATUS || ac_write_fail=1
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ for (key in D) D_is_set[key] = 1
+ FS = ""
+}
+/^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ {
+ line = \$ 0
+ split(line, arg, " ")
+ if (arg[1] == "#") {
+ defundef = arg[2]
+ mac1 = arg[3]
+ } else {
+ defundef = substr(arg[1], 2)
+ mac1 = arg[2]
+ }
+ split(mac1, mac2, "(") #)
+ macro = mac2[1]
+ if (D_is_set[macro]) {
+ # Preserve the white space surrounding the "#".
+ prefix = substr(line, 1, index(line, defundef) - 1)
+ print prefix "define", macro P[macro] D[macro]
+ next
+ } else {
+ # Replace #undef with comments. This is necessary, for example,
+ # in the case of _POSIX_SOURCE, which is predefined and required
+ # on some systems where configure will not decide to define it.
+ if (defundef == "undef") {
+ print "/*", line, "*/"
+ next
+ }
+ }
+}
+{ print }
+_ACAWK
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+ { { $as_echo "$as_me:$LINENO: error: could not setup config headers machinery" >&5
+$as_echo "$as_me: error: could not setup config headers machinery" >&2;}
+ { (exit 1); exit 1; }; }
+fi # test -n "$CONFIG_HEADERS"
+
+
+eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS :C $CONFIG_COMMANDS"
+shift
+for ac_tag
+do
+ case $ac_tag in
+ :[FHLC]) ac_mode=$ac_tag; continue;;
+ esac
+ case $ac_mode$ac_tag in
+ :[FHL]*:*);;
+ :L* | :C*:*) { { $as_echo "$as_me:$LINENO: error: Invalid tag $ac_tag." >&5
+$as_echo "$as_me: error: Invalid tag $ac_tag." >&2;}
+ { (exit 1); exit 1; }; };;
+ :[FH]-) ac_tag=-:-;;
+ :[FH]*) ac_tag=$ac_tag:$ac_tag.in;;
+ esac
+ ac_save_IFS=$IFS
+ IFS=:
+ set x $ac_tag
+ IFS=$ac_save_IFS
+ shift
+ ac_file=$1
+ shift
+
+ case $ac_mode in
+ :L) ac_source=$1;;
+ :[FH])
+ ac_file_inputs=
+ for ac_f
+ do
+ case $ac_f in
+ -) ac_f="$tmp/stdin";;
+ *) # Look for the file first in the build tree, then in the source tree
+ # (if the path is not absolute). The absolute path cannot be DOS-style,
+ # because $ac_f cannot contain `:'.
+ test -f "$ac_f" ||
+ case $ac_f in
+ [\\/$]*) false;;
+ *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";;
+ esac ||
+ { { $as_echo "$as_me:$LINENO: error: cannot find input file: $ac_f" >&5
+$as_echo "$as_me: error: cannot find input file: $ac_f" >&2;}
+ { (exit 1); exit 1; }; };;
+ esac
+ case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac
+ ac_file_inputs="$ac_file_inputs '$ac_f'"
+ done
+
+ # Let's still pretend it is `configure' which instantiates (i.e., don't
+ # use $as_me), people would be surprised to read:
+ # /* config.h. Generated by config.status. */
+ configure_input='Generated from '`
+ $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g'
+ `' by configure.'
+ if test x"$ac_file" != x-; then
+ configure_input="$ac_file. $configure_input"
+ { $as_echo "$as_me:$LINENO: creating $ac_file" >&5
+$as_echo "$as_me: creating $ac_file" >&6;}
+ fi
+ # Neutralize special characters interpreted by sed in replacement strings.
+ case $configure_input in #(
+ *\&* | *\|* | *\\* )
+ ac_sed_conf_input=`$as_echo "$configure_input" |
+ sed 's/[\\\\&|]/\\\\&/g'`;; #(
+ *) ac_sed_conf_input=$configure_input;;
+ esac
+
+ case $ac_tag in
+ *:-:* | *:-) cat >"$tmp/stdin" \
+ || { { $as_echo "$as_me:$LINENO: error: could not create $ac_file" >&5
+$as_echo "$as_me: error: could not create $ac_file" >&2;}
+ { (exit 1); exit 1; }; } ;;
+ esac
+ ;;
+ esac
+
+ ac_dir=`$as_dirname -- "$ac_file" ||
+$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$ac_file" : 'X\(//\)[^/]' \| \
+ X"$ac_file" : 'X\(//\)$' \| \
+ X"$ac_file" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$ac_file" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ { as_dir="$ac_dir"
+ case $as_dir in #(
+ -*) as_dir=./$as_dir;;
+ esac
+ test -d "$as_dir" || { $as_mkdir_p && mkdir -p "$as_dir"; } || {
+ as_dirs=
+ while :; do
+ case $as_dir in #(
+ *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
+ *) as_qdir=$as_dir;;
+ esac
+ as_dirs="'$as_qdir' $as_dirs"
+ as_dir=`$as_dirname -- "$as_dir" ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$as_dir" : 'X\(//\)[^/]' \| \
+ X"$as_dir" : 'X\(//\)$' \| \
+ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_dir" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ test -d "$as_dir" && break
+ done
+ test -z "$as_dirs" || eval "mkdir $as_dirs"
+ } || test -d "$as_dir" || { { $as_echo "$as_me:$LINENO: error: cannot create directory $as_dir" >&5
+$as_echo "$as_me: error: cannot create directory $as_dir" >&2;}
+ { (exit 1); exit 1; }; }; }
+ ac_builddir=.
+
+case "$ac_dir" in
+.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
+*)
+ ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
+ # A ".." for each directory in $ac_dir_suffix.
+ ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
+ case $ac_top_builddir_sub in
+ "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
+ *) ac_top_build_prefix=$ac_top_builddir_sub/ ;;
+ esac ;;
+esac
+ac_abs_top_builddir=$ac_pwd
+ac_abs_builddir=$ac_pwd$ac_dir_suffix
+# for backward compatibility:
+ac_top_builddir=$ac_top_build_prefix
+
+case $srcdir in
+ .) # We are building in place.
+ ac_srcdir=.
+ ac_top_srcdir=$ac_top_builddir_sub
+ ac_abs_top_srcdir=$ac_pwd ;;
+ [\\/]* | ?:[\\/]* ) # Absolute name.
+ ac_srcdir=$srcdir$ac_dir_suffix;
+ ac_top_srcdir=$srcdir
+ ac_abs_top_srcdir=$srcdir ;;
+ *) # Relative name.
+ ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
+ ac_top_srcdir=$ac_top_build_prefix$srcdir
+ ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
+esac
+ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
+
+
+ case $ac_mode in
+ :F)
+ #
+ # CONFIG_FILE
+ #
+
+ case $INSTALL in
+ [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;;
+ *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;;
+ esac
+ ac_MKDIR_P=$MKDIR_P
+ case $MKDIR_P in
+ [\\/$]* | ?:[\\/]* ) ;;
+ */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;;
+ esac
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# If the template does not know about datarootdir, expand it.
+# FIXME: This hack should be removed a few years after 2.60.
+ac_datarootdir_hack=; ac_datarootdir_seen=
+
+ac_sed_dataroot='
+/datarootdir/ {
+ p
+ q
+}
+/@datadir@/p
+/@docdir@/p
+/@infodir@/p
+/@localedir@/p
+/@mandir@/p
+'
+case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in
+*datarootdir*) ac_datarootdir_seen=yes;;
+*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*)
+ { $as_echo "$as_me:$LINENO: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5
+$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;}
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ ac_datarootdir_hack='
+ s&@datadir@&$datadir&g
+ s&@docdir@&$docdir&g
+ s&@infodir@&$infodir&g
+ s&@localedir@&$localedir&g
+ s&@mandir@&$mandir&g
+ s&\\\${datarootdir}&$datarootdir&g' ;;
+esac
+_ACEOF
+
+# Neutralize VPATH when `$srcdir' = `.'.
+# Shell code in configure.ac might set extrasub.
+# FIXME: do we really want to maintain this feature?
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ac_sed_extra="$ac_vpsub
+$extrasub
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+:t
+/@[a-zA-Z_][a-zA-Z_0-9]*@/!b
+s|@configure_input@|$ac_sed_conf_input|;t t
+s&@top_builddir@&$ac_top_builddir_sub&;t t
+s&@top_build_prefix@&$ac_top_build_prefix&;t t
+s&@srcdir@&$ac_srcdir&;t t
+s&@abs_srcdir@&$ac_abs_srcdir&;t t
+s&@top_srcdir@&$ac_top_srcdir&;t t
+s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t
+s&@builddir@&$ac_builddir&;t t
+s&@abs_builddir@&$ac_abs_builddir&;t t
+s&@abs_top_builddir@&$ac_abs_top_builddir&;t t
+s&@INSTALL@&$ac_INSTALL&;t t
+s&@MKDIR_P@&$ac_MKDIR_P&;t t
+$ac_datarootdir_hack
+"
+eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$tmp/subs.awk" >$tmp/out \
+ || { { $as_echo "$as_me:$LINENO: error: could not create $ac_file" >&5
+$as_echo "$as_me: error: could not create $ac_file" >&2;}
+ { (exit 1); exit 1; }; }
+
+test -z "$ac_datarootdir_hack$ac_datarootdir_seen" &&
+ { ac_out=`sed -n '/\${datarootdir}/p' "$tmp/out"`; test -n "$ac_out"; } &&
+ { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' "$tmp/out"`; test -z "$ac_out"; } &&
+ { $as_echo "$as_me:$LINENO: WARNING: $ac_file contains a reference to the variable \`datarootdir'
+which seems to be undefined. Please make sure it is defined." >&5
+$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir'
+which seems to be undefined. Please make sure it is defined." >&2;}
+
+ rm -f "$tmp/stdin"
+ case $ac_file in
+ -) cat "$tmp/out" && rm -f "$tmp/out";;
+ *) rm -f "$ac_file" && mv "$tmp/out" "$ac_file";;
+ esac \
+ || { { $as_echo "$as_me:$LINENO: error: could not create $ac_file" >&5
+$as_echo "$as_me: error: could not create $ac_file" >&2;}
+ { (exit 1); exit 1; }; }
+ ;;
+ :H)
+ #
+ # CONFIG_HEADER
+ #
+ if test x"$ac_file" != x-; then
+ {
+ $as_echo "/* $configure_input */" \
+ && eval '$AWK -f "$tmp/defines.awk"' "$ac_file_inputs"
+ } >"$tmp/config.h" \
+ || { { $as_echo "$as_me:$LINENO: error: could not create $ac_file" >&5
+$as_echo "$as_me: error: could not create $ac_file" >&2;}
+ { (exit 1); exit 1; }; }
+ if diff "$ac_file" "$tmp/config.h" >/dev/null 2>&1; then
+ { $as_echo "$as_me:$LINENO: $ac_file is unchanged" >&5
+$as_echo "$as_me: $ac_file is unchanged" >&6;}
+ else
+ rm -f "$ac_file"
+ mv "$tmp/config.h" "$ac_file" \
+ || { { $as_echo "$as_me:$LINENO: error: could not create $ac_file" >&5
+$as_echo "$as_me: error: could not create $ac_file" >&2;}
+ { (exit 1); exit 1; }; }
+ fi
+ else
+ $as_echo "/* $configure_input */" \
+ && eval '$AWK -f "$tmp/defines.awk"' "$ac_file_inputs" \
+ || { { $as_echo "$as_me:$LINENO: error: could not create -" >&5
+$as_echo "$as_me: error: could not create -" >&2;}
+ { (exit 1); exit 1; }; }
+ fi
+# Compute "$ac_file"'s index in $config_headers.
+_am_arg="$ac_file"
+_am_stamp_count=1
+for _am_header in $config_headers :; do
+ case $_am_header in
+ $_am_arg | $_am_arg:* )
+ break ;;
+ * )
+ _am_stamp_count=`expr $_am_stamp_count + 1` ;;
+ esac
+done
+echo "timestamp for $_am_arg" >`$as_dirname -- "$_am_arg" ||
+$as_expr X"$_am_arg" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$_am_arg" : 'X\(//\)[^/]' \| \
+ X"$_am_arg" : 'X\(//\)$' \| \
+ X"$_am_arg" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$_am_arg" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`/stamp-h$_am_stamp_count
+ ;;
+
+ :C) { $as_echo "$as_me:$LINENO: executing $ac_file commands" >&5
+$as_echo "$as_me: executing $ac_file commands" >&6;}
+ ;;
+ esac
+
+
+ case $ac_file$ac_mode in
+ "depfiles":C) test x"$AMDEP_TRUE" != x"" || for mf in $CONFIG_FILES; do
+ # Strip MF so we end up with the name of the file.
+ mf=`echo "$mf" | sed -e 's/:.*$//'`
+ # Check whether this is an Automake generated Makefile or not.
+ # We used to match only the files named `Makefile.in', but
+ # some people rename them; so instead we look at the file content.
+ # Grep'ing the first line is not enough: some people post-process
+ # each Makefile.in and add a new line on top of each file to say so.
+ # Grep'ing the whole file is not good either: AIX grep has a line
+ # limit of 2048, but all sed's we know have understand at least 4000.
+ if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then
+ dirpart=`$as_dirname -- "$mf" ||
+$as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$mf" : 'X\(//\)[^/]' \| \
+ X"$mf" : 'X\(//\)$' \| \
+ X"$mf" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$mf" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ else
+ continue
+ fi
+ # Extract the definition of DEPDIR, am__include, and am__quote
+ # from the Makefile without running `make'.
+ DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"`
+ test -z "$DEPDIR" && continue
+ am__include=`sed -n 's/^am__include = //p' < "$mf"`
+ test -z "am__include" && continue
+ am__quote=`sed -n 's/^am__quote = //p' < "$mf"`
+ # When using ansi2knr, U may be empty or an underscore; expand it
+ U=`sed -n 's/^U = //p' < "$mf"`
+ # Find all dependency output files, they are included files with
+ # $(DEPDIR) in their names. We invoke sed twice because it is the
+ # simplest approach to changing $(DEPDIR) to its actual value in the
+ # expansion.
+ for file in `sed -n "
+ s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \
+ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do
+ # Make sure the directory exists.
+ test -f "$dirpart/$file" && continue
+ fdir=`$as_dirname -- "$file" ||
+$as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$file" : 'X\(//\)[^/]' \| \
+ X"$file" : 'X\(//\)$' \| \
+ X"$file" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$file" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ { as_dir=$dirpart/$fdir
+ case $as_dir in #(
+ -*) as_dir=./$as_dir;;
+ esac
+ test -d "$as_dir" || { $as_mkdir_p && mkdir -p "$as_dir"; } || {
+ as_dirs=
+ while :; do
+ case $as_dir in #(
+ *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
+ *) as_qdir=$as_dir;;
+ esac
+ as_dirs="'$as_qdir' $as_dirs"
+ as_dir=`$as_dirname -- "$as_dir" ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$as_dir" : 'X\(//\)[^/]' \| \
+ X"$as_dir" : 'X\(//\)$' \| \
+ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_dir" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ test -d "$as_dir" && break
+ done
+ test -z "$as_dirs" || eval "mkdir $as_dirs"
+ } || test -d "$as_dir" || { { $as_echo "$as_me:$LINENO: error: cannot create directory $as_dir" >&5
+$as_echo "$as_me: error: cannot create directory $as_dir" >&2;}
+ { (exit 1); exit 1; }; }; }
+ # echo "creating $dirpart/$file"
+ echo '# dummy' > "$dirpart/$file"
+ done
+done
+ ;;
+ "libtool":C)
+
+ # See if we are running on zsh, and set the options which allow our
+ # commands through without removal of \ escapes.
+ if test -n "${ZSH_VERSION+set}" ; then
+ setopt NO_GLOB_SUBST
+ fi
+
+ cfgfile="${ofile}T"
+ trap "$RM \"$cfgfile\"; exit 1" 1 2 15
+ $RM "$cfgfile"
+
+ cat <<_LT_EOF >> "$cfgfile"
+#! $SHELL
+
+# `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services.
+# Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $VERSION
+# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+# NOTE: Changes made to this file will be lost: look at ltmain.sh.
+#
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005,
+# 2006, 2007, 2008 Free Software Foundation, Inc.
+# Written by Gordon Matzigkeit, 1996
+#
+# This file is part of GNU Libtool.
+#
+# GNU Libtool is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# As a special exception to the GNU General Public License,
+# if you distribute this file as part of a program or library that
+# is built using GNU Libtool, you may include this file under the
+# same distribution terms that you use for the rest of that program.
+#
+# GNU Libtool is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Libtool; see the file COPYING. If not, a copy
+# can be downloaded from http://www.gnu.org/licenses/gpl.html, or
+# obtained by writing to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+
+# The names of the tagged configurations supported by this script.
+available_tags="CXX "
+
+# ### BEGIN LIBTOOL CONFIG
+
+# Whether or not to optimize for fast installation.
+fast_install=$enable_fast_install
+
+# Which release of libtool.m4 was used?
+macro_version=$macro_version
+macro_revision=$macro_revision
+
+# Whether or not to build shared libraries.
+build_libtool_libs=$enable_shared
+
+# Whether or not to build static libraries.
+build_old_libs=$enable_static
+
+# What type of objects to build.
+pic_mode=$pic_mode
+
+# The host system.
+host_alias=$host_alias
+host=$host
+host_os=$host_os
+
+# The build system.
+build_alias=$build_alias
+build=$build
+build_os=$build_os
+
+# A sed program that does not truncate output.
+SED=$lt_SED
+
+# Sed that helps us avoid accidentally triggering echo(1) options like -n.
+Xsed="\$SED -e 1s/^X//"
+
+# A grep program that handles long lines.
+GREP=$lt_GREP
+
+# An ERE matcher.
+EGREP=$lt_EGREP
+
+# A literal string matcher.
+FGREP=$lt_FGREP
+
+# A BSD- or MS-compatible name lister.
+NM=$lt_NM
+
+# Whether we need soft or hard links.
+LN_S=$lt_LN_S
+
+# What is the maximum length of a command?
+max_cmd_len=$max_cmd_len
+
+# Object file suffix (normally "o").
+objext=$ac_objext
+
+# Executable file suffix (normally "").
+exeext=$exeext
+
+# whether the shell understands "unset".
+lt_unset=$lt_unset
+
+# turn spaces into newlines.
+SP2NL=$lt_lt_SP2NL
+
+# turn newlines into spaces.
+NL2SP=$lt_lt_NL2SP
+
+# How to create reloadable object files.
+reload_flag=$lt_reload_flag
+reload_cmds=$lt_reload_cmds
+
+# An object symbol dumper.
+OBJDUMP=$lt_OBJDUMP
+
+# Method to check whether dependent libraries are shared objects.
+deplibs_check_method=$lt_deplibs_check_method
+
+# Command to use when deplibs_check_method == "file_magic".
+file_magic_cmd=$lt_file_magic_cmd
+
+# The archiver.
+AR=$lt_AR
+AR_FLAGS=$lt_AR_FLAGS
+
+# A symbol stripping program.
+STRIP=$lt_STRIP
+
+# Commands used to install an old-style archive.
+RANLIB=$lt_RANLIB
+old_postinstall_cmds=$lt_old_postinstall_cmds
+old_postuninstall_cmds=$lt_old_postuninstall_cmds
+
+# A C compiler.
+LTCC=$lt_CC
+
+# LTCC compiler flags.
+LTCFLAGS=$lt_CFLAGS
+
+# Take the output of nm and produce a listing of raw symbols and C names.
+global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe
+
+# Transform the output of nm in a proper C declaration.
+global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl
+
+# Transform the output of nm in a C name address pair.
+global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address
+
+# Transform the output of nm in a C name address pair when lib prefix is needed.
+global_symbol_to_c_name_address_lib_prefix=$lt_lt_cv_sys_global_symbol_to_c_name_address_lib_prefix
+
+# The name of the directory that contains temporary libtool files.
+objdir=$objdir
+
+# Shell to use when invoking shell scripts.
+SHELL=$lt_SHELL
+
+# An echo program that does not interpret backslashes.
+ECHO=$lt_ECHO
+
+# Used to examine libraries when file_magic_cmd begins with "file".
+MAGIC_CMD=$MAGIC_CMD
+
+# Must we lock files when doing compilation?
+need_locks=$lt_need_locks
+
+# Tool to manipulate archived DWARF debug symbol files on Mac OS X.
+DSYMUTIL=$lt_DSYMUTIL
+
+# Tool to change global to local symbols on Mac OS X.
+NMEDIT=$lt_NMEDIT
+
+# Tool to manipulate fat objects and archives on Mac OS X.
+LIPO=$lt_LIPO
+
+# ldd/readelf like tool for Mach-O binaries on Mac OS X.
+OTOOL=$lt_OTOOL
+
+# ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4.
+OTOOL64=$lt_OTOOL64
+
+# Old archive suffix (normally "a").
+libext=$libext
+
+# Shared library suffix (normally ".so").
+shrext_cmds=$lt_shrext_cmds
+
+# The commands to extract the exported symbol list from a shared archive.
+extract_expsyms_cmds=$lt_extract_expsyms_cmds
+
+# Variables whose values should be saved in libtool wrapper scripts and
+# restored at link time.
+variables_saved_for_relink=$lt_variables_saved_for_relink
+
+# Do we need the "lib" prefix for modules?
+need_lib_prefix=$need_lib_prefix
+
+# Do we need a version for libraries?
+need_version=$need_version
+
+# Library versioning type.
+version_type=$version_type
+
+# Shared library runtime path variable.
+runpath_var=$runpath_var
+
+# Shared library path variable.
+shlibpath_var=$shlibpath_var
+
+# Is shlibpath searched before the hard-coded library search path?
+shlibpath_overrides_runpath=$shlibpath_overrides_runpath
+
+# Format of library name prefix.
+libname_spec=$lt_libname_spec
+
+# List of archive names. First name is the real one, the rest are links.
+# The last name is the one that the linker finds with -lNAME
+library_names_spec=$lt_library_names_spec
+
+# The coded name of the library, if different from the real name.
+soname_spec=$lt_soname_spec
+
+# Command to use after installation of a shared archive.
+postinstall_cmds=$lt_postinstall_cmds
+
+# Command to use after uninstallation of a shared archive.
+postuninstall_cmds=$lt_postuninstall_cmds
+
+# Commands used to finish a libtool library installation in a directory.
+finish_cmds=$lt_finish_cmds
+
+# As "finish_cmds", except a single script fragment to be evaled but
+# not shown.
+finish_eval=$lt_finish_eval
+
+# Whether we should hardcode library paths into libraries.
+hardcode_into_libs=$hardcode_into_libs
+
+# Compile-time system search path for libraries.
+sys_lib_search_path_spec=$lt_sys_lib_search_path_spec
+
+# Run-time system search path for libraries.
+sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec
+
+# Whether dlopen is supported.
+dlopen_support=$enable_dlopen
+
+# Whether dlopen of programs is supported.
+dlopen_self=$enable_dlopen_self
+
+# Whether dlopen of statically linked programs is supported.
+dlopen_self_static=$enable_dlopen_self_static
+
+# Commands to strip libraries.
+old_striplib=$lt_old_striplib
+striplib=$lt_striplib
+
+
+# The linker used to build libraries.
+LD=$lt_LD
+
+# Commands used to build an old-style archive.
+old_archive_cmds=$lt_old_archive_cmds
+
+# A language specific compiler.
+CC=$lt_compiler
+
+# Is the compiler the GNU compiler?
+with_gcc=$GCC
+
+# Compiler flag to turn off builtin functions.
+no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag
+
+# How to pass a linker flag through the compiler.
+wl=$lt_lt_prog_compiler_wl
+
+# Additional compiler flags for building library objects.
+pic_flag=$lt_lt_prog_compiler_pic
+
+# Compiler flag to prevent dynamic linking.
+link_static_flag=$lt_lt_prog_compiler_static
+
+# Does compiler simultaneously support -c and -o options?
+compiler_c_o=$lt_lt_cv_prog_compiler_c_o
+
+# Whether or not to add -lc for building shared libraries.
+build_libtool_need_lc=$archive_cmds_need_lc
+
+# Whether or not to disallow shared libs when runtime libs are static.
+allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes
+
+# Compiler flag to allow reflexive dlopens.
+export_dynamic_flag_spec=$lt_export_dynamic_flag_spec
+
+# Compiler flag to generate shared objects directly from archives.
+whole_archive_flag_spec=$lt_whole_archive_flag_spec
+
+# Whether the compiler copes with passing no objects directly.
+compiler_needs_object=$lt_compiler_needs_object
+
+# Create an old-style archive from a shared archive.
+old_archive_from_new_cmds=$lt_old_archive_from_new_cmds
+
+# Create a temporary old-style archive to link instead of a shared archive.
+old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds
+
+# Commands used to build a shared archive.
+archive_cmds=$lt_archive_cmds
+archive_expsym_cmds=$lt_archive_expsym_cmds
+
+# Commands used to build a loadable module if different from building
+# a shared archive.
+module_cmds=$lt_module_cmds
+module_expsym_cmds=$lt_module_expsym_cmds
+
+# Whether we are building with GNU ld or not.
+with_gnu_ld=$lt_with_gnu_ld
+
+# Flag that allows shared libraries with undefined symbols to be built.
+allow_undefined_flag=$lt_allow_undefined_flag
+
+# Flag that enforces no undefined symbols.
+no_undefined_flag=$lt_no_undefined_flag
+
+# Flag to hardcode \$libdir into a binary during linking.
+# This must work even if \$libdir does not exist
+hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec
+
+# If ld is used when linking, flag to hardcode \$libdir into a binary
+# during linking. This must work even if \$libdir does not exist.
+hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld
+
+# Whether we need a single "-rpath" flag with a separated argument.
+hardcode_libdir_separator=$lt_hardcode_libdir_separator
+
+# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes
+# DIR into the resulting binary.
+hardcode_direct=$hardcode_direct
+
+# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes
+# DIR into the resulting binary and the resulting library dependency is
+# "absolute",i.e impossible to change by setting \${shlibpath_var} if the
+# library is relocated.
+hardcode_direct_absolute=$hardcode_direct_absolute
+
+# Set to "yes" if using the -LDIR flag during linking hardcodes DIR
+# into the resulting binary.
+hardcode_minus_L=$hardcode_minus_L
+
+# Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR
+# into the resulting binary.
+hardcode_shlibpath_var=$hardcode_shlibpath_var
+
+# Set to "yes" if building a shared library automatically hardcodes DIR
+# into the library and all subsequent libraries and executables linked
+# against it.
+hardcode_automatic=$hardcode_automatic
+
+# Set to yes if linker adds runtime paths of dependent libraries
+# to runtime path list.
+inherit_rpath=$inherit_rpath
+
+# Whether libtool must link a program against all its dependency libraries.
+link_all_deplibs=$link_all_deplibs
+
+# Fix the shell variable \$srcfile for the compiler.
+fix_srcfile_path=$lt_fix_srcfile_path
+
+# Set to "yes" if exported symbols are required.
+always_export_symbols=$always_export_symbols
+
+# The commands to list exported symbols.
+export_symbols_cmds=$lt_export_symbols_cmds
+
+# Symbols that should not be listed in the preloaded symbols.
+exclude_expsyms=$lt_exclude_expsyms
+
+# Symbols that must always be exported.
+include_expsyms=$lt_include_expsyms
+
+# Commands necessary for linking programs (against libraries) with templates.
+prelink_cmds=$lt_prelink_cmds
+
+# Specify filename containing input files.
+file_list_spec=$lt_file_list_spec
+
+# How to hardcode a shared library path into an executable.
+hardcode_action=$hardcode_action
+
+# The directories searched by this compiler when creating a shared library.
+compiler_lib_search_dirs=$lt_compiler_lib_search_dirs
+
+# Dependencies to place before and after the objects being linked to
+# create a shared library.
+predep_objects=$lt_predep_objects
+postdep_objects=$lt_postdep_objects
+predeps=$lt_predeps
+postdeps=$lt_postdeps
+
+# The library search path used internally by the compiler when linking
+# a shared library.
+compiler_lib_search_path=$lt_compiler_lib_search_path
+
+# ### END LIBTOOL CONFIG
+
+_LT_EOF
+
+ case $host_os in
+ aix3*)
+ cat <<\_LT_EOF >> "$cfgfile"
+# AIX sometimes has problems with the GCC collect2 program. For some
+# reason, if we set the COLLECT_NAMES environment variable, the problems
+# vanish in a puff of smoke.
+if test "X${COLLECT_NAMES+set}" != Xset; then
+ COLLECT_NAMES=
+ export COLLECT_NAMES
+fi
+_LT_EOF
+ ;;
+ esac
+
+
+ltmain="$ac_aux_dir/ltmain.sh"
+
+
+ # We use sed instead of cat because bash on DJGPP gets confused if
+ # if finds mixed CR/LF and LF-only lines. Since sed operates in
+ # text mode, it properly converts lines to CR/LF. This bash problem
+ # is reportedly fixed, but why not run on old versions too?
+ sed '/^# Generated shell functions inserted here/q' "$ltmain" >> "$cfgfile" \
+ || (rm -f "$cfgfile"; exit 1)
+
+ case $xsi_shell in
+ yes)
+ cat << \_LT_EOF >> "$cfgfile"
+
+# func_dirname file append nondir_replacement
+# Compute the dirname of FILE. If nonempty, add APPEND to the result,
+# otherwise set result to NONDIR_REPLACEMENT.
+func_dirname ()
+{
+ case ${1} in
+ */*) func_dirname_result="${1%/*}${2}" ;;
+ * ) func_dirname_result="${3}" ;;
+ esac
+}
+
+# func_basename file
+func_basename ()
+{
+ func_basename_result="${1##*/}"
+}
+
+# func_dirname_and_basename file append nondir_replacement
+# perform func_basename and func_dirname in a single function
+# call:
+# dirname: Compute the dirname of FILE. If nonempty,
+# add APPEND to the result, otherwise set result
+# to NONDIR_REPLACEMENT.
+# value returned in "$func_dirname_result"
+# basename: Compute filename of FILE.
+# value retuned in "$func_basename_result"
+# Implementation must be kept synchronized with func_dirname
+# and func_basename. For efficiency, we do not delegate to
+# those functions but instead duplicate the functionality here.
+func_dirname_and_basename ()
+{
+ case ${1} in
+ */*) func_dirname_result="${1%/*}${2}" ;;
+ * ) func_dirname_result="${3}" ;;
+ esac
+ func_basename_result="${1##*/}"
+}
+
+# func_stripname prefix suffix name
+# strip PREFIX and SUFFIX off of NAME.
+# PREFIX and SUFFIX must not contain globbing or regex special
+# characters, hashes, percent signs, but SUFFIX may contain a leading
+# dot (in which case that matches only a dot).
+func_stripname ()
+{
+ # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are
+ # positional parameters, so assign one to ordinary parameter first.
+ func_stripname_result=${3}
+ func_stripname_result=${func_stripname_result#"${1}"}
+ func_stripname_result=${func_stripname_result%"${2}"}
+}
+
+# func_opt_split
+func_opt_split ()
+{
+ func_opt_split_opt=${1%%=*}
+ func_opt_split_arg=${1#*=}
+}
+
+# func_lo2o object
+func_lo2o ()
+{
+ case ${1} in
+ *.lo) func_lo2o_result=${1%.lo}.${objext} ;;
+ *) func_lo2o_result=${1} ;;
+ esac
+}
+
+# func_xform libobj-or-source
+func_xform ()
+{
+ func_xform_result=${1%.*}.lo
+}
+
+# func_arith arithmetic-term...
+func_arith ()
+{
+ func_arith_result=$(( $* ))
+}
+
+# func_len string
+# STRING may not start with a hyphen.
+func_len ()
+{
+ func_len_result=${#1}
+}
+
+_LT_EOF
+ ;;
+ *) # Bourne compatible functions.
+ cat << \_LT_EOF >> "$cfgfile"
+
+# func_dirname file append nondir_replacement
+# Compute the dirname of FILE. If nonempty, add APPEND to the result,
+# otherwise set result to NONDIR_REPLACEMENT.
+func_dirname ()
+{
+ # Extract subdirectory from the argument.
+ func_dirname_result=`$ECHO "X${1}" | $Xsed -e "$dirname"`
+ if test "X$func_dirname_result" = "X${1}"; then
+ func_dirname_result="${3}"
+ else
+ func_dirname_result="$func_dirname_result${2}"
+ fi
+}
+
+# func_basename file
+func_basename ()
+{
+ func_basename_result=`$ECHO "X${1}" | $Xsed -e "$basename"`
+}
+
+
+# func_stripname prefix suffix name
+# strip PREFIX and SUFFIX off of NAME.
+# PREFIX and SUFFIX must not contain globbing or regex special
+# characters, hashes, percent signs, but SUFFIX may contain a leading
+# dot (in which case that matches only a dot).
+# func_strip_suffix prefix name
+func_stripname ()
+{
+ case ${2} in
+ .*) func_stripname_result=`$ECHO "X${3}" \
+ | $Xsed -e "s%^${1}%%" -e "s%\\\\${2}\$%%"`;;
+ *) func_stripname_result=`$ECHO "X${3}" \
+ | $Xsed -e "s%^${1}%%" -e "s%${2}\$%%"`;;
+ esac
+}
+
+# sed scripts:
+my_sed_long_opt='1s/^\(-[^=]*\)=.*/\1/;q'
+my_sed_long_arg='1s/^-[^=]*=//'
+
+# func_opt_split
+func_opt_split ()
+{
+ func_opt_split_opt=`$ECHO "X${1}" | $Xsed -e "$my_sed_long_opt"`
+ func_opt_split_arg=`$ECHO "X${1}" | $Xsed -e "$my_sed_long_arg"`
+}
+
+# func_lo2o object
+func_lo2o ()
+{
+ func_lo2o_result=`$ECHO "X${1}" | $Xsed -e "$lo2o"`
+}
+
+# func_xform libobj-or-source
+func_xform ()
+{
+ func_xform_result=`$ECHO "X${1}" | $Xsed -e 's/\.[^.]*$/.lo/'`
+}
+
+# func_arith arithmetic-term...
+func_arith ()
+{
+ func_arith_result=`expr "$@"`
+}
+
+# func_len string
+# STRING may not start with a hyphen.
+func_len ()
+{
+ func_len_result=`expr "$1" : ".*" 2>/dev/null || echo $max_cmd_len`
+}
+
+_LT_EOF
+esac
+
+case $lt_shell_append in
+ yes)
+ cat << \_LT_EOF >> "$cfgfile"
+
+# func_append var value
+# Append VALUE to the end of shell variable VAR.
+func_append ()
+{
+ eval "$1+=\$2"
+}
+_LT_EOF
+ ;;
+ *)
+ cat << \_LT_EOF >> "$cfgfile"
+
+# func_append var value
+# Append VALUE to the end of shell variable VAR.
+func_append ()
+{
+ eval "$1=\$$1\$2"
+}
+
+_LT_EOF
+ ;;
+ esac
+
+
+ sed -n '/^# Generated shell functions inserted here/,$p' "$ltmain" >> "$cfgfile" \
+ || (rm -f "$cfgfile"; exit 1)
+
+ mv -f "$cfgfile" "$ofile" ||
+ (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile")
+ chmod +x "$ofile"
+
+
+ cat <<_LT_EOF >> "$ofile"
+
+# ### BEGIN LIBTOOL TAG CONFIG: CXX
+
+# The linker used to build libraries.
+LD=$lt_LD_CXX
+
+# Commands used to build an old-style archive.
+old_archive_cmds=$lt_old_archive_cmds_CXX
+
+# A language specific compiler.
+CC=$lt_compiler_CXX
+
+# Is the compiler the GNU compiler?
+with_gcc=$GCC_CXX
+
+# Compiler flag to turn off builtin functions.
+no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag_CXX
+
+# How to pass a linker flag through the compiler.
+wl=$lt_lt_prog_compiler_wl_CXX
+
+# Additional compiler flags for building library objects.
+pic_flag=$lt_lt_prog_compiler_pic_CXX
+
+# Compiler flag to prevent dynamic linking.
+link_static_flag=$lt_lt_prog_compiler_static_CXX
+
+# Does compiler simultaneously support -c and -o options?
+compiler_c_o=$lt_lt_cv_prog_compiler_c_o_CXX
+
+# Whether or not to add -lc for building shared libraries.
+build_libtool_need_lc=$archive_cmds_need_lc_CXX
+
+# Whether or not to disallow shared libs when runtime libs are static.
+allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes_CXX
+
+# Compiler flag to allow reflexive dlopens.
+export_dynamic_flag_spec=$lt_export_dynamic_flag_spec_CXX
+
+# Compiler flag to generate shared objects directly from archives.
+whole_archive_flag_spec=$lt_whole_archive_flag_spec_CXX
+
+# Whether the compiler copes with passing no objects directly.
+compiler_needs_object=$lt_compiler_needs_object_CXX
+
+# Create an old-style archive from a shared archive.
+old_archive_from_new_cmds=$lt_old_archive_from_new_cmds_CXX
+
+# Create a temporary old-style archive to link instead of a shared archive.
+old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds_CXX
+
+# Commands used to build a shared archive.
+archive_cmds=$lt_archive_cmds_CXX
+archive_expsym_cmds=$lt_archive_expsym_cmds_CXX
+
+# Commands used to build a loadable module if different from building
+# a shared archive.
+module_cmds=$lt_module_cmds_CXX
+module_expsym_cmds=$lt_module_expsym_cmds_CXX
+
+# Whether we are building with GNU ld or not.
+with_gnu_ld=$lt_with_gnu_ld_CXX
+
+# Flag that allows shared libraries with undefined symbols to be built.
+allow_undefined_flag=$lt_allow_undefined_flag_CXX
+
+# Flag that enforces no undefined symbols.
+no_undefined_flag=$lt_no_undefined_flag_CXX
+
+# Flag to hardcode \$libdir into a binary during linking.
+# This must work even if \$libdir does not exist
+hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec_CXX
+
+# If ld is used when linking, flag to hardcode \$libdir into a binary
+# during linking. This must work even if \$libdir does not exist.
+hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld_CXX
+
+# Whether we need a single "-rpath" flag with a separated argument.
+hardcode_libdir_separator=$lt_hardcode_libdir_separator_CXX
+
+# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes
+# DIR into the resulting binary.
+hardcode_direct=$hardcode_direct_CXX
+
+# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes
+# DIR into the resulting binary and the resulting library dependency is
+# "absolute",i.e impossible to change by setting \${shlibpath_var} if the
+# library is relocated.
+hardcode_direct_absolute=$hardcode_direct_absolute_CXX
+
+# Set to "yes" if using the -LDIR flag during linking hardcodes DIR
+# into the resulting binary.
+hardcode_minus_L=$hardcode_minus_L_CXX
+
+# Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR
+# into the resulting binary.
+hardcode_shlibpath_var=$hardcode_shlibpath_var_CXX
+
+# Set to "yes" if building a shared library automatically hardcodes DIR
+# into the library and all subsequent libraries and executables linked
+# against it.
+hardcode_automatic=$hardcode_automatic_CXX
+
+# Set to yes if linker adds runtime paths of dependent libraries
+# to runtime path list.
+inherit_rpath=$inherit_rpath_CXX
+
+# Whether libtool must link a program against all its dependency libraries.
+link_all_deplibs=$link_all_deplibs_CXX
+
+# Fix the shell variable \$srcfile for the compiler.
+fix_srcfile_path=$lt_fix_srcfile_path_CXX
+
+# Set to "yes" if exported symbols are required.
+always_export_symbols=$always_export_symbols_CXX
+
+# The commands to list exported symbols.
+export_symbols_cmds=$lt_export_symbols_cmds_CXX
+
+# Symbols that should not be listed in the preloaded symbols.
+exclude_expsyms=$lt_exclude_expsyms_CXX
+
+# Symbols that must always be exported.
+include_expsyms=$lt_include_expsyms_CXX
+
+# Commands necessary for linking programs (against libraries) with templates.
+prelink_cmds=$lt_prelink_cmds_CXX
+
+# Specify filename containing input files.
+file_list_spec=$lt_file_list_spec_CXX
+
+# How to hardcode a shared library path into an executable.
+hardcode_action=$hardcode_action_CXX
+
+# The directories searched by this compiler when creating a shared library.
+compiler_lib_search_dirs=$lt_compiler_lib_search_dirs_CXX
+
+# Dependencies to place before and after the objects being linked to
+# create a shared library.
+predep_objects=$lt_predep_objects_CXX
+postdep_objects=$lt_postdep_objects_CXX
+predeps=$lt_predeps_CXX
+postdeps=$lt_postdeps_CXX
+
+# The library search path used internally by the compiler when linking
+# a shared library.
+compiler_lib_search_path=$lt_compiler_lib_search_path_CXX
+
+# ### END LIBTOOL TAG CONFIG: CXX
+_LT_EOF
+
+ ;;
+
+ esac
+done # for ac_tag
+
+
+{ (exit 0); exit 0; }
+_ACEOF
+chmod +x $CONFIG_STATUS
+ac_clean_files=$ac_clean_files_save
+
+test $ac_write_fail = 0 ||
+ { { $as_echo "$as_me:$LINENO: error: write failure creating $CONFIG_STATUS" >&5
+$as_echo "$as_me: error: write failure creating $CONFIG_STATUS" >&2;}
+ { (exit 1); exit 1; }; }
+
+
+# configure is writing to config.log, and then calls config.status.
+# config.status does its own redirection, appending to config.log.
+# Unfortunately, on DOS this fails, as config.log is still kept open
+# by configure, so config.status won't be able to write to it; its
+# output is simply discarded. So we exec the FD to /dev/null,
+# effectively closing config.log, so it can be properly (re)opened and
+# appended to by config.status. When coming back to configure, we
+# need to make the FD available again.
+if test "$no_create" != yes; then
+ ac_cs_success=:
+ ac_config_status_args=
+ test "$silent" = yes &&
+ ac_config_status_args="$ac_config_status_args --quiet"
+ exec 5>/dev/null
+ $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false
+ exec 5>>config.log
+ # Use ||, not &&, to avoid exiting from the if with $? = 1, which
+ # would make configure fail if this is the last instruction.
+ $ac_cs_success || { (exit 1); exit 1; }
+fi
+if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then
+ { $as_echo "$as_me:$LINENO: WARNING: Unrecognized options: $ac_unrecognized_opts" >&5
+$as_echo "$as_me: WARNING: Unrecognized options: $ac_unrecognized_opts" >&2;}
+fi
+
diff --git a/src/third_party/gflags-2.0/configure.ac b/src/third_party/gflags-2.0/configure.ac
new file mode 100755
index 00000000000..eceee386327
--- /dev/null
+++ b/src/third_party/gflags-2.0/configure.ac
@@ -0,0 +1,131 @@
+## Process this file with autoconf to produce configure.
+## In general, the safest way to proceed is to run ./autogen.sh
+
+# make sure we're interpreted by some minimal autoconf
+AC_PREREQ(2.57)
+
+AC_INIT(gflags, 2.0, google-gflags@googlegroups.com)
+# Update this value for every release! (A:B:C will map to foo.so.(A-C).C.B)
+# http://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html
+SO_VERSION=3:0:1
+
+# The argument here is just something that should be in the current directory
+# (for sanity checking)
+AC_CONFIG_SRCDIR(README)
+AC_CONFIG_MACRO_DIR([m4])
+AM_INIT_AUTOMAKE([dist-zip])
+AM_CONFIG_HEADER(src/config.h)
+
+# Checks for programs.
+AC_PROG_CXX
+AC_PROG_CC
+AC_PROG_CPP
+AM_CONDITIONAL(GCC, test "$GCC" = yes) # let the Makefile know if we're gcc
+AC_CANONICAL_HOST
+
+# MinGW uses autoconf, but also needs the windows shim routines
+# (since it doesn't have its own support for, say, pthreads).
+# This requires us to #include a special header file, and also to
+# link in some windows versions of .o's instead of the unix versions.
+AH_BOTTOM([
+#if defined( __MINGW32__) || defined(__MINGW64__)
+#include "windows/port.h"
+#endif
+])
+# Populate $host_cpu, $host_os, etc.
+AC_CANONICAL_HOST
+case $host_os in
+ *mingw*)
+ # Disabling fast install keeps libtool from creating wrapper scripts
+ # around the executables it builds. Such scripts have caused failures on
+ # MinGW. Using this option means an extra link step is executed during
+ # "make install".
+ AC_DISABLE_FAST_INSTALL
+ # /tmp is a mount-point in mingw, and hard to use. use cwd instead
+ TEST_TMPDIR=gflags_testdir
+ ;;
+ *)
+ AC_ENABLE_FAST_INSTALL
+ TEST_TMPDIR=/tmp/gflags
+ ;;
+esac
+AC_SUBST(TEST_TMPDIR)
+
+# Uncomment this if you'll be exporting libraries (.so's)
+AC_PROG_LIBTOOL
+AC_SUBST(LIBTOOL_DEPS)
+AC_SUBST(SO_VERSION)
+
+# Check whether some low-level functions/files are available
+AC_HEADER_STDC
+
+# These are tested for by AC_HEADER_STDC, but I check again to set the var
+AC_CHECK_HEADER(stdint.h, ac_cv_have_stdint_h=1, ac_cv_have_stdint_h=0)
+AC_CHECK_HEADER(sys/types.h, ac_cv_have_systypes_h=1, ac_cv_have_systypes_h=0)
+AC_CHECK_HEADER(inttypes.h, ac_cv_have_inttypes_h=1, ac_cv_have_inttypes_h=0)
+AC_CHECK_HEADERS([fnmatch.h])
+AC_CHECK_HEADERS([sys/stat.h])
+AC_CHECK_HEADERS([unistd.h])
+
+# These are the types I need. We look for them in either stdint.h,
+# sys/types.h, or inttypes.h, all of which are part of the default-includes.
+AC_CHECK_TYPE(uint16_t, ac_cv_have_uint16_t=1, ac_cv_have_uint16_t=0)
+AC_CHECK_TYPE(u_int16_t, ac_cv_have_u_int16_t=1, ac_cv_have_u_int16_t=0)
+AC_CHECK_TYPE(__int16, ac_cv_have___int16=1, ac_cv_have___int16=0)
+
+AC_CHECK_FUNCS([strtoll strtoq])
+
+AX_C___ATTRIBUTE__
+# We only care about __attribute__ ((unused))
+if test x"$ac_cv___attribute__" = x"yes"; then
+ ac_cv___attribute__unused="__attribute__ ((unused))"
+else
+ ac_cv___attribute__unused=
+fi
+
+ACX_PTHREAD
+
+# Find out what namespace 'normal' STL code lives in, and also what namespace
+# the user wants our classes to be defined in
+AC_CXX_STL_NAMESPACE
+# TODO(csilvers): this should be renamed to gflags.
+AC_DEFINE_GOOGLE_NAMESPACE(google)
+
+# Solaris 10 6/06 has a bug where /usr/sfw/lib/libstdc++.la is empty.
+# If so, we replace it with our own version.
+LIBSTDCXX_LA_LINKER_FLAG=
+if test -f /usr/sfw/lib/libstdc++.la && ! test -s /usr/sfw/lib/libstdc++.la
+then
+ LIBSTDCXX_LA_LINKER_FLAG='-L$(top_srcdir)/src/solaris'
+fi
+AC_SUBST(LIBSTDCXX_LA_LINKER_FLAG)
+
+# These are what's needed by gflags.h.in
+AC_SUBST(ac_google_start_namespace)
+AC_SUBST(ac_google_end_namespace)
+AC_SUBST(ac_google_namespace)
+AC_SUBST(ac_cv___attribute__unused)
+AC_SUBST(ac_cv_have_stdint_h)
+AC_SUBST(ac_cv_have_systypes_h)
+AC_SUBST(ac_cv_have_inttypes_h)
+AC_SUBST(ac_cv_have_uint16_t)
+AC_SUBST(ac_cv_have_u_int16_t)
+AC_SUBST(ac_cv_have___int16)
+
+## Check out ../autoconf/ for other macros you can call to do useful stuff
+
+# For windows, this has a non-trivial value (__declspec(export)), but any
+# system that uses configure wants this to be the empty string.
+AC_DEFINE(GFLAGS_DLL_DECL,,
+ [Always the empty-string on non-windows systems.
+ On windows, should be "__declspec(dllexport)".
+ This way, when we compile the dll, we export our functions/classes.
+ It's safe to define this here because config.h is only used
+ internally, to compile the DLL, and every DLL source file
+ #includes "config.h" before anything else.])
+
+# Write generated configuration file, and also .h files
+AC_CONFIG_FILES([Makefile
+ src/gflags/gflags.h src/gflags/gflags_declare.h
+ src/gflags/gflags_completions.h])
+AC_OUTPUT
diff --git a/src/third_party/gflags-2.0/depcomp b/src/third_party/gflags-2.0/depcomp
new file mode 100755
index 00000000000..e5f9736c723
--- /dev/null
+++ b/src/third_party/gflags-2.0/depcomp
@@ -0,0 +1,589 @@
+#! /bin/sh
+# depcomp - compile a program generating dependencies as side-effects
+
+scriptversion=2007-03-29.01
+
+# Copyright (C) 1999, 2000, 2003, 2004, 2005, 2006, 2007 Free Software
+# Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+# 02110-1301, USA.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Originally written by Alexandre Oliva <oliva@dcc.unicamp.br>.
+
+case $1 in
+ '')
+ echo "$0: No command. Try \`$0 --help' for more information." 1>&2
+ exit 1;
+ ;;
+ -h | --h*)
+ cat <<\EOF
+Usage: depcomp [--help] [--version] PROGRAM [ARGS]
+
+Run PROGRAMS ARGS to compile a file, generating dependencies
+as side-effects.
+
+Environment variables:
+ depmode Dependency tracking mode.
+ source Source file read by `PROGRAMS ARGS'.
+ object Object file output by `PROGRAMS ARGS'.
+ DEPDIR directory where to store dependencies.
+ depfile Dependency file to output.
+ tmpdepfile Temporary file to use when outputing dependencies.
+ libtool Whether libtool is used (yes/no).
+
+Report bugs to <bug-automake@gnu.org>.
+EOF
+ exit $?
+ ;;
+ -v | --v*)
+ echo "depcomp $scriptversion"
+ exit $?
+ ;;
+esac
+
+if test -z "$depmode" || test -z "$source" || test -z "$object"; then
+ echo "depcomp: Variables source, object and depmode must be set" 1>&2
+ exit 1
+fi
+
+# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po.
+depfile=${depfile-`echo "$object" |
+ sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`}
+tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`}
+
+rm -f "$tmpdepfile"
+
+# Some modes work just like other modes, but use different flags. We
+# parameterize here, but still list the modes in the big case below,
+# to make depend.m4 easier to write. Note that we *cannot* use a case
+# here, because this file can only contain one case statement.
+if test "$depmode" = hp; then
+ # HP compiler uses -M and no extra arg.
+ gccflag=-M
+ depmode=gcc
+fi
+
+if test "$depmode" = dashXmstdout; then
+ # This is just like dashmstdout with a different argument.
+ dashmflag=-xM
+ depmode=dashmstdout
+fi
+
+case "$depmode" in
+gcc3)
+## gcc 3 implements dependency tracking that does exactly what
+## we want. Yay! Note: for some reason libtool 1.4 doesn't like
+## it if -MD -MP comes after the -MF stuff. Hmm.
+## Unfortunately, FreeBSD c89 acceptance of flags depends upon
+## the command line argument order; so add the flags where they
+## appear in depend2.am. Note that the slowdown incurred here
+## affects only configure: in makefiles, %FASTDEP% shortcuts this.
+ for arg
+ do
+ case $arg in
+ -c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;;
+ *) set fnord "$@" "$arg" ;;
+ esac
+ shift # fnord
+ shift # $arg
+ done
+ "$@"
+ stat=$?
+ if test $stat -eq 0; then :
+ else
+ rm -f "$tmpdepfile"
+ exit $stat
+ fi
+ mv "$tmpdepfile" "$depfile"
+ ;;
+
+gcc)
+## There are various ways to get dependency output from gcc. Here's
+## why we pick this rather obscure method:
+## - Don't want to use -MD because we'd like the dependencies to end
+## up in a subdir. Having to rename by hand is ugly.
+## (We might end up doing this anyway to support other compilers.)
+## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like
+## -MM, not -M (despite what the docs say).
+## - Using -M directly means running the compiler twice (even worse
+## than renaming).
+ if test -z "$gccflag"; then
+ gccflag=-MD,
+ fi
+ "$@" -Wp,"$gccflag$tmpdepfile"
+ stat=$?
+ if test $stat -eq 0; then :
+ else
+ rm -f "$tmpdepfile"
+ exit $stat
+ fi
+ rm -f "$depfile"
+ echo "$object : \\" > "$depfile"
+ alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
+## The second -e expression handles DOS-style file names with drive letters.
+ sed -e 's/^[^:]*: / /' \
+ -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile"
+## This next piece of magic avoids the `deleted header file' problem.
+## The problem is that when a header file which appears in a .P file
+## is deleted, the dependency causes make to die (because there is
+## typically no way to rebuild the header). We avoid this by adding
+## dummy dependencies for each header file. Too bad gcc doesn't do
+## this for us directly.
+ tr ' ' '
+' < "$tmpdepfile" |
+## Some versions of gcc put a space before the `:'. On the theory
+## that the space means something, we add a space to the output as
+## well.
+## Some versions of the HPUX 10.20 sed can't process this invocation
+## correctly. Breaking it into two sed invocations is a workaround.
+ sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
+ rm -f "$tmpdepfile"
+ ;;
+
+hp)
+ # This case exists only to let depend.m4 do its work. It works by
+ # looking at the text of this script. This case will never be run,
+ # since it is checked for above.
+ exit 1
+ ;;
+
+sgi)
+ if test "$libtool" = yes; then
+ "$@" "-Wp,-MDupdate,$tmpdepfile"
+ else
+ "$@" -MDupdate "$tmpdepfile"
+ fi
+ stat=$?
+ if test $stat -eq 0; then :
+ else
+ rm -f "$tmpdepfile"
+ exit $stat
+ fi
+ rm -f "$depfile"
+
+ if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files
+ echo "$object : \\" > "$depfile"
+
+ # Clip off the initial element (the dependent). Don't try to be
+ # clever and replace this with sed code, as IRIX sed won't handle
+ # lines with more than a fixed number of characters (4096 in
+ # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines;
+ # the IRIX cc adds comments like `#:fec' to the end of the
+ # dependency line.
+ tr ' ' '
+' < "$tmpdepfile" \
+ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \
+ tr '
+' ' ' >> $depfile
+ echo >> $depfile
+
+ # The second pass generates a dummy entry for each header file.
+ tr ' ' '
+' < "$tmpdepfile" \
+ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \
+ >> $depfile
+ else
+ # The sourcefile does not contain any dependencies, so just
+ # store a dummy comment line, to avoid errors with the Makefile
+ # "include basename.Plo" scheme.
+ echo "#dummy" > "$depfile"
+ fi
+ rm -f "$tmpdepfile"
+ ;;
+
+aix)
+ # The C for AIX Compiler uses -M and outputs the dependencies
+ # in a .u file. In older versions, this file always lives in the
+ # current directory. Also, the AIX compiler puts `$object:' at the
+ # start of each line; $object doesn't have directory information.
+ # Version 6 uses the directory in both cases.
+ dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
+ test "x$dir" = "x$object" && dir=
+ base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
+ if test "$libtool" = yes; then
+ tmpdepfile1=$dir$base.u
+ tmpdepfile2=$base.u
+ tmpdepfile3=$dir.libs/$base.u
+ "$@" -Wc,-M
+ else
+ tmpdepfile1=$dir$base.u
+ tmpdepfile2=$dir$base.u
+ tmpdepfile3=$dir$base.u
+ "$@" -M
+ fi
+ stat=$?
+
+ if test $stat -eq 0; then :
+ else
+ rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
+ exit $stat
+ fi
+
+ for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
+ do
+ test -f "$tmpdepfile" && break
+ done
+ if test -f "$tmpdepfile"; then
+ # Each line is of the form `foo.o: dependent.h'.
+ # Do two passes, one to just change these to
+ # `$object: dependent.h' and one to simply `dependent.h:'.
+ sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile"
+ # That's a tab and a space in the [].
+ sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile"
+ else
+ # The sourcefile does not contain any dependencies, so just
+ # store a dummy comment line, to avoid errors with the Makefile
+ # "include basename.Plo" scheme.
+ echo "#dummy" > "$depfile"
+ fi
+ rm -f "$tmpdepfile"
+ ;;
+
+icc)
+ # Intel's C compiler understands `-MD -MF file'. However on
+ # icc -MD -MF foo.d -c -o sub/foo.o sub/foo.c
+ # ICC 7.0 will fill foo.d with something like
+ # foo.o: sub/foo.c
+ # foo.o: sub/foo.h
+ # which is wrong. We want:
+ # sub/foo.o: sub/foo.c
+ # sub/foo.o: sub/foo.h
+ # sub/foo.c:
+ # sub/foo.h:
+ # ICC 7.1 will output
+ # foo.o: sub/foo.c sub/foo.h
+ # and will wrap long lines using \ :
+ # foo.o: sub/foo.c ... \
+ # sub/foo.h ... \
+ # ...
+
+ "$@" -MD -MF "$tmpdepfile"
+ stat=$?
+ if test $stat -eq 0; then :
+ else
+ rm -f "$tmpdepfile"
+ exit $stat
+ fi
+ rm -f "$depfile"
+ # Each line is of the form `foo.o: dependent.h',
+ # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'.
+ # Do two passes, one to just change these to
+ # `$object: dependent.h' and one to simply `dependent.h:'.
+ sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile"
+ # Some versions of the HPUX 10.20 sed can't process this invocation
+ # correctly. Breaking it into two sed invocations is a workaround.
+ sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" |
+ sed -e 's/$/ :/' >> "$depfile"
+ rm -f "$tmpdepfile"
+ ;;
+
+hp2)
+ # The "hp" stanza above does not work with aCC (C++) and HP's ia64
+ # compilers, which have integrated preprocessors. The correct option
+ # to use with these is +Maked; it writes dependencies to a file named
+ # 'foo.d', which lands next to the object file, wherever that
+ # happens to be.
+ # Much of this is similar to the tru64 case; see comments there.
+ dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
+ test "x$dir" = "x$object" && dir=
+ base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
+ if test "$libtool" = yes; then
+ tmpdepfile1=$dir$base.d
+ tmpdepfile2=$dir.libs/$base.d
+ "$@" -Wc,+Maked
+ else
+ tmpdepfile1=$dir$base.d
+ tmpdepfile2=$dir$base.d
+ "$@" +Maked
+ fi
+ stat=$?
+ if test $stat -eq 0; then :
+ else
+ rm -f "$tmpdepfile1" "$tmpdepfile2"
+ exit $stat
+ fi
+
+ for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2"
+ do
+ test -f "$tmpdepfile" && break
+ done
+ if test -f "$tmpdepfile"; then
+ sed -e "s,^.*\.[a-z]*:,$object:," "$tmpdepfile" > "$depfile"
+ # Add `dependent.h:' lines.
+ sed -ne '2,${; s/^ *//; s/ \\*$//; s/$/:/; p;}' "$tmpdepfile" >> "$depfile"
+ else
+ echo "#dummy" > "$depfile"
+ fi
+ rm -f "$tmpdepfile" "$tmpdepfile2"
+ ;;
+
+tru64)
+ # The Tru64 compiler uses -MD to generate dependencies as a side
+ # effect. `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'.
+ # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put
+ # dependencies in `foo.d' instead, so we check for that too.
+ # Subdirectories are respected.
+ dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
+ test "x$dir" = "x$object" && dir=
+ base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
+
+ if test "$libtool" = yes; then
+ # With Tru64 cc, shared objects can also be used to make a
+ # static library. This mechanism is used in libtool 1.4 series to
+ # handle both shared and static libraries in a single compilation.
+ # With libtool 1.4, dependencies were output in $dir.libs/$base.lo.d.
+ #
+ # With libtool 1.5 this exception was removed, and libtool now
+ # generates 2 separate objects for the 2 libraries. These two
+ # compilations output dependencies in $dir.libs/$base.o.d and
+ # in $dir$base.o.d. We have to check for both files, because
+ # one of the two compilations can be disabled. We should prefer
+ # $dir$base.o.d over $dir.libs/$base.o.d because the latter is
+ # automatically cleaned when .libs/ is deleted, while ignoring
+ # the former would cause a distcleancheck panic.
+ tmpdepfile1=$dir.libs/$base.lo.d # libtool 1.4
+ tmpdepfile2=$dir$base.o.d # libtool 1.5
+ tmpdepfile3=$dir.libs/$base.o.d # libtool 1.5
+ tmpdepfile4=$dir.libs/$base.d # Compaq CCC V6.2-504
+ "$@" -Wc,-MD
+ else
+ tmpdepfile1=$dir$base.o.d
+ tmpdepfile2=$dir$base.d
+ tmpdepfile3=$dir$base.d
+ tmpdepfile4=$dir$base.d
+ "$@" -MD
+ fi
+
+ stat=$?
+ if test $stat -eq 0; then :
+ else
+ rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4"
+ exit $stat
+ fi
+
+ for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4"
+ do
+ test -f "$tmpdepfile" && break
+ done
+ if test -f "$tmpdepfile"; then
+ sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile"
+ # That's a tab and a space in the [].
+ sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile"
+ else
+ echo "#dummy" > "$depfile"
+ fi
+ rm -f "$tmpdepfile"
+ ;;
+
+#nosideeffect)
+ # This comment above is used by automake to tell side-effect
+ # dependency tracking mechanisms from slower ones.
+
+dashmstdout)
+ # Important note: in order to support this mode, a compiler *must*
+ # always write the preprocessed file to stdout, regardless of -o.
+ "$@" || exit $?
+
+ # Remove the call to Libtool.
+ if test "$libtool" = yes; then
+ while test $1 != '--mode=compile'; do
+ shift
+ done
+ shift
+ fi
+
+ # Remove `-o $object'.
+ IFS=" "
+ for arg
+ do
+ case $arg in
+ -o)
+ shift
+ ;;
+ $object)
+ shift
+ ;;
+ *)
+ set fnord "$@" "$arg"
+ shift # fnord
+ shift # $arg
+ ;;
+ esac
+ done
+
+ test -z "$dashmflag" && dashmflag=-M
+ # Require at least two characters before searching for `:'
+ # in the target name. This is to cope with DOS-style filenames:
+ # a dependency such as `c:/foo/bar' could be seen as target `c' otherwise.
+ "$@" $dashmflag |
+ sed 's:^[ ]*[^: ][^:][^:]*\:[ ]*:'"$object"'\: :' > "$tmpdepfile"
+ rm -f "$depfile"
+ cat < "$tmpdepfile" > "$depfile"
+ tr ' ' '
+' < "$tmpdepfile" | \
+## Some versions of the HPUX 10.20 sed can't process this invocation
+## correctly. Breaking it into two sed invocations is a workaround.
+ sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
+ rm -f "$tmpdepfile"
+ ;;
+
+dashXmstdout)
+ # This case only exists to satisfy depend.m4. It is never actually
+ # run, as this mode is specially recognized in the preamble.
+ exit 1
+ ;;
+
+makedepend)
+ "$@" || exit $?
+ # Remove any Libtool call
+ if test "$libtool" = yes; then
+ while test $1 != '--mode=compile'; do
+ shift
+ done
+ shift
+ fi
+ # X makedepend
+ shift
+ cleared=no
+ for arg in "$@"; do
+ case $cleared in
+ no)
+ set ""; shift
+ cleared=yes ;;
+ esac
+ case "$arg" in
+ -D*|-I*)
+ set fnord "$@" "$arg"; shift ;;
+ # Strip any option that makedepend may not understand. Remove
+ # the object too, otherwise makedepend will parse it as a source file.
+ -*|$object)
+ ;;
+ *)
+ set fnord "$@" "$arg"; shift ;;
+ esac
+ done
+ obj_suffix="`echo $object | sed 's/^.*\././'`"
+ touch "$tmpdepfile"
+ ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@"
+ rm -f "$depfile"
+ cat < "$tmpdepfile" > "$depfile"
+ sed '1,2d' "$tmpdepfile" | tr ' ' '
+' | \
+## Some versions of the HPUX 10.20 sed can't process this invocation
+## correctly. Breaking it into two sed invocations is a workaround.
+ sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
+ rm -f "$tmpdepfile" "$tmpdepfile".bak
+ ;;
+
+cpp)
+ # Important note: in order to support this mode, a compiler *must*
+ # always write the preprocessed file to stdout.
+ "$@" || exit $?
+
+ # Remove the call to Libtool.
+ if test "$libtool" = yes; then
+ while test $1 != '--mode=compile'; do
+ shift
+ done
+ shift
+ fi
+
+ # Remove `-o $object'.
+ IFS=" "
+ for arg
+ do
+ case $arg in
+ -o)
+ shift
+ ;;
+ $object)
+ shift
+ ;;
+ *)
+ set fnord "$@" "$arg"
+ shift # fnord
+ shift # $arg
+ ;;
+ esac
+ done
+
+ "$@" -E |
+ sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \
+ -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' |
+ sed '$ s: \\$::' > "$tmpdepfile"
+ rm -f "$depfile"
+ echo "$object : \\" > "$depfile"
+ cat < "$tmpdepfile" >> "$depfile"
+ sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile"
+ rm -f "$tmpdepfile"
+ ;;
+
+msvisualcpp)
+ # Important note: in order to support this mode, a compiler *must*
+ # always write the preprocessed file to stdout, regardless of -o,
+ # because we must use -o when running libtool.
+ "$@" || exit $?
+ IFS=" "
+ for arg
+ do
+ case "$arg" in
+ "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI")
+ set fnord "$@"
+ shift
+ shift
+ ;;
+ *)
+ set fnord "$@" "$arg"
+ shift
+ shift
+ ;;
+ esac
+ done
+ "$@" -E |
+ sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::echo "`cygpath -u \\"\1\\"`":p' | sort | uniq > "$tmpdepfile"
+ rm -f "$depfile"
+ echo "$object : \\" > "$depfile"
+ . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s:: \1 \\:p' >> "$depfile"
+ echo " " >> "$depfile"
+ . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s::\1\::p' >> "$depfile"
+ rm -f "$tmpdepfile"
+ ;;
+
+none)
+ exec "$@"
+ ;;
+
+*)
+ echo "Unknown depmode $depmode" 1>&2
+ exit 1
+ ;;
+esac
+
+exit 0
+
+# Local Variables:
+# mode: shell-script
+# sh-indentation: 2
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-end: "$"
+# End:
diff --git a/src/third_party/gflags-2.0/doc/designstyle.css b/src/third_party/gflags-2.0/doc/designstyle.css
new file mode 100755
index 00000000000..f5d1ec2f767
--- /dev/null
+++ b/src/third_party/gflags-2.0/doc/designstyle.css
@@ -0,0 +1,115 @@
+body {
+ background-color: #ffffff;
+ color: black;
+ margin-right: 1in;
+ margin-left: 1in;
+}
+
+
+h1, h2, h3, h4, h5, h6 {
+ color: #3366ff;
+ font-family: sans-serif;
+}
+@media print {
+ /* Darker version for printing */
+ h1, h2, h3, h4, h5, h6 {
+ color: #000080;
+ font-family: helvetica, sans-serif;
+ }
+}
+
+h1 {
+ text-align: center;
+ font-size: 18pt;
+}
+h2 {
+ margin-left: -0.5in;
+}
+h3 {
+ margin-left: -0.25in;
+}
+h4 {
+ margin-left: -0.125in;
+}
+hr {
+ margin-left: -1in;
+}
+
+/* Definition lists: definition term bold */
+dt {
+ font-weight: bold;
+}
+
+address {
+ text-align: right;
+}
+/* Use the <code> tag for bits of code and <var> for variables and objects. */
+code,pre,samp,var {
+ color: #006000;
+}
+/* Use the <file> tag for file and directory paths and names. */
+file {
+ color: #905050;
+ font-family: monospace;
+}
+/* Use the <kbd> tag for stuff the user should type. */
+kbd {
+ color: #600000;
+}
+div.note p {
+ float: right;
+ width: 3in;
+ margin-right: 0%;
+ padding: 1px;
+ border: 2px solid #6060a0;
+ background-color: #fffff0;
+}
+
+UL.nobullets {
+ list-style-type: none;
+ list-style-image: none;
+ margin-left: -1em;
+}
+
+/*
+body:after {
+ content: "Google Confidential";
+}
+*/
+
+/* pretty printing styles. See prettify.js */
+.str { color: #080; }
+.kwd { color: #008; }
+.com { color: #800; }
+.typ { color: #606; }
+.lit { color: #066; }
+.pun { color: #660; }
+.pln { color: #000; }
+.tag { color: #008; }
+.atn { color: #606; }
+.atv { color: #080; }
+pre.prettyprint { padding: 2px; border: 1px solid #888; }
+
+.embsrc { background: #eee; }
+
+@media print {
+ .str { color: #060; }
+ .kwd { color: #006; font-weight: bold; }
+ .com { color: #600; font-style: italic; }
+ .typ { color: #404; font-weight: bold; }
+ .lit { color: #044; }
+ .pun { color: #440; }
+ .pln { color: #000; }
+ .tag { color: #006; font-weight: bold; }
+ .atn { color: #404; }
+ .atv { color: #060; }
+}
+
+/* Table Column Headers */
+.hdr {
+ color: #006;
+ font-weight: bold;
+ background-color: #dddddd; }
+.hdr2 {
+ color: #006;
+ background-color: #eeeeee; } \ No newline at end of file
diff --git a/src/third_party/gflags-2.0/doc/gflags.html b/src/third_party/gflags-2.0/doc/gflags.html
new file mode 100755
index 00000000000..abc6bd2a27c
--- /dev/null
+++ b/src/third_party/gflags-2.0/doc/gflags.html
@@ -0,0 +1,546 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+
+<html>
+<head>
+<title>How To Use Gflags (formerly Google Commandline Flags)</title>
+
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<link href="designstyle.css" type="text/css" rel="stylesheet">
+<style type="text/css">
+<!--
+ ol.bluelist li {
+ color: #3366ff;
+ font-family: sans-serif;
+ }
+ ol.bluelist li p {
+ color: #000;
+ font-family: "Times Roman", times, serif;
+ }
+ ul.blacklist li {
+ color: #000;
+ font-family: "Times Roman", times, serif;
+ }
+//-->
+</style>
+</head>
+
+<body>
+
+<h1>How To Use Gflags (formerly Google Commandline Flags)</h1>
+<small>(as of
+<script type=text/javascript>
+ var lm = new Date(document.lastModified);
+ document.write(lm.toDateString());
+</script>)
+</small>
+<br>
+
+<blockquote><dl>
+ <dt> Table of contents </dt>
+ <dd> <a href="#intro">Introduction</a> </dd>
+ <dd> <a href="#define">DEFINE: Defining Flags In Program</A> </dd>
+ <dd> <a href="#using">Accessing the Flag</A> </dd>
+ <dd> <a href="#declare">DECLARE: Using the Flag in a Different File</a> </dd>
+ <dd> <a href="#validate">RegisterFlagValidator: Sanity-checking Flag Values</a> </dd>
+ <dd> <a href="#together">Putting It Together: How to Set Up Flags</a> </dd>
+ <dd> <a href="#commandline">Setting Flags on the Command Line</a> </dd>
+ <dd> <a href="#varz">Setting Flags at Runtime</a> </dd>
+ <dd> <a href="#default">Changing the Default Flag Value</a> </dd>
+ <dd> <a href="#special">Special Flags</a> </dd>
+ <dd> <a href="#api">The API</a> </dd>
+ <dd> <br/> </dd>
+</dl></blockquote>
+
+<h2> <A NAME=intro>Introduction, and Comparison to Other Commandline
+ Flags Libraries</A> </h2>
+
+<p><b>Commandline flags</b> are flags that users specify on the
+command line when they run an executable. In the command</p>
+<pre>
+ fgrep -l -f /var/tmp/foo johannes brahms
+</pre>
+<p><code>-l</code> and <code>-f /var/tmp/foo</code> are the two
+commandline flags. (<code>johannes</code> and <code>brahms</code>,
+which don't start with a dash, are <b>commandline arguments</b>.)</p>
+
+<p>Typically, an application lists what flags the user is allowed to
+pass in, and what arguments they take -- in this example,
+<code>-l</code> takes no argument, and <code>-f</code> takes a
+string (in particular, a filename) as an argument. Users can use a
+library to help parse the commandline and store the flags in some data
+structure.</p>
+
+<p>Gflags, the commandline flags library used within Google,
+differs from other libraries,
+such as <code>getopt()</code>, in that flag definitions can be
+scattered around the source code, and not just listed in one place
+such as <code>main()</code>. In practice, this means that a single
+source-code file will define and use flags that are meaningful to that
+file. Any application that links in that file will get the flags, and
+the gflags library will automatically handle that
+flag appropriately.</p>
+
+<p>There's significant gain in flexibility, and ease of code reuse,
+due to this technique. However, there is a danger that two files will
+define the same flag, and then give an error when they're linked
+together.</p>
+
+<p>The rest of this document describes how to use the commandlineflag
+library. It's a C++ library, so examples are in C++. However, there
+is a Python port with the same functionality, and this discussion
+translates directly to Python.</p>
+
+
+<h2> <A name=define>DEFINE: Defining Flags In Program</A> </h2>
+
+<p> Defining a flag is easy: just use the appropriate macro for the
+type you want the flag to be, as defined at the bottom of
+<code>gflags/gflags.h</code>. Here's an example file,
+<code>foo.cc</code>:</p>
+
+<pre>
+ #include &lt;gflags/gflags.h&gt;
+
+ DEFINE_bool(big_menu, true, "Include 'advanced' options in the menu listing");
+ DEFINE_string(languages, "english,french,german",
+ "comma-separated list of languages to offer in the 'lang' menu");
+</pre>
+
+<p><code>DEFINE_bool</code> defines a boolean flag. Here are the
+types supported:</p>
+<ul>
+ <li> <code>DEFINE_bool</code>: boolean
+ <li> <code>DEFINE_int32</code>: 32-bit integer
+ <li> <code>DEFINE_int64</code>: 64-bit integer
+ <li> <code>DEFINE_uint64</code>: unsigned 64-bit integer
+ <li> <code>DEFINE_double</code>: double
+ <li> <code>DEFINE_string</code>: C++ string
+</ul>
+
+<p>Note that there are no 'complex' types like lists: the "languages"
+flag in our example is a list of strings, but is defined of type
+"string", not "list_of_string" or similar. This is by design. We'd
+rather use only simple types for the flags, and allow for complex,
+arbitrary parsing routines to parse them, than to try to put the logic
+inside the flags library proper.</p>
+
+<p>All DEFINE macros take the same three arguments: the name of the
+flag, its default value, and a 'help' string that describes its use.
+The 'help' string is displayed when the user runs the application with
+the <A HREF="#special"><code>--help</code> flag</A>.</p>
+
+<p>You can define a flag in any source-code file in your executable.
+Only define a flag once! If you want to access a flag in more than
+one source file, DEFINE it in one file, and <A
+HREF="#declare">DECLARE</A> it in the others. Even better, DEFINE it
+in <code>foo.cc</code> and DECLARE it in <code>foo.h</code>; then
+everyone who <code>#includes foo.h</code> can use the flag.</p>
+
+<p>
+Defining flags in libraries rather than in main() is powerful, but
+does have some costs. One is that a library might not have a good
+default value for its flags, for example if the flag holds a
+filename that might not exist in some environments. To mitigate such problems,
+you can use <a href="#validate">flag validators</a> to ensure prompt
+notification (in the form of a crash) of an invalid flag value.
+</p>
+
+<p>Note that while most functions in this library are defined in the
+<code>google</code> namespace, <code>DEFINE_foo</code> (and
+<code>DECLARE_foo</code>, <A HREF="#declare">below</A>), should always
+be in the global namespace.</p>
+
+
+<h2> <A name=using>Accessing the Flag</A> </h2>
+
+<p>All defined flags are available to the program as just a normal
+variable, with the prefix <code>FLAGS_</code> prepended. In the above
+example, the macros define two variables, <code>FLAGS_big_menu</code>
+(a bool), and <code>FLAGS_languages</code> (a C++ string).</p>
+
+<p>You can read and write to the flag just like any other
+variable:</p>
+<pre>
+ if (FLAGS_consider_made_up_languages)
+ FLAGS_languages += ",klingon"; // implied by --consider_made_up_languages
+ if (FLAGS_languages.find("finnish") != string::npos)
+ HandleFinnish();
+</pre>
+
+<p>You can also get and set flag values via special functions in
+<code>gflags.h</code>. That's a rarer use case, though.</p>
+
+
+<h2> <A name=declare>DECLARE: Using the Flag in a Different File</A> </h2>
+
+<p>Accessing a flag in the manner of the previous section only works
+if the flag was <code>DEFINE</code>-ed at the top of the file. If it
+wasn't, you'll get an 'unknown variable' error.</p>
+
+<p>The <code>DECLARE_type</code> macro is available when you want to
+use a flag that's defined in another file. For instance, if I were
+writing <code>bar.cc</code> but wanted to access the big_menu, flag, I
+would put this near the top of <code>bar.cc</code>:</p>
+<pre>
+ DECLARE_bool(big_menu);
+</pre>
+
+<p>This is functionally equivalent to saying <code>extern
+FLAGS_big_menu</code>.</p>
+
+<p>Note that such an extern declaration introduces a dependency
+between your file and the file that defines the <code>big_menu</code>
+flag: <code>foo.cc</code>, in this case. Such implicit dependencies
+can be difficult to manage in large projects. For that reason we
+recommend the following guideline:</p>
+
+<blockquote>
+If you DEFINE a flag in <code>foo.cc</code>, either don't DECLARE it
+at all, only DECLARE it in tightly related tests, or only DECLARE
+it in <code>foo.h</code>.
+</blockquote>
+
+<p>You should go the do-not-DECLARE route when the flag is only needed
+by <code>foo.cc</code>, and not in any other file. If you want to
+modify the value of the flag in the related test file to see if it is
+functioning as expected, DECLARE it in the <code>foo_test.cc</code>
+file.
+
+<p>If the flag does span multiple files, DECLARE it in the associated
+<code>.h</code> file, and make others <code>#include</code> that
+<code>.h</code> file if they want to access the flag. The
+<code>#include</code> will make explicit the dependency between the
+two files. This causes the flag to be a global variable.</p>
+
+
+<h2> <A name=validate>RegisterFlagValidator: Sanity-checking Flag Values</A> </h2>
+
+<p>After DEFINE-ing a flag, you may optionally register a validator
+function with the flag. If you do this, after the flag is parsed from
+the commandline, and whenever its value is changed via a call to
+<code>SetCommandLineOption()</code>, the validator function is called
+with the new value as an argument. The validator function should
+return 'true' if the flag value is valid, and false otherwise.
+If the function returns false for the new setting of the
+flag, the flag will retain its current value. If it returns false for the
+default value, ParseCommandLineFlags will die.
+
+<p>Here is an example use of this functionality:</p>
+<pre>
+static bool ValidatePort(const char* flagname, int32 value) {
+ if (value > 0 && value < 32768) // value is ok
+ return true;
+ printf("Invalid value for --%s: %d\n", flagname, (int)value);
+ return false;
+}
+DEFINE_int32(port, 0, "What port to listen on");
+static const bool port_dummy = RegisterFlagValidator(&FLAGS_port, &ValidatePort);
+</pre>
+
+<p>By doing the registration at global initialization time (right
+after the DEFINE), we ensure that the registration happens before
+the commandline is parsed at the beginning of <code>main()</code>.</p>
+
+<p><code>RegisterFlagValidator()</code> returns true if the
+registration is successful. It return false if the registration fails
+because a) the first argument does not refer to a commandline flag, or
+b) a different validator has already been registered for this flag.</p>
+
+
+<h2> <A name=together>Putting It Together: How to Set Up Flags</A> </h2>
+
+<p>The final piece is the one that tells the executable to process the
+commandline flags, and set the <code>FLAGS_*</code> variables to the
+appropriate, non-default value based on what is seen on the
+commandline. This is equivalent to the <code>getopt()</code> call in
+the getopt library, but has much less overhead to use. In fact, it's
+just a single function call:</p>
+
+<pre>
+ google::ParseCommandLineFlags(&argc, &argv, true);
+</pre>
+
+<p>Usually, this code is at the beginning of <code>main()</code>.
+<code>argc</code> and <code>argv</code> are exactly as passed in to
+<code>main()</code>. This routine might modify them, which is why
+pointers to them are passed in.</p>
+
+<p>The last argument is called "remove_flags". If true, then
+<code>ParseCommandLineFlags</code> removes the flags and their
+arguments from <code>argv</code>, and modifies <code>argc</code>
+appropriately. In this case, after the function call,
+<code>argv</code> will hold only commandline arguments, and not
+commandline flags.</p>
+
+<p>If, on the other hand, <code>remove_flags</code> is false, then
+<code>ParseCommandLineFlags</code> will leave argc unchanged, but will
+rearrange the arguments in argv so that the flags are all at the
+beginning. For example, if the input is <code>"/bin/foo" "arg1" "-q"
+"arg2"</code> (which is legal but weird), the function will rearrange
+<code>argv</code> so it reads <code>"/bin/foo", "-q", "arg1",
+"arg2"</code>. In this case, <code>ParseCommandLineFlags</code>
+returns the index into argv that holds the first commandline argument:
+that is, the index past the last flag. (In this example, it would
+return 2, since <code>argv[2]</code> points to <code>arg1</code>.)</p>
+
+<p>In either case, the <code>FLAGS_*</code> variables are modified
+based on what was <A HREF="#commandline">passed in on the
+commandline</A>.</p>
+
+
+<h2> <A name=commandline>Setting Flags on the Command Line</A> </h2>
+
+<p>The reason you make something a flag instead of a compile-time
+constant, is so users can specify a non-default value on the
+commandline. Here's how they might do it for an application that
+links in <code>foo.cc</code>:</p>
+<pre>
+ app_containing_foo --nobig_menu -languages="chinese,japanese,korean" ...
+</pre>
+
+<p>This sets <code>FLAGS_big_menu = false;</code> and
+<code>FLAGS_languages = "chinese,japanese,korean"</code>, when
+<code>ParseCommandLineFlags</code> is run.</p>
+
+<p>Note the atypical syntax for setting a boolean flag to false:
+putting "no" in front of its name. There's a fair bit of flexibility
+to how flags may be specified. Here's an example of all the ways to
+specify the "languages" flag:</p>
+<ul>
+ <li> <code>app_containing_foo --languages="chinese,japanese,korean"</code>
+ <li> <code>app_containing_foo -languages="chinese,japanese,korean"</code>
+ <li> <code>app_containing_foo --languages "chinese,japanese,korean"</code>
+ <li> <code>app_containing_foo -languages "chinese,japanese,korean"</code>
+</ul>
+
+<p>For boolean flags, the possibilities are slightly different:</p>
+<ul>
+ <li> <code>app_containing_foo --big_menu</code>
+ <li> <code>app_containing_foo --nobig_menu</code>
+ <li> <code>app_containing_foo --big_menu=true</code>
+ <li> <code>app_containing_foo --big_menu=false</code>
+</ul>
+<p>(as well as the single-dash variant on all of these).</p>
+
+<p>Despite this flexibility, we recommend using only a single form:
+<code>--variable=value</code> for non-boolean flags, and
+<code>--variable/--novariable</code> for boolean flags. This
+consistency will make your code more readable, and is also the format
+required for certain special-use cases like <A
+HREF="#flagfiles">flagfiles</A>.</p>
+
+<p>It is a fatal error to specify a flag on the commandline that has
+not been DEFINED somewhere in the executable. If you need that
+functionality for some reason -- say you want to use the same set of
+flags for several executables, but not all of them DEFINE every flag
+in your list -- you can specify <A
+HREF="#special"><code>--undefok</code></A> to suppress the error.</p>
+
+<p>As in getopt(), <code>--</code> by itself will terminate flags
+processing. So in <code>foo -f1 1 -- -f2 2</code>, <code>f1</code> is
+considered a flag, but <code>-f2</code> is not.</p>
+
+<p>If a flag is specified more than once, only the last specification
+is used; the others are ignored.</p>
+
+<p>Note that flags do not have single-letter synonyms, like they do in
+the getopt library, nor do we allow "combining" flags behind a
+single dash, as in <code>ls -la</code>.</p>
+
+
+
+<h2> <A name=default>Changing the Default Flag Value</A> </h2>
+
+<p>Sometimes a flag is defined in a library, and you want to change
+its default value in one application but not others. It's simple to
+do this: just assign a new value to the flag in <code>main()</code>,
+before calling <code>ParseCommandLineFlags()</code>:</p>
+<pre>
+ DECLARE_bool(lib_verbose); // mylib has a lib_verbose flag, default is false
+ int main(int argc, char** argv) {
+ FLAGS_lib_verbose = true; // in my app, I want a verbose lib by default
+ ParseCommandLineFlags(...);
+ }
+</pre>
+
+<p>For this application, users can still set the flag value on the
+commandline, but if they do not, the flag's value will default to
+true.</p>
+
+
+<h2> <A name="special">Special Flags</a> </h2>
+
+<p>There are a few flags defined by the commandlineflags module
+itself, and are available to all applications that use
+commandlineflags. These fall into
+three categories. First are the 'reporting' flags that, when found, cause
+the application to print some information about itself and exit.</p>
+
+<table><tr valign=top>
+ <td><code>--help</code></td>
+ <td>shows all flags from all files, sorted by file and then by name;
+ shows the flagname, its default value, and its help string</td>
+</tr><tr valign=top>
+ <td><code>--helpfull</code></td>
+ <td>same as -help, but unambiguously asks for all flags
+ (in case -help changes in the future)</td>
+</tr><tr valign=top>
+ <td><code>--helpshort</code></td>
+ <td>shows only flags for the file with the same name as the executable
+ (usually the one containing <code>main()</code>)</td>
+</tr><tr valign=top>
+ <td><code>--helpxml</code></td>
+ <td>like --help, but output is in xml for easier parsing</td>
+</tr><tr valign=top>
+ <td><code>--helpon=FILE &nbsp;</code></td>
+ <td>shows only flags defined in FILE.*</td>
+</tr><tr valign=top>
+ <td><code>--helpmatch=S</code></td>
+ <td>shows only flags defined in *S*.*</td>
+</tr><tr valign=top>
+ <td><code>--helppackage</code></td>
+ <td>shows flags defined in files in same directory as <code>main()</code></td>
+</tr><tr valign=top>
+ <td><code>--version</code></td>
+ <td>prints version info for the executable</td>
+</tr></table>
+
+<p>Second are the flags that affect how other flags are parsed.</p>
+
+<table><tr valign=top>
+ <td><code>--undefok=flagname,flagname,...</code></td>
+ <td>for those names listed as the argument to <code>--undefok</code>,
+ suppress the normal error-exit that occurs when
+ <code>--name</code> is seen on the commandline, but
+ <code>name</code> has not been DEFINED anywhere in the
+ application
+</table>
+
+<p>Third are the 'recursive' flags, that cause other flag values to be
+set: <code>--fromenv</code>, <code>--tryfromenv</code>,
+<code>--flagfile</code>. These are described below in more
+detail.</p>
+
+<h3> <code>--fromenv</code> </h3>
+
+<p><code>--fromenv=foo,bar</code> says to read the values for the
+<code>foo</code> and <code>bar</code> flags from the environment.
+In concert with this flag, you must actually set the values in the
+environment, via a line like one of the two below:</p>
+<pre>
+ export FLAGS_foo=xxx; export FLAGS_bar=yyy # sh
+ setenv FLAGS_foo xxx; setenv FLAGS_bar yyy # tcsh
+</pre>
+<p>This is equivalent to specifying <code>--foo=xxx</code>,
+<code>--bar=yyy</code> on the commandline.</p>
+
+<p>Note it is a fatal error to say <code>--fromenv=foo</code> if
+<code>foo</code> is not DEFINED somewhere in the application. (Though
+you can suppress this error via <code>--undefok=foo</code>, just like
+for any other flag.)</p>
+
+<p>It is also a fatal error to say <code>--fromenv=foo</code> if
+<code>FLAGS_foo</code> is not actually defined in the environment.</p>
+
+<h3> <code>--tryfromenv</code> </h3>
+
+<p><code>--tryfromenv</code> is exactly like <code>--fromenv</code>,
+except it is <b>not</b> a fatal error to say
+<code>--tryfromenv=foo</code> if <code>FLAGS_foo</code> is not
+actually defined in the environment. Instead, in such cases,
+<code>FLAGS_foo</code> just keeps its default value as specified in
+the application.</p>
+
+<p>Note it is still an error to say <code>--tryfromenv=foo</code> if
+<code>foo</code> is not DEFINED somewhere in the application.</p>
+
+<h3> <code>--flagfile</code> </h3>
+
+<p><code>--flagfile=f</code> tells the commandlineflags module to read
+the file <code>f</code>, and to run all the flag-assignments found in
+that file as if these flags had been specified on the commandline.</p>
+
+<p>In its simplest form, <code>f</code> should just be a list of flag
+assignments, one per line. Unlike on the commandline, the equals sign
+separating a flagname from its argument is <i>required</i> for
+flagfiles. An example flagfile, <code>/tmp/myflags</code>:</p>
+<pre>
+--nobig_menus
+--languages=english,french
+</pre>
+
+<p>With this flagfile, the following two lines are equivalent:<p>
+<pre>
+ ./myapp --foo --nobig_menus --languages=english,french --bar
+ ./myapp --foo --flagfile=/tmp/myflags --bar
+</pre>
+
+<p>Note that many errors are silently suppressed in flagfiles. In
+particular, unrecognized flagnames are silently ignored, as are flags
+that are missing a required value (e.g., a flagfile that just says
+<code>--languages</code>).</p>
+
+<p>The general format of a flagfile is a bit more complicated than the
+simple, common case above. It is: a sequence of filenames, one per
+line, followed by a sequence of flags, one per line, repeated as many
+times as desired. Filenames in a flagfile can use wildcards
+(<code>*</code> and <code>?</code>), and the sequence of flags located
+after a sequence of filenames is processed only if the current
+executable's name matches one of the filenames. It is possible to
+start the flagfile with a sequence of flags instead of a sequence of
+filenames; if such a sequence of flags is present, these flags are
+applied to the current executable no matter what it is.</p>
+
+<p>Lines that start with a <code>#</code> are ignored as comments.
+Leading whitespace is also ignored in flagfiles, as are blank
+lines.</p>
+
+<p>It is possible for a flagfile to use the <code>--flagfile</code>
+flag to include another flagfile.</p>
+
+<p>Flags are always processed in the expected order. That is,
+processing begins by examining the flags specified directly on the
+command line. If a flagfile is specified, its contents are processed,
+and then processing continues with remaining flags from the command
+line.</p>
+
+
+<h2> <A name="api">The API</a> </h2>
+
+<p>In addition to accessing <code>FLAGS_foo</code> directly, it is
+possible to access the flags programmatically, through an API. It is
+also possible to access information about a flag, such as its default
+value and help-string. A <code>FlagSaver</code> makes it easy to
+modify flags and then automatically undo the modifications later.
+Finally, there are somewhat unrelated, but useful, routines to easily
+access parts of <code>argv</code> outside main, including the program
+name (<code>argv[0]</code>).</p>
+
+<p>For more information about these routines, and other useful helper
+methods such as <code>google::SetUsageMessage()</code> and
+<code>google::SetVersionString</code>, see <code>gflags.h</code>.</p>
+
+
+<h2> <A name="misc">Miscellaneous Notes</code> </h2>
+
+<p>If your application has code like this:</p>
+<pre>
+ #define STRIP_FLAG_HELP 1 // this must go before the #include!
+ #include &lt;gflags/gflags.h&gt;
+</pre>
+<p>we will remove the help messages from the compiled source. This can
+reduce the size of the resulting binary somewhat, and may also be
+useful for security reasons.</p>
+
+
+<hr>
+<address>
+Craig Silverstein<br>
+<script type=text/javascript>
+ var lm = new Date(document.lastModified);
+ document.write(lm.toDateString());
+</script>
+</address>
+
+</body>
+</html>
diff --git a/src/third_party/gflags-2.0/gflags.sln b/src/third_party/gflags-2.0/gflags.sln
new file mode 100755
index 00000000000..2f6c057494d
--- /dev/null
+++ b/src/third_party/gflags-2.0/gflags.sln
@@ -0,0 +1,32 @@
+Microsoft Visual Studio Solution File, Format Version 8.00
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libgflags", "vsprojects\libgflags\libgflags.vcproj", "{FB27FBDB-E6C0-4D00-A7F8-1EEEF1B48ABC}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gflags_unittest", "vsprojects\gflags_unittest\gflags_unittest.vcproj", "{4B263748-5F0F-468C-8C5C-ED2682BB6BE3}"
+ ProjectSection(ProjectDependencies) = postProject
+ {FB27FBDB-E6C0-4D00-A7F8-1EEEF1B48ABC} = {FB27FBDB-E6C0-4D00-A7F8-1EEEF1B48ABC}
+ EndProjectSection
+EndProject
+Global
+ GlobalSection(SolutionConfiguration) = preSolution
+ Debug = Debug
+ Release = Release
+ EndGlobalSection
+ GlobalSection(ProjectDependencies) = postSolution
+ EndGlobalSection
+ GlobalSection(ProjectConfiguration) = postSolution
+ {FB27FBDB-E6C0-4D00-A7F8-1EEEF1B48ABC}.Debug.ActiveCfg = Debug|Win32
+ {FB27FBDB-E6C0-4D00-A7F8-1EEEF1B48ABC}.Debug.Build.0 = Debug|Win32
+ {FB27FBDB-E6C0-4D00-A7F8-1EEEF1B48ABC}.Release.ActiveCfg = Release|Win32
+ {FB27FBDB-E6C0-4D00-A7F8-1EEEF1B48ABC}.Release.Build.0 = Release|Win32
+ {4B263748-5F0F-468C-8C5C-ED2682BB6BE3}.Debug.ActiveCfg = Debug|Win32
+ {4B263748-5F0F-468C-8C5C-ED2682BB6BE3}.Debug.Build.0 = Debug|Win32
+ {4B263748-5F0F-468C-8C5C-ED2682BB6BE3}.Release.ActiveCfg = Release|Win32
+ {4B263748-5F0F-468C-8C5C-ED2682BB6BE3}.Release.Build.0 = Release|Win32
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ EndGlobalSection
+ GlobalSection(ExtensibilityAddIns) = postSolution
+ EndGlobalSection
+EndGlobal
diff --git a/src/third_party/gflags-2.0/install-sh b/src/third_party/gflags-2.0/install-sh
new file mode 100755
index 00000000000..a5897de6ea7
--- /dev/null
+++ b/src/third_party/gflags-2.0/install-sh
@@ -0,0 +1,519 @@
+#!/bin/sh
+# install - install a program, script, or datafile
+
+scriptversion=2006-12-25.00
+
+# This originates from X11R5 (mit/util/scripts/install.sh), which was
+# later released in X11R6 (xc/config/util/install.sh) with the
+# following copyright and license.
+#
+# Copyright (C) 1994 X Consortium
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to
+# deal in the Software without restriction, including without limitation the
+# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+# sell copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
+# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+# Except as contained in this notice, the name of the X Consortium shall not
+# be used in advertising or otherwise to promote the sale, use or other deal-
+# ings in this Software without prior written authorization from the X Consor-
+# tium.
+#
+#
+# FSF changes to this file are in the public domain.
+#
+# Calling this script install-sh is preferred over install.sh, to prevent
+# `make' implicit rules from creating a file called install from it
+# when there is no Makefile.
+#
+# This script is compatible with the BSD install script, but was written
+# from scratch.
+
+nl='
+'
+IFS=" "" $nl"
+
+# set DOITPROG to echo to test this script
+
+# Don't use :- since 4.3BSD and earlier shells don't like it.
+doit=${DOITPROG-}
+if test -z "$doit"; then
+ doit_exec=exec
+else
+ doit_exec=$doit
+fi
+
+# Put in absolute file names if you don't have them in your path;
+# or use environment vars.
+
+chgrpprog=${CHGRPPROG-chgrp}
+chmodprog=${CHMODPROG-chmod}
+chownprog=${CHOWNPROG-chown}
+cmpprog=${CMPPROG-cmp}
+cpprog=${CPPROG-cp}
+mkdirprog=${MKDIRPROG-mkdir}
+mvprog=${MVPROG-mv}
+rmprog=${RMPROG-rm}
+stripprog=${STRIPPROG-strip}
+
+posix_glob='?'
+initialize_posix_glob='
+ test "$posix_glob" != "?" || {
+ if (set -f) 2>/dev/null; then
+ posix_glob=
+ else
+ posix_glob=:
+ fi
+ }
+'
+
+posix_mkdir=
+
+# Desired mode of installed file.
+mode=0755
+
+chgrpcmd=
+chmodcmd=$chmodprog
+chowncmd=
+mvcmd=$mvprog
+rmcmd="$rmprog -f"
+stripcmd=
+
+src=
+dst=
+dir_arg=
+dst_arg=
+
+copy_on_change=false
+no_target_directory=
+
+usage="\
+Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
+ or: $0 [OPTION]... SRCFILES... DIRECTORY
+ or: $0 [OPTION]... -t DIRECTORY SRCFILES...
+ or: $0 [OPTION]... -d DIRECTORIES...
+
+In the 1st form, copy SRCFILE to DSTFILE.
+In the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
+In the 4th, create DIRECTORIES.
+
+Options:
+ --help display this help and exit.
+ --version display version info and exit.
+
+ -c (ignored)
+ -C install only if different (preserve the last data modification time)
+ -d create directories instead of installing files.
+ -g GROUP $chgrpprog installed files to GROUP.
+ -m MODE $chmodprog installed files to MODE.
+ -o USER $chownprog installed files to USER.
+ -s $stripprog installed files.
+ -t DIRECTORY install into DIRECTORY.
+ -T report an error if DSTFILE is a directory.
+
+Environment variables override the default commands:
+ CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
+ RMPROG STRIPPROG
+"
+
+while test $# -ne 0; do
+ case $1 in
+ -c) ;;
+
+ -C) copy_on_change=true;;
+
+ -d) dir_arg=true;;
+
+ -g) chgrpcmd="$chgrpprog $2"
+ shift;;
+
+ --help) echo "$usage"; exit $?;;
+
+ -m) mode=$2
+ case $mode in
+ *' '* | *' '* | *'
+'* | *'*'* | *'?'* | *'['*)
+ echo "$0: invalid mode: $mode" >&2
+ exit 1;;
+ esac
+ shift;;
+
+ -o) chowncmd="$chownprog $2"
+ shift;;
+
+ -s) stripcmd=$stripprog;;
+
+ -t) dst_arg=$2
+ shift;;
+
+ -T) no_target_directory=true;;
+
+ --version) echo "$0 $scriptversion"; exit $?;;
+
+ --) shift
+ break;;
+
+ -*) echo "$0: invalid option: $1" >&2
+ exit 1;;
+
+ *) break;;
+ esac
+ shift
+done
+
+if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
+ # When -d is used, all remaining arguments are directories to create.
+ # When -t is used, the destination is already specified.
+ # Otherwise, the last argument is the destination. Remove it from $@.
+ for arg
+ do
+ if test -n "$dst_arg"; then
+ # $@ is not empty: it contains at least $arg.
+ set fnord "$@" "$dst_arg"
+ shift # fnord
+ fi
+ shift # arg
+ dst_arg=$arg
+ done
+fi
+
+if test $# -eq 0; then
+ if test -z "$dir_arg"; then
+ echo "$0: no input file specified." >&2
+ exit 1
+ fi
+ # It's OK to call `install-sh -d' without argument.
+ # This can happen when creating conditional directories.
+ exit 0
+fi
+
+if test -z "$dir_arg"; then
+ trap '(exit $?); exit' 1 2 13 15
+
+ # Set umask so as not to create temps with too-generous modes.
+ # However, 'strip' requires both read and write access to temps.
+ case $mode in
+ # Optimize common cases.
+ *644) cp_umask=133;;
+ *755) cp_umask=22;;
+
+ *[0-7])
+ if test -z "$stripcmd"; then
+ u_plus_rw=
+ else
+ u_plus_rw='% 200'
+ fi
+ cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
+ *)
+ if test -z "$stripcmd"; then
+ u_plus_rw=
+ else
+ u_plus_rw=,u+rw
+ fi
+ cp_umask=$mode$u_plus_rw;;
+ esac
+fi
+
+for src
+do
+ # Protect names starting with `-'.
+ case $src in
+ -*) src=./$src;;
+ esac
+
+ if test -n "$dir_arg"; then
+ dst=$src
+ dstdir=$dst
+ test -d "$dstdir"
+ dstdir_status=$?
+ else
+
+ # Waiting for this to be detected by the "$cpprog $src $dsttmp" command
+ # might cause directories to be created, which would be especially bad
+ # if $src (and thus $dsttmp) contains '*'.
+ if test ! -f "$src" && test ! -d "$src"; then
+ echo "$0: $src does not exist." >&2
+ exit 1
+ fi
+
+ if test -z "$dst_arg"; then
+ echo "$0: no destination specified." >&2
+ exit 1
+ fi
+
+ dst=$dst_arg
+ # Protect names starting with `-'.
+ case $dst in
+ -*) dst=./$dst;;
+ esac
+
+ # If destination is a directory, append the input filename; won't work
+ # if double slashes aren't ignored.
+ if test -d "$dst"; then
+ if test -n "$no_target_directory"; then
+ echo "$0: $dst_arg: Is a directory" >&2
+ exit 1
+ fi
+ dstdir=$dst
+ dst=$dstdir/`basename "$src"`
+ dstdir_status=0
+ else
+ # Prefer dirname, but fall back on a substitute if dirname fails.
+ dstdir=`
+ (dirname "$dst") 2>/dev/null ||
+ expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$dst" : 'X\(//\)[^/]' \| \
+ X"$dst" : 'X\(//\)$' \| \
+ X"$dst" : 'X\(/\)' \| . 2>/dev/null ||
+ echo X"$dst" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'
+ `
+
+ test -d "$dstdir"
+ dstdir_status=$?
+ fi
+ fi
+
+ obsolete_mkdir_used=false
+
+ if test $dstdir_status != 0; then
+ case $posix_mkdir in
+ '')
+ # Create intermediate dirs using mode 755 as modified by the umask.
+ # This is like FreeBSD 'install' as of 1997-10-28.
+ umask=`umask`
+ case $stripcmd.$umask in
+ # Optimize common cases.
+ *[2367][2367]) mkdir_umask=$umask;;
+ .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;
+
+ *[0-7])
+ mkdir_umask=`expr $umask + 22 \
+ - $umask % 100 % 40 + $umask % 20 \
+ - $umask % 10 % 4 + $umask % 2
+ `;;
+ *) mkdir_umask=$umask,go-w;;
+ esac
+
+ # With -d, create the new directory with the user-specified mode.
+ # Otherwise, rely on $mkdir_umask.
+ if test -n "$dir_arg"; then
+ mkdir_mode=-m$mode
+ else
+ mkdir_mode=
+ fi
+
+ posix_mkdir=false
+ case $umask in
+ *[123567][0-7][0-7])
+ # POSIX mkdir -p sets u+wx bits regardless of umask, which
+ # is incompatible with FreeBSD 'install' when (umask & 300) != 0.
+ ;;
+ *)
+ tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
+ trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0
+
+ if (umask $mkdir_umask &&
+ exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1
+ then
+ if test -z "$dir_arg" || {
+ # Check for POSIX incompatibilities with -m.
+ # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
+ # other-writeable bit of parent directory when it shouldn't.
+ # FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
+ ls_ld_tmpdir=`ls -ld "$tmpdir"`
+ case $ls_ld_tmpdir in
+ d????-?r-*) different_mode=700;;
+ d????-?--*) different_mode=755;;
+ *) false;;
+ esac &&
+ $mkdirprog -m$different_mode -p -- "$tmpdir" && {
+ ls_ld_tmpdir_1=`ls -ld "$tmpdir"`
+ test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
+ }
+ }
+ then posix_mkdir=:
+ fi
+ rmdir "$tmpdir/d" "$tmpdir"
+ else
+ # Remove any dirs left behind by ancient mkdir implementations.
+ rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null
+ fi
+ trap '' 0;;
+ esac;;
+ esac
+
+ if
+ $posix_mkdir && (
+ umask $mkdir_umask &&
+ $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
+ )
+ then :
+ else
+
+ # The umask is ridiculous, or mkdir does not conform to POSIX,
+ # or it failed possibly due to a race condition. Create the
+ # directory the slow way, step by step, checking for races as we go.
+
+ case $dstdir in
+ /*) prefix='/';;
+ -*) prefix='./';;
+ *) prefix='';;
+ esac
+
+ eval "$initialize_posix_glob"
+
+ oIFS=$IFS
+ IFS=/
+ $posix_glob set -f
+ set fnord $dstdir
+ shift
+ $posix_glob set +f
+ IFS=$oIFS
+
+ prefixes=
+
+ for d
+ do
+ test -z "$d" && continue
+
+ prefix=$prefix$d
+ if test -d "$prefix"; then
+ prefixes=
+ else
+ if $posix_mkdir; then
+ (umask=$mkdir_umask &&
+ $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
+ # Don't fail if two instances are running concurrently.
+ test -d "$prefix" || exit 1
+ else
+ case $prefix in
+ *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
+ *) qprefix=$prefix;;
+ esac
+ prefixes="$prefixes '$qprefix'"
+ fi
+ fi
+ prefix=$prefix/
+ done
+
+ if test -n "$prefixes"; then
+ # Don't fail if two instances are running concurrently.
+ (umask $mkdir_umask &&
+ eval "\$doit_exec \$mkdirprog $prefixes") ||
+ test -d "$dstdir" || exit 1
+ obsolete_mkdir_used=true
+ fi
+ fi
+ fi
+
+ if test -n "$dir_arg"; then
+ { test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
+ { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
+ { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
+ test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
+ else
+
+ # Make a couple of temp file names in the proper directory.
+ dsttmp=$dstdir/_inst.$$_
+ rmtmp=$dstdir/_rm.$$_
+
+ # Trap to clean up those temp files at exit.
+ trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
+
+ # Copy the file name to the temp name.
+ (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") &&
+
+ # and set any options; do chmod last to preserve setuid bits.
+ #
+ # If any of these fail, we abort the whole thing. If we want to
+ # ignore errors from any of these, just make sure not to ignore
+ # errors from the above "$doit $cpprog $src $dsttmp" command.
+ #
+ { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } &&
+ { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } &&
+ { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } &&
+ { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&
+
+ # If -C, don't bother to copy if it wouldn't change the file.
+ if $copy_on_change &&
+ old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` &&
+ new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` &&
+
+ eval "$initialize_posix_glob" &&
+ $posix_glob set -f &&
+ set X $old && old=:$2:$4:$5:$6 &&
+ set X $new && new=:$2:$4:$5:$6 &&
+ $posix_glob set +f &&
+
+ test "$old" = "$new" &&
+ $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
+ then
+ rm -f "$dsttmp"
+ else
+ # Rename the file to the real destination.
+ $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||
+
+ # The rename failed, perhaps because mv can't rename something else
+ # to itself, or perhaps because mv is so ancient that it does not
+ # support -f.
+ {
+ # Now remove or move aside any old file at destination location.
+ # We try this two ways since rm can't unlink itself on some
+ # systems and the destination file might be busy for other
+ # reasons. In this case, the final cleanup might fail but the new
+ # file should still install successfully.
+ {
+ test ! -f "$dst" ||
+ $doit $rmcmd -f "$dst" 2>/dev/null ||
+ { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
+ { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }
+ } ||
+ { echo "$0: cannot unlink or rename $dst" >&2
+ (exit 1); exit 1
+ }
+ } &&
+
+ # Now rename the file to the real destination.
+ $doit $mvcmd "$dsttmp" "$dst"
+ }
+ fi || exit 1
+
+ trap '' 0
+ fi
+done
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-end: "$"
+# End:
diff --git a/src/third_party/gflags-2.0/libtool b/src/third_party/gflags-2.0/libtool
new file mode 100755
index 00000000000..6c33e26e1f8
--- /dev/null
+++ b/src/third_party/gflags-2.0/libtool
@@ -0,0 +1,9060 @@
+#! /bin/sh
+
+# libtool - Provide generalized library-building support services.
+# Generated automatically by config.status (gflags) 2.0
+# Libtool was configured on host Harishabds-MacBook-Pro.local:
+# NOTE: Changes made to this file will be lost: look at ltmain.sh.
+#
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005,
+# 2006, 2007, 2008 Free Software Foundation, Inc.
+# Written by Gordon Matzigkeit, 1996
+#
+# This file is part of GNU Libtool.
+#
+# GNU Libtool is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# As a special exception to the GNU General Public License,
+# if you distribute this file as part of a program or library that
+# is built using GNU Libtool, you may include this file under the
+# same distribution terms that you use for the rest of that program.
+#
+# GNU Libtool is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Libtool; see the file COPYING. If not, a copy
+# can be downloaded from http://www.gnu.org/licenses/gpl.html, or
+# obtained by writing to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+
+# The names of the tagged configurations supported by this script.
+available_tags="CXX "
+
+# ### BEGIN LIBTOOL CONFIG
+
+# Whether or not to optimize for fast installation.
+fast_install=needless
+
+# Which release of libtool.m4 was used?
+macro_version=2.2.6b
+macro_revision=1.3017
+
+# Whether or not to build shared libraries.
+build_libtool_libs=yes
+
+# Whether or not to build static libraries.
+build_old_libs=yes
+
+# What type of objects to build.
+pic_mode=default
+
+# The host system.
+host_alias=
+host=i386-apple-darwin12.2.0
+host_os=darwin12.2.0
+
+# The build system.
+build_alias=
+build=i386-apple-darwin12.2.0
+build_os=darwin12.2.0
+
+# A sed program that does not truncate output.
+SED="/usr/bin/sed"
+
+# Sed that helps us avoid accidentally triggering echo(1) options like -n.
+Xsed="$SED -e 1s/^X//"
+
+# A grep program that handles long lines.
+GREP="/usr/bin/grep"
+
+# An ERE matcher.
+EGREP="/usr/bin/grep -E"
+
+# A literal string matcher.
+FGREP="/usr/bin/grep -F"
+
+# A BSD- or MS-compatible name lister.
+NM="/usr/bin/nm"
+
+# Whether we need soft or hard links.
+LN_S="ln -s"
+
+# What is the maximum length of a command?
+max_cmd_len=196608
+
+# Object file suffix (normally "o").
+objext=o
+
+# Executable file suffix (normally "").
+exeext=
+
+# whether the shell understands "unset".
+lt_unset=unset
+
+# turn spaces into newlines.
+SP2NL="tr \\040 \\012"
+
+# turn newlines into spaces.
+NL2SP="tr \\015\\012 \\040\\040"
+
+# How to create reloadable object files.
+reload_flag=" -r"
+reload_cmds="\$LTCC \$LTCFLAGS -nostdlib \${wl}-r -o \$output\$reload_objs"
+
+# An object symbol dumper.
+OBJDUMP="false"
+
+# Method to check whether dependent libraries are shared objects.
+deplibs_check_method="pass_all"
+
+# Command to use when deplibs_check_method == "file_magic".
+file_magic_cmd="\$MAGIC_CMD"
+
+# The archiver.
+AR="ar"
+AR_FLAGS="cru"
+
+# A symbol stripping program.
+STRIP="strip"
+
+# Commands used to install an old-style archive.
+RANLIB="ranlib"
+old_postinstall_cmds="chmod 644 \$oldlib~\$RANLIB \$oldlib"
+old_postuninstall_cmds=""
+
+# A C compiler.
+LTCC="gcc"
+
+# LTCC compiler flags.
+LTCFLAGS="-g -O2"
+
+# Take the output of nm and produce a listing of raw symbols and C names.
+global_symbol_pipe="sed -n -e 's/^.*[ ]\\([BCDEGRST][BCDEGRST]*\\)[ ][ ]*_\\([_A-Za-z][_A-Za-z0-9]*\\)\$/\\1 _\\2 \\2/p'"
+
+# Transform the output of nm in a proper C declaration.
+global_symbol_to_cdecl="sed -n -e 's/^T .* \\(.*\\)\$/extern int \\1();/p' -e 's/^[BCDEGRST]* .* \\(.*\\)\$/extern char \\1;/p'"
+
+# Transform the output of nm in a C name address pair.
+global_symbol_to_c_name_address="sed -n -e 's/^: \\([^ ]*\\) \$/ {\\\"\\1\\\", (void *) 0},/p' -e 's/^[BCDEGRST]* \\([^ ]*\\) \\([^ ]*\\)\$/ {\"\\2\", (void *) \\&\\2},/p'"
+
+# Transform the output of nm in a C name address pair when lib prefix is needed.
+global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \\([^ ]*\\) \$/ {\\\"\\1\\\", (void *) 0},/p' -e 's/^[BCDEGRST]* \\([^ ]*\\) \\(lib[^ ]*\\)\$/ {\"\\2\", (void *) \\&\\2},/p' -e 's/^[BCDEGRST]* \\([^ ]*\\) \\([^ ]*\\)\$/ {\"lib\\2\", (void *) \\&\\2},/p'"
+
+# The name of the directory that contains temporary libtool files.
+objdir=.libs
+
+# Shell to use when invoking shell scripts.
+SHELL="/bin/sh"
+
+# An echo program that does not interpret backslashes.
+ECHO="/bin/echo"
+
+# Used to examine libraries when file_magic_cmd begins with "file".
+MAGIC_CMD=file
+
+# Must we lock files when doing compilation?
+need_locks="no"
+
+# Tool to manipulate archived DWARF debug symbol files on Mac OS X.
+DSYMUTIL="dsymutil"
+
+# Tool to change global to local symbols on Mac OS X.
+NMEDIT="nmedit"
+
+# Tool to manipulate fat objects and archives on Mac OS X.
+LIPO="lipo"
+
+# ldd/readelf like tool for Mach-O binaries on Mac OS X.
+OTOOL="otool"
+
+# ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4.
+OTOOL64=":"
+
+# Old archive suffix (normally "a").
+libext=a
+
+# Shared library suffix (normally ".so").
+shrext_cmds="\`test .\$module = .yes && echo .so || echo .dylib\`"
+
+# The commands to extract the exported symbol list from a shared archive.
+extract_expsyms_cmds=""
+
+# Variables whose values should be saved in libtool wrapper scripts and
+# restored at link time.
+variables_saved_for_relink="PATH DYLD_LIBRARY_PATH GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH"
+
+# Do we need the "lib" prefix for modules?
+need_lib_prefix=no
+
+# Do we need a version for libraries?
+need_version=no
+
+# Library versioning type.
+version_type=darwin
+
+# Shared library runtime path variable.
+runpath_var=
+
+# Shared library path variable.
+shlibpath_var=DYLD_LIBRARY_PATH
+
+# Is shlibpath searched before the hard-coded library search path?
+shlibpath_overrides_runpath=yes
+
+# Format of library name prefix.
+libname_spec="lib\$name"
+
+# List of archive names. First name is the real one, the rest are links.
+# The last name is the one that the linker finds with -lNAME
+library_names_spec="\${libname}\${release}\${major}\$shared_ext \${libname}\$shared_ext"
+
+# The coded name of the library, if different from the real name.
+soname_spec="\${libname}\${release}\${major}\$shared_ext"
+
+# Command to use after installation of a shared archive.
+postinstall_cmds=""
+
+# Command to use after uninstallation of a shared archive.
+postuninstall_cmds=""
+
+# Commands used to finish a libtool library installation in a directory.
+finish_cmds=""
+
+# As "finish_cmds", except a single script fragment to be evaled but
+# not shown.
+finish_eval=""
+
+# Whether we should hardcode library paths into libraries.
+hardcode_into_libs=no
+
+# Compile-time system search path for libraries.
+sys_lib_search_path_spec="/usr/llvm-gcc-4.2/lib/gcc/i686-apple-darwin11/4.2.1/x86_64 /usr/lib /usr/llvm-gcc-4.2/lib/gcc /usr/llvm-gcc-4.2/lib /usr/local/lib"
+
+# Run-time system search path for libraries.
+sys_lib_dlsearch_path_spec="/usr/local/lib /lib /usr/lib"
+
+# Whether dlopen is supported.
+dlopen_support=unknown
+
+# Whether dlopen of programs is supported.
+dlopen_self=unknown
+
+# Whether dlopen of statically linked programs is supported.
+dlopen_self_static=unknown
+
+# Commands to strip libraries.
+old_striplib="strip -S"
+striplib="strip -x"
+
+
+# The linker used to build libraries.
+LD="/usr/llvm-gcc-4.2/libexec/gcc/i686-apple-darwin11/4.2.1/ld"
+
+# Commands used to build an old-style archive.
+old_archive_cmds="\$AR \$AR_FLAGS \$oldlib\$oldobjs~\$RANLIB \$oldlib"
+
+# A language specific compiler.
+CC="gcc"
+
+# Is the compiler the GNU compiler?
+with_gcc=yes
+
+# Compiler flag to turn off builtin functions.
+no_builtin_flag=" -fno-builtin"
+
+# How to pass a linker flag through the compiler.
+wl="-Wl,"
+
+# Additional compiler flags for building library objects.
+pic_flag=" -fno-common -DPIC"
+
+# Compiler flag to prevent dynamic linking.
+link_static_flag=""
+
+# Does compiler simultaneously support -c and -o options?
+compiler_c_o="yes"
+
+# Whether or not to add -lc for building shared libraries.
+build_libtool_need_lc=no
+
+# Whether or not to disallow shared libs when runtime libs are static.
+allow_libtool_libs_with_static_runtimes=no
+
+# Compiler flag to allow reflexive dlopens.
+export_dynamic_flag_spec=""
+
+# Compiler flag to generate shared objects directly from archives.
+whole_archive_flag_spec=""
+
+# Whether the compiler copes with passing no objects directly.
+compiler_needs_object="no"
+
+# Create an old-style archive from a shared archive.
+old_archive_from_new_cmds=""
+
+# Create a temporary old-style archive to link instead of a shared archive.
+old_archive_from_expsyms_cmds=""
+
+# Commands used to build a shared archive.
+archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring \$single_module~\$DSYMUTIL \$lib || :"
+archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring \$single_module \${wl}-exported_symbols_list,\$output_objdir/\${libname}-symbols.expsym~\$DSYMUTIL \$lib || :"
+
+# Commands used to build a loadable module if different from building
+# a shared archive.
+module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags~\$DSYMUTIL \$lib || :"
+module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags \${wl}-exported_symbols_list,\$output_objdir/\${libname}-symbols.expsym~\$DSYMUTIL \$lib || :"
+
+# Whether we are building with GNU ld or not.
+with_gnu_ld="no"
+
+# Flag that allows shared libraries with undefined symbols to be built.
+allow_undefined_flag="\${wl}-undefined \${wl}dynamic_lookup"
+
+# Flag that enforces no undefined symbols.
+no_undefined_flag=""
+
+# Flag to hardcode $libdir into a binary during linking.
+# This must work even if $libdir does not exist
+hardcode_libdir_flag_spec=""
+
+# If ld is used when linking, flag to hardcode $libdir into a binary
+# during linking. This must work even if $libdir does not exist.
+hardcode_libdir_flag_spec_ld=""
+
+# Whether we need a single "-rpath" flag with a separated argument.
+hardcode_libdir_separator=""
+
+# Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes
+# DIR into the resulting binary.
+hardcode_direct=no
+
+# Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes
+# DIR into the resulting binary and the resulting library dependency is
+# "absolute",i.e impossible to change by setting ${shlibpath_var} if the
+# library is relocated.
+hardcode_direct_absolute=no
+
+# Set to "yes" if using the -LDIR flag during linking hardcodes DIR
+# into the resulting binary.
+hardcode_minus_L=no
+
+# Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR
+# into the resulting binary.
+hardcode_shlibpath_var=unsupported
+
+# Set to "yes" if building a shared library automatically hardcodes DIR
+# into the library and all subsequent libraries and executables linked
+# against it.
+hardcode_automatic=yes
+
+# Set to yes if linker adds runtime paths of dependent libraries
+# to runtime path list.
+inherit_rpath=no
+
+# Whether libtool must link a program against all its dependency libraries.
+link_all_deplibs=yes
+
+# Fix the shell variable $srcfile for the compiler.
+fix_srcfile_path=""
+
+# Set to "yes" if exported symbols are required.
+always_export_symbols=no
+
+# The commands to list exported symbols.
+export_symbols_cmds="\$NM \$libobjs \$convenience | \$global_symbol_pipe | \$SED 's/.* //' | sort | uniq > \$export_symbols"
+
+# Symbols that should not be listed in the preloaded symbols.
+exclude_expsyms="_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*"
+
+# Symbols that must always be exported.
+include_expsyms=""
+
+# Commands necessary for linking programs (against libraries) with templates.
+prelink_cmds=""
+
+# Specify filename containing input files.
+file_list_spec=""
+
+# How to hardcode a shared library path into an executable.
+hardcode_action=immediate
+
+# The directories searched by this compiler when creating a shared library.
+compiler_lib_search_dirs=""
+
+# Dependencies to place before and after the objects being linked to
+# create a shared library.
+predep_objects=""
+postdep_objects=""
+predeps=""
+postdeps=""
+
+# The library search path used internally by the compiler when linking
+# a shared library.
+compiler_lib_search_path=""
+
+# ### END LIBTOOL CONFIG
+
+# Generated from ltmain.m4sh.
+
+# ltmain.sh (GNU libtool) 2.2.6b
+# Written by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
+
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006, 2007 2008 Free Software Foundation, Inc.
+# This is free software; see the source for copying conditions. There is NO
+# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+# GNU Libtool is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# As a special exception to the GNU General Public License,
+# if you distribute this file as part of a program or library that
+# is built using GNU Libtool, you may include this file under the
+# same distribution terms that you use for the rest of that program.
+#
+# GNU Libtool is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Libtool; see the file COPYING. If not, a copy
+# can be downloaded from http://www.gnu.org/licenses/gpl.html,
+# or obtained by writing to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+# Usage: $progname [OPTION]... [MODE-ARG]...
+#
+# Provide generalized library-building support services.
+#
+# --config show all configuration variables
+# --debug enable verbose shell tracing
+# -n, --dry-run display commands without modifying any files
+# --features display basic configuration information and exit
+# --mode=MODE use operation mode MODE
+# --preserve-dup-deps don't remove duplicate dependency libraries
+# --quiet, --silent don't print informational messages
+# --tag=TAG use configuration variables from tag TAG
+# -v, --verbose print informational messages (default)
+# --version print version information
+# -h, --help print short or long help message
+#
+# MODE must be one of the following:
+#
+# clean remove files from the build directory
+# compile compile a source file into a libtool object
+# execute automatically set library path, then run a program
+# finish complete the installation of libtool libraries
+# install install libraries or executables
+# link create a library or an executable
+# uninstall remove libraries from an installed directory
+#
+# MODE-ARGS vary depending on the MODE.
+# Try `$progname --help --mode=MODE' for a more detailed description of MODE.
+#
+# When reporting a bug, please describe a test case to reproduce it and
+# include the following information:
+#
+# host-triplet: $host
+# shell: $SHELL
+# compiler: $LTCC
+# compiler flags: $LTCFLAGS
+# linker: $LD (gnu? $with_gnu_ld)
+# $progname: (GNU libtool) 2.2.6b Debian-2.2.6b-2ubuntu1
+# automake: $automake_version
+# autoconf: $autoconf_version
+#
+# Report bugs to <bug-libtool@gnu.org>.
+
+PROGRAM=ltmain.sh
+PACKAGE=libtool
+VERSION="2.2.6b Debian-2.2.6b-2ubuntu1"
+TIMESTAMP=""
+package_revision=1.3017
+
+# Be Bourne compatible
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+ emulate sh
+ NULLCMD=:
+ # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '${1+"$@"}'='"$@"'
+ setopt NO_GLOB_SUBST
+else
+ case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac
+fi
+BIN_SH=xpg4; export BIN_SH # for Tru64
+DUALCASE=1; export DUALCASE # for MKS sh
+
+# NLS nuisances: We save the old values to restore during execute mode.
+# Only set LANG and LC_ALL to C if already set.
+# These must not be set unconditionally because not all systems understand
+# e.g. LANG=C (notably SCO).
+lt_user_locale=
+lt_safe_locale=
+for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES
+do
+ eval "if test \"\${$lt_var+set}\" = set; then
+ save_$lt_var=\$$lt_var
+ $lt_var=C
+ export $lt_var
+ lt_user_locale=\"$lt_var=\\\$save_\$lt_var; \$lt_user_locale\"
+ lt_safe_locale=\"$lt_var=C; \$lt_safe_locale\"
+ fi"
+done
+
+$lt_unset CDPATH
+
+
+
+
+
+: ${CP="cp -f"}
+: ${ECHO="echo"}
+: ${EGREP="/bin/grep -E"}
+: ${FGREP="/bin/grep -F"}
+: ${GREP="/bin/grep"}
+: ${LN_S="ln -s"}
+: ${MAKE="make"}
+: ${MKDIR="mkdir"}
+: ${MV="mv -f"}
+: ${RM="rm -f"}
+: ${SED="/bin/sed"}
+: ${SHELL="${CONFIG_SHELL-/bin/sh}"}
+: ${Xsed="$SED -e 1s/^X//"}
+
+# Global variables:
+EXIT_SUCCESS=0
+EXIT_FAILURE=1
+EXIT_MISMATCH=63 # $? = 63 is used to indicate version mismatch to missing.
+EXIT_SKIP=77 # $? = 77 is used to indicate a skipped test to automake.
+
+exit_status=$EXIT_SUCCESS
+
+# Make sure IFS has a sensible default
+lt_nl='
+'
+IFS=" $lt_nl"
+
+dirname="s,/[^/]*$,,"
+basename="s,^.*/,,"
+
+# func_dirname_and_basename file append nondir_replacement
+# perform func_basename and func_dirname in a single function
+# call:
+# dirname: Compute the dirname of FILE. If nonempty,
+# add APPEND to the result, otherwise set result
+# to NONDIR_REPLACEMENT.
+# value returned in "$func_dirname_result"
+# basename: Compute filename of FILE.
+# value retuned in "$func_basename_result"
+# Implementation must be kept synchronized with func_dirname
+# and func_basename. For efficiency, we do not delegate to
+# those functions but instead duplicate the functionality here.
+func_dirname_and_basename ()
+{
+ # Extract subdirectory from the argument.
+ func_dirname_result=`$ECHO "X${1}" | $Xsed -e "$dirname"`
+ if test "X$func_dirname_result" = "X${1}"; then
+ func_dirname_result="${3}"
+ else
+ func_dirname_result="$func_dirname_result${2}"
+ fi
+ func_basename_result=`$ECHO "X${1}" | $Xsed -e "$basename"`
+}
+
+# Generated shell functions inserted here.
+
+# func_dirname file append nondir_replacement
+# Compute the dirname of FILE. If nonempty, add APPEND to the result,
+# otherwise set result to NONDIR_REPLACEMENT.
+func_dirname ()
+{
+ case ${1} in
+ */*) func_dirname_result="${1%/*}${2}" ;;
+ * ) func_dirname_result="${3}" ;;
+ esac
+}
+
+# func_basename file
+func_basename ()
+{
+ func_basename_result="${1##*/}"
+}
+
+# func_dirname_and_basename file append nondir_replacement
+# perform func_basename and func_dirname in a single function
+# call:
+# dirname: Compute the dirname of FILE. If nonempty,
+# add APPEND to the result, otherwise set result
+# to NONDIR_REPLACEMENT.
+# value returned in "$func_dirname_result"
+# basename: Compute filename of FILE.
+# value retuned in "$func_basename_result"
+# Implementation must be kept synchronized with func_dirname
+# and func_basename. For efficiency, we do not delegate to
+# those functions but instead duplicate the functionality here.
+func_dirname_and_basename ()
+{
+ case ${1} in
+ */*) func_dirname_result="${1%/*}${2}" ;;
+ * ) func_dirname_result="${3}" ;;
+ esac
+ func_basename_result="${1##*/}"
+}
+
+# func_stripname prefix suffix name
+# strip PREFIX and SUFFIX off of NAME.
+# PREFIX and SUFFIX must not contain globbing or regex special
+# characters, hashes, percent signs, but SUFFIX may contain a leading
+# dot (in which case that matches only a dot).
+func_stripname ()
+{
+ # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are
+ # positional parameters, so assign one to ordinary parameter first.
+ func_stripname_result=${3}
+ func_stripname_result=${func_stripname_result#"${1}"}
+ func_stripname_result=${func_stripname_result%"${2}"}
+}
+
+# func_opt_split
+func_opt_split ()
+{
+ func_opt_split_opt=${1%%=*}
+ func_opt_split_arg=${1#*=}
+}
+
+# func_lo2o object
+func_lo2o ()
+{
+ case ${1} in
+ *.lo) func_lo2o_result=${1%.lo}.${objext} ;;
+ *) func_lo2o_result=${1} ;;
+ esac
+}
+
+# func_xform libobj-or-source
+func_xform ()
+{
+ func_xform_result=${1%.*}.lo
+}
+
+# func_arith arithmetic-term...
+func_arith ()
+{
+ func_arith_result=$(( $* ))
+}
+
+# func_len string
+# STRING may not start with a hyphen.
+func_len ()
+{
+ func_len_result=${#1}
+}
+
+
+# func_append var value
+# Append VALUE to the end of shell variable VAR.
+func_append ()
+{
+ eval "$1+=\$2"
+}
+# Generated shell functions inserted here.
+
+# Work around backward compatibility issue on IRIX 6.5. On IRIX 6.4+, sh
+# is ksh but when the shell is invoked as "sh" and the current value of
+# the _XPG environment variable is not equal to 1 (one), the special
+# positional parameter $0, within a function call, is the name of the
+# function.
+progpath="$0"
+
+# The name of this program:
+# In the unlikely event $progname began with a '-', it would play havoc with
+# func_echo (imagine progname=-n), so we prepend ./ in that case:
+func_dirname_and_basename "$progpath"
+progname=$func_basename_result
+case $progname in
+ -*) progname=./$progname ;;
+esac
+
+# Make sure we have an absolute path for reexecution:
+case $progpath in
+ [\\/]*|[A-Za-z]:\\*) ;;
+ *[\\/]*)
+ progdir=$func_dirname_result
+ progdir=`cd "$progdir" && pwd`
+ progpath="$progdir/$progname"
+ ;;
+ *)
+ save_IFS="$IFS"
+ IFS=:
+ for progdir in $PATH; do
+ IFS="$save_IFS"
+ test -x "$progdir/$progname" && break
+ done
+ IFS="$save_IFS"
+ test -n "$progdir" || progdir=`pwd`
+ progpath="$progdir/$progname"
+ ;;
+esac
+
+# Sed substitution that helps us do robust quoting. It backslashifies
+# metacharacters that are still active within double-quoted strings.
+Xsed="${SED}"' -e 1s/^X//'
+sed_quote_subst='s/\([`"$\\]\)/\\\1/g'
+
+# Same as above, but do not quote variable references.
+double_quote_subst='s/\(["`\\]\)/\\\1/g'
+
+# Re-`\' parameter expansions in output of double_quote_subst that were
+# `\'-ed in input to the same. If an odd number of `\' preceded a '$'
+# in input to double_quote_subst, that '$' was protected from expansion.
+# Since each input `\' is now two `\'s, look for any number of runs of
+# four `\'s followed by two `\'s and then a '$'. `\' that '$'.
+bs='\\'
+bs2='\\\\'
+bs4='\\\\\\\\'
+dollar='\$'
+sed_double_backslash="\
+ s/$bs4/&\\
+/g
+ s/^$bs2$dollar/$bs&/
+ s/\\([^$bs]\\)$bs2$dollar/\\1$bs2$bs$dollar/g
+ s/\n//g"
+
+# Standard options:
+opt_dry_run=false
+opt_help=false
+opt_quiet=false
+opt_verbose=false
+opt_warning=:
+
+# func_echo arg...
+# Echo program name prefixed message, along with the current mode
+# name if it has been set yet.
+func_echo ()
+{
+ $ECHO "$progname${mode+: }$mode: $*"
+}
+
+# func_verbose arg...
+# Echo program name prefixed message in verbose mode only.
+func_verbose ()
+{
+ $opt_verbose && func_echo ${1+"$@"}
+
+ # A bug in bash halts the script if the last line of a function
+ # fails when set -e is in force, so we need another command to
+ # work around that:
+ :
+}
+
+# func_error arg...
+# Echo program name prefixed message to standard error.
+func_error ()
+{
+ $ECHO "$progname${mode+: }$mode: "${1+"$@"} 1>&2
+}
+
+# func_warning arg...
+# Echo program name prefixed warning message to standard error.
+func_warning ()
+{
+ $opt_warning && $ECHO "$progname${mode+: }$mode: warning: "${1+"$@"} 1>&2
+
+ # bash bug again:
+ :
+}
+
+# func_fatal_error arg...
+# Echo program name prefixed message to standard error, and exit.
+func_fatal_error ()
+{
+ func_error ${1+"$@"}
+ exit $EXIT_FAILURE
+}
+
+# func_fatal_help arg...
+# Echo program name prefixed message to standard error, followed by
+# a help hint, and exit.
+func_fatal_help ()
+{
+ func_error ${1+"$@"}
+ func_fatal_error "$help"
+}
+help="Try \`$progname --help' for more information." ## default
+
+
+# func_grep expression filename
+# Check whether EXPRESSION matches any line of FILENAME, without output.
+func_grep ()
+{
+ $GREP "$1" "$2" >/dev/null 2>&1
+}
+
+
+# func_mkdir_p directory-path
+# Make sure the entire path to DIRECTORY-PATH is available.
+func_mkdir_p ()
+{
+ my_directory_path="$1"
+ my_dir_list=
+
+ if test -n "$my_directory_path" && test "$opt_dry_run" != ":"; then
+
+ # Protect directory names starting with `-'
+ case $my_directory_path in
+ -*) my_directory_path="./$my_directory_path" ;;
+ esac
+
+ # While some portion of DIR does not yet exist...
+ while test ! -d "$my_directory_path"; do
+ # ...make a list in topmost first order. Use a colon delimited
+ # list incase some portion of path contains whitespace.
+ my_dir_list="$my_directory_path:$my_dir_list"
+
+ # If the last portion added has no slash in it, the list is done
+ case $my_directory_path in */*) ;; *) break ;; esac
+
+ # ...otherwise throw away the child directory and loop
+ my_directory_path=`$ECHO "X$my_directory_path" | $Xsed -e "$dirname"`
+ done
+ my_dir_list=`$ECHO "X$my_dir_list" | $Xsed -e 's,:*$,,'`
+
+ save_mkdir_p_IFS="$IFS"; IFS=':'
+ for my_dir in $my_dir_list; do
+ IFS="$save_mkdir_p_IFS"
+ # mkdir can fail with a `File exist' error if two processes
+ # try to create one of the directories concurrently. Don't
+ # stop in that case!
+ $MKDIR "$my_dir" 2>/dev/null || :
+ done
+ IFS="$save_mkdir_p_IFS"
+
+ # Bail out if we (or some other process) failed to create a directory.
+ test -d "$my_directory_path" || \
+ func_fatal_error "Failed to create \`$1'"
+ fi
+}
+
+
+# func_mktempdir [string]
+# Make a temporary directory that won't clash with other running
+# libtool processes, and avoids race conditions if possible. If
+# given, STRING is the basename for that directory.
+func_mktempdir ()
+{
+ my_template="${TMPDIR-/tmp}/${1-$progname}"
+
+ if test "$opt_dry_run" = ":"; then
+ # Return a directory name, but don't create it in dry-run mode
+ my_tmpdir="${my_template}-$$"
+ else
+
+ # If mktemp works, use that first and foremost
+ my_tmpdir=`mktemp -d "${my_template}-XXXXXXXX" 2>/dev/null`
+
+ if test ! -d "$my_tmpdir"; then
+ # Failing that, at least try and use $RANDOM to avoid a race
+ my_tmpdir="${my_template}-${RANDOM-0}$$"
+
+ save_mktempdir_umask=`umask`
+ umask 0077
+ $MKDIR "$my_tmpdir"
+ umask $save_mktempdir_umask
+ fi
+
+ # If we're not in dry-run mode, bomb out on failure
+ test -d "$my_tmpdir" || \
+ func_fatal_error "cannot create temporary directory \`$my_tmpdir'"
+ fi
+
+ $ECHO "X$my_tmpdir" | $Xsed
+}
+
+
+# func_quote_for_eval arg
+# Aesthetically quote ARG to be evaled later.
+# This function returns two values: FUNC_QUOTE_FOR_EVAL_RESULT
+# is double-quoted, suitable for a subsequent eval, whereas
+# FUNC_QUOTE_FOR_EVAL_UNQUOTED_RESULT has merely all characters
+# which are still active within double quotes backslashified.
+func_quote_for_eval ()
+{
+ case $1 in
+ *[\\\`\"\$]*)
+ func_quote_for_eval_unquoted_result=`$ECHO "X$1" | $Xsed -e "$sed_quote_subst"` ;;
+ *)
+ func_quote_for_eval_unquoted_result="$1" ;;
+ esac
+
+ case $func_quote_for_eval_unquoted_result in
+ # Double-quote args containing shell metacharacters to delay
+ # word splitting, command substitution and and variable
+ # expansion for a subsequent eval.
+ # Many Bourne shells cannot handle close brackets correctly
+ # in scan sets, so we specify it separately.
+ *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"")
+ func_quote_for_eval_result="\"$func_quote_for_eval_unquoted_result\""
+ ;;
+ *)
+ func_quote_for_eval_result="$func_quote_for_eval_unquoted_result"
+ esac
+}
+
+
+# func_quote_for_expand arg
+# Aesthetically quote ARG to be evaled later; same as above,
+# but do not quote variable references.
+func_quote_for_expand ()
+{
+ case $1 in
+ *[\\\`\"]*)
+ my_arg=`$ECHO "X$1" | $Xsed \
+ -e "$double_quote_subst" -e "$sed_double_backslash"` ;;
+ *)
+ my_arg="$1" ;;
+ esac
+
+ case $my_arg in
+ # Double-quote args containing shell metacharacters to delay
+ # word splitting and command substitution for a subsequent eval.
+ # Many Bourne shells cannot handle close brackets correctly
+ # in scan sets, so we specify it separately.
+ *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"")
+ my_arg="\"$my_arg\""
+ ;;
+ esac
+
+ func_quote_for_expand_result="$my_arg"
+}
+
+
+# func_show_eval cmd [fail_exp]
+# Unless opt_silent is true, then output CMD. Then, if opt_dryrun is
+# not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP
+# is given, then evaluate it.
+func_show_eval ()
+{
+ my_cmd="$1"
+ my_fail_exp="${2-:}"
+
+ ${opt_silent-false} || {
+ func_quote_for_expand "$my_cmd"
+ eval "func_echo $func_quote_for_expand_result"
+ }
+
+ if ${opt_dry_run-false}; then :; else
+ eval "$my_cmd"
+ my_status=$?
+ if test "$my_status" -eq 0; then :; else
+ eval "(exit $my_status); $my_fail_exp"
+ fi
+ fi
+}
+
+
+# func_show_eval_locale cmd [fail_exp]
+# Unless opt_silent is true, then output CMD. Then, if opt_dryrun is
+# not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP
+# is given, then evaluate it. Use the saved locale for evaluation.
+func_show_eval_locale ()
+{
+ my_cmd="$1"
+ my_fail_exp="${2-:}"
+
+ ${opt_silent-false} || {
+ func_quote_for_expand "$my_cmd"
+ eval "func_echo $func_quote_for_expand_result"
+ }
+
+ if ${opt_dry_run-false}; then :; else
+ eval "$lt_user_locale
+ $my_cmd"
+ my_status=$?
+ eval "$lt_safe_locale"
+ if test "$my_status" -eq 0; then :; else
+ eval "(exit $my_status); $my_fail_exp"
+ fi
+ fi
+}
+
+
+
+
+
+# func_version
+# Echo version message to standard output and exit.
+func_version ()
+{
+ $SED -n '/^# '$PROGRAM' (GNU /,/# warranty; / {
+ s/^# //
+ s/^# *$//
+ s/\((C)\)[ 0-9,-]*\( [1-9][0-9]*\)/\1\2/
+ p
+ }' < "$progpath"
+ exit $?
+}
+
+# func_usage
+# Echo short help message to standard output and exit.
+func_usage ()
+{
+ $SED -n '/^# Usage:/,/# -h/ {
+ s/^# //
+ s/^# *$//
+ s/\$progname/'$progname'/
+ p
+ }' < "$progpath"
+ $ECHO
+ $ECHO "run \`$progname --help | more' for full usage"
+ exit $?
+}
+
+# func_help
+# Echo long help message to standard output and exit.
+func_help ()
+{
+ $SED -n '/^# Usage:/,/# Report bugs to/ {
+ s/^# //
+ s/^# *$//
+ s*\$progname*'$progname'*
+ s*\$host*'"$host"'*
+ s*\$SHELL*'"$SHELL"'*
+ s*\$LTCC*'"$LTCC"'*
+ s*\$LTCFLAGS*'"$LTCFLAGS"'*
+ s*\$LD*'"$LD"'*
+ s/\$with_gnu_ld/'"$with_gnu_ld"'/
+ s/\$automake_version/'"`(automake --version) 2>/dev/null |$SED 1q`"'/
+ s/\$autoconf_version/'"`(autoconf --version) 2>/dev/null |$SED 1q`"'/
+ p
+ }' < "$progpath"
+ exit $?
+}
+
+# func_missing_arg argname
+# Echo program name prefixed message to standard error and set global
+# exit_cmd.
+func_missing_arg ()
+{
+ func_error "missing argument for $1"
+ exit_cmd=exit
+}
+
+exit_cmd=:
+
+
+
+
+
+# Check that we have a working $ECHO.
+if test "X$1" = X--no-reexec; then
+ # Discard the --no-reexec flag, and continue.
+ shift
+elif test "X$1" = X--fallback-echo; then
+ # Avoid inline document here, it may be left over
+ :
+elif test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t'; then
+ # Yippee, $ECHO works!
+ :
+else
+ # Restart under the correct shell, and then maybe $ECHO will work.
+ exec $SHELL "$progpath" --no-reexec ${1+"$@"}
+fi
+
+if test "X$1" = X--fallback-echo; then
+ # used as fallback echo
+ shift
+ cat <<EOF
+$*
+EOF
+ exit $EXIT_SUCCESS
+fi
+
+magic="%%%MAGIC variable%%%"
+magic_exe="%%%MAGIC EXE variable%%%"
+
+# Global variables.
+# $mode is unset
+nonopt=
+execute_dlfiles=
+preserve_args=
+lo2o="s/\\.lo\$/.${objext}/"
+o2lo="s/\\.${objext}\$/.lo/"
+extracted_archives=
+extracted_serial=0
+
+opt_dry_run=false
+opt_duplicate_deps=false
+opt_silent=false
+opt_debug=:
+
+# If this variable is set in any of the actions, the command in it
+# will be execed at the end. This prevents here-documents from being
+# left over by shells.
+exec_cmd=
+
+# func_fatal_configuration arg...
+# Echo program name prefixed message to standard error, followed by
+# a configuration failure hint, and exit.
+func_fatal_configuration ()
+{
+ func_error ${1+"$@"}
+ func_error "See the $PACKAGE documentation for more information."
+ func_fatal_error "Fatal configuration error."
+}
+
+
+# func_config
+# Display the configuration for all the tags in this script.
+func_config ()
+{
+ re_begincf='^# ### BEGIN LIBTOOL'
+ re_endcf='^# ### END LIBTOOL'
+
+ # Default configuration.
+ $SED "1,/$re_begincf CONFIG/d;/$re_endcf CONFIG/,\$d" < "$progpath"
+
+ # Now print the configurations for the tags.
+ for tagname in $taglist; do
+ $SED -n "/$re_begincf TAG CONFIG: $tagname\$/,/$re_endcf TAG CONFIG: $tagname\$/p" < "$progpath"
+ done
+
+ exit $?
+}
+
+# func_features
+# Display the features supported by this script.
+func_features ()
+{
+ $ECHO "host: $host"
+ if test "$build_libtool_libs" = yes; then
+ $ECHO "enable shared libraries"
+ else
+ $ECHO "disable shared libraries"
+ fi
+ if test "$build_old_libs" = yes; then
+ $ECHO "enable static libraries"
+ else
+ $ECHO "disable static libraries"
+ fi
+
+ exit $?
+}
+
+# func_enable_tag tagname
+# Verify that TAGNAME is valid, and either flag an error and exit, or
+# enable the TAGNAME tag. We also add TAGNAME to the global $taglist
+# variable here.
+func_enable_tag ()
+{
+ # Global variable:
+ tagname="$1"
+
+ re_begincf="^# ### BEGIN LIBTOOL TAG CONFIG: $tagname\$"
+ re_endcf="^# ### END LIBTOOL TAG CONFIG: $tagname\$"
+ sed_extractcf="/$re_begincf/,/$re_endcf/p"
+
+ # Validate tagname.
+ case $tagname in
+ *[!-_A-Za-z0-9,/]*)
+ func_fatal_error "invalid tag name: $tagname"
+ ;;
+ esac
+
+ # Don't test for the "default" C tag, as we know it's
+ # there but not specially marked.
+ case $tagname in
+ CC) ;;
+ *)
+ if $GREP "$re_begincf" "$progpath" >/dev/null 2>&1; then
+ taglist="$taglist $tagname"
+
+ # Evaluate the configuration. Be careful to quote the path
+ # and the sed script, to avoid splitting on whitespace, but
+ # also don't use non-portable quotes within backquotes within
+ # quotes we have to do it in 2 steps:
+ extractedcf=`$SED -n -e "$sed_extractcf" < "$progpath"`
+ eval "$extractedcf"
+ else
+ func_error "ignoring unknown tag $tagname"
+ fi
+ ;;
+ esac
+}
+
+# Parse options once, thoroughly. This comes as soon as possible in
+# the script to make things like `libtool --version' happen quickly.
+{
+
+ # Shorthand for --mode=foo, only valid as the first argument
+ case $1 in
+ clean|clea|cle|cl)
+ shift; set dummy --mode clean ${1+"$@"}; shift
+ ;;
+ compile|compil|compi|comp|com|co|c)
+ shift; set dummy --mode compile ${1+"$@"}; shift
+ ;;
+ execute|execut|execu|exec|exe|ex|e)
+ shift; set dummy --mode execute ${1+"$@"}; shift
+ ;;
+ finish|finis|fini|fin|fi|f)
+ shift; set dummy --mode finish ${1+"$@"}; shift
+ ;;
+ install|instal|insta|inst|ins|in|i)
+ shift; set dummy --mode install ${1+"$@"}; shift
+ ;;
+ link|lin|li|l)
+ shift; set dummy --mode link ${1+"$@"}; shift
+ ;;
+ uninstall|uninstal|uninsta|uninst|unins|unin|uni|un|u)
+ shift; set dummy --mode uninstall ${1+"$@"}; shift
+ ;;
+ esac
+
+ # Parse non-mode specific arguments:
+ while test "$#" -gt 0; do
+ opt="$1"
+ shift
+
+ case $opt in
+ --config) func_config ;;
+
+ --debug) preserve_args="$preserve_args $opt"
+ func_echo "enabling shell trace mode"
+ opt_debug='set -x'
+ $opt_debug
+ ;;
+
+ -dlopen) test "$#" -eq 0 && func_missing_arg "$opt" && break
+ execute_dlfiles="$execute_dlfiles $1"
+ shift
+ ;;
+
+ --dry-run | -n) opt_dry_run=: ;;
+ --features) func_features ;;
+ --finish) mode="finish" ;;
+
+ --mode) test "$#" -eq 0 && func_missing_arg "$opt" && break
+ case $1 in
+ # Valid mode arguments:
+ clean) ;;
+ compile) ;;
+ execute) ;;
+ finish) ;;
+ install) ;;
+ link) ;;
+ relink) ;;
+ uninstall) ;;
+
+ # Catch anything else as an error
+ *) func_error "invalid argument for $opt"
+ exit_cmd=exit
+ break
+ ;;
+ esac
+
+ mode="$1"
+ shift
+ ;;
+
+ --preserve-dup-deps)
+ opt_duplicate_deps=: ;;
+
+ --quiet|--silent) preserve_args="$preserve_args $opt"
+ opt_silent=:
+ ;;
+
+ --verbose| -v) preserve_args="$preserve_args $opt"
+ opt_silent=false
+ ;;
+
+ --tag) test "$#" -eq 0 && func_missing_arg "$opt" && break
+ preserve_args="$preserve_args $opt $1"
+ func_enable_tag "$1" # tagname is set here
+ shift
+ ;;
+
+ # Separate optargs to long options:
+ -dlopen=*|--mode=*|--tag=*)
+ func_opt_split "$opt"
+ set dummy "$func_opt_split_opt" "$func_opt_split_arg" ${1+"$@"}
+ shift
+ ;;
+
+ -\?|-h) func_usage ;;
+ --help) opt_help=: ;;
+ --version) func_version ;;
+
+ -*) func_fatal_help "unrecognized option \`$opt'" ;;
+
+ *) nonopt="$opt"
+ break
+ ;;
+ esac
+ done
+
+
+ case $host in
+ *cygwin* | *mingw* | *pw32* | *cegcc*)
+ # don't eliminate duplications in $postdeps and $predeps
+ opt_duplicate_compiler_generated_deps=:
+ ;;
+ *)
+ opt_duplicate_compiler_generated_deps=$opt_duplicate_deps
+ ;;
+ esac
+
+ # Having warned about all mis-specified options, bail out if
+ # anything was wrong.
+ $exit_cmd $EXIT_FAILURE
+}
+
+# func_check_version_match
+# Ensure that we are using m4 macros, and libtool script from the same
+# release of libtool.
+func_check_version_match ()
+{
+ if test "$package_revision" != "$macro_revision"; then
+ if test "$VERSION" != "$macro_version"; then
+ if test -z "$macro_version"; then
+ cat >&2 <<_LT_EOF
+$progname: Version mismatch error. This is $PACKAGE $VERSION, but the
+$progname: definition of this LT_INIT comes from an older release.
+$progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION
+$progname: and run autoconf again.
+_LT_EOF
+ else
+ cat >&2 <<_LT_EOF
+$progname: Version mismatch error. This is $PACKAGE $VERSION, but the
+$progname: definition of this LT_INIT comes from $PACKAGE $macro_version.
+$progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION
+$progname: and run autoconf again.
+_LT_EOF
+ fi
+ else
+ cat >&2 <<_LT_EOF
+$progname: Version mismatch error. This is $PACKAGE $VERSION, revision $package_revision,
+$progname: but the definition of this LT_INIT comes from revision $macro_revision.
+$progname: You should recreate aclocal.m4 with macros from revision $package_revision
+$progname: of $PACKAGE $VERSION and run autoconf again.
+_LT_EOF
+ fi
+
+ exit $EXIT_MISMATCH
+ fi
+}
+
+
+## ----------- ##
+## Main. ##
+## ----------- ##
+
+$opt_help || {
+ # Sanity checks first:
+ func_check_version_match
+
+ if test "$build_libtool_libs" != yes && test "$build_old_libs" != yes; then
+ func_fatal_configuration "not configured to build any kind of library"
+ fi
+
+ test -z "$mode" && func_fatal_error "error: you must specify a MODE."
+
+
+ # Darwin sucks
+ eval std_shrext=\"$shrext_cmds\"
+
+
+ # Only execute mode is allowed to have -dlopen flags.
+ if test -n "$execute_dlfiles" && test "$mode" != execute; then
+ func_error "unrecognized option \`-dlopen'"
+ $ECHO "$help" 1>&2
+ exit $EXIT_FAILURE
+ fi
+
+ # Change the help message to a mode-specific one.
+ generic_help="$help"
+ help="Try \`$progname --help --mode=$mode' for more information."
+}
+
+
+# func_lalib_p file
+# True iff FILE is a libtool `.la' library or `.lo' object file.
+# This function is only a basic sanity check; it will hardly flush out
+# determined imposters.
+func_lalib_p ()
+{
+ test -f "$1" &&
+ $SED -e 4q "$1" 2>/dev/null \
+ | $GREP "^# Generated by .*$PACKAGE" > /dev/null 2>&1
+}
+
+# func_lalib_unsafe_p file
+# True iff FILE is a libtool `.la' library or `.lo' object file.
+# This function implements the same check as func_lalib_p without
+# resorting to external programs. To this end, it redirects stdin and
+# closes it afterwards, without saving the original file descriptor.
+# As a safety measure, use it only where a negative result would be
+# fatal anyway. Works if `file' does not exist.
+func_lalib_unsafe_p ()
+{
+ lalib_p=no
+ if test -f "$1" && test -r "$1" && exec 5<&0 <"$1"; then
+ for lalib_p_l in 1 2 3 4
+ do
+ read lalib_p_line
+ case "$lalib_p_line" in
+ \#\ Generated\ by\ *$PACKAGE* ) lalib_p=yes; break;;
+ esac
+ done
+ exec 0<&5 5<&-
+ fi
+ test "$lalib_p" = yes
+}
+
+# func_ltwrapper_script_p file
+# True iff FILE is a libtool wrapper script
+# This function is only a basic sanity check; it will hardly flush out
+# determined imposters.
+func_ltwrapper_script_p ()
+{
+ func_lalib_p "$1"
+}
+
+# func_ltwrapper_executable_p file
+# True iff FILE is a libtool wrapper executable
+# This function is only a basic sanity check; it will hardly flush out
+# determined imposters.
+func_ltwrapper_executable_p ()
+{
+ func_ltwrapper_exec_suffix=
+ case $1 in
+ *.exe) ;;
+ *) func_ltwrapper_exec_suffix=.exe ;;
+ esac
+ $GREP "$magic_exe" "$1$func_ltwrapper_exec_suffix" >/dev/null 2>&1
+}
+
+# func_ltwrapper_scriptname file
+# Assumes file is an ltwrapper_executable
+# uses $file to determine the appropriate filename for a
+# temporary ltwrapper_script.
+func_ltwrapper_scriptname ()
+{
+ func_ltwrapper_scriptname_result=""
+ if func_ltwrapper_executable_p "$1"; then
+ func_dirname_and_basename "$1" "" "."
+ func_stripname '' '.exe' "$func_basename_result"
+ func_ltwrapper_scriptname_result="$func_dirname_result/$objdir/${func_stripname_result}_ltshwrapper"
+ fi
+}
+
+# func_ltwrapper_p file
+# True iff FILE is a libtool wrapper script or wrapper executable
+# This function is only a basic sanity check; it will hardly flush out
+# determined imposters.
+func_ltwrapper_p ()
+{
+ func_ltwrapper_script_p "$1" || func_ltwrapper_executable_p "$1"
+}
+
+
+# func_execute_cmds commands fail_cmd
+# Execute tilde-delimited COMMANDS.
+# If FAIL_CMD is given, eval that upon failure.
+# FAIL_CMD may read-access the current command in variable CMD!
+func_execute_cmds ()
+{
+ $opt_debug
+ save_ifs=$IFS; IFS='~'
+ for cmd in $1; do
+ IFS=$save_ifs
+ eval cmd=\"$cmd\"
+ func_show_eval "$cmd" "${2-:}"
+ done
+ IFS=$save_ifs
+}
+
+
+# func_source file
+# Source FILE, adding directory component if necessary.
+# Note that it is not necessary on cygwin/mingw to append a dot to
+# FILE even if both FILE and FILE.exe exist: automatic-append-.exe
+# behavior happens only for exec(3), not for open(2)! Also, sourcing
+# `FILE.' does not work on cygwin managed mounts.
+func_source ()
+{
+ $opt_debug
+ case $1 in
+ */* | *\\*) . "$1" ;;
+ *) . "./$1" ;;
+ esac
+}
+
+
+# func_infer_tag arg
+# Infer tagged configuration to use if any are available and
+# if one wasn't chosen via the "--tag" command line option.
+# Only attempt this if the compiler in the base compile
+# command doesn't match the default compiler.
+# arg is usually of the form 'gcc ...'
+func_infer_tag ()
+{
+ $opt_debug
+ if test -n "$available_tags" && test -z "$tagname"; then
+ CC_quoted=
+ for arg in $CC; do
+ func_quote_for_eval "$arg"
+ CC_quoted="$CC_quoted $func_quote_for_eval_result"
+ done
+ case $@ in
+ # Blanks in the command may have been stripped by the calling shell,
+ # but not from the CC environment variable when configure was run.
+ " $CC "* | "$CC "* | " `$ECHO $CC` "* | "`$ECHO $CC` "* | " $CC_quoted"* | "$CC_quoted "* | " `$ECHO $CC_quoted` "* | "`$ECHO $CC_quoted` "*) ;;
+ # Blanks at the start of $base_compile will cause this to fail
+ # if we don't check for them as well.
+ *)
+ for z in $available_tags; do
+ if $GREP "^# ### BEGIN LIBTOOL TAG CONFIG: $z$" < "$progpath" > /dev/null; then
+ # Evaluate the configuration.
+ eval "`${SED} -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^# ### END LIBTOOL TAG CONFIG: '$z'$/p' < $progpath`"
+ CC_quoted=
+ for arg in $CC; do
+ # Double-quote args containing other shell metacharacters.
+ func_quote_for_eval "$arg"
+ CC_quoted="$CC_quoted $func_quote_for_eval_result"
+ done
+ case "$@ " in
+ " $CC "* | "$CC "* | " `$ECHO $CC` "* | "`$ECHO $CC` "* | " $CC_quoted"* | "$CC_quoted "* | " `$ECHO $CC_quoted` "* | "`$ECHO $CC_quoted` "*)
+ # The compiler in the base compile command matches
+ # the one in the tagged configuration.
+ # Assume this is the tagged configuration we want.
+ tagname=$z
+ break
+ ;;
+ esac
+ fi
+ done
+ # If $tagname still isn't set, then no tagged configuration
+ # was found and let the user know that the "--tag" command
+ # line option must be used.
+ if test -z "$tagname"; then
+ func_echo "unable to infer tagged configuration"
+ func_fatal_error "specify a tag with \`--tag'"
+# else
+# func_verbose "using $tagname tagged configuration"
+ fi
+ ;;
+ esac
+ fi
+}
+
+
+
+# func_write_libtool_object output_name pic_name nonpic_name
+# Create a libtool object file (analogous to a ".la" file),
+# but don't create it if we're doing a dry run.
+func_write_libtool_object ()
+{
+ write_libobj=${1}
+ if test "$build_libtool_libs" = yes; then
+ write_lobj=\'${2}\'
+ else
+ write_lobj=none
+ fi
+
+ if test "$build_old_libs" = yes; then
+ write_oldobj=\'${3}\'
+ else
+ write_oldobj=none
+ fi
+
+ $opt_dry_run || {
+ cat >${write_libobj}T <<EOF
+# $write_libobj - a libtool object file
+# Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION
+#
+# Please DO NOT delete this file!
+# It is necessary for linking the library.
+
+# Name of the PIC object.
+pic_object=$write_lobj
+
+# Name of the non-PIC object
+non_pic_object=$write_oldobj
+
+EOF
+ $MV "${write_libobj}T" "${write_libobj}"
+ }
+}
+
+# func_mode_compile arg...
+func_mode_compile ()
+{
+ $opt_debug
+ # Get the compilation command and the source file.
+ base_compile=
+ srcfile="$nonopt" # always keep a non-empty value in "srcfile"
+ suppress_opt=yes
+ suppress_output=
+ arg_mode=normal
+ libobj=
+ later=
+ pie_flag=
+
+ for arg
+ do
+ case $arg_mode in
+ arg )
+ # do not "continue". Instead, add this to base_compile
+ lastarg="$arg"
+ arg_mode=normal
+ ;;
+
+ target )
+ libobj="$arg"
+ arg_mode=normal
+ continue
+ ;;
+
+ normal )
+ # Accept any command-line options.
+ case $arg in
+ -o)
+ test -n "$libobj" && \
+ func_fatal_error "you cannot specify \`-o' more than once"
+ arg_mode=target
+ continue
+ ;;
+
+ -pie | -fpie | -fPIE)
+ pie_flag="$pie_flag $arg"
+ continue
+ ;;
+
+ -shared | -static | -prefer-pic | -prefer-non-pic)
+ later="$later $arg"
+ continue
+ ;;
+
+ -no-suppress)
+ suppress_opt=no
+ continue
+ ;;
+
+ -Xcompiler)
+ arg_mode=arg # the next one goes into the "base_compile" arg list
+ continue # The current "srcfile" will either be retained or
+ ;; # replaced later. I would guess that would be a bug.
+
+ -Wc,*)
+ func_stripname '-Wc,' '' "$arg"
+ args=$func_stripname_result
+ lastarg=
+ save_ifs="$IFS"; IFS=','
+ for arg in $args; do
+ IFS="$save_ifs"
+ func_quote_for_eval "$arg"
+ lastarg="$lastarg $func_quote_for_eval_result"
+ done
+ IFS="$save_ifs"
+ func_stripname ' ' '' "$lastarg"
+ lastarg=$func_stripname_result
+
+ # Add the arguments to base_compile.
+ base_compile="$base_compile $lastarg"
+ continue
+ ;;
+
+ *)
+ # Accept the current argument as the source file.
+ # The previous "srcfile" becomes the current argument.
+ #
+ lastarg="$srcfile"
+ srcfile="$arg"
+ ;;
+ esac # case $arg
+ ;;
+ esac # case $arg_mode
+
+ # Aesthetically quote the previous argument.
+ func_quote_for_eval "$lastarg"
+ base_compile="$base_compile $func_quote_for_eval_result"
+ done # for arg
+
+ case $arg_mode in
+ arg)
+ func_fatal_error "you must specify an argument for -Xcompile"
+ ;;
+ target)
+ func_fatal_error "you must specify a target with \`-o'"
+ ;;
+ *)
+ # Get the name of the library object.
+ test -z "$libobj" && {
+ func_basename "$srcfile"
+ libobj="$func_basename_result"
+ }
+ ;;
+ esac
+
+ # Recognize several different file suffixes.
+ # If the user specifies -o file.o, it is replaced with file.lo
+ case $libobj in
+ *.[cCFSifmso] | \
+ *.ada | *.adb | *.ads | *.asm | \
+ *.c++ | *.cc | *.ii | *.class | *.cpp | *.cxx | \
+ *.[fF][09]? | *.for | *.java | *.obj | *.sx)
+ func_xform "$libobj"
+ libobj=$func_xform_result
+ ;;
+ esac
+
+ case $libobj in
+ *.lo) func_lo2o "$libobj"; obj=$func_lo2o_result ;;
+ *)
+ func_fatal_error "cannot determine name of library object from \`$libobj'"
+ ;;
+ esac
+
+ func_infer_tag $base_compile
+
+ for arg in $later; do
+ case $arg in
+ -shared)
+ test "$build_libtool_libs" != yes && \
+ func_fatal_configuration "can not build a shared library"
+ build_old_libs=no
+ continue
+ ;;
+
+ -static)
+ build_libtool_libs=no
+ build_old_libs=yes
+ continue
+ ;;
+
+ -prefer-pic)
+ pic_mode=yes
+ continue
+ ;;
+
+ -prefer-non-pic)
+ pic_mode=no
+ continue
+ ;;
+ esac
+ done
+
+ func_quote_for_eval "$libobj"
+ test "X$libobj" != "X$func_quote_for_eval_result" \
+ && $ECHO "X$libobj" | $GREP '[]~#^*{};<>?"'"'"' &()|`$[]' \
+ && func_warning "libobj name \`$libobj' may not contain shell special characters."
+ func_dirname_and_basename "$obj" "/" ""
+ objname="$func_basename_result"
+ xdir="$func_dirname_result"
+ lobj=${xdir}$objdir/$objname
+
+ test -z "$base_compile" && \
+ func_fatal_help "you must specify a compilation command"
+
+ # Delete any leftover library objects.
+ if test "$build_old_libs" = yes; then
+ removelist="$obj $lobj $libobj ${libobj}T"
+ else
+ removelist="$lobj $libobj ${libobj}T"
+ fi
+
+ # On Cygwin there's no "real" PIC flag so we must build both object types
+ case $host_os in
+ cygwin* | mingw* | pw32* | os2* | cegcc*)
+ pic_mode=default
+ ;;
+ esac
+ if test "$pic_mode" = no && test "$deplibs_check_method" != pass_all; then
+ # non-PIC code in shared libraries is not supported
+ pic_mode=default
+ fi
+
+ # Calculate the filename of the output object if compiler does
+ # not support -o with -c
+ if test "$compiler_c_o" = no; then
+ output_obj=`$ECHO "X$srcfile" | $Xsed -e 's%^.*/%%' -e 's%\.[^.]*$%%'`.${objext}
+ lockfile="$output_obj.lock"
+ else
+ output_obj=
+ need_locks=no
+ lockfile=
+ fi
+
+ # Lock this critical section if it is needed
+ # We use this script file to make the link, it avoids creating a new file
+ if test "$need_locks" = yes; then
+ until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do
+ func_echo "Waiting for $lockfile to be removed"
+ sleep 2
+ done
+ elif test "$need_locks" = warn; then
+ if test -f "$lockfile"; then
+ $ECHO "\
+*** ERROR, $lockfile exists and contains:
+`cat $lockfile 2>/dev/null`
+
+This indicates that another process is trying to use the same
+temporary object file, and libtool could not work around it because
+your compiler does not support \`-c' and \`-o' together. If you
+repeat this compilation, it may succeed, by chance, but you had better
+avoid parallel builds (make -j) in this platform, or get a better
+compiler."
+
+ $opt_dry_run || $RM $removelist
+ exit $EXIT_FAILURE
+ fi
+ removelist="$removelist $output_obj"
+ $ECHO "$srcfile" > "$lockfile"
+ fi
+
+ $opt_dry_run || $RM $removelist
+ removelist="$removelist $lockfile"
+ trap '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' 1 2 15
+
+ if test -n "$fix_srcfile_path"; then
+ eval srcfile=\"$fix_srcfile_path\"
+ fi
+ func_quote_for_eval "$srcfile"
+ qsrcfile=$func_quote_for_eval_result
+
+ # Only build a PIC object if we are building libtool libraries.
+ if test "$build_libtool_libs" = yes; then
+ # Without this assignment, base_compile gets emptied.
+ fbsd_hideous_sh_bug=$base_compile
+
+ if test "$pic_mode" != no; then
+ command="$base_compile $qsrcfile $pic_flag"
+ else
+ # Don't build PIC code
+ command="$base_compile $qsrcfile"
+ fi
+
+ func_mkdir_p "$xdir$objdir"
+
+ if test -z "$output_obj"; then
+ # Place PIC objects in $objdir
+ command="$command -o $lobj"
+ fi
+
+ func_show_eval_locale "$command" \
+ 'test -n "$output_obj" && $RM $removelist; exit $EXIT_FAILURE'
+
+ if test "$need_locks" = warn &&
+ test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then
+ $ECHO "\
+*** ERROR, $lockfile contains:
+`cat $lockfile 2>/dev/null`
+
+but it should contain:
+$srcfile
+
+This indicates that another process is trying to use the same
+temporary object file, and libtool could not work around it because
+your compiler does not support \`-c' and \`-o' together. If you
+repeat this compilation, it may succeed, by chance, but you had better
+avoid parallel builds (make -j) in this platform, or get a better
+compiler."
+
+ $opt_dry_run || $RM $removelist
+ exit $EXIT_FAILURE
+ fi
+
+ # Just move the object if needed, then go on to compile the next one
+ if test -n "$output_obj" && test "X$output_obj" != "X$lobj"; then
+ func_show_eval '$MV "$output_obj" "$lobj"' \
+ 'error=$?; $opt_dry_run || $RM $removelist; exit $error'
+ fi
+
+ # Allow error messages only from the first compilation.
+ if test "$suppress_opt" = yes; then
+ suppress_output=' >/dev/null 2>&1'
+ fi
+ fi
+
+ # Only build a position-dependent object if we build old libraries.
+ if test "$build_old_libs" = yes; then
+ if test "$pic_mode" != yes; then
+ # Don't build PIC code
+ command="$base_compile $qsrcfile$pie_flag"
+ else
+ command="$base_compile $qsrcfile $pic_flag"
+ fi
+ if test "$compiler_c_o" = yes; then
+ command="$command -o $obj"
+ fi
+
+ # Suppress compiler output if we already did a PIC compilation.
+ command="$command$suppress_output"
+ func_show_eval_locale "$command" \
+ '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE'
+
+ if test "$need_locks" = warn &&
+ test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then
+ $ECHO "\
+*** ERROR, $lockfile contains:
+`cat $lockfile 2>/dev/null`
+
+but it should contain:
+$srcfile
+
+This indicates that another process is trying to use the same
+temporary object file, and libtool could not work around it because
+your compiler does not support \`-c' and \`-o' together. If you
+repeat this compilation, it may succeed, by chance, but you had better
+avoid parallel builds (make -j) in this platform, or get a better
+compiler."
+
+ $opt_dry_run || $RM $removelist
+ exit $EXIT_FAILURE
+ fi
+
+ # Just move the object if needed
+ if test -n "$output_obj" && test "X$output_obj" != "X$obj"; then
+ func_show_eval '$MV "$output_obj" "$obj"' \
+ 'error=$?; $opt_dry_run || $RM $removelist; exit $error'
+ fi
+ fi
+
+ $opt_dry_run || {
+ func_write_libtool_object "$libobj" "$objdir/$objname" "$objname"
+
+ # Unlock the critical section if it was locked
+ if test "$need_locks" != no; then
+ removelist=$lockfile
+ $RM "$lockfile"
+ fi
+ }
+
+ exit $EXIT_SUCCESS
+}
+
+$opt_help || {
+test "$mode" = compile && func_mode_compile ${1+"$@"}
+}
+
+func_mode_help ()
+{
+ # We need to display help for each of the modes.
+ case $mode in
+ "")
+ # Generic help is extracted from the usage comments
+ # at the start of this file.
+ func_help
+ ;;
+
+ clean)
+ $ECHO \
+"Usage: $progname [OPTION]... --mode=clean RM [RM-OPTION]... FILE...
+
+Remove files from the build directory.
+
+RM is the name of the program to use to delete files associated with each FILE
+(typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed
+to RM.
+
+If FILE is a libtool library, object or program, all the files associated
+with it are deleted. Otherwise, only FILE itself is deleted using RM."
+ ;;
+
+ compile)
+ $ECHO \
+"Usage: $progname [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE
+
+Compile a source file into a libtool library object.
+
+This mode accepts the following additional options:
+
+ -o OUTPUT-FILE set the output file name to OUTPUT-FILE
+ -no-suppress do not suppress compiler output for multiple passes
+ -prefer-pic try to building PIC objects only
+ -prefer-non-pic try to building non-PIC objects only
+ -shared do not build a \`.o' file suitable for static linking
+ -static only build a \`.o' file suitable for static linking
+
+COMPILE-COMMAND is a command to be used in creating a \`standard' object file
+from the given SOURCEFILE.
+
+The output file name is determined by removing the directory component from
+SOURCEFILE, then substituting the C source code suffix \`.c' with the
+library object suffix, \`.lo'."
+ ;;
+
+ execute)
+ $ECHO \
+"Usage: $progname [OPTION]... --mode=execute COMMAND [ARGS]...
+
+Automatically set library path, then run a program.
+
+This mode accepts the following additional options:
+
+ -dlopen FILE add the directory containing FILE to the library path
+
+This mode sets the library path environment variable according to \`-dlopen'
+flags.
+
+If any of the ARGS are libtool executable wrappers, then they are translated
+into their corresponding uninstalled binary, and any of their required library
+directories are added to the library path.
+
+Then, COMMAND is executed, with ARGS as arguments."
+ ;;
+
+ finish)
+ $ECHO \
+"Usage: $progname [OPTION]... --mode=finish [LIBDIR]...
+
+Complete the installation of libtool libraries.
+
+Each LIBDIR is a directory that contains libtool libraries.
+
+The commands that this mode executes may require superuser privileges. Use
+the \`--dry-run' option if you just want to see what would be executed."
+ ;;
+
+ install)
+ $ECHO \
+"Usage: $progname [OPTION]... --mode=install INSTALL-COMMAND...
+
+Install executables or libraries.
+
+INSTALL-COMMAND is the installation command. The first component should be
+either the \`install' or \`cp' program.
+
+The following components of INSTALL-COMMAND are treated specially:
+
+ -inst-prefix PREFIX-DIR Use PREFIX-DIR as a staging area for installation
+
+The rest of the components are interpreted as arguments to that command (only
+BSD-compatible install options are recognized)."
+ ;;
+
+ link)
+ $ECHO \
+"Usage: $progname [OPTION]... --mode=link LINK-COMMAND...
+
+Link object files or libraries together to form another library, or to
+create an executable program.
+
+LINK-COMMAND is a command using the C compiler that you would use to create
+a program from several object files.
+
+The following components of LINK-COMMAND are treated specially:
+
+ -all-static do not do any dynamic linking at all
+ -avoid-version do not add a version suffix if possible
+ -dlopen FILE \`-dlpreopen' FILE if it cannot be dlopened at runtime
+ -dlpreopen FILE link in FILE and add its symbols to lt_preloaded_symbols
+ -export-dynamic allow symbols from OUTPUT-FILE to be resolved with dlsym(3)
+ -export-symbols SYMFILE
+ try to export only the symbols listed in SYMFILE
+ -export-symbols-regex REGEX
+ try to export only the symbols matching REGEX
+ -LLIBDIR search LIBDIR for required installed libraries
+ -lNAME OUTPUT-FILE requires the installed library libNAME
+ -module build a library that can dlopened
+ -no-fast-install disable the fast-install mode
+ -no-install link a not-installable executable
+ -no-undefined declare that a library does not refer to external symbols
+ -o OUTPUT-FILE create OUTPUT-FILE from the specified objects
+ -objectlist FILE Use a list of object files found in FILE to specify objects
+ -precious-files-regex REGEX
+ don't remove output files matching REGEX
+ -release RELEASE specify package release information
+ -rpath LIBDIR the created library will eventually be installed in LIBDIR
+ -R[ ]LIBDIR add LIBDIR to the runtime path of programs and libraries
+ -shared only do dynamic linking of libtool libraries
+ -shrext SUFFIX override the standard shared library file extension
+ -static do not do any dynamic linking of uninstalled libtool libraries
+ -static-libtool-libs
+ do not do any dynamic linking of libtool libraries
+ -version-info CURRENT[:REVISION[:AGE]]
+ specify library version info [each variable defaults to 0]
+ -weak LIBNAME declare that the target provides the LIBNAME interface
+
+All other options (arguments beginning with \`-') are ignored.
+
+Every other argument is treated as a filename. Files ending in \`.la' are
+treated as uninstalled libtool libraries, other files are standard or library
+object files.
+
+If the OUTPUT-FILE ends in \`.la', then a libtool library is created,
+only library objects (\`.lo' files) may be specified, and \`-rpath' is
+required, except when creating a convenience library.
+
+If OUTPUT-FILE ends in \`.a' or \`.lib', then a standard library is created
+using \`ar' and \`ranlib', or on Windows using \`lib'.
+
+If OUTPUT-FILE ends in \`.lo' or \`.${objext}', then a reloadable object file
+is created, otherwise an executable program is created."
+ ;;
+
+ uninstall)
+ $ECHO \
+"Usage: $progname [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE...
+
+Remove libraries from an installation directory.
+
+RM is the name of the program to use to delete files associated with each FILE
+(typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed
+to RM.
+
+If FILE is a libtool library, all the files associated with it are deleted.
+Otherwise, only FILE itself is deleted using RM."
+ ;;
+
+ *)
+ func_fatal_help "invalid operation mode \`$mode'"
+ ;;
+ esac
+
+ $ECHO
+ $ECHO "Try \`$progname --help' for more information about other modes."
+
+ exit $?
+}
+
+ # Now that we've collected a possible --mode arg, show help if necessary
+ $opt_help && func_mode_help
+
+
+# func_mode_execute arg...
+func_mode_execute ()
+{
+ $opt_debug
+ # The first argument is the command name.
+ cmd="$nonopt"
+ test -z "$cmd" && \
+ func_fatal_help "you must specify a COMMAND"
+
+ # Handle -dlopen flags immediately.
+ for file in $execute_dlfiles; do
+ test -f "$file" \
+ || func_fatal_help "\`$file' is not a file"
+
+ dir=
+ case $file in
+ *.la)
+ # Check to see that this really is a libtool archive.
+ func_lalib_unsafe_p "$file" \
+ || func_fatal_help "\`$lib' is not a valid libtool archive"
+
+ # Read the libtool library.
+ dlname=
+ library_names=
+ func_source "$file"
+
+ # Skip this library if it cannot be dlopened.
+ if test -z "$dlname"; then
+ # Warn if it was a shared library.
+ test -n "$library_names" && \
+ func_warning "\`$file' was not linked with \`-export-dynamic'"
+ continue
+ fi
+
+ func_dirname "$file" "" "."
+ dir="$func_dirname_result"
+
+ if test -f "$dir/$objdir/$dlname"; then
+ dir="$dir/$objdir"
+ else
+ if test ! -f "$dir/$dlname"; then
+ func_fatal_error "cannot find \`$dlname' in \`$dir' or \`$dir/$objdir'"
+ fi
+ fi
+ ;;
+
+ *.lo)
+ # Just add the directory containing the .lo file.
+ func_dirname "$file" "" "."
+ dir="$func_dirname_result"
+ ;;
+
+ *)
+ func_warning "\`-dlopen' is ignored for non-libtool libraries and objects"
+ continue
+ ;;
+ esac
+
+ # Get the absolute pathname.
+ absdir=`cd "$dir" && pwd`
+ test -n "$absdir" && dir="$absdir"
+
+ # Now add the directory to shlibpath_var.
+ if eval "test -z \"\$$shlibpath_var\""; then
+ eval "$shlibpath_var=\"\$dir\""
+ else
+ eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\""
+ fi
+ done
+
+ # This variable tells wrapper scripts just to set shlibpath_var
+ # rather than running their programs.
+ libtool_execute_magic="$magic"
+
+ # Check if any of the arguments is a wrapper script.
+ args=
+ for file
+ do
+ case $file in
+ -*) ;;
+ *)
+ # Do a test to see if this is really a libtool program.
+ if func_ltwrapper_script_p "$file"; then
+ func_source "$file"
+ # Transform arg to wrapped name.
+ file="$progdir/$program"
+ elif func_ltwrapper_executable_p "$file"; then
+ func_ltwrapper_scriptname "$file"
+ func_source "$func_ltwrapper_scriptname_result"
+ # Transform arg to wrapped name.
+ file="$progdir/$program"
+ fi
+ ;;
+ esac
+ # Quote arguments (to preserve shell metacharacters).
+ func_quote_for_eval "$file"
+ args="$args $func_quote_for_eval_result"
+ done
+
+ if test "X$opt_dry_run" = Xfalse; then
+ if test -n "$shlibpath_var"; then
+ # Export the shlibpath_var.
+ eval "export $shlibpath_var"
+ fi
+
+ # Restore saved environment variables
+ for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES
+ do
+ eval "if test \"\${save_$lt_var+set}\" = set; then
+ $lt_var=\$save_$lt_var; export $lt_var
+ else
+ $lt_unset $lt_var
+ fi"
+ done
+
+ # Now prepare to actually exec the command.
+ exec_cmd="\$cmd$args"
+ else
+ # Display what would be done.
+ if test -n "$shlibpath_var"; then
+ eval "\$ECHO \"\$shlibpath_var=\$$shlibpath_var\""
+ $ECHO "export $shlibpath_var"
+ fi
+ $ECHO "$cmd$args"
+ exit $EXIT_SUCCESS
+ fi
+}
+
+test "$mode" = execute && func_mode_execute ${1+"$@"}
+
+
+# func_mode_finish arg...
+func_mode_finish ()
+{
+ $opt_debug
+ libdirs="$nonopt"
+ admincmds=
+
+ if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then
+ for dir
+ do
+ libdirs="$libdirs $dir"
+ done
+
+ for libdir in $libdirs; do
+ if test -n "$finish_cmds"; then
+ # Do each command in the finish commands.
+ func_execute_cmds "$finish_cmds" 'admincmds="$admincmds
+'"$cmd"'"'
+ fi
+ if test -n "$finish_eval"; then
+ # Do the single finish_eval.
+ eval cmds=\"$finish_eval\"
+ $opt_dry_run || eval "$cmds" || admincmds="$admincmds
+ $cmds"
+ fi
+ done
+ fi
+
+ # Exit here if they wanted silent mode.
+ $opt_silent && exit $EXIT_SUCCESS
+
+ $ECHO "X----------------------------------------------------------------------" | $Xsed
+ $ECHO "Libraries have been installed in:"
+ for libdir in $libdirs; do
+ $ECHO " $libdir"
+ done
+ $ECHO
+ $ECHO "If you ever happen to want to link against installed libraries"
+ $ECHO "in a given directory, LIBDIR, you must either use libtool, and"
+ $ECHO "specify the full pathname of the library, or use the \`-LLIBDIR'"
+ $ECHO "flag during linking and do at least one of the following:"
+ if test -n "$shlibpath_var"; then
+ $ECHO " - add LIBDIR to the \`$shlibpath_var' environment variable"
+ $ECHO " during execution"
+ fi
+ if test -n "$runpath_var"; then
+ $ECHO " - add LIBDIR to the \`$runpath_var' environment variable"
+ $ECHO " during linking"
+ fi
+ if test -n "$hardcode_libdir_flag_spec"; then
+ libdir=LIBDIR
+ eval flag=\"$hardcode_libdir_flag_spec\"
+
+ $ECHO " - use the \`$flag' linker flag"
+ fi
+ if test -n "$admincmds"; then
+ $ECHO " - have your system administrator run these commands:$admincmds"
+ fi
+ if test -f /etc/ld.so.conf; then
+ $ECHO " - have your system administrator add LIBDIR to \`/etc/ld.so.conf'"
+ fi
+ $ECHO
+
+ $ECHO "See any operating system documentation about shared libraries for"
+ case $host in
+ solaris2.[6789]|solaris2.1[0-9])
+ $ECHO "more information, such as the ld(1), crle(1) and ld.so(8) manual"
+ $ECHO "pages."
+ ;;
+ *)
+ $ECHO "more information, such as the ld(1) and ld.so(8) manual pages."
+ ;;
+ esac
+ $ECHO "X----------------------------------------------------------------------" | $Xsed
+ exit $EXIT_SUCCESS
+}
+
+test "$mode" = finish && func_mode_finish ${1+"$@"}
+
+
+# func_mode_install arg...
+func_mode_install ()
+{
+ $opt_debug
+ # There may be an optional sh(1) argument at the beginning of
+ # install_prog (especially on Windows NT).
+ if test "$nonopt" = "$SHELL" || test "$nonopt" = /bin/sh ||
+ # Allow the use of GNU shtool's install command.
+ $ECHO "X$nonopt" | $GREP shtool >/dev/null; then
+ # Aesthetically quote it.
+ func_quote_for_eval "$nonopt"
+ install_prog="$func_quote_for_eval_result "
+ arg=$1
+ shift
+ else
+ install_prog=
+ arg=$nonopt
+ fi
+
+ # The real first argument should be the name of the installation program.
+ # Aesthetically quote it.
+ func_quote_for_eval "$arg"
+ install_prog="$install_prog$func_quote_for_eval_result"
+
+ # We need to accept at least all the BSD install flags.
+ dest=
+ files=
+ opts=
+ prev=
+ install_type=
+ isdir=no
+ stripme=
+ for arg
+ do
+ if test -n "$dest"; then
+ files="$files $dest"
+ dest=$arg
+ continue
+ fi
+
+ case $arg in
+ -d) isdir=yes ;;
+ -f)
+ case " $install_prog " in
+ *[\\\ /]cp\ *) ;;
+ *) prev=$arg ;;
+ esac
+ ;;
+ -g | -m | -o)
+ prev=$arg
+ ;;
+ -s)
+ stripme=" -s"
+ continue
+ ;;
+ -*)
+ ;;
+ *)
+ # If the previous option needed an argument, then skip it.
+ if test -n "$prev"; then
+ prev=
+ else
+ dest=$arg
+ continue
+ fi
+ ;;
+ esac
+
+ # Aesthetically quote the argument.
+ func_quote_for_eval "$arg"
+ install_prog="$install_prog $func_quote_for_eval_result"
+ done
+
+ test -z "$install_prog" && \
+ func_fatal_help "you must specify an install program"
+
+ test -n "$prev" && \
+ func_fatal_help "the \`$prev' option requires an argument"
+
+ if test -z "$files"; then
+ if test -z "$dest"; then
+ func_fatal_help "no file or destination specified"
+ else
+ func_fatal_help "you must specify a destination"
+ fi
+ fi
+
+ # Strip any trailing slash from the destination.
+ func_stripname '' '/' "$dest"
+ dest=$func_stripname_result
+
+ # Check to see that the destination is a directory.
+ test -d "$dest" && isdir=yes
+ if test "$isdir" = yes; then
+ destdir="$dest"
+ destname=
+ else
+ func_dirname_and_basename "$dest" "" "."
+ destdir="$func_dirname_result"
+ destname="$func_basename_result"
+
+ # Not a directory, so check to see that there is only one file specified.
+ set dummy $files; shift
+ test "$#" -gt 1 && \
+ func_fatal_help "\`$dest' is not a directory"
+ fi
+ case $destdir in
+ [\\/]* | [A-Za-z]:[\\/]*) ;;
+ *)
+ for file in $files; do
+ case $file in
+ *.lo) ;;
+ *)
+ func_fatal_help "\`$destdir' must be an absolute directory name"
+ ;;
+ esac
+ done
+ ;;
+ esac
+
+ # This variable tells wrapper scripts just to set variables rather
+ # than running their programs.
+ libtool_install_magic="$magic"
+
+ staticlibs=
+ future_libdirs=
+ current_libdirs=
+ for file in $files; do
+
+ # Do each installation.
+ case $file in
+ *.$libext)
+ # Do the static libraries later.
+ staticlibs="$staticlibs $file"
+ ;;
+
+ *.la)
+ # Check to see that this really is a libtool archive.
+ func_lalib_unsafe_p "$file" \
+ || func_fatal_help "\`$file' is not a valid libtool archive"
+
+ library_names=
+ old_library=
+ relink_command=
+ func_source "$file"
+
+ # Add the libdir to current_libdirs if it is the destination.
+ if test "X$destdir" = "X$libdir"; then
+ case "$current_libdirs " in
+ *" $libdir "*) ;;
+ *) current_libdirs="$current_libdirs $libdir" ;;
+ esac
+ else
+ # Note the libdir as a future libdir.
+ case "$future_libdirs " in
+ *" $libdir "*) ;;
+ *) future_libdirs="$future_libdirs $libdir" ;;
+ esac
+ fi
+
+ func_dirname "$file" "/" ""
+ dir="$func_dirname_result"
+ dir="$dir$objdir"
+
+ if test -n "$relink_command"; then
+ # Determine the prefix the user has applied to our future dir.
+ inst_prefix_dir=`$ECHO "X$destdir" | $Xsed -e "s%$libdir\$%%"`
+
+ # Don't allow the user to place us outside of our expected
+ # location b/c this prevents finding dependent libraries that
+ # are installed to the same prefix.
+ # At present, this check doesn't affect windows .dll's that
+ # are installed into $libdir/../bin (currently, that works fine)
+ # but it's something to keep an eye on.
+ test "$inst_prefix_dir" = "$destdir" && \
+ func_fatal_error "error: cannot install \`$file' to a directory not ending in $libdir"
+
+ if test -n "$inst_prefix_dir"; then
+ # Stick the inst_prefix_dir data into the link command.
+ relink_command=`$ECHO "X$relink_command" | $Xsed -e "s%@inst_prefix_dir@%-inst-prefix-dir $inst_prefix_dir%"`
+ else
+ relink_command=`$ECHO "X$relink_command" | $Xsed -e "s%@inst_prefix_dir@%%"`
+ fi
+
+ func_warning "relinking \`$file'"
+ func_show_eval "$relink_command" \
+ 'func_fatal_error "error: relink \`$file'\'' with the above command before installing it"'
+ fi
+
+ # See the names of the shared library.
+ set dummy $library_names; shift
+ if test -n "$1"; then
+ realname="$1"
+ shift
+
+ srcname="$realname"
+ test -n "$relink_command" && srcname="$realname"T
+
+ # Install the shared library and build the symlinks.
+ func_show_eval "$install_prog $dir/$srcname $destdir/$realname" \
+ 'exit $?'
+ tstripme="$stripme"
+ case $host_os in
+ cygwin* | mingw* | pw32* | cegcc*)
+ case $realname in
+ *.dll.a)
+ tstripme=""
+ ;;
+ esac
+ ;;
+ esac
+ if test -n "$tstripme" && test -n "$striplib"; then
+ func_show_eval "$striplib $destdir/$realname" 'exit $?'
+ fi
+
+ if test "$#" -gt 0; then
+ # Delete the old symlinks, and create new ones.
+ # Try `ln -sf' first, because the `ln' binary might depend on
+ # the symlink we replace! Solaris /bin/ln does not understand -f,
+ # so we also need to try rm && ln -s.
+ for linkname
+ do
+ test "$linkname" != "$realname" \
+ && func_show_eval "(cd $destdir && { $LN_S -f $realname $linkname || { $RM $linkname && $LN_S $realname $linkname; }; })"
+ done
+ fi
+
+ # Do each command in the postinstall commands.
+ lib="$destdir/$realname"
+ func_execute_cmds "$postinstall_cmds" 'exit $?'
+ fi
+
+ # Install the pseudo-library for information purposes.
+ func_basename "$file"
+ name="$func_basename_result"
+ instname="$dir/$name"i
+ func_show_eval "$install_prog $instname $destdir/$name" 'exit $?'
+
+ # Maybe install the static library, too.
+ test -n "$old_library" && staticlibs="$staticlibs $dir/$old_library"
+ ;;
+
+ *.lo)
+ # Install (i.e. copy) a libtool object.
+
+ # Figure out destination file name, if it wasn't already specified.
+ if test -n "$destname"; then
+ destfile="$destdir/$destname"
+ else
+ func_basename "$file"
+ destfile="$func_basename_result"
+ destfile="$destdir/$destfile"
+ fi
+
+ # Deduce the name of the destination old-style object file.
+ case $destfile in
+ *.lo)
+ func_lo2o "$destfile"
+ staticdest=$func_lo2o_result
+ ;;
+ *.$objext)
+ staticdest="$destfile"
+ destfile=
+ ;;
+ *)
+ func_fatal_help "cannot copy a libtool object to \`$destfile'"
+ ;;
+ esac
+
+ # Install the libtool object if requested.
+ test -n "$destfile" && \
+ func_show_eval "$install_prog $file $destfile" 'exit $?'
+
+ # Install the old object if enabled.
+ if test "$build_old_libs" = yes; then
+ # Deduce the name of the old-style object file.
+ func_lo2o "$file"
+ staticobj=$func_lo2o_result
+ func_show_eval "$install_prog \$staticobj \$staticdest" 'exit $?'
+ fi
+ exit $EXIT_SUCCESS
+ ;;
+
+ *)
+ # Figure out destination file name, if it wasn't already specified.
+ if test -n "$destname"; then
+ destfile="$destdir/$destname"
+ else
+ func_basename "$file"
+ destfile="$func_basename_result"
+ destfile="$destdir/$destfile"
+ fi
+
+ # If the file is missing, and there is a .exe on the end, strip it
+ # because it is most likely a libtool script we actually want to
+ # install
+ stripped_ext=""
+ case $file in
+ *.exe)
+ if test ! -f "$file"; then
+ func_stripname '' '.exe' "$file"
+ file=$func_stripname_result
+ stripped_ext=".exe"
+ fi
+ ;;
+ esac
+
+ # Do a test to see if this is really a libtool program.
+ case $host in
+ *cygwin* | *mingw*)
+ if func_ltwrapper_executable_p "$file"; then
+ func_ltwrapper_scriptname "$file"
+ wrapper=$func_ltwrapper_scriptname_result
+ else
+ func_stripname '' '.exe' "$file"
+ wrapper=$func_stripname_result
+ fi
+ ;;
+ *)
+ wrapper=$file
+ ;;
+ esac
+ if func_ltwrapper_script_p "$wrapper"; then
+ notinst_deplibs=
+ relink_command=
+
+ func_source "$wrapper"
+
+ # Check the variables that should have been set.
+ test -z "$generated_by_libtool_version" && \
+ func_fatal_error "invalid libtool wrapper script \`$wrapper'"
+
+ finalize=yes
+ for lib in $notinst_deplibs; do
+ # Check to see that each library is installed.
+ libdir=
+ if test -f "$lib"; then
+ func_source "$lib"
+ fi
+ libfile="$libdir/"`$ECHO "X$lib" | $Xsed -e 's%^.*/%%g'` ### testsuite: skip nested quoting test
+ if test -n "$libdir" && test ! -f "$libfile"; then
+ func_warning "\`$lib' has not been installed in \`$libdir'"
+ finalize=no
+ fi
+ done
+
+ relink_command=
+ func_source "$wrapper"
+
+ outputname=
+ if test "$fast_install" = no && test -n "$relink_command"; then
+ $opt_dry_run || {
+ if test "$finalize" = yes; then
+ tmpdir=`func_mktempdir`
+ func_basename "$file$stripped_ext"
+ file="$func_basename_result"
+ outputname="$tmpdir/$file"
+ # Replace the output file specification.
+ relink_command=`$ECHO "X$relink_command" | $Xsed -e 's%@OUTPUT@%'"$outputname"'%g'`
+
+ $opt_silent || {
+ func_quote_for_expand "$relink_command"
+ eval "func_echo $func_quote_for_expand_result"
+ }
+ if eval "$relink_command"; then :
+ else
+ func_error "error: relink \`$file' with the above command before installing it"
+ $opt_dry_run || ${RM}r "$tmpdir"
+ continue
+ fi
+ file="$outputname"
+ else
+ func_warning "cannot relink \`$file'"
+ fi
+ }
+ else
+ # Install the binary that we compiled earlier.
+ file=`$ECHO "X$file$stripped_ext" | $Xsed -e "s%\([^/]*\)$%$objdir/\1%"`
+ fi
+ fi
+
+ # remove .exe since cygwin /usr/bin/install will append another
+ # one anyway
+ case $install_prog,$host in
+ */usr/bin/install*,*cygwin*)
+ case $file:$destfile in
+ *.exe:*.exe)
+ # this is ok
+ ;;
+ *.exe:*)
+ destfile=$destfile.exe
+ ;;
+ *:*.exe)
+ func_stripname '' '.exe' "$destfile"
+ destfile=$func_stripname_result
+ ;;
+ esac
+ ;;
+ esac
+ func_show_eval "$install_prog\$stripme \$file \$destfile" 'exit $?'
+ $opt_dry_run || if test -n "$outputname"; then
+ ${RM}r "$tmpdir"
+ fi
+ ;;
+ esac
+ done
+
+ for file in $staticlibs; do
+ func_basename "$file"
+ name="$func_basename_result"
+
+ # Set up the ranlib parameters.
+ oldlib="$destdir/$name"
+
+ func_show_eval "$install_prog \$file \$oldlib" 'exit $?'
+
+ if test -n "$stripme" && test -n "$old_striplib"; then
+ func_show_eval "$old_striplib $oldlib" 'exit $?'
+ fi
+
+ # Do each command in the postinstall commands.
+ func_execute_cmds "$old_postinstall_cmds" 'exit $?'
+ done
+
+ test -n "$future_libdirs" && \
+ func_warning "remember to run \`$progname --finish$future_libdirs'"
+
+ if test -n "$current_libdirs"; then
+ # Maybe just do a dry run.
+ $opt_dry_run && current_libdirs=" -n$current_libdirs"
+ exec_cmd='$SHELL $progpath $preserve_args --finish$current_libdirs'
+ else
+ exit $EXIT_SUCCESS
+ fi
+}
+
+test "$mode" = install && func_mode_install ${1+"$@"}
+
+
+# func_generate_dlsyms outputname originator pic_p
+# Extract symbols from dlprefiles and create ${outputname}S.o with
+# a dlpreopen symbol table.
+func_generate_dlsyms ()
+{
+ $opt_debug
+ my_outputname="$1"
+ my_originator="$2"
+ my_pic_p="${3-no}"
+ my_prefix=`$ECHO "$my_originator" | sed 's%[^a-zA-Z0-9]%_%g'`
+ my_dlsyms=
+
+ if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
+ if test -n "$NM" && test -n "$global_symbol_pipe"; then
+ my_dlsyms="${my_outputname}S.c"
+ else
+ func_error "not configured to extract global symbols from dlpreopened files"
+ fi
+ fi
+
+ if test -n "$my_dlsyms"; then
+ case $my_dlsyms in
+ "") ;;
+ *.c)
+ # Discover the nlist of each of the dlfiles.
+ nlist="$output_objdir/${my_outputname}.nm"
+
+ func_show_eval "$RM $nlist ${nlist}S ${nlist}T"
+
+ # Parse the name list into a source file.
+ func_verbose "creating $output_objdir/$my_dlsyms"
+
+ $opt_dry_run || $ECHO > "$output_objdir/$my_dlsyms" "\
+/* $my_dlsyms - symbol resolution table for \`$my_outputname' dlsym emulation. */
+/* Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION */
+
+#ifdef __cplusplus
+extern \"C\" {
+#endif
+
+/* External symbol declarations for the compiler. */\
+"
+
+ if test "$dlself" = yes; then
+ func_verbose "generating symbol list for \`$output'"
+
+ $opt_dry_run || echo ': @PROGRAM@ ' > "$nlist"
+
+ # Add our own program objects to the symbol list.
+ progfiles=`$ECHO "X$objs$old_deplibs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP`
+ for progfile in $progfiles; do
+ func_verbose "extracting global C symbols from \`$progfile'"
+ $opt_dry_run || eval "$NM $progfile | $global_symbol_pipe >> '$nlist'"
+ done
+
+ if test -n "$exclude_expsyms"; then
+ $opt_dry_run || {
+ eval '$EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T'
+ eval '$MV "$nlist"T "$nlist"'
+ }
+ fi
+
+ if test -n "$export_symbols_regex"; then
+ $opt_dry_run || {
+ eval '$EGREP -e "$export_symbols_regex" "$nlist" > "$nlist"T'
+ eval '$MV "$nlist"T "$nlist"'
+ }
+ fi
+
+ # Prepare the list of exported symbols
+ if test -z "$export_symbols"; then
+ export_symbols="$output_objdir/$outputname.exp"
+ $opt_dry_run || {
+ $RM $export_symbols
+ eval "${SED} -n -e '/^: @PROGRAM@ $/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"'
+ case $host in
+ *cygwin* | *mingw* | *cegcc* )
+ eval "echo EXPORTS "'> "$output_objdir/$outputname.def"'
+ eval 'cat "$export_symbols" >> "$output_objdir/$outputname.def"'
+ ;;
+ esac
+ }
+ else
+ $opt_dry_run || {
+ eval "${SED} -e 's/\([].[*^$]\)/\\\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$outputname.exp"'
+ eval '$GREP -f "$output_objdir/$outputname.exp" < "$nlist" > "$nlist"T'
+ eval '$MV "$nlist"T "$nlist"'
+ case $host in
+ *cygwin | *mingw* | *cegcc* )
+ eval "echo EXPORTS "'> "$output_objdir/$outputname.def"'
+ eval 'cat "$nlist" >> "$output_objdir/$outputname.def"'
+ ;;
+ esac
+ }
+ fi
+ fi
+
+ for dlprefile in $dlprefiles; do
+ func_verbose "extracting global C symbols from \`$dlprefile'"
+ func_basename "$dlprefile"
+ name="$func_basename_result"
+ $opt_dry_run || {
+ eval '$ECHO ": $name " >> "$nlist"'
+ eval "$NM $dlprefile 2>/dev/null | $global_symbol_pipe >> '$nlist'"
+ }
+ done
+
+ $opt_dry_run || {
+ # Make sure we have at least an empty file.
+ test -f "$nlist" || : > "$nlist"
+
+ if test -n "$exclude_expsyms"; then
+ $EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T
+ $MV "$nlist"T "$nlist"
+ fi
+
+ # Try sorting and uniquifying the output.
+ if $GREP -v "^: " < "$nlist" |
+ if sort -k 3 </dev/null >/dev/null 2>&1; then
+ sort -k 3
+ else
+ sort +2
+ fi |
+ uniq > "$nlist"S; then
+ :
+ else
+ $GREP -v "^: " < "$nlist" > "$nlist"S
+ fi
+
+ if test -f "$nlist"S; then
+ eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$my_dlsyms"'
+ else
+ $ECHO '/* NONE */' >> "$output_objdir/$my_dlsyms"
+ fi
+
+ $ECHO >> "$output_objdir/$my_dlsyms" "\
+
+/* The mapping between symbol names and symbols. */
+typedef struct {
+ const char *name;
+ void *address;
+} lt_dlsymlist;
+"
+ case $host in
+ *cygwin* | *mingw* | *cegcc* )
+ $ECHO >> "$output_objdir/$my_dlsyms" "\
+/* DATA imports from DLLs on WIN32 con't be const, because
+ runtime relocations are performed -- see ld's documentation
+ on pseudo-relocs. */"
+ lt_dlsym_const= ;;
+ *osf5*)
+ echo >> "$output_objdir/$my_dlsyms" "\
+/* This system does not cope well with relocations in const data */"
+ lt_dlsym_const= ;;
+ *)
+ lt_dlsym_const=const ;;
+ esac
+
+ $ECHO >> "$output_objdir/$my_dlsyms" "\
+extern $lt_dlsym_const lt_dlsymlist
+lt_${my_prefix}_LTX_preloaded_symbols[];
+$lt_dlsym_const lt_dlsymlist
+lt_${my_prefix}_LTX_preloaded_symbols[] =
+{\
+ { \"$my_originator\", (void *) 0 },"
+
+ case $need_lib_prefix in
+ no)
+ eval "$global_symbol_to_c_name_address" < "$nlist" >> "$output_objdir/$my_dlsyms"
+ ;;
+ *)
+ eval "$global_symbol_to_c_name_address_lib_prefix" < "$nlist" >> "$output_objdir/$my_dlsyms"
+ ;;
+ esac
+ $ECHO >> "$output_objdir/$my_dlsyms" "\
+ {0, (void *) 0}
+};
+
+/* This works around a problem in FreeBSD linker */
+#ifdef FREEBSD_WORKAROUND
+static const void *lt_preloaded_setup() {
+ return lt_${my_prefix}_LTX_preloaded_symbols;
+}
+#endif
+
+#ifdef __cplusplus
+}
+#endif\
+"
+ } # !$opt_dry_run
+
+ pic_flag_for_symtable=
+ case "$compile_command " in
+ *" -static "*) ;;
+ *)
+ case $host in
+ # compiling the symbol table file with pic_flag works around
+ # a FreeBSD bug that causes programs to crash when -lm is
+ # linked before any other PIC object. But we must not use
+ # pic_flag when linking with -static. The problem exists in
+ # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1.
+ *-*-freebsd2*|*-*-freebsd3.0*|*-*-freebsdelf3.0*)
+ pic_flag_for_symtable=" $pic_flag -DFREEBSD_WORKAROUND" ;;
+ *-*-hpux*)
+ pic_flag_for_symtable=" $pic_flag" ;;
+ *)
+ if test "X$my_pic_p" != Xno; then
+ pic_flag_for_symtable=" $pic_flag"
+ fi
+ ;;
+ esac
+ ;;
+ esac
+ symtab_cflags=
+ for arg in $LTCFLAGS; do
+ case $arg in
+ -pie | -fpie | -fPIE) ;;
+ *) symtab_cflags="$symtab_cflags $arg" ;;
+ esac
+ done
+
+ # Now compile the dynamic symbol file.
+ func_show_eval '(cd $output_objdir && $LTCC$symtab_cflags -c$no_builtin_flag$pic_flag_for_symtable "$my_dlsyms")' 'exit $?'
+
+ # Clean up the generated files.
+ func_show_eval '$RM "$output_objdir/$my_dlsyms" "$nlist" "${nlist}S" "${nlist}T"'
+
+ # Transform the symbol file into the correct name.
+ symfileobj="$output_objdir/${my_outputname}S.$objext"
+ case $host in
+ *cygwin* | *mingw* | *cegcc* )
+ if test -f "$output_objdir/$my_outputname.def"; then
+ compile_command=`$ECHO "X$compile_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"`
+ finalize_command=`$ECHO "X$finalize_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"`
+ else
+ compile_command=`$ECHO "X$compile_command" | $Xsed -e "s%@SYMFILE@%$symfileobj%"`
+ finalize_command=`$ECHO "X$finalize_command" | $Xsed -e "s%@SYMFILE@%$symfileobj%"`
+ fi
+ ;;
+ *)
+ compile_command=`$ECHO "X$compile_command" | $Xsed -e "s%@SYMFILE@%$symfileobj%"`
+ finalize_command=`$ECHO "X$finalize_command" | $Xsed -e "s%@SYMFILE@%$symfileobj%"`
+ ;;
+ esac
+ ;;
+ *)
+ func_fatal_error "unknown suffix for \`$my_dlsyms'"
+ ;;
+ esac
+ else
+ # We keep going just in case the user didn't refer to
+ # lt_preloaded_symbols. The linker will fail if global_symbol_pipe
+ # really was required.
+
+ # Nullify the symbol file.
+ compile_command=`$ECHO "X$compile_command" | $Xsed -e "s% @SYMFILE@%%"`
+ finalize_command=`$ECHO "X$finalize_command" | $Xsed -e "s% @SYMFILE@%%"`
+ fi
+}
+
+# func_win32_libid arg
+# return the library type of file 'arg'
+#
+# Need a lot of goo to handle *both* DLLs and import libs
+# Has to be a shell function in order to 'eat' the argument
+# that is supplied when $file_magic_command is called.
+func_win32_libid ()
+{
+ $opt_debug
+ win32_libid_type="unknown"
+ win32_fileres=`file -L $1 2>/dev/null`
+ case $win32_fileres in
+ *ar\ archive\ import\ library*) # definitely import
+ win32_libid_type="x86 archive import"
+ ;;
+ *ar\ archive*) # could be an import, or static
+ if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null |
+ $EGREP 'file format pe-i386(.*architecture: i386)?' >/dev/null ; then
+ win32_nmres=`eval $NM -f posix -A $1 |
+ $SED -n -e '
+ 1,100{
+ / I /{
+ s,.*,import,
+ p
+ q
+ }
+ }'`
+ case $win32_nmres in
+ import*) win32_libid_type="x86 archive import";;
+ *) win32_libid_type="x86 archive static";;
+ esac
+ fi
+ ;;
+ *DLL*)
+ win32_libid_type="x86 DLL"
+ ;;
+ *executable*) # but shell scripts are "executable" too...
+ case $win32_fileres in
+ *MS\ Windows\ PE\ Intel*)
+ win32_libid_type="x86 DLL"
+ ;;
+ esac
+ ;;
+ esac
+ $ECHO "$win32_libid_type"
+}
+
+
+
+# func_extract_an_archive dir oldlib
+func_extract_an_archive ()
+{
+ $opt_debug
+ f_ex_an_ar_dir="$1"; shift
+ f_ex_an_ar_oldlib="$1"
+ func_show_eval "(cd \$f_ex_an_ar_dir && $AR x \"\$f_ex_an_ar_oldlib\")" 'exit $?'
+ if ($AR t "$f_ex_an_ar_oldlib" | sort | sort -uc >/dev/null 2>&1); then
+ :
+ else
+ func_fatal_error "object name conflicts in archive: $f_ex_an_ar_dir/$f_ex_an_ar_oldlib"
+ fi
+}
+
+
+# func_extract_archives gentop oldlib ...
+func_extract_archives ()
+{
+ $opt_debug
+ my_gentop="$1"; shift
+ my_oldlibs=${1+"$@"}
+ my_oldobjs=""
+ my_xlib=""
+ my_xabs=""
+ my_xdir=""
+
+ for my_xlib in $my_oldlibs; do
+ # Extract the objects.
+ case $my_xlib in
+ [\\/]* | [A-Za-z]:[\\/]*) my_xabs="$my_xlib" ;;
+ *) my_xabs=`pwd`"/$my_xlib" ;;
+ esac
+ func_basename "$my_xlib"
+ my_xlib="$func_basename_result"
+ my_xlib_u=$my_xlib
+ while :; do
+ case " $extracted_archives " in
+ *" $my_xlib_u "*)
+ func_arith $extracted_serial + 1
+ extracted_serial=$func_arith_result
+ my_xlib_u=lt$extracted_serial-$my_xlib ;;
+ *) break ;;
+ esac
+ done
+ extracted_archives="$extracted_archives $my_xlib_u"
+ my_xdir="$my_gentop/$my_xlib_u"
+
+ func_mkdir_p "$my_xdir"
+
+ case $host in
+ *-darwin*)
+ func_verbose "Extracting $my_xabs"
+ # Do not bother doing anything if just a dry run
+ $opt_dry_run || {
+ darwin_orig_dir=`pwd`
+ cd $my_xdir || exit $?
+ darwin_archive=$my_xabs
+ darwin_curdir=`pwd`
+ darwin_base_archive=`basename "$darwin_archive"`
+ darwin_arches=`$LIPO -info "$darwin_archive" 2>/dev/null | $GREP Architectures 2>/dev/null || true`
+ if test -n "$darwin_arches"; then
+ darwin_arches=`$ECHO "$darwin_arches" | $SED -e 's/.*are://'`
+ darwin_arch=
+ func_verbose "$darwin_base_archive has multiple architectures $darwin_arches"
+ for darwin_arch in $darwin_arches ; do
+ func_mkdir_p "unfat-$$/${darwin_base_archive}-${darwin_arch}"
+ $LIPO -thin $darwin_arch -output "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" "${darwin_archive}"
+ cd "unfat-$$/${darwin_base_archive}-${darwin_arch}"
+ func_extract_an_archive "`pwd`" "${darwin_base_archive}"
+ cd "$darwin_curdir"
+ $RM "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}"
+ done # $darwin_arches
+ ## Okay now we've a bunch of thin objects, gotta fatten them up :)
+ darwin_filelist=`find unfat-$$ -type f -name \*.o -print -o -name \*.lo -print | $SED -e "$basename" | sort -u`
+ darwin_file=
+ darwin_files=
+ for darwin_file in $darwin_filelist; do
+ darwin_files=`find unfat-$$ -name $darwin_file -print | $NL2SP`
+ $LIPO -create -output "$darwin_file" $darwin_files
+ done # $darwin_filelist
+ $RM -rf unfat-$$
+ cd "$darwin_orig_dir"
+ else
+ cd $darwin_orig_dir
+ func_extract_an_archive "$my_xdir" "$my_xabs"
+ fi # $darwin_arches
+ } # !$opt_dry_run
+ ;;
+ *)
+ func_extract_an_archive "$my_xdir" "$my_xabs"
+ ;;
+ esac
+ my_oldobjs="$my_oldobjs "`find $my_xdir -name \*.$objext -print -o -name \*.lo -print | $NL2SP`
+ done
+
+ func_extract_archives_result="$my_oldobjs"
+}
+
+
+
+# func_emit_wrapper_part1 [arg=no]
+#
+# Emit the first part of a libtool wrapper script on stdout.
+# For more information, see the description associated with
+# func_emit_wrapper(), below.
+func_emit_wrapper_part1 ()
+{
+ func_emit_wrapper_part1_arg1=no
+ if test -n "$1" ; then
+ func_emit_wrapper_part1_arg1=$1
+ fi
+
+ $ECHO "\
+#! $SHELL
+
+# $output - temporary wrapper script for $objdir/$outputname
+# Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION
+#
+# The $output program cannot be directly executed until all the libtool
+# libraries that it depends on are installed.
+#
+# This wrapper script should never be moved out of the build directory.
+# If it is, it will not operate correctly.
+
+# Sed substitution that helps us do robust quoting. It backslashifies
+# metacharacters that are still active within double-quoted strings.
+Xsed='${SED} -e 1s/^X//'
+sed_quote_subst='$sed_quote_subst'
+
+# Be Bourne compatible
+if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then
+ emulate sh
+ NULLCMD=:
+ # Zsh 3.x and 4.x performs word splitting on \${1+\"\$@\"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '\${1+\"\$@\"}'='\"\$@\"'
+ setopt NO_GLOB_SUBST
+else
+ case \`(set -o) 2>/dev/null\` in *posix*) set -o posix;; esac
+fi
+BIN_SH=xpg4; export BIN_SH # for Tru64
+DUALCASE=1; export DUALCASE # for MKS sh
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+relink_command=\"$relink_command\"
+
+# This environment variable determines our operation mode.
+if test \"\$libtool_install_magic\" = \"$magic\"; then
+ # install mode needs the following variables:
+ generated_by_libtool_version='$macro_version'
+ notinst_deplibs='$notinst_deplibs'
+else
+ # When we are sourced in execute mode, \$file and \$ECHO are already set.
+ if test \"\$libtool_execute_magic\" != \"$magic\"; then
+ ECHO=\"$qecho\"
+ file=\"\$0\"
+ # Make sure echo works.
+ if test \"X\$1\" = X--no-reexec; then
+ # Discard the --no-reexec flag, and continue.
+ shift
+ elif test \"X\`{ \$ECHO '\t'; } 2>/dev/null\`\" = 'X\t'; then
+ # Yippee, \$ECHO works!
+ :
+ else
+ # Restart under the correct shell, and then maybe \$ECHO will work.
+ exec $SHELL \"\$0\" --no-reexec \${1+\"\$@\"}
+ fi
+ fi\
+"
+ $ECHO "\
+
+ # Find the directory that this script lives in.
+ thisdir=\`\$ECHO \"X\$file\" | \$Xsed -e 's%/[^/]*$%%'\`
+ test \"x\$thisdir\" = \"x\$file\" && thisdir=.
+
+ # Follow symbolic links until we get to the real thisdir.
+ file=\`ls -ld \"\$file\" | ${SED} -n 's/.*-> //p'\`
+ while test -n \"\$file\"; do
+ destdir=\`\$ECHO \"X\$file\" | \$Xsed -e 's%/[^/]*\$%%'\`
+
+ # If there was a directory component, then change thisdir.
+ if test \"x\$destdir\" != \"x\$file\"; then
+ case \"\$destdir\" in
+ [\\\\/]* | [A-Za-z]:[\\\\/]*) thisdir=\"\$destdir\" ;;
+ *) thisdir=\"\$thisdir/\$destdir\" ;;
+ esac
+ fi
+
+ file=\`\$ECHO \"X\$file\" | \$Xsed -e 's%^.*/%%'\`
+ file=\`ls -ld \"\$thisdir/\$file\" | ${SED} -n 's/.*-> //p'\`
+ done
+"
+}
+# end: func_emit_wrapper_part1
+
+# func_emit_wrapper_part2 [arg=no]
+#
+# Emit the second part of a libtool wrapper script on stdout.
+# For more information, see the description associated with
+# func_emit_wrapper(), below.
+func_emit_wrapper_part2 ()
+{
+ func_emit_wrapper_part2_arg1=no
+ if test -n "$1" ; then
+ func_emit_wrapper_part2_arg1=$1
+ fi
+
+ $ECHO "\
+
+ # Usually 'no', except on cygwin/mingw when embedded into
+ # the cwrapper.
+ WRAPPER_SCRIPT_BELONGS_IN_OBJDIR=$func_emit_wrapper_part2_arg1
+ if test \"\$WRAPPER_SCRIPT_BELONGS_IN_OBJDIR\" = \"yes\"; then
+ # special case for '.'
+ if test \"\$thisdir\" = \".\"; then
+ thisdir=\`pwd\`
+ fi
+ # remove .libs from thisdir
+ case \"\$thisdir\" in
+ *[\\\\/]$objdir ) thisdir=\`\$ECHO \"X\$thisdir\" | \$Xsed -e 's%[\\\\/][^\\\\/]*$%%'\` ;;
+ $objdir ) thisdir=. ;;
+ esac
+ fi
+
+ # Try to get the absolute directory name.
+ absdir=\`cd \"\$thisdir\" && pwd\`
+ test -n \"\$absdir\" && thisdir=\"\$absdir\"
+"
+
+ if test "$fast_install" = yes; then
+ $ECHO "\
+ program=lt-'$outputname'$exeext
+ progdir=\"\$thisdir/$objdir\"
+
+ if test ! -f \"\$progdir/\$program\" ||
+ { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | ${SED} 1q\`; \\
+ test \"X\$file\" != \"X\$progdir/\$program\"; }; then
+
+ file=\"\$\$-\$program\"
+
+ if test ! -d \"\$progdir\"; then
+ $MKDIR \"\$progdir\"
+ else
+ $RM \"\$progdir/\$file\"
+ fi"
+
+ $ECHO "\
+
+ # relink executable if necessary
+ if test -n \"\$relink_command\"; then
+ if relink_command_output=\`eval \$relink_command 2>&1\`; then :
+ else
+ $ECHO \"\$relink_command_output\" >&2
+ $RM \"\$progdir/\$file\"
+ exit 1
+ fi
+ fi
+
+ $MV \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null ||
+ { $RM \"\$progdir/\$program\";
+ $MV \"\$progdir/\$file\" \"\$progdir/\$program\"; }
+ $RM \"\$progdir/\$file\"
+ fi"
+ else
+ $ECHO "\
+ program='$outputname'
+ progdir=\"\$thisdir/$objdir\"
+"
+ fi
+
+ $ECHO "\
+
+ if test -f \"\$progdir/\$program\"; then"
+
+ # Export our shlibpath_var if we have one.
+ if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then
+ $ECHO "\
+ # Add our own library path to $shlibpath_var
+ $shlibpath_var=\"$temp_rpath\$$shlibpath_var\"
+
+ # Some systems cannot cope with colon-terminated $shlibpath_var
+ # The second colon is a workaround for a bug in BeOS R4 sed
+ $shlibpath_var=\`\$ECHO \"X\$$shlibpath_var\" | \$Xsed -e 's/::*\$//'\`
+
+ export $shlibpath_var
+"
+ fi
+
+ # fixup the dll searchpath if we need to.
+ if test -n "$dllsearchpath"; then
+ $ECHO "\
+ # Add the dll search path components to the executable PATH
+ PATH=$dllsearchpath:\$PATH
+"
+ fi
+
+ $ECHO "\
+ if test \"\$libtool_execute_magic\" != \"$magic\"; then
+ # Run the actual program with our arguments.
+"
+ case $host in
+ # Backslashes separate directories on plain windows
+ *-*-mingw | *-*-os2* | *-cegcc*)
+ $ECHO "\
+ exec \"\$progdir\\\\\$program\" \${1+\"\$@\"}
+"
+ ;;
+
+ *)
+ $ECHO "\
+ exec \"\$progdir/\$program\" \${1+\"\$@\"}
+"
+ ;;
+ esac
+ $ECHO "\
+ \$ECHO \"\$0: cannot exec \$program \$*\" 1>&2
+ exit 1
+ fi
+ else
+ # The program doesn't exist.
+ \$ECHO \"\$0: error: \\\`\$progdir/\$program' does not exist\" 1>&2
+ \$ECHO \"This script is just a wrapper for \$program.\" 1>&2
+ $ECHO \"See the $PACKAGE documentation for more information.\" 1>&2
+ exit 1
+ fi
+fi\
+"
+}
+# end: func_emit_wrapper_part2
+
+
+# func_emit_wrapper [arg=no]
+#
+# Emit a libtool wrapper script on stdout.
+# Don't directly open a file because we may want to
+# incorporate the script contents within a cygwin/mingw
+# wrapper executable. Must ONLY be called from within
+# func_mode_link because it depends on a number of variables
+# set therein.
+#
+# ARG is the value that the WRAPPER_SCRIPT_BELONGS_IN_OBJDIR
+# variable will take. If 'yes', then the emitted script
+# will assume that the directory in which it is stored is
+# the $objdir directory. This is a cygwin/mingw-specific
+# behavior.
+func_emit_wrapper ()
+{
+ func_emit_wrapper_arg1=no
+ if test -n "$1" ; then
+ func_emit_wrapper_arg1=$1
+ fi
+
+ # split this up so that func_emit_cwrapperexe_src
+ # can call each part independently.
+ func_emit_wrapper_part1 "${func_emit_wrapper_arg1}"
+ func_emit_wrapper_part2 "${func_emit_wrapper_arg1}"
+}
+
+
+# func_to_host_path arg
+#
+# Convert paths to host format when used with build tools.
+# Intended for use with "native" mingw (where libtool itself
+# is running under the msys shell), or in the following cross-
+# build environments:
+# $build $host
+# mingw (msys) mingw [e.g. native]
+# cygwin mingw
+# *nix + wine mingw
+# where wine is equipped with the `winepath' executable.
+# In the native mingw case, the (msys) shell automatically
+# converts paths for any non-msys applications it launches,
+# but that facility isn't available from inside the cwrapper.
+# Similar accommodations are necessary for $host mingw and
+# $build cygwin. Calling this function does no harm for other
+# $host/$build combinations not listed above.
+#
+# ARG is the path (on $build) that should be converted to
+# the proper representation for $host. The result is stored
+# in $func_to_host_path_result.
+func_to_host_path ()
+{
+ func_to_host_path_result="$1"
+ if test -n "$1" ; then
+ case $host in
+ *mingw* )
+ lt_sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g'
+ case $build in
+ *mingw* ) # actually, msys
+ # awkward: cmd appends spaces to result
+ lt_sed_strip_trailing_spaces="s/[ ]*\$//"
+ func_to_host_path_tmp1=`( cmd //c echo "$1" |\
+ $SED -e "$lt_sed_strip_trailing_spaces" ) 2>/dev/null || echo ""`
+ func_to_host_path_result=`echo "$func_to_host_path_tmp1" |\
+ $SED -e "$lt_sed_naive_backslashify"`
+ ;;
+ *cygwin* )
+ func_to_host_path_tmp1=`cygpath -w "$1"`
+ func_to_host_path_result=`echo "$func_to_host_path_tmp1" |\
+ $SED -e "$lt_sed_naive_backslashify"`
+ ;;
+ * )
+ # Unfortunately, winepath does not exit with a non-zero
+ # error code, so we are forced to check the contents of
+ # stdout. On the other hand, if the command is not
+ # found, the shell will set an exit code of 127 and print
+ # *an error message* to stdout. So we must check for both
+ # error code of zero AND non-empty stdout, which explains
+ # the odd construction:
+ func_to_host_path_tmp1=`winepath -w "$1" 2>/dev/null`
+ if test "$?" -eq 0 && test -n "${func_to_host_path_tmp1}"; then
+ func_to_host_path_result=`echo "$func_to_host_path_tmp1" |\
+ $SED -e "$lt_sed_naive_backslashify"`
+ else
+ # Allow warning below.
+ func_to_host_path_result=""
+ fi
+ ;;
+ esac
+ if test -z "$func_to_host_path_result" ; then
+ func_error "Could not determine host path corresponding to"
+ func_error " '$1'"
+ func_error "Continuing, but uninstalled executables may not work."
+ # Fallback:
+ func_to_host_path_result="$1"
+ fi
+ ;;
+ esac
+ fi
+}
+# end: func_to_host_path
+
+# func_to_host_pathlist arg
+#
+# Convert pathlists to host format when used with build tools.
+# See func_to_host_path(), above. This function supports the
+# following $build/$host combinations (but does no harm for
+# combinations not listed here):
+# $build $host
+# mingw (msys) mingw [e.g. native]
+# cygwin mingw
+# *nix + wine mingw
+#
+# Path separators are also converted from $build format to
+# $host format. If ARG begins or ends with a path separator
+# character, it is preserved (but converted to $host format)
+# on output.
+#
+# ARG is a pathlist (on $build) that should be converted to
+# the proper representation on $host. The result is stored
+# in $func_to_host_pathlist_result.
+func_to_host_pathlist ()
+{
+ func_to_host_pathlist_result="$1"
+ if test -n "$1" ; then
+ case $host in
+ *mingw* )
+ lt_sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g'
+ # Remove leading and trailing path separator characters from
+ # ARG. msys behavior is inconsistent here, cygpath turns them
+ # into '.;' and ';.', and winepath ignores them completely.
+ func_to_host_pathlist_tmp2="$1"
+ # Once set for this call, this variable should not be
+ # reassigned. It is used in tha fallback case.
+ func_to_host_pathlist_tmp1=`echo "$func_to_host_pathlist_tmp2" |\
+ $SED -e 's|^:*||' -e 's|:*$||'`
+ case $build in
+ *mingw* ) # Actually, msys.
+ # Awkward: cmd appends spaces to result.
+ lt_sed_strip_trailing_spaces="s/[ ]*\$//"
+ func_to_host_pathlist_tmp2=`( cmd //c echo "$func_to_host_pathlist_tmp1" |\
+ $SED -e "$lt_sed_strip_trailing_spaces" ) 2>/dev/null || echo ""`
+ func_to_host_pathlist_result=`echo "$func_to_host_pathlist_tmp2" |\
+ $SED -e "$lt_sed_naive_backslashify"`
+ ;;
+ *cygwin* )
+ func_to_host_pathlist_tmp2=`cygpath -w -p "$func_to_host_pathlist_tmp1"`
+ func_to_host_pathlist_result=`echo "$func_to_host_pathlist_tmp2" |\
+ $SED -e "$lt_sed_naive_backslashify"`
+ ;;
+ * )
+ # unfortunately, winepath doesn't convert pathlists
+ func_to_host_pathlist_result=""
+ func_to_host_pathlist_oldIFS=$IFS
+ IFS=:
+ for func_to_host_pathlist_f in $func_to_host_pathlist_tmp1 ; do
+ IFS=$func_to_host_pathlist_oldIFS
+ if test -n "$func_to_host_pathlist_f" ; then
+ func_to_host_path "$func_to_host_pathlist_f"
+ if test -n "$func_to_host_path_result" ; then
+ if test -z "$func_to_host_pathlist_result" ; then
+ func_to_host_pathlist_result="$func_to_host_path_result"
+ else
+ func_to_host_pathlist_result="$func_to_host_pathlist_result;$func_to_host_path_result"
+ fi
+ fi
+ fi
+ IFS=:
+ done
+ IFS=$func_to_host_pathlist_oldIFS
+ ;;
+ esac
+ if test -z "$func_to_host_pathlist_result" ; then
+ func_error "Could not determine the host path(s) corresponding to"
+ func_error " '$1'"
+ func_error "Continuing, but uninstalled executables may not work."
+ # Fallback. This may break if $1 contains DOS-style drive
+ # specifications. The fix is not to complicate the expression
+ # below, but for the user to provide a working wine installation
+ # with winepath so that path translation in the cross-to-mingw
+ # case works properly.
+ lt_replace_pathsep_nix_to_dos="s|:|;|g"
+ func_to_host_pathlist_result=`echo "$func_to_host_pathlist_tmp1" |\
+ $SED -e "$lt_replace_pathsep_nix_to_dos"`
+ fi
+ # Now, add the leading and trailing path separators back
+ case "$1" in
+ :* ) func_to_host_pathlist_result=";$func_to_host_pathlist_result"
+ ;;
+ esac
+ case "$1" in
+ *: ) func_to_host_pathlist_result="$func_to_host_pathlist_result;"
+ ;;
+ esac
+ ;;
+ esac
+ fi
+}
+# end: func_to_host_pathlist
+
+# func_emit_cwrapperexe_src
+# emit the source code for a wrapper executable on stdout
+# Must ONLY be called from within func_mode_link because
+# it depends on a number of variable set therein.
+func_emit_cwrapperexe_src ()
+{
+ cat <<EOF
+
+/* $cwrappersource - temporary wrapper executable for $objdir/$outputname
+ Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION
+
+ The $output program cannot be directly executed until all the libtool
+ libraries that it depends on are installed.
+
+ This wrapper executable should never be moved out of the build directory.
+ If it is, it will not operate correctly.
+
+ Currently, it simply execs the wrapper *script* "$SHELL $output",
+ but could eventually absorb all of the scripts functionality and
+ exec $objdir/$outputname directly.
+*/
+EOF
+ cat <<"EOF"
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef _MSC_VER
+# include <direct.h>
+# include <process.h>
+# include <io.h>
+# define setmode _setmode
+#else
+# include <unistd.h>
+# include <stdint.h>
+# ifdef __CYGWIN__
+# include <io.h>
+# define HAVE_SETENV
+# ifdef __STRICT_ANSI__
+char *realpath (const char *, char *);
+int putenv (char *);
+int setenv (const char *, const char *, int);
+# endif
+# endif
+#endif
+#include <malloc.h>
+#include <stdarg.h>
+#include <assert.h>
+#include <string.h>
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+
+#if defined(PATH_MAX)
+# define LT_PATHMAX PATH_MAX
+#elif defined(MAXPATHLEN)
+# define LT_PATHMAX MAXPATHLEN
+#else
+# define LT_PATHMAX 1024
+#endif
+
+#ifndef S_IXOTH
+# define S_IXOTH 0
+#endif
+#ifndef S_IXGRP
+# define S_IXGRP 0
+#endif
+
+#ifdef _MSC_VER
+# define S_IXUSR _S_IEXEC
+# define stat _stat
+# ifndef _INTPTR_T_DEFINED
+# define intptr_t int
+# endif
+#endif
+
+#ifndef DIR_SEPARATOR
+# define DIR_SEPARATOR '/'
+# define PATH_SEPARATOR ':'
+#endif
+
+#if defined (_WIN32) || defined (__MSDOS__) || defined (__DJGPP__) || \
+ defined (__OS2__)
+# define HAVE_DOS_BASED_FILE_SYSTEM
+# define FOPEN_WB "wb"
+# ifndef DIR_SEPARATOR_2
+# define DIR_SEPARATOR_2 '\\'
+# endif
+# ifndef PATH_SEPARATOR_2
+# define PATH_SEPARATOR_2 ';'
+# endif
+#endif
+
+#ifndef DIR_SEPARATOR_2
+# define IS_DIR_SEPARATOR(ch) ((ch) == DIR_SEPARATOR)
+#else /* DIR_SEPARATOR_2 */
+# define IS_DIR_SEPARATOR(ch) \
+ (((ch) == DIR_SEPARATOR) || ((ch) == DIR_SEPARATOR_2))
+#endif /* DIR_SEPARATOR_2 */
+
+#ifndef PATH_SEPARATOR_2
+# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR)
+#else /* PATH_SEPARATOR_2 */
+# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR_2)
+#endif /* PATH_SEPARATOR_2 */
+
+#ifdef __CYGWIN__
+# define FOPEN_WB "wb"
+#endif
+
+#ifndef FOPEN_WB
+# define FOPEN_WB "w"
+#endif
+#ifndef _O_BINARY
+# define _O_BINARY 0
+#endif
+
+#define XMALLOC(type, num) ((type *) xmalloc ((num) * sizeof(type)))
+#define XFREE(stale) do { \
+ if (stale) { free ((void *) stale); stale = 0; } \
+} while (0)
+
+#undef LTWRAPPER_DEBUGPRINTF
+#if defined DEBUGWRAPPER
+# define LTWRAPPER_DEBUGPRINTF(args) ltwrapper_debugprintf args
+static void
+ltwrapper_debugprintf (const char *fmt, ...)
+{
+ va_list args;
+ va_start (args, fmt);
+ (void) vfprintf (stderr, fmt, args);
+ va_end (args);
+}
+#else
+# define LTWRAPPER_DEBUGPRINTF(args)
+#endif
+
+const char *program_name = NULL;
+
+void *xmalloc (size_t num);
+char *xstrdup (const char *string);
+const char *base_name (const char *name);
+char *find_executable (const char *wrapper);
+char *chase_symlinks (const char *pathspec);
+int make_executable (const char *path);
+int check_executable (const char *path);
+char *strendzap (char *str, const char *pat);
+void lt_fatal (const char *message, ...);
+void lt_setenv (const char *name, const char *value);
+char *lt_extend_str (const char *orig_value, const char *add, int to_end);
+void lt_opt_process_env_set (const char *arg);
+void lt_opt_process_env_prepend (const char *arg);
+void lt_opt_process_env_append (const char *arg);
+int lt_split_name_value (const char *arg, char** name, char** value);
+void lt_update_exe_path (const char *name, const char *value);
+void lt_update_lib_path (const char *name, const char *value);
+
+static const char *script_text_part1 =
+EOF
+
+ func_emit_wrapper_part1 yes |
+ $SED -e 's/\([\\"]\)/\\\1/g' \
+ -e 's/^/ "/' -e 's/$/\\n"/'
+ echo ";"
+ cat <<EOF
+
+static const char *script_text_part2 =
+EOF
+ func_emit_wrapper_part2 yes |
+ $SED -e 's/\([\\"]\)/\\\1/g' \
+ -e 's/^/ "/' -e 's/$/\\n"/'
+ echo ";"
+
+ cat <<EOF
+const char * MAGIC_EXE = "$magic_exe";
+const char * LIB_PATH_VARNAME = "$shlibpath_var";
+EOF
+
+ if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then
+ func_to_host_pathlist "$temp_rpath"
+ cat <<EOF
+const char * LIB_PATH_VALUE = "$func_to_host_pathlist_result";
+EOF
+ else
+ cat <<"EOF"
+const char * LIB_PATH_VALUE = "";
+EOF
+ fi
+
+ if test -n "$dllsearchpath"; then
+ func_to_host_pathlist "$dllsearchpath:"
+ cat <<EOF
+const char * EXE_PATH_VARNAME = "PATH";
+const char * EXE_PATH_VALUE = "$func_to_host_pathlist_result";
+EOF
+ else
+ cat <<"EOF"
+const char * EXE_PATH_VARNAME = "";
+const char * EXE_PATH_VALUE = "";
+EOF
+ fi
+
+ if test "$fast_install" = yes; then
+ cat <<EOF
+const char * TARGET_PROGRAM_NAME = "lt-$outputname"; /* hopefully, no .exe */
+EOF
+ else
+ cat <<EOF
+const char * TARGET_PROGRAM_NAME = "$outputname"; /* hopefully, no .exe */
+EOF
+ fi
+
+
+ cat <<"EOF"
+
+#define LTWRAPPER_OPTION_PREFIX "--lt-"
+#define LTWRAPPER_OPTION_PREFIX_LENGTH 5
+
+static const size_t opt_prefix_len = LTWRAPPER_OPTION_PREFIX_LENGTH;
+static const char *ltwrapper_option_prefix = LTWRAPPER_OPTION_PREFIX;
+
+static const char *dumpscript_opt = LTWRAPPER_OPTION_PREFIX "dump-script";
+
+static const size_t env_set_opt_len = LTWRAPPER_OPTION_PREFIX_LENGTH + 7;
+static const char *env_set_opt = LTWRAPPER_OPTION_PREFIX "env-set";
+ /* argument is putenv-style "foo=bar", value of foo is set to bar */
+
+static const size_t env_prepend_opt_len = LTWRAPPER_OPTION_PREFIX_LENGTH + 11;
+static const char *env_prepend_opt = LTWRAPPER_OPTION_PREFIX "env-prepend";
+ /* argument is putenv-style "foo=bar", new value of foo is bar${foo} */
+
+static const size_t env_append_opt_len = LTWRAPPER_OPTION_PREFIX_LENGTH + 10;
+static const char *env_append_opt = LTWRAPPER_OPTION_PREFIX "env-append";
+ /* argument is putenv-style "foo=bar", new value of foo is ${foo}bar */
+
+int
+main (int argc, char *argv[])
+{
+ char **newargz;
+ int newargc;
+ char *tmp_pathspec;
+ char *actual_cwrapper_path;
+ char *actual_cwrapper_name;
+ char *target_name;
+ char *lt_argv_zero;
+ intptr_t rval = 127;
+
+ int i;
+
+ program_name = (char *) xstrdup (base_name (argv[0]));
+ LTWRAPPER_DEBUGPRINTF (("(main) argv[0] : %s\n", argv[0]));
+ LTWRAPPER_DEBUGPRINTF (("(main) program_name : %s\n", program_name));
+
+ /* very simple arg parsing; don't want to rely on getopt */
+ for (i = 1; i < argc; i++)
+ {
+ if (strcmp (argv[i], dumpscript_opt) == 0)
+ {
+EOF
+ case "$host" in
+ *mingw* | *cygwin* )
+ # make stdout use "unix" line endings
+ echo " setmode(1,_O_BINARY);"
+ ;;
+ esac
+
+ cat <<"EOF"
+ printf ("%s", script_text_part1);
+ printf ("%s", script_text_part2);
+ return 0;
+ }
+ }
+
+ newargz = XMALLOC (char *, argc + 1);
+ tmp_pathspec = find_executable (argv[0]);
+ if (tmp_pathspec == NULL)
+ lt_fatal ("Couldn't find %s", argv[0]);
+ LTWRAPPER_DEBUGPRINTF (("(main) found exe (before symlink chase) at : %s\n",
+ tmp_pathspec));
+
+ actual_cwrapper_path = chase_symlinks (tmp_pathspec);
+ LTWRAPPER_DEBUGPRINTF (("(main) found exe (after symlink chase) at : %s\n",
+ actual_cwrapper_path));
+ XFREE (tmp_pathspec);
+
+ actual_cwrapper_name = xstrdup( base_name (actual_cwrapper_path));
+ strendzap (actual_cwrapper_path, actual_cwrapper_name);
+
+ /* wrapper name transforms */
+ strendzap (actual_cwrapper_name, ".exe");
+ tmp_pathspec = lt_extend_str (actual_cwrapper_name, ".exe", 1);
+ XFREE (actual_cwrapper_name);
+ actual_cwrapper_name = tmp_pathspec;
+ tmp_pathspec = 0;
+
+ /* target_name transforms -- use actual target program name; might have lt- prefix */
+ target_name = xstrdup (base_name (TARGET_PROGRAM_NAME));
+ strendzap (target_name, ".exe");
+ tmp_pathspec = lt_extend_str (target_name, ".exe", 1);
+ XFREE (target_name);
+ target_name = tmp_pathspec;
+ tmp_pathspec = 0;
+
+ LTWRAPPER_DEBUGPRINTF (("(main) libtool target name: %s\n",
+ target_name));
+EOF
+
+ cat <<EOF
+ newargz[0] =
+ XMALLOC (char, (strlen (actual_cwrapper_path) +
+ strlen ("$objdir") + 1 + strlen (actual_cwrapper_name) + 1));
+ strcpy (newargz[0], actual_cwrapper_path);
+ strcat (newargz[0], "$objdir");
+ strcat (newargz[0], "/");
+EOF
+
+ cat <<"EOF"
+ /* stop here, and copy so we don't have to do this twice */
+ tmp_pathspec = xstrdup (newargz[0]);
+
+ /* do NOT want the lt- prefix here, so use actual_cwrapper_name */
+ strcat (newargz[0], actual_cwrapper_name);
+
+ /* DO want the lt- prefix here if it exists, so use target_name */
+ lt_argv_zero = lt_extend_str (tmp_pathspec, target_name, 1);
+ XFREE (tmp_pathspec);
+ tmp_pathspec = NULL;
+EOF
+
+ case $host_os in
+ mingw*)
+ cat <<"EOF"
+ {
+ char* p;
+ while ((p = strchr (newargz[0], '\\')) != NULL)
+ {
+ *p = '/';
+ }
+ while ((p = strchr (lt_argv_zero, '\\')) != NULL)
+ {
+ *p = '/';
+ }
+ }
+EOF
+ ;;
+ esac
+
+ cat <<"EOF"
+ XFREE (target_name);
+ XFREE (actual_cwrapper_path);
+ XFREE (actual_cwrapper_name);
+
+ lt_setenv ("BIN_SH", "xpg4"); /* for Tru64 */
+ lt_setenv ("DUALCASE", "1"); /* for MSK sh */
+ lt_update_lib_path (LIB_PATH_VARNAME, LIB_PATH_VALUE);
+ lt_update_exe_path (EXE_PATH_VARNAME, EXE_PATH_VALUE);
+
+ newargc=0;
+ for (i = 1; i < argc; i++)
+ {
+ if (strncmp (argv[i], env_set_opt, env_set_opt_len) == 0)
+ {
+ if (argv[i][env_set_opt_len] == '=')
+ {
+ const char *p = argv[i] + env_set_opt_len + 1;
+ lt_opt_process_env_set (p);
+ }
+ else if (argv[i][env_set_opt_len] == '\0' && i + 1 < argc)
+ {
+ lt_opt_process_env_set (argv[++i]); /* don't copy */
+ }
+ else
+ lt_fatal ("%s missing required argument", env_set_opt);
+ continue;
+ }
+ if (strncmp (argv[i], env_prepend_opt, env_prepend_opt_len) == 0)
+ {
+ if (argv[i][env_prepend_opt_len] == '=')
+ {
+ const char *p = argv[i] + env_prepend_opt_len + 1;
+ lt_opt_process_env_prepend (p);
+ }
+ else if (argv[i][env_prepend_opt_len] == '\0' && i + 1 < argc)
+ {
+ lt_opt_process_env_prepend (argv[++i]); /* don't copy */
+ }
+ else
+ lt_fatal ("%s missing required argument", env_prepend_opt);
+ continue;
+ }
+ if (strncmp (argv[i], env_append_opt, env_append_opt_len) == 0)
+ {
+ if (argv[i][env_append_opt_len] == '=')
+ {
+ const char *p = argv[i] + env_append_opt_len + 1;
+ lt_opt_process_env_append (p);
+ }
+ else if (argv[i][env_append_opt_len] == '\0' && i + 1 < argc)
+ {
+ lt_opt_process_env_append (argv[++i]); /* don't copy */
+ }
+ else
+ lt_fatal ("%s missing required argument", env_append_opt);
+ continue;
+ }
+ if (strncmp (argv[i], ltwrapper_option_prefix, opt_prefix_len) == 0)
+ {
+ /* however, if there is an option in the LTWRAPPER_OPTION_PREFIX
+ namespace, but it is not one of the ones we know about and
+ have already dealt with, above (inluding dump-script), then
+ report an error. Otherwise, targets might begin to believe
+ they are allowed to use options in the LTWRAPPER_OPTION_PREFIX
+ namespace. The first time any user complains about this, we'll
+ need to make LTWRAPPER_OPTION_PREFIX a configure-time option
+ or a configure.ac-settable value.
+ */
+ lt_fatal ("Unrecognized option in %s namespace: '%s'",
+ ltwrapper_option_prefix, argv[i]);
+ }
+ /* otherwise ... */
+ newargz[++newargc] = xstrdup (argv[i]);
+ }
+ newargz[++newargc] = NULL;
+
+ LTWRAPPER_DEBUGPRINTF (("(main) lt_argv_zero : %s\n", (lt_argv_zero ? lt_argv_zero : "<NULL>")));
+ for (i = 0; i < newargc; i++)
+ {
+ LTWRAPPER_DEBUGPRINTF (("(main) newargz[%d] : %s\n", i, (newargz[i] ? newargz[i] : "<NULL>")));
+ }
+
+EOF
+
+ case $host_os in
+ mingw*)
+ cat <<"EOF"
+ /* execv doesn't actually work on mingw as expected on unix */
+ rval = _spawnv (_P_WAIT, lt_argv_zero, (const char * const *) newargz);
+ if (rval == -1)
+ {
+ /* failed to start process */
+ LTWRAPPER_DEBUGPRINTF (("(main) failed to launch target \"%s\": errno = %d\n", lt_argv_zero, errno));
+ return 127;
+ }
+ return rval;
+EOF
+ ;;
+ *)
+ cat <<"EOF"
+ execv (lt_argv_zero, newargz);
+ return rval; /* =127, but avoids unused variable warning */
+EOF
+ ;;
+ esac
+
+ cat <<"EOF"
+}
+
+void *
+xmalloc (size_t num)
+{
+ void *p = (void *) malloc (num);
+ if (!p)
+ lt_fatal ("Memory exhausted");
+
+ return p;
+}
+
+char *
+xstrdup (const char *string)
+{
+ return string ? strcpy ((char *) xmalloc (strlen (string) + 1),
+ string) : NULL;
+}
+
+const char *
+base_name (const char *name)
+{
+ const char *base;
+
+#if defined (HAVE_DOS_BASED_FILE_SYSTEM)
+ /* Skip over the disk name in MSDOS pathnames. */
+ if (isalpha ((unsigned char) name[0]) && name[1] == ':')
+ name += 2;
+#endif
+
+ for (base = name; *name; name++)
+ if (IS_DIR_SEPARATOR (*name))
+ base = name + 1;
+ return base;
+}
+
+int
+check_executable (const char *path)
+{
+ struct stat st;
+
+ LTWRAPPER_DEBUGPRINTF (("(check_executable) : %s\n",
+ path ? (*path ? path : "EMPTY!") : "NULL!"));
+ if ((!path) || (!*path))
+ return 0;
+
+ if ((stat (path, &st) >= 0)
+ && (st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH)))
+ return 1;
+ else
+ return 0;
+}
+
+int
+make_executable (const char *path)
+{
+ int rval = 0;
+ struct stat st;
+
+ LTWRAPPER_DEBUGPRINTF (("(make_executable) : %s\n",
+ path ? (*path ? path : "EMPTY!") : "NULL!"));
+ if ((!path) || (!*path))
+ return 0;
+
+ if (stat (path, &st) >= 0)
+ {
+ rval = chmod (path, st.st_mode | S_IXOTH | S_IXGRP | S_IXUSR);
+ }
+ return rval;
+}
+
+/* Searches for the full path of the wrapper. Returns
+ newly allocated full path name if found, NULL otherwise
+ Does not chase symlinks, even on platforms that support them.
+*/
+char *
+find_executable (const char *wrapper)
+{
+ int has_slash = 0;
+ const char *p;
+ const char *p_next;
+ /* static buffer for getcwd */
+ char tmp[LT_PATHMAX + 1];
+ int tmp_len;
+ char *concat_name;
+
+ LTWRAPPER_DEBUGPRINTF (("(find_executable) : %s\n",
+ wrapper ? (*wrapper ? wrapper : "EMPTY!") : "NULL!"));
+
+ if ((wrapper == NULL) || (*wrapper == '\0'))
+ return NULL;
+
+ /* Absolute path? */
+#if defined (HAVE_DOS_BASED_FILE_SYSTEM)
+ if (isalpha ((unsigned char) wrapper[0]) && wrapper[1] == ':')
+ {
+ concat_name = xstrdup (wrapper);
+ if (check_executable (concat_name))
+ return concat_name;
+ XFREE (concat_name);
+ }
+ else
+ {
+#endif
+ if (IS_DIR_SEPARATOR (wrapper[0]))
+ {
+ concat_name = xstrdup (wrapper);
+ if (check_executable (concat_name))
+ return concat_name;
+ XFREE (concat_name);
+ }
+#if defined (HAVE_DOS_BASED_FILE_SYSTEM)
+ }
+#endif
+
+ for (p = wrapper; *p; p++)
+ if (*p == '/')
+ {
+ has_slash = 1;
+ break;
+ }
+ if (!has_slash)
+ {
+ /* no slashes; search PATH */
+ const char *path = getenv ("PATH");
+ if (path != NULL)
+ {
+ for (p = path; *p; p = p_next)
+ {
+ const char *q;
+ size_t p_len;
+ for (q = p; *q; q++)
+ if (IS_PATH_SEPARATOR (*q))
+ break;
+ p_len = q - p;
+ p_next = (*q == '\0' ? q : q + 1);
+ if (p_len == 0)
+ {
+ /* empty path: current directory */
+ if (getcwd (tmp, LT_PATHMAX) == NULL)
+ lt_fatal ("getcwd failed");
+ tmp_len = strlen (tmp);
+ concat_name =
+ XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1);
+ memcpy (concat_name, tmp, tmp_len);
+ concat_name[tmp_len] = '/';
+ strcpy (concat_name + tmp_len + 1, wrapper);
+ }
+ else
+ {
+ concat_name =
+ XMALLOC (char, p_len + 1 + strlen (wrapper) + 1);
+ memcpy (concat_name, p, p_len);
+ concat_name[p_len] = '/';
+ strcpy (concat_name + p_len + 1, wrapper);
+ }
+ if (check_executable (concat_name))
+ return concat_name;
+ XFREE (concat_name);
+ }
+ }
+ /* not found in PATH; assume curdir */
+ }
+ /* Relative path | not found in path: prepend cwd */
+ if (getcwd (tmp, LT_PATHMAX) == NULL)
+ lt_fatal ("getcwd failed");
+ tmp_len = strlen (tmp);
+ concat_name = XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1);
+ memcpy (concat_name, tmp, tmp_len);
+ concat_name[tmp_len] = '/';
+ strcpy (concat_name + tmp_len + 1, wrapper);
+
+ if (check_executable (concat_name))
+ return concat_name;
+ XFREE (concat_name);
+ return NULL;
+}
+
+char *
+chase_symlinks (const char *pathspec)
+{
+#ifndef S_ISLNK
+ return xstrdup (pathspec);
+#else
+ char buf[LT_PATHMAX];
+ struct stat s;
+ char *tmp_pathspec = xstrdup (pathspec);
+ char *p;
+ int has_symlinks = 0;
+ while (strlen (tmp_pathspec) && !has_symlinks)
+ {
+ LTWRAPPER_DEBUGPRINTF (("checking path component for symlinks: %s\n",
+ tmp_pathspec));
+ if (lstat (tmp_pathspec, &s) == 0)
+ {
+ if (S_ISLNK (s.st_mode) != 0)
+ {
+ has_symlinks = 1;
+ break;
+ }
+
+ /* search backwards for last DIR_SEPARATOR */
+ p = tmp_pathspec + strlen (tmp_pathspec) - 1;
+ while ((p > tmp_pathspec) && (!IS_DIR_SEPARATOR (*p)))
+ p--;
+ if ((p == tmp_pathspec) && (!IS_DIR_SEPARATOR (*p)))
+ {
+ /* no more DIR_SEPARATORS left */
+ break;
+ }
+ *p = '\0';
+ }
+ else
+ {
+ char *errstr = strerror (errno);
+ lt_fatal ("Error accessing file %s (%s)", tmp_pathspec, errstr);
+ }
+ }
+ XFREE (tmp_pathspec);
+
+ if (!has_symlinks)
+ {
+ return xstrdup (pathspec);
+ }
+
+ tmp_pathspec = realpath (pathspec, buf);
+ if (tmp_pathspec == 0)
+ {
+ lt_fatal ("Could not follow symlinks for %s", pathspec);
+ }
+ return xstrdup (tmp_pathspec);
+#endif
+}
+
+char *
+strendzap (char *str, const char *pat)
+{
+ size_t len, patlen;
+
+ assert (str != NULL);
+ assert (pat != NULL);
+
+ len = strlen (str);
+ patlen = strlen (pat);
+
+ if (patlen <= len)
+ {
+ str += len - patlen;
+ if (strcmp (str, pat) == 0)
+ *str = '\0';
+ }
+ return str;
+}
+
+static void
+lt_error_core (int exit_status, const char *mode,
+ const char *message, va_list ap)
+{
+ fprintf (stderr, "%s: %s: ", program_name, mode);
+ vfprintf (stderr, message, ap);
+ fprintf (stderr, ".\n");
+
+ if (exit_status >= 0)
+ exit (exit_status);
+}
+
+void
+lt_fatal (const char *message, ...)
+{
+ va_list ap;
+ va_start (ap, message);
+ lt_error_core (EXIT_FAILURE, "FATAL", message, ap);
+ va_end (ap);
+}
+
+void
+lt_setenv (const char *name, const char *value)
+{
+ LTWRAPPER_DEBUGPRINTF (("(lt_setenv) setting '%s' to '%s'\n",
+ (name ? name : "<NULL>"),
+ (value ? value : "<NULL>")));
+ {
+#ifdef HAVE_SETENV
+ /* always make a copy, for consistency with !HAVE_SETENV */
+ char *str = xstrdup (value);
+ setenv (name, str, 1);
+#else
+ int len = strlen (name) + 1 + strlen (value) + 1;
+ char *str = XMALLOC (char, len);
+ sprintf (str, "%s=%s", name, value);
+ if (putenv (str) != EXIT_SUCCESS)
+ {
+ XFREE (str);
+ }
+#endif
+ }
+}
+
+char *
+lt_extend_str (const char *orig_value, const char *add, int to_end)
+{
+ char *new_value;
+ if (orig_value && *orig_value)
+ {
+ int orig_value_len = strlen (orig_value);
+ int add_len = strlen (add);
+ new_value = XMALLOC (char, add_len + orig_value_len + 1);
+ if (to_end)
+ {
+ strcpy (new_value, orig_value);
+ strcpy (new_value + orig_value_len, add);
+ }
+ else
+ {
+ strcpy (new_value, add);
+ strcpy (new_value + add_len, orig_value);
+ }
+ }
+ else
+ {
+ new_value = xstrdup (add);
+ }
+ return new_value;
+}
+
+int
+lt_split_name_value (const char *arg, char** name, char** value)
+{
+ const char *p;
+ int len;
+ if (!arg || !*arg)
+ return 1;
+
+ p = strchr (arg, (int)'=');
+
+ if (!p)
+ return 1;
+
+ *value = xstrdup (++p);
+
+ len = strlen (arg) - strlen (*value);
+ *name = XMALLOC (char, len);
+ strncpy (*name, arg, len-1);
+ (*name)[len - 1] = '\0';
+
+ return 0;
+}
+
+void
+lt_opt_process_env_set (const char *arg)
+{
+ char *name = NULL;
+ char *value = NULL;
+
+ if (lt_split_name_value (arg, &name, &value) != 0)
+ {
+ XFREE (name);
+ XFREE (value);
+ lt_fatal ("bad argument for %s: '%s'", env_set_opt, arg);
+ }
+
+ lt_setenv (name, value);
+ XFREE (name);
+ XFREE (value);
+}
+
+void
+lt_opt_process_env_prepend (const char *arg)
+{
+ char *name = NULL;
+ char *value = NULL;
+ char *new_value = NULL;
+
+ if (lt_split_name_value (arg, &name, &value) != 0)
+ {
+ XFREE (name);
+ XFREE (value);
+ lt_fatal ("bad argument for %s: '%s'", env_prepend_opt, arg);
+ }
+
+ new_value = lt_extend_str (getenv (name), value, 0);
+ lt_setenv (name, new_value);
+ XFREE (new_value);
+ XFREE (name);
+ XFREE (value);
+}
+
+void
+lt_opt_process_env_append (const char *arg)
+{
+ char *name = NULL;
+ char *value = NULL;
+ char *new_value = NULL;
+
+ if (lt_split_name_value (arg, &name, &value) != 0)
+ {
+ XFREE (name);
+ XFREE (value);
+ lt_fatal ("bad argument for %s: '%s'", env_append_opt, arg);
+ }
+
+ new_value = lt_extend_str (getenv (name), value, 1);
+ lt_setenv (name, new_value);
+ XFREE (new_value);
+ XFREE (name);
+ XFREE (value);
+}
+
+void
+lt_update_exe_path (const char *name, const char *value)
+{
+ LTWRAPPER_DEBUGPRINTF (("(lt_update_exe_path) modifying '%s' by prepending '%s'\n",
+ (name ? name : "<NULL>"),
+ (value ? value : "<NULL>")));
+
+ if (name && *name && value && *value)
+ {
+ char *new_value = lt_extend_str (getenv (name), value, 0);
+ /* some systems can't cope with a ':'-terminated path #' */
+ int len = strlen (new_value);
+ while (((len = strlen (new_value)) > 0) && IS_PATH_SEPARATOR (new_value[len-1]))
+ {
+ new_value[len-1] = '\0';
+ }
+ lt_setenv (name, new_value);
+ XFREE (new_value);
+ }
+}
+
+void
+lt_update_lib_path (const char *name, const char *value)
+{
+ LTWRAPPER_DEBUGPRINTF (("(lt_update_lib_path) modifying '%s' by prepending '%s'\n",
+ (name ? name : "<NULL>"),
+ (value ? value : "<NULL>")));
+
+ if (name && *name && value && *value)
+ {
+ char *new_value = lt_extend_str (getenv (name), value, 0);
+ lt_setenv (name, new_value);
+ XFREE (new_value);
+ }
+}
+
+
+EOF
+}
+# end: func_emit_cwrapperexe_src
+
+# func_mode_link arg...
+func_mode_link ()
+{
+ $opt_debug
+ case $host in
+ *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*)
+ # It is impossible to link a dll without this setting, and
+ # we shouldn't force the makefile maintainer to figure out
+ # which system we are compiling for in order to pass an extra
+ # flag for every libtool invocation.
+ # allow_undefined=no
+
+ # FIXME: Unfortunately, there are problems with the above when trying
+ # to make a dll which has undefined symbols, in which case not
+ # even a static library is built. For now, we need to specify
+ # -no-undefined on the libtool link line when we can be certain
+ # that all symbols are satisfied, otherwise we get a static library.
+ allow_undefined=yes
+ ;;
+ *)
+ allow_undefined=yes
+ ;;
+ esac
+ libtool_args=$nonopt
+ base_compile="$nonopt $@"
+ compile_command=$nonopt
+ finalize_command=$nonopt
+
+ compile_rpath=
+ finalize_rpath=
+ compile_shlibpath=
+ finalize_shlibpath=
+ convenience=
+ old_convenience=
+ deplibs=
+ old_deplibs=
+ compiler_flags=
+ linker_flags=
+ dllsearchpath=
+ lib_search_path=`pwd`
+ inst_prefix_dir=
+ new_inherited_linker_flags=
+
+ avoid_version=no
+ dlfiles=
+ dlprefiles=
+ dlself=no
+ export_dynamic=no
+ export_symbols=
+ export_symbols_regex=
+ generated=
+ libobjs=
+ ltlibs=
+ module=no
+ no_install=no
+ objs=
+ non_pic_objects=
+ precious_files_regex=
+ prefer_static_libs=no
+ preload=no
+ prev=
+ prevarg=
+ release=
+ rpath=
+ xrpath=
+ perm_rpath=
+ temp_rpath=
+ thread_safe=no
+ vinfo=
+ vinfo_number=no
+ weak_libs=
+ single_module="${wl}-single_module"
+ func_infer_tag $base_compile
+
+ # We need to know -static, to get the right output filenames.
+ for arg
+ do
+ case $arg in
+ -shared)
+ test "$build_libtool_libs" != yes && \
+ func_fatal_configuration "can not build a shared library"
+ build_old_libs=no
+ break
+ ;;
+ -all-static | -static | -static-libtool-libs)
+ case $arg in
+ -all-static)
+ if test "$build_libtool_libs" = yes && test -z "$link_static_flag"; then
+ func_warning "complete static linking is impossible in this configuration"
+ fi
+ if test -n "$link_static_flag"; then
+ dlopen_self=$dlopen_self_static
+ fi
+ prefer_static_libs=yes
+ ;;
+ -static)
+ if test -z "$pic_flag" && test -n "$link_static_flag"; then
+ dlopen_self=$dlopen_self_static
+ fi
+ prefer_static_libs=built
+ ;;
+ -static-libtool-libs)
+ if test -z "$pic_flag" && test -n "$link_static_flag"; then
+ dlopen_self=$dlopen_self_static
+ fi
+ prefer_static_libs=yes
+ ;;
+ esac
+ build_libtool_libs=no
+ build_old_libs=yes
+ break
+ ;;
+ esac
+ done
+
+ # See if our shared archives depend on static archives.
+ test -n "$old_archive_from_new_cmds" && build_old_libs=yes
+
+ # Go through the arguments, transforming them on the way.
+ while test "$#" -gt 0; do
+ arg="$1"
+ shift
+ func_quote_for_eval "$arg"
+ qarg=$func_quote_for_eval_unquoted_result
+ func_append libtool_args " $func_quote_for_eval_result"
+
+ # If the previous option needs an argument, assign it.
+ if test -n "$prev"; then
+ case $prev in
+ output)
+ func_append compile_command " @OUTPUT@"
+ func_append finalize_command " @OUTPUT@"
+ ;;
+ esac
+
+ case $prev in
+ dlfiles|dlprefiles)
+ if test "$preload" = no; then
+ # Add the symbol object into the linking commands.
+ func_append compile_command " @SYMFILE@"
+ func_append finalize_command " @SYMFILE@"
+ preload=yes
+ fi
+ case $arg in
+ *.la | *.lo) ;; # We handle these cases below.
+ force)
+ if test "$dlself" = no; then
+ dlself=needless
+ export_dynamic=yes
+ fi
+ prev=
+ continue
+ ;;
+ self)
+ if test "$prev" = dlprefiles; then
+ dlself=yes
+ elif test "$prev" = dlfiles && test "$dlopen_self" != yes; then
+ dlself=yes
+ else
+ dlself=needless
+ export_dynamic=yes
+ fi
+ prev=
+ continue
+ ;;
+ *)
+ if test "$prev" = dlfiles; then
+ dlfiles="$dlfiles $arg"
+ else
+ dlprefiles="$dlprefiles $arg"
+ fi
+ prev=
+ continue
+ ;;
+ esac
+ ;;
+ expsyms)
+ export_symbols="$arg"
+ test -f "$arg" \
+ || func_fatal_error "symbol file \`$arg' does not exist"
+ prev=
+ continue
+ ;;
+ expsyms_regex)
+ export_symbols_regex="$arg"
+ prev=
+ continue
+ ;;
+ framework)
+ case $host in
+ *-*-darwin*)
+ case "$deplibs " in
+ *" $qarg.ltframework "*) ;;
+ *) deplibs="$deplibs $qarg.ltframework" # this is fixed later
+ ;;
+ esac
+ ;;
+ esac
+ prev=
+ continue
+ ;;
+ inst_prefix)
+ inst_prefix_dir="$arg"
+ prev=
+ continue
+ ;;
+ objectlist)
+ if test -f "$arg"; then
+ save_arg=$arg
+ moreargs=
+ for fil in `cat "$save_arg"`
+ do
+# moreargs="$moreargs $fil"
+ arg=$fil
+ # A libtool-controlled object.
+
+ # Check to see that this really is a libtool object.
+ if func_lalib_unsafe_p "$arg"; then
+ pic_object=
+ non_pic_object=
+
+ # Read the .lo file
+ func_source "$arg"
+
+ if test -z "$pic_object" ||
+ test -z "$non_pic_object" ||
+ test "$pic_object" = none &&
+ test "$non_pic_object" = none; then
+ func_fatal_error "cannot find name of object for \`$arg'"
+ fi
+
+ # Extract subdirectory from the argument.
+ func_dirname "$arg" "/" ""
+ xdir="$func_dirname_result"
+
+ if test "$pic_object" != none; then
+ # Prepend the subdirectory the object is found in.
+ pic_object="$xdir$pic_object"
+
+ if test "$prev" = dlfiles; then
+ if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then
+ dlfiles="$dlfiles $pic_object"
+ prev=
+ continue
+ else
+ # If libtool objects are unsupported, then we need to preload.
+ prev=dlprefiles
+ fi
+ fi
+
+ # CHECK ME: I think I busted this. -Ossama
+ if test "$prev" = dlprefiles; then
+ # Preload the old-style object.
+ dlprefiles="$dlprefiles $pic_object"
+ prev=
+ fi
+
+ # A PIC object.
+ func_append libobjs " $pic_object"
+ arg="$pic_object"
+ fi
+
+ # Non-PIC object.
+ if test "$non_pic_object" != none; then
+ # Prepend the subdirectory the object is found in.
+ non_pic_object="$xdir$non_pic_object"
+
+ # A standard non-PIC object
+ func_append non_pic_objects " $non_pic_object"
+ if test -z "$pic_object" || test "$pic_object" = none ; then
+ arg="$non_pic_object"
+ fi
+ else
+ # If the PIC object exists, use it instead.
+ # $xdir was prepended to $pic_object above.
+ non_pic_object="$pic_object"
+ func_append non_pic_objects " $non_pic_object"
+ fi
+ else
+ # Only an error if not doing a dry-run.
+ if $opt_dry_run; then
+ # Extract subdirectory from the argument.
+ func_dirname "$arg" "/" ""
+ xdir="$func_dirname_result"
+
+ func_lo2o "$arg"
+ pic_object=$xdir$objdir/$func_lo2o_result
+ non_pic_object=$xdir$func_lo2o_result
+ func_append libobjs " $pic_object"
+ func_append non_pic_objects " $non_pic_object"
+ else
+ func_fatal_error "\`$arg' is not a valid libtool object"
+ fi
+ fi
+ done
+ else
+ func_fatal_error "link input file \`$arg' does not exist"
+ fi
+ arg=$save_arg
+ prev=
+ continue
+ ;;
+ precious_regex)
+ precious_files_regex="$arg"
+ prev=
+ continue
+ ;;
+ release)
+ release="-$arg"
+ prev=
+ continue
+ ;;
+ rpath | xrpath)
+ # We need an absolute path.
+ case $arg in
+ [\\/]* | [A-Za-z]:[\\/]*) ;;
+ *)
+ func_fatal_error "only absolute run-paths are allowed"
+ ;;
+ esac
+ if test "$prev" = rpath; then
+ case "$rpath " in
+ *" $arg "*) ;;
+ *) rpath="$rpath $arg" ;;
+ esac
+ else
+ case "$xrpath " in
+ *" $arg "*) ;;
+ *) xrpath="$xrpath $arg" ;;
+ esac
+ fi
+ prev=
+ continue
+ ;;
+ shrext)
+ shrext_cmds="$arg"
+ prev=
+ continue
+ ;;
+ weak)
+ weak_libs="$weak_libs $arg"
+ prev=
+ continue
+ ;;
+ xcclinker)
+ linker_flags="$linker_flags $qarg"
+ compiler_flags="$compiler_flags $qarg"
+ prev=
+ func_append compile_command " $qarg"
+ func_append finalize_command " $qarg"
+ continue
+ ;;
+ xcompiler)
+ compiler_flags="$compiler_flags $qarg"
+ prev=
+ func_append compile_command " $qarg"
+ func_append finalize_command " $qarg"
+ continue
+ ;;
+ xlinker)
+ linker_flags="$linker_flags $qarg"
+ compiler_flags="$compiler_flags $wl$qarg"
+ prev=
+ func_append compile_command " $wl$qarg"
+ func_append finalize_command " $wl$qarg"
+ continue
+ ;;
+ *)
+ eval "$prev=\"\$arg\""
+ prev=
+ continue
+ ;;
+ esac
+ fi # test -n "$prev"
+
+ prevarg="$arg"
+
+ case $arg in
+ -all-static)
+ if test -n "$link_static_flag"; then
+ # See comment for -static flag below, for more details.
+ func_append compile_command " $link_static_flag"
+ func_append finalize_command " $link_static_flag"
+ fi
+ continue
+ ;;
+
+ -allow-undefined)
+ # FIXME: remove this flag sometime in the future.
+ func_fatal_error "\`-allow-undefined' must not be used because it is the default"
+ ;;
+
+ -avoid-version)
+ avoid_version=yes
+ continue
+ ;;
+
+ -dlopen)
+ prev=dlfiles
+ continue
+ ;;
+
+ -dlpreopen)
+ prev=dlprefiles
+ continue
+ ;;
+
+ -export-dynamic)
+ export_dynamic=yes
+ continue
+ ;;
+
+ -export-symbols | -export-symbols-regex)
+ if test -n "$export_symbols" || test -n "$export_symbols_regex"; then
+ func_fatal_error "more than one -exported-symbols argument is not allowed"
+ fi
+ if test "X$arg" = "X-export-symbols"; then
+ prev=expsyms
+ else
+ prev=expsyms_regex
+ fi
+ continue
+ ;;
+
+ -framework)
+ prev=framework
+ continue
+ ;;
+
+ -inst-prefix-dir)
+ prev=inst_prefix
+ continue
+ ;;
+
+ # The native IRIX linker understands -LANG:*, -LIST:* and -LNO:*
+ # so, if we see these flags be careful not to treat them like -L
+ -L[A-Z][A-Z]*:*)
+ case $with_gcc/$host in
+ no/*-*-irix* | /*-*-irix*)
+ func_append compile_command " $arg"
+ func_append finalize_command " $arg"
+ ;;
+ esac
+ continue
+ ;;
+
+ -L*)
+ func_stripname '-L' '' "$arg"
+ dir=$func_stripname_result
+ if test -z "$dir"; then
+ if test "$#" -gt 0; then
+ func_fatal_error "require no space between \`-L' and \`$1'"
+ else
+ func_fatal_error "need path for \`-L' option"
+ fi
+ fi
+ # We need an absolute path.
+ case $dir in
+ [\\/]* | [A-Za-z]:[\\/]*) ;;
+ *)
+ absdir=`cd "$dir" && pwd`
+ test -z "$absdir" && \
+ func_fatal_error "cannot determine absolute directory name of \`$dir'"
+ dir="$absdir"
+ ;;
+ esac
+ case "$deplibs " in
+ *" -L$dir "*) ;;
+ *)
+ deplibs="$deplibs -L$dir"
+ lib_search_path="$lib_search_path $dir"
+ ;;
+ esac
+ case $host in
+ *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*)
+ testbindir=`$ECHO "X$dir" | $Xsed -e 's*/lib$*/bin*'`
+ case :$dllsearchpath: in
+ *":$dir:"*) ;;
+ ::) dllsearchpath=$dir;;
+ *) dllsearchpath="$dllsearchpath:$dir";;
+ esac
+ case :$dllsearchpath: in
+ *":$testbindir:"*) ;;
+ ::) dllsearchpath=$testbindir;;
+ *) dllsearchpath="$dllsearchpath:$testbindir";;
+ esac
+ ;;
+ esac
+ continue
+ ;;
+
+ -l*)
+ if test "X$arg" = "X-lc" || test "X$arg" = "X-lm"; then
+ case $host in
+ *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-beos* | *-cegcc*)
+ # These systems don't actually have a C or math library (as such)
+ continue
+ ;;
+ *-*-os2*)
+ # These systems don't actually have a C library (as such)
+ test "X$arg" = "X-lc" && continue
+ ;;
+ *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*)
+ # Do not include libc due to us having libc/libc_r.
+ test "X$arg" = "X-lc" && continue
+ ;;
+ *-*-rhapsody* | *-*-darwin1.[012])
+ # Rhapsody C and math libraries are in the System framework
+ deplibs="$deplibs System.ltframework"
+ continue
+ ;;
+ *-*-sco3.2v5* | *-*-sco5v6*)
+ # Causes problems with __ctype
+ test "X$arg" = "X-lc" && continue
+ ;;
+ *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*)
+ # Compiler inserts libc in the correct place for threads to work
+ test "X$arg" = "X-lc" && continue
+ ;;
+ esac
+ elif test "X$arg" = "X-lc_r"; then
+ case $host in
+ *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*)
+ # Do not include libc_r directly, use -pthread flag.
+ continue
+ ;;
+ esac
+ fi
+ deplibs="$deplibs $arg"
+ continue
+ ;;
+
+ -module)
+ module=yes
+ continue
+ ;;
+
+ # Tru64 UNIX uses -model [arg] to determine the layout of C++
+ # classes, name mangling, and exception handling.
+ # Darwin uses the -arch flag to determine output architecture.
+ -model|-arch|-isysroot)
+ compiler_flags="$compiler_flags $arg"
+ func_append compile_command " $arg"
+ func_append finalize_command " $arg"
+ prev=xcompiler
+ continue
+ ;;
+
+ -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe|-threads)
+ compiler_flags="$compiler_flags $arg"
+ func_append compile_command " $arg"
+ func_append finalize_command " $arg"
+ case "$new_inherited_linker_flags " in
+ *" $arg "*) ;;
+ * ) new_inherited_linker_flags="$new_inherited_linker_flags $arg" ;;
+ esac
+ continue
+ ;;
+
+ -multi_module)
+ single_module="${wl}-multi_module"
+ continue
+ ;;
+
+ -no-fast-install)
+ fast_install=no
+ continue
+ ;;
+
+ -no-install)
+ case $host in
+ *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-darwin* | *-cegcc*)
+ # The PATH hackery in wrapper scripts is required on Windows
+ # and Darwin in order for the loader to find any dlls it needs.
+ func_warning "\`-no-install' is ignored for $host"
+ func_warning "assuming \`-no-fast-install' instead"
+ fast_install=no
+ ;;
+ *) no_install=yes ;;
+ esac
+ continue
+ ;;
+
+ -no-undefined)
+ allow_undefined=no
+ continue
+ ;;
+
+ -objectlist)
+ prev=objectlist
+ continue
+ ;;
+
+ -o) prev=output ;;
+
+ -precious-files-regex)
+ prev=precious_regex
+ continue
+ ;;
+
+ -release)
+ prev=release
+ continue
+ ;;
+
+ -rpath)
+ prev=rpath
+ continue
+ ;;
+
+ -R)
+ prev=xrpath
+ continue
+ ;;
+
+ -R*)
+ func_stripname '-R' '' "$arg"
+ dir=$func_stripname_result
+ # We need an absolute path.
+ case $dir in
+ [\\/]* | [A-Za-z]:[\\/]*) ;;
+ *)
+ func_fatal_error "only absolute run-paths are allowed"
+ ;;
+ esac
+ case "$xrpath " in
+ *" $dir "*) ;;
+ *) xrpath="$xrpath $dir" ;;
+ esac
+ continue
+ ;;
+
+ -shared)
+ # The effects of -shared are defined in a previous loop.
+ continue
+ ;;
+
+ -shrext)
+ prev=shrext
+ continue
+ ;;
+
+ -static | -static-libtool-libs)
+ # The effects of -static are defined in a previous loop.
+ # We used to do the same as -all-static on platforms that
+ # didn't have a PIC flag, but the assumption that the effects
+ # would be equivalent was wrong. It would break on at least
+ # Digital Unix and AIX.
+ continue
+ ;;
+
+ -thread-safe)
+ thread_safe=yes
+ continue
+ ;;
+
+ -version-info)
+ prev=vinfo
+ continue
+ ;;
+
+ -version-number)
+ prev=vinfo
+ vinfo_number=yes
+ continue
+ ;;
+
+ -weak)
+ prev=weak
+ continue
+ ;;
+
+ -Wc,*)
+ func_stripname '-Wc,' '' "$arg"
+ args=$func_stripname_result
+ arg=
+ save_ifs="$IFS"; IFS=','
+ for flag in $args; do
+ IFS="$save_ifs"
+ func_quote_for_eval "$flag"
+ arg="$arg $wl$func_quote_for_eval_result"
+ compiler_flags="$compiler_flags $func_quote_for_eval_result"
+ done
+ IFS="$save_ifs"
+ func_stripname ' ' '' "$arg"
+ arg=$func_stripname_result
+ ;;
+
+ -Wl,*)
+ func_stripname '-Wl,' '' "$arg"
+ args=$func_stripname_result
+ arg=
+ save_ifs="$IFS"; IFS=','
+ for flag in $args; do
+ IFS="$save_ifs"
+ func_quote_for_eval "$flag"
+ arg="$arg $wl$func_quote_for_eval_result"
+ compiler_flags="$compiler_flags $wl$func_quote_for_eval_result"
+ linker_flags="$linker_flags $func_quote_for_eval_result"
+ done
+ IFS="$save_ifs"
+ func_stripname ' ' '' "$arg"
+ arg=$func_stripname_result
+ ;;
+
+ -Xcompiler)
+ prev=xcompiler
+ continue
+ ;;
+
+ -Xlinker)
+ prev=xlinker
+ continue
+ ;;
+
+ -XCClinker)
+ prev=xcclinker
+ continue
+ ;;
+
+ # -msg_* for osf cc
+ -msg_*)
+ func_quote_for_eval "$arg"
+ arg="$func_quote_for_eval_result"
+ ;;
+
+ # -64, -mips[0-9] enable 64-bit mode on the SGI compiler
+ # -r[0-9][0-9]* specifies the processor on the SGI compiler
+ # -xarch=*, -xtarget=* enable 64-bit mode on the Sun compiler
+ # +DA*, +DD* enable 64-bit mode on the HP compiler
+ # -q* pass through compiler args for the IBM compiler
+ # -m*, -t[45]*, -txscale* pass through architecture-specific
+ # compiler args for GCC
+ # -F/path gives path to uninstalled frameworks, gcc on darwin
+ # -p, -pg, --coverage, -fprofile-* pass through profiling flag for GCC
+ # @file GCC response files
+ -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*| \
+ -t[45]*|-txscale*|-p|-pg|--coverage|-fprofile-*|-F*|@*)
+ func_quote_for_eval "$arg"
+ arg="$func_quote_for_eval_result"
+ func_append compile_command " $arg"
+ func_append finalize_command " $arg"
+ compiler_flags="$compiler_flags $arg"
+ continue
+ ;;
+
+ # Some other compiler flag.
+ -* | +*)
+ func_quote_for_eval "$arg"
+ arg="$func_quote_for_eval_result"
+ ;;
+
+ *.$objext)
+ # A standard object.
+ objs="$objs $arg"
+ ;;
+
+ *.lo)
+ # A libtool-controlled object.
+
+ # Check to see that this really is a libtool object.
+ if func_lalib_unsafe_p "$arg"; then
+ pic_object=
+ non_pic_object=
+
+ # Read the .lo file
+ func_source "$arg"
+
+ if test -z "$pic_object" ||
+ test -z "$non_pic_object" ||
+ test "$pic_object" = none &&
+ test "$non_pic_object" = none; then
+ func_fatal_error "cannot find name of object for \`$arg'"
+ fi
+
+ # Extract subdirectory from the argument.
+ func_dirname "$arg" "/" ""
+ xdir="$func_dirname_result"
+
+ if test "$pic_object" != none; then
+ # Prepend the subdirectory the object is found in.
+ pic_object="$xdir$pic_object"
+
+ if test "$prev" = dlfiles; then
+ if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then
+ dlfiles="$dlfiles $pic_object"
+ prev=
+ continue
+ else
+ # If libtool objects are unsupported, then we need to preload.
+ prev=dlprefiles
+ fi
+ fi
+
+ # CHECK ME: I think I busted this. -Ossama
+ if test "$prev" = dlprefiles; then
+ # Preload the old-style object.
+ dlprefiles="$dlprefiles $pic_object"
+ prev=
+ fi
+
+ # A PIC object.
+ func_append libobjs " $pic_object"
+ arg="$pic_object"
+ fi
+
+ # Non-PIC object.
+ if test "$non_pic_object" != none; then
+ # Prepend the subdirectory the object is found in.
+ non_pic_object="$xdir$non_pic_object"
+
+ # A standard non-PIC object
+ func_append non_pic_objects " $non_pic_object"
+ if test -z "$pic_object" || test "$pic_object" = none ; then
+ arg="$non_pic_object"
+ fi
+ else
+ # If the PIC object exists, use it instead.
+ # $xdir was prepended to $pic_object above.
+ non_pic_object="$pic_object"
+ func_append non_pic_objects " $non_pic_object"
+ fi
+ else
+ # Only an error if not doing a dry-run.
+ if $opt_dry_run; then
+ # Extract subdirectory from the argument.
+ func_dirname "$arg" "/" ""
+ xdir="$func_dirname_result"
+
+ func_lo2o "$arg"
+ pic_object=$xdir$objdir/$func_lo2o_result
+ non_pic_object=$xdir$func_lo2o_result
+ func_append libobjs " $pic_object"
+ func_append non_pic_objects " $non_pic_object"
+ else
+ func_fatal_error "\`$arg' is not a valid libtool object"
+ fi
+ fi
+ ;;
+
+ *.$libext)
+ # An archive.
+ deplibs="$deplibs $arg"
+ old_deplibs="$old_deplibs $arg"
+ continue
+ ;;
+
+ *.la)
+ # A libtool-controlled library.
+
+ if test "$prev" = dlfiles; then
+ # This library was specified with -dlopen.
+ dlfiles="$dlfiles $arg"
+ prev=
+ elif test "$prev" = dlprefiles; then
+ # The library was specified with -dlpreopen.
+ dlprefiles="$dlprefiles $arg"
+ prev=
+ else
+ deplibs="$deplibs $arg"
+ fi
+ continue
+ ;;
+
+ # Some other compiler argument.
+ *)
+ # Unknown arguments in both finalize_command and compile_command need
+ # to be aesthetically quoted because they are evaled later.
+ func_quote_for_eval "$arg"
+ arg="$func_quote_for_eval_result"
+ ;;
+ esac # arg
+
+ # Now actually substitute the argument into the commands.
+ if test -n "$arg"; then
+ func_append compile_command " $arg"
+ func_append finalize_command " $arg"
+ fi
+ done # argument parsing loop
+
+ test -n "$prev" && \
+ func_fatal_help "the \`$prevarg' option requires an argument"
+
+ if test "$export_dynamic" = yes && test -n "$export_dynamic_flag_spec"; then
+ eval arg=\"$export_dynamic_flag_spec\"
+ func_append compile_command " $arg"
+ func_append finalize_command " $arg"
+ fi
+
+ oldlibs=
+ # calculate the name of the file, without its directory
+ func_basename "$output"
+ outputname="$func_basename_result"
+ libobjs_save="$libobjs"
+
+ if test -n "$shlibpath_var"; then
+ # get the directories listed in $shlibpath_var
+ eval shlib_search_path=\`\$ECHO \"X\${$shlibpath_var}\" \| \$Xsed -e \'s/:/ /g\'\`
+ else
+ shlib_search_path=
+ fi
+ eval sys_lib_search_path=\"$sys_lib_search_path_spec\"
+ eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\"
+
+ func_dirname "$output" "/" ""
+ output_objdir="$func_dirname_result$objdir"
+ # Create the object directory.
+ func_mkdir_p "$output_objdir"
+
+ # Determine the type of output
+ case $output in
+ "")
+ func_fatal_help "you must specify an output file"
+ ;;
+ *.$libext) linkmode=oldlib ;;
+ *.lo | *.$objext) linkmode=obj ;;
+ *.la) linkmode=lib ;;
+ *) linkmode=prog ;; # Anything else should be a program.
+ esac
+
+ specialdeplibs=
+
+ libs=
+ # Find all interdependent deplibs by searching for libraries
+ # that are linked more than once (e.g. -la -lb -la)
+ for deplib in $deplibs; do
+ if $opt_duplicate_deps ; then
+ case "$libs " in
+ *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;;
+ esac
+ fi
+ libs="$libs $deplib"
+ done
+
+ if test "$linkmode" = lib; then
+ libs="$predeps $libs $compiler_lib_search_path $postdeps"
+
+ # Compute libraries that are listed more than once in $predeps
+ # $postdeps and mark them as special (i.e., whose duplicates are
+ # not to be eliminated).
+ pre_post_deps=
+ if $opt_duplicate_compiler_generated_deps; then
+ for pre_post_dep in $predeps $postdeps; do
+ case "$pre_post_deps " in
+ *" $pre_post_dep "*) specialdeplibs="$specialdeplibs $pre_post_deps" ;;
+ esac
+ pre_post_deps="$pre_post_deps $pre_post_dep"
+ done
+ fi
+ pre_post_deps=
+ fi
+
+ deplibs=
+ newdependency_libs=
+ newlib_search_path=
+ need_relink=no # whether we're linking any uninstalled libtool libraries
+ notinst_deplibs= # not-installed libtool libraries
+ notinst_path= # paths that contain not-installed libtool libraries
+
+ case $linkmode in
+ lib)
+ passes="conv dlpreopen link"
+ for file in $dlfiles $dlprefiles; do
+ case $file in
+ *.la) ;;
+ *)
+ func_fatal_help "libraries can \`-dlopen' only libtool libraries: $file"
+ ;;
+ esac
+ done
+ ;;
+ prog)
+ compile_deplibs=
+ finalize_deplibs=
+ alldeplibs=no
+ newdlfiles=
+ newdlprefiles=
+ passes="conv scan dlopen dlpreopen link"
+ ;;
+ *) passes="conv"
+ ;;
+ esac
+
+ for pass in $passes; do
+ # The preopen pass in lib mode reverses $deplibs; put it back here
+ # so that -L comes before libs that need it for instance...
+ if test "$linkmode,$pass" = "lib,link"; then
+ ## FIXME: Find the place where the list is rebuilt in the wrong
+ ## order, and fix it there properly
+ tmp_deplibs=
+ for deplib in $deplibs; do
+ tmp_deplibs="$deplib $tmp_deplibs"
+ done
+ deplibs="$tmp_deplibs"
+ fi
+
+ if test "$linkmode,$pass" = "lib,link" ||
+ test "$linkmode,$pass" = "prog,scan"; then
+ libs="$deplibs"
+ deplibs=
+ fi
+ if test "$linkmode" = prog; then
+ case $pass in
+ dlopen) libs="$dlfiles" ;;
+ dlpreopen) libs="$dlprefiles" ;;
+ link)
+ libs="$deplibs %DEPLIBS%"
+ test "X$link_all_deplibs" != Xno && libs="$libs $dependency_libs"
+ ;;
+ esac
+ fi
+ if test "$linkmode,$pass" = "lib,dlpreopen"; then
+ # Collect and forward deplibs of preopened libtool libs
+ for lib in $dlprefiles; do
+ # Ignore non-libtool-libs
+ dependency_libs=
+ case $lib in
+ *.la) func_source "$lib" ;;
+ esac
+
+ # Collect preopened libtool deplibs, except any this library
+ # has declared as weak libs
+ for deplib in $dependency_libs; do
+ deplib_base=`$ECHO "X$deplib" | $Xsed -e "$basename"`
+ case " $weak_libs " in
+ *" $deplib_base "*) ;;
+ *) deplibs="$deplibs $deplib" ;;
+ esac
+ done
+ done
+ libs="$dlprefiles"
+ fi
+ if test "$pass" = dlopen; then
+ # Collect dlpreopened libraries
+ save_deplibs="$deplibs"
+ deplibs=
+ fi
+
+ for deplib in $libs; do
+ lib=
+ found=no
+ case $deplib in
+ -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe|-threads)
+ if test "$linkmode,$pass" = "prog,link"; then
+ compile_deplibs="$deplib $compile_deplibs"
+ finalize_deplibs="$deplib $finalize_deplibs"
+ else
+ compiler_flags="$compiler_flags $deplib"
+ if test "$linkmode" = lib ; then
+ case "$new_inherited_linker_flags " in
+ *" $deplib "*) ;;
+ * ) new_inherited_linker_flags="$new_inherited_linker_flags $deplib" ;;
+ esac
+ fi
+ fi
+ continue
+ ;;
+ -l*)
+ if test "$linkmode" != lib && test "$linkmode" != prog; then
+ func_warning "\`-l' is ignored for archives/objects"
+ continue
+ fi
+ func_stripname '-l' '' "$deplib"
+ name=$func_stripname_result
+ if test "$linkmode" = lib; then
+ searchdirs="$newlib_search_path $lib_search_path $compiler_lib_search_dirs $sys_lib_search_path $shlib_search_path"
+ else
+ searchdirs="$newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path"
+ fi
+ for searchdir in $searchdirs; do
+ for search_ext in .la $std_shrext .so .a; do
+ # Search the libtool library
+ lib="$searchdir/lib${name}${search_ext}"
+ if test -f "$lib"; then
+ if test "$search_ext" = ".la"; then
+ found=yes
+ else
+ found=no
+ fi
+ break 2
+ fi
+ done
+ done
+ if test "$found" != yes; then
+ # deplib doesn't seem to be a libtool library
+ if test "$linkmode,$pass" = "prog,link"; then
+ compile_deplibs="$deplib $compile_deplibs"
+ finalize_deplibs="$deplib $finalize_deplibs"
+ else
+ deplibs="$deplib $deplibs"
+ test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs"
+ fi
+ continue
+ else # deplib is a libtool library
+ # If $allow_libtool_libs_with_static_runtimes && $deplib is a stdlib,
+ # We need to do some special things here, and not later.
+ if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+ case " $predeps $postdeps " in
+ *" $deplib "*)
+ if func_lalib_p "$lib"; then
+ library_names=
+ old_library=
+ func_source "$lib"
+ for l in $old_library $library_names; do
+ ll="$l"
+ done
+ if test "X$ll" = "X$old_library" ; then # only static version available
+ found=no
+ func_dirname "$lib" "" "."
+ ladir="$func_dirname_result"
+ lib=$ladir/$old_library
+ if test "$linkmode,$pass" = "prog,link"; then
+ compile_deplibs="$deplib $compile_deplibs"
+ finalize_deplibs="$deplib $finalize_deplibs"
+ else
+ deplibs="$deplib $deplibs"
+ test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs"
+ fi
+ continue
+ fi
+ fi
+ ;;
+ *) ;;
+ esac
+ fi
+ fi
+ ;; # -l
+ *.ltframework)
+ if test "$linkmode,$pass" = "prog,link"; then
+ compile_deplibs="$deplib $compile_deplibs"
+ finalize_deplibs="$deplib $finalize_deplibs"
+ else
+ deplibs="$deplib $deplibs"
+ if test "$linkmode" = lib ; then
+ case "$new_inherited_linker_flags " in
+ *" $deplib "*) ;;
+ * ) new_inherited_linker_flags="$new_inherited_linker_flags $deplib" ;;
+ esac
+ fi
+ fi
+ continue
+ ;;
+ -L*)
+ case $linkmode in
+ lib)
+ deplibs="$deplib $deplibs"
+ test "$pass" = conv && continue
+ newdependency_libs="$deplib $newdependency_libs"
+ func_stripname '-L' '' "$deplib"
+ newlib_search_path="$newlib_search_path $func_stripname_result"
+ ;;
+ prog)
+ if test "$pass" = conv; then
+ deplibs="$deplib $deplibs"
+ continue
+ fi
+ if test "$pass" = scan; then
+ deplibs="$deplib $deplibs"
+ else
+ compile_deplibs="$deplib $compile_deplibs"
+ finalize_deplibs="$deplib $finalize_deplibs"
+ fi
+ func_stripname '-L' '' "$deplib"
+ newlib_search_path="$newlib_search_path $func_stripname_result"
+ ;;
+ *)
+ func_warning "\`-L' is ignored for archives/objects"
+ ;;
+ esac # linkmode
+ continue
+ ;; # -L
+ -R*)
+ if test "$pass" = link; then
+ func_stripname '-R' '' "$deplib"
+ dir=$func_stripname_result
+ # Make sure the xrpath contains only unique directories.
+ case "$xrpath " in
+ *" $dir "*) ;;
+ *) xrpath="$xrpath $dir" ;;
+ esac
+ fi
+ deplibs="$deplib $deplibs"
+ continue
+ ;;
+ *.la) lib="$deplib" ;;
+ *.$libext)
+ if test "$pass" = conv; then
+ deplibs="$deplib $deplibs"
+ continue
+ fi
+ case $linkmode in
+ lib)
+ # Linking convenience modules into shared libraries is allowed,
+ # but linking other static libraries is non-portable.
+ case " $dlpreconveniencelibs " in
+ *" $deplib "*) ;;
+ *)
+ valid_a_lib=no
+ case $deplibs_check_method in
+ match_pattern*)
+ set dummy $deplibs_check_method; shift
+ match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"`
+ if eval "\$ECHO \"X$deplib\"" 2>/dev/null | $Xsed -e 10q \
+ | $EGREP "$match_pattern_regex" > /dev/null; then
+ valid_a_lib=yes
+ fi
+ ;;
+ pass_all)
+ valid_a_lib=yes
+ ;;
+ esac
+ if test "$valid_a_lib" != yes; then
+ $ECHO
+ $ECHO "*** Warning: Trying to link with static lib archive $deplib."
+ $ECHO "*** I have the capability to make that library automatically link in when"
+ $ECHO "*** you link to this library. But I can only do this if you have a"
+ $ECHO "*** shared version of the library, which you do not appear to have"
+ $ECHO "*** because the file extensions .$libext of this argument makes me believe"
+ $ECHO "*** that it is just a static archive that I should not use here."
+ else
+ $ECHO
+ $ECHO "*** Warning: Linking the shared library $output against the"
+ $ECHO "*** static library $deplib is not portable!"
+ deplibs="$deplib $deplibs"
+ fi
+ ;;
+ esac
+ continue
+ ;;
+ prog)
+ if test "$pass" != link; then
+ deplibs="$deplib $deplibs"
+ else
+ compile_deplibs="$deplib $compile_deplibs"
+ finalize_deplibs="$deplib $finalize_deplibs"
+ fi
+ continue
+ ;;
+ esac # linkmode
+ ;; # *.$libext
+ *.lo | *.$objext)
+ if test "$pass" = conv; then
+ deplibs="$deplib $deplibs"
+ elif test "$linkmode" = prog; then
+ if test "$pass" = dlpreopen || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then
+ # If there is no dlopen support or we're linking statically,
+ # we need to preload.
+ newdlprefiles="$newdlprefiles $deplib"
+ compile_deplibs="$deplib $compile_deplibs"
+ finalize_deplibs="$deplib $finalize_deplibs"
+ else
+ newdlfiles="$newdlfiles $deplib"
+ fi
+ fi
+ continue
+ ;;
+ %DEPLIBS%)
+ alldeplibs=yes
+ continue
+ ;;
+ esac # case $deplib
+
+ if test "$found" = yes || test -f "$lib"; then :
+ else
+ func_fatal_error "cannot find the library \`$lib' or unhandled argument \`$deplib'"
+ fi
+
+ # Check to see that this really is a libtool archive.
+ func_lalib_unsafe_p "$lib" \
+ || func_fatal_error "\`$lib' is not a valid libtool archive"
+
+ func_dirname "$lib" "" "."
+ ladir="$func_dirname_result"
+
+ dlname=
+ dlopen=
+ dlpreopen=
+ libdir=
+ library_names=
+ old_library=
+ inherited_linker_flags=
+ # If the library was installed with an old release of libtool,
+ # it will not redefine variables installed, or shouldnotlink
+ installed=yes
+ shouldnotlink=no
+ avoidtemprpath=
+
+
+ # Read the .la file
+ func_source "$lib"
+
+ # Convert "-framework foo" to "foo.ltframework"
+ if test -n "$inherited_linker_flags"; then
+ tmp_inherited_linker_flags=`$ECHO "X$inherited_linker_flags" | $Xsed -e 's/-framework \([^ $]*\)/\1.ltframework/g'`
+ for tmp_inherited_linker_flag in $tmp_inherited_linker_flags; do
+ case " $new_inherited_linker_flags " in
+ *" $tmp_inherited_linker_flag "*) ;;
+ *) new_inherited_linker_flags="$new_inherited_linker_flags $tmp_inherited_linker_flag";;
+ esac
+ done
+ fi
+ dependency_libs=`$ECHO "X $dependency_libs" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'`
+ if test "$linkmode,$pass" = "lib,link" ||
+ test "$linkmode,$pass" = "prog,scan" ||
+ { test "$linkmode" != prog && test "$linkmode" != lib; }; then
+ test -n "$dlopen" && dlfiles="$dlfiles $dlopen"
+ test -n "$dlpreopen" && dlprefiles="$dlprefiles $dlpreopen"
+ fi
+
+ if test "$pass" = conv; then
+ # Only check for convenience libraries
+ deplibs="$lib $deplibs"
+ if test -z "$libdir"; then
+ if test -z "$old_library"; then
+ func_fatal_error "cannot find name of link library for \`$lib'"
+ fi
+ # It is a libtool convenience library, so add in its objects.
+ convenience="$convenience $ladir/$objdir/$old_library"
+ old_convenience="$old_convenience $ladir/$objdir/$old_library"
+ tmp_libs=
+ for deplib in $dependency_libs; do
+ deplibs="$deplib $deplibs"
+ if $opt_duplicate_deps ; then
+ case "$tmp_libs " in
+ *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;;
+ esac
+ fi
+ tmp_libs="$tmp_libs $deplib"
+ done
+ elif test "$linkmode" != prog && test "$linkmode" != lib; then
+ func_fatal_error "\`$lib' is not a convenience library"
+ fi
+ continue
+ fi # $pass = conv
+
+
+ # Get the name of the library we link against.
+ linklib=
+ for l in $old_library $library_names; do
+ linklib="$l"
+ done
+ if test -z "$linklib"; then
+ func_fatal_error "cannot find name of link library for \`$lib'"
+ fi
+
+ # This library was specified with -dlopen.
+ if test "$pass" = dlopen; then
+ if test -z "$libdir"; then
+ func_fatal_error "cannot -dlopen a convenience library: \`$lib'"
+ fi
+ if test -z "$dlname" ||
+ test "$dlopen_support" != yes ||
+ test "$build_libtool_libs" = no; then
+ # If there is no dlname, no dlopen support or we're linking
+ # statically, we need to preload. We also need to preload any
+ # dependent libraries so libltdl's deplib preloader doesn't
+ # bomb out in the load deplibs phase.
+ dlprefiles="$dlprefiles $lib $dependency_libs"
+ else
+ newdlfiles="$newdlfiles $lib"
+ fi
+ continue
+ fi # $pass = dlopen
+
+ # We need an absolute path.
+ case $ladir in
+ [\\/]* | [A-Za-z]:[\\/]*) abs_ladir="$ladir" ;;
+ *)
+ abs_ladir=`cd "$ladir" && pwd`
+ if test -z "$abs_ladir"; then
+ func_warning "cannot determine absolute directory name of \`$ladir'"
+ func_warning "passing it literally to the linker, although it might fail"
+ abs_ladir="$ladir"
+ fi
+ ;;
+ esac
+ func_basename "$lib"
+ laname="$func_basename_result"
+
+ # Find the relevant object directory and library name.
+ if test "X$installed" = Xyes; then
+ if test ! -f "$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then
+ func_warning "library \`$lib' was moved."
+ dir="$ladir"
+ absdir="$abs_ladir"
+ libdir="$abs_ladir"
+ else
+ dir="$libdir"
+ absdir="$libdir"
+ fi
+ test "X$hardcode_automatic" = Xyes && avoidtemprpath=yes
+ else
+ if test ! -f "$ladir/$objdir/$linklib" && test -f "$abs_ladir/$linklib"; then
+ dir="$ladir"
+ absdir="$abs_ladir"
+ # Remove this search path later
+ notinst_path="$notinst_path $abs_ladir"
+ else
+ dir="$ladir/$objdir"
+ absdir="$abs_ladir/$objdir"
+ # Remove this search path later
+ notinst_path="$notinst_path $abs_ladir"
+ fi
+ fi # $installed = yes
+ func_stripname 'lib' '.la' "$laname"
+ name=$func_stripname_result
+
+ # This library was specified with -dlpreopen.
+ if test "$pass" = dlpreopen; then
+ if test -z "$libdir" && test "$linkmode" = prog; then
+ func_fatal_error "only libraries may -dlpreopen a convenience library: \`$lib'"
+ fi
+ # Prefer using a static library (so that no silly _DYNAMIC symbols
+ # are required to link).
+ if test -n "$old_library"; then
+ newdlprefiles="$newdlprefiles $dir/$old_library"
+ # Keep a list of preopened convenience libraries to check
+ # that they are being used correctly in the link pass.
+ test -z "$libdir" && \
+ dlpreconveniencelibs="$dlpreconveniencelibs $dir/$old_library"
+ # Otherwise, use the dlname, so that lt_dlopen finds it.
+ elif test -n "$dlname"; then
+ newdlprefiles="$newdlprefiles $dir/$dlname"
+ else
+ newdlprefiles="$newdlprefiles $dir/$linklib"
+ fi
+ fi # $pass = dlpreopen
+
+ if test -z "$libdir"; then
+ # Link the convenience library
+ if test "$linkmode" = lib; then
+ deplibs="$dir/$old_library $deplibs"
+ elif test "$linkmode,$pass" = "prog,link"; then
+ compile_deplibs="$dir/$old_library $compile_deplibs"
+ finalize_deplibs="$dir/$old_library $finalize_deplibs"
+ else
+ deplibs="$lib $deplibs" # used for prog,scan pass
+ fi
+ continue
+ fi
+
+
+ if test "$linkmode" = prog && test "$pass" != link; then
+ newlib_search_path="$newlib_search_path $ladir"
+ deplibs="$lib $deplibs"
+
+ linkalldeplibs=no
+ if test "$link_all_deplibs" != no || test -z "$library_names" ||
+ test "$build_libtool_libs" = no; then
+ linkalldeplibs=yes
+ fi
+
+ tmp_libs=
+ for deplib in $dependency_libs; do
+ case $deplib in
+ -L*) func_stripname '-L' '' "$deplib"
+ newlib_search_path="$newlib_search_path $func_stripname_result"
+ ;;
+ esac
+ # Need to link against all dependency_libs?
+ if test "$linkalldeplibs" = yes; then
+ deplibs="$deplib $deplibs"
+ else
+ # Need to hardcode shared library paths
+ # or/and link against static libraries
+ newdependency_libs="$deplib $newdependency_libs"
+ fi
+ if $opt_duplicate_deps ; then
+ case "$tmp_libs " in
+ *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;;
+ esac
+ fi
+ tmp_libs="$tmp_libs $deplib"
+ done # for deplib
+ continue
+ fi # $linkmode = prog...
+
+ if test "$linkmode,$pass" = "prog,link"; then
+ if test -n "$library_names" &&
+ { { test "$prefer_static_libs" = no ||
+ test "$prefer_static_libs,$installed" = "built,yes"; } ||
+ test -z "$old_library"; }; then
+ # We need to hardcode the library path
+ if test -n "$shlibpath_var" && test -z "$avoidtemprpath" ; then
+ # Make sure the rpath contains only unique directories.
+ case "$temp_rpath:" in
+ *"$absdir:"*) ;;
+ *) temp_rpath="$temp_rpath$absdir:" ;;
+ esac
+ fi
+
+ # Hardcode the library path.
+ # Skip directories that are in the system default run-time
+ # search path.
+ case " $sys_lib_dlsearch_path " in
+ *" $absdir "*) ;;
+ *)
+ case "$compile_rpath " in
+ *" $absdir "*) ;;
+ *) compile_rpath="$compile_rpath $absdir"
+ esac
+ ;;
+ esac
+ case " $sys_lib_dlsearch_path " in
+ *" $libdir "*) ;;
+ *)
+ case "$finalize_rpath " in
+ *" $libdir "*) ;;
+ *) finalize_rpath="$finalize_rpath $libdir"
+ esac
+ ;;
+ esac
+ fi # $linkmode,$pass = prog,link...
+
+ if test "$alldeplibs" = yes &&
+ { test "$deplibs_check_method" = pass_all ||
+ { test "$build_libtool_libs" = yes &&
+ test -n "$library_names"; }; }; then
+ # We only need to search for static libraries
+ continue
+ fi
+ fi
+
+ link_static=no # Whether the deplib will be linked statically
+ use_static_libs=$prefer_static_libs
+ if test "$use_static_libs" = built && test "$installed" = yes; then
+ use_static_libs=no
+ fi
+ if test -n "$library_names" &&
+ { test "$use_static_libs" = no || test -z "$old_library"; }; then
+ case $host in
+ *cygwin* | *mingw* | *cegcc*)
+ # No point in relinking DLLs because paths are not encoded
+ notinst_deplibs="$notinst_deplibs $lib"
+ need_relink=no
+ ;;
+ *)
+ if test "$installed" = no; then
+ notinst_deplibs="$notinst_deplibs $lib"
+ need_relink=yes
+ fi
+ ;;
+ esac
+ # This is a shared library
+
+ # Warn about portability, can't link against -module's on some
+ # systems (darwin). Don't bleat about dlopened modules though!
+ dlopenmodule=""
+ for dlpremoduletest in $dlprefiles; do
+ if test "X$dlpremoduletest" = "X$lib"; then
+ dlopenmodule="$dlpremoduletest"
+ break
+ fi
+ done
+ if test -z "$dlopenmodule" && test "$shouldnotlink" = yes && test "$pass" = link; then
+ $ECHO
+ if test "$linkmode" = prog; then
+ $ECHO "*** Warning: Linking the executable $output against the loadable module"
+ else
+ $ECHO "*** Warning: Linking the shared library $output against the loadable module"
+ fi
+ $ECHO "*** $linklib is not portable!"
+ fi
+ if test "$linkmode" = lib &&
+ test "$hardcode_into_libs" = yes; then
+ # Hardcode the library path.
+ # Skip directories that are in the system default run-time
+ # search path.
+ case " $sys_lib_dlsearch_path " in
+ *" $absdir "*) ;;
+ *)
+ case "$compile_rpath " in
+ *" $absdir "*) ;;
+ *) compile_rpath="$compile_rpath $absdir"
+ esac
+ ;;
+ esac
+ case " $sys_lib_dlsearch_path " in
+ *" $libdir "*) ;;
+ *)
+ case "$finalize_rpath " in
+ *" $libdir "*) ;;
+ *) finalize_rpath="$finalize_rpath $libdir"
+ esac
+ ;;
+ esac
+ fi
+
+ if test -n "$old_archive_from_expsyms_cmds"; then
+ # figure out the soname
+ set dummy $library_names
+ shift
+ realname="$1"
+ shift
+ libname=`eval "\\$ECHO \"$libname_spec\""`
+ # use dlname if we got it. it's perfectly good, no?
+ if test -n "$dlname"; then
+ soname="$dlname"
+ elif test -n "$soname_spec"; then
+ # bleh windows
+ case $host in
+ *cygwin* | mingw* | *cegcc*)
+ func_arith $current - $age
+ major=$func_arith_result
+ versuffix="-$major"
+ ;;
+ esac
+ eval soname=\"$soname_spec\"
+ else
+ soname="$realname"
+ fi
+
+ # Make a new name for the extract_expsyms_cmds to use
+ soroot="$soname"
+ func_basename "$soroot"
+ soname="$func_basename_result"
+ func_stripname 'lib' '.dll' "$soname"
+ newlib=libimp-$func_stripname_result.a
+
+ # If the library has no export list, then create one now
+ if test -f "$output_objdir/$soname-def"; then :
+ else
+ func_verbose "extracting exported symbol list from \`$soname'"
+ func_execute_cmds "$extract_expsyms_cmds" 'exit $?'
+ fi
+
+ # Create $newlib
+ if test -f "$output_objdir/$newlib"; then :; else
+ func_verbose "generating import library for \`$soname'"
+ func_execute_cmds "$old_archive_from_expsyms_cmds" 'exit $?'
+ fi
+ # make sure the library variables are pointing to the new library
+ dir=$output_objdir
+ linklib=$newlib
+ fi # test -n "$old_archive_from_expsyms_cmds"
+
+ if test "$linkmode" = prog || test "$mode" != relink; then
+ add_shlibpath=
+ add_dir=
+ add=
+ lib_linked=yes
+ case $hardcode_action in
+ immediate | unsupported)
+ if test "$hardcode_direct" = no; then
+ add="$dir/$linklib"
+ case $host in
+ *-*-sco3.2v5.0.[024]*) add_dir="-L$dir" ;;
+ *-*-sysv4*uw2*) add_dir="-L$dir" ;;
+ *-*-sysv5OpenUNIX* | *-*-sysv5UnixWare7.[01].[10]* | \
+ *-*-unixware7*) add_dir="-L$dir" ;;
+ *-*-darwin* )
+ # if the lib is a (non-dlopened) module then we can not
+ # link against it, someone is ignoring the earlier warnings
+ if /usr/bin/file -L $add 2> /dev/null |
+ $GREP ": [^:]* bundle" >/dev/null ; then
+ if test "X$dlopenmodule" != "X$lib"; then
+ $ECHO "*** Warning: lib $linklib is a module, not a shared library"
+ if test -z "$old_library" ; then
+ $ECHO
+ $ECHO "*** And there doesn't seem to be a static archive available"
+ $ECHO "*** The link will probably fail, sorry"
+ else
+ add="$dir/$old_library"
+ fi
+ elif test -n "$old_library"; then
+ add="$dir/$old_library"
+ fi
+ fi
+ esac
+ elif test "$hardcode_minus_L" = no; then
+ case $host in
+ *-*-sunos*) add_shlibpath="$dir" ;;
+ esac
+ add_dir="-L$dir"
+ add="-l$name"
+ elif test "$hardcode_shlibpath_var" = no; then
+ add_shlibpath="$dir"
+ add="-l$name"
+ else
+ lib_linked=no
+ fi
+ ;;
+ relink)
+ if test "$hardcode_direct" = yes &&
+ test "$hardcode_direct_absolute" = no; then
+ add="$dir/$linklib"
+ elif test "$hardcode_minus_L" = yes; then
+ add_dir="-L$dir"
+ # Try looking first in the location we're being installed to.
+ if test -n "$inst_prefix_dir"; then
+ case $libdir in
+ [\\/]*)
+ add_dir="$add_dir -L$inst_prefix_dir$libdir"
+ ;;
+ esac
+ fi
+ add="-l$name"
+ elif test "$hardcode_shlibpath_var" = yes; then
+ add_shlibpath="$dir"
+ add="-l$name"
+ else
+ lib_linked=no
+ fi
+ ;;
+ *) lib_linked=no ;;
+ esac
+
+ if test "$lib_linked" != yes; then
+ func_fatal_configuration "unsupported hardcode properties"
+ fi
+
+ if test -n "$add_shlibpath"; then
+ case :$compile_shlibpath: in
+ *":$add_shlibpath:"*) ;;
+ *) compile_shlibpath="$compile_shlibpath$add_shlibpath:" ;;
+ esac
+ fi
+ if test "$linkmode" = prog; then
+ test -n "$add_dir" && compile_deplibs="$add_dir $compile_deplibs"
+ test -n "$add" && compile_deplibs="$add $compile_deplibs"
+ else
+ test -n "$add_dir" && deplibs="$add_dir $deplibs"
+ test -n "$add" && deplibs="$add $deplibs"
+ if test "$hardcode_direct" != yes &&
+ test "$hardcode_minus_L" != yes &&
+ test "$hardcode_shlibpath_var" = yes; then
+ case :$finalize_shlibpath: in
+ *":$libdir:"*) ;;
+ *) finalize_shlibpath="$finalize_shlibpath$libdir:" ;;
+ esac
+ fi
+ fi
+ fi
+
+ if test "$linkmode" = prog || test "$mode" = relink; then
+ add_shlibpath=
+ add_dir=
+ add=
+ # Finalize command for both is simple: just hardcode it.
+ if test "$hardcode_direct" = yes &&
+ test "$hardcode_direct_absolute" = no; then
+ add="$libdir/$linklib"
+ elif test "$hardcode_minus_L" = yes; then
+ add_dir="-L$libdir"
+ add="-l$name"
+ elif test "$hardcode_shlibpath_var" = yes; then
+ case :$finalize_shlibpath: in
+ *":$libdir:"*) ;;
+ *) finalize_shlibpath="$finalize_shlibpath$libdir:" ;;
+ esac
+ add="-l$name"
+ elif test "$hardcode_automatic" = yes; then
+ if test -n "$inst_prefix_dir" &&
+ test -f "$inst_prefix_dir$libdir/$linklib" ; then
+ add="$inst_prefix_dir$libdir/$linklib"
+ else
+ add="$libdir/$linklib"
+ fi
+ else
+ # We cannot seem to hardcode it, guess we'll fake it.
+ add_dir="-L$libdir"
+ # Try looking first in the location we're being installed to.
+ if test -n "$inst_prefix_dir"; then
+ case $libdir in
+ [\\/]*)
+ add_dir="$add_dir -L$inst_prefix_dir$libdir"
+ ;;
+ esac
+ fi
+ add="-l$name"
+ fi
+
+ if test "$linkmode" = prog; then
+ test -n "$add_dir" && finalize_deplibs="$add_dir $finalize_deplibs"
+ test -n "$add" && finalize_deplibs="$add $finalize_deplibs"
+ else
+ test -n "$add_dir" && deplibs="$add_dir $deplibs"
+ test -n "$add" && deplibs="$add $deplibs"
+ fi
+ fi
+ elif test "$linkmode" = prog; then
+ # Here we assume that one of hardcode_direct or hardcode_minus_L
+ # is not unsupported. This is valid on all known static and
+ # shared platforms.
+ if test "$hardcode_direct" != unsupported; then
+ test -n "$old_library" && linklib="$old_library"
+ compile_deplibs="$dir/$linklib $compile_deplibs"
+ finalize_deplibs="$dir/$linklib $finalize_deplibs"
+ else
+ compile_deplibs="-l$name -L$dir $compile_deplibs"
+ finalize_deplibs="-l$name -L$dir $finalize_deplibs"
+ fi
+ elif test "$build_libtool_libs" = yes; then
+ # Not a shared library
+ if test "$deplibs_check_method" != pass_all; then
+ # We're trying link a shared library against a static one
+ # but the system doesn't support it.
+
+ # Just print a warning and add the library to dependency_libs so
+ # that the program can be linked against the static library.
+ $ECHO
+ $ECHO "*** Warning: This system can not link to static lib archive $lib."
+ $ECHO "*** I have the capability to make that library automatically link in when"
+ $ECHO "*** you link to this library. But I can only do this if you have a"
+ $ECHO "*** shared version of the library, which you do not appear to have."
+ if test "$module" = yes; then
+ $ECHO "*** But as you try to build a module library, libtool will still create "
+ $ECHO "*** a static module, that should work as long as the dlopening application"
+ $ECHO "*** is linked with the -dlopen flag to resolve symbols at runtime."
+ if test -z "$global_symbol_pipe"; then
+ $ECHO
+ $ECHO "*** However, this would only work if libtool was able to extract symbol"
+ $ECHO "*** lists from a program, using \`nm' or equivalent, but libtool could"
+ $ECHO "*** not find such a program. So, this module is probably useless."
+ $ECHO "*** \`nm' from GNU binutils and a full rebuild may help."
+ fi
+ if test "$build_old_libs" = no; then
+ build_libtool_libs=module
+ build_old_libs=yes
+ else
+ build_libtool_libs=no
+ fi
+ fi
+ else
+ deplibs="$dir/$old_library $deplibs"
+ link_static=yes
+ fi
+ fi # link shared/static library?
+
+ if test "$linkmode" = lib; then
+ if test -n "$dependency_libs" &&
+ { test "$hardcode_into_libs" != yes ||
+ test "$build_old_libs" = yes ||
+ test "$link_static" = yes; }; then
+ # Extract -R from dependency_libs
+ temp_deplibs=
+ for libdir in $dependency_libs; do
+ case $libdir in
+ -R*) func_stripname '-R' '' "$libdir"
+ temp_xrpath=$func_stripname_result
+ case " $xrpath " in
+ *" $temp_xrpath "*) ;;
+ *) xrpath="$xrpath $temp_xrpath";;
+ esac;;
+ *) temp_deplibs="$temp_deplibs $libdir";;
+ esac
+ done
+ dependency_libs="$temp_deplibs"
+ fi
+
+ newlib_search_path="$newlib_search_path $absdir"
+ # Link against this library
+ test "$link_static" = no && newdependency_libs="$abs_ladir/$laname $newdependency_libs"
+ # ... and its dependency_libs
+ tmp_libs=
+ for deplib in $dependency_libs; do
+ newdependency_libs="$deplib $newdependency_libs"
+ if $opt_duplicate_deps ; then
+ case "$tmp_libs " in
+ *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;;
+ esac
+ fi
+ tmp_libs="$tmp_libs $deplib"
+ done
+
+ if test "$link_all_deplibs" != no; then
+ # Add the search paths of all dependency libraries
+ for deplib in $dependency_libs; do
+ path=
+ case $deplib in
+ -L*) path="$deplib" ;;
+ *.la)
+ func_dirname "$deplib" "" "."
+ dir="$func_dirname_result"
+ # We need an absolute path.
+ case $dir in
+ [\\/]* | [A-Za-z]:[\\/]*) absdir="$dir" ;;
+ *)
+ absdir=`cd "$dir" && pwd`
+ if test -z "$absdir"; then
+ func_warning "cannot determine absolute directory name of \`$dir'"
+ absdir="$dir"
+ fi
+ ;;
+ esac
+ if $GREP "^installed=no" $deplib > /dev/null; then
+ case $host in
+ *-*-darwin*)
+ depdepl=
+ eval deplibrary_names=`${SED} -n -e 's/^library_names=\(.*\)$/\1/p' $deplib`
+ if test -n "$deplibrary_names" ; then
+ for tmp in $deplibrary_names ; do
+ depdepl=$tmp
+ done
+ if test -f "$absdir/$objdir/$depdepl" ; then
+ depdepl="$absdir/$objdir/$depdepl"
+ darwin_install_name=`${OTOOL} -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'`
+ if test -z "$darwin_install_name"; then
+ darwin_install_name=`${OTOOL64} -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'`
+ fi
+ compiler_flags="$compiler_flags ${wl}-dylib_file ${wl}${darwin_install_name}:${depdepl}"
+ linker_flags="$linker_flags -dylib_file ${darwin_install_name}:${depdepl}"
+ path=
+ fi
+ fi
+ ;;
+ *)
+ path="-L$absdir/$objdir"
+ ;;
+ esac
+ else
+ eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib`
+ test -z "$libdir" && \
+ func_fatal_error "\`$deplib' is not a valid libtool archive"
+ test "$absdir" != "$libdir" && \
+ func_warning "\`$deplib' seems to be moved"
+
+ path="-L$absdir"
+ fi
+ ;;
+ esac
+ case " $deplibs " in
+ *" $path "*) ;;
+ *) deplibs="$path $deplibs" ;;
+ esac
+ done
+ fi # link_all_deplibs != no
+ fi # linkmode = lib
+ done # for deplib in $libs
+ if test "$pass" = link; then
+ if test "$linkmode" = "prog"; then
+ compile_deplibs="$new_inherited_linker_flags $compile_deplibs"
+ finalize_deplibs="$new_inherited_linker_flags $finalize_deplibs"
+ else
+ compiler_flags="$compiler_flags "`$ECHO "X $new_inherited_linker_flags" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'`
+ fi
+ fi
+ dependency_libs="$newdependency_libs"
+ if test "$pass" = dlpreopen; then
+ # Link the dlpreopened libraries before other libraries
+ for deplib in $save_deplibs; do
+ deplibs="$deplib $deplibs"
+ done
+ fi
+ if test "$pass" != dlopen; then
+ if test "$pass" != conv; then
+ # Make sure lib_search_path contains only unique directories.
+ lib_search_path=
+ for dir in $newlib_search_path; do
+ case "$lib_search_path " in
+ *" $dir "*) ;;
+ *) lib_search_path="$lib_search_path $dir" ;;
+ esac
+ done
+ newlib_search_path=
+ fi
+
+ if test "$linkmode,$pass" != "prog,link"; then
+ vars="deplibs"
+ else
+ vars="compile_deplibs finalize_deplibs"
+ fi
+ for var in $vars dependency_libs; do
+ # Add libraries to $var in reverse order
+ eval tmp_libs=\"\$$var\"
+ new_libs=
+ for deplib in $tmp_libs; do
+ # FIXME: Pedantically, this is the right thing to do, so
+ # that some nasty dependency loop isn't accidentally
+ # broken:
+ #new_libs="$deplib $new_libs"
+ # Pragmatically, this seems to cause very few problems in
+ # practice:
+ case $deplib in
+ -L*) new_libs="$deplib $new_libs" ;;
+ -R*) ;;
+ *)
+ # And here is the reason: when a library appears more
+ # than once as an explicit dependence of a library, or
+ # is implicitly linked in more than once by the
+ # compiler, it is considered special, and multiple
+ # occurrences thereof are not removed. Compare this
+ # with having the same library being listed as a
+ # dependency of multiple other libraries: in this case,
+ # we know (pedantically, we assume) the library does not
+ # need to be listed more than once, so we keep only the
+ # last copy. This is not always right, but it is rare
+ # enough that we require users that really mean to play
+ # such unportable linking tricks to link the library
+ # using -Wl,-lname, so that libtool does not consider it
+ # for duplicate removal.
+ case " $specialdeplibs " in
+ *" $deplib "*) new_libs="$deplib $new_libs" ;;
+ *)
+ case " $new_libs " in
+ *" $deplib "*) ;;
+ *) new_libs="$deplib $new_libs" ;;
+ esac
+ ;;
+ esac
+ ;;
+ esac
+ done
+ tmp_libs=
+ for deplib in $new_libs; do
+ case $deplib in
+ -L*)
+ case " $tmp_libs " in
+ *" $deplib "*) ;;
+ *) tmp_libs="$tmp_libs $deplib" ;;
+ esac
+ ;;
+ *) tmp_libs="$tmp_libs $deplib" ;;
+ esac
+ done
+ eval $var=\"$tmp_libs\"
+ done # for var
+ fi
+ # Last step: remove runtime libs from dependency_libs
+ # (they stay in deplibs)
+ tmp_libs=
+ for i in $dependency_libs ; do
+ case " $predeps $postdeps $compiler_lib_search_path " in
+ *" $i "*)
+ i=""
+ ;;
+ esac
+ if test -n "$i" ; then
+ tmp_libs="$tmp_libs $i"
+ fi
+ done
+ dependency_libs=$tmp_libs
+ done # for pass
+ if test "$linkmode" = prog; then
+ dlfiles="$newdlfiles"
+ fi
+ if test "$linkmode" = prog || test "$linkmode" = lib; then
+ dlprefiles="$newdlprefiles"
+ fi
+
+ case $linkmode in
+ oldlib)
+ if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
+ func_warning "\`-dlopen' is ignored for archives"
+ fi
+
+ case " $deplibs" in
+ *\ -l* | *\ -L*)
+ func_warning "\`-l' and \`-L' are ignored for archives" ;;
+ esac
+
+ test -n "$rpath" && \
+ func_warning "\`-rpath' is ignored for archives"
+
+ test -n "$xrpath" && \
+ func_warning "\`-R' is ignored for archives"
+
+ test -n "$vinfo" && \
+ func_warning "\`-version-info/-version-number' is ignored for archives"
+
+ test -n "$release" && \
+ func_warning "\`-release' is ignored for archives"
+
+ test -n "$export_symbols$export_symbols_regex" && \
+ func_warning "\`-export-symbols' is ignored for archives"
+
+ # Now set the variables for building old libraries.
+ build_libtool_libs=no
+ oldlibs="$output"
+ objs="$objs$old_deplibs"
+ ;;
+
+ lib)
+ # Make sure we only generate libraries of the form `libNAME.la'.
+ case $outputname in
+ lib*)
+ func_stripname 'lib' '.la' "$outputname"
+ name=$func_stripname_result
+ eval shared_ext=\"$shrext_cmds\"
+ eval libname=\"$libname_spec\"
+ ;;
+ *)
+ test "$module" = no && \
+ func_fatal_help "libtool library \`$output' must begin with \`lib'"
+
+ if test "$need_lib_prefix" != no; then
+ # Add the "lib" prefix for modules if required
+ func_stripname '' '.la' "$outputname"
+ name=$func_stripname_result
+ eval shared_ext=\"$shrext_cmds\"
+ eval libname=\"$libname_spec\"
+ else
+ func_stripname '' '.la' "$outputname"
+ libname=$func_stripname_result
+ fi
+ ;;
+ esac
+
+ if test -n "$objs"; then
+ if test "$deplibs_check_method" != pass_all; then
+ func_fatal_error "cannot build libtool library \`$output' from non-libtool objects on this host:$objs"
+ else
+ $ECHO
+ $ECHO "*** Warning: Linking the shared library $output against the non-libtool"
+ $ECHO "*** objects $objs is not portable!"
+ libobjs="$libobjs $objs"
+ fi
+ fi
+
+ test "$dlself" != no && \
+ func_warning "\`-dlopen self' is ignored for libtool libraries"
+
+ set dummy $rpath
+ shift
+ test "$#" -gt 1 && \
+ func_warning "ignoring multiple \`-rpath's for a libtool library"
+
+ install_libdir="$1"
+
+ oldlibs=
+ if test -z "$rpath"; then
+ if test "$build_libtool_libs" = yes; then
+ # Building a libtool convenience library.
+ # Some compilers have problems with a `.al' extension so
+ # convenience libraries should have the same extension an
+ # archive normally would.
+ oldlibs="$output_objdir/$libname.$libext $oldlibs"
+ build_libtool_libs=convenience
+ build_old_libs=yes
+ fi
+
+ test -n "$vinfo" && \
+ func_warning "\`-version-info/-version-number' is ignored for convenience libraries"
+
+ test -n "$release" && \
+ func_warning "\`-release' is ignored for convenience libraries"
+ else
+
+ # Parse the version information argument.
+ save_ifs="$IFS"; IFS=':'
+ set dummy $vinfo 0 0 0
+ shift
+ IFS="$save_ifs"
+
+ test -n "$7" && \
+ func_fatal_help "too many parameters to \`-version-info'"
+
+ # convert absolute version numbers to libtool ages
+ # this retains compatibility with .la files and attempts
+ # to make the code below a bit more comprehensible
+
+ case $vinfo_number in
+ yes)
+ number_major="$1"
+ number_minor="$2"
+ number_revision="$3"
+ #
+ # There are really only two kinds -- those that
+ # use the current revision as the major version
+ # and those that subtract age and use age as
+ # a minor version. But, then there is irix
+ # which has an extra 1 added just for fun
+ #
+ case $version_type in
+ darwin|linux|osf|windows|none)
+ func_arith $number_major + $number_minor
+ current=$func_arith_result
+ age="$number_minor"
+ revision="$number_revision"
+ ;;
+ freebsd-aout|freebsd-elf|sunos)
+ current="$number_major"
+ revision="$number_minor"
+ age="0"
+ ;;
+ irix|nonstopux)
+ func_arith $number_major + $number_minor
+ current=$func_arith_result
+ age="$number_minor"
+ revision="$number_minor"
+ lt_irix_increment=no
+ ;;
+ *)
+ func_fatal_configuration "$modename: unknown library version type \`$version_type'"
+ ;;
+ esac
+ ;;
+ no)
+ current="$1"
+ revision="$2"
+ age="$3"
+ ;;
+ esac
+
+ # Check that each of the things are valid numbers.
+ case $current in
+ 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;;
+ *)
+ func_error "CURRENT \`$current' must be a nonnegative integer"
+ func_fatal_error "\`$vinfo' is not valid version information"
+ ;;
+ esac
+
+ case $revision in
+ 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;;
+ *)
+ func_error "REVISION \`$revision' must be a nonnegative integer"
+ func_fatal_error "\`$vinfo' is not valid version information"
+ ;;
+ esac
+
+ case $age in
+ 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;;
+ *)
+ func_error "AGE \`$age' must be a nonnegative integer"
+ func_fatal_error "\`$vinfo' is not valid version information"
+ ;;
+ esac
+
+ if test "$age" -gt "$current"; then
+ func_error "AGE \`$age' is greater than the current interface number \`$current'"
+ func_fatal_error "\`$vinfo' is not valid version information"
+ fi
+
+ # Calculate the version variables.
+ major=
+ versuffix=
+ verstring=
+ case $version_type in
+ none) ;;
+
+ darwin)
+ # Like Linux, but with the current version available in
+ # verstring for coding it into the library header
+ func_arith $current - $age
+ major=.$func_arith_result
+ versuffix="$major.$age.$revision"
+ # Darwin ld doesn't like 0 for these options...
+ func_arith $current + 1
+ minor_current=$func_arith_result
+ xlcverstring="${wl}-compatibility_version ${wl}$minor_current ${wl}-current_version ${wl}$minor_current.$revision"
+ verstring="-compatibility_version $minor_current -current_version $minor_current.$revision"
+ ;;
+
+ freebsd-aout)
+ major=".$current"
+ versuffix=".$current.$revision";
+ ;;
+
+ freebsd-elf)
+ major=".$current"
+ versuffix=".$current"
+ ;;
+
+ irix | nonstopux)
+ if test "X$lt_irix_increment" = "Xno"; then
+ func_arith $current - $age
+ else
+ func_arith $current - $age + 1
+ fi
+ major=$func_arith_result
+
+ case $version_type in
+ nonstopux) verstring_prefix=nonstopux ;;
+ *) verstring_prefix=sgi ;;
+ esac
+ verstring="$verstring_prefix$major.$revision"
+
+ # Add in all the interfaces that we are compatible with.
+ loop=$revision
+ while test "$loop" -ne 0; do
+ func_arith $revision - $loop
+ iface=$func_arith_result
+ func_arith $loop - 1
+ loop=$func_arith_result
+ verstring="$verstring_prefix$major.$iface:$verstring"
+ done
+
+ # Before this point, $major must not contain `.'.
+ major=.$major
+ versuffix="$major.$revision"
+ ;;
+
+ linux)
+ func_arith $current - $age
+ major=.$func_arith_result
+ versuffix="$major.$age.$revision"
+ ;;
+
+ osf)
+ func_arith $current - $age
+ major=.$func_arith_result
+ versuffix=".$current.$age.$revision"
+ verstring="$current.$age.$revision"
+
+ # Add in all the interfaces that we are compatible with.
+ loop=$age
+ while test "$loop" -ne 0; do
+ func_arith $current - $loop
+ iface=$func_arith_result
+ func_arith $loop - 1
+ loop=$func_arith_result
+ verstring="$verstring:${iface}.0"
+ done
+
+ # Make executables depend on our current version.
+ verstring="$verstring:${current}.0"
+ ;;
+
+ qnx)
+ major=".$current"
+ versuffix=".$current"
+ ;;
+
+ sunos)
+ major=".$current"
+ versuffix=".$current.$revision"
+ ;;
+
+ windows)
+ # Use '-' rather than '.', since we only want one
+ # extension on DOS 8.3 filesystems.
+ func_arith $current - $age
+ major=$func_arith_result
+ versuffix="-$major"
+ ;;
+
+ *)
+ func_fatal_configuration "unknown library version type \`$version_type'"
+ ;;
+ esac
+
+ # Clear the version info if we defaulted, and they specified a release.
+ if test -z "$vinfo" && test -n "$release"; then
+ major=
+ case $version_type in
+ darwin)
+ # we can't check for "0.0" in archive_cmds due to quoting
+ # problems, so we reset it completely
+ verstring=
+ ;;
+ *)
+ verstring="0.0"
+ ;;
+ esac
+ if test "$need_version" = no; then
+ versuffix=
+ else
+ versuffix=".0.0"
+ fi
+ fi
+
+ # Remove version info from name if versioning should be avoided
+ if test "$avoid_version" = yes && test "$need_version" = no; then
+ major=
+ versuffix=
+ verstring=""
+ fi
+
+ # Check to see if the archive will have undefined symbols.
+ if test "$allow_undefined" = yes; then
+ if test "$allow_undefined_flag" = unsupported; then
+ func_warning "undefined symbols not allowed in $host shared libraries"
+ build_libtool_libs=no
+ build_old_libs=yes
+ fi
+ else
+ # Don't allow undefined symbols.
+ allow_undefined_flag="$no_undefined_flag"
+ fi
+
+ fi
+
+ func_generate_dlsyms "$libname" "$libname" "yes"
+ libobjs="$libobjs $symfileobj"
+ test "X$libobjs" = "X " && libobjs=
+
+ if test "$mode" != relink; then
+ # Remove our outputs, but don't remove object files since they
+ # may have been created when compiling PIC objects.
+ removelist=
+ tempremovelist=`$ECHO "$output_objdir/*"`
+ for p in $tempremovelist; do
+ case $p in
+ *.$objext | *.gcno)
+ ;;
+ $output_objdir/$outputname | $output_objdir/$libname.* | $output_objdir/${libname}${release}.*)
+ if test "X$precious_files_regex" != "X"; then
+ if $ECHO "$p" | $EGREP -e "$precious_files_regex" >/dev/null 2>&1
+ then
+ continue
+ fi
+ fi
+ removelist="$removelist $p"
+ ;;
+ *) ;;
+ esac
+ done
+ test -n "$removelist" && \
+ func_show_eval "${RM}r \$removelist"
+ fi
+
+ # Now set the variables for building old libraries.
+ if test "$build_old_libs" = yes && test "$build_libtool_libs" != convenience ; then
+ oldlibs="$oldlibs $output_objdir/$libname.$libext"
+
+ # Transform .lo files to .o files.
+ oldobjs="$objs "`$ECHO "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}'$/d' -e "$lo2o" | $NL2SP`
+ fi
+
+ # Eliminate all temporary directories.
+ #for path in $notinst_path; do
+ # lib_search_path=`$ECHO "X$lib_search_path " | $Xsed -e "s% $path % %g"`
+ # deplibs=`$ECHO "X$deplibs " | $Xsed -e "s% -L$path % %g"`
+ # dependency_libs=`$ECHO "X$dependency_libs " | $Xsed -e "s% -L$path % %g"`
+ #done
+
+ if test -n "$xrpath"; then
+ # If the user specified any rpath flags, then add them.
+ temp_xrpath=
+ for libdir in $xrpath; do
+ temp_xrpath="$temp_xrpath -R$libdir"
+ case "$finalize_rpath " in
+ *" $libdir "*) ;;
+ *) finalize_rpath="$finalize_rpath $libdir" ;;
+ esac
+ done
+ if test "$hardcode_into_libs" != yes || test "$build_old_libs" = yes; then
+ dependency_libs="$temp_xrpath $dependency_libs"
+ fi
+ fi
+
+ # Make sure dlfiles contains only unique files that won't be dlpreopened
+ old_dlfiles="$dlfiles"
+ dlfiles=
+ for lib in $old_dlfiles; do
+ case " $dlprefiles $dlfiles " in
+ *" $lib "*) ;;
+ *) dlfiles="$dlfiles $lib" ;;
+ esac
+ done
+
+ # Make sure dlprefiles contains only unique files
+ old_dlprefiles="$dlprefiles"
+ dlprefiles=
+ for lib in $old_dlprefiles; do
+ case "$dlprefiles " in
+ *" $lib "*) ;;
+ *) dlprefiles="$dlprefiles $lib" ;;
+ esac
+ done
+
+ if test "$build_libtool_libs" = yes; then
+ if test -n "$rpath"; then
+ case $host in
+ *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos* | *-cegcc*)
+ # these systems don't actually have a c library (as such)!
+ ;;
+ *-*-rhapsody* | *-*-darwin1.[012])
+ # Rhapsody C library is in the System framework
+ deplibs="$deplibs System.ltframework"
+ ;;
+ *-*-netbsd*)
+ # Don't link with libc until the a.out ld.so is fixed.
+ ;;
+ *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*)
+ # Do not include libc due to us having libc/libc_r.
+ ;;
+ *-*-sco3.2v5* | *-*-sco5v6*)
+ # Causes problems with __ctype
+ ;;
+ *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*)
+ # Compiler inserts libc in the correct place for threads to work
+ ;;
+ *)
+ # Add libc to deplibs on all other systems if necessary.
+ if test "$build_libtool_need_lc" = "yes"; then
+ deplibs="$deplibs -lc"
+ fi
+ ;;
+ esac
+ fi
+
+ # Transform deplibs into only deplibs that can be linked in shared.
+ name_save=$name
+ libname_save=$libname
+ release_save=$release
+ versuffix_save=$versuffix
+ major_save=$major
+ # I'm not sure if I'm treating the release correctly. I think
+ # release should show up in the -l (ie -lgmp5) so we don't want to
+ # add it in twice. Is that correct?
+ release=""
+ versuffix=""
+ major=""
+ newdeplibs=
+ droppeddeps=no
+ case $deplibs_check_method in
+ pass_all)
+ # Don't check for shared/static. Everything works.
+ # This might be a little naive. We might want to check
+ # whether the library exists or not. But this is on
+ # osf3 & osf4 and I'm not really sure... Just
+ # implementing what was already the behavior.
+ newdeplibs=$deplibs
+ ;;
+ test_compile)
+ # This code stresses the "libraries are programs" paradigm to its
+ # limits. Maybe even breaks it. We compile a program, linking it
+ # against the deplibs as a proxy for the library. Then we can check
+ # whether they linked in statically or dynamically with ldd.
+ $opt_dry_run || $RM conftest.c
+ cat > conftest.c <<EOF
+ int main() { return 0; }
+EOF
+ $opt_dry_run || $RM conftest
+ if $LTCC $LTCFLAGS -o conftest conftest.c $deplibs; then
+ ldd_output=`ldd conftest`
+ for i in $deplibs; do
+ case $i in
+ -l*)
+ func_stripname -l '' "$i"
+ name=$func_stripname_result
+ if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+ case " $predeps $postdeps " in
+ *" $i "*)
+ newdeplibs="$newdeplibs $i"
+ i=""
+ ;;
+ esac
+ fi
+ if test -n "$i" ; then
+ libname=`eval "\\$ECHO \"$libname_spec\""`
+ deplib_matches=`eval "\\$ECHO \"$library_names_spec\""`
+ set dummy $deplib_matches; shift
+ deplib_match=$1
+ if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0 ; then
+ newdeplibs="$newdeplibs $i"
+ else
+ droppeddeps=yes
+ $ECHO
+ $ECHO "*** Warning: dynamic linker does not accept needed library $i."
+ $ECHO "*** I have the capability to make that library automatically link in when"
+ $ECHO "*** you link to this library. But I can only do this if you have a"
+ $ECHO "*** shared version of the library, which I believe you do not have"
+ $ECHO "*** because a test_compile did reveal that the linker did not use it for"
+ $ECHO "*** its dynamic dependency list that programs get resolved with at runtime."
+ fi
+ fi
+ ;;
+ *)
+ newdeplibs="$newdeplibs $i"
+ ;;
+ esac
+ done
+ else
+ # Error occurred in the first compile. Let's try to salvage
+ # the situation: Compile a separate program for each library.
+ for i in $deplibs; do
+ case $i in
+ -l*)
+ func_stripname -l '' "$i"
+ name=$func_stripname_result
+ $opt_dry_run || $RM conftest
+ if $LTCC $LTCFLAGS -o conftest conftest.c $i; then
+ ldd_output=`ldd conftest`
+ if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+ case " $predeps $postdeps " in
+ *" $i "*)
+ newdeplibs="$newdeplibs $i"
+ i=""
+ ;;
+ esac
+ fi
+ if test -n "$i" ; then
+ libname=`eval "\\$ECHO \"$libname_spec\""`
+ deplib_matches=`eval "\\$ECHO \"$library_names_spec\""`
+ set dummy $deplib_matches; shift
+ deplib_match=$1
+ if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0 ; then
+ newdeplibs="$newdeplibs $i"
+ else
+ droppeddeps=yes
+ $ECHO
+ $ECHO "*** Warning: dynamic linker does not accept needed library $i."
+ $ECHO "*** I have the capability to make that library automatically link in when"
+ $ECHO "*** you link to this library. But I can only do this if you have a"
+ $ECHO "*** shared version of the library, which you do not appear to have"
+ $ECHO "*** because a test_compile did reveal that the linker did not use this one"
+ $ECHO "*** as a dynamic dependency that programs can get resolved with at runtime."
+ fi
+ fi
+ else
+ droppeddeps=yes
+ $ECHO
+ $ECHO "*** Warning! Library $i is needed by this library but I was not able to"
+ $ECHO "*** make it link in! You will probably need to install it or some"
+ $ECHO "*** library that it depends on before this library will be fully"
+ $ECHO "*** functional. Installing it before continuing would be even better."
+ fi
+ ;;
+ *)
+ newdeplibs="$newdeplibs $i"
+ ;;
+ esac
+ done
+ fi
+ ;;
+ file_magic*)
+ set dummy $deplibs_check_method; shift
+ file_magic_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"`
+ for a_deplib in $deplibs; do
+ case $a_deplib in
+ -l*)
+ func_stripname -l '' "$a_deplib"
+ name=$func_stripname_result
+ if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+ case " $predeps $postdeps " in
+ *" $a_deplib "*)
+ newdeplibs="$newdeplibs $a_deplib"
+ a_deplib=""
+ ;;
+ esac
+ fi
+ if test -n "$a_deplib" ; then
+ libname=`eval "\\$ECHO \"$libname_spec\""`
+ for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do
+ potential_libs=`ls $i/$libname[.-]* 2>/dev/null`
+ for potent_lib in $potential_libs; do
+ # Follow soft links.
+ if ls -lLd "$potent_lib" 2>/dev/null |
+ $GREP " -> " >/dev/null; then
+ continue
+ fi
+ # The statement above tries to avoid entering an
+ # endless loop below, in case of cyclic links.
+ # We might still enter an endless loop, since a link
+ # loop can be closed while we follow links,
+ # but so what?
+ potlib="$potent_lib"
+ while test -h "$potlib" 2>/dev/null; do
+ potliblink=`ls -ld $potlib | ${SED} 's/.* -> //'`
+ case $potliblink in
+ [\\/]* | [A-Za-z]:[\\/]*) potlib="$potliblink";;
+ *) potlib=`$ECHO "X$potlib" | $Xsed -e 's,[^/]*$,,'`"$potliblink";;
+ esac
+ done
+ if eval $file_magic_cmd \"\$potlib\" 2>/dev/null |
+ $SED -e 10q |
+ $EGREP "$file_magic_regex" > /dev/null; then
+ newdeplibs="$newdeplibs $a_deplib"
+ a_deplib=""
+ break 2
+ fi
+ done
+ done
+ fi
+ if test -n "$a_deplib" ; then
+ droppeddeps=yes
+ $ECHO
+ $ECHO "*** Warning: linker path does not have real file for library $a_deplib."
+ $ECHO "*** I have the capability to make that library automatically link in when"
+ $ECHO "*** you link to this library. But I can only do this if you have a"
+ $ECHO "*** shared version of the library, which you do not appear to have"
+ $ECHO "*** because I did check the linker path looking for a file starting"
+ if test -z "$potlib" ; then
+ $ECHO "*** with $libname but no candidates were found. (...for file magic test)"
+ else
+ $ECHO "*** with $libname and none of the candidates passed a file format test"
+ $ECHO "*** using a file magic. Last file checked: $potlib"
+ fi
+ fi
+ ;;
+ *)
+ # Add a -L argument.
+ newdeplibs="$newdeplibs $a_deplib"
+ ;;
+ esac
+ done # Gone through all deplibs.
+ ;;
+ match_pattern*)
+ set dummy $deplibs_check_method; shift
+ match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"`
+ for a_deplib in $deplibs; do
+ case $a_deplib in
+ -l*)
+ func_stripname -l '' "$a_deplib"
+ name=$func_stripname_result
+ if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+ case " $predeps $postdeps " in
+ *" $a_deplib "*)
+ newdeplibs="$newdeplibs $a_deplib"
+ a_deplib=""
+ ;;
+ esac
+ fi
+ if test -n "$a_deplib" ; then
+ libname=`eval "\\$ECHO \"$libname_spec\""`
+ for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do
+ potential_libs=`ls $i/$libname[.-]* 2>/dev/null`
+ for potent_lib in $potential_libs; do
+ potlib="$potent_lib" # see symlink-check above in file_magic test
+ if eval "\$ECHO \"X$potent_lib\"" 2>/dev/null | $Xsed -e 10q | \
+ $EGREP "$match_pattern_regex" > /dev/null; then
+ newdeplibs="$newdeplibs $a_deplib"
+ a_deplib=""
+ break 2
+ fi
+ done
+ done
+ fi
+ if test -n "$a_deplib" ; then
+ droppeddeps=yes
+ $ECHO
+ $ECHO "*** Warning: linker path does not have real file for library $a_deplib."
+ $ECHO "*** I have the capability to make that library automatically link in when"
+ $ECHO "*** you link to this library. But I can only do this if you have a"
+ $ECHO "*** shared version of the library, which you do not appear to have"
+ $ECHO "*** because I did check the linker path looking for a file starting"
+ if test -z "$potlib" ; then
+ $ECHO "*** with $libname but no candidates were found. (...for regex pattern test)"
+ else
+ $ECHO "*** with $libname and none of the candidates passed a file format test"
+ $ECHO "*** using a regex pattern. Last file checked: $potlib"
+ fi
+ fi
+ ;;
+ *)
+ # Add a -L argument.
+ newdeplibs="$newdeplibs $a_deplib"
+ ;;
+ esac
+ done # Gone through all deplibs.
+ ;;
+ none | unknown | *)
+ newdeplibs=""
+ tmp_deplibs=`$ECHO "X $deplibs" | $Xsed \
+ -e 's/ -lc$//' -e 's/ -[LR][^ ]*//g'`
+ if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+ for i in $predeps $postdeps ; do
+ # can't use Xsed below, because $i might contain '/'
+ tmp_deplibs=`$ECHO "X $tmp_deplibs" | $Xsed -e "s,$i,,"`
+ done
+ fi
+ if $ECHO "X $tmp_deplibs" | $Xsed -e 's/[ ]//g' |
+ $GREP . >/dev/null; then
+ $ECHO
+ if test "X$deplibs_check_method" = "Xnone"; then
+ $ECHO "*** Warning: inter-library dependencies are not supported in this platform."
+ else
+ $ECHO "*** Warning: inter-library dependencies are not known to be supported."
+ fi
+ $ECHO "*** All declared inter-library dependencies are being dropped."
+ droppeddeps=yes
+ fi
+ ;;
+ esac
+ versuffix=$versuffix_save
+ major=$major_save
+ release=$release_save
+ libname=$libname_save
+ name=$name_save
+
+ case $host in
+ *-*-rhapsody* | *-*-darwin1.[012])
+ # On Rhapsody replace the C library with the System framework
+ newdeplibs=`$ECHO "X $newdeplibs" | $Xsed -e 's/ -lc / System.ltframework /'`
+ ;;
+ esac
+
+ if test "$droppeddeps" = yes; then
+ if test "$module" = yes; then
+ $ECHO
+ $ECHO "*** Warning: libtool could not satisfy all declared inter-library"
+ $ECHO "*** dependencies of module $libname. Therefore, libtool will create"
+ $ECHO "*** a static module, that should work as long as the dlopening"
+ $ECHO "*** application is linked with the -dlopen flag."
+ if test -z "$global_symbol_pipe"; then
+ $ECHO
+ $ECHO "*** However, this would only work if libtool was able to extract symbol"
+ $ECHO "*** lists from a program, using \`nm' or equivalent, but libtool could"
+ $ECHO "*** not find such a program. So, this module is probably useless."
+ $ECHO "*** \`nm' from GNU binutils and a full rebuild may help."
+ fi
+ if test "$build_old_libs" = no; then
+ oldlibs="$output_objdir/$libname.$libext"
+ build_libtool_libs=module
+ build_old_libs=yes
+ else
+ build_libtool_libs=no
+ fi
+ else
+ $ECHO "*** The inter-library dependencies that have been dropped here will be"
+ $ECHO "*** automatically added whenever a program is linked with this library"
+ $ECHO "*** or is declared to -dlopen it."
+
+ if test "$allow_undefined" = no; then
+ $ECHO
+ $ECHO "*** Since this library must not contain undefined symbols,"
+ $ECHO "*** because either the platform does not support them or"
+ $ECHO "*** it was explicitly requested with -no-undefined,"
+ $ECHO "*** libtool will only create a static version of it."
+ if test "$build_old_libs" = no; then
+ oldlibs="$output_objdir/$libname.$libext"
+ build_libtool_libs=module
+ build_old_libs=yes
+ else
+ build_libtool_libs=no
+ fi
+ fi
+ fi
+ fi
+ # Done checking deplibs!
+ deplibs=$newdeplibs
+ fi
+ # Time to change all our "foo.ltframework" stuff back to "-framework foo"
+ case $host in
+ *-*-darwin*)
+ newdeplibs=`$ECHO "X $newdeplibs" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'`
+ new_inherited_linker_flags=`$ECHO "X $new_inherited_linker_flags" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'`
+ deplibs=`$ECHO "X $deplibs" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'`
+ ;;
+ esac
+
+ # move library search paths that coincide with paths to not yet
+ # installed libraries to the beginning of the library search list
+ new_libs=
+ for path in $notinst_path; do
+ case " $new_libs " in
+ *" -L$path/$objdir "*) ;;
+ *)
+ case " $deplibs " in
+ *" -L$path/$objdir "*)
+ new_libs="$new_libs -L$path/$objdir" ;;
+ esac
+ ;;
+ esac
+ done
+ for deplib in $deplibs; do
+ case $deplib in
+ -L*)
+ case " $new_libs " in
+ *" $deplib "*) ;;
+ *) new_libs="$new_libs $deplib" ;;
+ esac
+ ;;
+ *) new_libs="$new_libs $deplib" ;;
+ esac
+ done
+ deplibs="$new_libs"
+
+ # All the library-specific variables (install_libdir is set above).
+ library_names=
+ old_library=
+ dlname=
+
+ # Test again, we may have decided not to build it any more
+ if test "$build_libtool_libs" = yes; then
+ if test "$hardcode_into_libs" = yes; then
+ # Hardcode the library paths
+ hardcode_libdirs=
+ dep_rpath=
+ rpath="$finalize_rpath"
+ test "$mode" != relink && rpath="$compile_rpath$rpath"
+ for libdir in $rpath; do
+ if test -n "$hardcode_libdir_flag_spec"; then
+ if test -n "$hardcode_libdir_separator"; then
+ if test -z "$hardcode_libdirs"; then
+ hardcode_libdirs="$libdir"
+ else
+ # Just accumulate the unique libdirs.
+ case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in
+ *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
+ ;;
+ *)
+ hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir"
+ ;;
+ esac
+ fi
+ else
+ eval flag=\"$hardcode_libdir_flag_spec\"
+ dep_rpath="$dep_rpath $flag"
+ fi
+ elif test -n "$runpath_var"; then
+ case "$perm_rpath " in
+ *" $libdir "*) ;;
+ *) perm_rpath="$perm_rpath $libdir" ;;
+ esac
+ fi
+ done
+ # Substitute the hardcoded libdirs into the rpath.
+ if test -n "$hardcode_libdir_separator" &&
+ test -n "$hardcode_libdirs"; then
+ libdir="$hardcode_libdirs"
+ if test -n "$hardcode_libdir_flag_spec_ld"; then
+ eval dep_rpath=\"$hardcode_libdir_flag_spec_ld\"
+ else
+ eval dep_rpath=\"$hardcode_libdir_flag_spec\"
+ fi
+ fi
+ if test -n "$runpath_var" && test -n "$perm_rpath"; then
+ # We should set the runpath_var.
+ rpath=
+ for dir in $perm_rpath; do
+ rpath="$rpath$dir:"
+ done
+ eval "$runpath_var='$rpath\$$runpath_var'; export $runpath_var"
+ fi
+ test -n "$dep_rpath" && deplibs="$dep_rpath $deplibs"
+ fi
+
+ shlibpath="$finalize_shlibpath"
+ test "$mode" != relink && shlibpath="$compile_shlibpath$shlibpath"
+ if test -n "$shlibpath"; then
+ eval "$shlibpath_var='$shlibpath\$$shlibpath_var'; export $shlibpath_var"
+ fi
+
+ # Get the real and link names of the library.
+ eval shared_ext=\"$shrext_cmds\"
+ eval library_names=\"$library_names_spec\"
+ set dummy $library_names
+ shift
+ realname="$1"
+ shift
+
+ if test -n "$soname_spec"; then
+ eval soname=\"$soname_spec\"
+ else
+ soname="$realname"
+ fi
+ if test -z "$dlname"; then
+ dlname=$soname
+ fi
+
+ lib="$output_objdir/$realname"
+ linknames=
+ for link
+ do
+ linknames="$linknames $link"
+ done
+
+ # Use standard objects if they are pic
+ test -z "$pic_flag" && libobjs=`$ECHO "X$libobjs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP`
+ test "X$libobjs" = "X " && libobjs=
+
+ delfiles=
+ if test -n "$export_symbols" && test -n "$include_expsyms"; then
+ $opt_dry_run || cp "$export_symbols" "$output_objdir/$libname.uexp"
+ export_symbols="$output_objdir/$libname.uexp"
+ delfiles="$delfiles $export_symbols"
+ fi
+
+ orig_export_symbols=
+ case $host_os in
+ cygwin* | mingw* | cegcc*)
+ if test -n "$export_symbols" && test -z "$export_symbols_regex"; then
+ # exporting using user supplied symfile
+ if test "x`$SED 1q $export_symbols`" != xEXPORTS; then
+ # and it's NOT already a .def file. Must figure out
+ # which of the given symbols are data symbols and tag
+ # them as such. So, trigger use of export_symbols_cmds.
+ # export_symbols gets reassigned inside the "prepare
+ # the list of exported symbols" if statement, so the
+ # include_expsyms logic still works.
+ orig_export_symbols="$export_symbols"
+ export_symbols=
+ always_export_symbols=yes
+ fi
+ fi
+ ;;
+ esac
+
+ # Prepare the list of exported symbols
+ if test -z "$export_symbols"; then
+ if test "$always_export_symbols" = yes || test -n "$export_symbols_regex"; then
+ func_verbose "generating symbol list for \`$libname.la'"
+ export_symbols="$output_objdir/$libname.exp"
+ $opt_dry_run || $RM $export_symbols
+ cmds=$export_symbols_cmds
+ save_ifs="$IFS"; IFS='~'
+ for cmd in $cmds; do
+ IFS="$save_ifs"
+ eval cmd=\"$cmd\"
+ func_len " $cmd"
+ len=$func_len_result
+ if test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then
+ func_show_eval "$cmd" 'exit $?'
+ skipped_export=false
+ else
+ # The command line is too long to execute in one step.
+ func_verbose "using reloadable object file for export list..."
+ skipped_export=:
+ # Break out early, otherwise skipped_export may be
+ # set to false by a later but shorter cmd.
+ break
+ fi
+ done
+ IFS="$save_ifs"
+ if test -n "$export_symbols_regex" && test "X$skipped_export" != "X:"; then
+ func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"'
+ func_show_eval '$MV "${export_symbols}T" "$export_symbols"'
+ fi
+ fi
+ fi
+
+ if test -n "$export_symbols" && test -n "$include_expsyms"; then
+ tmp_export_symbols="$export_symbols"
+ test -n "$orig_export_symbols" && tmp_export_symbols="$orig_export_symbols"
+ $opt_dry_run || eval '$ECHO "X$include_expsyms" | $Xsed | $SP2NL >> "$tmp_export_symbols"'
+ fi
+
+ if test "X$skipped_export" != "X:" && test -n "$orig_export_symbols"; then
+ # The given exports_symbols file has to be filtered, so filter it.
+ func_verbose "filter symbol list for \`$libname.la' to tag DATA exports"
+ # FIXME: $output_objdir/$libname.filter potentially contains lots of
+ # 's' commands which not all seds can handle. GNU sed should be fine
+ # though. Also, the filter scales superlinearly with the number of
+ # global variables. join(1) would be nice here, but unfortunately
+ # isn't a blessed tool.
+ $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter
+ delfiles="$delfiles $export_symbols $output_objdir/$libname.filter"
+ export_symbols=$output_objdir/$libname.def
+ $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols
+ fi
+
+ tmp_deplibs=
+ for test_deplib in $deplibs; do
+ case " $convenience " in
+ *" $test_deplib "*) ;;
+ *)
+ tmp_deplibs="$tmp_deplibs $test_deplib"
+ ;;
+ esac
+ done
+ deplibs="$tmp_deplibs"
+
+ if test -n "$convenience"; then
+ if test -n "$whole_archive_flag_spec" &&
+ test "$compiler_needs_object" = yes &&
+ test -z "$libobjs"; then
+ # extract the archives, so we have objects to list.
+ # TODO: could optimize this to just extract one archive.
+ whole_archive_flag_spec=
+ fi
+ if test -n "$whole_archive_flag_spec"; then
+ save_libobjs=$libobjs
+ eval libobjs=\"\$libobjs $whole_archive_flag_spec\"
+ test "X$libobjs" = "X " && libobjs=
+ else
+ gentop="$output_objdir/${outputname}x"
+ generated="$generated $gentop"
+
+ func_extract_archives $gentop $convenience
+ libobjs="$libobjs $func_extract_archives_result"
+ test "X$libobjs" = "X " && libobjs=
+ fi
+ fi
+
+ if test "$thread_safe" = yes && test -n "$thread_safe_flag_spec"; then
+ eval flag=\"$thread_safe_flag_spec\"
+ linker_flags="$linker_flags $flag"
+ fi
+
+ # Make a backup of the uninstalled library when relinking
+ if test "$mode" = relink; then
+ $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}U && $MV $realname ${realname}U)' || exit $?
+ fi
+
+ # Do each of the archive commands.
+ if test "$module" = yes && test -n "$module_cmds" ; then
+ if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then
+ eval test_cmds=\"$module_expsym_cmds\"
+ cmds=$module_expsym_cmds
+ else
+ eval test_cmds=\"$module_cmds\"
+ cmds=$module_cmds
+ fi
+ else
+ if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then
+ eval test_cmds=\"$archive_expsym_cmds\"
+ cmds=$archive_expsym_cmds
+ else
+ eval test_cmds=\"$archive_cmds\"
+ cmds=$archive_cmds
+ fi
+ fi
+
+ if test "X$skipped_export" != "X:" &&
+ func_len " $test_cmds" &&
+ len=$func_len_result &&
+ test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then
+ :
+ else
+ # The command line is too long to link in one step, link piecewise
+ # or, if using GNU ld and skipped_export is not :, use a linker
+ # script.
+
+ # Save the value of $output and $libobjs because we want to
+ # use them later. If we have whole_archive_flag_spec, we
+ # want to use save_libobjs as it was before
+ # whole_archive_flag_spec was expanded, because we can't
+ # assume the linker understands whole_archive_flag_spec.
+ # This may have to be revisited, in case too many
+ # convenience libraries get linked in and end up exceeding
+ # the spec.
+ if test -z "$convenience" || test -z "$whole_archive_flag_spec"; then
+ save_libobjs=$libobjs
+ fi
+ save_output=$output
+ output_la=`$ECHO "X$output" | $Xsed -e "$basename"`
+
+ # Clear the reloadable object creation command queue and
+ # initialize k to one.
+ test_cmds=
+ concat_cmds=
+ objlist=
+ last_robj=
+ k=1
+
+ if test -n "$save_libobjs" && test "X$skipped_export" != "X:" && test "$with_gnu_ld" = yes; then
+ output=${output_objdir}/${output_la}.lnkscript
+ func_verbose "creating GNU ld script: $output"
+ $ECHO 'INPUT (' > $output
+ for obj in $save_libobjs
+ do
+ $ECHO "$obj" >> $output
+ done
+ $ECHO ')' >> $output
+ delfiles="$delfiles $output"
+ elif test -n "$save_libobjs" && test "X$skipped_export" != "X:" && test "X$file_list_spec" != X; then
+ output=${output_objdir}/${output_la}.lnk
+ func_verbose "creating linker input file list: $output"
+ : > $output
+ set x $save_libobjs
+ shift
+ firstobj=
+ if test "$compiler_needs_object" = yes; then
+ firstobj="$1 "
+ shift
+ fi
+ for obj
+ do
+ $ECHO "$obj" >> $output
+ done
+ delfiles="$delfiles $output"
+ output=$firstobj\"$file_list_spec$output\"
+ else
+ if test -n "$save_libobjs"; then
+ func_verbose "creating reloadable object files..."
+ output=$output_objdir/$output_la-${k}.$objext
+ eval test_cmds=\"$reload_cmds\"
+ func_len " $test_cmds"
+ len0=$func_len_result
+ len=$len0
+
+ # Loop over the list of objects to be linked.
+ for obj in $save_libobjs
+ do
+ func_len " $obj"
+ func_arith $len + $func_len_result
+ len=$func_arith_result
+ if test "X$objlist" = X ||
+ test "$len" -lt "$max_cmd_len"; then
+ func_append objlist " $obj"
+ else
+ # The command $test_cmds is almost too long, add a
+ # command to the queue.
+ if test "$k" -eq 1 ; then
+ # The first file doesn't have a previous command to add.
+ eval concat_cmds=\"$reload_cmds $objlist $last_robj\"
+ else
+ # All subsequent reloadable object files will link in
+ # the last one created.
+ eval concat_cmds=\"\$concat_cmds~$reload_cmds $objlist $last_robj~\$RM $last_robj\"
+ fi
+ last_robj=$output_objdir/$output_la-${k}.$objext
+ func_arith $k + 1
+ k=$func_arith_result
+ output=$output_objdir/$output_la-${k}.$objext
+ objlist=$obj
+ func_len " $last_robj"
+ func_arith $len0 + $func_len_result
+ len=$func_arith_result
+ fi
+ done
+ # Handle the remaining objects by creating one last
+ # reloadable object file. All subsequent reloadable object
+ # files will link in the last one created.
+ test -z "$concat_cmds" || concat_cmds=$concat_cmds~
+ eval concat_cmds=\"\${concat_cmds}$reload_cmds $objlist $last_robj\"
+ if test -n "$last_robj"; then
+ eval concat_cmds=\"\${concat_cmds}~\$RM $last_robj\"
+ fi
+ delfiles="$delfiles $output"
+
+ else
+ output=
+ fi
+
+ if ${skipped_export-false}; then
+ func_verbose "generating symbol list for \`$libname.la'"
+ export_symbols="$output_objdir/$libname.exp"
+ $opt_dry_run || $RM $export_symbols
+ libobjs=$output
+ # Append the command to create the export file.
+ test -z "$concat_cmds" || concat_cmds=$concat_cmds~
+ eval concat_cmds=\"\$concat_cmds$export_symbols_cmds\"
+ if test -n "$last_robj"; then
+ eval concat_cmds=\"\$concat_cmds~\$RM $last_robj\"
+ fi
+ fi
+
+ test -n "$save_libobjs" &&
+ func_verbose "creating a temporary reloadable object file: $output"
+
+ # Loop through the commands generated above and execute them.
+ save_ifs="$IFS"; IFS='~'
+ for cmd in $concat_cmds; do
+ IFS="$save_ifs"
+ $opt_silent || {
+ func_quote_for_expand "$cmd"
+ eval "func_echo $func_quote_for_expand_result"
+ }
+ $opt_dry_run || eval "$cmd" || {
+ lt_exit=$?
+
+ # Restore the uninstalled library and exit
+ if test "$mode" = relink; then
+ ( cd "$output_objdir" && \
+ $RM "${realname}T" && \
+ $MV "${realname}U" "$realname" )
+ fi
+
+ exit $lt_exit
+ }
+ done
+ IFS="$save_ifs"
+
+ if test -n "$export_symbols_regex" && ${skipped_export-false}; then
+ func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"'
+ func_show_eval '$MV "${export_symbols}T" "$export_symbols"'
+ fi
+ fi
+
+ if ${skipped_export-false}; then
+ if test -n "$export_symbols" && test -n "$include_expsyms"; then
+ tmp_export_symbols="$export_symbols"
+ test -n "$orig_export_symbols" && tmp_export_symbols="$orig_export_symbols"
+ $opt_dry_run || eval '$ECHO "X$include_expsyms" | $Xsed | $SP2NL >> "$tmp_export_symbols"'
+ fi
+
+ if test -n "$orig_export_symbols"; then
+ # The given exports_symbols file has to be filtered, so filter it.
+ func_verbose "filter symbol list for \`$libname.la' to tag DATA exports"
+ # FIXME: $output_objdir/$libname.filter potentially contains lots of
+ # 's' commands which not all seds can handle. GNU sed should be fine
+ # though. Also, the filter scales superlinearly with the number of
+ # global variables. join(1) would be nice here, but unfortunately
+ # isn't a blessed tool.
+ $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter
+ delfiles="$delfiles $export_symbols $output_objdir/$libname.filter"
+ export_symbols=$output_objdir/$libname.def
+ $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols
+ fi
+ fi
+
+ libobjs=$output
+ # Restore the value of output.
+ output=$save_output
+
+ if test -n "$convenience" && test -n "$whole_archive_flag_spec"; then
+ eval libobjs=\"\$libobjs $whole_archive_flag_spec\"
+ test "X$libobjs" = "X " && libobjs=
+ fi
+ # Expand the library linking commands again to reset the
+ # value of $libobjs for piecewise linking.
+
+ # Do each of the archive commands.
+ if test "$module" = yes && test -n "$module_cmds" ; then
+ if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then
+ cmds=$module_expsym_cmds
+ else
+ cmds=$module_cmds
+ fi
+ else
+ if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then
+ cmds=$archive_expsym_cmds
+ else
+ cmds=$archive_cmds
+ fi
+ fi
+ fi
+
+ if test -n "$delfiles"; then
+ # Append the command to remove temporary files to $cmds.
+ eval cmds=\"\$cmds~\$RM $delfiles\"
+ fi
+
+ # Add any objects from preloaded convenience libraries
+ if test -n "$dlprefiles"; then
+ gentop="$output_objdir/${outputname}x"
+ generated="$generated $gentop"
+
+ func_extract_archives $gentop $dlprefiles
+ libobjs="$libobjs $func_extract_archives_result"
+ test "X$libobjs" = "X " && libobjs=
+ fi
+
+ save_ifs="$IFS"; IFS='~'
+ for cmd in $cmds; do
+ IFS="$save_ifs"
+ eval cmd=\"$cmd\"
+ $opt_silent || {
+ func_quote_for_expand "$cmd"
+ eval "func_echo $func_quote_for_expand_result"
+ }
+ $opt_dry_run || eval "$cmd" || {
+ lt_exit=$?
+
+ # Restore the uninstalled library and exit
+ if test "$mode" = relink; then
+ ( cd "$output_objdir" && \
+ $RM "${realname}T" && \
+ $MV "${realname}U" "$realname" )
+ fi
+
+ exit $lt_exit
+ }
+ done
+ IFS="$save_ifs"
+
+ # Restore the uninstalled library and exit
+ if test "$mode" = relink; then
+ $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}T && $MV $realname ${realname}T && $MV ${realname}U $realname)' || exit $?
+
+ if test -n "$convenience"; then
+ if test -z "$whole_archive_flag_spec"; then
+ func_show_eval '${RM}r "$gentop"'
+ fi
+ fi
+
+ exit $EXIT_SUCCESS
+ fi
+
+ # Create links to the real library.
+ for linkname in $linknames; do
+ if test "$realname" != "$linkname"; then
+ func_show_eval '(cd "$output_objdir" && $RM "$linkname" && $LN_S "$realname" "$linkname")' 'exit $?'
+ fi
+ done
+
+ # If -module or -export-dynamic was specified, set the dlname.
+ if test "$module" = yes || test "$export_dynamic" = yes; then
+ # On all known operating systems, these are identical.
+ dlname="$soname"
+ fi
+ fi
+ ;;
+
+ obj)
+ if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
+ func_warning "\`-dlopen' is ignored for objects"
+ fi
+
+ case " $deplibs" in
+ *\ -l* | *\ -L*)
+ func_warning "\`-l' and \`-L' are ignored for objects" ;;
+ esac
+
+ test -n "$rpath" && \
+ func_warning "\`-rpath' is ignored for objects"
+
+ test -n "$xrpath" && \
+ func_warning "\`-R' is ignored for objects"
+
+ test -n "$vinfo" && \
+ func_warning "\`-version-info' is ignored for objects"
+
+ test -n "$release" && \
+ func_warning "\`-release' is ignored for objects"
+
+ case $output in
+ *.lo)
+ test -n "$objs$old_deplibs" && \
+ func_fatal_error "cannot build library object \`$output' from non-libtool objects"
+
+ libobj=$output
+ func_lo2o "$libobj"
+ obj=$func_lo2o_result
+ ;;
+ *)
+ libobj=
+ obj="$output"
+ ;;
+ esac
+
+ # Delete the old objects.
+ $opt_dry_run || $RM $obj $libobj
+
+ # Objects from convenience libraries. This assumes
+ # single-version convenience libraries. Whenever we create
+ # different ones for PIC/non-PIC, this we'll have to duplicate
+ # the extraction.
+ reload_conv_objs=
+ gentop=
+ # reload_cmds runs $LD directly, so let us get rid of
+ # -Wl from whole_archive_flag_spec and hope we can get by with
+ # turning comma into space..
+ wl=
+
+ if test -n "$convenience"; then
+ if test -n "$whole_archive_flag_spec"; then
+ eval tmp_whole_archive_flags=\"$whole_archive_flag_spec\"
+ reload_conv_objs=$reload_objs\ `$ECHO "X$tmp_whole_archive_flags" | $Xsed -e 's|,| |g'`
+ else
+ gentop="$output_objdir/${obj}x"
+ generated="$generated $gentop"
+
+ func_extract_archives $gentop $convenience
+ reload_conv_objs="$reload_objs $func_extract_archives_result"
+ fi
+ fi
+
+ # Create the old-style object.
+ reload_objs="$objs$old_deplibs "`$ECHO "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}$'/d' -e '/\.lib$/d' -e "$lo2o" | $NL2SP`" $reload_conv_objs" ### testsuite: skip nested quoting test
+
+ output="$obj"
+ func_execute_cmds "$reload_cmds" 'exit $?'
+
+ # Exit if we aren't doing a library object file.
+ if test -z "$libobj"; then
+ if test -n "$gentop"; then
+ func_show_eval '${RM}r "$gentop"'
+ fi
+
+ exit $EXIT_SUCCESS
+ fi
+
+ if test "$build_libtool_libs" != yes; then
+ if test -n "$gentop"; then
+ func_show_eval '${RM}r "$gentop"'
+ fi
+
+ # Create an invalid libtool object if no PIC, so that we don't
+ # accidentally link it into a program.
+ # $show "echo timestamp > $libobj"
+ # $opt_dry_run || eval "echo timestamp > $libobj" || exit $?
+ exit $EXIT_SUCCESS
+ fi
+
+ if test -n "$pic_flag" || test "$pic_mode" != default; then
+ # Only do commands if we really have different PIC objects.
+ reload_objs="$libobjs $reload_conv_objs"
+ output="$libobj"
+ func_execute_cmds "$reload_cmds" 'exit $?'
+ fi
+
+ if test -n "$gentop"; then
+ func_show_eval '${RM}r "$gentop"'
+ fi
+
+ exit $EXIT_SUCCESS
+ ;;
+
+ prog)
+ case $host in
+ *cygwin*) func_stripname '' '.exe' "$output"
+ output=$func_stripname_result.exe;;
+ esac
+ test -n "$vinfo" && \
+ func_warning "\`-version-info' is ignored for programs"
+
+ test -n "$release" && \
+ func_warning "\`-release' is ignored for programs"
+
+ test "$preload" = yes \
+ && test "$dlopen_support" = unknown \
+ && test "$dlopen_self" = unknown \
+ && test "$dlopen_self_static" = unknown && \
+ func_warning "\`LT_INIT([dlopen])' not used. Assuming no dlopen support."
+
+ case $host in
+ *-*-rhapsody* | *-*-darwin1.[012])
+ # On Rhapsody replace the C library is the System framework
+ compile_deplibs=`$ECHO "X $compile_deplibs" | $Xsed -e 's/ -lc / System.ltframework /'`
+ finalize_deplibs=`$ECHO "X $finalize_deplibs" | $Xsed -e 's/ -lc / System.ltframework /'`
+ ;;
+ esac
+
+ case $host in
+ *-*-darwin*)
+ # Don't allow lazy linking, it breaks C++ global constructors
+ # But is supposedly fixed on 10.4 or later (yay!).
+ if test "$tagname" = CXX ; then
+ case ${MACOSX_DEPLOYMENT_TARGET-10.0} in
+ 10.[0123])
+ compile_command="$compile_command ${wl}-bind_at_load"
+ finalize_command="$finalize_command ${wl}-bind_at_load"
+ ;;
+ esac
+ fi
+ # Time to change all our "foo.ltframework" stuff back to "-framework foo"
+ compile_deplibs=`$ECHO "X $compile_deplibs" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'`
+ finalize_deplibs=`$ECHO "X $finalize_deplibs" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'`
+ ;;
+ esac
+
+
+ # move library search paths that coincide with paths to not yet
+ # installed libraries to the beginning of the library search list
+ new_libs=
+ for path in $notinst_path; do
+ case " $new_libs " in
+ *" -L$path/$objdir "*) ;;
+ *)
+ case " $compile_deplibs " in
+ *" -L$path/$objdir "*)
+ new_libs="$new_libs -L$path/$objdir" ;;
+ esac
+ ;;
+ esac
+ done
+ for deplib in $compile_deplibs; do
+ case $deplib in
+ -L*)
+ case " $new_libs " in
+ *" $deplib "*) ;;
+ *) new_libs="$new_libs $deplib" ;;
+ esac
+ ;;
+ *) new_libs="$new_libs $deplib" ;;
+ esac
+ done
+ compile_deplibs="$new_libs"
+
+
+ compile_command="$compile_command $compile_deplibs"
+ finalize_command="$finalize_command $finalize_deplibs"
+
+ if test -n "$rpath$xrpath"; then
+ # If the user specified any rpath flags, then add them.
+ for libdir in $rpath $xrpath; do
+ # This is the magic to use -rpath.
+ case "$finalize_rpath " in
+ *" $libdir "*) ;;
+ *) finalize_rpath="$finalize_rpath $libdir" ;;
+ esac
+ done
+ fi
+
+ # Now hardcode the library paths
+ rpath=
+ hardcode_libdirs=
+ for libdir in $compile_rpath $finalize_rpath; do
+ if test -n "$hardcode_libdir_flag_spec"; then
+ if test -n "$hardcode_libdir_separator"; then
+ if test -z "$hardcode_libdirs"; then
+ hardcode_libdirs="$libdir"
+ else
+ # Just accumulate the unique libdirs.
+ case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in
+ *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
+ ;;
+ *)
+ hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir"
+ ;;
+ esac
+ fi
+ else
+ eval flag=\"$hardcode_libdir_flag_spec\"
+ rpath="$rpath $flag"
+ fi
+ elif test -n "$runpath_var"; then
+ case "$perm_rpath " in
+ *" $libdir "*) ;;
+ *) perm_rpath="$perm_rpath $libdir" ;;
+ esac
+ fi
+ case $host in
+ *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*)
+ testbindir=`${ECHO} "$libdir" | ${SED} -e 's*/lib$*/bin*'`
+ case :$dllsearchpath: in
+ *":$libdir:"*) ;;
+ ::) dllsearchpath=$libdir;;
+ *) dllsearchpath="$dllsearchpath:$libdir";;
+ esac
+ case :$dllsearchpath: in
+ *":$testbindir:"*) ;;
+ ::) dllsearchpath=$testbindir;;
+ *) dllsearchpath="$dllsearchpath:$testbindir";;
+ esac
+ ;;
+ esac
+ done
+ # Substitute the hardcoded libdirs into the rpath.
+ if test -n "$hardcode_libdir_separator" &&
+ test -n "$hardcode_libdirs"; then
+ libdir="$hardcode_libdirs"
+ eval rpath=\" $hardcode_libdir_flag_spec\"
+ fi
+ compile_rpath="$rpath"
+
+ rpath=
+ hardcode_libdirs=
+ for libdir in $finalize_rpath; do
+ if test -n "$hardcode_libdir_flag_spec"; then
+ if test -n "$hardcode_libdir_separator"; then
+ if test -z "$hardcode_libdirs"; then
+ hardcode_libdirs="$libdir"
+ else
+ # Just accumulate the unique libdirs.
+ case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in
+ *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
+ ;;
+ *)
+ hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir"
+ ;;
+ esac
+ fi
+ else
+ eval flag=\"$hardcode_libdir_flag_spec\"
+ rpath="$rpath $flag"
+ fi
+ elif test -n "$runpath_var"; then
+ case "$finalize_perm_rpath " in
+ *" $libdir "*) ;;
+ *) finalize_perm_rpath="$finalize_perm_rpath $libdir" ;;
+ esac
+ fi
+ done
+ # Substitute the hardcoded libdirs into the rpath.
+ if test -n "$hardcode_libdir_separator" &&
+ test -n "$hardcode_libdirs"; then
+ libdir="$hardcode_libdirs"
+ eval rpath=\" $hardcode_libdir_flag_spec\"
+ fi
+ finalize_rpath="$rpath"
+
+ if test -n "$libobjs" && test "$build_old_libs" = yes; then
+ # Transform all the library objects into standard objects.
+ compile_command=`$ECHO "X$compile_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP`
+ finalize_command=`$ECHO "X$finalize_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP`
+ fi
+
+ func_generate_dlsyms "$outputname" "@PROGRAM@" "no"
+
+ # template prelinking step
+ if test -n "$prelink_cmds"; then
+ func_execute_cmds "$prelink_cmds" 'exit $?'
+ fi
+
+ wrappers_required=yes
+ case $host in
+ *cygwin* | *mingw* )
+ if test "$build_libtool_libs" != yes; then
+ wrappers_required=no
+ fi
+ ;;
+ *cegcc)
+ # Disable wrappers for cegcc, we are cross compiling anyway.
+ wrappers_required=no
+ ;;
+ *)
+ if test "$need_relink" = no || test "$build_libtool_libs" != yes; then
+ wrappers_required=no
+ fi
+ ;;
+ esac
+ if test "$wrappers_required" = no; then
+ # Replace the output file specification.
+ compile_command=`$ECHO "X$compile_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'`
+ link_command="$compile_command$compile_rpath"
+
+ # We have no uninstalled library dependencies, so finalize right now.
+ exit_status=0
+ func_show_eval "$link_command" 'exit_status=$?'
+
+ # Delete the generated files.
+ if test -f "$output_objdir/${outputname}S.${objext}"; then
+ func_show_eval '$RM "$output_objdir/${outputname}S.${objext}"'
+ fi
+
+ exit $exit_status
+ fi
+
+ if test -n "$compile_shlibpath$finalize_shlibpath"; then
+ compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command"
+ fi
+ if test -n "$finalize_shlibpath"; then
+ finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command"
+ fi
+
+ compile_var=
+ finalize_var=
+ if test -n "$runpath_var"; then
+ if test -n "$perm_rpath"; then
+ # We should set the runpath_var.
+ rpath=
+ for dir in $perm_rpath; do
+ rpath="$rpath$dir:"
+ done
+ compile_var="$runpath_var=\"$rpath\$$runpath_var\" "
+ fi
+ if test -n "$finalize_perm_rpath"; then
+ # We should set the runpath_var.
+ rpath=
+ for dir in $finalize_perm_rpath; do
+ rpath="$rpath$dir:"
+ done
+ finalize_var="$runpath_var=\"$rpath\$$runpath_var\" "
+ fi
+ fi
+
+ if test "$no_install" = yes; then
+ # We don't need to create a wrapper script.
+ link_command="$compile_var$compile_command$compile_rpath"
+ # Replace the output file specification.
+ link_command=`$ECHO "X$link_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'`
+ # Delete the old output file.
+ $opt_dry_run || $RM $output
+ # Link the executable and exit
+ func_show_eval "$link_command" 'exit $?'
+ exit $EXIT_SUCCESS
+ fi
+
+ if test "$hardcode_action" = relink; then
+ # Fast installation is not supported
+ link_command="$compile_var$compile_command$compile_rpath"
+ relink_command="$finalize_var$finalize_command$finalize_rpath"
+
+ func_warning "this platform does not like uninstalled shared libraries"
+ func_warning "\`$output' will be relinked during installation"
+ else
+ if test "$fast_install" != no; then
+ link_command="$finalize_var$compile_command$finalize_rpath"
+ if test "$fast_install" = yes; then
+ relink_command=`$ECHO "X$compile_var$compile_command$compile_rpath" | $Xsed -e 's%@OUTPUT@%\$progdir/\$file%g'`
+ else
+ # fast_install is set to needless
+ relink_command=
+ fi
+ else
+ link_command="$compile_var$compile_command$compile_rpath"
+ relink_command="$finalize_var$finalize_command$finalize_rpath"
+ fi
+ fi
+
+ # Replace the output file specification.
+ link_command=`$ECHO "X$link_command" | $Xsed -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'`
+
+ # Delete the old output files.
+ $opt_dry_run || $RM $output $output_objdir/$outputname $output_objdir/lt-$outputname
+
+ func_show_eval "$link_command" 'exit $?'
+
+ # Now create the wrapper script.
+ func_verbose "creating $output"
+
+ # Quote the relink command for shipping.
+ if test -n "$relink_command"; then
+ # Preserve any variables that may affect compiler behavior
+ for var in $variables_saved_for_relink; do
+ if eval test -z \"\${$var+set}\"; then
+ relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command"
+ elif eval var_value=\$$var; test -z "$var_value"; then
+ relink_command="$var=; export $var; $relink_command"
+ else
+ func_quote_for_eval "$var_value"
+ relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command"
+ fi
+ done
+ relink_command="(cd `pwd`; $relink_command)"
+ relink_command=`$ECHO "X$relink_command" | $Xsed -e "$sed_quote_subst"`
+ fi
+
+ # Quote $ECHO for shipping.
+ if test "X$ECHO" = "X$SHELL $progpath --fallback-echo"; then
+ case $progpath in
+ [\\/]* | [A-Za-z]:[\\/]*) qecho="$SHELL $progpath --fallback-echo";;
+ *) qecho="$SHELL `pwd`/$progpath --fallback-echo";;
+ esac
+ qecho=`$ECHO "X$qecho" | $Xsed -e "$sed_quote_subst"`
+ else
+ qecho=`$ECHO "X$ECHO" | $Xsed -e "$sed_quote_subst"`
+ fi
+
+ # Only actually do things if not in dry run mode.
+ $opt_dry_run || {
+ # win32 will think the script is a binary if it has
+ # a .exe suffix, so we strip it off here.
+ case $output in
+ *.exe) func_stripname '' '.exe' "$output"
+ output=$func_stripname_result ;;
+ esac
+ # test for cygwin because mv fails w/o .exe extensions
+ case $host in
+ *cygwin*)
+ exeext=.exe
+ func_stripname '' '.exe' "$outputname"
+ outputname=$func_stripname_result ;;
+ *) exeext= ;;
+ esac
+ case $host in
+ *cygwin* | *mingw* )
+ func_dirname_and_basename "$output" "" "."
+ output_name=$func_basename_result
+ output_path=$func_dirname_result
+ cwrappersource="$output_path/$objdir/lt-$output_name.c"
+ cwrapper="$output_path/$output_name.exe"
+ $RM $cwrappersource $cwrapper
+ trap "$RM $cwrappersource $cwrapper; exit $EXIT_FAILURE" 1 2 15
+
+ func_emit_cwrapperexe_src > $cwrappersource
+
+ # The wrapper executable is built using the $host compiler,
+ # because it contains $host paths and files. If cross-
+ # compiling, it, like the target executable, must be
+ # executed on the $host or under an emulation environment.
+ $opt_dry_run || {
+ $LTCC $LTCFLAGS -o $cwrapper $cwrappersource
+ $STRIP $cwrapper
+ }
+
+ # Now, create the wrapper script for func_source use:
+ func_ltwrapper_scriptname $cwrapper
+ $RM $func_ltwrapper_scriptname_result
+ trap "$RM $func_ltwrapper_scriptname_result; exit $EXIT_FAILURE" 1 2 15
+ $opt_dry_run || {
+ # note: this script will not be executed, so do not chmod.
+ if test "x$build" = "x$host" ; then
+ $cwrapper --lt-dump-script > $func_ltwrapper_scriptname_result
+ else
+ func_emit_wrapper no > $func_ltwrapper_scriptname_result
+ fi
+ }
+ ;;
+ * )
+ $RM $output
+ trap "$RM $output; exit $EXIT_FAILURE" 1 2 15
+
+ func_emit_wrapper no > $output
+ chmod +x $output
+ ;;
+ esac
+ }
+ exit $EXIT_SUCCESS
+ ;;
+ esac
+
+ # See if we need to build an old-fashioned archive.
+ for oldlib in $oldlibs; do
+
+ if test "$build_libtool_libs" = convenience; then
+ oldobjs="$libobjs_save $symfileobj"
+ addlibs="$convenience"
+ build_libtool_libs=no
+ else
+ if test "$build_libtool_libs" = module; then
+ oldobjs="$libobjs_save"
+ build_libtool_libs=no
+ else
+ oldobjs="$old_deplibs $non_pic_objects"
+ if test "$preload" = yes && test -f "$symfileobj"; then
+ oldobjs="$oldobjs $symfileobj"
+ fi
+ fi
+ addlibs="$old_convenience"
+ fi
+
+ if test -n "$addlibs"; then
+ gentop="$output_objdir/${outputname}x"
+ generated="$generated $gentop"
+
+ func_extract_archives $gentop $addlibs
+ oldobjs="$oldobjs $func_extract_archives_result"
+ fi
+
+ # Do each command in the archive commands.
+ if test -n "$old_archive_from_new_cmds" && test "$build_libtool_libs" = yes; then
+ cmds=$old_archive_from_new_cmds
+ else
+
+ # Add any objects from preloaded convenience libraries
+ if test -n "$dlprefiles"; then
+ gentop="$output_objdir/${outputname}x"
+ generated="$generated $gentop"
+
+ func_extract_archives $gentop $dlprefiles
+ oldobjs="$oldobjs $func_extract_archives_result"
+ fi
+
+ # POSIX demands no paths to be encoded in archives. We have
+ # to avoid creating archives with duplicate basenames if we
+ # might have to extract them afterwards, e.g., when creating a
+ # static archive out of a convenience library, or when linking
+ # the entirety of a libtool archive into another (currently
+ # not supported by libtool).
+ if (for obj in $oldobjs
+ do
+ func_basename "$obj"
+ $ECHO "$func_basename_result"
+ done | sort | sort -uc >/dev/null 2>&1); then
+ :
+ else
+ $ECHO "copying selected object files to avoid basename conflicts..."
+ gentop="$output_objdir/${outputname}x"
+ generated="$generated $gentop"
+ func_mkdir_p "$gentop"
+ save_oldobjs=$oldobjs
+ oldobjs=
+ counter=1
+ for obj in $save_oldobjs
+ do
+ func_basename "$obj"
+ objbase="$func_basename_result"
+ case " $oldobjs " in
+ " ") oldobjs=$obj ;;
+ *[\ /]"$objbase "*)
+ while :; do
+ # Make sure we don't pick an alternate name that also
+ # overlaps.
+ newobj=lt$counter-$objbase
+ func_arith $counter + 1
+ counter=$func_arith_result
+ case " $oldobjs " in
+ *[\ /]"$newobj "*) ;;
+ *) if test ! -f "$gentop/$newobj"; then break; fi ;;
+ esac
+ done
+ func_show_eval "ln $obj $gentop/$newobj || cp $obj $gentop/$newobj"
+ oldobjs="$oldobjs $gentop/$newobj"
+ ;;
+ *) oldobjs="$oldobjs $obj" ;;
+ esac
+ done
+ fi
+ eval cmds=\"$old_archive_cmds\"
+
+ func_len " $cmds"
+ len=$func_len_result
+ if test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then
+ cmds=$old_archive_cmds
+ else
+ # the command line is too long to link in one step, link in parts
+ func_verbose "using piecewise archive linking..."
+ save_RANLIB=$RANLIB
+ RANLIB=:
+ objlist=
+ concat_cmds=
+ save_oldobjs=$oldobjs
+ oldobjs=
+ # Is there a better way of finding the last object in the list?
+ for obj in $save_oldobjs
+ do
+ last_oldobj=$obj
+ done
+ eval test_cmds=\"$old_archive_cmds\"
+ func_len " $test_cmds"
+ len0=$func_len_result
+ len=$len0
+ for obj in $save_oldobjs
+ do
+ func_len " $obj"
+ func_arith $len + $func_len_result
+ len=$func_arith_result
+ func_append objlist " $obj"
+ if test "$len" -lt "$max_cmd_len"; then
+ :
+ else
+ # the above command should be used before it gets too long
+ oldobjs=$objlist
+ if test "$obj" = "$last_oldobj" ; then
+ RANLIB=$save_RANLIB
+ fi
+ test -z "$concat_cmds" || concat_cmds=$concat_cmds~
+ eval concat_cmds=\"\${concat_cmds}$old_archive_cmds\"
+ objlist=
+ len=$len0
+ fi
+ done
+ RANLIB=$save_RANLIB
+ oldobjs=$objlist
+ if test "X$oldobjs" = "X" ; then
+ eval cmds=\"\$concat_cmds\"
+ else
+ eval cmds=\"\$concat_cmds~\$old_archive_cmds\"
+ fi
+ fi
+ fi
+ func_execute_cmds "$cmds" 'exit $?'
+ done
+
+ test -n "$generated" && \
+ func_show_eval "${RM}r$generated"
+
+ # Now create the libtool archive.
+ case $output in
+ *.la)
+ old_library=
+ test "$build_old_libs" = yes && old_library="$libname.$libext"
+ func_verbose "creating $output"
+
+ # Preserve any variables that may affect compiler behavior
+ for var in $variables_saved_for_relink; do
+ if eval test -z \"\${$var+set}\"; then
+ relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command"
+ elif eval var_value=\$$var; test -z "$var_value"; then
+ relink_command="$var=; export $var; $relink_command"
+ else
+ func_quote_for_eval "$var_value"
+ relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command"
+ fi
+ done
+ # Quote the link command for shipping.
+ relink_command="(cd `pwd`; $SHELL $progpath $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)"
+ relink_command=`$ECHO "X$relink_command" | $Xsed -e "$sed_quote_subst"`
+ if test "$hardcode_automatic" = yes ; then
+ relink_command=
+ fi
+
+ # Only create the output if not a dry run.
+ $opt_dry_run || {
+ for installed in no yes; do
+ if test "$installed" = yes; then
+ if test -z "$install_libdir"; then
+ break
+ fi
+ output="$output_objdir/$outputname"i
+ # Replace all uninstalled libtool libraries with the installed ones
+ newdependency_libs=
+ for deplib in $dependency_libs; do
+ case $deplib in
+ *.la)
+ func_basename "$deplib"
+ name="$func_basename_result"
+ eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib`
+ test -z "$libdir" && \
+ func_fatal_error "\`$deplib' is not a valid libtool archive"
+ newdependency_libs="$newdependency_libs $libdir/$name"
+ ;;
+ *) newdependency_libs="$newdependency_libs $deplib" ;;
+ esac
+ done
+ dependency_libs="$newdependency_libs"
+ newdlfiles=
+
+ for lib in $dlfiles; do
+ case $lib in
+ *.la)
+ func_basename "$lib"
+ name="$func_basename_result"
+ eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib`
+ test -z "$libdir" && \
+ func_fatal_error "\`$lib' is not a valid libtool archive"
+ newdlfiles="$newdlfiles $libdir/$name"
+ ;;
+ *) newdlfiles="$newdlfiles $lib" ;;
+ esac
+ done
+ dlfiles="$newdlfiles"
+ newdlprefiles=
+ for lib in $dlprefiles; do
+ case $lib in
+ *.la)
+ # Only pass preopened files to the pseudo-archive (for
+ # eventual linking with the app. that links it) if we
+ # didn't already link the preopened objects directly into
+ # the library:
+ func_basename "$lib"
+ name="$func_basename_result"
+ eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib`
+ test -z "$libdir" && \
+ func_fatal_error "\`$lib' is not a valid libtool archive"
+ newdlprefiles="$newdlprefiles $libdir/$name"
+ ;;
+ esac
+ done
+ dlprefiles="$newdlprefiles"
+ else
+ newdlfiles=
+ for lib in $dlfiles; do
+ case $lib in
+ [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;;
+ *) abs=`pwd`"/$lib" ;;
+ esac
+ newdlfiles="$newdlfiles $abs"
+ done
+ dlfiles="$newdlfiles"
+ newdlprefiles=
+ for lib in $dlprefiles; do
+ case $lib in
+ [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;;
+ *) abs=`pwd`"/$lib" ;;
+ esac
+ newdlprefiles="$newdlprefiles $abs"
+ done
+ dlprefiles="$newdlprefiles"
+ fi
+ $RM $output
+ # place dlname in correct position for cygwin
+ tdlname=$dlname
+ case $host,$output,$installed,$module,$dlname in
+ *cygwin*,*lai,yes,no,*.dll | *mingw*,*lai,yes,no,*.dll | *cegcc*,*lai,yes,no,*.dll) tdlname=../bin/$dlname ;;
+ esac
+ $ECHO > $output "\
+# $outputname - a libtool library file
+# Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION
+#
+# Please DO NOT delete this file!
+# It is necessary for linking the library.
+
+# The name that we can dlopen(3).
+dlname='$tdlname'
+
+# Names of this library.
+library_names='$library_names'
+
+# The name of the static archive.
+old_library='$old_library'
+
+# Linker flags that can not go in dependency_libs.
+inherited_linker_flags='$new_inherited_linker_flags'
+
+# Libraries that this one depends upon.
+dependency_libs='$dependency_libs'
+
+# Names of additional weak libraries provided by this library
+weak_library_names='$weak_libs'
+
+# Version information for $libname.
+current=$current
+age=$age
+revision=$revision
+
+# Is this an already installed library?
+installed=$installed
+
+# Should we warn about portability when linking against -modules?
+shouldnotlink=$module
+
+# Files to dlopen/dlpreopen
+dlopen='$dlfiles'
+dlpreopen='$dlprefiles'
+
+# Directory that this library needs to be installed in:
+libdir='$install_libdir'"
+ if test "$installed" = no && test "$need_relink" = yes; then
+ $ECHO >> $output "\
+relink_command=\"$relink_command\""
+ fi
+ done
+ }
+
+ # Do a symbolic link so that the libtool archive can be found in
+ # LD_LIBRARY_PATH before the program is installed.
+ func_show_eval '( cd "$output_objdir" && $RM "$outputname" && $LN_S "../$outputname" "$outputname" )' 'exit $?'
+ ;;
+ esac
+ exit $EXIT_SUCCESS
+}
+
+{ test "$mode" = link || test "$mode" = relink; } &&
+ func_mode_link ${1+"$@"}
+
+
+# func_mode_uninstall arg...
+func_mode_uninstall ()
+{
+ $opt_debug
+ RM="$nonopt"
+ files=
+ rmforce=
+ exit_status=0
+
+ # This variable tells wrapper scripts just to set variables rather
+ # than running their programs.
+ libtool_install_magic="$magic"
+
+ for arg
+ do
+ case $arg in
+ -f) RM="$RM $arg"; rmforce=yes ;;
+ -*) RM="$RM $arg" ;;
+ *) files="$files $arg" ;;
+ esac
+ done
+
+ test -z "$RM" && \
+ func_fatal_help "you must specify an RM program"
+
+ rmdirs=
+
+ origobjdir="$objdir"
+ for file in $files; do
+ func_dirname "$file" "" "."
+ dir="$func_dirname_result"
+ if test "X$dir" = X.; then
+ objdir="$origobjdir"
+ else
+ objdir="$dir/$origobjdir"
+ fi
+ func_basename "$file"
+ name="$func_basename_result"
+ test "$mode" = uninstall && objdir="$dir"
+
+ # Remember objdir for removal later, being careful to avoid duplicates
+ if test "$mode" = clean; then
+ case " $rmdirs " in
+ *" $objdir "*) ;;
+ *) rmdirs="$rmdirs $objdir" ;;
+ esac
+ fi
+
+ # Don't error if the file doesn't exist and rm -f was used.
+ if { test -L "$file"; } >/dev/null 2>&1 ||
+ { test -h "$file"; } >/dev/null 2>&1 ||
+ test -f "$file"; then
+ :
+ elif test -d "$file"; then
+ exit_status=1
+ continue
+ elif test "$rmforce" = yes; then
+ continue
+ fi
+
+ rmfiles="$file"
+
+ case $name in
+ *.la)
+ # Possibly a libtool archive, so verify it.
+ if func_lalib_p "$file"; then
+ func_source $dir/$name
+
+ # Delete the libtool libraries and symlinks.
+ for n in $library_names; do
+ rmfiles="$rmfiles $objdir/$n"
+ done
+ test -n "$old_library" && rmfiles="$rmfiles $objdir/$old_library"
+
+ case "$mode" in
+ clean)
+ case " $library_names " in
+ # " " in the beginning catches empty $dlname
+ *" $dlname "*) ;;
+ *) rmfiles="$rmfiles $objdir/$dlname" ;;
+ esac
+ test -n "$libdir" && rmfiles="$rmfiles $objdir/$name $objdir/${name}i"
+ ;;
+ uninstall)
+ if test -n "$library_names"; then
+ # Do each command in the postuninstall commands.
+ func_execute_cmds "$postuninstall_cmds" 'test "$rmforce" = yes || exit_status=1'
+ fi
+
+ if test -n "$old_library"; then
+ # Do each command in the old_postuninstall commands.
+ func_execute_cmds "$old_postuninstall_cmds" 'test "$rmforce" = yes || exit_status=1'
+ fi
+ # FIXME: should reinstall the best remaining shared library.
+ ;;
+ esac
+ fi
+ ;;
+
+ *.lo)
+ # Possibly a libtool object, so verify it.
+ if func_lalib_p "$file"; then
+
+ # Read the .lo file
+ func_source $dir/$name
+
+ # Add PIC object to the list of files to remove.
+ if test -n "$pic_object" &&
+ test "$pic_object" != none; then
+ rmfiles="$rmfiles $dir/$pic_object"
+ fi
+
+ # Add non-PIC object to the list of files to remove.
+ if test -n "$non_pic_object" &&
+ test "$non_pic_object" != none; then
+ rmfiles="$rmfiles $dir/$non_pic_object"
+ fi
+ fi
+ ;;
+
+ *)
+ if test "$mode" = clean ; then
+ noexename=$name
+ case $file in
+ *.exe)
+ func_stripname '' '.exe' "$file"
+ file=$func_stripname_result
+ func_stripname '' '.exe' "$name"
+ noexename=$func_stripname_result
+ # $file with .exe has already been added to rmfiles,
+ # add $file without .exe
+ rmfiles="$rmfiles $file"
+ ;;
+ esac
+ # Do a test to see if this is a libtool program.
+ if func_ltwrapper_p "$file"; then
+ if func_ltwrapper_executable_p "$file"; then
+ func_ltwrapper_scriptname "$file"
+ relink_command=
+ func_source $func_ltwrapper_scriptname_result
+ rmfiles="$rmfiles $func_ltwrapper_scriptname_result"
+ else
+ relink_command=
+ func_source $dir/$noexename
+ fi
+
+ # note $name still contains .exe if it was in $file originally
+ # as does the version of $file that was added into $rmfiles
+ rmfiles="$rmfiles $objdir/$name $objdir/${name}S.${objext}"
+ if test "$fast_install" = yes && test -n "$relink_command"; then
+ rmfiles="$rmfiles $objdir/lt-$name"
+ fi
+ if test "X$noexename" != "X$name" ; then
+ rmfiles="$rmfiles $objdir/lt-${noexename}.c"
+ fi
+ fi
+ fi
+ ;;
+ esac
+ func_show_eval "$RM $rmfiles" 'exit_status=1'
+ done
+ objdir="$origobjdir"
+
+ # Try to remove the ${objdir}s in the directories where we deleted files
+ for dir in $rmdirs; do
+ if test -d "$dir"; then
+ func_show_eval "rmdir $dir >/dev/null 2>&1"
+ fi
+ done
+
+ exit $exit_status
+}
+
+{ test "$mode" = uninstall || test "$mode" = clean; } &&
+ func_mode_uninstall ${1+"$@"}
+
+test -z "$mode" && {
+ help="$generic_help"
+ func_fatal_help "you must specify a MODE"
+}
+
+test -z "$exec_cmd" && \
+ func_fatal_help "invalid operation mode \`$mode'"
+
+if test -n "$exec_cmd"; then
+ eval exec "$exec_cmd"
+ exit $EXIT_FAILURE
+fi
+
+exit $exit_status
+
+
+# The TAGs below are defined such that we never get into a situation
+# in which we disable both kinds of libraries. Given conflicting
+# choices, we go for a static library, that is the most portable,
+# since we can't tell whether shared libraries were disabled because
+# the user asked for that or because the platform doesn't support
+# them. This is particularly important on AIX, because we don't
+# support having both static and shared libraries enabled at the same
+# time on that platform, so we default to a shared-only configuration.
+# If a disable-shared tag is given, we'll fallback to a static-only
+# configuration. But we'll never go from static-only to shared-only.
+
+# ### BEGIN LIBTOOL TAG CONFIG: disable-shared
+build_libtool_libs=no
+build_old_libs=yes
+# ### END LIBTOOL TAG CONFIG: disable-shared
+
+# ### BEGIN LIBTOOL TAG CONFIG: disable-static
+build_old_libs=`case $build_libtool_libs in yes) echo no;; *) echo yes;; esac`
+# ### END LIBTOOL TAG CONFIG: disable-static
+
+# Local Variables:
+# mode:shell-script
+# sh-indentation:2
+# End:
+# vi:sw=2
+
+
+# ### BEGIN LIBTOOL TAG CONFIG: CXX
+
+# The linker used to build libraries.
+LD="/usr/llvm-gcc-4.2/libexec/gcc/i686-apple-darwin11/4.2.1/ld"
+
+# Commands used to build an old-style archive.
+old_archive_cmds="\$AR \$AR_FLAGS \$oldlib\$oldobjs~\$RANLIB \$oldlib"
+
+# A language specific compiler.
+CC="g++"
+
+# Is the compiler the GNU compiler?
+with_gcc=yes
+
+# Compiler flag to turn off builtin functions.
+no_builtin_flag=" -fno-builtin"
+
+# How to pass a linker flag through the compiler.
+wl="-Wl,"
+
+# Additional compiler flags for building library objects.
+pic_flag=" -fno-common -DPIC"
+
+# Compiler flag to prevent dynamic linking.
+link_static_flag=""
+
+# Does compiler simultaneously support -c and -o options?
+compiler_c_o="yes"
+
+# Whether or not to add -lc for building shared libraries.
+build_libtool_need_lc=no
+
+# Whether or not to disallow shared libs when runtime libs are static.
+allow_libtool_libs_with_static_runtimes=no
+
+# Compiler flag to allow reflexive dlopens.
+export_dynamic_flag_spec=""
+
+# Compiler flag to generate shared objects directly from archives.
+whole_archive_flag_spec=""
+
+# Whether the compiler copes with passing no objects directly.
+compiler_needs_object="no"
+
+# Create an old-style archive from a shared archive.
+old_archive_from_new_cmds=""
+
+# Create a temporary old-style archive to link instead of a shared archive.
+old_archive_from_expsyms_cmds=""
+
+# Commands used to build a shared archive.
+archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring \$single_module~\$DSYMUTIL \$lib || :"
+archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring \$single_module \${wl}-exported_symbols_list,\$output_objdir/\${libname}-symbols.expsym~\$DSYMUTIL \$lib || :"
+
+# Commands used to build a loadable module if different from building
+# a shared archive.
+module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags~\$DSYMUTIL \$lib || :"
+module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags \${wl}-exported_symbols_list,\$output_objdir/\${libname}-symbols.expsym~\$DSYMUTIL \$lib || :"
+
+# Whether we are building with GNU ld or not.
+with_gnu_ld="no"
+
+# Flag that allows shared libraries with undefined symbols to be built.
+allow_undefined_flag="\${wl}-undefined \${wl}dynamic_lookup"
+
+# Flag that enforces no undefined symbols.
+no_undefined_flag=""
+
+# Flag to hardcode $libdir into a binary during linking.
+# This must work even if $libdir does not exist
+hardcode_libdir_flag_spec=""
+
+# If ld is used when linking, flag to hardcode $libdir into a binary
+# during linking. This must work even if $libdir does not exist.
+hardcode_libdir_flag_spec_ld=""
+
+# Whether we need a single "-rpath" flag with a separated argument.
+hardcode_libdir_separator=""
+
+# Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes
+# DIR into the resulting binary.
+hardcode_direct=no
+
+# Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes
+# DIR into the resulting binary and the resulting library dependency is
+# "absolute",i.e impossible to change by setting ${shlibpath_var} if the
+# library is relocated.
+hardcode_direct_absolute=no
+
+# Set to "yes" if using the -LDIR flag during linking hardcodes DIR
+# into the resulting binary.
+hardcode_minus_L=no
+
+# Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR
+# into the resulting binary.
+hardcode_shlibpath_var=unsupported
+
+# Set to "yes" if building a shared library automatically hardcodes DIR
+# into the library and all subsequent libraries and executables linked
+# against it.
+hardcode_automatic=yes
+
+# Set to yes if linker adds runtime paths of dependent libraries
+# to runtime path list.
+inherit_rpath=no
+
+# Whether libtool must link a program against all its dependency libraries.
+link_all_deplibs=yes
+
+# Fix the shell variable $srcfile for the compiler.
+fix_srcfile_path=""
+
+# Set to "yes" if exported symbols are required.
+always_export_symbols=no
+
+# The commands to list exported symbols.
+export_symbols_cmds="\$NM \$libobjs \$convenience | \$global_symbol_pipe | \$SED 's/.* //' | sort | uniq > \$export_symbols"
+
+# Symbols that should not be listed in the preloaded symbols.
+exclude_expsyms="_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*"
+
+# Symbols that must always be exported.
+include_expsyms=""
+
+# Commands necessary for linking programs (against libraries) with templates.
+prelink_cmds=""
+
+# Specify filename containing input files.
+file_list_spec=""
+
+# How to hardcode a shared library path into an executable.
+hardcode_action=immediate
+
+# The directories searched by this compiler when creating a shared library.
+compiler_lib_search_dirs=""
+
+# Dependencies to place before and after the objects being linked to
+# create a shared library.
+predep_objects=""
+postdep_objects=""
+predeps=""
+postdeps=""
+
+# The library search path used internally by the compiler when linking
+# a shared library.
+compiler_lib_search_path=""
+
+# ### END LIBTOOL TAG CONFIG: CXX
diff --git a/src/third_party/gflags-2.0/ltmain.sh b/src/third_party/gflags-2.0/ltmain.sh
new file mode 100755
index 00000000000..7ed280bc952
--- /dev/null
+++ b/src/third_party/gflags-2.0/ltmain.sh
@@ -0,0 +1,8413 @@
+# Generated from ltmain.m4sh.
+
+# ltmain.sh (GNU libtool) 2.2.6b
+# Written by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
+
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006, 2007 2008 Free Software Foundation, Inc.
+# This is free software; see the source for copying conditions. There is NO
+# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+# GNU Libtool is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# As a special exception to the GNU General Public License,
+# if you distribute this file as part of a program or library that
+# is built using GNU Libtool, you may include this file under the
+# same distribution terms that you use for the rest of that program.
+#
+# GNU Libtool is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Libtool; see the file COPYING. If not, a copy
+# can be downloaded from http://www.gnu.org/licenses/gpl.html,
+# or obtained by writing to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+# Usage: $progname [OPTION]... [MODE-ARG]...
+#
+# Provide generalized library-building support services.
+#
+# --config show all configuration variables
+# --debug enable verbose shell tracing
+# -n, --dry-run display commands without modifying any files
+# --features display basic configuration information and exit
+# --mode=MODE use operation mode MODE
+# --preserve-dup-deps don't remove duplicate dependency libraries
+# --quiet, --silent don't print informational messages
+# --tag=TAG use configuration variables from tag TAG
+# -v, --verbose print informational messages (default)
+# --version print version information
+# -h, --help print short or long help message
+#
+# MODE must be one of the following:
+#
+# clean remove files from the build directory
+# compile compile a source file into a libtool object
+# execute automatically set library path, then run a program
+# finish complete the installation of libtool libraries
+# install install libraries or executables
+# link create a library or an executable
+# uninstall remove libraries from an installed directory
+#
+# MODE-ARGS vary depending on the MODE.
+# Try `$progname --help --mode=MODE' for a more detailed description of MODE.
+#
+# When reporting a bug, please describe a test case to reproduce it and
+# include the following information:
+#
+# host-triplet: $host
+# shell: $SHELL
+# compiler: $LTCC
+# compiler flags: $LTCFLAGS
+# linker: $LD (gnu? $with_gnu_ld)
+# $progname: (GNU libtool) 2.2.6b Debian-2.2.6b-2ubuntu1
+# automake: $automake_version
+# autoconf: $autoconf_version
+#
+# Report bugs to <bug-libtool@gnu.org>.
+
+PROGRAM=ltmain.sh
+PACKAGE=libtool
+VERSION="2.2.6b Debian-2.2.6b-2ubuntu1"
+TIMESTAMP=""
+package_revision=1.3017
+
+# Be Bourne compatible
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+ emulate sh
+ NULLCMD=:
+ # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '${1+"$@"}'='"$@"'
+ setopt NO_GLOB_SUBST
+else
+ case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac
+fi
+BIN_SH=xpg4; export BIN_SH # for Tru64
+DUALCASE=1; export DUALCASE # for MKS sh
+
+# NLS nuisances: We save the old values to restore during execute mode.
+# Only set LANG and LC_ALL to C if already set.
+# These must not be set unconditionally because not all systems understand
+# e.g. LANG=C (notably SCO).
+lt_user_locale=
+lt_safe_locale=
+for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES
+do
+ eval "if test \"\${$lt_var+set}\" = set; then
+ save_$lt_var=\$$lt_var
+ $lt_var=C
+ export $lt_var
+ lt_user_locale=\"$lt_var=\\\$save_\$lt_var; \$lt_user_locale\"
+ lt_safe_locale=\"$lt_var=C; \$lt_safe_locale\"
+ fi"
+done
+
+$lt_unset CDPATH
+
+
+
+
+
+: ${CP="cp -f"}
+: ${ECHO="echo"}
+: ${EGREP="/bin/grep -E"}
+: ${FGREP="/bin/grep -F"}
+: ${GREP="/bin/grep"}
+: ${LN_S="ln -s"}
+: ${MAKE="make"}
+: ${MKDIR="mkdir"}
+: ${MV="mv -f"}
+: ${RM="rm -f"}
+: ${SED="/bin/sed"}
+: ${SHELL="${CONFIG_SHELL-/bin/sh}"}
+: ${Xsed="$SED -e 1s/^X//"}
+
+# Global variables:
+EXIT_SUCCESS=0
+EXIT_FAILURE=1
+EXIT_MISMATCH=63 # $? = 63 is used to indicate version mismatch to missing.
+EXIT_SKIP=77 # $? = 77 is used to indicate a skipped test to automake.
+
+exit_status=$EXIT_SUCCESS
+
+# Make sure IFS has a sensible default
+lt_nl='
+'
+IFS=" $lt_nl"
+
+dirname="s,/[^/]*$,,"
+basename="s,^.*/,,"
+
+# func_dirname_and_basename file append nondir_replacement
+# perform func_basename and func_dirname in a single function
+# call:
+# dirname: Compute the dirname of FILE. If nonempty,
+# add APPEND to the result, otherwise set result
+# to NONDIR_REPLACEMENT.
+# value returned in "$func_dirname_result"
+# basename: Compute filename of FILE.
+# value retuned in "$func_basename_result"
+# Implementation must be kept synchronized with func_dirname
+# and func_basename. For efficiency, we do not delegate to
+# those functions but instead duplicate the functionality here.
+func_dirname_and_basename ()
+{
+ # Extract subdirectory from the argument.
+ func_dirname_result=`$ECHO "X${1}" | $Xsed -e "$dirname"`
+ if test "X$func_dirname_result" = "X${1}"; then
+ func_dirname_result="${3}"
+ else
+ func_dirname_result="$func_dirname_result${2}"
+ fi
+ func_basename_result=`$ECHO "X${1}" | $Xsed -e "$basename"`
+}
+
+# Generated shell functions inserted here.
+
+# Work around backward compatibility issue on IRIX 6.5. On IRIX 6.4+, sh
+# is ksh but when the shell is invoked as "sh" and the current value of
+# the _XPG environment variable is not equal to 1 (one), the special
+# positional parameter $0, within a function call, is the name of the
+# function.
+progpath="$0"
+
+# The name of this program:
+# In the unlikely event $progname began with a '-', it would play havoc with
+# func_echo (imagine progname=-n), so we prepend ./ in that case:
+func_dirname_and_basename "$progpath"
+progname=$func_basename_result
+case $progname in
+ -*) progname=./$progname ;;
+esac
+
+# Make sure we have an absolute path for reexecution:
+case $progpath in
+ [\\/]*|[A-Za-z]:\\*) ;;
+ *[\\/]*)
+ progdir=$func_dirname_result
+ progdir=`cd "$progdir" && pwd`
+ progpath="$progdir/$progname"
+ ;;
+ *)
+ save_IFS="$IFS"
+ IFS=:
+ for progdir in $PATH; do
+ IFS="$save_IFS"
+ test -x "$progdir/$progname" && break
+ done
+ IFS="$save_IFS"
+ test -n "$progdir" || progdir=`pwd`
+ progpath="$progdir/$progname"
+ ;;
+esac
+
+# Sed substitution that helps us do robust quoting. It backslashifies
+# metacharacters that are still active within double-quoted strings.
+Xsed="${SED}"' -e 1s/^X//'
+sed_quote_subst='s/\([`"$\\]\)/\\\1/g'
+
+# Same as above, but do not quote variable references.
+double_quote_subst='s/\(["`\\]\)/\\\1/g'
+
+# Re-`\' parameter expansions in output of double_quote_subst that were
+# `\'-ed in input to the same. If an odd number of `\' preceded a '$'
+# in input to double_quote_subst, that '$' was protected from expansion.
+# Since each input `\' is now two `\'s, look for any number of runs of
+# four `\'s followed by two `\'s and then a '$'. `\' that '$'.
+bs='\\'
+bs2='\\\\'
+bs4='\\\\\\\\'
+dollar='\$'
+sed_double_backslash="\
+ s/$bs4/&\\
+/g
+ s/^$bs2$dollar/$bs&/
+ s/\\([^$bs]\\)$bs2$dollar/\\1$bs2$bs$dollar/g
+ s/\n//g"
+
+# Standard options:
+opt_dry_run=false
+opt_help=false
+opt_quiet=false
+opt_verbose=false
+opt_warning=:
+
+# func_echo arg...
+# Echo program name prefixed message, along with the current mode
+# name if it has been set yet.
+func_echo ()
+{
+ $ECHO "$progname${mode+: }$mode: $*"
+}
+
+# func_verbose arg...
+# Echo program name prefixed message in verbose mode only.
+func_verbose ()
+{
+ $opt_verbose && func_echo ${1+"$@"}
+
+ # A bug in bash halts the script if the last line of a function
+ # fails when set -e is in force, so we need another command to
+ # work around that:
+ :
+}
+
+# func_error arg...
+# Echo program name prefixed message to standard error.
+func_error ()
+{
+ $ECHO "$progname${mode+: }$mode: "${1+"$@"} 1>&2
+}
+
+# func_warning arg...
+# Echo program name prefixed warning message to standard error.
+func_warning ()
+{
+ $opt_warning && $ECHO "$progname${mode+: }$mode: warning: "${1+"$@"} 1>&2
+
+ # bash bug again:
+ :
+}
+
+# func_fatal_error arg...
+# Echo program name prefixed message to standard error, and exit.
+func_fatal_error ()
+{
+ func_error ${1+"$@"}
+ exit $EXIT_FAILURE
+}
+
+# func_fatal_help arg...
+# Echo program name prefixed message to standard error, followed by
+# a help hint, and exit.
+func_fatal_help ()
+{
+ func_error ${1+"$@"}
+ func_fatal_error "$help"
+}
+help="Try \`$progname --help' for more information." ## default
+
+
+# func_grep expression filename
+# Check whether EXPRESSION matches any line of FILENAME, without output.
+func_grep ()
+{
+ $GREP "$1" "$2" >/dev/null 2>&1
+}
+
+
+# func_mkdir_p directory-path
+# Make sure the entire path to DIRECTORY-PATH is available.
+func_mkdir_p ()
+{
+ my_directory_path="$1"
+ my_dir_list=
+
+ if test -n "$my_directory_path" && test "$opt_dry_run" != ":"; then
+
+ # Protect directory names starting with `-'
+ case $my_directory_path in
+ -*) my_directory_path="./$my_directory_path" ;;
+ esac
+
+ # While some portion of DIR does not yet exist...
+ while test ! -d "$my_directory_path"; do
+ # ...make a list in topmost first order. Use a colon delimited
+ # list incase some portion of path contains whitespace.
+ my_dir_list="$my_directory_path:$my_dir_list"
+
+ # If the last portion added has no slash in it, the list is done
+ case $my_directory_path in */*) ;; *) break ;; esac
+
+ # ...otherwise throw away the child directory and loop
+ my_directory_path=`$ECHO "X$my_directory_path" | $Xsed -e "$dirname"`
+ done
+ my_dir_list=`$ECHO "X$my_dir_list" | $Xsed -e 's,:*$,,'`
+
+ save_mkdir_p_IFS="$IFS"; IFS=':'
+ for my_dir in $my_dir_list; do
+ IFS="$save_mkdir_p_IFS"
+ # mkdir can fail with a `File exist' error if two processes
+ # try to create one of the directories concurrently. Don't
+ # stop in that case!
+ $MKDIR "$my_dir" 2>/dev/null || :
+ done
+ IFS="$save_mkdir_p_IFS"
+
+ # Bail out if we (or some other process) failed to create a directory.
+ test -d "$my_directory_path" || \
+ func_fatal_error "Failed to create \`$1'"
+ fi
+}
+
+
+# func_mktempdir [string]
+# Make a temporary directory that won't clash with other running
+# libtool processes, and avoids race conditions if possible. If
+# given, STRING is the basename for that directory.
+func_mktempdir ()
+{
+ my_template="${TMPDIR-/tmp}/${1-$progname}"
+
+ if test "$opt_dry_run" = ":"; then
+ # Return a directory name, but don't create it in dry-run mode
+ my_tmpdir="${my_template}-$$"
+ else
+
+ # If mktemp works, use that first and foremost
+ my_tmpdir=`mktemp -d "${my_template}-XXXXXXXX" 2>/dev/null`
+
+ if test ! -d "$my_tmpdir"; then
+ # Failing that, at least try and use $RANDOM to avoid a race
+ my_tmpdir="${my_template}-${RANDOM-0}$$"
+
+ save_mktempdir_umask=`umask`
+ umask 0077
+ $MKDIR "$my_tmpdir"
+ umask $save_mktempdir_umask
+ fi
+
+ # If we're not in dry-run mode, bomb out on failure
+ test -d "$my_tmpdir" || \
+ func_fatal_error "cannot create temporary directory \`$my_tmpdir'"
+ fi
+
+ $ECHO "X$my_tmpdir" | $Xsed
+}
+
+
+# func_quote_for_eval arg
+# Aesthetically quote ARG to be evaled later.
+# This function returns two values: FUNC_QUOTE_FOR_EVAL_RESULT
+# is double-quoted, suitable for a subsequent eval, whereas
+# FUNC_QUOTE_FOR_EVAL_UNQUOTED_RESULT has merely all characters
+# which are still active within double quotes backslashified.
+func_quote_for_eval ()
+{
+ case $1 in
+ *[\\\`\"\$]*)
+ func_quote_for_eval_unquoted_result=`$ECHO "X$1" | $Xsed -e "$sed_quote_subst"` ;;
+ *)
+ func_quote_for_eval_unquoted_result="$1" ;;
+ esac
+
+ case $func_quote_for_eval_unquoted_result in
+ # Double-quote args containing shell metacharacters to delay
+ # word splitting, command substitution and and variable
+ # expansion for a subsequent eval.
+ # Many Bourne shells cannot handle close brackets correctly
+ # in scan sets, so we specify it separately.
+ *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"")
+ func_quote_for_eval_result="\"$func_quote_for_eval_unquoted_result\""
+ ;;
+ *)
+ func_quote_for_eval_result="$func_quote_for_eval_unquoted_result"
+ esac
+}
+
+
+# func_quote_for_expand arg
+# Aesthetically quote ARG to be evaled later; same as above,
+# but do not quote variable references.
+func_quote_for_expand ()
+{
+ case $1 in
+ *[\\\`\"]*)
+ my_arg=`$ECHO "X$1" | $Xsed \
+ -e "$double_quote_subst" -e "$sed_double_backslash"` ;;
+ *)
+ my_arg="$1" ;;
+ esac
+
+ case $my_arg in
+ # Double-quote args containing shell metacharacters to delay
+ # word splitting and command substitution for a subsequent eval.
+ # Many Bourne shells cannot handle close brackets correctly
+ # in scan sets, so we specify it separately.
+ *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"")
+ my_arg="\"$my_arg\""
+ ;;
+ esac
+
+ func_quote_for_expand_result="$my_arg"
+}
+
+
+# func_show_eval cmd [fail_exp]
+# Unless opt_silent is true, then output CMD. Then, if opt_dryrun is
+# not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP
+# is given, then evaluate it.
+func_show_eval ()
+{
+ my_cmd="$1"
+ my_fail_exp="${2-:}"
+
+ ${opt_silent-false} || {
+ func_quote_for_expand "$my_cmd"
+ eval "func_echo $func_quote_for_expand_result"
+ }
+
+ if ${opt_dry_run-false}; then :; else
+ eval "$my_cmd"
+ my_status=$?
+ if test "$my_status" -eq 0; then :; else
+ eval "(exit $my_status); $my_fail_exp"
+ fi
+ fi
+}
+
+
+# func_show_eval_locale cmd [fail_exp]
+# Unless opt_silent is true, then output CMD. Then, if opt_dryrun is
+# not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP
+# is given, then evaluate it. Use the saved locale for evaluation.
+func_show_eval_locale ()
+{
+ my_cmd="$1"
+ my_fail_exp="${2-:}"
+
+ ${opt_silent-false} || {
+ func_quote_for_expand "$my_cmd"
+ eval "func_echo $func_quote_for_expand_result"
+ }
+
+ if ${opt_dry_run-false}; then :; else
+ eval "$lt_user_locale
+ $my_cmd"
+ my_status=$?
+ eval "$lt_safe_locale"
+ if test "$my_status" -eq 0; then :; else
+ eval "(exit $my_status); $my_fail_exp"
+ fi
+ fi
+}
+
+
+
+
+
+# func_version
+# Echo version message to standard output and exit.
+func_version ()
+{
+ $SED -n '/^# '$PROGRAM' (GNU /,/# warranty; / {
+ s/^# //
+ s/^# *$//
+ s/\((C)\)[ 0-9,-]*\( [1-9][0-9]*\)/\1\2/
+ p
+ }' < "$progpath"
+ exit $?
+}
+
+# func_usage
+# Echo short help message to standard output and exit.
+func_usage ()
+{
+ $SED -n '/^# Usage:/,/# -h/ {
+ s/^# //
+ s/^# *$//
+ s/\$progname/'$progname'/
+ p
+ }' < "$progpath"
+ $ECHO
+ $ECHO "run \`$progname --help | more' for full usage"
+ exit $?
+}
+
+# func_help
+# Echo long help message to standard output and exit.
+func_help ()
+{
+ $SED -n '/^# Usage:/,/# Report bugs to/ {
+ s/^# //
+ s/^# *$//
+ s*\$progname*'$progname'*
+ s*\$host*'"$host"'*
+ s*\$SHELL*'"$SHELL"'*
+ s*\$LTCC*'"$LTCC"'*
+ s*\$LTCFLAGS*'"$LTCFLAGS"'*
+ s*\$LD*'"$LD"'*
+ s/\$with_gnu_ld/'"$with_gnu_ld"'/
+ s/\$automake_version/'"`(automake --version) 2>/dev/null |$SED 1q`"'/
+ s/\$autoconf_version/'"`(autoconf --version) 2>/dev/null |$SED 1q`"'/
+ p
+ }' < "$progpath"
+ exit $?
+}
+
+# func_missing_arg argname
+# Echo program name prefixed message to standard error and set global
+# exit_cmd.
+func_missing_arg ()
+{
+ func_error "missing argument for $1"
+ exit_cmd=exit
+}
+
+exit_cmd=:
+
+
+
+
+
+# Check that we have a working $ECHO.
+if test "X$1" = X--no-reexec; then
+ # Discard the --no-reexec flag, and continue.
+ shift
+elif test "X$1" = X--fallback-echo; then
+ # Avoid inline document here, it may be left over
+ :
+elif test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t'; then
+ # Yippee, $ECHO works!
+ :
+else
+ # Restart under the correct shell, and then maybe $ECHO will work.
+ exec $SHELL "$progpath" --no-reexec ${1+"$@"}
+fi
+
+if test "X$1" = X--fallback-echo; then
+ # used as fallback echo
+ shift
+ cat <<EOF
+$*
+EOF
+ exit $EXIT_SUCCESS
+fi
+
+magic="%%%MAGIC variable%%%"
+magic_exe="%%%MAGIC EXE variable%%%"
+
+# Global variables.
+# $mode is unset
+nonopt=
+execute_dlfiles=
+preserve_args=
+lo2o="s/\\.lo\$/.${objext}/"
+o2lo="s/\\.${objext}\$/.lo/"
+extracted_archives=
+extracted_serial=0
+
+opt_dry_run=false
+opt_duplicate_deps=false
+opt_silent=false
+opt_debug=:
+
+# If this variable is set in any of the actions, the command in it
+# will be execed at the end. This prevents here-documents from being
+# left over by shells.
+exec_cmd=
+
+# func_fatal_configuration arg...
+# Echo program name prefixed message to standard error, followed by
+# a configuration failure hint, and exit.
+func_fatal_configuration ()
+{
+ func_error ${1+"$@"}
+ func_error "See the $PACKAGE documentation for more information."
+ func_fatal_error "Fatal configuration error."
+}
+
+
+# func_config
+# Display the configuration for all the tags in this script.
+func_config ()
+{
+ re_begincf='^# ### BEGIN LIBTOOL'
+ re_endcf='^# ### END LIBTOOL'
+
+ # Default configuration.
+ $SED "1,/$re_begincf CONFIG/d;/$re_endcf CONFIG/,\$d" < "$progpath"
+
+ # Now print the configurations for the tags.
+ for tagname in $taglist; do
+ $SED -n "/$re_begincf TAG CONFIG: $tagname\$/,/$re_endcf TAG CONFIG: $tagname\$/p" < "$progpath"
+ done
+
+ exit $?
+}
+
+# func_features
+# Display the features supported by this script.
+func_features ()
+{
+ $ECHO "host: $host"
+ if test "$build_libtool_libs" = yes; then
+ $ECHO "enable shared libraries"
+ else
+ $ECHO "disable shared libraries"
+ fi
+ if test "$build_old_libs" = yes; then
+ $ECHO "enable static libraries"
+ else
+ $ECHO "disable static libraries"
+ fi
+
+ exit $?
+}
+
+# func_enable_tag tagname
+# Verify that TAGNAME is valid, and either flag an error and exit, or
+# enable the TAGNAME tag. We also add TAGNAME to the global $taglist
+# variable here.
+func_enable_tag ()
+{
+ # Global variable:
+ tagname="$1"
+
+ re_begincf="^# ### BEGIN LIBTOOL TAG CONFIG: $tagname\$"
+ re_endcf="^# ### END LIBTOOL TAG CONFIG: $tagname\$"
+ sed_extractcf="/$re_begincf/,/$re_endcf/p"
+
+ # Validate tagname.
+ case $tagname in
+ *[!-_A-Za-z0-9,/]*)
+ func_fatal_error "invalid tag name: $tagname"
+ ;;
+ esac
+
+ # Don't test for the "default" C tag, as we know it's
+ # there but not specially marked.
+ case $tagname in
+ CC) ;;
+ *)
+ if $GREP "$re_begincf" "$progpath" >/dev/null 2>&1; then
+ taglist="$taglist $tagname"
+
+ # Evaluate the configuration. Be careful to quote the path
+ # and the sed script, to avoid splitting on whitespace, but
+ # also don't use non-portable quotes within backquotes within
+ # quotes we have to do it in 2 steps:
+ extractedcf=`$SED -n -e "$sed_extractcf" < "$progpath"`
+ eval "$extractedcf"
+ else
+ func_error "ignoring unknown tag $tagname"
+ fi
+ ;;
+ esac
+}
+
+# Parse options once, thoroughly. This comes as soon as possible in
+# the script to make things like `libtool --version' happen quickly.
+{
+
+ # Shorthand for --mode=foo, only valid as the first argument
+ case $1 in
+ clean|clea|cle|cl)
+ shift; set dummy --mode clean ${1+"$@"}; shift
+ ;;
+ compile|compil|compi|comp|com|co|c)
+ shift; set dummy --mode compile ${1+"$@"}; shift
+ ;;
+ execute|execut|execu|exec|exe|ex|e)
+ shift; set dummy --mode execute ${1+"$@"}; shift
+ ;;
+ finish|finis|fini|fin|fi|f)
+ shift; set dummy --mode finish ${1+"$@"}; shift
+ ;;
+ install|instal|insta|inst|ins|in|i)
+ shift; set dummy --mode install ${1+"$@"}; shift
+ ;;
+ link|lin|li|l)
+ shift; set dummy --mode link ${1+"$@"}; shift
+ ;;
+ uninstall|uninstal|uninsta|uninst|unins|unin|uni|un|u)
+ shift; set dummy --mode uninstall ${1+"$@"}; shift
+ ;;
+ esac
+
+ # Parse non-mode specific arguments:
+ while test "$#" -gt 0; do
+ opt="$1"
+ shift
+
+ case $opt in
+ --config) func_config ;;
+
+ --debug) preserve_args="$preserve_args $opt"
+ func_echo "enabling shell trace mode"
+ opt_debug='set -x'
+ $opt_debug
+ ;;
+
+ -dlopen) test "$#" -eq 0 && func_missing_arg "$opt" && break
+ execute_dlfiles="$execute_dlfiles $1"
+ shift
+ ;;
+
+ --dry-run | -n) opt_dry_run=: ;;
+ --features) func_features ;;
+ --finish) mode="finish" ;;
+
+ --mode) test "$#" -eq 0 && func_missing_arg "$opt" && break
+ case $1 in
+ # Valid mode arguments:
+ clean) ;;
+ compile) ;;
+ execute) ;;
+ finish) ;;
+ install) ;;
+ link) ;;
+ relink) ;;
+ uninstall) ;;
+
+ # Catch anything else as an error
+ *) func_error "invalid argument for $opt"
+ exit_cmd=exit
+ break
+ ;;
+ esac
+
+ mode="$1"
+ shift
+ ;;
+
+ --preserve-dup-deps)
+ opt_duplicate_deps=: ;;
+
+ --quiet|--silent) preserve_args="$preserve_args $opt"
+ opt_silent=:
+ ;;
+
+ --verbose| -v) preserve_args="$preserve_args $opt"
+ opt_silent=false
+ ;;
+
+ --tag) test "$#" -eq 0 && func_missing_arg "$opt" && break
+ preserve_args="$preserve_args $opt $1"
+ func_enable_tag "$1" # tagname is set here
+ shift
+ ;;
+
+ # Separate optargs to long options:
+ -dlopen=*|--mode=*|--tag=*)
+ func_opt_split "$opt"
+ set dummy "$func_opt_split_opt" "$func_opt_split_arg" ${1+"$@"}
+ shift
+ ;;
+
+ -\?|-h) func_usage ;;
+ --help) opt_help=: ;;
+ --version) func_version ;;
+
+ -*) func_fatal_help "unrecognized option \`$opt'" ;;
+
+ *) nonopt="$opt"
+ break
+ ;;
+ esac
+ done
+
+
+ case $host in
+ *cygwin* | *mingw* | *pw32* | *cegcc*)
+ # don't eliminate duplications in $postdeps and $predeps
+ opt_duplicate_compiler_generated_deps=:
+ ;;
+ *)
+ opt_duplicate_compiler_generated_deps=$opt_duplicate_deps
+ ;;
+ esac
+
+ # Having warned about all mis-specified options, bail out if
+ # anything was wrong.
+ $exit_cmd $EXIT_FAILURE
+}
+
+# func_check_version_match
+# Ensure that we are using m4 macros, and libtool script from the same
+# release of libtool.
+func_check_version_match ()
+{
+ if test "$package_revision" != "$macro_revision"; then
+ if test "$VERSION" != "$macro_version"; then
+ if test -z "$macro_version"; then
+ cat >&2 <<_LT_EOF
+$progname: Version mismatch error. This is $PACKAGE $VERSION, but the
+$progname: definition of this LT_INIT comes from an older release.
+$progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION
+$progname: and run autoconf again.
+_LT_EOF
+ else
+ cat >&2 <<_LT_EOF
+$progname: Version mismatch error. This is $PACKAGE $VERSION, but the
+$progname: definition of this LT_INIT comes from $PACKAGE $macro_version.
+$progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION
+$progname: and run autoconf again.
+_LT_EOF
+ fi
+ else
+ cat >&2 <<_LT_EOF
+$progname: Version mismatch error. This is $PACKAGE $VERSION, revision $package_revision,
+$progname: but the definition of this LT_INIT comes from revision $macro_revision.
+$progname: You should recreate aclocal.m4 with macros from revision $package_revision
+$progname: of $PACKAGE $VERSION and run autoconf again.
+_LT_EOF
+ fi
+
+ exit $EXIT_MISMATCH
+ fi
+}
+
+
+## ----------- ##
+## Main. ##
+## ----------- ##
+
+$opt_help || {
+ # Sanity checks first:
+ func_check_version_match
+
+ if test "$build_libtool_libs" != yes && test "$build_old_libs" != yes; then
+ func_fatal_configuration "not configured to build any kind of library"
+ fi
+
+ test -z "$mode" && func_fatal_error "error: you must specify a MODE."
+
+
+ # Darwin sucks
+ eval std_shrext=\"$shrext_cmds\"
+
+
+ # Only execute mode is allowed to have -dlopen flags.
+ if test -n "$execute_dlfiles" && test "$mode" != execute; then
+ func_error "unrecognized option \`-dlopen'"
+ $ECHO "$help" 1>&2
+ exit $EXIT_FAILURE
+ fi
+
+ # Change the help message to a mode-specific one.
+ generic_help="$help"
+ help="Try \`$progname --help --mode=$mode' for more information."
+}
+
+
+# func_lalib_p file
+# True iff FILE is a libtool `.la' library or `.lo' object file.
+# This function is only a basic sanity check; it will hardly flush out
+# determined imposters.
+func_lalib_p ()
+{
+ test -f "$1" &&
+ $SED -e 4q "$1" 2>/dev/null \
+ | $GREP "^# Generated by .*$PACKAGE" > /dev/null 2>&1
+}
+
+# func_lalib_unsafe_p file
+# True iff FILE is a libtool `.la' library or `.lo' object file.
+# This function implements the same check as func_lalib_p without
+# resorting to external programs. To this end, it redirects stdin and
+# closes it afterwards, without saving the original file descriptor.
+# As a safety measure, use it only where a negative result would be
+# fatal anyway. Works if `file' does not exist.
+func_lalib_unsafe_p ()
+{
+ lalib_p=no
+ if test -f "$1" && test -r "$1" && exec 5<&0 <"$1"; then
+ for lalib_p_l in 1 2 3 4
+ do
+ read lalib_p_line
+ case "$lalib_p_line" in
+ \#\ Generated\ by\ *$PACKAGE* ) lalib_p=yes; break;;
+ esac
+ done
+ exec 0<&5 5<&-
+ fi
+ test "$lalib_p" = yes
+}
+
+# func_ltwrapper_script_p file
+# True iff FILE is a libtool wrapper script
+# This function is only a basic sanity check; it will hardly flush out
+# determined imposters.
+func_ltwrapper_script_p ()
+{
+ func_lalib_p "$1"
+}
+
+# func_ltwrapper_executable_p file
+# True iff FILE is a libtool wrapper executable
+# This function is only a basic sanity check; it will hardly flush out
+# determined imposters.
+func_ltwrapper_executable_p ()
+{
+ func_ltwrapper_exec_suffix=
+ case $1 in
+ *.exe) ;;
+ *) func_ltwrapper_exec_suffix=.exe ;;
+ esac
+ $GREP "$magic_exe" "$1$func_ltwrapper_exec_suffix" >/dev/null 2>&1
+}
+
+# func_ltwrapper_scriptname file
+# Assumes file is an ltwrapper_executable
+# uses $file to determine the appropriate filename for a
+# temporary ltwrapper_script.
+func_ltwrapper_scriptname ()
+{
+ func_ltwrapper_scriptname_result=""
+ if func_ltwrapper_executable_p "$1"; then
+ func_dirname_and_basename "$1" "" "."
+ func_stripname '' '.exe' "$func_basename_result"
+ func_ltwrapper_scriptname_result="$func_dirname_result/$objdir/${func_stripname_result}_ltshwrapper"
+ fi
+}
+
+# func_ltwrapper_p file
+# True iff FILE is a libtool wrapper script or wrapper executable
+# This function is only a basic sanity check; it will hardly flush out
+# determined imposters.
+func_ltwrapper_p ()
+{
+ func_ltwrapper_script_p "$1" || func_ltwrapper_executable_p "$1"
+}
+
+
+# func_execute_cmds commands fail_cmd
+# Execute tilde-delimited COMMANDS.
+# If FAIL_CMD is given, eval that upon failure.
+# FAIL_CMD may read-access the current command in variable CMD!
+func_execute_cmds ()
+{
+ $opt_debug
+ save_ifs=$IFS; IFS='~'
+ for cmd in $1; do
+ IFS=$save_ifs
+ eval cmd=\"$cmd\"
+ func_show_eval "$cmd" "${2-:}"
+ done
+ IFS=$save_ifs
+}
+
+
+# func_source file
+# Source FILE, adding directory component if necessary.
+# Note that it is not necessary on cygwin/mingw to append a dot to
+# FILE even if both FILE and FILE.exe exist: automatic-append-.exe
+# behavior happens only for exec(3), not for open(2)! Also, sourcing
+# `FILE.' does not work on cygwin managed mounts.
+func_source ()
+{
+ $opt_debug
+ case $1 in
+ */* | *\\*) . "$1" ;;
+ *) . "./$1" ;;
+ esac
+}
+
+
+# func_infer_tag arg
+# Infer tagged configuration to use if any are available and
+# if one wasn't chosen via the "--tag" command line option.
+# Only attempt this if the compiler in the base compile
+# command doesn't match the default compiler.
+# arg is usually of the form 'gcc ...'
+func_infer_tag ()
+{
+ $opt_debug
+ if test -n "$available_tags" && test -z "$tagname"; then
+ CC_quoted=
+ for arg in $CC; do
+ func_quote_for_eval "$arg"
+ CC_quoted="$CC_quoted $func_quote_for_eval_result"
+ done
+ case $@ in
+ # Blanks in the command may have been stripped by the calling shell,
+ # but not from the CC environment variable when configure was run.
+ " $CC "* | "$CC "* | " `$ECHO $CC` "* | "`$ECHO $CC` "* | " $CC_quoted"* | "$CC_quoted "* | " `$ECHO $CC_quoted` "* | "`$ECHO $CC_quoted` "*) ;;
+ # Blanks at the start of $base_compile will cause this to fail
+ # if we don't check for them as well.
+ *)
+ for z in $available_tags; do
+ if $GREP "^# ### BEGIN LIBTOOL TAG CONFIG: $z$" < "$progpath" > /dev/null; then
+ # Evaluate the configuration.
+ eval "`${SED} -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^# ### END LIBTOOL TAG CONFIG: '$z'$/p' < $progpath`"
+ CC_quoted=
+ for arg in $CC; do
+ # Double-quote args containing other shell metacharacters.
+ func_quote_for_eval "$arg"
+ CC_quoted="$CC_quoted $func_quote_for_eval_result"
+ done
+ case "$@ " in
+ " $CC "* | "$CC "* | " `$ECHO $CC` "* | "`$ECHO $CC` "* | " $CC_quoted"* | "$CC_quoted "* | " `$ECHO $CC_quoted` "* | "`$ECHO $CC_quoted` "*)
+ # The compiler in the base compile command matches
+ # the one in the tagged configuration.
+ # Assume this is the tagged configuration we want.
+ tagname=$z
+ break
+ ;;
+ esac
+ fi
+ done
+ # If $tagname still isn't set, then no tagged configuration
+ # was found and let the user know that the "--tag" command
+ # line option must be used.
+ if test -z "$tagname"; then
+ func_echo "unable to infer tagged configuration"
+ func_fatal_error "specify a tag with \`--tag'"
+# else
+# func_verbose "using $tagname tagged configuration"
+ fi
+ ;;
+ esac
+ fi
+}
+
+
+
+# func_write_libtool_object output_name pic_name nonpic_name
+# Create a libtool object file (analogous to a ".la" file),
+# but don't create it if we're doing a dry run.
+func_write_libtool_object ()
+{
+ write_libobj=${1}
+ if test "$build_libtool_libs" = yes; then
+ write_lobj=\'${2}\'
+ else
+ write_lobj=none
+ fi
+
+ if test "$build_old_libs" = yes; then
+ write_oldobj=\'${3}\'
+ else
+ write_oldobj=none
+ fi
+
+ $opt_dry_run || {
+ cat >${write_libobj}T <<EOF
+# $write_libobj - a libtool object file
+# Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION
+#
+# Please DO NOT delete this file!
+# It is necessary for linking the library.
+
+# Name of the PIC object.
+pic_object=$write_lobj
+
+# Name of the non-PIC object
+non_pic_object=$write_oldobj
+
+EOF
+ $MV "${write_libobj}T" "${write_libobj}"
+ }
+}
+
+# func_mode_compile arg...
+func_mode_compile ()
+{
+ $opt_debug
+ # Get the compilation command and the source file.
+ base_compile=
+ srcfile="$nonopt" # always keep a non-empty value in "srcfile"
+ suppress_opt=yes
+ suppress_output=
+ arg_mode=normal
+ libobj=
+ later=
+ pie_flag=
+
+ for arg
+ do
+ case $arg_mode in
+ arg )
+ # do not "continue". Instead, add this to base_compile
+ lastarg="$arg"
+ arg_mode=normal
+ ;;
+
+ target )
+ libobj="$arg"
+ arg_mode=normal
+ continue
+ ;;
+
+ normal )
+ # Accept any command-line options.
+ case $arg in
+ -o)
+ test -n "$libobj" && \
+ func_fatal_error "you cannot specify \`-o' more than once"
+ arg_mode=target
+ continue
+ ;;
+
+ -pie | -fpie | -fPIE)
+ pie_flag="$pie_flag $arg"
+ continue
+ ;;
+
+ -shared | -static | -prefer-pic | -prefer-non-pic)
+ later="$later $arg"
+ continue
+ ;;
+
+ -no-suppress)
+ suppress_opt=no
+ continue
+ ;;
+
+ -Xcompiler)
+ arg_mode=arg # the next one goes into the "base_compile" arg list
+ continue # The current "srcfile" will either be retained or
+ ;; # replaced later. I would guess that would be a bug.
+
+ -Wc,*)
+ func_stripname '-Wc,' '' "$arg"
+ args=$func_stripname_result
+ lastarg=
+ save_ifs="$IFS"; IFS=','
+ for arg in $args; do
+ IFS="$save_ifs"
+ func_quote_for_eval "$arg"
+ lastarg="$lastarg $func_quote_for_eval_result"
+ done
+ IFS="$save_ifs"
+ func_stripname ' ' '' "$lastarg"
+ lastarg=$func_stripname_result
+
+ # Add the arguments to base_compile.
+ base_compile="$base_compile $lastarg"
+ continue
+ ;;
+
+ *)
+ # Accept the current argument as the source file.
+ # The previous "srcfile" becomes the current argument.
+ #
+ lastarg="$srcfile"
+ srcfile="$arg"
+ ;;
+ esac # case $arg
+ ;;
+ esac # case $arg_mode
+
+ # Aesthetically quote the previous argument.
+ func_quote_for_eval "$lastarg"
+ base_compile="$base_compile $func_quote_for_eval_result"
+ done # for arg
+
+ case $arg_mode in
+ arg)
+ func_fatal_error "you must specify an argument for -Xcompile"
+ ;;
+ target)
+ func_fatal_error "you must specify a target with \`-o'"
+ ;;
+ *)
+ # Get the name of the library object.
+ test -z "$libobj" && {
+ func_basename "$srcfile"
+ libobj="$func_basename_result"
+ }
+ ;;
+ esac
+
+ # Recognize several different file suffixes.
+ # If the user specifies -o file.o, it is replaced with file.lo
+ case $libobj in
+ *.[cCFSifmso] | \
+ *.ada | *.adb | *.ads | *.asm | \
+ *.c++ | *.cc | *.ii | *.class | *.cpp | *.cxx | \
+ *.[fF][09]? | *.for | *.java | *.obj | *.sx)
+ func_xform "$libobj"
+ libobj=$func_xform_result
+ ;;
+ esac
+
+ case $libobj in
+ *.lo) func_lo2o "$libobj"; obj=$func_lo2o_result ;;
+ *)
+ func_fatal_error "cannot determine name of library object from \`$libobj'"
+ ;;
+ esac
+
+ func_infer_tag $base_compile
+
+ for arg in $later; do
+ case $arg in
+ -shared)
+ test "$build_libtool_libs" != yes && \
+ func_fatal_configuration "can not build a shared library"
+ build_old_libs=no
+ continue
+ ;;
+
+ -static)
+ build_libtool_libs=no
+ build_old_libs=yes
+ continue
+ ;;
+
+ -prefer-pic)
+ pic_mode=yes
+ continue
+ ;;
+
+ -prefer-non-pic)
+ pic_mode=no
+ continue
+ ;;
+ esac
+ done
+
+ func_quote_for_eval "$libobj"
+ test "X$libobj" != "X$func_quote_for_eval_result" \
+ && $ECHO "X$libobj" | $GREP '[]~#^*{};<>?"'"'"' &()|`$[]' \
+ && func_warning "libobj name \`$libobj' may not contain shell special characters."
+ func_dirname_and_basename "$obj" "/" ""
+ objname="$func_basename_result"
+ xdir="$func_dirname_result"
+ lobj=${xdir}$objdir/$objname
+
+ test -z "$base_compile" && \
+ func_fatal_help "you must specify a compilation command"
+
+ # Delete any leftover library objects.
+ if test "$build_old_libs" = yes; then
+ removelist="$obj $lobj $libobj ${libobj}T"
+ else
+ removelist="$lobj $libobj ${libobj}T"
+ fi
+
+ # On Cygwin there's no "real" PIC flag so we must build both object types
+ case $host_os in
+ cygwin* | mingw* | pw32* | os2* | cegcc*)
+ pic_mode=default
+ ;;
+ esac
+ if test "$pic_mode" = no && test "$deplibs_check_method" != pass_all; then
+ # non-PIC code in shared libraries is not supported
+ pic_mode=default
+ fi
+
+ # Calculate the filename of the output object if compiler does
+ # not support -o with -c
+ if test "$compiler_c_o" = no; then
+ output_obj=`$ECHO "X$srcfile" | $Xsed -e 's%^.*/%%' -e 's%\.[^.]*$%%'`.${objext}
+ lockfile="$output_obj.lock"
+ else
+ output_obj=
+ need_locks=no
+ lockfile=
+ fi
+
+ # Lock this critical section if it is needed
+ # We use this script file to make the link, it avoids creating a new file
+ if test "$need_locks" = yes; then
+ until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do
+ func_echo "Waiting for $lockfile to be removed"
+ sleep 2
+ done
+ elif test "$need_locks" = warn; then
+ if test -f "$lockfile"; then
+ $ECHO "\
+*** ERROR, $lockfile exists and contains:
+`cat $lockfile 2>/dev/null`
+
+This indicates that another process is trying to use the same
+temporary object file, and libtool could not work around it because
+your compiler does not support \`-c' and \`-o' together. If you
+repeat this compilation, it may succeed, by chance, but you had better
+avoid parallel builds (make -j) in this platform, or get a better
+compiler."
+
+ $opt_dry_run || $RM $removelist
+ exit $EXIT_FAILURE
+ fi
+ removelist="$removelist $output_obj"
+ $ECHO "$srcfile" > "$lockfile"
+ fi
+
+ $opt_dry_run || $RM $removelist
+ removelist="$removelist $lockfile"
+ trap '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' 1 2 15
+
+ if test -n "$fix_srcfile_path"; then
+ eval srcfile=\"$fix_srcfile_path\"
+ fi
+ func_quote_for_eval "$srcfile"
+ qsrcfile=$func_quote_for_eval_result
+
+ # Only build a PIC object if we are building libtool libraries.
+ if test "$build_libtool_libs" = yes; then
+ # Without this assignment, base_compile gets emptied.
+ fbsd_hideous_sh_bug=$base_compile
+
+ if test "$pic_mode" != no; then
+ command="$base_compile $qsrcfile $pic_flag"
+ else
+ # Don't build PIC code
+ command="$base_compile $qsrcfile"
+ fi
+
+ func_mkdir_p "$xdir$objdir"
+
+ if test -z "$output_obj"; then
+ # Place PIC objects in $objdir
+ command="$command -o $lobj"
+ fi
+
+ func_show_eval_locale "$command" \
+ 'test -n "$output_obj" && $RM $removelist; exit $EXIT_FAILURE'
+
+ if test "$need_locks" = warn &&
+ test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then
+ $ECHO "\
+*** ERROR, $lockfile contains:
+`cat $lockfile 2>/dev/null`
+
+but it should contain:
+$srcfile
+
+This indicates that another process is trying to use the same
+temporary object file, and libtool could not work around it because
+your compiler does not support \`-c' and \`-o' together. If you
+repeat this compilation, it may succeed, by chance, but you had better
+avoid parallel builds (make -j) in this platform, or get a better
+compiler."
+
+ $opt_dry_run || $RM $removelist
+ exit $EXIT_FAILURE
+ fi
+
+ # Just move the object if needed, then go on to compile the next one
+ if test -n "$output_obj" && test "X$output_obj" != "X$lobj"; then
+ func_show_eval '$MV "$output_obj" "$lobj"' \
+ 'error=$?; $opt_dry_run || $RM $removelist; exit $error'
+ fi
+
+ # Allow error messages only from the first compilation.
+ if test "$suppress_opt" = yes; then
+ suppress_output=' >/dev/null 2>&1'
+ fi
+ fi
+
+ # Only build a position-dependent object if we build old libraries.
+ if test "$build_old_libs" = yes; then
+ if test "$pic_mode" != yes; then
+ # Don't build PIC code
+ command="$base_compile $qsrcfile$pie_flag"
+ else
+ command="$base_compile $qsrcfile $pic_flag"
+ fi
+ if test "$compiler_c_o" = yes; then
+ command="$command -o $obj"
+ fi
+
+ # Suppress compiler output if we already did a PIC compilation.
+ command="$command$suppress_output"
+ func_show_eval_locale "$command" \
+ '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE'
+
+ if test "$need_locks" = warn &&
+ test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then
+ $ECHO "\
+*** ERROR, $lockfile contains:
+`cat $lockfile 2>/dev/null`
+
+but it should contain:
+$srcfile
+
+This indicates that another process is trying to use the same
+temporary object file, and libtool could not work around it because
+your compiler does not support \`-c' and \`-o' together. If you
+repeat this compilation, it may succeed, by chance, but you had better
+avoid parallel builds (make -j) in this platform, or get a better
+compiler."
+
+ $opt_dry_run || $RM $removelist
+ exit $EXIT_FAILURE
+ fi
+
+ # Just move the object if needed
+ if test -n "$output_obj" && test "X$output_obj" != "X$obj"; then
+ func_show_eval '$MV "$output_obj" "$obj"' \
+ 'error=$?; $opt_dry_run || $RM $removelist; exit $error'
+ fi
+ fi
+
+ $opt_dry_run || {
+ func_write_libtool_object "$libobj" "$objdir/$objname" "$objname"
+
+ # Unlock the critical section if it was locked
+ if test "$need_locks" != no; then
+ removelist=$lockfile
+ $RM "$lockfile"
+ fi
+ }
+
+ exit $EXIT_SUCCESS
+}
+
+$opt_help || {
+test "$mode" = compile && func_mode_compile ${1+"$@"}
+}
+
+func_mode_help ()
+{
+ # We need to display help for each of the modes.
+ case $mode in
+ "")
+ # Generic help is extracted from the usage comments
+ # at the start of this file.
+ func_help
+ ;;
+
+ clean)
+ $ECHO \
+"Usage: $progname [OPTION]... --mode=clean RM [RM-OPTION]... FILE...
+
+Remove files from the build directory.
+
+RM is the name of the program to use to delete files associated with each FILE
+(typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed
+to RM.
+
+If FILE is a libtool library, object or program, all the files associated
+with it are deleted. Otherwise, only FILE itself is deleted using RM."
+ ;;
+
+ compile)
+ $ECHO \
+"Usage: $progname [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE
+
+Compile a source file into a libtool library object.
+
+This mode accepts the following additional options:
+
+ -o OUTPUT-FILE set the output file name to OUTPUT-FILE
+ -no-suppress do not suppress compiler output for multiple passes
+ -prefer-pic try to building PIC objects only
+ -prefer-non-pic try to building non-PIC objects only
+ -shared do not build a \`.o' file suitable for static linking
+ -static only build a \`.o' file suitable for static linking
+
+COMPILE-COMMAND is a command to be used in creating a \`standard' object file
+from the given SOURCEFILE.
+
+The output file name is determined by removing the directory component from
+SOURCEFILE, then substituting the C source code suffix \`.c' with the
+library object suffix, \`.lo'."
+ ;;
+
+ execute)
+ $ECHO \
+"Usage: $progname [OPTION]... --mode=execute COMMAND [ARGS]...
+
+Automatically set library path, then run a program.
+
+This mode accepts the following additional options:
+
+ -dlopen FILE add the directory containing FILE to the library path
+
+This mode sets the library path environment variable according to \`-dlopen'
+flags.
+
+If any of the ARGS are libtool executable wrappers, then they are translated
+into their corresponding uninstalled binary, and any of their required library
+directories are added to the library path.
+
+Then, COMMAND is executed, with ARGS as arguments."
+ ;;
+
+ finish)
+ $ECHO \
+"Usage: $progname [OPTION]... --mode=finish [LIBDIR]...
+
+Complete the installation of libtool libraries.
+
+Each LIBDIR is a directory that contains libtool libraries.
+
+The commands that this mode executes may require superuser privileges. Use
+the \`--dry-run' option if you just want to see what would be executed."
+ ;;
+
+ install)
+ $ECHO \
+"Usage: $progname [OPTION]... --mode=install INSTALL-COMMAND...
+
+Install executables or libraries.
+
+INSTALL-COMMAND is the installation command. The first component should be
+either the \`install' or \`cp' program.
+
+The following components of INSTALL-COMMAND are treated specially:
+
+ -inst-prefix PREFIX-DIR Use PREFIX-DIR as a staging area for installation
+
+The rest of the components are interpreted as arguments to that command (only
+BSD-compatible install options are recognized)."
+ ;;
+
+ link)
+ $ECHO \
+"Usage: $progname [OPTION]... --mode=link LINK-COMMAND...
+
+Link object files or libraries together to form another library, or to
+create an executable program.
+
+LINK-COMMAND is a command using the C compiler that you would use to create
+a program from several object files.
+
+The following components of LINK-COMMAND are treated specially:
+
+ -all-static do not do any dynamic linking at all
+ -avoid-version do not add a version suffix if possible
+ -dlopen FILE \`-dlpreopen' FILE if it cannot be dlopened at runtime
+ -dlpreopen FILE link in FILE and add its symbols to lt_preloaded_symbols
+ -export-dynamic allow symbols from OUTPUT-FILE to be resolved with dlsym(3)
+ -export-symbols SYMFILE
+ try to export only the symbols listed in SYMFILE
+ -export-symbols-regex REGEX
+ try to export only the symbols matching REGEX
+ -LLIBDIR search LIBDIR for required installed libraries
+ -lNAME OUTPUT-FILE requires the installed library libNAME
+ -module build a library that can dlopened
+ -no-fast-install disable the fast-install mode
+ -no-install link a not-installable executable
+ -no-undefined declare that a library does not refer to external symbols
+ -o OUTPUT-FILE create OUTPUT-FILE from the specified objects
+ -objectlist FILE Use a list of object files found in FILE to specify objects
+ -precious-files-regex REGEX
+ don't remove output files matching REGEX
+ -release RELEASE specify package release information
+ -rpath LIBDIR the created library will eventually be installed in LIBDIR
+ -R[ ]LIBDIR add LIBDIR to the runtime path of programs and libraries
+ -shared only do dynamic linking of libtool libraries
+ -shrext SUFFIX override the standard shared library file extension
+ -static do not do any dynamic linking of uninstalled libtool libraries
+ -static-libtool-libs
+ do not do any dynamic linking of libtool libraries
+ -version-info CURRENT[:REVISION[:AGE]]
+ specify library version info [each variable defaults to 0]
+ -weak LIBNAME declare that the target provides the LIBNAME interface
+
+All other options (arguments beginning with \`-') are ignored.
+
+Every other argument is treated as a filename. Files ending in \`.la' are
+treated as uninstalled libtool libraries, other files are standard or library
+object files.
+
+If the OUTPUT-FILE ends in \`.la', then a libtool library is created,
+only library objects (\`.lo' files) may be specified, and \`-rpath' is
+required, except when creating a convenience library.
+
+If OUTPUT-FILE ends in \`.a' or \`.lib', then a standard library is created
+using \`ar' and \`ranlib', or on Windows using \`lib'.
+
+If OUTPUT-FILE ends in \`.lo' or \`.${objext}', then a reloadable object file
+is created, otherwise an executable program is created."
+ ;;
+
+ uninstall)
+ $ECHO \
+"Usage: $progname [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE...
+
+Remove libraries from an installation directory.
+
+RM is the name of the program to use to delete files associated with each FILE
+(typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed
+to RM.
+
+If FILE is a libtool library, all the files associated with it are deleted.
+Otherwise, only FILE itself is deleted using RM."
+ ;;
+
+ *)
+ func_fatal_help "invalid operation mode \`$mode'"
+ ;;
+ esac
+
+ $ECHO
+ $ECHO "Try \`$progname --help' for more information about other modes."
+
+ exit $?
+}
+
+ # Now that we've collected a possible --mode arg, show help if necessary
+ $opt_help && func_mode_help
+
+
+# func_mode_execute arg...
+func_mode_execute ()
+{
+ $opt_debug
+ # The first argument is the command name.
+ cmd="$nonopt"
+ test -z "$cmd" && \
+ func_fatal_help "you must specify a COMMAND"
+
+ # Handle -dlopen flags immediately.
+ for file in $execute_dlfiles; do
+ test -f "$file" \
+ || func_fatal_help "\`$file' is not a file"
+
+ dir=
+ case $file in
+ *.la)
+ # Check to see that this really is a libtool archive.
+ func_lalib_unsafe_p "$file" \
+ || func_fatal_help "\`$lib' is not a valid libtool archive"
+
+ # Read the libtool library.
+ dlname=
+ library_names=
+ func_source "$file"
+
+ # Skip this library if it cannot be dlopened.
+ if test -z "$dlname"; then
+ # Warn if it was a shared library.
+ test -n "$library_names" && \
+ func_warning "\`$file' was not linked with \`-export-dynamic'"
+ continue
+ fi
+
+ func_dirname "$file" "" "."
+ dir="$func_dirname_result"
+
+ if test -f "$dir/$objdir/$dlname"; then
+ dir="$dir/$objdir"
+ else
+ if test ! -f "$dir/$dlname"; then
+ func_fatal_error "cannot find \`$dlname' in \`$dir' or \`$dir/$objdir'"
+ fi
+ fi
+ ;;
+
+ *.lo)
+ # Just add the directory containing the .lo file.
+ func_dirname "$file" "" "."
+ dir="$func_dirname_result"
+ ;;
+
+ *)
+ func_warning "\`-dlopen' is ignored for non-libtool libraries and objects"
+ continue
+ ;;
+ esac
+
+ # Get the absolute pathname.
+ absdir=`cd "$dir" && pwd`
+ test -n "$absdir" && dir="$absdir"
+
+ # Now add the directory to shlibpath_var.
+ if eval "test -z \"\$$shlibpath_var\""; then
+ eval "$shlibpath_var=\"\$dir\""
+ else
+ eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\""
+ fi
+ done
+
+ # This variable tells wrapper scripts just to set shlibpath_var
+ # rather than running their programs.
+ libtool_execute_magic="$magic"
+
+ # Check if any of the arguments is a wrapper script.
+ args=
+ for file
+ do
+ case $file in
+ -*) ;;
+ *)
+ # Do a test to see if this is really a libtool program.
+ if func_ltwrapper_script_p "$file"; then
+ func_source "$file"
+ # Transform arg to wrapped name.
+ file="$progdir/$program"
+ elif func_ltwrapper_executable_p "$file"; then
+ func_ltwrapper_scriptname "$file"
+ func_source "$func_ltwrapper_scriptname_result"
+ # Transform arg to wrapped name.
+ file="$progdir/$program"
+ fi
+ ;;
+ esac
+ # Quote arguments (to preserve shell metacharacters).
+ func_quote_for_eval "$file"
+ args="$args $func_quote_for_eval_result"
+ done
+
+ if test "X$opt_dry_run" = Xfalse; then
+ if test -n "$shlibpath_var"; then
+ # Export the shlibpath_var.
+ eval "export $shlibpath_var"
+ fi
+
+ # Restore saved environment variables
+ for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES
+ do
+ eval "if test \"\${save_$lt_var+set}\" = set; then
+ $lt_var=\$save_$lt_var; export $lt_var
+ else
+ $lt_unset $lt_var
+ fi"
+ done
+
+ # Now prepare to actually exec the command.
+ exec_cmd="\$cmd$args"
+ else
+ # Display what would be done.
+ if test -n "$shlibpath_var"; then
+ eval "\$ECHO \"\$shlibpath_var=\$$shlibpath_var\""
+ $ECHO "export $shlibpath_var"
+ fi
+ $ECHO "$cmd$args"
+ exit $EXIT_SUCCESS
+ fi
+}
+
+test "$mode" = execute && func_mode_execute ${1+"$@"}
+
+
+# func_mode_finish arg...
+func_mode_finish ()
+{
+ $opt_debug
+ libdirs="$nonopt"
+ admincmds=
+
+ if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then
+ for dir
+ do
+ libdirs="$libdirs $dir"
+ done
+
+ for libdir in $libdirs; do
+ if test -n "$finish_cmds"; then
+ # Do each command in the finish commands.
+ func_execute_cmds "$finish_cmds" 'admincmds="$admincmds
+'"$cmd"'"'
+ fi
+ if test -n "$finish_eval"; then
+ # Do the single finish_eval.
+ eval cmds=\"$finish_eval\"
+ $opt_dry_run || eval "$cmds" || admincmds="$admincmds
+ $cmds"
+ fi
+ done
+ fi
+
+ # Exit here if they wanted silent mode.
+ $opt_silent && exit $EXIT_SUCCESS
+
+ $ECHO "X----------------------------------------------------------------------" | $Xsed
+ $ECHO "Libraries have been installed in:"
+ for libdir in $libdirs; do
+ $ECHO " $libdir"
+ done
+ $ECHO
+ $ECHO "If you ever happen to want to link against installed libraries"
+ $ECHO "in a given directory, LIBDIR, you must either use libtool, and"
+ $ECHO "specify the full pathname of the library, or use the \`-LLIBDIR'"
+ $ECHO "flag during linking and do at least one of the following:"
+ if test -n "$shlibpath_var"; then
+ $ECHO " - add LIBDIR to the \`$shlibpath_var' environment variable"
+ $ECHO " during execution"
+ fi
+ if test -n "$runpath_var"; then
+ $ECHO " - add LIBDIR to the \`$runpath_var' environment variable"
+ $ECHO " during linking"
+ fi
+ if test -n "$hardcode_libdir_flag_spec"; then
+ libdir=LIBDIR
+ eval flag=\"$hardcode_libdir_flag_spec\"
+
+ $ECHO " - use the \`$flag' linker flag"
+ fi
+ if test -n "$admincmds"; then
+ $ECHO " - have your system administrator run these commands:$admincmds"
+ fi
+ if test -f /etc/ld.so.conf; then
+ $ECHO " - have your system administrator add LIBDIR to \`/etc/ld.so.conf'"
+ fi
+ $ECHO
+
+ $ECHO "See any operating system documentation about shared libraries for"
+ case $host in
+ solaris2.[6789]|solaris2.1[0-9])
+ $ECHO "more information, such as the ld(1), crle(1) and ld.so(8) manual"
+ $ECHO "pages."
+ ;;
+ *)
+ $ECHO "more information, such as the ld(1) and ld.so(8) manual pages."
+ ;;
+ esac
+ $ECHO "X----------------------------------------------------------------------" | $Xsed
+ exit $EXIT_SUCCESS
+}
+
+test "$mode" = finish && func_mode_finish ${1+"$@"}
+
+
+# func_mode_install arg...
+func_mode_install ()
+{
+ $opt_debug
+ # There may be an optional sh(1) argument at the beginning of
+ # install_prog (especially on Windows NT).
+ if test "$nonopt" = "$SHELL" || test "$nonopt" = /bin/sh ||
+ # Allow the use of GNU shtool's install command.
+ $ECHO "X$nonopt" | $GREP shtool >/dev/null; then
+ # Aesthetically quote it.
+ func_quote_for_eval "$nonopt"
+ install_prog="$func_quote_for_eval_result "
+ arg=$1
+ shift
+ else
+ install_prog=
+ arg=$nonopt
+ fi
+
+ # The real first argument should be the name of the installation program.
+ # Aesthetically quote it.
+ func_quote_for_eval "$arg"
+ install_prog="$install_prog$func_quote_for_eval_result"
+
+ # We need to accept at least all the BSD install flags.
+ dest=
+ files=
+ opts=
+ prev=
+ install_type=
+ isdir=no
+ stripme=
+ for arg
+ do
+ if test -n "$dest"; then
+ files="$files $dest"
+ dest=$arg
+ continue
+ fi
+
+ case $arg in
+ -d) isdir=yes ;;
+ -f)
+ case " $install_prog " in
+ *[\\\ /]cp\ *) ;;
+ *) prev=$arg ;;
+ esac
+ ;;
+ -g | -m | -o)
+ prev=$arg
+ ;;
+ -s)
+ stripme=" -s"
+ continue
+ ;;
+ -*)
+ ;;
+ *)
+ # If the previous option needed an argument, then skip it.
+ if test -n "$prev"; then
+ prev=
+ else
+ dest=$arg
+ continue
+ fi
+ ;;
+ esac
+
+ # Aesthetically quote the argument.
+ func_quote_for_eval "$arg"
+ install_prog="$install_prog $func_quote_for_eval_result"
+ done
+
+ test -z "$install_prog" && \
+ func_fatal_help "you must specify an install program"
+
+ test -n "$prev" && \
+ func_fatal_help "the \`$prev' option requires an argument"
+
+ if test -z "$files"; then
+ if test -z "$dest"; then
+ func_fatal_help "no file or destination specified"
+ else
+ func_fatal_help "you must specify a destination"
+ fi
+ fi
+
+ # Strip any trailing slash from the destination.
+ func_stripname '' '/' "$dest"
+ dest=$func_stripname_result
+
+ # Check to see that the destination is a directory.
+ test -d "$dest" && isdir=yes
+ if test "$isdir" = yes; then
+ destdir="$dest"
+ destname=
+ else
+ func_dirname_and_basename "$dest" "" "."
+ destdir="$func_dirname_result"
+ destname="$func_basename_result"
+
+ # Not a directory, so check to see that there is only one file specified.
+ set dummy $files; shift
+ test "$#" -gt 1 && \
+ func_fatal_help "\`$dest' is not a directory"
+ fi
+ case $destdir in
+ [\\/]* | [A-Za-z]:[\\/]*) ;;
+ *)
+ for file in $files; do
+ case $file in
+ *.lo) ;;
+ *)
+ func_fatal_help "\`$destdir' must be an absolute directory name"
+ ;;
+ esac
+ done
+ ;;
+ esac
+
+ # This variable tells wrapper scripts just to set variables rather
+ # than running their programs.
+ libtool_install_magic="$magic"
+
+ staticlibs=
+ future_libdirs=
+ current_libdirs=
+ for file in $files; do
+
+ # Do each installation.
+ case $file in
+ *.$libext)
+ # Do the static libraries later.
+ staticlibs="$staticlibs $file"
+ ;;
+
+ *.la)
+ # Check to see that this really is a libtool archive.
+ func_lalib_unsafe_p "$file" \
+ || func_fatal_help "\`$file' is not a valid libtool archive"
+
+ library_names=
+ old_library=
+ relink_command=
+ func_source "$file"
+
+ # Add the libdir to current_libdirs if it is the destination.
+ if test "X$destdir" = "X$libdir"; then
+ case "$current_libdirs " in
+ *" $libdir "*) ;;
+ *) current_libdirs="$current_libdirs $libdir" ;;
+ esac
+ else
+ # Note the libdir as a future libdir.
+ case "$future_libdirs " in
+ *" $libdir "*) ;;
+ *) future_libdirs="$future_libdirs $libdir" ;;
+ esac
+ fi
+
+ func_dirname "$file" "/" ""
+ dir="$func_dirname_result"
+ dir="$dir$objdir"
+
+ if test -n "$relink_command"; then
+ # Determine the prefix the user has applied to our future dir.
+ inst_prefix_dir=`$ECHO "X$destdir" | $Xsed -e "s%$libdir\$%%"`
+
+ # Don't allow the user to place us outside of our expected
+ # location b/c this prevents finding dependent libraries that
+ # are installed to the same prefix.
+ # At present, this check doesn't affect windows .dll's that
+ # are installed into $libdir/../bin (currently, that works fine)
+ # but it's something to keep an eye on.
+ test "$inst_prefix_dir" = "$destdir" && \
+ func_fatal_error "error: cannot install \`$file' to a directory not ending in $libdir"
+
+ if test -n "$inst_prefix_dir"; then
+ # Stick the inst_prefix_dir data into the link command.
+ relink_command=`$ECHO "X$relink_command" | $Xsed -e "s%@inst_prefix_dir@%-inst-prefix-dir $inst_prefix_dir%"`
+ else
+ relink_command=`$ECHO "X$relink_command" | $Xsed -e "s%@inst_prefix_dir@%%"`
+ fi
+
+ func_warning "relinking \`$file'"
+ func_show_eval "$relink_command" \
+ 'func_fatal_error "error: relink \`$file'\'' with the above command before installing it"'
+ fi
+
+ # See the names of the shared library.
+ set dummy $library_names; shift
+ if test -n "$1"; then
+ realname="$1"
+ shift
+
+ srcname="$realname"
+ test -n "$relink_command" && srcname="$realname"T
+
+ # Install the shared library and build the symlinks.
+ func_show_eval "$install_prog $dir/$srcname $destdir/$realname" \
+ 'exit $?'
+ tstripme="$stripme"
+ case $host_os in
+ cygwin* | mingw* | pw32* | cegcc*)
+ case $realname in
+ *.dll.a)
+ tstripme=""
+ ;;
+ esac
+ ;;
+ esac
+ if test -n "$tstripme" && test -n "$striplib"; then
+ func_show_eval "$striplib $destdir/$realname" 'exit $?'
+ fi
+
+ if test "$#" -gt 0; then
+ # Delete the old symlinks, and create new ones.
+ # Try `ln -sf' first, because the `ln' binary might depend on
+ # the symlink we replace! Solaris /bin/ln does not understand -f,
+ # so we also need to try rm && ln -s.
+ for linkname
+ do
+ test "$linkname" != "$realname" \
+ && func_show_eval "(cd $destdir && { $LN_S -f $realname $linkname || { $RM $linkname && $LN_S $realname $linkname; }; })"
+ done
+ fi
+
+ # Do each command in the postinstall commands.
+ lib="$destdir/$realname"
+ func_execute_cmds "$postinstall_cmds" 'exit $?'
+ fi
+
+ # Install the pseudo-library for information purposes.
+ func_basename "$file"
+ name="$func_basename_result"
+ instname="$dir/$name"i
+ func_show_eval "$install_prog $instname $destdir/$name" 'exit $?'
+
+ # Maybe install the static library, too.
+ test -n "$old_library" && staticlibs="$staticlibs $dir/$old_library"
+ ;;
+
+ *.lo)
+ # Install (i.e. copy) a libtool object.
+
+ # Figure out destination file name, if it wasn't already specified.
+ if test -n "$destname"; then
+ destfile="$destdir/$destname"
+ else
+ func_basename "$file"
+ destfile="$func_basename_result"
+ destfile="$destdir/$destfile"
+ fi
+
+ # Deduce the name of the destination old-style object file.
+ case $destfile in
+ *.lo)
+ func_lo2o "$destfile"
+ staticdest=$func_lo2o_result
+ ;;
+ *.$objext)
+ staticdest="$destfile"
+ destfile=
+ ;;
+ *)
+ func_fatal_help "cannot copy a libtool object to \`$destfile'"
+ ;;
+ esac
+
+ # Install the libtool object if requested.
+ test -n "$destfile" && \
+ func_show_eval "$install_prog $file $destfile" 'exit $?'
+
+ # Install the old object if enabled.
+ if test "$build_old_libs" = yes; then
+ # Deduce the name of the old-style object file.
+ func_lo2o "$file"
+ staticobj=$func_lo2o_result
+ func_show_eval "$install_prog \$staticobj \$staticdest" 'exit $?'
+ fi
+ exit $EXIT_SUCCESS
+ ;;
+
+ *)
+ # Figure out destination file name, if it wasn't already specified.
+ if test -n "$destname"; then
+ destfile="$destdir/$destname"
+ else
+ func_basename "$file"
+ destfile="$func_basename_result"
+ destfile="$destdir/$destfile"
+ fi
+
+ # If the file is missing, and there is a .exe on the end, strip it
+ # because it is most likely a libtool script we actually want to
+ # install
+ stripped_ext=""
+ case $file in
+ *.exe)
+ if test ! -f "$file"; then
+ func_stripname '' '.exe' "$file"
+ file=$func_stripname_result
+ stripped_ext=".exe"
+ fi
+ ;;
+ esac
+
+ # Do a test to see if this is really a libtool program.
+ case $host in
+ *cygwin* | *mingw*)
+ if func_ltwrapper_executable_p "$file"; then
+ func_ltwrapper_scriptname "$file"
+ wrapper=$func_ltwrapper_scriptname_result
+ else
+ func_stripname '' '.exe' "$file"
+ wrapper=$func_stripname_result
+ fi
+ ;;
+ *)
+ wrapper=$file
+ ;;
+ esac
+ if func_ltwrapper_script_p "$wrapper"; then
+ notinst_deplibs=
+ relink_command=
+
+ func_source "$wrapper"
+
+ # Check the variables that should have been set.
+ test -z "$generated_by_libtool_version" && \
+ func_fatal_error "invalid libtool wrapper script \`$wrapper'"
+
+ finalize=yes
+ for lib in $notinst_deplibs; do
+ # Check to see that each library is installed.
+ libdir=
+ if test -f "$lib"; then
+ func_source "$lib"
+ fi
+ libfile="$libdir/"`$ECHO "X$lib" | $Xsed -e 's%^.*/%%g'` ### testsuite: skip nested quoting test
+ if test -n "$libdir" && test ! -f "$libfile"; then
+ func_warning "\`$lib' has not been installed in \`$libdir'"
+ finalize=no
+ fi
+ done
+
+ relink_command=
+ func_source "$wrapper"
+
+ outputname=
+ if test "$fast_install" = no && test -n "$relink_command"; then
+ $opt_dry_run || {
+ if test "$finalize" = yes; then
+ tmpdir=`func_mktempdir`
+ func_basename "$file$stripped_ext"
+ file="$func_basename_result"
+ outputname="$tmpdir/$file"
+ # Replace the output file specification.
+ relink_command=`$ECHO "X$relink_command" | $Xsed -e 's%@OUTPUT@%'"$outputname"'%g'`
+
+ $opt_silent || {
+ func_quote_for_expand "$relink_command"
+ eval "func_echo $func_quote_for_expand_result"
+ }
+ if eval "$relink_command"; then :
+ else
+ func_error "error: relink \`$file' with the above command before installing it"
+ $opt_dry_run || ${RM}r "$tmpdir"
+ continue
+ fi
+ file="$outputname"
+ else
+ func_warning "cannot relink \`$file'"
+ fi
+ }
+ else
+ # Install the binary that we compiled earlier.
+ file=`$ECHO "X$file$stripped_ext" | $Xsed -e "s%\([^/]*\)$%$objdir/\1%"`
+ fi
+ fi
+
+ # remove .exe since cygwin /usr/bin/install will append another
+ # one anyway
+ case $install_prog,$host in
+ */usr/bin/install*,*cygwin*)
+ case $file:$destfile in
+ *.exe:*.exe)
+ # this is ok
+ ;;
+ *.exe:*)
+ destfile=$destfile.exe
+ ;;
+ *:*.exe)
+ func_stripname '' '.exe' "$destfile"
+ destfile=$func_stripname_result
+ ;;
+ esac
+ ;;
+ esac
+ func_show_eval "$install_prog\$stripme \$file \$destfile" 'exit $?'
+ $opt_dry_run || if test -n "$outputname"; then
+ ${RM}r "$tmpdir"
+ fi
+ ;;
+ esac
+ done
+
+ for file in $staticlibs; do
+ func_basename "$file"
+ name="$func_basename_result"
+
+ # Set up the ranlib parameters.
+ oldlib="$destdir/$name"
+
+ func_show_eval "$install_prog \$file \$oldlib" 'exit $?'
+
+ if test -n "$stripme" && test -n "$old_striplib"; then
+ func_show_eval "$old_striplib $oldlib" 'exit $?'
+ fi
+
+ # Do each command in the postinstall commands.
+ func_execute_cmds "$old_postinstall_cmds" 'exit $?'
+ done
+
+ test -n "$future_libdirs" && \
+ func_warning "remember to run \`$progname --finish$future_libdirs'"
+
+ if test -n "$current_libdirs"; then
+ # Maybe just do a dry run.
+ $opt_dry_run && current_libdirs=" -n$current_libdirs"
+ exec_cmd='$SHELL $progpath $preserve_args --finish$current_libdirs'
+ else
+ exit $EXIT_SUCCESS
+ fi
+}
+
+test "$mode" = install && func_mode_install ${1+"$@"}
+
+
+# func_generate_dlsyms outputname originator pic_p
+# Extract symbols from dlprefiles and create ${outputname}S.o with
+# a dlpreopen symbol table.
+func_generate_dlsyms ()
+{
+ $opt_debug
+ my_outputname="$1"
+ my_originator="$2"
+ my_pic_p="${3-no}"
+ my_prefix=`$ECHO "$my_originator" | sed 's%[^a-zA-Z0-9]%_%g'`
+ my_dlsyms=
+
+ if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
+ if test -n "$NM" && test -n "$global_symbol_pipe"; then
+ my_dlsyms="${my_outputname}S.c"
+ else
+ func_error "not configured to extract global symbols from dlpreopened files"
+ fi
+ fi
+
+ if test -n "$my_dlsyms"; then
+ case $my_dlsyms in
+ "") ;;
+ *.c)
+ # Discover the nlist of each of the dlfiles.
+ nlist="$output_objdir/${my_outputname}.nm"
+
+ func_show_eval "$RM $nlist ${nlist}S ${nlist}T"
+
+ # Parse the name list into a source file.
+ func_verbose "creating $output_objdir/$my_dlsyms"
+
+ $opt_dry_run || $ECHO > "$output_objdir/$my_dlsyms" "\
+/* $my_dlsyms - symbol resolution table for \`$my_outputname' dlsym emulation. */
+/* Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION */
+
+#ifdef __cplusplus
+extern \"C\" {
+#endif
+
+/* External symbol declarations for the compiler. */\
+"
+
+ if test "$dlself" = yes; then
+ func_verbose "generating symbol list for \`$output'"
+
+ $opt_dry_run || echo ': @PROGRAM@ ' > "$nlist"
+
+ # Add our own program objects to the symbol list.
+ progfiles=`$ECHO "X$objs$old_deplibs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP`
+ for progfile in $progfiles; do
+ func_verbose "extracting global C symbols from \`$progfile'"
+ $opt_dry_run || eval "$NM $progfile | $global_symbol_pipe >> '$nlist'"
+ done
+
+ if test -n "$exclude_expsyms"; then
+ $opt_dry_run || {
+ eval '$EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T'
+ eval '$MV "$nlist"T "$nlist"'
+ }
+ fi
+
+ if test -n "$export_symbols_regex"; then
+ $opt_dry_run || {
+ eval '$EGREP -e "$export_symbols_regex" "$nlist" > "$nlist"T'
+ eval '$MV "$nlist"T "$nlist"'
+ }
+ fi
+
+ # Prepare the list of exported symbols
+ if test -z "$export_symbols"; then
+ export_symbols="$output_objdir/$outputname.exp"
+ $opt_dry_run || {
+ $RM $export_symbols
+ eval "${SED} -n -e '/^: @PROGRAM@ $/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"'
+ case $host in
+ *cygwin* | *mingw* | *cegcc* )
+ eval "echo EXPORTS "'> "$output_objdir/$outputname.def"'
+ eval 'cat "$export_symbols" >> "$output_objdir/$outputname.def"'
+ ;;
+ esac
+ }
+ else
+ $opt_dry_run || {
+ eval "${SED} -e 's/\([].[*^$]\)/\\\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$outputname.exp"'
+ eval '$GREP -f "$output_objdir/$outputname.exp" < "$nlist" > "$nlist"T'
+ eval '$MV "$nlist"T "$nlist"'
+ case $host in
+ *cygwin | *mingw* | *cegcc* )
+ eval "echo EXPORTS "'> "$output_objdir/$outputname.def"'
+ eval 'cat "$nlist" >> "$output_objdir/$outputname.def"'
+ ;;
+ esac
+ }
+ fi
+ fi
+
+ for dlprefile in $dlprefiles; do
+ func_verbose "extracting global C symbols from \`$dlprefile'"
+ func_basename "$dlprefile"
+ name="$func_basename_result"
+ $opt_dry_run || {
+ eval '$ECHO ": $name " >> "$nlist"'
+ eval "$NM $dlprefile 2>/dev/null | $global_symbol_pipe >> '$nlist'"
+ }
+ done
+
+ $opt_dry_run || {
+ # Make sure we have at least an empty file.
+ test -f "$nlist" || : > "$nlist"
+
+ if test -n "$exclude_expsyms"; then
+ $EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T
+ $MV "$nlist"T "$nlist"
+ fi
+
+ # Try sorting and uniquifying the output.
+ if $GREP -v "^: " < "$nlist" |
+ if sort -k 3 </dev/null >/dev/null 2>&1; then
+ sort -k 3
+ else
+ sort +2
+ fi |
+ uniq > "$nlist"S; then
+ :
+ else
+ $GREP -v "^: " < "$nlist" > "$nlist"S
+ fi
+
+ if test -f "$nlist"S; then
+ eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$my_dlsyms"'
+ else
+ $ECHO '/* NONE */' >> "$output_objdir/$my_dlsyms"
+ fi
+
+ $ECHO >> "$output_objdir/$my_dlsyms" "\
+
+/* The mapping between symbol names and symbols. */
+typedef struct {
+ const char *name;
+ void *address;
+} lt_dlsymlist;
+"
+ case $host in
+ *cygwin* | *mingw* | *cegcc* )
+ $ECHO >> "$output_objdir/$my_dlsyms" "\
+/* DATA imports from DLLs on WIN32 con't be const, because
+ runtime relocations are performed -- see ld's documentation
+ on pseudo-relocs. */"
+ lt_dlsym_const= ;;
+ *osf5*)
+ echo >> "$output_objdir/$my_dlsyms" "\
+/* This system does not cope well with relocations in const data */"
+ lt_dlsym_const= ;;
+ *)
+ lt_dlsym_const=const ;;
+ esac
+
+ $ECHO >> "$output_objdir/$my_dlsyms" "\
+extern $lt_dlsym_const lt_dlsymlist
+lt_${my_prefix}_LTX_preloaded_symbols[];
+$lt_dlsym_const lt_dlsymlist
+lt_${my_prefix}_LTX_preloaded_symbols[] =
+{\
+ { \"$my_originator\", (void *) 0 },"
+
+ case $need_lib_prefix in
+ no)
+ eval "$global_symbol_to_c_name_address" < "$nlist" >> "$output_objdir/$my_dlsyms"
+ ;;
+ *)
+ eval "$global_symbol_to_c_name_address_lib_prefix" < "$nlist" >> "$output_objdir/$my_dlsyms"
+ ;;
+ esac
+ $ECHO >> "$output_objdir/$my_dlsyms" "\
+ {0, (void *) 0}
+};
+
+/* This works around a problem in FreeBSD linker */
+#ifdef FREEBSD_WORKAROUND
+static const void *lt_preloaded_setup() {
+ return lt_${my_prefix}_LTX_preloaded_symbols;
+}
+#endif
+
+#ifdef __cplusplus
+}
+#endif\
+"
+ } # !$opt_dry_run
+
+ pic_flag_for_symtable=
+ case "$compile_command " in
+ *" -static "*) ;;
+ *)
+ case $host in
+ # compiling the symbol table file with pic_flag works around
+ # a FreeBSD bug that causes programs to crash when -lm is
+ # linked before any other PIC object. But we must not use
+ # pic_flag when linking with -static. The problem exists in
+ # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1.
+ *-*-freebsd2*|*-*-freebsd3.0*|*-*-freebsdelf3.0*)
+ pic_flag_for_symtable=" $pic_flag -DFREEBSD_WORKAROUND" ;;
+ *-*-hpux*)
+ pic_flag_for_symtable=" $pic_flag" ;;
+ *)
+ if test "X$my_pic_p" != Xno; then
+ pic_flag_for_symtable=" $pic_flag"
+ fi
+ ;;
+ esac
+ ;;
+ esac
+ symtab_cflags=
+ for arg in $LTCFLAGS; do
+ case $arg in
+ -pie | -fpie | -fPIE) ;;
+ *) symtab_cflags="$symtab_cflags $arg" ;;
+ esac
+ done
+
+ # Now compile the dynamic symbol file.
+ func_show_eval '(cd $output_objdir && $LTCC$symtab_cflags -c$no_builtin_flag$pic_flag_for_symtable "$my_dlsyms")' 'exit $?'
+
+ # Clean up the generated files.
+ func_show_eval '$RM "$output_objdir/$my_dlsyms" "$nlist" "${nlist}S" "${nlist}T"'
+
+ # Transform the symbol file into the correct name.
+ symfileobj="$output_objdir/${my_outputname}S.$objext"
+ case $host in
+ *cygwin* | *mingw* | *cegcc* )
+ if test -f "$output_objdir/$my_outputname.def"; then
+ compile_command=`$ECHO "X$compile_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"`
+ finalize_command=`$ECHO "X$finalize_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"`
+ else
+ compile_command=`$ECHO "X$compile_command" | $Xsed -e "s%@SYMFILE@%$symfileobj%"`
+ finalize_command=`$ECHO "X$finalize_command" | $Xsed -e "s%@SYMFILE@%$symfileobj%"`
+ fi
+ ;;
+ *)
+ compile_command=`$ECHO "X$compile_command" | $Xsed -e "s%@SYMFILE@%$symfileobj%"`
+ finalize_command=`$ECHO "X$finalize_command" | $Xsed -e "s%@SYMFILE@%$symfileobj%"`
+ ;;
+ esac
+ ;;
+ *)
+ func_fatal_error "unknown suffix for \`$my_dlsyms'"
+ ;;
+ esac
+ else
+ # We keep going just in case the user didn't refer to
+ # lt_preloaded_symbols. The linker will fail if global_symbol_pipe
+ # really was required.
+
+ # Nullify the symbol file.
+ compile_command=`$ECHO "X$compile_command" | $Xsed -e "s% @SYMFILE@%%"`
+ finalize_command=`$ECHO "X$finalize_command" | $Xsed -e "s% @SYMFILE@%%"`
+ fi
+}
+
+# func_win32_libid arg
+# return the library type of file 'arg'
+#
+# Need a lot of goo to handle *both* DLLs and import libs
+# Has to be a shell function in order to 'eat' the argument
+# that is supplied when $file_magic_command is called.
+func_win32_libid ()
+{
+ $opt_debug
+ win32_libid_type="unknown"
+ win32_fileres=`file -L $1 2>/dev/null`
+ case $win32_fileres in
+ *ar\ archive\ import\ library*) # definitely import
+ win32_libid_type="x86 archive import"
+ ;;
+ *ar\ archive*) # could be an import, or static
+ if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null |
+ $EGREP 'file format pe-i386(.*architecture: i386)?' >/dev/null ; then
+ win32_nmres=`eval $NM -f posix -A $1 |
+ $SED -n -e '
+ 1,100{
+ / I /{
+ s,.*,import,
+ p
+ q
+ }
+ }'`
+ case $win32_nmres in
+ import*) win32_libid_type="x86 archive import";;
+ *) win32_libid_type="x86 archive static";;
+ esac
+ fi
+ ;;
+ *DLL*)
+ win32_libid_type="x86 DLL"
+ ;;
+ *executable*) # but shell scripts are "executable" too...
+ case $win32_fileres in
+ *MS\ Windows\ PE\ Intel*)
+ win32_libid_type="x86 DLL"
+ ;;
+ esac
+ ;;
+ esac
+ $ECHO "$win32_libid_type"
+}
+
+
+
+# func_extract_an_archive dir oldlib
+func_extract_an_archive ()
+{
+ $opt_debug
+ f_ex_an_ar_dir="$1"; shift
+ f_ex_an_ar_oldlib="$1"
+ func_show_eval "(cd \$f_ex_an_ar_dir && $AR x \"\$f_ex_an_ar_oldlib\")" 'exit $?'
+ if ($AR t "$f_ex_an_ar_oldlib" | sort | sort -uc >/dev/null 2>&1); then
+ :
+ else
+ func_fatal_error "object name conflicts in archive: $f_ex_an_ar_dir/$f_ex_an_ar_oldlib"
+ fi
+}
+
+
+# func_extract_archives gentop oldlib ...
+func_extract_archives ()
+{
+ $opt_debug
+ my_gentop="$1"; shift
+ my_oldlibs=${1+"$@"}
+ my_oldobjs=""
+ my_xlib=""
+ my_xabs=""
+ my_xdir=""
+
+ for my_xlib in $my_oldlibs; do
+ # Extract the objects.
+ case $my_xlib in
+ [\\/]* | [A-Za-z]:[\\/]*) my_xabs="$my_xlib" ;;
+ *) my_xabs=`pwd`"/$my_xlib" ;;
+ esac
+ func_basename "$my_xlib"
+ my_xlib="$func_basename_result"
+ my_xlib_u=$my_xlib
+ while :; do
+ case " $extracted_archives " in
+ *" $my_xlib_u "*)
+ func_arith $extracted_serial + 1
+ extracted_serial=$func_arith_result
+ my_xlib_u=lt$extracted_serial-$my_xlib ;;
+ *) break ;;
+ esac
+ done
+ extracted_archives="$extracted_archives $my_xlib_u"
+ my_xdir="$my_gentop/$my_xlib_u"
+
+ func_mkdir_p "$my_xdir"
+
+ case $host in
+ *-darwin*)
+ func_verbose "Extracting $my_xabs"
+ # Do not bother doing anything if just a dry run
+ $opt_dry_run || {
+ darwin_orig_dir=`pwd`
+ cd $my_xdir || exit $?
+ darwin_archive=$my_xabs
+ darwin_curdir=`pwd`
+ darwin_base_archive=`basename "$darwin_archive"`
+ darwin_arches=`$LIPO -info "$darwin_archive" 2>/dev/null | $GREP Architectures 2>/dev/null || true`
+ if test -n "$darwin_arches"; then
+ darwin_arches=`$ECHO "$darwin_arches" | $SED -e 's/.*are://'`
+ darwin_arch=
+ func_verbose "$darwin_base_archive has multiple architectures $darwin_arches"
+ for darwin_arch in $darwin_arches ; do
+ func_mkdir_p "unfat-$$/${darwin_base_archive}-${darwin_arch}"
+ $LIPO -thin $darwin_arch -output "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" "${darwin_archive}"
+ cd "unfat-$$/${darwin_base_archive}-${darwin_arch}"
+ func_extract_an_archive "`pwd`" "${darwin_base_archive}"
+ cd "$darwin_curdir"
+ $RM "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}"
+ done # $darwin_arches
+ ## Okay now we've a bunch of thin objects, gotta fatten them up :)
+ darwin_filelist=`find unfat-$$ -type f -name \*.o -print -o -name \*.lo -print | $SED -e "$basename" | sort -u`
+ darwin_file=
+ darwin_files=
+ for darwin_file in $darwin_filelist; do
+ darwin_files=`find unfat-$$ -name $darwin_file -print | $NL2SP`
+ $LIPO -create -output "$darwin_file" $darwin_files
+ done # $darwin_filelist
+ $RM -rf unfat-$$
+ cd "$darwin_orig_dir"
+ else
+ cd $darwin_orig_dir
+ func_extract_an_archive "$my_xdir" "$my_xabs"
+ fi # $darwin_arches
+ } # !$opt_dry_run
+ ;;
+ *)
+ func_extract_an_archive "$my_xdir" "$my_xabs"
+ ;;
+ esac
+ my_oldobjs="$my_oldobjs "`find $my_xdir -name \*.$objext -print -o -name \*.lo -print | $NL2SP`
+ done
+
+ func_extract_archives_result="$my_oldobjs"
+}
+
+
+
+# func_emit_wrapper_part1 [arg=no]
+#
+# Emit the first part of a libtool wrapper script on stdout.
+# For more information, see the description associated with
+# func_emit_wrapper(), below.
+func_emit_wrapper_part1 ()
+{
+ func_emit_wrapper_part1_arg1=no
+ if test -n "$1" ; then
+ func_emit_wrapper_part1_arg1=$1
+ fi
+
+ $ECHO "\
+#! $SHELL
+
+# $output - temporary wrapper script for $objdir/$outputname
+# Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION
+#
+# The $output program cannot be directly executed until all the libtool
+# libraries that it depends on are installed.
+#
+# This wrapper script should never be moved out of the build directory.
+# If it is, it will not operate correctly.
+
+# Sed substitution that helps us do robust quoting. It backslashifies
+# metacharacters that are still active within double-quoted strings.
+Xsed='${SED} -e 1s/^X//'
+sed_quote_subst='$sed_quote_subst'
+
+# Be Bourne compatible
+if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then
+ emulate sh
+ NULLCMD=:
+ # Zsh 3.x and 4.x performs word splitting on \${1+\"\$@\"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '\${1+\"\$@\"}'='\"\$@\"'
+ setopt NO_GLOB_SUBST
+else
+ case \`(set -o) 2>/dev/null\` in *posix*) set -o posix;; esac
+fi
+BIN_SH=xpg4; export BIN_SH # for Tru64
+DUALCASE=1; export DUALCASE # for MKS sh
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+relink_command=\"$relink_command\"
+
+# This environment variable determines our operation mode.
+if test \"\$libtool_install_magic\" = \"$magic\"; then
+ # install mode needs the following variables:
+ generated_by_libtool_version='$macro_version'
+ notinst_deplibs='$notinst_deplibs'
+else
+ # When we are sourced in execute mode, \$file and \$ECHO are already set.
+ if test \"\$libtool_execute_magic\" != \"$magic\"; then
+ ECHO=\"$qecho\"
+ file=\"\$0\"
+ # Make sure echo works.
+ if test \"X\$1\" = X--no-reexec; then
+ # Discard the --no-reexec flag, and continue.
+ shift
+ elif test \"X\`{ \$ECHO '\t'; } 2>/dev/null\`\" = 'X\t'; then
+ # Yippee, \$ECHO works!
+ :
+ else
+ # Restart under the correct shell, and then maybe \$ECHO will work.
+ exec $SHELL \"\$0\" --no-reexec \${1+\"\$@\"}
+ fi
+ fi\
+"
+ $ECHO "\
+
+ # Find the directory that this script lives in.
+ thisdir=\`\$ECHO \"X\$file\" | \$Xsed -e 's%/[^/]*$%%'\`
+ test \"x\$thisdir\" = \"x\$file\" && thisdir=.
+
+ # Follow symbolic links until we get to the real thisdir.
+ file=\`ls -ld \"\$file\" | ${SED} -n 's/.*-> //p'\`
+ while test -n \"\$file\"; do
+ destdir=\`\$ECHO \"X\$file\" | \$Xsed -e 's%/[^/]*\$%%'\`
+
+ # If there was a directory component, then change thisdir.
+ if test \"x\$destdir\" != \"x\$file\"; then
+ case \"\$destdir\" in
+ [\\\\/]* | [A-Za-z]:[\\\\/]*) thisdir=\"\$destdir\" ;;
+ *) thisdir=\"\$thisdir/\$destdir\" ;;
+ esac
+ fi
+
+ file=\`\$ECHO \"X\$file\" | \$Xsed -e 's%^.*/%%'\`
+ file=\`ls -ld \"\$thisdir/\$file\" | ${SED} -n 's/.*-> //p'\`
+ done
+"
+}
+# end: func_emit_wrapper_part1
+
+# func_emit_wrapper_part2 [arg=no]
+#
+# Emit the second part of a libtool wrapper script on stdout.
+# For more information, see the description associated with
+# func_emit_wrapper(), below.
+func_emit_wrapper_part2 ()
+{
+ func_emit_wrapper_part2_arg1=no
+ if test -n "$1" ; then
+ func_emit_wrapper_part2_arg1=$1
+ fi
+
+ $ECHO "\
+
+ # Usually 'no', except on cygwin/mingw when embedded into
+ # the cwrapper.
+ WRAPPER_SCRIPT_BELONGS_IN_OBJDIR=$func_emit_wrapper_part2_arg1
+ if test \"\$WRAPPER_SCRIPT_BELONGS_IN_OBJDIR\" = \"yes\"; then
+ # special case for '.'
+ if test \"\$thisdir\" = \".\"; then
+ thisdir=\`pwd\`
+ fi
+ # remove .libs from thisdir
+ case \"\$thisdir\" in
+ *[\\\\/]$objdir ) thisdir=\`\$ECHO \"X\$thisdir\" | \$Xsed -e 's%[\\\\/][^\\\\/]*$%%'\` ;;
+ $objdir ) thisdir=. ;;
+ esac
+ fi
+
+ # Try to get the absolute directory name.
+ absdir=\`cd \"\$thisdir\" && pwd\`
+ test -n \"\$absdir\" && thisdir=\"\$absdir\"
+"
+
+ if test "$fast_install" = yes; then
+ $ECHO "\
+ program=lt-'$outputname'$exeext
+ progdir=\"\$thisdir/$objdir\"
+
+ if test ! -f \"\$progdir/\$program\" ||
+ { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | ${SED} 1q\`; \\
+ test \"X\$file\" != \"X\$progdir/\$program\"; }; then
+
+ file=\"\$\$-\$program\"
+
+ if test ! -d \"\$progdir\"; then
+ $MKDIR \"\$progdir\"
+ else
+ $RM \"\$progdir/\$file\"
+ fi"
+
+ $ECHO "\
+
+ # relink executable if necessary
+ if test -n \"\$relink_command\"; then
+ if relink_command_output=\`eval \$relink_command 2>&1\`; then :
+ else
+ $ECHO \"\$relink_command_output\" >&2
+ $RM \"\$progdir/\$file\"
+ exit 1
+ fi
+ fi
+
+ $MV \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null ||
+ { $RM \"\$progdir/\$program\";
+ $MV \"\$progdir/\$file\" \"\$progdir/\$program\"; }
+ $RM \"\$progdir/\$file\"
+ fi"
+ else
+ $ECHO "\
+ program='$outputname'
+ progdir=\"\$thisdir/$objdir\"
+"
+ fi
+
+ $ECHO "\
+
+ if test -f \"\$progdir/\$program\"; then"
+
+ # Export our shlibpath_var if we have one.
+ if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then
+ $ECHO "\
+ # Add our own library path to $shlibpath_var
+ $shlibpath_var=\"$temp_rpath\$$shlibpath_var\"
+
+ # Some systems cannot cope with colon-terminated $shlibpath_var
+ # The second colon is a workaround for a bug in BeOS R4 sed
+ $shlibpath_var=\`\$ECHO \"X\$$shlibpath_var\" | \$Xsed -e 's/::*\$//'\`
+
+ export $shlibpath_var
+"
+ fi
+
+ # fixup the dll searchpath if we need to.
+ if test -n "$dllsearchpath"; then
+ $ECHO "\
+ # Add the dll search path components to the executable PATH
+ PATH=$dllsearchpath:\$PATH
+"
+ fi
+
+ $ECHO "\
+ if test \"\$libtool_execute_magic\" != \"$magic\"; then
+ # Run the actual program with our arguments.
+"
+ case $host in
+ # Backslashes separate directories on plain windows
+ *-*-mingw | *-*-os2* | *-cegcc*)
+ $ECHO "\
+ exec \"\$progdir\\\\\$program\" \${1+\"\$@\"}
+"
+ ;;
+
+ *)
+ $ECHO "\
+ exec \"\$progdir/\$program\" \${1+\"\$@\"}
+"
+ ;;
+ esac
+ $ECHO "\
+ \$ECHO \"\$0: cannot exec \$program \$*\" 1>&2
+ exit 1
+ fi
+ else
+ # The program doesn't exist.
+ \$ECHO \"\$0: error: \\\`\$progdir/\$program' does not exist\" 1>&2
+ \$ECHO \"This script is just a wrapper for \$program.\" 1>&2
+ $ECHO \"See the $PACKAGE documentation for more information.\" 1>&2
+ exit 1
+ fi
+fi\
+"
+}
+# end: func_emit_wrapper_part2
+
+
+# func_emit_wrapper [arg=no]
+#
+# Emit a libtool wrapper script on stdout.
+# Don't directly open a file because we may want to
+# incorporate the script contents within a cygwin/mingw
+# wrapper executable. Must ONLY be called from within
+# func_mode_link because it depends on a number of variables
+# set therein.
+#
+# ARG is the value that the WRAPPER_SCRIPT_BELONGS_IN_OBJDIR
+# variable will take. If 'yes', then the emitted script
+# will assume that the directory in which it is stored is
+# the $objdir directory. This is a cygwin/mingw-specific
+# behavior.
+func_emit_wrapper ()
+{
+ func_emit_wrapper_arg1=no
+ if test -n "$1" ; then
+ func_emit_wrapper_arg1=$1
+ fi
+
+ # split this up so that func_emit_cwrapperexe_src
+ # can call each part independently.
+ func_emit_wrapper_part1 "${func_emit_wrapper_arg1}"
+ func_emit_wrapper_part2 "${func_emit_wrapper_arg1}"
+}
+
+
+# func_to_host_path arg
+#
+# Convert paths to host format when used with build tools.
+# Intended for use with "native" mingw (where libtool itself
+# is running under the msys shell), or in the following cross-
+# build environments:
+# $build $host
+# mingw (msys) mingw [e.g. native]
+# cygwin mingw
+# *nix + wine mingw
+# where wine is equipped with the `winepath' executable.
+# In the native mingw case, the (msys) shell automatically
+# converts paths for any non-msys applications it launches,
+# but that facility isn't available from inside the cwrapper.
+# Similar accommodations are necessary for $host mingw and
+# $build cygwin. Calling this function does no harm for other
+# $host/$build combinations not listed above.
+#
+# ARG is the path (on $build) that should be converted to
+# the proper representation for $host. The result is stored
+# in $func_to_host_path_result.
+func_to_host_path ()
+{
+ func_to_host_path_result="$1"
+ if test -n "$1" ; then
+ case $host in
+ *mingw* )
+ lt_sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g'
+ case $build in
+ *mingw* ) # actually, msys
+ # awkward: cmd appends spaces to result
+ lt_sed_strip_trailing_spaces="s/[ ]*\$//"
+ func_to_host_path_tmp1=`( cmd //c echo "$1" |\
+ $SED -e "$lt_sed_strip_trailing_spaces" ) 2>/dev/null || echo ""`
+ func_to_host_path_result=`echo "$func_to_host_path_tmp1" |\
+ $SED -e "$lt_sed_naive_backslashify"`
+ ;;
+ *cygwin* )
+ func_to_host_path_tmp1=`cygpath -w "$1"`
+ func_to_host_path_result=`echo "$func_to_host_path_tmp1" |\
+ $SED -e "$lt_sed_naive_backslashify"`
+ ;;
+ * )
+ # Unfortunately, winepath does not exit with a non-zero
+ # error code, so we are forced to check the contents of
+ # stdout. On the other hand, if the command is not
+ # found, the shell will set an exit code of 127 and print
+ # *an error message* to stdout. So we must check for both
+ # error code of zero AND non-empty stdout, which explains
+ # the odd construction:
+ func_to_host_path_tmp1=`winepath -w "$1" 2>/dev/null`
+ if test "$?" -eq 0 && test -n "${func_to_host_path_tmp1}"; then
+ func_to_host_path_result=`echo "$func_to_host_path_tmp1" |\
+ $SED -e "$lt_sed_naive_backslashify"`
+ else
+ # Allow warning below.
+ func_to_host_path_result=""
+ fi
+ ;;
+ esac
+ if test -z "$func_to_host_path_result" ; then
+ func_error "Could not determine host path corresponding to"
+ func_error " '$1'"
+ func_error "Continuing, but uninstalled executables may not work."
+ # Fallback:
+ func_to_host_path_result="$1"
+ fi
+ ;;
+ esac
+ fi
+}
+# end: func_to_host_path
+
+# func_to_host_pathlist arg
+#
+# Convert pathlists to host format when used with build tools.
+# See func_to_host_path(), above. This function supports the
+# following $build/$host combinations (but does no harm for
+# combinations not listed here):
+# $build $host
+# mingw (msys) mingw [e.g. native]
+# cygwin mingw
+# *nix + wine mingw
+#
+# Path separators are also converted from $build format to
+# $host format. If ARG begins or ends with a path separator
+# character, it is preserved (but converted to $host format)
+# on output.
+#
+# ARG is a pathlist (on $build) that should be converted to
+# the proper representation on $host. The result is stored
+# in $func_to_host_pathlist_result.
+func_to_host_pathlist ()
+{
+ func_to_host_pathlist_result="$1"
+ if test -n "$1" ; then
+ case $host in
+ *mingw* )
+ lt_sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g'
+ # Remove leading and trailing path separator characters from
+ # ARG. msys behavior is inconsistent here, cygpath turns them
+ # into '.;' and ';.', and winepath ignores them completely.
+ func_to_host_pathlist_tmp2="$1"
+ # Once set for this call, this variable should not be
+ # reassigned. It is used in tha fallback case.
+ func_to_host_pathlist_tmp1=`echo "$func_to_host_pathlist_tmp2" |\
+ $SED -e 's|^:*||' -e 's|:*$||'`
+ case $build in
+ *mingw* ) # Actually, msys.
+ # Awkward: cmd appends spaces to result.
+ lt_sed_strip_trailing_spaces="s/[ ]*\$//"
+ func_to_host_pathlist_tmp2=`( cmd //c echo "$func_to_host_pathlist_tmp1" |\
+ $SED -e "$lt_sed_strip_trailing_spaces" ) 2>/dev/null || echo ""`
+ func_to_host_pathlist_result=`echo "$func_to_host_pathlist_tmp2" |\
+ $SED -e "$lt_sed_naive_backslashify"`
+ ;;
+ *cygwin* )
+ func_to_host_pathlist_tmp2=`cygpath -w -p "$func_to_host_pathlist_tmp1"`
+ func_to_host_pathlist_result=`echo "$func_to_host_pathlist_tmp2" |\
+ $SED -e "$lt_sed_naive_backslashify"`
+ ;;
+ * )
+ # unfortunately, winepath doesn't convert pathlists
+ func_to_host_pathlist_result=""
+ func_to_host_pathlist_oldIFS=$IFS
+ IFS=:
+ for func_to_host_pathlist_f in $func_to_host_pathlist_tmp1 ; do
+ IFS=$func_to_host_pathlist_oldIFS
+ if test -n "$func_to_host_pathlist_f" ; then
+ func_to_host_path "$func_to_host_pathlist_f"
+ if test -n "$func_to_host_path_result" ; then
+ if test -z "$func_to_host_pathlist_result" ; then
+ func_to_host_pathlist_result="$func_to_host_path_result"
+ else
+ func_to_host_pathlist_result="$func_to_host_pathlist_result;$func_to_host_path_result"
+ fi
+ fi
+ fi
+ IFS=:
+ done
+ IFS=$func_to_host_pathlist_oldIFS
+ ;;
+ esac
+ if test -z "$func_to_host_pathlist_result" ; then
+ func_error "Could not determine the host path(s) corresponding to"
+ func_error " '$1'"
+ func_error "Continuing, but uninstalled executables may not work."
+ # Fallback. This may break if $1 contains DOS-style drive
+ # specifications. The fix is not to complicate the expression
+ # below, but for the user to provide a working wine installation
+ # with winepath so that path translation in the cross-to-mingw
+ # case works properly.
+ lt_replace_pathsep_nix_to_dos="s|:|;|g"
+ func_to_host_pathlist_result=`echo "$func_to_host_pathlist_tmp1" |\
+ $SED -e "$lt_replace_pathsep_nix_to_dos"`
+ fi
+ # Now, add the leading and trailing path separators back
+ case "$1" in
+ :* ) func_to_host_pathlist_result=";$func_to_host_pathlist_result"
+ ;;
+ esac
+ case "$1" in
+ *: ) func_to_host_pathlist_result="$func_to_host_pathlist_result;"
+ ;;
+ esac
+ ;;
+ esac
+ fi
+}
+# end: func_to_host_pathlist
+
+# func_emit_cwrapperexe_src
+# emit the source code for a wrapper executable on stdout
+# Must ONLY be called from within func_mode_link because
+# it depends on a number of variable set therein.
+func_emit_cwrapperexe_src ()
+{
+ cat <<EOF
+
+/* $cwrappersource - temporary wrapper executable for $objdir/$outputname
+ Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION
+
+ The $output program cannot be directly executed until all the libtool
+ libraries that it depends on are installed.
+
+ This wrapper executable should never be moved out of the build directory.
+ If it is, it will not operate correctly.
+
+ Currently, it simply execs the wrapper *script* "$SHELL $output",
+ but could eventually absorb all of the scripts functionality and
+ exec $objdir/$outputname directly.
+*/
+EOF
+ cat <<"EOF"
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef _MSC_VER
+# include <direct.h>
+# include <process.h>
+# include <io.h>
+# define setmode _setmode
+#else
+# include <unistd.h>
+# include <stdint.h>
+# ifdef __CYGWIN__
+# include <io.h>
+# define HAVE_SETENV
+# ifdef __STRICT_ANSI__
+char *realpath (const char *, char *);
+int putenv (char *);
+int setenv (const char *, const char *, int);
+# endif
+# endif
+#endif
+#include <malloc.h>
+#include <stdarg.h>
+#include <assert.h>
+#include <string.h>
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+
+#if defined(PATH_MAX)
+# define LT_PATHMAX PATH_MAX
+#elif defined(MAXPATHLEN)
+# define LT_PATHMAX MAXPATHLEN
+#else
+# define LT_PATHMAX 1024
+#endif
+
+#ifndef S_IXOTH
+# define S_IXOTH 0
+#endif
+#ifndef S_IXGRP
+# define S_IXGRP 0
+#endif
+
+#ifdef _MSC_VER
+# define S_IXUSR _S_IEXEC
+# define stat _stat
+# ifndef _INTPTR_T_DEFINED
+# define intptr_t int
+# endif
+#endif
+
+#ifndef DIR_SEPARATOR
+# define DIR_SEPARATOR '/'
+# define PATH_SEPARATOR ':'
+#endif
+
+#if defined (_WIN32) || defined (__MSDOS__) || defined (__DJGPP__) || \
+ defined (__OS2__)
+# define HAVE_DOS_BASED_FILE_SYSTEM
+# define FOPEN_WB "wb"
+# ifndef DIR_SEPARATOR_2
+# define DIR_SEPARATOR_2 '\\'
+# endif
+# ifndef PATH_SEPARATOR_2
+# define PATH_SEPARATOR_2 ';'
+# endif
+#endif
+
+#ifndef DIR_SEPARATOR_2
+# define IS_DIR_SEPARATOR(ch) ((ch) == DIR_SEPARATOR)
+#else /* DIR_SEPARATOR_2 */
+# define IS_DIR_SEPARATOR(ch) \
+ (((ch) == DIR_SEPARATOR) || ((ch) == DIR_SEPARATOR_2))
+#endif /* DIR_SEPARATOR_2 */
+
+#ifndef PATH_SEPARATOR_2
+# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR)
+#else /* PATH_SEPARATOR_2 */
+# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR_2)
+#endif /* PATH_SEPARATOR_2 */
+
+#ifdef __CYGWIN__
+# define FOPEN_WB "wb"
+#endif
+
+#ifndef FOPEN_WB
+# define FOPEN_WB "w"
+#endif
+#ifndef _O_BINARY
+# define _O_BINARY 0
+#endif
+
+#define XMALLOC(type, num) ((type *) xmalloc ((num) * sizeof(type)))
+#define XFREE(stale) do { \
+ if (stale) { free ((void *) stale); stale = 0; } \
+} while (0)
+
+#undef LTWRAPPER_DEBUGPRINTF
+#if defined DEBUGWRAPPER
+# define LTWRAPPER_DEBUGPRINTF(args) ltwrapper_debugprintf args
+static void
+ltwrapper_debugprintf (const char *fmt, ...)
+{
+ va_list args;
+ va_start (args, fmt);
+ (void) vfprintf (stderr, fmt, args);
+ va_end (args);
+}
+#else
+# define LTWRAPPER_DEBUGPRINTF(args)
+#endif
+
+const char *program_name = NULL;
+
+void *xmalloc (size_t num);
+char *xstrdup (const char *string);
+const char *base_name (const char *name);
+char *find_executable (const char *wrapper);
+char *chase_symlinks (const char *pathspec);
+int make_executable (const char *path);
+int check_executable (const char *path);
+char *strendzap (char *str, const char *pat);
+void lt_fatal (const char *message, ...);
+void lt_setenv (const char *name, const char *value);
+char *lt_extend_str (const char *orig_value, const char *add, int to_end);
+void lt_opt_process_env_set (const char *arg);
+void lt_opt_process_env_prepend (const char *arg);
+void lt_opt_process_env_append (const char *arg);
+int lt_split_name_value (const char *arg, char** name, char** value);
+void lt_update_exe_path (const char *name, const char *value);
+void lt_update_lib_path (const char *name, const char *value);
+
+static const char *script_text_part1 =
+EOF
+
+ func_emit_wrapper_part1 yes |
+ $SED -e 's/\([\\"]\)/\\\1/g' \
+ -e 's/^/ "/' -e 's/$/\\n"/'
+ echo ";"
+ cat <<EOF
+
+static const char *script_text_part2 =
+EOF
+ func_emit_wrapper_part2 yes |
+ $SED -e 's/\([\\"]\)/\\\1/g' \
+ -e 's/^/ "/' -e 's/$/\\n"/'
+ echo ";"
+
+ cat <<EOF
+const char * MAGIC_EXE = "$magic_exe";
+const char * LIB_PATH_VARNAME = "$shlibpath_var";
+EOF
+
+ if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then
+ func_to_host_pathlist "$temp_rpath"
+ cat <<EOF
+const char * LIB_PATH_VALUE = "$func_to_host_pathlist_result";
+EOF
+ else
+ cat <<"EOF"
+const char * LIB_PATH_VALUE = "";
+EOF
+ fi
+
+ if test -n "$dllsearchpath"; then
+ func_to_host_pathlist "$dllsearchpath:"
+ cat <<EOF
+const char * EXE_PATH_VARNAME = "PATH";
+const char * EXE_PATH_VALUE = "$func_to_host_pathlist_result";
+EOF
+ else
+ cat <<"EOF"
+const char * EXE_PATH_VARNAME = "";
+const char * EXE_PATH_VALUE = "";
+EOF
+ fi
+
+ if test "$fast_install" = yes; then
+ cat <<EOF
+const char * TARGET_PROGRAM_NAME = "lt-$outputname"; /* hopefully, no .exe */
+EOF
+ else
+ cat <<EOF
+const char * TARGET_PROGRAM_NAME = "$outputname"; /* hopefully, no .exe */
+EOF
+ fi
+
+
+ cat <<"EOF"
+
+#define LTWRAPPER_OPTION_PREFIX "--lt-"
+#define LTWRAPPER_OPTION_PREFIX_LENGTH 5
+
+static const size_t opt_prefix_len = LTWRAPPER_OPTION_PREFIX_LENGTH;
+static const char *ltwrapper_option_prefix = LTWRAPPER_OPTION_PREFIX;
+
+static const char *dumpscript_opt = LTWRAPPER_OPTION_PREFIX "dump-script";
+
+static const size_t env_set_opt_len = LTWRAPPER_OPTION_PREFIX_LENGTH + 7;
+static const char *env_set_opt = LTWRAPPER_OPTION_PREFIX "env-set";
+ /* argument is putenv-style "foo=bar", value of foo is set to bar */
+
+static const size_t env_prepend_opt_len = LTWRAPPER_OPTION_PREFIX_LENGTH + 11;
+static const char *env_prepend_opt = LTWRAPPER_OPTION_PREFIX "env-prepend";
+ /* argument is putenv-style "foo=bar", new value of foo is bar${foo} */
+
+static const size_t env_append_opt_len = LTWRAPPER_OPTION_PREFIX_LENGTH + 10;
+static const char *env_append_opt = LTWRAPPER_OPTION_PREFIX "env-append";
+ /* argument is putenv-style "foo=bar", new value of foo is ${foo}bar */
+
+int
+main (int argc, char *argv[])
+{
+ char **newargz;
+ int newargc;
+ char *tmp_pathspec;
+ char *actual_cwrapper_path;
+ char *actual_cwrapper_name;
+ char *target_name;
+ char *lt_argv_zero;
+ intptr_t rval = 127;
+
+ int i;
+
+ program_name = (char *) xstrdup (base_name (argv[0]));
+ LTWRAPPER_DEBUGPRINTF (("(main) argv[0] : %s\n", argv[0]));
+ LTWRAPPER_DEBUGPRINTF (("(main) program_name : %s\n", program_name));
+
+ /* very simple arg parsing; don't want to rely on getopt */
+ for (i = 1; i < argc; i++)
+ {
+ if (strcmp (argv[i], dumpscript_opt) == 0)
+ {
+EOF
+ case "$host" in
+ *mingw* | *cygwin* )
+ # make stdout use "unix" line endings
+ echo " setmode(1,_O_BINARY);"
+ ;;
+ esac
+
+ cat <<"EOF"
+ printf ("%s", script_text_part1);
+ printf ("%s", script_text_part2);
+ return 0;
+ }
+ }
+
+ newargz = XMALLOC (char *, argc + 1);
+ tmp_pathspec = find_executable (argv[0]);
+ if (tmp_pathspec == NULL)
+ lt_fatal ("Couldn't find %s", argv[0]);
+ LTWRAPPER_DEBUGPRINTF (("(main) found exe (before symlink chase) at : %s\n",
+ tmp_pathspec));
+
+ actual_cwrapper_path = chase_symlinks (tmp_pathspec);
+ LTWRAPPER_DEBUGPRINTF (("(main) found exe (after symlink chase) at : %s\n",
+ actual_cwrapper_path));
+ XFREE (tmp_pathspec);
+
+ actual_cwrapper_name = xstrdup( base_name (actual_cwrapper_path));
+ strendzap (actual_cwrapper_path, actual_cwrapper_name);
+
+ /* wrapper name transforms */
+ strendzap (actual_cwrapper_name, ".exe");
+ tmp_pathspec = lt_extend_str (actual_cwrapper_name, ".exe", 1);
+ XFREE (actual_cwrapper_name);
+ actual_cwrapper_name = tmp_pathspec;
+ tmp_pathspec = 0;
+
+ /* target_name transforms -- use actual target program name; might have lt- prefix */
+ target_name = xstrdup (base_name (TARGET_PROGRAM_NAME));
+ strendzap (target_name, ".exe");
+ tmp_pathspec = lt_extend_str (target_name, ".exe", 1);
+ XFREE (target_name);
+ target_name = tmp_pathspec;
+ tmp_pathspec = 0;
+
+ LTWRAPPER_DEBUGPRINTF (("(main) libtool target name: %s\n",
+ target_name));
+EOF
+
+ cat <<EOF
+ newargz[0] =
+ XMALLOC (char, (strlen (actual_cwrapper_path) +
+ strlen ("$objdir") + 1 + strlen (actual_cwrapper_name) + 1));
+ strcpy (newargz[0], actual_cwrapper_path);
+ strcat (newargz[0], "$objdir");
+ strcat (newargz[0], "/");
+EOF
+
+ cat <<"EOF"
+ /* stop here, and copy so we don't have to do this twice */
+ tmp_pathspec = xstrdup (newargz[0]);
+
+ /* do NOT want the lt- prefix here, so use actual_cwrapper_name */
+ strcat (newargz[0], actual_cwrapper_name);
+
+ /* DO want the lt- prefix here if it exists, so use target_name */
+ lt_argv_zero = lt_extend_str (tmp_pathspec, target_name, 1);
+ XFREE (tmp_pathspec);
+ tmp_pathspec = NULL;
+EOF
+
+ case $host_os in
+ mingw*)
+ cat <<"EOF"
+ {
+ char* p;
+ while ((p = strchr (newargz[0], '\\')) != NULL)
+ {
+ *p = '/';
+ }
+ while ((p = strchr (lt_argv_zero, '\\')) != NULL)
+ {
+ *p = '/';
+ }
+ }
+EOF
+ ;;
+ esac
+
+ cat <<"EOF"
+ XFREE (target_name);
+ XFREE (actual_cwrapper_path);
+ XFREE (actual_cwrapper_name);
+
+ lt_setenv ("BIN_SH", "xpg4"); /* for Tru64 */
+ lt_setenv ("DUALCASE", "1"); /* for MSK sh */
+ lt_update_lib_path (LIB_PATH_VARNAME, LIB_PATH_VALUE);
+ lt_update_exe_path (EXE_PATH_VARNAME, EXE_PATH_VALUE);
+
+ newargc=0;
+ for (i = 1; i < argc; i++)
+ {
+ if (strncmp (argv[i], env_set_opt, env_set_opt_len) == 0)
+ {
+ if (argv[i][env_set_opt_len] == '=')
+ {
+ const char *p = argv[i] + env_set_opt_len + 1;
+ lt_opt_process_env_set (p);
+ }
+ else if (argv[i][env_set_opt_len] == '\0' && i + 1 < argc)
+ {
+ lt_opt_process_env_set (argv[++i]); /* don't copy */
+ }
+ else
+ lt_fatal ("%s missing required argument", env_set_opt);
+ continue;
+ }
+ if (strncmp (argv[i], env_prepend_opt, env_prepend_opt_len) == 0)
+ {
+ if (argv[i][env_prepend_opt_len] == '=')
+ {
+ const char *p = argv[i] + env_prepend_opt_len + 1;
+ lt_opt_process_env_prepend (p);
+ }
+ else if (argv[i][env_prepend_opt_len] == '\0' && i + 1 < argc)
+ {
+ lt_opt_process_env_prepend (argv[++i]); /* don't copy */
+ }
+ else
+ lt_fatal ("%s missing required argument", env_prepend_opt);
+ continue;
+ }
+ if (strncmp (argv[i], env_append_opt, env_append_opt_len) == 0)
+ {
+ if (argv[i][env_append_opt_len] == '=')
+ {
+ const char *p = argv[i] + env_append_opt_len + 1;
+ lt_opt_process_env_append (p);
+ }
+ else if (argv[i][env_append_opt_len] == '\0' && i + 1 < argc)
+ {
+ lt_opt_process_env_append (argv[++i]); /* don't copy */
+ }
+ else
+ lt_fatal ("%s missing required argument", env_append_opt);
+ continue;
+ }
+ if (strncmp (argv[i], ltwrapper_option_prefix, opt_prefix_len) == 0)
+ {
+ /* however, if there is an option in the LTWRAPPER_OPTION_PREFIX
+ namespace, but it is not one of the ones we know about and
+ have already dealt with, above (inluding dump-script), then
+ report an error. Otherwise, targets might begin to believe
+ they are allowed to use options in the LTWRAPPER_OPTION_PREFIX
+ namespace. The first time any user complains about this, we'll
+ need to make LTWRAPPER_OPTION_PREFIX a configure-time option
+ or a configure.ac-settable value.
+ */
+ lt_fatal ("Unrecognized option in %s namespace: '%s'",
+ ltwrapper_option_prefix, argv[i]);
+ }
+ /* otherwise ... */
+ newargz[++newargc] = xstrdup (argv[i]);
+ }
+ newargz[++newargc] = NULL;
+
+ LTWRAPPER_DEBUGPRINTF (("(main) lt_argv_zero : %s\n", (lt_argv_zero ? lt_argv_zero : "<NULL>")));
+ for (i = 0; i < newargc; i++)
+ {
+ LTWRAPPER_DEBUGPRINTF (("(main) newargz[%d] : %s\n", i, (newargz[i] ? newargz[i] : "<NULL>")));
+ }
+
+EOF
+
+ case $host_os in
+ mingw*)
+ cat <<"EOF"
+ /* execv doesn't actually work on mingw as expected on unix */
+ rval = _spawnv (_P_WAIT, lt_argv_zero, (const char * const *) newargz);
+ if (rval == -1)
+ {
+ /* failed to start process */
+ LTWRAPPER_DEBUGPRINTF (("(main) failed to launch target \"%s\": errno = %d\n", lt_argv_zero, errno));
+ return 127;
+ }
+ return rval;
+EOF
+ ;;
+ *)
+ cat <<"EOF"
+ execv (lt_argv_zero, newargz);
+ return rval; /* =127, but avoids unused variable warning */
+EOF
+ ;;
+ esac
+
+ cat <<"EOF"
+}
+
+void *
+xmalloc (size_t num)
+{
+ void *p = (void *) malloc (num);
+ if (!p)
+ lt_fatal ("Memory exhausted");
+
+ return p;
+}
+
+char *
+xstrdup (const char *string)
+{
+ return string ? strcpy ((char *) xmalloc (strlen (string) + 1),
+ string) : NULL;
+}
+
+const char *
+base_name (const char *name)
+{
+ const char *base;
+
+#if defined (HAVE_DOS_BASED_FILE_SYSTEM)
+ /* Skip over the disk name in MSDOS pathnames. */
+ if (isalpha ((unsigned char) name[0]) && name[1] == ':')
+ name += 2;
+#endif
+
+ for (base = name; *name; name++)
+ if (IS_DIR_SEPARATOR (*name))
+ base = name + 1;
+ return base;
+}
+
+int
+check_executable (const char *path)
+{
+ struct stat st;
+
+ LTWRAPPER_DEBUGPRINTF (("(check_executable) : %s\n",
+ path ? (*path ? path : "EMPTY!") : "NULL!"));
+ if ((!path) || (!*path))
+ return 0;
+
+ if ((stat (path, &st) >= 0)
+ && (st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH)))
+ return 1;
+ else
+ return 0;
+}
+
+int
+make_executable (const char *path)
+{
+ int rval = 0;
+ struct stat st;
+
+ LTWRAPPER_DEBUGPRINTF (("(make_executable) : %s\n",
+ path ? (*path ? path : "EMPTY!") : "NULL!"));
+ if ((!path) || (!*path))
+ return 0;
+
+ if (stat (path, &st) >= 0)
+ {
+ rval = chmod (path, st.st_mode | S_IXOTH | S_IXGRP | S_IXUSR);
+ }
+ return rval;
+}
+
+/* Searches for the full path of the wrapper. Returns
+ newly allocated full path name if found, NULL otherwise
+ Does not chase symlinks, even on platforms that support them.
+*/
+char *
+find_executable (const char *wrapper)
+{
+ int has_slash = 0;
+ const char *p;
+ const char *p_next;
+ /* static buffer for getcwd */
+ char tmp[LT_PATHMAX + 1];
+ int tmp_len;
+ char *concat_name;
+
+ LTWRAPPER_DEBUGPRINTF (("(find_executable) : %s\n",
+ wrapper ? (*wrapper ? wrapper : "EMPTY!") : "NULL!"));
+
+ if ((wrapper == NULL) || (*wrapper == '\0'))
+ return NULL;
+
+ /* Absolute path? */
+#if defined (HAVE_DOS_BASED_FILE_SYSTEM)
+ if (isalpha ((unsigned char) wrapper[0]) && wrapper[1] == ':')
+ {
+ concat_name = xstrdup (wrapper);
+ if (check_executable (concat_name))
+ return concat_name;
+ XFREE (concat_name);
+ }
+ else
+ {
+#endif
+ if (IS_DIR_SEPARATOR (wrapper[0]))
+ {
+ concat_name = xstrdup (wrapper);
+ if (check_executable (concat_name))
+ return concat_name;
+ XFREE (concat_name);
+ }
+#if defined (HAVE_DOS_BASED_FILE_SYSTEM)
+ }
+#endif
+
+ for (p = wrapper; *p; p++)
+ if (*p == '/')
+ {
+ has_slash = 1;
+ break;
+ }
+ if (!has_slash)
+ {
+ /* no slashes; search PATH */
+ const char *path = getenv ("PATH");
+ if (path != NULL)
+ {
+ for (p = path; *p; p = p_next)
+ {
+ const char *q;
+ size_t p_len;
+ for (q = p; *q; q++)
+ if (IS_PATH_SEPARATOR (*q))
+ break;
+ p_len = q - p;
+ p_next = (*q == '\0' ? q : q + 1);
+ if (p_len == 0)
+ {
+ /* empty path: current directory */
+ if (getcwd (tmp, LT_PATHMAX) == NULL)
+ lt_fatal ("getcwd failed");
+ tmp_len = strlen (tmp);
+ concat_name =
+ XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1);
+ memcpy (concat_name, tmp, tmp_len);
+ concat_name[tmp_len] = '/';
+ strcpy (concat_name + tmp_len + 1, wrapper);
+ }
+ else
+ {
+ concat_name =
+ XMALLOC (char, p_len + 1 + strlen (wrapper) + 1);
+ memcpy (concat_name, p, p_len);
+ concat_name[p_len] = '/';
+ strcpy (concat_name + p_len + 1, wrapper);
+ }
+ if (check_executable (concat_name))
+ return concat_name;
+ XFREE (concat_name);
+ }
+ }
+ /* not found in PATH; assume curdir */
+ }
+ /* Relative path | not found in path: prepend cwd */
+ if (getcwd (tmp, LT_PATHMAX) == NULL)
+ lt_fatal ("getcwd failed");
+ tmp_len = strlen (tmp);
+ concat_name = XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1);
+ memcpy (concat_name, tmp, tmp_len);
+ concat_name[tmp_len] = '/';
+ strcpy (concat_name + tmp_len + 1, wrapper);
+
+ if (check_executable (concat_name))
+ return concat_name;
+ XFREE (concat_name);
+ return NULL;
+}
+
+char *
+chase_symlinks (const char *pathspec)
+{
+#ifndef S_ISLNK
+ return xstrdup (pathspec);
+#else
+ char buf[LT_PATHMAX];
+ struct stat s;
+ char *tmp_pathspec = xstrdup (pathspec);
+ char *p;
+ int has_symlinks = 0;
+ while (strlen (tmp_pathspec) && !has_symlinks)
+ {
+ LTWRAPPER_DEBUGPRINTF (("checking path component for symlinks: %s\n",
+ tmp_pathspec));
+ if (lstat (tmp_pathspec, &s) == 0)
+ {
+ if (S_ISLNK (s.st_mode) != 0)
+ {
+ has_symlinks = 1;
+ break;
+ }
+
+ /* search backwards for last DIR_SEPARATOR */
+ p = tmp_pathspec + strlen (tmp_pathspec) - 1;
+ while ((p > tmp_pathspec) && (!IS_DIR_SEPARATOR (*p)))
+ p--;
+ if ((p == tmp_pathspec) && (!IS_DIR_SEPARATOR (*p)))
+ {
+ /* no more DIR_SEPARATORS left */
+ break;
+ }
+ *p = '\0';
+ }
+ else
+ {
+ char *errstr = strerror (errno);
+ lt_fatal ("Error accessing file %s (%s)", tmp_pathspec, errstr);
+ }
+ }
+ XFREE (tmp_pathspec);
+
+ if (!has_symlinks)
+ {
+ return xstrdup (pathspec);
+ }
+
+ tmp_pathspec = realpath (pathspec, buf);
+ if (tmp_pathspec == 0)
+ {
+ lt_fatal ("Could not follow symlinks for %s", pathspec);
+ }
+ return xstrdup (tmp_pathspec);
+#endif
+}
+
+char *
+strendzap (char *str, const char *pat)
+{
+ size_t len, patlen;
+
+ assert (str != NULL);
+ assert (pat != NULL);
+
+ len = strlen (str);
+ patlen = strlen (pat);
+
+ if (patlen <= len)
+ {
+ str += len - patlen;
+ if (strcmp (str, pat) == 0)
+ *str = '\0';
+ }
+ return str;
+}
+
+static void
+lt_error_core (int exit_status, const char *mode,
+ const char *message, va_list ap)
+{
+ fprintf (stderr, "%s: %s: ", program_name, mode);
+ vfprintf (stderr, message, ap);
+ fprintf (stderr, ".\n");
+
+ if (exit_status >= 0)
+ exit (exit_status);
+}
+
+void
+lt_fatal (const char *message, ...)
+{
+ va_list ap;
+ va_start (ap, message);
+ lt_error_core (EXIT_FAILURE, "FATAL", message, ap);
+ va_end (ap);
+}
+
+void
+lt_setenv (const char *name, const char *value)
+{
+ LTWRAPPER_DEBUGPRINTF (("(lt_setenv) setting '%s' to '%s'\n",
+ (name ? name : "<NULL>"),
+ (value ? value : "<NULL>")));
+ {
+#ifdef HAVE_SETENV
+ /* always make a copy, for consistency with !HAVE_SETENV */
+ char *str = xstrdup (value);
+ setenv (name, str, 1);
+#else
+ int len = strlen (name) + 1 + strlen (value) + 1;
+ char *str = XMALLOC (char, len);
+ sprintf (str, "%s=%s", name, value);
+ if (putenv (str) != EXIT_SUCCESS)
+ {
+ XFREE (str);
+ }
+#endif
+ }
+}
+
+char *
+lt_extend_str (const char *orig_value, const char *add, int to_end)
+{
+ char *new_value;
+ if (orig_value && *orig_value)
+ {
+ int orig_value_len = strlen (orig_value);
+ int add_len = strlen (add);
+ new_value = XMALLOC (char, add_len + orig_value_len + 1);
+ if (to_end)
+ {
+ strcpy (new_value, orig_value);
+ strcpy (new_value + orig_value_len, add);
+ }
+ else
+ {
+ strcpy (new_value, add);
+ strcpy (new_value + add_len, orig_value);
+ }
+ }
+ else
+ {
+ new_value = xstrdup (add);
+ }
+ return new_value;
+}
+
+int
+lt_split_name_value (const char *arg, char** name, char** value)
+{
+ const char *p;
+ int len;
+ if (!arg || !*arg)
+ return 1;
+
+ p = strchr (arg, (int)'=');
+
+ if (!p)
+ return 1;
+
+ *value = xstrdup (++p);
+
+ len = strlen (arg) - strlen (*value);
+ *name = XMALLOC (char, len);
+ strncpy (*name, arg, len-1);
+ (*name)[len - 1] = '\0';
+
+ return 0;
+}
+
+void
+lt_opt_process_env_set (const char *arg)
+{
+ char *name = NULL;
+ char *value = NULL;
+
+ if (lt_split_name_value (arg, &name, &value) != 0)
+ {
+ XFREE (name);
+ XFREE (value);
+ lt_fatal ("bad argument for %s: '%s'", env_set_opt, arg);
+ }
+
+ lt_setenv (name, value);
+ XFREE (name);
+ XFREE (value);
+}
+
+void
+lt_opt_process_env_prepend (const char *arg)
+{
+ char *name = NULL;
+ char *value = NULL;
+ char *new_value = NULL;
+
+ if (lt_split_name_value (arg, &name, &value) != 0)
+ {
+ XFREE (name);
+ XFREE (value);
+ lt_fatal ("bad argument for %s: '%s'", env_prepend_opt, arg);
+ }
+
+ new_value = lt_extend_str (getenv (name), value, 0);
+ lt_setenv (name, new_value);
+ XFREE (new_value);
+ XFREE (name);
+ XFREE (value);
+}
+
+void
+lt_opt_process_env_append (const char *arg)
+{
+ char *name = NULL;
+ char *value = NULL;
+ char *new_value = NULL;
+
+ if (lt_split_name_value (arg, &name, &value) != 0)
+ {
+ XFREE (name);
+ XFREE (value);
+ lt_fatal ("bad argument for %s: '%s'", env_append_opt, arg);
+ }
+
+ new_value = lt_extend_str (getenv (name), value, 1);
+ lt_setenv (name, new_value);
+ XFREE (new_value);
+ XFREE (name);
+ XFREE (value);
+}
+
+void
+lt_update_exe_path (const char *name, const char *value)
+{
+ LTWRAPPER_DEBUGPRINTF (("(lt_update_exe_path) modifying '%s' by prepending '%s'\n",
+ (name ? name : "<NULL>"),
+ (value ? value : "<NULL>")));
+
+ if (name && *name && value && *value)
+ {
+ char *new_value = lt_extend_str (getenv (name), value, 0);
+ /* some systems can't cope with a ':'-terminated path #' */
+ int len = strlen (new_value);
+ while (((len = strlen (new_value)) > 0) && IS_PATH_SEPARATOR (new_value[len-1]))
+ {
+ new_value[len-1] = '\0';
+ }
+ lt_setenv (name, new_value);
+ XFREE (new_value);
+ }
+}
+
+void
+lt_update_lib_path (const char *name, const char *value)
+{
+ LTWRAPPER_DEBUGPRINTF (("(lt_update_lib_path) modifying '%s' by prepending '%s'\n",
+ (name ? name : "<NULL>"),
+ (value ? value : "<NULL>")));
+
+ if (name && *name && value && *value)
+ {
+ char *new_value = lt_extend_str (getenv (name), value, 0);
+ lt_setenv (name, new_value);
+ XFREE (new_value);
+ }
+}
+
+
+EOF
+}
+# end: func_emit_cwrapperexe_src
+
+# func_mode_link arg...
+func_mode_link ()
+{
+ $opt_debug
+ case $host in
+ *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*)
+ # It is impossible to link a dll without this setting, and
+ # we shouldn't force the makefile maintainer to figure out
+ # which system we are compiling for in order to pass an extra
+ # flag for every libtool invocation.
+ # allow_undefined=no
+
+ # FIXME: Unfortunately, there are problems with the above when trying
+ # to make a dll which has undefined symbols, in which case not
+ # even a static library is built. For now, we need to specify
+ # -no-undefined on the libtool link line when we can be certain
+ # that all symbols are satisfied, otherwise we get a static library.
+ allow_undefined=yes
+ ;;
+ *)
+ allow_undefined=yes
+ ;;
+ esac
+ libtool_args=$nonopt
+ base_compile="$nonopt $@"
+ compile_command=$nonopt
+ finalize_command=$nonopt
+
+ compile_rpath=
+ finalize_rpath=
+ compile_shlibpath=
+ finalize_shlibpath=
+ convenience=
+ old_convenience=
+ deplibs=
+ old_deplibs=
+ compiler_flags=
+ linker_flags=
+ dllsearchpath=
+ lib_search_path=`pwd`
+ inst_prefix_dir=
+ new_inherited_linker_flags=
+
+ avoid_version=no
+ dlfiles=
+ dlprefiles=
+ dlself=no
+ export_dynamic=no
+ export_symbols=
+ export_symbols_regex=
+ generated=
+ libobjs=
+ ltlibs=
+ module=no
+ no_install=no
+ objs=
+ non_pic_objects=
+ precious_files_regex=
+ prefer_static_libs=no
+ preload=no
+ prev=
+ prevarg=
+ release=
+ rpath=
+ xrpath=
+ perm_rpath=
+ temp_rpath=
+ thread_safe=no
+ vinfo=
+ vinfo_number=no
+ weak_libs=
+ single_module="${wl}-single_module"
+ func_infer_tag $base_compile
+
+ # We need to know -static, to get the right output filenames.
+ for arg
+ do
+ case $arg in
+ -shared)
+ test "$build_libtool_libs" != yes && \
+ func_fatal_configuration "can not build a shared library"
+ build_old_libs=no
+ break
+ ;;
+ -all-static | -static | -static-libtool-libs)
+ case $arg in
+ -all-static)
+ if test "$build_libtool_libs" = yes && test -z "$link_static_flag"; then
+ func_warning "complete static linking is impossible in this configuration"
+ fi
+ if test -n "$link_static_flag"; then
+ dlopen_self=$dlopen_self_static
+ fi
+ prefer_static_libs=yes
+ ;;
+ -static)
+ if test -z "$pic_flag" && test -n "$link_static_flag"; then
+ dlopen_self=$dlopen_self_static
+ fi
+ prefer_static_libs=built
+ ;;
+ -static-libtool-libs)
+ if test -z "$pic_flag" && test -n "$link_static_flag"; then
+ dlopen_self=$dlopen_self_static
+ fi
+ prefer_static_libs=yes
+ ;;
+ esac
+ build_libtool_libs=no
+ build_old_libs=yes
+ break
+ ;;
+ esac
+ done
+
+ # See if our shared archives depend on static archives.
+ test -n "$old_archive_from_new_cmds" && build_old_libs=yes
+
+ # Go through the arguments, transforming them on the way.
+ while test "$#" -gt 0; do
+ arg="$1"
+ shift
+ func_quote_for_eval "$arg"
+ qarg=$func_quote_for_eval_unquoted_result
+ func_append libtool_args " $func_quote_for_eval_result"
+
+ # If the previous option needs an argument, assign it.
+ if test -n "$prev"; then
+ case $prev in
+ output)
+ func_append compile_command " @OUTPUT@"
+ func_append finalize_command " @OUTPUT@"
+ ;;
+ esac
+
+ case $prev in
+ dlfiles|dlprefiles)
+ if test "$preload" = no; then
+ # Add the symbol object into the linking commands.
+ func_append compile_command " @SYMFILE@"
+ func_append finalize_command " @SYMFILE@"
+ preload=yes
+ fi
+ case $arg in
+ *.la | *.lo) ;; # We handle these cases below.
+ force)
+ if test "$dlself" = no; then
+ dlself=needless
+ export_dynamic=yes
+ fi
+ prev=
+ continue
+ ;;
+ self)
+ if test "$prev" = dlprefiles; then
+ dlself=yes
+ elif test "$prev" = dlfiles && test "$dlopen_self" != yes; then
+ dlself=yes
+ else
+ dlself=needless
+ export_dynamic=yes
+ fi
+ prev=
+ continue
+ ;;
+ *)
+ if test "$prev" = dlfiles; then
+ dlfiles="$dlfiles $arg"
+ else
+ dlprefiles="$dlprefiles $arg"
+ fi
+ prev=
+ continue
+ ;;
+ esac
+ ;;
+ expsyms)
+ export_symbols="$arg"
+ test -f "$arg" \
+ || func_fatal_error "symbol file \`$arg' does not exist"
+ prev=
+ continue
+ ;;
+ expsyms_regex)
+ export_symbols_regex="$arg"
+ prev=
+ continue
+ ;;
+ framework)
+ case $host in
+ *-*-darwin*)
+ case "$deplibs " in
+ *" $qarg.ltframework "*) ;;
+ *) deplibs="$deplibs $qarg.ltframework" # this is fixed later
+ ;;
+ esac
+ ;;
+ esac
+ prev=
+ continue
+ ;;
+ inst_prefix)
+ inst_prefix_dir="$arg"
+ prev=
+ continue
+ ;;
+ objectlist)
+ if test -f "$arg"; then
+ save_arg=$arg
+ moreargs=
+ for fil in `cat "$save_arg"`
+ do
+# moreargs="$moreargs $fil"
+ arg=$fil
+ # A libtool-controlled object.
+
+ # Check to see that this really is a libtool object.
+ if func_lalib_unsafe_p "$arg"; then
+ pic_object=
+ non_pic_object=
+
+ # Read the .lo file
+ func_source "$arg"
+
+ if test -z "$pic_object" ||
+ test -z "$non_pic_object" ||
+ test "$pic_object" = none &&
+ test "$non_pic_object" = none; then
+ func_fatal_error "cannot find name of object for \`$arg'"
+ fi
+
+ # Extract subdirectory from the argument.
+ func_dirname "$arg" "/" ""
+ xdir="$func_dirname_result"
+
+ if test "$pic_object" != none; then
+ # Prepend the subdirectory the object is found in.
+ pic_object="$xdir$pic_object"
+
+ if test "$prev" = dlfiles; then
+ if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then
+ dlfiles="$dlfiles $pic_object"
+ prev=
+ continue
+ else
+ # If libtool objects are unsupported, then we need to preload.
+ prev=dlprefiles
+ fi
+ fi
+
+ # CHECK ME: I think I busted this. -Ossama
+ if test "$prev" = dlprefiles; then
+ # Preload the old-style object.
+ dlprefiles="$dlprefiles $pic_object"
+ prev=
+ fi
+
+ # A PIC object.
+ func_append libobjs " $pic_object"
+ arg="$pic_object"
+ fi
+
+ # Non-PIC object.
+ if test "$non_pic_object" != none; then
+ # Prepend the subdirectory the object is found in.
+ non_pic_object="$xdir$non_pic_object"
+
+ # A standard non-PIC object
+ func_append non_pic_objects " $non_pic_object"
+ if test -z "$pic_object" || test "$pic_object" = none ; then
+ arg="$non_pic_object"
+ fi
+ else
+ # If the PIC object exists, use it instead.
+ # $xdir was prepended to $pic_object above.
+ non_pic_object="$pic_object"
+ func_append non_pic_objects " $non_pic_object"
+ fi
+ else
+ # Only an error if not doing a dry-run.
+ if $opt_dry_run; then
+ # Extract subdirectory from the argument.
+ func_dirname "$arg" "/" ""
+ xdir="$func_dirname_result"
+
+ func_lo2o "$arg"
+ pic_object=$xdir$objdir/$func_lo2o_result
+ non_pic_object=$xdir$func_lo2o_result
+ func_append libobjs " $pic_object"
+ func_append non_pic_objects " $non_pic_object"
+ else
+ func_fatal_error "\`$arg' is not a valid libtool object"
+ fi
+ fi
+ done
+ else
+ func_fatal_error "link input file \`$arg' does not exist"
+ fi
+ arg=$save_arg
+ prev=
+ continue
+ ;;
+ precious_regex)
+ precious_files_regex="$arg"
+ prev=
+ continue
+ ;;
+ release)
+ release="-$arg"
+ prev=
+ continue
+ ;;
+ rpath | xrpath)
+ # We need an absolute path.
+ case $arg in
+ [\\/]* | [A-Za-z]:[\\/]*) ;;
+ *)
+ func_fatal_error "only absolute run-paths are allowed"
+ ;;
+ esac
+ if test "$prev" = rpath; then
+ case "$rpath " in
+ *" $arg "*) ;;
+ *) rpath="$rpath $arg" ;;
+ esac
+ else
+ case "$xrpath " in
+ *" $arg "*) ;;
+ *) xrpath="$xrpath $arg" ;;
+ esac
+ fi
+ prev=
+ continue
+ ;;
+ shrext)
+ shrext_cmds="$arg"
+ prev=
+ continue
+ ;;
+ weak)
+ weak_libs="$weak_libs $arg"
+ prev=
+ continue
+ ;;
+ xcclinker)
+ linker_flags="$linker_flags $qarg"
+ compiler_flags="$compiler_flags $qarg"
+ prev=
+ func_append compile_command " $qarg"
+ func_append finalize_command " $qarg"
+ continue
+ ;;
+ xcompiler)
+ compiler_flags="$compiler_flags $qarg"
+ prev=
+ func_append compile_command " $qarg"
+ func_append finalize_command " $qarg"
+ continue
+ ;;
+ xlinker)
+ linker_flags="$linker_flags $qarg"
+ compiler_flags="$compiler_flags $wl$qarg"
+ prev=
+ func_append compile_command " $wl$qarg"
+ func_append finalize_command " $wl$qarg"
+ continue
+ ;;
+ *)
+ eval "$prev=\"\$arg\""
+ prev=
+ continue
+ ;;
+ esac
+ fi # test -n "$prev"
+
+ prevarg="$arg"
+
+ case $arg in
+ -all-static)
+ if test -n "$link_static_flag"; then
+ # See comment for -static flag below, for more details.
+ func_append compile_command " $link_static_flag"
+ func_append finalize_command " $link_static_flag"
+ fi
+ continue
+ ;;
+
+ -allow-undefined)
+ # FIXME: remove this flag sometime in the future.
+ func_fatal_error "\`-allow-undefined' must not be used because it is the default"
+ ;;
+
+ -avoid-version)
+ avoid_version=yes
+ continue
+ ;;
+
+ -dlopen)
+ prev=dlfiles
+ continue
+ ;;
+
+ -dlpreopen)
+ prev=dlprefiles
+ continue
+ ;;
+
+ -export-dynamic)
+ export_dynamic=yes
+ continue
+ ;;
+
+ -export-symbols | -export-symbols-regex)
+ if test -n "$export_symbols" || test -n "$export_symbols_regex"; then
+ func_fatal_error "more than one -exported-symbols argument is not allowed"
+ fi
+ if test "X$arg" = "X-export-symbols"; then
+ prev=expsyms
+ else
+ prev=expsyms_regex
+ fi
+ continue
+ ;;
+
+ -framework)
+ prev=framework
+ continue
+ ;;
+
+ -inst-prefix-dir)
+ prev=inst_prefix
+ continue
+ ;;
+
+ # The native IRIX linker understands -LANG:*, -LIST:* and -LNO:*
+ # so, if we see these flags be careful not to treat them like -L
+ -L[A-Z][A-Z]*:*)
+ case $with_gcc/$host in
+ no/*-*-irix* | /*-*-irix*)
+ func_append compile_command " $arg"
+ func_append finalize_command " $arg"
+ ;;
+ esac
+ continue
+ ;;
+
+ -L*)
+ func_stripname '-L' '' "$arg"
+ dir=$func_stripname_result
+ if test -z "$dir"; then
+ if test "$#" -gt 0; then
+ func_fatal_error "require no space between \`-L' and \`$1'"
+ else
+ func_fatal_error "need path for \`-L' option"
+ fi
+ fi
+ # We need an absolute path.
+ case $dir in
+ [\\/]* | [A-Za-z]:[\\/]*) ;;
+ *)
+ absdir=`cd "$dir" && pwd`
+ test -z "$absdir" && \
+ func_fatal_error "cannot determine absolute directory name of \`$dir'"
+ dir="$absdir"
+ ;;
+ esac
+ case "$deplibs " in
+ *" -L$dir "*) ;;
+ *)
+ deplibs="$deplibs -L$dir"
+ lib_search_path="$lib_search_path $dir"
+ ;;
+ esac
+ case $host in
+ *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*)
+ testbindir=`$ECHO "X$dir" | $Xsed -e 's*/lib$*/bin*'`
+ case :$dllsearchpath: in
+ *":$dir:"*) ;;
+ ::) dllsearchpath=$dir;;
+ *) dllsearchpath="$dllsearchpath:$dir";;
+ esac
+ case :$dllsearchpath: in
+ *":$testbindir:"*) ;;
+ ::) dllsearchpath=$testbindir;;
+ *) dllsearchpath="$dllsearchpath:$testbindir";;
+ esac
+ ;;
+ esac
+ continue
+ ;;
+
+ -l*)
+ if test "X$arg" = "X-lc" || test "X$arg" = "X-lm"; then
+ case $host in
+ *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-beos* | *-cegcc*)
+ # These systems don't actually have a C or math library (as such)
+ continue
+ ;;
+ *-*-os2*)
+ # These systems don't actually have a C library (as such)
+ test "X$arg" = "X-lc" && continue
+ ;;
+ *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*)
+ # Do not include libc due to us having libc/libc_r.
+ test "X$arg" = "X-lc" && continue
+ ;;
+ *-*-rhapsody* | *-*-darwin1.[012])
+ # Rhapsody C and math libraries are in the System framework
+ deplibs="$deplibs System.ltframework"
+ continue
+ ;;
+ *-*-sco3.2v5* | *-*-sco5v6*)
+ # Causes problems with __ctype
+ test "X$arg" = "X-lc" && continue
+ ;;
+ *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*)
+ # Compiler inserts libc in the correct place for threads to work
+ test "X$arg" = "X-lc" && continue
+ ;;
+ esac
+ elif test "X$arg" = "X-lc_r"; then
+ case $host in
+ *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*)
+ # Do not include libc_r directly, use -pthread flag.
+ continue
+ ;;
+ esac
+ fi
+ deplibs="$deplibs $arg"
+ continue
+ ;;
+
+ -module)
+ module=yes
+ continue
+ ;;
+
+ # Tru64 UNIX uses -model [arg] to determine the layout of C++
+ # classes, name mangling, and exception handling.
+ # Darwin uses the -arch flag to determine output architecture.
+ -model|-arch|-isysroot)
+ compiler_flags="$compiler_flags $arg"
+ func_append compile_command " $arg"
+ func_append finalize_command " $arg"
+ prev=xcompiler
+ continue
+ ;;
+
+ -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe|-threads)
+ compiler_flags="$compiler_flags $arg"
+ func_append compile_command " $arg"
+ func_append finalize_command " $arg"
+ case "$new_inherited_linker_flags " in
+ *" $arg "*) ;;
+ * ) new_inherited_linker_flags="$new_inherited_linker_flags $arg" ;;
+ esac
+ continue
+ ;;
+
+ -multi_module)
+ single_module="${wl}-multi_module"
+ continue
+ ;;
+
+ -no-fast-install)
+ fast_install=no
+ continue
+ ;;
+
+ -no-install)
+ case $host in
+ *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-darwin* | *-cegcc*)
+ # The PATH hackery in wrapper scripts is required on Windows
+ # and Darwin in order for the loader to find any dlls it needs.
+ func_warning "\`-no-install' is ignored for $host"
+ func_warning "assuming \`-no-fast-install' instead"
+ fast_install=no
+ ;;
+ *) no_install=yes ;;
+ esac
+ continue
+ ;;
+
+ -no-undefined)
+ allow_undefined=no
+ continue
+ ;;
+
+ -objectlist)
+ prev=objectlist
+ continue
+ ;;
+
+ -o) prev=output ;;
+
+ -precious-files-regex)
+ prev=precious_regex
+ continue
+ ;;
+
+ -release)
+ prev=release
+ continue
+ ;;
+
+ -rpath)
+ prev=rpath
+ continue
+ ;;
+
+ -R)
+ prev=xrpath
+ continue
+ ;;
+
+ -R*)
+ func_stripname '-R' '' "$arg"
+ dir=$func_stripname_result
+ # We need an absolute path.
+ case $dir in
+ [\\/]* | [A-Za-z]:[\\/]*) ;;
+ *)
+ func_fatal_error "only absolute run-paths are allowed"
+ ;;
+ esac
+ case "$xrpath " in
+ *" $dir "*) ;;
+ *) xrpath="$xrpath $dir" ;;
+ esac
+ continue
+ ;;
+
+ -shared)
+ # The effects of -shared are defined in a previous loop.
+ continue
+ ;;
+
+ -shrext)
+ prev=shrext
+ continue
+ ;;
+
+ -static | -static-libtool-libs)
+ # The effects of -static are defined in a previous loop.
+ # We used to do the same as -all-static on platforms that
+ # didn't have a PIC flag, but the assumption that the effects
+ # would be equivalent was wrong. It would break on at least
+ # Digital Unix and AIX.
+ continue
+ ;;
+
+ -thread-safe)
+ thread_safe=yes
+ continue
+ ;;
+
+ -version-info)
+ prev=vinfo
+ continue
+ ;;
+
+ -version-number)
+ prev=vinfo
+ vinfo_number=yes
+ continue
+ ;;
+
+ -weak)
+ prev=weak
+ continue
+ ;;
+
+ -Wc,*)
+ func_stripname '-Wc,' '' "$arg"
+ args=$func_stripname_result
+ arg=
+ save_ifs="$IFS"; IFS=','
+ for flag in $args; do
+ IFS="$save_ifs"
+ func_quote_for_eval "$flag"
+ arg="$arg $wl$func_quote_for_eval_result"
+ compiler_flags="$compiler_flags $func_quote_for_eval_result"
+ done
+ IFS="$save_ifs"
+ func_stripname ' ' '' "$arg"
+ arg=$func_stripname_result
+ ;;
+
+ -Wl,*)
+ func_stripname '-Wl,' '' "$arg"
+ args=$func_stripname_result
+ arg=
+ save_ifs="$IFS"; IFS=','
+ for flag in $args; do
+ IFS="$save_ifs"
+ func_quote_for_eval "$flag"
+ arg="$arg $wl$func_quote_for_eval_result"
+ compiler_flags="$compiler_flags $wl$func_quote_for_eval_result"
+ linker_flags="$linker_flags $func_quote_for_eval_result"
+ done
+ IFS="$save_ifs"
+ func_stripname ' ' '' "$arg"
+ arg=$func_stripname_result
+ ;;
+
+ -Xcompiler)
+ prev=xcompiler
+ continue
+ ;;
+
+ -Xlinker)
+ prev=xlinker
+ continue
+ ;;
+
+ -XCClinker)
+ prev=xcclinker
+ continue
+ ;;
+
+ # -msg_* for osf cc
+ -msg_*)
+ func_quote_for_eval "$arg"
+ arg="$func_quote_for_eval_result"
+ ;;
+
+ # -64, -mips[0-9] enable 64-bit mode on the SGI compiler
+ # -r[0-9][0-9]* specifies the processor on the SGI compiler
+ # -xarch=*, -xtarget=* enable 64-bit mode on the Sun compiler
+ # +DA*, +DD* enable 64-bit mode on the HP compiler
+ # -q* pass through compiler args for the IBM compiler
+ # -m*, -t[45]*, -txscale* pass through architecture-specific
+ # compiler args for GCC
+ # -F/path gives path to uninstalled frameworks, gcc on darwin
+ # -p, -pg, --coverage, -fprofile-* pass through profiling flag for GCC
+ # @file GCC response files
+ -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*| \
+ -t[45]*|-txscale*|-p|-pg|--coverage|-fprofile-*|-F*|@*)
+ func_quote_for_eval "$arg"
+ arg="$func_quote_for_eval_result"
+ func_append compile_command " $arg"
+ func_append finalize_command " $arg"
+ compiler_flags="$compiler_flags $arg"
+ continue
+ ;;
+
+ # Some other compiler flag.
+ -* | +*)
+ func_quote_for_eval "$arg"
+ arg="$func_quote_for_eval_result"
+ ;;
+
+ *.$objext)
+ # A standard object.
+ objs="$objs $arg"
+ ;;
+
+ *.lo)
+ # A libtool-controlled object.
+
+ # Check to see that this really is a libtool object.
+ if func_lalib_unsafe_p "$arg"; then
+ pic_object=
+ non_pic_object=
+
+ # Read the .lo file
+ func_source "$arg"
+
+ if test -z "$pic_object" ||
+ test -z "$non_pic_object" ||
+ test "$pic_object" = none &&
+ test "$non_pic_object" = none; then
+ func_fatal_error "cannot find name of object for \`$arg'"
+ fi
+
+ # Extract subdirectory from the argument.
+ func_dirname "$arg" "/" ""
+ xdir="$func_dirname_result"
+
+ if test "$pic_object" != none; then
+ # Prepend the subdirectory the object is found in.
+ pic_object="$xdir$pic_object"
+
+ if test "$prev" = dlfiles; then
+ if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then
+ dlfiles="$dlfiles $pic_object"
+ prev=
+ continue
+ else
+ # If libtool objects are unsupported, then we need to preload.
+ prev=dlprefiles
+ fi
+ fi
+
+ # CHECK ME: I think I busted this. -Ossama
+ if test "$prev" = dlprefiles; then
+ # Preload the old-style object.
+ dlprefiles="$dlprefiles $pic_object"
+ prev=
+ fi
+
+ # A PIC object.
+ func_append libobjs " $pic_object"
+ arg="$pic_object"
+ fi
+
+ # Non-PIC object.
+ if test "$non_pic_object" != none; then
+ # Prepend the subdirectory the object is found in.
+ non_pic_object="$xdir$non_pic_object"
+
+ # A standard non-PIC object
+ func_append non_pic_objects " $non_pic_object"
+ if test -z "$pic_object" || test "$pic_object" = none ; then
+ arg="$non_pic_object"
+ fi
+ else
+ # If the PIC object exists, use it instead.
+ # $xdir was prepended to $pic_object above.
+ non_pic_object="$pic_object"
+ func_append non_pic_objects " $non_pic_object"
+ fi
+ else
+ # Only an error if not doing a dry-run.
+ if $opt_dry_run; then
+ # Extract subdirectory from the argument.
+ func_dirname "$arg" "/" ""
+ xdir="$func_dirname_result"
+
+ func_lo2o "$arg"
+ pic_object=$xdir$objdir/$func_lo2o_result
+ non_pic_object=$xdir$func_lo2o_result
+ func_append libobjs " $pic_object"
+ func_append non_pic_objects " $non_pic_object"
+ else
+ func_fatal_error "\`$arg' is not a valid libtool object"
+ fi
+ fi
+ ;;
+
+ *.$libext)
+ # An archive.
+ deplibs="$deplibs $arg"
+ old_deplibs="$old_deplibs $arg"
+ continue
+ ;;
+
+ *.la)
+ # A libtool-controlled library.
+
+ if test "$prev" = dlfiles; then
+ # This library was specified with -dlopen.
+ dlfiles="$dlfiles $arg"
+ prev=
+ elif test "$prev" = dlprefiles; then
+ # The library was specified with -dlpreopen.
+ dlprefiles="$dlprefiles $arg"
+ prev=
+ else
+ deplibs="$deplibs $arg"
+ fi
+ continue
+ ;;
+
+ # Some other compiler argument.
+ *)
+ # Unknown arguments in both finalize_command and compile_command need
+ # to be aesthetically quoted because they are evaled later.
+ func_quote_for_eval "$arg"
+ arg="$func_quote_for_eval_result"
+ ;;
+ esac # arg
+
+ # Now actually substitute the argument into the commands.
+ if test -n "$arg"; then
+ func_append compile_command " $arg"
+ func_append finalize_command " $arg"
+ fi
+ done # argument parsing loop
+
+ test -n "$prev" && \
+ func_fatal_help "the \`$prevarg' option requires an argument"
+
+ if test "$export_dynamic" = yes && test -n "$export_dynamic_flag_spec"; then
+ eval arg=\"$export_dynamic_flag_spec\"
+ func_append compile_command " $arg"
+ func_append finalize_command " $arg"
+ fi
+
+ oldlibs=
+ # calculate the name of the file, without its directory
+ func_basename "$output"
+ outputname="$func_basename_result"
+ libobjs_save="$libobjs"
+
+ if test -n "$shlibpath_var"; then
+ # get the directories listed in $shlibpath_var
+ eval shlib_search_path=\`\$ECHO \"X\${$shlibpath_var}\" \| \$Xsed -e \'s/:/ /g\'\`
+ else
+ shlib_search_path=
+ fi
+ eval sys_lib_search_path=\"$sys_lib_search_path_spec\"
+ eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\"
+
+ func_dirname "$output" "/" ""
+ output_objdir="$func_dirname_result$objdir"
+ # Create the object directory.
+ func_mkdir_p "$output_objdir"
+
+ # Determine the type of output
+ case $output in
+ "")
+ func_fatal_help "you must specify an output file"
+ ;;
+ *.$libext) linkmode=oldlib ;;
+ *.lo | *.$objext) linkmode=obj ;;
+ *.la) linkmode=lib ;;
+ *) linkmode=prog ;; # Anything else should be a program.
+ esac
+
+ specialdeplibs=
+
+ libs=
+ # Find all interdependent deplibs by searching for libraries
+ # that are linked more than once (e.g. -la -lb -la)
+ for deplib in $deplibs; do
+ if $opt_duplicate_deps ; then
+ case "$libs " in
+ *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;;
+ esac
+ fi
+ libs="$libs $deplib"
+ done
+
+ if test "$linkmode" = lib; then
+ libs="$predeps $libs $compiler_lib_search_path $postdeps"
+
+ # Compute libraries that are listed more than once in $predeps
+ # $postdeps and mark them as special (i.e., whose duplicates are
+ # not to be eliminated).
+ pre_post_deps=
+ if $opt_duplicate_compiler_generated_deps; then
+ for pre_post_dep in $predeps $postdeps; do
+ case "$pre_post_deps " in
+ *" $pre_post_dep "*) specialdeplibs="$specialdeplibs $pre_post_deps" ;;
+ esac
+ pre_post_deps="$pre_post_deps $pre_post_dep"
+ done
+ fi
+ pre_post_deps=
+ fi
+
+ deplibs=
+ newdependency_libs=
+ newlib_search_path=
+ need_relink=no # whether we're linking any uninstalled libtool libraries
+ notinst_deplibs= # not-installed libtool libraries
+ notinst_path= # paths that contain not-installed libtool libraries
+
+ case $linkmode in
+ lib)
+ passes="conv dlpreopen link"
+ for file in $dlfiles $dlprefiles; do
+ case $file in
+ *.la) ;;
+ *)
+ func_fatal_help "libraries can \`-dlopen' only libtool libraries: $file"
+ ;;
+ esac
+ done
+ ;;
+ prog)
+ compile_deplibs=
+ finalize_deplibs=
+ alldeplibs=no
+ newdlfiles=
+ newdlprefiles=
+ passes="conv scan dlopen dlpreopen link"
+ ;;
+ *) passes="conv"
+ ;;
+ esac
+
+ for pass in $passes; do
+ # The preopen pass in lib mode reverses $deplibs; put it back here
+ # so that -L comes before libs that need it for instance...
+ if test "$linkmode,$pass" = "lib,link"; then
+ ## FIXME: Find the place where the list is rebuilt in the wrong
+ ## order, and fix it there properly
+ tmp_deplibs=
+ for deplib in $deplibs; do
+ tmp_deplibs="$deplib $tmp_deplibs"
+ done
+ deplibs="$tmp_deplibs"
+ fi
+
+ if test "$linkmode,$pass" = "lib,link" ||
+ test "$linkmode,$pass" = "prog,scan"; then
+ libs="$deplibs"
+ deplibs=
+ fi
+ if test "$linkmode" = prog; then
+ case $pass in
+ dlopen) libs="$dlfiles" ;;
+ dlpreopen) libs="$dlprefiles" ;;
+ link)
+ libs="$deplibs %DEPLIBS%"
+ test "X$link_all_deplibs" != Xno && libs="$libs $dependency_libs"
+ ;;
+ esac
+ fi
+ if test "$linkmode,$pass" = "lib,dlpreopen"; then
+ # Collect and forward deplibs of preopened libtool libs
+ for lib in $dlprefiles; do
+ # Ignore non-libtool-libs
+ dependency_libs=
+ case $lib in
+ *.la) func_source "$lib" ;;
+ esac
+
+ # Collect preopened libtool deplibs, except any this library
+ # has declared as weak libs
+ for deplib in $dependency_libs; do
+ deplib_base=`$ECHO "X$deplib" | $Xsed -e "$basename"`
+ case " $weak_libs " in
+ *" $deplib_base "*) ;;
+ *) deplibs="$deplibs $deplib" ;;
+ esac
+ done
+ done
+ libs="$dlprefiles"
+ fi
+ if test "$pass" = dlopen; then
+ # Collect dlpreopened libraries
+ save_deplibs="$deplibs"
+ deplibs=
+ fi
+
+ for deplib in $libs; do
+ lib=
+ found=no
+ case $deplib in
+ -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe|-threads)
+ if test "$linkmode,$pass" = "prog,link"; then
+ compile_deplibs="$deplib $compile_deplibs"
+ finalize_deplibs="$deplib $finalize_deplibs"
+ else
+ compiler_flags="$compiler_flags $deplib"
+ if test "$linkmode" = lib ; then
+ case "$new_inherited_linker_flags " in
+ *" $deplib "*) ;;
+ * ) new_inherited_linker_flags="$new_inherited_linker_flags $deplib" ;;
+ esac
+ fi
+ fi
+ continue
+ ;;
+ -l*)
+ if test "$linkmode" != lib && test "$linkmode" != prog; then
+ func_warning "\`-l' is ignored for archives/objects"
+ continue
+ fi
+ func_stripname '-l' '' "$deplib"
+ name=$func_stripname_result
+ if test "$linkmode" = lib; then
+ searchdirs="$newlib_search_path $lib_search_path $compiler_lib_search_dirs $sys_lib_search_path $shlib_search_path"
+ else
+ searchdirs="$newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path"
+ fi
+ for searchdir in $searchdirs; do
+ for search_ext in .la $std_shrext .so .a; do
+ # Search the libtool library
+ lib="$searchdir/lib${name}${search_ext}"
+ if test -f "$lib"; then
+ if test "$search_ext" = ".la"; then
+ found=yes
+ else
+ found=no
+ fi
+ break 2
+ fi
+ done
+ done
+ if test "$found" != yes; then
+ # deplib doesn't seem to be a libtool library
+ if test "$linkmode,$pass" = "prog,link"; then
+ compile_deplibs="$deplib $compile_deplibs"
+ finalize_deplibs="$deplib $finalize_deplibs"
+ else
+ deplibs="$deplib $deplibs"
+ test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs"
+ fi
+ continue
+ else # deplib is a libtool library
+ # If $allow_libtool_libs_with_static_runtimes && $deplib is a stdlib,
+ # We need to do some special things here, and not later.
+ if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+ case " $predeps $postdeps " in
+ *" $deplib "*)
+ if func_lalib_p "$lib"; then
+ library_names=
+ old_library=
+ func_source "$lib"
+ for l in $old_library $library_names; do
+ ll="$l"
+ done
+ if test "X$ll" = "X$old_library" ; then # only static version available
+ found=no
+ func_dirname "$lib" "" "."
+ ladir="$func_dirname_result"
+ lib=$ladir/$old_library
+ if test "$linkmode,$pass" = "prog,link"; then
+ compile_deplibs="$deplib $compile_deplibs"
+ finalize_deplibs="$deplib $finalize_deplibs"
+ else
+ deplibs="$deplib $deplibs"
+ test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs"
+ fi
+ continue
+ fi
+ fi
+ ;;
+ *) ;;
+ esac
+ fi
+ fi
+ ;; # -l
+ *.ltframework)
+ if test "$linkmode,$pass" = "prog,link"; then
+ compile_deplibs="$deplib $compile_deplibs"
+ finalize_deplibs="$deplib $finalize_deplibs"
+ else
+ deplibs="$deplib $deplibs"
+ if test "$linkmode" = lib ; then
+ case "$new_inherited_linker_flags " in
+ *" $deplib "*) ;;
+ * ) new_inherited_linker_flags="$new_inherited_linker_flags $deplib" ;;
+ esac
+ fi
+ fi
+ continue
+ ;;
+ -L*)
+ case $linkmode in
+ lib)
+ deplibs="$deplib $deplibs"
+ test "$pass" = conv && continue
+ newdependency_libs="$deplib $newdependency_libs"
+ func_stripname '-L' '' "$deplib"
+ newlib_search_path="$newlib_search_path $func_stripname_result"
+ ;;
+ prog)
+ if test "$pass" = conv; then
+ deplibs="$deplib $deplibs"
+ continue
+ fi
+ if test "$pass" = scan; then
+ deplibs="$deplib $deplibs"
+ else
+ compile_deplibs="$deplib $compile_deplibs"
+ finalize_deplibs="$deplib $finalize_deplibs"
+ fi
+ func_stripname '-L' '' "$deplib"
+ newlib_search_path="$newlib_search_path $func_stripname_result"
+ ;;
+ *)
+ func_warning "\`-L' is ignored for archives/objects"
+ ;;
+ esac # linkmode
+ continue
+ ;; # -L
+ -R*)
+ if test "$pass" = link; then
+ func_stripname '-R' '' "$deplib"
+ dir=$func_stripname_result
+ # Make sure the xrpath contains only unique directories.
+ case "$xrpath " in
+ *" $dir "*) ;;
+ *) xrpath="$xrpath $dir" ;;
+ esac
+ fi
+ deplibs="$deplib $deplibs"
+ continue
+ ;;
+ *.la) lib="$deplib" ;;
+ *.$libext)
+ if test "$pass" = conv; then
+ deplibs="$deplib $deplibs"
+ continue
+ fi
+ case $linkmode in
+ lib)
+ # Linking convenience modules into shared libraries is allowed,
+ # but linking other static libraries is non-portable.
+ case " $dlpreconveniencelibs " in
+ *" $deplib "*) ;;
+ *)
+ valid_a_lib=no
+ case $deplibs_check_method in
+ match_pattern*)
+ set dummy $deplibs_check_method; shift
+ match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"`
+ if eval "\$ECHO \"X$deplib\"" 2>/dev/null | $Xsed -e 10q \
+ | $EGREP "$match_pattern_regex" > /dev/null; then
+ valid_a_lib=yes
+ fi
+ ;;
+ pass_all)
+ valid_a_lib=yes
+ ;;
+ esac
+ if test "$valid_a_lib" != yes; then
+ $ECHO
+ $ECHO "*** Warning: Trying to link with static lib archive $deplib."
+ $ECHO "*** I have the capability to make that library automatically link in when"
+ $ECHO "*** you link to this library. But I can only do this if you have a"
+ $ECHO "*** shared version of the library, which you do not appear to have"
+ $ECHO "*** because the file extensions .$libext of this argument makes me believe"
+ $ECHO "*** that it is just a static archive that I should not use here."
+ else
+ $ECHO
+ $ECHO "*** Warning: Linking the shared library $output against the"
+ $ECHO "*** static library $deplib is not portable!"
+ deplibs="$deplib $deplibs"
+ fi
+ ;;
+ esac
+ continue
+ ;;
+ prog)
+ if test "$pass" != link; then
+ deplibs="$deplib $deplibs"
+ else
+ compile_deplibs="$deplib $compile_deplibs"
+ finalize_deplibs="$deplib $finalize_deplibs"
+ fi
+ continue
+ ;;
+ esac # linkmode
+ ;; # *.$libext
+ *.lo | *.$objext)
+ if test "$pass" = conv; then
+ deplibs="$deplib $deplibs"
+ elif test "$linkmode" = prog; then
+ if test "$pass" = dlpreopen || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then
+ # If there is no dlopen support or we're linking statically,
+ # we need to preload.
+ newdlprefiles="$newdlprefiles $deplib"
+ compile_deplibs="$deplib $compile_deplibs"
+ finalize_deplibs="$deplib $finalize_deplibs"
+ else
+ newdlfiles="$newdlfiles $deplib"
+ fi
+ fi
+ continue
+ ;;
+ %DEPLIBS%)
+ alldeplibs=yes
+ continue
+ ;;
+ esac # case $deplib
+
+ if test "$found" = yes || test -f "$lib"; then :
+ else
+ func_fatal_error "cannot find the library \`$lib' or unhandled argument \`$deplib'"
+ fi
+
+ # Check to see that this really is a libtool archive.
+ func_lalib_unsafe_p "$lib" \
+ || func_fatal_error "\`$lib' is not a valid libtool archive"
+
+ func_dirname "$lib" "" "."
+ ladir="$func_dirname_result"
+
+ dlname=
+ dlopen=
+ dlpreopen=
+ libdir=
+ library_names=
+ old_library=
+ inherited_linker_flags=
+ # If the library was installed with an old release of libtool,
+ # it will not redefine variables installed, or shouldnotlink
+ installed=yes
+ shouldnotlink=no
+ avoidtemprpath=
+
+
+ # Read the .la file
+ func_source "$lib"
+
+ # Convert "-framework foo" to "foo.ltframework"
+ if test -n "$inherited_linker_flags"; then
+ tmp_inherited_linker_flags=`$ECHO "X$inherited_linker_flags" | $Xsed -e 's/-framework \([^ $]*\)/\1.ltframework/g'`
+ for tmp_inherited_linker_flag in $tmp_inherited_linker_flags; do
+ case " $new_inherited_linker_flags " in
+ *" $tmp_inherited_linker_flag "*) ;;
+ *) new_inherited_linker_flags="$new_inherited_linker_flags $tmp_inherited_linker_flag";;
+ esac
+ done
+ fi
+ dependency_libs=`$ECHO "X $dependency_libs" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'`
+ if test "$linkmode,$pass" = "lib,link" ||
+ test "$linkmode,$pass" = "prog,scan" ||
+ { test "$linkmode" != prog && test "$linkmode" != lib; }; then
+ test -n "$dlopen" && dlfiles="$dlfiles $dlopen"
+ test -n "$dlpreopen" && dlprefiles="$dlprefiles $dlpreopen"
+ fi
+
+ if test "$pass" = conv; then
+ # Only check for convenience libraries
+ deplibs="$lib $deplibs"
+ if test -z "$libdir"; then
+ if test -z "$old_library"; then
+ func_fatal_error "cannot find name of link library for \`$lib'"
+ fi
+ # It is a libtool convenience library, so add in its objects.
+ convenience="$convenience $ladir/$objdir/$old_library"
+ old_convenience="$old_convenience $ladir/$objdir/$old_library"
+ tmp_libs=
+ for deplib in $dependency_libs; do
+ deplibs="$deplib $deplibs"
+ if $opt_duplicate_deps ; then
+ case "$tmp_libs " in
+ *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;;
+ esac
+ fi
+ tmp_libs="$tmp_libs $deplib"
+ done
+ elif test "$linkmode" != prog && test "$linkmode" != lib; then
+ func_fatal_error "\`$lib' is not a convenience library"
+ fi
+ continue
+ fi # $pass = conv
+
+
+ # Get the name of the library we link against.
+ linklib=
+ for l in $old_library $library_names; do
+ linklib="$l"
+ done
+ if test -z "$linklib"; then
+ func_fatal_error "cannot find name of link library for \`$lib'"
+ fi
+
+ # This library was specified with -dlopen.
+ if test "$pass" = dlopen; then
+ if test -z "$libdir"; then
+ func_fatal_error "cannot -dlopen a convenience library: \`$lib'"
+ fi
+ if test -z "$dlname" ||
+ test "$dlopen_support" != yes ||
+ test "$build_libtool_libs" = no; then
+ # If there is no dlname, no dlopen support or we're linking
+ # statically, we need to preload. We also need to preload any
+ # dependent libraries so libltdl's deplib preloader doesn't
+ # bomb out in the load deplibs phase.
+ dlprefiles="$dlprefiles $lib $dependency_libs"
+ else
+ newdlfiles="$newdlfiles $lib"
+ fi
+ continue
+ fi # $pass = dlopen
+
+ # We need an absolute path.
+ case $ladir in
+ [\\/]* | [A-Za-z]:[\\/]*) abs_ladir="$ladir" ;;
+ *)
+ abs_ladir=`cd "$ladir" && pwd`
+ if test -z "$abs_ladir"; then
+ func_warning "cannot determine absolute directory name of \`$ladir'"
+ func_warning "passing it literally to the linker, although it might fail"
+ abs_ladir="$ladir"
+ fi
+ ;;
+ esac
+ func_basename "$lib"
+ laname="$func_basename_result"
+
+ # Find the relevant object directory and library name.
+ if test "X$installed" = Xyes; then
+ if test ! -f "$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then
+ func_warning "library \`$lib' was moved."
+ dir="$ladir"
+ absdir="$abs_ladir"
+ libdir="$abs_ladir"
+ else
+ dir="$libdir"
+ absdir="$libdir"
+ fi
+ test "X$hardcode_automatic" = Xyes && avoidtemprpath=yes
+ else
+ if test ! -f "$ladir/$objdir/$linklib" && test -f "$abs_ladir/$linklib"; then
+ dir="$ladir"
+ absdir="$abs_ladir"
+ # Remove this search path later
+ notinst_path="$notinst_path $abs_ladir"
+ else
+ dir="$ladir/$objdir"
+ absdir="$abs_ladir/$objdir"
+ # Remove this search path later
+ notinst_path="$notinst_path $abs_ladir"
+ fi
+ fi # $installed = yes
+ func_stripname 'lib' '.la' "$laname"
+ name=$func_stripname_result
+
+ # This library was specified with -dlpreopen.
+ if test "$pass" = dlpreopen; then
+ if test -z "$libdir" && test "$linkmode" = prog; then
+ func_fatal_error "only libraries may -dlpreopen a convenience library: \`$lib'"
+ fi
+ # Prefer using a static library (so that no silly _DYNAMIC symbols
+ # are required to link).
+ if test -n "$old_library"; then
+ newdlprefiles="$newdlprefiles $dir/$old_library"
+ # Keep a list of preopened convenience libraries to check
+ # that they are being used correctly in the link pass.
+ test -z "$libdir" && \
+ dlpreconveniencelibs="$dlpreconveniencelibs $dir/$old_library"
+ # Otherwise, use the dlname, so that lt_dlopen finds it.
+ elif test -n "$dlname"; then
+ newdlprefiles="$newdlprefiles $dir/$dlname"
+ else
+ newdlprefiles="$newdlprefiles $dir/$linklib"
+ fi
+ fi # $pass = dlpreopen
+
+ if test -z "$libdir"; then
+ # Link the convenience library
+ if test "$linkmode" = lib; then
+ deplibs="$dir/$old_library $deplibs"
+ elif test "$linkmode,$pass" = "prog,link"; then
+ compile_deplibs="$dir/$old_library $compile_deplibs"
+ finalize_deplibs="$dir/$old_library $finalize_deplibs"
+ else
+ deplibs="$lib $deplibs" # used for prog,scan pass
+ fi
+ continue
+ fi
+
+
+ if test "$linkmode" = prog && test "$pass" != link; then
+ newlib_search_path="$newlib_search_path $ladir"
+ deplibs="$lib $deplibs"
+
+ linkalldeplibs=no
+ if test "$link_all_deplibs" != no || test -z "$library_names" ||
+ test "$build_libtool_libs" = no; then
+ linkalldeplibs=yes
+ fi
+
+ tmp_libs=
+ for deplib in $dependency_libs; do
+ case $deplib in
+ -L*) func_stripname '-L' '' "$deplib"
+ newlib_search_path="$newlib_search_path $func_stripname_result"
+ ;;
+ esac
+ # Need to link against all dependency_libs?
+ if test "$linkalldeplibs" = yes; then
+ deplibs="$deplib $deplibs"
+ else
+ # Need to hardcode shared library paths
+ # or/and link against static libraries
+ newdependency_libs="$deplib $newdependency_libs"
+ fi
+ if $opt_duplicate_deps ; then
+ case "$tmp_libs " in
+ *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;;
+ esac
+ fi
+ tmp_libs="$tmp_libs $deplib"
+ done # for deplib
+ continue
+ fi # $linkmode = prog...
+
+ if test "$linkmode,$pass" = "prog,link"; then
+ if test -n "$library_names" &&
+ { { test "$prefer_static_libs" = no ||
+ test "$prefer_static_libs,$installed" = "built,yes"; } ||
+ test -z "$old_library"; }; then
+ # We need to hardcode the library path
+ if test -n "$shlibpath_var" && test -z "$avoidtemprpath" ; then
+ # Make sure the rpath contains only unique directories.
+ case "$temp_rpath:" in
+ *"$absdir:"*) ;;
+ *) temp_rpath="$temp_rpath$absdir:" ;;
+ esac
+ fi
+
+ # Hardcode the library path.
+ # Skip directories that are in the system default run-time
+ # search path.
+ case " $sys_lib_dlsearch_path " in
+ *" $absdir "*) ;;
+ *)
+ case "$compile_rpath " in
+ *" $absdir "*) ;;
+ *) compile_rpath="$compile_rpath $absdir"
+ esac
+ ;;
+ esac
+ case " $sys_lib_dlsearch_path " in
+ *" $libdir "*) ;;
+ *)
+ case "$finalize_rpath " in
+ *" $libdir "*) ;;
+ *) finalize_rpath="$finalize_rpath $libdir"
+ esac
+ ;;
+ esac
+ fi # $linkmode,$pass = prog,link...
+
+ if test "$alldeplibs" = yes &&
+ { test "$deplibs_check_method" = pass_all ||
+ { test "$build_libtool_libs" = yes &&
+ test -n "$library_names"; }; }; then
+ # We only need to search for static libraries
+ continue
+ fi
+ fi
+
+ link_static=no # Whether the deplib will be linked statically
+ use_static_libs=$prefer_static_libs
+ if test "$use_static_libs" = built && test "$installed" = yes; then
+ use_static_libs=no
+ fi
+ if test -n "$library_names" &&
+ { test "$use_static_libs" = no || test -z "$old_library"; }; then
+ case $host in
+ *cygwin* | *mingw* | *cegcc*)
+ # No point in relinking DLLs because paths are not encoded
+ notinst_deplibs="$notinst_deplibs $lib"
+ need_relink=no
+ ;;
+ *)
+ if test "$installed" = no; then
+ notinst_deplibs="$notinst_deplibs $lib"
+ need_relink=yes
+ fi
+ ;;
+ esac
+ # This is a shared library
+
+ # Warn about portability, can't link against -module's on some
+ # systems (darwin). Don't bleat about dlopened modules though!
+ dlopenmodule=""
+ for dlpremoduletest in $dlprefiles; do
+ if test "X$dlpremoduletest" = "X$lib"; then
+ dlopenmodule="$dlpremoduletest"
+ break
+ fi
+ done
+ if test -z "$dlopenmodule" && test "$shouldnotlink" = yes && test "$pass" = link; then
+ $ECHO
+ if test "$linkmode" = prog; then
+ $ECHO "*** Warning: Linking the executable $output against the loadable module"
+ else
+ $ECHO "*** Warning: Linking the shared library $output against the loadable module"
+ fi
+ $ECHO "*** $linklib is not portable!"
+ fi
+ if test "$linkmode" = lib &&
+ test "$hardcode_into_libs" = yes; then
+ # Hardcode the library path.
+ # Skip directories that are in the system default run-time
+ # search path.
+ case " $sys_lib_dlsearch_path " in
+ *" $absdir "*) ;;
+ *)
+ case "$compile_rpath " in
+ *" $absdir "*) ;;
+ *) compile_rpath="$compile_rpath $absdir"
+ esac
+ ;;
+ esac
+ case " $sys_lib_dlsearch_path " in
+ *" $libdir "*) ;;
+ *)
+ case "$finalize_rpath " in
+ *" $libdir "*) ;;
+ *) finalize_rpath="$finalize_rpath $libdir"
+ esac
+ ;;
+ esac
+ fi
+
+ if test -n "$old_archive_from_expsyms_cmds"; then
+ # figure out the soname
+ set dummy $library_names
+ shift
+ realname="$1"
+ shift
+ libname=`eval "\\$ECHO \"$libname_spec\""`
+ # use dlname if we got it. it's perfectly good, no?
+ if test -n "$dlname"; then
+ soname="$dlname"
+ elif test -n "$soname_spec"; then
+ # bleh windows
+ case $host in
+ *cygwin* | mingw* | *cegcc*)
+ func_arith $current - $age
+ major=$func_arith_result
+ versuffix="-$major"
+ ;;
+ esac
+ eval soname=\"$soname_spec\"
+ else
+ soname="$realname"
+ fi
+
+ # Make a new name for the extract_expsyms_cmds to use
+ soroot="$soname"
+ func_basename "$soroot"
+ soname="$func_basename_result"
+ func_stripname 'lib' '.dll' "$soname"
+ newlib=libimp-$func_stripname_result.a
+
+ # If the library has no export list, then create one now
+ if test -f "$output_objdir/$soname-def"; then :
+ else
+ func_verbose "extracting exported symbol list from \`$soname'"
+ func_execute_cmds "$extract_expsyms_cmds" 'exit $?'
+ fi
+
+ # Create $newlib
+ if test -f "$output_objdir/$newlib"; then :; else
+ func_verbose "generating import library for \`$soname'"
+ func_execute_cmds "$old_archive_from_expsyms_cmds" 'exit $?'
+ fi
+ # make sure the library variables are pointing to the new library
+ dir=$output_objdir
+ linklib=$newlib
+ fi # test -n "$old_archive_from_expsyms_cmds"
+
+ if test "$linkmode" = prog || test "$mode" != relink; then
+ add_shlibpath=
+ add_dir=
+ add=
+ lib_linked=yes
+ case $hardcode_action in
+ immediate | unsupported)
+ if test "$hardcode_direct" = no; then
+ add="$dir/$linklib"
+ case $host in
+ *-*-sco3.2v5.0.[024]*) add_dir="-L$dir" ;;
+ *-*-sysv4*uw2*) add_dir="-L$dir" ;;
+ *-*-sysv5OpenUNIX* | *-*-sysv5UnixWare7.[01].[10]* | \
+ *-*-unixware7*) add_dir="-L$dir" ;;
+ *-*-darwin* )
+ # if the lib is a (non-dlopened) module then we can not
+ # link against it, someone is ignoring the earlier warnings
+ if /usr/bin/file -L $add 2> /dev/null |
+ $GREP ": [^:]* bundle" >/dev/null ; then
+ if test "X$dlopenmodule" != "X$lib"; then
+ $ECHO "*** Warning: lib $linklib is a module, not a shared library"
+ if test -z "$old_library" ; then
+ $ECHO
+ $ECHO "*** And there doesn't seem to be a static archive available"
+ $ECHO "*** The link will probably fail, sorry"
+ else
+ add="$dir/$old_library"
+ fi
+ elif test -n "$old_library"; then
+ add="$dir/$old_library"
+ fi
+ fi
+ esac
+ elif test "$hardcode_minus_L" = no; then
+ case $host in
+ *-*-sunos*) add_shlibpath="$dir" ;;
+ esac
+ add_dir="-L$dir"
+ add="-l$name"
+ elif test "$hardcode_shlibpath_var" = no; then
+ add_shlibpath="$dir"
+ add="-l$name"
+ else
+ lib_linked=no
+ fi
+ ;;
+ relink)
+ if test "$hardcode_direct" = yes &&
+ test "$hardcode_direct_absolute" = no; then
+ add="$dir/$linklib"
+ elif test "$hardcode_minus_L" = yes; then
+ add_dir="-L$dir"
+ # Try looking first in the location we're being installed to.
+ if test -n "$inst_prefix_dir"; then
+ case $libdir in
+ [\\/]*)
+ add_dir="$add_dir -L$inst_prefix_dir$libdir"
+ ;;
+ esac
+ fi
+ add="-l$name"
+ elif test "$hardcode_shlibpath_var" = yes; then
+ add_shlibpath="$dir"
+ add="-l$name"
+ else
+ lib_linked=no
+ fi
+ ;;
+ *) lib_linked=no ;;
+ esac
+
+ if test "$lib_linked" != yes; then
+ func_fatal_configuration "unsupported hardcode properties"
+ fi
+
+ if test -n "$add_shlibpath"; then
+ case :$compile_shlibpath: in
+ *":$add_shlibpath:"*) ;;
+ *) compile_shlibpath="$compile_shlibpath$add_shlibpath:" ;;
+ esac
+ fi
+ if test "$linkmode" = prog; then
+ test -n "$add_dir" && compile_deplibs="$add_dir $compile_deplibs"
+ test -n "$add" && compile_deplibs="$add $compile_deplibs"
+ else
+ test -n "$add_dir" && deplibs="$add_dir $deplibs"
+ test -n "$add" && deplibs="$add $deplibs"
+ if test "$hardcode_direct" != yes &&
+ test "$hardcode_minus_L" != yes &&
+ test "$hardcode_shlibpath_var" = yes; then
+ case :$finalize_shlibpath: in
+ *":$libdir:"*) ;;
+ *) finalize_shlibpath="$finalize_shlibpath$libdir:" ;;
+ esac
+ fi
+ fi
+ fi
+
+ if test "$linkmode" = prog || test "$mode" = relink; then
+ add_shlibpath=
+ add_dir=
+ add=
+ # Finalize command for both is simple: just hardcode it.
+ if test "$hardcode_direct" = yes &&
+ test "$hardcode_direct_absolute" = no; then
+ add="$libdir/$linklib"
+ elif test "$hardcode_minus_L" = yes; then
+ add_dir="-L$libdir"
+ add="-l$name"
+ elif test "$hardcode_shlibpath_var" = yes; then
+ case :$finalize_shlibpath: in
+ *":$libdir:"*) ;;
+ *) finalize_shlibpath="$finalize_shlibpath$libdir:" ;;
+ esac
+ add="-l$name"
+ elif test "$hardcode_automatic" = yes; then
+ if test -n "$inst_prefix_dir" &&
+ test -f "$inst_prefix_dir$libdir/$linklib" ; then
+ add="$inst_prefix_dir$libdir/$linklib"
+ else
+ add="$libdir/$linklib"
+ fi
+ else
+ # We cannot seem to hardcode it, guess we'll fake it.
+ add_dir="-L$libdir"
+ # Try looking first in the location we're being installed to.
+ if test -n "$inst_prefix_dir"; then
+ case $libdir in
+ [\\/]*)
+ add_dir="$add_dir -L$inst_prefix_dir$libdir"
+ ;;
+ esac
+ fi
+ add="-l$name"
+ fi
+
+ if test "$linkmode" = prog; then
+ test -n "$add_dir" && finalize_deplibs="$add_dir $finalize_deplibs"
+ test -n "$add" && finalize_deplibs="$add $finalize_deplibs"
+ else
+ test -n "$add_dir" && deplibs="$add_dir $deplibs"
+ test -n "$add" && deplibs="$add $deplibs"
+ fi
+ fi
+ elif test "$linkmode" = prog; then
+ # Here we assume that one of hardcode_direct or hardcode_minus_L
+ # is not unsupported. This is valid on all known static and
+ # shared platforms.
+ if test "$hardcode_direct" != unsupported; then
+ test -n "$old_library" && linklib="$old_library"
+ compile_deplibs="$dir/$linklib $compile_deplibs"
+ finalize_deplibs="$dir/$linklib $finalize_deplibs"
+ else
+ compile_deplibs="-l$name -L$dir $compile_deplibs"
+ finalize_deplibs="-l$name -L$dir $finalize_deplibs"
+ fi
+ elif test "$build_libtool_libs" = yes; then
+ # Not a shared library
+ if test "$deplibs_check_method" != pass_all; then
+ # We're trying link a shared library against a static one
+ # but the system doesn't support it.
+
+ # Just print a warning and add the library to dependency_libs so
+ # that the program can be linked against the static library.
+ $ECHO
+ $ECHO "*** Warning: This system can not link to static lib archive $lib."
+ $ECHO "*** I have the capability to make that library automatically link in when"
+ $ECHO "*** you link to this library. But I can only do this if you have a"
+ $ECHO "*** shared version of the library, which you do not appear to have."
+ if test "$module" = yes; then
+ $ECHO "*** But as you try to build a module library, libtool will still create "
+ $ECHO "*** a static module, that should work as long as the dlopening application"
+ $ECHO "*** is linked with the -dlopen flag to resolve symbols at runtime."
+ if test -z "$global_symbol_pipe"; then
+ $ECHO
+ $ECHO "*** However, this would only work if libtool was able to extract symbol"
+ $ECHO "*** lists from a program, using \`nm' or equivalent, but libtool could"
+ $ECHO "*** not find such a program. So, this module is probably useless."
+ $ECHO "*** \`nm' from GNU binutils and a full rebuild may help."
+ fi
+ if test "$build_old_libs" = no; then
+ build_libtool_libs=module
+ build_old_libs=yes
+ else
+ build_libtool_libs=no
+ fi
+ fi
+ else
+ deplibs="$dir/$old_library $deplibs"
+ link_static=yes
+ fi
+ fi # link shared/static library?
+
+ if test "$linkmode" = lib; then
+ if test -n "$dependency_libs" &&
+ { test "$hardcode_into_libs" != yes ||
+ test "$build_old_libs" = yes ||
+ test "$link_static" = yes; }; then
+ # Extract -R from dependency_libs
+ temp_deplibs=
+ for libdir in $dependency_libs; do
+ case $libdir in
+ -R*) func_stripname '-R' '' "$libdir"
+ temp_xrpath=$func_stripname_result
+ case " $xrpath " in
+ *" $temp_xrpath "*) ;;
+ *) xrpath="$xrpath $temp_xrpath";;
+ esac;;
+ *) temp_deplibs="$temp_deplibs $libdir";;
+ esac
+ done
+ dependency_libs="$temp_deplibs"
+ fi
+
+ newlib_search_path="$newlib_search_path $absdir"
+ # Link against this library
+ test "$link_static" = no && newdependency_libs="$abs_ladir/$laname $newdependency_libs"
+ # ... and its dependency_libs
+ tmp_libs=
+ for deplib in $dependency_libs; do
+ newdependency_libs="$deplib $newdependency_libs"
+ if $opt_duplicate_deps ; then
+ case "$tmp_libs " in
+ *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;;
+ esac
+ fi
+ tmp_libs="$tmp_libs $deplib"
+ done
+
+ if test "$link_all_deplibs" != no; then
+ # Add the search paths of all dependency libraries
+ for deplib in $dependency_libs; do
+ path=
+ case $deplib in
+ -L*) path="$deplib" ;;
+ *.la)
+ func_dirname "$deplib" "" "."
+ dir="$func_dirname_result"
+ # We need an absolute path.
+ case $dir in
+ [\\/]* | [A-Za-z]:[\\/]*) absdir="$dir" ;;
+ *)
+ absdir=`cd "$dir" && pwd`
+ if test -z "$absdir"; then
+ func_warning "cannot determine absolute directory name of \`$dir'"
+ absdir="$dir"
+ fi
+ ;;
+ esac
+ if $GREP "^installed=no" $deplib > /dev/null; then
+ case $host in
+ *-*-darwin*)
+ depdepl=
+ eval deplibrary_names=`${SED} -n -e 's/^library_names=\(.*\)$/\1/p' $deplib`
+ if test -n "$deplibrary_names" ; then
+ for tmp in $deplibrary_names ; do
+ depdepl=$tmp
+ done
+ if test -f "$absdir/$objdir/$depdepl" ; then
+ depdepl="$absdir/$objdir/$depdepl"
+ darwin_install_name=`${OTOOL} -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'`
+ if test -z "$darwin_install_name"; then
+ darwin_install_name=`${OTOOL64} -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'`
+ fi
+ compiler_flags="$compiler_flags ${wl}-dylib_file ${wl}${darwin_install_name}:${depdepl}"
+ linker_flags="$linker_flags -dylib_file ${darwin_install_name}:${depdepl}"
+ path=
+ fi
+ fi
+ ;;
+ *)
+ path="-L$absdir/$objdir"
+ ;;
+ esac
+ else
+ eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib`
+ test -z "$libdir" && \
+ func_fatal_error "\`$deplib' is not a valid libtool archive"
+ test "$absdir" != "$libdir" && \
+ func_warning "\`$deplib' seems to be moved"
+
+ path="-L$absdir"
+ fi
+ ;;
+ esac
+ case " $deplibs " in
+ *" $path "*) ;;
+ *) deplibs="$path $deplibs" ;;
+ esac
+ done
+ fi # link_all_deplibs != no
+ fi # linkmode = lib
+ done # for deplib in $libs
+ if test "$pass" = link; then
+ if test "$linkmode" = "prog"; then
+ compile_deplibs="$new_inherited_linker_flags $compile_deplibs"
+ finalize_deplibs="$new_inherited_linker_flags $finalize_deplibs"
+ else
+ compiler_flags="$compiler_flags "`$ECHO "X $new_inherited_linker_flags" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'`
+ fi
+ fi
+ dependency_libs="$newdependency_libs"
+ if test "$pass" = dlpreopen; then
+ # Link the dlpreopened libraries before other libraries
+ for deplib in $save_deplibs; do
+ deplibs="$deplib $deplibs"
+ done
+ fi
+ if test "$pass" != dlopen; then
+ if test "$pass" != conv; then
+ # Make sure lib_search_path contains only unique directories.
+ lib_search_path=
+ for dir in $newlib_search_path; do
+ case "$lib_search_path " in
+ *" $dir "*) ;;
+ *) lib_search_path="$lib_search_path $dir" ;;
+ esac
+ done
+ newlib_search_path=
+ fi
+
+ if test "$linkmode,$pass" != "prog,link"; then
+ vars="deplibs"
+ else
+ vars="compile_deplibs finalize_deplibs"
+ fi
+ for var in $vars dependency_libs; do
+ # Add libraries to $var in reverse order
+ eval tmp_libs=\"\$$var\"
+ new_libs=
+ for deplib in $tmp_libs; do
+ # FIXME: Pedantically, this is the right thing to do, so
+ # that some nasty dependency loop isn't accidentally
+ # broken:
+ #new_libs="$deplib $new_libs"
+ # Pragmatically, this seems to cause very few problems in
+ # practice:
+ case $deplib in
+ -L*) new_libs="$deplib $new_libs" ;;
+ -R*) ;;
+ *)
+ # And here is the reason: when a library appears more
+ # than once as an explicit dependence of a library, or
+ # is implicitly linked in more than once by the
+ # compiler, it is considered special, and multiple
+ # occurrences thereof are not removed. Compare this
+ # with having the same library being listed as a
+ # dependency of multiple other libraries: in this case,
+ # we know (pedantically, we assume) the library does not
+ # need to be listed more than once, so we keep only the
+ # last copy. This is not always right, but it is rare
+ # enough that we require users that really mean to play
+ # such unportable linking tricks to link the library
+ # using -Wl,-lname, so that libtool does not consider it
+ # for duplicate removal.
+ case " $specialdeplibs " in
+ *" $deplib "*) new_libs="$deplib $new_libs" ;;
+ *)
+ case " $new_libs " in
+ *" $deplib "*) ;;
+ *) new_libs="$deplib $new_libs" ;;
+ esac
+ ;;
+ esac
+ ;;
+ esac
+ done
+ tmp_libs=
+ for deplib in $new_libs; do
+ case $deplib in
+ -L*)
+ case " $tmp_libs " in
+ *" $deplib "*) ;;
+ *) tmp_libs="$tmp_libs $deplib" ;;
+ esac
+ ;;
+ *) tmp_libs="$tmp_libs $deplib" ;;
+ esac
+ done
+ eval $var=\"$tmp_libs\"
+ done # for var
+ fi
+ # Last step: remove runtime libs from dependency_libs
+ # (they stay in deplibs)
+ tmp_libs=
+ for i in $dependency_libs ; do
+ case " $predeps $postdeps $compiler_lib_search_path " in
+ *" $i "*)
+ i=""
+ ;;
+ esac
+ if test -n "$i" ; then
+ tmp_libs="$tmp_libs $i"
+ fi
+ done
+ dependency_libs=$tmp_libs
+ done # for pass
+ if test "$linkmode" = prog; then
+ dlfiles="$newdlfiles"
+ fi
+ if test "$linkmode" = prog || test "$linkmode" = lib; then
+ dlprefiles="$newdlprefiles"
+ fi
+
+ case $linkmode in
+ oldlib)
+ if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
+ func_warning "\`-dlopen' is ignored for archives"
+ fi
+
+ case " $deplibs" in
+ *\ -l* | *\ -L*)
+ func_warning "\`-l' and \`-L' are ignored for archives" ;;
+ esac
+
+ test -n "$rpath" && \
+ func_warning "\`-rpath' is ignored for archives"
+
+ test -n "$xrpath" && \
+ func_warning "\`-R' is ignored for archives"
+
+ test -n "$vinfo" && \
+ func_warning "\`-version-info/-version-number' is ignored for archives"
+
+ test -n "$release" && \
+ func_warning "\`-release' is ignored for archives"
+
+ test -n "$export_symbols$export_symbols_regex" && \
+ func_warning "\`-export-symbols' is ignored for archives"
+
+ # Now set the variables for building old libraries.
+ build_libtool_libs=no
+ oldlibs="$output"
+ objs="$objs$old_deplibs"
+ ;;
+
+ lib)
+ # Make sure we only generate libraries of the form `libNAME.la'.
+ case $outputname in
+ lib*)
+ func_stripname 'lib' '.la' "$outputname"
+ name=$func_stripname_result
+ eval shared_ext=\"$shrext_cmds\"
+ eval libname=\"$libname_spec\"
+ ;;
+ *)
+ test "$module" = no && \
+ func_fatal_help "libtool library \`$output' must begin with \`lib'"
+
+ if test "$need_lib_prefix" != no; then
+ # Add the "lib" prefix for modules if required
+ func_stripname '' '.la' "$outputname"
+ name=$func_stripname_result
+ eval shared_ext=\"$shrext_cmds\"
+ eval libname=\"$libname_spec\"
+ else
+ func_stripname '' '.la' "$outputname"
+ libname=$func_stripname_result
+ fi
+ ;;
+ esac
+
+ if test -n "$objs"; then
+ if test "$deplibs_check_method" != pass_all; then
+ func_fatal_error "cannot build libtool library \`$output' from non-libtool objects on this host:$objs"
+ else
+ $ECHO
+ $ECHO "*** Warning: Linking the shared library $output against the non-libtool"
+ $ECHO "*** objects $objs is not portable!"
+ libobjs="$libobjs $objs"
+ fi
+ fi
+
+ test "$dlself" != no && \
+ func_warning "\`-dlopen self' is ignored for libtool libraries"
+
+ set dummy $rpath
+ shift
+ test "$#" -gt 1 && \
+ func_warning "ignoring multiple \`-rpath's for a libtool library"
+
+ install_libdir="$1"
+
+ oldlibs=
+ if test -z "$rpath"; then
+ if test "$build_libtool_libs" = yes; then
+ # Building a libtool convenience library.
+ # Some compilers have problems with a `.al' extension so
+ # convenience libraries should have the same extension an
+ # archive normally would.
+ oldlibs="$output_objdir/$libname.$libext $oldlibs"
+ build_libtool_libs=convenience
+ build_old_libs=yes
+ fi
+
+ test -n "$vinfo" && \
+ func_warning "\`-version-info/-version-number' is ignored for convenience libraries"
+
+ test -n "$release" && \
+ func_warning "\`-release' is ignored for convenience libraries"
+ else
+
+ # Parse the version information argument.
+ save_ifs="$IFS"; IFS=':'
+ set dummy $vinfo 0 0 0
+ shift
+ IFS="$save_ifs"
+
+ test -n "$7" && \
+ func_fatal_help "too many parameters to \`-version-info'"
+
+ # convert absolute version numbers to libtool ages
+ # this retains compatibility with .la files and attempts
+ # to make the code below a bit more comprehensible
+
+ case $vinfo_number in
+ yes)
+ number_major="$1"
+ number_minor="$2"
+ number_revision="$3"
+ #
+ # There are really only two kinds -- those that
+ # use the current revision as the major version
+ # and those that subtract age and use age as
+ # a minor version. But, then there is irix
+ # which has an extra 1 added just for fun
+ #
+ case $version_type in
+ darwin|linux|osf|windows|none)
+ func_arith $number_major + $number_minor
+ current=$func_arith_result
+ age="$number_minor"
+ revision="$number_revision"
+ ;;
+ freebsd-aout|freebsd-elf|sunos)
+ current="$number_major"
+ revision="$number_minor"
+ age="0"
+ ;;
+ irix|nonstopux)
+ func_arith $number_major + $number_minor
+ current=$func_arith_result
+ age="$number_minor"
+ revision="$number_minor"
+ lt_irix_increment=no
+ ;;
+ *)
+ func_fatal_configuration "$modename: unknown library version type \`$version_type'"
+ ;;
+ esac
+ ;;
+ no)
+ current="$1"
+ revision="$2"
+ age="$3"
+ ;;
+ esac
+
+ # Check that each of the things are valid numbers.
+ case $current in
+ 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;;
+ *)
+ func_error "CURRENT \`$current' must be a nonnegative integer"
+ func_fatal_error "\`$vinfo' is not valid version information"
+ ;;
+ esac
+
+ case $revision in
+ 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;;
+ *)
+ func_error "REVISION \`$revision' must be a nonnegative integer"
+ func_fatal_error "\`$vinfo' is not valid version information"
+ ;;
+ esac
+
+ case $age in
+ 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;;
+ *)
+ func_error "AGE \`$age' must be a nonnegative integer"
+ func_fatal_error "\`$vinfo' is not valid version information"
+ ;;
+ esac
+
+ if test "$age" -gt "$current"; then
+ func_error "AGE \`$age' is greater than the current interface number \`$current'"
+ func_fatal_error "\`$vinfo' is not valid version information"
+ fi
+
+ # Calculate the version variables.
+ major=
+ versuffix=
+ verstring=
+ case $version_type in
+ none) ;;
+
+ darwin)
+ # Like Linux, but with the current version available in
+ # verstring for coding it into the library header
+ func_arith $current - $age
+ major=.$func_arith_result
+ versuffix="$major.$age.$revision"
+ # Darwin ld doesn't like 0 for these options...
+ func_arith $current + 1
+ minor_current=$func_arith_result
+ xlcverstring="${wl}-compatibility_version ${wl}$minor_current ${wl}-current_version ${wl}$minor_current.$revision"
+ verstring="-compatibility_version $minor_current -current_version $minor_current.$revision"
+ ;;
+
+ freebsd-aout)
+ major=".$current"
+ versuffix=".$current.$revision";
+ ;;
+
+ freebsd-elf)
+ major=".$current"
+ versuffix=".$current"
+ ;;
+
+ irix | nonstopux)
+ if test "X$lt_irix_increment" = "Xno"; then
+ func_arith $current - $age
+ else
+ func_arith $current - $age + 1
+ fi
+ major=$func_arith_result
+
+ case $version_type in
+ nonstopux) verstring_prefix=nonstopux ;;
+ *) verstring_prefix=sgi ;;
+ esac
+ verstring="$verstring_prefix$major.$revision"
+
+ # Add in all the interfaces that we are compatible with.
+ loop=$revision
+ while test "$loop" -ne 0; do
+ func_arith $revision - $loop
+ iface=$func_arith_result
+ func_arith $loop - 1
+ loop=$func_arith_result
+ verstring="$verstring_prefix$major.$iface:$verstring"
+ done
+
+ # Before this point, $major must not contain `.'.
+ major=.$major
+ versuffix="$major.$revision"
+ ;;
+
+ linux)
+ func_arith $current - $age
+ major=.$func_arith_result
+ versuffix="$major.$age.$revision"
+ ;;
+
+ osf)
+ func_arith $current - $age
+ major=.$func_arith_result
+ versuffix=".$current.$age.$revision"
+ verstring="$current.$age.$revision"
+
+ # Add in all the interfaces that we are compatible with.
+ loop=$age
+ while test "$loop" -ne 0; do
+ func_arith $current - $loop
+ iface=$func_arith_result
+ func_arith $loop - 1
+ loop=$func_arith_result
+ verstring="$verstring:${iface}.0"
+ done
+
+ # Make executables depend on our current version.
+ verstring="$verstring:${current}.0"
+ ;;
+
+ qnx)
+ major=".$current"
+ versuffix=".$current"
+ ;;
+
+ sunos)
+ major=".$current"
+ versuffix=".$current.$revision"
+ ;;
+
+ windows)
+ # Use '-' rather than '.', since we only want one
+ # extension on DOS 8.3 filesystems.
+ func_arith $current - $age
+ major=$func_arith_result
+ versuffix="-$major"
+ ;;
+
+ *)
+ func_fatal_configuration "unknown library version type \`$version_type'"
+ ;;
+ esac
+
+ # Clear the version info if we defaulted, and they specified a release.
+ if test -z "$vinfo" && test -n "$release"; then
+ major=
+ case $version_type in
+ darwin)
+ # we can't check for "0.0" in archive_cmds due to quoting
+ # problems, so we reset it completely
+ verstring=
+ ;;
+ *)
+ verstring="0.0"
+ ;;
+ esac
+ if test "$need_version" = no; then
+ versuffix=
+ else
+ versuffix=".0.0"
+ fi
+ fi
+
+ # Remove version info from name if versioning should be avoided
+ if test "$avoid_version" = yes && test "$need_version" = no; then
+ major=
+ versuffix=
+ verstring=""
+ fi
+
+ # Check to see if the archive will have undefined symbols.
+ if test "$allow_undefined" = yes; then
+ if test "$allow_undefined_flag" = unsupported; then
+ func_warning "undefined symbols not allowed in $host shared libraries"
+ build_libtool_libs=no
+ build_old_libs=yes
+ fi
+ else
+ # Don't allow undefined symbols.
+ allow_undefined_flag="$no_undefined_flag"
+ fi
+
+ fi
+
+ func_generate_dlsyms "$libname" "$libname" "yes"
+ libobjs="$libobjs $symfileobj"
+ test "X$libobjs" = "X " && libobjs=
+
+ if test "$mode" != relink; then
+ # Remove our outputs, but don't remove object files since they
+ # may have been created when compiling PIC objects.
+ removelist=
+ tempremovelist=`$ECHO "$output_objdir/*"`
+ for p in $tempremovelist; do
+ case $p in
+ *.$objext | *.gcno)
+ ;;
+ $output_objdir/$outputname | $output_objdir/$libname.* | $output_objdir/${libname}${release}.*)
+ if test "X$precious_files_regex" != "X"; then
+ if $ECHO "$p" | $EGREP -e "$precious_files_regex" >/dev/null 2>&1
+ then
+ continue
+ fi
+ fi
+ removelist="$removelist $p"
+ ;;
+ *) ;;
+ esac
+ done
+ test -n "$removelist" && \
+ func_show_eval "${RM}r \$removelist"
+ fi
+
+ # Now set the variables for building old libraries.
+ if test "$build_old_libs" = yes && test "$build_libtool_libs" != convenience ; then
+ oldlibs="$oldlibs $output_objdir/$libname.$libext"
+
+ # Transform .lo files to .o files.
+ oldobjs="$objs "`$ECHO "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}'$/d' -e "$lo2o" | $NL2SP`
+ fi
+
+ # Eliminate all temporary directories.
+ #for path in $notinst_path; do
+ # lib_search_path=`$ECHO "X$lib_search_path " | $Xsed -e "s% $path % %g"`
+ # deplibs=`$ECHO "X$deplibs " | $Xsed -e "s% -L$path % %g"`
+ # dependency_libs=`$ECHO "X$dependency_libs " | $Xsed -e "s% -L$path % %g"`
+ #done
+
+ if test -n "$xrpath"; then
+ # If the user specified any rpath flags, then add them.
+ temp_xrpath=
+ for libdir in $xrpath; do
+ temp_xrpath="$temp_xrpath -R$libdir"
+ case "$finalize_rpath " in
+ *" $libdir "*) ;;
+ *) finalize_rpath="$finalize_rpath $libdir" ;;
+ esac
+ done
+ if test "$hardcode_into_libs" != yes || test "$build_old_libs" = yes; then
+ dependency_libs="$temp_xrpath $dependency_libs"
+ fi
+ fi
+
+ # Make sure dlfiles contains only unique files that won't be dlpreopened
+ old_dlfiles="$dlfiles"
+ dlfiles=
+ for lib in $old_dlfiles; do
+ case " $dlprefiles $dlfiles " in
+ *" $lib "*) ;;
+ *) dlfiles="$dlfiles $lib" ;;
+ esac
+ done
+
+ # Make sure dlprefiles contains only unique files
+ old_dlprefiles="$dlprefiles"
+ dlprefiles=
+ for lib in $old_dlprefiles; do
+ case "$dlprefiles " in
+ *" $lib "*) ;;
+ *) dlprefiles="$dlprefiles $lib" ;;
+ esac
+ done
+
+ if test "$build_libtool_libs" = yes; then
+ if test -n "$rpath"; then
+ case $host in
+ *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos* | *-cegcc*)
+ # these systems don't actually have a c library (as such)!
+ ;;
+ *-*-rhapsody* | *-*-darwin1.[012])
+ # Rhapsody C library is in the System framework
+ deplibs="$deplibs System.ltframework"
+ ;;
+ *-*-netbsd*)
+ # Don't link with libc until the a.out ld.so is fixed.
+ ;;
+ *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*)
+ # Do not include libc due to us having libc/libc_r.
+ ;;
+ *-*-sco3.2v5* | *-*-sco5v6*)
+ # Causes problems with __ctype
+ ;;
+ *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*)
+ # Compiler inserts libc in the correct place for threads to work
+ ;;
+ *)
+ # Add libc to deplibs on all other systems if necessary.
+ if test "$build_libtool_need_lc" = "yes"; then
+ deplibs="$deplibs -lc"
+ fi
+ ;;
+ esac
+ fi
+
+ # Transform deplibs into only deplibs that can be linked in shared.
+ name_save=$name
+ libname_save=$libname
+ release_save=$release
+ versuffix_save=$versuffix
+ major_save=$major
+ # I'm not sure if I'm treating the release correctly. I think
+ # release should show up in the -l (ie -lgmp5) so we don't want to
+ # add it in twice. Is that correct?
+ release=""
+ versuffix=""
+ major=""
+ newdeplibs=
+ droppeddeps=no
+ case $deplibs_check_method in
+ pass_all)
+ # Don't check for shared/static. Everything works.
+ # This might be a little naive. We might want to check
+ # whether the library exists or not. But this is on
+ # osf3 & osf4 and I'm not really sure... Just
+ # implementing what was already the behavior.
+ newdeplibs=$deplibs
+ ;;
+ test_compile)
+ # This code stresses the "libraries are programs" paradigm to its
+ # limits. Maybe even breaks it. We compile a program, linking it
+ # against the deplibs as a proxy for the library. Then we can check
+ # whether they linked in statically or dynamically with ldd.
+ $opt_dry_run || $RM conftest.c
+ cat > conftest.c <<EOF
+ int main() { return 0; }
+EOF
+ $opt_dry_run || $RM conftest
+ if $LTCC $LTCFLAGS -o conftest conftest.c $deplibs; then
+ ldd_output=`ldd conftest`
+ for i in $deplibs; do
+ case $i in
+ -l*)
+ func_stripname -l '' "$i"
+ name=$func_stripname_result
+ if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+ case " $predeps $postdeps " in
+ *" $i "*)
+ newdeplibs="$newdeplibs $i"
+ i=""
+ ;;
+ esac
+ fi
+ if test -n "$i" ; then
+ libname=`eval "\\$ECHO \"$libname_spec\""`
+ deplib_matches=`eval "\\$ECHO \"$library_names_spec\""`
+ set dummy $deplib_matches; shift
+ deplib_match=$1
+ if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0 ; then
+ newdeplibs="$newdeplibs $i"
+ else
+ droppeddeps=yes
+ $ECHO
+ $ECHO "*** Warning: dynamic linker does not accept needed library $i."
+ $ECHO "*** I have the capability to make that library automatically link in when"
+ $ECHO "*** you link to this library. But I can only do this if you have a"
+ $ECHO "*** shared version of the library, which I believe you do not have"
+ $ECHO "*** because a test_compile did reveal that the linker did not use it for"
+ $ECHO "*** its dynamic dependency list that programs get resolved with at runtime."
+ fi
+ fi
+ ;;
+ *)
+ newdeplibs="$newdeplibs $i"
+ ;;
+ esac
+ done
+ else
+ # Error occurred in the first compile. Let's try to salvage
+ # the situation: Compile a separate program for each library.
+ for i in $deplibs; do
+ case $i in
+ -l*)
+ func_stripname -l '' "$i"
+ name=$func_stripname_result
+ $opt_dry_run || $RM conftest
+ if $LTCC $LTCFLAGS -o conftest conftest.c $i; then
+ ldd_output=`ldd conftest`
+ if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+ case " $predeps $postdeps " in
+ *" $i "*)
+ newdeplibs="$newdeplibs $i"
+ i=""
+ ;;
+ esac
+ fi
+ if test -n "$i" ; then
+ libname=`eval "\\$ECHO \"$libname_spec\""`
+ deplib_matches=`eval "\\$ECHO \"$library_names_spec\""`
+ set dummy $deplib_matches; shift
+ deplib_match=$1
+ if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0 ; then
+ newdeplibs="$newdeplibs $i"
+ else
+ droppeddeps=yes
+ $ECHO
+ $ECHO "*** Warning: dynamic linker does not accept needed library $i."
+ $ECHO "*** I have the capability to make that library automatically link in when"
+ $ECHO "*** you link to this library. But I can only do this if you have a"
+ $ECHO "*** shared version of the library, which you do not appear to have"
+ $ECHO "*** because a test_compile did reveal that the linker did not use this one"
+ $ECHO "*** as a dynamic dependency that programs can get resolved with at runtime."
+ fi
+ fi
+ else
+ droppeddeps=yes
+ $ECHO
+ $ECHO "*** Warning! Library $i is needed by this library but I was not able to"
+ $ECHO "*** make it link in! You will probably need to install it or some"
+ $ECHO "*** library that it depends on before this library will be fully"
+ $ECHO "*** functional. Installing it before continuing would be even better."
+ fi
+ ;;
+ *)
+ newdeplibs="$newdeplibs $i"
+ ;;
+ esac
+ done
+ fi
+ ;;
+ file_magic*)
+ set dummy $deplibs_check_method; shift
+ file_magic_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"`
+ for a_deplib in $deplibs; do
+ case $a_deplib in
+ -l*)
+ func_stripname -l '' "$a_deplib"
+ name=$func_stripname_result
+ if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+ case " $predeps $postdeps " in
+ *" $a_deplib "*)
+ newdeplibs="$newdeplibs $a_deplib"
+ a_deplib=""
+ ;;
+ esac
+ fi
+ if test -n "$a_deplib" ; then
+ libname=`eval "\\$ECHO \"$libname_spec\""`
+ for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do
+ potential_libs=`ls $i/$libname[.-]* 2>/dev/null`
+ for potent_lib in $potential_libs; do
+ # Follow soft links.
+ if ls -lLd "$potent_lib" 2>/dev/null |
+ $GREP " -> " >/dev/null; then
+ continue
+ fi
+ # The statement above tries to avoid entering an
+ # endless loop below, in case of cyclic links.
+ # We might still enter an endless loop, since a link
+ # loop can be closed while we follow links,
+ # but so what?
+ potlib="$potent_lib"
+ while test -h "$potlib" 2>/dev/null; do
+ potliblink=`ls -ld $potlib | ${SED} 's/.* -> //'`
+ case $potliblink in
+ [\\/]* | [A-Za-z]:[\\/]*) potlib="$potliblink";;
+ *) potlib=`$ECHO "X$potlib" | $Xsed -e 's,[^/]*$,,'`"$potliblink";;
+ esac
+ done
+ if eval $file_magic_cmd \"\$potlib\" 2>/dev/null |
+ $SED -e 10q |
+ $EGREP "$file_magic_regex" > /dev/null; then
+ newdeplibs="$newdeplibs $a_deplib"
+ a_deplib=""
+ break 2
+ fi
+ done
+ done
+ fi
+ if test -n "$a_deplib" ; then
+ droppeddeps=yes
+ $ECHO
+ $ECHO "*** Warning: linker path does not have real file for library $a_deplib."
+ $ECHO "*** I have the capability to make that library automatically link in when"
+ $ECHO "*** you link to this library. But I can only do this if you have a"
+ $ECHO "*** shared version of the library, which you do not appear to have"
+ $ECHO "*** because I did check the linker path looking for a file starting"
+ if test -z "$potlib" ; then
+ $ECHO "*** with $libname but no candidates were found. (...for file magic test)"
+ else
+ $ECHO "*** with $libname and none of the candidates passed a file format test"
+ $ECHO "*** using a file magic. Last file checked: $potlib"
+ fi
+ fi
+ ;;
+ *)
+ # Add a -L argument.
+ newdeplibs="$newdeplibs $a_deplib"
+ ;;
+ esac
+ done # Gone through all deplibs.
+ ;;
+ match_pattern*)
+ set dummy $deplibs_check_method; shift
+ match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"`
+ for a_deplib in $deplibs; do
+ case $a_deplib in
+ -l*)
+ func_stripname -l '' "$a_deplib"
+ name=$func_stripname_result
+ if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+ case " $predeps $postdeps " in
+ *" $a_deplib "*)
+ newdeplibs="$newdeplibs $a_deplib"
+ a_deplib=""
+ ;;
+ esac
+ fi
+ if test -n "$a_deplib" ; then
+ libname=`eval "\\$ECHO \"$libname_spec\""`
+ for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do
+ potential_libs=`ls $i/$libname[.-]* 2>/dev/null`
+ for potent_lib in $potential_libs; do
+ potlib="$potent_lib" # see symlink-check above in file_magic test
+ if eval "\$ECHO \"X$potent_lib\"" 2>/dev/null | $Xsed -e 10q | \
+ $EGREP "$match_pattern_regex" > /dev/null; then
+ newdeplibs="$newdeplibs $a_deplib"
+ a_deplib=""
+ break 2
+ fi
+ done
+ done
+ fi
+ if test -n "$a_deplib" ; then
+ droppeddeps=yes
+ $ECHO
+ $ECHO "*** Warning: linker path does not have real file for library $a_deplib."
+ $ECHO "*** I have the capability to make that library automatically link in when"
+ $ECHO "*** you link to this library. But I can only do this if you have a"
+ $ECHO "*** shared version of the library, which you do not appear to have"
+ $ECHO "*** because I did check the linker path looking for a file starting"
+ if test -z "$potlib" ; then
+ $ECHO "*** with $libname but no candidates were found. (...for regex pattern test)"
+ else
+ $ECHO "*** with $libname and none of the candidates passed a file format test"
+ $ECHO "*** using a regex pattern. Last file checked: $potlib"
+ fi
+ fi
+ ;;
+ *)
+ # Add a -L argument.
+ newdeplibs="$newdeplibs $a_deplib"
+ ;;
+ esac
+ done # Gone through all deplibs.
+ ;;
+ none | unknown | *)
+ newdeplibs=""
+ tmp_deplibs=`$ECHO "X $deplibs" | $Xsed \
+ -e 's/ -lc$//' -e 's/ -[LR][^ ]*//g'`
+ if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+ for i in $predeps $postdeps ; do
+ # can't use Xsed below, because $i might contain '/'
+ tmp_deplibs=`$ECHO "X $tmp_deplibs" | $Xsed -e "s,$i,,"`
+ done
+ fi
+ if $ECHO "X $tmp_deplibs" | $Xsed -e 's/[ ]//g' |
+ $GREP . >/dev/null; then
+ $ECHO
+ if test "X$deplibs_check_method" = "Xnone"; then
+ $ECHO "*** Warning: inter-library dependencies are not supported in this platform."
+ else
+ $ECHO "*** Warning: inter-library dependencies are not known to be supported."
+ fi
+ $ECHO "*** All declared inter-library dependencies are being dropped."
+ droppeddeps=yes
+ fi
+ ;;
+ esac
+ versuffix=$versuffix_save
+ major=$major_save
+ release=$release_save
+ libname=$libname_save
+ name=$name_save
+
+ case $host in
+ *-*-rhapsody* | *-*-darwin1.[012])
+ # On Rhapsody replace the C library with the System framework
+ newdeplibs=`$ECHO "X $newdeplibs" | $Xsed -e 's/ -lc / System.ltframework /'`
+ ;;
+ esac
+
+ if test "$droppeddeps" = yes; then
+ if test "$module" = yes; then
+ $ECHO
+ $ECHO "*** Warning: libtool could not satisfy all declared inter-library"
+ $ECHO "*** dependencies of module $libname. Therefore, libtool will create"
+ $ECHO "*** a static module, that should work as long as the dlopening"
+ $ECHO "*** application is linked with the -dlopen flag."
+ if test -z "$global_symbol_pipe"; then
+ $ECHO
+ $ECHO "*** However, this would only work if libtool was able to extract symbol"
+ $ECHO "*** lists from a program, using \`nm' or equivalent, but libtool could"
+ $ECHO "*** not find such a program. So, this module is probably useless."
+ $ECHO "*** \`nm' from GNU binutils and a full rebuild may help."
+ fi
+ if test "$build_old_libs" = no; then
+ oldlibs="$output_objdir/$libname.$libext"
+ build_libtool_libs=module
+ build_old_libs=yes
+ else
+ build_libtool_libs=no
+ fi
+ else
+ $ECHO "*** The inter-library dependencies that have been dropped here will be"
+ $ECHO "*** automatically added whenever a program is linked with this library"
+ $ECHO "*** or is declared to -dlopen it."
+
+ if test "$allow_undefined" = no; then
+ $ECHO
+ $ECHO "*** Since this library must not contain undefined symbols,"
+ $ECHO "*** because either the platform does not support them or"
+ $ECHO "*** it was explicitly requested with -no-undefined,"
+ $ECHO "*** libtool will only create a static version of it."
+ if test "$build_old_libs" = no; then
+ oldlibs="$output_objdir/$libname.$libext"
+ build_libtool_libs=module
+ build_old_libs=yes
+ else
+ build_libtool_libs=no
+ fi
+ fi
+ fi
+ fi
+ # Done checking deplibs!
+ deplibs=$newdeplibs
+ fi
+ # Time to change all our "foo.ltframework" stuff back to "-framework foo"
+ case $host in
+ *-*-darwin*)
+ newdeplibs=`$ECHO "X $newdeplibs" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'`
+ new_inherited_linker_flags=`$ECHO "X $new_inherited_linker_flags" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'`
+ deplibs=`$ECHO "X $deplibs" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'`
+ ;;
+ esac
+
+ # move library search paths that coincide with paths to not yet
+ # installed libraries to the beginning of the library search list
+ new_libs=
+ for path in $notinst_path; do
+ case " $new_libs " in
+ *" -L$path/$objdir "*) ;;
+ *)
+ case " $deplibs " in
+ *" -L$path/$objdir "*)
+ new_libs="$new_libs -L$path/$objdir" ;;
+ esac
+ ;;
+ esac
+ done
+ for deplib in $deplibs; do
+ case $deplib in
+ -L*)
+ case " $new_libs " in
+ *" $deplib "*) ;;
+ *) new_libs="$new_libs $deplib" ;;
+ esac
+ ;;
+ *) new_libs="$new_libs $deplib" ;;
+ esac
+ done
+ deplibs="$new_libs"
+
+ # All the library-specific variables (install_libdir is set above).
+ library_names=
+ old_library=
+ dlname=
+
+ # Test again, we may have decided not to build it any more
+ if test "$build_libtool_libs" = yes; then
+ if test "$hardcode_into_libs" = yes; then
+ # Hardcode the library paths
+ hardcode_libdirs=
+ dep_rpath=
+ rpath="$finalize_rpath"
+ test "$mode" != relink && rpath="$compile_rpath$rpath"
+ for libdir in $rpath; do
+ if test -n "$hardcode_libdir_flag_spec"; then
+ if test -n "$hardcode_libdir_separator"; then
+ if test -z "$hardcode_libdirs"; then
+ hardcode_libdirs="$libdir"
+ else
+ # Just accumulate the unique libdirs.
+ case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in
+ *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
+ ;;
+ *)
+ hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir"
+ ;;
+ esac
+ fi
+ else
+ eval flag=\"$hardcode_libdir_flag_spec\"
+ dep_rpath="$dep_rpath $flag"
+ fi
+ elif test -n "$runpath_var"; then
+ case "$perm_rpath " in
+ *" $libdir "*) ;;
+ *) perm_rpath="$perm_rpath $libdir" ;;
+ esac
+ fi
+ done
+ # Substitute the hardcoded libdirs into the rpath.
+ if test -n "$hardcode_libdir_separator" &&
+ test -n "$hardcode_libdirs"; then
+ libdir="$hardcode_libdirs"
+ if test -n "$hardcode_libdir_flag_spec_ld"; then
+ eval dep_rpath=\"$hardcode_libdir_flag_spec_ld\"
+ else
+ eval dep_rpath=\"$hardcode_libdir_flag_spec\"
+ fi
+ fi
+ if test -n "$runpath_var" && test -n "$perm_rpath"; then
+ # We should set the runpath_var.
+ rpath=
+ for dir in $perm_rpath; do
+ rpath="$rpath$dir:"
+ done
+ eval "$runpath_var='$rpath\$$runpath_var'; export $runpath_var"
+ fi
+ test -n "$dep_rpath" && deplibs="$dep_rpath $deplibs"
+ fi
+
+ shlibpath="$finalize_shlibpath"
+ test "$mode" != relink && shlibpath="$compile_shlibpath$shlibpath"
+ if test -n "$shlibpath"; then
+ eval "$shlibpath_var='$shlibpath\$$shlibpath_var'; export $shlibpath_var"
+ fi
+
+ # Get the real and link names of the library.
+ eval shared_ext=\"$shrext_cmds\"
+ eval library_names=\"$library_names_spec\"
+ set dummy $library_names
+ shift
+ realname="$1"
+ shift
+
+ if test -n "$soname_spec"; then
+ eval soname=\"$soname_spec\"
+ else
+ soname="$realname"
+ fi
+ if test -z "$dlname"; then
+ dlname=$soname
+ fi
+
+ lib="$output_objdir/$realname"
+ linknames=
+ for link
+ do
+ linknames="$linknames $link"
+ done
+
+ # Use standard objects if they are pic
+ test -z "$pic_flag" && libobjs=`$ECHO "X$libobjs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP`
+ test "X$libobjs" = "X " && libobjs=
+
+ delfiles=
+ if test -n "$export_symbols" && test -n "$include_expsyms"; then
+ $opt_dry_run || cp "$export_symbols" "$output_objdir/$libname.uexp"
+ export_symbols="$output_objdir/$libname.uexp"
+ delfiles="$delfiles $export_symbols"
+ fi
+
+ orig_export_symbols=
+ case $host_os in
+ cygwin* | mingw* | cegcc*)
+ if test -n "$export_symbols" && test -z "$export_symbols_regex"; then
+ # exporting using user supplied symfile
+ if test "x`$SED 1q $export_symbols`" != xEXPORTS; then
+ # and it's NOT already a .def file. Must figure out
+ # which of the given symbols are data symbols and tag
+ # them as such. So, trigger use of export_symbols_cmds.
+ # export_symbols gets reassigned inside the "prepare
+ # the list of exported symbols" if statement, so the
+ # include_expsyms logic still works.
+ orig_export_symbols="$export_symbols"
+ export_symbols=
+ always_export_symbols=yes
+ fi
+ fi
+ ;;
+ esac
+
+ # Prepare the list of exported symbols
+ if test -z "$export_symbols"; then
+ if test "$always_export_symbols" = yes || test -n "$export_symbols_regex"; then
+ func_verbose "generating symbol list for \`$libname.la'"
+ export_symbols="$output_objdir/$libname.exp"
+ $opt_dry_run || $RM $export_symbols
+ cmds=$export_symbols_cmds
+ save_ifs="$IFS"; IFS='~'
+ for cmd in $cmds; do
+ IFS="$save_ifs"
+ eval cmd=\"$cmd\"
+ func_len " $cmd"
+ len=$func_len_result
+ if test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then
+ func_show_eval "$cmd" 'exit $?'
+ skipped_export=false
+ else
+ # The command line is too long to execute in one step.
+ func_verbose "using reloadable object file for export list..."
+ skipped_export=:
+ # Break out early, otherwise skipped_export may be
+ # set to false by a later but shorter cmd.
+ break
+ fi
+ done
+ IFS="$save_ifs"
+ if test -n "$export_symbols_regex" && test "X$skipped_export" != "X:"; then
+ func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"'
+ func_show_eval '$MV "${export_symbols}T" "$export_symbols"'
+ fi
+ fi
+ fi
+
+ if test -n "$export_symbols" && test -n "$include_expsyms"; then
+ tmp_export_symbols="$export_symbols"
+ test -n "$orig_export_symbols" && tmp_export_symbols="$orig_export_symbols"
+ $opt_dry_run || eval '$ECHO "X$include_expsyms" | $Xsed | $SP2NL >> "$tmp_export_symbols"'
+ fi
+
+ if test "X$skipped_export" != "X:" && test -n "$orig_export_symbols"; then
+ # The given exports_symbols file has to be filtered, so filter it.
+ func_verbose "filter symbol list for \`$libname.la' to tag DATA exports"
+ # FIXME: $output_objdir/$libname.filter potentially contains lots of
+ # 's' commands which not all seds can handle. GNU sed should be fine
+ # though. Also, the filter scales superlinearly with the number of
+ # global variables. join(1) would be nice here, but unfortunately
+ # isn't a blessed tool.
+ $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter
+ delfiles="$delfiles $export_symbols $output_objdir/$libname.filter"
+ export_symbols=$output_objdir/$libname.def
+ $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols
+ fi
+
+ tmp_deplibs=
+ for test_deplib in $deplibs; do
+ case " $convenience " in
+ *" $test_deplib "*) ;;
+ *)
+ tmp_deplibs="$tmp_deplibs $test_deplib"
+ ;;
+ esac
+ done
+ deplibs="$tmp_deplibs"
+
+ if test -n "$convenience"; then
+ if test -n "$whole_archive_flag_spec" &&
+ test "$compiler_needs_object" = yes &&
+ test -z "$libobjs"; then
+ # extract the archives, so we have objects to list.
+ # TODO: could optimize this to just extract one archive.
+ whole_archive_flag_spec=
+ fi
+ if test -n "$whole_archive_flag_spec"; then
+ save_libobjs=$libobjs
+ eval libobjs=\"\$libobjs $whole_archive_flag_spec\"
+ test "X$libobjs" = "X " && libobjs=
+ else
+ gentop="$output_objdir/${outputname}x"
+ generated="$generated $gentop"
+
+ func_extract_archives $gentop $convenience
+ libobjs="$libobjs $func_extract_archives_result"
+ test "X$libobjs" = "X " && libobjs=
+ fi
+ fi
+
+ if test "$thread_safe" = yes && test -n "$thread_safe_flag_spec"; then
+ eval flag=\"$thread_safe_flag_spec\"
+ linker_flags="$linker_flags $flag"
+ fi
+
+ # Make a backup of the uninstalled library when relinking
+ if test "$mode" = relink; then
+ $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}U && $MV $realname ${realname}U)' || exit $?
+ fi
+
+ # Do each of the archive commands.
+ if test "$module" = yes && test -n "$module_cmds" ; then
+ if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then
+ eval test_cmds=\"$module_expsym_cmds\"
+ cmds=$module_expsym_cmds
+ else
+ eval test_cmds=\"$module_cmds\"
+ cmds=$module_cmds
+ fi
+ else
+ if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then
+ eval test_cmds=\"$archive_expsym_cmds\"
+ cmds=$archive_expsym_cmds
+ else
+ eval test_cmds=\"$archive_cmds\"
+ cmds=$archive_cmds
+ fi
+ fi
+
+ if test "X$skipped_export" != "X:" &&
+ func_len " $test_cmds" &&
+ len=$func_len_result &&
+ test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then
+ :
+ else
+ # The command line is too long to link in one step, link piecewise
+ # or, if using GNU ld and skipped_export is not :, use a linker
+ # script.
+
+ # Save the value of $output and $libobjs because we want to
+ # use them later. If we have whole_archive_flag_spec, we
+ # want to use save_libobjs as it was before
+ # whole_archive_flag_spec was expanded, because we can't
+ # assume the linker understands whole_archive_flag_spec.
+ # This may have to be revisited, in case too many
+ # convenience libraries get linked in and end up exceeding
+ # the spec.
+ if test -z "$convenience" || test -z "$whole_archive_flag_spec"; then
+ save_libobjs=$libobjs
+ fi
+ save_output=$output
+ output_la=`$ECHO "X$output" | $Xsed -e "$basename"`
+
+ # Clear the reloadable object creation command queue and
+ # initialize k to one.
+ test_cmds=
+ concat_cmds=
+ objlist=
+ last_robj=
+ k=1
+
+ if test -n "$save_libobjs" && test "X$skipped_export" != "X:" && test "$with_gnu_ld" = yes; then
+ output=${output_objdir}/${output_la}.lnkscript
+ func_verbose "creating GNU ld script: $output"
+ $ECHO 'INPUT (' > $output
+ for obj in $save_libobjs
+ do
+ $ECHO "$obj" >> $output
+ done
+ $ECHO ')' >> $output
+ delfiles="$delfiles $output"
+ elif test -n "$save_libobjs" && test "X$skipped_export" != "X:" && test "X$file_list_spec" != X; then
+ output=${output_objdir}/${output_la}.lnk
+ func_verbose "creating linker input file list: $output"
+ : > $output
+ set x $save_libobjs
+ shift
+ firstobj=
+ if test "$compiler_needs_object" = yes; then
+ firstobj="$1 "
+ shift
+ fi
+ for obj
+ do
+ $ECHO "$obj" >> $output
+ done
+ delfiles="$delfiles $output"
+ output=$firstobj\"$file_list_spec$output\"
+ else
+ if test -n "$save_libobjs"; then
+ func_verbose "creating reloadable object files..."
+ output=$output_objdir/$output_la-${k}.$objext
+ eval test_cmds=\"$reload_cmds\"
+ func_len " $test_cmds"
+ len0=$func_len_result
+ len=$len0
+
+ # Loop over the list of objects to be linked.
+ for obj in $save_libobjs
+ do
+ func_len " $obj"
+ func_arith $len + $func_len_result
+ len=$func_arith_result
+ if test "X$objlist" = X ||
+ test "$len" -lt "$max_cmd_len"; then
+ func_append objlist " $obj"
+ else
+ # The command $test_cmds is almost too long, add a
+ # command to the queue.
+ if test "$k" -eq 1 ; then
+ # The first file doesn't have a previous command to add.
+ eval concat_cmds=\"$reload_cmds $objlist $last_robj\"
+ else
+ # All subsequent reloadable object files will link in
+ # the last one created.
+ eval concat_cmds=\"\$concat_cmds~$reload_cmds $objlist $last_robj~\$RM $last_robj\"
+ fi
+ last_robj=$output_objdir/$output_la-${k}.$objext
+ func_arith $k + 1
+ k=$func_arith_result
+ output=$output_objdir/$output_la-${k}.$objext
+ objlist=$obj
+ func_len " $last_robj"
+ func_arith $len0 + $func_len_result
+ len=$func_arith_result
+ fi
+ done
+ # Handle the remaining objects by creating one last
+ # reloadable object file. All subsequent reloadable object
+ # files will link in the last one created.
+ test -z "$concat_cmds" || concat_cmds=$concat_cmds~
+ eval concat_cmds=\"\${concat_cmds}$reload_cmds $objlist $last_robj\"
+ if test -n "$last_robj"; then
+ eval concat_cmds=\"\${concat_cmds}~\$RM $last_robj\"
+ fi
+ delfiles="$delfiles $output"
+
+ else
+ output=
+ fi
+
+ if ${skipped_export-false}; then
+ func_verbose "generating symbol list for \`$libname.la'"
+ export_symbols="$output_objdir/$libname.exp"
+ $opt_dry_run || $RM $export_symbols
+ libobjs=$output
+ # Append the command to create the export file.
+ test -z "$concat_cmds" || concat_cmds=$concat_cmds~
+ eval concat_cmds=\"\$concat_cmds$export_symbols_cmds\"
+ if test -n "$last_robj"; then
+ eval concat_cmds=\"\$concat_cmds~\$RM $last_robj\"
+ fi
+ fi
+
+ test -n "$save_libobjs" &&
+ func_verbose "creating a temporary reloadable object file: $output"
+
+ # Loop through the commands generated above and execute them.
+ save_ifs="$IFS"; IFS='~'
+ for cmd in $concat_cmds; do
+ IFS="$save_ifs"
+ $opt_silent || {
+ func_quote_for_expand "$cmd"
+ eval "func_echo $func_quote_for_expand_result"
+ }
+ $opt_dry_run || eval "$cmd" || {
+ lt_exit=$?
+
+ # Restore the uninstalled library and exit
+ if test "$mode" = relink; then
+ ( cd "$output_objdir" && \
+ $RM "${realname}T" && \
+ $MV "${realname}U" "$realname" )
+ fi
+
+ exit $lt_exit
+ }
+ done
+ IFS="$save_ifs"
+
+ if test -n "$export_symbols_regex" && ${skipped_export-false}; then
+ func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"'
+ func_show_eval '$MV "${export_symbols}T" "$export_symbols"'
+ fi
+ fi
+
+ if ${skipped_export-false}; then
+ if test -n "$export_symbols" && test -n "$include_expsyms"; then
+ tmp_export_symbols="$export_symbols"
+ test -n "$orig_export_symbols" && tmp_export_symbols="$orig_export_symbols"
+ $opt_dry_run || eval '$ECHO "X$include_expsyms" | $Xsed | $SP2NL >> "$tmp_export_symbols"'
+ fi
+
+ if test -n "$orig_export_symbols"; then
+ # The given exports_symbols file has to be filtered, so filter it.
+ func_verbose "filter symbol list for \`$libname.la' to tag DATA exports"
+ # FIXME: $output_objdir/$libname.filter potentially contains lots of
+ # 's' commands which not all seds can handle. GNU sed should be fine
+ # though. Also, the filter scales superlinearly with the number of
+ # global variables. join(1) would be nice here, but unfortunately
+ # isn't a blessed tool.
+ $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter
+ delfiles="$delfiles $export_symbols $output_objdir/$libname.filter"
+ export_symbols=$output_objdir/$libname.def
+ $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols
+ fi
+ fi
+
+ libobjs=$output
+ # Restore the value of output.
+ output=$save_output
+
+ if test -n "$convenience" && test -n "$whole_archive_flag_spec"; then
+ eval libobjs=\"\$libobjs $whole_archive_flag_spec\"
+ test "X$libobjs" = "X " && libobjs=
+ fi
+ # Expand the library linking commands again to reset the
+ # value of $libobjs for piecewise linking.
+
+ # Do each of the archive commands.
+ if test "$module" = yes && test -n "$module_cmds" ; then
+ if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then
+ cmds=$module_expsym_cmds
+ else
+ cmds=$module_cmds
+ fi
+ else
+ if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then
+ cmds=$archive_expsym_cmds
+ else
+ cmds=$archive_cmds
+ fi
+ fi
+ fi
+
+ if test -n "$delfiles"; then
+ # Append the command to remove temporary files to $cmds.
+ eval cmds=\"\$cmds~\$RM $delfiles\"
+ fi
+
+ # Add any objects from preloaded convenience libraries
+ if test -n "$dlprefiles"; then
+ gentop="$output_objdir/${outputname}x"
+ generated="$generated $gentop"
+
+ func_extract_archives $gentop $dlprefiles
+ libobjs="$libobjs $func_extract_archives_result"
+ test "X$libobjs" = "X " && libobjs=
+ fi
+
+ save_ifs="$IFS"; IFS='~'
+ for cmd in $cmds; do
+ IFS="$save_ifs"
+ eval cmd=\"$cmd\"
+ $opt_silent || {
+ func_quote_for_expand "$cmd"
+ eval "func_echo $func_quote_for_expand_result"
+ }
+ $opt_dry_run || eval "$cmd" || {
+ lt_exit=$?
+
+ # Restore the uninstalled library and exit
+ if test "$mode" = relink; then
+ ( cd "$output_objdir" && \
+ $RM "${realname}T" && \
+ $MV "${realname}U" "$realname" )
+ fi
+
+ exit $lt_exit
+ }
+ done
+ IFS="$save_ifs"
+
+ # Restore the uninstalled library and exit
+ if test "$mode" = relink; then
+ $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}T && $MV $realname ${realname}T && $MV ${realname}U $realname)' || exit $?
+
+ if test -n "$convenience"; then
+ if test -z "$whole_archive_flag_spec"; then
+ func_show_eval '${RM}r "$gentop"'
+ fi
+ fi
+
+ exit $EXIT_SUCCESS
+ fi
+
+ # Create links to the real library.
+ for linkname in $linknames; do
+ if test "$realname" != "$linkname"; then
+ func_show_eval '(cd "$output_objdir" && $RM "$linkname" && $LN_S "$realname" "$linkname")' 'exit $?'
+ fi
+ done
+
+ # If -module or -export-dynamic was specified, set the dlname.
+ if test "$module" = yes || test "$export_dynamic" = yes; then
+ # On all known operating systems, these are identical.
+ dlname="$soname"
+ fi
+ fi
+ ;;
+
+ obj)
+ if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
+ func_warning "\`-dlopen' is ignored for objects"
+ fi
+
+ case " $deplibs" in
+ *\ -l* | *\ -L*)
+ func_warning "\`-l' and \`-L' are ignored for objects" ;;
+ esac
+
+ test -n "$rpath" && \
+ func_warning "\`-rpath' is ignored for objects"
+
+ test -n "$xrpath" && \
+ func_warning "\`-R' is ignored for objects"
+
+ test -n "$vinfo" && \
+ func_warning "\`-version-info' is ignored for objects"
+
+ test -n "$release" && \
+ func_warning "\`-release' is ignored for objects"
+
+ case $output in
+ *.lo)
+ test -n "$objs$old_deplibs" && \
+ func_fatal_error "cannot build library object \`$output' from non-libtool objects"
+
+ libobj=$output
+ func_lo2o "$libobj"
+ obj=$func_lo2o_result
+ ;;
+ *)
+ libobj=
+ obj="$output"
+ ;;
+ esac
+
+ # Delete the old objects.
+ $opt_dry_run || $RM $obj $libobj
+
+ # Objects from convenience libraries. This assumes
+ # single-version convenience libraries. Whenever we create
+ # different ones for PIC/non-PIC, this we'll have to duplicate
+ # the extraction.
+ reload_conv_objs=
+ gentop=
+ # reload_cmds runs $LD directly, so let us get rid of
+ # -Wl from whole_archive_flag_spec and hope we can get by with
+ # turning comma into space..
+ wl=
+
+ if test -n "$convenience"; then
+ if test -n "$whole_archive_flag_spec"; then
+ eval tmp_whole_archive_flags=\"$whole_archive_flag_spec\"
+ reload_conv_objs=$reload_objs\ `$ECHO "X$tmp_whole_archive_flags" | $Xsed -e 's|,| |g'`
+ else
+ gentop="$output_objdir/${obj}x"
+ generated="$generated $gentop"
+
+ func_extract_archives $gentop $convenience
+ reload_conv_objs="$reload_objs $func_extract_archives_result"
+ fi
+ fi
+
+ # Create the old-style object.
+ reload_objs="$objs$old_deplibs "`$ECHO "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}$'/d' -e '/\.lib$/d' -e "$lo2o" | $NL2SP`" $reload_conv_objs" ### testsuite: skip nested quoting test
+
+ output="$obj"
+ func_execute_cmds "$reload_cmds" 'exit $?'
+
+ # Exit if we aren't doing a library object file.
+ if test -z "$libobj"; then
+ if test -n "$gentop"; then
+ func_show_eval '${RM}r "$gentop"'
+ fi
+
+ exit $EXIT_SUCCESS
+ fi
+
+ if test "$build_libtool_libs" != yes; then
+ if test -n "$gentop"; then
+ func_show_eval '${RM}r "$gentop"'
+ fi
+
+ # Create an invalid libtool object if no PIC, so that we don't
+ # accidentally link it into a program.
+ # $show "echo timestamp > $libobj"
+ # $opt_dry_run || eval "echo timestamp > $libobj" || exit $?
+ exit $EXIT_SUCCESS
+ fi
+
+ if test -n "$pic_flag" || test "$pic_mode" != default; then
+ # Only do commands if we really have different PIC objects.
+ reload_objs="$libobjs $reload_conv_objs"
+ output="$libobj"
+ func_execute_cmds "$reload_cmds" 'exit $?'
+ fi
+
+ if test -n "$gentop"; then
+ func_show_eval '${RM}r "$gentop"'
+ fi
+
+ exit $EXIT_SUCCESS
+ ;;
+
+ prog)
+ case $host in
+ *cygwin*) func_stripname '' '.exe' "$output"
+ output=$func_stripname_result.exe;;
+ esac
+ test -n "$vinfo" && \
+ func_warning "\`-version-info' is ignored for programs"
+
+ test -n "$release" && \
+ func_warning "\`-release' is ignored for programs"
+
+ test "$preload" = yes \
+ && test "$dlopen_support" = unknown \
+ && test "$dlopen_self" = unknown \
+ && test "$dlopen_self_static" = unknown && \
+ func_warning "\`LT_INIT([dlopen])' not used. Assuming no dlopen support."
+
+ case $host in
+ *-*-rhapsody* | *-*-darwin1.[012])
+ # On Rhapsody replace the C library is the System framework
+ compile_deplibs=`$ECHO "X $compile_deplibs" | $Xsed -e 's/ -lc / System.ltframework /'`
+ finalize_deplibs=`$ECHO "X $finalize_deplibs" | $Xsed -e 's/ -lc / System.ltframework /'`
+ ;;
+ esac
+
+ case $host in
+ *-*-darwin*)
+ # Don't allow lazy linking, it breaks C++ global constructors
+ # But is supposedly fixed on 10.4 or later (yay!).
+ if test "$tagname" = CXX ; then
+ case ${MACOSX_DEPLOYMENT_TARGET-10.0} in
+ 10.[0123])
+ compile_command="$compile_command ${wl}-bind_at_load"
+ finalize_command="$finalize_command ${wl}-bind_at_load"
+ ;;
+ esac
+ fi
+ # Time to change all our "foo.ltframework" stuff back to "-framework foo"
+ compile_deplibs=`$ECHO "X $compile_deplibs" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'`
+ finalize_deplibs=`$ECHO "X $finalize_deplibs" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'`
+ ;;
+ esac
+
+
+ # move library search paths that coincide with paths to not yet
+ # installed libraries to the beginning of the library search list
+ new_libs=
+ for path in $notinst_path; do
+ case " $new_libs " in
+ *" -L$path/$objdir "*) ;;
+ *)
+ case " $compile_deplibs " in
+ *" -L$path/$objdir "*)
+ new_libs="$new_libs -L$path/$objdir" ;;
+ esac
+ ;;
+ esac
+ done
+ for deplib in $compile_deplibs; do
+ case $deplib in
+ -L*)
+ case " $new_libs " in
+ *" $deplib "*) ;;
+ *) new_libs="$new_libs $deplib" ;;
+ esac
+ ;;
+ *) new_libs="$new_libs $deplib" ;;
+ esac
+ done
+ compile_deplibs="$new_libs"
+
+
+ compile_command="$compile_command $compile_deplibs"
+ finalize_command="$finalize_command $finalize_deplibs"
+
+ if test -n "$rpath$xrpath"; then
+ # If the user specified any rpath flags, then add them.
+ for libdir in $rpath $xrpath; do
+ # This is the magic to use -rpath.
+ case "$finalize_rpath " in
+ *" $libdir "*) ;;
+ *) finalize_rpath="$finalize_rpath $libdir" ;;
+ esac
+ done
+ fi
+
+ # Now hardcode the library paths
+ rpath=
+ hardcode_libdirs=
+ for libdir in $compile_rpath $finalize_rpath; do
+ if test -n "$hardcode_libdir_flag_spec"; then
+ if test -n "$hardcode_libdir_separator"; then
+ if test -z "$hardcode_libdirs"; then
+ hardcode_libdirs="$libdir"
+ else
+ # Just accumulate the unique libdirs.
+ case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in
+ *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
+ ;;
+ *)
+ hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir"
+ ;;
+ esac
+ fi
+ else
+ eval flag=\"$hardcode_libdir_flag_spec\"
+ rpath="$rpath $flag"
+ fi
+ elif test -n "$runpath_var"; then
+ case "$perm_rpath " in
+ *" $libdir "*) ;;
+ *) perm_rpath="$perm_rpath $libdir" ;;
+ esac
+ fi
+ case $host in
+ *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*)
+ testbindir=`${ECHO} "$libdir" | ${SED} -e 's*/lib$*/bin*'`
+ case :$dllsearchpath: in
+ *":$libdir:"*) ;;
+ ::) dllsearchpath=$libdir;;
+ *) dllsearchpath="$dllsearchpath:$libdir";;
+ esac
+ case :$dllsearchpath: in
+ *":$testbindir:"*) ;;
+ ::) dllsearchpath=$testbindir;;
+ *) dllsearchpath="$dllsearchpath:$testbindir";;
+ esac
+ ;;
+ esac
+ done
+ # Substitute the hardcoded libdirs into the rpath.
+ if test -n "$hardcode_libdir_separator" &&
+ test -n "$hardcode_libdirs"; then
+ libdir="$hardcode_libdirs"
+ eval rpath=\" $hardcode_libdir_flag_spec\"
+ fi
+ compile_rpath="$rpath"
+
+ rpath=
+ hardcode_libdirs=
+ for libdir in $finalize_rpath; do
+ if test -n "$hardcode_libdir_flag_spec"; then
+ if test -n "$hardcode_libdir_separator"; then
+ if test -z "$hardcode_libdirs"; then
+ hardcode_libdirs="$libdir"
+ else
+ # Just accumulate the unique libdirs.
+ case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in
+ *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
+ ;;
+ *)
+ hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir"
+ ;;
+ esac
+ fi
+ else
+ eval flag=\"$hardcode_libdir_flag_spec\"
+ rpath="$rpath $flag"
+ fi
+ elif test -n "$runpath_var"; then
+ case "$finalize_perm_rpath " in
+ *" $libdir "*) ;;
+ *) finalize_perm_rpath="$finalize_perm_rpath $libdir" ;;
+ esac
+ fi
+ done
+ # Substitute the hardcoded libdirs into the rpath.
+ if test -n "$hardcode_libdir_separator" &&
+ test -n "$hardcode_libdirs"; then
+ libdir="$hardcode_libdirs"
+ eval rpath=\" $hardcode_libdir_flag_spec\"
+ fi
+ finalize_rpath="$rpath"
+
+ if test -n "$libobjs" && test "$build_old_libs" = yes; then
+ # Transform all the library objects into standard objects.
+ compile_command=`$ECHO "X$compile_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP`
+ finalize_command=`$ECHO "X$finalize_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP`
+ fi
+
+ func_generate_dlsyms "$outputname" "@PROGRAM@" "no"
+
+ # template prelinking step
+ if test -n "$prelink_cmds"; then
+ func_execute_cmds "$prelink_cmds" 'exit $?'
+ fi
+
+ wrappers_required=yes
+ case $host in
+ *cygwin* | *mingw* )
+ if test "$build_libtool_libs" != yes; then
+ wrappers_required=no
+ fi
+ ;;
+ *cegcc)
+ # Disable wrappers for cegcc, we are cross compiling anyway.
+ wrappers_required=no
+ ;;
+ *)
+ if test "$need_relink" = no || test "$build_libtool_libs" != yes; then
+ wrappers_required=no
+ fi
+ ;;
+ esac
+ if test "$wrappers_required" = no; then
+ # Replace the output file specification.
+ compile_command=`$ECHO "X$compile_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'`
+ link_command="$compile_command$compile_rpath"
+
+ # We have no uninstalled library dependencies, so finalize right now.
+ exit_status=0
+ func_show_eval "$link_command" 'exit_status=$?'
+
+ # Delete the generated files.
+ if test -f "$output_objdir/${outputname}S.${objext}"; then
+ func_show_eval '$RM "$output_objdir/${outputname}S.${objext}"'
+ fi
+
+ exit $exit_status
+ fi
+
+ if test -n "$compile_shlibpath$finalize_shlibpath"; then
+ compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command"
+ fi
+ if test -n "$finalize_shlibpath"; then
+ finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command"
+ fi
+
+ compile_var=
+ finalize_var=
+ if test -n "$runpath_var"; then
+ if test -n "$perm_rpath"; then
+ # We should set the runpath_var.
+ rpath=
+ for dir in $perm_rpath; do
+ rpath="$rpath$dir:"
+ done
+ compile_var="$runpath_var=\"$rpath\$$runpath_var\" "
+ fi
+ if test -n "$finalize_perm_rpath"; then
+ # We should set the runpath_var.
+ rpath=
+ for dir in $finalize_perm_rpath; do
+ rpath="$rpath$dir:"
+ done
+ finalize_var="$runpath_var=\"$rpath\$$runpath_var\" "
+ fi
+ fi
+
+ if test "$no_install" = yes; then
+ # We don't need to create a wrapper script.
+ link_command="$compile_var$compile_command$compile_rpath"
+ # Replace the output file specification.
+ link_command=`$ECHO "X$link_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'`
+ # Delete the old output file.
+ $opt_dry_run || $RM $output
+ # Link the executable and exit
+ func_show_eval "$link_command" 'exit $?'
+ exit $EXIT_SUCCESS
+ fi
+
+ if test "$hardcode_action" = relink; then
+ # Fast installation is not supported
+ link_command="$compile_var$compile_command$compile_rpath"
+ relink_command="$finalize_var$finalize_command$finalize_rpath"
+
+ func_warning "this platform does not like uninstalled shared libraries"
+ func_warning "\`$output' will be relinked during installation"
+ else
+ if test "$fast_install" != no; then
+ link_command="$finalize_var$compile_command$finalize_rpath"
+ if test "$fast_install" = yes; then
+ relink_command=`$ECHO "X$compile_var$compile_command$compile_rpath" | $Xsed -e 's%@OUTPUT@%\$progdir/\$file%g'`
+ else
+ # fast_install is set to needless
+ relink_command=
+ fi
+ else
+ link_command="$compile_var$compile_command$compile_rpath"
+ relink_command="$finalize_var$finalize_command$finalize_rpath"
+ fi
+ fi
+
+ # Replace the output file specification.
+ link_command=`$ECHO "X$link_command" | $Xsed -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'`
+
+ # Delete the old output files.
+ $opt_dry_run || $RM $output $output_objdir/$outputname $output_objdir/lt-$outputname
+
+ func_show_eval "$link_command" 'exit $?'
+
+ # Now create the wrapper script.
+ func_verbose "creating $output"
+
+ # Quote the relink command for shipping.
+ if test -n "$relink_command"; then
+ # Preserve any variables that may affect compiler behavior
+ for var in $variables_saved_for_relink; do
+ if eval test -z \"\${$var+set}\"; then
+ relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command"
+ elif eval var_value=\$$var; test -z "$var_value"; then
+ relink_command="$var=; export $var; $relink_command"
+ else
+ func_quote_for_eval "$var_value"
+ relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command"
+ fi
+ done
+ relink_command="(cd `pwd`; $relink_command)"
+ relink_command=`$ECHO "X$relink_command" | $Xsed -e "$sed_quote_subst"`
+ fi
+
+ # Quote $ECHO for shipping.
+ if test "X$ECHO" = "X$SHELL $progpath --fallback-echo"; then
+ case $progpath in
+ [\\/]* | [A-Za-z]:[\\/]*) qecho="$SHELL $progpath --fallback-echo";;
+ *) qecho="$SHELL `pwd`/$progpath --fallback-echo";;
+ esac
+ qecho=`$ECHO "X$qecho" | $Xsed -e "$sed_quote_subst"`
+ else
+ qecho=`$ECHO "X$ECHO" | $Xsed -e "$sed_quote_subst"`
+ fi
+
+ # Only actually do things if not in dry run mode.
+ $opt_dry_run || {
+ # win32 will think the script is a binary if it has
+ # a .exe suffix, so we strip it off here.
+ case $output in
+ *.exe) func_stripname '' '.exe' "$output"
+ output=$func_stripname_result ;;
+ esac
+ # test for cygwin because mv fails w/o .exe extensions
+ case $host in
+ *cygwin*)
+ exeext=.exe
+ func_stripname '' '.exe' "$outputname"
+ outputname=$func_stripname_result ;;
+ *) exeext= ;;
+ esac
+ case $host in
+ *cygwin* | *mingw* )
+ func_dirname_and_basename "$output" "" "."
+ output_name=$func_basename_result
+ output_path=$func_dirname_result
+ cwrappersource="$output_path/$objdir/lt-$output_name.c"
+ cwrapper="$output_path/$output_name.exe"
+ $RM $cwrappersource $cwrapper
+ trap "$RM $cwrappersource $cwrapper; exit $EXIT_FAILURE" 1 2 15
+
+ func_emit_cwrapperexe_src > $cwrappersource
+
+ # The wrapper executable is built using the $host compiler,
+ # because it contains $host paths and files. If cross-
+ # compiling, it, like the target executable, must be
+ # executed on the $host or under an emulation environment.
+ $opt_dry_run || {
+ $LTCC $LTCFLAGS -o $cwrapper $cwrappersource
+ $STRIP $cwrapper
+ }
+
+ # Now, create the wrapper script for func_source use:
+ func_ltwrapper_scriptname $cwrapper
+ $RM $func_ltwrapper_scriptname_result
+ trap "$RM $func_ltwrapper_scriptname_result; exit $EXIT_FAILURE" 1 2 15
+ $opt_dry_run || {
+ # note: this script will not be executed, so do not chmod.
+ if test "x$build" = "x$host" ; then
+ $cwrapper --lt-dump-script > $func_ltwrapper_scriptname_result
+ else
+ func_emit_wrapper no > $func_ltwrapper_scriptname_result
+ fi
+ }
+ ;;
+ * )
+ $RM $output
+ trap "$RM $output; exit $EXIT_FAILURE" 1 2 15
+
+ func_emit_wrapper no > $output
+ chmod +x $output
+ ;;
+ esac
+ }
+ exit $EXIT_SUCCESS
+ ;;
+ esac
+
+ # See if we need to build an old-fashioned archive.
+ for oldlib in $oldlibs; do
+
+ if test "$build_libtool_libs" = convenience; then
+ oldobjs="$libobjs_save $symfileobj"
+ addlibs="$convenience"
+ build_libtool_libs=no
+ else
+ if test "$build_libtool_libs" = module; then
+ oldobjs="$libobjs_save"
+ build_libtool_libs=no
+ else
+ oldobjs="$old_deplibs $non_pic_objects"
+ if test "$preload" = yes && test -f "$symfileobj"; then
+ oldobjs="$oldobjs $symfileobj"
+ fi
+ fi
+ addlibs="$old_convenience"
+ fi
+
+ if test -n "$addlibs"; then
+ gentop="$output_objdir/${outputname}x"
+ generated="$generated $gentop"
+
+ func_extract_archives $gentop $addlibs
+ oldobjs="$oldobjs $func_extract_archives_result"
+ fi
+
+ # Do each command in the archive commands.
+ if test -n "$old_archive_from_new_cmds" && test "$build_libtool_libs" = yes; then
+ cmds=$old_archive_from_new_cmds
+ else
+
+ # Add any objects from preloaded convenience libraries
+ if test -n "$dlprefiles"; then
+ gentop="$output_objdir/${outputname}x"
+ generated="$generated $gentop"
+
+ func_extract_archives $gentop $dlprefiles
+ oldobjs="$oldobjs $func_extract_archives_result"
+ fi
+
+ # POSIX demands no paths to be encoded in archives. We have
+ # to avoid creating archives with duplicate basenames if we
+ # might have to extract them afterwards, e.g., when creating a
+ # static archive out of a convenience library, or when linking
+ # the entirety of a libtool archive into another (currently
+ # not supported by libtool).
+ if (for obj in $oldobjs
+ do
+ func_basename "$obj"
+ $ECHO "$func_basename_result"
+ done | sort | sort -uc >/dev/null 2>&1); then
+ :
+ else
+ $ECHO "copying selected object files to avoid basename conflicts..."
+ gentop="$output_objdir/${outputname}x"
+ generated="$generated $gentop"
+ func_mkdir_p "$gentop"
+ save_oldobjs=$oldobjs
+ oldobjs=
+ counter=1
+ for obj in $save_oldobjs
+ do
+ func_basename "$obj"
+ objbase="$func_basename_result"
+ case " $oldobjs " in
+ " ") oldobjs=$obj ;;
+ *[\ /]"$objbase "*)
+ while :; do
+ # Make sure we don't pick an alternate name that also
+ # overlaps.
+ newobj=lt$counter-$objbase
+ func_arith $counter + 1
+ counter=$func_arith_result
+ case " $oldobjs " in
+ *[\ /]"$newobj "*) ;;
+ *) if test ! -f "$gentop/$newobj"; then break; fi ;;
+ esac
+ done
+ func_show_eval "ln $obj $gentop/$newobj || cp $obj $gentop/$newobj"
+ oldobjs="$oldobjs $gentop/$newobj"
+ ;;
+ *) oldobjs="$oldobjs $obj" ;;
+ esac
+ done
+ fi
+ eval cmds=\"$old_archive_cmds\"
+
+ func_len " $cmds"
+ len=$func_len_result
+ if test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then
+ cmds=$old_archive_cmds
+ else
+ # the command line is too long to link in one step, link in parts
+ func_verbose "using piecewise archive linking..."
+ save_RANLIB=$RANLIB
+ RANLIB=:
+ objlist=
+ concat_cmds=
+ save_oldobjs=$oldobjs
+ oldobjs=
+ # Is there a better way of finding the last object in the list?
+ for obj in $save_oldobjs
+ do
+ last_oldobj=$obj
+ done
+ eval test_cmds=\"$old_archive_cmds\"
+ func_len " $test_cmds"
+ len0=$func_len_result
+ len=$len0
+ for obj in $save_oldobjs
+ do
+ func_len " $obj"
+ func_arith $len + $func_len_result
+ len=$func_arith_result
+ func_append objlist " $obj"
+ if test "$len" -lt "$max_cmd_len"; then
+ :
+ else
+ # the above command should be used before it gets too long
+ oldobjs=$objlist
+ if test "$obj" = "$last_oldobj" ; then
+ RANLIB=$save_RANLIB
+ fi
+ test -z "$concat_cmds" || concat_cmds=$concat_cmds~
+ eval concat_cmds=\"\${concat_cmds}$old_archive_cmds\"
+ objlist=
+ len=$len0
+ fi
+ done
+ RANLIB=$save_RANLIB
+ oldobjs=$objlist
+ if test "X$oldobjs" = "X" ; then
+ eval cmds=\"\$concat_cmds\"
+ else
+ eval cmds=\"\$concat_cmds~\$old_archive_cmds\"
+ fi
+ fi
+ fi
+ func_execute_cmds "$cmds" 'exit $?'
+ done
+
+ test -n "$generated" && \
+ func_show_eval "${RM}r$generated"
+
+ # Now create the libtool archive.
+ case $output in
+ *.la)
+ old_library=
+ test "$build_old_libs" = yes && old_library="$libname.$libext"
+ func_verbose "creating $output"
+
+ # Preserve any variables that may affect compiler behavior
+ for var in $variables_saved_for_relink; do
+ if eval test -z \"\${$var+set}\"; then
+ relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command"
+ elif eval var_value=\$$var; test -z "$var_value"; then
+ relink_command="$var=; export $var; $relink_command"
+ else
+ func_quote_for_eval "$var_value"
+ relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command"
+ fi
+ done
+ # Quote the link command for shipping.
+ relink_command="(cd `pwd`; $SHELL $progpath $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)"
+ relink_command=`$ECHO "X$relink_command" | $Xsed -e "$sed_quote_subst"`
+ if test "$hardcode_automatic" = yes ; then
+ relink_command=
+ fi
+
+ # Only create the output if not a dry run.
+ $opt_dry_run || {
+ for installed in no yes; do
+ if test "$installed" = yes; then
+ if test -z "$install_libdir"; then
+ break
+ fi
+ output="$output_objdir/$outputname"i
+ # Replace all uninstalled libtool libraries with the installed ones
+ newdependency_libs=
+ for deplib in $dependency_libs; do
+ case $deplib in
+ *.la)
+ func_basename "$deplib"
+ name="$func_basename_result"
+ eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib`
+ test -z "$libdir" && \
+ func_fatal_error "\`$deplib' is not a valid libtool archive"
+ newdependency_libs="$newdependency_libs $libdir/$name"
+ ;;
+ *) newdependency_libs="$newdependency_libs $deplib" ;;
+ esac
+ done
+ dependency_libs="$newdependency_libs"
+ newdlfiles=
+
+ for lib in $dlfiles; do
+ case $lib in
+ *.la)
+ func_basename "$lib"
+ name="$func_basename_result"
+ eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib`
+ test -z "$libdir" && \
+ func_fatal_error "\`$lib' is not a valid libtool archive"
+ newdlfiles="$newdlfiles $libdir/$name"
+ ;;
+ *) newdlfiles="$newdlfiles $lib" ;;
+ esac
+ done
+ dlfiles="$newdlfiles"
+ newdlprefiles=
+ for lib in $dlprefiles; do
+ case $lib in
+ *.la)
+ # Only pass preopened files to the pseudo-archive (for
+ # eventual linking with the app. that links it) if we
+ # didn't already link the preopened objects directly into
+ # the library:
+ func_basename "$lib"
+ name="$func_basename_result"
+ eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib`
+ test -z "$libdir" && \
+ func_fatal_error "\`$lib' is not a valid libtool archive"
+ newdlprefiles="$newdlprefiles $libdir/$name"
+ ;;
+ esac
+ done
+ dlprefiles="$newdlprefiles"
+ else
+ newdlfiles=
+ for lib in $dlfiles; do
+ case $lib in
+ [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;;
+ *) abs=`pwd`"/$lib" ;;
+ esac
+ newdlfiles="$newdlfiles $abs"
+ done
+ dlfiles="$newdlfiles"
+ newdlprefiles=
+ for lib in $dlprefiles; do
+ case $lib in
+ [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;;
+ *) abs=`pwd`"/$lib" ;;
+ esac
+ newdlprefiles="$newdlprefiles $abs"
+ done
+ dlprefiles="$newdlprefiles"
+ fi
+ $RM $output
+ # place dlname in correct position for cygwin
+ tdlname=$dlname
+ case $host,$output,$installed,$module,$dlname in
+ *cygwin*,*lai,yes,no,*.dll | *mingw*,*lai,yes,no,*.dll | *cegcc*,*lai,yes,no,*.dll) tdlname=../bin/$dlname ;;
+ esac
+ $ECHO > $output "\
+# $outputname - a libtool library file
+# Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION
+#
+# Please DO NOT delete this file!
+# It is necessary for linking the library.
+
+# The name that we can dlopen(3).
+dlname='$tdlname'
+
+# Names of this library.
+library_names='$library_names'
+
+# The name of the static archive.
+old_library='$old_library'
+
+# Linker flags that can not go in dependency_libs.
+inherited_linker_flags='$new_inherited_linker_flags'
+
+# Libraries that this one depends upon.
+dependency_libs='$dependency_libs'
+
+# Names of additional weak libraries provided by this library
+weak_library_names='$weak_libs'
+
+# Version information for $libname.
+current=$current
+age=$age
+revision=$revision
+
+# Is this an already installed library?
+installed=$installed
+
+# Should we warn about portability when linking against -modules?
+shouldnotlink=$module
+
+# Files to dlopen/dlpreopen
+dlopen='$dlfiles'
+dlpreopen='$dlprefiles'
+
+# Directory that this library needs to be installed in:
+libdir='$install_libdir'"
+ if test "$installed" = no && test "$need_relink" = yes; then
+ $ECHO >> $output "\
+relink_command=\"$relink_command\""
+ fi
+ done
+ }
+
+ # Do a symbolic link so that the libtool archive can be found in
+ # LD_LIBRARY_PATH before the program is installed.
+ func_show_eval '( cd "$output_objdir" && $RM "$outputname" && $LN_S "../$outputname" "$outputname" )' 'exit $?'
+ ;;
+ esac
+ exit $EXIT_SUCCESS
+}
+
+{ test "$mode" = link || test "$mode" = relink; } &&
+ func_mode_link ${1+"$@"}
+
+
+# func_mode_uninstall arg...
+func_mode_uninstall ()
+{
+ $opt_debug
+ RM="$nonopt"
+ files=
+ rmforce=
+ exit_status=0
+
+ # This variable tells wrapper scripts just to set variables rather
+ # than running their programs.
+ libtool_install_magic="$magic"
+
+ for arg
+ do
+ case $arg in
+ -f) RM="$RM $arg"; rmforce=yes ;;
+ -*) RM="$RM $arg" ;;
+ *) files="$files $arg" ;;
+ esac
+ done
+
+ test -z "$RM" && \
+ func_fatal_help "you must specify an RM program"
+
+ rmdirs=
+
+ origobjdir="$objdir"
+ for file in $files; do
+ func_dirname "$file" "" "."
+ dir="$func_dirname_result"
+ if test "X$dir" = X.; then
+ objdir="$origobjdir"
+ else
+ objdir="$dir/$origobjdir"
+ fi
+ func_basename "$file"
+ name="$func_basename_result"
+ test "$mode" = uninstall && objdir="$dir"
+
+ # Remember objdir for removal later, being careful to avoid duplicates
+ if test "$mode" = clean; then
+ case " $rmdirs " in
+ *" $objdir "*) ;;
+ *) rmdirs="$rmdirs $objdir" ;;
+ esac
+ fi
+
+ # Don't error if the file doesn't exist and rm -f was used.
+ if { test -L "$file"; } >/dev/null 2>&1 ||
+ { test -h "$file"; } >/dev/null 2>&1 ||
+ test -f "$file"; then
+ :
+ elif test -d "$file"; then
+ exit_status=1
+ continue
+ elif test "$rmforce" = yes; then
+ continue
+ fi
+
+ rmfiles="$file"
+
+ case $name in
+ *.la)
+ # Possibly a libtool archive, so verify it.
+ if func_lalib_p "$file"; then
+ func_source $dir/$name
+
+ # Delete the libtool libraries and symlinks.
+ for n in $library_names; do
+ rmfiles="$rmfiles $objdir/$n"
+ done
+ test -n "$old_library" && rmfiles="$rmfiles $objdir/$old_library"
+
+ case "$mode" in
+ clean)
+ case " $library_names " in
+ # " " in the beginning catches empty $dlname
+ *" $dlname "*) ;;
+ *) rmfiles="$rmfiles $objdir/$dlname" ;;
+ esac
+ test -n "$libdir" && rmfiles="$rmfiles $objdir/$name $objdir/${name}i"
+ ;;
+ uninstall)
+ if test -n "$library_names"; then
+ # Do each command in the postuninstall commands.
+ func_execute_cmds "$postuninstall_cmds" 'test "$rmforce" = yes || exit_status=1'
+ fi
+
+ if test -n "$old_library"; then
+ # Do each command in the old_postuninstall commands.
+ func_execute_cmds "$old_postuninstall_cmds" 'test "$rmforce" = yes || exit_status=1'
+ fi
+ # FIXME: should reinstall the best remaining shared library.
+ ;;
+ esac
+ fi
+ ;;
+
+ *.lo)
+ # Possibly a libtool object, so verify it.
+ if func_lalib_p "$file"; then
+
+ # Read the .lo file
+ func_source $dir/$name
+
+ # Add PIC object to the list of files to remove.
+ if test -n "$pic_object" &&
+ test "$pic_object" != none; then
+ rmfiles="$rmfiles $dir/$pic_object"
+ fi
+
+ # Add non-PIC object to the list of files to remove.
+ if test -n "$non_pic_object" &&
+ test "$non_pic_object" != none; then
+ rmfiles="$rmfiles $dir/$non_pic_object"
+ fi
+ fi
+ ;;
+
+ *)
+ if test "$mode" = clean ; then
+ noexename=$name
+ case $file in
+ *.exe)
+ func_stripname '' '.exe' "$file"
+ file=$func_stripname_result
+ func_stripname '' '.exe' "$name"
+ noexename=$func_stripname_result
+ # $file with .exe has already been added to rmfiles,
+ # add $file without .exe
+ rmfiles="$rmfiles $file"
+ ;;
+ esac
+ # Do a test to see if this is a libtool program.
+ if func_ltwrapper_p "$file"; then
+ if func_ltwrapper_executable_p "$file"; then
+ func_ltwrapper_scriptname "$file"
+ relink_command=
+ func_source $func_ltwrapper_scriptname_result
+ rmfiles="$rmfiles $func_ltwrapper_scriptname_result"
+ else
+ relink_command=
+ func_source $dir/$noexename
+ fi
+
+ # note $name still contains .exe if it was in $file originally
+ # as does the version of $file that was added into $rmfiles
+ rmfiles="$rmfiles $objdir/$name $objdir/${name}S.${objext}"
+ if test "$fast_install" = yes && test -n "$relink_command"; then
+ rmfiles="$rmfiles $objdir/lt-$name"
+ fi
+ if test "X$noexename" != "X$name" ; then
+ rmfiles="$rmfiles $objdir/lt-${noexename}.c"
+ fi
+ fi
+ fi
+ ;;
+ esac
+ func_show_eval "$RM $rmfiles" 'exit_status=1'
+ done
+ objdir="$origobjdir"
+
+ # Try to remove the ${objdir}s in the directories where we deleted files
+ for dir in $rmdirs; do
+ if test -d "$dir"; then
+ func_show_eval "rmdir $dir >/dev/null 2>&1"
+ fi
+ done
+
+ exit $exit_status
+}
+
+{ test "$mode" = uninstall || test "$mode" = clean; } &&
+ func_mode_uninstall ${1+"$@"}
+
+test -z "$mode" && {
+ help="$generic_help"
+ func_fatal_help "you must specify a MODE"
+}
+
+test -z "$exec_cmd" && \
+ func_fatal_help "invalid operation mode \`$mode'"
+
+if test -n "$exec_cmd"; then
+ eval exec "$exec_cmd"
+ exit $EXIT_FAILURE
+fi
+
+exit $exit_status
+
+
+# The TAGs below are defined such that we never get into a situation
+# in which we disable both kinds of libraries. Given conflicting
+# choices, we go for a static library, that is the most portable,
+# since we can't tell whether shared libraries were disabled because
+# the user asked for that or because the platform doesn't support
+# them. This is particularly important on AIX, because we don't
+# support having both static and shared libraries enabled at the same
+# time on that platform, so we default to a shared-only configuration.
+# If a disable-shared tag is given, we'll fallback to a static-only
+# configuration. But we'll never go from static-only to shared-only.
+
+# ### BEGIN LIBTOOL TAG CONFIG: disable-shared
+build_libtool_libs=no
+build_old_libs=yes
+# ### END LIBTOOL TAG CONFIG: disable-shared
+
+# ### BEGIN LIBTOOL TAG CONFIG: disable-static
+build_old_libs=`case $build_libtool_libs in yes) echo no;; *) echo yes;; esac`
+# ### END LIBTOOL TAG CONFIG: disable-static
+
+# Local Variables:
+# mode:shell-script
+# sh-indentation:2
+# End:
+# vi:sw=2
+
diff --git a/src/third_party/gflags-2.0/m4/ac_have_attribute.m4 b/src/third_party/gflags-2.0/m4/ac_have_attribute.m4
new file mode 100755
index 00000000000..19f4021e990
--- /dev/null
+++ b/src/third_party/gflags-2.0/m4/ac_have_attribute.m4
@@ -0,0 +1,16 @@
+AC_DEFUN([AX_C___ATTRIBUTE__], [
+ AC_MSG_CHECKING(for __attribute__)
+ AC_CACHE_VAL(ac_cv___attribute__, [
+ AC_TRY_COMPILE(
+ [#include <stdlib.h>
+ static void foo(void) __attribute__ ((unused));
+ void foo(void) { exit(1); }],
+ [],
+ ac_cv___attribute__=yes,
+ ac_cv___attribute__=no
+ )])
+ if test "$ac_cv___attribute__" = "yes"; then
+ AC_DEFINE(HAVE___ATTRIBUTE__, 1, [define if your compiler has __attribute__])
+ fi
+ AC_MSG_RESULT($ac_cv___attribute__)
+])
diff --git a/src/third_party/gflags-2.0/m4/acx_pthread.m4 b/src/third_party/gflags-2.0/m4/acx_pthread.m4
new file mode 100755
index 00000000000..89d42c7449e
--- /dev/null
+++ b/src/third_party/gflags-2.0/m4/acx_pthread.m4
@@ -0,0 +1,397 @@
+# This was retrieved from
+# http://svn.0pointer.de/viewvc/trunk/common/acx_pthread.m4?revision=1277&root=avahi
+# See also (perhaps for new versions?)
+# http://svn.0pointer.de/viewvc/trunk/common/acx_pthread.m4?root=avahi
+#
+# We've rewritten the inconsistency check code (from avahi), to work
+# more broadly. In particular, it no longer assumes ld accepts -zdefs.
+# This caused a restructing of the code, but the functionality has only
+# changed a little.
+
+dnl @synopsis ACX_PTHREAD([ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]])
+dnl
+dnl @summary figure out how to build C programs using POSIX threads
+dnl
+dnl This macro figures out how to build C programs using POSIX threads.
+dnl It sets the PTHREAD_LIBS output variable to the threads library and
+dnl linker flags, and the PTHREAD_CFLAGS output variable to any special
+dnl C compiler flags that are needed. (The user can also force certain
+dnl compiler flags/libs to be tested by setting these environment
+dnl variables.)
+dnl
+dnl Also sets PTHREAD_CC to any special C compiler that is needed for
+dnl multi-threaded programs (defaults to the value of CC otherwise).
+dnl (This is necessary on AIX to use the special cc_r compiler alias.)
+dnl
+dnl NOTE: You are assumed to not only compile your program with these
+dnl flags, but also link it with them as well. e.g. you should link
+dnl with $PTHREAD_CC $CFLAGS $PTHREAD_CFLAGS $LDFLAGS ... $PTHREAD_LIBS
+dnl $LIBS
+dnl
+dnl If you are only building threads programs, you may wish to use
+dnl these variables in your default LIBS, CFLAGS, and CC:
+dnl
+dnl LIBS="$PTHREAD_LIBS $LIBS"
+dnl CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+dnl CC="$PTHREAD_CC"
+dnl
+dnl In addition, if the PTHREAD_CREATE_JOINABLE thread-attribute
+dnl constant has a nonstandard name, defines PTHREAD_CREATE_JOINABLE to
+dnl that name (e.g. PTHREAD_CREATE_UNDETACHED on AIX).
+dnl
+dnl ACTION-IF-FOUND is a list of shell commands to run if a threads
+dnl library is found, and ACTION-IF-NOT-FOUND is a list of commands to
+dnl run it if it is not found. If ACTION-IF-FOUND is not specified, the
+dnl default action will define HAVE_PTHREAD.
+dnl
+dnl Please let the authors know if this macro fails on any platform, or
+dnl if you have any other suggestions or comments. This macro was based
+dnl on work by SGJ on autoconf scripts for FFTW (www.fftw.org) (with
+dnl help from M. Frigo), as well as ac_pthread and hb_pthread macros
+dnl posted by Alejandro Forero Cuervo to the autoconf macro repository.
+dnl We are also grateful for the helpful feedback of numerous users.
+dnl
+dnl @category InstalledPackages
+dnl @author Steven G. Johnson <stevenj@alum.mit.edu>
+dnl @version 2006-05-29
+dnl @license GPLWithACException
+dnl
+dnl Checks for GCC shared/pthread inconsistency based on work by
+dnl Marcin Owsiany <marcin@owsiany.pl>
+
+
+AC_DEFUN([ACX_PTHREAD], [
+AC_REQUIRE([AC_CANONICAL_HOST])
+AC_LANG_SAVE
+AC_LANG_C
+acx_pthread_ok=no
+
+# We used to check for pthread.h first, but this fails if pthread.h
+# requires special compiler flags (e.g. on True64 or Sequent).
+# It gets checked for in the link test anyway.
+
+# First of all, check if the user has set any of the PTHREAD_LIBS,
+# etcetera environment variables, and if threads linking works using
+# them:
+if test x"$PTHREAD_LIBS$PTHREAD_CFLAGS" != x; then
+ save_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+ save_LIBS="$LIBS"
+ LIBS="$PTHREAD_LIBS $LIBS"
+ AC_MSG_CHECKING([for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS])
+ AC_TRY_LINK_FUNC(pthread_join, acx_pthread_ok=yes)
+ AC_MSG_RESULT($acx_pthread_ok)
+ if test x"$acx_pthread_ok" = xno; then
+ PTHREAD_LIBS=""
+ PTHREAD_CFLAGS=""
+ fi
+ LIBS="$save_LIBS"
+ CFLAGS="$save_CFLAGS"
+fi
+
+# We must check for the threads library under a number of different
+# names; the ordering is very important because some systems
+# (e.g. DEC) have both -lpthread and -lpthreads, where one of the
+# libraries is broken (non-POSIX).
+
+# Create a list of thread flags to try. Items starting with a "-" are
+# C compiler flags, and other items are library names, except for "none"
+# which indicates that we try without any flags at all, and "pthread-config"
+# which is a program returning the flags for the Pth emulation library.
+
+acx_pthread_flags="pthreads none -Kthread -kthread lthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config"
+
+# The ordering *is* (sometimes) important. Some notes on the
+# individual items follow:
+
+# pthreads: AIX (must check this before -lpthread)
+# none: in case threads are in libc; should be tried before -Kthread and
+# other compiler flags to prevent continual compiler warnings
+# -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h)
+# -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able)
+# lthread: LinuxThreads port on FreeBSD (also preferred to -pthread)
+# -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads)
+# -pthreads: Solaris/gcc
+# -mthreads: Mingw32/gcc, Lynx/gcc
+# -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it
+# doesn't hurt to check since this sometimes defines pthreads too;
+# also defines -D_REENTRANT)
+# ... -mt is also the pthreads flag for HP/aCC
+# pthread: Linux, etcetera
+# --thread-safe: KAI C++
+# pthread-config: use pthread-config program (for GNU Pth library)
+
+case "${host_cpu}-${host_os}" in
+ *solaris*)
+
+ # On Solaris (at least, for some versions), libc contains stubbed
+ # (non-functional) versions of the pthreads routines, so link-based
+ # tests will erroneously succeed. (We need to link with -pthreads/-mt/
+ # -lpthread.) (The stubs are missing pthread_cleanup_push, or rather
+ # a function called by this macro, so we could check for that, but
+ # who knows whether they'll stub that too in a future libc.) So,
+ # we'll just look for -pthreads and -lpthread first:
+
+ acx_pthread_flags="-pthreads pthread -mt -pthread $acx_pthread_flags"
+ ;;
+esac
+
+if test x"$acx_pthread_ok" = xno; then
+for flag in $acx_pthread_flags; do
+
+ case $flag in
+ none)
+ AC_MSG_CHECKING([whether pthreads work without any flags])
+ ;;
+
+ -*)
+ AC_MSG_CHECKING([whether pthreads work with $flag])
+ PTHREAD_CFLAGS="$flag"
+ ;;
+
+ pthread-config)
+ AC_CHECK_PROG(acx_pthread_config, pthread-config, yes, no)
+ if test x"$acx_pthread_config" = xno; then continue; fi
+ PTHREAD_CFLAGS="`pthread-config --cflags`"
+ PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`"
+ ;;
+
+ *)
+ AC_MSG_CHECKING([for the pthreads library -l$flag])
+ PTHREAD_LIBS="-l$flag"
+ ;;
+ esac
+
+ save_LIBS="$LIBS"
+ save_CFLAGS="$CFLAGS"
+ LIBS="$PTHREAD_LIBS $LIBS"
+ CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+
+ # Check for various functions. We must include pthread.h,
+ # since some functions may be macros. (On the Sequent, we
+ # need a special flag -Kthread to make this header compile.)
+ # We check for pthread_join because it is in -lpthread on IRIX
+ # while pthread_create is in libc. We check for pthread_attr_init
+ # due to DEC craziness with -lpthreads. We check for
+ # pthread_cleanup_push because it is one of the few pthread
+ # functions on Solaris that doesn't have a non-functional libc stub.
+ # We try pthread_create on general principles.
+ AC_TRY_LINK([#include <pthread.h>],
+ [pthread_t th; pthread_join(th, 0);
+ pthread_attr_init(0); pthread_cleanup_push(0, 0);
+ pthread_create(0,0,0,0); pthread_cleanup_pop(0); ],
+ [acx_pthread_ok=yes])
+
+ LIBS="$save_LIBS"
+ CFLAGS="$save_CFLAGS"
+
+ AC_MSG_RESULT($acx_pthread_ok)
+ if test "x$acx_pthread_ok" = xyes; then
+ break;
+ fi
+
+ PTHREAD_LIBS=""
+ PTHREAD_CFLAGS=""
+done
+fi
+
+# Various other checks:
+if test "x$acx_pthread_ok" = xyes; then
+ save_LIBS="$LIBS"
+ LIBS="$PTHREAD_LIBS $LIBS"
+ save_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+
+ # Detect AIX lossage: JOINABLE attribute is called UNDETACHED.
+ AC_MSG_CHECKING([for joinable pthread attribute])
+ attr_name=unknown
+ for attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do
+ AC_TRY_LINK([#include <pthread.h>], [int attr=$attr; return attr;],
+ [attr_name=$attr; break])
+ done
+ AC_MSG_RESULT($attr_name)
+ if test "$attr_name" != PTHREAD_CREATE_JOINABLE; then
+ AC_DEFINE_UNQUOTED(PTHREAD_CREATE_JOINABLE, $attr_name,
+ [Define to necessary symbol if this constant
+ uses a non-standard name on your system.])
+ fi
+
+ AC_MSG_CHECKING([if more special flags are required for pthreads])
+ flag=no
+ case "${host_cpu}-${host_os}" in
+ *-aix* | *-freebsd* | *-darwin*) flag="-D_THREAD_SAFE";;
+ *solaris* | *-osf* | *-hpux*) flag="-D_REENTRANT";;
+ esac
+ AC_MSG_RESULT(${flag})
+ if test "x$flag" != xno; then
+ PTHREAD_CFLAGS="$flag $PTHREAD_CFLAGS"
+ fi
+
+ LIBS="$save_LIBS"
+ CFLAGS="$save_CFLAGS"
+ # More AIX lossage: must compile with xlc_r or cc_r
+ if test x"$GCC" != xyes; then
+ AC_CHECK_PROGS(PTHREAD_CC, xlc_r cc_r, ${CC})
+ else
+ PTHREAD_CC=$CC
+ fi
+
+ # The next part tries to detect GCC inconsistency with -shared on some
+ # architectures and systems. The problem is that in certain
+ # configurations, when -shared is specified, GCC "forgets" to
+ # internally use various flags which are still necessary.
+
+ #
+ # Prepare the flags
+ #
+ save_CFLAGS="$CFLAGS"
+ save_LIBS="$LIBS"
+ save_CC="$CC"
+
+ # Try with the flags determined by the earlier checks.
+ #
+ # -Wl,-z,defs forces link-time symbol resolution, so that the
+ # linking checks with -shared actually have any value
+ #
+ # FIXME: -fPIC is required for -shared on many architectures,
+ # so we specify it here, but the right way would probably be to
+ # properly detect whether it is actually required.
+ CFLAGS="-shared -fPIC -Wl,-z,defs $CFLAGS $PTHREAD_CFLAGS"
+ LIBS="$PTHREAD_LIBS $LIBS"
+ CC="$PTHREAD_CC"
+
+ # In order not to create several levels of indentation, we test
+ # the value of "$done" until we find the cure or run out of ideas.
+ done="no"
+
+ # First, make sure the CFLAGS we added are actually accepted by our
+ # compiler. If not (and OS X's ld, for instance, does not accept -z),
+ # then we can't do this test.
+ if test x"$done" = xno; then
+ AC_MSG_CHECKING([whether to check for GCC pthread/shared inconsistencies])
+ AC_TRY_LINK(,, , [done=yes])
+
+ if test "x$done" = xyes ; then
+ AC_MSG_RESULT([no])
+ else
+ AC_MSG_RESULT([yes])
+ fi
+ fi
+
+ if test x"$done" = xno; then
+ AC_MSG_CHECKING([whether -pthread is sufficient with -shared])
+ AC_TRY_LINK([#include <pthread.h>],
+ [pthread_t th; pthread_join(th, 0);
+ pthread_attr_init(0); pthread_cleanup_push(0, 0);
+ pthread_create(0,0,0,0); pthread_cleanup_pop(0); ],
+ [done=yes])
+
+ if test "x$done" = xyes; then
+ AC_MSG_RESULT([yes])
+ else
+ AC_MSG_RESULT([no])
+ fi
+ fi
+
+ #
+ # Linux gcc on some architectures such as mips/mipsel forgets
+ # about -lpthread
+ #
+ if test x"$done" = xno; then
+ AC_MSG_CHECKING([whether -lpthread fixes that])
+ LIBS="-lpthread $PTHREAD_LIBS $save_LIBS"
+ AC_TRY_LINK([#include <pthread.h>],
+ [pthread_t th; pthread_join(th, 0);
+ pthread_attr_init(0); pthread_cleanup_push(0, 0);
+ pthread_create(0,0,0,0); pthread_cleanup_pop(0); ],
+ [done=yes])
+
+ if test "x$done" = xyes; then
+ AC_MSG_RESULT([yes])
+ PTHREAD_LIBS="-lpthread $PTHREAD_LIBS"
+ else
+ AC_MSG_RESULT([no])
+ fi
+ fi
+ #
+ # FreeBSD 4.10 gcc forgets to use -lc_r instead of -lc
+ #
+ if test x"$done" = xno; then
+ AC_MSG_CHECKING([whether -lc_r fixes that])
+ LIBS="-lc_r $PTHREAD_LIBS $save_LIBS"
+ AC_TRY_LINK([#include <pthread.h>],
+ [pthread_t th; pthread_join(th, 0);
+ pthread_attr_init(0); pthread_cleanup_push(0, 0);
+ pthread_create(0,0,0,0); pthread_cleanup_pop(0); ],
+ [done=yes])
+
+ if test "x$done" = xyes; then
+ AC_MSG_RESULT([yes])
+ PTHREAD_LIBS="-lc_r $PTHREAD_LIBS"
+ else
+ AC_MSG_RESULT([no])
+ fi
+ fi
+ if test x"$done" = xno; then
+ # OK, we have run out of ideas
+ AC_MSG_WARN([Impossible to determine how to use pthreads with shared libraries])
+
+ # so it's not safe to assume that we may use pthreads
+ acx_pthread_ok=no
+ fi
+
+ AC_MSG_CHECKING([whether what we have so far is sufficient with -nostdlib])
+ CFLAGS="-nostdlib $CFLAGS"
+ # we need c with nostdlib
+ LIBS="$LIBS -lc"
+ AC_TRY_LINK([#include <pthread.h>],
+ [pthread_t th; pthread_join(th, 0);
+ pthread_attr_init(0); pthread_cleanup_push(0, 0);
+ pthread_create(0,0,0,0); pthread_cleanup_pop(0); ],
+ [done=yes],[done=no])
+
+ if test "x$done" = xyes; then
+ AC_MSG_RESULT([yes])
+ else
+ AC_MSG_RESULT([no])
+ fi
+
+ if test x"$done" = xno; then
+ AC_MSG_CHECKING([whether -lpthread saves the day])
+ LIBS="-lpthread $LIBS"
+ AC_TRY_LINK([#include <pthread.h>],
+ [pthread_t th; pthread_join(th, 0);
+ pthread_attr_init(0); pthread_cleanup_push(0, 0);
+ pthread_create(0,0,0,0); pthread_cleanup_pop(0); ],
+ [done=yes],[done=no])
+
+ if test "x$done" = xyes; then
+ AC_MSG_RESULT([yes])
+ PTHREAD_LIBS="$PTHREAD_LIBS -lpthread"
+ else
+ AC_MSG_RESULT([no])
+ AC_MSG_WARN([Impossible to determine how to use pthreads with shared libraries and -nostdlib])
+ fi
+ fi
+
+ CFLAGS="$save_CFLAGS"
+ LIBS="$save_LIBS"
+ CC="$save_CC"
+else
+ PTHREAD_CC="$CC"
+fi
+
+AC_SUBST(PTHREAD_LIBS)
+AC_SUBST(PTHREAD_CFLAGS)
+AC_SUBST(PTHREAD_CC)
+
+# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND:
+if test x"$acx_pthread_ok" = xyes; then
+ ifelse([$1],,AC_DEFINE(HAVE_PTHREAD,1,[Define if you have POSIX threads libraries and header files.]),[$1])
+ :
+else
+ acx_pthread_ok=no
+ $2
+fi
+AC_LANG_RESTORE
+])dnl ACX_PTHREAD
diff --git a/src/third_party/gflags-2.0/m4/google_namespace.m4 b/src/third_party/gflags-2.0/m4/google_namespace.m4
new file mode 100755
index 00000000000..7f244cc084c
--- /dev/null
+++ b/src/third_party/gflags-2.0/m4/google_namespace.m4
@@ -0,0 +1,42 @@
+# Allow users to override the namespace we define our application's classes in
+# Arg $1 is the default namespace to use if --enable-namespace isn't present.
+
+# In general, $1 should be 'google', so we put all our exported symbols in a
+# unique namespace that is not likely to conflict with anyone else. However,
+# when it makes sense -- for instance, when publishing stl-like code -- you
+# may want to go with a different default, like 'std'.
+
+# We guarantee the invariant that GOOGLE_NAMESPACE starts with ::,
+# unless it's the empty string. Thus, it's always safe to do
+# GOOGLE_NAMESPACE::foo and be sure you're getting the foo that's
+# actually in the google namespace, and not some other namespace that
+# the namespace rules might kick in.
+
+AC_DEFUN([AC_DEFINE_GOOGLE_NAMESPACE],
+ [google_namespace_default=[$1]
+ AC_ARG_ENABLE(namespace, [ --enable-namespace=FOO to define these Google
+ classes in the FOO namespace. --disable-namespace
+ to define them in the global namespace. Default
+ is to define them in namespace $1.],
+ [case "$enableval" in
+ yes) google_namespace="$google_namespace_default" ;;
+ no) google_namespace="" ;;
+ *) google_namespace="$enableval" ;;
+ esac],
+ [google_namespace="$google_namespace_default"])
+ if test -n "$google_namespace"; then
+ ac_google_namespace="::$google_namespace"
+ ac_google_start_namespace="namespace $google_namespace {"
+ ac_google_end_namespace="}"
+ else
+ ac_google_namespace=""
+ ac_google_start_namespace=""
+ ac_google_end_namespace=""
+ fi
+ AC_DEFINE_UNQUOTED(GOOGLE_NAMESPACE, $ac_google_namespace,
+ Namespace for Google classes)
+ AC_DEFINE_UNQUOTED(_START_GOOGLE_NAMESPACE_, $ac_google_start_namespace,
+ Puts following code inside the Google namespace)
+ AC_DEFINE_UNQUOTED(_END_GOOGLE_NAMESPACE_, $ac_google_end_namespace,
+ Stops putting the code inside the Google namespace)
+])
diff --git a/src/third_party/gflags-2.0/m4/libtool.m4 b/src/third_party/gflags-2.0/m4/libtool.m4
new file mode 100755
index 00000000000..a3fee5360f6
--- /dev/null
+++ b/src/third_party/gflags-2.0/m4/libtool.m4
@@ -0,0 +1,7377 @@
+# libtool.m4 - Configure libtool for the host system. -*-Autoconf-*-
+#
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005,
+# 2006, 2007, 2008 Free Software Foundation, Inc.
+# Written by Gordon Matzigkeit, 1996
+#
+# This file is free software; the Free Software Foundation gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+
+m4_define([_LT_COPYING], [dnl
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005,
+# 2006, 2007, 2008 Free Software Foundation, Inc.
+# Written by Gordon Matzigkeit, 1996
+#
+# This file is part of GNU Libtool.
+#
+# GNU Libtool is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# As a special exception to the GNU General Public License,
+# if you distribute this file as part of a program or library that
+# is built using GNU Libtool, you may include this file under the
+# same distribution terms that you use for the rest of that program.
+#
+# GNU Libtool is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Libtool; see the file COPYING. If not, a copy
+# can be downloaded from http://www.gnu.org/licenses/gpl.html, or
+# obtained by writing to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+])
+
+# serial 56 LT_INIT
+
+
+# LT_PREREQ(VERSION)
+# ------------------
+# Complain and exit if this libtool version is less that VERSION.
+m4_defun([LT_PREREQ],
+[m4_if(m4_version_compare(m4_defn([LT_PACKAGE_VERSION]), [$1]), -1,
+ [m4_default([$3],
+ [m4_fatal([Libtool version $1 or higher is required],
+ 63)])],
+ [$2])])
+
+
+# _LT_CHECK_BUILDDIR
+# ------------------
+# Complain if the absolute build directory name contains unusual characters
+m4_defun([_LT_CHECK_BUILDDIR],
+[case `pwd` in
+ *\ * | *\ *)
+ AC_MSG_WARN([Libtool does not cope well with whitespace in `pwd`]) ;;
+esac
+])
+
+
+# LT_INIT([OPTIONS])
+# ------------------
+AC_DEFUN([LT_INIT],
+[AC_PREREQ([2.58])dnl We use AC_INCLUDES_DEFAULT
+AC_BEFORE([$0], [LT_LANG])dnl
+AC_BEFORE([$0], [LT_OUTPUT])dnl
+AC_BEFORE([$0], [LTDL_INIT])dnl
+m4_require([_LT_CHECK_BUILDDIR])dnl
+
+dnl Autoconf doesn't catch unexpanded LT_ macros by default:
+m4_pattern_forbid([^_?LT_[A-Z_]+$])dnl
+m4_pattern_allow([^(_LT_EOF|LT_DLGLOBAL|LT_DLLAZY_OR_NOW|LT_MULTI_MODULE)$])dnl
+dnl aclocal doesn't pull ltoptions.m4, ltsugar.m4, or ltversion.m4
+dnl unless we require an AC_DEFUNed macro:
+AC_REQUIRE([LTOPTIONS_VERSION])dnl
+AC_REQUIRE([LTSUGAR_VERSION])dnl
+AC_REQUIRE([LTVERSION_VERSION])dnl
+AC_REQUIRE([LTOBSOLETE_VERSION])dnl
+m4_require([_LT_PROG_LTMAIN])dnl
+
+dnl Parse OPTIONS
+_LT_SET_OPTIONS([$0], [$1])
+
+# This can be used to rebuild libtool when needed
+LIBTOOL_DEPS="$ltmain"
+
+# Always use our own libtool.
+LIBTOOL='$(SHELL) $(top_builddir)/libtool'
+AC_SUBST(LIBTOOL)dnl
+
+_LT_SETUP
+
+# Only expand once:
+m4_define([LT_INIT])
+])# LT_INIT
+
+# Old names:
+AU_ALIAS([AC_PROG_LIBTOOL], [LT_INIT])
+AU_ALIAS([AM_PROG_LIBTOOL], [LT_INIT])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_PROG_LIBTOOL], [])
+dnl AC_DEFUN([AM_PROG_LIBTOOL], [])
+
+
+# _LT_CC_BASENAME(CC)
+# -------------------
+# Calculate cc_basename. Skip known compiler wrappers and cross-prefix.
+m4_defun([_LT_CC_BASENAME],
+[for cc_temp in $1""; do
+ case $cc_temp in
+ compile | *[[\\/]]compile | ccache | *[[\\/]]ccache ) ;;
+ distcc | *[[\\/]]distcc | purify | *[[\\/]]purify ) ;;
+ \-*) ;;
+ *) break;;
+ esac
+done
+cc_basename=`$ECHO "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"`
+])
+
+
+# _LT_FILEUTILS_DEFAULTS
+# ----------------------
+# It is okay to use these file commands and assume they have been set
+# sensibly after `m4_require([_LT_FILEUTILS_DEFAULTS])'.
+m4_defun([_LT_FILEUTILS_DEFAULTS],
+[: ${CP="cp -f"}
+: ${MV="mv -f"}
+: ${RM="rm -f"}
+])# _LT_FILEUTILS_DEFAULTS
+
+
+# _LT_SETUP
+# ---------
+m4_defun([_LT_SETUP],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_CANONICAL_BUILD])dnl
+_LT_DECL([], [host_alias], [0], [The host system])dnl
+_LT_DECL([], [host], [0])dnl
+_LT_DECL([], [host_os], [0])dnl
+dnl
+_LT_DECL([], [build_alias], [0], [The build system])dnl
+_LT_DECL([], [build], [0])dnl
+_LT_DECL([], [build_os], [0])dnl
+dnl
+AC_REQUIRE([AC_PROG_CC])dnl
+AC_REQUIRE([LT_PATH_LD])dnl
+AC_REQUIRE([LT_PATH_NM])dnl
+dnl
+AC_REQUIRE([AC_PROG_LN_S])dnl
+test -z "$LN_S" && LN_S="ln -s"
+_LT_DECL([], [LN_S], [1], [Whether we need soft or hard links])dnl
+dnl
+AC_REQUIRE([LT_CMD_MAX_LEN])dnl
+_LT_DECL([objext], [ac_objext], [0], [Object file suffix (normally "o")])dnl
+_LT_DECL([], [exeext], [0], [Executable file suffix (normally "")])dnl
+dnl
+m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_CHECK_SHELL_FEATURES])dnl
+m4_require([_LT_CMD_RELOAD])dnl
+m4_require([_LT_CHECK_MAGIC_METHOD])dnl
+m4_require([_LT_CMD_OLD_ARCHIVE])dnl
+m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl
+
+_LT_CONFIG_LIBTOOL_INIT([
+# See if we are running on zsh, and set the options which allow our
+# commands through without removal of \ escapes INIT.
+if test -n "\${ZSH_VERSION+set}" ; then
+ setopt NO_GLOB_SUBST
+fi
+])
+if test -n "${ZSH_VERSION+set}" ; then
+ setopt NO_GLOB_SUBST
+fi
+
+_LT_CHECK_OBJDIR
+
+m4_require([_LT_TAG_COMPILER])dnl
+_LT_PROG_ECHO_BACKSLASH
+
+case $host_os in
+aix3*)
+ # AIX sometimes has problems with the GCC collect2 program. For some
+ # reason, if we set the COLLECT_NAMES environment variable, the problems
+ # vanish in a puff of smoke.
+ if test "X${COLLECT_NAMES+set}" != Xset; then
+ COLLECT_NAMES=
+ export COLLECT_NAMES
+ fi
+ ;;
+esac
+
+# Sed substitution that helps us do robust quoting. It backslashifies
+# metacharacters that are still active within double-quoted strings.
+sed_quote_subst='s/\([["`$\\]]\)/\\\1/g'
+
+# Same as above, but do not quote variable references.
+double_quote_subst='s/\([["`\\]]\)/\\\1/g'
+
+# Sed substitution to delay expansion of an escaped shell variable in a
+# double_quote_subst'ed string.
+delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g'
+
+# Sed substitution to delay expansion of an escaped single quote.
+delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g'
+
+# Sed substitution to avoid accidental globbing in evaled expressions
+no_glob_subst='s/\*/\\\*/g'
+
+# Global variables:
+ofile=libtool
+can_build_shared=yes
+
+# All known linkers require a `.a' archive for static linking (except MSVC,
+# which needs '.lib').
+libext=a
+
+with_gnu_ld="$lt_cv_prog_gnu_ld"
+
+old_CC="$CC"
+old_CFLAGS="$CFLAGS"
+
+# Set sane defaults for various variables
+test -z "$CC" && CC=cc
+test -z "$LTCC" && LTCC=$CC
+test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS
+test -z "$LD" && LD=ld
+test -z "$ac_objext" && ac_objext=o
+
+_LT_CC_BASENAME([$compiler])
+
+# Only perform the check for file, if the check method requires it
+test -z "$MAGIC_CMD" && MAGIC_CMD=file
+case $deplibs_check_method in
+file_magic*)
+ if test "$file_magic_cmd" = '$MAGIC_CMD'; then
+ _LT_PATH_MAGIC
+ fi
+ ;;
+esac
+
+# Use C for the default configuration in the libtool script
+LT_SUPPORTED_TAG([CC])
+_LT_LANG_C_CONFIG
+_LT_LANG_DEFAULT_CONFIG
+_LT_CONFIG_COMMANDS
+])# _LT_SETUP
+
+
+# _LT_PROG_LTMAIN
+# ---------------
+# Note that this code is called both from `configure', and `config.status'
+# now that we use AC_CONFIG_COMMANDS to generate libtool. Notably,
+# `config.status' has no value for ac_aux_dir unless we are using Automake,
+# so we pass a copy along to make sure it has a sensible value anyway.
+m4_defun([_LT_PROG_LTMAIN],
+[m4_ifdef([AC_REQUIRE_AUX_FILE], [AC_REQUIRE_AUX_FILE([ltmain.sh])])dnl
+_LT_CONFIG_LIBTOOL_INIT([ac_aux_dir='$ac_aux_dir'])
+ltmain="$ac_aux_dir/ltmain.sh"
+])# _LT_PROG_LTMAIN
+
+
+## ------------------------------------- ##
+## Accumulate code for creating libtool. ##
+## ------------------------------------- ##
+
+# So that we can recreate a full libtool script including additional
+# tags, we accumulate the chunks of code to send to AC_CONFIG_COMMANDS
+# in macros and then make a single call at the end using the `libtool'
+# label.
+
+
+# _LT_CONFIG_LIBTOOL_INIT([INIT-COMMANDS])
+# ----------------------------------------
+# Register INIT-COMMANDS to be passed to AC_CONFIG_COMMANDS later.
+m4_define([_LT_CONFIG_LIBTOOL_INIT],
+[m4_ifval([$1],
+ [m4_append([_LT_OUTPUT_LIBTOOL_INIT],
+ [$1
+])])])
+
+# Initialize.
+m4_define([_LT_OUTPUT_LIBTOOL_INIT])
+
+
+# _LT_CONFIG_LIBTOOL([COMMANDS])
+# ------------------------------
+# Register COMMANDS to be passed to AC_CONFIG_COMMANDS later.
+m4_define([_LT_CONFIG_LIBTOOL],
+[m4_ifval([$1],
+ [m4_append([_LT_OUTPUT_LIBTOOL_COMMANDS],
+ [$1
+])])])
+
+# Initialize.
+m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS])
+
+
+# _LT_CONFIG_SAVE_COMMANDS([COMMANDS], [INIT_COMMANDS])
+# -----------------------------------------------------
+m4_defun([_LT_CONFIG_SAVE_COMMANDS],
+[_LT_CONFIG_LIBTOOL([$1])
+_LT_CONFIG_LIBTOOL_INIT([$2])
+])
+
+
+# _LT_FORMAT_COMMENT([COMMENT])
+# -----------------------------
+# Add leading comment marks to the start of each line, and a trailing
+# full-stop to the whole comment if one is not present already.
+m4_define([_LT_FORMAT_COMMENT],
+[m4_ifval([$1], [
+m4_bpatsubst([m4_bpatsubst([$1], [^ *], [# ])],
+ [['`$\]], [\\\&])]m4_bmatch([$1], [[!?.]$], [], [.])
+)])
+
+
+
+## ------------------------ ##
+## FIXME: Eliminate VARNAME ##
+## ------------------------ ##
+
+
+# _LT_DECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION], [IS-TAGGED?])
+# -------------------------------------------------------------------
+# CONFIGNAME is the name given to the value in the libtool script.
+# VARNAME is the (base) name used in the configure script.
+# VALUE may be 0, 1 or 2 for a computed quote escaped value based on
+# VARNAME. Any other value will be used directly.
+m4_define([_LT_DECL],
+[lt_if_append_uniq([lt_decl_varnames], [$2], [, ],
+ [lt_dict_add_subkey([lt_decl_dict], [$2], [libtool_name],
+ [m4_ifval([$1], [$1], [$2])])
+ lt_dict_add_subkey([lt_decl_dict], [$2], [value], [$3])
+ m4_ifval([$4],
+ [lt_dict_add_subkey([lt_decl_dict], [$2], [description], [$4])])
+ lt_dict_add_subkey([lt_decl_dict], [$2],
+ [tagged?], [m4_ifval([$5], [yes], [no])])])
+])
+
+
+# _LT_TAGDECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION])
+# --------------------------------------------------------
+m4_define([_LT_TAGDECL], [_LT_DECL([$1], [$2], [$3], [$4], [yes])])
+
+
+# lt_decl_tag_varnames([SEPARATOR], [VARNAME1...])
+# ------------------------------------------------
+m4_define([lt_decl_tag_varnames],
+[_lt_decl_filter([tagged?], [yes], $@)])
+
+
+# _lt_decl_filter(SUBKEY, VALUE, [SEPARATOR], [VARNAME1..])
+# ---------------------------------------------------------
+m4_define([_lt_decl_filter],
+[m4_case([$#],
+ [0], [m4_fatal([$0: too few arguments: $#])],
+ [1], [m4_fatal([$0: too few arguments: $#: $1])],
+ [2], [lt_dict_filter([lt_decl_dict], [$1], [$2], [], lt_decl_varnames)],
+ [3], [lt_dict_filter([lt_decl_dict], [$1], [$2], [$3], lt_decl_varnames)],
+ [lt_dict_filter([lt_decl_dict], $@)])[]dnl
+])
+
+
+# lt_decl_quote_varnames([SEPARATOR], [VARNAME1...])
+# --------------------------------------------------
+m4_define([lt_decl_quote_varnames],
+[_lt_decl_filter([value], [1], $@)])
+
+
+# lt_decl_dquote_varnames([SEPARATOR], [VARNAME1...])
+# ---------------------------------------------------
+m4_define([lt_decl_dquote_varnames],
+[_lt_decl_filter([value], [2], $@)])
+
+
+# lt_decl_varnames_tagged([SEPARATOR], [VARNAME1...])
+# ---------------------------------------------------
+m4_define([lt_decl_varnames_tagged],
+[m4_assert([$# <= 2])dnl
+_$0(m4_quote(m4_default([$1], [[, ]])),
+ m4_ifval([$2], [[$2]], [m4_dquote(lt_decl_tag_varnames)]),
+ m4_split(m4_normalize(m4_quote(_LT_TAGS)), [ ]))])
+m4_define([_lt_decl_varnames_tagged],
+[m4_ifval([$3], [lt_combine([$1], [$2], [_], $3)])])
+
+
+# lt_decl_all_varnames([SEPARATOR], [VARNAME1...])
+# ------------------------------------------------
+m4_define([lt_decl_all_varnames],
+[_$0(m4_quote(m4_default([$1], [[, ]])),
+ m4_if([$2], [],
+ m4_quote(lt_decl_varnames),
+ m4_quote(m4_shift($@))))[]dnl
+])
+m4_define([_lt_decl_all_varnames],
+[lt_join($@, lt_decl_varnames_tagged([$1],
+ lt_decl_tag_varnames([[, ]], m4_shift($@))))dnl
+])
+
+
+# _LT_CONFIG_STATUS_DECLARE([VARNAME])
+# ------------------------------------
+# Quote a variable value, and forward it to `config.status' so that its
+# declaration there will have the same value as in `configure'. VARNAME
+# must have a single quote delimited value for this to work.
+m4_define([_LT_CONFIG_STATUS_DECLARE],
+[$1='`$ECHO "X$][$1" | $Xsed -e "$delay_single_quote_subst"`'])
+
+
+# _LT_CONFIG_STATUS_DECLARATIONS
+# ------------------------------
+# We delimit libtool config variables with single quotes, so when
+# we write them to config.status, we have to be sure to quote all
+# embedded single quotes properly. In configure, this macro expands
+# each variable declared with _LT_DECL (and _LT_TAGDECL) into:
+#
+# <var>='`$ECHO "X$<var>" | $Xsed -e "$delay_single_quote_subst"`'
+m4_defun([_LT_CONFIG_STATUS_DECLARATIONS],
+[m4_foreach([_lt_var], m4_quote(lt_decl_all_varnames),
+ [m4_n([_LT_CONFIG_STATUS_DECLARE(_lt_var)])])])
+
+
+# _LT_LIBTOOL_TAGS
+# ----------------
+# Output comment and list of tags supported by the script
+m4_defun([_LT_LIBTOOL_TAGS],
+[_LT_FORMAT_COMMENT([The names of the tagged configurations supported by this script])dnl
+available_tags="_LT_TAGS"dnl
+])
+
+
+# _LT_LIBTOOL_DECLARE(VARNAME, [TAG])
+# -----------------------------------
+# Extract the dictionary values for VARNAME (optionally with TAG) and
+# expand to a commented shell variable setting:
+#
+# # Some comment about what VAR is for.
+# visible_name=$lt_internal_name
+m4_define([_LT_LIBTOOL_DECLARE],
+[_LT_FORMAT_COMMENT(m4_quote(lt_dict_fetch([lt_decl_dict], [$1],
+ [description])))[]dnl
+m4_pushdef([_libtool_name],
+ m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [libtool_name])))[]dnl
+m4_case(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [value])),
+ [0], [_libtool_name=[$]$1],
+ [1], [_libtool_name=$lt_[]$1],
+ [2], [_libtool_name=$lt_[]$1],
+ [_libtool_name=lt_dict_fetch([lt_decl_dict], [$1], [value])])[]dnl
+m4_ifval([$2], [_$2])[]m4_popdef([_libtool_name])[]dnl
+])
+
+
+# _LT_LIBTOOL_CONFIG_VARS
+# -----------------------
+# Produce commented declarations of non-tagged libtool config variables
+# suitable for insertion in the LIBTOOL CONFIG section of the `libtool'
+# script. Tagged libtool config variables (even for the LIBTOOL CONFIG
+# section) are produced by _LT_LIBTOOL_TAG_VARS.
+m4_defun([_LT_LIBTOOL_CONFIG_VARS],
+[m4_foreach([_lt_var],
+ m4_quote(_lt_decl_filter([tagged?], [no], [], lt_decl_varnames)),
+ [m4_n([_LT_LIBTOOL_DECLARE(_lt_var)])])])
+
+
+# _LT_LIBTOOL_TAG_VARS(TAG)
+# -------------------------
+m4_define([_LT_LIBTOOL_TAG_VARS],
+[m4_foreach([_lt_var], m4_quote(lt_decl_tag_varnames),
+ [m4_n([_LT_LIBTOOL_DECLARE(_lt_var, [$1])])])])
+
+
+# _LT_TAGVAR(VARNAME, [TAGNAME])
+# ------------------------------
+m4_define([_LT_TAGVAR], [m4_ifval([$2], [$1_$2], [$1])])
+
+
+# _LT_CONFIG_COMMANDS
+# -------------------
+# Send accumulated output to $CONFIG_STATUS. Thanks to the lists of
+# variables for single and double quote escaping we saved from calls
+# to _LT_DECL, we can put quote escaped variables declarations
+# into `config.status', and then the shell code to quote escape them in
+# for loops in `config.status'. Finally, any additional code accumulated
+# from calls to _LT_CONFIG_LIBTOOL_INIT is expanded.
+m4_defun([_LT_CONFIG_COMMANDS],
+[AC_PROVIDE_IFELSE([LT_OUTPUT],
+ dnl If the libtool generation code has been placed in $CONFIG_LT,
+ dnl instead of duplicating it all over again into config.status,
+ dnl then we will have config.status run $CONFIG_LT later, so it
+ dnl needs to know what name is stored there:
+ [AC_CONFIG_COMMANDS([libtool],
+ [$SHELL $CONFIG_LT || AS_EXIT(1)], [CONFIG_LT='$CONFIG_LT'])],
+ dnl If the libtool generation code is destined for config.status,
+ dnl expand the accumulated commands and init code now:
+ [AC_CONFIG_COMMANDS([libtool],
+ [_LT_OUTPUT_LIBTOOL_COMMANDS], [_LT_OUTPUT_LIBTOOL_COMMANDS_INIT])])
+])#_LT_CONFIG_COMMANDS
+
+
+# Initialize.
+m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS_INIT],
+[
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+sed_quote_subst='$sed_quote_subst'
+double_quote_subst='$double_quote_subst'
+delay_variable_subst='$delay_variable_subst'
+_LT_CONFIG_STATUS_DECLARATIONS
+LTCC='$LTCC'
+LTCFLAGS='$LTCFLAGS'
+compiler='$compiler_DEFAULT'
+
+# Quote evaled strings.
+for var in lt_decl_all_varnames([[ \
+]], lt_decl_quote_varnames); do
+ case \`eval \\\\\$ECHO "X\\\\\$\$var"\` in
+ *[[\\\\\\\`\\"\\\$]]*)
+ eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"X\\\$\$var\\" | \\\$Xsed -e \\"\\\$sed_quote_subst\\"\\\`\\\\\\""
+ ;;
+ *)
+ eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\""
+ ;;
+ esac
+done
+
+# Double-quote double-evaled strings.
+for var in lt_decl_all_varnames([[ \
+]], lt_decl_dquote_varnames); do
+ case \`eval \\\\\$ECHO "X\\\\\$\$var"\` in
+ *[[\\\\\\\`\\"\\\$]]*)
+ eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"X\\\$\$var\\" | \\\$Xsed -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\""
+ ;;
+ *)
+ eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\""
+ ;;
+ esac
+done
+
+# Fix-up fallback echo if it was mangled by the above quoting rules.
+case \$lt_ECHO in
+*'\\\[$]0 --fallback-echo"')dnl "
+ lt_ECHO=\`\$ECHO "X\$lt_ECHO" | \$Xsed -e 's/\\\\\\\\\\\\\\\[$]0 --fallback-echo"\[$]/\[$]0 --fallback-echo"/'\`
+ ;;
+esac
+
+_LT_OUTPUT_LIBTOOL_INIT
+])
+
+
+# LT_OUTPUT
+# ---------
+# This macro allows early generation of the libtool script (before
+# AC_OUTPUT is called), incase it is used in configure for compilation
+# tests.
+AC_DEFUN([LT_OUTPUT],
+[: ${CONFIG_LT=./config.lt}
+AC_MSG_NOTICE([creating $CONFIG_LT])
+cat >"$CONFIG_LT" <<_LTEOF
+#! $SHELL
+# Generated by $as_me.
+# Run this file to recreate a libtool stub with the current configuration.
+
+lt_cl_silent=false
+SHELL=\${CONFIG_SHELL-$SHELL}
+_LTEOF
+
+cat >>"$CONFIG_LT" <<\_LTEOF
+AS_SHELL_SANITIZE
+_AS_PREPARE
+
+exec AS_MESSAGE_FD>&1
+exec AS_MESSAGE_LOG_FD>>config.log
+{
+ echo
+ AS_BOX([Running $as_me.])
+} >&AS_MESSAGE_LOG_FD
+
+lt_cl_help="\
+\`$as_me' creates a local libtool stub from the current configuration,
+for use in further configure time tests before the real libtool is
+generated.
+
+Usage: $[0] [[OPTIONS]]
+
+ -h, --help print this help, then exit
+ -V, --version print version number, then exit
+ -q, --quiet do not print progress messages
+ -d, --debug don't remove temporary files
+
+Report bugs to <bug-libtool@gnu.org>."
+
+lt_cl_version="\
+m4_ifset([AC_PACKAGE_NAME], [AC_PACKAGE_NAME ])config.lt[]dnl
+m4_ifset([AC_PACKAGE_VERSION], [ AC_PACKAGE_VERSION])
+configured by $[0], generated by m4_PACKAGE_STRING.
+
+Copyright (C) 2008 Free Software Foundation, Inc.
+This config.lt script is free software; the Free Software Foundation
+gives unlimited permision to copy, distribute and modify it."
+
+while test $[#] != 0
+do
+ case $[1] in
+ --version | --v* | -V )
+ echo "$lt_cl_version"; exit 0 ;;
+ --help | --h* | -h )
+ echo "$lt_cl_help"; exit 0 ;;
+ --debug | --d* | -d )
+ debug=: ;;
+ --quiet | --q* | --silent | --s* | -q )
+ lt_cl_silent=: ;;
+
+ -*) AC_MSG_ERROR([unrecognized option: $[1]
+Try \`$[0] --help' for more information.]) ;;
+
+ *) AC_MSG_ERROR([unrecognized argument: $[1]
+Try \`$[0] --help' for more information.]) ;;
+ esac
+ shift
+done
+
+if $lt_cl_silent; then
+ exec AS_MESSAGE_FD>/dev/null
+fi
+_LTEOF
+
+cat >>"$CONFIG_LT" <<_LTEOF
+_LT_OUTPUT_LIBTOOL_COMMANDS_INIT
+_LTEOF
+
+cat >>"$CONFIG_LT" <<\_LTEOF
+AC_MSG_NOTICE([creating $ofile])
+_LT_OUTPUT_LIBTOOL_COMMANDS
+AS_EXIT(0)
+_LTEOF
+chmod +x "$CONFIG_LT"
+
+# configure is writing to config.log, but config.lt does its own redirection,
+# appending to config.log, which fails on DOS, as config.log is still kept
+# open by configure. Here we exec the FD to /dev/null, effectively closing
+# config.log, so it can be properly (re)opened and appended to by config.lt.
+if test "$no_create" != yes; then
+ lt_cl_success=:
+ test "$silent" = yes &&
+ lt_config_lt_args="$lt_config_lt_args --quiet"
+ exec AS_MESSAGE_LOG_FD>/dev/null
+ $SHELL "$CONFIG_LT" $lt_config_lt_args || lt_cl_success=false
+ exec AS_MESSAGE_LOG_FD>>config.log
+ $lt_cl_success || AS_EXIT(1)
+fi
+])# LT_OUTPUT
+
+
+# _LT_CONFIG(TAG)
+# ---------------
+# If TAG is the built-in tag, create an initial libtool script with a
+# default configuration from the untagged config vars. Otherwise add code
+# to config.status for appending the configuration named by TAG from the
+# matching tagged config vars.
+m4_defun([_LT_CONFIG],
+[m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+_LT_CONFIG_SAVE_COMMANDS([
+ m4_define([_LT_TAG], m4_if([$1], [], [C], [$1]))dnl
+ m4_if(_LT_TAG, [C], [
+ # See if we are running on zsh, and set the options which allow our
+ # commands through without removal of \ escapes.
+ if test -n "${ZSH_VERSION+set}" ; then
+ setopt NO_GLOB_SUBST
+ fi
+
+ cfgfile="${ofile}T"
+ trap "$RM \"$cfgfile\"; exit 1" 1 2 15
+ $RM "$cfgfile"
+
+ cat <<_LT_EOF >> "$cfgfile"
+#! $SHELL
+
+# `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services.
+# Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $VERSION
+# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+# NOTE: Changes made to this file will be lost: look at ltmain.sh.
+#
+_LT_COPYING
+_LT_LIBTOOL_TAGS
+
+# ### BEGIN LIBTOOL CONFIG
+_LT_LIBTOOL_CONFIG_VARS
+_LT_LIBTOOL_TAG_VARS
+# ### END LIBTOOL CONFIG
+
+_LT_EOF
+
+ case $host_os in
+ aix3*)
+ cat <<\_LT_EOF >> "$cfgfile"
+# AIX sometimes has problems with the GCC collect2 program. For some
+# reason, if we set the COLLECT_NAMES environment variable, the problems
+# vanish in a puff of smoke.
+if test "X${COLLECT_NAMES+set}" != Xset; then
+ COLLECT_NAMES=
+ export COLLECT_NAMES
+fi
+_LT_EOF
+ ;;
+ esac
+
+ _LT_PROG_LTMAIN
+
+ # We use sed instead of cat because bash on DJGPP gets confused if
+ # if finds mixed CR/LF and LF-only lines. Since sed operates in
+ # text mode, it properly converts lines to CR/LF. This bash problem
+ # is reportedly fixed, but why not run on old versions too?
+ sed '/^# Generated shell functions inserted here/q' "$ltmain" >> "$cfgfile" \
+ || (rm -f "$cfgfile"; exit 1)
+
+ _LT_PROG_XSI_SHELLFNS
+
+ sed -n '/^# Generated shell functions inserted here/,$p' "$ltmain" >> "$cfgfile" \
+ || (rm -f "$cfgfile"; exit 1)
+
+ mv -f "$cfgfile" "$ofile" ||
+ (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile")
+ chmod +x "$ofile"
+],
+[cat <<_LT_EOF >> "$ofile"
+
+dnl Unfortunately we have to use $1 here, since _LT_TAG is not expanded
+dnl in a comment (ie after a #).
+# ### BEGIN LIBTOOL TAG CONFIG: $1
+_LT_LIBTOOL_TAG_VARS(_LT_TAG)
+# ### END LIBTOOL TAG CONFIG: $1
+_LT_EOF
+])dnl /m4_if
+],
+[m4_if([$1], [], [
+ PACKAGE='$PACKAGE'
+ VERSION='$VERSION'
+ TIMESTAMP='$TIMESTAMP'
+ RM='$RM'
+ ofile='$ofile'], [])
+])dnl /_LT_CONFIG_SAVE_COMMANDS
+])# _LT_CONFIG
+
+
+# LT_SUPPORTED_TAG(TAG)
+# ---------------------
+# Trace this macro to discover what tags are supported by the libtool
+# --tag option, using:
+# autoconf --trace 'LT_SUPPORTED_TAG:$1'
+AC_DEFUN([LT_SUPPORTED_TAG], [])
+
+
+# C support is built-in for now
+m4_define([_LT_LANG_C_enabled], [])
+m4_define([_LT_TAGS], [])
+
+
+# LT_LANG(LANG)
+# -------------
+# Enable libtool support for the given language if not already enabled.
+AC_DEFUN([LT_LANG],
+[AC_BEFORE([$0], [LT_OUTPUT])dnl
+m4_case([$1],
+ [C], [_LT_LANG(C)],
+ [C++], [_LT_LANG(CXX)],
+ [Java], [_LT_LANG(GCJ)],
+ [Fortran 77], [_LT_LANG(F77)],
+ [Fortran], [_LT_LANG(FC)],
+ [Windows Resource], [_LT_LANG(RC)],
+ [m4_ifdef([_LT_LANG_]$1[_CONFIG],
+ [_LT_LANG($1)],
+ [m4_fatal([$0: unsupported language: "$1"])])])dnl
+])# LT_LANG
+
+
+# _LT_LANG(LANGNAME)
+# ------------------
+m4_defun([_LT_LANG],
+[m4_ifdef([_LT_LANG_]$1[_enabled], [],
+ [LT_SUPPORTED_TAG([$1])dnl
+ m4_append([_LT_TAGS], [$1 ])dnl
+ m4_define([_LT_LANG_]$1[_enabled], [])dnl
+ _LT_LANG_$1_CONFIG($1)])dnl
+])# _LT_LANG
+
+
+# _LT_LANG_DEFAULT_CONFIG
+# -----------------------
+m4_defun([_LT_LANG_DEFAULT_CONFIG],
+[AC_PROVIDE_IFELSE([AC_PROG_CXX],
+ [LT_LANG(CXX)],
+ [m4_define([AC_PROG_CXX], defn([AC_PROG_CXX])[LT_LANG(CXX)])])
+
+AC_PROVIDE_IFELSE([AC_PROG_F77],
+ [LT_LANG(F77)],
+ [m4_define([AC_PROG_F77], defn([AC_PROG_F77])[LT_LANG(F77)])])
+
+AC_PROVIDE_IFELSE([AC_PROG_FC],
+ [LT_LANG(FC)],
+ [m4_define([AC_PROG_FC], defn([AC_PROG_FC])[LT_LANG(FC)])])
+
+dnl The call to [A][M_PROG_GCJ] is quoted like that to stop aclocal
+dnl pulling things in needlessly.
+AC_PROVIDE_IFELSE([AC_PROG_GCJ],
+ [LT_LANG(GCJ)],
+ [AC_PROVIDE_IFELSE([A][M_PROG_GCJ],
+ [LT_LANG(GCJ)],
+ [AC_PROVIDE_IFELSE([LT_PROG_GCJ],
+ [LT_LANG(GCJ)],
+ [m4_ifdef([AC_PROG_GCJ],
+ [m4_define([AC_PROG_GCJ], defn([AC_PROG_GCJ])[LT_LANG(GCJ)])])
+ m4_ifdef([A][M_PROG_GCJ],
+ [m4_define([A][M_PROG_GCJ], defn([A][M_PROG_GCJ])[LT_LANG(GCJ)])])
+ m4_ifdef([LT_PROG_GCJ],
+ [m4_define([LT_PROG_GCJ], defn([LT_PROG_GCJ])[LT_LANG(GCJ)])])])])])
+
+AC_PROVIDE_IFELSE([LT_PROG_RC],
+ [LT_LANG(RC)],
+ [m4_define([LT_PROG_RC], defn([LT_PROG_RC])[LT_LANG(RC)])])
+])# _LT_LANG_DEFAULT_CONFIG
+
+# Obsolete macros:
+AU_DEFUN([AC_LIBTOOL_CXX], [LT_LANG(C++)])
+AU_DEFUN([AC_LIBTOOL_F77], [LT_LANG(Fortran 77)])
+AU_DEFUN([AC_LIBTOOL_FC], [LT_LANG(Fortran)])
+AU_DEFUN([AC_LIBTOOL_GCJ], [LT_LANG(Java)])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_CXX], [])
+dnl AC_DEFUN([AC_LIBTOOL_F77], [])
+dnl AC_DEFUN([AC_LIBTOOL_FC], [])
+dnl AC_DEFUN([AC_LIBTOOL_GCJ], [])
+
+
+# _LT_TAG_COMPILER
+# ----------------
+m4_defun([_LT_TAG_COMPILER],
+[AC_REQUIRE([AC_PROG_CC])dnl
+
+_LT_DECL([LTCC], [CC], [1], [A C compiler])dnl
+_LT_DECL([LTCFLAGS], [CFLAGS], [1], [LTCC compiler flags])dnl
+_LT_TAGDECL([CC], [compiler], [1], [A language specific compiler])dnl
+_LT_TAGDECL([with_gcc], [GCC], [0], [Is the compiler the GNU compiler?])dnl
+
+# If no C compiler was specified, use CC.
+LTCC=${LTCC-"$CC"}
+
+# If no C compiler flags were specified, use CFLAGS.
+LTCFLAGS=${LTCFLAGS-"$CFLAGS"}
+
+# Allow CC to be a program name with arguments.
+compiler=$CC
+])# _LT_TAG_COMPILER
+
+
+# _LT_COMPILER_BOILERPLATE
+# ------------------------
+# Check for compiler boilerplate output or warnings with
+# the simple compiler test code.
+m4_defun([_LT_COMPILER_BOILERPLATE],
+[m4_require([_LT_DECL_SED])dnl
+ac_outfile=conftest.$ac_objext
+echo "$lt_simple_compile_test_code" >conftest.$ac_ext
+eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_compiler_boilerplate=`cat conftest.err`
+$RM conftest*
+])# _LT_COMPILER_BOILERPLATE
+
+
+# _LT_LINKER_BOILERPLATE
+# ----------------------
+# Check for linker boilerplate output or warnings with
+# the simple link test code.
+m4_defun([_LT_LINKER_BOILERPLATE],
+[m4_require([_LT_DECL_SED])dnl
+ac_outfile=conftest.$ac_objext
+echo "$lt_simple_link_test_code" >conftest.$ac_ext
+eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_linker_boilerplate=`cat conftest.err`
+$RM -r conftest*
+])# _LT_LINKER_BOILERPLATE
+
+# _LT_REQUIRED_DARWIN_CHECKS
+# -------------------------
+m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[
+ case $host_os in
+ rhapsody* | darwin*)
+ AC_CHECK_TOOL([DSYMUTIL], [dsymutil], [:])
+ AC_CHECK_TOOL([NMEDIT], [nmedit], [:])
+ AC_CHECK_TOOL([LIPO], [lipo], [:])
+ AC_CHECK_TOOL([OTOOL], [otool], [:])
+ AC_CHECK_TOOL([OTOOL64], [otool64], [:])
+ _LT_DECL([], [DSYMUTIL], [1],
+ [Tool to manipulate archived DWARF debug symbol files on Mac OS X])
+ _LT_DECL([], [NMEDIT], [1],
+ [Tool to change global to local symbols on Mac OS X])
+ _LT_DECL([], [LIPO], [1],
+ [Tool to manipulate fat objects and archives on Mac OS X])
+ _LT_DECL([], [OTOOL], [1],
+ [ldd/readelf like tool for Mach-O binaries on Mac OS X])
+ _LT_DECL([], [OTOOL64], [1],
+ [ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4])
+
+ AC_CACHE_CHECK([for -single_module linker flag],[lt_cv_apple_cc_single_mod],
+ [lt_cv_apple_cc_single_mod=no
+ if test -z "${LT_MULTI_MODULE}"; then
+ # By default we will add the -single_module flag. You can override
+ # by either setting the environment variable LT_MULTI_MODULE
+ # non-empty at configure time, or by adding -multi_module to the
+ # link flags.
+ rm -rf libconftest.dylib*
+ echo "int foo(void){return 1;}" > conftest.c
+ echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \
+-dynamiclib -Wl,-single_module conftest.c" >&AS_MESSAGE_LOG_FD
+ $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \
+ -dynamiclib -Wl,-single_module conftest.c 2>conftest.err
+ _lt_result=$?
+ if test -f libconftest.dylib && test ! -s conftest.err && test $_lt_result = 0; then
+ lt_cv_apple_cc_single_mod=yes
+ else
+ cat conftest.err >&AS_MESSAGE_LOG_FD
+ fi
+ rm -rf libconftest.dylib*
+ rm -f conftest.*
+ fi])
+ AC_CACHE_CHECK([for -exported_symbols_list linker flag],
+ [lt_cv_ld_exported_symbols_list],
+ [lt_cv_ld_exported_symbols_list=no
+ save_LDFLAGS=$LDFLAGS
+ echo "_main" > conftest.sym
+ LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym"
+ AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])],
+ [lt_cv_ld_exported_symbols_list=yes],
+ [lt_cv_ld_exported_symbols_list=no])
+ LDFLAGS="$save_LDFLAGS"
+ ])
+ case $host_os in
+ rhapsody* | darwin1.[[012]])
+ _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;;
+ darwin1.*)
+ _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;;
+ darwin*) # darwin 5.x on
+ # if running on 10.5 or later, the deployment target defaults
+ # to the OS version, if on x86, and 10.4, the deployment
+ # target defaults to 10.4. Don't you love it?
+ case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in
+ 10.0,*86*-darwin8*|10.0,*-darwin[[91]]*)
+ _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;;
+ 10.[[012]]*)
+ _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;;
+ 10.*)
+ _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;;
+ esac
+ ;;
+ esac
+ if test "$lt_cv_apple_cc_single_mod" = "yes"; then
+ _lt_dar_single_mod='$single_module'
+ fi
+ if test "$lt_cv_ld_exported_symbols_list" = "yes"; then
+ _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym'
+ else
+ _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}'
+ fi
+ if test "$DSYMUTIL" != ":"; then
+ _lt_dsymutil='~$DSYMUTIL $lib || :'
+ else
+ _lt_dsymutil=
+ fi
+ ;;
+ esac
+])
+
+
+# _LT_DARWIN_LINKER_FEATURES
+# --------------------------
+# Checks for linker and compiler features on darwin
+m4_defun([_LT_DARWIN_LINKER_FEATURES],
+[
+ m4_require([_LT_REQUIRED_DARWIN_CHECKS])
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+ _LT_TAGVAR(hardcode_direct, $1)=no
+ _LT_TAGVAR(hardcode_automatic, $1)=yes
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported
+ _LT_TAGVAR(whole_archive_flag_spec, $1)=''
+ _LT_TAGVAR(link_all_deplibs, $1)=yes
+ _LT_TAGVAR(allow_undefined_flag, $1)="$_lt_dar_allow_undefined"
+ case $cc_basename in
+ ifort*) _lt_dar_can_shared=yes ;;
+ *) _lt_dar_can_shared=$GCC ;;
+ esac
+ if test "$_lt_dar_can_shared" = "yes"; then
+ output_verbose_link_cmd=echo
+ _LT_TAGVAR(archive_cmds, $1)="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}"
+ _LT_TAGVAR(module_cmds, $1)="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}"
+ _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}"
+ _LT_TAGVAR(module_expsym_cmds, $1)="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}"
+ m4_if([$1], [CXX],
+[ if test "$lt_cv_apple_cc_single_mod" != "yes"; then
+ _LT_TAGVAR(archive_cmds, $1)="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dsymutil}"
+ _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dar_export_syms}${_lt_dsymutil}"
+ fi
+],[])
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+])
+
+# _LT_SYS_MODULE_PATH_AIX
+# -----------------------
+# Links a minimal program and checks the executable
+# for the system default hardcoded library path. In most cases,
+# this is /usr/lib:/lib, but when the MPI compilers are used
+# the location of the communication and MPI libs are included too.
+# If we don't find anything, use the default library path according
+# to the aix ld manual.
+m4_defun([_LT_SYS_MODULE_PATH_AIX],
+[m4_require([_LT_DECL_SED])dnl
+AC_LINK_IFELSE(AC_LANG_PROGRAM,[
+lt_aix_libpath_sed='
+ /Import File Strings/,/^$/ {
+ /^0/ {
+ s/^0 *\(.*\)$/\1/
+ p
+ }
+ }'
+aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+# Check for a 64-bit object if we didn't find anything.
+if test -z "$aix_libpath"; then
+ aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+fi],[])
+if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
+])# _LT_SYS_MODULE_PATH_AIX
+
+
+# _LT_SHELL_INIT(ARG)
+# -------------------
+m4_define([_LT_SHELL_INIT],
+[ifdef([AC_DIVERSION_NOTICE],
+ [AC_DIVERT_PUSH(AC_DIVERSION_NOTICE)],
+ [AC_DIVERT_PUSH(NOTICE)])
+$1
+AC_DIVERT_POP
+])# _LT_SHELL_INIT
+
+
+# _LT_PROG_ECHO_BACKSLASH
+# -----------------------
+# Add some code to the start of the generated configure script which
+# will find an echo command which doesn't interpret backslashes.
+m4_defun([_LT_PROG_ECHO_BACKSLASH],
+[_LT_SHELL_INIT([
+# Check that we are running under the correct shell.
+SHELL=${CONFIG_SHELL-/bin/sh}
+
+case X$lt_ECHO in
+X*--fallback-echo)
+ # Remove one level of quotation (which was required for Make).
+ ECHO=`echo "$lt_ECHO" | sed 's,\\\\\[$]\\[$]0,'[$]0','`
+ ;;
+esac
+
+ECHO=${lt_ECHO-echo}
+if test "X[$]1" = X--no-reexec; then
+ # Discard the --no-reexec flag, and continue.
+ shift
+elif test "X[$]1" = X--fallback-echo; then
+ # Avoid inline document here, it may be left over
+ :
+elif test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' ; then
+ # Yippee, $ECHO works!
+ :
+else
+ # Restart under the correct shell.
+ exec $SHELL "[$]0" --no-reexec ${1+"[$]@"}
+fi
+
+if test "X[$]1" = X--fallback-echo; then
+ # used as fallback echo
+ shift
+ cat <<_LT_EOF
+[$]*
+_LT_EOF
+ exit 0
+fi
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+if test -z "$lt_ECHO"; then
+ if test "X${echo_test_string+set}" != Xset; then
+ # find a string as large as possible, as long as the shell can cope with it
+ for cmd in 'sed 50q "[$]0"' 'sed 20q "[$]0"' 'sed 10q "[$]0"' 'sed 2q "[$]0"' 'echo test'; do
+ # expected sizes: less than 2Kb, 1Kb, 512 bytes, 16 bytes, ...
+ if { echo_test_string=`eval $cmd`; } 2>/dev/null &&
+ { test "X$echo_test_string" = "X$echo_test_string"; } 2>/dev/null
+ then
+ break
+ fi
+ done
+ fi
+
+ if test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' &&
+ echo_testing_string=`{ $ECHO "$echo_test_string"; } 2>/dev/null` &&
+ test "X$echo_testing_string" = "X$echo_test_string"; then
+ :
+ else
+ # The Solaris, AIX, and Digital Unix default echo programs unquote
+ # backslashes. This makes it impossible to quote backslashes using
+ # echo "$something" | sed 's/\\/\\\\/g'
+ #
+ # So, first we look for a working echo in the user's PATH.
+
+ lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+ for dir in $PATH /usr/ucb; do
+ IFS="$lt_save_ifs"
+ if (test -f $dir/echo || test -f $dir/echo$ac_exeext) &&
+ test "X`($dir/echo '\t') 2>/dev/null`" = 'X\t' &&
+ echo_testing_string=`($dir/echo "$echo_test_string") 2>/dev/null` &&
+ test "X$echo_testing_string" = "X$echo_test_string"; then
+ ECHO="$dir/echo"
+ break
+ fi
+ done
+ IFS="$lt_save_ifs"
+
+ if test "X$ECHO" = Xecho; then
+ # We didn't find a better echo, so look for alternatives.
+ if test "X`{ print -r '\t'; } 2>/dev/null`" = 'X\t' &&
+ echo_testing_string=`{ print -r "$echo_test_string"; } 2>/dev/null` &&
+ test "X$echo_testing_string" = "X$echo_test_string"; then
+ # This shell has a builtin print -r that does the trick.
+ ECHO='print -r'
+ elif { test -f /bin/ksh || test -f /bin/ksh$ac_exeext; } &&
+ test "X$CONFIG_SHELL" != X/bin/ksh; then
+ # If we have ksh, try running configure again with it.
+ ORIGINAL_CONFIG_SHELL=${CONFIG_SHELL-/bin/sh}
+ export ORIGINAL_CONFIG_SHELL
+ CONFIG_SHELL=/bin/ksh
+ export CONFIG_SHELL
+ exec $CONFIG_SHELL "[$]0" --no-reexec ${1+"[$]@"}
+ else
+ # Try using printf.
+ ECHO='printf %s\n'
+ if test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' &&
+ echo_testing_string=`{ $ECHO "$echo_test_string"; } 2>/dev/null` &&
+ test "X$echo_testing_string" = "X$echo_test_string"; then
+ # Cool, printf works
+ :
+ elif echo_testing_string=`($ORIGINAL_CONFIG_SHELL "[$]0" --fallback-echo '\t') 2>/dev/null` &&
+ test "X$echo_testing_string" = 'X\t' &&
+ echo_testing_string=`($ORIGINAL_CONFIG_SHELL "[$]0" --fallback-echo "$echo_test_string") 2>/dev/null` &&
+ test "X$echo_testing_string" = "X$echo_test_string"; then
+ CONFIG_SHELL=$ORIGINAL_CONFIG_SHELL
+ export CONFIG_SHELL
+ SHELL="$CONFIG_SHELL"
+ export SHELL
+ ECHO="$CONFIG_SHELL [$]0 --fallback-echo"
+ elif echo_testing_string=`($CONFIG_SHELL "[$]0" --fallback-echo '\t') 2>/dev/null` &&
+ test "X$echo_testing_string" = 'X\t' &&
+ echo_testing_string=`($CONFIG_SHELL "[$]0" --fallback-echo "$echo_test_string") 2>/dev/null` &&
+ test "X$echo_testing_string" = "X$echo_test_string"; then
+ ECHO="$CONFIG_SHELL [$]0 --fallback-echo"
+ else
+ # maybe with a smaller string...
+ prev=:
+
+ for cmd in 'echo test' 'sed 2q "[$]0"' 'sed 10q "[$]0"' 'sed 20q "[$]0"' 'sed 50q "[$]0"'; do
+ if { test "X$echo_test_string" = "X`eval $cmd`"; } 2>/dev/null
+ then
+ break
+ fi
+ prev="$cmd"
+ done
+
+ if test "$prev" != 'sed 50q "[$]0"'; then
+ echo_test_string=`eval $prev`
+ export echo_test_string
+ exec ${ORIGINAL_CONFIG_SHELL-${CONFIG_SHELL-/bin/sh}} "[$]0" ${1+"[$]@"}
+ else
+ # Oops. We lost completely, so just stick with echo.
+ ECHO=echo
+ fi
+ fi
+ fi
+ fi
+ fi
+fi
+
+# Copy echo and quote the copy suitably for passing to libtool from
+# the Makefile, instead of quoting the original, which is used later.
+lt_ECHO=$ECHO
+if test "X$lt_ECHO" = "X$CONFIG_SHELL [$]0 --fallback-echo"; then
+ lt_ECHO="$CONFIG_SHELL \\\$\[$]0 --fallback-echo"
+fi
+
+AC_SUBST(lt_ECHO)
+])
+_LT_DECL([], [SHELL], [1], [Shell to use when invoking shell scripts])
+_LT_DECL([], [ECHO], [1],
+ [An echo program that does not interpret backslashes])
+])# _LT_PROG_ECHO_BACKSLASH
+
+
+# _LT_ENABLE_LOCK
+# ---------------
+m4_defun([_LT_ENABLE_LOCK],
+[AC_ARG_ENABLE([libtool-lock],
+ [AS_HELP_STRING([--disable-libtool-lock],
+ [avoid locking (might break parallel builds)])])
+test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes
+
+# Some flags need to be propagated to the compiler or linker for good
+# libtool support.
+case $host in
+ia64-*-hpux*)
+ # Find out which ABI we are using.
+ echo 'int i;' > conftest.$ac_ext
+ if AC_TRY_EVAL(ac_compile); then
+ case `/usr/bin/file conftest.$ac_objext` in
+ *ELF-32*)
+ HPUX_IA64_MODE="32"
+ ;;
+ *ELF-64*)
+ HPUX_IA64_MODE="64"
+ ;;
+ esac
+ fi
+ rm -rf conftest*
+ ;;
+*-*-irix6*)
+ # Find out which ABI we are using.
+ echo '[#]line __oline__ "configure"' > conftest.$ac_ext
+ if AC_TRY_EVAL(ac_compile); then
+ if test "$lt_cv_prog_gnu_ld" = yes; then
+ case `/usr/bin/file conftest.$ac_objext` in
+ *32-bit*)
+ LD="${LD-ld} -melf32bsmip"
+ ;;
+ *N32*)
+ LD="${LD-ld} -melf32bmipn32"
+ ;;
+ *64-bit*)
+ LD="${LD-ld} -melf64bmip"
+ ;;
+ esac
+ else
+ case `/usr/bin/file conftest.$ac_objext` in
+ *32-bit*)
+ LD="${LD-ld} -32"
+ ;;
+ *N32*)
+ LD="${LD-ld} -n32"
+ ;;
+ *64-bit*)
+ LD="${LD-ld} -64"
+ ;;
+ esac
+ fi
+ fi
+ rm -rf conftest*
+ ;;
+
+x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \
+s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
+ # Find out which ABI we are using.
+ echo 'int i;' > conftest.$ac_ext
+ if AC_TRY_EVAL(ac_compile); then
+ case `/usr/bin/file conftest.o` in
+ *32-bit*)
+ case $host in
+ x86_64-*kfreebsd*-gnu)
+ LD="${LD-ld} -m elf_i386_fbsd"
+ ;;
+ x86_64-*linux*)
+ LD="${LD-ld} -m elf_i386"
+ ;;
+ ppc64-*linux*|powerpc64-*linux*)
+ LD="${LD-ld} -m elf32ppclinux"
+ ;;
+ s390x-*linux*)
+ LD="${LD-ld} -m elf_s390"
+ ;;
+ sparc64-*linux*)
+ LD="${LD-ld} -m elf32_sparc"
+ ;;
+ esac
+ ;;
+ *64-bit*)
+ case $host in
+ x86_64-*kfreebsd*-gnu)
+ LD="${LD-ld} -m elf_x86_64_fbsd"
+ ;;
+ x86_64-*linux*)
+ LD="${LD-ld} -m elf_x86_64"
+ ;;
+ ppc*-*linux*|powerpc*-*linux*)
+ LD="${LD-ld} -m elf64ppc"
+ ;;
+ s390*-*linux*|s390*-*tpf*)
+ LD="${LD-ld} -m elf64_s390"
+ ;;
+ sparc*-*linux*)
+ LD="${LD-ld} -m elf64_sparc"
+ ;;
+ esac
+ ;;
+ esac
+ fi
+ rm -rf conftest*
+ ;;
+
+*-*-sco3.2v5*)
+ # On SCO OpenServer 5, we need -belf to get full-featured binaries.
+ SAVE_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS -belf"
+ AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf,
+ [AC_LANG_PUSH(C)
+ AC_LINK_IFELSE([AC_LANG_PROGRAM([[]],[[]])],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no])
+ AC_LANG_POP])
+ if test x"$lt_cv_cc_needs_belf" != x"yes"; then
+ # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf
+ CFLAGS="$SAVE_CFLAGS"
+ fi
+ ;;
+sparc*-*solaris*)
+ # Find out which ABI we are using.
+ echo 'int i;' > conftest.$ac_ext
+ if AC_TRY_EVAL(ac_compile); then
+ case `/usr/bin/file conftest.o` in
+ *64-bit*)
+ case $lt_cv_prog_gnu_ld in
+ yes*) LD="${LD-ld} -m elf64_sparc" ;;
+ *)
+ if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then
+ LD="${LD-ld} -64"
+ fi
+ ;;
+ esac
+ ;;
+ esac
+ fi
+ rm -rf conftest*
+ ;;
+esac
+
+need_locks="$enable_libtool_lock"
+])# _LT_ENABLE_LOCK
+
+
+# _LT_CMD_OLD_ARCHIVE
+# -------------------
+m4_defun([_LT_CMD_OLD_ARCHIVE],
+[AC_CHECK_TOOL(AR, ar, false)
+test -z "$AR" && AR=ar
+test -z "$AR_FLAGS" && AR_FLAGS=cru
+_LT_DECL([], [AR], [1], [The archiver])
+_LT_DECL([], [AR_FLAGS], [1])
+
+AC_CHECK_TOOL(STRIP, strip, :)
+test -z "$STRIP" && STRIP=:
+_LT_DECL([], [STRIP], [1], [A symbol stripping program])
+
+AC_CHECK_TOOL(RANLIB, ranlib, :)
+test -z "$RANLIB" && RANLIB=:
+_LT_DECL([], [RANLIB], [1],
+ [Commands used to install an old-style archive])
+
+# Determine commands to create old-style static archives.
+old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs'
+old_postinstall_cmds='chmod 644 $oldlib'
+old_postuninstall_cmds=
+
+if test -n "$RANLIB"; then
+ case $host_os in
+ openbsd*)
+ old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$oldlib"
+ ;;
+ *)
+ old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$oldlib"
+ ;;
+ esac
+ old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib"
+fi
+_LT_DECL([], [old_postinstall_cmds], [2])
+_LT_DECL([], [old_postuninstall_cmds], [2])
+_LT_TAGDECL([], [old_archive_cmds], [2],
+ [Commands used to build an old-style archive])
+])# _LT_CMD_OLD_ARCHIVE
+
+
+# _LT_COMPILER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS,
+# [OUTPUT-FILE], [ACTION-SUCCESS], [ACTION-FAILURE])
+# ----------------------------------------------------------------
+# Check whether the given compiler option works
+AC_DEFUN([_LT_COMPILER_OPTION],
+[m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_DECL_SED])dnl
+AC_CACHE_CHECK([$1], [$2],
+ [$2=no
+ m4_if([$4], , [ac_outfile=conftest.$ac_objext], [ac_outfile=$4])
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+ lt_compiler_flag="$3"
+ # Insert the option either (1) after the last *FLAGS variable, or
+ # (2) before a word containing "conftest.", or (3) at the end.
+ # Note that $ac_compile itself does not contain backslashes and begins
+ # with a dollar sign (not a hyphen), so the echo should work correctly.
+ # The option is referenced via a variable to avoid confusing sed.
+ lt_compile=`echo "$ac_compile" | $SED \
+ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+ -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \
+ -e 's:$: $lt_compiler_flag:'`
+ (eval echo "\"\$as_me:__oline__: $lt_compile\"" >&AS_MESSAGE_LOG_FD)
+ (eval "$lt_compile" 2>conftest.err)
+ ac_status=$?
+ cat conftest.err >&AS_MESSAGE_LOG_FD
+ echo "$as_me:__oline__: \$? = $ac_status" >&AS_MESSAGE_LOG_FD
+ if (exit $ac_status) && test -s "$ac_outfile"; then
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings other than the usual output.
+ $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp
+ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+ if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
+ $2=yes
+ fi
+ fi
+ $RM conftest*
+])
+
+if test x"[$]$2" = xyes; then
+ m4_if([$5], , :, [$5])
+else
+ m4_if([$6], , :, [$6])
+fi
+])# _LT_COMPILER_OPTION
+
+# Old name:
+AU_ALIAS([AC_LIBTOOL_COMPILER_OPTION], [_LT_COMPILER_OPTION])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_COMPILER_OPTION], [])
+
+
+# _LT_LINKER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS,
+# [ACTION-SUCCESS], [ACTION-FAILURE])
+# ----------------------------------------------------
+# Check whether the given linker option works
+AC_DEFUN([_LT_LINKER_OPTION],
+[m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_DECL_SED])dnl
+AC_CACHE_CHECK([$1], [$2],
+ [$2=no
+ save_LDFLAGS="$LDFLAGS"
+ LDFLAGS="$LDFLAGS $3"
+ echo "$lt_simple_link_test_code" > conftest.$ac_ext
+ if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then
+ # The linker can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ if test -s conftest.err; then
+ # Append any errors to the config.log.
+ cat conftest.err 1>&AS_MESSAGE_LOG_FD
+ $ECHO "X$_lt_linker_boilerplate" | $Xsed -e '/^$/d' > conftest.exp
+ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+ if diff conftest.exp conftest.er2 >/dev/null; then
+ $2=yes
+ fi
+ else
+ $2=yes
+ fi
+ fi
+ $RM -r conftest*
+ LDFLAGS="$save_LDFLAGS"
+])
+
+if test x"[$]$2" = xyes; then
+ m4_if([$4], , :, [$4])
+else
+ m4_if([$5], , :, [$5])
+fi
+])# _LT_LINKER_OPTION
+
+# Old name:
+AU_ALIAS([AC_LIBTOOL_LINKER_OPTION], [_LT_LINKER_OPTION])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_LINKER_OPTION], [])
+
+
+# LT_CMD_MAX_LEN
+#---------------
+AC_DEFUN([LT_CMD_MAX_LEN],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+# find the maximum length of command line arguments
+AC_MSG_CHECKING([the maximum length of command line arguments])
+AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl
+ i=0
+ teststring="ABCD"
+
+ case $build_os in
+ msdosdjgpp*)
+ # On DJGPP, this test can blow up pretty badly due to problems in libc
+ # (any single argument exceeding 2000 bytes causes a buffer overrun
+ # during glob expansion). Even if it were fixed, the result of this
+ # check would be larger than it should be.
+ lt_cv_sys_max_cmd_len=12288; # 12K is about right
+ ;;
+
+ gnu*)
+ # Under GNU Hurd, this test is not required because there is
+ # no limit to the length of command line arguments.
+ # Libtool will interpret -1 as no limit whatsoever
+ lt_cv_sys_max_cmd_len=-1;
+ ;;
+
+ cygwin* | mingw* | cegcc*)
+ # On Win9x/ME, this test blows up -- it succeeds, but takes
+ # about 5 minutes as the teststring grows exponentially.
+ # Worse, since 9x/ME are not pre-emptively multitasking,
+ # you end up with a "frozen" computer, even though with patience
+ # the test eventually succeeds (with a max line length of 256k).
+ # Instead, let's just punt: use the minimum linelength reported by
+ # all of the supported platforms: 8192 (on NT/2K/XP).
+ lt_cv_sys_max_cmd_len=8192;
+ ;;
+
+ amigaos*)
+ # On AmigaOS with pdksh, this test takes hours, literally.
+ # So we just punt and use a minimum line length of 8192.
+ lt_cv_sys_max_cmd_len=8192;
+ ;;
+
+ netbsd* | freebsd* | openbsd* | darwin* | dragonfly*)
+ # This has been around since 386BSD, at least. Likely further.
+ if test -x /sbin/sysctl; then
+ lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax`
+ elif test -x /usr/sbin/sysctl; then
+ lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax`
+ else
+ lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs
+ fi
+ # And add a safety zone
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4`
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3`
+ ;;
+
+ interix*)
+ # We know the value 262144 and hardcode it with a safety zone (like BSD)
+ lt_cv_sys_max_cmd_len=196608
+ ;;
+
+ osf*)
+ # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure
+ # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not
+ # nice to cause kernel panics so lets avoid the loop below.
+ # First set a reasonable default.
+ lt_cv_sys_max_cmd_len=16384
+ #
+ if test -x /sbin/sysconfig; then
+ case `/sbin/sysconfig -q proc exec_disable_arg_limit` in
+ *1*) lt_cv_sys_max_cmd_len=-1 ;;
+ esac
+ fi
+ ;;
+ sco3.2v5*)
+ lt_cv_sys_max_cmd_len=102400
+ ;;
+ sysv5* | sco5v6* | sysv4.2uw2*)
+ kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null`
+ if test -n "$kargmax"; then
+ lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[[ ]]//'`
+ else
+ lt_cv_sys_max_cmd_len=32768
+ fi
+ ;;
+ *)
+ lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null`
+ if test -n "$lt_cv_sys_max_cmd_len"; then
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4`
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3`
+ else
+ # Make teststring a little bigger before we do anything with it.
+ # a 1K string should be a reasonable start.
+ for i in 1 2 3 4 5 6 7 8 ; do
+ teststring=$teststring$teststring
+ done
+ SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}}
+ # If test is not a shell built-in, we'll probably end up computing a
+ # maximum length that is only half of the actual maximum length, but
+ # we can't tell.
+ while { test "X"`$SHELL [$]0 --fallback-echo "X$teststring$teststring" 2>/dev/null` \
+ = "XX$teststring$teststring"; } >/dev/null 2>&1 &&
+ test $i != 17 # 1/2 MB should be enough
+ do
+ i=`expr $i + 1`
+ teststring=$teststring$teststring
+ done
+ # Only check the string length outside the loop.
+ lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1`
+ teststring=
+ # Add a significant safety factor because C++ compilers can tack on
+ # massive amounts of additional arguments before passing them to the
+ # linker. It appears as though 1/2 is a usable value.
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2`
+ fi
+ ;;
+ esac
+])
+if test -n $lt_cv_sys_max_cmd_len ; then
+ AC_MSG_RESULT($lt_cv_sys_max_cmd_len)
+else
+ AC_MSG_RESULT(none)
+fi
+max_cmd_len=$lt_cv_sys_max_cmd_len
+_LT_DECL([], [max_cmd_len], [0],
+ [What is the maximum length of a command?])
+])# LT_CMD_MAX_LEN
+
+# Old name:
+AU_ALIAS([AC_LIBTOOL_SYS_MAX_CMD_LEN], [LT_CMD_MAX_LEN])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_SYS_MAX_CMD_LEN], [])
+
+
+# _LT_HEADER_DLFCN
+# ----------------
+m4_defun([_LT_HEADER_DLFCN],
+[AC_CHECK_HEADERS([dlfcn.h], [], [], [AC_INCLUDES_DEFAULT])dnl
+])# _LT_HEADER_DLFCN
+
+
+# _LT_TRY_DLOPEN_SELF (ACTION-IF-TRUE, ACTION-IF-TRUE-W-USCORE,
+# ACTION-IF-FALSE, ACTION-IF-CROSS-COMPILING)
+# ----------------------------------------------------------------
+m4_defun([_LT_TRY_DLOPEN_SELF],
+[m4_require([_LT_HEADER_DLFCN])dnl
+if test "$cross_compiling" = yes; then :
+ [$4]
+else
+ lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
+ lt_status=$lt_dlunknown
+ cat > conftest.$ac_ext <<_LT_EOF
+[#line __oline__ "configure"
+#include "confdefs.h"
+
+#if HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
+#include <stdio.h>
+
+#ifdef RTLD_GLOBAL
+# define LT_DLGLOBAL RTLD_GLOBAL
+#else
+# ifdef DL_GLOBAL
+# define LT_DLGLOBAL DL_GLOBAL
+# else
+# define LT_DLGLOBAL 0
+# endif
+#endif
+
+/* We may have to define LT_DLLAZY_OR_NOW in the command line if we
+ find out it does not work in some platform. */
+#ifndef LT_DLLAZY_OR_NOW
+# ifdef RTLD_LAZY
+# define LT_DLLAZY_OR_NOW RTLD_LAZY
+# else
+# ifdef DL_LAZY
+# define LT_DLLAZY_OR_NOW DL_LAZY
+# else
+# ifdef RTLD_NOW
+# define LT_DLLAZY_OR_NOW RTLD_NOW
+# else
+# ifdef DL_NOW
+# define LT_DLLAZY_OR_NOW DL_NOW
+# else
+# define LT_DLLAZY_OR_NOW 0
+# endif
+# endif
+# endif
+# endif
+#endif
+
+void fnord() { int i=42;}
+int main ()
+{
+ void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
+ int status = $lt_dlunknown;
+
+ if (self)
+ {
+ if (dlsym (self,"fnord")) status = $lt_dlno_uscore;
+ else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore;
+ /* dlclose (self); */
+ }
+ else
+ puts (dlerror ());
+
+ return status;
+}]
+_LT_EOF
+ if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext} 2>/dev/null; then
+ (./conftest; exit; ) >&AS_MESSAGE_LOG_FD 2>/dev/null
+ lt_status=$?
+ case x$lt_status in
+ x$lt_dlno_uscore) $1 ;;
+ x$lt_dlneed_uscore) $2 ;;
+ x$lt_dlunknown|x*) $3 ;;
+ esac
+ else :
+ # compilation failed
+ $3
+ fi
+fi
+rm -fr conftest*
+])# _LT_TRY_DLOPEN_SELF
+
+
+# LT_SYS_DLOPEN_SELF
+# ------------------
+AC_DEFUN([LT_SYS_DLOPEN_SELF],
+[m4_require([_LT_HEADER_DLFCN])dnl
+if test "x$enable_dlopen" != xyes; then
+ enable_dlopen=unknown
+ enable_dlopen_self=unknown
+ enable_dlopen_self_static=unknown
+else
+ lt_cv_dlopen=no
+ lt_cv_dlopen_libs=
+
+ case $host_os in
+ beos*)
+ lt_cv_dlopen="load_add_on"
+ lt_cv_dlopen_libs=
+ lt_cv_dlopen_self=yes
+ ;;
+
+ mingw* | pw32* | cegcc*)
+ lt_cv_dlopen="LoadLibrary"
+ lt_cv_dlopen_libs=
+ ;;
+
+ cygwin*)
+ lt_cv_dlopen="dlopen"
+ lt_cv_dlopen_libs=
+ ;;
+
+ darwin*)
+ # if libdl is installed we need to link against it
+ AC_CHECK_LIB([dl], [dlopen],
+ [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"],[
+ lt_cv_dlopen="dyld"
+ lt_cv_dlopen_libs=
+ lt_cv_dlopen_self=yes
+ ])
+ ;;
+
+ *)
+ AC_CHECK_FUNC([shl_load],
+ [lt_cv_dlopen="shl_load"],
+ [AC_CHECK_LIB([dld], [shl_load],
+ [lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld"],
+ [AC_CHECK_FUNC([dlopen],
+ [lt_cv_dlopen="dlopen"],
+ [AC_CHECK_LIB([dl], [dlopen],
+ [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"],
+ [AC_CHECK_LIB([svld], [dlopen],
+ [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"],
+ [AC_CHECK_LIB([dld], [dld_link],
+ [lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld"])
+ ])
+ ])
+ ])
+ ])
+ ])
+ ;;
+ esac
+
+ if test "x$lt_cv_dlopen" != xno; then
+ enable_dlopen=yes
+ else
+ enable_dlopen=no
+ fi
+
+ case $lt_cv_dlopen in
+ dlopen)
+ save_CPPFLAGS="$CPPFLAGS"
+ test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H"
+
+ save_LDFLAGS="$LDFLAGS"
+ wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\"
+
+ save_LIBS="$LIBS"
+ LIBS="$lt_cv_dlopen_libs $LIBS"
+
+ AC_CACHE_CHECK([whether a program can dlopen itself],
+ lt_cv_dlopen_self, [dnl
+ _LT_TRY_DLOPEN_SELF(
+ lt_cv_dlopen_self=yes, lt_cv_dlopen_self=yes,
+ lt_cv_dlopen_self=no, lt_cv_dlopen_self=cross)
+ ])
+
+ if test "x$lt_cv_dlopen_self" = xyes; then
+ wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\"
+ AC_CACHE_CHECK([whether a statically linked program can dlopen itself],
+ lt_cv_dlopen_self_static, [dnl
+ _LT_TRY_DLOPEN_SELF(
+ lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=yes,
+ lt_cv_dlopen_self_static=no, lt_cv_dlopen_self_static=cross)
+ ])
+ fi
+
+ CPPFLAGS="$save_CPPFLAGS"
+ LDFLAGS="$save_LDFLAGS"
+ LIBS="$save_LIBS"
+ ;;
+ esac
+
+ case $lt_cv_dlopen_self in
+ yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;;
+ *) enable_dlopen_self=unknown ;;
+ esac
+
+ case $lt_cv_dlopen_self_static in
+ yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;;
+ *) enable_dlopen_self_static=unknown ;;
+ esac
+fi
+_LT_DECL([dlopen_support], [enable_dlopen], [0],
+ [Whether dlopen is supported])
+_LT_DECL([dlopen_self], [enable_dlopen_self], [0],
+ [Whether dlopen of programs is supported])
+_LT_DECL([dlopen_self_static], [enable_dlopen_self_static], [0],
+ [Whether dlopen of statically linked programs is supported])
+])# LT_SYS_DLOPEN_SELF
+
+# Old name:
+AU_ALIAS([AC_LIBTOOL_DLOPEN_SELF], [LT_SYS_DLOPEN_SELF])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_DLOPEN_SELF], [])
+
+
+# _LT_COMPILER_C_O([TAGNAME])
+# ---------------------------
+# Check to see if options -c and -o are simultaneously supported by compiler.
+# This macro does not hard code the compiler like AC_PROG_CC_C_O.
+m4_defun([_LT_COMPILER_C_O],
+[m4_require([_LT_DECL_SED])dnl
+m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_TAG_COMPILER])dnl
+AC_CACHE_CHECK([if $compiler supports -c -o file.$ac_objext],
+ [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)],
+ [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=no
+ $RM -r conftest 2>/dev/null
+ mkdir conftest
+ cd conftest
+ mkdir out
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+ lt_compiler_flag="-o out/conftest2.$ac_objext"
+ # Insert the option either (1) after the last *FLAGS variable, or
+ # (2) before a word containing "conftest.", or (3) at the end.
+ # Note that $ac_compile itself does not contain backslashes and begins
+ # with a dollar sign (not a hyphen), so the echo should work correctly.
+ lt_compile=`echo "$ac_compile" | $SED \
+ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+ -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \
+ -e 's:$: $lt_compiler_flag:'`
+ (eval echo "\"\$as_me:__oline__: $lt_compile\"" >&AS_MESSAGE_LOG_FD)
+ (eval "$lt_compile" 2>out/conftest.err)
+ ac_status=$?
+ cat out/conftest.err >&AS_MESSAGE_LOG_FD
+ echo "$as_me:__oline__: \$? = $ac_status" >&AS_MESSAGE_LOG_FD
+ if (exit $ac_status) && test -s out/conftest2.$ac_objext
+ then
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp
+ $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
+ if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
+ _LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes
+ fi
+ fi
+ chmod u+w . 2>&AS_MESSAGE_LOG_FD
+ $RM conftest*
+ # SGI C++ compiler will create directory out/ii_files/ for
+ # template instantiation
+ test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files
+ $RM out/* && rmdir out
+ cd ..
+ $RM -r conftest
+ $RM conftest*
+])
+_LT_TAGDECL([compiler_c_o], [lt_cv_prog_compiler_c_o], [1],
+ [Does compiler simultaneously support -c and -o options?])
+])# _LT_COMPILER_C_O
+
+
+# _LT_COMPILER_FILE_LOCKS([TAGNAME])
+# ----------------------------------
+# Check to see if we can do hard links to lock some files if needed
+m4_defun([_LT_COMPILER_FILE_LOCKS],
+[m4_require([_LT_ENABLE_LOCK])dnl
+m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+_LT_COMPILER_C_O([$1])
+
+hard_links="nottested"
+if test "$_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)" = no && test "$need_locks" != no; then
+ # do not overwrite the value of need_locks provided by the user
+ AC_MSG_CHECKING([if we can lock with hard links])
+ hard_links=yes
+ $RM conftest*
+ ln conftest.a conftest.b 2>/dev/null && hard_links=no
+ touch conftest.a
+ ln conftest.a conftest.b 2>&5 || hard_links=no
+ ln conftest.a conftest.b 2>/dev/null && hard_links=no
+ AC_MSG_RESULT([$hard_links])
+ if test "$hard_links" = no; then
+ AC_MSG_WARN([`$CC' does not support `-c -o', so `make -j' may be unsafe])
+ need_locks=warn
+ fi
+else
+ need_locks=no
+fi
+_LT_DECL([], [need_locks], [1], [Must we lock files when doing compilation?])
+])# _LT_COMPILER_FILE_LOCKS
+
+
+# _LT_CHECK_OBJDIR
+# ----------------
+m4_defun([_LT_CHECK_OBJDIR],
+[AC_CACHE_CHECK([for objdir], [lt_cv_objdir],
+[rm -f .libs 2>/dev/null
+mkdir .libs 2>/dev/null
+if test -d .libs; then
+ lt_cv_objdir=.libs
+else
+ # MS-DOS does not allow filenames that begin with a dot.
+ lt_cv_objdir=_libs
+fi
+rmdir .libs 2>/dev/null])
+objdir=$lt_cv_objdir
+_LT_DECL([], [objdir], [0],
+ [The name of the directory that contains temporary libtool files])dnl
+m4_pattern_allow([LT_OBJDIR])dnl
+AC_DEFINE_UNQUOTED(LT_OBJDIR, "$lt_cv_objdir/",
+ [Define to the sub-directory in which libtool stores uninstalled libraries.])
+])# _LT_CHECK_OBJDIR
+
+
+# _LT_LINKER_HARDCODE_LIBPATH([TAGNAME])
+# --------------------------------------
+# Check hardcoding attributes.
+m4_defun([_LT_LINKER_HARDCODE_LIBPATH],
+[AC_MSG_CHECKING([how to hardcode library paths into programs])
+_LT_TAGVAR(hardcode_action, $1)=
+if test -n "$_LT_TAGVAR(hardcode_libdir_flag_spec, $1)" ||
+ test -n "$_LT_TAGVAR(runpath_var, $1)" ||
+ test "X$_LT_TAGVAR(hardcode_automatic, $1)" = "Xyes" ; then
+
+ # We can hardcode non-existent directories.
+ if test "$_LT_TAGVAR(hardcode_direct, $1)" != no &&
+ # If the only mechanism to avoid hardcoding is shlibpath_var, we
+ # have to relink, otherwise we might link with an installed library
+ # when we should be linking with a yet-to-be-installed one
+ ## test "$_LT_TAGVAR(hardcode_shlibpath_var, $1)" != no &&
+ test "$_LT_TAGVAR(hardcode_minus_L, $1)" != no; then
+ # Linking always hardcodes the temporary library directory.
+ _LT_TAGVAR(hardcode_action, $1)=relink
+ else
+ # We can link without hardcoding, and we can hardcode nonexisting dirs.
+ _LT_TAGVAR(hardcode_action, $1)=immediate
+ fi
+else
+ # We cannot hardcode anything, or else we can only hardcode existing
+ # directories.
+ _LT_TAGVAR(hardcode_action, $1)=unsupported
+fi
+AC_MSG_RESULT([$_LT_TAGVAR(hardcode_action, $1)])
+
+if test "$_LT_TAGVAR(hardcode_action, $1)" = relink ||
+ test "$_LT_TAGVAR(inherit_rpath, $1)" = yes; then
+ # Fast installation is not supported
+ enable_fast_install=no
+elif test "$shlibpath_overrides_runpath" = yes ||
+ test "$enable_shared" = no; then
+ # Fast installation is not necessary
+ enable_fast_install=needless
+fi
+_LT_TAGDECL([], [hardcode_action], [0],
+ [How to hardcode a shared library path into an executable])
+])# _LT_LINKER_HARDCODE_LIBPATH
+
+
+# _LT_CMD_STRIPLIB
+# ----------------
+m4_defun([_LT_CMD_STRIPLIB],
+[m4_require([_LT_DECL_EGREP])
+striplib=
+old_striplib=
+AC_MSG_CHECKING([whether stripping libraries is possible])
+if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then
+ test -z "$old_striplib" && old_striplib="$STRIP --strip-debug"
+ test -z "$striplib" && striplib="$STRIP --strip-unneeded"
+ AC_MSG_RESULT([yes])
+else
+# FIXME - insert some real tests, host_os isn't really good enough
+ case $host_os in
+ darwin*)
+ if test -n "$STRIP" ; then
+ striplib="$STRIP -x"
+ old_striplib="$STRIP -S"
+ AC_MSG_RESULT([yes])
+ else
+ AC_MSG_RESULT([no])
+ fi
+ ;;
+ *)
+ AC_MSG_RESULT([no])
+ ;;
+ esac
+fi
+_LT_DECL([], [old_striplib], [1], [Commands to strip libraries])
+_LT_DECL([], [striplib], [1])
+])# _LT_CMD_STRIPLIB
+
+
+# _LT_SYS_DYNAMIC_LINKER([TAG])
+# -----------------------------
+# PORTME Fill in your ld.so characteristics
+m4_defun([_LT_SYS_DYNAMIC_LINKER],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+m4_require([_LT_DECL_EGREP])dnl
+m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_DECL_OBJDUMP])dnl
+m4_require([_LT_DECL_SED])dnl
+AC_MSG_CHECKING([dynamic linker characteristics])
+m4_if([$1],
+ [], [
+if test "$GCC" = yes; then
+ case $host_os in
+ darwin*) lt_awk_arg="/^libraries:/,/LR/" ;;
+ *) lt_awk_arg="/^libraries:/" ;;
+ esac
+ lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e "s,=/,/,g"`
+ if $ECHO "$lt_search_path_spec" | $GREP ';' >/dev/null ; then
+ # if the path contains ";" then we assume it to be the separator
+ # otherwise default to the standard path separator (i.e. ":") - it is
+ # assumed that no part of a normal pathname contains ";" but that should
+ # okay in the real world where ";" in dirpaths is itself problematic.
+ lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED -e 's/;/ /g'`
+ else
+ lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
+ fi
+ # Ok, now we have the path, separated by spaces, we can step through it
+ # and add multilib dir if necessary.
+ lt_tmp_lt_search_path_spec=
+ lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null`
+ for lt_sys_path in $lt_search_path_spec; do
+ if test -d "$lt_sys_path/$lt_multi_os_dir"; then
+ lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir"
+ else
+ test -d "$lt_sys_path" && \
+ lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path"
+ fi
+ done
+ lt_search_path_spec=`$ECHO $lt_tmp_lt_search_path_spec | awk '
+BEGIN {RS=" "; FS="/|\n";} {
+ lt_foo="";
+ lt_count=0;
+ for (lt_i = NF; lt_i > 0; lt_i--) {
+ if ($lt_i != "" && $lt_i != ".") {
+ if ($lt_i == "..") {
+ lt_count++;
+ } else {
+ if (lt_count == 0) {
+ lt_foo="/" $lt_i lt_foo;
+ } else {
+ lt_count--;
+ }
+ }
+ }
+ }
+ if (lt_foo != "") { lt_freq[[lt_foo]]++; }
+ if (lt_freq[[lt_foo]] == 1) { print lt_foo; }
+}'`
+ sys_lib_search_path_spec=`$ECHO $lt_search_path_spec`
+else
+ sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib"
+fi])
+library_names_spec=
+libname_spec='lib$name'
+soname_spec=
+shrext_cmds=".so"
+postinstall_cmds=
+postuninstall_cmds=
+finish_cmds=
+finish_eval=
+shlibpath_var=
+shlibpath_overrides_runpath=unknown
+version_type=none
+dynamic_linker="$host_os ld.so"
+sys_lib_dlsearch_path_spec="/lib /usr/lib"
+need_lib_prefix=unknown
+hardcode_into_libs=no
+
+# when you set need_version to no, make sure it does not cause -set_version
+# flags to be left without arguments
+need_version=unknown
+
+case $host_os in
+aix3*)
+ version_type=linux
+ library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a'
+ shlibpath_var=LIBPATH
+
+ # AIX 3 has no versioning support, so we append a major version to the name.
+ soname_spec='${libname}${release}${shared_ext}$major'
+ ;;
+
+aix[[4-9]]*)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ hardcode_into_libs=yes
+ if test "$host_cpu" = ia64; then
+ # AIX 5 supports IA64
+ library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}'
+ shlibpath_var=LD_LIBRARY_PATH
+ else
+ # With GCC up to 2.95.x, collect2 would create an import file
+ # for dependence libraries. The import file would start with
+ # the line `#! .'. This would cause the generated library to
+ # depend on `.', always an invalid library. This was fixed in
+ # development snapshots of GCC prior to 3.0.
+ case $host_os in
+ aix4 | aix4.[[01]] | aix4.[[01]].*)
+ if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)'
+ echo ' yes '
+ echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then
+ :
+ else
+ can_build_shared=no
+ fi
+ ;;
+ esac
+ # AIX (on Power*) has no versioning support, so currently we can not hardcode correct
+ # soname into executable. Probably we can add versioning support to
+ # collect2, so additional links can be useful in future.
+ if test "$aix_use_runtimelinking" = yes; then
+ # If using run time linking (on AIX 4.2 or later) use lib<name>.so
+ # instead of lib<name>.a to let people know that these are not
+ # typical AIX shared libraries.
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ else
+ # We preserve .a as extension for shared libraries through AIX4.2
+ # and later when we are not doing run time linking.
+ library_names_spec='${libname}${release}.a $libname.a'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ fi
+ shlibpath_var=LIBPATH
+ fi
+ ;;
+
+amigaos*)
+ case $host_cpu in
+ powerpc)
+ # Since July 2007 AmigaOS4 officially supports .so libraries.
+ # When compiling the executable, add -use-dynld -Lsobjs: to the compileline.
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ ;;
+ m68k)
+ library_names_spec='$libname.ixlibrary $libname.a'
+ # Create ${libname}_ixlibrary.a entries in /sys/libs.
+ finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$ECHO "X$lib" | $Xsed -e '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done'
+ ;;
+ esac
+ ;;
+
+beos*)
+ library_names_spec='${libname}${shared_ext}'
+ dynamic_linker="$host_os ld.so"
+ shlibpath_var=LIBRARY_PATH
+ ;;
+
+bsdi[[45]]*)
+ version_type=linux
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib"
+ sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib"
+ # the default ld.so.conf also contains /usr/contrib/lib and
+ # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow
+ # libtool to hard-code these into programs
+ ;;
+
+cygwin* | mingw* | pw32* | cegcc*)
+ version_type=windows
+ shrext_cmds=".dll"
+ need_version=no
+ need_lib_prefix=no
+
+ case $GCC,$host_os in
+ yes,cygwin* | yes,mingw* | yes,pw32* | yes,cegcc*)
+ library_names_spec='$libname.dll.a'
+ # DLL is installed to $(libdir)/../bin by postinstall_cmds
+ postinstall_cmds='base_file=`basename \${file}`~
+ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~
+ dldir=$destdir/`dirname \$dlpath`~
+ test -d \$dldir || mkdir -p \$dldir~
+ $install_prog $dir/$dlname \$dldir/$dlname~
+ chmod a+x \$dldir/$dlname~
+ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then
+ eval '\''$striplib \$dldir/$dlname'\'' || exit \$?;
+ fi'
+ postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
+ dlpath=$dir/\$dldll~
+ $RM \$dlpath'
+ shlibpath_overrides_runpath=yes
+
+ case $host_os in
+ cygwin*)
+ # Cygwin DLLs use 'cyg' prefix rather than 'lib'
+ soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}'
+ sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib"
+ ;;
+ mingw* | cegcc*)
+ # MinGW DLLs use traditional 'lib' prefix
+ soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}'
+ sys_lib_search_path_spec=`$CC -print-search-dirs | $GREP "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"`
+ if $ECHO "$sys_lib_search_path_spec" | [$GREP ';[c-zC-Z]:/' >/dev/null]; then
+ # It is most probably a Windows format PATH printed by
+ # mingw gcc, but we are running on Cygwin. Gcc prints its search
+ # path with ; separators, and with drive letters. We can handle the
+ # drive letters (cygwin fileutils understands them), so leave them,
+ # especially as we might pass files found there to a mingw objdump,
+ # which wouldn't understand a cygwinified path. Ahh.
+ sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`
+ else
+ sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
+ fi
+ ;;
+ pw32*)
+ # pw32 DLLs use 'pw' prefix rather than 'lib'
+ library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}'
+ ;;
+ esac
+ ;;
+
+ *)
+ library_names_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext} $libname.lib'
+ ;;
+ esac
+ dynamic_linker='Win32 ld.exe'
+ # FIXME: first we should search . and the directory the executable is in
+ shlibpath_var=PATH
+ ;;
+
+darwin* | rhapsody*)
+ dynamic_linker="$host_os dyld"
+ version_type=darwin
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext'
+ soname_spec='${libname}${release}${major}$shared_ext'
+ shlibpath_overrides_runpath=yes
+ shlibpath_var=DYLD_LIBRARY_PATH
+ shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`'
+m4_if([$1], [],[
+ sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib"])
+ sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib'
+ ;;
+
+dgux*)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ ;;
+
+freebsd1*)
+ dynamic_linker=no
+ ;;
+
+freebsd* | dragonfly*)
+ # DragonFly does not have aout. When/if they implement a new
+ # versioning mechanism, adjust this.
+ if test -x /usr/bin/objformat; then
+ objformat=`/usr/bin/objformat`
+ else
+ case $host_os in
+ freebsd[[123]]*) objformat=aout ;;
+ *) objformat=elf ;;
+ esac
+ fi
+ version_type=freebsd-$objformat
+ case $version_type in
+ freebsd-elf*)
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
+ need_version=no
+ need_lib_prefix=no
+ ;;
+ freebsd-*)
+ library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix'
+ need_version=yes
+ ;;
+ esac
+ shlibpath_var=LD_LIBRARY_PATH
+ case $host_os in
+ freebsd2*)
+ shlibpath_overrides_runpath=yes
+ ;;
+ freebsd3.[[01]]* | freebsdelf3.[[01]]*)
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ ;;
+ freebsd3.[[2-9]]* | freebsdelf3.[[2-9]]* | \
+ freebsd4.[[0-5]] | freebsdelf4.[[0-5]] | freebsd4.1.1 | freebsdelf4.1.1)
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ ;;
+ *) # from 4.6 on, and DragonFly
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ ;;
+ esac
+ ;;
+
+gnu*)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ hardcode_into_libs=yes
+ ;;
+
+hpux9* | hpux10* | hpux11*)
+ # Give a soname corresponding to the major version so that dld.sl refuses to
+ # link against other versions.
+ version_type=sunos
+ need_lib_prefix=no
+ need_version=no
+ case $host_cpu in
+ ia64*)
+ shrext_cmds='.so'
+ hardcode_into_libs=yes
+ dynamic_linker="$host_os dld.so"
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ if test "X$HPUX_IA64_MODE" = X32; then
+ sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib"
+ else
+ sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64"
+ fi
+ sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+ ;;
+ hppa*64*)
+ shrext_cmds='.sl'
+ hardcode_into_libs=yes
+ dynamic_linker="$host_os dld.sl"
+ shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH
+ shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64"
+ sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+ ;;
+ *)
+ shrext_cmds='.sl'
+ dynamic_linker="$host_os dld.sl"
+ shlibpath_var=SHLIB_PATH
+ shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ ;;
+ esac
+ # HP-UX runs *really* slowly unless shared libraries are mode 555.
+ postinstall_cmds='chmod 555 $lib'
+ ;;
+
+interix[[3-9]]*)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ ;;
+
+irix5* | irix6* | nonstopux*)
+ case $host_os in
+ nonstopux*) version_type=nonstopux ;;
+ *)
+ if test "$lt_cv_prog_gnu_ld" = yes; then
+ version_type=linux
+ else
+ version_type=irix
+ fi ;;
+ esac
+ need_lib_prefix=no
+ need_version=no
+ soname_spec='${libname}${release}${shared_ext}$major'
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}'
+ case $host_os in
+ irix5* | nonstopux*)
+ libsuff= shlibsuff=
+ ;;
+ *)
+ case $LD in # libtool.m4 will add one of these switches to LD
+ *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ")
+ libsuff= shlibsuff= libmagic=32-bit;;
+ *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ")
+ libsuff=32 shlibsuff=N32 libmagic=N32;;
+ *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ")
+ libsuff=64 shlibsuff=64 libmagic=64-bit;;
+ *) libsuff= shlibsuff= libmagic=never-match;;
+ esac
+ ;;
+ esac
+ shlibpath_var=LD_LIBRARY${shlibsuff}_PATH
+ shlibpath_overrides_runpath=no
+ sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}"
+ sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}"
+ hardcode_into_libs=yes
+ ;;
+
+# No shared lib support for Linux oldld, aout, or coff.
+linux*oldld* | linux*aout* | linux*coff*)
+ dynamic_linker=no
+ ;;
+
+# This must be Linux ELF.
+linux* | k*bsd*-gnu | kopensolaris*-gnu)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ # Some binutils ld are patched to set DT_RUNPATH
+ save_LDFLAGS=$LDFLAGS
+ save_libdir=$libdir
+ eval "libdir=/foo; wl=\"$_LT_TAGVAR(lt_prog_compiler_wl, $1)\"; \
+ LDFLAGS=\"\$LDFLAGS $_LT_TAGVAR(hardcode_libdir_flag_spec, $1)\""
+ AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])],
+ [AS_IF([ ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null],
+ [shlibpath_overrides_runpath=yes])])
+ LDFLAGS=$save_LDFLAGS
+ libdir=$save_libdir
+
+ # This implies no fast_install, which is unacceptable.
+ # Some rework will be needed to allow for fast_install
+ # before this can be enabled.
+ hardcode_into_libs=yes
+
+ # Append ld.so.conf contents to the search path
+ if test -f /etc/ld.so.conf; then
+ lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \[$]2)); skip = 1; } { if (!skip) print \[$]0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '`
+ sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra"
+ fi
+
+ # We used to test for /lib/ld.so.1 and disable shared libraries on
+ # powerpc, because MkLinux only supported shared libraries with the
+ # GNU dynamic linker. Since this was broken with cross compilers,
+ # most powerpc-linux boxes support dynamic linking these days and
+ # people can always --disable-shared, the test was removed, and we
+ # assume the GNU/Linux dynamic linker is in use.
+ dynamic_linker='GNU/Linux ld.so'
+ ;;
+
+netbsdelf*-gnu)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ dynamic_linker='NetBSD ld.elf_so'
+ ;;
+
+netbsd*)
+ version_type=sunos
+ need_lib_prefix=no
+ need_version=no
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+ dynamic_linker='NetBSD (a.out) ld.so'
+ else
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ dynamic_linker='NetBSD ld.elf_so'
+ fi
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ ;;
+
+newsos6)
+ version_type=linux
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ ;;
+
+*nto* | *qnx*)
+ version_type=qnx
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ dynamic_linker='ldqnx.so'
+ ;;
+
+openbsd*)
+ version_type=sunos
+ sys_lib_dlsearch_path_spec="/usr/lib"
+ need_lib_prefix=no
+ # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs.
+ case $host_os in
+ openbsd3.3 | openbsd3.3.*) need_version=yes ;;
+ *) need_version=no ;;
+ esac
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+ case $host_os in
+ openbsd2.[[89]] | openbsd2.[[89]].*)
+ shlibpath_overrides_runpath=no
+ ;;
+ *)
+ shlibpath_overrides_runpath=yes
+ ;;
+ esac
+ else
+ shlibpath_overrides_runpath=yes
+ fi
+ ;;
+
+os2*)
+ libname_spec='$name'
+ shrext_cmds=".dll"
+ need_lib_prefix=no
+ library_names_spec='$libname${shared_ext} $libname.a'
+ dynamic_linker='OS/2 ld.exe'
+ shlibpath_var=LIBPATH
+ ;;
+
+osf3* | osf4* | osf5*)
+ version_type=osf
+ need_lib_prefix=no
+ need_version=no
+ soname_spec='${libname}${release}${shared_ext}$major'
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ shlibpath_var=LD_LIBRARY_PATH
+ sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib"
+ sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec"
+ ;;
+
+rdos*)
+ dynamic_linker=no
+ ;;
+
+solaris*)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ # ldd complains unless libraries are executable
+ postinstall_cmds='chmod +x $lib'
+ ;;
+
+sunos4*)
+ version_type=sunos
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+ finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ if test "$with_gnu_ld" = yes; then
+ need_lib_prefix=no
+ fi
+ need_version=yes
+ ;;
+
+sysv4 | sysv4.3*)
+ version_type=linux
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ case $host_vendor in
+ sni)
+ shlibpath_overrides_runpath=no
+ need_lib_prefix=no
+ runpath_var=LD_RUN_PATH
+ ;;
+ siemens)
+ need_lib_prefix=no
+ ;;
+ motorola)
+ need_lib_prefix=no
+ need_version=no
+ shlibpath_overrides_runpath=no
+ sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib'
+ ;;
+ esac
+ ;;
+
+sysv4*MP*)
+ if test -d /usr/nec ;then
+ version_type=linux
+ library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}'
+ soname_spec='$libname${shared_ext}.$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ fi
+ ;;
+
+sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+ version_type=freebsd-elf
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ if test "$with_gnu_ld" = yes; then
+ sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib'
+ else
+ sys_lib_search_path_spec='/usr/ccs/lib /usr/lib'
+ case $host_os in
+ sco3.2v5*)
+ sys_lib_search_path_spec="$sys_lib_search_path_spec /lib"
+ ;;
+ esac
+ fi
+ sys_lib_dlsearch_path_spec='/usr/lib'
+ ;;
+
+tpf*)
+ # TPF is a cross-target only. Preferred cross-host = GNU/Linux.
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ ;;
+
+uts4*)
+ version_type=linux
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ ;;
+
+*)
+ dynamic_linker=no
+ ;;
+esac
+AC_MSG_RESULT([$dynamic_linker])
+test "$dynamic_linker" = no && can_build_shared=no
+
+variables_saved_for_relink="PATH $shlibpath_var $runpath_var"
+if test "$GCC" = yes; then
+ variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH"
+fi
+
+if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then
+ sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec"
+fi
+if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then
+ sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec"
+fi
+
+_LT_DECL([], [variables_saved_for_relink], [1],
+ [Variables whose values should be saved in libtool wrapper scripts and
+ restored at link time])
+_LT_DECL([], [need_lib_prefix], [0],
+ [Do we need the "lib" prefix for modules?])
+_LT_DECL([], [need_version], [0], [Do we need a version for libraries?])
+_LT_DECL([], [version_type], [0], [Library versioning type])
+_LT_DECL([], [runpath_var], [0], [Shared library runtime path variable])
+_LT_DECL([], [shlibpath_var], [0],[Shared library path variable])
+_LT_DECL([], [shlibpath_overrides_runpath], [0],
+ [Is shlibpath searched before the hard-coded library search path?])
+_LT_DECL([], [libname_spec], [1], [Format of library name prefix])
+_LT_DECL([], [library_names_spec], [1],
+ [[List of archive names. First name is the real one, the rest are links.
+ The last name is the one that the linker finds with -lNAME]])
+_LT_DECL([], [soname_spec], [1],
+ [[The coded name of the library, if different from the real name]])
+_LT_DECL([], [postinstall_cmds], [2],
+ [Command to use after installation of a shared archive])
+_LT_DECL([], [postuninstall_cmds], [2],
+ [Command to use after uninstallation of a shared archive])
+_LT_DECL([], [finish_cmds], [2],
+ [Commands used to finish a libtool library installation in a directory])
+_LT_DECL([], [finish_eval], [1],
+ [[As "finish_cmds", except a single script fragment to be evaled but
+ not shown]])
+_LT_DECL([], [hardcode_into_libs], [0],
+ [Whether we should hardcode library paths into libraries])
+_LT_DECL([], [sys_lib_search_path_spec], [2],
+ [Compile-time system search path for libraries])
+_LT_DECL([], [sys_lib_dlsearch_path_spec], [2],
+ [Run-time system search path for libraries])
+])# _LT_SYS_DYNAMIC_LINKER
+
+
+# _LT_PATH_TOOL_PREFIX(TOOL)
+# --------------------------
+# find a file program which can recognize shared library
+AC_DEFUN([_LT_PATH_TOOL_PREFIX],
+[m4_require([_LT_DECL_EGREP])dnl
+AC_MSG_CHECKING([for $1])
+AC_CACHE_VAL(lt_cv_path_MAGIC_CMD,
+[case $MAGIC_CMD in
+[[\\/*] | ?:[\\/]*])
+ lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path.
+ ;;
+*)
+ lt_save_MAGIC_CMD="$MAGIC_CMD"
+ lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+dnl $ac_dummy forces splitting on constant user-supplied paths.
+dnl POSIX.2 word splitting is done only on the output of word expansions,
+dnl not every word. This closes a longstanding sh security hole.
+ ac_dummy="m4_if([$2], , $PATH, [$2])"
+ for ac_dir in $ac_dummy; do
+ IFS="$lt_save_ifs"
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$1; then
+ lt_cv_path_MAGIC_CMD="$ac_dir/$1"
+ if test -n "$file_magic_test_file"; then
+ case $deplibs_check_method in
+ "file_magic "*)
+ file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"`
+ MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+ if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
+ $EGREP "$file_magic_regex" > /dev/null; then
+ :
+ else
+ cat <<_LT_EOF 1>&2
+
+*** Warning: the command libtool uses to detect shared libraries,
+*** $file_magic_cmd, produces output that libtool cannot recognize.
+*** The result is that libtool may fail to recognize shared libraries
+*** as such. This will affect the creation of libtool libraries that
+*** depend on shared libraries, but programs linked with such libtool
+*** libraries will work regardless of this problem. Nevertheless, you
+*** may want to report the problem to your system manager and/or to
+*** bug-libtool@gnu.org
+
+_LT_EOF
+ fi ;;
+ esac
+ fi
+ break
+ fi
+ done
+ IFS="$lt_save_ifs"
+ MAGIC_CMD="$lt_save_MAGIC_CMD"
+ ;;
+esac])
+MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+if test -n "$MAGIC_CMD"; then
+ AC_MSG_RESULT($MAGIC_CMD)
+else
+ AC_MSG_RESULT(no)
+fi
+_LT_DECL([], [MAGIC_CMD], [0],
+ [Used to examine libraries when file_magic_cmd begins with "file"])dnl
+])# _LT_PATH_TOOL_PREFIX
+
+# Old name:
+AU_ALIAS([AC_PATH_TOOL_PREFIX], [_LT_PATH_TOOL_PREFIX])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_PATH_TOOL_PREFIX], [])
+
+
+# _LT_PATH_MAGIC
+# --------------
+# find a file program which can recognize a shared library
+m4_defun([_LT_PATH_MAGIC],
+[_LT_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin$PATH_SEPARATOR$PATH)
+if test -z "$lt_cv_path_MAGIC_CMD"; then
+ if test -n "$ac_tool_prefix"; then
+ _LT_PATH_TOOL_PREFIX(file, /usr/bin$PATH_SEPARATOR$PATH)
+ else
+ MAGIC_CMD=:
+ fi
+fi
+])# _LT_PATH_MAGIC
+
+
+# LT_PATH_LD
+# ----------
+# find the pathname to the GNU or non-GNU linker
+AC_DEFUN([LT_PATH_LD],
+[AC_REQUIRE([AC_PROG_CC])dnl
+AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_CANONICAL_BUILD])dnl
+m4_require([_LT_DECL_SED])dnl
+m4_require([_LT_DECL_EGREP])dnl
+
+AC_ARG_WITH([gnu-ld],
+ [AS_HELP_STRING([--with-gnu-ld],
+ [assume the C compiler uses GNU ld @<:@default=no@:>@])],
+ [test "$withval" = no || with_gnu_ld=yes],
+ [with_gnu_ld=no])dnl
+
+ac_prog=ld
+if test "$GCC" = yes; then
+ # Check if gcc -print-prog-name=ld gives a path.
+ AC_MSG_CHECKING([for ld used by $CC])
+ case $host in
+ *-*-mingw*)
+ # gcc leaves a trailing carriage return which upsets mingw
+ ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
+ *)
+ ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;
+ esac
+ case $ac_prog in
+ # Accept absolute paths.
+ [[\\/]]* | ?:[[\\/]]*)
+ re_direlt='/[[^/]][[^/]]*/\.\./'
+ # Canonicalize the pathname of ld
+ ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'`
+ while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do
+ ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"`
+ done
+ test -z "$LD" && LD="$ac_prog"
+ ;;
+ "")
+ # If it fails, then pretend we aren't using GCC.
+ ac_prog=ld
+ ;;
+ *)
+ # If it is relative, then search for the first ld in PATH.
+ with_gnu_ld=unknown
+ ;;
+ esac
+elif test "$with_gnu_ld" = yes; then
+ AC_MSG_CHECKING([for GNU ld])
+else
+ AC_MSG_CHECKING([for non-GNU ld])
+fi
+AC_CACHE_VAL(lt_cv_path_LD,
+[if test -z "$LD"; then
+ lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+ for ac_dir in $PATH; do
+ IFS="$lt_save_ifs"
+ test -z "$ac_dir" && ac_dir=.
+ if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
+ lt_cv_path_LD="$ac_dir/$ac_prog"
+ # Check to see if the program is GNU ld. I'd rather use --version,
+ # but apparently some variants of GNU ld only accept -v.
+ # Break only if it was the GNU/non-GNU ld that we prefer.
+ case `"$lt_cv_path_LD" -v 2>&1 </dev/null` in
+ *GNU* | *'with BFD'*)
+ test "$with_gnu_ld" != no && break
+ ;;
+ *)
+ test "$with_gnu_ld" != yes && break
+ ;;
+ esac
+ fi
+ done
+ IFS="$lt_save_ifs"
+else
+ lt_cv_path_LD="$LD" # Let the user override the test with a path.
+fi])
+LD="$lt_cv_path_LD"
+if test -n "$LD"; then
+ AC_MSG_RESULT($LD)
+else
+ AC_MSG_RESULT(no)
+fi
+test -z "$LD" && AC_MSG_ERROR([no acceptable ld found in \$PATH])
+_LT_PATH_LD_GNU
+AC_SUBST([LD])
+
+_LT_TAGDECL([], [LD], [1], [The linker used to build libraries])
+])# LT_PATH_LD
+
+# Old names:
+AU_ALIAS([AM_PROG_LD], [LT_PATH_LD])
+AU_ALIAS([AC_PROG_LD], [LT_PATH_LD])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AM_PROG_LD], [])
+dnl AC_DEFUN([AC_PROG_LD], [])
+
+
+# _LT_PATH_LD_GNU
+#- --------------
+m4_defun([_LT_PATH_LD_GNU],
+[AC_CACHE_CHECK([if the linker ($LD) is GNU ld], lt_cv_prog_gnu_ld,
+[# I'd rather use --version here, but apparently some GNU lds only accept -v.
+case `$LD -v 2>&1 </dev/null` in
+*GNU* | *'with BFD'*)
+ lt_cv_prog_gnu_ld=yes
+ ;;
+*)
+ lt_cv_prog_gnu_ld=no
+ ;;
+esac])
+with_gnu_ld=$lt_cv_prog_gnu_ld
+])# _LT_PATH_LD_GNU
+
+
+# _LT_CMD_RELOAD
+# --------------
+# find reload flag for linker
+# -- PORTME Some linkers may need a different reload flag.
+m4_defun([_LT_CMD_RELOAD],
+[AC_CACHE_CHECK([for $LD option to reload object files],
+ lt_cv_ld_reload_flag,
+ [lt_cv_ld_reload_flag='-r'])
+reload_flag=$lt_cv_ld_reload_flag
+case $reload_flag in
+"" | " "*) ;;
+*) reload_flag=" $reload_flag" ;;
+esac
+reload_cmds='$LD$reload_flag -o $output$reload_objs'
+case $host_os in
+ darwin*)
+ if test "$GCC" = yes; then
+ reload_cmds='$LTCC $LTCFLAGS -nostdlib ${wl}-r -o $output$reload_objs'
+ else
+ reload_cmds='$LD$reload_flag -o $output$reload_objs'
+ fi
+ ;;
+esac
+_LT_DECL([], [reload_flag], [1], [How to create reloadable object files])dnl
+_LT_DECL([], [reload_cmds], [2])dnl
+])# _LT_CMD_RELOAD
+
+
+# _LT_CHECK_MAGIC_METHOD
+# ----------------------
+# how to check for library dependencies
+# -- PORTME fill in with the dynamic library characteristics
+m4_defun([_LT_CHECK_MAGIC_METHOD],
+[m4_require([_LT_DECL_EGREP])
+m4_require([_LT_DECL_OBJDUMP])
+AC_CACHE_CHECK([how to recognize dependent libraries],
+lt_cv_deplibs_check_method,
+[lt_cv_file_magic_cmd='$MAGIC_CMD'
+lt_cv_file_magic_test_file=
+lt_cv_deplibs_check_method='unknown'
+# Need to set the preceding variable on all platforms that support
+# interlibrary dependencies.
+# 'none' -- dependencies not supported.
+# `unknown' -- same as none, but documents that we really don't know.
+# 'pass_all' -- all dependencies passed with no checks.
+# 'test_compile' -- check by making test program.
+# 'file_magic [[regex]]' -- check by looking for files in library path
+# which responds to the $file_magic_cmd with a given extended regex.
+# If you have `file' or equivalent on your system and you're not sure
+# whether `pass_all' will *always* work, you probably want this one.
+
+case $host_os in
+aix[[4-9]]*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+beos*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+bsdi[[45]]*)
+ lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib)'
+ lt_cv_file_magic_cmd='/usr/bin/file -L'
+ lt_cv_file_magic_test_file=/shlib/libc.so
+ ;;
+
+cygwin*)
+ # func_win32_libid is a shell function defined in ltmain.sh
+ lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
+ lt_cv_file_magic_cmd='func_win32_libid'
+ ;;
+
+mingw* | pw32*)
+ # Base MSYS/MinGW do not provide the 'file' command needed by
+ # func_win32_libid shell function, so use a weaker test based on 'objdump',
+ # unless we find 'file', for example because we are cross-compiling.
+ if ( file / ) >/dev/null 2>&1; then
+ lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
+ lt_cv_file_magic_cmd='func_win32_libid'
+ else
+ lt_cv_deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?'
+ lt_cv_file_magic_cmd='$OBJDUMP -f'
+ fi
+ ;;
+
+cegcc)
+ # use the weaker test based on 'objdump'. See mingw*.
+ lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?'
+ lt_cv_file_magic_cmd='$OBJDUMP -f'
+ ;;
+
+darwin* | rhapsody*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+freebsd* | dragonfly*)
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then
+ case $host_cpu in
+ i*86 )
+ # Not sure whether the presence of OpenBSD here was a mistake.
+ # Let's accept both of them until this is cleared up.
+ lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[[3-9]]86 (compact )?demand paged shared library'
+ lt_cv_file_magic_cmd=/usr/bin/file
+ lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*`
+ ;;
+ esac
+ else
+ lt_cv_deplibs_check_method=pass_all
+ fi
+ ;;
+
+gnu*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+hpux10.20* | hpux11*)
+ lt_cv_file_magic_cmd=/usr/bin/file
+ case $host_cpu in
+ ia64*)
+ lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|ELF-[[0-9]][[0-9]]) shared object file - IA64'
+ lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so
+ ;;
+ hppa*64*)
+ [lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - PA-RISC [0-9].[0-9]']
+ lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl
+ ;;
+ *)
+ lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|PA-RISC[[0-9]].[[0-9]]) shared library'
+ lt_cv_file_magic_test_file=/usr/lib/libc.sl
+ ;;
+ esac
+ ;;
+
+interix[[3-9]]*)
+ # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here
+ lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|\.a)$'
+ ;;
+
+irix5* | irix6* | nonstopux*)
+ case $LD in
+ *-32|*"-32 ") libmagic=32-bit;;
+ *-n32|*"-n32 ") libmagic=N32;;
+ *-64|*"-64 ") libmagic=64-bit;;
+ *) libmagic=never-match;;
+ esac
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+# This must be Linux ELF.
+linux* | k*bsd*-gnu | kopensolaris*-gnu)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+netbsd* | netbsdelf*-gnu)
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then
+ lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$'
+ else
+ lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|_pic\.a)$'
+ fi
+ ;;
+
+newos6*)
+ lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (executable|dynamic lib)'
+ lt_cv_file_magic_cmd=/usr/bin/file
+ lt_cv_file_magic_test_file=/usr/lib/libnls.so
+ ;;
+
+*nto* | *qnx*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+openbsd*)
+ if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+ lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|\.so|_pic\.a)$'
+ else
+ lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$'
+ fi
+ ;;
+
+osf3* | osf4* | osf5*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+rdos*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+solaris*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+sysv4 | sysv4.3*)
+ case $host_vendor in
+ motorola)
+ lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib) M[[0-9]][[0-9]]* Version [[0-9]]'
+ lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*`
+ ;;
+ ncr)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+ sequent)
+ lt_cv_file_magic_cmd='/bin/file'
+ lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB (shared object|dynamic lib )'
+ ;;
+ sni)
+ lt_cv_file_magic_cmd='/bin/file'
+ lt_cv_deplibs_check_method="file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB dynamic lib"
+ lt_cv_file_magic_test_file=/lib/libc.so
+ ;;
+ siemens)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+ pc)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+ esac
+ ;;
+
+tpf*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+esac
+])
+file_magic_cmd=$lt_cv_file_magic_cmd
+deplibs_check_method=$lt_cv_deplibs_check_method
+test -z "$deplibs_check_method" && deplibs_check_method=unknown
+
+_LT_DECL([], [deplibs_check_method], [1],
+ [Method to check whether dependent libraries are shared objects])
+_LT_DECL([], [file_magic_cmd], [1],
+ [Command to use when deplibs_check_method == "file_magic"])
+])# _LT_CHECK_MAGIC_METHOD
+
+
+# LT_PATH_NM
+# ----------
+# find the pathname to a BSD- or MS-compatible name lister
+AC_DEFUN([LT_PATH_NM],
+[AC_REQUIRE([AC_PROG_CC])dnl
+AC_CACHE_CHECK([for BSD- or MS-compatible name lister (nm)], lt_cv_path_NM,
+[if test -n "$NM"; then
+ # Let the user override the test.
+ lt_cv_path_NM="$NM"
+else
+ lt_nm_to_check="${ac_tool_prefix}nm"
+ if test -n "$ac_tool_prefix" && test "$build" = "$host"; then
+ lt_nm_to_check="$lt_nm_to_check nm"
+ fi
+ for lt_tmp_nm in $lt_nm_to_check; do
+ lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+ for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do
+ IFS="$lt_save_ifs"
+ test -z "$ac_dir" && ac_dir=.
+ tmp_nm="$ac_dir/$lt_tmp_nm"
+ if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then
+ # Check to see if the nm accepts a BSD-compat flag.
+ # Adding the `sed 1q' prevents false positives on HP-UX, which says:
+ # nm: unknown option "B" ignored
+ # Tru64's nm complains that /dev/null is an invalid object file
+ case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in
+ */dev/null* | *'Invalid file or object type'*)
+ lt_cv_path_NM="$tmp_nm -B"
+ break
+ ;;
+ *)
+ case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in
+ */dev/null*)
+ lt_cv_path_NM="$tmp_nm -p"
+ break
+ ;;
+ *)
+ lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but
+ continue # so that we can try to find one that supports BSD flags
+ ;;
+ esac
+ ;;
+ esac
+ fi
+ done
+ IFS="$lt_save_ifs"
+ done
+ : ${lt_cv_path_NM=no}
+fi])
+if test "$lt_cv_path_NM" != "no"; then
+ NM="$lt_cv_path_NM"
+else
+ # Didn't find any BSD compatible name lister, look for dumpbin.
+ AC_CHECK_TOOLS(DUMPBIN, ["dumpbin -symbols" "link -dump -symbols"], :)
+ AC_SUBST([DUMPBIN])
+ if test "$DUMPBIN" != ":"; then
+ NM="$DUMPBIN"
+ fi
+fi
+test -z "$NM" && NM=nm
+AC_SUBST([NM])
+_LT_DECL([], [NM], [1], [A BSD- or MS-compatible name lister])dnl
+
+AC_CACHE_CHECK([the name lister ($NM) interface], [lt_cv_nm_interface],
+ [lt_cv_nm_interface="BSD nm"
+ echo "int some_variable = 0;" > conftest.$ac_ext
+ (eval echo "\"\$as_me:__oline__: $ac_compile\"" >&AS_MESSAGE_LOG_FD)
+ (eval "$ac_compile" 2>conftest.err)
+ cat conftest.err >&AS_MESSAGE_LOG_FD
+ (eval echo "\"\$as_me:__oline__: $NM \\\"conftest.$ac_objext\\\"\"" >&AS_MESSAGE_LOG_FD)
+ (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out)
+ cat conftest.err >&AS_MESSAGE_LOG_FD
+ (eval echo "\"\$as_me:__oline__: output\"" >&AS_MESSAGE_LOG_FD)
+ cat conftest.out >&AS_MESSAGE_LOG_FD
+ if $GREP 'External.*some_variable' conftest.out > /dev/null; then
+ lt_cv_nm_interface="MS dumpbin"
+ fi
+ rm -f conftest*])
+])# LT_PATH_NM
+
+# Old names:
+AU_ALIAS([AM_PROG_NM], [LT_PATH_NM])
+AU_ALIAS([AC_PROG_NM], [LT_PATH_NM])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AM_PROG_NM], [])
+dnl AC_DEFUN([AC_PROG_NM], [])
+
+
+# LT_LIB_M
+# --------
+# check for math library
+AC_DEFUN([LT_LIB_M],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+LIBM=
+case $host in
+*-*-beos* | *-*-cygwin* | *-*-pw32* | *-*-darwin*)
+ # These system don't have libm, or don't need it
+ ;;
+*-ncr-sysv4.3*)
+ AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM="-lmw")
+ AC_CHECK_LIB(m, cos, LIBM="$LIBM -lm")
+ ;;
+*)
+ AC_CHECK_LIB(m, cos, LIBM="-lm")
+ ;;
+esac
+AC_SUBST([LIBM])
+])# LT_LIB_M
+
+# Old name:
+AU_ALIAS([AC_CHECK_LIBM], [LT_LIB_M])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_CHECK_LIBM], [])
+
+
+# _LT_COMPILER_NO_RTTI([TAGNAME])
+# -------------------------------
+m4_defun([_LT_COMPILER_NO_RTTI],
+[m4_require([_LT_TAG_COMPILER])dnl
+
+_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=
+
+if test "$GCC" = yes; then
+ _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin'
+
+ _LT_COMPILER_OPTION([if $compiler supports -fno-rtti -fno-exceptions],
+ lt_cv_prog_compiler_rtti_exceptions,
+ [-fno-rtti -fno-exceptions], [],
+ [_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)="$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) -fno-rtti -fno-exceptions"])
+fi
+_LT_TAGDECL([no_builtin_flag], [lt_prog_compiler_no_builtin_flag], [1],
+ [Compiler flag to turn off builtin functions])
+])# _LT_COMPILER_NO_RTTI
+
+
+# _LT_CMD_GLOBAL_SYMBOLS
+# ----------------------
+m4_defun([_LT_CMD_GLOBAL_SYMBOLS],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_PROG_CC])dnl
+AC_REQUIRE([LT_PATH_NM])dnl
+AC_REQUIRE([LT_PATH_LD])dnl
+m4_require([_LT_DECL_SED])dnl
+m4_require([_LT_DECL_EGREP])dnl
+m4_require([_LT_TAG_COMPILER])dnl
+
+# Check for command to grab the raw symbol name followed by C symbol from nm.
+AC_MSG_CHECKING([command to parse $NM output from $compiler object])
+AC_CACHE_VAL([lt_cv_sys_global_symbol_pipe],
+[
+# These are sane defaults that work on at least a few old systems.
+# [They come from Ultrix. What could be older than Ultrix?!! ;)]
+
+# Character class describing NM global symbol codes.
+symcode='[[BCDEGRST]]'
+
+# Regexp to match symbols that can be accessed directly from C.
+sympat='\([[_A-Za-z]][[_A-Za-z0-9]]*\)'
+
+# Define system-specific variables.
+case $host_os in
+aix*)
+ symcode='[[BCDT]]'
+ ;;
+cygwin* | mingw* | pw32* | cegcc*)
+ symcode='[[ABCDGISTW]]'
+ ;;
+hpux*)
+ if test "$host_cpu" = ia64; then
+ symcode='[[ABCDEGRST]]'
+ fi
+ ;;
+irix* | nonstopux*)
+ symcode='[[BCDEGRST]]'
+ ;;
+osf*)
+ symcode='[[BCDEGQRST]]'
+ ;;
+solaris*)
+ symcode='[[BDRT]]'
+ ;;
+sco3.2v5*)
+ symcode='[[DT]]'
+ ;;
+sysv4.2uw2*)
+ symcode='[[DT]]'
+ ;;
+sysv5* | sco5v6* | unixware* | OpenUNIX*)
+ symcode='[[ABDT]]'
+ ;;
+sysv4)
+ symcode='[[DFNSTU]]'
+ ;;
+esac
+
+# If we're using GNU nm, then use its standard symbol codes.
+case `$NM -V 2>&1` in
+*GNU* | *'with BFD'*)
+ symcode='[[ABCDGIRSTW]]' ;;
+esac
+
+# Transform an extracted symbol line into a proper C declaration.
+# Some systems (esp. on ia64) link data and code symbols differently,
+# so use this general approach.
+lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'"
+
+# Transform an extracted symbol line into symbol name and symbol address
+lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\) $/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"\2\", (void *) \&\2},/p'"
+lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([[^ ]]*\) $/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \(lib[[^ ]]*\)$/ {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"lib\2\", (void *) \&\2},/p'"
+
+# Handle CRLF in mingw tool chain
+opt_cr=
+case $build_os in
+mingw*)
+ opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp
+ ;;
+esac
+
+# Try without a prefix underscore, then with it.
+for ac_symprfx in "" "_"; do
+
+ # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol.
+ symxfrm="\\1 $ac_symprfx\\2 \\2"
+
+ # Write the raw and C identifiers.
+ if test "$lt_cv_nm_interface" = "MS dumpbin"; then
+ # Fake it for dumpbin and say T for any non-static function
+ # and D for any global variable.
+ # Also find C++ and __fastcall symbols from MSVC++,
+ # which start with @ or ?.
+ lt_cv_sys_global_symbol_pipe="$AWK ['"\
+" {last_section=section; section=\$ 3};"\
+" /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\
+" \$ 0!~/External *\|/{next};"\
+" / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\
+" {if(hide[section]) next};"\
+" {f=0}; \$ 0~/\(\).*\|/{f=1}; {printf f ? \"T \" : \"D \"};"\
+" {split(\$ 0, a, /\||\r/); split(a[2], s)};"\
+" s[1]~/^[@?]/{print s[1], s[1]; next};"\
+" s[1]~prfx {split(s[1],t,\"@\"); print t[1], substr(t[1],length(prfx))}"\
+" ' prfx=^$ac_symprfx]"
+ else
+ lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[ ]]\($symcode$symcode*\)[[ ]][[ ]]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'"
+ fi
+
+ # Check to see that the pipe works correctly.
+ pipe_works=no
+
+ rm -f conftest*
+ cat > conftest.$ac_ext <<_LT_EOF
+#ifdef __cplusplus
+extern "C" {
+#endif
+char nm_test_var;
+void nm_test_func(void);
+void nm_test_func(void){}
+#ifdef __cplusplus
+}
+#endif
+int main(){nm_test_var='a';nm_test_func();return(0);}
+_LT_EOF
+
+ if AC_TRY_EVAL(ac_compile); then
+ # Now try to grab the symbols.
+ nlist=conftest.nm
+ if AC_TRY_EVAL(NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $nlist) && test -s "$nlist"; then
+ # Try sorting and uniquifying the output.
+ if sort "$nlist" | uniq > "$nlist"T; then
+ mv -f "$nlist"T "$nlist"
+ else
+ rm -f "$nlist"T
+ fi
+
+ # Make sure that we snagged all the symbols we need.
+ if $GREP ' nm_test_var$' "$nlist" >/dev/null; then
+ if $GREP ' nm_test_func$' "$nlist" >/dev/null; then
+ cat <<_LT_EOF > conftest.$ac_ext
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+_LT_EOF
+ # Now generate the symbol file.
+ eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext'
+
+ cat <<_LT_EOF >> conftest.$ac_ext
+
+/* The mapping between symbol names and symbols. */
+const struct {
+ const char *name;
+ void *address;
+}
+lt__PROGRAM__LTX_preloaded_symbols[[]] =
+{
+ { "@PROGRAM@", (void *) 0 },
+_LT_EOF
+ $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (void *) \&\2},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext
+ cat <<\_LT_EOF >> conftest.$ac_ext
+ {0, (void *) 0}
+};
+
+/* This works around a problem in FreeBSD linker */
+#ifdef FREEBSD_WORKAROUND
+static const void *lt_preloaded_setup() {
+ return lt__PROGRAM__LTX_preloaded_symbols;
+}
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+_LT_EOF
+ # Now try linking the two files.
+ mv conftest.$ac_objext conftstm.$ac_objext
+ lt_save_LIBS="$LIBS"
+ lt_save_CFLAGS="$CFLAGS"
+ LIBS="conftstm.$ac_objext"
+ CFLAGS="$CFLAGS$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)"
+ if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext}; then
+ pipe_works=yes
+ fi
+ LIBS="$lt_save_LIBS"
+ CFLAGS="$lt_save_CFLAGS"
+ else
+ echo "cannot find nm_test_func in $nlist" >&AS_MESSAGE_LOG_FD
+ fi
+ else
+ echo "cannot find nm_test_var in $nlist" >&AS_MESSAGE_LOG_FD
+ fi
+ else
+ echo "cannot run $lt_cv_sys_global_symbol_pipe" >&AS_MESSAGE_LOG_FD
+ fi
+ else
+ echo "$progname: failed program was:" >&AS_MESSAGE_LOG_FD
+ cat conftest.$ac_ext >&5
+ fi
+ rm -rf conftest* conftst*
+
+ # Do not use the global_symbol_pipe unless it works.
+ if test "$pipe_works" = yes; then
+ break
+ else
+ lt_cv_sys_global_symbol_pipe=
+ fi
+done
+])
+if test -z "$lt_cv_sys_global_symbol_pipe"; then
+ lt_cv_sys_global_symbol_to_cdecl=
+fi
+if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then
+ AC_MSG_RESULT(failed)
+else
+ AC_MSG_RESULT(ok)
+fi
+
+_LT_DECL([global_symbol_pipe], [lt_cv_sys_global_symbol_pipe], [1],
+ [Take the output of nm and produce a listing of raw symbols and C names])
+_LT_DECL([global_symbol_to_cdecl], [lt_cv_sys_global_symbol_to_cdecl], [1],
+ [Transform the output of nm in a proper C declaration])
+_LT_DECL([global_symbol_to_c_name_address],
+ [lt_cv_sys_global_symbol_to_c_name_address], [1],
+ [Transform the output of nm in a C name address pair])
+_LT_DECL([global_symbol_to_c_name_address_lib_prefix],
+ [lt_cv_sys_global_symbol_to_c_name_address_lib_prefix], [1],
+ [Transform the output of nm in a C name address pair when lib prefix is needed])
+]) # _LT_CMD_GLOBAL_SYMBOLS
+
+
+# _LT_COMPILER_PIC([TAGNAME])
+# ---------------------------
+m4_defun([_LT_COMPILER_PIC],
+[m4_require([_LT_TAG_COMPILER])dnl
+_LT_TAGVAR(lt_prog_compiler_wl, $1)=
+_LT_TAGVAR(lt_prog_compiler_pic, $1)=
+_LT_TAGVAR(lt_prog_compiler_static, $1)=
+
+AC_MSG_CHECKING([for $compiler option to produce PIC])
+m4_if([$1], [CXX], [
+ # C++ specific cases for pic, static, wl, etc.
+ if test "$GXX" = yes; then
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+
+ case $host_os in
+ aix*)
+ # All AIX code is PIC.
+ if test "$host_cpu" = ia64; then
+ # AIX 5 now supports IA64 processor
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ fi
+ ;;
+
+ amigaos*)
+ case $host_cpu in
+ powerpc)
+ # see comment about AmigaOS4 .so support
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ ;;
+ m68k)
+ # FIXME: we need at least 68020 code to build shared libraries, but
+ # adding the `-m68020' flag to GCC prevents building anything better,
+ # like `-m68040'.
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4'
+ ;;
+ esac
+ ;;
+
+ beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
+ # PIC is the default for these OSes.
+ ;;
+ mingw* | cygwin* | os2* | pw32* | cegcc*)
+ # This hack is so that the source file can tell whether it is being
+ # built for inclusion in a dll (and should export symbols for example).
+ # Although the cygwin gcc ignores -fPIC, still need this for old-style
+ # (--disable-auto-import) libraries
+ m4_if([$1], [GCJ], [],
+ [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'])
+ ;;
+ darwin* | rhapsody*)
+ # PIC is the default on this platform
+ # Common symbols not allowed in MH_DYLIB files
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common'
+ ;;
+ *djgpp*)
+ # DJGPP does not support shared libraries at all
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)=
+ ;;
+ interix[[3-9]]*)
+ # Interix 3.x gcc -fpic/-fPIC options generate broken code.
+ # Instead, we relocate shared libraries at runtime.
+ ;;
+ sysv4*MP*)
+ if test -d /usr/nec; then
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic
+ fi
+ ;;
+ hpux*)
+ # PIC is the default for 64-bit PA HP-UX, but not for 32-bit
+ # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag
+ # sets the default TLS model and affects inlining.
+ case $host_cpu in
+ hppa*64*)
+ ;;
+ *)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ ;;
+ esac
+ ;;
+ *qnx* | *nto*)
+ # QNX uses GNU C++, but need to define -shared option too, otherwise
+ # it will coredump.
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared'
+ ;;
+ *)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ ;;
+ esac
+ else
+ case $host_os in
+ aix[[4-9]]*)
+ # All AIX code is PIC.
+ if test "$host_cpu" = ia64; then
+ # AIX 5 now supports IA64 processor
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ else
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp'
+ fi
+ ;;
+ chorus*)
+ case $cc_basename in
+ cxch68*)
+ # Green Hills C++ Compiler
+ # _LT_TAGVAR(lt_prog_compiler_static, $1)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a"
+ ;;
+ esac
+ ;;
+ dgux*)
+ case $cc_basename in
+ ec++*)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ ;;
+ ghcx*)
+ # Green Hills C++ Compiler
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ freebsd* | dragonfly*)
+ # FreeBSD uses GNU C++
+ ;;
+ hpux9* | hpux10* | hpux11*)
+ case $cc_basename in
+ CC*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive'
+ if test "$host_cpu" != ia64; then
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z'
+ fi
+ ;;
+ aCC*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive'
+ case $host_cpu in
+ hppa*64*|ia64*)
+ # +Z the default
+ ;;
+ *)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z'
+ ;;
+ esac
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ interix*)
+ # This is c89, which is MS Visual C++ (no shared libs)
+ # Anyone wants to do a port?
+ ;;
+ irix5* | irix6* | nonstopux*)
+ case $cc_basename in
+ CC*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+ # CC pic flag -KPIC is the default.
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ linux* | k*bsd*-gnu | kopensolaris*-gnu)
+ case $cc_basename in
+ KCC*)
+ # KAI C++ Compiler
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ ;;
+ ecpc* )
+ # old Intel C++ for x86_64 which still supported -KPIC.
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+ ;;
+ icpc* )
+ # Intel C++, used to be incompatible with GCC.
+ # ICC 10 doesn't accept -KPIC any more.
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+ ;;
+ pgCC* | pgcpp*)
+ # Portland Group C++ compiler
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+ cxx*)
+ # Compaq C++
+ # Make sure the PIC flag is empty. It appears that all Alpha
+ # Linux and Compaq Tru64 Unix objects are PIC.
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)=
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+ ;;
+ xlc* | xlC*)
+ # IBM XL 8.0 on PPC
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink'
+ ;;
+ *)
+ case `$CC -V 2>&1 | sed 5q` in
+ *Sun\ C*)
+ # Sun C++ 5.9
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld '
+ ;;
+ esac
+ ;;
+ esac
+ ;;
+ lynxos*)
+ ;;
+ m88k*)
+ ;;
+ mvs*)
+ case $cc_basename in
+ cxx*)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-W c,exportall'
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ netbsd* | netbsdelf*-gnu)
+ ;;
+ *qnx* | *nto*)
+ # QNX uses GNU C++, but need to define -shared option too, otherwise
+ # it will coredump.
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared'
+ ;;
+ osf3* | osf4* | osf5*)
+ case $cc_basename in
+ KCC*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,'
+ ;;
+ RCC*)
+ # Rational C++ 2.4.1
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
+ ;;
+ cxx*)
+ # Digital/Compaq C++
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ # Make sure the PIC flag is empty. It appears that all Alpha
+ # Linux and Compaq Tru64 Unix objects are PIC.
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)=
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ psos*)
+ ;;
+ solaris*)
+ case $cc_basename in
+ CC*)
+ # Sun C++ 4.2, 5.x and Centerline C++
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld '
+ ;;
+ gcx*)
+ # Green Hills C++ Compiler
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC'
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ sunos4*)
+ case $cc_basename in
+ CC*)
+ # Sun C++ 4.x
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+ lcc*)
+ # Lucid
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
+ case $cc_basename in
+ CC*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+ esac
+ ;;
+ tandem*)
+ case $cc_basename in
+ NCC*)
+ # NonStop-UX NCC 3.20
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ vxworks*)
+ ;;
+ *)
+ _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no
+ ;;
+ esac
+ fi
+],
+[
+ if test "$GCC" = yes; then
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+
+ case $host_os in
+ aix*)
+ # All AIX code is PIC.
+ if test "$host_cpu" = ia64; then
+ # AIX 5 now supports IA64 processor
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ fi
+ ;;
+
+ amigaos*)
+ case $host_cpu in
+ powerpc)
+ # see comment about AmigaOS4 .so support
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ ;;
+ m68k)
+ # FIXME: we need at least 68020 code to build shared libraries, but
+ # adding the `-m68020' flag to GCC prevents building anything better,
+ # like `-m68040'.
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4'
+ ;;
+ esac
+ ;;
+
+ beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
+ # PIC is the default for these OSes.
+ ;;
+
+ mingw* | cygwin* | pw32* | os2* | cegcc*)
+ # This hack is so that the source file can tell whether it is being
+ # built for inclusion in a dll (and should export symbols for example).
+ # Although the cygwin gcc ignores -fPIC, still need this for old-style
+ # (--disable-auto-import) libraries
+ m4_if([$1], [GCJ], [],
+ [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'])
+ ;;
+
+ darwin* | rhapsody*)
+ # PIC is the default on this platform
+ # Common symbols not allowed in MH_DYLIB files
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common'
+ ;;
+
+ hpux*)
+ # PIC is the default for 64-bit PA HP-UX, but not for 32-bit
+ # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag
+ # sets the default TLS model and affects inlining.
+ case $host_cpu in
+ hppa*64*)
+ # +Z the default
+ ;;
+ *)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ ;;
+ esac
+ ;;
+
+ interix[[3-9]]*)
+ # Interix 3.x gcc -fpic/-fPIC options generate broken code.
+ # Instead, we relocate shared libraries at runtime.
+ ;;
+
+ msdosdjgpp*)
+ # Just because we use GCC doesn't mean we suddenly get shared libraries
+ # on systems that don't support them.
+ _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no
+ enable_shared=no
+ ;;
+
+ *nto* | *qnx*)
+ # QNX uses GNU C++, but need to define -shared option too, otherwise
+ # it will coredump.
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared'
+ ;;
+
+ sysv4*MP*)
+ if test -d /usr/nec; then
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic
+ fi
+ ;;
+
+ *)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ ;;
+ esac
+ else
+ # PORTME Check for flag to pass linker flags through the system compiler.
+ case $host_os in
+ aix*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ if test "$host_cpu" = ia64; then
+ # AIX 5 now supports IA64 processor
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ else
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp'
+ fi
+ ;;
+
+ mingw* | cygwin* | pw32* | os2* | cegcc*)
+ # This hack is so that the source file can tell whether it is being
+ # built for inclusion in a dll (and should export symbols for example).
+ m4_if([$1], [GCJ], [],
+ [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'])
+ ;;
+
+ hpux9* | hpux10* | hpux11*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
+ # not for PA HP-UX.
+ case $host_cpu in
+ hppa*64*|ia64*)
+ # +Z the default
+ ;;
+ *)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z'
+ ;;
+ esac
+ # Is there a better lt_prog_compiler_static that works with the bundled CC?
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive'
+ ;;
+
+ irix5* | irix6* | nonstopux*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ # PIC (with -KPIC) is the default.
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+ ;;
+
+ linux* | k*bsd*-gnu | kopensolaris*-gnu)
+ case $cc_basename in
+ # old Intel for x86_64 which still supported -KPIC.
+ ecc*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+ ;;
+ # icc used to be incompatible with GCC.
+ # ICC 10 doesn't accept -KPIC any more.
+ icc* | ifort*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+ ;;
+ # Lahey Fortran 8.1.
+ lf95*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='--shared'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='--static'
+ ;;
+ pgcc* | pgf77* | pgf90* | pgf95*)
+ # Portland Group compilers (*not* the Pentium gcc compiler,
+ # which looks to be a dead project)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+ ccc*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ # All Alpha code is PIC.
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+ ;;
+ xl*)
+ # IBM XL C 8.0/Fortran 10.1 on PPC
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink'
+ ;;
+ *)
+ case `$CC -V 2>&1 | sed 5q` in
+ *Sun\ C*)
+ # Sun C 5.9
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ ;;
+ *Sun\ F*)
+ # Sun Fortran 8.3 passes all unrecognized flags to the linker
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)=''
+ ;;
+ esac
+ ;;
+ esac
+ ;;
+
+ newsos6)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+
+ *nto* | *qnx*)
+ # QNX uses GNU C++, but need to define -shared option too, otherwise
+ # it will coredump.
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared'
+ ;;
+
+ osf3* | osf4* | osf5*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ # All OSF/1 code is PIC.
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+ ;;
+
+ rdos*)
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+ ;;
+
+ solaris*)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ case $cc_basename in
+ f77* | f90* | f95*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ';;
+ *)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,';;
+ esac
+ ;;
+
+ sunos4*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld '
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+
+ sysv4 | sysv4.2uw2* | sysv4.3*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+
+ sysv4*MP*)
+ if test -d /usr/nec ;then
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-Kconform_pic'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ fi
+ ;;
+
+ sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+
+ unicos*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no
+ ;;
+
+ uts4*)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+
+ *)
+ _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no
+ ;;
+ esac
+ fi
+])
+case $host_os in
+ # For platforms which do not support PIC, -DPIC is meaningless:
+ *djgpp*)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)=
+ ;;
+ *)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)="$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])"
+ ;;
+esac
+AC_MSG_RESULT([$_LT_TAGVAR(lt_prog_compiler_pic, $1)])
+_LT_TAGDECL([wl], [lt_prog_compiler_wl], [1],
+ [How to pass a linker flag through the compiler])
+
+#
+# Check to make sure the PIC flag actually works.
+#
+if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then
+ _LT_COMPILER_OPTION([if $compiler PIC flag $_LT_TAGVAR(lt_prog_compiler_pic, $1) works],
+ [_LT_TAGVAR(lt_cv_prog_compiler_pic_works, $1)],
+ [$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])], [],
+ [case $_LT_TAGVAR(lt_prog_compiler_pic, $1) in
+ "" | " "*) ;;
+ *) _LT_TAGVAR(lt_prog_compiler_pic, $1)=" $_LT_TAGVAR(lt_prog_compiler_pic, $1)" ;;
+ esac],
+ [_LT_TAGVAR(lt_prog_compiler_pic, $1)=
+ _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no])
+fi
+_LT_TAGDECL([pic_flag], [lt_prog_compiler_pic], [1],
+ [Additional compiler flags for building library objects])
+
+#
+# Check to make sure the static flag actually works.
+#
+wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) eval lt_tmp_static_flag=\"$_LT_TAGVAR(lt_prog_compiler_static, $1)\"
+_LT_LINKER_OPTION([if $compiler static flag $lt_tmp_static_flag works],
+ _LT_TAGVAR(lt_cv_prog_compiler_static_works, $1),
+ $lt_tmp_static_flag,
+ [],
+ [_LT_TAGVAR(lt_prog_compiler_static, $1)=])
+_LT_TAGDECL([link_static_flag], [lt_prog_compiler_static], [1],
+ [Compiler flag to prevent dynamic linking])
+])# _LT_COMPILER_PIC
+
+
+# _LT_LINKER_SHLIBS([TAGNAME])
+# ----------------------------
+# See if the linker supports building shared libraries.
+m4_defun([_LT_LINKER_SHLIBS],
+[AC_REQUIRE([LT_PATH_LD])dnl
+AC_REQUIRE([LT_PATH_NM])dnl
+m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_DECL_EGREP])dnl
+m4_require([_LT_DECL_SED])dnl
+m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl
+m4_require([_LT_TAG_COMPILER])dnl
+AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries])
+m4_if([$1], [CXX], [
+ _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+ case $host_os in
+ aix[[4-9]]*)
+ # If we're using GNU nm, then we don't want the "-C" option.
+ # -C means demangle to AIX nm, but means don't demangle with GNU nm
+ if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
+ _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
+ else
+ _LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
+ fi
+ ;;
+ pw32*)
+ _LT_TAGVAR(export_symbols_cmds, $1)="$ltdll_cmds"
+ ;;
+ cygwin* | mingw* | cegcc*)
+ _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;/^.*[[ ]]__nm__/s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols'
+ ;;
+ linux* | k*bsd*-gnu)
+ _LT_TAGVAR(link_all_deplibs, $1)=no
+ ;;
+ *)
+ _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+ ;;
+ esac
+ _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*']
+], [
+ runpath_var=
+ _LT_TAGVAR(allow_undefined_flag, $1)=
+ _LT_TAGVAR(always_export_symbols, $1)=no
+ _LT_TAGVAR(archive_cmds, $1)=
+ _LT_TAGVAR(archive_expsym_cmds, $1)=
+ _LT_TAGVAR(compiler_needs_object, $1)=no
+ _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)=
+ _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+ _LT_TAGVAR(hardcode_automatic, $1)=no
+ _LT_TAGVAR(hardcode_direct, $1)=no
+ _LT_TAGVAR(hardcode_direct_absolute, $1)=no
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
+ _LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)=
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=
+ _LT_TAGVAR(hardcode_minus_L, $1)=no
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported
+ _LT_TAGVAR(inherit_rpath, $1)=no
+ _LT_TAGVAR(link_all_deplibs, $1)=unknown
+ _LT_TAGVAR(module_cmds, $1)=
+ _LT_TAGVAR(module_expsym_cmds, $1)=
+ _LT_TAGVAR(old_archive_from_new_cmds, $1)=
+ _LT_TAGVAR(old_archive_from_expsyms_cmds, $1)=
+ _LT_TAGVAR(thread_safe_flag_spec, $1)=
+ _LT_TAGVAR(whole_archive_flag_spec, $1)=
+ # include_expsyms should be a list of space-separated symbols to be *always*
+ # included in the symbol list
+ _LT_TAGVAR(include_expsyms, $1)=
+ # exclude_expsyms can be an extended regexp of symbols to exclude
+ # it will be wrapped by ` (' and `)$', so one must not match beginning or
+ # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc',
+ # as well as any symbol that contains `d'.
+ _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*']
+ # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out
+ # platforms (ab)use it in PIC code, but their linkers get confused if
+ # the symbol is explicitly referenced. Since portable code cannot
+ # rely on this symbol name, it's probably fine to never include it in
+ # preloaded symbol tables.
+ # Exclude shared library initialization/finalization symbols.
+dnl Note also adjust exclude_expsyms for C++ above.
+ extract_expsyms_cmds=
+
+ case $host_os in
+ cygwin* | mingw* | pw32* | cegcc*)
+ # FIXME: the MSVC++ port hasn't been tested in a loooong time
+ # When not using gcc, we currently assume that we are using
+ # Microsoft Visual C++.
+ if test "$GCC" != yes; then
+ with_gnu_ld=no
+ fi
+ ;;
+ interix*)
+ # we just hope/assume this is gcc and not c89 (= MSVC++)
+ with_gnu_ld=yes
+ ;;
+ openbsd*)
+ with_gnu_ld=no
+ ;;
+ linux* | k*bsd*-gnu)
+ _LT_TAGVAR(link_all_deplibs, $1)=no
+ ;;
+ esac
+
+ _LT_TAGVAR(ld_shlibs, $1)=yes
+ if test "$with_gnu_ld" = yes; then
+ # If archive_cmds runs LD, not CC, wlarc should be empty
+ wlarc='${wl}'
+
+ # Set some defaults for GNU ld with shared library support. These
+ # are reset later if shared libraries are not supported. Putting them
+ # here allows them to be overridden if necessary.
+ runpath_var=LD_RUN_PATH
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
+ # ancient GNU ld didn't support --whole-archive et. al.
+ if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then
+ _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+ else
+ _LT_TAGVAR(whole_archive_flag_spec, $1)=
+ fi
+ supports_anon_versioning=no
+ case `$LD -v 2>&1` in
+ *GNU\ gold*) supports_anon_versioning=yes ;;
+ *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.10.*) ;; # catch versions < 2.11
+ *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ...
+ *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ...
+ *\ 2.11.*) ;; # other 2.11 versions
+ *) supports_anon_versioning=yes ;;
+ esac
+
+ # See if GNU ld supports shared libraries.
+ case $host_os in
+ aix[[3-9]]*)
+ # On AIX/PPC, the GNU linker is very broken
+ if test "$host_cpu" != ia64; then
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ cat <<_LT_EOF 1>&2
+
+*** Warning: the GNU linker, at least up to release 2.9.1, is reported
+*** to be unable to reliably create shared libraries on AIX.
+*** Therefore, libtool is disabling shared libraries support. If you
+*** really care for shared libraries, you may want to modify your PATH
+*** so that a non-GNU linker is found, and then restart.
+
+_LT_EOF
+ fi
+ ;;
+
+ amigaos*)
+ case $host_cpu in
+ powerpc)
+ # see comment about AmigaOS4 .so support
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)=''
+ ;;
+ m68k)
+ _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ ;;
+ esac
+ ;;
+
+ beos*)
+ if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+ # Joseph Beckenbach <jrb3@best.com> says some releases of gcc
+ # support --undefined. This deserves some investigation. FIXME
+ _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+
+ cygwin* | mingw* | pw32* | cegcc*)
+ # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless,
+ # as there is no search path for DLLs.
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+ _LT_TAGVAR(always_export_symbols, $1)=no
+ _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+ _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/'\'' | $SED -e '\''/^[[AITW]][[ ]]/s/.*[[ ]]//'\'' | sort | uniq > $export_symbols'
+
+ if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+ # If the export-symbols file already is a .def file (1st line
+ # is EXPORTS), use it as is; otherwise, prepend...
+ _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+ cp $export_symbols $output_objdir/$soname.def;
+ else
+ echo EXPORTS > $output_objdir/$soname.def;
+ cat $export_symbols >> $output_objdir/$soname.def;
+ fi~
+ $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+
+ interix[[3-9]]*)
+ _LT_TAGVAR(hardcode_direct, $1)=no
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+ # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.
+ # Instead, shared libraries are loaded at an image base (0x10000000 by
+ # default) and relocated if they conflict, which is a slow very memory
+ # consuming and fragmenting process. To avoid this, we pick a random,
+ # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
+ # time. Moving up from 0x10000000 also allows more sbrk(2) space.
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+ ;;
+
+ gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu)
+ tmp_diet=no
+ if test "$host_os" = linux-dietlibc; then
+ case $cc_basename in
+ diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn)
+ esac
+ fi
+ if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \
+ && test "$tmp_diet" = no
+ then
+ tmp_addflag=
+ tmp_sharedflag='-shared'
+ case $cc_basename,$host_cpu in
+ pgcc*) # Portland Group C compiler
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive'
+ tmp_addflag=' $pic_flag'
+ ;;
+ pgf77* | pgf90* | pgf95*) # Portland Group f77 and f90 compilers
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive'
+ tmp_addflag=' $pic_flag -Mnomain' ;;
+ ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64
+ tmp_addflag=' -i_dynamic' ;;
+ efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64
+ tmp_addflag=' -i_dynamic -nofor_main' ;;
+ ifc* | ifort*) # Intel Fortran compiler
+ tmp_addflag=' -nofor_main' ;;
+ lf95*) # Lahey Fortran 8.1
+ _LT_TAGVAR(whole_archive_flag_spec, $1)=
+ tmp_sharedflag='--shared' ;;
+ xl[[cC]]*) # IBM XL C 8.0 on PPC (deal with xlf below)
+ tmp_sharedflag='-qmkshrobj'
+ tmp_addflag= ;;
+ esac
+ case `$CC -V 2>&1 | sed 5q` in
+ *Sun\ C*) # Sun C 5.9
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive'
+ _LT_TAGVAR(compiler_needs_object, $1)=yes
+ tmp_sharedflag='-G' ;;
+ *Sun\ F*) # Sun Fortran 8.3
+ tmp_sharedflag='-G' ;;
+ esac
+ _LT_TAGVAR(archive_cmds, $1)='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+
+ if test "x$supports_anon_versioning" = xyes; then
+ _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~
+ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+ echo "local: *; };" >> $output_objdir/$libname.ver~
+ $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib'
+ fi
+
+ case $cc_basename in
+ xlf*)
+ # IBM XL Fortran 10.1 on PPC cannot create shared libs itself
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='--whole-archive$convenience --no-whole-archive'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
+ _LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='-rpath $libdir'
+ _LT_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $compiler_flags -soname $soname -o $lib'
+ if test "x$supports_anon_versioning" = xyes; then
+ _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~
+ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+ echo "local: *; };" >> $output_objdir/$libname.ver~
+ $LD -shared $libobjs $deplibs $compiler_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib'
+ fi
+ ;;
+ esac
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+
+ netbsd* | netbsdelf*-gnu)
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+ _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib'
+ wlarc=
+ else
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ fi
+ ;;
+
+ solaris*)
+ if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ cat <<_LT_EOF 1>&2
+
+*** Warning: The releases 2.8.* of the GNU linker cannot reliably
+*** create shared libraries on Solaris systems. Therefore, libtool
+*** is disabling shared libraries support. We urge you to upgrade GNU
+*** binutils to release 2.9.1 or newer. Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+_LT_EOF
+ elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+
+ sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*)
+ case `$LD -v 2>&1` in
+ *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.1[[0-5]].*)
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ cat <<_LT_EOF 1>&2
+
+*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not
+*** reliably create shared libraries on SCO systems. Therefore, libtool
+*** is disabling shared libraries support. We urge you to upgrade GNU
+*** binutils to release 2.16.91.0.3 or newer. Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+_LT_EOF
+ ;;
+ *)
+ # For security reasons, it is highly recommended that you always
+ # use absolute paths for naming shared libraries, and exclude the
+ # DT_RUNPATH tag from executables and libraries. But doing so
+ # requires that you compile everything twice, which is a pain.
+ if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+ esac
+ ;;
+
+ sunos4*)
+ _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+ wlarc=
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ *)
+ if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+ esac
+
+ if test "$_LT_TAGVAR(ld_shlibs, $1)" = no; then
+ runpath_var=
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)=
+ _LT_TAGVAR(whole_archive_flag_spec, $1)=
+ fi
+ else
+ # PORTME fill in a description of your system's linker (not GNU ld)
+ case $host_os in
+ aix3*)
+ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+ _LT_TAGVAR(always_export_symbols, $1)=yes
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname'
+ # Note: this linker hardcodes the directories in LIBPATH if there
+ # are no directories specified by -L.
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then
+ # Neither direct hardcoding nor static linking is supported with a
+ # broken collect2.
+ _LT_TAGVAR(hardcode_direct, $1)=unsupported
+ fi
+ ;;
+
+ aix[[4-9]]*)
+ if test "$host_cpu" = ia64; then
+ # On IA64, the linker does run time linking by default, so we don't
+ # have to do anything special.
+ aix_use_runtimelinking=no
+ exp_sym_flag='-Bexport'
+ no_entry_flag=""
+ else
+ # If we're using GNU nm, then we don't want the "-C" option.
+ # -C means demangle to AIX nm, but means don't demangle with GNU nm
+ if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
+ _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
+ else
+ _LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
+ fi
+ aix_use_runtimelinking=no
+
+ # Test if we are trying to use run time linking or normal
+ # AIX style linking. If -brtl is somewhere in LDFLAGS, we
+ # need to do runtime linking.
+ case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*)
+ for ld_flag in $LDFLAGS; do
+ if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then
+ aix_use_runtimelinking=yes
+ break
+ fi
+ done
+ ;;
+ esac
+
+ exp_sym_flag='-bexport'
+ no_entry_flag='-bnoentry'
+ fi
+
+ # When large executables or shared objects are built, AIX ld can
+ # have problems creating the table of contents. If linking a library
+ # or program results in "error TOC overflow" add -mminimal-toc to
+ # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not
+ # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.
+
+ _LT_TAGVAR(archive_cmds, $1)=''
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=':'
+ _LT_TAGVAR(link_all_deplibs, $1)=yes
+ _LT_TAGVAR(file_list_spec, $1)='${wl}-f,'
+
+ if test "$GCC" = yes; then
+ case $host_os in aix4.[[012]]|aix4.[[012]].*)
+ # We only want to do this on AIX 4.2 and lower, the check
+ # below for broken collect2 doesn't work under 4.3+
+ collect2name=`${CC} -print-prog-name=collect2`
+ if test -f "$collect2name" &&
+ strings "$collect2name" | $GREP resolve_lib_name >/dev/null
+ then
+ # We have reworked collect2
+ :
+ else
+ # We have old collect2
+ _LT_TAGVAR(hardcode_direct, $1)=unsupported
+ # It fails to find uninstalled libraries when the uninstalled
+ # path is not listed in the libpath. Setting hardcode_minus_L
+ # to unsupported forces relinking
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=
+ fi
+ ;;
+ esac
+ shared_flag='-shared'
+ if test "$aix_use_runtimelinking" = yes; then
+ shared_flag="$shared_flag "'${wl}-G'
+ fi
+ _LT_TAGVAR(link_all_deplibs, $1)=no
+ else
+ # not using gcc
+ if test "$host_cpu" = ia64; then
+ # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
+ # chokes on -Wl,-G. The following line is correct:
+ shared_flag='-G'
+ else
+ if test "$aix_use_runtimelinking" = yes; then
+ shared_flag='${wl}-G'
+ else
+ shared_flag='${wl}-bM:SRE'
+ fi
+ fi
+ fi
+
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-bexpall'
+ # It seems that -bexpall does not export symbols beginning with
+ # underscore (_), so it is better to generate a list of symbols to export.
+ _LT_TAGVAR(always_export_symbols, $1)=yes
+ if test "$aix_use_runtimelinking" = yes; then
+ # Warning - without using the other runtime loading flags (-brtl),
+ # -berok will link without error, but may produce a broken library.
+ _LT_TAGVAR(allow_undefined_flag, $1)='-berok'
+ # Determine the default libpath from the value encoded in an
+ # empty executable.
+ _LT_SYS_MODULE_PATH_AIX
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath"
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then $ECHO "X${wl}${allow_undefined_flag}" | $Xsed; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag"
+ else
+ if test "$host_cpu" = ia64; then
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib'
+ _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs"
+ _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols"
+ else
+ # Determine the default libpath from the value encoded in an
+ # empty executable.
+ _LT_SYS_MODULE_PATH_AIX
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath"
+ # Warning - without using the other run time loading flags,
+ # -berok will link without error, but may produce a broken library.
+ _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok'
+ _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok'
+ # Exported symbols can be pulled into shared objects from archives
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience'
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=yes
+ # This is similar to how AIX traditionally builds its shared libraries.
+ _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
+ fi
+ fi
+ ;;
+
+ amigaos*)
+ case $host_cpu in
+ powerpc)
+ # see comment about AmigaOS4 .so support
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)=''
+ ;;
+ m68k)
+ _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ ;;
+ esac
+ ;;
+
+ bsdi[[45]]*)
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)=-rdynamic
+ ;;
+
+ cygwin* | mingw* | pw32* | cegcc*)
+ # When not using gcc, we currently assume that we are using
+ # Microsoft Visual C++.
+ # hardcode_libdir_flag_spec is actually meaningless, as there is
+ # no search path for DLLs.
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' '
+ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+ # Tell ltmain to make .lib files, not .a files.
+ libext=lib
+ # Tell ltmain to make .dll files, not .so files.
+ shrext_cmds=".dll"
+ # FIXME: Setting linknames here is a bad hack.
+ _LT_TAGVAR(archive_cmds, $1)='$CC -o $lib $libobjs $compiler_flags `$ECHO "X$deplibs" | $Xsed -e '\''s/ -lc$//'\''` -link -dll~linknames='
+ # The linker will automatically build a .lib file if we build a DLL.
+ _LT_TAGVAR(old_archive_from_new_cmds, $1)='true'
+ # FIXME: Should let the user specify the lib program.
+ _LT_TAGVAR(old_archive_cmds, $1)='lib -OUT:$oldlib$oldobjs$old_deplibs'
+ _LT_TAGVAR(fix_srcfile_path, $1)='`cygpath -w "$srcfile"`'
+ _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+ ;;
+
+ darwin* | rhapsody*)
+ _LT_DARWIN_LINKER_FEATURES($1)
+ ;;
+
+ dgux*)
+ _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ freebsd1*)
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+
+ # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor
+ # support. Future versions do this automatically, but an explicit c++rt0.o
+ # does not break anything, and helps significantly (at the cost of a little
+ # extra space).
+ freebsd2.2*)
+ _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ # Unfortunately, older versions of FreeBSD 2 do not have this feature.
+ freebsd2*)
+ _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ # FreeBSD 3 and greater uses gcc -shared to do shared libraries.
+ freebsd* | dragonfly*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ hpux9*)
+ if test "$GCC" = yes; then
+ _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+ else
+ _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+ fi
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+
+ # hardcode_minus_L: Not really in the search PATH,
+ # but as the default location of the library.
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+ ;;
+
+ hpux10*)
+ if test "$GCC" = yes -a "$with_gnu_ld" = no; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+ else
+ _LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'
+ fi
+ if test "$with_gnu_ld" = no; then
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
+ _LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='+b $libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+ # hardcode_minus_L: Not really in the search PATH,
+ # but as the default location of the library.
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ fi
+ ;;
+
+ hpux11*)
+ if test "$GCC" = yes -a "$with_gnu_ld" = no; then
+ case $host_cpu in
+ hppa*64*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ ia64*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ *)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ esac
+ else
+ case $host_cpu in
+ hppa*64*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ ia64*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ *)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ esac
+ fi
+ if test "$with_gnu_ld" = no; then
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+
+ case $host_cpu in
+ hppa*64*|ia64*)
+ _LT_TAGVAR(hardcode_direct, $1)=no
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+ *)
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+
+ # hardcode_minus_L: Not really in the search PATH,
+ # but as the default location of the library.
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ ;;
+ esac
+ fi
+ ;;
+
+ irix5* | irix6* | nonstopux*)
+ if test "$GCC" = yes; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ # Try to use the -exported_symbol ld option, if it does not
+ # work, assume that -exports_file does not work either and
+ # implicitly export all symbols.
+ save_LDFLAGS="$LDFLAGS"
+ LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null"
+ AC_LINK_IFELSE(int foo(void) {},
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib'
+ )
+ LDFLAGS="$save_LDFLAGS"
+ else
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib'
+ fi
+ _LT_TAGVAR(archive_cmds_need_lc, $1)='no'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+ _LT_TAGVAR(inherit_rpath, $1)=yes
+ _LT_TAGVAR(link_all_deplibs, $1)=yes
+ ;;
+
+ netbsd* | netbsdelf*-gnu)
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+ _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out
+ else
+ _LT_TAGVAR(archive_cmds, $1)='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF
+ fi
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ newsos6)
+ _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ *nto* | *qnx*)
+ ;;
+
+ openbsd*)
+ if test -f /usr/libexec/ld.so; then
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+ if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+ else
+ case $host_os in
+ openbsd[[01]].* | openbsd2.[[0-7]] | openbsd2.[[0-7]].*)
+ _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+ ;;
+ *)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+ ;;
+ esac
+ fi
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+
+ os2*)
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+ _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~$ECHO DATA >> $output_objdir/$libname.def~$ECHO " SINGLE NONSHARED" >> $output_objdir/$libname.def~$ECHO EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def'
+ _LT_TAGVAR(old_archive_from_new_cmds, $1)='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def'
+ ;;
+
+ osf3*)
+ if test "$GCC" = yes; then
+ _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ else
+ _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib'
+ fi
+ _LT_TAGVAR(archive_cmds_need_lc, $1)='no'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+ ;;
+
+ osf4* | osf5*) # as osf3* with the addition of -msym flag
+ if test "$GCC" = yes; then
+ _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+ else
+ _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~
+ $CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp'
+
+ # Both c and cxx compiler support -rpath directly
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir'
+ fi
+ _LT_TAGVAR(archive_cmds_need_lc, $1)='no'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+ ;;
+
+ solaris*)
+ _LT_TAGVAR(no_undefined_flag, $1)=' -z defs'
+ if test "$GCC" = yes; then
+ wlarc='${wl}'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $CC -shared ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
+ else
+ case `$CC -V 2>&1` in
+ *"Compilers 5.0"*)
+ wlarc=''
+ _LT_TAGVAR(archive_cmds, $1)='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp'
+ ;;
+ *)
+ wlarc='${wl}'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $CC -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
+ ;;
+ esac
+ fi
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ case $host_os in
+ solaris2.[[0-5]] | solaris2.[[0-5]].*) ;;
+ *)
+ # The compiler driver will combine and reorder linker options,
+ # but understands `-z linker_flag'. GCC discards it without `$wl',
+ # but is careful enough not to reorder.
+ # Supported since Solaris 2.6 (maybe 2.5.1?)
+ if test "$GCC" = yes; then
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract'
+ else
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract'
+ fi
+ ;;
+ esac
+ _LT_TAGVAR(link_all_deplibs, $1)=yes
+ ;;
+
+ sunos4*)
+ if test "x$host_vendor" = xsequent; then
+ # Use $CC to link under sequent, because it throws in some extra .o
+ # files that make .init and .fini sections work.
+ _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags'
+ else
+ _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags'
+ fi
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ sysv4)
+ case $host_vendor in
+ sni)
+ _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(hardcode_direct, $1)=yes # is this really true???
+ ;;
+ siemens)
+ ## LD is ld it makes a PLAMLIB
+ ## CC just makes a GrossModule.
+ _LT_TAGVAR(archive_cmds, $1)='$LD -G -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(reload_cmds, $1)='$CC -r -o $output$reload_objs'
+ _LT_TAGVAR(hardcode_direct, $1)=no
+ ;;
+ motorola)
+ _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(hardcode_direct, $1)=no #Motorola manual says yes, but my tests say they lie
+ ;;
+ esac
+ runpath_var='LD_RUN_PATH'
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ sysv4.3*)
+ _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='-Bexport'
+ ;;
+
+ sysv4*MP*)
+ if test -d /usr/nec; then
+ _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ runpath_var=LD_RUN_PATH
+ hardcode_runpath_var=yes
+ _LT_TAGVAR(ld_shlibs, $1)=yes
+ fi
+ ;;
+
+ sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*)
+ _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text'
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ runpath_var='LD_RUN_PATH'
+
+ if test "$GCC" = yes; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ else
+ _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ fi
+ ;;
+
+ sysv5* | sco3.2v5* | sco5v6*)
+ # Note: We can NOT use -z defs as we might desire, because we do not
+ # link with -lc, and that would cause any symbols used from libc to
+ # always be unresolved, which means just about no library would
+ # ever link correctly. If we're not using GNU ld we use -z text
+ # though, which does catch some bad symbols but isn't as heavy-handed
+ # as -z defs.
+ _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text'
+ _LT_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs'
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R,$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=':'
+ _LT_TAGVAR(link_all_deplibs, $1)=yes
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport'
+ runpath_var='LD_RUN_PATH'
+
+ if test "$GCC" = yes; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ else
+ _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ fi
+ ;;
+
+ uts4*)
+ _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ *)
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ esac
+
+ if test x$host_vendor = xsni; then
+ case $host in
+ sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Blargedynsym'
+ ;;
+ esac
+ fi
+ fi
+])
+AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)])
+test "$_LT_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no
+
+_LT_TAGVAR(with_gnu_ld, $1)=$with_gnu_ld
+
+_LT_DECL([], [libext], [0], [Old archive suffix (normally "a")])dnl
+_LT_DECL([], [shrext_cmds], [1], [Shared library suffix (normally ".so")])dnl
+_LT_DECL([], [extract_expsyms_cmds], [2],
+ [The commands to extract the exported symbol list from a shared archive])
+
+#
+# Do we need to explicitly link libc?
+#
+case "x$_LT_TAGVAR(archive_cmds_need_lc, $1)" in
+x|xyes)
+ # Assume -lc should be added
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=yes
+
+ if test "$enable_shared" = yes && test "$GCC" = yes; then
+ case $_LT_TAGVAR(archive_cmds, $1) in
+ *'~'*)
+ # FIXME: we may have to deal with multi-command sequences.
+ ;;
+ '$CC '*)
+ # Test whether the compiler implicitly links with -lc since on some
+ # systems, -lgcc has to come before -lc. If gcc already passes -lc
+ # to ld, don't add -lc before -lgcc.
+ AC_MSG_CHECKING([whether -lc should be explicitly linked in])
+ $RM conftest*
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+ if AC_TRY_EVAL(ac_compile) 2>conftest.err; then
+ soname=conftest
+ lib=conftest
+ libobjs=conftest.$ac_objext
+ deplibs=
+ wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1)
+ pic_flag=$_LT_TAGVAR(lt_prog_compiler_pic, $1)
+ compiler_flags=-v
+ linker_flags=-v
+ verstring=
+ output_objdir=.
+ libname=conftest
+ lt_save_allow_undefined_flag=$_LT_TAGVAR(allow_undefined_flag, $1)
+ _LT_TAGVAR(allow_undefined_flag, $1)=
+ if AC_TRY_EVAL(_LT_TAGVAR(archive_cmds, $1) 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1)
+ then
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+ else
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=yes
+ fi
+ _LT_TAGVAR(allow_undefined_flag, $1)=$lt_save_allow_undefined_flag
+ else
+ cat conftest.err 1>&5
+ fi
+ $RM conftest*
+ AC_MSG_RESULT([$_LT_TAGVAR(archive_cmds_need_lc, $1)])
+ ;;
+ esac
+ fi
+ ;;
+esac
+
+_LT_TAGDECL([build_libtool_need_lc], [archive_cmds_need_lc], [0],
+ [Whether or not to add -lc for building shared libraries])
+_LT_TAGDECL([allow_libtool_libs_with_static_runtimes],
+ [enable_shared_with_static_runtimes], [0],
+ [Whether or not to disallow shared libs when runtime libs are static])
+_LT_TAGDECL([], [export_dynamic_flag_spec], [1],
+ [Compiler flag to allow reflexive dlopens])
+_LT_TAGDECL([], [whole_archive_flag_spec], [1],
+ [Compiler flag to generate shared objects directly from archives])
+_LT_TAGDECL([], [compiler_needs_object], [1],
+ [Whether the compiler copes with passing no objects directly])
+_LT_TAGDECL([], [old_archive_from_new_cmds], [2],
+ [Create an old-style archive from a shared archive])
+_LT_TAGDECL([], [old_archive_from_expsyms_cmds], [2],
+ [Create a temporary old-style archive to link instead of a shared archive])
+_LT_TAGDECL([], [archive_cmds], [2], [Commands used to build a shared archive])
+_LT_TAGDECL([], [archive_expsym_cmds], [2])
+_LT_TAGDECL([], [module_cmds], [2],
+ [Commands used to build a loadable module if different from building
+ a shared archive.])
+_LT_TAGDECL([], [module_expsym_cmds], [2])
+_LT_TAGDECL([], [with_gnu_ld], [1],
+ [Whether we are building with GNU ld or not])
+_LT_TAGDECL([], [allow_undefined_flag], [1],
+ [Flag that allows shared libraries with undefined symbols to be built])
+_LT_TAGDECL([], [no_undefined_flag], [1],
+ [Flag that enforces no undefined symbols])
+_LT_TAGDECL([], [hardcode_libdir_flag_spec], [1],
+ [Flag to hardcode $libdir into a binary during linking.
+ This must work even if $libdir does not exist])
+_LT_TAGDECL([], [hardcode_libdir_flag_spec_ld], [1],
+ [[If ld is used when linking, flag to hardcode $libdir into a binary
+ during linking. This must work even if $libdir does not exist]])
+_LT_TAGDECL([], [hardcode_libdir_separator], [1],
+ [Whether we need a single "-rpath" flag with a separated argument])
+_LT_TAGDECL([], [hardcode_direct], [0],
+ [Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes
+ DIR into the resulting binary])
+_LT_TAGDECL([], [hardcode_direct_absolute], [0],
+ [Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes
+ DIR into the resulting binary and the resulting library dependency is
+ "absolute", i.e impossible to change by setting ${shlibpath_var} if the
+ library is relocated])
+_LT_TAGDECL([], [hardcode_minus_L], [0],
+ [Set to "yes" if using the -LDIR flag during linking hardcodes DIR
+ into the resulting binary])
+_LT_TAGDECL([], [hardcode_shlibpath_var], [0],
+ [Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR
+ into the resulting binary])
+_LT_TAGDECL([], [hardcode_automatic], [0],
+ [Set to "yes" if building a shared library automatically hardcodes DIR
+ into the library and all subsequent libraries and executables linked
+ against it])
+_LT_TAGDECL([], [inherit_rpath], [0],
+ [Set to yes if linker adds runtime paths of dependent libraries
+ to runtime path list])
+_LT_TAGDECL([], [link_all_deplibs], [0],
+ [Whether libtool must link a program against all its dependency libraries])
+_LT_TAGDECL([], [fix_srcfile_path], [1],
+ [Fix the shell variable $srcfile for the compiler])
+_LT_TAGDECL([], [always_export_symbols], [0],
+ [Set to "yes" if exported symbols are required])
+_LT_TAGDECL([], [export_symbols_cmds], [2],
+ [The commands to list exported symbols])
+_LT_TAGDECL([], [exclude_expsyms], [1],
+ [Symbols that should not be listed in the preloaded symbols])
+_LT_TAGDECL([], [include_expsyms], [1],
+ [Symbols that must always be exported])
+_LT_TAGDECL([], [prelink_cmds], [2],
+ [Commands necessary for linking programs (against libraries) with templates])
+_LT_TAGDECL([], [file_list_spec], [1],
+ [Specify filename containing input files])
+dnl FIXME: Not yet implemented
+dnl _LT_TAGDECL([], [thread_safe_flag_spec], [1],
+dnl [Compiler flag to generate thread safe objects])
+])# _LT_LINKER_SHLIBS
+
+
+# _LT_LANG_C_CONFIG([TAG])
+# ------------------------
+# Ensure that the configuration variables for a C compiler are suitably
+# defined. These variables are subsequently used by _LT_CONFIG to write
+# the compiler configuration to `libtool'.
+m4_defun([_LT_LANG_C_CONFIG],
+[m4_require([_LT_DECL_EGREP])dnl
+lt_save_CC="$CC"
+AC_LANG_PUSH(C)
+
+# Source file extension for C test sources.
+ac_ext=c
+
+# Object file extension for compiled C test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code="int some_variable = 0;"
+
+# Code to be used in simple link tests
+lt_simple_link_test_code='int main(){return(0);}'
+
+_LT_TAG_COMPILER
+# Save the default compiler, since it gets overwritten when the other
+# tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP.
+compiler_DEFAULT=$CC
+
+# save warnings/boilerplate of simple test code
+_LT_COMPILER_BOILERPLATE
+_LT_LINKER_BOILERPLATE
+
+## CAVEAT EMPTOR:
+## There is no encapsulation within the following macros, do not change
+## the running order or otherwise move them around unless you know exactly
+## what you are doing...
+if test -n "$compiler"; then
+ _LT_COMPILER_NO_RTTI($1)
+ _LT_COMPILER_PIC($1)
+ _LT_COMPILER_C_O($1)
+ _LT_COMPILER_FILE_LOCKS($1)
+ _LT_LINKER_SHLIBS($1)
+ _LT_SYS_DYNAMIC_LINKER($1)
+ _LT_LINKER_HARDCODE_LIBPATH($1)
+ LT_SYS_DLOPEN_SELF
+ _LT_CMD_STRIPLIB
+
+ # Report which library types will actually be built
+ AC_MSG_CHECKING([if libtool supports shared libraries])
+ AC_MSG_RESULT([$can_build_shared])
+
+ AC_MSG_CHECKING([whether to build shared libraries])
+ test "$can_build_shared" = "no" && enable_shared=no
+
+ # On AIX, shared libraries and static libraries use the same namespace, and
+ # are all built from PIC.
+ case $host_os in
+ aix3*)
+ test "$enable_shared" = yes && enable_static=no
+ if test -n "$RANLIB"; then
+ archive_cmds="$archive_cmds~\$RANLIB \$lib"
+ postinstall_cmds='$RANLIB $lib'
+ fi
+ ;;
+
+ aix[[4-9]]*)
+ if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then
+ test "$enable_shared" = yes && enable_static=no
+ fi
+ ;;
+ esac
+ AC_MSG_RESULT([$enable_shared])
+
+ AC_MSG_CHECKING([whether to build static libraries])
+ # Make sure either enable_shared or enable_static is yes.
+ test "$enable_shared" = yes || enable_static=yes
+ AC_MSG_RESULT([$enable_static])
+
+ _LT_CONFIG($1)
+fi
+AC_LANG_POP
+CC="$lt_save_CC"
+])# _LT_LANG_C_CONFIG
+
+
+# _LT_PROG_CXX
+# ------------
+# Since AC_PROG_CXX is broken, in that it returns g++ if there is no c++
+# compiler, we have our own version here.
+m4_defun([_LT_PROG_CXX],
+[
+pushdef([AC_MSG_ERROR], [_lt_caught_CXX_error=yes])
+AC_PROG_CXX
+if test -n "$CXX" && ( test "X$CXX" != "Xno" &&
+ ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) ||
+ (test "X$CXX" != "Xg++"))) ; then
+ AC_PROG_CXXCPP
+else
+ _lt_caught_CXX_error=yes
+fi
+popdef([AC_MSG_ERROR])
+])# _LT_PROG_CXX
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([_LT_PROG_CXX], [])
+
+
+# _LT_LANG_CXX_CONFIG([TAG])
+# --------------------------
+# Ensure that the configuration variables for a C++ compiler are suitably
+# defined. These variables are subsequently used by _LT_CONFIG to write
+# the compiler configuration to `libtool'.
+m4_defun([_LT_LANG_CXX_CONFIG],
+[AC_REQUIRE([_LT_PROG_CXX])dnl
+m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_DECL_EGREP])dnl
+
+AC_LANG_PUSH(C++)
+_LT_TAGVAR(archive_cmds_need_lc, $1)=no
+_LT_TAGVAR(allow_undefined_flag, $1)=
+_LT_TAGVAR(always_export_symbols, $1)=no
+_LT_TAGVAR(archive_expsym_cmds, $1)=
+_LT_TAGVAR(compiler_needs_object, $1)=no
+_LT_TAGVAR(export_dynamic_flag_spec, $1)=
+_LT_TAGVAR(hardcode_direct, $1)=no
+_LT_TAGVAR(hardcode_direct_absolute, $1)=no
+_LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
+_LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)=
+_LT_TAGVAR(hardcode_libdir_separator, $1)=
+_LT_TAGVAR(hardcode_minus_L, $1)=no
+_LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported
+_LT_TAGVAR(hardcode_automatic, $1)=no
+_LT_TAGVAR(inherit_rpath, $1)=no
+_LT_TAGVAR(module_cmds, $1)=
+_LT_TAGVAR(module_expsym_cmds, $1)=
+_LT_TAGVAR(link_all_deplibs, $1)=unknown
+_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
+_LT_TAGVAR(no_undefined_flag, $1)=
+_LT_TAGVAR(whole_archive_flag_spec, $1)=
+_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no
+
+# Source file extension for C++ test sources.
+ac_ext=cpp
+
+# Object file extension for compiled C++ test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# No sense in running all these tests if we already determined that
+# the CXX compiler isn't working. Some variables (like enable_shared)
+# are currently assumed to apply to all compilers on this platform,
+# and will be corrupted by setting them based on a non-working compiler.
+if test "$_lt_caught_CXX_error" != yes; then
+ # Code to be used in simple compile tests
+ lt_simple_compile_test_code="int some_variable = 0;"
+
+ # Code to be used in simple link tests
+ lt_simple_link_test_code='int main(int, char *[[]]) { return(0); }'
+
+ # ltmain only uses $CC for tagged configurations so make sure $CC is set.
+ _LT_TAG_COMPILER
+
+ # save warnings/boilerplate of simple test code
+ _LT_COMPILER_BOILERPLATE
+ _LT_LINKER_BOILERPLATE
+
+ # Allow CC to be a program name with arguments.
+ lt_save_CC=$CC
+ lt_save_LD=$LD
+ lt_save_GCC=$GCC
+ GCC=$GXX
+ lt_save_with_gnu_ld=$with_gnu_ld
+ lt_save_path_LD=$lt_cv_path_LD
+ if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then
+ lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx
+ else
+ $as_unset lt_cv_prog_gnu_ld
+ fi
+ if test -n "${lt_cv_path_LDCXX+set}"; then
+ lt_cv_path_LD=$lt_cv_path_LDCXX
+ else
+ $as_unset lt_cv_path_LD
+ fi
+ test -z "${LDCXX+set}" || LD=$LDCXX
+ CC=${CXX-"c++"}
+ compiler=$CC
+ _LT_TAGVAR(compiler, $1)=$CC
+ _LT_CC_BASENAME([$compiler])
+
+ if test -n "$compiler"; then
+ # We don't want -fno-exception when compiling C++ code, so set the
+ # no_builtin_flag separately
+ if test "$GXX" = yes; then
+ _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin'
+ else
+ _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=
+ fi
+
+ if test "$GXX" = yes; then
+ # Set up default GNU C++ configuration
+
+ LT_PATH_LD
+
+ # Check if GNU C++ uses GNU ld as the underlying linker, since the
+ # archiving commands below assume that GNU ld is being used.
+ if test "$with_gnu_ld" = yes; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
+
+ # If archive_cmds runs LD, not CC, wlarc should be empty
+ # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to
+ # investigate it a little bit more. (MM)
+ wlarc='${wl}'
+
+ # ancient GNU ld didn't support --whole-archive et. al.
+ if eval "`$CC -print-prog-name=ld` --help 2>&1" |
+ $GREP 'no-whole-archive' > /dev/null; then
+ _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+ else
+ _LT_TAGVAR(whole_archive_flag_spec, $1)=
+ fi
+ else
+ with_gnu_ld=no
+ wlarc=
+
+ # A generic and very simple default shared library creation
+ # command for GNU C++ for the case where it uses the native
+ # linker, instead of GNU ld. If possible, this setting should
+ # overridden to take advantage of the native linker features on
+ # the platform it is being used on.
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib'
+ fi
+
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "\-L"'
+
+ else
+ GXX=no
+ with_gnu_ld=no
+ wlarc=
+ fi
+
+ # PORTME: fill in a description of your system's C++ link characteristics
+ AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries])
+ _LT_TAGVAR(ld_shlibs, $1)=yes
+ case $host_os in
+ aix3*)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ aix[[4-9]]*)
+ if test "$host_cpu" = ia64; then
+ # On IA64, the linker does run time linking by default, so we don't
+ # have to do anything special.
+ aix_use_runtimelinking=no
+ exp_sym_flag='-Bexport'
+ no_entry_flag=""
+ else
+ aix_use_runtimelinking=no
+
+ # Test if we are trying to use run time linking or normal
+ # AIX style linking. If -brtl is somewhere in LDFLAGS, we
+ # need to do runtime linking.
+ case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*)
+ for ld_flag in $LDFLAGS; do
+ case $ld_flag in
+ *-brtl*)
+ aix_use_runtimelinking=yes
+ break
+ ;;
+ esac
+ done
+ ;;
+ esac
+
+ exp_sym_flag='-bexport'
+ no_entry_flag='-bnoentry'
+ fi
+
+ # When large executables or shared objects are built, AIX ld can
+ # have problems creating the table of contents. If linking a library
+ # or program results in "error TOC overflow" add -mminimal-toc to
+ # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not
+ # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.
+
+ _LT_TAGVAR(archive_cmds, $1)=''
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=':'
+ _LT_TAGVAR(link_all_deplibs, $1)=yes
+ _LT_TAGVAR(file_list_spec, $1)='${wl}-f,'
+
+ if test "$GXX" = yes; then
+ case $host_os in aix4.[[012]]|aix4.[[012]].*)
+ # We only want to do this on AIX 4.2 and lower, the check
+ # below for broken collect2 doesn't work under 4.3+
+ collect2name=`${CC} -print-prog-name=collect2`
+ if test -f "$collect2name" &&
+ strings "$collect2name" | $GREP resolve_lib_name >/dev/null
+ then
+ # We have reworked collect2
+ :
+ else
+ # We have old collect2
+ _LT_TAGVAR(hardcode_direct, $1)=unsupported
+ # It fails to find uninstalled libraries when the uninstalled
+ # path is not listed in the libpath. Setting hardcode_minus_L
+ # to unsupported forces relinking
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=
+ fi
+ esac
+ shared_flag='-shared'
+ if test "$aix_use_runtimelinking" = yes; then
+ shared_flag="$shared_flag "'${wl}-G'
+ fi
+ else
+ # not using gcc
+ if test "$host_cpu" = ia64; then
+ # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
+ # chokes on -Wl,-G. The following line is correct:
+ shared_flag='-G'
+ else
+ if test "$aix_use_runtimelinking" = yes; then
+ shared_flag='${wl}-G'
+ else
+ shared_flag='${wl}-bM:SRE'
+ fi
+ fi
+ fi
+
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-bexpall'
+ # It seems that -bexpall does not export symbols beginning with
+ # underscore (_), so it is better to generate a list of symbols to
+ # export.
+ _LT_TAGVAR(always_export_symbols, $1)=yes
+ if test "$aix_use_runtimelinking" = yes; then
+ # Warning - without using the other runtime loading flags (-brtl),
+ # -berok will link without error, but may produce a broken library.
+ _LT_TAGVAR(allow_undefined_flag, $1)='-berok'
+ # Determine the default libpath from the value encoded in an empty
+ # executable.
+ _LT_SYS_MODULE_PATH_AIX
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath"
+
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then $ECHO "X${wl}${allow_undefined_flag}" | $Xsed; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag"
+ else
+ if test "$host_cpu" = ia64; then
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib'
+ _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs"
+ _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols"
+ else
+ # Determine the default libpath from the value encoded in an
+ # empty executable.
+ _LT_SYS_MODULE_PATH_AIX
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath"
+ # Warning - without using the other run time loading flags,
+ # -berok will link without error, but may produce a broken library.
+ _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok'
+ _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok'
+ # Exported symbols can be pulled into shared objects from archives
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience'
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=yes
+ # This is similar to how AIX traditionally builds its shared
+ # libraries.
+ _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
+ fi
+ fi
+ ;;
+
+ beos*)
+ if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+ # Joseph Beckenbach <jrb3@best.com> says some releases of gcc
+ # support --undefined. This deserves some investigation. FIXME
+ _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+
+ chorus*)
+ case $cc_basename in
+ *)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ esac
+ ;;
+
+ cygwin* | mingw* | pw32* | cegcc*)
+ # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless,
+ # as there is no search path for DLLs.
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+ _LT_TAGVAR(always_export_symbols, $1)=no
+ _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+
+ if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+ # If the export-symbols file already is a .def file (1st line
+ # is EXPORTS), use it as is; otherwise, prepend...
+ _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+ cp $export_symbols $output_objdir/$soname.def;
+ else
+ echo EXPORTS > $output_objdir/$soname.def;
+ cat $export_symbols >> $output_objdir/$soname.def;
+ fi~
+ $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+ darwin* | rhapsody*)
+ _LT_DARWIN_LINKER_FEATURES($1)
+ ;;
+
+ dgux*)
+ case $cc_basename in
+ ec++*)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ ghcx*)
+ # Green Hills C++ Compiler
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ *)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ esac
+ ;;
+
+ freebsd[[12]]*)
+ # C++ shared libraries reported to be fairly broken before
+ # switch to ELF
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+
+ freebsd-elf*)
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+ ;;
+
+ freebsd* | dragonfly*)
+ # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF
+ # conventions
+ _LT_TAGVAR(ld_shlibs, $1)=yes
+ ;;
+
+ gnu*)
+ ;;
+
+ hpux9*)
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH,
+ # but as the default
+ # location of the library.
+
+ case $cc_basename in
+ CC*)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ aCC*)
+ _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -b ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ #
+ # There doesn't appear to be a way to prevent this compiler from
+ # explicitly linking system object files so we need to strip them
+ # from the output so that they don't get included in the library
+ # dependencies.
+ output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed'
+ ;;
+ *)
+ if test "$GXX" = yes; then
+ _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -nostdlib -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+ else
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+ esac
+ ;;
+
+ hpux10*|hpux11*)
+ if test $with_gnu_ld = no; then
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+
+ case $host_cpu in
+ hppa*64*|ia64*)
+ ;;
+ *)
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+ ;;
+ esac
+ fi
+ case $host_cpu in
+ hppa*64*|ia64*)
+ _LT_TAGVAR(hardcode_direct, $1)=no
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+ *)
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH,
+ # but as the default
+ # location of the library.
+ ;;
+ esac
+
+ case $cc_basename in
+ CC*)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ aCC*)
+ case $host_cpu in
+ hppa*64*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ ;;
+ ia64*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ ;;
+ *)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ ;;
+ esac
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ #
+ # There doesn't appear to be a way to prevent this compiler from
+ # explicitly linking system object files so we need to strip them
+ # from the output so that they don't get included in the library
+ # dependencies.
+ output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed'
+ ;;
+ *)
+ if test "$GXX" = yes; then
+ if test $with_gnu_ld = no; then
+ case $host_cpu in
+ hppa*64*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ ;;
+ ia64*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ ;;
+ *)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ ;;
+ esac
+ fi
+ else
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+ esac
+ ;;
+
+ interix[[3-9]]*)
+ _LT_TAGVAR(hardcode_direct, $1)=no
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+ # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.
+ # Instead, shared libraries are loaded at an image base (0x10000000 by
+ # default) and relocated if they conflict, which is a slow very memory
+ # consuming and fragmenting process. To avoid this, we pick a random,
+ # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
+ # time. Moving up from 0x10000000 also allows more sbrk(2) space.
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+ ;;
+ irix5* | irix6*)
+ case $cc_basename in
+ CC*)
+ # SGI C++
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib'
+
+ # Archives containing C++ object files must be created using
+ # "CC -ar", where "CC" is the IRIX C++ compiler. This is
+ # necessary to make sure instantiated templates are included
+ # in the archive.
+ _LT_TAGVAR(old_archive_cmds, $1)='$CC -ar -WR,-u -o $oldlib $oldobjs'
+ ;;
+ *)
+ if test "$GXX" = yes; then
+ if test "$with_gnu_ld" = no; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ else
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` -o $lib'
+ fi
+ fi
+ _LT_TAGVAR(link_all_deplibs, $1)=yes
+ ;;
+ esac
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+ _LT_TAGVAR(inherit_rpath, $1)=yes
+ ;;
+
+ linux* | k*bsd*-gnu | kopensolaris*-gnu)
+ case $cc_basename in
+ KCC*)
+ # Kuck and Associates, Inc. (KAI) C++ Compiler
+
+ # KCC will only create a shared library if the output file
+ # ends with ".so" (or ".sl" for HP-UX), so rename the library
+ # to its proper name (with version) after linking.
+ _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib ${wl}-retain-symbols-file,$export_symbols; mv \$templib $lib'
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ #
+ # There doesn't appear to be a way to prevent this compiler from
+ # explicitly linking system object files so we need to strip them
+ # from the output so that they don't get included in the library
+ # dependencies.
+ output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed'
+
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
+
+ # Archives containing C++ object files must be created using
+ # "CC -Bstatic", where "CC" is the KAI C++ compiler.
+ _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs'
+ ;;
+ icpc* | ecpc* )
+ # Intel C++
+ with_gnu_ld=yes
+ # version 8.0 and above of icpc choke on multiply defined symbols
+ # if we add $predep_objects and $postdep_objects, however 7.1 and
+ # earlier do not add the objects themselves.
+ case `$CC -V 2>&1` in
+ *"Version 7."*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ ;;
+ *) # Version 8.0 or newer
+ tmp_idyn=
+ case $host_cpu in
+ ia64*) tmp_idyn=' -i_dynamic';;
+ esac
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ ;;
+ esac
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive'
+ ;;
+ pgCC* | pgcpp*)
+ # Portland Group C++ compiler
+ case `$CC -V` in
+ *pgCC\ [[1-5]]* | *pgcpp\ [[1-5]]*)
+ _LT_TAGVAR(prelink_cmds, $1)='tpldir=Template.dir~
+ rm -rf $tpldir~
+ $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~
+ compile_command="$compile_command `find $tpldir -name \*.o | $NL2SP`"'
+ _LT_TAGVAR(old_archive_cmds, $1)='tpldir=Template.dir~
+ rm -rf $tpldir~
+ $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~
+ $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | $NL2SP`~
+ $RANLIB $oldlib'
+ _LT_TAGVAR(archive_cmds, $1)='tpldir=Template.dir~
+ rm -rf $tpldir~
+ $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~
+ $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='tpldir=Template.dir~
+ rm -rf $tpldir~
+ $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~
+ $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib'
+ ;;
+ *) # Version 6 will use weak symbols
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib'
+ ;;
+ esac
+
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive'
+ ;;
+ cxx*)
+ # Compaq C++
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib ${wl}-retain-symbols-file $wl$export_symbols'
+
+ runpath_var=LD_RUN_PATH
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ #
+ # There doesn't appear to be a way to prevent this compiler from
+ # explicitly linking system object files so we need to strip them
+ # from the output so that they don't get included in the library
+ # dependencies.
+ output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`$ECHO "X$templist" | $Xsed -e "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed'
+ ;;
+ xl*)
+ # IBM XL 8.0 on PPC, with GNU ld
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ if test "x$supports_anon_versioning" = xyes; then
+ _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~
+ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+ echo "local: *; };" >> $output_objdir/$libname.ver~
+ $CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib'
+ fi
+ ;;
+ *)
+ case `$CC -V 2>&1 | sed 5q` in
+ *Sun\ C*)
+ # Sun C++ 5.9
+ _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file ${wl}$export_symbols'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive'
+ _LT_TAGVAR(compiler_needs_object, $1)=yes
+
+ # Not sure whether something based on
+ # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1
+ # would be better.
+ output_verbose_link_cmd='echo'
+
+ # Archives containing C++ object files must be created using
+ # "CC -xar", where "CC" is the Sun C++ compiler. This is
+ # necessary to make sure instantiated templates are included
+ # in the archive.
+ _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs'
+ ;;
+ esac
+ ;;
+ esac
+ ;;
+
+ lynxos*)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+
+ m88k*)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+
+ mvs*)
+ case $cc_basename in
+ cxx*)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ *)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ esac
+ ;;
+
+ netbsd*)
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+ _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags'
+ wlarc=
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ fi
+ # Workaround some broken pre-1.5 toolchains
+ output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"'
+ ;;
+
+ *nto* | *qnx*)
+ _LT_TAGVAR(ld_shlibs, $1)=yes
+ ;;
+
+ openbsd2*)
+ # C++ shared libraries are fairly broken
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+
+ openbsd*)
+ if test -f /usr/libexec/ld.so; then
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+ if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+ _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+ fi
+ output_verbose_link_cmd=echo
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+
+ osf3* | osf4* | osf5*)
+ case $cc_basename in
+ KCC*)
+ # Kuck and Associates, Inc. (KAI) C++ Compiler
+
+ # KCC will only create a shared library if the output file
+ # ends with ".so" (or ".sl" for HP-UX), so rename the library
+ # to its proper name (with version) after linking.
+ _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib'
+
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+
+ # Archives containing C++ object files must be created using
+ # the KAI C++ compiler.
+ case $host in
+ osf3*) _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' ;;
+ *) _LT_TAGVAR(old_archive_cmds, $1)='$CC -o $oldlib $oldobjs' ;;
+ esac
+ ;;
+ RCC*)
+ # Rational C++ 2.4.1
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ cxx*)
+ case $host in
+ osf3*)
+ _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && $ECHO "X${wl}-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+ ;;
+ *)
+ _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~
+ echo "-hidden">> $lib.exp~
+ $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname ${wl}-input ${wl}$lib.exp `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib~
+ $RM $lib.exp'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir'
+ ;;
+ esac
+
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ #
+ # There doesn't appear to be a way to prevent this compiler from
+ # explicitly linking system object files so we need to strip them
+ # from the output so that they don't get included in the library
+ # dependencies.
+ output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`$ECHO "X$templist" | $Xsed -e "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed'
+ ;;
+ *)
+ if test "$GXX" = yes && test "$with_gnu_ld" = no; then
+ _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*'
+ case $host in
+ osf3*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ ;;
+ *)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ ;;
+ esac
+
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "\-L"'
+
+ else
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+ esac
+ ;;
+
+ psos*)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+
+ sunos4*)
+ case $cc_basename in
+ CC*)
+ # Sun C++ 4.x
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ lcc*)
+ # Lucid
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ *)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ esac
+ ;;
+
+ solaris*)
+ case $cc_basename in
+ CC*)
+ # Sun C++ 4.2, 5.x and Centerline C++
+ _LT_TAGVAR(archive_cmds_need_lc,$1)=yes
+ _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $CC -G${allow_undefined_flag} ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
+
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ case $host_os in
+ solaris2.[[0-5]] | solaris2.[[0-5]].*) ;;
+ *)
+ # The compiler driver will combine and reorder linker options,
+ # but understands `-z linker_flag'.
+ # Supported since Solaris 2.6 (maybe 2.5.1?)
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract'
+ ;;
+ esac
+ _LT_TAGVAR(link_all_deplibs, $1)=yes
+
+ output_verbose_link_cmd='echo'
+
+ # Archives containing C++ object files must be created using
+ # "CC -xar", where "CC" is the Sun C++ compiler. This is
+ # necessary to make sure instantiated templates are included
+ # in the archive.
+ _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs'
+ ;;
+ gcx*)
+ # Green Hills C++ Compiler
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
+
+ # The C++ compiler must be used to create the archive.
+ _LT_TAGVAR(old_archive_cmds, $1)='$CC $LDFLAGS -archive -o $oldlib $oldobjs'
+ ;;
+ *)
+ # GNU C++ compiler with Solaris linker
+ if test "$GXX" = yes && test "$with_gnu_ld" = no; then
+ _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-z ${wl}defs'
+ if $CC --version | $GREP -v '^2\.7' > /dev/null; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $CC -shared -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
+
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "\-L"'
+ else
+ # g++ 2.7 appears to require `-G' NOT `-shared' on this
+ # platform.
+ _LT_TAGVAR(archive_cmds, $1)='$CC -G -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $CC -G -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
+
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP "\-L"'
+ fi
+
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $wl$libdir'
+ case $host_os in
+ solaris2.[[0-5]] | solaris2.[[0-5]].*) ;;
+ *)
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract'
+ ;;
+ esac
+ fi
+ ;;
+ esac
+ ;;
+
+ sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*)
+ _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text'
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ runpath_var='LD_RUN_PATH'
+
+ case $cc_basename in
+ CC*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ *)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ esac
+ ;;
+
+ sysv5* | sco3.2v5* | sco5v6*)
+ # Note: We can NOT use -z defs as we might desire, because we do not
+ # link with -lc, and that would cause any symbols used from libc to
+ # always be unresolved, which means just about no library would
+ # ever link correctly. If we're not using GNU ld we use -z text
+ # though, which does catch some bad symbols but isn't as heavy-handed
+ # as -z defs.
+ _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text'
+ _LT_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs'
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R,$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=':'
+ _LT_TAGVAR(link_all_deplibs, $1)=yes
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport'
+ runpath_var='LD_RUN_PATH'
+
+ case $cc_basename in
+ CC*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ *)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ esac
+ ;;
+
+ tandem*)
+ case $cc_basename in
+ NCC*)
+ # NonStop-UX NCC 3.20
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ *)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ esac
+ ;;
+
+ vxworks*)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+
+ *)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ esac
+
+ AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)])
+ test "$_LT_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no
+
+ _LT_TAGVAR(GCC, $1)="$GXX"
+ _LT_TAGVAR(LD, $1)="$LD"
+
+ ## CAVEAT EMPTOR:
+ ## There is no encapsulation within the following macros, do not change
+ ## the running order or otherwise move them around unless you know exactly
+ ## what you are doing...
+ _LT_SYS_HIDDEN_LIBDEPS($1)
+ _LT_COMPILER_PIC($1)
+ _LT_COMPILER_C_O($1)
+ _LT_COMPILER_FILE_LOCKS($1)
+ _LT_LINKER_SHLIBS($1)
+ _LT_SYS_DYNAMIC_LINKER($1)
+ _LT_LINKER_HARDCODE_LIBPATH($1)
+
+ _LT_CONFIG($1)
+ fi # test -n "$compiler"
+
+ CC=$lt_save_CC
+ LDCXX=$LD
+ LD=$lt_save_LD
+ GCC=$lt_save_GCC
+ with_gnu_ld=$lt_save_with_gnu_ld
+ lt_cv_path_LDCXX=$lt_cv_path_LD
+ lt_cv_path_LD=$lt_save_path_LD
+ lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld
+ lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld
+fi # test "$_lt_caught_CXX_error" != yes
+
+AC_LANG_POP
+])# _LT_LANG_CXX_CONFIG
+
+
+# _LT_SYS_HIDDEN_LIBDEPS([TAGNAME])
+# ---------------------------------
+# Figure out "hidden" library dependencies from verbose
+# compiler output when linking a shared library.
+# Parse the compiler output and extract the necessary
+# objects, libraries and library flags.
+m4_defun([_LT_SYS_HIDDEN_LIBDEPS],
+[m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+# Dependencies to place before and after the object being linked:
+_LT_TAGVAR(predep_objects, $1)=
+_LT_TAGVAR(postdep_objects, $1)=
+_LT_TAGVAR(predeps, $1)=
+_LT_TAGVAR(postdeps, $1)=
+_LT_TAGVAR(compiler_lib_search_path, $1)=
+
+dnl we can't use the lt_simple_compile_test_code here,
+dnl because it contains code intended for an executable,
+dnl not a library. It's possible we should let each
+dnl tag define a new lt_????_link_test_code variable,
+dnl but it's only used here...
+m4_if([$1], [], [cat > conftest.$ac_ext <<_LT_EOF
+int a;
+void foo (void) { a = 0; }
+_LT_EOF
+], [$1], [CXX], [cat > conftest.$ac_ext <<_LT_EOF
+class Foo
+{
+public:
+ Foo (void) { a = 0; }
+private:
+ int a;
+};
+_LT_EOF
+], [$1], [F77], [cat > conftest.$ac_ext <<_LT_EOF
+ subroutine foo
+ implicit none
+ integer*4 a
+ a=0
+ return
+ end
+_LT_EOF
+], [$1], [FC], [cat > conftest.$ac_ext <<_LT_EOF
+ subroutine foo
+ implicit none
+ integer a
+ a=0
+ return
+ end
+_LT_EOF
+], [$1], [GCJ], [cat > conftest.$ac_ext <<_LT_EOF
+public class foo {
+ private int a;
+ public void bar (void) {
+ a = 0;
+ }
+};
+_LT_EOF
+])
+dnl Parse the compiler output and extract the necessary
+dnl objects, libraries and library flags.
+if AC_TRY_EVAL(ac_compile); then
+ # Parse the compiler output and extract the necessary
+ # objects, libraries and library flags.
+
+ # Sentinel used to keep track of whether or not we are before
+ # the conftest object file.
+ pre_test_object_deps_done=no
+
+ for p in `eval "$output_verbose_link_cmd"`; do
+ case $p in
+
+ -L* | -R* | -l*)
+ # Some compilers place space between "-{L,R}" and the path.
+ # Remove the space.
+ if test $p = "-L" ||
+ test $p = "-R"; then
+ prev=$p
+ continue
+ else
+ prev=
+ fi
+
+ if test "$pre_test_object_deps_done" = no; then
+ case $p in
+ -L* | -R*)
+ # Internal compiler library paths should come after those
+ # provided the user. The postdeps already come after the
+ # user supplied libs so there is no need to process them.
+ if test -z "$_LT_TAGVAR(compiler_lib_search_path, $1)"; then
+ _LT_TAGVAR(compiler_lib_search_path, $1)="${prev}${p}"
+ else
+ _LT_TAGVAR(compiler_lib_search_path, $1)="${_LT_TAGVAR(compiler_lib_search_path, $1)} ${prev}${p}"
+ fi
+ ;;
+ # The "-l" case would never come before the object being
+ # linked, so don't bother handling this case.
+ esac
+ else
+ if test -z "$_LT_TAGVAR(postdeps, $1)"; then
+ _LT_TAGVAR(postdeps, $1)="${prev}${p}"
+ else
+ _LT_TAGVAR(postdeps, $1)="${_LT_TAGVAR(postdeps, $1)} ${prev}${p}"
+ fi
+ fi
+ ;;
+
+ *.$objext)
+ # This assumes that the test object file only shows up
+ # once in the compiler output.
+ if test "$p" = "conftest.$objext"; then
+ pre_test_object_deps_done=yes
+ continue
+ fi
+
+ if test "$pre_test_object_deps_done" = no; then
+ if test -z "$_LT_TAGVAR(predep_objects, $1)"; then
+ _LT_TAGVAR(predep_objects, $1)="$p"
+ else
+ _LT_TAGVAR(predep_objects, $1)="$_LT_TAGVAR(predep_objects, $1) $p"
+ fi
+ else
+ if test -z "$_LT_TAGVAR(postdep_objects, $1)"; then
+ _LT_TAGVAR(postdep_objects, $1)="$p"
+ else
+ _LT_TAGVAR(postdep_objects, $1)="$_LT_TAGVAR(postdep_objects, $1) $p"
+ fi
+ fi
+ ;;
+
+ *) ;; # Ignore the rest.
+
+ esac
+ done
+
+ # Clean up.
+ rm -f a.out a.exe
+else
+ echo "libtool.m4: error: problem compiling $1 test program"
+fi
+
+$RM -f confest.$objext
+
+# PORTME: override above test on systems where it is broken
+m4_if([$1], [CXX],
+[case $host_os in
+interix[[3-9]]*)
+ # Interix 3.5 installs completely hosed .la files for C++, so rather than
+ # hack all around it, let's just trust "g++" to DTRT.
+ _LT_TAGVAR(predep_objects,$1)=
+ _LT_TAGVAR(postdep_objects,$1)=
+ _LT_TAGVAR(postdeps,$1)=
+ ;;
+
+linux*)
+ case `$CC -V 2>&1 | sed 5q` in
+ *Sun\ C*)
+ # Sun C++ 5.9
+
+ # The more standards-conforming stlport4 library is
+ # incompatible with the Cstd library. Avoid specifying
+ # it if it's in CXXFLAGS. Ignore libCrun as
+ # -library=stlport4 depends on it.
+ case " $CXX $CXXFLAGS " in
+ *" -library=stlport4 "*)
+ solaris_use_stlport4=yes
+ ;;
+ esac
+
+ if test "$solaris_use_stlport4" != yes; then
+ _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun'
+ fi
+ ;;
+ esac
+ ;;
+
+solaris*)
+ case $cc_basename in
+ CC*)
+ # The more standards-conforming stlport4 library is
+ # incompatible with the Cstd library. Avoid specifying
+ # it if it's in CXXFLAGS. Ignore libCrun as
+ # -library=stlport4 depends on it.
+ case " $CXX $CXXFLAGS " in
+ *" -library=stlport4 "*)
+ solaris_use_stlport4=yes
+ ;;
+ esac
+
+ # Adding this requires a known-good setup of shared libraries for
+ # Sun compiler versions before 5.6, else PIC objects from an old
+ # archive will be linked into the output, leading to subtle bugs.
+ if test "$solaris_use_stlport4" != yes; then
+ _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun'
+ fi
+ ;;
+ esac
+ ;;
+esac
+])
+
+case " $_LT_TAGVAR(postdeps, $1) " in
+*" -lc "*) _LT_TAGVAR(archive_cmds_need_lc, $1)=no ;;
+esac
+ _LT_TAGVAR(compiler_lib_search_dirs, $1)=
+if test -n "${_LT_TAGVAR(compiler_lib_search_path, $1)}"; then
+ _LT_TAGVAR(compiler_lib_search_dirs, $1)=`echo " ${_LT_TAGVAR(compiler_lib_search_path, $1)}" | ${SED} -e 's! -L! !g' -e 's!^ !!'`
+fi
+_LT_TAGDECL([], [compiler_lib_search_dirs], [1],
+ [The directories searched by this compiler when creating a shared library])
+_LT_TAGDECL([], [predep_objects], [1],
+ [Dependencies to place before and after the objects being linked to
+ create a shared library])
+_LT_TAGDECL([], [postdep_objects], [1])
+_LT_TAGDECL([], [predeps], [1])
+_LT_TAGDECL([], [postdeps], [1])
+_LT_TAGDECL([], [compiler_lib_search_path], [1],
+ [The library search path used internally by the compiler when linking
+ a shared library])
+])# _LT_SYS_HIDDEN_LIBDEPS
+
+
+# _LT_PROG_F77
+# ------------
+# Since AC_PROG_F77 is broken, in that it returns the empty string
+# if there is no fortran compiler, we have our own version here.
+m4_defun([_LT_PROG_F77],
+[
+pushdef([AC_MSG_ERROR], [_lt_disable_F77=yes])
+AC_PROG_F77
+if test -z "$F77" || test "X$F77" = "Xno"; then
+ _lt_disable_F77=yes
+fi
+popdef([AC_MSG_ERROR])
+])# _LT_PROG_F77
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([_LT_PROG_F77], [])
+
+
+# _LT_LANG_F77_CONFIG([TAG])
+# --------------------------
+# Ensure that the configuration variables for a Fortran 77 compiler are
+# suitably defined. These variables are subsequently used by _LT_CONFIG
+# to write the compiler configuration to `libtool'.
+m4_defun([_LT_LANG_F77_CONFIG],
+[AC_REQUIRE([_LT_PROG_F77])dnl
+AC_LANG_PUSH(Fortran 77)
+
+_LT_TAGVAR(archive_cmds_need_lc, $1)=no
+_LT_TAGVAR(allow_undefined_flag, $1)=
+_LT_TAGVAR(always_export_symbols, $1)=no
+_LT_TAGVAR(archive_expsym_cmds, $1)=
+_LT_TAGVAR(export_dynamic_flag_spec, $1)=
+_LT_TAGVAR(hardcode_direct, $1)=no
+_LT_TAGVAR(hardcode_direct_absolute, $1)=no
+_LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
+_LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)=
+_LT_TAGVAR(hardcode_libdir_separator, $1)=
+_LT_TAGVAR(hardcode_minus_L, $1)=no
+_LT_TAGVAR(hardcode_automatic, $1)=no
+_LT_TAGVAR(inherit_rpath, $1)=no
+_LT_TAGVAR(module_cmds, $1)=
+_LT_TAGVAR(module_expsym_cmds, $1)=
+_LT_TAGVAR(link_all_deplibs, $1)=unknown
+_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
+_LT_TAGVAR(no_undefined_flag, $1)=
+_LT_TAGVAR(whole_archive_flag_spec, $1)=
+_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no
+
+# Source file extension for f77 test sources.
+ac_ext=f
+
+# Object file extension for compiled f77 test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# No sense in running all these tests if we already determined that
+# the F77 compiler isn't working. Some variables (like enable_shared)
+# are currently assumed to apply to all compilers on this platform,
+# and will be corrupted by setting them based on a non-working compiler.
+if test "$_lt_disable_F77" != yes; then
+ # Code to be used in simple compile tests
+ lt_simple_compile_test_code="\
+ subroutine t
+ return
+ end
+"
+
+ # Code to be used in simple link tests
+ lt_simple_link_test_code="\
+ program t
+ end
+"
+
+ # ltmain only uses $CC for tagged configurations so make sure $CC is set.
+ _LT_TAG_COMPILER
+
+ # save warnings/boilerplate of simple test code
+ _LT_COMPILER_BOILERPLATE
+ _LT_LINKER_BOILERPLATE
+
+ # Allow CC to be a program name with arguments.
+ lt_save_CC="$CC"
+ lt_save_GCC=$GCC
+ CC=${F77-"f77"}
+ compiler=$CC
+ _LT_TAGVAR(compiler, $1)=$CC
+ _LT_CC_BASENAME([$compiler])
+ GCC=$G77
+ if test -n "$compiler"; then
+ AC_MSG_CHECKING([if libtool supports shared libraries])
+ AC_MSG_RESULT([$can_build_shared])
+
+ AC_MSG_CHECKING([whether to build shared libraries])
+ test "$can_build_shared" = "no" && enable_shared=no
+
+ # On AIX, shared libraries and static libraries use the same namespace, and
+ # are all built from PIC.
+ case $host_os in
+ aix3*)
+ test "$enable_shared" = yes && enable_static=no
+ if test -n "$RANLIB"; then
+ archive_cmds="$archive_cmds~\$RANLIB \$lib"
+ postinstall_cmds='$RANLIB $lib'
+ fi
+ ;;
+ aix[[4-9]]*)
+ if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then
+ test "$enable_shared" = yes && enable_static=no
+ fi
+ ;;
+ esac
+ AC_MSG_RESULT([$enable_shared])
+
+ AC_MSG_CHECKING([whether to build static libraries])
+ # Make sure either enable_shared or enable_static is yes.
+ test "$enable_shared" = yes || enable_static=yes
+ AC_MSG_RESULT([$enable_static])
+
+ _LT_TAGVAR(GCC, $1)="$G77"
+ _LT_TAGVAR(LD, $1)="$LD"
+
+ ## CAVEAT EMPTOR:
+ ## There is no encapsulation within the following macros, do not change
+ ## the running order or otherwise move them around unless you know exactly
+ ## what you are doing...
+ _LT_COMPILER_PIC($1)
+ _LT_COMPILER_C_O($1)
+ _LT_COMPILER_FILE_LOCKS($1)
+ _LT_LINKER_SHLIBS($1)
+ _LT_SYS_DYNAMIC_LINKER($1)
+ _LT_LINKER_HARDCODE_LIBPATH($1)
+
+ _LT_CONFIG($1)
+ fi # test -n "$compiler"
+
+ GCC=$lt_save_GCC
+ CC="$lt_save_CC"
+fi # test "$_lt_disable_F77" != yes
+
+AC_LANG_POP
+])# _LT_LANG_F77_CONFIG
+
+
+# _LT_PROG_FC
+# -----------
+# Since AC_PROG_FC is broken, in that it returns the empty string
+# if there is no fortran compiler, we have our own version here.
+m4_defun([_LT_PROG_FC],
+[
+pushdef([AC_MSG_ERROR], [_lt_disable_FC=yes])
+AC_PROG_FC
+if test -z "$FC" || test "X$FC" = "Xno"; then
+ _lt_disable_FC=yes
+fi
+popdef([AC_MSG_ERROR])
+])# _LT_PROG_FC
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([_LT_PROG_FC], [])
+
+
+# _LT_LANG_FC_CONFIG([TAG])
+# -------------------------
+# Ensure that the configuration variables for a Fortran compiler are
+# suitably defined. These variables are subsequently used by _LT_CONFIG
+# to write the compiler configuration to `libtool'.
+m4_defun([_LT_LANG_FC_CONFIG],
+[AC_REQUIRE([_LT_PROG_FC])dnl
+AC_LANG_PUSH(Fortran)
+
+_LT_TAGVAR(archive_cmds_need_lc, $1)=no
+_LT_TAGVAR(allow_undefined_flag, $1)=
+_LT_TAGVAR(always_export_symbols, $1)=no
+_LT_TAGVAR(archive_expsym_cmds, $1)=
+_LT_TAGVAR(export_dynamic_flag_spec, $1)=
+_LT_TAGVAR(hardcode_direct, $1)=no
+_LT_TAGVAR(hardcode_direct_absolute, $1)=no
+_LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
+_LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)=
+_LT_TAGVAR(hardcode_libdir_separator, $1)=
+_LT_TAGVAR(hardcode_minus_L, $1)=no
+_LT_TAGVAR(hardcode_automatic, $1)=no
+_LT_TAGVAR(inherit_rpath, $1)=no
+_LT_TAGVAR(module_cmds, $1)=
+_LT_TAGVAR(module_expsym_cmds, $1)=
+_LT_TAGVAR(link_all_deplibs, $1)=unknown
+_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
+_LT_TAGVAR(no_undefined_flag, $1)=
+_LT_TAGVAR(whole_archive_flag_spec, $1)=
+_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no
+
+# Source file extension for fc test sources.
+ac_ext=${ac_fc_srcext-f}
+
+# Object file extension for compiled fc test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# No sense in running all these tests if we already determined that
+# the FC compiler isn't working. Some variables (like enable_shared)
+# are currently assumed to apply to all compilers on this platform,
+# and will be corrupted by setting them based on a non-working compiler.
+if test "$_lt_disable_FC" != yes; then
+ # Code to be used in simple compile tests
+ lt_simple_compile_test_code="\
+ subroutine t
+ return
+ end
+"
+
+ # Code to be used in simple link tests
+ lt_simple_link_test_code="\
+ program t
+ end
+"
+
+ # ltmain only uses $CC for tagged configurations so make sure $CC is set.
+ _LT_TAG_COMPILER
+
+ # save warnings/boilerplate of simple test code
+ _LT_COMPILER_BOILERPLATE
+ _LT_LINKER_BOILERPLATE
+
+ # Allow CC to be a program name with arguments.
+ lt_save_CC="$CC"
+ lt_save_GCC=$GCC
+ CC=${FC-"f95"}
+ compiler=$CC
+ GCC=$ac_cv_fc_compiler_gnu
+
+ _LT_TAGVAR(compiler, $1)=$CC
+ _LT_CC_BASENAME([$compiler])
+
+ if test -n "$compiler"; then
+ AC_MSG_CHECKING([if libtool supports shared libraries])
+ AC_MSG_RESULT([$can_build_shared])
+
+ AC_MSG_CHECKING([whether to build shared libraries])
+ test "$can_build_shared" = "no" && enable_shared=no
+
+ # On AIX, shared libraries and static libraries use the same namespace, and
+ # are all built from PIC.
+ case $host_os in
+ aix3*)
+ test "$enable_shared" = yes && enable_static=no
+ if test -n "$RANLIB"; then
+ archive_cmds="$archive_cmds~\$RANLIB \$lib"
+ postinstall_cmds='$RANLIB $lib'
+ fi
+ ;;
+ aix[[4-9]]*)
+ if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then
+ test "$enable_shared" = yes && enable_static=no
+ fi
+ ;;
+ esac
+ AC_MSG_RESULT([$enable_shared])
+
+ AC_MSG_CHECKING([whether to build static libraries])
+ # Make sure either enable_shared or enable_static is yes.
+ test "$enable_shared" = yes || enable_static=yes
+ AC_MSG_RESULT([$enable_static])
+
+ _LT_TAGVAR(GCC, $1)="$ac_cv_fc_compiler_gnu"
+ _LT_TAGVAR(LD, $1)="$LD"
+
+ ## CAVEAT EMPTOR:
+ ## There is no encapsulation within the following macros, do not change
+ ## the running order or otherwise move them around unless you know exactly
+ ## what you are doing...
+ _LT_SYS_HIDDEN_LIBDEPS($1)
+ _LT_COMPILER_PIC($1)
+ _LT_COMPILER_C_O($1)
+ _LT_COMPILER_FILE_LOCKS($1)
+ _LT_LINKER_SHLIBS($1)
+ _LT_SYS_DYNAMIC_LINKER($1)
+ _LT_LINKER_HARDCODE_LIBPATH($1)
+
+ _LT_CONFIG($1)
+ fi # test -n "$compiler"
+
+ GCC=$lt_save_GCC
+ CC="$lt_save_CC"
+fi # test "$_lt_disable_FC" != yes
+
+AC_LANG_POP
+])# _LT_LANG_FC_CONFIG
+
+
+# _LT_LANG_GCJ_CONFIG([TAG])
+# --------------------------
+# Ensure that the configuration variables for the GNU Java Compiler compiler
+# are suitably defined. These variables are subsequently used by _LT_CONFIG
+# to write the compiler configuration to `libtool'.
+m4_defun([_LT_LANG_GCJ_CONFIG],
+[AC_REQUIRE([LT_PROG_GCJ])dnl
+AC_LANG_SAVE
+
+# Source file extension for Java test sources.
+ac_ext=java
+
+# Object file extension for compiled Java test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code="class foo {}"
+
+# Code to be used in simple link tests
+lt_simple_link_test_code='public class conftest { public static void main(String[[]] argv) {}; }'
+
+# ltmain only uses $CC for tagged configurations so make sure $CC is set.
+_LT_TAG_COMPILER
+
+# save warnings/boilerplate of simple test code
+_LT_COMPILER_BOILERPLATE
+_LT_LINKER_BOILERPLATE
+
+# Allow CC to be a program name with arguments.
+lt_save_CC="$CC"
+lt_save_GCC=$GCC
+GCC=yes
+CC=${GCJ-"gcj"}
+compiler=$CC
+_LT_TAGVAR(compiler, $1)=$CC
+_LT_TAGVAR(LD, $1)="$LD"
+_LT_CC_BASENAME([$compiler])
+
+# GCJ did not exist at the time GCC didn't implicitly link libc in.
+_LT_TAGVAR(archive_cmds_need_lc, $1)=no
+
+_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
+
+## CAVEAT EMPTOR:
+## There is no encapsulation within the following macros, do not change
+## the running order or otherwise move them around unless you know exactly
+## what you are doing...
+if test -n "$compiler"; then
+ _LT_COMPILER_NO_RTTI($1)
+ _LT_COMPILER_PIC($1)
+ _LT_COMPILER_C_O($1)
+ _LT_COMPILER_FILE_LOCKS($1)
+ _LT_LINKER_SHLIBS($1)
+ _LT_LINKER_HARDCODE_LIBPATH($1)
+
+ _LT_CONFIG($1)
+fi
+
+AC_LANG_RESTORE
+
+GCC=$lt_save_GCC
+CC="$lt_save_CC"
+])# _LT_LANG_GCJ_CONFIG
+
+
+# _LT_LANG_RC_CONFIG([TAG])
+# -------------------------
+# Ensure that the configuration variables for the Windows resource compiler
+# are suitably defined. These variables are subsequently used by _LT_CONFIG
+# to write the compiler configuration to `libtool'.
+m4_defun([_LT_LANG_RC_CONFIG],
+[AC_REQUIRE([LT_PROG_RC])dnl
+AC_LANG_SAVE
+
+# Source file extension for RC test sources.
+ac_ext=rc
+
+# Object file extension for compiled RC test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }'
+
+# Code to be used in simple link tests
+lt_simple_link_test_code="$lt_simple_compile_test_code"
+
+# ltmain only uses $CC for tagged configurations so make sure $CC is set.
+_LT_TAG_COMPILER
+
+# save warnings/boilerplate of simple test code
+_LT_COMPILER_BOILERPLATE
+_LT_LINKER_BOILERPLATE
+
+# Allow CC to be a program name with arguments.
+lt_save_CC="$CC"
+lt_save_GCC=$GCC
+GCC=
+CC=${RC-"windres"}
+compiler=$CC
+_LT_TAGVAR(compiler, $1)=$CC
+_LT_CC_BASENAME([$compiler])
+_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes
+
+if test -n "$compiler"; then
+ :
+ _LT_CONFIG($1)
+fi
+
+GCC=$lt_save_GCC
+AC_LANG_RESTORE
+CC="$lt_save_CC"
+])# _LT_LANG_RC_CONFIG
+
+
+# LT_PROG_GCJ
+# -----------
+AC_DEFUN([LT_PROG_GCJ],
+[m4_ifdef([AC_PROG_GCJ], [AC_PROG_GCJ],
+ [m4_ifdef([A][M_PROG_GCJ], [A][M_PROG_GCJ],
+ [AC_CHECK_TOOL(GCJ, gcj,)
+ test "x${GCJFLAGS+set}" = xset || GCJFLAGS="-g -O2"
+ AC_SUBST(GCJFLAGS)])])[]dnl
+])
+
+# Old name:
+AU_ALIAS([LT_AC_PROG_GCJ], [LT_PROG_GCJ])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([LT_AC_PROG_GCJ], [])
+
+
+# LT_PROG_RC
+# ----------
+AC_DEFUN([LT_PROG_RC],
+[AC_CHECK_TOOL(RC, windres,)
+])
+
+# Old name:
+AU_ALIAS([LT_AC_PROG_RC], [LT_PROG_RC])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([LT_AC_PROG_RC], [])
+
+
+# _LT_DECL_EGREP
+# --------------
+# If we don't have a new enough Autoconf to choose the best grep
+# available, choose the one first in the user's PATH.
+m4_defun([_LT_DECL_EGREP],
+[AC_REQUIRE([AC_PROG_EGREP])dnl
+AC_REQUIRE([AC_PROG_FGREP])dnl
+test -z "$GREP" && GREP=grep
+_LT_DECL([], [GREP], [1], [A grep program that handles long lines])
+_LT_DECL([], [EGREP], [1], [An ERE matcher])
+_LT_DECL([], [FGREP], [1], [A literal string matcher])
+dnl Non-bleeding-edge autoconf doesn't subst GREP, so do it here too
+AC_SUBST([GREP])
+])
+
+
+# _LT_DECL_OBJDUMP
+# --------------
+# If we don't have a new enough Autoconf to choose the best objdump
+# available, choose the one first in the user's PATH.
+m4_defun([_LT_DECL_OBJDUMP],
+[AC_CHECK_TOOL(OBJDUMP, objdump, false)
+test -z "$OBJDUMP" && OBJDUMP=objdump
+_LT_DECL([], [OBJDUMP], [1], [An object symbol dumper])
+AC_SUBST([OBJDUMP])
+])
+
+
+# _LT_DECL_SED
+# ------------
+# Check for a fully-functional sed program, that truncates
+# as few characters as possible. Prefer GNU sed if found.
+m4_defun([_LT_DECL_SED],
+[AC_PROG_SED
+test -z "$SED" && SED=sed
+Xsed="$SED -e 1s/^X//"
+_LT_DECL([], [SED], [1], [A sed program that does not truncate output])
+_LT_DECL([], [Xsed], ["\$SED -e 1s/^X//"],
+ [Sed that helps us avoid accidentally triggering echo(1) options like -n])
+])# _LT_DECL_SED
+
+m4_ifndef([AC_PROG_SED], [
+############################################################
+# NOTE: This macro has been submitted for inclusion into #
+# GNU Autoconf as AC_PROG_SED. When it is available in #
+# a released version of Autoconf we should remove this #
+# macro and use it instead. #
+############################################################
+
+m4_defun([AC_PROG_SED],
+[AC_MSG_CHECKING([for a sed that does not truncate output])
+AC_CACHE_VAL(lt_cv_path_SED,
+[# Loop through the user's path and test for sed and gsed.
+# Then use that list of sed's as ones to test for truncation.
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for lt_ac_prog in sed gsed; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$lt_ac_prog$ac_exec_ext"; then
+ lt_ac_sed_list="$lt_ac_sed_list $as_dir/$lt_ac_prog$ac_exec_ext"
+ fi
+ done
+ done
+done
+IFS=$as_save_IFS
+lt_ac_max=0
+lt_ac_count=0
+# Add /usr/xpg4/bin/sed as it is typically found on Solaris
+# along with /bin/sed that truncates output.
+for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do
+ test ! -f $lt_ac_sed && continue
+ cat /dev/null > conftest.in
+ lt_ac_count=0
+ echo $ECHO_N "0123456789$ECHO_C" >conftest.in
+ # Check for GNU sed and select it if it is found.
+ if "$lt_ac_sed" --version 2>&1 < /dev/null | grep 'GNU' > /dev/null; then
+ lt_cv_path_SED=$lt_ac_sed
+ break
+ fi
+ while true; do
+ cat conftest.in conftest.in >conftest.tmp
+ mv conftest.tmp conftest.in
+ cp conftest.in conftest.nl
+ echo >>conftest.nl
+ $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break
+ cmp -s conftest.out conftest.nl || break
+ # 10000 chars as input seems more than enough
+ test $lt_ac_count -gt 10 && break
+ lt_ac_count=`expr $lt_ac_count + 1`
+ if test $lt_ac_count -gt $lt_ac_max; then
+ lt_ac_max=$lt_ac_count
+ lt_cv_path_SED=$lt_ac_sed
+ fi
+ done
+done
+])
+SED=$lt_cv_path_SED
+AC_SUBST([SED])
+AC_MSG_RESULT([$SED])
+])#AC_PROG_SED
+])#m4_ifndef
+
+# Old name:
+AU_ALIAS([LT_AC_PROG_SED], [AC_PROG_SED])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([LT_AC_PROG_SED], [])
+
+
+# _LT_CHECK_SHELL_FEATURES
+# ------------------------
+# Find out whether the shell is Bourne or XSI compatible,
+# or has some other useful features.
+m4_defun([_LT_CHECK_SHELL_FEATURES],
+[AC_MSG_CHECKING([whether the shell understands some XSI constructs])
+# Try some XSI features
+xsi_shell=no
+( _lt_dummy="a/b/c"
+ test "${_lt_dummy##*/},${_lt_dummy%/*},"${_lt_dummy%"$_lt_dummy"}, \
+ = c,a/b,, \
+ && eval 'test $(( 1 + 1 )) -eq 2 \
+ && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \
+ && xsi_shell=yes
+AC_MSG_RESULT([$xsi_shell])
+_LT_CONFIG_LIBTOOL_INIT([xsi_shell='$xsi_shell'])
+
+AC_MSG_CHECKING([whether the shell understands "+="])
+lt_shell_append=no
+( foo=bar; set foo baz; eval "$[1]+=\$[2]" && test "$foo" = barbaz ) \
+ >/dev/null 2>&1 \
+ && lt_shell_append=yes
+AC_MSG_RESULT([$lt_shell_append])
+_LT_CONFIG_LIBTOOL_INIT([lt_shell_append='$lt_shell_append'])
+
+if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+ lt_unset=unset
+else
+ lt_unset=false
+fi
+_LT_DECL([], [lt_unset], [0], [whether the shell understands "unset"])dnl
+
+# test EBCDIC or ASCII
+case `echo X|tr X '\101'` in
+ A) # ASCII based system
+ # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr
+ lt_SP2NL='tr \040 \012'
+ lt_NL2SP='tr \015\012 \040\040'
+ ;;
+ *) # EBCDIC based system
+ lt_SP2NL='tr \100 \n'
+ lt_NL2SP='tr \r\n \100\100'
+ ;;
+esac
+_LT_DECL([SP2NL], [lt_SP2NL], [1], [turn spaces into newlines])dnl
+_LT_DECL([NL2SP], [lt_NL2SP], [1], [turn newlines into spaces])dnl
+])# _LT_CHECK_SHELL_FEATURES
+
+
+# _LT_PROG_XSI_SHELLFNS
+# ---------------------
+# Bourne and XSI compatible variants of some useful shell functions.
+m4_defun([_LT_PROG_XSI_SHELLFNS],
+[case $xsi_shell in
+ yes)
+ cat << \_LT_EOF >> "$cfgfile"
+
+# func_dirname file append nondir_replacement
+# Compute the dirname of FILE. If nonempty, add APPEND to the result,
+# otherwise set result to NONDIR_REPLACEMENT.
+func_dirname ()
+{
+ case ${1} in
+ */*) func_dirname_result="${1%/*}${2}" ;;
+ * ) func_dirname_result="${3}" ;;
+ esac
+}
+
+# func_basename file
+func_basename ()
+{
+ func_basename_result="${1##*/}"
+}
+
+# func_dirname_and_basename file append nondir_replacement
+# perform func_basename and func_dirname in a single function
+# call:
+# dirname: Compute the dirname of FILE. If nonempty,
+# add APPEND to the result, otherwise set result
+# to NONDIR_REPLACEMENT.
+# value returned in "$func_dirname_result"
+# basename: Compute filename of FILE.
+# value retuned in "$func_basename_result"
+# Implementation must be kept synchronized with func_dirname
+# and func_basename. For efficiency, we do not delegate to
+# those functions but instead duplicate the functionality here.
+func_dirname_and_basename ()
+{
+ case ${1} in
+ */*) func_dirname_result="${1%/*}${2}" ;;
+ * ) func_dirname_result="${3}" ;;
+ esac
+ func_basename_result="${1##*/}"
+}
+
+# func_stripname prefix suffix name
+# strip PREFIX and SUFFIX off of NAME.
+# PREFIX and SUFFIX must not contain globbing or regex special
+# characters, hashes, percent signs, but SUFFIX may contain a leading
+# dot (in which case that matches only a dot).
+func_stripname ()
+{
+ # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are
+ # positional parameters, so assign one to ordinary parameter first.
+ func_stripname_result=${3}
+ func_stripname_result=${func_stripname_result#"${1}"}
+ func_stripname_result=${func_stripname_result%"${2}"}
+}
+
+# func_opt_split
+func_opt_split ()
+{
+ func_opt_split_opt=${1%%=*}
+ func_opt_split_arg=${1#*=}
+}
+
+# func_lo2o object
+func_lo2o ()
+{
+ case ${1} in
+ *.lo) func_lo2o_result=${1%.lo}.${objext} ;;
+ *) func_lo2o_result=${1} ;;
+ esac
+}
+
+# func_xform libobj-or-source
+func_xform ()
+{
+ func_xform_result=${1%.*}.lo
+}
+
+# func_arith arithmetic-term...
+func_arith ()
+{
+ func_arith_result=$(( $[*] ))
+}
+
+# func_len string
+# STRING may not start with a hyphen.
+func_len ()
+{
+ func_len_result=${#1}
+}
+
+_LT_EOF
+ ;;
+ *) # Bourne compatible functions.
+ cat << \_LT_EOF >> "$cfgfile"
+
+# func_dirname file append nondir_replacement
+# Compute the dirname of FILE. If nonempty, add APPEND to the result,
+# otherwise set result to NONDIR_REPLACEMENT.
+func_dirname ()
+{
+ # Extract subdirectory from the argument.
+ func_dirname_result=`$ECHO "X${1}" | $Xsed -e "$dirname"`
+ if test "X$func_dirname_result" = "X${1}"; then
+ func_dirname_result="${3}"
+ else
+ func_dirname_result="$func_dirname_result${2}"
+ fi
+}
+
+# func_basename file
+func_basename ()
+{
+ func_basename_result=`$ECHO "X${1}" | $Xsed -e "$basename"`
+}
+
+dnl func_dirname_and_basename
+dnl A portable version of this function is already defined in general.m4sh
+dnl so there is no need for it here.
+
+# func_stripname prefix suffix name
+# strip PREFIX and SUFFIX off of NAME.
+# PREFIX and SUFFIX must not contain globbing or regex special
+# characters, hashes, percent signs, but SUFFIX may contain a leading
+# dot (in which case that matches only a dot).
+# func_strip_suffix prefix name
+func_stripname ()
+{
+ case ${2} in
+ .*) func_stripname_result=`$ECHO "X${3}" \
+ | $Xsed -e "s%^${1}%%" -e "s%\\\\${2}\$%%"`;;
+ *) func_stripname_result=`$ECHO "X${3}" \
+ | $Xsed -e "s%^${1}%%" -e "s%${2}\$%%"`;;
+ esac
+}
+
+# sed scripts:
+my_sed_long_opt='1s/^\(-[[^=]]*\)=.*/\1/;q'
+my_sed_long_arg='1s/^-[[^=]]*=//'
+
+# func_opt_split
+func_opt_split ()
+{
+ func_opt_split_opt=`$ECHO "X${1}" | $Xsed -e "$my_sed_long_opt"`
+ func_opt_split_arg=`$ECHO "X${1}" | $Xsed -e "$my_sed_long_arg"`
+}
+
+# func_lo2o object
+func_lo2o ()
+{
+ func_lo2o_result=`$ECHO "X${1}" | $Xsed -e "$lo2o"`
+}
+
+# func_xform libobj-or-source
+func_xform ()
+{
+ func_xform_result=`$ECHO "X${1}" | $Xsed -e 's/\.[[^.]]*$/.lo/'`
+}
+
+# func_arith arithmetic-term...
+func_arith ()
+{
+ func_arith_result=`expr "$[@]"`
+}
+
+# func_len string
+# STRING may not start with a hyphen.
+func_len ()
+{
+ func_len_result=`expr "$[1]" : ".*" 2>/dev/null || echo $max_cmd_len`
+}
+
+_LT_EOF
+esac
+
+case $lt_shell_append in
+ yes)
+ cat << \_LT_EOF >> "$cfgfile"
+
+# func_append var value
+# Append VALUE to the end of shell variable VAR.
+func_append ()
+{
+ eval "$[1]+=\$[2]"
+}
+_LT_EOF
+ ;;
+ *)
+ cat << \_LT_EOF >> "$cfgfile"
+
+# func_append var value
+# Append VALUE to the end of shell variable VAR.
+func_append ()
+{
+ eval "$[1]=\$$[1]\$[2]"
+}
+
+_LT_EOF
+ ;;
+ esac
+])
diff --git a/src/third_party/gflags-2.0/m4/ltoptions.m4 b/src/third_party/gflags-2.0/m4/ltoptions.m4
new file mode 100755
index 00000000000..34151a3ba62
--- /dev/null
+++ b/src/third_party/gflags-2.0/m4/ltoptions.m4
@@ -0,0 +1,368 @@
+# Helper functions for option handling. -*- Autoconf -*-
+#
+# Copyright (C) 2004, 2005, 2007, 2008 Free Software Foundation, Inc.
+# Written by Gary V. Vaughan, 2004
+#
+# This file is free software; the Free Software Foundation gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+
+# serial 6 ltoptions.m4
+
+# This is to help aclocal find these macros, as it can't see m4_define.
+AC_DEFUN([LTOPTIONS_VERSION], [m4_if([1])])
+
+
+# _LT_MANGLE_OPTION(MACRO-NAME, OPTION-NAME)
+# ------------------------------------------
+m4_define([_LT_MANGLE_OPTION],
+[[_LT_OPTION_]m4_bpatsubst($1__$2, [[^a-zA-Z0-9_]], [_])])
+
+
+# _LT_SET_OPTION(MACRO-NAME, OPTION-NAME)
+# ---------------------------------------
+# Set option OPTION-NAME for macro MACRO-NAME, and if there is a
+# matching handler defined, dispatch to it. Other OPTION-NAMEs are
+# saved as a flag.
+m4_define([_LT_SET_OPTION],
+[m4_define(_LT_MANGLE_OPTION([$1], [$2]))dnl
+m4_ifdef(_LT_MANGLE_DEFUN([$1], [$2]),
+ _LT_MANGLE_DEFUN([$1], [$2]),
+ [m4_warning([Unknown $1 option `$2'])])[]dnl
+])
+
+
+# _LT_IF_OPTION(MACRO-NAME, OPTION-NAME, IF-SET, [IF-NOT-SET])
+# ------------------------------------------------------------
+# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise.
+m4_define([_LT_IF_OPTION],
+[m4_ifdef(_LT_MANGLE_OPTION([$1], [$2]), [$3], [$4])])
+
+
+# _LT_UNLESS_OPTIONS(MACRO-NAME, OPTION-LIST, IF-NOT-SET)
+# -------------------------------------------------------
+# Execute IF-NOT-SET unless all options in OPTION-LIST for MACRO-NAME
+# are set.
+m4_define([_LT_UNLESS_OPTIONS],
+[m4_foreach([_LT_Option], m4_split(m4_normalize([$2])),
+ [m4_ifdef(_LT_MANGLE_OPTION([$1], _LT_Option),
+ [m4_define([$0_found])])])[]dnl
+m4_ifdef([$0_found], [m4_undefine([$0_found])], [$3
+])[]dnl
+])
+
+
+# _LT_SET_OPTIONS(MACRO-NAME, OPTION-LIST)
+# ----------------------------------------
+# OPTION-LIST is a space-separated list of Libtool options associated
+# with MACRO-NAME. If any OPTION has a matching handler declared with
+# LT_OPTION_DEFINE, dispatch to that macro; otherwise complain about
+# the unknown option and exit.
+m4_defun([_LT_SET_OPTIONS],
+[# Set options
+m4_foreach([_LT_Option], m4_split(m4_normalize([$2])),
+ [_LT_SET_OPTION([$1], _LT_Option)])
+
+m4_if([$1],[LT_INIT],[
+ dnl
+ dnl Simply set some default values (i.e off) if boolean options were not
+ dnl specified:
+ _LT_UNLESS_OPTIONS([LT_INIT], [dlopen], [enable_dlopen=no
+ ])
+ _LT_UNLESS_OPTIONS([LT_INIT], [win32-dll], [enable_win32_dll=no
+ ])
+ dnl
+ dnl If no reference was made to various pairs of opposing options, then
+ dnl we run the default mode handler for the pair. For example, if neither
+ dnl `shared' nor `disable-shared' was passed, we enable building of shared
+ dnl archives by default:
+ _LT_UNLESS_OPTIONS([LT_INIT], [shared disable-shared], [_LT_ENABLE_SHARED])
+ _LT_UNLESS_OPTIONS([LT_INIT], [static disable-static], [_LT_ENABLE_STATIC])
+ _LT_UNLESS_OPTIONS([LT_INIT], [pic-only no-pic], [_LT_WITH_PIC])
+ _LT_UNLESS_OPTIONS([LT_INIT], [fast-install disable-fast-install],
+ [_LT_ENABLE_FAST_INSTALL])
+ ])
+])# _LT_SET_OPTIONS
+
+
+## --------------------------------- ##
+## Macros to handle LT_INIT options. ##
+## --------------------------------- ##
+
+# _LT_MANGLE_DEFUN(MACRO-NAME, OPTION-NAME)
+# -----------------------------------------
+m4_define([_LT_MANGLE_DEFUN],
+[[_LT_OPTION_DEFUN_]m4_bpatsubst(m4_toupper([$1__$2]), [[^A-Z0-9_]], [_])])
+
+
+# LT_OPTION_DEFINE(MACRO-NAME, OPTION-NAME, CODE)
+# -----------------------------------------------
+m4_define([LT_OPTION_DEFINE],
+[m4_define(_LT_MANGLE_DEFUN([$1], [$2]), [$3])[]dnl
+])# LT_OPTION_DEFINE
+
+
+# dlopen
+# ------
+LT_OPTION_DEFINE([LT_INIT], [dlopen], [enable_dlopen=yes
+])
+
+AU_DEFUN([AC_LIBTOOL_DLOPEN],
+[_LT_SET_OPTION([LT_INIT], [dlopen])
+AC_DIAGNOSE([obsolete],
+[$0: Remove this warning and the call to _LT_SET_OPTION when you
+put the `dlopen' option into LT_INIT's first parameter.])
+])
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_DLOPEN], [])
+
+
+# win32-dll
+# ---------
+# Declare package support for building win32 dll's.
+LT_OPTION_DEFINE([LT_INIT], [win32-dll],
+[enable_win32_dll=yes
+
+case $host in
+*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-cegcc*)
+ AC_CHECK_TOOL(AS, as, false)
+ AC_CHECK_TOOL(DLLTOOL, dlltool, false)
+ AC_CHECK_TOOL(OBJDUMP, objdump, false)
+ ;;
+esac
+
+test -z "$AS" && AS=as
+_LT_DECL([], [AS], [0], [Assembler program])dnl
+
+test -z "$DLLTOOL" && DLLTOOL=dlltool
+_LT_DECL([], [DLLTOOL], [0], [DLL creation program])dnl
+
+test -z "$OBJDUMP" && OBJDUMP=objdump
+_LT_DECL([], [OBJDUMP], [0], [Object dumper program])dnl
+])# win32-dll
+
+AU_DEFUN([AC_LIBTOOL_WIN32_DLL],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+_LT_SET_OPTION([LT_INIT], [win32-dll])
+AC_DIAGNOSE([obsolete],
+[$0: Remove this warning and the call to _LT_SET_OPTION when you
+put the `win32-dll' option into LT_INIT's first parameter.])
+])
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_WIN32_DLL], [])
+
+
+# _LT_ENABLE_SHARED([DEFAULT])
+# ----------------------------
+# implement the --enable-shared flag, and supports the `shared' and
+# `disable-shared' LT_INIT options.
+# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'.
+m4_define([_LT_ENABLE_SHARED],
+[m4_define([_LT_ENABLE_SHARED_DEFAULT], [m4_if($1, no, no, yes)])dnl
+AC_ARG_ENABLE([shared],
+ [AS_HELP_STRING([--enable-shared@<:@=PKGS@:>@],
+ [build shared libraries @<:@default=]_LT_ENABLE_SHARED_DEFAULT[@:>@])],
+ [p=${PACKAGE-default}
+ case $enableval in
+ yes) enable_shared=yes ;;
+ no) enable_shared=no ;;
+ *)
+ enable_shared=no
+ # Look at the argument we got. We use all the common list separators.
+ lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+ for pkg in $enableval; do
+ IFS="$lt_save_ifs"
+ if test "X$pkg" = "X$p"; then
+ enable_shared=yes
+ fi
+ done
+ IFS="$lt_save_ifs"
+ ;;
+ esac],
+ [enable_shared=]_LT_ENABLE_SHARED_DEFAULT)
+
+ _LT_DECL([build_libtool_libs], [enable_shared], [0],
+ [Whether or not to build shared libraries])
+])# _LT_ENABLE_SHARED
+
+LT_OPTION_DEFINE([LT_INIT], [shared], [_LT_ENABLE_SHARED([yes])])
+LT_OPTION_DEFINE([LT_INIT], [disable-shared], [_LT_ENABLE_SHARED([no])])
+
+# Old names:
+AC_DEFUN([AC_ENABLE_SHARED],
+[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[shared])
+])
+
+AC_DEFUN([AC_DISABLE_SHARED],
+[_LT_SET_OPTION([LT_INIT], [disable-shared])
+])
+
+AU_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)])
+AU_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)])
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AM_ENABLE_SHARED], [])
+dnl AC_DEFUN([AM_DISABLE_SHARED], [])
+
+
+
+# _LT_ENABLE_STATIC([DEFAULT])
+# ----------------------------
+# implement the --enable-static flag, and support the `static' and
+# `disable-static' LT_INIT options.
+# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'.
+m4_define([_LT_ENABLE_STATIC],
+[m4_define([_LT_ENABLE_STATIC_DEFAULT], [m4_if($1, no, no, yes)])dnl
+AC_ARG_ENABLE([static],
+ [AS_HELP_STRING([--enable-static@<:@=PKGS@:>@],
+ [build static libraries @<:@default=]_LT_ENABLE_STATIC_DEFAULT[@:>@])],
+ [p=${PACKAGE-default}
+ case $enableval in
+ yes) enable_static=yes ;;
+ no) enable_static=no ;;
+ *)
+ enable_static=no
+ # Look at the argument we got. We use all the common list separators.
+ lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+ for pkg in $enableval; do
+ IFS="$lt_save_ifs"
+ if test "X$pkg" = "X$p"; then
+ enable_static=yes
+ fi
+ done
+ IFS="$lt_save_ifs"
+ ;;
+ esac],
+ [enable_static=]_LT_ENABLE_STATIC_DEFAULT)
+
+ _LT_DECL([build_old_libs], [enable_static], [0],
+ [Whether or not to build static libraries])
+])# _LT_ENABLE_STATIC
+
+LT_OPTION_DEFINE([LT_INIT], [static], [_LT_ENABLE_STATIC([yes])])
+LT_OPTION_DEFINE([LT_INIT], [disable-static], [_LT_ENABLE_STATIC([no])])
+
+# Old names:
+AC_DEFUN([AC_ENABLE_STATIC],
+[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[static])
+])
+
+AC_DEFUN([AC_DISABLE_STATIC],
+[_LT_SET_OPTION([LT_INIT], [disable-static])
+])
+
+AU_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)])
+AU_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)])
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AM_ENABLE_STATIC], [])
+dnl AC_DEFUN([AM_DISABLE_STATIC], [])
+
+
+
+# _LT_ENABLE_FAST_INSTALL([DEFAULT])
+# ----------------------------------
+# implement the --enable-fast-install flag, and support the `fast-install'
+# and `disable-fast-install' LT_INIT options.
+# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'.
+m4_define([_LT_ENABLE_FAST_INSTALL],
+[m4_define([_LT_ENABLE_FAST_INSTALL_DEFAULT], [m4_if($1, no, no, yes)])dnl
+AC_ARG_ENABLE([fast-install],
+ [AS_HELP_STRING([--enable-fast-install@<:@=PKGS@:>@],
+ [optimize for fast installation @<:@default=]_LT_ENABLE_FAST_INSTALL_DEFAULT[@:>@])],
+ [p=${PACKAGE-default}
+ case $enableval in
+ yes) enable_fast_install=yes ;;
+ no) enable_fast_install=no ;;
+ *)
+ enable_fast_install=no
+ # Look at the argument we got. We use all the common list separators.
+ lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+ for pkg in $enableval; do
+ IFS="$lt_save_ifs"
+ if test "X$pkg" = "X$p"; then
+ enable_fast_install=yes
+ fi
+ done
+ IFS="$lt_save_ifs"
+ ;;
+ esac],
+ [enable_fast_install=]_LT_ENABLE_FAST_INSTALL_DEFAULT)
+
+_LT_DECL([fast_install], [enable_fast_install], [0],
+ [Whether or not to optimize for fast installation])dnl
+])# _LT_ENABLE_FAST_INSTALL
+
+LT_OPTION_DEFINE([LT_INIT], [fast-install], [_LT_ENABLE_FAST_INSTALL([yes])])
+LT_OPTION_DEFINE([LT_INIT], [disable-fast-install], [_LT_ENABLE_FAST_INSTALL([no])])
+
+# Old names:
+AU_DEFUN([AC_ENABLE_FAST_INSTALL],
+[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[fast-install])
+AC_DIAGNOSE([obsolete],
+[$0: Remove this warning and the call to _LT_SET_OPTION when you put
+the `fast-install' option into LT_INIT's first parameter.])
+])
+
+AU_DEFUN([AC_DISABLE_FAST_INSTALL],
+[_LT_SET_OPTION([LT_INIT], [disable-fast-install])
+AC_DIAGNOSE([obsolete],
+[$0: Remove this warning and the call to _LT_SET_OPTION when you put
+the `disable-fast-install' option into LT_INIT's first parameter.])
+])
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_ENABLE_FAST_INSTALL], [])
+dnl AC_DEFUN([AM_DISABLE_FAST_INSTALL], [])
+
+
+# _LT_WITH_PIC([MODE])
+# --------------------
+# implement the --with-pic flag, and support the `pic-only' and `no-pic'
+# LT_INIT options.
+# MODE is either `yes' or `no'. If omitted, it defaults to `both'.
+m4_define([_LT_WITH_PIC],
+[AC_ARG_WITH([pic],
+ [AS_HELP_STRING([--with-pic],
+ [try to use only PIC/non-PIC objects @<:@default=use both@:>@])],
+ [pic_mode="$withval"],
+ [pic_mode=default])
+
+test -z "$pic_mode" && pic_mode=m4_default([$1], [default])
+
+_LT_DECL([], [pic_mode], [0], [What type of objects to build])dnl
+])# _LT_WITH_PIC
+
+LT_OPTION_DEFINE([LT_INIT], [pic-only], [_LT_WITH_PIC([yes])])
+LT_OPTION_DEFINE([LT_INIT], [no-pic], [_LT_WITH_PIC([no])])
+
+# Old name:
+AU_DEFUN([AC_LIBTOOL_PICMODE],
+[_LT_SET_OPTION([LT_INIT], [pic-only])
+AC_DIAGNOSE([obsolete],
+[$0: Remove this warning and the call to _LT_SET_OPTION when you
+put the `pic-only' option into LT_INIT's first parameter.])
+])
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_PICMODE], [])
+
+## ----------------- ##
+## LTDL_INIT Options ##
+## ----------------- ##
+
+m4_define([_LTDL_MODE], [])
+LT_OPTION_DEFINE([LTDL_INIT], [nonrecursive],
+ [m4_define([_LTDL_MODE], [nonrecursive])])
+LT_OPTION_DEFINE([LTDL_INIT], [recursive],
+ [m4_define([_LTDL_MODE], [recursive])])
+LT_OPTION_DEFINE([LTDL_INIT], [subproject],
+ [m4_define([_LTDL_MODE], [subproject])])
+
+m4_define([_LTDL_TYPE], [])
+LT_OPTION_DEFINE([LTDL_INIT], [installable],
+ [m4_define([_LTDL_TYPE], [installable])])
+LT_OPTION_DEFINE([LTDL_INIT], [convenience],
+ [m4_define([_LTDL_TYPE], [convenience])])
diff --git a/src/third_party/gflags-2.0/m4/ltsugar.m4 b/src/third_party/gflags-2.0/m4/ltsugar.m4
new file mode 100755
index 00000000000..9000a057d31
--- /dev/null
+++ b/src/third_party/gflags-2.0/m4/ltsugar.m4
@@ -0,0 +1,123 @@
+# ltsugar.m4 -- libtool m4 base layer. -*-Autoconf-*-
+#
+# Copyright (C) 2004, 2005, 2007, 2008 Free Software Foundation, Inc.
+# Written by Gary V. Vaughan, 2004
+#
+# This file is free software; the Free Software Foundation gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+
+# serial 6 ltsugar.m4
+
+# This is to help aclocal find these macros, as it can't see m4_define.
+AC_DEFUN([LTSUGAR_VERSION], [m4_if([0.1])])
+
+
+# lt_join(SEP, ARG1, [ARG2...])
+# -----------------------------
+# Produce ARG1SEPARG2...SEPARGn, omitting [] arguments and their
+# associated separator.
+# Needed until we can rely on m4_join from Autoconf 2.62, since all earlier
+# versions in m4sugar had bugs.
+m4_define([lt_join],
+[m4_if([$#], [1], [],
+ [$#], [2], [[$2]],
+ [m4_if([$2], [], [], [[$2]_])$0([$1], m4_shift(m4_shift($@)))])])
+m4_define([_lt_join],
+[m4_if([$#$2], [2], [],
+ [m4_if([$2], [], [], [[$1$2]])$0([$1], m4_shift(m4_shift($@)))])])
+
+
+# lt_car(LIST)
+# lt_cdr(LIST)
+# ------------
+# Manipulate m4 lists.
+# These macros are necessary as long as will still need to support
+# Autoconf-2.59 which quotes differently.
+m4_define([lt_car], [[$1]])
+m4_define([lt_cdr],
+[m4_if([$#], 0, [m4_fatal([$0: cannot be called without arguments])],
+ [$#], 1, [],
+ [m4_dquote(m4_shift($@))])])
+m4_define([lt_unquote], $1)
+
+
+# lt_append(MACRO-NAME, STRING, [SEPARATOR])
+# ------------------------------------------
+# Redefine MACRO-NAME to hold its former content plus `SEPARATOR'`STRING'.
+# Note that neither SEPARATOR nor STRING are expanded; they are appended
+# to MACRO-NAME as is (leaving the expansion for when MACRO-NAME is invoked).
+# No SEPARATOR is output if MACRO-NAME was previously undefined (different
+# than defined and empty).
+#
+# This macro is needed until we can rely on Autoconf 2.62, since earlier
+# versions of m4sugar mistakenly expanded SEPARATOR but not STRING.
+m4_define([lt_append],
+[m4_define([$1],
+ m4_ifdef([$1], [m4_defn([$1])[$3]])[$2])])
+
+
+
+# lt_combine(SEP, PREFIX-LIST, INFIX, SUFFIX1, [SUFFIX2...])
+# ----------------------------------------------------------
+# Produce a SEP delimited list of all paired combinations of elements of
+# PREFIX-LIST with SUFFIX1 through SUFFIXn. Each element of the list
+# has the form PREFIXmINFIXSUFFIXn.
+# Needed until we can rely on m4_combine added in Autoconf 2.62.
+m4_define([lt_combine],
+[m4_if(m4_eval([$# > 3]), [1],
+ [m4_pushdef([_Lt_sep], [m4_define([_Lt_sep], m4_defn([lt_car]))])]]dnl
+[[m4_foreach([_Lt_prefix], [$2],
+ [m4_foreach([_Lt_suffix],
+ ]m4_dquote(m4_dquote(m4_shift(m4_shift(m4_shift($@)))))[,
+ [_Lt_sep([$1])[]m4_defn([_Lt_prefix])[$3]m4_defn([_Lt_suffix])])])])])
+
+
+# lt_if_append_uniq(MACRO-NAME, VARNAME, [SEPARATOR], [UNIQ], [NOT-UNIQ])
+# -----------------------------------------------------------------------
+# Iff MACRO-NAME does not yet contain VARNAME, then append it (delimited
+# by SEPARATOR if supplied) and expand UNIQ, else NOT-UNIQ.
+m4_define([lt_if_append_uniq],
+[m4_ifdef([$1],
+ [m4_if(m4_index([$3]m4_defn([$1])[$3], [$3$2$3]), [-1],
+ [lt_append([$1], [$2], [$3])$4],
+ [$5])],
+ [lt_append([$1], [$2], [$3])$4])])
+
+
+# lt_dict_add(DICT, KEY, VALUE)
+# -----------------------------
+m4_define([lt_dict_add],
+[m4_define([$1($2)], [$3])])
+
+
+# lt_dict_add_subkey(DICT, KEY, SUBKEY, VALUE)
+# --------------------------------------------
+m4_define([lt_dict_add_subkey],
+[m4_define([$1($2:$3)], [$4])])
+
+
+# lt_dict_fetch(DICT, KEY, [SUBKEY])
+# ----------------------------------
+m4_define([lt_dict_fetch],
+[m4_ifval([$3],
+ m4_ifdef([$1($2:$3)], [m4_defn([$1($2:$3)])]),
+ m4_ifdef([$1($2)], [m4_defn([$1($2)])]))])
+
+
+# lt_if_dict_fetch(DICT, KEY, [SUBKEY], VALUE, IF-TRUE, [IF-FALSE])
+# -----------------------------------------------------------------
+m4_define([lt_if_dict_fetch],
+[m4_if(lt_dict_fetch([$1], [$2], [$3]), [$4],
+ [$5],
+ [$6])])
+
+
+# lt_dict_filter(DICT, [SUBKEY], VALUE, [SEPARATOR], KEY, [...])
+# --------------------------------------------------------------
+m4_define([lt_dict_filter],
+[m4_if([$5], [], [],
+ [lt_join(m4_quote(m4_default([$4], [[, ]])),
+ lt_unquote(m4_split(m4_normalize(m4_foreach(_Lt_key, lt_car([m4_shiftn(4, $@)]),
+ [lt_if_dict_fetch([$1], _Lt_key, [$2], [$3], [_Lt_key ])])))))])[]dnl
+])
diff --git a/src/third_party/gflags-2.0/m4/ltversion.m4 b/src/third_party/gflags-2.0/m4/ltversion.m4
new file mode 100755
index 00000000000..f3c53098024
--- /dev/null
+++ b/src/third_party/gflags-2.0/m4/ltversion.m4
@@ -0,0 +1,23 @@
+# ltversion.m4 -- version numbers -*- Autoconf -*-
+#
+# Copyright (C) 2004 Free Software Foundation, Inc.
+# Written by Scott James Remnant, 2004
+#
+# This file is free software; the Free Software Foundation gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+
+# Generated from ltversion.in.
+
+# serial 3017 ltversion.m4
+# This file is part of GNU Libtool
+
+m4_define([LT_PACKAGE_VERSION], [2.2.6b])
+m4_define([LT_PACKAGE_REVISION], [1.3017])
+
+AC_DEFUN([LTVERSION_VERSION],
+[macro_version='2.2.6b'
+macro_revision='1.3017'
+_LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?])
+_LT_DECL(, macro_revision, 0)
+])
diff --git a/src/third_party/gflags-2.0/m4/lt~obsolete.m4 b/src/third_party/gflags-2.0/m4/lt~obsolete.m4
new file mode 100755
index 00000000000..637bb2066c4
--- /dev/null
+++ b/src/third_party/gflags-2.0/m4/lt~obsolete.m4
@@ -0,0 +1,92 @@
+# lt~obsolete.m4 -- aclocal satisfying obsolete definitions. -*-Autoconf-*-
+#
+# Copyright (C) 2004, 2005, 2007 Free Software Foundation, Inc.
+# Written by Scott James Remnant, 2004.
+#
+# This file is free software; the Free Software Foundation gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+
+# serial 4 lt~obsolete.m4
+
+# These exist entirely to fool aclocal when bootstrapping libtool.
+#
+# In the past libtool.m4 has provided macros via AC_DEFUN (or AU_DEFUN)
+# which have later been changed to m4_define as they aren't part of the
+# exported API, or moved to Autoconf or Automake where they belong.
+#
+# The trouble is, aclocal is a bit thick. It'll see the old AC_DEFUN
+# in /usr/share/aclocal/libtool.m4 and remember it, then when it sees us
+# using a macro with the same name in our local m4/libtool.m4 it'll
+# pull the old libtool.m4 in (it doesn't see our shiny new m4_define
+# and doesn't know about Autoconf macros at all.)
+#
+# So we provide this file, which has a silly filename so it's always
+# included after everything else. This provides aclocal with the
+# AC_DEFUNs it wants, but when m4 processes it, it doesn't do anything
+# because those macros already exist, or will be overwritten later.
+# We use AC_DEFUN over AU_DEFUN for compatibility with aclocal-1.6.
+#
+# Anytime we withdraw an AC_DEFUN or AU_DEFUN, remember to add it here.
+# Yes, that means every name once taken will need to remain here until
+# we give up compatibility with versions before 1.7, at which point
+# we need to keep only those names which we still refer to.
+
+# This is to help aclocal find these macros, as it can't see m4_define.
+AC_DEFUN([LTOBSOLETE_VERSION], [m4_if([1])])
+
+m4_ifndef([AC_LIBTOOL_LINKER_OPTION], [AC_DEFUN([AC_LIBTOOL_LINKER_OPTION])])
+m4_ifndef([AC_PROG_EGREP], [AC_DEFUN([AC_PROG_EGREP])])
+m4_ifndef([_LT_AC_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH])])
+m4_ifndef([_LT_AC_SHELL_INIT], [AC_DEFUN([_LT_AC_SHELL_INIT])])
+m4_ifndef([_LT_AC_SYS_LIBPATH_AIX], [AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX])])
+m4_ifndef([_LT_PROG_LTMAIN], [AC_DEFUN([_LT_PROG_LTMAIN])])
+m4_ifndef([_LT_AC_TAGVAR], [AC_DEFUN([_LT_AC_TAGVAR])])
+m4_ifndef([AC_LTDL_ENABLE_INSTALL], [AC_DEFUN([AC_LTDL_ENABLE_INSTALL])])
+m4_ifndef([AC_LTDL_PREOPEN], [AC_DEFUN([AC_LTDL_PREOPEN])])
+m4_ifndef([_LT_AC_SYS_COMPILER], [AC_DEFUN([_LT_AC_SYS_COMPILER])])
+m4_ifndef([_LT_AC_LOCK], [AC_DEFUN([_LT_AC_LOCK])])
+m4_ifndef([AC_LIBTOOL_SYS_OLD_ARCHIVE], [AC_DEFUN([AC_LIBTOOL_SYS_OLD_ARCHIVE])])
+m4_ifndef([_LT_AC_TRY_DLOPEN_SELF], [AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF])])
+m4_ifndef([AC_LIBTOOL_PROG_CC_C_O], [AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O])])
+m4_ifndef([AC_LIBTOOL_SYS_HARD_LINK_LOCKS], [AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS])])
+m4_ifndef([AC_LIBTOOL_OBJDIR], [AC_DEFUN([AC_LIBTOOL_OBJDIR])])
+m4_ifndef([AC_LTDL_OBJDIR], [AC_DEFUN([AC_LTDL_OBJDIR])])
+m4_ifndef([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH], [AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH])])
+m4_ifndef([AC_LIBTOOL_SYS_LIB_STRIP], [AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP])])
+m4_ifndef([AC_PATH_MAGIC], [AC_DEFUN([AC_PATH_MAGIC])])
+m4_ifndef([AC_PROG_LD_GNU], [AC_DEFUN([AC_PROG_LD_GNU])])
+m4_ifndef([AC_PROG_LD_RELOAD_FLAG], [AC_DEFUN([AC_PROG_LD_RELOAD_FLAG])])
+m4_ifndef([AC_DEPLIBS_CHECK_METHOD], [AC_DEFUN([AC_DEPLIBS_CHECK_METHOD])])
+m4_ifndef([AC_LIBTOOL_PROG_COMPILER_NO_RTTI], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI])])
+m4_ifndef([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], [AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE])])
+m4_ifndef([AC_LIBTOOL_PROG_COMPILER_PIC], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC])])
+m4_ifndef([AC_LIBTOOL_PROG_LD_SHLIBS], [AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS])])
+m4_ifndef([AC_LIBTOOL_POSTDEP_PREDEP], [AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP])])
+m4_ifndef([LT_AC_PROG_EGREP], [AC_DEFUN([LT_AC_PROG_EGREP])])
+m4_ifndef([LT_AC_PROG_SED], [AC_DEFUN([LT_AC_PROG_SED])])
+m4_ifndef([_LT_CC_BASENAME], [AC_DEFUN([_LT_CC_BASENAME])])
+m4_ifndef([_LT_COMPILER_BOILERPLATE], [AC_DEFUN([_LT_COMPILER_BOILERPLATE])])
+m4_ifndef([_LT_LINKER_BOILERPLATE], [AC_DEFUN([_LT_LINKER_BOILERPLATE])])
+m4_ifndef([_AC_PROG_LIBTOOL], [AC_DEFUN([_AC_PROG_LIBTOOL])])
+m4_ifndef([AC_LIBTOOL_SETUP], [AC_DEFUN([AC_LIBTOOL_SETUP])])
+m4_ifndef([_LT_AC_CHECK_DLFCN], [AC_DEFUN([_LT_AC_CHECK_DLFCN])])
+m4_ifndef([AC_LIBTOOL_SYS_DYNAMIC_LINKER], [AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER])])
+m4_ifndef([_LT_AC_TAGCONFIG], [AC_DEFUN([_LT_AC_TAGCONFIG])])
+m4_ifndef([AC_DISABLE_FAST_INSTALL], [AC_DEFUN([AC_DISABLE_FAST_INSTALL])])
+m4_ifndef([_LT_AC_LANG_CXX], [AC_DEFUN([_LT_AC_LANG_CXX])])
+m4_ifndef([_LT_AC_LANG_F77], [AC_DEFUN([_LT_AC_LANG_F77])])
+m4_ifndef([_LT_AC_LANG_GCJ], [AC_DEFUN([_LT_AC_LANG_GCJ])])
+m4_ifndef([AC_LIBTOOL_RC], [AC_DEFUN([AC_LIBTOOL_RC])])
+m4_ifndef([AC_LIBTOOL_LANG_C_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG])])
+m4_ifndef([_LT_AC_LANG_C_CONFIG], [AC_DEFUN([_LT_AC_LANG_C_CONFIG])])
+m4_ifndef([AC_LIBTOOL_LANG_CXX_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG])])
+m4_ifndef([_LT_AC_LANG_CXX_CONFIG], [AC_DEFUN([_LT_AC_LANG_CXX_CONFIG])])
+m4_ifndef([AC_LIBTOOL_LANG_F77_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_F77_CONFIG])])
+m4_ifndef([_LT_AC_LANG_F77_CONFIG], [AC_DEFUN([_LT_AC_LANG_F77_CONFIG])])
+m4_ifndef([AC_LIBTOOL_LANG_GCJ_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_GCJ_CONFIG])])
+m4_ifndef([_LT_AC_LANG_GCJ_CONFIG], [AC_DEFUN([_LT_AC_LANG_GCJ_CONFIG])])
+m4_ifndef([AC_LIBTOOL_LANG_RC_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_RC_CONFIG])])
+m4_ifndef([_LT_AC_LANG_RC_CONFIG], [AC_DEFUN([_LT_AC_LANG_RC_CONFIG])])
+m4_ifndef([AC_LIBTOOL_CONFIG], [AC_DEFUN([AC_LIBTOOL_CONFIG])])
+m4_ifndef([_LT_AC_FILE_LTDLL_C], [AC_DEFUN([_LT_AC_FILE_LTDLL_C])])
diff --git a/src/third_party/gflags-2.0/m4/namespaces.m4 b/src/third_party/gflags-2.0/m4/namespaces.m4
new file mode 100755
index 00000000000..d78dbe4cc2e
--- /dev/null
+++ b/src/third_party/gflags-2.0/m4/namespaces.m4
@@ -0,0 +1,15 @@
+# Checks whether the compiler implements namespaces
+AC_DEFUN([AC_CXX_NAMESPACES],
+ [AC_CACHE_CHECK(whether the compiler implements namespaces,
+ ac_cv_cxx_namespaces,
+ [AC_LANG_SAVE
+ AC_LANG_CPLUSPLUS
+ AC_TRY_COMPILE([namespace Outer {
+ namespace Inner { int i = 0; }}],
+ [using namespace Outer::Inner; return i;],
+ ac_cv_cxx_namespaces=yes,
+ ac_cv_cxx_namespaces=no)
+ AC_LANG_RESTORE])
+ if test "$ac_cv_cxx_namespaces" = yes; then
+ AC_DEFINE(HAVE_NAMESPACES, 1, [define if the compiler implements namespaces])
+ fi])
diff --git a/src/third_party/gflags-2.0/m4/stl_namespace.m4 b/src/third_party/gflags-2.0/m4/stl_namespace.m4
new file mode 100755
index 00000000000..989ad80696a
--- /dev/null
+++ b/src/third_party/gflags-2.0/m4/stl_namespace.m4
@@ -0,0 +1,25 @@
+# We check what namespace stl code like vector expects to be executed in
+
+AC_DEFUN([AC_CXX_STL_NAMESPACE],
+ [AC_CACHE_CHECK(
+ what namespace STL code is in,
+ ac_cv_cxx_stl_namespace,
+ [AC_REQUIRE([AC_CXX_NAMESPACES])
+ AC_LANG_SAVE
+ AC_LANG_CPLUSPLUS
+ AC_TRY_COMPILE([#include <vector>],
+ [vector<int> t; return 0;],
+ ac_cv_cxx_stl_namespace=none)
+ AC_TRY_COMPILE([#include <vector>],
+ [std::vector<int> t; return 0;],
+ ac_cv_cxx_stl_namespace=std)
+ AC_LANG_RESTORE])
+ if test "$ac_cv_cxx_stl_namespace" = none; then
+ AC_DEFINE(STL_NAMESPACE,,
+ [the namespace where STL code like vector<> is defined])
+ fi
+ if test "$ac_cv_cxx_stl_namespace" = std; then
+ AC_DEFINE(STL_NAMESPACE,std,
+ [the namespace where STL code like vector<> is defined])
+ fi
+])
diff --git a/src/third_party/gflags-2.0/makelog b/src/third_party/gflags-2.0/makelog
new file mode 100755
index 00000000000..8768c763d74
--- /dev/null
+++ b/src/third_party/gflags-2.0/makelog
@@ -0,0 +1,77 @@
+/bin/sh ./libtool --tag=CXX --mode=compile g++ -DHAVE_CONFIG_H -I. -I./src -I./src -D_THREAD_SAFE -DNDEBUG -g -O2 -MT libgflags_la-gflags.lo -MD -MP -MF .deps/libgflags_la-gflags.Tpo -c -o libgflags_la-gflags.lo `test -f 'src/gflags.cc' || echo './'`src/gflags.cc
+libtool: compile: g++ -DHAVE_CONFIG_H -I. -I./src -I./src -D_THREAD_SAFE -DNDEBUG -g -O2 -MT libgflags_la-gflags.lo -MD -MP -MF .deps/libgflags_la-gflags.Tpo -c src/gflags.cc -fno-common -DPIC -o .libs/libgflags_la-gflags.o
+libtool: compile: g++ -DHAVE_CONFIG_H -I. -I./src -I./src -D_THREAD_SAFE -DNDEBUG -g -O2 -MT libgflags_la-gflags.lo -MD -MP -MF .deps/libgflags_la-gflags.Tpo -c src/gflags.cc -o libgflags_la-gflags.o >/dev/null 2>&1
+mv -f .deps/libgflags_la-gflags.Tpo .deps/libgflags_la-gflags.Plo
+/bin/sh ./libtool --tag=CXX --mode=compile g++ -DHAVE_CONFIG_H -I. -I./src -I./src -D_THREAD_SAFE -DNDEBUG -g -O2 -MT libgflags_la-gflags_reporting.lo -MD -MP -MF .deps/libgflags_la-gflags_reporting.Tpo -c -o libgflags_la-gflags_reporting.lo `test -f 'src/gflags_reporting.cc' || echo './'`src/gflags_reporting.cc
+libtool: compile: g++ -DHAVE_CONFIG_H -I. -I./src -I./src -D_THREAD_SAFE -DNDEBUG -g -O2 -MT libgflags_la-gflags_reporting.lo -MD -MP -MF .deps/libgflags_la-gflags_reporting.Tpo -c src/gflags_reporting.cc -fno-common -DPIC -o .libs/libgflags_la-gflags_reporting.o
+libtool: compile: g++ -DHAVE_CONFIG_H -I. -I./src -I./src -D_THREAD_SAFE -DNDEBUG -g -O2 -MT libgflags_la-gflags_reporting.lo -MD -MP -MF .deps/libgflags_la-gflags_reporting.Tpo -c src/gflags_reporting.cc -o libgflags_la-gflags_reporting.o >/dev/null 2>&1
+mv -f .deps/libgflags_la-gflags_reporting.Tpo .deps/libgflags_la-gflags_reporting.Plo
+/bin/sh ./libtool --tag=CXX --mode=compile g++ -DHAVE_CONFIG_H -I. -I./src -I./src -D_THREAD_SAFE -DNDEBUG -g -O2 -MT libgflags_la-gflags_completions.lo -MD -MP -MF .deps/libgflags_la-gflags_completions.Tpo -c -o libgflags_la-gflags_completions.lo `test -f 'src/gflags_completions.cc' || echo './'`src/gflags_completions.cc
+libtool: compile: g++ -DHAVE_CONFIG_H -I. -I./src -I./src -D_THREAD_SAFE -DNDEBUG -g -O2 -MT libgflags_la-gflags_completions.lo -MD -MP -MF .deps/libgflags_la-gflags_completions.Tpo -c src/gflags_completions.cc -fno-common -DPIC -o .libs/libgflags_la-gflags_completions.o
+libtool: compile: g++ -DHAVE_CONFIG_H -I. -I./src -I./src -D_THREAD_SAFE -DNDEBUG -g -O2 -MT libgflags_la-gflags_completions.lo -MD -MP -MF .deps/libgflags_la-gflags_completions.Tpo -c src/gflags_completions.cc -o libgflags_la-gflags_completions.o >/dev/null 2>&1
+mv -f .deps/libgflags_la-gflags_completions.Tpo .deps/libgflags_la-gflags_completions.Plo
+/bin/sh ./libtool --tag=CXX --mode=link g++ -D_THREAD_SAFE -DNDEBUG -g -O2 -D_THREAD_SAFE -version-info 3:0:1 -o libgflags.la -rpath /usr/local/lib libgflags_la-gflags.lo libgflags_la-gflags_reporting.lo libgflags_la-gflags_completions.lo
+libtool: link: g++ -dynamiclib -Wl,-undefined -Wl,dynamic_lookup -o .libs/libgflags.2.dylib .libs/libgflags_la-gflags.o .libs/libgflags_la-gflags_reporting.o .libs/libgflags_la-gflags_completions.o -install_name /usr/local/lib/libgflags.2.dylib -compatibility_version 4 -current_version 4.0 -Wl,-single_module
+libtool: link: dsymutil .libs/libgflags.2.dylib || :
+libtool: link: (cd ".libs" && rm -f "libgflags.dylib" && ln -s "libgflags.2.dylib" "libgflags.dylib")
+libtool: link: ar cru .libs/libgflags.a libgflags_la-gflags.o libgflags_la-gflags_reporting.o libgflags_la-gflags_completions.o
+libtool: link: ranlib .libs/libgflags.a
+libtool: link: ( cd ".libs" && rm -f "libgflags.la" && ln -s "../libgflags.la" "libgflags.la" )
+/bin/sh ./libtool --tag=CXX --mode=compile g++ -DHAVE_CONFIG_H -I. -I./src -I./src -DNDEBUG -DNO_THREADS -g -O2 -MT libgflags_nothreads_la-gflags.lo -MD -MP -MF .deps/libgflags_nothreads_la-gflags.Tpo -c -o libgflags_nothreads_la-gflags.lo `test -f 'src/gflags.cc' || echo './'`src/gflags.cc
+libtool: compile: g++ -DHAVE_CONFIG_H -I. -I./src -I./src -DNDEBUG -DNO_THREADS -g -O2 -MT libgflags_nothreads_la-gflags.lo -MD -MP -MF .deps/libgflags_nothreads_la-gflags.Tpo -c src/gflags.cc -fno-common -DPIC -o .libs/libgflags_nothreads_la-gflags.o
+libtool: compile: g++ -DHAVE_CONFIG_H -I. -I./src -I./src -DNDEBUG -DNO_THREADS -g -O2 -MT libgflags_nothreads_la-gflags.lo -MD -MP -MF .deps/libgflags_nothreads_la-gflags.Tpo -c src/gflags.cc -o libgflags_nothreads_la-gflags.o >/dev/null 2>&1
+mv -f .deps/libgflags_nothreads_la-gflags.Tpo .deps/libgflags_nothreads_la-gflags.Plo
+/bin/sh ./libtool --tag=CXX --mode=compile g++ -DHAVE_CONFIG_H -I. -I./src -I./src -DNDEBUG -DNO_THREADS -g -O2 -MT libgflags_nothreads_la-gflags_reporting.lo -MD -MP -MF .deps/libgflags_nothreads_la-gflags_reporting.Tpo -c -o libgflags_nothreads_la-gflags_reporting.lo `test -f 'src/gflags_reporting.cc' || echo './'`src/gflags_reporting.cc
+libtool: compile: g++ -DHAVE_CONFIG_H -I. -I./src -I./src -DNDEBUG -DNO_THREADS -g -O2 -MT libgflags_nothreads_la-gflags_reporting.lo -MD -MP -MF .deps/libgflags_nothreads_la-gflags_reporting.Tpo -c src/gflags_reporting.cc -fno-common -DPIC -o .libs/libgflags_nothreads_la-gflags_reporting.o
+libtool: compile: g++ -DHAVE_CONFIG_H -I. -I./src -I./src -DNDEBUG -DNO_THREADS -g -O2 -MT libgflags_nothreads_la-gflags_reporting.lo -MD -MP -MF .deps/libgflags_nothreads_la-gflags_reporting.Tpo -c src/gflags_reporting.cc -o libgflags_nothreads_la-gflags_reporting.o >/dev/null 2>&1
+mv -f .deps/libgflags_nothreads_la-gflags_reporting.Tpo .deps/libgflags_nothreads_la-gflags_reporting.Plo
+/bin/sh ./libtool --tag=CXX --mode=compile g++ -DHAVE_CONFIG_H -I. -I./src -I./src -DNDEBUG -DNO_THREADS -g -O2 -MT libgflags_nothreads_la-gflags_completions.lo -MD -MP -MF .deps/libgflags_nothreads_la-gflags_completions.Tpo -c -o libgflags_nothreads_la-gflags_completions.lo `test -f 'src/gflags_completions.cc' || echo './'`src/gflags_completions.cc
+libtool: compile: g++ -DHAVE_CONFIG_H -I. -I./src -I./src -DNDEBUG -DNO_THREADS -g -O2 -MT libgflags_nothreads_la-gflags_completions.lo -MD -MP -MF .deps/libgflags_nothreads_la-gflags_completions.Tpo -c src/gflags_completions.cc -fno-common -DPIC -o .libs/libgflags_nothreads_la-gflags_completions.o
+libtool: compile: g++ -DHAVE_CONFIG_H -I. -I./src -I./src -DNDEBUG -DNO_THREADS -g -O2 -MT libgflags_nothreads_la-gflags_completions.lo -MD -MP -MF .deps/libgflags_nothreads_la-gflags_completions.Tpo -c src/gflags_completions.cc -o libgflags_nothreads_la-gflags_completions.o >/dev/null 2>&1
+mv -f .deps/libgflags_nothreads_la-gflags_completions.Tpo .deps/libgflags_nothreads_la-gflags_completions.Plo
+/bin/sh ./libtool --tag=CXX --mode=link g++ -DNDEBUG -DNO_THREADS -g -O2 -version-info 3:0:1 -o libgflags_nothreads.la -rpath /usr/local/lib libgflags_nothreads_la-gflags.lo libgflags_nothreads_la-gflags_reporting.lo libgflags_nothreads_la-gflags_completions.lo
+libtool: link: g++ -dynamiclib -Wl,-undefined -Wl,dynamic_lookup -o .libs/libgflags_nothreads.2.dylib .libs/libgflags_nothreads_la-gflags.o .libs/libgflags_nothreads_la-gflags_reporting.o .libs/libgflags_nothreads_la-gflags_completions.o -install_name /usr/local/lib/libgflags_nothreads.2.dylib -compatibility_version 4 -current_version 4.0 -Wl,-single_module
+libtool: link: dsymutil .libs/libgflags_nothreads.2.dylib || :
+libtool: link: (cd ".libs" && rm -f "libgflags_nothreads.dylib" && ln -s "libgflags_nothreads.2.dylib" "libgflags_nothreads.dylib")
+libtool: link: ar cru .libs/libgflags_nothreads.a libgflags_nothreads_la-gflags.o libgflags_nothreads_la-gflags_reporting.o libgflags_nothreads_la-gflags_completions.o
+libtool: link: ranlib .libs/libgflags_nothreads.a
+libtool: link: ( cd ".libs" && rm -f "libgflags_nothreads.la" && ln -s "../libgflags_nothreads.la" "libgflags_nothreads.la" )
+g++ -DHAVE_CONFIG_H -I. -I./src -I./src -D_THREAD_SAFE -g -O2 -MT gflags_unittest-gflags_unittest.o -MD -MP -MF .deps/gflags_unittest-gflags_unittest.Tpo -c -o gflags_unittest-gflags_unittest.o `test -f 'src/gflags_unittest.cc' || echo './'`src/gflags_unittest.cc
+mv -f .deps/gflags_unittest-gflags_unittest.Tpo .deps/gflags_unittest-gflags_unittest.Po
+/bin/sh ./libtool --tag=CXX --mode=link g++ -D_THREAD_SAFE -g -O2 -D_THREAD_SAFE -o gflags_unittest gflags_unittest-gflags_unittest.o libgflags.la
+libtool: link: g++ -D_THREAD_SAFE -g -O2 -D_THREAD_SAFE -o .libs/gflags_unittest gflags_unittest-gflags_unittest.o -Wl,-bind_at_load ./.libs/libgflags.dylib
+g++ -DHAVE_CONFIG_H -I. -I./src -I./src -Wall -Wwrite-strings -Woverloaded-virtual -Wno-sign-compare -g -O2 -MT gflags_unittest.o -MD -MP -MF .deps/gflags_unittest.Tpo -c -o gflags_unittest.o `test -f 'src/gflags_unittest.cc' || echo './'`src/gflags_unittest.cc
+mv -f .deps/gflags_unittest.Tpo .deps/gflags_unittest.Po
+/bin/sh ./libtool --tag=CXX --mode=link g++ -Wall -Wwrite-strings -Woverloaded-virtual -Wno-sign-compare -g -O2 -no-undefined -o gflags_nothreads_unittest gflags_unittest.o libgflags_nothreads.la
+libtool: link: g++ -Wall -Wwrite-strings -Woverloaded-virtual -Wno-sign-compare -g -O2 -o .libs/gflags_nothreads_unittest gflags_unittest.o -Wl,-bind_at_load ./.libs/libgflags_nothreads.dylib
+rm -f src/gflags_unittest-main.cc
+cp -p ./src/gflags_unittest.cc src/gflags_unittest-main.cc
+g++ -DHAVE_CONFIG_H -I. -I./src -I./src -Wall -Wwrite-strings -Woverloaded-virtual -Wno-sign-compare -g -O2 -MT gflags_unittest-main.o -MD -MP -MF .deps/gflags_unittest-main.Tpo -c -o gflags_unittest-main.o `test -f 'src/gflags_unittest-main.cc' || echo './'`src/gflags_unittest-main.cc
+mv -f .deps/gflags_unittest-main.Tpo .deps/gflags_unittest-main.Po
+/bin/sh ./libtool --tag=CXX --mode=link g++ -Wall -Wwrite-strings -Woverloaded-virtual -Wno-sign-compare -g -O2 -no-undefined -o gflags_unittest2 gflags_unittest-main.o libgflags_nothreads.la
+libtool: link: g++ -Wall -Wwrite-strings -Woverloaded-virtual -Wno-sign-compare -g -O2 -o .libs/gflags_unittest2 gflags_unittest-main.o -Wl,-bind_at_load ./.libs/libgflags_nothreads.dylib
+rm -f src/gflags_unittest_main.cc
+cp -p ./src/gflags_unittest.cc src/gflags_unittest_main.cc
+g++ -DHAVE_CONFIG_H -I. -I./src -I./src -Wall -Wwrite-strings -Woverloaded-virtual -Wno-sign-compare -g -O2 -MT gflags_unittest_main.o -MD -MP -MF .deps/gflags_unittest_main.Tpo -c -o gflags_unittest_main.o `test -f 'src/gflags_unittest_main.cc' || echo './'`src/gflags_unittest_main.cc
+mv -f .deps/gflags_unittest_main.Tpo .deps/gflags_unittest_main.Po
+/bin/sh ./libtool --tag=CXX --mode=link g++ -Wall -Wwrite-strings -Woverloaded-virtual -Wno-sign-compare -g -O2 -no-undefined -o gflags_unittest3 gflags_unittest_main.o libgflags_nothreads.la
+libtool: link: g++ -Wall -Wwrite-strings -Woverloaded-virtual -Wno-sign-compare -g -O2 -o .libs/gflags_unittest3 gflags_unittest_main.o -Wl,-bind_at_load ./.libs/libgflags_nothreads.dylib
+g++ -DHAVE_CONFIG_H -I. -I./src -I./src -D_THREAD_SAFE -g -O2 -MT gflags_strip_flags_test-gflags_strip_flags_test.o -MD -MP -MF .deps/gflags_strip_flags_test-gflags_strip_flags_test.Tpo -c -o gflags_strip_flags_test-gflags_strip_flags_test.o `test -f 'src/gflags_strip_flags_test.cc' || echo './'`src/gflags_strip_flags_test.cc
+mv -f .deps/gflags_strip_flags_test-gflags_strip_flags_test.Tpo .deps/gflags_strip_flags_test-gflags_strip_flags_test.Po
+/bin/sh ./libtool --tag=CXX --mode=link g++ -D_THREAD_SAFE -g -O2 -D_THREAD_SAFE -o gflags_strip_flags_test gflags_strip_flags_test-gflags_strip_flags_test.o libgflags.la
+libtool: link: g++ -D_THREAD_SAFE -g -O2 -D_THREAD_SAFE -o .libs/gflags_strip_flags_test gflags_strip_flags_test-gflags_strip_flags_test.o -Wl,-bind_at_load ./.libs/libgflags.dylib
+echo 'prefix=/usr/local' > "libgflags.pc".tmp
+echo 'exec_prefix='`echo '/usr/local' | sed 's@^/usr/local@${prefix}@'` >> "libgflags.pc".tmp
+echo 'libdir='`echo '/usr/local/lib' | sed 's@^/usr/local@${exec_prefix}@'` >> "libgflags.pc".tmp
+echo 'includedir='`echo '/usr/local/include' | sed 's@^/usr/local@${prefix}@'` >> "libgflags.pc".tmp
+echo '' >> "libgflags.pc".tmp
+echo 'Name: gflags' >> "libgflags.pc".tmp
+echo 'Version: 2.0' >> "libgflags.pc".tmp
+grep '^Summary:' ./packages/rpm/rpm.spec | sed s/^Summary:/Description:/ | head -n1 >> "libgflags.pc".tmp
+grep '^URL: ' ./packages/rpm/rpm.spec >> "libgflags.pc".tmp
+echo 'Requires:' >> "libgflags.pc".tmp
+echo 'Libs: -L${libdir} -lgflags' >> "libgflags.pc".tmp
+echo 'Libs.private: -D_THREAD_SAFE ' >> "libgflags.pc".tmp
+echo 'Cflags: -I${includedir}' >> "libgflags.pc".tmp
+mv -f "libgflags.pc".tmp "libgflags.pc"
+grep -v Libs.private libgflags.pc | sed s/-lgflags/-lgflags_nothreads/ > "libgflags_nothreads.pc"
diff --git a/src/third_party/gflags-2.0/missing b/src/third_party/gflags-2.0/missing
new file mode 100755
index 00000000000..1c8ff7049d8
--- /dev/null
+++ b/src/third_party/gflags-2.0/missing
@@ -0,0 +1,367 @@
+#! /bin/sh
+# Common stub for a few missing GNU programs while installing.
+
+scriptversion=2006-05-10.23
+
+# Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005, 2006
+# Free Software Foundation, Inc.
+# Originally by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+# 02110-1301, USA.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+if test $# -eq 0; then
+ echo 1>&2 "Try \`$0 --help' for more information"
+ exit 1
+fi
+
+run=:
+sed_output='s/.* --output[ =]\([^ ]*\).*/\1/p'
+sed_minuso='s/.* -o \([^ ]*\).*/\1/p'
+
+# In the cases where this matters, `missing' is being run in the
+# srcdir already.
+if test -f configure.ac; then
+ configure_ac=configure.ac
+else
+ configure_ac=configure.in
+fi
+
+msg="missing on your system"
+
+case $1 in
+--run)
+ # Try to run requested program, and just exit if it succeeds.
+ run=
+ shift
+ "$@" && exit 0
+ # Exit code 63 means version mismatch. This often happens
+ # when the user try to use an ancient version of a tool on
+ # a file that requires a minimum version. In this case we
+ # we should proceed has if the program had been absent, or
+ # if --run hadn't been passed.
+ if test $? = 63; then
+ run=:
+ msg="probably too old"
+ fi
+ ;;
+
+ -h|--h|--he|--hel|--help)
+ echo "\
+$0 [OPTION]... PROGRAM [ARGUMENT]...
+
+Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an
+error status if there is no known handling for PROGRAM.
+
+Options:
+ -h, --help display this help and exit
+ -v, --version output version information and exit
+ --run try to run the given command, and emulate it if it fails
+
+Supported PROGRAM values:
+ aclocal touch file \`aclocal.m4'
+ autoconf touch file \`configure'
+ autoheader touch file \`config.h.in'
+ autom4te touch the output file, or create a stub one
+ automake touch all \`Makefile.in' files
+ bison create \`y.tab.[ch]', if possible, from existing .[ch]
+ flex create \`lex.yy.c', if possible, from existing .c
+ help2man touch the output file
+ lex create \`lex.yy.c', if possible, from existing .c
+ makeinfo touch the output file
+ tar try tar, gnutar, gtar, then tar without non-portable flags
+ yacc create \`y.tab.[ch]', if possible, from existing .[ch]
+
+Send bug reports to <bug-automake@gnu.org>."
+ exit $?
+ ;;
+
+ -v|--v|--ve|--ver|--vers|--versi|--versio|--version)
+ echo "missing $scriptversion (GNU Automake)"
+ exit $?
+ ;;
+
+ -*)
+ echo 1>&2 "$0: Unknown \`$1' option"
+ echo 1>&2 "Try \`$0 --help' for more information"
+ exit 1
+ ;;
+
+esac
+
+# Now exit if we have it, but it failed. Also exit now if we
+# don't have it and --version was passed (most likely to detect
+# the program).
+case $1 in
+ lex|yacc)
+ # Not GNU programs, they don't have --version.
+ ;;
+
+ tar)
+ if test -n "$run"; then
+ echo 1>&2 "ERROR: \`tar' requires --run"
+ exit 1
+ elif test "x$2" = "x--version" || test "x$2" = "x--help"; then
+ exit 1
+ fi
+ ;;
+
+ *)
+ if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
+ # We have it, but it failed.
+ exit 1
+ elif test "x$2" = "x--version" || test "x$2" = "x--help"; then
+ # Could not run --version or --help. This is probably someone
+ # running `$TOOL --version' or `$TOOL --help' to check whether
+ # $TOOL exists and not knowing $TOOL uses missing.
+ exit 1
+ fi
+ ;;
+esac
+
+# If it does not exist, or fails to run (possibly an outdated version),
+# try to emulate it.
+case $1 in
+ aclocal*)
+ echo 1>&2 "\
+WARNING: \`$1' is $msg. You should only need it if
+ you modified \`acinclude.m4' or \`${configure_ac}'. You might want
+ to install the \`Automake' and \`Perl' packages. Grab them from
+ any GNU archive site."
+ touch aclocal.m4
+ ;;
+
+ autoconf)
+ echo 1>&2 "\
+WARNING: \`$1' is $msg. You should only need it if
+ you modified \`${configure_ac}'. You might want to install the
+ \`Autoconf' and \`GNU m4' packages. Grab them from any GNU
+ archive site."
+ touch configure
+ ;;
+
+ autoheader)
+ echo 1>&2 "\
+WARNING: \`$1' is $msg. You should only need it if
+ you modified \`acconfig.h' or \`${configure_ac}'. You might want
+ to install the \`Autoconf' and \`GNU m4' packages. Grab them
+ from any GNU archive site."
+ files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}`
+ test -z "$files" && files="config.h"
+ touch_files=
+ for f in $files; do
+ case $f in
+ *:*) touch_files="$touch_files "`echo "$f" |
+ sed -e 's/^[^:]*://' -e 's/:.*//'`;;
+ *) touch_files="$touch_files $f.in";;
+ esac
+ done
+ touch $touch_files
+ ;;
+
+ automake*)
+ echo 1>&2 "\
+WARNING: \`$1' is $msg. You should only need it if
+ you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'.
+ You might want to install the \`Automake' and \`Perl' packages.
+ Grab them from any GNU archive site."
+ find . -type f -name Makefile.am -print |
+ sed 's/\.am$/.in/' |
+ while read f; do touch "$f"; done
+ ;;
+
+ autom4te)
+ echo 1>&2 "\
+WARNING: \`$1' is needed, but is $msg.
+ You might have modified some files without having the
+ proper tools for further handling them.
+ You can get \`$1' as part of \`Autoconf' from any GNU
+ archive site."
+
+ file=`echo "$*" | sed -n "$sed_output"`
+ test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"`
+ if test -f "$file"; then
+ touch $file
+ else
+ test -z "$file" || exec >$file
+ echo "#! /bin/sh"
+ echo "# Created by GNU Automake missing as a replacement of"
+ echo "# $ $@"
+ echo "exit 0"
+ chmod +x $file
+ exit 1
+ fi
+ ;;
+
+ bison|yacc)
+ echo 1>&2 "\
+WARNING: \`$1' $msg. You should only need it if
+ you modified a \`.y' file. You may need the \`Bison' package
+ in order for those modifications to take effect. You can get
+ \`Bison' from any GNU archive site."
+ rm -f y.tab.c y.tab.h
+ if test $# -ne 1; then
+ eval LASTARG="\${$#}"
+ case $LASTARG in
+ *.y)
+ SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'`
+ if test -f "$SRCFILE"; then
+ cp "$SRCFILE" y.tab.c
+ fi
+ SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'`
+ if test -f "$SRCFILE"; then
+ cp "$SRCFILE" y.tab.h
+ fi
+ ;;
+ esac
+ fi
+ if test ! -f y.tab.h; then
+ echo >y.tab.h
+ fi
+ if test ! -f y.tab.c; then
+ echo 'main() { return 0; }' >y.tab.c
+ fi
+ ;;
+
+ lex|flex)
+ echo 1>&2 "\
+WARNING: \`$1' is $msg. You should only need it if
+ you modified a \`.l' file. You may need the \`Flex' package
+ in order for those modifications to take effect. You can get
+ \`Flex' from any GNU archive site."
+ rm -f lex.yy.c
+ if test $# -ne 1; then
+ eval LASTARG="\${$#}"
+ case $LASTARG in
+ *.l)
+ SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'`
+ if test -f "$SRCFILE"; then
+ cp "$SRCFILE" lex.yy.c
+ fi
+ ;;
+ esac
+ fi
+ if test ! -f lex.yy.c; then
+ echo 'main() { return 0; }' >lex.yy.c
+ fi
+ ;;
+
+ help2man)
+ echo 1>&2 "\
+WARNING: \`$1' is $msg. You should only need it if
+ you modified a dependency of a manual page. You may need the
+ \`Help2man' package in order for those modifications to take
+ effect. You can get \`Help2man' from any GNU archive site."
+
+ file=`echo "$*" | sed -n "$sed_output"`
+ test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"`
+ if test -f "$file"; then
+ touch $file
+ else
+ test -z "$file" || exec >$file
+ echo ".ab help2man is required to generate this page"
+ exit 1
+ fi
+ ;;
+
+ makeinfo)
+ echo 1>&2 "\
+WARNING: \`$1' is $msg. You should only need it if
+ you modified a \`.texi' or \`.texinfo' file, or any other file
+ indirectly affecting the aspect of the manual. The spurious
+ call might also be the consequence of using a buggy \`make' (AIX,
+ DU, IRIX). You might want to install the \`Texinfo' package or
+ the \`GNU make' package. Grab either from any GNU archive site."
+ # The file to touch is that specified with -o ...
+ file=`echo "$*" | sed -n "$sed_output"`
+ test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"`
+ if test -z "$file"; then
+ # ... or it is the one specified with @setfilename ...
+ infile=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'`
+ file=`sed -n '
+ /^@setfilename/{
+ s/.* \([^ ]*\) *$/\1/
+ p
+ q
+ }' $infile`
+ # ... or it is derived from the source name (dir/f.texi becomes f.info)
+ test -z "$file" && file=`echo "$infile" | sed 's,.*/,,;s,.[^.]*$,,'`.info
+ fi
+ # If the file does not exist, the user really needs makeinfo;
+ # let's fail without touching anything.
+ test -f $file || exit 1
+ touch $file
+ ;;
+
+ tar)
+ shift
+
+ # We have already tried tar in the generic part.
+ # Look for gnutar/gtar before invocation to avoid ugly error
+ # messages.
+ if (gnutar --version > /dev/null 2>&1); then
+ gnutar "$@" && exit 0
+ fi
+ if (gtar --version > /dev/null 2>&1); then
+ gtar "$@" && exit 0
+ fi
+ firstarg="$1"
+ if shift; then
+ case $firstarg in
+ *o*)
+ firstarg=`echo "$firstarg" | sed s/o//`
+ tar "$firstarg" "$@" && exit 0
+ ;;
+ esac
+ case $firstarg in
+ *h*)
+ firstarg=`echo "$firstarg" | sed s/h//`
+ tar "$firstarg" "$@" && exit 0
+ ;;
+ esac
+ fi
+
+ echo 1>&2 "\
+WARNING: I can't seem to be able to run \`tar' with the given arguments.
+ You may want to install GNU tar or Free paxutils, or check the
+ command line arguments."
+ exit 1
+ ;;
+
+ *)
+ echo 1>&2 "\
+WARNING: \`$1' is needed, and is $msg.
+ You might have modified some files without having the
+ proper tools for further handling them. Check the \`README' file,
+ it often tells you about the needed prerequisites for installing
+ this package. You may also peek at any GNU archive site, in case
+ some other package would contain this missing \`$1' program."
+ exit 1
+ ;;
+esac
+
+exit 0
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-end: "$"
+# End:
diff --git a/src/third_party/gflags-2.0/packages/deb.sh b/src/third_party/gflags-2.0/packages/deb.sh
new file mode 100755
index 00000000000..31b423c12fa
--- /dev/null
+++ b/src/third_party/gflags-2.0/packages/deb.sh
@@ -0,0 +1,74 @@
+#!/bin/bash -e
+
+# This takes one commandline argument, the name of the package. If no
+# name is given, then we'll end up just using the name associated with
+# an arbitrary .tar.gz file in the rootdir. That's fine: there's probably
+# only one.
+#
+# Run this from the 'packages' directory, just under rootdir
+
+## Set LIB to lib if exporting a library, empty-string else
+LIB=
+#LIB=lib
+
+PACKAGE="$1"
+VERSION="$2"
+
+# We can only build Debian packages, if the Debian build tools are installed
+if [ \! -x /usr/bin/debuild ]; then
+ echo "Cannot find /usr/bin/debuild. Not building Debian packages." 1>&2
+ exit 0
+fi
+
+# Double-check we're in the packages directory, just under rootdir
+if [ \! -r ../Makefile -a \! -r ../INSTALL ]; then
+ echo "Must run $0 in the 'packages' directory, under the root directory." 1>&2
+ echo "Also, you must run \"make dist\" before running this script." 1>&2
+ exit 0
+fi
+
+# Find the top directory for this package
+topdir="${PWD%/*}"
+
+# Find the tar archive built by "make dist"
+archive="${PACKAGE}-${VERSION}"
+archive_with_underscore="${PACKAGE}_${VERSION}"
+if [ -z "${archive}" ]; then
+ echo "Cannot find ../$PACKAGE*.tar.gz. Run \"make dist\" first." 1>&2
+ exit 0
+fi
+
+# Create a pristine directory for building the Debian package files
+trap 'rm -rf '`pwd`/tmp'; exit $?' EXIT SIGHUP SIGINT SIGTERM
+
+rm -rf tmp
+mkdir -p tmp
+cd tmp
+
+# Debian has very specific requirements about the naming of build
+# directories, and tar archives. It also wants to write all generated
+# packages to the parent of the source directory. We accommodate these
+# requirements by building directly from the tar file.
+ln -s "${topdir}/${archive}.tar.gz" "${LIB}${archive}.orig.tar.gz"
+# Some version of debuilder want foo.orig.tar.gz with _ between versions.
+ln -s "${topdir}/${archive}.tar.gz" "${LIB}${archive_with_underscore}.orig.tar.gz"
+tar zfx "${LIB}${archive}.orig.tar.gz"
+[ -n "${LIB}" ] && mv "${archive}" "${LIB}${archive}"
+cd "${LIB}${archive}"
+# This is one of those 'specific requirements': where the deb control files live
+cp -a "packages/deb" "debian"
+
+# Now, we can call Debian's standard build tool
+debuild -uc -us
+cd ../.. # get back to the original top-level dir
+
+# We'll put the result in a subdirectory that's named after the OS version
+# we've made this .deb file for.
+destdir="debian-$(cat /etc/debian_version 2>/dev/null || echo UNKNOWN)"
+
+rm -rf "$destdir"
+mkdir -p "$destdir"
+mv $(find tmp -mindepth 1 -maxdepth 1 -type f) "$destdir"
+
+echo
+echo "The Debian package files are located in $PWD/$destdir"
diff --git a/src/third_party/gflags-2.0/packages/deb/changelog b/src/third_party/gflags-2.0/packages/deb/changelog
new file mode 100755
index 00000000000..6ba6dad10a0
--- /dev/null
+++ b/src/third_party/gflags-2.0/packages/deb/changelog
@@ -0,0 +1,135 @@
+gflags (2.0-1) unstable; urgency=low
+
+ * New upstream release.
+
+ -- Google Inc. and others <google-gflags@googlegroups.com> Wed, 25 Jan 2012 15:09:14 -0800
+
+gflags (1.7-1) unstable; urgency=low
+
+ * New upstream release.
+
+ -- Google Inc. <opensource@google.com> Tue, 20 Dec 2011 19:48:57 -0800
+
+gflags (1.6-1) unstable; urgency=low
+
+ * New upstream release.
+
+ -- Google Inc. <opensource@google.com> Fri, 29 Jul 2011 19:05:21 -0700
+
+gflags (1.5-1) unstable; urgency=low
+
+ * New upstream release.
+
+ -- Google Inc. <opensource@google.com> Mon, 24 Jan 2011 16:11:35 -0800
+
+gflags (1.4-2) unstable; urgency=low
+
+ * Accidentally uploaded an outdated .deb to Google Code; this is the right one
+
+ -- Google Inc. <opensource@google.com> Wed, 13 Oct 2010 17:48:44 -0700
+
+gflags (1.4-1) unstable; urgency=low
+
+ * New upstream release.
+
+ -- Google Inc. <opensource@google.com> Wed, 13 Oct 2010 17:40:12 -0700
+
+gflags (1.3-1) unstable; urgency=low
+
+ * New upstream release.
+
+ -- Google Inc. <opensource@google.com> Mon, 04 Jan 2010 18:09:30 -0800
+
+gflags (1.2-1) unstable; urgency=low
+
+ * New upstream release.
+
+ -- Google Inc. <opensource@google.com> Thu, 10 Sep 2009 12:53:04 -0700
+
+gflags (1.1-1) unstable; urgency=low
+
+ * New upstream release.
+ * Renamed package to gflags, from google-gflags, to match the package
+ and library names used in the .rpm file, and in the tarball.
+
+ -- Google Inc. <opensource@google.com> Tue, 14 Apr 2009 12:35:25 -0700
+
+google-gflags (1.0-1) unstable; urgency=low
+
+ * New upstream release.
+
+ -- Google Inc. <opensource@google.com> Fri, 03 Oct 2008 15:16:46 -0700
+
+google-gflags (1.0rc2-1) unstable; urgency=low
+
+ * New upstream release.
+
+ -- Google Inc. <opensource@google.com> Tue, 18 Sep 2008 12:58:05 -0700
+
+google-gflags (1.0rc1-1) unstable; urgency=low
+
+ * New upstream release.
+
+ -- Google Inc. <opensource@google.com> Tue, 19 Aug 2008 16:15:48 -0700
+
+google-gflags (0.9-1) unstable; urgency=low
+
+ * New upstream release.
+
+ -- Google Inc. <opensource@google.com> Mon, 21 Jul 2008 23:01:38 -0700
+
+google-gflags (0.8-1) unstable; urgency=low
+
+ * New upstream release.
+
+ -- Google Inc. <opensource@google.com> Wed, 26 Mar 2008 15:20:18 -0700
+
+google-gflags (0.7-1) unstable; urgency=low
+
+ * New upstream release.
+
+ -- Google Inc. <opensource@google.com> Thu, 18 Oct 2007 11:33:20 -0700
+
+google-gflags (0.6-2) unstable; urgency=low
+
+ * Somehow 0.6-1 was missing the lib* control files, so the .deb produced
+ was empty. Fix that to get an actual valid .deb file.
+
+ -- Google Inc. <opensource@google.com> Wed, 15 Aug 2007 12:32:01 -0700
+
+google-gflags (0.6-1) unstable; urgency=low
+
+ * New upstream release.
+
+ -- Google Inc. <opensource@google.com> Wed, 15 Aug 2007 07:35:51 -0700
+
+google-gflags (0.5-1) unstable; urgency=low
+
+ * New upstream release.
+
+ -- Google Inc. <opensource@google.com> Tue, 12 Jun 2007 15:23:42 -0700
+
+google-gflags (0.4-1) unstable; urgency=low
+
+ * New upstream release.
+
+ -- Google Inc. <opensource@google.com> Thu, 19 Apr 2007 15:18:43 -0700
+
+google-gflags (0.3-1) unstable; urgency=low
+
+ * New upstream release.
+
+ -- Google Inc. <opensource@google.com> Mon, 22 Jan 2007 15:33:06 -0800
+
+google-gflags (0.2-1) unstable; urgency=low
+
+ * New upstream release.
+
+ -- Google Inc. <opensource@google.com> Wed, 28 Mar 2007 12:15:56 -0700
+
+google-gflags (0.1-1) unstable; urgency=low
+
+ * Initial release.
+
+ -- Google Inc. <opensource@google.com> Wed, 13 Dec 2006 11:33:30 -0800
+
diff --git a/src/third_party/gflags-2.0/packages/deb/compat b/src/third_party/gflags-2.0/packages/deb/compat
new file mode 100755
index 00000000000..b8626c4cff2
--- /dev/null
+++ b/src/third_party/gflags-2.0/packages/deb/compat
@@ -0,0 +1 @@
+4
diff --git a/src/third_party/gflags-2.0/packages/deb/control b/src/third_party/gflags-2.0/packages/deb/control
new file mode 100755
index 00000000000..b06c76f6c27
--- /dev/null
+++ b/src/third_party/gflags-2.0/packages/deb/control
@@ -0,0 +1,25 @@
+Source: gflags
+Priority: optional
+Maintainer: Google Inc. and others <google-gflags@googlegroups.com>
+Build-Depends: debhelper (>= 4.0.0), binutils
+Standards-Version: 3.6.1
+
+Package: libgflags-dev
+Section: libdevel
+Architecture: any
+Depends: libgflags0 (= ${Source-Version})
+Description: a library that implements commandline flags
+ processing. As such it's a replacement for getopt(). It has increased
+ flexibility, including built-in support for C++ types like string, and
+ the ability to define flags in the source file in which they're used.
+ The devel package contains static and debug libraries and header files
+ for developing applications that use the gflags package.
+
+Package: libgflags0
+Section: libs
+Architecture: any
+Depends: ${shlibs:Depends}
+Description: a library that implements commandline flags
+ processing. As such it's a replacement for getopt(). It has increased
+ flexibility, including built-in support for C++ types like string, and
+ the ability to define flags in the source file in which they're used.
diff --git a/src/third_party/gflags-2.0/packages/deb/copyright b/src/third_party/gflags-2.0/packages/deb/copyright
new file mode 100755
index 00000000000..d85450b5179
--- /dev/null
+++ b/src/third_party/gflags-2.0/packages/deb/copyright
@@ -0,0 +1,35 @@
+This package was debianized by Craig Silverstein <google-ctemplate@google.com>
+on Wed, 25 Jan 2012 15:09:14 -0800.
+
+It was downloaded from http://code.google.com/p/gflags/downloads/list
+
+Upstream Author: google-gflags@google.com
+
+Copyright (c) 2006, Google Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+ * Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+copyright notice, this list of conditions and the following disclaimer
+in the documentation and/or other materials provided with the
+distribution.
+ * Neither the name of Google Inc. nor the names of its
+contributors may be used to endorse or promote products derived from
+this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/src/third_party/gflags-2.0/packages/deb/docs b/src/third_party/gflags-2.0/packages/deb/docs
new file mode 100755
index 00000000000..6405ee88c1d
--- /dev/null
+++ b/src/third_party/gflags-2.0/packages/deb/docs
@@ -0,0 +1,8 @@
+AUTHORS
+COPYING
+ChangeLog
+INSTALL
+NEWS
+README
+doc/designstyle.css
+doc/gflags.html
diff --git a/src/third_party/gflags-2.0/packages/deb/libgflags-dev.dirs b/src/third_party/gflags-2.0/packages/deb/libgflags-dev.dirs
new file mode 100755
index 00000000000..4ae69a66586
--- /dev/null
+++ b/src/third_party/gflags-2.0/packages/deb/libgflags-dev.dirs
@@ -0,0 +1,5 @@
+usr/lib
+usr/lib/pkgconfig
+usr/include
+usr/include/google
+usr/include/gflags
diff --git a/src/third_party/gflags-2.0/packages/deb/libgflags-dev.install b/src/third_party/gflags-2.0/packages/deb/libgflags-dev.install
new file mode 100755
index 00000000000..926d54b7330
--- /dev/null
+++ b/src/third_party/gflags-2.0/packages/deb/libgflags-dev.install
@@ -0,0 +1,12 @@
+usr/include/google/*
+usr/include/gflags/*
+usr/lib/lib*.so
+usr/lib/lib*.a
+usr/lib/*.la
+usr/lib/pkgconfig/*.pc
+debian/tmp/usr/include/google/*
+debian/tmp/usr/include/gflags/*
+debian/tmp/usr/lib/lib*.so
+debian/tmp/usr/lib/lib*.a
+debian/tmp/usr/lib/*.la
+debian/tmp/usr/lib/pkgconfig/*.pc
diff --git a/src/third_party/gflags-2.0/packages/deb/libgflags0.dirs b/src/third_party/gflags-2.0/packages/deb/libgflags0.dirs
new file mode 100755
index 00000000000..14f5b95d7f4
--- /dev/null
+++ b/src/third_party/gflags-2.0/packages/deb/libgflags0.dirs
@@ -0,0 +1,2 @@
+usr/lib
+usr/bin
diff --git a/src/third_party/gflags-2.0/packages/deb/libgflags0.install b/src/third_party/gflags-2.0/packages/deb/libgflags0.install
new file mode 100755
index 00000000000..434db322403
--- /dev/null
+++ b/src/third_party/gflags-2.0/packages/deb/libgflags0.install
@@ -0,0 +1,4 @@
+usr/lib/lib*.so.*
+debian/tmp/usr/lib/lib*.so.*
+usr/bin/*
+debian/tmp/usr/bin/*
diff --git a/src/third_party/gflags-2.0/packages/deb/rules b/src/third_party/gflags-2.0/packages/deb/rules
new file mode 100755
index 00000000000..f520befd259
--- /dev/null
+++ b/src/third_party/gflags-2.0/packages/deb/rules
@@ -0,0 +1,117 @@
+#!/usr/bin/make -f
+# -*- makefile -*-
+# Sample debian/rules that uses debhelper.
+# This file was originally written by Joey Hess and Craig Small.
+# As a special exception, when this file is copied by dh-make into a
+# dh-make output file, you may use that output file without restriction.
+# This special exception was added by Craig Small in version 0.37 of dh-make.
+
+# Uncomment this to turn on verbose mode.
+#export DH_VERBOSE=1
+
+
+# These are used for cross-compiling and for saving the configure script
+# from having to guess our platform (since we know it already)
+DEB_HOST_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_HOST_GNU_TYPE)
+DEB_BUILD_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_BUILD_GNU_TYPE)
+
+
+CFLAGS = -Wall -g
+
+ifneq (,$(findstring noopt,$(DEB_BUILD_OPTIONS)))
+ CFLAGS += -O0
+else
+ CFLAGS += -O2
+endif
+ifeq (,$(findstring nostrip,$(DEB_BUILD_OPTIONS)))
+ INSTALL_PROGRAM += -s
+endif
+
+# shared library versions, option 1
+#version=2.0.5
+#major=2
+# option 2, assuming the library is created as src/.libs/libfoo.so.2.0.5 or so
+version=`ls src/.libs/lib*.so.* | \
+ awk '{if (match($$0,/[0-9]+\.[0-9]+\.[0-9]+$$/)) print substr($$0,RSTART)}'`
+major=`ls src/.libs/lib*.so.* | \
+ awk '{if (match($$0,/\.so\.[0-9]+$$/)) print substr($$0,RSTART+4)}'`
+
+config.status: configure
+ dh_testdir
+ # Add here commands to configure the package.
+ CFLAGS="$(CFLAGS)" ./configure --host=$(DEB_HOST_GNU_TYPE) --build=$(DEB_BUILD_GNU_TYPE) --prefix=/usr --mandir=\$${prefix}/share/man --infodir=\$${prefix}/share/info
+
+
+build: build-stamp
+build-stamp: config.status
+ dh_testdir
+
+ # Add here commands to compile the package.
+ $(MAKE)
+
+ touch build-stamp
+
+clean:
+ dh_testdir
+ dh_testroot
+ rm -f build-stamp
+
+ # Add here commands to clean up after the build process.
+ -$(MAKE) distclean
+ifneq "$(wildcard /usr/share/misc/config.sub)" ""
+ cp -f /usr/share/misc/config.sub config.sub
+endif
+ifneq "$(wildcard /usr/share/misc/config.guess)" ""
+ cp -f /usr/share/misc/config.guess config.guess
+endif
+
+
+ dh_clean
+
+install: build
+ dh_testdir
+ dh_testroot
+ dh_clean -k
+ dh_installdirs
+
+ # Add here commands to install the package into debian/tmp
+ $(MAKE) install DESTDIR=$(CURDIR)/debian/tmp
+
+
+# Build architecture-independent files here.
+binary-indep: build install
+# We have nothing to do by default.
+
+# Build architecture-dependent files here.
+binary-arch: build install
+ dh_testdir
+ dh_testroot
+ dh_installchangelogs ChangeLog
+ dh_installdocs
+ dh_installexamples
+ dh_install --sourcedir=debian/tmp
+# dh_installmenu
+# dh_installdebconf
+# dh_installlogrotate
+# dh_installemacsen
+# dh_installpam
+# dh_installmime
+# dh_installinit
+# dh_installcron
+# dh_installinfo
+ dh_installman
+ dh_link
+ dh_strip
+ dh_compress
+ dh_fixperms
+# dh_perl
+# dh_python
+ dh_makeshlibs
+ dh_installdeb
+ dh_shlibdeps
+ dh_gencontrol
+ dh_md5sums
+ dh_builddeb
+
+binary: binary-indep binary-arch
+.PHONY: build clean binary-indep binary-arch binary install
diff --git a/src/third_party/gflags-2.0/packages/rpm.sh b/src/third_party/gflags-2.0/packages/rpm.sh
new file mode 100755
index 00000000000..045422590ed
--- /dev/null
+++ b/src/third_party/gflags-2.0/packages/rpm.sh
@@ -0,0 +1,86 @@
+#!/bin/sh -e
+
+# Run this from the 'packages' directory, just under rootdir
+
+# We can only build rpm packages, if the rpm build tools are installed
+if [ \! -x /usr/bin/rpmbuild ]
+then
+ echo "Cannot find /usr/bin/rpmbuild. Not building an rpm." 1>&2
+ exit 0
+fi
+
+# Check the commandline flags
+PACKAGE="$1"
+VERSION="$2"
+fullname="${PACKAGE}-${VERSION}"
+archive=../$fullname.tar.gz
+
+if [ -z "$1" -o -z "$2" ]
+then
+ echo "Usage: $0 <package name> <package version>" 1>&2
+ exit 0
+fi
+
+# Double-check we're in the packages directory, just under rootdir
+if [ \! -r ../Makefile -a \! -r ../INSTALL ]
+then
+ echo "Must run $0 in the 'packages' directory, under the root directory." 1>&2
+ echo "Also, you must run \"make dist\" before running this script." 1>&2
+ exit 0
+fi
+
+if [ \! -r "$archive" ]
+then
+ echo "Cannot find $archive. Run \"make dist\" first." 1>&2
+ exit 0
+fi
+
+# Create the directory where the input lives, and where the output should live
+RPM_SOURCE_DIR="/tmp/rpmsource-$fullname"
+RPM_BUILD_DIR="/tmp/rpmbuild-$fullname"
+
+trap 'rm -rf $RPM_SOURCE_DIR $RPM_BUILD_DIR; exit $?' EXIT SIGHUP SIGINT SIGTERM
+
+rm -rf "$RPM_SOURCE_DIR" "$RPM_BUILD_DIR"
+mkdir "$RPM_SOURCE_DIR"
+mkdir "$RPM_BUILD_DIR"
+
+cp "$archive" "$RPM_SOURCE_DIR"
+
+# rpmbuild -- as far as I can tell -- asks the OS what CPU it has.
+# This may differ from what kind of binaries gcc produces. dpkg
+# does a better job of this, so if we can run 'dpkg --print-architecture'
+# to get the build CPU, we use that in preference of the rpmbuild
+# default.
+target=`dpkg --print-architecture 2>/dev/null || echo ""`
+if [ -n "$target" ]
+then
+ target=" --target $target"
+fi
+
+rpmbuild -bb rpm/rpm.spec $target \
+ --define "NAME $PACKAGE" \
+ --define "VERSION $VERSION" \
+ --define "_sourcedir $RPM_SOURCE_DIR" \
+ --define "_builddir $RPM_BUILD_DIR" \
+ --define "_rpmdir $RPM_SOURCE_DIR"
+
+# We put the output in a directory based on what system we've built for
+destdir=rpm-unknown
+if [ -r /etc/issue ]
+then
+ grep "Red Hat.*release 7" /etc/issue >/dev/null 2>&1 && destdir=rh7
+ grep "Red Hat.*release 8" /etc/issue >/dev/null 2>&1 && destdir=rh8
+ grep "Red Hat.*release 9" /etc/issue >/dev/null 2>&1 && destdir=rh9
+ if grep Fedora /etc/issue >/dev/null; then
+ destdir=fc`grep Fedora /etc/issue | cut -d' ' -f 4`;
+ fi
+fi
+
+rm -rf "$destdir"
+mkdir -p "$destdir"
+# We want to get not only the main package but devel etc, hence the middle *
+mv "$RPM_SOURCE_DIR"/*/"${PACKAGE}"-*"${VERSION}"*.rpm "$destdir"
+
+echo
+echo "The rpm package file(s) are located in $PWD/$destdir"
diff --git a/src/third_party/gflags-2.0/packages/rpm/rpm.spec b/src/third_party/gflags-2.0/packages/rpm/rpm.spec
new file mode 100755
index 00000000000..f74e38a9c5f
--- /dev/null
+++ b/src/third_party/gflags-2.0/packages/rpm/rpm.spec
@@ -0,0 +1,81 @@
+%define RELEASE 1
+%define rel %{?CUSTOM_RELEASE} %{!?CUSTOM_RELEASE:%RELEASE}
+%define prefix /usr
+
+Name: %NAME
+Summary: A commandline flags library that allows for distributed flags
+Version: %VERSION
+Release: %rel
+Group: Development/Libraries
+URL: http://code.google.com/p/gflags
+License: BSD
+Vendor: Google Inc. and others
+Packager: Google Inc. and others <google-gflags@googlegroups.com>
+Source: http://%{NAME}.googlecode.com/files/%{NAME}-%{VERSION}.tar.gz
+Distribution: Redhat 7 and above.
+Buildroot: %{_tmppath}/%{name}-root
+Prefix: %prefix
+
+%description
+The %name package contains a library that implements commandline flags
+processing. As such it's a replacement for getopt(). It has increased
+flexibility, including built-in support for C++ types like string, and
+the ability to define flags in the source file in which they're used.
+
+%package devel
+Summary: A commandline flags library that allows for distributed flags
+Group: Development/Libraries
+Requires: %{NAME} = %{VERSION}
+
+%description devel
+The %name-devel package contains static and debug libraries and header
+files for developing applications that use the %name package.
+
+%changelog
+ * Thu Sep 10 2009 <opensource@google.com>
+ - Change from '%configure' to something like it, but without -m32
+
+ * Mon Apr 20 2009 <opensource@google.com>
+ - Change build rule to use '%configure' rather than './configure'
+ - Change install to use DESTDIR instead of prefix for make install.
+ - Use wildcards for doc/ and lib/ directories
+ - Use {_libdir}/{_includedir}/etc instead of {prefix}/lib, etc
+
+ * Tue Dec 13 2006 <opensource@google.com>
+ - First draft
+
+%prep
+%setup
+
+%build
+# I can't use '% configure', because it defines -m32 which breaks the
+# build somehow on my system. But I do take as much from % configure
+# (in /usr/lib/rpm/macros) as I can.
+./configure --prefix=%{_prefix} --exec-prefix=%{_exec_prefix} --bindir=%{_bindir} --sbindir=%{_sbindir} --sysconfdir=%{_sysconfdir} --datadir=%{_datadir} --includedir=%{_includedir} --libdir=%{_libdir} --libexecdir=%{_libexecdir} --localstatedir=%{_localstatedir} --sharedstatedir=%{_sharedstatedir} --mandir=%{_mandir} --infodir=%{_infodir}
+make
+
+%install
+rm -rf $RPM_BUILD_ROOT
+make DESTDIR=$RPM_BUILD_ROOT install
+
+%clean
+rm -rf $RPM_BUILD_ROOT
+
+%files
+%defattr(-,root,root)
+
+%docdir %{prefix}/share/doc/%{NAME}-%{VERSION}
+%{prefix}/share/doc/%{NAME}-%{VERSION}/*
+
+%{_libdir}/*.so.*
+%{_bindir}/gflags_completions.sh
+
+%files devel
+%defattr(-,root,root)
+
+%{_includedir}/gflags
+%{_includedir}/google
+%{_libdir}/*.a
+%{_libdir}/*.la
+%{_libdir}/*.so
+%{_libdir}/pkgconfig/*.pc
diff --git a/src/third_party/gflags-2.0/src/config.h b/src/third_party/gflags-2.0/src/config.h
new file mode 100755
index 00000000000..68b02cd4ce3
--- /dev/null
+++ b/src/third_party/gflags-2.0/src/config.h
@@ -0,0 +1,115 @@
+/* src/config.h. Generated from config.h.in by configure. */
+/* src/config.h.in. Generated from configure.ac by autoheader. */
+
+/* Always the empty-string on non-windows systems. On windows, should be
+ "__declspec(dllexport)". This way, when we compile the dll, we export our
+ functions/classes. It's safe to define this here because config.h is only
+ used internally, to compile the DLL, and every DLL source file #includes
+ "config.h" before anything else. */
+#define GFLAGS_DLL_DECL /**/
+
+/* Namespace for Google classes */
+#define GOOGLE_NAMESPACE ::google
+
+/* Define to 1 if you have the <dlfcn.h> header file. */
+#define HAVE_DLFCN_H 1
+
+/* Define to 1 if you have the <fnmatch.h> header file. */
+#ifndef _WIN32
+#define HAVE_FNMATCH_H 1
+#endif
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#ifndef _WIN32
+#define HAVE_INTTYPES_H 1
+#endif
+
+/* Define to 1 if you have the <memory.h> header file. */
+#define HAVE_MEMORY_H 1
+
+/* define if the compiler implements namespaces */
+#define HAVE_NAMESPACES 1
+
+/* Define if you have POSIX threads libraries and header files. */
+#define HAVE_PTHREAD 1
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#define HAVE_STDINT_H 1
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#define HAVE_STDLIB_H 1
+
+/* Define to 1 if you have the <strings.h> header file. */
+#define HAVE_STRINGS_H 1
+
+/* Define to 1 if you have the <string.h> header file. */
+#define HAVE_STRING_H 1
+
+/* Define to 1 if you have the `strtoll' function. */
+#define HAVE_STRTOLL 1
+
+/* Define to 1 if you have the `strtoq' function. */
+#define HAVE_STRTOQ 1
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#define HAVE_SYS_STAT_H 1
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#define HAVE_SYS_TYPES_H 1
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#define HAVE_UNISTD_H 1
+
+/* define if your compiler has __attribute__ */
+#ifndef _WIN32
+#define HAVE___ATTRIBUTE__ 1
+#else
+#define HAVE___ATTRIBUTE__ 0
+#endif
+
+/* Define to the sub-directory in which libtool stores uninstalled libraries.
+ */
+#define LT_OBJDIR ".libs/"
+
+/* Name of package */
+#define PACKAGE "gflags"
+
+/* Define to the address where bug reports for this package should be sent. */
+#define PACKAGE_BUGREPORT "google-gflags@googlegroups.com"
+
+/* Define to the full name of this package. */
+#define PACKAGE_NAME "gflags"
+
+/* Define to the full name and version of this package. */
+#define PACKAGE_STRING "gflags 2.0"
+
+/* Define to the one symbol short name of this package. */
+#define PACKAGE_TARNAME "gflags"
+
+/* Define to the version of this package. */
+#define PACKAGE_VERSION "2.0"
+
+/* Define to necessary symbol if this constant uses a non-standard name on
+ your system. */
+/* #undef PTHREAD_CREATE_JOINABLE */
+
+/* Define to 1 if you have the ANSI C header files. */
+#define STDC_HEADERS 1
+
+/* the namespace where STL code like vector<> is defined */
+#define STL_NAMESPACE std
+
+/* Version number of package */
+#define VERSION "2.0"
+
+/* Stops putting the code inside the Google namespace */
+#define _END_GOOGLE_NAMESPACE_ }
+
+/* Puts following code inside the Google namespace */
+#define _START_GOOGLE_NAMESPACE_ namespace google {
+
+
+#if defined( __MINGW32__) || defined(__MINGW64__) || defined (_MSC_VER)
+#include "windows/port.h"
+#endif
+
diff --git a/src/third_party/gflags-2.0/src/config.h.in b/src/third_party/gflags-2.0/src/config.h.in
new file mode 100755
index 00000000000..5338b733986
--- /dev/null
+++ b/src/third_party/gflags-2.0/src/config.h.in
@@ -0,0 +1,106 @@
+/* src/config.h.in. Generated from configure.ac by autoheader. */
+
+/* Always the empty-string on non-windows systems. On windows, should be
+ "__declspec(dllexport)". This way, when we compile the dll, we export our
+ functions/classes. It's safe to define this here because config.h is only
+ used internally, to compile the DLL, and every DLL source file #includes
+ "config.h" before anything else. */
+#undef GFLAGS_DLL_DECL
+
+/* Namespace for Google classes */
+#undef GOOGLE_NAMESPACE
+
+/* Define to 1 if you have the <dlfcn.h> header file. */
+#undef HAVE_DLFCN_H
+
+/* Define to 1 if you have the <fnmatch.h> header file. */
+#undef HAVE_FNMATCH_H
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#undef HAVE_INTTYPES_H
+
+/* Define to 1 if you have the <memory.h> header file. */
+#undef HAVE_MEMORY_H
+
+/* define if the compiler implements namespaces */
+#undef HAVE_NAMESPACES
+
+/* Define if you have POSIX threads libraries and header files. */
+#undef HAVE_PTHREAD
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#undef HAVE_STDINT_H
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#undef HAVE_STDLIB_H
+
+/* Define to 1 if you have the <strings.h> header file. */
+#undef HAVE_STRINGS_H
+
+/* Define to 1 if you have the <string.h> header file. */
+#undef HAVE_STRING_H
+
+/* Define to 1 if you have the `strtoll' function. */
+#undef HAVE_STRTOLL
+
+/* Define to 1 if you have the `strtoq' function. */
+#undef HAVE_STRTOQ
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#undef HAVE_SYS_STAT_H
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#undef HAVE_SYS_TYPES_H
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#undef HAVE_UNISTD_H
+
+/* define if your compiler has __attribute__ */
+#undef HAVE___ATTRIBUTE__
+
+/* Define to the sub-directory in which libtool stores uninstalled libraries.
+ */
+#undef LT_OBJDIR
+
+/* Name of package */
+#undef PACKAGE
+
+/* Define to the address where bug reports for this package should be sent. */
+#undef PACKAGE_BUGREPORT
+
+/* Define to the full name of this package. */
+#undef PACKAGE_NAME
+
+/* Define to the full name and version of this package. */
+#undef PACKAGE_STRING
+
+/* Define to the one symbol short name of this package. */
+#undef PACKAGE_TARNAME
+
+/* Define to the version of this package. */
+#undef PACKAGE_VERSION
+
+/* Define to necessary symbol if this constant uses a non-standard name on
+ your system. */
+#undef PTHREAD_CREATE_JOINABLE
+
+/* Define to 1 if you have the ANSI C header files. */
+#undef STDC_HEADERS
+
+/* the namespace where STL code like vector<> is defined */
+#undef STL_NAMESPACE
+
+/* Version number of package */
+#undef VERSION
+
+/* Stops putting the code inside the Google namespace */
+#undef _END_GOOGLE_NAMESPACE_
+
+/* Puts following code inside the Google namespace */
+#undef _START_GOOGLE_NAMESPACE_
+
+
+#if defined( __MINGW32__) || defined(__MINGW64__)
+#include "windows/port.h"
+#endif
+
diff --git a/src/third_party/gflags-2.0/src/config_for_unittests.h b/src/third_party/gflags-2.0/src/config_for_unittests.h
new file mode 100755
index 00000000000..ac0df4cfdbf
--- /dev/null
+++ b/src/third_party/gflags-2.0/src/config_for_unittests.h
@@ -0,0 +1,63 @@
+// Copyright (c) 2007, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// ---
+// All Rights Reserved.
+//
+//
+// This file is needed for windows -- unittests are not part of the
+// gflags dll, but still want to include config.h just like the
+// dll does, so they can use internal tools and APIs for testing.
+//
+// The problem is that config.h declares GFLAGS_DLL_DECL to be
+// for exporting symbols, but the unittest needs to *import* symbols
+// (since it's not the dll).
+//
+// The solution is to have this file, which is just like config.h but
+// sets GFLAGS_DLL_DECL to do a dllimport instead of a dllexport.
+//
+// The reason we need this extra GFLAGS_DLL_DECL_FOR_UNITTESTS
+// variable is in case people want to set GFLAGS_DLL_DECL explicitly
+// to something other than __declspec(dllexport). In that case, they
+// may want to use something other than __declspec(dllimport) for the
+// unittest case. For that, we allow folks to define both
+// GFLAGS_DLL_DECL and GFLAGS_DLL_DECL_FOR_UNITTESTS explicitly.
+//
+// NOTE: This file is equivalent to config.h on non-windows systems,
+// which never defined GFLAGS_DLL_DECL_FOR_UNITTESTS and always
+// define GFLAGS_DLL_DECL to the empty string.
+
+#include "config.h"
+
+#undef GFLAGS_DLL_DECL
+#ifdef GFLAGS_DLL_DECL_FOR_UNITTESTS
+# define GFLAGS_DLL_DECL GFLAGS_DLL_DECL_FOR_UNITTESTS
+#else
+# define GFLAGS_DLL_DECL // if DLL_DECL_FOR_UNITTESTS isn't defined, use ""
+#endif
diff --git a/src/third_party/gflags-2.0/src/gflags.cc b/src/third_party/gflags-2.0/src/gflags.cc
new file mode 100755
index 00000000000..dec933b7f3e
--- /dev/null
+++ b/src/third_party/gflags-2.0/src/gflags.cc
@@ -0,0 +1,1971 @@
+// Copyright (c) 1999, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// ---
+// Revamped and reorganized by Craig Silverstein
+//
+// This file contains the implementation of all our command line flags
+// stuff. Here's how everything fits together
+//
+// * FlagRegistry owns CommandLineFlags owns FlagValue.
+// * FlagSaver holds a FlagRegistry (saves it at construct time,
+// restores it at destroy time).
+// * CommandLineFlagParser lives outside that hierarchy, but works on
+// CommandLineFlags (modifying the FlagValues).
+// * Free functions like SetCommandLineOption() work via one of the
+// above (such as CommandLineFlagParser).
+//
+// In more detail:
+//
+// -- The main classes that hold flag data:
+//
+// FlagValue holds the current value of a flag. It's
+// pseudo-templatized: every operation on a FlagValue is typed. It
+// also deals with storage-lifetime issues (so flag values don't go
+// away in a destructor), which is why we need a whole class to hold a
+// variable's value.
+//
+// CommandLineFlag is all the information about a single command-line
+// flag. It has a FlagValue for the flag's current value, but also
+// the flag's name, type, etc.
+//
+// FlagRegistry is a collection of CommandLineFlags. There's the
+// global registry, which is where flags defined via DEFINE_foo()
+// live. But it's possible to define your own flag, manually, in a
+// different registry you create. (In practice, multiple registries
+// are used only by FlagSaver).
+//
+// A given FlagValue is owned by exactly one CommandLineFlag. A given
+// CommandLineFlag is owned by exactly one FlagRegistry. FlagRegistry
+// has a lock; any operation that writes to a FlagValue or
+// CommandLineFlag owned by that registry must acquire the
+// FlagRegistry lock before doing so.
+//
+// --- Some other classes and free functions:
+//
+// CommandLineFlagInfo is a client-exposed version of CommandLineFlag.
+// Once it's instantiated, it has no dependencies or relationships
+// with any other part of this file.
+//
+// FlagRegisterer is the helper class used by the DEFINE_* macros to
+// allow work to be done at global initialization time.
+//
+// CommandLineFlagParser is the class that reads from the commandline
+// and instantiates flag values based on that. It needs to poke into
+// the innards of the FlagValue->CommandLineFlag->FlagRegistry class
+// hierarchy to do that. It's careful to acquire the FlagRegistry
+// lock before doing any writing or other non-const actions.
+//
+// GetCommandLineOption is just a hook into registry routines to
+// retrieve a flag based on its name. SetCommandLineOption, on the
+// other hand, hooks into CommandLineFlagParser. Other API functions
+// are, similarly, mostly hooks into the functionality described above.
+
+// This comes first to ensure we define __STDC_FORMAT_MACROS in time.
+#ifdef _WIN32
+#include "windows/config.h"
+#define safe_vsnprintf _vsnprintf
+#define snprintf _snprintf
+#else
+#include <config.h>
+#endif
+
+#if defined(HAVE_INTTYPES_H) && !defined(__STDC_FORMAT_MACROS)
+# define __STDC_FORMAT_MACROS 1 // gcc requires this to get PRId64, etc.
+#endif
+
+#ifdef _WIN32
+#include "windows/gflags/gflags.h"
+#else
+#include <gflags/gflags.h>
+#endif
+#include <assert.h>
+#include <ctype.h>
+#include <errno.h>
+#ifdef HAVE_FNMATCH_H
+# include <fnmatch.h>
+#endif
+#include <stdarg.h> // For va_list and related operations
+#include <stdio.h>
+#include <string.h>
+
+#include <algorithm>
+#include <map>
+#include <string>
+#include <utility> // for pair<>
+#include <vector>
+#include "mutex.h"
+#include "util.h"
+
+#ifndef PATH_SEPARATOR
+#define PATH_SEPARATOR '/'
+#endif
+
+
+// Special flags, type 1: the 'recursive' flags. They set another flag's val.
+DEFINE_string(flagfile, "",
+ "load flags from file");
+DEFINE_string(fromenv, "",
+ "set flags from the environment"
+ " [use 'export FLAGS_flag1=value']");
+DEFINE_string(tryfromenv, "",
+ "set flags from the environment if present");
+
+// Special flags, type 2: the 'parsing' flags. They modify how we parse.
+DEFINE_string(undefok, "",
+ "comma-separated list of flag names that it is okay to specify "
+ "on the command line even if the program does not define a flag "
+ "with that name. IMPORTANT: flags in this list that have "
+ "arguments MUST use the flag=value format");
+
+_START_GOOGLE_NAMESPACE_
+
+using std::map;
+using std::pair;
+using std::sort;
+using std::string;
+using std::vector;
+
+// This is used by the unittest to test error-exit code
+void GFLAGS_DLL_DECL (*gflags_exitfunc)(int) = &exit; // from stdlib.h
+
+
+// The help message indicating that the commandline flag has been
+// 'stripped'. It will not show up when doing "-help" and its
+// variants. The flag is stripped if STRIP_FLAG_HELP is set to 1
+// before including base/gflags.h
+
+// This is used by this file, and also in gflags_reporting.cc
+const char kStrippedFlagHelp[] = "\001\002\003\004 (unknown) \004\003\002\001";
+
+namespace {
+
+// There are also 'reporting' flags, in gflags_reporting.cc.
+
+static const char kError[] = "ERROR: ";
+
+// Indicates that undefined options are to be ignored.
+// Enables deferred processing of flags in dynamically loaded libraries.
+static bool allow_command_line_reparsing = false;
+
+static bool logging_is_probably_set_up = false;
+
+// This is a 'prototype' validate-function. 'Real' validate
+// functions, take a flag-value as an argument: ValidateFn(bool) or
+// ValidateFn(uint64). However, for easier storage, we strip off this
+// argument and then restore it when actually calling the function on
+// a flag value.
+typedef bool (*ValidateFnProto)();
+
+// Whether we should die when reporting an error.
+enum DieWhenReporting { DIE, DO_NOT_DIE };
+
+// Report Error and exit if requested.
+static void ReportError(DieWhenReporting should_die, const char* format, ...) {
+ char error_message[255];
+ va_list ap;
+ va_start(ap, format);
+ vsnprintf(error_message, sizeof(error_message), format, ap);
+ va_end(ap);
+ fprintf(stderr, "%s", error_message);
+ fflush(stderr); // should be unnecessary, but cygwin's rxvt buffers stderr
+ if (should_die == DIE) gflags_exitfunc(1);
+}
+
+
+// --------------------------------------------------------------------
+// FlagValue
+// This represent the value a single flag might have. The major
+// functionality is to convert from a string to an object of a
+// given type, and back. Thread-compatible.
+// --------------------------------------------------------------------
+
+class CommandLineFlag;
+class FlagValue {
+ public:
+ FlagValue(void* valbuf, const char* type, bool transfer_ownership_of_value);
+ ~FlagValue();
+
+ bool ParseFrom(const char* spec);
+ string ToString() const;
+
+ private:
+ friend class CommandLineFlag; // for many things, including Validate()
+ friend class GOOGLE_NAMESPACE::FlagSaverImpl; // calls New()
+ friend class FlagRegistry; // checks value_buffer_ for flags_by_ptr_ map
+ template <typename T> friend T GetFromEnv(const char*, const char*, T);
+ friend bool TryParseLocked(const CommandLineFlag*, FlagValue*,
+ const char*, string*); // for New(), CopyFrom()
+
+ enum ValueType {
+ FV_BOOL = 0,
+ FV_INT32 = 1,
+ FV_INT64 = 2,
+ FV_UINT64 = 3,
+ FV_DOUBLE = 4,
+ FV_STRING = 5,
+ FV_MAX_INDEX = 5,
+ };
+ const char* TypeName() const;
+ bool Equal(const FlagValue& x) const;
+ FlagValue* New() const; // creates a new one with default value
+ void CopyFrom(const FlagValue& x);
+ int ValueSize() const;
+
+ // Calls the given validate-fn on value_buffer_, and returns
+ // whatever it returns. But first casts validate_fn_proto to a
+ // function that takes our value as an argument (eg void
+ // (*validate_fn)(bool) for a bool flag).
+ bool Validate(const char* flagname, ValidateFnProto validate_fn_proto) const;
+
+ void* value_buffer_; // points to the buffer holding our data
+ int8 type_; // how to interpret value_
+ bool owns_value_; // whether to free value on destruct
+
+ FlagValue(const FlagValue&); // no copying!
+ void operator=(const FlagValue&);
+};
+
+
+// This could be a templated method of FlagValue, but doing so adds to the
+// size of the .o. Since there's no type-safety here anyway, macro is ok.
+#define VALUE_AS(type) *reinterpret_cast<type*>(value_buffer_)
+#define OTHER_VALUE_AS(fv, type) *reinterpret_cast<type*>(fv.value_buffer_)
+#define SET_VALUE_AS(type, value) VALUE_AS(type) = (value)
+
+FlagValue::FlagValue(void* valbuf, const char* type,
+ bool transfer_ownership_of_value)
+ : value_buffer_(valbuf),
+ owns_value_(transfer_ownership_of_value) {
+ for (type_ = 0; type_ <= FV_MAX_INDEX; ++type_) {
+ if (!strcmp(type, TypeName())) {
+ break;
+ }
+ }
+ assert(type_ <= FV_MAX_INDEX); // Unknown typename
+}
+
+FlagValue::~FlagValue() {
+ if (!owns_value_) {
+ return;
+ }
+ switch (type_) {
+ case FV_BOOL: delete reinterpret_cast<bool*>(value_buffer_); break;
+ case FV_INT32: delete reinterpret_cast<int32*>(value_buffer_); break;
+ case FV_INT64: delete reinterpret_cast<int64*>(value_buffer_); break;
+ case FV_UINT64: delete reinterpret_cast<uint64*>(value_buffer_); break;
+ case FV_DOUBLE: delete reinterpret_cast<double*>(value_buffer_); break;
+ case FV_STRING: delete reinterpret_cast<string*>(value_buffer_); break;
+ }
+}
+
+bool FlagValue::ParseFrom(const char* value) {
+ if (type_ == FV_BOOL) {
+ const char* kTrue[] = { "1", "t", "true", "y", "yes" };
+ const char* kFalse[] = { "0", "f", "false", "n", "no" };
+ COMPILE_ASSERT(sizeof(kTrue) == sizeof(kFalse), true_false_equal);
+ for (size_t i = 0; i < sizeof(kTrue)/sizeof(*kTrue); ++i) {
+ if (strcasecmp(value, kTrue[i]) == 0) {
+ SET_VALUE_AS(bool, true);
+ return true;
+ } else if (strcasecmp(value, kFalse[i]) == 0) {
+ SET_VALUE_AS(bool, false);
+ return true;
+ }
+ }
+ return false; // didn't match a legal input
+
+ } else if (type_ == FV_STRING) {
+ SET_VALUE_AS(string, value);
+ return true;
+ }
+
+ // OK, it's likely to be numeric, and we'll be using a strtoXXX method.
+ if (value[0] == '\0') // empty-string is only allowed for string type.
+ return false;
+ char* end;
+ // Leading 0x puts us in base 16. But leading 0 does not put us in base 8!
+ // It caused too many bugs when we had that behavior.
+ int base = 10; // by default
+ if (value[0] == '0' && (value[1] == 'x' || value[1] == 'X'))
+ base = 16;
+ errno = 0;
+
+ switch (type_) {
+ case FV_INT32: {
+ const int64 r = strto64(value, &end, base);
+ if (errno || end != value + strlen(value)) return false; // bad parse
+ if (static_cast<int32>(r) != r) // worked, but number out of range
+ return false;
+ SET_VALUE_AS(int32, static_cast<int32>(r));
+ return true;
+ }
+ case FV_INT64: {
+ const int64 r = strto64(value, &end, base);
+ if (errno || end != value + strlen(value)) return false; // bad parse
+ SET_VALUE_AS(int64, r);
+ return true;
+ }
+ case FV_UINT64: {
+ while (*value == ' ') value++;
+ if (*value == '-') return false; // negative number
+ const uint64 r = strtou64(value, &end, base);
+ if (errno || end != value + strlen(value)) return false; // bad parse
+ SET_VALUE_AS(uint64, r);
+ return true;
+ }
+ case FV_DOUBLE: {
+ const double r = strtod(value, &end);
+ if (errno || end != value + strlen(value)) return false; // bad parse
+ SET_VALUE_AS(double, r);
+ return true;
+ }
+ default: {
+ assert(false); // unknown type
+ return false;
+ }
+ }
+}
+
+string FlagValue::ToString() const {
+ char intbuf[64]; // enough to hold even the biggest number
+ switch (type_) {
+ case FV_BOOL:
+ return VALUE_AS(bool) ? "true" : "false";
+ case FV_INT32:
+ snprintf(intbuf, sizeof(intbuf), "%"PRId32, VALUE_AS(int32));
+ return intbuf;
+ case FV_INT64:
+ snprintf(intbuf, sizeof(intbuf), "%"PRId64, VALUE_AS(int64));
+ return intbuf;
+ case FV_UINT64:
+ snprintf(intbuf, sizeof(intbuf), "%"PRIu64, VALUE_AS(uint64));
+ return intbuf;
+ case FV_DOUBLE:
+ snprintf(intbuf, sizeof(intbuf), "%.17g", VALUE_AS(double));
+ return intbuf;
+ case FV_STRING:
+ return VALUE_AS(string);
+ default:
+ assert(false);
+ return ""; // unknown type
+ }
+}
+
+bool FlagValue::Validate(const char* flagname,
+ ValidateFnProto validate_fn_proto) const {
+ switch (type_) {
+ case FV_BOOL:
+ return reinterpret_cast<bool (*)(const char*, bool)>(
+ validate_fn_proto)(flagname, VALUE_AS(bool));
+ case FV_INT32:
+ return reinterpret_cast<bool (*)(const char*, int32)>(
+ validate_fn_proto)(flagname, VALUE_AS(int32));
+ case FV_INT64:
+ return reinterpret_cast<bool (*)(const char*, int64)>(
+ validate_fn_proto)(flagname, VALUE_AS(int64));
+ case FV_UINT64:
+ return reinterpret_cast<bool (*)(const char*, uint64)>(
+ validate_fn_proto)(flagname, VALUE_AS(uint64));
+ case FV_DOUBLE:
+ return reinterpret_cast<bool (*)(const char*, double)>(
+ validate_fn_proto)(flagname, VALUE_AS(double));
+ case FV_STRING:
+ return reinterpret_cast<bool (*)(const char*, const string&)>(
+ validate_fn_proto)(flagname, VALUE_AS(string));
+ default:
+ assert(false); // unknown type
+ return false;
+ }
+}
+
+const char* FlagValue::TypeName() const {
+ static const char types[] =
+ "bool\0xx"
+ "int32\0x"
+ "int64\0x"
+ "uint64\0"
+ "double\0"
+ "string";
+ if (type_ > FV_MAX_INDEX) {
+ assert(false);
+ return "";
+ }
+ // Directly indexing the strigns in the 'types' string, each of them
+ // is 7 bytes long.
+ return &types[type_ * 7];
+}
+
+bool FlagValue::Equal(const FlagValue& x) const {
+ if (type_ != x.type_)
+ return false;
+ switch (type_) {
+ case FV_BOOL: return VALUE_AS(bool) == OTHER_VALUE_AS(x, bool);
+ case FV_INT32: return VALUE_AS(int32) == OTHER_VALUE_AS(x, int32);
+ case FV_INT64: return VALUE_AS(int64) == OTHER_VALUE_AS(x, int64);
+ case FV_UINT64: return VALUE_AS(uint64) == OTHER_VALUE_AS(x, uint64);
+ case FV_DOUBLE: return VALUE_AS(double) == OTHER_VALUE_AS(x, double);
+ case FV_STRING: return VALUE_AS(string) == OTHER_VALUE_AS(x, string);
+ default: assert(false); return false; // unknown type
+ }
+}
+
+FlagValue* FlagValue::New() const {
+ const char *type = TypeName();
+ switch (type_) {
+ case FV_BOOL: return new FlagValue(new bool(false), type, true);
+ case FV_INT32: return new FlagValue(new int32(0), type, true);
+ case FV_INT64: return new FlagValue(new int64(0), type, true);
+ case FV_UINT64: return new FlagValue(new uint64(0), type, true);
+ case FV_DOUBLE: return new FlagValue(new double(0.0), type, true);
+ case FV_STRING: return new FlagValue(new string, type, true);
+ default: assert(false); return NULL; // unknown type
+ }
+}
+
+void FlagValue::CopyFrom(const FlagValue& x) {
+ assert(type_ == x.type_);
+ switch (type_) {
+ case FV_BOOL: SET_VALUE_AS(bool, OTHER_VALUE_AS(x, bool)); break;
+ case FV_INT32: SET_VALUE_AS(int32, OTHER_VALUE_AS(x, int32)); break;
+ case FV_INT64: SET_VALUE_AS(int64, OTHER_VALUE_AS(x, int64)); break;
+ case FV_UINT64: SET_VALUE_AS(uint64, OTHER_VALUE_AS(x, uint64)); break;
+ case FV_DOUBLE: SET_VALUE_AS(double, OTHER_VALUE_AS(x, double)); break;
+ case FV_STRING: SET_VALUE_AS(string, OTHER_VALUE_AS(x, string)); break;
+ default: assert(false); // unknown type
+ }
+}
+
+int FlagValue::ValueSize() const {
+ if (type_ > FV_MAX_INDEX) {
+ assert(false); // unknown type
+ return 0;
+ }
+ static const uint8 valuesize[] = {
+ sizeof(bool),
+ sizeof(int32),
+ sizeof(int64),
+ sizeof(uint64),
+ sizeof(double),
+ sizeof(string),
+ };
+ return valuesize[type_];
+}
+
+// --------------------------------------------------------------------
+// CommandLineFlag
+// This represents a single flag, including its name, description,
+// default value, and current value. Mostly this serves as a
+// struct, though it also knows how to register itself.
+// All CommandLineFlags are owned by a (exactly one)
+// FlagRegistry. If you wish to modify fields in this class, you
+// should acquire the FlagRegistry lock for the registry that owns
+// this flag.
+// --------------------------------------------------------------------
+
+class CommandLineFlag {
+ public:
+ // Note: we take over memory-ownership of current_val and default_val.
+ CommandLineFlag(const char* name, const char* help, const char* filename,
+ FlagValue* current_val, FlagValue* default_val);
+ ~CommandLineFlag();
+
+ const char* name() const { return name_; }
+ const char* help() const { return help_; }
+ const char* filename() const { return file_; }
+ const char* CleanFileName() const; // nixes irrelevant prefix such as homedir
+ string current_value() const { return current_->ToString(); }
+ string default_value() const { return defvalue_->ToString(); }
+ const char* type_name() const { return defvalue_->TypeName(); }
+ ValidateFnProto validate_function() const { return validate_fn_proto_; }
+ const void* flag_ptr() const { return current_->value_buffer_; }
+
+ void FillCommandLineFlagInfo(struct CommandLineFlagInfo* result);
+
+ // If validate_fn_proto_ is non-NULL, calls it on value, returns result.
+ bool Validate(const FlagValue& value) const;
+ bool ValidateCurrent() const { return Validate(*current_); }
+
+ private:
+ // for SetFlagLocked() and setting flags_by_ptr_
+ friend class FlagRegistry;
+ friend class GOOGLE_NAMESPACE::FlagSaverImpl; // for cloning the values
+ // set validate_fn
+ friend bool AddFlagValidator(const void*, ValidateFnProto);
+
+ // This copies all the non-const members: modified, processed, defvalue, etc.
+ void CopyFrom(const CommandLineFlag& src);
+
+ void UpdateModifiedBit();
+
+ const char* const name_; // Flag name
+ const char* const help_; // Help message
+ const char* const file_; // Which file did this come from?
+ bool modified_; // Set after default assignment?
+ FlagValue* defvalue_; // Default value for flag
+ FlagValue* current_; // Current value for flag
+ // This is a casted, 'generic' version of validate_fn, which actually
+ // takes a flag-value as an arg (void (*validate_fn)(bool), say).
+ // When we pass this to current_->Validate(), it will cast it back to
+ // the proper type. This may be NULL to mean we have no validate_fn.
+ ValidateFnProto validate_fn_proto_;
+
+ CommandLineFlag(const CommandLineFlag&); // no copying!
+ void operator=(const CommandLineFlag&);
+};
+
+CommandLineFlag::CommandLineFlag(const char* name, const char* help,
+ const char* filename,
+ FlagValue* current_val, FlagValue* default_val)
+ : name_(name), help_(help), file_(filename), modified_(false),
+ defvalue_(default_val), current_(current_val), validate_fn_proto_(NULL) {
+}
+
+CommandLineFlag::~CommandLineFlag() {
+ delete current_;
+ delete defvalue_;
+}
+
+const char* CommandLineFlag::CleanFileName() const {
+ // Compute top-level directory & file that this appears in
+ // search full path backwards.
+ // Stop going backwards at kRootDir; and skip by the first slash.
+ static const char kRootDir[] = ""; // can set this to root directory,
+
+ if (sizeof(kRootDir)-1 == 0) // no prefix to strip
+ return filename();
+
+ const char* clean_name = filename() + strlen(filename()) - 1;
+ while ( clean_name > filename() ) {
+ if (*clean_name == PATH_SEPARATOR) {
+ if (strncmp(clean_name, kRootDir, sizeof(kRootDir)-1) == 0) {
+ clean_name += sizeof(kRootDir)-1; // past root-dir
+ break;
+ }
+ }
+ --clean_name;
+ }
+ while ( *clean_name == PATH_SEPARATOR ) ++clean_name; // Skip any slashes
+ return clean_name;
+}
+
+void CommandLineFlag::FillCommandLineFlagInfo(
+ CommandLineFlagInfo* result) {
+ result->name = name();
+ result->type = type_name();
+ result->description = help();
+ result->current_value = current_value();
+ result->default_value = default_value();
+ result->filename = CleanFileName();
+ UpdateModifiedBit();
+ result->is_default = !modified_;
+ result->has_validator_fn = validate_function() != NULL;
+ result->flag_ptr = flag_ptr();
+}
+
+void CommandLineFlag::UpdateModifiedBit() {
+ // Update the "modified" bit in case somebody bypassed the
+ // Flags API and wrote directly through the FLAGS_name variable.
+ if (!modified_ && !current_->Equal(*defvalue_)) {
+ modified_ = true;
+ }
+}
+
+void CommandLineFlag::CopyFrom(const CommandLineFlag& src) {
+ // Note we only copy the non-const members; others are fixed at construct time
+ if (modified_ != src.modified_) modified_ = src.modified_;
+ if (!current_->Equal(*src.current_)) current_->CopyFrom(*src.current_);
+ if (!defvalue_->Equal(*src.defvalue_)) defvalue_->CopyFrom(*src.defvalue_);
+ if (validate_fn_proto_ != src.validate_fn_proto_)
+ validate_fn_proto_ = src.validate_fn_proto_;
+}
+
+bool CommandLineFlag::Validate(const FlagValue& value) const {
+
+ if (validate_function() == NULL)
+ return true;
+ else
+ return value.Validate(name(), validate_function());
+}
+
+
+// --------------------------------------------------------------------
+// FlagRegistry
+// A FlagRegistry singleton object holds all flag objects indexed
+// by their names so that if you know a flag's name (as a C
+// string), you can access or set it. If the function is named
+// FooLocked(), you must own the registry lock before calling
+// the function; otherwise, you should *not* hold the lock, and
+// the function will acquire it itself if needed.
+// --------------------------------------------------------------------
+
+struct StringCmp { // Used by the FlagRegistry map class to compare char*'s
+ bool operator() (const char* s1, const char* s2) const {
+ return (strcmp(s1, s2) < 0);
+ }
+};
+
+
+class FlagRegistry {
+ public:
+ FlagRegistry() {
+ }
+ ~FlagRegistry() {
+ // Not using STLDeleteElements as that resides in util and this
+ // class is base.
+ for (FlagMap::iterator p = flags_.begin(), e = flags_.end(); p != e; ++p) {
+ CommandLineFlag* flag = p->second;
+ delete flag;
+ }
+ }
+
+ static void DeleteGlobalRegistry() {
+ delete global_registry_;
+ global_registry_ = NULL;
+ }
+
+ // Store a flag in this registry. Takes ownership of the given pointer.
+ void RegisterFlag(CommandLineFlag* flag);
+
+ void Lock() { lock_.Lock(); }
+ void Unlock() { lock_.Unlock(); }
+
+ // Returns the flag object for the specified name, or NULL if not found.
+ CommandLineFlag* FindFlagLocked(const char* name);
+
+ // Returns the flag object whose current-value is stored at flag_ptr.
+ // That is, for whom current_->value_buffer_ == flag_ptr
+ CommandLineFlag* FindFlagViaPtrLocked(const void* flag_ptr);
+
+ // A fancier form of FindFlag that works correctly if name is of the
+ // form flag=value. In that case, we set key to point to flag, and
+ // modify v to point to the value (if present), and return the flag
+ // with the given name. If the flag does not exist, returns NULL
+ // and sets error_message.
+ CommandLineFlag* SplitArgumentLocked(const char* argument,
+ string* key, const char** v,
+ string* error_message);
+
+ // Set the value of a flag. If the flag was successfully set to
+ // value, set msg to indicate the new flag-value, and return true.
+ // Otherwise, set msg to indicate the error, leave flag unchanged,
+ // and return false. msg can be NULL.
+ bool SetFlagLocked(CommandLineFlag* flag, const char* value,
+ FlagSettingMode set_mode, string* msg);
+
+ static FlagRegistry* GlobalRegistry(); // returns a singleton registry
+
+ private:
+ friend class GOOGLE_NAMESPACE::FlagSaverImpl; // reads all the flags in order to copy them
+ friend class CommandLineFlagParser; // for ValidateAllFlags
+ friend void GOOGLE_NAMESPACE::GetAllFlags(vector<CommandLineFlagInfo>*);
+
+ // The map from name to flag, for FindFlagLocked().
+ typedef map<const char*, CommandLineFlag*, StringCmp> FlagMap;
+ typedef FlagMap::iterator FlagIterator;
+ typedef FlagMap::const_iterator FlagConstIterator;
+ FlagMap flags_;
+
+ // The map from current-value pointer to flag, fo FindFlagViaPtrLocked().
+ typedef map<const void*, CommandLineFlag*> FlagPtrMap;
+ FlagPtrMap flags_by_ptr_;
+
+ static FlagRegistry* global_registry_; // a singleton registry
+
+ Mutex lock_;
+ static Mutex global_registry_lock_;
+
+ static void InitGlobalRegistry();
+
+ // Disallow
+ FlagRegistry(const FlagRegistry&);
+ FlagRegistry& operator=(const FlagRegistry&);
+};
+
+class FlagRegistryLock {
+ public:
+ explicit FlagRegistryLock(FlagRegistry* fr) : fr_(fr) { fr_->Lock(); }
+ ~FlagRegistryLock() { fr_->Unlock(); }
+ private:
+ FlagRegistry *const fr_;
+};
+
+
+void FlagRegistry::RegisterFlag(CommandLineFlag* flag) {
+ Lock();
+ pair<FlagIterator, bool> ins =
+ flags_.insert(pair<const char*, CommandLineFlag*>(flag->name(), flag));
+ if (ins.second == false) { // means the name was already in the map
+ if (strcmp(ins.first->second->filename(), flag->filename()) != 0) {
+ ReportError(DIE, "ERROR: flag '%s' was defined more than once "
+ "(in files '%s' and '%s').\n",
+ flag->name(),
+ ins.first->second->filename(),
+ flag->filename());
+ } else {
+ ReportError(DIE, "ERROR: something wrong with flag '%s' in file '%s'. "
+ "One possibility: file '%s' is being linked both statically "
+ "and dynamically into this executable.\n",
+ flag->name(),
+ flag->filename(), flag->filename());
+ }
+ }
+ // Also add to the flags_by_ptr_ map.
+ flags_by_ptr_[flag->current_->value_buffer_] = flag;
+ Unlock();
+}
+
+CommandLineFlag* FlagRegistry::FindFlagLocked(const char* name) {
+ FlagConstIterator i = flags_.find(name);
+ if (i == flags_.end()) {
+ return NULL;
+ } else {
+ return i->second;
+ }
+}
+
+CommandLineFlag* FlagRegistry::FindFlagViaPtrLocked(const void* flag_ptr) {
+ FlagPtrMap::const_iterator i = flags_by_ptr_.find(flag_ptr);
+ if (i == flags_by_ptr_.end()) {
+ return NULL;
+ } else {
+ return i->second;
+ }
+}
+
+CommandLineFlag* FlagRegistry::SplitArgumentLocked(const char* arg,
+ string* key,
+ const char** v,
+ string* error_message) {
+ // Find the flag object for this option
+ const char* flag_name;
+ const char* value = strchr(arg, '=');
+ if (value == NULL) {
+ key->assign(arg);
+ *v = NULL;
+ } else {
+ // Strip out the "=value" portion from arg
+ key->assign(arg, value-arg);
+ *v = ++value; // advance past the '='
+ }
+ flag_name = key->c_str();
+
+ CommandLineFlag* flag = FindFlagLocked(flag_name);
+
+ if (flag == NULL) {
+ // If we can't find the flag-name, then we should return an error.
+ // The one exception is if 1) the flag-name is 'nox', 2) there
+ // exists a flag named 'x', and 3) 'x' is a boolean flag.
+ // In that case, we want to return flag 'x'.
+ if (!(flag_name[0] == 'n' && flag_name[1] == 'o')) {
+ // flag-name is not 'nox', so we're not in the exception case.
+ *error_message = StringPrintf("%sunknown command line flag '%s'\n",
+ kError, key->c_str());
+ return NULL;
+ }
+ flag = FindFlagLocked(flag_name+2);
+ if (flag == NULL) {
+ // No flag named 'x' exists, so we're not in the exception case.
+ *error_message = StringPrintf("%sunknown command line flag '%s'\n",
+ kError, key->c_str());
+ return NULL;
+ }
+ if (strcmp(flag->type_name(), "bool") != 0) {
+ // 'x' exists but is not boolean, so we're not in the exception case.
+ *error_message = StringPrintf(
+ "%sboolean value (%s) specified for %s command line flag\n",
+ kError, key->c_str(), flag->type_name());
+ return NULL;
+ }
+ // We're in the exception case!
+ // Make up a fake value to replace the "no" we stripped out
+ key->assign(flag_name+2); // the name without the "no"
+ *v = "0";
+ }
+
+ // Assign a value if this is a boolean flag
+ if (*v == NULL && strcmp(flag->type_name(), "bool") == 0) {
+ *v = "1"; // the --nox case was already handled, so this is the --x case
+ }
+
+ return flag;
+}
+
+bool TryParseLocked(const CommandLineFlag* flag, FlagValue* flag_value,
+ const char* value, string* msg) {
+ // Use tenative_value, not flag_value, until we know value is valid.
+ FlagValue* tentative_value = flag_value->New();
+ if (!tentative_value->ParseFrom(value)) {
+ if (msg) {
+ StringAppendF(msg,
+ "%sillegal value '%s' specified for %s flag '%s'\n",
+ kError, value,
+ flag->type_name(), flag->name());
+ }
+ delete tentative_value;
+ return false;
+ } else if (!flag->Validate(*tentative_value)) {
+ if (msg) {
+ StringAppendF(msg,
+ "%sfailed validation of new value '%s' for flag '%s'\n",
+ kError, tentative_value->ToString().c_str(),
+ flag->name());
+ }
+ delete tentative_value;
+ return false;
+ } else {
+ flag_value->CopyFrom(*tentative_value);
+ if (msg) {
+ StringAppendF(msg, "%s set to %s\n",
+ flag->name(), flag_value->ToString().c_str());
+ }
+ delete tentative_value;
+ return true;
+ }
+}
+
+bool FlagRegistry::SetFlagLocked(CommandLineFlag* flag,
+ const char* value,
+ FlagSettingMode set_mode,
+ string* msg) {
+ flag->UpdateModifiedBit();
+ switch (set_mode) {
+ case SET_FLAGS_VALUE: {
+ // set or modify the flag's value
+ if (!TryParseLocked(flag, flag->current_, value, msg))
+ return false;
+ flag->modified_ = true;
+ break;
+ }
+ case SET_FLAG_IF_DEFAULT: {
+ // set the flag's value, but only if it hasn't been set by someone else
+ if (!flag->modified_) {
+ if (!TryParseLocked(flag, flag->current_, value, msg))
+ return false;
+ flag->modified_ = true;
+ } else {
+ *msg = StringPrintf("%s set to %s",
+ flag->name(), flag->current_value().c_str());
+ }
+ break;
+ }
+ case SET_FLAGS_DEFAULT: {
+ // modify the flag's default-value
+ if (!TryParseLocked(flag, flag->defvalue_, value, msg))
+ return false;
+ if (!flag->modified_) {
+ // Need to set both defvalue *and* current, in this case
+ TryParseLocked(flag, flag->current_, value, NULL);
+ }
+ break;
+ }
+ default: {
+ // unknown set_mode
+ assert(false);
+ return false;
+ }
+ }
+
+ return true;
+}
+
+// Get the singleton FlagRegistry object
+FlagRegistry* FlagRegistry::global_registry_ = NULL;
+Mutex FlagRegistry::global_registry_lock_(Mutex::LINKER_INITIALIZED);
+
+FlagRegistry* FlagRegistry::GlobalRegistry() {
+ MutexLock acquire_lock(&global_registry_lock_);
+ if (!global_registry_) {
+ global_registry_ = new FlagRegistry;
+ }
+ return global_registry_;
+}
+
+// --------------------------------------------------------------------
+// CommandLineFlagParser
+// Parsing is done in two stages. In the first, we go through
+// argv. For every flag-like arg we can make sense of, we parse
+// it and set the appropriate FLAGS_* variable. For every flag-
+// like arg we can't make sense of, we store it in a vector,
+// along with an explanation of the trouble. In stage 2, we
+// handle the 'reporting' flags like --help and --mpm_version.
+// (This is via a call to HandleCommandLineHelpFlags(), in
+// gflags_reporting.cc.)
+// An optional stage 3 prints out the error messages.
+// This is a bit of a simplification. For instance, --flagfile
+// is handled as soon as it's seen in stage 1, not in stage 2.
+// --------------------------------------------------------------------
+
+class CommandLineFlagParser {
+ public:
+ // The argument is the flag-registry to register the parsed flags in
+ explicit CommandLineFlagParser(FlagRegistry* reg) : registry_(reg) {}
+ ~CommandLineFlagParser() {}
+
+ // Stage 1: Every time this is called, it reads all flags in argv.
+ // However, it ignores all flags that have been successfully set
+ // before. Typically this is only called once, so this 'reparsing'
+ // behavior isn't important. It can be useful when trying to
+ // reparse after loading a dll, though.
+ uint32 ParseNewCommandLineFlags(int* argc, char*** argv, bool remove_flags);
+
+ // Stage 2: print reporting info and exit, if requested.
+ // In gflags_reporting.cc:HandleCommandLineHelpFlags().
+
+ // Stage 3: validate all the commandline flags that have validators
+ // registered.
+ void ValidateAllFlags();
+
+ // Stage 4: report any errors and return true if any were found.
+ bool ReportErrors();
+
+ // Set a particular command line option. "newval" is a string
+ // describing the new value that the option has been set to. If
+ // option_name does not specify a valid option name, or value is not
+ // a valid value for option_name, newval is empty. Does recursive
+ // processing for --flagfile and --fromenv. Returns the new value
+ // if everything went ok, or empty-string if not. (Actually, the
+ // return-string could hold many flag/value pairs due to --flagfile.)
+ // NB: Must have called registry_->Lock() before calling this function.
+ string ProcessSingleOptionLocked(CommandLineFlag* flag,
+ const char* value,
+ FlagSettingMode set_mode);
+
+ // Set a whole batch of command line options as specified by contentdata,
+ // which is in flagfile format (and probably has been read from a flagfile).
+ // Returns the new value if everything went ok, or empty-string if
+ // not. (Actually, the return-string could hold many flag/value
+ // pairs due to --flagfile.)
+ // NB: Must have called registry_->Lock() before calling this function.
+ string ProcessOptionsFromStringLocked(const string& contentdata,
+ FlagSettingMode set_mode);
+
+ // These are the 'recursive' flags, defined at the top of this file.
+ // Whenever we see these flags on the commandline, we must take action.
+ // These are called by ProcessSingleOptionLocked and, similarly, return
+ // new values if everything went ok, or the empty-string if not.
+ string ProcessFlagfileLocked(const string& flagval, FlagSettingMode set_mode);
+ // diff fromenv/tryfromenv
+ string ProcessFromenvLocked(const string& flagval, FlagSettingMode set_mode,
+ bool errors_are_fatal);
+
+ private:
+ FlagRegistry* const registry_;
+ map<string, string> error_flags_; // map from name to error message
+ // This could be a set<string>, but we reuse the map to minimize the .o size
+ map<string, string> undefined_names_; // --[flag] name was not registered
+};
+
+
+// Parse a list of (comma-separated) flags.
+static void ParseFlagList(const char* value, vector<string>* flags) {
+ for (const char *p = value; p && *p; value = p) {
+ p = strchr(value, ',');
+ size_t len;
+ if (p) {
+ len = p - value;
+ p++;
+ } else {
+ len = strlen(value);
+ }
+
+ if (len == 0)
+ ReportError(DIE, "ERROR: empty flaglist entry\n");
+ if (value[0] == '-')
+ ReportError(DIE, "ERROR: flag \"%*s\" begins with '-'\n", len, value);
+
+ flags->push_back(string(value, len));
+ }
+}
+
+// Snarf an entire file into a C++ string. This is just so that we
+// can do all the I/O in one place and not worry about it everywhere.
+// Plus, it's convenient to have the whole file contents at hand.
+// Adds a newline at the end of the file.
+#define PFATAL(s) do { perror(s); gflags_exitfunc(1); } while (0)
+
+static string ReadFileIntoString(const char* filename) {
+ const int kBufSize = 8092;
+ char buffer[kBufSize];
+ string s;
+ FILE* fp = fopen(filename, "r");
+ if (!fp) PFATAL(filename);
+ size_t n;
+ while ( (n=fread(buffer, 1, kBufSize, fp)) > 0 ) {
+ if (ferror(fp)) PFATAL(filename);
+ s.append(buffer, n);
+ }
+ fclose(fp);
+ return s;
+}
+
+uint32 CommandLineFlagParser::ParseNewCommandLineFlags(int* argc, char*** argv,
+ bool remove_flags) {
+ const char *program_name = strrchr((*argv)[0], PATH_SEPARATOR); // nix path
+ program_name = (program_name == NULL ? (*argv)[0] : program_name+1);
+
+ int first_nonopt = *argc; // for non-options moved to the end
+
+ registry_->Lock();
+ for (int i = 1; i < first_nonopt; i++) {
+ char* arg = (*argv)[i];
+
+ // Like getopt(), we permute non-option flags to be at the end.
+ if (arg[0] != '-' || // must be a program argument
+ (arg[0] == '-' && arg[1] == '\0')) { // "-" is an argument, not a flag
+ memmove((*argv) + i, (*argv) + i+1, (*argc - (i+1)) * sizeof((*argv)[i]));
+ (*argv)[*argc-1] = arg; // we go last
+ first_nonopt--; // we've been pushed onto the stack
+ i--; // to undo the i++ in the loop
+ continue;
+ }
+
+ if (arg[0] == '-') arg++; // allow leading '-'
+ if (arg[0] == '-') arg++; // or leading '--'
+
+ // -- alone means what it does for GNU: stop options parsing
+ if (*arg == '\0') {
+ first_nonopt = i+1;
+ break;
+ }
+
+ // Find the flag object for this option
+ string key;
+ const char* value;
+ string error_message;
+ CommandLineFlag* flag = registry_->SplitArgumentLocked(arg, &key, &value,
+ &error_message);
+ if (flag == NULL) {
+ undefined_names_[key] = ""; // value isn't actually used
+ error_flags_[key] = error_message;
+ continue;
+ }
+
+ if (value == NULL) {
+ // Boolean options are always assigned a value by SplitArgumentLocked()
+ assert(strcmp(flag->type_name(), "bool") != 0);
+ if (i+1 >= first_nonopt) {
+ // This flag needs a value, but there is nothing available
+ error_flags_[key] = (string(kError) + "flag '" + (*argv)[i] + "'"
+ + " is missing its argument");
+ if (flag->help() && flag->help()[0] > '\001') {
+ // Be useful in case we have a non-stripped description.
+ error_flags_[key] += string("; flag description: ") + flag->help();
+ }
+ error_flags_[key] += "\n";
+ break; // we treat this as an unrecoverable error
+ } else {
+ value = (*argv)[++i]; // read next arg for value
+
+ // Heuristic to detect the case where someone treats a string arg
+ // like a bool:
+ // --my_string_var --foo=bar
+ // We look for a flag of string type, whose value begins with a
+ // dash, and where the flag-name and value are separated by a
+ // space rather than an '='.
+ // To avoid false positives, we also require the word "true"
+ // or "false" in the help string. Without this, a valid usage
+ // "-lat -30.5" would trigger the warning. The common cases we
+ // want to solve talk about true and false as values.
+ if (value[0] == '-'
+ && strcmp(flag->type_name(), "string") == 0
+ && (strstr(flag->help(), "true")
+ || strstr(flag->help(), "false"))) {
+ LOG(WARNING) << "Did you really mean to set flag '"
+ << flag->name() << "' to the value '"
+ << value << "'?";
+ }
+ }
+ }
+
+ // TODO(csilvers): only set a flag if we hadn't set it before here
+ ProcessSingleOptionLocked(flag, value, SET_FLAGS_VALUE);
+ }
+ registry_->Unlock();
+
+ if (remove_flags) { // Fix up argc and argv by removing command line flags
+ (*argv)[first_nonopt-1] = (*argv)[0];
+ (*argv) += (first_nonopt-1);
+ (*argc) -= (first_nonopt-1);
+ first_nonopt = 1; // because we still don't count argv[0]
+ }
+
+ logging_is_probably_set_up = true; // because we've parsed --logdir, etc.
+
+ return first_nonopt;
+}
+
+string CommandLineFlagParser::ProcessFlagfileLocked(const string& flagval,
+ FlagSettingMode set_mode) {
+ if (flagval.empty())
+ return "";
+
+ string msg;
+ vector<string> filename_list;
+ ParseFlagList(flagval.c_str(), &filename_list); // take a list of filenames
+ for (size_t i = 0; i < filename_list.size(); ++i) {
+ const char* file = filename_list[i].c_str();
+ msg += ProcessOptionsFromStringLocked(ReadFileIntoString(file), set_mode);
+ }
+ return msg;
+}
+
+string CommandLineFlagParser::ProcessFromenvLocked(const string& flagval,
+ FlagSettingMode set_mode,
+ bool errors_are_fatal) {
+ if (flagval.empty())
+ return "";
+
+ string msg;
+ vector<string> flaglist;
+ ParseFlagList(flagval.c_str(), &flaglist);
+
+ for (size_t i = 0; i < flaglist.size(); ++i) {
+ const char* flagname = flaglist[i].c_str();
+ CommandLineFlag* flag = registry_->FindFlagLocked(flagname);
+ if (flag == NULL) {
+ error_flags_[flagname] =
+ StringPrintf("%sunknown command line flag '%s' "
+ "(via --fromenv or --tryfromenv)\n",
+ kError, flagname);
+ undefined_names_[flagname] = "";
+ continue;
+ }
+
+ const string envname = string("FLAGS_") + string(flagname);
+ const char* envval = getenv(envname.c_str());
+ if (!envval) {
+ if (errors_are_fatal) {
+ error_flags_[flagname] = (string(kError) + envname +
+ " not found in environment\n");
+ }
+ continue;
+ }
+
+ // Avoid infinite recursion.
+ if ((strcmp(envval, "fromenv") == 0) ||
+ (strcmp(envval, "tryfromenv") == 0)) {
+ error_flags_[flagname] =
+ StringPrintf("%sinfinite recursion on environment flag '%s'\n",
+ kError, envval);
+ continue;
+ }
+
+ msg += ProcessSingleOptionLocked(flag, envval, set_mode);
+ }
+ return msg;
+}
+
+string CommandLineFlagParser::ProcessSingleOptionLocked(
+ CommandLineFlag* flag, const char* value, FlagSettingMode set_mode) {
+ string msg;
+ if (value && !registry_->SetFlagLocked(flag, value, set_mode, &msg)) {
+ error_flags_[flag->name()] = msg;
+ return "";
+ }
+
+ // The recursive flags, --flagfile and --fromenv and --tryfromenv,
+ // must be dealt with as soon as they're seen. They will emit
+ // messages of their own.
+ if (strcmp(flag->name(), "flagfile") == 0) {
+ msg += ProcessFlagfileLocked(FLAGS_flagfile, set_mode);
+
+ } else if (strcmp(flag->name(), "fromenv") == 0) {
+ // last arg indicates envval-not-found is fatal (unlike in --tryfromenv)
+ msg += ProcessFromenvLocked(FLAGS_fromenv, set_mode, true);
+
+ } else if (strcmp(flag->name(), "tryfromenv") == 0) {
+ msg += ProcessFromenvLocked(FLAGS_tryfromenv, set_mode, false);
+ }
+
+ return msg;
+}
+
+void CommandLineFlagParser::ValidateAllFlags() {
+ FlagRegistryLock frl(registry_);
+ for (FlagRegistry::FlagConstIterator i = registry_->flags_.begin();
+ i != registry_->flags_.end(); ++i) {
+ if (!i->second->ValidateCurrent()) {
+ // only set a message if one isn't already there. (If there's
+ // an error message, our job is done, even if it's not exactly
+ // the same error.)
+ if (error_flags_[i->second->name()].empty())
+ error_flags_[i->second->name()] =
+ string(kError) + "--" + i->second->name() +
+ " must be set on the commandline"
+ " (default value fails validation)\n";
+ }
+ }
+}
+
+bool CommandLineFlagParser::ReportErrors() {
+ // error_flags_ indicates errors we saw while parsing.
+ // But we ignore undefined-names if ok'ed by --undef_ok
+ if (!FLAGS_undefok.empty()) {
+ vector<string> flaglist;
+ ParseFlagList(FLAGS_undefok.c_str(), &flaglist);
+ for (size_t i = 0; i < flaglist.size(); ++i) {
+ // We also deal with --no<flag>, in case the flagname was boolean
+ const string no_version = string("no") + flaglist[i];
+ if (undefined_names_.find(flaglist[i]) != undefined_names_.end()) {
+ error_flags_[flaglist[i]] = ""; // clear the error message
+ } else if (undefined_names_.find(no_version) != undefined_names_.end()) {
+ error_flags_[no_version] = "";
+ }
+ }
+ }
+ // Likewise, if they decided to allow reparsing, all undefined-names
+ // are ok; we just silently ignore them now, and hope that a future
+ // parse will pick them up somehow.
+ if (allow_command_line_reparsing) {
+ for (map<string, string>::const_iterator it = undefined_names_.begin();
+ it != undefined_names_.end(); ++it)
+ error_flags_[it->first] = ""; // clear the error message
+ }
+
+ bool found_error = false;
+ string error_message;
+ for (map<string, string>::const_iterator it = error_flags_.begin();
+ it != error_flags_.end(); ++it) {
+ if (!it->second.empty()) {
+ error_message.append(it->second.data(), it->second.size());
+ found_error = true;
+ }
+ }
+ if (found_error)
+ ReportError(DO_NOT_DIE, "%s", error_message.c_str());
+ return found_error;
+}
+
+string CommandLineFlagParser::ProcessOptionsFromStringLocked(
+ const string& contentdata, FlagSettingMode set_mode) {
+ string retval;
+ const char* flagfile_contents = contentdata.c_str();
+ bool flags_are_relevant = true; // set to false when filenames don't match
+ bool in_filename_section = false;
+
+ const char* line_end = flagfile_contents;
+ // We read this file a line at a time.
+ for (; line_end; flagfile_contents = line_end + 1) {
+ while (*flagfile_contents && isspace(*flagfile_contents))
+ ++flagfile_contents;
+ line_end = strchr(flagfile_contents, '\n');
+ size_t len = line_end ? line_end - flagfile_contents
+ : strlen(flagfile_contents);
+ string line(flagfile_contents, len);
+
+ // Each line can be one of four things:
+ // 1) A comment line -- we skip it
+ // 2) An empty line -- we skip it
+ // 3) A list of filenames -- starts a new filenames+flags section
+ // 4) A --flag=value line -- apply if previous filenames match
+ if (line.empty() || line[0] == '#') {
+ // comment or empty line; just ignore
+
+ } else if (line[0] == '-') { // flag
+ in_filename_section = false; // instead, it was a flag-line
+ if (!flags_are_relevant) // skip this flag; applies to someone else
+ continue;
+
+ const char* name_and_val = line.c_str() + 1; // skip the leading -
+ if (*name_and_val == '-')
+ name_and_val++; // skip second - too
+ string key;
+ const char* value;
+ string error_message;
+ CommandLineFlag* flag = registry_->SplitArgumentLocked(name_and_val,
+ &key, &value,
+ &error_message);
+ // By API, errors parsing flagfile lines are silently ignored.
+ if (flag == NULL) {
+ // "WARNING: flagname '" + key + "' not found\n"
+ } else if (value == NULL) {
+ // "WARNING: flagname '" + key + "' missing a value\n"
+ } else {
+ retval += ProcessSingleOptionLocked(flag, value, set_mode);
+ }
+
+ } else { // a filename!
+ if (!in_filename_section) { // start over: assume filenames don't match
+ in_filename_section = true;
+ flags_are_relevant = false;
+ }
+
+ // Split the line up at spaces into glob-patterns
+ const char* space = line.c_str(); // just has to be non-NULL
+ for (const char* word = line.c_str(); *space; word = space+1) {
+ if (flags_are_relevant) // we can stop as soon as we match
+ break;
+ space = strchr(word, ' ');
+ if (space == NULL)
+ space = word + strlen(word);
+ const string glob(word, space - word);
+ // We try matching both against the full argv0 and basename(argv0)
+ if (glob == ProgramInvocationName() // small optimization
+ || glob == ProgramInvocationShortName()
+#ifdef HAVE_FNMATCH_H
+ || fnmatch(glob.c_str(),
+ ProgramInvocationName(),
+ FNM_PATHNAME) == 0
+ || fnmatch(glob.c_str(),
+ ProgramInvocationShortName(),
+ FNM_PATHNAME) == 0
+#endif
+ ) {
+ flags_are_relevant = true;
+ }
+ }
+ }
+ }
+ return retval;
+}
+
+// --------------------------------------------------------------------
+// GetFromEnv()
+// AddFlagValidator()
+// These are helper functions for routines like BoolFromEnv() and
+// RegisterFlagValidator, defined below. They're defined here so
+// they can live in the unnamed namespace (which makes friendship
+// declarations for these classes possible).
+// --------------------------------------------------------------------
+
+template<typename T>
+T GetFromEnv(const char *varname, const char* type, T dflt) {
+ const char* const valstr = getenv(varname);
+ if (!valstr)
+ return dflt;
+ FlagValue ifv(new T, type, true);
+ if (!ifv.ParseFrom(valstr))
+ ReportError(DIE, "ERROR: error parsing env variable '%s' with value '%s'\n",
+ varname, valstr);
+ return OTHER_VALUE_AS(ifv, T);
+}
+
+bool AddFlagValidator(const void* flag_ptr, ValidateFnProto validate_fn_proto) {
+ // We want a lock around this routine, in case two threads try to
+ // add a validator (hopefully the same one!) at once. We could use
+ // our own thread, but we need to loook at the registry anyway, so
+ // we just steal that one.
+ FlagRegistry* const registry = FlagRegistry::GlobalRegistry();
+ FlagRegistryLock frl(registry);
+ // First, find the flag whose current-flag storage is 'flag'.
+ // This is the CommandLineFlag whose current_->value_buffer_ == flag
+ CommandLineFlag* flag = registry->FindFlagViaPtrLocked(flag_ptr);
+ if (!flag) {
+ LOG(WARNING) << "Ignoring RegisterValidateFunction() for flag pointer "
+ << flag_ptr << ": no flag found at that address";
+ return false;
+ } else if (validate_fn_proto == flag->validate_function()) {
+ return true; // ok to register the same function over and over again
+ } else if (validate_fn_proto != NULL && flag->validate_function() != NULL) {
+ LOG(WARNING) << "Ignoring RegisterValidateFunction() for flag '"
+ << flag->name() << "': validate-fn already registered";
+ return false;
+ } else {
+ flag->validate_fn_proto_ = validate_fn_proto;
+ return true;
+ }
+}
+
+} // end unnamed namespaces
+
+
+// Now define the functions that are exported via the .h file
+
+// --------------------------------------------------------------------
+// FlagRegisterer
+// This class exists merely to have a global constructor (the
+// kind that runs before main(), that goes an initializes each
+// flag that's been declared. Note that it's very important we
+// don't have a destructor that deletes flag_, because that would
+// cause us to delete current_storage/defvalue_storage as well,
+// which can cause a crash if anything tries to access the flag
+// values in a global destructor.
+// --------------------------------------------------------------------
+
+FlagRegisterer::FlagRegisterer(const char* name, const char* type,
+ const char* help, const char* filename,
+ void* current_storage, void* defvalue_storage) {
+ if (help == NULL)
+ help = "";
+ // FlagValue expects the type-name to not include any namespace
+ // components, so we get rid of those, if any.
+ if (strchr(type, ':'))
+ type = strrchr(type, ':') + 1;
+ FlagValue* current = new FlagValue(current_storage, type, false);
+ FlagValue* defvalue = new FlagValue(defvalue_storage, type, false);
+ // Importantly, flag_ will never be deleted, so storage is always good.
+ CommandLineFlag* flag = new CommandLineFlag(name, help, filename,
+ current, defvalue);
+ FlagRegistry::GlobalRegistry()->RegisterFlag(flag); // default registry
+}
+
+// --------------------------------------------------------------------
+// GetAllFlags()
+// The main way the FlagRegistry class exposes its data. This
+// returns, as strings, all the info about all the flags in
+// the main registry, sorted first by filename they are defined
+// in, and then by flagname.
+// --------------------------------------------------------------------
+
+struct FilenameFlagnameCmp {
+ bool operator()(const CommandLineFlagInfo& a,
+ const CommandLineFlagInfo& b) const {
+ int cmp = strcmp(a.filename.c_str(), b.filename.c_str());
+ if (cmp == 0)
+ cmp = strcmp(a.name.c_str(), b.name.c_str()); // secondary sort key
+ return cmp < 0;
+ }
+};
+
+void GetAllFlags(vector<CommandLineFlagInfo>* OUTPUT) {
+ FlagRegistry* const registry = FlagRegistry::GlobalRegistry();
+ registry->Lock();
+ for (FlagRegistry::FlagConstIterator i = registry->flags_.begin();
+ i != registry->flags_.end(); ++i) {
+ CommandLineFlagInfo fi;
+ i->second->FillCommandLineFlagInfo(&fi);
+ OUTPUT->push_back(fi);
+ }
+ registry->Unlock();
+ // Now sort the flags, first by filename they occur in, then alphabetically
+ sort(OUTPUT->begin(), OUTPUT->end(), FilenameFlagnameCmp());
+}
+
+// --------------------------------------------------------------------
+// SetArgv()
+// GetArgvs()
+// GetArgv()
+// GetArgv0()
+// ProgramInvocationName()
+// ProgramInvocationShortName()
+// SetUsageMessage()
+// ProgramUsage()
+// Functions to set and get argv. Typically the setter is called
+// by ParseCommandLineFlags. Also can get the ProgramUsage string,
+// set by SetUsageMessage.
+// --------------------------------------------------------------------
+
+// These values are not protected by a Mutex because they are normally
+// set only once during program startup.
+static const char* argv0 = "UNKNOWN"; // just the program name
+static const char* cmdline = ""; // the entire command-line
+static vector<string> argvs;
+static uint32 argv_sum = 0;
+static const char* program_usage = NULL;
+
+void SetArgv(int argc, const char** argv) {
+ static bool called_set_argv = false;
+ if (called_set_argv) // we already have an argv for you
+ return;
+
+ called_set_argv = true;
+
+ assert(argc > 0); // every program has at least a progname
+ argv0 = strdup(argv[0]); // small memory leak, but fn only called once
+ assert(argv0);
+
+ string cmdline_string; // easier than doing strcats
+ for (int i = 0; i < argc; i++) {
+ if (i != 0) {
+ cmdline_string += " ";
+ }
+ cmdline_string += argv[i];
+ argvs.push_back(argv[i]);
+ }
+ cmdline = strdup(cmdline_string.c_str()); // another small memory leak
+ assert(cmdline);
+
+ // Compute a simple sum of all the chars in argv
+ for (const char* c = cmdline; *c; c++)
+ argv_sum += *c;
+}
+
+const vector<string>& GetArgvs() { return argvs; }
+const char* GetArgv() { return cmdline; }
+const char* GetArgv0() { return argv0; }
+uint32 GetArgvSum() { return argv_sum; }
+const char* ProgramInvocationName() { // like the GNU libc fn
+ return GetArgv0();
+}
+const char* ProgramInvocationShortName() { // like the GNU libc fn
+ const char* slash = strrchr(argv0, '/');
+#ifdef OS_WINDOWS
+ if (!slash) slash = strrchr(argv0, '\\');
+#endif
+ return slash ? slash + 1 : argv0;
+}
+
+void SetUsageMessage(const string& usage) {
+ if (program_usage != NULL)
+ ReportError(DIE, "ERROR: SetUsageMessage() called twice\n");
+ program_usage = strdup(usage.c_str()); // small memory leak
+}
+
+const char* ProgramUsage() {
+ if (program_usage) {
+ return program_usage;
+ }
+ return "Warning: SetUsageMessage() never called";
+}
+
+// --------------------------------------------------------------------
+// SetVersionString()
+// VersionString()
+// --------------------------------------------------------------------
+
+static const char* version_string = NULL;
+
+void SetVersionString(const string& version) {
+ if (version_string != NULL)
+ ReportError(DIE, "ERROR: SetVersionString() called twice\n");
+ version_string = strdup(version.c_str()); // small memory leak
+}
+
+const char* VersionString() {
+ return version_string ? version_string : "";
+}
+
+
+// --------------------------------------------------------------------
+// GetCommandLineOption()
+// GetCommandLineFlagInfo()
+// GetCommandLineFlagInfoOrDie()
+// SetCommandLineOption()
+// SetCommandLineOptionWithMode()
+// The programmatic way to set a flag's value, using a string
+// for its name rather than the variable itself (that is,
+// SetCommandLineOption("foo", x) rather than FLAGS_foo = x).
+// There's also a bit more flexibility here due to the various
+// set-modes, but typically these are used when you only have
+// that flag's name as a string, perhaps at runtime.
+// All of these work on the default, global registry.
+// For GetCommandLineOption, return false if no such flag
+// is known, true otherwise. We clear "value" if a suitable
+// flag is found.
+// --------------------------------------------------------------------
+
+
+bool GetCommandLineOption(const char* name, string* value) {
+ if (NULL == name)
+ return false;
+ assert(value);
+
+ FlagRegistry* const registry = FlagRegistry::GlobalRegistry();
+ FlagRegistryLock frl(registry);
+ CommandLineFlag* flag = registry->FindFlagLocked(name);
+ if (flag == NULL) {
+ return false;
+ } else {
+ *value = flag->current_value();
+ return true;
+ }
+}
+
+bool GetCommandLineFlagInfo(const char* name, CommandLineFlagInfo* OUTPUT) {
+ if (NULL == name) return false;
+ FlagRegistry* const registry = FlagRegistry::GlobalRegistry();
+ FlagRegistryLock frl(registry);
+ CommandLineFlag* flag = registry->FindFlagLocked(name);
+ if (flag == NULL) {
+ return false;
+ } else {
+ assert(OUTPUT);
+ flag->FillCommandLineFlagInfo(OUTPUT);
+ return true;
+ }
+}
+
+CommandLineFlagInfo GetCommandLineFlagInfoOrDie(const char* name) {
+ CommandLineFlagInfo info;
+ if (!GetCommandLineFlagInfo(name, &info)) {
+ fprintf(stderr, "FATAL ERROR: flag name '%s' doesn't exist\n", name);
+ gflags_exitfunc(1); // almost certainly gflags_exitfunc()
+ }
+ return info;
+}
+
+string SetCommandLineOptionWithMode(const char* name, const char* value,
+ FlagSettingMode set_mode) {
+ string result;
+ FlagRegistry* const registry = FlagRegistry::GlobalRegistry();
+ FlagRegistryLock frl(registry);
+ CommandLineFlag* flag = registry->FindFlagLocked(name);
+ if (flag) {
+ CommandLineFlagParser parser(registry);
+ result = parser.ProcessSingleOptionLocked(flag, value, set_mode);
+ if (!result.empty()) { // in the error case, we've already logged
+ // Could consider logging this change
+ }
+ }
+ // The API of this function is that we return empty string on error
+ return result;
+}
+
+string SetCommandLineOption(const char* name, const char* value) {
+ return SetCommandLineOptionWithMode(name, value, SET_FLAGS_VALUE);
+}
+
+// --------------------------------------------------------------------
+// FlagSaver
+// FlagSaverImpl
+// This class stores the states of all flags at construct time,
+// and restores all flags to that state at destruct time.
+// Its major implementation challenge is that it never modifies
+// pointers in the 'main' registry, so global FLAG_* vars always
+// point to the right place.
+// --------------------------------------------------------------------
+
+class FlagSaverImpl {
+ public:
+ // Constructs an empty FlagSaverImpl object.
+ explicit FlagSaverImpl(FlagRegistry* main_registry)
+ : main_registry_(main_registry) { }
+ ~FlagSaverImpl() {
+ // reclaim memory from each of our CommandLineFlags
+ vector<CommandLineFlag*>::const_iterator it;
+ for (it = backup_registry_.begin(); it != backup_registry_.end(); ++it)
+ delete *it;
+ }
+
+ // Saves the flag states from the flag registry into this object.
+ // It's an error to call this more than once.
+ // Must be called when the registry mutex is not held.
+ void SaveFromRegistry() {
+ FlagRegistryLock frl(main_registry_);
+ assert(backup_registry_.empty()); // call only once!
+ for (FlagRegistry::FlagConstIterator it = main_registry_->flags_.begin();
+ it != main_registry_->flags_.end();
+ ++it) {
+ const CommandLineFlag* main = it->second;
+ // Sets up all the const variables in backup correctly
+ CommandLineFlag* backup = new CommandLineFlag(
+ main->name(), main->help(), main->filename(),
+ main->current_->New(), main->defvalue_->New());
+ // Sets up all the non-const variables in backup correctly
+ backup->CopyFrom(*main);
+ backup_registry_.push_back(backup); // add it to a convenient list
+ }
+ }
+
+ // Restores the saved flag states into the flag registry. We
+ // assume no flags were added or deleted from the registry since
+ // the SaveFromRegistry; if they were, that's trouble! Must be
+ // called when the registry mutex is not held.
+ void RestoreToRegistry() {
+ FlagRegistryLock frl(main_registry_);
+ vector<CommandLineFlag*>::const_iterator it;
+ for (it = backup_registry_.begin(); it != backup_registry_.end(); ++it) {
+ CommandLineFlag* main = main_registry_->FindFlagLocked((*it)->name());
+ if (main != NULL) { // if NULL, flag got deleted from registry(!)
+ main->CopyFrom(**it);
+ }
+ }
+ }
+
+ private:
+ FlagRegistry* const main_registry_;
+ vector<CommandLineFlag*> backup_registry_;
+
+ FlagSaverImpl(const FlagSaverImpl&); // no copying!
+ void operator=(const FlagSaverImpl&);
+};
+
+FlagSaver::FlagSaver()
+ : impl_(new FlagSaverImpl(FlagRegistry::GlobalRegistry())) {
+ impl_->SaveFromRegistry();
+}
+
+FlagSaver::~FlagSaver() {
+ impl_->RestoreToRegistry();
+ delete impl_;
+}
+
+
+// --------------------------------------------------------------------
+// CommandlineFlagsIntoString()
+// ReadFlagsFromString()
+// AppendFlagsIntoFile()
+// ReadFromFlagsFile()
+// These are mostly-deprecated routines that stick the
+// commandline flags into a file/string and read them back
+// out again. I can see a use for CommandlineFlagsIntoString,
+// for creating a flagfile, but the rest don't seem that useful
+// -- some, I think, are a poor-man's attempt at FlagSaver --
+// and are included only until we can delete them from callers.
+// Note they don't save --flagfile flags (though they do save
+// the result of having called the flagfile, of course).
+// --------------------------------------------------------------------
+
+static string TheseCommandlineFlagsIntoString(
+ const vector<CommandLineFlagInfo>& flags) {
+ vector<CommandLineFlagInfo>::const_iterator i;
+
+ size_t retval_space = 0;
+ for (i = flags.begin(); i != flags.end(); ++i) {
+ // An (over)estimate of how much space it will take to print this flag
+ retval_space += i->name.length() + i->current_value.length() + 5;
+ }
+
+ string retval;
+ retval.reserve(retval_space);
+ for (i = flags.begin(); i != flags.end(); ++i) {
+ retval += "--";
+ retval += i->name;
+ retval += "=";
+ retval += i->current_value;
+ retval += "\n";
+ }
+ return retval;
+}
+
+string CommandlineFlagsIntoString() {
+ vector<CommandLineFlagInfo> sorted_flags;
+ GetAllFlags(&sorted_flags);
+ return TheseCommandlineFlagsIntoString(sorted_flags);
+}
+
+bool ReadFlagsFromString(const string& flagfilecontents,
+ const char* /*prog_name*/, // TODO(csilvers): nix this
+ bool errors_are_fatal) {
+ FlagRegistry* const registry = FlagRegistry::GlobalRegistry();
+ FlagSaverImpl saved_states(registry);
+ saved_states.SaveFromRegistry();
+
+ CommandLineFlagParser parser(registry);
+ registry->Lock();
+ parser.ProcessOptionsFromStringLocked(flagfilecontents, SET_FLAGS_VALUE);
+ registry->Unlock();
+ // Should we handle --help and such when reading flags from a string? Sure.
+ //HandleCommandLineHelpFlags();
+ if (parser.ReportErrors()) {
+ // Error. Restore all global flags to their previous values.
+ if (errors_are_fatal)
+ gflags_exitfunc(1);
+ saved_states.RestoreToRegistry();
+ return false;
+ }
+ return true;
+}
+
+// TODO(csilvers): nix prog_name in favor of ProgramInvocationShortName()
+bool AppendFlagsIntoFile(const string& filename, const char *prog_name) {
+ FILE *fp = fopen(filename.c_str(), "a");
+ if (!fp) {
+ return false;
+ }
+
+ if (prog_name)
+ fprintf(fp, "%s\n", prog_name);
+
+ vector<CommandLineFlagInfo> flags;
+ GetAllFlags(&flags);
+ // But we don't want --flagfile, which leads to weird recursion issues
+ vector<CommandLineFlagInfo>::iterator i;
+ for (i = flags.begin(); i != flags.end(); ++i) {
+ if (strcmp(i->name.c_str(), "flagfile") == 0) {
+ flags.erase(i);
+ break;
+ }
+ }
+ fprintf(fp, "%s", TheseCommandlineFlagsIntoString(flags).c_str());
+
+ fclose(fp);
+ return true;
+}
+
+bool ReadFromFlagsFile(const string& filename, const char* prog_name,
+ bool errors_are_fatal) {
+ return ReadFlagsFromString(ReadFileIntoString(filename.c_str()),
+ prog_name, errors_are_fatal);
+}
+
+
+// --------------------------------------------------------------------
+// BoolFromEnv()
+// Int32FromEnv()
+// Int64FromEnv()
+// Uint64FromEnv()
+// DoubleFromEnv()
+// StringFromEnv()
+// Reads the value from the environment and returns it.
+// We use an FlagValue to make the parsing easy.
+// Example usage:
+// DEFINE_bool(myflag, BoolFromEnv("MYFLAG_DEFAULT", false), "whatever");
+// --------------------------------------------------------------------
+
+bool BoolFromEnv(const char *v, bool dflt) {
+ return GetFromEnv(v, "bool", dflt);
+}
+int32 Int32FromEnv(const char *v, int32 dflt) {
+ return GetFromEnv(v, "int32", dflt);
+}
+int64 Int64FromEnv(const char *v, int64 dflt) {
+ return GetFromEnv(v, "int64", dflt);
+}
+uint64 Uint64FromEnv(const char *v, uint64 dflt) {
+ return GetFromEnv(v, "uint64", dflt);
+}
+double DoubleFromEnv(const char *v, double dflt) {
+ return GetFromEnv(v, "double", dflt);
+}
+const char *StringFromEnv(const char *varname, const char *dflt) {
+ const char* const val = getenv(varname);
+ return val ? val : dflt;
+}
+
+
+// --------------------------------------------------------------------
+// RegisterFlagValidator()
+// RegisterFlagValidator() is the function that clients use to
+// 'decorate' a flag with a validation function. Once this is
+// done, every time the flag is set (including when the flag
+// is parsed from argv), the validator-function is called.
+// These functions return true if the validator was added
+// successfully, or false if not: the flag already has a validator,
+// (only one allowed per flag), the 1st arg isn't a flag, etc.
+// This function is not thread-safe.
+// --------------------------------------------------------------------
+
+bool RegisterFlagValidator(const bool* flag,
+ bool (*validate_fn)(const char*, bool)) {
+ return AddFlagValidator(flag, reinterpret_cast<ValidateFnProto>(validate_fn));
+}
+bool RegisterFlagValidator(const int32* flag,
+ bool (*validate_fn)(const char*, int32)) {
+ return AddFlagValidator(flag, reinterpret_cast<ValidateFnProto>(validate_fn));
+}
+bool RegisterFlagValidator(const int64* flag,
+ bool (*validate_fn)(const char*, int64)) {
+ return AddFlagValidator(flag, reinterpret_cast<ValidateFnProto>(validate_fn));
+}
+bool RegisterFlagValidator(const uint64* flag,
+ bool (*validate_fn)(const char*, uint64)) {
+ return AddFlagValidator(flag, reinterpret_cast<ValidateFnProto>(validate_fn));
+}
+bool RegisterFlagValidator(const double* flag,
+ bool (*validate_fn)(const char*, double)) {
+ return AddFlagValidator(flag, reinterpret_cast<ValidateFnProto>(validate_fn));
+}
+bool RegisterFlagValidator(const string* flag,
+ bool (*validate_fn)(const char*, const string&)) {
+ return AddFlagValidator(flag, reinterpret_cast<ValidateFnProto>(validate_fn));
+}
+
+
+// --------------------------------------------------------------------
+// ParseCommandLineFlags()
+// ParseCommandLineNonHelpFlags()
+// HandleCommandLineHelpFlags()
+// This is the main function called from main(), to actually
+// parse the commandline. It modifies argc and argv as described
+// at the top of gflags.h. You can also divide this
+// function into two parts, if you want to do work between
+// the parsing of the flags and the printing of any help output.
+// --------------------------------------------------------------------
+
+static uint32 ParseCommandLineFlagsInternal(int* argc, char*** argv,
+ bool remove_flags, bool do_report) {
+ SetArgv(*argc, const_cast<const char**>(*argv)); // save it for later
+
+ FlagRegistry* const registry = FlagRegistry::GlobalRegistry();
+ CommandLineFlagParser parser(registry);
+
+ // When we parse the commandline flags, we'll handle --flagfile,
+ // --tryfromenv, etc. as we see them (since flag-evaluation order
+ // may be important). But sometimes apps set FLAGS_tryfromenv/etc.
+ // manually before calling ParseCommandLineFlags. We want to evaluate
+ // those too, as if they were the first flags on the commandline.
+ registry->Lock();
+ parser.ProcessFlagfileLocked(FLAGS_flagfile, SET_FLAGS_VALUE);
+ // Last arg here indicates whether flag-not-found is a fatal error or not
+ parser.ProcessFromenvLocked(FLAGS_fromenv, SET_FLAGS_VALUE, true);
+ parser.ProcessFromenvLocked(FLAGS_tryfromenv, SET_FLAGS_VALUE, false);
+ registry->Unlock();
+
+ // Now get the flags specified on the commandline
+ const int r = parser.ParseNewCommandLineFlags(argc, argv, remove_flags);
+
+ //if (do_report)
+ //HandleCommandLineHelpFlags(); // may cause us to exit on --help, etc.
+
+ // See if any of the unset flags fail their validation checks
+ parser.ValidateAllFlags();
+
+ if (parser.ReportErrors()) // may cause us to exit on illegal flags
+ gflags_exitfunc(1);
+ return r;
+}
+
+uint32 ParseCommandLineFlags(int* argc, char*** argv, bool remove_flags) {
+ return ParseCommandLineFlagsInternal(argc, argv, remove_flags, true);
+}
+
+uint32 ParseCommandLineNonHelpFlags(int* argc, char*** argv,
+ bool remove_flags) {
+ return ParseCommandLineFlagsInternal(argc, argv, remove_flags, false);
+}
+
+// --------------------------------------------------------------------
+// AllowCommandLineReparsing()
+// ReparseCommandLineNonHelpFlags()
+// This is most useful for shared libraries. The idea is if
+// a flag is defined in a shared library that is dlopen'ed
+// sometime after main(), you can ParseCommandLineFlags before
+// the dlopen, then ReparseCommandLineNonHelpFlags() after the
+// dlopen, to get the new flags. But you have to explicitly
+// Allow() it; otherwise, you get the normal default behavior
+// of unrecognized flags calling a fatal error.
+// TODO(csilvers): this isn't used. Just delete it?
+// --------------------------------------------------------------------
+
+void AllowCommandLineReparsing() {
+ allow_command_line_reparsing = true;
+}
+
+void ReparseCommandLineNonHelpFlags() {
+ // We make a copy of argc and argv to pass in
+ const vector<string>& argvs = GetArgvs();
+ int tmp_argc = static_cast<int>(argvs.size());
+ char** tmp_argv = new char* [tmp_argc + 1];
+ for (int i = 0; i < tmp_argc; ++i)
+ tmp_argv[i] = strdup(argvs[i].c_str()); // TODO(csilvers): don't dup
+
+ ParseCommandLineNonHelpFlags(&tmp_argc, &tmp_argv, false);
+
+ for (int i = 0; i < tmp_argc; ++i)
+ free(tmp_argv[i]);
+ delete[] tmp_argv;
+}
+
+void ShutDownCommandLineFlags() {
+ FlagRegistry::DeleteGlobalRegistry();
+}
+
+_END_GOOGLE_NAMESPACE_
diff --git a/src/third_party/gflags-2.0/src/gflags/gflags.h b/src/third_party/gflags-2.0/src/gflags/gflags.h
new file mode 100755
index 00000000000..da6cae21041
--- /dev/null
+++ b/src/third_party/gflags-2.0/src/gflags/gflags.h
@@ -0,0 +1,569 @@
+// Copyright (c) 2006, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// ---
+// Revamped and reorganized by Craig Silverstein
+//
+// This is the file that should be included by any file which declares
+// or defines a command line flag or wants to parse command line flags
+// or print a program usage message (which will include information about
+// flags). Executive summary, in the form of an example foo.cc file:
+//
+// #include "foo.h" // foo.h has a line "DECLARE_int32(start);"
+// #include "validators.h" // hypothetical file defining ValidateIsFile()
+//
+// DEFINE_int32(end, 1000, "The last record to read");
+//
+// DEFINE_string(filename, "my_file.txt", "The file to read");
+// // Crash if the specified file does not exist.
+// static bool dummy = RegisterFlagValidator(&FLAGS_filename,
+// &ValidateIsFile);
+//
+// DECLARE_bool(verbose); // some other file has a DEFINE_bool(verbose, ...)
+//
+// void MyFunc() {
+// if (FLAGS_verbose) printf("Records %d-%d\n", FLAGS_start, FLAGS_end);
+// }
+//
+// Then, at the command-line:
+// ./foo --noverbose --start=5 --end=100
+//
+// For more details, see
+// doc/gflags.html
+//
+// --- A note about thread-safety:
+//
+// We describe many functions in this routine as being thread-hostile,
+// thread-compatible, or thread-safe. Here are the meanings we use:
+//
+// thread-safe: it is safe for multiple threads to call this routine
+// (or, when referring to a class, methods of this class)
+// concurrently.
+// thread-hostile: it is not safe for multiple threads to call this
+// routine (or methods of this class) concurrently. In gflags,
+// most thread-hostile routines are intended to be called early in,
+// or even before, main() -- that is, before threads are spawned.
+// thread-compatible: it is safe for multiple threads to read from
+// this variable (when applied to variables), or to call const
+// methods of this class (when applied to classes), as long as no
+// other thread is writing to the variable or calling non-const
+// methods of this class.
+
+#ifndef BASE_COMMANDLINEFLAGS_H_
+#define BASE_COMMANDLINEFLAGS_H_
+
+#include <string>
+#include <vector>
+#include <gflags/gflags_declare.h> // IWYU pragma: export
+namespace google {
+
+//
+// NOTE: all functions below MUST have an explicit 'extern' before
+// them. Our automated opensourcing tools use this as a signal to do
+// appropriate munging for windows, which needs to add GFLAGS_DLL_DECL.
+//
+#define GFLAGS_DLL_DECL /* rewritten to be non-empty in windows dir */
+#define GFLAGS_DLL_DEFINE_FLAG /* rewritten to be non-empty in windows dir */
+
+
+// --------------------------------------------------------------------
+// To actually define a flag in a file, use DEFINE_bool,
+// DEFINE_string, etc. at the bottom of this file. You may also find
+// it useful to register a validator with the flag. This ensures that
+// when the flag is parsed from the commandline, or is later set via
+// SetCommandLineOption, we call the validation function. It is _not_
+// called when you assign the value to the flag directly using the = operator.
+//
+// The validation function should return true if the flag value is valid, and
+// false otherwise. If the function returns false for the new setting of the
+// flag, the flag will retain its current value. If it returns false for the
+// default value, ParseCommandLineFlags() will die.
+//
+// This function is safe to call at global construct time (as in the
+// example below).
+//
+// Example use:
+// static bool ValidatePort(const char* flagname, int32 value) {
+// if (value > 0 && value < 32768) // value is ok
+// return true;
+// printf("Invalid value for --%s: %d\n", flagname, (int)value);
+// return false;
+// }
+// DEFINE_int32(port, 0, "What port to listen on");
+// static bool dummy = RegisterFlagValidator(&FLAGS_port, &ValidatePort);
+
+// Returns true if successfully registered, false if not (because the
+// first argument doesn't point to a command-line flag, or because a
+// validator is already registered for this flag).
+extern bool RegisterFlagValidator(const bool* flag,
+ bool (*validate_fn)(const char*, bool));
+extern bool RegisterFlagValidator(const int32* flag,
+ bool (*validate_fn)(const char*, int32));
+extern bool RegisterFlagValidator(const int64* flag,
+ bool (*validate_fn)(const char*, int64));
+extern bool RegisterFlagValidator(const uint64* flag,
+ bool (*validate_fn)(const char*, uint64));
+extern bool RegisterFlagValidator(const double* flag,
+ bool (*validate_fn)(const char*, double));
+extern bool RegisterFlagValidator(const std::string* flag,
+ bool (*validate_fn)(const char*,
+ const std::string&));
+
+
+// --------------------------------------------------------------------
+// These methods are the best way to get access to info about the
+// list of commandline flags. Note that these routines are pretty slow.
+// GetAllFlags: mostly-complete info about the list, sorted by file.
+// ShowUsageWithFlags: pretty-prints the list to stdout (what --help does)
+// ShowUsageWithFlagsRestrict: limit to filenames with restrict as a substr
+//
+// In addition to accessing flags, you can also access argv[0] (the program
+// name) and argv (the entire commandline), which we sock away a copy of.
+// These variables are static, so you should only set them once.
+
+struct GFLAGS_DLL_DECL CommandLineFlagInfo {
+ std::string name; // the name of the flag
+ std::string type; // the type of the flag: int32, etc
+ std::string description; // the "help text" associated with the flag
+ std::string current_value; // the current value, as a string
+ std::string default_value; // the default value, as a string
+ std::string filename; // 'cleaned' version of filename holding the flag
+ bool has_validator_fn; // true if RegisterFlagValidator called on this flag
+ bool is_default; // true if the flag has the default value and
+ // has not been set explicitly from the cmdline
+ // or via SetCommandLineOption
+ const void* flag_ptr; // pointer to the flag's current value (i.e. FLAGS_foo)
+};
+
+// Using this inside of a validator is a recipe for a deadlock.
+// TODO(user) Fix locking when validators are running, to make it safe to
+// call validators during ParseAllFlags.
+// Also make sure then to uncomment the corresponding unit test in
+// gflags_unittest.sh
+extern void GetAllFlags(std::vector<CommandLineFlagInfo>* OUTPUT);
+// These two are actually defined in gflags_reporting.cc.
+extern void ShowUsageWithFlags(const char *argv0); // what --help does
+extern void ShowUsageWithFlagsRestrict(const char *argv0, const char *restrict);
+
+// Create a descriptive string for a flag.
+// Goes to some trouble to make pretty line breaks.
+extern std::string DescribeOneFlag(const CommandLineFlagInfo& flag);
+
+// Thread-hostile; meant to be called before any threads are spawned.
+extern void SetArgv(int argc, const char** argv);
+
+// The following functions are thread-safe as long as SetArgv() is
+// only called before any threads start.
+extern const std::vector<std::string>& GetArgvs();
+extern const char* GetArgv(); // all of argv as a string
+extern const char* GetArgv0(); // only argv0
+extern uint32 GetArgvSum(); // simple checksum of argv
+extern const char* ProgramInvocationName(); // argv0, or "UNKNOWN" if not set
+extern const char* ProgramInvocationShortName(); // basename(argv0)
+
+// ProgramUsage() is thread-safe as long as SetUsageMessage() is only
+// called before any threads start.
+extern const char* ProgramUsage(); // string set by SetUsageMessage()
+
+// VersionString() is thread-safe as long as SetVersionString() is only
+// called before any threads start.
+extern const char* VersionString(); // string set by SetVersionString()
+
+
+
+// --------------------------------------------------------------------
+// Normally you access commandline flags by just saying "if (FLAGS_foo)"
+// or whatever, and set them by calling "FLAGS_foo = bar" (or, more
+// commonly, via the DEFINE_foo macro). But if you need a bit more
+// control, we have programmatic ways to get/set the flags as well.
+// These programmatic ways to access flags are thread-safe, but direct
+// access is only thread-compatible.
+
+// Return true iff the flagname was found.
+// OUTPUT is set to the flag's value, or unchanged if we return false.
+extern bool GetCommandLineOption(const char* name, std::string* OUTPUT);
+
+// Return true iff the flagname was found. OUTPUT is set to the flag's
+// CommandLineFlagInfo or unchanged if we return false.
+extern bool GetCommandLineFlagInfo(const char* name,
+ CommandLineFlagInfo* OUTPUT);
+
+// Return the CommandLineFlagInfo of the flagname. exit() if name not found.
+// Example usage, to check if a flag's value is currently the default value:
+// if (GetCommandLineFlagInfoOrDie("foo").is_default) ...
+extern CommandLineFlagInfo GetCommandLineFlagInfoOrDie(const char* name);
+
+enum GFLAGS_DLL_DECL FlagSettingMode {
+ // update the flag's value (can call this multiple times).
+ SET_FLAGS_VALUE,
+ // update the flag's value, but *only if* it has not yet been updated
+ // with SET_FLAGS_VALUE, SET_FLAG_IF_DEFAULT, or "FLAGS_xxx = nondef".
+ SET_FLAG_IF_DEFAULT,
+ // set the flag's default value to this. If the flag has not yet updated
+ // yet (via SET_FLAGS_VALUE, SET_FLAG_IF_DEFAULT, or "FLAGS_xxx = nondef")
+ // change the flag's current value to the new default value as well.
+ SET_FLAGS_DEFAULT
+};
+
+// Set a particular flag ("command line option"). Returns a string
+// describing the new value that the option has been set to. The
+// return value API is not well-specified, so basically just depend on
+// it to be empty if the setting failed for some reason -- the name is
+// not a valid flag name, or the value is not a valid value -- and
+// non-empty else.
+
+// SetCommandLineOption uses set_mode == SET_FLAGS_VALUE (the common case)
+extern std::string SetCommandLineOption(const char* name, const char* value);
+extern std::string SetCommandLineOptionWithMode(const char* name, const char* value,
+ FlagSettingMode set_mode);
+
+
+// --------------------------------------------------------------------
+// Saves the states (value, default value, whether the user has set
+// the flag, registered validators, etc) of all flags, and restores
+// them when the FlagSaver is destroyed. This is very useful in
+// tests, say, when you want to let your tests change the flags, but
+// make sure that they get reverted to the original states when your
+// test is complete.
+//
+// Example usage:
+// void TestFoo() {
+// FlagSaver s1;
+// FLAG_foo = false;
+// FLAG_bar = "some value";
+//
+// // test happens here. You can return at any time
+// // without worrying about restoring the FLAG values.
+// }
+//
+// Note: This class is marked with ATTRIBUTE_UNUSED because all the
+// work is done in the constructor and destructor, so in the standard
+// usage example above, the compiler would complain that it's an
+// unused variable.
+//
+// This class is thread-safe. However, its destructor writes to
+// exactly the set of flags that have changed value during its
+// lifetime, so concurrent _direct_ access to those flags
+// (i.e. FLAGS_foo instead of {Get,Set}CommandLineOption()) is unsafe.
+
+class GFLAGS_DLL_DECL FlagSaver {
+ public:
+ FlagSaver();
+ ~FlagSaver();
+
+ private:
+ class FlagSaverImpl* impl_; // we use pimpl here to keep API steady
+
+ FlagSaver(const FlagSaver&); // no copying!
+ void operator=(const FlagSaver&);
+}
+#ifndef _WIN32
+__attribute__ ((unused));
+#else
+;
+#endif
+
+// --------------------------------------------------------------------
+// Some deprecated or hopefully-soon-to-be-deprecated functions.
+
+// This is often used for logging. TODO(csilvers): figure out a better way
+extern std::string CommandlineFlagsIntoString();
+// Usually where this is used, a FlagSaver should be used instead.
+extern bool ReadFlagsFromString(const std::string& flagfilecontents,
+ const char* prog_name,
+ bool errors_are_fatal); // uses SET_FLAGS_VALUE
+
+// These let you manually implement --flagfile functionality.
+// DEPRECATED.
+extern bool AppendFlagsIntoFile(const std::string& filename, const char* prog_name);
+extern bool ReadFromFlagsFile(const std::string& filename, const char* prog_name,
+ bool errors_are_fatal); // uses SET_FLAGS_VALUE
+
+
+// --------------------------------------------------------------------
+// Useful routines for initializing flags from the environment.
+// In each case, if 'varname' does not exist in the environment
+// return defval. If 'varname' does exist but is not valid
+// (e.g., not a number for an int32 flag), abort with an error.
+// Otherwise, return the value. NOTE: for booleans, for true use
+// 't' or 'T' or 'true' or '1', for false 'f' or 'F' or 'false' or '0'.
+
+extern bool BoolFromEnv(const char *varname, bool defval);
+extern int32 Int32FromEnv(const char *varname, int32 defval);
+extern int64 Int64FromEnv(const char *varname, int64 defval);
+extern uint64 Uint64FromEnv(const char *varname, uint64 defval);
+extern double DoubleFromEnv(const char *varname, double defval);
+extern const char *StringFromEnv(const char *varname, const char *defval);
+
+
+// --------------------------------------------------------------------
+// The next two functions parse gflags from main():
+
+// Set the "usage" message for this program. For example:
+// string usage("This program does nothing. Sample usage:\n");
+// usage += argv[0] + " <uselessarg1> <uselessarg2>";
+// SetUsageMessage(usage);
+// Do not include commandline flags in the usage: we do that for you!
+// Thread-hostile; meant to be called before any threads are spawned.
+extern void SetUsageMessage(const std::string& usage);
+
+// Sets the version string, which is emitted with --version.
+// For instance: SetVersionString("1.3");
+// Thread-hostile; meant to be called before any threads are spawned.
+extern void SetVersionString(const std::string& version);
+
+
+// Looks for flags in argv and parses them. Rearranges argv to put
+// flags first, or removes them entirely if remove_flags is true.
+// If a flag is defined more than once in the command line or flag
+// file, the last definition is used. Returns the index (into argv)
+// of the first non-flag argument.
+// See top-of-file for more details on this function.
+#ifndef SWIG // In swig, use ParseCommandLineFlagsScript() instead.
+extern uint32 ParseCommandLineFlags(int *argc, char*** argv, bool remove_flags);
+#endif
+
+
+// Calls to ParseCommandLineNonHelpFlags and then to
+// HandleCommandLineHelpFlags can be used instead of a call to
+// ParseCommandLineFlags during initialization, in order to allow for
+// changing default values for some FLAGS (via
+// e.g. SetCommandLineOptionWithMode calls) between the time of
+// command line parsing and the time of dumping help information for
+// the flags as a result of command line parsing. If a flag is
+// defined more than once in the command line or flag file, the last
+// definition is used. Returns the index (into argv) of the first
+// non-flag argument. (If remove_flags is true, will always return 1.)
+extern uint32 ParseCommandLineNonHelpFlags(int *argc, char*** argv,
+ bool remove_flags);
+// This is actually defined in gflags_reporting.cc.
+// This function is misnamed (it also handles --version, etc.), but
+// it's too late to change that now. :-(
+extern void HandleCommandLineHelpFlags(); // in gflags_reporting.cc
+
+// Allow command line reparsing. Disables the error normally
+// generated when an unknown flag is found, since it may be found in a
+// later parse. Thread-hostile; meant to be called before any threads
+// are spawned.
+extern void AllowCommandLineReparsing();
+
+// Reparse the flags that have not yet been recognized. Only flags
+// registered since the last parse will be recognized. Any flag value
+// must be provided as part of the argument using "=", not as a
+// separate command line argument that follows the flag argument.
+// Intended for handling flags from dynamically loaded libraries,
+// since their flags are not registered until they are loaded.
+extern void ReparseCommandLineNonHelpFlags();
+
+// Clean up memory allocated by flags. This is only needed to reduce
+// the quantity of "potentially leaked" reports emitted by memory
+// debugging tools such as valgrind. It is not required for normal
+// operation, or for the google perftools heap-checker. It must only
+// be called when the process is about to exit, and all threads that
+// might access flags are quiescent. Referencing flags after this is
+// called will have unexpected consequences. This is not safe to run
+// when multiple threads might be running: the function is
+// thread-hostile.
+extern void ShutDownCommandLineFlags();
+
+
+// --------------------------------------------------------------------
+// Now come the command line flag declaration/definition macros that
+// will actually be used. They're kind of hairy. A major reason
+// for this is initialization: we want people to be able to access
+// variables in global constructors and have that not crash, even if
+// their global constructor runs before the global constructor here.
+// (Obviously, we can't guarantee the flags will have the correct
+// default value in that case, but at least accessing them is safe.)
+// The only way to do that is have flags point to a static buffer.
+// So we make one, using a union to ensure proper alignment, and
+// then use placement-new to actually set up the flag with the
+// correct default value. In the same vein, we have to worry about
+// flag access in global destructors, so FlagRegisterer has to be
+// careful never to destroy the flag-values it constructs.
+//
+// Note that when we define a flag variable FLAGS_<name>, we also
+// preemptively define a junk variable, FLAGS_no<name>. This is to
+// cause a link-time error if someone tries to define 2 flags with
+// names like "logging" and "nologging". We do this because a bool
+// flag FLAG can be set from the command line to true with a "-FLAG"
+// argument, and to false with a "-noFLAG" argument, and so this can
+// potentially avert confusion.
+//
+// We also put flags into their own namespace. It is purposefully
+// named in an opaque way that people should have trouble typing
+// directly. The idea is that DEFINE puts the flag in the weird
+// namespace, and DECLARE imports the flag from there into the current
+// namespace. The net result is to force people to use DECLARE to get
+// access to a flag, rather than saying "extern bool FLAGS_whatever;"
+// or some such instead. We want this so we can put extra
+// functionality (like sanity-checking) in DECLARE if we want, and
+// make sure it is picked up everywhere.
+//
+// We also put the type of the variable in the namespace, so that
+// people can't DECLARE_int32 something that they DEFINE_bool'd
+// elsewhere.
+
+class GFLAGS_DLL_DECL FlagRegisterer {
+ public:
+ FlagRegisterer(const char* name, const char* type,
+ const char* help, const char* filename,
+ void* current_storage, void* defvalue_storage);
+};
+
+// If your application #defines STRIP_FLAG_HELP to a non-zero value
+// before #including this file, we remove the help message from the
+// binary file. This can reduce the size of the resulting binary
+// somewhat, and may also be useful for security reasons.
+
+extern const char kStrippedFlagHelp[];
+
+}
+
+#ifndef SWIG // In swig, ignore the main flag declarations
+
+#if defined(STRIP_FLAG_HELP) && STRIP_FLAG_HELP > 0
+// Need this construct to avoid the 'defined but not used' warning.
+#define MAYBE_STRIPPED_HELP(txt) \
+ (false ? (txt) : ::google::kStrippedFlagHelp)
+#else
+#define MAYBE_STRIPPED_HELP(txt) txt
+#endif
+
+// Each command-line flag has two variables associated with it: one
+// with the current value, and one with the default value. However,
+// we have a third variable, which is where value is assigned; it's a
+// constant. This guarantees that FLAG_##value is initialized at
+// static initialization time (e.g. before program-start) rather than
+// than global construction time (which is after program-start but
+// before main), at least when 'value' is a compile-time constant. We
+// use a small trick for the "default value" variable, and call it
+// FLAGS_no<name>. This serves the second purpose of assuring a
+// compile error if someone tries to define a flag named no<name>
+// which is illegal (--foo and --nofoo both affect the "foo" flag).
+#define DEFINE_VARIABLE(type, shorttype, name, value, help) \
+ namespace fL##shorttype { \
+ static const type FLAGS_nono##name = value; \
+ /* We always want to export defined variables, dll or no */ \
+ GFLAGS_DLL_DEFINE_FLAG type FLAGS_##name = FLAGS_nono##name; \
+ type FLAGS_no##name = FLAGS_nono##name; \
+ static ::google::FlagRegisterer o_##name( \
+ #name, #type, MAYBE_STRIPPED_HELP(help), __FILE__, \
+ &FLAGS_##name, &FLAGS_no##name); \
+ } \
+ using fL##shorttype::FLAGS_##name
+
+// For DEFINE_bool, we want to do the extra check that the passed-in
+// value is actually a bool, and not a string or something that can be
+// coerced to a bool. These declarations (no definition needed!) will
+// help us do that, and never evaluate From, which is important.
+// We'll use 'sizeof(IsBool(val))' to distinguish. This code requires
+// that the compiler have different sizes for bool & double. Since
+// this is not guaranteed by the standard, we check it with a
+// COMPILE_ASSERT.
+namespace fLB {
+struct CompileAssert {};
+typedef CompileAssert expected_sizeof_double_neq_sizeof_bool[
+ (sizeof(double) != sizeof(bool)) ? 1 : -1];
+template<typename From> double GFLAGS_DLL_DECL IsBoolFlag(const From& from);
+GFLAGS_DLL_DECL bool IsBoolFlag(bool from);
+} // namespace fLB
+
+// Here are the actual DEFINE_*-macros. The respective DECLARE_*-macros
+// are in a separate include, gflags_declare.h, for reducing
+// the physical transitive size for DECLARE use.
+#define DEFINE_bool(name, val, txt) \
+ namespace fLB { \
+ typedef ::fLB::CompileAssert FLAG_##name##_value_is_not_a_bool[ \
+ (sizeof(::fLB::IsBoolFlag(val)) != sizeof(double)) ? 1 : -1]; \
+ } \
+ DEFINE_VARIABLE(bool, B, name, val, txt)
+
+#define DEFINE_int32(name, val, txt) \
+ DEFINE_VARIABLE(::google::int32, I, \
+ name, val, txt)
+
+#define DEFINE_int64(name, val, txt) \
+ DEFINE_VARIABLE(::google::int64, I64, \
+ name, val, txt)
+
+#define DEFINE_uint64(name,val, txt) \
+ DEFINE_VARIABLE(::google::uint64, U64, \
+ name, val, txt)
+
+#define DEFINE_double(name, val, txt) \
+ DEFINE_VARIABLE(double, D, name, val, txt)
+
+// Strings are trickier, because they're not a POD, so we can't
+// construct them at static-initialization time (instead they get
+// constructed at global-constructor time, which is much later). To
+// try to avoid crashes in that case, we use a char buffer to store
+// the string, which we can static-initialize, and then placement-new
+// into it later. It's not perfect, but the best we can do.
+
+namespace fLS {
+
+inline clstring* dont_pass0toDEFINE_string(char *stringspot,
+ const char *value) {
+ return new(stringspot) clstring(value);
+}
+inline clstring* dont_pass0toDEFINE_string(char *stringspot,
+ const clstring &value) {
+ return new(stringspot) clstring(value);
+}
+inline clstring* dont_pass0toDEFINE_string(char *stringspot,
+ int value);
+} // namespace fLS
+
+// We need to define a var named FLAGS_no##name so people don't define
+// --string and --nostring. And we need a temporary place to put val
+// so we don't have to evaluate it twice. Two great needs that go
+// great together!
+// The weird 'using' + 'extern' inside the fLS namespace is to work around
+// an unknown compiler bug/issue with the gcc 4.2.1 on SUSE 10. See
+// http://code.google.com/p/google-gflags/issues/detail?id=20
+#define DEFINE_string(name, val, txt) \
+ namespace fLS { \
+ using ::fLS::clstring; \
+ static union { void* align; char s[sizeof(clstring)]; } s_##name[2]; \
+ clstring* const FLAGS_no##name = ::fLS:: \
+ dont_pass0toDEFINE_string(s_##name[0].s, \
+ val); \
+ static ::google::FlagRegisterer o_##name( \
+ #name, "string", MAYBE_STRIPPED_HELP(txt), __FILE__, \
+ s_##name[0].s, new (s_##name[1].s) clstring(*FLAGS_no##name)); \
+ extern GFLAGS_DLL_DEFINE_FLAG clstring& FLAGS_##name; \
+ using fLS::FLAGS_##name; \
+ clstring& FLAGS_##name = *FLAGS_no##name; \
+ } \
+ using fLS::FLAGS_##name
+
+#endif // SWIG
+
+#endif // BASE_COMMANDLINEFLAGS_H_
diff --git a/src/third_party/gflags-2.0/src/gflags/gflags.h.in b/src/third_party/gflags-2.0/src/gflags/gflags.h.in
new file mode 100755
index 00000000000..c58beeed4c9
--- /dev/null
+++ b/src/third_party/gflags-2.0/src/gflags/gflags.h.in
@@ -0,0 +1,565 @@
+// Copyright (c) 2006, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// ---
+// Revamped and reorganized by Craig Silverstein
+//
+// This is the file that should be included by any file which declares
+// or defines a command line flag or wants to parse command line flags
+// or print a program usage message (which will include information about
+// flags). Executive summary, in the form of an example foo.cc file:
+//
+// #include "foo.h" // foo.h has a line "DECLARE_int32(start);"
+// #include "validators.h" // hypothetical file defining ValidateIsFile()
+//
+// DEFINE_int32(end, 1000, "The last record to read");
+//
+// DEFINE_string(filename, "my_file.txt", "The file to read");
+// // Crash if the specified file does not exist.
+// static bool dummy = RegisterFlagValidator(&FLAGS_filename,
+// &ValidateIsFile);
+//
+// DECLARE_bool(verbose); // some other file has a DEFINE_bool(verbose, ...)
+//
+// void MyFunc() {
+// if (FLAGS_verbose) printf("Records %d-%d\n", FLAGS_start, FLAGS_end);
+// }
+//
+// Then, at the command-line:
+// ./foo --noverbose --start=5 --end=100
+//
+// For more details, see
+// doc/gflags.html
+//
+// --- A note about thread-safety:
+//
+// We describe many functions in this routine as being thread-hostile,
+// thread-compatible, or thread-safe. Here are the meanings we use:
+//
+// thread-safe: it is safe for multiple threads to call this routine
+// (or, when referring to a class, methods of this class)
+// concurrently.
+// thread-hostile: it is not safe for multiple threads to call this
+// routine (or methods of this class) concurrently. In gflags,
+// most thread-hostile routines are intended to be called early in,
+// or even before, main() -- that is, before threads are spawned.
+// thread-compatible: it is safe for multiple threads to read from
+// this variable (when applied to variables), or to call const
+// methods of this class (when applied to classes), as long as no
+// other thread is writing to the variable or calling non-const
+// methods of this class.
+
+#ifndef BASE_COMMANDLINEFLAGS_H_
+#define BASE_COMMANDLINEFLAGS_H_
+
+#include <string>
+#include <vector>
+#include <gflags/gflags_declare.h> // IWYU pragma: export
+@ac_google_start_namespace@
+
+//
+// NOTE: all functions below MUST have an explicit 'extern' before
+// them. Our automated opensourcing tools use this as a signal to do
+// appropriate munging for windows, which needs to add GFLAGS_DLL_DECL.
+//
+#define GFLAGS_DLL_DECL /* rewritten to be non-empty in windows dir */
+#define GFLAGS_DLL_DEFINE_FLAG /* rewritten to be non-empty in windows dir */
+
+
+// --------------------------------------------------------------------
+// To actually define a flag in a file, use DEFINE_bool,
+// DEFINE_string, etc. at the bottom of this file. You may also find
+// it useful to register a validator with the flag. This ensures that
+// when the flag is parsed from the commandline, or is later set via
+// SetCommandLineOption, we call the validation function. It is _not_
+// called when you assign the value to the flag directly using the = operator.
+//
+// The validation function should return true if the flag value is valid, and
+// false otherwise. If the function returns false for the new setting of the
+// flag, the flag will retain its current value. If it returns false for the
+// default value, ParseCommandLineFlags() will die.
+//
+// This function is safe to call at global construct time (as in the
+// example below).
+//
+// Example use:
+// static bool ValidatePort(const char* flagname, int32 value) {
+// if (value > 0 && value < 32768) // value is ok
+// return true;
+// printf("Invalid value for --%s: %d\n", flagname, (int)value);
+// return false;
+// }
+// DEFINE_int32(port, 0, "What port to listen on");
+// static bool dummy = RegisterFlagValidator(&FLAGS_port, &ValidatePort);
+
+// Returns true if successfully registered, false if not (because the
+// first argument doesn't point to a command-line flag, or because a
+// validator is already registered for this flag).
+extern bool RegisterFlagValidator(const bool* flag,
+ bool (*validate_fn)(const char*, bool));
+extern bool RegisterFlagValidator(const int32* flag,
+ bool (*validate_fn)(const char*, int32));
+extern bool RegisterFlagValidator(const int64* flag,
+ bool (*validate_fn)(const char*, int64));
+extern bool RegisterFlagValidator(const uint64* flag,
+ bool (*validate_fn)(const char*, uint64));
+extern bool RegisterFlagValidator(const double* flag,
+ bool (*validate_fn)(const char*, double));
+extern bool RegisterFlagValidator(const std::string* flag,
+ bool (*validate_fn)(const char*,
+ const std::string&));
+
+
+// --------------------------------------------------------------------
+// These methods are the best way to get access to info about the
+// list of commandline flags. Note that these routines are pretty slow.
+// GetAllFlags: mostly-complete info about the list, sorted by file.
+// ShowUsageWithFlags: pretty-prints the list to stdout (what --help does)
+// ShowUsageWithFlagsRestrict: limit to filenames with restrict as a substr
+//
+// In addition to accessing flags, you can also access argv[0] (the program
+// name) and argv (the entire commandline), which we sock away a copy of.
+// These variables are static, so you should only set them once.
+
+struct GFLAGS_DLL_DECL CommandLineFlagInfo {
+ std::string name; // the name of the flag
+ std::string type; // the type of the flag: int32, etc
+ std::string description; // the "help text" associated with the flag
+ std::string current_value; // the current value, as a string
+ std::string default_value; // the default value, as a string
+ std::string filename; // 'cleaned' version of filename holding the flag
+ bool has_validator_fn; // true if RegisterFlagValidator called on this flag
+ bool is_default; // true if the flag has the default value and
+ // has not been set explicitly from the cmdline
+ // or via SetCommandLineOption
+ const void* flag_ptr; // pointer to the flag's current value (i.e. FLAGS_foo)
+};
+
+// Using this inside of a validator is a recipe for a deadlock.
+// TODO(user) Fix locking when validators are running, to make it safe to
+// call validators during ParseAllFlags.
+// Also make sure then to uncomment the corresponding unit test in
+// gflags_unittest.sh
+extern void GetAllFlags(std::vector<CommandLineFlagInfo>* OUTPUT);
+// These two are actually defined in gflags_reporting.cc.
+extern void ShowUsageWithFlags(const char *argv0); // what --help does
+extern void ShowUsageWithFlagsRestrict(const char *argv0, const char *restrict);
+
+// Create a descriptive string for a flag.
+// Goes to some trouble to make pretty line breaks.
+extern std::string DescribeOneFlag(const CommandLineFlagInfo& flag);
+
+// Thread-hostile; meant to be called before any threads are spawned.
+extern void SetArgv(int argc, const char** argv);
+
+// The following functions are thread-safe as long as SetArgv() is
+// only called before any threads start.
+extern const std::vector<std::string>& GetArgvs();
+extern const char* GetArgv(); // all of argv as a string
+extern const char* GetArgv0(); // only argv0
+extern uint32 GetArgvSum(); // simple checksum of argv
+extern const char* ProgramInvocationName(); // argv0, or "UNKNOWN" if not set
+extern const char* ProgramInvocationShortName(); // basename(argv0)
+
+// ProgramUsage() is thread-safe as long as SetUsageMessage() is only
+// called before any threads start.
+extern const char* ProgramUsage(); // string set by SetUsageMessage()
+
+// VersionString() is thread-safe as long as SetVersionString() is only
+// called before any threads start.
+extern const char* VersionString(); // string set by SetVersionString()
+
+
+
+// --------------------------------------------------------------------
+// Normally you access commandline flags by just saying "if (FLAGS_foo)"
+// or whatever, and set them by calling "FLAGS_foo = bar" (or, more
+// commonly, via the DEFINE_foo macro). But if you need a bit more
+// control, we have programmatic ways to get/set the flags as well.
+// These programmatic ways to access flags are thread-safe, but direct
+// access is only thread-compatible.
+
+// Return true iff the flagname was found.
+// OUTPUT is set to the flag's value, or unchanged if we return false.
+extern bool GetCommandLineOption(const char* name, std::string* OUTPUT);
+
+// Return true iff the flagname was found. OUTPUT is set to the flag's
+// CommandLineFlagInfo or unchanged if we return false.
+extern bool GetCommandLineFlagInfo(const char* name,
+ CommandLineFlagInfo* OUTPUT);
+
+// Return the CommandLineFlagInfo of the flagname. exit() if name not found.
+// Example usage, to check if a flag's value is currently the default value:
+// if (GetCommandLineFlagInfoOrDie("foo").is_default) ...
+extern CommandLineFlagInfo GetCommandLineFlagInfoOrDie(const char* name);
+
+enum GFLAGS_DLL_DECL FlagSettingMode {
+ // update the flag's value (can call this multiple times).
+ SET_FLAGS_VALUE,
+ // update the flag's value, but *only if* it has not yet been updated
+ // with SET_FLAGS_VALUE, SET_FLAG_IF_DEFAULT, or "FLAGS_xxx = nondef".
+ SET_FLAG_IF_DEFAULT,
+ // set the flag's default value to this. If the flag has not yet updated
+ // yet (via SET_FLAGS_VALUE, SET_FLAG_IF_DEFAULT, or "FLAGS_xxx = nondef")
+ // change the flag's current value to the new default value as well.
+ SET_FLAGS_DEFAULT
+};
+
+// Set a particular flag ("command line option"). Returns a string
+// describing the new value that the option has been set to. The
+// return value API is not well-specified, so basically just depend on
+// it to be empty if the setting failed for some reason -- the name is
+// not a valid flag name, or the value is not a valid value -- and
+// non-empty else.
+
+// SetCommandLineOption uses set_mode == SET_FLAGS_VALUE (the common case)
+extern std::string SetCommandLineOption(const char* name, const char* value);
+extern std::string SetCommandLineOptionWithMode(const char* name, const char* value,
+ FlagSettingMode set_mode);
+
+
+// --------------------------------------------------------------------
+// Saves the states (value, default value, whether the user has set
+// the flag, registered validators, etc) of all flags, and restores
+// them when the FlagSaver is destroyed. This is very useful in
+// tests, say, when you want to let your tests change the flags, but
+// make sure that they get reverted to the original states when your
+// test is complete.
+//
+// Example usage:
+// void TestFoo() {
+// FlagSaver s1;
+// FLAG_foo = false;
+// FLAG_bar = "some value";
+//
+// // test happens here. You can return at any time
+// // without worrying about restoring the FLAG values.
+// }
+//
+// Note: This class is marked with ATTRIBUTE_UNUSED because all the
+// work is done in the constructor and destructor, so in the standard
+// usage example above, the compiler would complain that it's an
+// unused variable.
+//
+// This class is thread-safe. However, its destructor writes to
+// exactly the set of flags that have changed value during its
+// lifetime, so concurrent _direct_ access to those flags
+// (i.e. FLAGS_foo instead of {Get,Set}CommandLineOption()) is unsafe.
+
+class GFLAGS_DLL_DECL FlagSaver {
+ public:
+ FlagSaver();
+ ~FlagSaver();
+
+ private:
+ class FlagSaverImpl* impl_; // we use pimpl here to keep API steady
+
+ FlagSaver(const FlagSaver&); // no copying!
+ void operator=(const FlagSaver&);
+}
+@ac_cv___attribute__unused@;
+
+// --------------------------------------------------------------------
+// Some deprecated or hopefully-soon-to-be-deprecated functions.
+
+// This is often used for logging. TODO(csilvers): figure out a better way
+extern std::string CommandlineFlagsIntoString();
+// Usually where this is used, a FlagSaver should be used instead.
+extern bool ReadFlagsFromString(const std::string& flagfilecontents,
+ const char* prog_name,
+ bool errors_are_fatal); // uses SET_FLAGS_VALUE
+
+// These let you manually implement --flagfile functionality.
+// DEPRECATED.
+extern bool AppendFlagsIntoFile(const std::string& filename, const char* prog_name);
+extern bool ReadFromFlagsFile(const std::string& filename, const char* prog_name,
+ bool errors_are_fatal); // uses SET_FLAGS_VALUE
+
+
+// --------------------------------------------------------------------
+// Useful routines for initializing flags from the environment.
+// In each case, if 'varname' does not exist in the environment
+// return defval. If 'varname' does exist but is not valid
+// (e.g., not a number for an int32 flag), abort with an error.
+// Otherwise, return the value. NOTE: for booleans, for true use
+// 't' or 'T' or 'true' or '1', for false 'f' or 'F' or 'false' or '0'.
+
+extern bool BoolFromEnv(const char *varname, bool defval);
+extern int32 Int32FromEnv(const char *varname, int32 defval);
+extern int64 Int64FromEnv(const char *varname, int64 defval);
+extern uint64 Uint64FromEnv(const char *varname, uint64 defval);
+extern double DoubleFromEnv(const char *varname, double defval);
+extern const char *StringFromEnv(const char *varname, const char *defval);
+
+
+// --------------------------------------------------------------------
+// The next two functions parse gflags from main():
+
+// Set the "usage" message for this program. For example:
+// string usage("This program does nothing. Sample usage:\n");
+// usage += argv[0] + " <uselessarg1> <uselessarg2>";
+// SetUsageMessage(usage);
+// Do not include commandline flags in the usage: we do that for you!
+// Thread-hostile; meant to be called before any threads are spawned.
+extern void SetUsageMessage(const std::string& usage);
+
+// Sets the version string, which is emitted with --version.
+// For instance: SetVersionString("1.3");
+// Thread-hostile; meant to be called before any threads are spawned.
+extern void SetVersionString(const std::string& version);
+
+
+// Looks for flags in argv and parses them. Rearranges argv to put
+// flags first, or removes them entirely if remove_flags is true.
+// If a flag is defined more than once in the command line or flag
+// file, the last definition is used. Returns the index (into argv)
+// of the first non-flag argument.
+// See top-of-file for more details on this function.
+#ifndef SWIG // In swig, use ParseCommandLineFlagsScript() instead.
+extern uint32 ParseCommandLineFlags(int *argc, char*** argv, bool remove_flags);
+#endif
+
+
+// Calls to ParseCommandLineNonHelpFlags and then to
+// HandleCommandLineHelpFlags can be used instead of a call to
+// ParseCommandLineFlags during initialization, in order to allow for
+// changing default values for some FLAGS (via
+// e.g. SetCommandLineOptionWithMode calls) between the time of
+// command line parsing and the time of dumping help information for
+// the flags as a result of command line parsing. If a flag is
+// defined more than once in the command line or flag file, the last
+// definition is used. Returns the index (into argv) of the first
+// non-flag argument. (If remove_flags is true, will always return 1.)
+extern uint32 ParseCommandLineNonHelpFlags(int *argc, char*** argv,
+ bool remove_flags);
+// This is actually defined in gflags_reporting.cc.
+// This function is misnamed (it also handles --version, etc.), but
+// it's too late to change that now. :-(
+extern void HandleCommandLineHelpFlags(); // in gflags_reporting.cc
+
+// Allow command line reparsing. Disables the error normally
+// generated when an unknown flag is found, since it may be found in a
+// later parse. Thread-hostile; meant to be called before any threads
+// are spawned.
+extern void AllowCommandLineReparsing();
+
+// Reparse the flags that have not yet been recognized. Only flags
+// registered since the last parse will be recognized. Any flag value
+// must be provided as part of the argument using "=", not as a
+// separate command line argument that follows the flag argument.
+// Intended for handling flags from dynamically loaded libraries,
+// since their flags are not registered until they are loaded.
+extern void ReparseCommandLineNonHelpFlags();
+
+// Clean up memory allocated by flags. This is only needed to reduce
+// the quantity of "potentially leaked" reports emitted by memory
+// debugging tools such as valgrind. It is not required for normal
+// operation, or for the google perftools heap-checker. It must only
+// be called when the process is about to exit, and all threads that
+// might access flags are quiescent. Referencing flags after this is
+// called will have unexpected consequences. This is not safe to run
+// when multiple threads might be running: the function is
+// thread-hostile.
+extern void ShutDownCommandLineFlags();
+
+
+// --------------------------------------------------------------------
+// Now come the command line flag declaration/definition macros that
+// will actually be used. They're kind of hairy. A major reason
+// for this is initialization: we want people to be able to access
+// variables in global constructors and have that not crash, even if
+// their global constructor runs before the global constructor here.
+// (Obviously, we can't guarantee the flags will have the correct
+// default value in that case, but at least accessing them is safe.)
+// The only way to do that is have flags point to a static buffer.
+// So we make one, using a union to ensure proper alignment, and
+// then use placement-new to actually set up the flag with the
+// correct default value. In the same vein, we have to worry about
+// flag access in global destructors, so FlagRegisterer has to be
+// careful never to destroy the flag-values it constructs.
+//
+// Note that when we define a flag variable FLAGS_<name>, we also
+// preemptively define a junk variable, FLAGS_no<name>. This is to
+// cause a link-time error if someone tries to define 2 flags with
+// names like "logging" and "nologging". We do this because a bool
+// flag FLAG can be set from the command line to true with a "-FLAG"
+// argument, and to false with a "-noFLAG" argument, and so this can
+// potentially avert confusion.
+//
+// We also put flags into their own namespace. It is purposefully
+// named in an opaque way that people should have trouble typing
+// directly. The idea is that DEFINE puts the flag in the weird
+// namespace, and DECLARE imports the flag from there into the current
+// namespace. The net result is to force people to use DECLARE to get
+// access to a flag, rather than saying "extern bool FLAGS_whatever;"
+// or some such instead. We want this so we can put extra
+// functionality (like sanity-checking) in DECLARE if we want, and
+// make sure it is picked up everywhere.
+//
+// We also put the type of the variable in the namespace, so that
+// people can't DECLARE_int32 something that they DEFINE_bool'd
+// elsewhere.
+
+class GFLAGS_DLL_DECL FlagRegisterer {
+ public:
+ FlagRegisterer(const char* name, const char* type,
+ const char* help, const char* filename,
+ void* current_storage, void* defvalue_storage);
+};
+
+// If your application #defines STRIP_FLAG_HELP to a non-zero value
+// before #including this file, we remove the help message from the
+// binary file. This can reduce the size of the resulting binary
+// somewhat, and may also be useful for security reasons.
+
+extern const char kStrippedFlagHelp[];
+
+@ac_google_end_namespace@
+
+#ifndef SWIG // In swig, ignore the main flag declarations
+
+#if defined(STRIP_FLAG_HELP) && STRIP_FLAG_HELP > 0
+// Need this construct to avoid the 'defined but not used' warning.
+#define MAYBE_STRIPPED_HELP(txt) \
+ (false ? (txt) : @ac_google_namespace@::kStrippedFlagHelp)
+#else
+#define MAYBE_STRIPPED_HELP(txt) txt
+#endif
+
+// Each command-line flag has two variables associated with it: one
+// with the current value, and one with the default value. However,
+// we have a third variable, which is where value is assigned; it's a
+// constant. This guarantees that FLAG_##value is initialized at
+// static initialization time (e.g. before program-start) rather than
+// than global construction time (which is after program-start but
+// before main), at least when 'value' is a compile-time constant. We
+// use a small trick for the "default value" variable, and call it
+// FLAGS_no<name>. This serves the second purpose of assuring a
+// compile error if someone tries to define a flag named no<name>
+// which is illegal (--foo and --nofoo both affect the "foo" flag).
+#define DEFINE_VARIABLE(type, shorttype, name, value, help) \
+ namespace fL##shorttype { \
+ static const type FLAGS_nono##name = value; \
+ /* We always want to export defined variables, dll or no */ \
+ GFLAGS_DLL_DEFINE_FLAG type FLAGS_##name = FLAGS_nono##name; \
+ type FLAGS_no##name = FLAGS_nono##name; \
+ static @ac_google_namespace@::FlagRegisterer o_##name( \
+ #name, #type, MAYBE_STRIPPED_HELP(help), __FILE__, \
+ &FLAGS_##name, &FLAGS_no##name); \
+ } \
+ using fL##shorttype::FLAGS_##name
+
+// For DEFINE_bool, we want to do the extra check that the passed-in
+// value is actually a bool, and not a string or something that can be
+// coerced to a bool. These declarations (no definition needed!) will
+// help us do that, and never evaluate From, which is important.
+// We'll use 'sizeof(IsBool(val))' to distinguish. This code requires
+// that the compiler have different sizes for bool & double. Since
+// this is not guaranteed by the standard, we check it with a
+// COMPILE_ASSERT.
+namespace fLB {
+struct CompileAssert {};
+typedef CompileAssert expected_sizeof_double_neq_sizeof_bool[
+ (sizeof(double) != sizeof(bool)) ? 1 : -1];
+template<typename From> double GFLAGS_DLL_DECL IsBoolFlag(const From& from);
+GFLAGS_DLL_DECL bool IsBoolFlag(bool from);
+} // namespace fLB
+
+// Here are the actual DEFINE_*-macros. The respective DECLARE_*-macros
+// are in a separate include, gflags_declare.h, for reducing
+// the physical transitive size for DECLARE use.
+#define DEFINE_bool(name, val, txt) \
+ namespace fLB { \
+ typedef ::fLB::CompileAssert FLAG_##name##_value_is_not_a_bool[ \
+ (sizeof(::fLB::IsBoolFlag(val)) != sizeof(double)) ? 1 : -1]; \
+ } \
+ DEFINE_VARIABLE(bool, B, name, val, txt)
+
+#define DEFINE_int32(name, val, txt) \
+ DEFINE_VARIABLE(@ac_google_namespace@::int32, I, \
+ name, val, txt)
+
+#define DEFINE_int64(name, val, txt) \
+ DEFINE_VARIABLE(@ac_google_namespace@::int64, I64, \
+ name, val, txt)
+
+#define DEFINE_uint64(name,val, txt) \
+ DEFINE_VARIABLE(@ac_google_namespace@::uint64, U64, \
+ name, val, txt)
+
+#define DEFINE_double(name, val, txt) \
+ DEFINE_VARIABLE(double, D, name, val, txt)
+
+// Strings are trickier, because they're not a POD, so we can't
+// construct them at static-initialization time (instead they get
+// constructed at global-constructor time, which is much later). To
+// try to avoid crashes in that case, we use a char buffer to store
+// the string, which we can static-initialize, and then placement-new
+// into it later. It's not perfect, but the best we can do.
+
+namespace fLS {
+
+inline clstring* dont_pass0toDEFINE_string(char *stringspot,
+ const char *value) {
+ return new(stringspot) clstring(value);
+}
+inline clstring* dont_pass0toDEFINE_string(char *stringspot,
+ const clstring &value) {
+ return new(stringspot) clstring(value);
+}
+inline clstring* dont_pass0toDEFINE_string(char *stringspot,
+ int value);
+} // namespace fLS
+
+// We need to define a var named FLAGS_no##name so people don't define
+// --string and --nostring. And we need a temporary place to put val
+// so we don't have to evaluate it twice. Two great needs that go
+// great together!
+// The weird 'using' + 'extern' inside the fLS namespace is to work around
+// an unknown compiler bug/issue with the gcc 4.2.1 on SUSE 10. See
+// http://code.google.com/p/google-gflags/issues/detail?id=20
+#define DEFINE_string(name, val, txt) \
+ namespace fLS { \
+ using ::fLS::clstring; \
+ static union { void* align; char s[sizeof(clstring)]; } s_##name[2]; \
+ clstring* const FLAGS_no##name = ::fLS:: \
+ dont_pass0toDEFINE_string(s_##name[0].s, \
+ val); \
+ static @ac_google_namespace@::FlagRegisterer o_##name( \
+ #name, "string", MAYBE_STRIPPED_HELP(txt), __FILE__, \
+ s_##name[0].s, new (s_##name[1].s) clstring(*FLAGS_no##name)); \
+ extern GFLAGS_DLL_DEFINE_FLAG clstring& FLAGS_##name; \
+ using fLS::FLAGS_##name; \
+ clstring& FLAGS_##name = *FLAGS_no##name; \
+ } \
+ using fLS::FLAGS_##name
+
+#endif // SWIG
+
+#endif // BASE_COMMANDLINEFLAGS_H_
diff --git a/src/third_party/gflags-2.0/src/gflags/gflags_completions.h b/src/third_party/gflags-2.0/src/gflags/gflags_completions.h
new file mode 100755
index 00000000000..37f5b0ec2cf
--- /dev/null
+++ b/src/third_party/gflags-2.0/src/gflags/gflags_completions.h
@@ -0,0 +1,130 @@
+// Copyright (c) 2008, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// ---
+
+//
+// Implement helpful bash-style command line flag completions
+//
+// ** Functional API:
+// HandleCommandLineCompletions() should be called early during
+// program startup, but after command line flag code has been
+// initialized, such as the beginning of HandleCommandLineHelpFlags().
+// It checks the value of the flag --tab_completion_word. If this
+// flag is empty, nothing happens here. If it contains a string,
+// however, then HandleCommandLineCompletions() will hijack the
+// process, attempting to identify the intention behind this
+// completion. Regardless of the outcome of this deduction, the
+// process will be terminated, similar to --helpshort flag
+// handling.
+//
+// ** Overview of Bash completions:
+// Bash can be told to programatically determine completions for the
+// current 'cursor word'. It does this by (in this case) invoking a
+// command with some additional arguments identifying the command
+// being executed, the word being completed, and the previous word
+// (if any). Bash then expects a sequence of output lines to be
+// printed to stdout. If these lines all contain a common prefix
+// longer than the cursor word, bash will replace the cursor word
+// with that common prefix, and display nothing. If there isn't such
+// a common prefix, bash will display the lines in pages using 'more'.
+//
+// ** Strategy taken for command line completions:
+// If we can deduce either the exact flag intended, or a common flag
+// prefix, we'll output exactly that. Otherwise, if information
+// must be displayed to the user, we'll take the opportunity to add
+// some helpful information beyond just the flag name (specifically,
+// we'll include the default flag value and as much of the flag's
+// description as can fit on a single terminal line width, as specified
+// by the flag --tab_completion_columns). Furthermore, we'll try to
+// make bash order the output such that the most useful or relevent
+// flags are the most likely to be shown at the top.
+//
+// ** Additional features:
+// To assist in finding that one really useful flag, substring matching
+// was implemented. Before pressing a <TAB> to get completion for the
+// current word, you can append one or more '?' to the flag to do
+// substring matching. Here's the semantics:
+// --foo<TAB> Show me all flags with names prefixed by 'foo'
+// --foo?<TAB> Show me all flags with 'foo' somewhere in the name
+// --foo??<TAB> Same as prior case, but also search in module
+// definition path for 'foo'
+// --foo???<TAB> Same as prior case, but also search in flag
+// descriptions for 'foo'
+// Finally, we'll trim the output to a relatively small number of
+// flags to keep bash quiet about the verbosity of output. If one
+// really wanted to see all possible matches, appending a '+' to the
+// search word will force the exhaustive list of matches to be printed.
+//
+// ** How to have bash accept completions from a binary:
+// Bash requires that it be informed about each command that programmatic
+// completion should be enabled for. Example addition to a .bashrc
+// file would be (your path to gflags_completions.sh file may differ):
+
+/*
+$ complete -o bashdefault -o default -o nospace -C \
+ '/home/build/eng/bash/bash_completions.sh --tab_completion_columns $COLUMNS' \
+ time env binary_name another_binary [...]
+*/
+
+// This would allow the following to work:
+// $ /path/to/binary_name --vmodule<TAB>
+// Or:
+// $ ./bin/path/another_binary --gfs_u<TAB>
+// (etc)
+//
+// Sadly, it appears that bash gives no easy way to force this behavior for
+// all commands. That's where the "time" in the above example comes in.
+// If you haven't specifically added a command to the list of completion
+// supported commands, you can still get completions by prefixing the
+// entire command with "env".
+// $ env /some/brand/new/binary --vmod<TAB>
+// Assuming that "binary" is a newly compiled binary, this should still
+// produce the expected completion output.
+
+
+#ifndef BASE_COMMANDLINEFLAGS_COMPLETIONS_H_
+#define BASE_COMMANDLINEFLAGS_COMPLETIONS_H_
+
+// Annoying stuff for windows -- makes sure clients can import these functions
+//
+// NOTE: all functions below MUST have an explicit 'extern' before
+// them. Our automated opensourcing tools use this as a signal to do
+// appropriate munging for windows, which needs to add GFLAGS_DLL_DECL.
+//
+#define GFLAGS_DLL_DECL /* rewritten to be non-empty in windows dir */
+
+
+namespace google {
+
+extern void HandleCommandLineCompletions(void);
+
+}
+
+#endif // BASE_COMMANDLINEFLAGS_COMPLETIONS_H_
diff --git a/src/third_party/gflags-2.0/src/gflags/gflags_completions.h.in b/src/third_party/gflags-2.0/src/gflags/gflags_completions.h.in
new file mode 100755
index 00000000000..8d6a84c5260
--- /dev/null
+++ b/src/third_party/gflags-2.0/src/gflags/gflags_completions.h.in
@@ -0,0 +1,130 @@
+// Copyright (c) 2008, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// ---
+
+//
+// Implement helpful bash-style command line flag completions
+//
+// ** Functional API:
+// HandleCommandLineCompletions() should be called early during
+// program startup, but after command line flag code has been
+// initialized, such as the beginning of HandleCommandLineHelpFlags().
+// It checks the value of the flag --tab_completion_word. If this
+// flag is empty, nothing happens here. If it contains a string,
+// however, then HandleCommandLineCompletions() will hijack the
+// process, attempting to identify the intention behind this
+// completion. Regardless of the outcome of this deduction, the
+// process will be terminated, similar to --helpshort flag
+// handling.
+//
+// ** Overview of Bash completions:
+// Bash can be told to programatically determine completions for the
+// current 'cursor word'. It does this by (in this case) invoking a
+// command with some additional arguments identifying the command
+// being executed, the word being completed, and the previous word
+// (if any). Bash then expects a sequence of output lines to be
+// printed to stdout. If these lines all contain a common prefix
+// longer than the cursor word, bash will replace the cursor word
+// with that common prefix, and display nothing. If there isn't such
+// a common prefix, bash will display the lines in pages using 'more'.
+//
+// ** Strategy taken for command line completions:
+// If we can deduce either the exact flag intended, or a common flag
+// prefix, we'll output exactly that. Otherwise, if information
+// must be displayed to the user, we'll take the opportunity to add
+// some helpful information beyond just the flag name (specifically,
+// we'll include the default flag value and as much of the flag's
+// description as can fit on a single terminal line width, as specified
+// by the flag --tab_completion_columns). Furthermore, we'll try to
+// make bash order the output such that the most useful or relevent
+// flags are the most likely to be shown at the top.
+//
+// ** Additional features:
+// To assist in finding that one really useful flag, substring matching
+// was implemented. Before pressing a <TAB> to get completion for the
+// current word, you can append one or more '?' to the flag to do
+// substring matching. Here's the semantics:
+// --foo<TAB> Show me all flags with names prefixed by 'foo'
+// --foo?<TAB> Show me all flags with 'foo' somewhere in the name
+// --foo??<TAB> Same as prior case, but also search in module
+// definition path for 'foo'
+// --foo???<TAB> Same as prior case, but also search in flag
+// descriptions for 'foo'
+// Finally, we'll trim the output to a relatively small number of
+// flags to keep bash quiet about the verbosity of output. If one
+// really wanted to see all possible matches, appending a '+' to the
+// search word will force the exhaustive list of matches to be printed.
+//
+// ** How to have bash accept completions from a binary:
+// Bash requires that it be informed about each command that programmatic
+// completion should be enabled for. Example addition to a .bashrc
+// file would be (your path to gflags_completions.sh file may differ):
+
+/*
+$ complete -o bashdefault -o default -o nospace -C \
+ '/home/build/eng/bash/bash_completions.sh --tab_completion_columns $COLUMNS' \
+ time env binary_name another_binary [...]
+*/
+
+// This would allow the following to work:
+// $ /path/to/binary_name --vmodule<TAB>
+// Or:
+// $ ./bin/path/another_binary --gfs_u<TAB>
+// (etc)
+//
+// Sadly, it appears that bash gives no easy way to force this behavior for
+// all commands. That's where the "time" in the above example comes in.
+// If you haven't specifically added a command to the list of completion
+// supported commands, you can still get completions by prefixing the
+// entire command with "env".
+// $ env /some/brand/new/binary --vmod<TAB>
+// Assuming that "binary" is a newly compiled binary, this should still
+// produce the expected completion output.
+
+
+#ifndef BASE_COMMANDLINEFLAGS_COMPLETIONS_H_
+#define BASE_COMMANDLINEFLAGS_COMPLETIONS_H_
+
+// Annoying stuff for windows -- makes sure clients can import these functions
+//
+// NOTE: all functions below MUST have an explicit 'extern' before
+// them. Our automated opensourcing tools use this as a signal to do
+// appropriate munging for windows, which needs to add GFLAGS_DLL_DECL.
+//
+#define GFLAGS_DLL_DECL /* rewritten to be non-empty in windows dir */
+
+
+@ac_google_start_namespace@
+
+extern void HandleCommandLineCompletions(void);
+
+@ac_google_end_namespace@
+
+#endif // BASE_COMMANDLINEFLAGS_COMPLETIONS_H_
diff --git a/src/third_party/gflags-2.0/src/gflags/gflags_declare.h b/src/third_party/gflags-2.0/src/gflags/gflags_declare.h
new file mode 100755
index 00000000000..f900666ff58
--- /dev/null
+++ b/src/third_party/gflags-2.0/src/gflags/gflags_declare.h
@@ -0,0 +1,112 @@
+// Copyright (c) 1999, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// ---
+//
+// Revamped and reorganized by Craig Silverstein
+//
+// This is the file that should be included by any file which declares
+// command line flag.
+
+#ifndef BASE_COMMANDLINEFLAGS_DECLARE_H_
+#define BASE_COMMANDLINEFLAGS_DECLARE_H_
+
+#include <string>
+#if 1
+#include <stdint.h> // the normal place uint16_t is defined
+#endif
+#if 1
+#include <sys/types.h> // the normal place u_int16_t is defined
+#endif
+#ifndef _WIN32
+#include <inttypes.h> // a third place for uint16_t or u_int16_t
+#endif
+
+namespace google {
+#if 1 // the C99 format
+typedef int32_t int32;
+typedef uint32_t uint32;
+typedef int64_t int64;
+typedef uint64_t uint64;
+#elif 1 // the BSD format
+typedef int32_t int32;
+typedef u_int32_t uint32;
+typedef int64_t int64;
+typedef u_int64_t uint64;
+#elif 0 // the windows (vc7) format
+typedef __int32 int32;
+typedef unsigned __int32 uint32;
+typedef __int64 int64;
+typedef unsigned __int64 uint64;
+#else
+#error Do not know how to define a 32-bit integer quantity on your system
+#endif
+}
+
+
+#define GFLAGS_DLL_DECLARE_FLAG /* rewritten to be non-empty in windows dir */
+
+namespace fLS {
+
+// The meaning of "string" might be different between now and when the
+// macros below get invoked (e.g., if someone is experimenting with
+// other string implementations that get defined after this file is
+// included). Save the current meaning now and use it in the macros.
+typedef std::string clstring;
+
+}
+
+#define DECLARE_VARIABLE(type, shorttype, name) \
+ /* We always want to import declared variables, dll or no */ \
+ namespace fL##shorttype { extern GFLAGS_DLL_DECLARE_FLAG type FLAGS_##name; } \
+ using fL##shorttype::FLAGS_##name
+
+#define DECLARE_bool(name) \
+ DECLARE_VARIABLE(bool, B, name)
+
+#define DECLARE_int32(name) \
+ DECLARE_VARIABLE(::google::int32, I, name)
+
+#define DECLARE_int64(name) \
+ DECLARE_VARIABLE(::google::int64, I64, name)
+
+#define DECLARE_uint64(name) \
+ DECLARE_VARIABLE(::google::uint64, U64, name)
+
+#define DECLARE_double(name) \
+ DECLARE_VARIABLE(double, D, name)
+
+#define DECLARE_string(name) \
+ namespace fLS { \
+ using ::fLS::clstring; \
+ extern GFLAGS_DLL_DECLARE_FLAG ::fLS::clstring& FLAGS_##name; \
+ } \
+ using fLS::FLAGS_##name
+
+#endif // BASE_COMMANDLINEFLAGS_DECLARE_H_
diff --git a/src/third_party/gflags-2.0/src/gflags/gflags_declare.h.in b/src/third_party/gflags-2.0/src/gflags/gflags_declare.h.in
new file mode 100755
index 00000000000..893c8816ef9
--- /dev/null
+++ b/src/third_party/gflags-2.0/src/gflags/gflags_declare.h.in
@@ -0,0 +1,112 @@
+// Copyright (c) 1999, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// ---
+//
+// Revamped and reorganized by Craig Silverstein
+//
+// This is the file that should be included by any file which declares
+// command line flag.
+
+#ifndef BASE_COMMANDLINEFLAGS_DECLARE_H_
+#define BASE_COMMANDLINEFLAGS_DECLARE_H_
+
+#include <string>
+#if @ac_cv_have_stdint_h@
+#include <stdint.h> // the normal place uint16_t is defined
+#endif
+#if @ac_cv_have_systypes_h@
+#include <sys/types.h> // the normal place u_int16_t is defined
+#endif
+#if @ac_cv_have_inttypes_h@
+#include <inttypes.h> // a third place for uint16_t or u_int16_t
+#endif
+
+@ac_google_start_namespace@
+#if @ac_cv_have_uint16_t@ // the C99 format
+typedef int32_t int32;
+typedef uint32_t uint32;
+typedef int64_t int64;
+typedef uint64_t uint64;
+#elif @ac_cv_have_u_int16_t@ // the BSD format
+typedef int32_t int32;
+typedef u_int32_t uint32;
+typedef int64_t int64;
+typedef u_int64_t uint64;
+#elif @ac_cv_have___int16@ // the windows (vc7) format
+typedef __int32 int32;
+typedef unsigned __int32 uint32;
+typedef __int64 int64;
+typedef unsigned __int64 uint64;
+#else
+#error Do not know how to define a 32-bit integer quantity on your system
+#endif
+@ac_google_end_namespace@
+
+
+#define GFLAGS_DLL_DECLARE_FLAG /* rewritten to be non-empty in windows dir */
+
+namespace fLS {
+
+// The meaning of "string" might be different between now and when the
+// macros below get invoked (e.g., if someone is experimenting with
+// other string implementations that get defined after this file is
+// included). Save the current meaning now and use it in the macros.
+typedef std::string clstring;
+
+}
+
+#define DECLARE_VARIABLE(type, shorttype, name) \
+ /* We always want to import declared variables, dll or no */ \
+ namespace fL##shorttype { extern GFLAGS_DLL_DECLARE_FLAG type FLAGS_##name; } \
+ using fL##shorttype::FLAGS_##name
+
+#define DECLARE_bool(name) \
+ DECLARE_VARIABLE(bool, B, name)
+
+#define DECLARE_int32(name) \
+ DECLARE_VARIABLE(@ac_google_namespace@::int32, I, name)
+
+#define DECLARE_int64(name) \
+ DECLARE_VARIABLE(@ac_google_namespace@::int64, I64, name)
+
+#define DECLARE_uint64(name) \
+ DECLARE_VARIABLE(@ac_google_namespace@::uint64, U64, name)
+
+#define DECLARE_double(name) \
+ DECLARE_VARIABLE(double, D, name)
+
+#define DECLARE_string(name) \
+ namespace fLS { \
+ using ::fLS::clstring; \
+ extern GFLAGS_DLL_DECLARE_FLAG ::fLS::clstring& FLAGS_##name; \
+ } \
+ using fLS::FLAGS_##name
+
+#endif // BASE_COMMANDLINEFLAGS_DECLARE_H_
diff --git a/src/third_party/gflags-2.0/src/gflags_completions.cc b/src/third_party/gflags-2.0/src/gflags_completions.cc
new file mode 100755
index 00000000000..17439dd9a10
--- /dev/null
+++ b/src/third_party/gflags-2.0/src/gflags_completions.cc
@@ -0,0 +1,768 @@
+// Copyright (c) 2008, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// ---
+
+// Bash-style command line flag completion for C++ binaries
+//
+// This module implements bash-style completions. It achieves this
+// goal in the following broad chunks:
+//
+// 1) Take a to-be-completed word, and examine it for search hints
+// 2) Identify all potentially matching flags
+// 2a) If there are no matching flags, do nothing.
+// 2b) If all matching flags share a common prefix longer than the
+// completion word, output just that matching prefix
+// 3) Categorize those flags to produce a rough ordering of relevence.
+// 4) Potentially trim the set of flags returned to a smaller number
+// that bash is happier with
+// 5) Output the matching flags in groups ordered by relevence.
+// 5a) Force bash to place most-relevent groups at the top of the list
+// 5b) Trim most flag's descriptions to fit on a single terminal line
+
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h> // for strlen
+
+#include <set>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include <gflags/gflags.h>
+#include "util.h"
+
+using std::set;
+using std::string;
+using std::vector;
+
+#ifndef PATH_SEPARATOR
+#define PATH_SEPARATOR '/'
+#endif
+
+DEFINE_string(tab_completion_word, "",
+ "If non-empty, HandleCommandLineCompletions() will hijack the "
+ "process and attempt to do bash-style command line flag "
+ "completion on this value.");
+DEFINE_int32(tab_completion_columns, 80,
+ "Number of columns to use in output for tab completion");
+
+_START_GOOGLE_NAMESPACE_
+
+namespace {
+// Function prototypes and Type forward declarations. Code may be
+// more easily understood if it is roughly ordered according to
+// control flow, rather than by C's "declare before use" ordering
+struct CompletionOptions;
+struct NotableFlags;
+
+// The entry point if flag completion is to be used.
+static void PrintFlagCompletionInfo(void);
+
+
+// 1) Examine search word
+static void CanonicalizeCursorWordAndSearchOptions(
+ const string &cursor_word,
+ string *canonical_search_token,
+ CompletionOptions *options);
+
+static bool RemoveTrailingChar(string *str, char c);
+
+
+// 2) Find all matches
+static void FindMatchingFlags(
+ const vector<CommandLineFlagInfo> &all_flags,
+ const CompletionOptions &options,
+ const string &match_token,
+ set<const CommandLineFlagInfo *> *all_matches,
+ string *longest_common_prefix);
+
+static bool DoesSingleFlagMatch(
+ const CommandLineFlagInfo &flag,
+ const CompletionOptions &options,
+ const string &match_token);
+
+
+// 3) Categorize matches
+static void CategorizeAllMatchingFlags(
+ const set<const CommandLineFlagInfo *> &all_matches,
+ const string &search_token,
+ const string &module,
+ const string &package_dir,
+ NotableFlags *notable_flags);
+
+static void TryFindModuleAndPackageDir(
+ const vector<CommandLineFlagInfo> all_flags,
+ string *module,
+ string *package_dir);
+
+
+// 4) Decide which flags to use
+static void FinalizeCompletionOutput(
+ const set<const CommandLineFlagInfo *> &matching_flags,
+ CompletionOptions *options,
+ NotableFlags *notable_flags,
+ vector<string> *completions);
+
+static void RetrieveUnusedFlags(
+ const set<const CommandLineFlagInfo *> &matching_flags,
+ const NotableFlags &notable_flags,
+ set<const CommandLineFlagInfo *> *unused_flags);
+
+
+// 5) Output matches
+static void OutputSingleGroupWithLimit(
+ const set<const CommandLineFlagInfo *> &group,
+ const string &line_indentation,
+ const string &header,
+ const string &footer,
+ bool long_output_format,
+ int *remaining_line_limit,
+ size_t *completion_elements_added,
+ vector<string> *completions);
+
+// (helpers for #5)
+static string GetShortFlagLine(
+ const string &line_indentation,
+ const CommandLineFlagInfo &info);
+
+static string GetLongFlagLine(
+ const string &line_indentation,
+ const CommandLineFlagInfo &info);
+
+
+//
+// Useful types
+
+// Try to deduce the intentions behind this completion attempt. Return the
+// canonical search term in 'canonical_search_token'. Binary search options
+// are returned in the various booleans, which should all have intuitive
+// semantics, possibly except:
+// - return_all_matching_flags: Generally, we'll trim the number of
+// returned candidates to some small number, showing those that are
+// most likely to be useful first. If this is set, however, the user
+// really does want us to return every single flag as an option.
+// - force_no_update: Any time we output lines, all of which share a
+// common prefix, bash will 'helpfully' not even bother to show the
+// output, instead changing the current word to be that common prefix.
+// If it's clear this shouldn't happen, we'll set this boolean
+struct CompletionOptions {
+ bool flag_name_substring_search;
+ bool flag_location_substring_search;
+ bool flag_description_substring_search;
+ bool return_all_matching_flags;
+ bool force_no_update;
+};
+
+// Notable flags are flags that are special or preferred for some
+// reason. For example, flags that are defined in the binary's module
+// are expected to be much more relevent than flags defined in some
+// other random location. These sets are specified roughly in precedence
+// order. Once a flag is placed in one of these 'higher' sets, it won't
+// be placed in any of the 'lower' sets.
+struct NotableFlags {
+ typedef set<const CommandLineFlagInfo *> FlagSet;
+ FlagSet perfect_match_flag;
+ FlagSet module_flags; // Found in module file
+ FlagSet package_flags; // Found in same directory as module file
+ FlagSet most_common_flags; // One of the XXX most commonly supplied flags
+ FlagSet subpackage_flags; // Found in subdirectories of package
+};
+
+
+//
+// Tab completion implementation - entry point
+static void PrintFlagCompletionInfo(void) {
+ string cursor_word = FLAGS_tab_completion_word;
+ string canonical_token;
+ CompletionOptions options = { };
+ CanonicalizeCursorWordAndSearchOptions(
+ cursor_word,
+ &canonical_token,
+ &options);
+
+ DVLOG(1) << "Identified canonical_token: '" << canonical_token << "'";
+
+ vector<CommandLineFlagInfo> all_flags;
+ set<const CommandLineFlagInfo *> matching_flags;
+ GetAllFlags(&all_flags);
+ DVLOG(2) << "Found " << all_flags.size() << " flags overall";
+
+ string longest_common_prefix;
+ FindMatchingFlags(
+ all_flags,
+ options,
+ canonical_token,
+ &matching_flags,
+ &longest_common_prefix);
+ DVLOG(1) << "Identified " << matching_flags.size() << " matching flags";
+ DVLOG(1) << "Identified " << longest_common_prefix
+ << " as longest common prefix.";
+ if (longest_common_prefix.size() > canonical_token.size()) {
+ // There's actually a shared common prefix to all matching flags,
+ // so may as well output that and quit quickly.
+ DVLOG(1) << "The common prefix '" << longest_common_prefix
+ << "' was longer than the token '" << canonical_token
+ << "'. Returning just this prefix for completion.";
+ fprintf(stdout, "--%s", longest_common_prefix.c_str());
+ return;
+ }
+ if (matching_flags.empty()) {
+ VLOG(1) << "There were no matching flags, returning nothing.";
+ return;
+ }
+
+ string module;
+ string package_dir;
+ TryFindModuleAndPackageDir(all_flags, &module, &package_dir);
+ DVLOG(1) << "Identified module: '" << module << "'";
+ DVLOG(1) << "Identified package_dir: '" << package_dir << "'";
+
+ NotableFlags notable_flags;
+ CategorizeAllMatchingFlags(
+ matching_flags,
+ canonical_token,
+ module,
+ package_dir,
+ &notable_flags);
+ DVLOG(2) << "Categorized matching flags:";
+ DVLOG(2) << " perfect_match: " << notable_flags.perfect_match_flag.size();
+ DVLOG(2) << " module: " << notable_flags.module_flags.size();
+ DVLOG(2) << " package: " << notable_flags.package_flags.size();
+ DVLOG(2) << " most common: " << notable_flags.most_common_flags.size();
+ DVLOG(2) << " subpackage: " << notable_flags.subpackage_flags.size();
+
+ vector<string> completions;
+ FinalizeCompletionOutput(
+ matching_flags,
+ &options,
+ &notable_flags,
+ &completions);
+
+ if (options.force_no_update)
+ completions.push_back("~");
+
+ DVLOG(1) << "Finalized with " << completions.size()
+ << " chosen completions";
+
+ for (vector<string>::const_iterator it = completions.begin();
+ it != completions.end();
+ ++it) {
+ DVLOG(9) << " Completion entry: '" << *it << "'";
+ fprintf(stdout, "%s\n", it->c_str());
+ }
+}
+
+
+// 1) Examine search word (and helper method)
+static void CanonicalizeCursorWordAndSearchOptions(
+ const string &cursor_word,
+ string *canonical_search_token,
+ CompletionOptions *options) {
+ *canonical_search_token = cursor_word;
+ if (canonical_search_token->empty()) return;
+
+ // Get rid of leading quotes and dashes in the search term
+ if ((*canonical_search_token)[0] == '"')
+ *canonical_search_token = canonical_search_token->substr(1);
+ while ((*canonical_search_token)[0] == '-')
+ *canonical_search_token = canonical_search_token->substr(1);
+
+ options->flag_name_substring_search = false;
+ options->flag_location_substring_search = false;
+ options->flag_description_substring_search = false;
+ options->return_all_matching_flags = false;
+ options->force_no_update = false;
+
+ // Look for all search options we can deduce now. Do this by walking
+ // backwards through the term, looking for up to three '?' and up to
+ // one '+' as suffixed characters. Consume them if found, and remove
+ // them from the canonical search token.
+ int found_question_marks = 0;
+ int found_plusses = 0;
+ while (true) {
+ if (found_question_marks < 3 &&
+ RemoveTrailingChar(canonical_search_token, '?')) {
+ ++found_question_marks;
+ continue;
+ }
+ if (found_plusses < 1 &&
+ RemoveTrailingChar(canonical_search_token, '+')) {
+ ++found_plusses;
+ continue;
+ }
+ break;
+ }
+
+ switch (found_question_marks) { // all fallthroughs
+ case 3: options->flag_description_substring_search = true;
+ case 2: options->flag_location_substring_search = true;
+ case 1: options->flag_name_substring_search = true;
+ };
+
+ options->return_all_matching_flags = (found_plusses > 0);
+}
+
+// Returns true if a char was removed
+static bool RemoveTrailingChar(string *str, char c) {
+ if (str->empty()) return false;
+ if ((*str)[str->size() - 1] == c) {
+ *str = str->substr(0, str->size() - 1);
+ return true;
+ }
+ return false;
+}
+
+
+// 2) Find all matches (and helper methods)
+static void FindMatchingFlags(
+ const vector<CommandLineFlagInfo> &all_flags,
+ const CompletionOptions &options,
+ const string &match_token,
+ set<const CommandLineFlagInfo *> *all_matches,
+ string *longest_common_prefix) {
+ all_matches->clear();
+ bool first_match = true;
+ for (vector<CommandLineFlagInfo>::const_iterator it = all_flags.begin();
+ it != all_flags.end();
+ ++it) {
+ if (DoesSingleFlagMatch(*it, options, match_token)) {
+ all_matches->insert(&*it);
+ if (first_match) {
+ first_match = false;
+ *longest_common_prefix = it->name;
+ } else {
+ if (longest_common_prefix->empty() || it->name.empty()) {
+ longest_common_prefix->clear();
+ continue;
+ }
+ string::size_type pos = 0;
+ while (pos < longest_common_prefix->size() &&
+ pos < it->name.size() &&
+ (*longest_common_prefix)[pos] == it->name[pos])
+ ++pos;
+ longest_common_prefix->erase(pos);
+ }
+ }
+ }
+}
+
+// Given the set of all flags, the parsed match options, and the
+// canonical search token, produce the set of all candidate matching
+// flags for subsequent analysis or filtering.
+static bool DoesSingleFlagMatch(
+ const CommandLineFlagInfo &flag,
+ const CompletionOptions &options,
+ const string &match_token) {
+ // Is there a prefix match?
+ string::size_type pos = flag.name.find(match_token);
+ if (pos == 0) return true;
+
+ // Is there a substring match if we want it?
+ if (options.flag_name_substring_search &&
+ pos != string::npos)
+ return true;
+
+ // Is there a location match if we want it?
+ if (options.flag_location_substring_search &&
+ flag.filename.find(match_token) != string::npos)
+ return true;
+
+ // TODO(user): All searches should probably be case-insensitive
+ // (especially this one...)
+ if (options.flag_description_substring_search &&
+ flag.description.find(match_token) != string::npos)
+ return true;
+
+ return false;
+}
+
+// 3) Categorize matches (and helper method)
+
+// Given a set of matching flags, categorize them by
+// likely relevence to this specific binary
+static void CategorizeAllMatchingFlags(
+ const set<const CommandLineFlagInfo *> &all_matches,
+ const string &search_token,
+ const string &module, // empty if we couldn't find any
+ const string &package_dir, // empty if we couldn't find any
+ NotableFlags *notable_flags) {
+ notable_flags->perfect_match_flag.clear();
+ notable_flags->module_flags.clear();
+ notable_flags->package_flags.clear();
+ notable_flags->most_common_flags.clear();
+ notable_flags->subpackage_flags.clear();
+
+ for (set<const CommandLineFlagInfo *>::const_iterator it =
+ all_matches.begin();
+ it != all_matches.end();
+ ++it) {
+ DVLOG(2) << "Examining match '" << (*it)->name << "'";
+ DVLOG(7) << " filename: '" << (*it)->filename << "'";
+ string::size_type pos = string::npos;
+ if (!package_dir.empty())
+ pos = (*it)->filename.find(package_dir);
+ string::size_type slash = string::npos;
+ if (pos != string::npos) // candidate for package or subpackage match
+ slash = (*it)->filename.find(
+ PATH_SEPARATOR,
+ pos + package_dir.size() + 1);
+
+ if ((*it)->name == search_token) {
+ // Exact match on some flag's name
+ notable_flags->perfect_match_flag.insert(*it);
+ DVLOG(3) << "Result: perfect match";
+ } else if (!module.empty() && (*it)->filename == module) {
+ // Exact match on module filename
+ notable_flags->module_flags.insert(*it);
+ DVLOG(3) << "Result: module match";
+ } else if (!package_dir.empty() &&
+ pos != string::npos && slash == string::npos) {
+ // In the package, since there was no slash after the package portion
+ notable_flags->package_flags.insert(*it);
+ DVLOG(3) << "Result: package match";
+ } else if (false) {
+ // In the list of the XXX most commonly supplied flags overall
+ // TODO(user): Compile this list.
+ DVLOG(3) << "Result: most-common match";
+ } else if (!package_dir.empty() &&
+ pos != string::npos && slash != string::npos) {
+ // In a subdirectory of the package
+ notable_flags->subpackage_flags.insert(*it);
+ DVLOG(3) << "Result: subpackage match";
+ }
+
+ DVLOG(3) << "Result: not special match";
+ }
+}
+
+static void PushNameWithSuffix(vector<string>* suffixes, const char* suffix) {
+ suffixes->push_back(
+ StringPrintf("/%s%s", ProgramInvocationShortName(), suffix));
+}
+
+static void TryFindModuleAndPackageDir(
+ const vector<CommandLineFlagInfo> all_flags,
+ string *module,
+ string *package_dir) {
+ module->clear();
+ package_dir->clear();
+
+ vector<string> suffixes;
+ // TODO(user): There's some inherant ambiguity here - multiple directories
+ // could share the same trailing folder and file structure (and even worse,
+ // same file names), causing us to be unsure as to which of the two is the
+ // actual package for this binary. In this case, we'll arbitrarily choose.
+ PushNameWithSuffix(&suffixes, ".");
+ PushNameWithSuffix(&suffixes, "-main.");
+ PushNameWithSuffix(&suffixes, "_main.");
+ // These four are new but probably merited?
+ PushNameWithSuffix(&suffixes, "-test.");
+ PushNameWithSuffix(&suffixes, "_test.");
+ PushNameWithSuffix(&suffixes, "-unittest.");
+ PushNameWithSuffix(&suffixes, "_unittest.");
+
+ for (vector<CommandLineFlagInfo>::const_iterator it = all_flags.begin();
+ it != all_flags.end();
+ ++it) {
+ for (vector<string>::const_iterator suffix = suffixes.begin();
+ suffix != suffixes.end();
+ ++suffix) {
+ // TODO(user): Make sure the match is near the end of the string
+ if (it->filename.find(*suffix) != string::npos) {
+ *module = it->filename;
+ string::size_type sep = it->filename.rfind(PATH_SEPARATOR);
+ *package_dir = it->filename.substr(0, (sep == string::npos) ? 0 : sep);
+ return;
+ }
+ }
+ }
+}
+
+// Can't specialize template type on a locally defined type. Silly C++...
+struct DisplayInfoGroup {
+ const char* header;
+ const char* footer;
+ set<const CommandLineFlagInfo *> *group;
+
+ int SizeInLines() const {
+ int size_in_lines = static_cast<int>(group->size()) + 1;
+ if (strlen(header) > 0) {
+ size_in_lines++;
+ }
+ if (strlen(footer) > 0) {
+ size_in_lines++;
+ }
+ return size_in_lines;
+ }
+};
+
+// 4) Finalize and trim output flag set
+static void FinalizeCompletionOutput(
+ const set<const CommandLineFlagInfo *> &matching_flags,
+ CompletionOptions *options,
+ NotableFlags *notable_flags,
+ vector<string> *completions) {
+
+ // We want to output lines in groups. Each group needs to be indented
+ // the same to keep its lines together. Unless otherwise required,
+ // only 99 lines should be output to prevent bash from harassing the
+ // user.
+
+ // First, figure out which output groups we'll actually use. For each
+ // nonempty group, there will be ~3 lines of header & footer, plus all
+ // output lines themselves.
+ int max_desired_lines = // "999999 flags should be enough for anyone. -dave"
+ (options->return_all_matching_flags ? 999999 : 98);
+ int lines_so_far = 0;
+
+ vector<DisplayInfoGroup> output_groups;
+ bool perfect_match_found = false;
+ if (lines_so_far < max_desired_lines &&
+ !notable_flags->perfect_match_flag.empty()) {
+ perfect_match_found = true;
+ DisplayInfoGroup group =
+ { "",
+ "==========",
+ &notable_flags->perfect_match_flag };
+ lines_so_far += group.SizeInLines();
+ output_groups.push_back(group);
+ }
+ if (lines_so_far < max_desired_lines &&
+ !notable_flags->module_flags.empty()) {
+ DisplayInfoGroup group = {
+ "-* Matching module flags *-",
+ "===========================",
+ &notable_flags->module_flags };
+ lines_so_far += group.SizeInLines();
+ output_groups.push_back(group);
+ }
+ if (lines_so_far < max_desired_lines &&
+ !notable_flags->package_flags.empty()) {
+ DisplayInfoGroup group = {
+ "-* Matching package flags *-",
+ "============================",
+ &notable_flags->package_flags };
+ lines_so_far += group.SizeInLines();
+ output_groups.push_back(group);
+ }
+ if (lines_so_far < max_desired_lines &&
+ !notable_flags->most_common_flags.empty()) {
+ DisplayInfoGroup group = {
+ "-* Commonly used flags *-",
+ "=========================",
+ &notable_flags->most_common_flags };
+ lines_so_far += group.SizeInLines();
+ output_groups.push_back(group);
+ }
+ if (lines_so_far < max_desired_lines &&
+ !notable_flags->subpackage_flags.empty()) {
+ DisplayInfoGroup group = {
+ "-* Matching sub-package flags *-",
+ "================================",
+ &notable_flags->subpackage_flags };
+ lines_so_far += group.SizeInLines();
+ output_groups.push_back(group);
+ }
+
+ set<const CommandLineFlagInfo *> obscure_flags; // flags not notable
+ if (lines_so_far < max_desired_lines) {
+ RetrieveUnusedFlags(matching_flags, *notable_flags, &obscure_flags);
+ if (!obscure_flags.empty()) {
+ DisplayInfoGroup group = {
+ "-* Other flags *-",
+ "",
+ &obscure_flags };
+ lines_so_far += group.SizeInLines();
+ output_groups.push_back(group);
+ }
+ }
+
+ // Second, go through each of the chosen output groups and output
+ // as many of those flags as we can, while remaining below our limit
+ int remaining_lines = max_desired_lines;
+ size_t completions_output = 0;
+ int indent = static_cast<int>(output_groups.size()) - 1;
+ for (vector<DisplayInfoGroup>::const_iterator it =
+ output_groups.begin();
+ it != output_groups.end();
+ ++it, --indent) {
+ OutputSingleGroupWithLimit(
+ *it->group, // group
+ string(indent, ' '), // line indentation
+ string(it->header), // header
+ string(it->footer), // footer
+ perfect_match_found, // long format
+ &remaining_lines, // line limit - reduces this by number printed
+ &completions_output, // completions (not lines) added
+ completions); // produced completions
+ perfect_match_found = false;
+ }
+
+ if (completions_output != matching_flags.size()) {
+ options->force_no_update = false;
+ completions->push_back("~ (Remaining flags hidden) ~");
+ } else {
+ options->force_no_update = true;
+ }
+}
+
+static void RetrieveUnusedFlags(
+ const set<const CommandLineFlagInfo *> &matching_flags,
+ const NotableFlags &notable_flags,
+ set<const CommandLineFlagInfo *> *unused_flags) {
+ // Remove from 'matching_flags' set all members of the sets of
+ // flags we've already printed (specifically, those in notable_flags)
+ for (set<const CommandLineFlagInfo *>::const_iterator it =
+ matching_flags.begin();
+ it != matching_flags.end();
+ ++it) {
+ if (notable_flags.perfect_match_flag.count(*it) ||
+ notable_flags.module_flags.count(*it) ||
+ notable_flags.package_flags.count(*it) ||
+ notable_flags.most_common_flags.count(*it) ||
+ notable_flags.subpackage_flags.count(*it))
+ continue;
+ unused_flags->insert(*it);
+ }
+}
+
+// 5) Output matches (and helper methods)
+
+static void OutputSingleGroupWithLimit(
+ const set<const CommandLineFlagInfo *> &group,
+ const string &line_indentation,
+ const string &header,
+ const string &footer,
+ bool long_output_format,
+ int *remaining_line_limit,
+ size_t *completion_elements_output,
+ vector<string> *completions) {
+ if (group.empty()) return;
+ if (!header.empty()) {
+ if (*remaining_line_limit < 2) return;
+ *remaining_line_limit -= 2;
+ completions->push_back(line_indentation + header);
+ completions->push_back(line_indentation + string(header.size(), '-'));
+ }
+ for (set<const CommandLineFlagInfo *>::const_iterator it = group.begin();
+ it != group.end() && *remaining_line_limit > 0;
+ ++it) {
+ --*remaining_line_limit;
+ ++*completion_elements_output;
+ completions->push_back(
+ (long_output_format
+ ? GetLongFlagLine(line_indentation, **it)
+ : GetShortFlagLine(line_indentation, **it)));
+ }
+ if (!footer.empty()) {
+ if (*remaining_line_limit < 1) return;
+ --*remaining_line_limit;
+ completions->push_back(line_indentation + footer);
+ }
+}
+
+static string GetShortFlagLine(
+ const string &line_indentation,
+ const CommandLineFlagInfo &info) {
+ string prefix;
+ bool is_string = (info.type == "string");
+ SStringPrintf(&prefix, "%s--%s [%s%s%s] ",
+ line_indentation.c_str(),
+ info.name.c_str(),
+ (is_string ? "'" : ""),
+ info.default_value.c_str(),
+ (is_string ? "'" : ""));
+ int remainder =
+ FLAGS_tab_completion_columns - static_cast<int>(prefix.size());
+ string suffix;
+ if (remainder > 0)
+ suffix =
+ (static_cast<int>(info.description.size()) > remainder ?
+ (info.description.substr(0, remainder - 3) + "...").c_str() :
+ info.description.c_str());
+ return prefix + suffix;
+}
+
+static string GetLongFlagLine(
+ const string &line_indentation,
+ const CommandLineFlagInfo &info) {
+
+ string output = DescribeOneFlag(info);
+
+ // Replace '-' with '--', and remove trailing newline before appending
+ // the module definition location.
+ string old_flagname = "-" + info.name;
+ output.replace(
+ output.find(old_flagname),
+ old_flagname.size(),
+ "-" + old_flagname);
+ // Stick a newline and indentation in front of the type and default
+ // portions of DescribeOneFlag()s description
+ static const char kNewlineWithIndent[] = "\n ";
+ output.replace(output.find(" type:"), 1, string(kNewlineWithIndent));
+ output.replace(output.find(" default:"), 1, string(kNewlineWithIndent));
+ output = StringPrintf("%s Details for '--%s':\n"
+ "%s defined: %s",
+ line_indentation.c_str(),
+ info.name.c_str(),
+ output.c_str(),
+ info.filename.c_str());
+
+ // Eliminate any doubled newlines that crept in. Specifically, if
+ // DescribeOneFlag() decided to break the line just before "type"
+ // or "default", we don't want to introduce an extra blank line
+ static const string line_of_spaces(FLAGS_tab_completion_columns, ' ');
+ static const char kDoubledNewlines[] = "\n \n";
+ for (string::size_type newlines = output.find(kDoubledNewlines);
+ newlines != string::npos;
+ newlines = output.find(kDoubledNewlines))
+ // Replace each 'doubled newline' with a single newline
+ output.replace(newlines, sizeof(kDoubledNewlines) - 1, string("\n"));
+
+ for (string::size_type newline = output.find('\n');
+ newline != string::npos;
+ newline = output.find('\n')) {
+ int newline_pos = static_cast<int>(newline) % FLAGS_tab_completion_columns;
+ int missing_spaces = FLAGS_tab_completion_columns - newline_pos;
+ output.replace(newline, 1, line_of_spaces, 1, missing_spaces);
+ }
+ return output;
+}
+} // anonymous
+
+void HandleCommandLineCompletions(void) {
+ if (FLAGS_tab_completion_word.empty()) return;
+ PrintFlagCompletionInfo();
+ gflags_exitfunc(0);
+}
+
+_END_GOOGLE_NAMESPACE_
diff --git a/src/third_party/gflags-2.0/src/gflags_completions.sh b/src/third_party/gflags-2.0/src/gflags_completions.sh
new file mode 100755
index 00000000000..c5fb7e6bc57
--- /dev/null
+++ b/src/third_party/gflags-2.0/src/gflags_completions.sh
@@ -0,0 +1,117 @@
+#!/bin/bash
+
+# Copyright (c) 2008, Google Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+# * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+# ---
+# Author: Dave Nicponski
+#
+# This script is invoked by bash in response to a matching compspec. When
+# this happens, bash calls this script using the command shown in the -C
+# block of the complete entry, but also appends 3 arguments. They are:
+# - The command being used for completion
+# - The word being completed
+# - The word preceding the completion word.
+#
+# Here's an example of how you might use this script:
+# $ complete -o bashdefault -o default -o nospace -C \
+# '/usr/local/bin/gflags_completions.sh --tab_completion_columns $COLUMNS' \
+# time env binary_name another_binary [...]
+
+# completion_word_index gets the index of the (N-1)th argument for
+# this command line. completion_word gets the actual argument from
+# this command line at the (N-1)th position
+completion_word_index="$(($# - 1))"
+completion_word="${!completion_word_index}"
+
+# TODO(user): Replace this once gflags_completions.cc has
+# a bool parameter indicating unambiguously to hijack the process for
+# completion purposes.
+if [ -z "$completion_word" ]; then
+ # Until an empty value for the completion word stops being misunderstood
+ # by binaries, don't actually execute the binary or the process
+ # won't be hijacked!
+ exit 0
+fi
+
+# binary_index gets the index of the command being completed (which bash
+# places in the (N-2)nd position. binary gets the actual command from
+# this command line at that (N-2)nd position
+binary_index="$(($# - 2))"
+binary="${!binary_index}"
+
+# For completions to be universal, we may have setup the compspec to
+# trigger on 'harmless pass-through' commands, like 'time' or 'env'.
+# If the command being completed is one of those two, we'll need to
+# identify the actual command being executed. To do this, we need
+# the actual command line that the <TAB> was pressed on. Bash helpfully
+# places this in the $COMP_LINE variable.
+if [ "$binary" == "time" ] || [ "$binary" == "env" ]; then
+ # we'll assume that the first 'argument' is actually the
+ # binary
+
+
+ # TODO(user): This is not perfect - the 'env' command, for instance,
+ # is allowed to have options between the 'env' and 'the command to
+ # be executed'. For example, consider:
+ # $ env FOO="bar" bin/do_something --help<TAB>
+ # In this case, we'll mistake the FOO="bar" portion as the binary.
+ # Perhaps we should continuing consuming leading words until we
+ # either run out of words, or find a word that is a valid file
+ # marked as executable. I can't think of any reason this wouldn't
+ # work.
+
+ # Break up the 'original command line' (not this script's command line,
+ # rather the one the <TAB> was pressed on) and find the second word.
+ parts=( ${COMP_LINE} )
+ binary=${parts[1]}
+fi
+
+# Build the command line to use for completion. Basically it involves
+# passing through all the arguments given to this script (except the 3
+# that bash added), and appending a '--tab_completion_word "WORD"' to
+# the arguments.
+params=""
+for ((i=1; i<=$(($# - 3)); ++i)); do
+ params="$params \"${!i}\"";
+done
+params="$params --tab_completion_word \"$completion_word\""
+
+# TODO(user): Perhaps stash the output in a temporary file somewhere
+# in /tmp, and only cat it to stdout if the command returned a success
+# code, to prevent false positives
+
+# If we think we have a reasonable command to execute, then execute it
+# and hope for the best.
+candidate=$(type -p "$binary")
+if [ ! -z "$candidate" ]; then
+ eval "$candidate 2>/dev/null $params"
+elif [ -f "$binary" ] && [ -x "$binary" ]; then
+ eval "$binary 2>/dev/null $params"
+fi
diff --git a/src/third_party/gflags-2.0/src/gflags_nc.cc b/src/third_party/gflags-2.0/src/gflags_nc.cc
new file mode 100755
index 00000000000..c2836127344
--- /dev/null
+++ b/src/third_party/gflags-2.0/src/gflags_nc.cc
@@ -0,0 +1,68 @@
+// Copyright (c) 2009, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// ---
+//
+// A negative comiple test for gflags.
+
+#include <gflags/gflags.h>
+
+#if defined(TEST_SWAPPED_ARGS)
+
+DEFINE_bool(some_bool_flag,
+ "the default value should go here, not the description",
+ false);
+
+
+#elif defined(TEST_INT_INSTEAD_OF_BOOL)
+
+DEFINE_bool(some_bool_flag_2,
+ 0,
+ "should have been an int32 flag but mistakenly used bool instead");
+
+#elif defined(TEST_BOOL_IN_QUOTES)
+
+
+DEFINE_bool(some_bool_flag_3,
+ "false",
+ "false in in quotes, which is wrong");
+
+#elif defined(TEST_SANITY)
+
+DEFINE_bool(some_bool_flag_4,
+ true,
+ "this is the correct usage of DEFINE_bool");
+
+#elif defined(TEST_DEFINE_STRING_WITH_0)
+
+DEFINE_string(some_string_flag,
+ 0,
+ "Trying to construct a string by passing 0 would cause a crash.");
+
+#endif
diff --git a/src/third_party/gflags-2.0/src/gflags_reporting.cc b/src/third_party/gflags-2.0/src/gflags_reporting.cc
new file mode 100755
index 00000000000..b75066b201f
--- /dev/null
+++ b/src/third_party/gflags-2.0/src/gflags_reporting.cc
@@ -0,0 +1,447 @@
+// Copyright (c) 1999, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// ---
+//
+// Revamped and reorganized by Craig Silverstein
+//
+// This file contains code for handling the 'reporting' flags. These
+// are flags that, when present, cause the program to report some
+// information and then exit. --help and --version are the canonical
+// reporting flags, but we also have flags like --helpxml, etc.
+//
+// There's only one function that's meant to be called externally:
+// HandleCommandLineHelpFlags(). (Well, actually, ShowUsageWithFlags(),
+// ShowUsageWithFlagsRestrict(), and DescribeOneFlag() can be called
+// externally too, but there's little need for it.) These are all
+// declared in the main gflags.h header file.
+//
+// HandleCommandLineHelpFlags() will check what 'reporting' flags have
+// been defined, if any -- the "help" part of the function name is a
+// bit misleading -- and do the relevant reporting. It should be
+// called after all flag-values have been assigned, that is, after
+// parsing the command-line.
+
+#include <config.h>
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+#include <assert.h>
+#include <string>
+#include <vector>
+#include <gflags/gflags.h>
+#include <gflags/gflags_completions.h>
+#include "util.h"
+
+#ifndef PATH_SEPARATOR
+#define PATH_SEPARATOR '/'
+#endif
+
+// The 'reporting' flags. They all call gflags_exitfunc().
+DEFINE_bool(help, false,
+ "show help on all flags [tip: all flags can have two dashes]");
+DEFINE_bool(helpfull, false,
+ "show help on all flags -- same as -help");
+DEFINE_bool(helpshort, false,
+ "show help on only the main module for this program");
+DEFINE_string(helpon, "",
+ "show help on the modules named by this flag value");
+DEFINE_string(helpmatch, "",
+ "show help on modules whose name contains the specified substr");
+DEFINE_bool(helppackage, false,
+ "show help on all modules in the main package");
+DEFINE_bool(helpxml, false,
+ "produce an xml version of help");
+DEFINE_bool(version, false,
+ "show version and build info and exit");
+
+_START_GOOGLE_NAMESPACE_
+
+using std::string;
+using std::vector;
+
+
+// --------------------------------------------------------------------
+// DescribeOneFlag()
+// DescribeOneFlagInXML()
+// Routines that pretty-print info about a flag. These use
+// a CommandLineFlagInfo, which is the way the gflags
+// API exposes static info about a flag.
+// --------------------------------------------------------------------
+
+static const int kLineLength = 80;
+
+static void AddString(const string& s,
+ string* final_string, int* chars_in_line) {
+ const int slen = static_cast<int>(s.length());
+ if (*chars_in_line + 1 + slen >= kLineLength) { // < 80 chars/line
+ *final_string += "\n ";
+ *chars_in_line = 6;
+ } else {
+ *final_string += " ";
+ *chars_in_line += 1;
+ }
+ *final_string += s;
+ *chars_in_line += slen;
+}
+
+static string PrintStringFlagsWithQuotes(const CommandLineFlagInfo& flag,
+ const string& text, bool current) {
+ const char* c_string = (current ? flag.current_value.c_str() :
+ flag.default_value.c_str());
+ if (strcmp(flag.type.c_str(), "string") == 0) { // add quotes for strings
+ return StringPrintf("%s: \"%s\"", text.c_str(), c_string);
+ } else {
+ return StringPrintf("%s: %s", text.c_str(), c_string);
+ }
+}
+
+// Create a descriptive string for a flag.
+// Goes to some trouble to make pretty line breaks.
+string DescribeOneFlag(const CommandLineFlagInfo& flag) {
+ string main_part;
+ SStringPrintf(&main_part, " -%s (%s)",
+ flag.name.c_str(),
+ flag.description.c_str());
+ const char* c_string = main_part.c_str();
+ int chars_left = static_cast<int>(main_part.length());
+ string final_string = "";
+ int chars_in_line = 0; // how many chars in current line so far?
+ while (1) {
+ assert((size_t)chars_left == strlen(c_string)); // Unless there's a \0 in there?
+ const char* newline = strchr(c_string, '\n');
+ if (newline == NULL && chars_in_line+chars_left < kLineLength) {
+ // The whole remainder of the string fits on this line
+ final_string += c_string;
+ chars_in_line += chars_left;
+ break;
+ }
+ if (newline != NULL && newline - c_string < kLineLength - chars_in_line) {
+ int n = static_cast<int>(newline - c_string);
+ final_string.append(c_string, n);
+ chars_left -= n + 1;
+ c_string += n + 1;
+ } else {
+ // Find the last whitespace on this 80-char line
+ int whitespace = kLineLength-chars_in_line-1; // < 80 chars/line
+ while ( whitespace > 0 && !isspace(c_string[whitespace]) ) {
+ --whitespace;
+ }
+ if (whitespace <= 0) {
+ // Couldn't find any whitespace to make a line break. Just dump the
+ // rest out!
+ final_string += c_string;
+ chars_in_line = kLineLength; // next part gets its own line for sure!
+ break;
+ }
+ final_string += string(c_string, whitespace);
+ chars_in_line += whitespace;
+ while (isspace(c_string[whitespace])) ++whitespace;
+ c_string += whitespace;
+ chars_left -= whitespace;
+ }
+ if (*c_string == '\0')
+ break;
+ StringAppendF(&final_string, "\n ");
+ chars_in_line = 6;
+ }
+
+ // Append data type
+ AddString(string("type: ") + flag.type, &final_string, &chars_in_line);
+ // The listed default value will be the actual default from the flag
+ // definition in the originating source file, unless the value has
+ // subsequently been modified using SetCommandLineOptionWithMode() with mode
+ // SET_FLAGS_DEFAULT, or by setting FLAGS_foo = bar before ParseCommandLineFlags().
+ AddString(PrintStringFlagsWithQuotes(flag, "default", false), &final_string,
+ &chars_in_line);
+ if (!flag.is_default) {
+ AddString(PrintStringFlagsWithQuotes(flag, "currently", true),
+ &final_string, &chars_in_line);
+ }
+
+ StringAppendF(&final_string, "\n");
+ return final_string;
+}
+
+// Simple routine to xml-escape a string: escape & and < only.
+static string XMLText(const string& txt) {
+ string ans = txt;
+ for (string::size_type pos = 0; (pos = ans.find("&", pos)) != string::npos; )
+ ans.replace(pos++, 1, "&amp;");
+ for (string::size_type pos = 0; (pos = ans.find("<", pos)) != string::npos; )
+ ans.replace(pos++, 1, "&lt;");
+ return ans;
+}
+
+static void AddXMLTag(string* r, const char* tag, const string& txt) {
+ StringAppendF(r, "<%s>%s</%s>", tag, XMLText(txt).c_str(), tag);
+}
+
+
+static string DescribeOneFlagInXML(const CommandLineFlagInfo& flag) {
+ // The file and flagname could have been attributes, but default
+ // and meaning need to avoid attribute normalization. This way it
+ // can be parsed by simple programs, in addition to xml parsers.
+ string r("<flag>");
+ AddXMLTag(&r, "file", flag.filename);
+ AddXMLTag(&r, "name", flag.name);
+ AddXMLTag(&r, "meaning", flag.description);
+ AddXMLTag(&r, "default", flag.default_value);
+ AddXMLTag(&r, "current", flag.current_value);
+ AddXMLTag(&r, "type", flag.type);
+ r += "</flag>";
+ return r;
+}
+
+// --------------------------------------------------------------------
+// ShowUsageWithFlags()
+// ShowUsageWithFlagsRestrict()
+// ShowXMLOfFlags()
+// These routines variously expose the registry's list of flag
+// values. ShowUsage*() prints the flag-value information
+// to stdout in a user-readable format (that's what --help uses).
+// The Restrict() version limits what flags are shown.
+// ShowXMLOfFlags() prints the flag-value information to stdout
+// in a machine-readable format. In all cases, the flags are
+// sorted: first by filename they are defined in, then by flagname.
+// --------------------------------------------------------------------
+
+static const char* Basename(const char* filename) {
+ const char* sep = strrchr(filename, PATH_SEPARATOR);
+ return sep ? sep + 1 : filename;
+}
+
+static string Dirname(const string& filename) {
+ string::size_type sep = filename.rfind(PATH_SEPARATOR);
+ return filename.substr(0, (sep == string::npos) ? 0 : sep);
+}
+
+// Test whether a filename contains at least one of the substrings.
+static bool FileMatchesSubstring(const string& filename,
+ const vector<string>& substrings) {
+ for (vector<string>::const_iterator target = substrings.begin();
+ target != substrings.end();
+ ++target) {
+ if (strstr(filename.c_str(), target->c_str()) != NULL)
+ return true;
+ // If the substring starts with a '/', that means that we want
+ // the string to be at the beginning of a directory component.
+ // That should match the first directory component as well, so
+ // we allow '/foo' to match a filename of 'foo'.
+ if (!target->empty() && (*target)[0] == '/' &&
+ strncmp(filename.c_str(), target->c_str() + 1,
+ strlen(target->c_str() + 1)) == 0)
+ return true;
+ }
+ return false;
+}
+
+// Show help for every filename which matches any of the target substrings.
+// If substrings is empty, shows help for every file. If a flag's help message
+// has been stripped (e.g. by adding '#define STRIP_FLAG_HELP 1'
+// before including gflags/gflags.h), then this flag will not be displayed
+// by '--help' and its variants.
+static void ShowUsageWithFlagsMatching(const char *argv0,
+ const vector<string> &substrings) {
+ fprintf(stdout, "%s: %s\n", Basename(argv0), ProgramUsage());
+
+ vector<CommandLineFlagInfo> flags;
+ GetAllFlags(&flags); // flags are sorted by filename, then flagname
+
+ string last_filename; // so we know when we're at a new file
+ bool first_directory = true; // controls blank lines between dirs
+ bool found_match = false; // stays false iff no dir matches restrict
+ for (vector<CommandLineFlagInfo>::const_iterator flag = flags.begin();
+ flag != flags.end();
+ ++flag) {
+ if (substrings.empty() ||
+ FileMatchesSubstring(flag->filename, substrings)) {
+ // If the flag has been stripped, pretend that it doesn't exist.
+ if (flag->description == kStrippedFlagHelp) continue;
+ found_match = true; // this flag passed the match!
+ if (flag->filename != last_filename) { // new file
+ if (Dirname(flag->filename) != Dirname(last_filename)) { // new dir!
+ if (!first_directory)
+ fprintf(stdout, "\n\n"); // put blank lines between directories
+ first_directory = false;
+ }
+ fprintf(stdout, "\n Flags from %s:\n", flag->filename.c_str());
+ last_filename = flag->filename;
+ }
+ // Now print this flag
+ fprintf(stdout, "%s", DescribeOneFlag(*flag).c_str());
+ }
+ }
+ if (!found_match && !substrings.empty()) {
+ fprintf(stdout, "\n No modules matched: use -help\n");
+ }
+}
+
+void ShowUsageWithFlagsRestrict(const char *argv0, const char *restrict) {
+ vector<string> substrings;
+ if (restrict != NULL && *restrict != '\0') {
+ substrings.push_back(restrict);
+ }
+ ShowUsageWithFlagsMatching(argv0, substrings);
+}
+
+void ShowUsageWithFlags(const char *argv0) {
+ ShowUsageWithFlagsRestrict(argv0, "");
+}
+
+// Convert the help, program, and usage to xml.
+static void ShowXMLOfFlags(const char *prog_name) {
+ vector<CommandLineFlagInfo> flags;
+ GetAllFlags(&flags); // flags are sorted: by filename, then flagname
+
+ // XML. There is no corresponding schema yet
+ fprintf(stdout, "<?xml version=\"1.0\"?>\n");
+ // The document
+ fprintf(stdout, "<AllFlags>\n");
+ // the program name and usage
+ fprintf(stdout, "<program>%s</program>\n",
+ XMLText(Basename(prog_name)).c_str());
+ fprintf(stdout, "<usage>%s</usage>\n",
+ XMLText(ProgramUsage()).c_str());
+ // All the flags
+ for (vector<CommandLineFlagInfo>::const_iterator flag = flags.begin();
+ flag != flags.end();
+ ++flag) {
+ if (flag->description != kStrippedFlagHelp)
+ fprintf(stdout, "%s\n", DescribeOneFlagInXML(*flag).c_str());
+ }
+ // The end of the document
+ fprintf(stdout, "</AllFlags>\n");
+}
+
+// --------------------------------------------------------------------
+// ShowVersion()
+// Called upon --version. Prints build-related info.
+// --------------------------------------------------------------------
+
+static void ShowVersion() {
+ const char* version_string = VersionString();
+ if (version_string && *version_string) {
+ fprintf(stdout, "%s version %s\n",
+ ProgramInvocationShortName(), version_string);
+ } else {
+ fprintf(stdout, "%s\n", ProgramInvocationShortName());
+ }
+# if !defined(NDEBUG)
+ fprintf(stdout, "Debug build (NDEBUG not #defined)\n");
+# endif
+}
+
+static void AppendPrognameStrings(vector<string>* substrings,
+ const char* progname) {
+ string r("/");
+ r += progname;
+ substrings->push_back(r + ".");
+ substrings->push_back(r + "-main.");
+ substrings->push_back(r + "_main.");
+}
+
+// --------------------------------------------------------------------
+// HandleCommandLineHelpFlags()
+// Checks all the 'reporting' commandline flags to see if any
+// have been set. If so, handles them appropriately. Note
+// that all of them, by definition, cause the program to exit
+// if they trigger.
+// --------------------------------------------------------------------
+
+void HandleCommandLineHelpFlags() {
+ const char* progname = ProgramInvocationShortName();
+
+ HandleCommandLineCompletions();
+
+ vector<string> substrings;
+ AppendPrognameStrings(&substrings, progname);
+
+ if (FLAGS_helpshort) {
+ // show only flags related to this binary:
+ // E.g. for fileutil.cc, want flags containing ... "/fileutil." cc
+ ShowUsageWithFlagsMatching(progname, substrings);
+ gflags_exitfunc(1);
+
+ } else if (FLAGS_help || FLAGS_helpfull) {
+ // show all options
+ ShowUsageWithFlagsRestrict(progname, ""); // empty restrict
+ gflags_exitfunc(1);
+
+ } else if (!FLAGS_helpon.empty()) {
+ string restrict = "/" + FLAGS_helpon + ".";
+ ShowUsageWithFlagsRestrict(progname, restrict.c_str());
+ gflags_exitfunc(1);
+
+ } else if (!FLAGS_helpmatch.empty()) {
+ ShowUsageWithFlagsRestrict(progname, FLAGS_helpmatch.c_str());
+ gflags_exitfunc(1);
+
+ } else if (FLAGS_helppackage) {
+ // Shows help for all files in the same directory as main(). We
+ // don't want to resort to looking at dirname(progname), because
+ // the user can pick progname, and it may not relate to the file
+ // where main() resides. So instead, we search the flags for a
+ // filename like "/progname.cc", and take the dirname of that.
+ vector<CommandLineFlagInfo> flags;
+ GetAllFlags(&flags);
+ string last_package;
+ for (vector<CommandLineFlagInfo>::const_iterator flag = flags.begin();
+ flag != flags.end();
+ ++flag) {
+ if (!FileMatchesSubstring(flag->filename, substrings))
+ continue;
+ const string package = Dirname(flag->filename) + "/";
+ if (package != last_package) {
+ ShowUsageWithFlagsRestrict(progname, package.c_str());
+ VLOG(7) << "Found package: " << package;
+ if (!last_package.empty()) { // means this isn't our first pkg
+ LOG(WARNING) << "Multiple packages contain a file=" << progname;
+ }
+ last_package = package;
+ }
+ }
+ if (last_package.empty()) { // never found a package to print
+ LOG(WARNING) << "Unable to find a package for file=" << progname;
+ }
+ gflags_exitfunc(1);
+
+ } else if (FLAGS_helpxml) {
+ ShowXMLOfFlags(progname);
+ gflags_exitfunc(1);
+
+ } else if (FLAGS_version) {
+ ShowVersion();
+ // Unlike help, we may be asking for version in a script, so return 0
+ gflags_exitfunc(0);
+
+ }
+}
+
+_END_GOOGLE_NAMESPACE_
diff --git a/src/third_party/gflags-2.0/src/gflags_strip_flags_test.cc b/src/third_party/gflags-2.0/src/gflags_strip_flags_test.cc
new file mode 100755
index 00000000000..001ccd331ea
--- /dev/null
+++ b/src/third_party/gflags-2.0/src/gflags_strip_flags_test.cc
@@ -0,0 +1,61 @@
+// Copyright (c) 2011, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// ---
+// Author: csilvers@google.com (Craig Silverstein)
+//
+// A simple program that uses STRIP_FLAG_HELP. We'll have a shell
+// script that runs 'strings' over this program and makes sure
+// that the help string is not in there.
+
+#include "config_for_unittests.h"
+#define STRIP_FLAG_HELP 1
+#include <gflags/gflags.h>
+
+#include <stdio.h>
+
+using GOOGLE_NAMESPACE::SetUsageMessage;
+using GOOGLE_NAMESPACE::ParseCommandLineFlags;
+
+
+DEFINE_bool(test, true, "This text should be stripped out");
+
+int main(int argc, char** argv) {
+ SetUsageMessage("Usage message");
+ ParseCommandLineFlags(&argc, &argv, false);
+
+ // Unfortunately, for us, libtool can replace executables with a shell
+ // script that does some work before calling the 'real' executable
+ // under a different name. We need the 'real' executable name to run
+ // 'strings' on it, so we construct this binary to print the real
+ // name (argv[0]) on stdout when run.
+ puts(argv[0]);
+
+ return 0;
+}
diff --git a/src/third_party/gflags-2.0/src/gflags_strip_flags_test.sh b/src/third_party/gflags-2.0/src/gflags_strip_flags_test.sh
new file mode 100755
index 00000000000..9ebb4570a78
--- /dev/null
+++ b/src/third_party/gflags-2.0/src/gflags_strip_flags_test.sh
@@ -0,0 +1,80 @@
+#!/bin/sh
+#
+# Copyright (c) 2011, Google Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+# * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+# ---
+# Author: csilvers@google.com (Craig Silverstein)
+
+if [ -z "$1" ]; then
+ echo "USAGE: $0 <unittest exe>"
+ exit 1
+fi
+BINARY="$1"
+
+# Make sure the binary exists...
+if ! "$BINARY" >/dev/null 2>/dev/null
+then
+ echo "Cannot run binary $BINARY"
+ exit 1
+fi
+
+# Make sure the --help output doesn't print the stripped text.
+if "$BINARY" --help | grep "This text should be stripped out" >/dev/null 2>&1
+then
+ echo "Text not stripped from --help like it should be: $BINARY"
+ exit 1
+fi
+
+# Make sure the stripped text isn't in the binary at all.
+if strings --help >/dev/null 2>&1 # make sure the binary exists
+then
+ # Unfortunately, for us, libtool can replace executables with a
+ # shell script that does some work before calling the 'real'
+ # executable under a different name. We need the 'real'
+ # executable name to run 'strings' on it, so we construct this
+ # binary to print the real name (argv[0]) on stdout when run.
+ REAL_BINARY=`"$BINARY"`
+ # On cygwin, we may need to add a '.exe' extension by hand.
+ [ -f "$REAL_BINARY.exe" ] && REAL_BINARY="$REAL_BINARY.exe"
+ if strings "$REAL_BINARY" | grep "This text should be stripped" >/dev/null 2>&1
+ then
+ echo "Text not stripped from binary like it should be: $BINARY"
+ exit 1
+ fi
+
+ # Let's also do a sanity check to make sure strings is working properly
+ if ! strings "$REAL_BINARY" | grep "Usage message" >/dev/null 2>&1
+ then
+ echo "Usage text not found in binary like it should be: $BINARY"
+ exit 1
+ fi
+fi
+
+echo "PASS"
diff --git a/src/third_party/gflags-2.0/src/gflags_unittest.cc b/src/third_party/gflags-2.0/src/gflags_unittest.cc
new file mode 100755
index 00000000000..08abc1b72db
--- /dev/null
+++ b/src/third_party/gflags-2.0/src/gflags_unittest.cc
@@ -0,0 +1,1539 @@
+// Copyright (c) 2005, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// ---
+//
+// For now, this unit test does not cover all features of
+// gflags.cc
+
+#include "config_for_unittests.h"
+#include <gflags/gflags.h>
+
+#include <math.h> // for isinf() and isnan()
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif // for unlink()
+#include <vector>
+#include <string>
+#include "util.h"
+TEST_INIT
+EXPECT_DEATH_INIT
+
+// I don't actually use this header file, but #include it under the
+// old location to make sure that the include-header-forwarding
+// works. But don't bother on windows; the windows port is so new
+// it never had the old location-names.
+#ifndef _MSC_VER
+#include <google/gflags_completions.h>
+void (*unused_fn)() = &GOOGLE_NAMESPACE::HandleCommandLineCompletions;
+#endif
+
+using std::string;
+using std::vector;
+using GOOGLE_NAMESPACE::int32;
+using GOOGLE_NAMESPACE::FlagRegisterer;
+using GOOGLE_NAMESPACE::StringFromEnv;
+using GOOGLE_NAMESPACE::RegisterFlagValidator;
+using GOOGLE_NAMESPACE::CommandLineFlagInfo;
+using GOOGLE_NAMESPACE::GetAllFlags;
+
+DEFINE_string(test_tmpdir, "/tmp/gflags_unittest", "Dir we use for temp files");
+#ifdef _MSC_VER // in MSVC, we run from the vsprojects directory
+DEFINE_string(srcdir, "..\\..",
+ "Source-dir root, needed to find gflags_unittest_flagfile");
+#else
+DEFINE_string(srcdir, StringFromEnv("SRCDIR", "."),
+ "Source-dir root, needed to find gflags_unittest_flagfile");
+#endif
+
+DECLARE_string(tryfromenv); // in gflags.cc
+
+DEFINE_bool(test_bool, false, "tests bool-ness");
+DEFINE_int32(test_int32, -1, "");
+DEFINE_int64(test_int64, -2, "");
+DEFINE_uint64(test_uint64, 2, "");
+DEFINE_double(test_double, -1.0, "");
+DEFINE_string(test_string, "initial", "");
+
+//
+// The below ugliness gets some additional code coverage in the -helpxml
+// and -helpmatch test cases having to do with string lengths and formatting
+//
+DEFINE_bool(test_bool_with_quite_quite_quite_quite_quite_quite_quite_quite_quite_quite_quite_quite_quite_quite_long_name,
+ false,
+ "extremely_extremely_extremely_extremely_extremely_extremely_extremely_extremely_long_meaning");
+
+DEFINE_string(test_str1, "initial", "");
+DEFINE_string(test_str2, "initial", "");
+DEFINE_string(test_str3, "initial", "");
+
+// This is used to test setting tryfromenv manually
+DEFINE_string(test_tryfromenv, "initial", "");
+
+// Don't try this at home!
+static int changeable_var = 12;
+DEFINE_int32(changeable_var, ++changeable_var, "");
+
+static int changeable_bool_var = 8008;
+DEFINE_bool(changeable_bool_var, ++changeable_bool_var == 8009, "");
+
+static int changeable_string_var = 0;
+static string ChangeableString() {
+ char r[] = {static_cast<char>('0' + ++changeable_string_var), '\0'};
+ return r;
+}
+DEFINE_string(changeable_string_var, ChangeableString(), "");
+
+// These are never used in this unittest, but can be used by
+// gflags_unittest.sh when it needs to specify flags
+// that are legal for gflags_unittest but don't need to
+// be a particular value.
+DEFINE_bool(unused_bool, true, "unused bool-ness");
+DEFINE_int32(unused_int32, -1001, "");
+DEFINE_int64(unused_int64, -2001, "");
+DEFINE_uint64(unused_uint64, 2000, "");
+DEFINE_double(unused_double, -1000.0, "");
+DEFINE_string(unused_string, "unused", "");
+
+// These flags are used by gflags_unittest.sh
+DEFINE_bool(changed_bool1, false, "changed");
+DEFINE_bool(changed_bool2, false, "changed");
+DEFINE_bool(long_helpstring, false,
+ "This helpstring goes on forever and ever and ever and ever and "
+ "ever and ever and ever and ever and ever and ever and ever and "
+ "ever and ever and ever and ever and ever and ever and ever and "
+ "ever and ever and ever and ever and ever and ever and ever and "
+ "ever and ever and ever and ever and ever and ever and ever and "
+ "ever and ever and ever and ever and ever and ever and ever and "
+ "ever and ever and ever and ever and ever and ever and ever and "
+ "ever and ever and ever and ever and ever and ever and ever and "
+ "ever and ever and ever and ever and ever and ever and ever and "
+ "ever and ever and ever and ever and ever and ever and ever and "
+ "ever. This is the end of a long helpstring");
+
+
+static bool AlwaysFail(const char* flag, bool value) { return value == false; }
+DEFINE_bool(always_fail, false, "will fail to validate when you set it");
+namespace {
+bool dummy = RegisterFlagValidator(&FLAGS_always_fail, AlwaysFail);
+}
+
+// See the comment by GetAllFlags in gflags.h
+static bool DeadlockIfCantLockInValidators(const char* flag, bool value) {
+ if (!value) {
+ return true;
+ }
+ vector<CommandLineFlagInfo> dummy;
+ GetAllFlags(&dummy);
+ return true;
+}
+DEFINE_bool(deadlock_if_cant_lock,
+ false,
+ "will deadlock if set to true and "
+ "if locking of registry in validators fails.");
+namespace {
+bool dummy1 = RegisterFlagValidator(&FLAGS_deadlock_if_cant_lock,
+ DeadlockIfCantLockInValidators);
+}
+
+#define MAKEFLAG(x) DEFINE_int32(test_flag_num##x, x, "Test flag")
+
+// Define 10 flags
+#define MAKEFLAG10(x) \
+ MAKEFLAG(x##0); \
+ MAKEFLAG(x##1); \
+ MAKEFLAG(x##2); \
+ MAKEFLAG(x##3); \
+ MAKEFLAG(x##4); \
+ MAKEFLAG(x##5); \
+ MAKEFLAG(x##6); \
+ MAKEFLAG(x##7); \
+ MAKEFLAG(x##8); \
+ MAKEFLAG(x##9)
+
+// Define 100 flags
+#define MAKEFLAG100(x) \
+ MAKEFLAG10(x##0); \
+ MAKEFLAG10(x##1); \
+ MAKEFLAG10(x##2); \
+ MAKEFLAG10(x##3); \
+ MAKEFLAG10(x##4); \
+ MAKEFLAG10(x##5); \
+ MAKEFLAG10(x##6); \
+ MAKEFLAG10(x##7); \
+ MAKEFLAG10(x##8); \
+ MAKEFLAG10(x##9)
+
+// Define a bunch of command-line flags. Each occurrence of the MAKEFLAG100
+// macro defines 100 integer flags. This lets us test the effect of having
+// many flags on startup time.
+MAKEFLAG100(1);
+MAKEFLAG100(2);
+MAKEFLAG100(3);
+MAKEFLAG100(4);
+MAKEFLAG100(5);
+MAKEFLAG100(6);
+MAKEFLAG100(7);
+MAKEFLAG100(8);
+MAKEFLAG100(9);
+MAKEFLAG100(10);
+MAKEFLAG100(11);
+MAKEFLAG100(12);
+MAKEFLAG100(13);
+MAKEFLAG100(14);
+MAKEFLAG100(15);
+
+#undef MAKEFLAG100
+#undef MAKEFLAG10
+#undef MAKEFLAG
+
+// This is a pseudo-flag -- we want to register a flag with a filename
+// at the top level, but there is no way to do this except by faking
+// the filename.
+namespace fLI {
+ static const int32 FLAGS_nonotldflag1 = 12;
+ int32 FLAGS_tldflag1 = FLAGS_nonotldflag1;
+ int32 FLAGS_notldflag1 = FLAGS_nonotldflag1;
+ static FlagRegisterer o_tldflag1(
+ "tldflag1", "int32",
+ "should show up in --helpshort", "gflags_unittest.cc",
+ &FLAGS_tldflag1, &FLAGS_notldflag1);
+}
+using fLI::FLAGS_tldflag1;
+
+namespace fLI {
+ static const int32 FLAGS_nonotldflag2 = 23;
+ int32 FLAGS_tldflag2 = FLAGS_nonotldflag2;
+ int32 FLAGS_notldflag2 = FLAGS_nonotldflag2;
+ static FlagRegisterer o_tldflag2(
+ "tldflag2", "int32",
+ "should show up in --helpshort", "gflags_unittest.",
+ &FLAGS_tldflag2, &FLAGS_notldflag2);
+}
+using fLI::FLAGS_tldflag2;
+
+_START_GOOGLE_NAMESPACE_
+
+namespace {
+
+
+static string TmpFile(const string& basename) {
+#ifdef _MSC_VER
+ return FLAGS_test_tmpdir + "\\" + basename;
+#else
+ return FLAGS_test_tmpdir + "/" + basename;
+#endif
+}
+
+// Returns the definition of the --flagfile flag to be used in the tests.
+// Must be called after ParseCommandLineFlags().
+static const char* GetFlagFileFlag() {
+#ifdef _MSC_VER
+ static const string flagfile = FLAGS_srcdir + "\\src\\gflags_unittest_flagfile";
+#else
+ static const string flagfile = FLAGS_srcdir + "/src/gflags_unittest_flagfile";
+#endif
+ static const string flagfile_flag = string("--flagfile=") + flagfile;
+ return flagfile_flag.c_str();
+}
+
+
+// Defining a variable of type CompileAssertTypesEqual<T1, T2> will cause a
+// compiler error iff T1 and T2 are different types.
+template <typename T1, typename T2>
+struct CompileAssertTypesEqual;
+
+template <typename T>
+struct CompileAssertTypesEqual<T, T> {
+};
+
+
+template <typename Expected, typename Actual>
+void AssertIsType(Actual& x) {
+ CompileAssertTypesEqual<Expected, Actual>();
+}
+
+// Verify all the flags are the right type.
+TEST(FlagTypes, FlagTypes) {
+ AssertIsType<bool>(FLAGS_test_bool);
+ AssertIsType<int32>(FLAGS_test_int32);
+ AssertIsType<int64>(FLAGS_test_int64);
+ AssertIsType<uint64>(FLAGS_test_uint64);
+ AssertIsType<double>(FLAGS_test_double);
+ AssertIsType<string>(FLAGS_test_string);
+}
+
+#ifdef GTEST_HAS_DEATH_TEST
+// Death tests for "help" options.
+//
+// The help system automatically calls gflags_exitfunc(1) when you specify any of
+// the help-related flags ("-helpmatch", "-helpxml") so we can't test
+// those mainline.
+
+// Tests that "-helpmatch" causes the process to die.
+TEST(ReadFlagsFromStringDeathTest, HelpMatch) {
+ EXPECT_DEATH(ReadFlagsFromString("-helpmatch=base", GetArgv0(), true),
+ "");
+}
+
+
+// Tests that "-helpxml" causes the process to die.
+TEST(ReadFlagsFromStringDeathTest, HelpXml) {
+ EXPECT_DEATH(ReadFlagsFromString("-helpxml", GetArgv0(), true),
+ "");
+}
+#endif
+
+
+// A subroutine needed for testing reading flags from a string.
+void TestFlagString(const string& flags,
+ const string& expected_string,
+ bool expected_bool,
+ int32 expected_int32,
+ double expected_double) {
+ EXPECT_TRUE(ReadFlagsFromString(flags,
+ GetArgv0(),
+ // errors are fatal
+ true));
+
+ EXPECT_EQ(expected_string, FLAGS_test_string);
+ EXPECT_EQ(expected_bool, FLAGS_test_bool);
+ EXPECT_EQ(expected_int32, FLAGS_test_int32);
+ EXPECT_DOUBLE_EQ(expected_double, FLAGS_test_double);
+}
+
+
+// Tests reading flags from a string.
+TEST(FlagFileTest, ReadFlagsFromString) {
+ TestFlagString(
+ // Flag string
+ "-test_string=continued\n"
+ "# some comments are in order\n"
+ "# some\n"
+ " # comments\n"
+ "#are\n"
+ " #trickier\n"
+ "# than others\n"
+ "-test_bool=true\n"
+ " -test_int32=1\n"
+ "-test_double=0.0\n",
+ // Expected values
+ "continued",
+ true,
+ 1,
+ 0.0);
+
+ TestFlagString(
+ // Flag string
+ "# let's make sure it can update values\n"
+ "-test_string=initial\n"
+ "-test_bool=false\n"
+ "-test_int32=123\n"
+ "-test_double=123.0\n",
+ // Expected values
+ "initial",
+ false,
+ 123,
+ 123.0);
+}
+
+// Tests the filename part of the flagfile
+TEST(FlagFileTest, FilenamesOurfileLast) {
+ FLAGS_test_string = "initial";
+ FLAGS_test_bool = false;
+ FLAGS_test_int32 = -1;
+ FLAGS_test_double = -1.0;
+ TestFlagString(
+ // Flag string
+ "-test_string=continued\n"
+ "# some comments are in order\n"
+ "# some\n"
+ " # comments\n"
+ "#are\n"
+ " #trickier\n"
+ "# than others\n"
+ "not_our_filename\n"
+ "-test_bool=true\n"
+ " -test_int32=1\n"
+ "gflags_unittest\n"
+ "-test_double=1000.0\n",
+ // Expected values
+ "continued",
+ false,
+ -1,
+ 1000.0);
+}
+
+TEST(FlagFileTest, FilenamesOurfileFirst) {
+ FLAGS_test_string = "initial";
+ FLAGS_test_bool = false;
+ FLAGS_test_int32 = -1;
+ FLAGS_test_double = -1.0;
+ TestFlagString(
+ // Flag string
+ "-test_string=continued\n"
+ "# some comments are in order\n"
+ "# some\n"
+ " # comments\n"
+ "#are\n"
+ " #trickier\n"
+ "# than others\n"
+ "gflags_unittest\n"
+ "-test_bool=true\n"
+ " -test_int32=1\n"
+ "not_our_filename\n"
+ "-test_double=1000.0\n",
+ // Expected values
+ "continued",
+ true,
+ 1,
+ -1.0);
+}
+
+#ifdef HAVE_FNMATCH_H // otherwise glob isn't supported
+TEST(FlagFileTest, FilenamesOurfileGlob) {
+ FLAGS_test_string = "initial";
+ FLAGS_test_bool = false;
+ FLAGS_test_int32 = -1;
+ FLAGS_test_double = -1.0;
+ TestFlagString(
+ // Flag string
+ "-test_string=continued\n"
+ "# some comments are in order\n"
+ "# some\n"
+ " # comments\n"
+ "#are\n"
+ " #trickier\n"
+ "# than others\n"
+ "*flags*\n"
+ "-test_bool=true\n"
+ " -test_int32=1\n"
+ "flags\n"
+ "-test_double=1000.0\n",
+ // Expected values
+ "continued",
+ true,
+ 1,
+ -1.0);
+}
+
+TEST(FlagFileTest, FilenamesOurfileInBigList) {
+ FLAGS_test_string = "initial";
+ FLAGS_test_bool = false;
+ FLAGS_test_int32 = -1;
+ FLAGS_test_double = -1.0;
+ TestFlagString(
+ // Flag string
+ "-test_string=continued\n"
+ "# some comments are in order\n"
+ "# some\n"
+ " # comments\n"
+ "#are\n"
+ " #trickier\n"
+ "# than others\n"
+ "*first* *flags* *third*\n"
+ "-test_bool=true\n"
+ " -test_int32=1\n"
+ "flags\n"
+ "-test_double=1000.0\n",
+ // Expected values
+ "continued",
+ true,
+ 1,
+ -1.0);
+}
+#endif // ifdef HAVE_FNMATCH_H
+
+// Tests that a failed flag-from-string read keeps flags at default values
+TEST(FlagFileTest, FailReadFlagsFromString) {
+ FLAGS_test_int32 = 119;
+ string flags("# let's make sure it can update values\n"
+ "-test_string=non_initial\n"
+ "-test_bool=false\n"
+ "-test_int32=123\n"
+ "-test_double=illegal\n");
+
+ EXPECT_FALSE(ReadFlagsFromString(flags,
+ GetArgv0(),
+ // errors are fatal
+ false));
+
+ EXPECT_EQ(119, FLAGS_test_int32);
+ EXPECT_EQ("initial", FLAGS_test_string);
+}
+
+// Tests that flags can be set to ordinary values.
+TEST(SetFlagValueTest, OrdinaryValues) {
+ EXPECT_EQ("initial", FLAGS_test_str1);
+
+ SetCommandLineOptionWithMode("test_str1", "second", SET_FLAG_IF_DEFAULT);
+ EXPECT_EQ("second", FLAGS_test_str1); // set; was default
+
+ SetCommandLineOptionWithMode("test_str1", "third", SET_FLAG_IF_DEFAULT);
+ EXPECT_EQ("second", FLAGS_test_str1); // already set once
+
+ FLAGS_test_str1 = "initial";
+ SetCommandLineOptionWithMode("test_str1", "third", SET_FLAG_IF_DEFAULT);
+ EXPECT_EQ("initial", FLAGS_test_str1); // still already set before
+
+ SetCommandLineOptionWithMode("test_str1", "third", SET_FLAGS_VALUE);
+ EXPECT_EQ("third", FLAGS_test_str1); // changed value
+
+ SetCommandLineOptionWithMode("test_str1", "fourth", SET_FLAGS_DEFAULT);
+ EXPECT_EQ("third", FLAGS_test_str1);
+ // value not changed (already set before)
+
+ EXPECT_EQ("initial", FLAGS_test_str2);
+
+ SetCommandLineOptionWithMode("test_str2", "second", SET_FLAGS_DEFAULT);
+ EXPECT_EQ("second", FLAGS_test_str2); // changed (was default)
+
+ FLAGS_test_str2 = "extra";
+ EXPECT_EQ("extra", FLAGS_test_str2);
+
+ FLAGS_test_str2 = "second";
+ SetCommandLineOptionWithMode("test_str2", "third", SET_FLAGS_DEFAULT);
+ EXPECT_EQ("third", FLAGS_test_str2); // still changed (was equal to default)
+
+ SetCommandLineOptionWithMode("test_str2", "fourth", SET_FLAG_IF_DEFAULT);
+ EXPECT_EQ("fourth", FLAGS_test_str2); // changed (was default)
+
+ EXPECT_EQ("initial", FLAGS_test_str3);
+
+ SetCommandLineOptionWithMode("test_str3", "second", SET_FLAGS_DEFAULT);
+ EXPECT_EQ("second", FLAGS_test_str3); // changed
+
+ FLAGS_test_str3 = "third";
+ SetCommandLineOptionWithMode("test_str3", "fourth", SET_FLAGS_DEFAULT);
+ EXPECT_EQ("third", FLAGS_test_str3); // not changed (was set)
+
+ SetCommandLineOptionWithMode("test_str3", "fourth", SET_FLAG_IF_DEFAULT);
+ EXPECT_EQ("third", FLAGS_test_str3); // not changed (was set)
+
+ SetCommandLineOptionWithMode("test_str3", "fourth", SET_FLAGS_VALUE);
+ EXPECT_EQ("fourth", FLAGS_test_str3); // changed value
+}
+
+
+// Tests that flags can be set to exceptional values.
+// Note: apparently MINGW doesn't parse inf and nan correctly:
+// http://www.mail-archive.com/bug-gnulib@gnu.org/msg09573.html
+// This url says FreeBSD also has a problem, but I didn't see that.
+TEST(SetFlagValueTest, ExceptionalValues) {
+#if defined(isinf) && !defined(__MINGW32__)
+ EXPECT_EQ("test_double set to inf\n",
+ SetCommandLineOption("test_double", "inf"));
+ EXPECT_INF(FLAGS_test_double);
+
+ EXPECT_EQ("test_double set to inf\n",
+ SetCommandLineOption("test_double", "INF"));
+ EXPECT_INF(FLAGS_test_double);
+#endif
+
+ // set some bad values
+ EXPECT_EQ("",
+ SetCommandLineOption("test_double", "0.1xxx"));
+ EXPECT_EQ("",
+ SetCommandLineOption("test_double", " "));
+ EXPECT_EQ("",
+ SetCommandLineOption("test_double", ""));
+#if defined(isinf) && !defined(__MINGW32__)
+ EXPECT_EQ("test_double set to -inf\n",
+ SetCommandLineOption("test_double", "-inf"));
+ EXPECT_INF(FLAGS_test_double);
+ EXPECT_GT(0, FLAGS_test_double);
+#endif
+
+#if defined(isnan) && !defined(__MINGW32__)
+ EXPECT_EQ("test_double set to nan\n",
+ SetCommandLineOption("test_double", "NaN"));
+ EXPECT_NAN(FLAGS_test_double);
+#endif
+}
+
+// Tests that integer flags can be specified in many ways
+TEST(SetFlagValueTest, DifferentRadices) {
+ EXPECT_EQ("test_int32 set to 12\n",
+ SetCommandLineOption("test_int32", "12"));
+
+ EXPECT_EQ("test_int32 set to 16\n",
+ SetCommandLineOption("test_int32", "0x10"));
+
+ EXPECT_EQ("test_int32 set to 34\n",
+ SetCommandLineOption("test_int32", "0X22"));
+
+ // Leading 0 is *not* octal; it's still decimal
+ EXPECT_EQ("test_int32 set to 10\n",
+ SetCommandLineOption("test_int32", "010"));
+}
+
+// Tests what happens when you try to set a flag to an illegal value
+TEST(SetFlagValueTest, IllegalValues) {
+ FLAGS_test_bool = true;
+ FLAGS_test_int32 = 119;
+ FLAGS_test_int64 = 1191;
+ FLAGS_test_uint64 = 11911;
+
+ EXPECT_EQ("",
+ SetCommandLineOption("test_bool", "12"));
+
+ EXPECT_EQ("",
+ SetCommandLineOption("test_int32", "7000000000000"));
+
+ // TODO(csilvers): uncomment this when we disallow negative numbers for uint64
+#if 0
+ EXPECT_EQ("",
+ SetCommandLineOption("test_uint64", "-1"));
+#endif
+
+ EXPECT_EQ("",
+ SetCommandLineOption("test_int64", "not a number!"));
+
+ // Test the empty string with each type of input
+ EXPECT_EQ("", SetCommandLineOption("test_bool", ""));
+ EXPECT_EQ("", SetCommandLineOption("test_int32", ""));
+ EXPECT_EQ("", SetCommandLineOption("test_int64", ""));
+ EXPECT_EQ("", SetCommandLineOption("test_uint64", ""));
+ EXPECT_EQ("", SetCommandLineOption("test_double", ""));
+ EXPECT_EQ("test_string set to \n", SetCommandLineOption("test_string", ""));
+
+ EXPECT_TRUE(FLAGS_test_bool);
+ EXPECT_EQ(119, FLAGS_test_int32);
+ EXPECT_EQ(1191, FLAGS_test_int64);
+ EXPECT_EQ(11911, FLAGS_test_uint64);
+}
+
+
+// Tests that we only evaluate macro args once
+TEST(MacroArgs, EvaluateOnce) {
+ EXPECT_EQ(13, FLAGS_changeable_var);
+ // Make sure we don't ++ the value somehow, when evaluating the flag.
+ EXPECT_EQ(13, FLAGS_changeable_var);
+ // Make sure the macro only evaluated this var once.
+ EXPECT_EQ(13, changeable_var);
+ // Make sure the actual value and default value are the same
+ SetCommandLineOptionWithMode("changeable_var", "21", SET_FLAG_IF_DEFAULT);
+ EXPECT_EQ(21, FLAGS_changeable_var);
+}
+
+TEST(MacroArgs, EvaluateOnceBool) {
+ EXPECT_TRUE(FLAGS_changeable_bool_var);
+ EXPECT_TRUE(FLAGS_changeable_bool_var);
+ EXPECT_EQ(8009, changeable_bool_var);
+ SetCommandLineOptionWithMode("changeable_bool_var", "false",
+ SET_FLAG_IF_DEFAULT);
+ EXPECT_FALSE(FLAGS_changeable_bool_var);
+}
+
+TEST(MacroArgs, EvaluateOnceStrings) {
+ EXPECT_EQ("1", FLAGS_changeable_string_var);
+ EXPECT_EQ("1", FLAGS_changeable_string_var);
+ EXPECT_EQ(1, changeable_string_var);
+ SetCommandLineOptionWithMode("changeable_string_var", "different",
+ SET_FLAG_IF_DEFAULT);
+ EXPECT_EQ("different", FLAGS_changeable_string_var);
+}
+
+// Tests that the FooFromEnv does the right thing
+TEST(FromEnvTest, LegalValues) {
+ setenv("BOOL_VAL1", "true", 1);
+ setenv("BOOL_VAL2", "false", 1);
+ setenv("BOOL_VAL3", "1", 1);
+ setenv("BOOL_VAL4", "F", 1);
+ EXPECT_TRUE(BoolFromEnv("BOOL_VAL1", false));
+ EXPECT_FALSE(BoolFromEnv("BOOL_VAL2", true));
+ EXPECT_TRUE(BoolFromEnv("BOOL_VAL3", false));
+ EXPECT_FALSE(BoolFromEnv("BOOL_VAL4", true));
+ EXPECT_TRUE(BoolFromEnv("BOOL_VAL_UNKNOWN", true));
+ EXPECT_FALSE(BoolFromEnv("BOOL_VAL_UNKNOWN", false));
+
+ setenv("INT_VAL1", "1", 1);
+ setenv("INT_VAL2", "-1", 1);
+ EXPECT_EQ(1, Int32FromEnv("INT_VAL1", 10));
+ EXPECT_EQ(-1, Int32FromEnv("INT_VAL2", 10));
+ EXPECT_EQ(10, Int32FromEnv("INT_VAL_UNKNOWN", 10));
+
+ setenv("INT_VAL3", "1099511627776", 1);
+ EXPECT_EQ(1, Int64FromEnv("INT_VAL1", 20));
+ EXPECT_EQ(-1, Int64FromEnv("INT_VAL2", 20));
+ EXPECT_EQ(1099511627776LL, Int64FromEnv("INT_VAL3", 20));
+ EXPECT_EQ(20, Int64FromEnv("INT_VAL_UNKNOWN", 20));
+
+ EXPECT_EQ(1, Uint64FromEnv("INT_VAL1", 30));
+ EXPECT_EQ(1099511627776ULL, Uint64FromEnv("INT_VAL3", 30));
+ EXPECT_EQ(30, Uint64FromEnv("INT_VAL_UNKNOWN", 30));
+
+ // I pick values here that can be easily represented exactly in floating-point
+ setenv("DOUBLE_VAL1", "0.0", 1);
+ setenv("DOUBLE_VAL2", "1.0", 1);
+ setenv("DOUBLE_VAL3", "-1.0", 1);
+ EXPECT_EQ(0.0, DoubleFromEnv("DOUBLE_VAL1", 40.0));
+ EXPECT_EQ(1.0, DoubleFromEnv("DOUBLE_VAL2", 40.0));
+ EXPECT_EQ(-1.0, DoubleFromEnv("DOUBLE_VAL3", 40.0));
+ EXPECT_EQ(40.0, DoubleFromEnv("DOUBLE_VAL_UNKNOWN", 40.0));
+
+ setenv("STRING_VAL1", "", 1);
+ setenv("STRING_VAL2", "my happy string!", 1);
+ EXPECT_STREQ("", StringFromEnv("STRING_VAL1", "unknown"));
+ EXPECT_STREQ("my happy string!", StringFromEnv("STRING_VAL2", "unknown"));
+ EXPECT_STREQ("unknown", StringFromEnv("STRING_VAL_UNKNOWN", "unknown"));
+}
+
+#ifdef GTEST_HAS_DEATH_TEST
+// Tests that the FooFromEnv dies on parse-error
+TEST(FromEnvDeathTest, IllegalValues) {
+ setenv("BOOL_BAD1", "so true!", 1);
+ setenv("BOOL_BAD2", "", 1);
+ EXPECT_DEATH(BoolFromEnv("BOOL_BAD1", false), "error parsing env variable");
+ EXPECT_DEATH(BoolFromEnv("BOOL_BAD2", true), "error parsing env variable");
+
+ setenv("INT_BAD1", "one", 1);
+ setenv("INT_BAD2", "100000000000000000", 1);
+ setenv("INT_BAD3", "0xx10", 1);
+ setenv("INT_BAD4", "", 1);
+ EXPECT_DEATH(Int32FromEnv("INT_BAD1", 10), "error parsing env variable");
+ EXPECT_DEATH(Int32FromEnv("INT_BAD2", 10), "error parsing env variable");
+ EXPECT_DEATH(Int32FromEnv("INT_BAD3", 10), "error parsing env variable");
+ EXPECT_DEATH(Int32FromEnv("INT_BAD4", 10), "error parsing env variable");
+
+ setenv("BIGINT_BAD1", "18446744073709551616000", 1);
+ EXPECT_DEATH(Int64FromEnv("INT_BAD1", 20), "error parsing env variable");
+ EXPECT_DEATH(Int64FromEnv("INT_BAD3", 20), "error parsing env variable");
+ EXPECT_DEATH(Int64FromEnv("INT_BAD4", 20), "error parsing env variable");
+ EXPECT_DEATH(Int64FromEnv("BIGINT_BAD1", 200), "error parsing env variable");
+
+ setenv("BIGINT_BAD2", "-1", 1);
+ EXPECT_DEATH(Uint64FromEnv("INT_BAD1", 30), "error parsing env variable");
+ EXPECT_DEATH(Uint64FromEnv("INT_BAD3", 30), "error parsing env variable");
+ EXPECT_DEATH(Uint64FromEnv("INT_BAD4", 30), "error parsing env variable");
+ EXPECT_DEATH(Uint64FromEnv("BIGINT_BAD1", 30), "error parsing env variable");
+ // TODO(csilvers): uncomment this when we disallow negative numbers for uint64
+#if 0
+ EXPECT_DEATH(Uint64FromEnv("BIGINT_BAD2", 30), "error parsing env variable");
+#endif
+
+ setenv("DOUBLE_BAD1", "0.0.0", 1);
+ setenv("DOUBLE_BAD2", "", 1);
+ EXPECT_DEATH(DoubleFromEnv("DOUBLE_BAD1", 40.0), "error parsing env variable");
+ EXPECT_DEATH(DoubleFromEnv("DOUBLE_BAD2", 40.0), "error parsing env variable");
+}
+#endif
+
+
+// Tests that FlagSaver can save the states of string flags.
+TEST(FlagSaverTest, CanSaveStringFlagStates) {
+ // 1. Initializes the flags.
+
+ // State of flag test_str1:
+ // default value - "initial"
+ // current value - "initial"
+ // not set - true
+
+ SetCommandLineOptionWithMode("test_str2", "second", SET_FLAGS_VALUE);
+ // State of flag test_str2:
+ // default value - "initial"
+ // current value - "second"
+ // not set - false
+
+ SetCommandLineOptionWithMode("test_str3", "second", SET_FLAGS_DEFAULT);
+ // State of flag test_str3:
+ // default value - "second"
+ // current value - "second"
+ // not set - true
+
+ // 2. Saves the flag states.
+
+ {
+ FlagSaver fs;
+
+ // 3. Modifies the flag states.
+
+ SetCommandLineOptionWithMode("test_str1", "second", SET_FLAGS_VALUE);
+ EXPECT_EQ("second", FLAGS_test_str1);
+ // State of flag test_str1:
+ // default value - "second"
+ // current value - "second"
+ // not set - true
+
+ SetCommandLineOptionWithMode("test_str2", "third", SET_FLAGS_DEFAULT);
+ EXPECT_EQ("second", FLAGS_test_str2);
+ // State of flag test_str2:
+ // default value - "third"
+ // current value - "second"
+ // not set - false
+
+ SetCommandLineOptionWithMode("test_str3", "third", SET_FLAGS_VALUE);
+ EXPECT_EQ("third", FLAGS_test_str3);
+ // State of flag test_str1:
+ // default value - "second"
+ // current value - "third"
+ // not set - false
+
+ // 4. Restores the flag states.
+ }
+
+ // 5. Verifies that the states were restored.
+
+ // Verifies that the value of test_str1 was restored.
+ EXPECT_EQ("initial", FLAGS_test_str1);
+ // Verifies that the "not set" attribute of test_str1 was restored to true.
+ SetCommandLineOptionWithMode("test_str1", "second", SET_FLAG_IF_DEFAULT);
+ EXPECT_EQ("second", FLAGS_test_str1);
+
+ // Verifies that the value of test_str2 was restored.
+ EXPECT_EQ("second", FLAGS_test_str2);
+ // Verifies that the "not set" attribute of test_str2 was restored to false.
+ SetCommandLineOptionWithMode("test_str2", "fourth", SET_FLAG_IF_DEFAULT);
+ EXPECT_EQ("second", FLAGS_test_str2);
+
+ // Verifies that the value of test_str3 was restored.
+ EXPECT_EQ("second", FLAGS_test_str3);
+ // Verifies that the "not set" attribute of test_str3 was restored to true.
+ SetCommandLineOptionWithMode("test_str3", "fourth", SET_FLAG_IF_DEFAULT);
+ EXPECT_EQ("fourth", FLAGS_test_str3);
+}
+
+
+// Tests that FlagSaver can save the values of various-typed flags.
+TEST(FlagSaverTest, CanSaveVariousTypedFlagValues) {
+ // Initializes the flags.
+ FLAGS_test_bool = false;
+ FLAGS_test_int32 = -1;
+ FLAGS_test_int64 = -2;
+ FLAGS_test_uint64 = 3;
+ FLAGS_test_double = 4.0;
+ FLAGS_test_string = "good";
+
+ // Saves the flag states.
+ {
+ FlagSaver fs;
+
+ // Modifies the flags.
+ FLAGS_test_bool = true;
+ FLAGS_test_int32 = -5;
+ FLAGS_test_int64 = -6;
+ FLAGS_test_uint64 = 7;
+ FLAGS_test_double = 8.0;
+ FLAGS_test_string = "bad";
+
+ // Restores the flag states.
+ }
+
+ // Verifies the flag values were restored.
+ EXPECT_FALSE(FLAGS_test_bool);
+ EXPECT_EQ(-1, FLAGS_test_int32);
+ EXPECT_EQ(-2, FLAGS_test_int64);
+ EXPECT_EQ(3, FLAGS_test_uint64);
+ EXPECT_DOUBLE_EQ(4.0, FLAGS_test_double);
+ EXPECT_EQ("good", FLAGS_test_string);
+}
+
+TEST(GetAllFlagsTest, BaseTest) {
+ vector<CommandLineFlagInfo> flags;
+ GetAllFlags(&flags);
+ bool found_test_bool = false;
+ vector<CommandLineFlagInfo>::const_iterator i;
+ for (i = flags.begin(); i != flags.end(); ++i) {
+ if (i->name == "test_bool") {
+ found_test_bool = true;
+ EXPECT_EQ(i->type, "bool");
+ EXPECT_EQ(i->default_value, "false");
+ EXPECT_EQ(i->flag_ptr, &FLAGS_test_bool);
+ break;
+ }
+ }
+ EXPECT_TRUE(found_test_bool);
+}
+
+TEST(ShowUsageWithFlagsTest, BaseTest) {
+ // TODO(csilvers): test this by allowing output other than to stdout.
+ // Not urgent since this functionality is tested via
+ // gflags_unittest.sh, though only through use of --help.
+}
+
+TEST(ShowUsageWithFlagsRestrictTest, BaseTest) {
+ // TODO(csilvers): test this by allowing output other than to stdout.
+ // Not urgent since this functionality is tested via
+ // gflags_unittest.sh, though only through use of --helpmatch.
+}
+
+// Note: all these argv-based tests depend on SetArgv being called
+// before ParseCommandLineFlags() in main(), below.
+TEST(GetArgvsTest, BaseTest) {
+ vector<string> argvs = GetArgvs();
+ EXPECT_EQ(4, argvs.size());
+ EXPECT_EQ("/test/argv/for/gflags_unittest", argvs[0]);
+ EXPECT_EQ("argv 2", argvs[1]);
+ EXPECT_EQ("3rd argv", argvs[2]);
+ EXPECT_EQ("argv #4", argvs[3]);
+}
+
+TEST(GetArgvTest, BaseTest) {
+ EXPECT_STREQ("/test/argv/for/gflags_unittest "
+ "argv 2 3rd argv argv #4", GetArgv());
+}
+
+TEST(GetArgv0Test, BaseTest) {
+ EXPECT_STREQ("/test/argv/for/gflags_unittest", GetArgv0());
+}
+
+TEST(GetArgvSumTest, BaseTest) {
+ // This number is just the sum of the ASCII values of all the chars
+ // in GetArgv().
+ EXPECT_EQ(4904, GetArgvSum());
+}
+
+TEST(ProgramInvocationNameTest, BaseTest) {
+ EXPECT_STREQ("/test/argv/for/gflags_unittest",
+ ProgramInvocationName());
+}
+
+TEST(ProgramInvocationShortNameTest, BaseTest) {
+ EXPECT_STREQ("gflags_unittest", ProgramInvocationShortName());
+}
+
+TEST(ProgramUsageTest, BaseTest) { // Depends on 1st arg to ParseCommandLineFlags()
+ EXPECT_STREQ("/test/argv/for/gflags_unittest: "
+ "<useless flag> [...]\nDoes something useless.\n",
+ ProgramUsage());
+}
+
+TEST(GetCommandLineOptionTest, NameExistsAndIsDefault) {
+ string value("will be changed");
+ bool r = GetCommandLineOption("test_bool", &value);
+ EXPECT_TRUE(r);
+ EXPECT_EQ("false", value);
+
+ r = GetCommandLineOption("test_int32", &value);
+ EXPECT_TRUE(r);
+ EXPECT_EQ("-1", value);
+}
+
+TEST(GetCommandLineOptionTest, NameExistsAndWasAssigned) {
+ FLAGS_test_int32 = 400;
+ string value("will be changed");
+ const bool r = GetCommandLineOption("test_int32", &value);
+ EXPECT_TRUE(r);
+ EXPECT_EQ("400", value);
+}
+
+TEST(GetCommandLineOptionTest, NameExistsAndWasSet) {
+ SetCommandLineOption("test_int32", "700");
+ string value("will be changed");
+ const bool r = GetCommandLineOption("test_int32", &value);
+ EXPECT_TRUE(r);
+ EXPECT_EQ("700", value);
+}
+
+TEST(GetCommandLineOptionTest, NameExistsAndWasNotSet) {
+ // This doesn't set the flag's value, but rather its default value.
+ // is_default is still true, but the 'default' value returned has changed!
+ SetCommandLineOptionWithMode("test_int32", "800", SET_FLAGS_DEFAULT);
+ string value("will be changed");
+ const bool r = GetCommandLineOption("test_int32", &value);
+ EXPECT_TRUE(r);
+ EXPECT_EQ("800", value);
+ EXPECT_TRUE(GetCommandLineFlagInfoOrDie("test_int32").is_default);
+}
+
+TEST(GetCommandLineOptionTest, NameExistsAndWasConditionallySet) {
+ SetCommandLineOptionWithMode("test_int32", "900", SET_FLAG_IF_DEFAULT);
+ string value("will be changed");
+ const bool r = GetCommandLineOption("test_int32", &value);
+ EXPECT_TRUE(r);
+ EXPECT_EQ("900", value);
+}
+
+TEST(GetCommandLineOptionTest, NameDoesNotExist) {
+ string value("will not be changed");
+ const bool r = GetCommandLineOption("test_int3210", &value);
+ EXPECT_FALSE(r);
+ EXPECT_EQ("will not be changed", value);
+}
+
+TEST(GetCommandLineFlagInfoTest, FlagExists) {
+ CommandLineFlagInfo info;
+ bool r = GetCommandLineFlagInfo("test_int32", &info);
+ EXPECT_TRUE(r);
+ EXPECT_EQ("test_int32", info.name);
+ EXPECT_EQ("int32", info.type);
+ EXPECT_EQ("", info.description);
+ EXPECT_EQ("-1", info.current_value);
+ EXPECT_EQ("-1", info.default_value);
+ EXPECT_TRUE(info.is_default);
+ EXPECT_FALSE(info.has_validator_fn);
+ EXPECT_EQ(&FLAGS_test_int32, info.flag_ptr);
+
+ FLAGS_test_bool = true;
+ r = GetCommandLineFlagInfo("test_bool", &info);
+ EXPECT_TRUE(r);
+ EXPECT_EQ("test_bool", info.name);
+ EXPECT_EQ("bool", info.type);
+ EXPECT_EQ("tests bool-ness", info.description);
+ EXPECT_EQ("true", info.current_value);
+ EXPECT_EQ("false", info.default_value);
+ EXPECT_FALSE(info.is_default);
+ EXPECT_FALSE(info.has_validator_fn);
+ EXPECT_EQ(&FLAGS_test_bool, info.flag_ptr);
+
+ FLAGS_test_bool = false;
+ r = GetCommandLineFlagInfo("test_bool", &info);
+ EXPECT_TRUE(r);
+ EXPECT_EQ("test_bool", info.name);
+ EXPECT_EQ("bool", info.type);
+ EXPECT_EQ("tests bool-ness", info.description);
+ EXPECT_EQ("false", info.current_value);
+ EXPECT_EQ("false", info.default_value);
+ EXPECT_FALSE(info.is_default); // value is same, but flag *was* modified
+ EXPECT_FALSE(info.has_validator_fn);
+ EXPECT_EQ(&FLAGS_test_bool, info.flag_ptr);
+}
+
+TEST(GetCommandLineFlagInfoTest, FlagDoesNotExist) {
+ CommandLineFlagInfo info;
+ // Set to some random values that GetCommandLineFlagInfo should not change
+ info.name = "name";
+ info.type = "type";
+ info.current_value = "curr";
+ info.default_value = "def";
+ info.filename = "/";
+ info.is_default = false;
+ info.has_validator_fn = true;
+ info.flag_ptr = NULL;
+ bool r = GetCommandLineFlagInfo("test_int3210", &info);
+ EXPECT_FALSE(r);
+ EXPECT_EQ("name", info.name);
+ EXPECT_EQ("type", info.type);
+ EXPECT_EQ("", info.description);
+ EXPECT_EQ("curr", info.current_value);
+ EXPECT_EQ("def", info.default_value);
+ EXPECT_EQ("/", info.filename);
+ EXPECT_FALSE(info.is_default);
+ EXPECT_TRUE(info.has_validator_fn);
+ EXPECT_EQ(NULL, info.flag_ptr);
+}
+
+TEST(GetCommandLineFlagInfoOrDieTest, FlagExistsAndIsDefault) {
+ CommandLineFlagInfo info;
+ info = GetCommandLineFlagInfoOrDie("test_int32");
+ EXPECT_EQ("test_int32", info.name);
+ EXPECT_EQ("int32", info.type);
+ EXPECT_EQ("", info.description);
+ EXPECT_EQ("-1", info.current_value);
+ EXPECT_EQ("-1", info.default_value);
+ EXPECT_TRUE(info.is_default);
+ EXPECT_EQ(&FLAGS_test_int32, info.flag_ptr);
+ info = GetCommandLineFlagInfoOrDie("test_bool");
+ EXPECT_EQ("test_bool", info.name);
+ EXPECT_EQ("bool", info.type);
+ EXPECT_EQ("tests bool-ness", info.description);
+ EXPECT_EQ("false", info.current_value);
+ EXPECT_EQ("false", info.default_value);
+ EXPECT_TRUE(info.is_default);
+ EXPECT_FALSE(info.has_validator_fn);
+ EXPECT_EQ(&FLAGS_test_bool, info.flag_ptr);
+}
+
+TEST(GetCommandLineFlagInfoOrDieTest, FlagExistsAndWasAssigned) {
+ FLAGS_test_int32 = 400;
+ CommandLineFlagInfo info;
+ info = GetCommandLineFlagInfoOrDie("test_int32");
+ EXPECT_EQ("test_int32", info.name);
+ EXPECT_EQ("int32", info.type);
+ EXPECT_EQ("", info.description);
+ EXPECT_EQ("400", info.current_value);
+ EXPECT_EQ("-1", info.default_value);
+ EXPECT_FALSE(info.is_default);
+ EXPECT_EQ(&FLAGS_test_int32, info.flag_ptr);
+ FLAGS_test_bool = true;
+ info = GetCommandLineFlagInfoOrDie("test_bool");
+ EXPECT_EQ("test_bool", info.name);
+ EXPECT_EQ("bool", info.type);
+ EXPECT_EQ("tests bool-ness", info.description);
+ EXPECT_EQ("true", info.current_value);
+ EXPECT_EQ("false", info.default_value);
+ EXPECT_FALSE(info.is_default);
+ EXPECT_FALSE(info.has_validator_fn);
+ EXPECT_EQ(&FLAGS_test_bool, info.flag_ptr);
+}
+
+#ifdef GTEST_HAS_DEATH_TEST
+TEST(GetCommandLineFlagInfoOrDieDeathTest, FlagDoesNotExist) {
+ EXPECT_DEATH(GetCommandLineFlagInfoOrDie("test_int3210"),
+ ".*: flag test_int3210 does not exist");
+}
+#endif
+
+
+// These are lightly tested because they're deprecated. Basically,
+// the tests are meant to cover how existing users use these functions,
+// but not necessarily how new users could use them.
+TEST(DeprecatedFunctionsTest, CommandlineFlagsIntoString) {
+ string s = CommandlineFlagsIntoString();
+ EXPECT_NE(string::npos, s.find("--test_bool="));
+}
+
+TEST(DeprecatedFunctionsTest, AppendFlagsIntoFile) {
+ FLAGS_test_int32 = 10; // just to make the test more interesting
+ string filename(TmpFile("flagfile"));
+ unlink(filename.c_str()); // just to be safe
+ const bool r = AppendFlagsIntoFile(filename, "not the real argv0");
+ EXPECT_TRUE(r);
+
+ FILE* fp = fopen(filename.c_str(), "r");
+ EXPECT_TRUE(fp != NULL);
+ char line[8192];
+ EXPECT_TRUE(fgets(line, sizeof(line)-1, fp) != NULL); // get the first line
+ // First line should be progname.
+ EXPECT_STREQ("not the real argv0\n", line);
+
+ bool found_bool = false, found_int32 = false;
+ while (fgets(line, sizeof(line)-1, fp)) {
+ line[sizeof(line)-1] = '\0'; // just to be safe
+ if (strcmp(line, "--test_bool=false\n") == 0)
+ found_bool = true;
+ if (strcmp(line, "--test_int32=10\n") == 0)
+ found_int32 = true;
+ }
+ EXPECT_TRUE(found_int32);
+ EXPECT_TRUE(found_bool);
+ fclose(fp);
+}
+
+TEST(DeprecatedFunctionsTest, ReadFromFlagsFile) {
+ FLAGS_test_int32 = -10; // just to make the test more interesting
+ string filename(TmpFile("flagfile2"));
+ unlink(filename.c_str()); // just to be safe
+ bool r = AppendFlagsIntoFile(filename, GetArgv0());
+ EXPECT_TRUE(r);
+
+ FLAGS_test_int32 = -11;
+ r = ReadFromFlagsFile(filename, GetArgv0(), true);
+ EXPECT_TRUE(r);
+ EXPECT_EQ(-10, FLAGS_test_int32);
+} // unnamed namespace
+
+TEST(DeprecatedFunctionsTest, ReadFromFlagsFileFailure) {
+ FLAGS_test_int32 = -20;
+ string filename(TmpFile("flagfile3"));
+ FILE* fp = fopen(filename.c_str(), "w");
+ EXPECT_TRUE(fp != NULL);
+ // Note the error in the bool assignment below...
+ fprintf(fp, "%s\n--test_int32=-21\n--test_bool=not_a_bool!\n", GetArgv0());
+ fclose(fp);
+
+ FLAGS_test_int32 = -22;
+ const bool r = ReadFromFlagsFile(filename, GetArgv0(), false);
+ EXPECT_FALSE(r);
+ EXPECT_EQ(-22, FLAGS_test_int32); // the -21 from the flagsfile didn't take
+}
+
+TEST(FlagsSetBeforeInitTest, TryFromEnv) {
+ EXPECT_EQ("pre-set", FLAGS_test_tryfromenv);
+}
+
+// The following test case verifies that ParseCommandLineFlags() and
+// ParseCommandLineNonHelpFlags() uses the last definition of a flag
+// in case it's defined more than once.
+
+DEFINE_int32(test_flag, -1, "used for testing gflags.cc");
+
+// Parses and returns the --test_flag flag.
+// If with_help is true, calls ParseCommandLineFlags; otherwise calls
+// ParseCommandLineNonHelpFlags.
+int32 ParseTestFlag(bool with_help, int argc, const char** const_argv) {
+ FlagSaver fs; // Restores the flags before returning.
+
+ // Makes a copy of the input array s.t. it can be reused
+ // (ParseCommandLineFlags() will alter the array).
+ char** const argv_save = new char*[argc + 1];
+ char** argv = argv_save;
+ memcpy(argv, const_argv, sizeof(*argv)*(argc + 1));
+
+ if (with_help) {
+ ParseCommandLineFlags(&argc, &argv, true);
+ } else {
+ ParseCommandLineNonHelpFlags(&argc, &argv, true);
+ }
+
+ delete[] argv_save;
+ return FLAGS_test_flag;
+}
+
+TEST(ParseCommandLineFlagsUsesLastDefinitionTest,
+ WhenFlagIsDefinedTwiceOnCommandLine) {
+ const char* argv[] = {
+ "my_test",
+ "--test_flag=1",
+ "--test_flag=2",
+ NULL,
+ };
+
+ EXPECT_EQ(2, ParseTestFlag(true, arraysize(argv) - 1, argv));
+ EXPECT_EQ(2, ParseTestFlag(false, arraysize(argv) - 1, argv));
+}
+
+TEST(ParseCommandLineFlagsUsesLastDefinitionTest,
+ WhenFlagIsDefinedTwiceInFlagFile) {
+ const char* argv[] = {
+ "my_test",
+ GetFlagFileFlag(),
+ NULL,
+ };
+
+ EXPECT_EQ(2, ParseTestFlag(true, arraysize(argv) - 1, argv));
+ EXPECT_EQ(2, ParseTestFlag(false, arraysize(argv) - 1, argv));
+}
+
+TEST(ParseCommandLineFlagsUsesLastDefinitionTest,
+ WhenFlagIsDefinedInCommandLineAndThenFlagFile) {
+ const char* argv[] = {
+ "my_test",
+ "--test_flag=0",
+ GetFlagFileFlag(),
+ NULL,
+ };
+
+ EXPECT_EQ(2, ParseTestFlag(true, arraysize(argv) - 1, argv));
+ EXPECT_EQ(2, ParseTestFlag(false, arraysize(argv) - 1, argv));
+}
+
+TEST(ParseCommandLineFlagsUsesLastDefinitionTest,
+ WhenFlagIsDefinedInFlagFileAndThenCommandLine) {
+ const char* argv[] = {
+ "my_test",
+ GetFlagFileFlag(),
+ "--test_flag=3",
+ NULL,
+ };
+
+ EXPECT_EQ(3, ParseTestFlag(true, arraysize(argv) - 1, argv));
+ EXPECT_EQ(3, ParseTestFlag(false, arraysize(argv) - 1, argv));
+}
+
+TEST(ParseCommandLineFlagsUsesLastDefinitionTest,
+ WhenFlagIsDefinedInCommandLineAndFlagFileAndThenCommandLine) {
+ const char* argv[] = {
+ "my_test",
+ "--test_flag=0",
+ GetFlagFileFlag(),
+ "--test_flag=3",
+ NULL,
+ };
+
+ EXPECT_EQ(3, ParseTestFlag(true, arraysize(argv) - 1, argv));
+ EXPECT_EQ(3, ParseTestFlag(false, arraysize(argv) - 1, argv));
+}
+
+TEST(ParseCommandLineFlagsAndDashArgs, TwoDashArgFirst) {
+ const char* argv[] = {
+ "my_test",
+ "--",
+ "--test_flag=0",
+ NULL,
+ };
+
+ EXPECT_EQ(-1, ParseTestFlag(true, arraysize(argv) - 1, argv));
+ EXPECT_EQ(-1, ParseTestFlag(false, arraysize(argv) - 1, argv));
+}
+
+TEST(ParseCommandLineFlagsAndDashArgs, TwoDashArgMiddle) {
+ const char* argv[] = {
+ "my_test",
+ "--test_flag=7",
+ "--",
+ "--test_flag=0",
+ NULL,
+ };
+
+ EXPECT_EQ(7, ParseTestFlag(true, arraysize(argv) - 1, argv));
+ EXPECT_EQ(7, ParseTestFlag(false, arraysize(argv) - 1, argv));
+}
+
+TEST(ParseCommandLineFlagsAndDashArgs, OneDashArg) {
+ const char* argv[] = {
+ "my_test",
+ "-",
+ "--test_flag=0",
+ NULL,
+ };
+
+ EXPECT_EQ(0, ParseTestFlag(true, arraysize(argv) - 1, argv));
+ EXPECT_EQ(0, ParseTestFlag(false, arraysize(argv) - 1, argv));
+}
+
+#ifdef GTEST_HAS_DEATH_TEST
+TEST(ParseCommandLineFlagsUnknownFlagDeathTest,
+ FlagIsCompletelyUnknown) {
+ const char* argv[] = {
+ "my_test",
+ "--this_flag_does_not_exist",
+ NULL,
+ };
+
+ EXPECT_DEATH(ParseTestFlag(true, arraysize(argv) - 1, argv),
+ "unknown command line flag.*");
+ EXPECT_DEATH(ParseTestFlag(false, arraysize(argv) - 1, argv),
+ "unknown command line flag.*");
+}
+
+TEST(ParseCommandLineFlagsUnknownFlagDeathTest,
+ BoolFlagIsCompletelyUnknown) {
+ const char* argv[] = {
+ "my_test",
+ "--nothis_flag_does_not_exist",
+ NULL,
+ };
+
+ EXPECT_DEATH(ParseTestFlag(true, arraysize(argv) - 1, argv),
+ "unknown command line flag.*");
+ EXPECT_DEATH(ParseTestFlag(false, arraysize(argv) - 1, argv),
+ "unknown command line flag.*");
+}
+
+TEST(ParseCommandLineFlagsUnknownFlagDeathTest,
+ FlagIsNotABool) {
+ const char* argv[] = {
+ "my_test",
+ "--notest_string",
+ NULL,
+ };
+
+ EXPECT_DEATH(ParseTestFlag(true, arraysize(argv) - 1, argv),
+ "boolean value .* specified for .* command line flag");
+ EXPECT_DEATH(ParseTestFlag(false, arraysize(argv) - 1, argv),
+ "boolean value .* specified for .* command line flag");
+}
+#endif
+
+TEST(ParseCommandLineFlagsWrongFields,
+ DescriptionIsInvalid) {
+ // These must not be automatic variables, since command line flags
+ // aren't unregistered and gUnit uses FlagSaver to save and restore
+ // command line flags' values. If these are on the stack, then when
+ // later tests attempt to save and restore their values, the stack
+ // addresses of these variables will be overwritten... Stack smash!
+ static bool current_storage;
+ static bool defvalue_storage;
+ FlagRegisterer fr("flag_name", "bool", 0, "filename",
+ &current_storage, &defvalue_storage);
+ CommandLineFlagInfo fi;
+ EXPECT_TRUE(GetCommandLineFlagInfo("flag_name", &fi));
+ EXPECT_EQ("", fi.description);
+ EXPECT_EQ(&current_storage, fi.flag_ptr);
+}
+
+static bool ValidateTestFlagIs5(const char* flagname, int32 flagval) {
+ if (flagval == 5)
+ return true;
+ printf("%s isn't 5!\n", flagname);
+ return false;
+}
+
+static bool ValidateTestFlagIs10(const char* flagname, int32 flagval) {
+ return flagval == 10;
+}
+
+
+TEST(FlagsValidator, ValidFlagViaArgv) {
+ const char* argv[] = {
+ "my_test",
+ "--test_flag=5",
+ NULL,
+ };
+ EXPECT_TRUE(RegisterFlagValidator(&FLAGS_test_flag, &ValidateTestFlagIs5));
+ EXPECT_EQ(5, ParseTestFlag(true, arraysize(argv) - 1, argv));
+ // Undo the flag validator setting
+ EXPECT_TRUE(RegisterFlagValidator(&FLAGS_test_flag, NULL));
+}
+
+TEST(FlagsValidator, ValidFlagViaSetDefault) {
+ EXPECT_TRUE(RegisterFlagValidator(&FLAGS_test_flag, &ValidateTestFlagIs5));
+ // SetCommandLineOptionWithMode returns the empty string on error.
+ EXPECT_NE("", SetCommandLineOptionWithMode("test_flag", "5",
+ SET_FLAG_IF_DEFAULT));
+ EXPECT_TRUE(RegisterFlagValidator(&FLAGS_test_flag, NULL));
+}
+
+TEST(FlagsValidator, ValidFlagViaSetValue) {
+ EXPECT_TRUE(RegisterFlagValidator(&FLAGS_test_flag, &ValidateTestFlagIs5));
+ FLAGS_test_flag = 100; // doesn't trigger the validator
+ // SetCommandLineOptionWithMode returns the empty string on error.
+ EXPECT_NE("", SetCommandLineOptionWithMode("test_flag", "5",
+ SET_FLAGS_VALUE));
+ EXPECT_NE("", SetCommandLineOptionWithMode("test_flag", "5",
+ SET_FLAGS_DEFAULT));
+ EXPECT_NE("", SetCommandLineOption("test_flag", "5"));
+ EXPECT_TRUE(RegisterFlagValidator(&FLAGS_test_flag, NULL));
+}
+
+#ifdef GTEST_HAS_DEATH_TEST
+TEST(FlagsValidatorDeathTest, InvalidFlagViaArgv) {
+ const char* argv[] = {
+ "my_test",
+ "--test_flag=50",
+ NULL,
+ };
+ EXPECT_TRUE(RegisterFlagValidator(&FLAGS_test_flag, &ValidateTestFlagIs5));
+ EXPECT_DEATH(ParseTestFlag(true, arraysize(argv) - 1, argv),
+ "ERROR: failed validation of new value '50' for flag 'test_flag'");
+ EXPECT_TRUE(RegisterFlagValidator(&FLAGS_test_flag, NULL));
+}
+#endif
+
+TEST(FlagsValidator, InvalidFlagViaSetDefault) {
+ EXPECT_TRUE(RegisterFlagValidator(&FLAGS_test_flag, &ValidateTestFlagIs5));
+ // SetCommandLineOptionWithMode returns the empty string on error.
+ EXPECT_EQ("", SetCommandLineOptionWithMode("test_flag", "50",
+ SET_FLAG_IF_DEFAULT));
+ EXPECT_EQ(-1, FLAGS_test_flag); // the setting-to-50 should have failed
+ EXPECT_TRUE(RegisterFlagValidator(&FLAGS_test_flag, NULL));
+}
+
+TEST(FlagsValidator, InvalidFlagViaSetValue) {
+ EXPECT_TRUE(RegisterFlagValidator(&FLAGS_test_flag, &ValidateTestFlagIs5));
+ FLAGS_test_flag = 100; // doesn't trigger the validator
+ // SetCommandLineOptionWithMode returns the empty string on error.
+ EXPECT_EQ("", SetCommandLineOptionWithMode("test_flag", "50",
+ SET_FLAGS_VALUE));
+ EXPECT_EQ("", SetCommandLineOptionWithMode("test_flag", "50",
+ SET_FLAGS_DEFAULT));
+ EXPECT_EQ("", SetCommandLineOption("test_flag", "50"));
+ EXPECT_EQ(100, FLAGS_test_flag); // the setting-to-50 should have failed
+ EXPECT_TRUE(RegisterFlagValidator(&FLAGS_test_flag, NULL));
+}
+
+#ifdef GTEST_HAS_DEATH_TEST
+TEST(FlagsValidatorDeathTest, InvalidFlagNeverSet) {
+ // If a flag keeps its default value, and that default value is
+ // invalid, we should die at argv-parse time.
+ const char* argv[] = {
+ "my_test",
+ NULL,
+ };
+ EXPECT_TRUE(RegisterFlagValidator(&FLAGS_test_flag, &ValidateTestFlagIs5));
+ EXPECT_DEATH(ParseTestFlag(true, arraysize(argv) - 1, argv),
+ "ERROR: --test_flag must be set on the commandline");
+}
+#endif
+
+TEST(FlagsValidator, InvalidFlagPtr) {
+ int32 dummy;
+ EXPECT_FALSE(RegisterFlagValidator(NULL, &ValidateTestFlagIs5));
+ EXPECT_FALSE(RegisterFlagValidator(&dummy, &ValidateTestFlagIs5));
+}
+
+TEST(FlagsValidator, RegisterValidatorTwice) {
+ EXPECT_TRUE(RegisterFlagValidator(&FLAGS_test_flag, &ValidateTestFlagIs5));
+ EXPECT_TRUE(RegisterFlagValidator(&FLAGS_test_flag, &ValidateTestFlagIs5));
+ EXPECT_FALSE(RegisterFlagValidator(&FLAGS_test_flag, &ValidateTestFlagIs10));
+ EXPECT_FALSE(RegisterFlagValidator(&FLAGS_test_flag, &ValidateTestFlagIs10));
+ EXPECT_TRUE(RegisterFlagValidator(&FLAGS_test_flag, &ValidateTestFlagIs5));
+ EXPECT_TRUE(RegisterFlagValidator(&FLAGS_test_flag, NULL));
+ EXPECT_TRUE(RegisterFlagValidator(&FLAGS_test_flag, &ValidateTestFlagIs10));
+ EXPECT_TRUE(RegisterFlagValidator(&FLAGS_test_flag, NULL));
+}
+
+TEST(FlagsValidator, CommandLineFlagInfo) {
+ CommandLineFlagInfo info;
+ info = GetCommandLineFlagInfoOrDie("test_flag");
+ EXPECT_FALSE(info.has_validator_fn);
+
+ EXPECT_TRUE(RegisterFlagValidator(&FLAGS_test_flag, &ValidateTestFlagIs5));
+ info = GetCommandLineFlagInfoOrDie("test_flag");
+ EXPECT_TRUE(info.has_validator_fn);
+
+ EXPECT_TRUE(RegisterFlagValidator(&FLAGS_test_flag, NULL));
+ info = GetCommandLineFlagInfoOrDie("test_flag");
+ EXPECT_FALSE(info.has_validator_fn);
+}
+
+TEST(FlagsValidator, FlagSaver) {
+ {
+ FlagSaver fs;
+ EXPECT_TRUE(RegisterFlagValidator(&FLAGS_test_flag, &ValidateTestFlagIs5));
+ EXPECT_EQ("", SetCommandLineOption("test_flag", "50")); // fails validation
+ }
+ EXPECT_NE("", SetCommandLineOption("test_flag", "50")); // validator is gone
+
+ EXPECT_TRUE(RegisterFlagValidator(&FLAGS_test_flag, &ValidateTestFlagIs5));
+ {
+ FlagSaver fs;
+ EXPECT_TRUE(RegisterFlagValidator(&FLAGS_test_flag, NULL));
+ EXPECT_NE("", SetCommandLineOption("test_flag", "50")); // no validator
+ }
+ EXPECT_EQ("", SetCommandLineOption("test_flag", "50")); // validator is back
+}
+
+
+} // unnamed namespace
+
+int main(int argc, char **argv) {
+ // We need to call SetArgv before parsing flags, so our "test" argv will
+ // win out over this executable's real argv. That makes running this
+ // test with a real --help flag kinda annoying, unfortunately.
+ const char* test_argv[] = { "/test/argv/for/gflags_unittest",
+ "argv 2", "3rd argv", "argv #4" };
+ SetArgv(arraysize(test_argv), test_argv);
+
+ // The first arg is the usage message, also important for testing.
+ string usage_message = (string(GetArgv0()) +
+ ": <useless flag> [...]\nDoes something useless.\n");
+
+ // We test setting tryfromenv manually, and making sure
+ // ParseCommandLineFlags still evaluates it.
+ FLAGS_tryfromenv = "test_tryfromenv";
+ setenv("FLAGS_test_tryfromenv", "pre-set", 1);
+
+ // Modify flag values from declared default value in two ways.
+ // The recommended way:
+ SetCommandLineOptionWithMode("changed_bool1", "true", SET_FLAGS_DEFAULT);
+
+ // The non-recommended way:
+ FLAGS_changed_bool2 = true;
+
+ SetUsageMessage(usage_message.c_str());
+ SetVersionString("test_version");
+ ParseCommandLineFlags(&argc, &argv, true);
+ MakeTmpdir(&FLAGS_test_tmpdir);
+
+ const int exit_status = RUN_ALL_TESTS();
+ ShutDownCommandLineFlags();
+ return exit_status;
+}
+
+_END_GOOGLE_NAMESPACE_
+
+int main(int argc, char** argv) {
+ return GOOGLE_NAMESPACE::main(argc, argv);
+}
+
diff --git a/src/third_party/gflags-2.0/src/gflags_unittest.sh b/src/third_party/gflags-2.0/src/gflags_unittest.sh
new file mode 100755
index 00000000000..c81e41e75ee
--- /dev/null
+++ b/src/third_party/gflags-2.0/src/gflags_unittest.sh
@@ -0,0 +1,237 @@
+#!/bin/bash
+
+# Copyright (c) 2006, Google Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+# * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+# ---
+# Author: Craig Silverstein
+#
+# Just tries to run the gflags_unittest with various flags
+# defined in gflags.cc, and make sure they give the
+# appropriate exit status and appropriate error message.
+
+if [ -z "$1" ]; then
+ echo "USAGE: $0 <unittest exe> [top_srcdir] [tmpdir]"
+ exit 1
+fi
+EXE="$1"
+SRCDIR="${2:-./}"
+TMPDIR="${3:-/tmp/gflags}"
+EXE2="${EXE}2" # eg, gflags_unittest2
+EXE3="${EXE}3" # eg, gflags_unittest3
+
+# $1: executable
+# $2: line-number $3: expected return code. $4: substring of expected output.
+# $5: a substring you *don't* expect to find in the output. $6+ flags
+ExpectExe() {
+ local executable="$1"
+ shift
+ local line_number="$1"
+ shift
+ local expected_rc="$1"
+ shift
+ local expected_output="$1"
+ shift
+ local unexpected_output="$1"
+ shift
+
+ # We always add --srcdir because it's needed for correctness
+ "$executable" --srcdir="$SRCDIR" "$@" > "$TMPDIR/test.$line_number" 2>&1
+
+ local actual_rc=$?
+ if [ $actual_rc != $expected_rc ]; then
+ echo "Test on line $line_number failed:" \
+ "expected rc $expected_rc, got $actual_rc"
+ exit 1;
+ fi
+ if [ -n "$expected_output" ] &&
+ ! fgrep -e "$expected_output" "$TMPDIR/test.$line_number" >/dev/null; then
+ echo "Test on line $line_number failed:" \
+ "did not find expected substring '$expected_output'"
+ exit 1;
+ fi
+ if [ -n "$unexpected_output" ] &&
+ fgrep -e "$unexpected_output" "$TMPDIR/test.$line_number" >/dev/null; then
+ echo "Test line $line_number failed:" \
+ "found unexpected substring '$unexpected_output'"
+ exit 1;
+ fi
+}
+
+# $1: line-number $2: expected return code. $3: substring of expected output.
+# $4: a substring you *don't* expect to find in the output. $5+ flags
+Expect() {
+ ExpectExe "$EXE" "$@"
+}
+
+rm -rf "$TMPDIR"
+mkdir "$TMPDIR" || exit 2
+
+# Create a few flagfiles we can use later
+echo "--version" > "$TMPDIR/flagfile.1"
+echo "--foo=bar" > "$TMPDIR/flagfile.2"
+echo "--nounused_bool" >> "$TMPDIR/flagfile.2"
+echo "--flagfile=$TMPDIR/flagfile.2" > "$TMPDIR/flagfile.3"
+
+# Set a few environment variables (useful for --tryfromenv)
+export FLAGS_undefok=foo,bar
+export FLAGS_weirdo=
+export FLAGS_version=true
+export FLAGS_help=false
+
+# First, just make sure the unittest works as-is
+Expect $LINENO 0 "PASS" ""
+
+# --help should show all flags, including flags from gflags_reporting
+Expect $LINENO 1 "/gflags_reporting.cc" "" --help
+
+# Make sure that --help prints even very long helpstrings.
+Expect $LINENO 1 "end of a long helpstring" "" --help
+
+# Make sure --help reflects flag changes made before flag-parsing
+Expect $LINENO 1 \
+ "-changed_bool1 (changed) type: bool default: true" "" --help
+Expect $LINENO 1 \
+ "-changed_bool2 (changed) type: bool default: false currently: true" "" \
+ --help
+# And on the command-line, too
+Expect $LINENO 1 \
+ "-changeable_string_var () type: string default: \"1\" currently: \"2\"" \
+ "" --changeable_string_var 2 --help
+
+# --nohelp and --help=false should be as if we didn't say anything
+Expect $LINENO 0 "PASS" "" --nohelp
+Expect $LINENO 0 "PASS" "" --help=false
+
+# --helpfull is the same as help
+Expect $LINENO 1 "/gflags_reporting.cc" "" -helpfull
+
+# --helpshort should show only flags from the unittest itself
+Expect $LINENO 1 "/gflags_unittest.cc" \
+ "/gflags_reporting.cc" --helpshort
+
+# --helpshort should show the tldflag we created in the unittest dir
+Expect $LINENO 1 "tldflag1" "/google.cc" --helpshort
+Expect $LINENO 1 "tldflag2" "/google.cc" --helpshort
+
+# --helpshort should work if the main source file is suffixed with [_-]main
+ExpectExe "$EXE2" $LINENO 1 "/gflags_unittest-main.cc" \
+ "/gflags_reporting.cc" --helpshort
+ExpectExe "$EXE3" $LINENO 1 "/gflags_unittest_main.cc" \
+ "/gflags_reporting.cc" --helpshort
+
+# --helpon needs an argument
+Expect $LINENO 1 \
+ "'--helpon' is missing its argument; flag description: show help on" \
+ "" --helpon
+
+# --helpon argument indicates what file we'll show args from
+Expect $LINENO 1 "/gflags.cc" "/gflags_unittest.cc" \
+ --helpon=gflags
+
+# another way of specifying the argument
+Expect $LINENO 1 "/gflags.cc" "/gflags_unittest.cc" \
+ --helpon gflags
+
+# test another argument
+Expect $LINENO 1 "/gflags_unittest.cc" "/gflags.cc" \
+ --helpon=gflags_unittest
+
+# helpmatch is like helpon but takes substrings
+Expect $LINENO 1 "/gflags_reporting.cc" \
+ "/gflags_unittest.cc" -helpmatch reporting
+Expect $LINENO 1 "/gflags_unittest.cc" \
+ "/gflags.cc" -helpmatch=unittest
+
+# if no flags are found with helpmatch or helpon, suggest --help
+Expect $LINENO 1 "No modules matched" "/gflags_unittest.cc" \
+ -helpmatch=nosuchsubstring
+Expect $LINENO 1 "No modules matched" "/gflags_unittest.cc" \
+ -helpon=nosuchmodule
+
+# helppackage shows all the flags in the same dir as this unittest
+# --help should show all flags, including flags from google.cc
+Expect $LINENO 1 "/gflags_reporting.cc" "" --helppackage
+
+# xml!
+Expect $LINENO 1 "/gflags_unittest.cc</file>" \
+ "/gflags_unittest.cc:" --helpxml
+
+# just print the version info and exit
+Expect $LINENO 0 "gflags_unittest" "gflags_unittest.cc" --version
+Expect $LINENO 0 "version test_version" "gflags_unittest.cc" --version
+
+# --undefok is a fun flag...
+Expect $LINENO 1 "unknown command line flag 'foo'" "" --undefok= --foo --unused_bool
+Expect $LINENO 0 "PASS" "" --undefok=foo --foo --unused_bool
+# If you say foo is ok to be undefined, we'll accept --nofoo as well
+Expect $LINENO 0 "PASS" "" --undefok=foo --nofoo --unused_bool
+# It's ok if the foo is in the middle
+Expect $LINENO 0 "PASS" "" --undefok=fee,fi,foo,fum --foo --unused_bool
+# But the spelling has to be just right...
+Expect $LINENO 1 "unknown command line flag 'foo'" "" --undefok=fo --foo --unused_bool
+Expect $LINENO 1 "unknown command line flag 'foo'" "" --undefok=foot --foo --unused_bool
+
+# See if we can successfully load our flags from the flagfile
+Expect $LINENO 0 "gflags_unittest" "gflags_unittest.cc" \
+ --flagfile="$TMPDIR/flagfile.1"
+Expect $LINENO 0 "PASS" "" --flagfile="$TMPDIR/flagfile.2"
+Expect $LINENO 0 "PASS" "" --flagfile="$TMPDIR/flagfile.3"
+
+# Also try to load flags from the environment
+Expect $LINENO 0 "gflags_unittest" "gflags_unittest.cc" \
+ --fromenv=version
+Expect $LINENO 0 "gflags_unittest" "gflags_unittest.cc" \
+ --tryfromenv=version
+Expect $LINENO 0 "PASS" "" --fromenv=help
+Expect $LINENO 0 "PASS" "" --tryfromenv=help
+Expect $LINENO 1 "helpfull not found in environment" "" --fromenv=helpfull
+Expect $LINENO 0 "PASS" "" --tryfromenv=helpfull
+Expect $LINENO 0 "PASS" "" --tryfromenv=undefok --foo
+Expect $LINENO 1 "unknown command line flag" "" --tryfromenv=weirdo
+Expect $LINENO 0 "gflags_unittest" "gflags_unittest.cc" \
+ --tryfromenv=test_bool,version,unused_bool
+Expect $LINENO 1 "not found in environment" "" --fromenv=test_bool
+Expect $LINENO 1 "unknown command line flag" "" --fromenv=test_bool,ok
+# Here, the --version overrides the fromenv
+Expect $LINENO 0 "gflags_unittest" "gflags_unittest.cc" \
+ --fromenv=test_bool,version,ok
+
+# Make sure -- by itself stops argv processing
+Expect $LINENO 0 "PASS" "" -- --help
+
+
+# And we should die if the flag value doesn't pass the validator
+Expect $LINENO 1 "ERROR: failed validation of new value 'true' for flag 'always_fail'" "" --always_fail
+
+# TODO(user) And if locking in validators fails.
+# Expect $LINENO 0 "PASS" "" --deadlock_if_cant_lock
+
+echo "PASS"
+exit 0
diff --git a/src/third_party/gflags-2.0/src/gflags_unittest_flagfile b/src/third_party/gflags-2.0/src/gflags_unittest_flagfile
new file mode 100755
index 00000000000..f4fa0c4d5c5
--- /dev/null
+++ b/src/third_party/gflags-2.0/src/gflags_unittest_flagfile
@@ -0,0 +1,2 @@
+--test_flag=1
+--test_flag=2
diff --git a/src/third_party/gflags-2.0/src/google/gflags.h b/src/third_party/gflags-2.0/src/google/gflags.h
new file mode 100755
index 00000000000..c1adcb824bb
--- /dev/null
+++ b/src/third_party/gflags-2.0/src/google/gflags.h
@@ -0,0 +1,34 @@
+// Copyright (c) 2006, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Header files have moved from the google directory to the gflags
+// directory. This forwarding file is provided only for backwards
+// compatibility. Use gflags/gflags.h in all new code.
+
+#include <gflags/gflags.h>
diff --git a/src/third_party/gflags-2.0/src/google/gflags_completions.h b/src/third_party/gflags-2.0/src/google/gflags_completions.h
new file mode 100755
index 00000000000..614ef098ac3
--- /dev/null
+++ b/src/third_party/gflags-2.0/src/google/gflags_completions.h
@@ -0,0 +1,34 @@
+// Copyright (c) 2008, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Header files have moved from the google directory to the gflags
+// directory. This forwarding file is provided only for backwards
+// compatibility. Use gflags/gflags_completions.h in all new code.
+
+#include <gflags/gflags_completions.h>
diff --git a/src/third_party/gflags-2.0/src/mutex.h b/src/third_party/gflags-2.0/src/mutex.h
new file mode 100755
index 00000000000..7c3c060a043
--- /dev/null
+++ b/src/third_party/gflags-2.0/src/mutex.h
@@ -0,0 +1,356 @@
+// Copyright (c) 2007, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// ---
+//
+// A simple mutex wrapper, supporting locks and read-write locks.
+// You should assume the locks are *not* re-entrant.
+//
+// To use: you should define the following macros in your configure.ac:
+// ACX_PTHREAD
+// AC_RWLOCK
+// The latter is defined in ../autoconf.
+//
+// This class is meant to be internal-only and should be wrapped by an
+// internal namespace. Before you use this module, please give the
+// name of your internal namespace for this module. Or, if you want
+// to expose it, you'll want to move it to the Google namespace. We
+// cannot put this class in global namespace because there can be some
+// problems when we have multiple versions of Mutex in each shared object.
+//
+// NOTE: by default, we have #ifdef'ed out the TryLock() method.
+// This is for two reasons:
+// 1) TryLock() under Windows is a bit annoying (it requires a
+// #define to be defined very early).
+// 2) TryLock() is broken for NO_THREADS mode, at least in NDEBUG
+// mode.
+// If you need TryLock(), and either these two caveats are not a
+// problem for you, or you're willing to work around them, then
+// feel free to #define GMUTEX_TRYLOCK, or to remove the #ifdefs
+// in the code below.
+//
+// CYGWIN NOTE: Cygwin support for rwlock seems to be buggy:
+// http://www.cygwin.com/ml/cygwin/2008-12/msg00017.html
+// Because of that, we might as well use windows locks for
+// cygwin. They seem to be more reliable than the cygwin pthreads layer.
+//
+// TRICKY IMPLEMENTATION NOTE:
+// This class is designed to be safe to use during
+// dynamic-initialization -- that is, by global constructors that are
+// run before main() starts. The issue in this case is that
+// dynamic-initialization happens in an unpredictable order, and it
+// could be that someone else's dynamic initializer could call a
+// function that tries to acquire this mutex -- but that all happens
+// before this mutex's constructor has run. (This can happen even if
+// the mutex and the function that uses the mutex are in the same .cc
+// file.) Basically, because Mutex does non-trivial work in its
+// constructor, it's not, in the naive implementation, safe to use
+// before dynamic initialization has run on it.
+//
+// The solution used here is to pair the actual mutex primitive with a
+// bool that is set to true when the mutex is dynamically initialized.
+// (Before that it's false.) Then we modify all mutex routines to
+// look at the bool, and not try to lock/unlock until the bool makes
+// it to true (which happens after the Mutex constructor has run.)
+//
+// This works because before main() starts -- particularly, during
+// dynamic initialization -- there are no threads, so a) it's ok that
+// the mutex operations are a no-op, since we don't need locking then
+// anyway; and b) we can be quite confident our bool won't change
+// state between a call to Lock() and a call to Unlock() (that would
+// require a global constructor in one translation unit to call Lock()
+// and another global constructor in another translation unit to call
+// Unlock() later, which is pretty perverse).
+//
+// That said, it's tricky, and can conceivably fail; it's safest to
+// avoid trying to acquire a mutex in a global constructor, if you
+// can. One way it can fail is that a really smart compiler might
+// initialize the bool to true at static-initialization time (too
+// early) rather than at dynamic-initialization time. To discourage
+// that, we set is_safe_ to true in code (not the constructor
+// colon-initializer) and set it to true via a function that always
+// evaluates to true, but that the compiler can't know always
+// evaluates to true. This should be good enough.
+//
+// A related issue is code that could try to access the mutex
+// after it's been destroyed in the global destructors (because
+// the Mutex global destructor runs before some other global
+// destructor, that tries to acquire the mutex). The way we
+// deal with this is by taking a constructor arg that global
+// mutexes should pass in, that causes the destructor to do no
+// work. We still depend on the compiler not doing anything
+// weird to a Mutex's memory after it is destroyed, but for a
+// static global variable, that's pretty safe.
+
+#ifndef GOOGLE_MUTEX_H_
+#define GOOGLE_MUTEX_H_
+
+#include "config.h" // to figure out pthreads support
+
+#if defined(NO_THREADS)
+ typedef int MutexType; // to keep a lock-count
+#elif defined(_WIN32) || defined(__CYGWIN32__) || defined(__CYGWIN64__)
+# ifndef WIN32_LEAN_AND_MEAN
+# define WIN32_LEAN_AND_MEAN // We only need minimal includes
+# endif
+# ifndef NOMINMAX
+# define NOMINMAX // Don't want windows to override min()/max()
+# endif
+# ifdef GMUTEX_TRYLOCK
+ // We need Windows NT or later for TryEnterCriticalSection(). If you
+ // don't need that functionality, you can remove these _WIN32_WINNT
+ // lines, and change TryLock() to assert(0) or something.
+# ifndef _WIN32_WINNT
+# define _WIN32_WINNT 0x0400
+# endif
+# endif
+# include <windows.h>
+ typedef CRITICAL_SECTION MutexType;
+#elif defined(HAVE_PTHREAD) && defined(HAVE_RWLOCK)
+ // Needed for pthread_rwlock_*. If it causes problems, you could take it
+ // out, but then you'd have to unset HAVE_RWLOCK (at least on linux -- it
+ // *does* cause problems for FreeBSD, or MacOSX, but isn't needed
+ // for locking there.)
+# ifdef __linux__
+# if _XOPEN_SOURCE < 500 // including not being defined at all
+# undef _XOPEN_SOURCE
+# define _XOPEN_SOURCE 500 // may be needed to get the rwlock calls
+# endif
+# endif
+# include <pthread.h>
+ typedef pthread_rwlock_t MutexType;
+#elif defined(HAVE_PTHREAD)
+# include <pthread.h>
+ typedef pthread_mutex_t MutexType;
+#else
+# error Need to implement mutex.h for your architecture, or #define NO_THREADS
+#endif
+
+#include <assert.h>
+#include <stdlib.h> // for abort()
+
+#define MUTEX_NAMESPACE gflags_mutex_namespace
+
+namespace MUTEX_NAMESPACE {
+
+class Mutex {
+ public:
+ // This is used for the single-arg constructor
+ enum LinkerInitialized { LINKER_INITIALIZED };
+
+ // Create a Mutex that is not held by anybody. This constructor is
+ // typically used for Mutexes allocated on the heap or the stack.
+ inline Mutex();
+ // This constructor should be used for global, static Mutex objects.
+ // It inhibits work being done by the destructor, which makes it
+ // safer for code that tries to acqiure this mutex in their global
+ // destructor.
+ inline Mutex(LinkerInitialized);
+
+ // Destructor
+ inline ~Mutex();
+
+ inline void Lock(); // Block if needed until free then acquire exclusively
+ inline void Unlock(); // Release a lock acquired via Lock()
+#ifdef GMUTEX_TRYLOCK
+ inline bool TryLock(); // If free, Lock() and return true, else return false
+#endif
+ // Note that on systems that don't support read-write locks, these may
+ // be implemented as synonyms to Lock() and Unlock(). So you can use
+ // these for efficiency, but don't use them anyplace where being able
+ // to do shared reads is necessary to avoid deadlock.
+ inline void ReaderLock(); // Block until free or shared then acquire a share
+ inline void ReaderUnlock(); // Release a read share of this Mutex
+ inline void WriterLock() { Lock(); } // Acquire an exclusive lock
+ inline void WriterUnlock() { Unlock(); } // Release a lock from WriterLock()
+
+ private:
+ MutexType mutex_;
+ // We want to make sure that the compiler sets is_safe_ to true only
+ // when we tell it to, and never makes assumptions is_safe_ is
+ // always true. volatile is the most reliable way to do that.
+ volatile bool is_safe_;
+ // This indicates which constructor was called.
+ bool destroy_;
+
+ inline void SetIsSafe() { is_safe_ = true; }
+
+ // Catch the error of writing Mutex when intending MutexLock.
+ Mutex(Mutex* /*ignored*/) {}
+ // Disallow "evil" constructors
+ Mutex(const Mutex&);
+ void operator=(const Mutex&);
+};
+
+// Now the implementation of Mutex for various systems
+#if defined(NO_THREADS)
+
+// When we don't have threads, we can be either reading or writing,
+// but not both. We can have lots of readers at once (in no-threads
+// mode, that's most likely to happen in recursive function calls),
+// but only one writer. We represent this by having mutex_ be -1 when
+// writing and a number > 0 when reading (and 0 when no lock is held).
+//
+// In debug mode, we assert these invariants, while in non-debug mode
+// we do nothing, for efficiency. That's why everything is in an
+// assert.
+
+Mutex::Mutex() : mutex_(0) { }
+Mutex::Mutex(Mutex::LinkerInitialized) : mutex_(0) { }
+Mutex::~Mutex() { assert(mutex_ == 0); }
+void Mutex::Lock() { assert(--mutex_ == -1); }
+void Mutex::Unlock() { assert(mutex_++ == -1); }
+#ifdef GMUTEX_TRYLOCK
+bool Mutex::TryLock() { if (mutex_) return false; Lock(); return true; }
+#endif
+void Mutex::ReaderLock() { assert(++mutex_ > 0); }
+void Mutex::ReaderUnlock() { assert(mutex_-- > 0); }
+
+#elif defined(_WIN32) || defined(__CYGWIN32__) || defined(__CYGWIN64__)
+
+Mutex::Mutex() : destroy_(true) {
+ InitializeCriticalSection(&mutex_);
+ SetIsSafe();
+}
+Mutex::Mutex(LinkerInitialized) : destroy_(false) {
+ InitializeCriticalSection(&mutex_);
+ SetIsSafe();
+}
+Mutex::~Mutex() { if (destroy_) DeleteCriticalSection(&mutex_); }
+void Mutex::Lock() { if (is_safe_) EnterCriticalSection(&mutex_); }
+void Mutex::Unlock() { if (is_safe_) LeaveCriticalSection(&mutex_); }
+#ifdef GMUTEX_TRYLOCK
+bool Mutex::TryLock() { return is_safe_ ?
+ TryEnterCriticalSection(&mutex_) != 0 : true; }
+#endif
+void Mutex::ReaderLock() { Lock(); } // we don't have read-write locks
+void Mutex::ReaderUnlock() { Unlock(); }
+
+#elif defined(HAVE_PTHREAD) && defined(HAVE_RWLOCK)
+
+#define SAFE_PTHREAD(fncall) do { /* run fncall if is_safe_ is true */ \
+ if (is_safe_ && fncall(&mutex_) != 0) abort(); \
+} while (0)
+
+Mutex::Mutex() : destroy_(true) {
+ SetIsSafe();
+ if (is_safe_ && pthread_rwlock_init(&mutex_, NULL) != 0) abort();
+}
+Mutex::Mutex(Mutex::LinkerInitialized) : destroy_(false) {
+ SetIsSafe();
+ if (is_safe_ && pthread_rwlock_init(&mutex_, NULL) != 0) abort();
+}
+Mutex::~Mutex() { if (destroy_) SAFE_PTHREAD(pthread_rwlock_destroy); }
+void Mutex::Lock() { SAFE_PTHREAD(pthread_rwlock_wrlock); }
+void Mutex::Unlock() { SAFE_PTHREAD(pthread_rwlock_unlock); }
+#ifdef GMUTEX_TRYLOCK
+bool Mutex::TryLock() { return is_safe_ ?
+ pthread_rwlock_trywrlock(&mutex_) == 0 : true; }
+#endif
+void Mutex::ReaderLock() { SAFE_PTHREAD(pthread_rwlock_rdlock); }
+void Mutex::ReaderUnlock() { SAFE_PTHREAD(pthread_rwlock_unlock); }
+#undef SAFE_PTHREAD
+
+#elif defined(HAVE_PTHREAD)
+
+#define SAFE_PTHREAD(fncall) do { /* run fncall if is_safe_ is true */ \
+ if (is_safe_ && fncall(&mutex_) != 0) abort(); \
+} while (0)
+
+Mutex::Mutex() : destroy_(true) {
+ SetIsSafe();
+ if (is_safe_ && pthread_mutex_init(&mutex_, NULL) != 0) abort();
+}
+Mutex::Mutex(Mutex::LinkerInitialized) : destroy_(false) {
+ SetIsSafe();
+ if (is_safe_ && pthread_mutex_init(&mutex_, NULL) != 0) abort();
+}
+Mutex::~Mutex() { if (destroy_) SAFE_PTHREAD(pthread_mutex_destroy); }
+void Mutex::Lock() { SAFE_PTHREAD(pthread_mutex_lock); }
+void Mutex::Unlock() { SAFE_PTHREAD(pthread_mutex_unlock); }
+#ifdef GMUTEX_TRYLOCK
+bool Mutex::TryLock() { return is_safe_ ?
+ pthread_mutex_trylock(&mutex_) == 0 : true; }
+#endif
+void Mutex::ReaderLock() { Lock(); }
+void Mutex::ReaderUnlock() { Unlock(); }
+#undef SAFE_PTHREAD
+
+#endif
+
+// --------------------------------------------------------------------------
+// Some helper classes
+
+// MutexLock(mu) acquires mu when constructed and releases it when destroyed.
+class MutexLock {
+ public:
+ explicit MutexLock(Mutex *mu) : mu_(mu) { mu_->Lock(); }
+ ~MutexLock() { mu_->Unlock(); }
+ private:
+ Mutex * const mu_;
+ // Disallow "evil" constructors
+ MutexLock(const MutexLock&);
+ void operator=(const MutexLock&);
+};
+
+// ReaderMutexLock and WriterMutexLock do the same, for rwlocks
+class ReaderMutexLock {
+ public:
+ explicit ReaderMutexLock(Mutex *mu) : mu_(mu) { mu_->ReaderLock(); }
+ ~ReaderMutexLock() { mu_->ReaderUnlock(); }
+ private:
+ Mutex * const mu_;
+ // Disallow "evil" constructors
+ ReaderMutexLock(const ReaderMutexLock&);
+ void operator=(const ReaderMutexLock&);
+};
+
+class WriterMutexLock {
+ public:
+ explicit WriterMutexLock(Mutex *mu) : mu_(mu) { mu_->WriterLock(); }
+ ~WriterMutexLock() { mu_->WriterUnlock(); }
+ private:
+ Mutex * const mu_;
+ // Disallow "evil" constructors
+ WriterMutexLock(const WriterMutexLock&);
+ void operator=(const WriterMutexLock&);
+};
+
+// Catch bug where variable name is omitted, e.g. MutexLock (&mu);
+#define MutexLock(x) COMPILE_ASSERT(0, mutex_lock_decl_missing_var_name)
+#define ReaderMutexLock(x) COMPILE_ASSERT(0, rmutex_lock_decl_missing_var_name)
+#define WriterMutexLock(x) COMPILE_ASSERT(0, wmutex_lock_decl_missing_var_name)
+
+} // namespace MUTEX_NAMESPACE
+
+using namespace MUTEX_NAMESPACE;
+
+#undef MUTEX_NAMESPACE
+
+#endif /* #define GOOGLE_MUTEX_H__ */
diff --git a/src/third_party/gflags-2.0/src/solaris/libstdc++.la b/src/third_party/gflags-2.0/src/solaris/libstdc++.la
new file mode 100755
index 00000000000..3edf4254192
--- /dev/null
+++ b/src/third_party/gflags-2.0/src/solaris/libstdc++.la
@@ -0,0 +1,51 @@
+# libstdc++.la - a libtool library file
+# Generated by ltmain.sh - GNU libtool 1.4a-GCC3.0 (1.641.2.256 2001/05/28 20:09:07 with GCC-local changes)
+#
+# Please DO NOT delete this file!
+# It is necessary for linking the library.
+
+# ---
+# NOTE: This file lives in /usr/sfw/lib on Solaris 10. Unfortunately,
+# due to an apparent bug in the Solaris 10 6/06 release,
+# /usr/sfw/lib/libstdc++.la is empty. Below is the correct content,
+# according to
+# http://forum.java.sun.com/thread.jspa?threadID=5073150
+# By passing LDFLAGS='-Lsrc/solaris' to configure, make will pick up
+# this copy of the file rather than the empty copy in /usr/sfw/lib.
+#
+# Also see
+# http://www.technicalarticles.org/index.php/Compiling_MySQL_5.0_on_Solaris_10
+#
+# Note: this is for 32-bit systems. If you have a 64-bit system,
+# uncomment the appropriate dependency_libs line below.
+# ----
+
+# The name that we can dlopen(3).
+dlname='libstdc++.so.6'
+
+# Names of this library.
+library_names='libstdc++.so.6.0.3 libstdc++.so.6 libstdc++.so'
+
+# The name of the static archive.
+old_library='libstdc++.a'
+
+# Libraries that this one depends upon.
+# 32-bit version:
+dependency_libs='-lc -lm -L/usr/sfw/lib -lgcc_s'
+# 64-bit version:
+#dependency_libs='-L/lib/64 -lc -lm -L/usr/sfw/lib/64 -lgcc_s'
+
+# Version information for libstdc++.
+current=6
+age=0
+revision=3
+
+# Is this an already installed library?
+installed=yes
+
+# Files to dlopen/dlpreopen
+dlopen=''
+dlpreopen=''
+
+# Directory that this library needs to be installed in:
+libdir='/usr/sfw/lib'
diff --git a/src/third_party/gflags-2.0/src/stamp-h1 b/src/third_party/gflags-2.0/src/stamp-h1
new file mode 100755
index 00000000000..57ea58e405b
--- /dev/null
+++ b/src/third_party/gflags-2.0/src/stamp-h1
@@ -0,0 +1 @@
+timestamp for src/config.h
diff --git a/src/third_party/gflags-2.0/src/util.h b/src/third_party/gflags-2.0/src/util.h
new file mode 100755
index 00000000000..91ec675d029
--- /dev/null
+++ b/src/third_party/gflags-2.0/src/util.h
@@ -0,0 +1,333 @@
+// Copyright (c) 2011, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// ---
+//
+// Some generically useful utility routines that in google-land would
+// be their own projects. We make a shortened version here.
+
+#ifndef GFLAGS_UTIL_H_
+#define GFLAGS_UTIL_H_
+
+#include <assert.h>
+#include <config.h>
+#ifdef HAVE_INTTYPES_H
+# include <inttypes.h>
+#endif
+#include <stdarg.h> // for va_*
+#ifdef _WIN32
+# include <varargs.h>
+#endif
+#include <stdlib.h>
+#include <stdio.h>
+#include <iostream>
+#include <string>
+#ifdef HAVE_SYS_STAT_H
+# include <sys/stat.h>
+#endif // for mkdir()
+
+_START_GOOGLE_NAMESPACE_
+
+// This is used for unittests for death-testing. It is defined in gflags.cc.
+extern GFLAGS_DLL_DECL void (*gflags_exitfunc)(int);
+
+// Work properly if either strtoll or strtoq is on this system
+#ifdef HAVE_STRTOLL
+# define strto64 strtoll
+# define strtou64 strtoull
+#elif HAVE_STRTOQ
+# define strto64 strtoq
+# define strtou64 strtouq
+#else
+// Neither strtoll nor strtoq are defined. I hope strtol works!
+# define strto64 strtol
+# define strtou64 strtoul
+#endif
+
+// If we have inttypes.h, it will have defined PRId32/etc for us. If
+// not, take our best guess.
+#ifndef PRId32
+# define PRId32 "d"
+#endif
+#ifndef PRId64
+# define PRId64 "lld"
+#endif
+#ifndef PRIu64
+# define PRIu64 "llu"
+#endif
+
+typedef signed char int8;
+typedef unsigned char uint8;
+
+// -- utility macros ---------------------------------------------------------
+
+template <bool> struct CompileAssert {};
+#define COMPILE_ASSERT(expr, msg) \
+ typedef CompileAssert<(bool(expr))> msg[bool(expr) ? 1 : -1]
+
+// Returns the number of elements in an array.
+#define arraysize(arr) (sizeof(arr)/sizeof(*(arr)))
+
+
+// -- logging and testing ---------------------------------------------------
+
+// For now, we ignore the level for logging, and don't show *VLOG's at
+// all, except by hand-editing the lines below
+#define LOG(level) std::cerr
+#define VLOG(level) if (true) {} else std::cerr
+#define DVLOG(level) if (true) {} else std::cerr
+
+// CHECK dies with a fatal error if condition is not true. It is *not*
+// controlled by NDEBUG, so the check will be executed regardless of
+// compilation mode. Therefore, it is safe to do things like:
+// CHECK(fp->Write(x) == 4)
+// We allow stream-like objects after this for debugging, but they're ignored.
+#define EXPECT_TRUE(condition) \
+ if (true) { \
+ if (!(condition)) { \
+ fprintf(stderr, "Check failed: %s\n", #condition); \
+ exit(1); \
+ } \
+ } else std::cerr << ""
+
+#define EXPECT_OP(op, val1, val2) \
+ if (true) { \
+ if (!((val1) op (val2))) { \
+ fprintf(stderr, "Check failed: %s %s %s\n", #val1, #op, #val2); \
+ exit(1); \
+ } \
+ } else std::cerr << ""
+
+#define EXPECT_EQ(val1, val2) EXPECT_OP(==, val1, val2)
+#define EXPECT_NE(val1, val2) EXPECT_OP(!=, val1, val2)
+#define EXPECT_LE(val1, val2) EXPECT_OP(<=, val1, val2)
+#define EXPECT_LT(val1, val2) EXPECT_OP(< , val1, val2)
+#define EXPECT_GE(val1, val2) EXPECT_OP(>=, val1, val2)
+#define EXPECT_GT(val1, val2) EXPECT_OP(> , val1, val2)
+#define EXPECT_FALSE(cond) EXPECT_TRUE(!(cond))
+
+// C99 declares isnan and isinf should be macros, so the #ifdef test
+// should be reliable everywhere. Of course, it's not, but these
+// are testing pertty marginal functionality anyway, so it's ok to
+// not-run them even in situations they might, with effort, be made to work.
+#ifdef isnan // Some compilers, like sun's for Solaris 10, don't define this
+#define EXPECT_NAN(arg) \
+ do { \
+ if (!isnan(arg)) { \
+ fprintf(stderr, "Check failed: isnan(%s)\n", #arg); \
+ exit(1); \
+ } \
+ } while (0)
+#else
+#define EXPECT_NAN(arg)
+#endif
+
+#ifdef isinf // Some compilers, like sun's for Solaris 10, don't define this
+#define EXPECT_INF(arg) \
+ do { \
+ if (!isinf(arg)) { \
+ fprintf(stderr, "Check failed: isinf(%s)\n", #arg); \
+ exit(1); \
+ } \
+ } while (0)
+#else
+#define EXPECT_INF(arg)
+#endif
+
+#define EXPECT_DOUBLE_EQ(val1, val2) \
+ do { \
+ if (((val1) < (val2) - 0.001 || (val1) > (val2) + 0.001)) { \
+ fprintf(stderr, "Check failed: %s == %s\n", #val1, #val2); \
+ exit(1); \
+ } \
+ } while (0)
+
+#define EXPECT_STREQ(val1, val2) \
+ do { \
+ if (strcmp((val1), (val2)) != 0) { \
+ fprintf(stderr, "Check failed: streq(%s, %s)\n", #val1, #val2); \
+ exit(1); \
+ } \
+ } while (0)
+
+// Call this in a .cc file where you will later call RUN_ALL_TESTS in main().
+#define TEST_INIT \
+ static std::vector<void (*)()> g_testlist; /* the tests to run */ \
+ static int RUN_ALL_TESTS() { \
+ std::vector<void (*)()>::const_iterator it; \
+ for (it = g_testlist.begin(); it != g_testlist.end(); ++it) { \
+ (*it)(); /* The test will error-exit if there's a problem. */ \
+ } \
+ fprintf(stderr, "\nPassed %d tests\n\nPASS\n", \
+ static_cast<int>(g_testlist.size())); \
+ return 0; \
+ }
+
+// Note that this macro uses a FlagSaver to keep tests isolated.
+#define TEST(a, b) \
+ struct Test_##a##_##b { \
+ Test_##a##_##b() { g_testlist.push_back(&Run); } \
+ static void Run() { \
+ FlagSaver fs; \
+ fprintf(stderr, "Running test %s/%s\n", #a, #b); \
+ RunTest(); \
+ } \
+ static void RunTest(); \
+ }; \
+ static Test_##a##_##b g_test_##a##_##b; \
+ void Test_##a##_##b::RunTest()
+
+// This is a dummy class that eases the google->opensource transition.
+namespace testing {
+class Test {};
+}
+
+// Call this in a .cc file where you will later call EXPECT_DEATH
+#define EXPECT_DEATH_INIT \
+ static bool g_called_exit; \
+ static void CalledExit(int) { g_called_exit = true; }
+
+#define EXPECT_DEATH(fn, msg) \
+ do { \
+ g_called_exit = false; \
+ gflags_exitfunc = &CalledExit; \
+ fn; \
+ gflags_exitfunc = &exit; /* set back to its default */ \
+ if (!g_called_exit) { \
+ fprintf(stderr, "Function didn't die (%s): %s\n", msg, #fn); \
+ exit(1); \
+ } \
+ } while (0)
+
+#define GTEST_HAS_DEATH_TEST 1
+
+// -- path routines ----------------------------------------------------------
+
+// Tries to create the directory path as a temp-dir. If it fails,
+// changes path to some directory it *can* create.
+#if defined(__MINGW32__)
+#include <io.h>
+inline void MakeTmpdir(std::string* path) {
+ // I had trouble creating a directory in /tmp from mingw
+ *path = "./gflags_unittest_testdir";
+ mkdir(path->c_str()); // mingw has a weird one-arg mkdir
+}
+#elif defined(_MSC_VER)
+#include <direct.h>
+#include <windows.h>
+inline void MakeTmpdir(std::string* path) {
+ char tmppath_buffer[1024];
+ int tmppath_len = GetTempPathA(sizeof(tmppath_buffer), tmppath_buffer);
+ assert(tmppath_len > 0 && tmppath_len < sizeof(tmppath_buffer));
+ assert(tmppath_buffer[tmppath_len - 1] == '\\'); // API guarantees it
+ *path = std::string(tmppath_buffer) + "gflags_unittest_testdir";
+ _mkdir(path->c_str());
+}
+#else
+inline void MakeTmpdir(std::string* path) {
+ mkdir(path->c_str(), 0755);
+}
+#endif
+
+#ifdef _WIN32
+#define va_copy(a,b) (void)((a)=(b))
+#endif
+
+// -- string routines --------------------------------------------------------
+
+inline void InternalStringPrintf(std::string* output, const char* format,
+ va_list ap) {
+ char space[128]; // try a small buffer and hope it fits
+
+ // It's possible for methods that use a va_list to invalidate
+ // the data in it upon use. The fix is to make a copy
+ // of the structure before using it and use that copy instead.
+ va_list backup_ap;
+ va_copy(backup_ap, ap);
+ int bytes_written = vsnprintf(space, sizeof(space), format, backup_ap);
+ va_end(backup_ap);
+
+ if ((bytes_written >= 0) && ((size_t)bytes_written < sizeof(space))) {
+ output->append(space, bytes_written);
+ return;
+ }
+
+ // Repeatedly increase buffer size until it fits.
+ int length = sizeof(space);
+ while (true) {
+ if (bytes_written < 0) {
+ // Older snprintf() behavior. :-( Just try doubling the buffer size
+ length *= 2;
+ } else {
+ // We need exactly "bytes_written+1" characters
+ length = bytes_written+1;
+ }
+ char* buf = new char[length];
+
+ // Restore the va_list before we use it again
+ va_copy(backup_ap, ap);
+ bytes_written = vsnprintf(buf, length, format, backup_ap);
+ va_end(backup_ap);
+
+ if ((bytes_written >= 0) && (bytes_written < length)) {
+ output->append(buf, bytes_written);
+ delete[] buf;
+ return;
+ }
+ delete[] buf;
+ }
+}
+
+// Clears output before writing to it.
+inline void SStringPrintf(std::string* output, const char* format, ...) {
+ va_list ap;
+ va_start(ap, format);
+ output->clear();
+ InternalStringPrintf(output, format, ap);
+ va_end(ap);
+}
+
+inline void StringAppendF(std::string* output, const char* format, ...) {
+ va_list ap;
+ va_start(ap, format);
+ InternalStringPrintf(output, format, ap);
+ va_end(ap);
+}
+
+inline std::string StringPrintf(const char* format, ...) {
+ va_list ap;
+ va_start(ap, format);
+ std::string output;
+ InternalStringPrintf(&output, format, ap);
+ va_end(ap);
+ return output;
+}
+
+_END_GOOGLE_NAMESPACE_
+
+#endif // GFLAGS_UTIL_H_
diff --git a/src/third_party/gflags-2.0/src/windows/config.h b/src/third_party/gflags-2.0/src/windows/config.h
new file mode 100755
index 00000000000..dcca757e493
--- /dev/null
+++ b/src/third_party/gflags-2.0/src/windows/config.h
@@ -0,0 +1,139 @@
+/* src/config.h.in. Generated from configure.ac by autoheader. */
+
+/* Sometimes we accidentally #include this config.h instead of the one
+ in .. -- this is particularly true for msys/mingw, which uses the
+ unix config.h but also runs code in the windows directory.
+ */
+#ifdef __MINGW32__
+#include "../config.h"
+#define GOOGLE_GFLAGS_WINDOWS_CONFIG_H_
+#endif
+
+#ifndef GOOGLE_GFLAGS_WINDOWS_CONFIG_H_
+#define GOOGLE_GFLAGS_WINDOWS_CONFIG_H_
+
+/* Always the empty-string on non-windows systems. On windows, should be
+ "__declspec(dllexport)". This way, when we compile the dll, we export our
+ functions/classes. It's safe to define this here because config.h is only
+ used internally, to compile the DLL, and every DLL source file #includes
+ "config.h" before anything else. */
+#ifndef GFLAGS_DLL_DECL
+# define GFLAGS_IS_A_DLL 1 /* not set if you're statically linking */
+# define GFLAGS_DLL_DECL __declspec(dllexport)
+# define GFLAGS_DLL_DECL_FOR_UNITTESTS __declspec(dllimport)
+#endif
+
+/* Namespace for Google classes */
+#define GOOGLE_NAMESPACE ::google
+
+/* Define to 1 if you have the <dlfcn.h> header file. */
+#undef HAVE_DLFCN_H
+
+/* Define to 1 if you have the <fnmatch.h> header file. */
+#undef HAVE_FNMATCH_H
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#undef HAVE_INTTYPES_H
+
+/* Define to 1 if you have the <memory.h> header file. */
+#undef HAVE_MEMORY_H
+
+/* define if the compiler implements namespaces */
+#define HAVE_NAMESPACES 1
+
+/* Define if you have POSIX threads libraries and header files. */
+#undef HAVE_PTHREAD
+
+/* Define to 1 if you have the `putenv' function. */
+#define HAVE_PUTENV 1
+
+/* Define to 1 if you have the `setenv' function. */
+#undef HAVE_SETENV
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#undef HAVE_STDINT_H
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#define HAVE_STDLIB_H 1
+
+/* Define to 1 if you have the <strings.h> header file. */
+#undef HAVE_STRINGS_H
+
+/* Define to 1 if you have the <string.h> header file. */
+#define HAVE_STRING_H 1
+
+/* Define to 1 if you have the `strtoll' function. */
+#define HAVE_STRTOLL 1
+
+/* Define to 1 if you have the `strtoq' function. */
+#define HAVE_STRTOQ 1
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#define HAVE_SYS_STAT_H 1
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#define HAVE_SYS_TYPES_H 1
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#undef HAVE_UNISTD_H
+
+/* define if your compiler has __attribute__ */
+#undef HAVE___ATTRIBUTE__
+
+/* Define to the sub-directory in which libtool stores uninstalled libraries.
+ */
+#undef LT_OBJDIR
+
+/* Name of package */
+#undef PACKAGE
+
+/* Define to the address where bug reports for this package should be sent. */
+#undef PACKAGE_BUGREPORT
+
+/* Define to the full name of this package. */
+#undef PACKAGE_NAME
+
+/* Define to the full name and version of this package. */
+#undef PACKAGE_STRING
+
+/* Define to the one symbol short name of this package. */
+#undef PACKAGE_TARNAME
+
+/* Define to the home page for this package. */
+#undef PACKAGE_URL
+
+/* Define to the version of this package. */
+#undef PACKAGE_VERSION
+
+/* Define to necessary symbol if this constant uses a non-standard name on
+ your system. */
+#undef PTHREAD_CREATE_JOINABLE
+
+/* Define to 1 if you have the ANSI C header files. */
+#define STDC_HEADERS 1
+
+/* the namespace where STL code like vector<> is defined */
+#define STL_NAMESPACE std
+
+/* Version number of package */
+#undef VERSION
+
+/* Stops putting the code inside the Google namespace */
+#define _END_GOOGLE_NAMESPACE_ }
+
+/* Puts following code inside the Google namespace */
+#define _START_GOOGLE_NAMESPACE_ namespace google {
+
+// ---------------------------------------------------------------------
+// Extra stuff not found in config.h.in
+
+// This must be defined before the windows.h is included. It's needed
+// for mutex.h, to give access to the TryLock method.
+#ifndef _WIN32_WINNT
+# define _WIN32_WINNT 0x0400
+#endif
+
+// TODO(csilvers): include windows/port.h in every relevant source file instead?
+#include "windows/port.h"
+
+#endif /* GOOGLE_GFLAGS_WINDOWS_CONFIG_H_ */
diff --git a/src/third_party/gflags-2.0/src/windows/gflags/gflags.h b/src/third_party/gflags-2.0/src/windows/gflags/gflags.h
new file mode 100755
index 00000000000..8b70a37cf9a
--- /dev/null
+++ b/src/third_party/gflags-2.0/src/windows/gflags/gflags.h
@@ -0,0 +1,569 @@
+// Copyright (c) 2006, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// ---
+// Revamped and reorganized by Craig Silverstein
+//
+// This is the file that should be included by any file which declares
+// or defines a command line flag or wants to parse command line flags
+// or print a program usage message (which will include information about
+// flags). Executive summary, in the form of an example foo.cc file:
+//
+// #include "foo.h" // foo.h has a line "DECLARE_int32(start);"
+// #include "validators.h" // hypothetical file defining ValidateIsFile()
+//
+// DEFINE_int32(end, 1000, "The last record to read");
+//
+// DEFINE_string(filename, "my_file.txt", "The file to read");
+// // Crash if the specified file does not exist.
+// static bool dummy = RegisterFlagValidator(&FLAGS_filename,
+// &ValidateIsFile);
+//
+// DECLARE_bool(verbose); // some other file has a DEFINE_bool(verbose, ...)
+//
+// void MyFunc() {
+// if (FLAGS_verbose) printf("Records %d-%d\n", FLAGS_start, FLAGS_end);
+// }
+//
+// Then, at the command-line:
+// ./foo --noverbose --start=5 --end=100
+//
+// For more details, see
+// doc/gflags.html
+//
+// --- A note about thread-safety:
+//
+// We describe many functions in this routine as being thread-hostile,
+// thread-compatible, or thread-safe. Here are the meanings we use:
+//
+// thread-safe: it is safe for multiple threads to call this routine
+// (or, when referring to a class, methods of this class)
+// concurrently.
+// thread-hostile: it is not safe for multiple threads to call this
+// routine (or methods of this class) concurrently. In gflags,
+// most thread-hostile routines are intended to be called early in,
+// or even before, main() -- that is, before threads are spawned.
+// thread-compatible: it is safe for multiple threads to read from
+// this variable (when applied to variables), or to call const
+// methods of this class (when applied to classes), as long as no
+// other thread is writing to the variable or calling non-const
+// methods of this class.
+
+#ifndef BASE_COMMANDLINEFLAGS_H_
+#define BASE_COMMANDLINEFLAGS_H_
+
+#include <string>
+#include <vector>
+#include <gflags/gflags_declare.h> // IWYU pragma: export
+namespace google {
+
+//
+// NOTE: all functions below MUST have an explicit 'extern' before
+// them. Our automated opensourcing tools use this as a signal to do
+// appropriate munging for windows, which needs to add GFLAGS_DLL_DECL.
+//
+#if defined(_MSC_VER) && !defined(GFLAGS_DLL_DECL)
+# define GFLAGS_DLL_DECL __declspec(dllimport)
+#endif
+#if defined(_MSC_VER) && !defined(GFLAGS_DLL_DEFINE_FLAG)
+# define GFLAGS_DLL_DEFINE_FLAG __declspec(dllexport)
+#endif
+
+
+// --------------------------------------------------------------------
+// To actually define a flag in a file, use DEFINE_bool,
+// DEFINE_string, etc. at the bottom of this file. You may also find
+// it useful to register a validator with the flag. This ensures that
+// when the flag is parsed from the commandline, or is later set via
+// SetCommandLineOption, we call the validation function. It is _not_
+// called when you assign the value to the flag directly using the = operator.
+//
+// The validation function should return true if the flag value is valid, and
+// false otherwise. If the function returns false for the new setting of the
+// flag, the flag will retain its current value. If it returns false for the
+// default value, ParseCommandLineFlags() will die.
+//
+// This function is safe to call at global construct time (as in the
+// example below).
+//
+// Example use:
+// static bool ValidatePort(const char* flagname, int32 value) {
+// if (value > 0 && value < 32768) // value is ok
+// return true;
+// printf("Invalid value for --%s: %d\n", flagname, (int)value);
+// return false;
+// }
+// DEFINE_int32(port, 0, "What port to listen on");
+// static bool dummy = RegisterFlagValidator(&FLAGS_port, &ValidatePort);
+
+// Returns true if successfully registered, false if not (because the
+// first argument doesn't point to a command-line flag, or because a
+// validator is already registered for this flag).
+extern GFLAGS_DLL_DECL bool RegisterFlagValidator(const bool* flag,
+ bool (*validate_fn)(const char*, bool));
+extern GFLAGS_DLL_DECL bool RegisterFlagValidator(const int32* flag,
+ bool (*validate_fn)(const char*, int32));
+extern GFLAGS_DLL_DECL bool RegisterFlagValidator(const int64* flag,
+ bool (*validate_fn)(const char*, int64));
+extern GFLAGS_DLL_DECL bool RegisterFlagValidator(const uint64* flag,
+ bool (*validate_fn)(const char*, uint64));
+extern GFLAGS_DLL_DECL bool RegisterFlagValidator(const double* flag,
+ bool (*validate_fn)(const char*, double));
+extern GFLAGS_DLL_DECL bool RegisterFlagValidator(const std::string* flag,
+ bool (*validate_fn)(const char*,
+ const std::string&));
+
+
+// --------------------------------------------------------------------
+// These methods are the best way to get access to info about the
+// list of commandline flags. Note that these routines are pretty slow.
+// GetAllFlags: mostly-complete info about the list, sorted by file.
+// ShowUsageWithFlags: pretty-prints the list to stdout (what --help does)
+// ShowUsageWithFlagsRestrict: limit to filenames with restrict as a substr
+//
+// In addition to accessing flags, you can also access argv[0] (the program
+// name) and argv (the entire commandline), which we sock away a copy of.
+// These variables are static, so you should only set them once.
+
+struct GFLAGS_DLL_DECL CommandLineFlagInfo {
+ std::string name; // the name of the flag
+ std::string type; // the type of the flag: int32, etc
+ std::string description; // the "help text" associated with the flag
+ std::string current_value; // the current value, as a string
+ std::string default_value; // the default value, as a string
+ std::string filename; // 'cleaned' version of filename holding the flag
+ bool has_validator_fn; // true if RegisterFlagValidator called on this flag
+ bool is_default; // true if the flag has the default value and
+ // has not been set explicitly from the cmdline
+ // or via SetCommandLineOption
+ const void* flag_ptr; // pointer to the flag's current value (i.e. FLAGS_foo)
+};
+
+// Using this inside of a validator is a recipe for a deadlock.
+// TODO(user) Fix locking when validators are running, to make it safe to
+// call validators during ParseAllFlags.
+// Also make sure then to uncomment the corresponding unit test in
+// gflags_unittest.sh
+extern GFLAGS_DLL_DECL void GetAllFlags(std::vector<CommandLineFlagInfo>* OUTPUT);
+// These two are actually defined in gflags_reporting.cc.
+extern GFLAGS_DLL_DECL void ShowUsageWithFlags(const char *argv0); // what --help does
+extern GFLAGS_DLL_DECL void ShowUsageWithFlagsRestrict(const char *argv0, const char *restrict);
+
+// Create a descriptive string for a flag.
+// Goes to some trouble to make pretty line breaks.
+extern GFLAGS_DLL_DECL std::string DescribeOneFlag(const CommandLineFlagInfo& flag);
+
+// Thread-hostile; meant to be called before any threads are spawned.
+extern GFLAGS_DLL_DECL void SetArgv(int argc, const char** argv);
+
+// The following functions are thread-safe as long as SetArgv() is
+// only called before any threads start.
+extern GFLAGS_DLL_DECL const std::vector<std::string>& GetArgvs();
+extern GFLAGS_DLL_DECL const char* GetArgv(); // all of argv as a string
+extern GFLAGS_DLL_DECL const char* GetArgv0(); // only argv0
+extern GFLAGS_DLL_DECL uint32 GetArgvSum(); // simple checksum of argv
+extern GFLAGS_DLL_DECL const char* ProgramInvocationName(); // argv0, or "UNKNOWN" if not set
+extern GFLAGS_DLL_DECL const char* ProgramInvocationShortName(); // basename(argv0)
+
+// ProgramUsage() is thread-safe as long as SetUsageMessage() is only
+// called before any threads start.
+extern GFLAGS_DLL_DECL const char* ProgramUsage(); // string set by SetUsageMessage()
+
+// VersionString() is thread-safe as long as SetVersionString() is only
+// called before any threads start.
+extern GFLAGS_DLL_DECL const char* VersionString(); // string set by SetVersionString()
+
+
+
+// --------------------------------------------------------------------
+// Normally you access commandline flags by just saying "if (FLAGS_foo)"
+// or whatever, and set them by calling "FLAGS_foo = bar" (or, more
+// commonly, via the DEFINE_foo macro). But if you need a bit more
+// control, we have programmatic ways to get/set the flags as well.
+// These programmatic ways to access flags are thread-safe, but direct
+// access is only thread-compatible.
+
+// Return true iff the flagname was found.
+// OUTPUT is set to the flag's value, or unchanged if we return false.
+extern GFLAGS_DLL_DECL bool GetCommandLineOption(const char* name, std::string* OUTPUT);
+
+// Return true iff the flagname was found. OUTPUT is set to the flag's
+// CommandLineFlagInfo or unchanged if we return false.
+extern GFLAGS_DLL_DECL bool GetCommandLineFlagInfo(const char* name,
+ CommandLineFlagInfo* OUTPUT);
+
+// Return the CommandLineFlagInfo of the flagname. exit() if name not found.
+// Example usage, to check if a flag's value is currently the default value:
+// if (GetCommandLineFlagInfoOrDie("foo").is_default) ...
+extern GFLAGS_DLL_DECL CommandLineFlagInfo GetCommandLineFlagInfoOrDie(const char* name);
+
+enum GFLAGS_DLL_DECL FlagSettingMode {
+ // update the flag's value (can call this multiple times).
+ SET_FLAGS_VALUE,
+ // update the flag's value, but *only if* it has not yet been updated
+ // with SET_FLAGS_VALUE, SET_FLAG_IF_DEFAULT, or "FLAGS_xxx = nondef".
+ SET_FLAG_IF_DEFAULT,
+ // set the flag's default value to this. If the flag has not yet updated
+ // yet (via SET_FLAGS_VALUE, SET_FLAG_IF_DEFAULT, or "FLAGS_xxx = nondef")
+ // change the flag's current value to the new default value as well.
+ SET_FLAGS_DEFAULT
+};
+
+// Set a particular flag ("command line option"). Returns a string
+// describing the new value that the option has been set to. The
+// return value API is not well-specified, so basically just depend on
+// it to be empty if the setting failed for some reason -- the name is
+// not a valid flag name, or the value is not a valid value -- and
+// non-empty else.
+
+// SetCommandLineOption uses set_mode == SET_FLAGS_VALUE (the common case)
+extern GFLAGS_DLL_DECL std::string SetCommandLineOption(const char* name, const char* value);
+extern GFLAGS_DLL_DECL std::string SetCommandLineOptionWithMode(const char* name, const char* value,
+ FlagSettingMode set_mode);
+
+
+// --------------------------------------------------------------------
+// Saves the states (value, default value, whether the user has set
+// the flag, registered validators, etc) of all flags, and restores
+// them when the FlagSaver is destroyed. This is very useful in
+// tests, say, when you want to let your tests change the flags, but
+// make sure that they get reverted to the original states when your
+// test is complete.
+//
+// Example usage:
+// void TestFoo() {
+// FlagSaver s1;
+// FLAG_foo = false;
+// FLAG_bar = "some value";
+//
+// // test happens here. You can return at any time
+// // without worrying about restoring the FLAG values.
+// }
+//
+// Note: This class is marked with ATTRIBUTE_UNUSED because all the
+// work is done in the constructor and destructor, so in the standard
+// usage example above, the compiler would complain that it's an
+// unused variable.
+//
+// This class is thread-safe. However, its destructor writes to
+// exactly the set of flags that have changed value during its
+// lifetime, so concurrent _direct_ access to those flags
+// (i.e. FLAGS_foo instead of {Get,Set}CommandLineOption()) is unsafe.
+
+class GFLAGS_DLL_DECL FlagSaver {
+ public:
+ FlagSaver();
+ ~FlagSaver();
+
+ private:
+ class FlagSaverImpl* impl_; // we use pimpl here to keep API steady
+
+ FlagSaver(const FlagSaver&); // no copying!
+ void operator=(const FlagSaver&);
+}
+;
+
+// --------------------------------------------------------------------
+// Some deprecated or hopefully-soon-to-be-deprecated functions.
+
+// This is often used for logging. TODO(csilvers): figure out a better way
+extern GFLAGS_DLL_DECL std::string CommandlineFlagsIntoString();
+// Usually where this is used, a FlagSaver should be used instead.
+extern GFLAGS_DLL_DECL bool ReadFlagsFromString(const std::string& flagfilecontents,
+ const char* prog_name,
+ bool errors_are_fatal); // uses SET_FLAGS_VALUE
+
+// These let you manually implement --flagfile functionality.
+// DEPRECATED.
+extern GFLAGS_DLL_DECL bool AppendFlagsIntoFile(const std::string& filename, const char* prog_name);
+extern GFLAGS_DLL_DECL bool ReadFromFlagsFile(const std::string& filename, const char* prog_name,
+ bool errors_are_fatal); // uses SET_FLAGS_VALUE
+
+
+// --------------------------------------------------------------------
+// Useful routines for initializing flags from the environment.
+// In each case, if 'varname' does not exist in the environment
+// return defval. If 'varname' does exist but is not valid
+// (e.g., not a number for an int32 flag), abort with an error.
+// Otherwise, return the value. NOTE: for booleans, for true use
+// 't' or 'T' or 'true' or '1', for false 'f' or 'F' or 'false' or '0'.
+
+extern GFLAGS_DLL_DECL bool BoolFromEnv(const char *varname, bool defval);
+extern GFLAGS_DLL_DECL int32 Int32FromEnv(const char *varname, int32 defval);
+extern GFLAGS_DLL_DECL int64 Int64FromEnv(const char *varname, int64 defval);
+extern GFLAGS_DLL_DECL uint64 Uint64FromEnv(const char *varname, uint64 defval);
+extern GFLAGS_DLL_DECL double DoubleFromEnv(const char *varname, double defval);
+extern GFLAGS_DLL_DECL const char *StringFromEnv(const char *varname, const char *defval);
+
+
+// --------------------------------------------------------------------
+// The next two functions parse gflags from main():
+
+// Set the "usage" message for this program. For example:
+// string usage("This program does nothing. Sample usage:\n");
+// usage += argv[0] + " <uselessarg1> <uselessarg2>";
+// SetUsageMessage(usage);
+// Do not include commandline flags in the usage: we do that for you!
+// Thread-hostile; meant to be called before any threads are spawned.
+extern GFLAGS_DLL_DECL void SetUsageMessage(const std::string& usage);
+
+// Sets the version string, which is emitted with --version.
+// For instance: SetVersionString("1.3");
+// Thread-hostile; meant to be called before any threads are spawned.
+extern GFLAGS_DLL_DECL void SetVersionString(const std::string& version);
+
+
+// Looks for flags in argv and parses them. Rearranges argv to put
+// flags first, or removes them entirely if remove_flags is true.
+// If a flag is defined more than once in the command line or flag
+// file, the last definition is used. Returns the index (into argv)
+// of the first non-flag argument.
+// See top-of-file for more details on this function.
+#ifndef SWIG // In swig, use ParseCommandLineFlagsScript() instead.
+extern GFLAGS_DLL_DECL uint32 ParseCommandLineFlags(int *argc, char*** argv, bool remove_flags);
+#endif
+
+
+// Calls to ParseCommandLineNonHelpFlags and then to
+// HandleCommandLineHelpFlags can be used instead of a call to
+// ParseCommandLineFlags during initialization, in order to allow for
+// changing default values for some FLAGS (via
+// e.g. SetCommandLineOptionWithMode calls) between the time of
+// command line parsing and the time of dumping help information for
+// the flags as a result of command line parsing. If a flag is
+// defined more than once in the command line or flag file, the last
+// definition is used. Returns the index (into argv) of the first
+// non-flag argument. (If remove_flags is true, will always return 1.)
+extern GFLAGS_DLL_DECL uint32 ParseCommandLineNonHelpFlags(int *argc, char*** argv,
+ bool remove_flags);
+// This is actually defined in gflags_reporting.cc.
+// This function is misnamed (it also handles --version, etc.), but
+// it's too late to change that now. :-(
+extern GFLAGS_DLL_DECL void HandleCommandLineHelpFlags(); // in gflags_reporting.cc
+
+// Allow command line reparsing. Disables the error normally
+// generated when an unknown flag is found, since it may be found in a
+// later parse. Thread-hostile; meant to be called before any threads
+// are spawned.
+extern GFLAGS_DLL_DECL void AllowCommandLineReparsing();
+
+// Reparse the flags that have not yet been recognized. Only flags
+// registered since the last parse will be recognized. Any flag value
+// must be provided as part of the argument using "=", not as a
+// separate command line argument that follows the flag argument.
+// Intended for handling flags from dynamically loaded libraries,
+// since their flags are not registered until they are loaded.
+extern GFLAGS_DLL_DECL void ReparseCommandLineNonHelpFlags();
+
+// Clean up memory allocated by flags. This is only needed to reduce
+// the quantity of "potentially leaked" reports emitted by memory
+// debugging tools such as valgrind. It is not required for normal
+// operation, or for the google perftools heap-checker. It must only
+// be called when the process is about to exit, and all threads that
+// might access flags are quiescent. Referencing flags after this is
+// called will have unexpected consequences. This is not safe to run
+// when multiple threads might be running: the function is
+// thread-hostile.
+extern GFLAGS_DLL_DECL void ShutDownCommandLineFlags();
+
+
+// --------------------------------------------------------------------
+// Now come the command line flag declaration/definition macros that
+// will actually be used. They're kind of hairy. A major reason
+// for this is initialization: we want people to be able to access
+// variables in global constructors and have that not crash, even if
+// their global constructor runs before the global constructor here.
+// (Obviously, we can't guarantee the flags will have the correct
+// default value in that case, but at least accessing them is safe.)
+// The only way to do that is have flags point to a static buffer.
+// So we make one, using a union to ensure proper alignment, and
+// then use placement-new to actually set up the flag with the
+// correct default value. In the same vein, we have to worry about
+// flag access in global destructors, so FlagRegisterer has to be
+// careful never to destroy the flag-values it constructs.
+//
+// Note that when we define a flag variable FLAGS_<name>, we also
+// preemptively define a junk variable, FLAGS_no<name>. This is to
+// cause a link-time error if someone tries to define 2 flags with
+// names like "logging" and "nologging". We do this because a bool
+// flag FLAG can be set from the command line to true with a "-FLAG"
+// argument, and to false with a "-noFLAG" argument, and so this can
+// potentially avert confusion.
+//
+// We also put flags into their own namespace. It is purposefully
+// named in an opaque way that people should have trouble typing
+// directly. The idea is that DEFINE puts the flag in the weird
+// namespace, and DECLARE imports the flag from there into the current
+// namespace. The net result is to force people to use DECLARE to get
+// access to a flag, rather than saying "extern bool FLAGS_whatever;"
+// or some such instead. We want this so we can put extra
+// functionality (like sanity-checking) in DECLARE if we want, and
+// make sure it is picked up everywhere.
+//
+// We also put the type of the variable in the namespace, so that
+// people can't DECLARE_int32 something that they DEFINE_bool'd
+// elsewhere.
+
+class GFLAGS_DLL_DECL FlagRegisterer {
+ public:
+ FlagRegisterer(const char* name, const char* type,
+ const char* help, const char* filename,
+ void* current_storage, void* defvalue_storage);
+};
+
+// If your application #defines STRIP_FLAG_HELP to a non-zero value
+// before #including this file, we remove the help message from the
+// binary file. This can reduce the size of the resulting binary
+// somewhat, and may also be useful for security reasons.
+
+extern GFLAGS_DLL_DECL const char kStrippedFlagHelp[];
+
+}
+
+#ifndef SWIG // In swig, ignore the main flag declarations
+
+#if defined(STRIP_FLAG_HELP) && STRIP_FLAG_HELP > 0
+// Need this construct to avoid the 'defined but not used' warning.
+#define MAYBE_STRIPPED_HELP(txt) \
+ (false ? (txt) : ::google::kStrippedFlagHelp)
+#else
+#define MAYBE_STRIPPED_HELP(txt) txt
+#endif
+
+// Each command-line flag has two variables associated with it: one
+// with the current value, and one with the default value. However,
+// we have a third variable, which is where value is assigned; it's a
+// constant. This guarantees that FLAG_##value is initialized at
+// static initialization time (e.g. before program-start) rather than
+// than global construction time (which is after program-start but
+// before main), at least when 'value' is a compile-time constant. We
+// use a small trick for the "default value" variable, and call it
+// FLAGS_no<name>. This serves the second purpose of assuring a
+// compile error if someone tries to define a flag named no<name>
+// which is illegal (--foo and --nofoo both affect the "foo" flag).
+#define DEFINE_VARIABLE(type, shorttype, name, value, help) \
+ namespace fL##shorttype { \
+ static const type FLAGS_nono##name = value; \
+ /* We always want to export defined variables, dll or no */ \
+ GFLAGS_DLL_DEFINE_FLAG type FLAGS_##name = FLAGS_nono##name; \
+ type FLAGS_no##name = FLAGS_nono##name; \
+ static ::google::FlagRegisterer o_##name( \
+ #name, #type, MAYBE_STRIPPED_HELP(help), __FILE__, \
+ &FLAGS_##name, &FLAGS_no##name); \
+ } \
+ using fL##shorttype::FLAGS_##name
+
+// For DEFINE_bool, we want to do the extra check that the passed-in
+// value is actually a bool, and not a string or something that can be
+// coerced to a bool. These declarations (no definition needed!) will
+// help us do that, and never evaluate From, which is important.
+// We'll use 'sizeof(IsBool(val))' to distinguish. This code requires
+// that the compiler have different sizes for bool & double. Since
+// this is not guaranteed by the standard, we check it with a
+// COMPILE_ASSERT.
+namespace fLB {
+struct CompileAssert {};
+typedef CompileAssert expected_sizeof_double_neq_sizeof_bool[
+ (sizeof(double) != sizeof(bool)) ? 1 : -1];
+template<typename From> double GFLAGS_DLL_DECL IsBoolFlag(const From& from);
+GFLAGS_DLL_DECL bool IsBoolFlag(bool from);
+} // namespace fLB
+
+// Here are the actual DEFINE_*-macros. The respective DECLARE_*-macros
+// are in a separate include, gflags_declare.h, for reducing
+// the physical transitive size for DECLARE use.
+#define DEFINE_bool(name, val, txt) \
+ namespace fLB { \
+ typedef ::fLB::CompileAssert FLAG_##name##_value_is_not_a_bool[ \
+ (sizeof(::fLB::IsBoolFlag(val)) != sizeof(double)) ? 1 : -1]; \
+ } \
+ DEFINE_VARIABLE(bool, B, name, val, txt)
+
+#define DEFINE_int32(name, val, txt) \
+ DEFINE_VARIABLE(::google::int32, I, \
+ name, val, txt)
+
+#define DEFINE_int64(name, val, txt) \
+ DEFINE_VARIABLE(::google::int64, I64, \
+ name, val, txt)
+
+#define DEFINE_uint64(name,val, txt) \
+ DEFINE_VARIABLE(::google::uint64, U64, \
+ name, val, txt)
+
+#define DEFINE_double(name, val, txt) \
+ DEFINE_VARIABLE(double, D, name, val, txt)
+
+// Strings are trickier, because they're not a POD, so we can't
+// construct them at static-initialization time (instead they get
+// constructed at global-constructor time, which is much later). To
+// try to avoid crashes in that case, we use a char buffer to store
+// the string, which we can static-initialize, and then placement-new
+// into it later. It's not perfect, but the best we can do.
+
+namespace fLS {
+
+inline clstring* dont_pass0toDEFINE_string(char *stringspot,
+ const char *value) {
+ return new(stringspot) clstring(value);
+}
+inline clstring* dont_pass0toDEFINE_string(char *stringspot,
+ const clstring &value) {
+ return new(stringspot) clstring(value);
+}
+inline clstring* dont_pass0toDEFINE_string(char *stringspot,
+ int value);
+} // namespace fLS
+
+// We need to define a var named FLAGS_no##name so people don't define
+// --string and --nostring. And we need a temporary place to put val
+// so we don't have to evaluate it twice. Two great needs that go
+// great together!
+// The weird 'using' + 'extern' inside the fLS namespace is to work around
+// an unknown compiler bug/issue with the gcc 4.2.1 on SUSE 10. See
+// http://code.google.com/p/google-gflags/issues/detail?id=20
+#define DEFINE_string(name, val, txt) \
+ namespace fLS { \
+ using ::fLS::clstring; \
+ static union { void* align; char s[sizeof(clstring)]; } s_##name[2]; \
+ clstring* const FLAGS_no##name = ::fLS:: \
+ dont_pass0toDEFINE_string(s_##name[0].s, \
+ val); \
+ static ::google::FlagRegisterer o_##name( \
+ #name, "string", MAYBE_STRIPPED_HELP(txt), __FILE__, \
+ s_##name[0].s, new (s_##name[1].s) clstring(*FLAGS_no##name)); \
+ extern GFLAGS_DLL_DEFINE_FLAG clstring& FLAGS_##name; \
+ using fLS::FLAGS_##name; \
+ clstring& FLAGS_##name = *FLAGS_no##name; \
+ } \
+ using fLS::FLAGS_##name
+
+#endif // SWIG
+
+#endif // BASE_COMMANDLINEFLAGS_H_
diff --git a/src/third_party/gflags-2.0/src/windows/gflags/gflags_completions.h b/src/third_party/gflags-2.0/src/windows/gflags/gflags_completions.h
new file mode 100755
index 00000000000..bf049fe2b2c
--- /dev/null
+++ b/src/third_party/gflags-2.0/src/windows/gflags/gflags_completions.h
@@ -0,0 +1,132 @@
+// Copyright (c) 2008, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// ---
+
+//
+// Implement helpful bash-style command line flag completions
+//
+// ** Functional API:
+// HandleCommandLineCompletions() should be called early during
+// program startup, but after command line flag code has been
+// initialized, such as the beginning of HandleCommandLineHelpFlags().
+// It checks the value of the flag --tab_completion_word. If this
+// flag is empty, nothing happens here. If it contains a string,
+// however, then HandleCommandLineCompletions() will hijack the
+// process, attempting to identify the intention behind this
+// completion. Regardless of the outcome of this deduction, the
+// process will be terminated, similar to --helpshort flag
+// handling.
+//
+// ** Overview of Bash completions:
+// Bash can be told to programatically determine completions for the
+// current 'cursor word'. It does this by (in this case) invoking a
+// command with some additional arguments identifying the command
+// being executed, the word being completed, and the previous word
+// (if any). Bash then expects a sequence of output lines to be
+// printed to stdout. If these lines all contain a common prefix
+// longer than the cursor word, bash will replace the cursor word
+// with that common prefix, and display nothing. If there isn't such
+// a common prefix, bash will display the lines in pages using 'more'.
+//
+// ** Strategy taken for command line completions:
+// If we can deduce either the exact flag intended, or a common flag
+// prefix, we'll output exactly that. Otherwise, if information
+// must be displayed to the user, we'll take the opportunity to add
+// some helpful information beyond just the flag name (specifically,
+// we'll include the default flag value and as much of the flag's
+// description as can fit on a single terminal line width, as specified
+// by the flag --tab_completion_columns). Furthermore, we'll try to
+// make bash order the output such that the most useful or relevent
+// flags are the most likely to be shown at the top.
+//
+// ** Additional features:
+// To assist in finding that one really useful flag, substring matching
+// was implemented. Before pressing a <TAB> to get completion for the
+// current word, you can append one or more '?' to the flag to do
+// substring matching. Here's the semantics:
+// --foo<TAB> Show me all flags with names prefixed by 'foo'
+// --foo?<TAB> Show me all flags with 'foo' somewhere in the name
+// --foo??<TAB> Same as prior case, but also search in module
+// definition path for 'foo'
+// --foo???<TAB> Same as prior case, but also search in flag
+// descriptions for 'foo'
+// Finally, we'll trim the output to a relatively small number of
+// flags to keep bash quiet about the verbosity of output. If one
+// really wanted to see all possible matches, appending a '+' to the
+// search word will force the exhaustive list of matches to be printed.
+//
+// ** How to have bash accept completions from a binary:
+// Bash requires that it be informed about each command that programmatic
+// completion should be enabled for. Example addition to a .bashrc
+// file would be (your path to gflags_completions.sh file may differ):
+
+/*
+$ complete -o bashdefault -o default -o nospace -C \
+ '/home/build/eng/bash/bash_completions.sh --tab_completion_columns $COLUMNS' \
+ time env binary_name another_binary [...]
+*/
+
+// This would allow the following to work:
+// $ /path/to/binary_name --vmodule<TAB>
+// Or:
+// $ ./bin/path/another_binary --gfs_u<TAB>
+// (etc)
+//
+// Sadly, it appears that bash gives no easy way to force this behavior for
+// all commands. That's where the "time" in the above example comes in.
+// If you haven't specifically added a command to the list of completion
+// supported commands, you can still get completions by prefixing the
+// entire command with "env".
+// $ env /some/brand/new/binary --vmod<TAB>
+// Assuming that "binary" is a newly compiled binary, this should still
+// produce the expected completion output.
+
+
+#ifndef BASE_COMMANDLINEFLAGS_COMPLETIONS_H_
+#define BASE_COMMANDLINEFLAGS_COMPLETIONS_H_
+
+// Annoying stuff for windows -- makes sure clients can import these functions
+//
+// NOTE: all functions below MUST have an explicit 'extern' before
+// them. Our automated opensourcing tools use this as a signal to do
+// appropriate munging for windows, which needs to add GFLAGS_DLL_DECL.
+//
+#if defined(_MSC_VER) && !defined(GFLAGS_DLL_DECL)
+# define GFLAGS_DLL_DECL __declspec(dllimport)
+#endif
+
+
+namespace google {
+
+extern GFLAGS_DLL_DECL void HandleCommandLineCompletions(void);
+
+}
+
+#endif // BASE_COMMANDLINEFLAGS_COMPLETIONS_H_
diff --git a/src/third_party/gflags-2.0/src/windows/gflags/gflags_declare.h b/src/third_party/gflags-2.0/src/windows/gflags/gflags_declare.h
new file mode 100755
index 00000000000..5fca1e4d7c6
--- /dev/null
+++ b/src/third_party/gflags-2.0/src/windows/gflags/gflags_declare.h
@@ -0,0 +1,114 @@
+// Copyright (c) 1999, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// ---
+//
+// Revamped and reorganized by Craig Silverstein
+//
+// This is the file that should be included by any file which declares
+// command line flag.
+
+#ifndef BASE_COMMANDLINEFLAGS_DECLARE_H_
+#define BASE_COMMANDLINEFLAGS_DECLARE_H_
+
+#include <string>
+#if 0
+#include <stdint.h> // the normal place uint16_t is defined
+#endif
+#if 1
+#include <sys/types.h> // the normal place u_int16_t is defined
+#endif
+#if 0
+#include <inttypes.h> // a third place for uint16_t or u_int16_t
+#endif
+
+namespace google {
+#if 0 // the C99 format
+typedef int32_t int32;
+typedef uint32_t uint32;
+typedef int64_t int64;
+typedef uint64_t uint64;
+#elif 0 // the BSD format
+typedef int32_t int32;
+typedef u_int32_t uint32;
+typedef int64_t int64;
+typedef u_int64_t uint64;
+#elif 1 // the windows (vc7) format
+typedef __int32 int32;
+typedef unsigned __int32 uint32;
+typedef __int64 int64;
+typedef unsigned __int64 uint64;
+#else
+#error Do not know how to define a 32-bit integer quantity on your system
+#endif
+}
+
+
+#if defined(_MSC_VER) && !defined(GFLAGS_DLL_DECLARE_FLAG)
+# define GFLAGS_DLL_DECLARE_FLAG __declspec(dllimport)
+#endif
+
+namespace fLS {
+
+// The meaning of "string" might be different between now and when the
+// macros below get invoked (e.g., if someone is experimenting with
+// other string implementations that get defined after this file is
+// included). Save the current meaning now and use it in the macros.
+typedef std::string clstring;
+
+}
+
+#define DECLARE_VARIABLE(type, shorttype, name) \
+ /* We always want to import declared variables, dll or no */ \
+ namespace fL##shorttype { extern GFLAGS_DLL_DECLARE_FLAG type FLAGS_##name; } \
+ using fL##shorttype::FLAGS_##name
+
+#define DECLARE_bool(name) \
+ DECLARE_VARIABLE(bool, B, name)
+
+#define DECLARE_int32(name) \
+ DECLARE_VARIABLE(::google::int32, I, name)
+
+#define DECLARE_int64(name) \
+ DECLARE_VARIABLE(::google::int64, I64, name)
+
+#define DECLARE_uint64(name) \
+ DECLARE_VARIABLE(::google::uint64, U64, name)
+
+#define DECLARE_double(name) \
+ DECLARE_VARIABLE(double, D, name)
+
+#define DECLARE_string(name) \
+ namespace fLS { \
+ using ::fLS::clstring; \
+ extern GFLAGS_DLL_DECLARE_FLAG ::fLS::clstring& FLAGS_##name; \
+ } \
+ using fLS::FLAGS_##name
+
+#endif // BASE_COMMANDLINEFLAGS_DECLARE_H_
diff --git a/src/third_party/gflags-2.0/src/windows/port.cc b/src/third_party/gflags-2.0/src/windows/port.cc
new file mode 100755
index 00000000000..fb47698d7ab
--- /dev/null
+++ b/src/third_party/gflags-2.0/src/windows/port.cc
@@ -0,0 +1,62 @@
+/* Copyright (c) 2009, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ---
+ * Author: Craig Silverstein
+ */
+
+#ifndef _WIN32
+# error You should only be including windows/port.cc in a windows environment!
+#endif
+
+#include <config.h>
+#include <string.h> // for strlen(), memset(), memcmp()
+#include <assert.h>
+#include <stdarg.h> // for va_list, va_start, va_end
+#include <windows.h>
+#include "port.h"
+
+// These call the windows _vsnprintf, but always NUL-terminate.
+#if !defined(__MINGW32__) && !defined(__MINGW64__) /* mingw already defines */
+int safe_vsnprintf(char *str, size_t size, const char *format, va_list ap) {
+ if (size == 0) // not even room for a \0?
+ return -1; // not what C99 says to do, but what windows does
+ str[size-1] = '\0';
+ return _vsnprintf(str, size-1, format, ap);
+}
+
+int snprintf(char *str, size_t size, const char *format, ...) {
+ int r;
+ va_list ap;
+ va_start(ap, format);
+ r = vsnprintf(str, size, format, ap);
+ va_end(ap);
+ return r;
+}
+#endif /* #if !defined(__MINGW32__) && !defined(__MINGW64__) */
diff --git a/src/third_party/gflags-2.0/src/windows/port.h b/src/third_party/gflags-2.0/src/windows/port.h
new file mode 100755
index 00000000000..eea4eb591b0
--- /dev/null
+++ b/src/third_party/gflags-2.0/src/windows/port.h
@@ -0,0 +1,111 @@
+/* Copyright (c) 2009, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ---
+ * Author: Craig Silverstein
+ *
+ * These are some portability typedefs and defines to make it a bit
+ * easier to compile this code under VC++.
+ *
+ * Several of these are taken from glib:
+ * http://developer.gnome.org/doc/API/glib/glib-windows-compatability-functions.html
+ */
+
+#ifndef GOOGLE_GFLAGS_WINDOWS_PORT_H_
+#define GOOGLE_GFLAGS_WINDOWS_PORT_H_
+
+#ifdef _WIN32
+
+#ifndef WIN32_LEAN_AND_MEAN
+#define WIN32_LEAN_AND_MEAN /* We always want minimal includes */
+#endif
+#include <windows.h>
+#include <direct.h> /* for mkdir */
+#include <stdlib.h> /* for _putenv, getenv */
+#include <stdio.h> /* need this to override stdio's snprintf */
+#include <stdarg.h> /* util.h uses va_copy */
+#include <string.h> /* for _stricmp */
+
+/* We can't just use _vsnprintf and _snprintf as drop-in-replacements,
+ * because they don't always NUL-terminate. :-( We also can't use the
+ * name vsnprintf, since windows defines that (but not snprintf (!)).
+ */
+#if !defined(__MINGW32__) && !defined(__MINGW64__) /* mingw already defines */
+extern GFLAGS_DLL_DECL int snprintf(char *str, size_t size,
+ const char *format, ...);
+extern int GFLAGS_DLL_DECL safe_vsnprintf(char *str, size_t size,
+ const char *format, va_list ap);
+#define vsnprintf(str, size, format, ap) safe_vsnprintf(str, size, format, ap)
+#define va_copy(dst, src) (dst) = (src)
+#endif /* #if !defined(__MINGW32__) && !defined(__MINGW64__) */
+
+inline void setenv(const char* name, const char* value, int) {
+ // In windows, it's impossible to set a variable to the empty string.
+ // We handle this by setting it to "0" and the NUL-ing out the \0.
+ // That is, we putenv("FOO=0") and then find out where in memory the
+ // putenv wrote "FOO=0", and change it in-place to "FOO=\0".
+ // c.f. http://svn.apache.org/viewvc/stdcxx/trunk/tests/src/environ.cpp?r1=611451&r2=637508&pathrev=637508
+ static const char* const kFakeZero = "0";
+ if (*value == '\0')
+ value = kFakeZero;
+ // Apparently the semantics of putenv() is that the input
+ // must live forever, so we leak memory here. :-(
+ const int nameval_len = strlen(name) + 1 + strlen(value) + 1;
+ char* nameval = reinterpret_cast<char*>(malloc(nameval_len));
+ snprintf(nameval, nameval_len, "%s=%s", name, value);
+ _putenv(nameval);
+ if (value == kFakeZero) {
+ nameval[nameval_len - 2] = '\0'; // works when putenv() makes no copy
+ if (*getenv(name) != '\0')
+ *getenv(name) = '\0'; // works when putenv() copies nameval
+ }
+}
+
+#define strcasecmp _stricmp
+
+#define PRId32 "d"
+#define PRIu32 "u"
+#define PRId64 "I64d"
+#define PRIu64 "I64u"
+
+#ifndef __MINGW32__
+#define strtoq _strtoi64
+#define strtouq _strtoui64
+#define strtoll _strtoi64
+#define strtoull _strtoui64
+#define atoll _atoi64
+#endif
+
+#ifndef PATH_MAX
+#define PATH_MAX 1024
+#endif
+
+#endif /* _WIN32 */
+
+#endif /* GOOGLE_GFLAGS_WINDOWS_PORT_H_ */
diff --git a/src/third_party/gflags-2.0/vsprojects/gflags_unittest/gflags_unittest.vcproj b/src/third_party/gflags-2.0/vsprojects/gflags_unittest/gflags_unittest.vcproj
new file mode 100755
index 00000000000..2f6705de6d8
--- /dev/null
+++ b/src/third_party/gflags-2.0/vsprojects/gflags_unittest/gflags_unittest.vcproj
@@ -0,0 +1,159 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="7.10"
+ Name="gflags_unittest"
+ ProjectGUID="{4B263748-5F0F-468C-8C5C-ED2682BB6BE3}"
+ Keyword="Win32Proj">
+ <Platforms>
+ <Platform
+ Name="Win32"/>
+ </Platforms>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="1"
+ CharacterSet="2">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
+ MinimalRebuild="TRUE"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="5"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ DebugInformationFormat="4"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLinkerTool"
+ OutputFile="$(OutDir)/gflags_unittest.exe"
+ LinkIncremental="2"
+ GenerateDebugInformation="TRUE"
+ ProgramDatabaseFile="$(OutDir)/gflags_unittest.pdb"
+ SubSystem="1"
+ TargetMachine="1"/>
+ <Tool
+ Name="VCMIDLTool"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCWebDeploymentTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="1"
+ CharacterSet="2">
+ <Tool
+ Name="VCCLCompilerTool"
+ PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
+ RuntimeLibrary="4"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ DebugInformationFormat="3"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLinkerTool"
+ OutputFile="$(OutDir)/gflags_unittest.exe"
+ LinkIncremental="1"
+ GenerateDebugInformation="TRUE"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="1"/>
+ <Tool
+ Name="VCMIDLTool"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCWebDeploymentTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
+ <File
+ RelativePath="..\..\src\gflags_unittest.cc">
+ <FileConfiguration
+ Name="Debug|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories="..\..\src\windows; ..\..\src"
+ RuntimeLibrary="3"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories="..\..\src\windows; ..\..\src"
+ RuntimeLibrary="2"/>
+ </FileConfiguration>
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{AFC737F1-C7A5-4376-A066-2A32D752A2FF}">
+ <File
+ RelativePath="..\..\src\windows\gflags\gflags.h">
+ </File>
+ <File
+ RelativePath="..\..\src\windows\gflags\gflags_declare.h">
+ </File>
+ <File
+ RelativePath="..\..\src\windows\gflags\gflags_completions.h">
+ </File>
+ <File
+ RelativePath="..\..\src\windows\config.h">
+ </File>
+ <File
+ RelativePath="..\..\src\config_for_unittests.h">
+ </File>
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
+ UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}">
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/src/third_party/gflags-2.0/vsprojects/libgflags/libgflags.vcproj b/src/third_party/gflags-2.0/vsprojects/libgflags/libgflags.vcproj
new file mode 100755
index 00000000000..24fea0d9e57
--- /dev/null
+++ b/src/third_party/gflags-2.0/vsprojects/libgflags/libgflags.vcproj
@@ -0,0 +1,211 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="7.10"
+ Name="libgflags"
+ ProjectGUID="{FB27FBDB-E6C0-4D00-A7F8-1EEEF1B48ABC}"
+ RootNamespace="libgflags"
+ Keyword="Win32Proj">
+ <Platforms>
+ <Platform
+ Name="Win32"/>
+ </Platforms>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="2"
+ CharacterSet="2">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;LIBGFLAGS_EXPORTS"
+ MinimalRebuild="TRUE"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="1"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ DebugInformationFormat="4"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLinkerTool"
+ OutputFile="$(OutDir)/libgflags-debug.dll"
+ LinkIncremental="2"
+ GenerateDebugInformation="TRUE"
+ ProgramDatabaseFile="$(OutDir)/libgflags-debug.pdb"
+ SubSystem="2"
+ ImportLibrary="$(OutDir)/libgflags-debug.lib"
+ TargetMachine="1"/>
+ <Tool
+ Name="VCMIDLTool"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCWebDeploymentTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="2"
+ CharacterSet="2">
+ <Tool
+ Name="VCCLCompilerTool"
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;LIBGFLAGS_EXPORTS"
+ RuntimeLibrary="0"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ DebugInformationFormat="3"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLinkerTool"
+ OutputFile="$(OutDir)/libgflags.dll"
+ LinkIncremental="1"
+ GenerateDebugInformation="TRUE"
+ SubSystem="2"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ ImportLibrary="$(OutDir)/libgflags.lib"
+ TargetMachine="1"/>
+ <Tool
+ Name="VCMIDLTool"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCWebDeploymentTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
+ <File
+ RelativePath="..\..\src\gflags.cc">
+ <FileConfiguration
+ Name="Debug|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories="..\..\src\windows; ..\..\src"
+ RuntimeLibrary="3"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories="..\..\src\windows; ..\..\src"
+ RuntimeLibrary="2"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="..\..\src\gflags_reporting.cc">
+ <FileConfiguration
+ Name="Debug|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories="..\..\src\windows; ..\..\src"
+ RuntimeLibrary="3"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories="..\..\src\windows; ..\..\src"
+ RuntimeLibrary="2"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="..\..\src\gflags_completions.cc">
+ <FileConfiguration
+ Name="Debug|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories="..\..\src\windows; ..\..\src"
+ RuntimeLibrary="3"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories="..\..\src\windows; ..\..\src"
+ RuntimeLibrary="2"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="..\..\src\windows\port.cc">
+ <FileConfiguration
+ Name="Debug|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories="..\..\src\windows; ..\..\src"
+ RuntimeLibrary="3"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories="..\..\src\windows; ..\..\src"
+ RuntimeLibrary="2"/>
+ </FileConfiguration>
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">
+ <File
+ RelativePath="..\..\src\mutex.h">
+ </File>
+ <File
+ RelativePath="..\..\src\windows\gflags\gflags.h">
+ </File>
+ <File
+ RelativePath="..\..\src\windows\gflags\gflags_declare.h">
+ </File>
+ <File
+ RelativePath="..\..\src\windows\gflags\gflags_completions.h">
+ </File>
+ <File
+ RelativePath="..\..\src\windows\config.h">
+ </File>
+ <File
+ RelativePath="..\..\src\windows\port.h">
+ </File>
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/src/third_party/s2/LICENSE-2.0.txt b/src/third_party/s2/LICENSE-2.0.txt
new file mode 100644
index 00000000000..d6456956733
--- /dev/null
+++ b/src/third_party/s2/LICENSE-2.0.txt
@@ -0,0 +1,202 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
diff --git a/src/third_party/s2/Makefile b/src/third_party/s2/Makefile
new file mode 100644
index 00000000000..cbc4fed9873
--- /dev/null
+++ b/src/third_party/s2/Makefile
@@ -0,0 +1,223 @@
+# Please edit the following:
+PYTHON_VER=2.6
+
+# TODO(tudorh): Fix this.
+GFLAGS_DIR=/Users/hk/
+
+SWIG_BINARY=swig
+ZLIB_DIR=/usr
+
+# ----- No more editing below -----
+
+PYTHON_INC=-I/usr/include/python$(PYTHON_VER) -I/usr/lib/python$(PYTHON_VER)
+
+DEBUG=-O -DNDEBUG
+SYSCFLAGS=-fPIC
+CCC=g++
+
+GFLAGS_INC = -I$(GFLAGS_DIR)/include
+ZLIB_INC = -I$(ZLIB_DIR)/include
+CFLAGS= $(SYSCFLAGS) $(DEBUG) -I. -DARCH_K8 $(GFLAGS_INC) $(ZLIB_INC) \
+ -Wno-deprecated -DS2_USE_EXACTFLOAT
+
+# ----- OS Dependent -----
+OS=$(shell uname -s)
+
+ifeq ($(OS),Linux)
+LD = gcc -shared
+GFLAGS_LNK = -Wl,-rpath $(GFLAGS_DIR)/lib -L$(GFLAGS_DIR)/lib -lgflags
+ZLIB_LNK = -Wl,-rpath $(ZLIB_DIR)/lib -L$(ZLIB_DIR)/lib -lz
+endif
+ifeq ($(OS),Darwin) # Assume Mac Os X
+LD = ld -arch x86_64 -bundle -flat_namespace -undefined suppress
+GFLAGS_LNK = -L$(GFLAGS_DIR)/lib -lgflags
+ZLIB_LNK = -L$(ZLIB_DIR)/lib -lz
+CFLAGS += -DOS_MACOSX -DHASH_NAMESPACE=std
+endif
+
+LDFLAGS=$(GFLAGS_LNK) $(ZLIB_LNK)
+
+# Real targets
+
+BINARIES= #s2cellid_test
+
+all: libs $(BINARIES)
+
+LIBS = \
+ libgoogle-base.a\
+ libgoogle-strings.a\
+ libgoogle-util-math.a\
+ libgoogle-util-coding.a\
+ libgoogle-util-geometry-s2cellid.a\
+ libgoogle-util-geometry-s2.a\
+ libgoogle-util-geometry-s2testing.a
+
+libs: $(LIBS)
+
+clean:
+ rm -f *.a
+ rm -f objs/*.o
+ rm -f $(BINARIES)
+ rm -f *.so
+
+# base.
+
+GOOGLE_BASE_LIB_OBJS = \
+ base/objs/int128.o\
+ base/objs/logging.o\
+ base/objs/stringprintf.o
+
+base/objs/int128.o:base/int128.cc
+ $(CCC) $(CFLAGS) -c base/int128.cc -o base/objs/int128.o
+base/objs/logging.o:base/logging.cc
+ $(CCC) $(CFLAGS) -c base/logging.cc -o base/objs/logging.o
+base/objs/stringprintf.o:base/stringprintf.cc
+ $(CCC) $(CFLAGS) -c base/stringprintf.cc -o base/objs/stringprintf.o
+base/objs/strtoint.o:base/strtoint.cc
+ $(CCC) $(CFLAGS) -c base/strtoint.cc -o base/objs/strtoint.o
+
+libgoogle-base.a: $(GOOGLE_BASE_LIB_OBJS)
+ ar rv libgoogle-base.a $(GOOGLE_BASE_LIB_OBJS)
+
+# strings
+
+GOOGLE_STRINGS_LIB_OBJS = \
+ strings/objs/ascii_ctype.o\
+ strings/objs/split.o\
+ strings/objs/stringprintf.o\
+ strings/objs/strutil.o
+
+strings/objs/ascii_ctype.o:strings/ascii_ctype.cc
+ $(CCC) $(CFLAGS) -c strings/ascii_ctype.cc -o strings/objs/ascii_ctype.o
+strings/objs/split.o:strings/split.cc
+ $(CCC) $(CFLAGS) -c strings/split.cc -o strings/objs/split.o
+strings/objs/stringprintf.o:strings/stringprintf.cc
+ $(CCC) $(CFLAGS) -c strings/stringprintf.cc -o strings/objs/stringprintf.o
+strings/objs/strutil.o:strings/strutil.cc
+ $(CCC) $(CFLAGS) -c strings/strutil.cc -o strings/objs/strutil.o
+
+libgoogle-strings.a: $(GOOGLE_STRINGS_LIB_OBJS)
+ ar rv libgoogle-strings.a $(GOOGLE_STRINGS_LIB_OBJS)
+
+# util/coding
+
+GOOGLE_UTIL_CODING_LIB_OBJS = \
+ util/coding/objs/coder.o\
+ util/coding/objs/varint.o
+
+util/coding/objs/coder.o:util/coding/coder.cc
+ $(CCC) $(CFLAGS) -c util/coding/coder.cc -o util/coding/objs/coder.o
+util/coding/objs/varint.o:util/coding/varint.cc
+ $(CCC) $(CFLAGS) -c util/coding/varint.cc -o util/coding/objs/varint.o
+
+libgoogle-util-coding.a: $(GOOGLE_UTIL_CODING_LIB_OBJS)
+ ar rv libgoogle-util-coding.a $(GOOGLE_UTIL_CODING_LIB_OBJS)
+
+# util/math
+
+GOOGLE_UTIL_MATH_LIB_OBJS = \
+ util/math/objs/mathutil.o\
+ util/math/objs/mathlimits.o\
+ util/math/objs/exactfloat.o
+
+util/math/objs/mathutil.o:util/math/mathutil.cc
+ $(CCC) $(CFLAGS) -c util/math/mathutil.cc -o util/math/objs/mathutil.o
+util/math/objs/mathlimits.o:util/math/mathlimits.cc
+ $(CCC) $(CFLAGS) -c util/math/mathlimits.cc -o util/math/objs/mathlimits.o
+util/math/objs/exactfloat.o:util/math/exactfloat/exactfloat.cc
+ $(CCC) $(CFLAGS) -c util/math/exactfloat/exactfloat.cc -o util/math/objs/exactfloat.o
+#util/math/objs/exactfloat_test.o:util/math/exactfloat/exactfloat_test.cc
+# $(CCC) $(CFLAGS) -c util/math/exactfloat/exactfloat_test.cc -o util/math/objs/exactfloat_test.o
+#util/math/objs/vector_unittest.o:util/math/vector_unittest.cc
+# $(CCC) $(CFLAGS) -c util/math/vector_unittest.cc -o util/math/objs/vector_unittest.o
+
+libgoogle-util-math.a: $(GOOGLE_UTIL_MATH_LIB_OBJS)
+ ar rv libgoogle-util-math.a $(GOOGLE_UTIL_MATH_LIB_OBJS)
+#exactfloat_test: $(LIBS) objs/exactfloat_test.o
+# $(CCC) $(CFLAGS) $(LDFLAGS) objs/exactfloat_test.o $(LIBS) -o exactfloat_test
+#vector_unittest: $(LIBS) objs/vector_unittest.o
+# $(CCC) $(CFLAGS) $(LDFLAGS) objs/vector_unittest.o $(LIBS) -o vector_unittest
+
+# util/geometry
+
+GOOGLE_UTIL_GEOMETRY_S2CELLID_LIB_OBJS = \
+ objs/s1angle.o\
+ objs/s2.o\
+ objs/s2cellid.o\
+ objs/s2latlng.o
+
+GOOGLE_UTIL_GEOMETRY_S2_LIB_OBJS = \
+ objs/s1interval.o\
+ objs/s2cap.o\
+ objs/s2cell.o\
+ objs/s2cellunion.o\
+ objs/s2edgeindex.o\
+ objs/s2edgeutil.o\
+ objs/s2latlngrect.o\
+ objs/s2loop.o\
+ objs/s2pointregion.o\
+ objs/s2polygon.o\
+ objs/s2polygonbuilder.o\
+ objs/s2polyline.o\
+ objs/s2r2rect.o\
+ objs/s2region.o\
+ objs/s2regioncoverer.o\
+ objs/s2regionintersection.o\
+ objs/s2regionunion.o
+
+GOOGLE_UTIL_GEOMETRY_S2TESTING_LIB_OBJS = \
+ objs/s2testing.o
+
+objs/s1angle.o:s1angle.cc
+ $(CCC) $(CFLAGS) -c s1angle.cc -o objs/s1angle.o
+objs/s1interval.o:s1interval.cc
+ $(CCC) $(CFLAGS) -c s1interval.cc -o objs/s1interval.o
+objs/s2.o:s2.cc
+ $(CCC) $(CFLAGS) -c s2.cc -o objs/s2.o
+objs/s2cap.o:s2cap.cc
+ $(CCC) $(CFLAGS) -c s2cap.cc -o objs/s2cap.o
+objs/s2cell.o:s2cell.cc
+ $(CCC) $(CFLAGS) -c s2cell.cc -o objs/s2cell.o
+objs/s2cellid.o:s2cellid.cc
+ $(CCC) $(CFLAGS) -c s2cellid.cc -o objs/s2cellid.o
+objs/s2cellunion.o:s2cellunion.cc
+ $(CCC) $(CFLAGS) -c s2cellunion.cc -o objs/s2cellunion.o
+objs/s2edgeindex.o:s2edgeindex.cc
+ $(CCC) $(CFLAGS) -c s2edgeindex.cc -o objs/s2edgeindex.o
+objs/s2edgeutil.o:s2edgeutil.cc
+ $(CCC) $(CFLAGS) -c s2edgeutil.cc -o objs/s2edgeutil.o
+objs/s2latlng.o:s2latlng.cc
+ $(CCC) $(CFLAGS) -c s2latlng.cc -o objs/s2latlng.o
+objs/s2latlngrect.o:s2latlngrect.cc
+ $(CCC) $(CFLAGS) -c s2latlngrect.cc -o objs/s2latlngrect.o
+objs/s2loop.o:s2loop.cc
+ $(CCC) $(CFLAGS) -c s2loop.cc -o objs/s2loop.o
+objs/s2pointregion.o:s2pointregion.cc
+ $(CCC) $(CFLAGS) -c s2pointregion.cc -o objs/s2pointregion.o
+objs/s2polygon.o:s2polygon.cc
+ $(CCC) $(CFLAGS) -c s2polygon.cc -o objs/s2polygon.o
+objs/s2polygonbuilder.o:s2polygonbuilder.cc
+ $(CCC) $(CFLAGS) -c s2polygonbuilder.cc -o objs/s2polygonbuilder.o
+objs/s2polyline.o:s2polyline.cc
+ $(CCC) $(CFLAGS) -c s2polyline.cc -o objs/s2polyline.o
+objs/s2r2rect.o:s2r2rect.cc
+ $(CCC) $(CFLAGS) -c s2r2rect.cc -o objs/s2r2rect.o
+objs/s2region.o:s2region.cc
+ $(CCC) $(CFLAGS) -c s2region.cc -o objs/s2region.o
+objs/s2regioncoverer.o:s2regioncoverer.cc
+ $(CCC) $(CFLAGS) -c s2regioncoverer.cc -o objs/s2regioncoverer.o
+objs/s2regionintersection.o:s2regionintersection.cc
+ $(CCC) $(CFLAGS) -c s2regionintersection.cc -o objs/s2regionintersection.o
+objs/s2regionunion.o:s2regionunion.cc
+ $(CCC) $(CFLAGS) -c s2regionunion.cc -o objs/s2regionunion.o
+objs/s2testing.o:s2testing.cc
+ $(CCC) $(CFLAGS) -c s2testing.cc -o objs/s2testing.o
+
+libgoogle-util-geometry-s2cellid.a: $(GOOGLE_UTIL_GEOMETRY_S2CELLID_LIB_OBJS)
+ ar rv libs2cellid.a $(GOOGLE_UTIL_GEOMETRY_S2CELLID_LIB_OBJS)
+
+libgoogle-util-geometry-s2.a: $(GOOGLE_UTIL_GEOMETRY_S2_LIB_OBJS)
+ ar rv libs2.a $(GOOGLE_UTIL_GEOMETRY_S2_LIB_OBJS)
+
+libgoogle-util-geometry-s2testing.a: $(GOOGLE_UTIL_GEOMETRY_S2TESTING_LIB_OBJS)
+ ar rv libs2testing.a $(GOOGLE_UTIL_GEOMETRY_S2TESTING_LIB_OBJS)
diff --git a/src/third_party/s2/SConscript b/src/third_party/s2/SConscript
new file mode 100644
index 00000000000..c2fdb9c2ec5
--- /dev/null
+++ b/src/third_party/s2/SConscript
@@ -0,0 +1,56 @@
+# -*- mode: python -*-
+
+Import("env windows linux darwin solaris")
+
+env = env.Clone()
+
+env.SConscript( [
+ "base/SConscript",
+ "strings/SConscript",
+ "util/coding/SConscript",
+ "util/math/SConscript",
+ ] )
+
+env.Append(CCFLAGS=['-Isrc/third_party/s2'])
+env.Append(CCFLAGS=['-Isrc/third_party/gflags-2.0/src'])
+env.Append(CCFLAGS=['-DDEBUG_MODE=false'])
+
+env.StaticLibrary( "s2",
+ [
+ "s1angle.cc",
+ "s2.cc",
+ "s2cellid.cc",
+ "s2latlng.cc",
+ "s1interval.cc",
+ "s2cap.cc",
+ "s2cell.cc",
+ "s2cellunion.cc",
+ "s2edgeindex.cc",
+ "s2edgeutil.cc",
+ "s2latlngrect.cc",
+ "s2loop.cc",
+ "s2pointregion.cc",
+ "s2polygon.cc",
+ "s2polygonbuilder.cc",
+ "s2polyline.cc",
+ "s2r2rect.cc",
+ "s2region.cc",
+ "s2regioncoverer.cc",
+ "s2regionintersection.cc",
+ "s2regionunion.cc",
+ ], LIBDEPS=['$BUILD_DIR/third_party/s2/base/base',
+ '$BUILD_DIR/third_party/s2/strings/strings',
+ '$BUILD_DIR/third_party/s2/util/coding/coding',
+ '$BUILD_DIR/third_party/gflags-2.0/gflags',
+ '$BUILD_DIR/third_party/s2/util/math/math'])
+
+#env.Program('r1interval_test', ['r1interval_test.cc'],
+# LIBDEPS=['s2', '$BUILD_DIR/third_party/gtest/gtest_with_main'])
+#env.Program('s1angle_test', ['s1angle_test.cc'],
+# LIBDEPS=['s2', '$BUILD_DIR/third_party/gtest/gtest_with_main'])
+#env.Program('s1interval_test', ['s1interval_test.cc'],
+# LIBDEPS=['s2', '$BUILD_DIR/third_party/gtest/gtest_with_main'])
+#env.Program('s2regioncoverer_test', ['s2regioncoverer_test.cc'],
+# LIBDEPS=['s2', '$BUILD_DIR/third_party/gtest/gtest_with_main'])
+#env.Program('s2_test', ['s2_test.cc'],
+# LIBDEPS=['s2', '$BUILD_DIR/third_party/gtest/gtest_with_main'])
diff --git a/src/third_party/s2/base/SConscript b/src/third_party/s2/base/SConscript
new file mode 100755
index 00000000000..e208968a6a9
--- /dev/null
+++ b/src/third_party/s2/base/SConscript
@@ -0,0 +1,16 @@
+# -*- mode: python -*-
+
+Import("env windows linux darwin solaris")
+
+env = env.Clone()
+
+env.Append(CCFLAGS=['-Isrc/third_party/s2'])
+
+env.StaticLibrary(
+ "base",
+ [
+ "int128.cc",
+ "logging.cc",
+ "stringprintf.cc",
+ "strtoint.cc",
+ ])
diff --git a/src/third_party/s2/base/basictypes.h b/src/third_party/s2/base/basictypes.h
new file mode 100755
index 00000000000..437852f96a8
--- /dev/null
+++ b/src/third_party/s2/base/basictypes.h
@@ -0,0 +1,103 @@
+//
+// Copyright 2001 - 2003 Google, Inc.
+//
+
+#ifndef _BASICTYPES_H_
+#define _BASICTYPES_H_
+
+#include "base/integral_types.h"
+#include "base/casts.h"
+#include "base/port.h"
+
+//
+// Google-specific types
+//
+
+// id for odp categories
+typedef uint32 CatId;
+const CatId kIllegalCatId = static_cast<CatId>(0);
+
+typedef uint32 TermId;
+const TermId kIllegalTermId = static_cast<TermId>(0);
+
+typedef uint32 HostId;
+const HostId kIllegalHostId = static_cast<HostId>(0);
+
+typedef uint32 DomainId;
+const DomainId kIllegalDomainId = static_cast<DomainId>(0);
+
+// Pagerank related types.
+// TODO(user) - we'd like to move this into google3/pagerank/
+// prtype.h, but this datatype is used all over and that would be
+// a major change.
+// To get a complete picture of all the datatypes used for PageRank
+// and the functions to convert between them, please see google3/
+// pagerank/prtype.h
+typedef uint16 DocumentPageRank; // value in [0, kNumPageRankValues)
+const int kNumPageRankValues = 1 << (sizeof(DocumentPageRank) * 8);
+const DocumentPageRank kIllegalPagerank = 0;
+
+// Used for fielded search
+typedef int32 FieldValue;
+const FieldValue kIllegalFieldValue = static_cast<FieldValue>(INT_MAX);
+
+// It is expected that we *never* have a collision of Fingerprints for
+// 2 distinct objects. No object has kIllegalFprint as its Fingerprint.
+typedef uint64 Fprint;
+const Fprint kIllegalFprint = static_cast<Fprint>(0);
+const Fprint kMaxFprint = static_cast<Fprint>(kuint64max);
+
+// 64 bit checksum (see common/checksummer.{h,cc})
+typedef uint64 Checksum64;
+
+const Checksum64 kIllegalChecksum = static_cast<Checksum64>(0);
+
+// In contrast to Fingerprints, we *do* expect Hash<i> values to collide
+// from time to time (although we obviously prefer them not to). Also
+// note that there is an illegal hash value for each size hash.
+typedef uint32 Hash32;
+typedef uint16 Hash16;
+typedef unsigned char Hash8;
+
+const Hash32 kIllegalHash32 = static_cast<Hash32>(4294967295UL); // 2^32-1
+const Hash16 kIllegalHash16 = static_cast<Hash16>(65535U); // 2^16-1
+const Hash8 kIllegalHash8 = static_cast<Hash8>(255); // 2^8-1
+
+
+// Include docid.h at end because it needs the trait stuff.
+#include "base/docid.h"
+
+
+// MetatagId refers to metatag-id that we assign to
+// each metatag <name, value> pair..
+typedef uint32 MetatagId;
+
+// Argument type used in interfaces that can optionally take ownership
+// of a passed in argument. If TAKE_OWNERSHIP is passed, the called
+// object takes ownership of the argument. Otherwise it does not.
+enum Ownership {
+ DO_NOT_TAKE_OWNERSHIP,
+ TAKE_OWNERSHIP
+};
+
+// Use these as the mlock_bytes parameter to MLock and MLockGeneral
+enum { MLOCK_ALL = -1, MLOCK_NONE = 0 };
+
+// The following enum should be used only as a constructor argument to indicate
+// that the variable has static storage class, and that the constructor should
+// do nothing to its state. It indicates to the reader that it is legal to
+// declare a static nistance of the class, provided the constructor is given
+// the base::LINKER_INITIALIZED argument. Normally, it is unsafe to declare a
+// static variable that has a constructor or a destructor because invocation
+// order is undefined. However, IF the type can be initialized by filling with
+// zeroes (which the loader does for static variables), AND the type's
+// destructor does nothing to the storage, then a constructor for static initialization
+// can be declared as
+// explicit MyClass(base::LinkerInitialized x) {}
+// and invoked as
+// static MyClass my_variable_name(base::LINKER_INITIALIZED);
+namespace base {
+enum LinkerInitialized { LINKER_INITIALIZED };
+}
+
+#endif // _BASICTYPES_H_
diff --git a/src/third_party/s2/base/casts.h b/src/third_party/s2/base/casts.h
new file mode 100755
index 00000000000..ca9702a7587
--- /dev/null
+++ b/src/third_party/s2/base/casts.h
@@ -0,0 +1,396 @@
+// Copyright 2009 Google Inc. All Rights Reserved.
+//
+// Various Google-specific casting templates.
+//
+// This code is compiled directly on many platforms, including client
+// platforms like Windows, Mac, and embedded systems. Before making
+// any changes here, make sure that you're not breaking any platforms.
+//
+
+#ifndef BASE_CASTS_H_
+#define BASE_CASTS_H_
+
+#include <assert.h> // for use with down_cast<>
+#include <string.h> // for memcpy
+#include <limits.h> // for enumeration casts and tests
+#include <typeinfo> // for enumeration casts and tests
+
+#include "base/macros.h"
+
+
+// Use implicit_cast as a safe version of static_cast or const_cast
+// for upcasting in the type hierarchy (i.e. casting a pointer to Foo
+// to a pointer to SuperclassOfFoo or casting a pointer to Foo to
+// a const pointer to Foo).
+// When you use implicit_cast, the compiler checks that the cast is safe.
+// Such explicit implicit_casts are necessary in surprisingly many
+// situations where C++ demands an exact type match instead of an
+// argument type convertable to a target type.
+//
+// The From type can be inferred, so the preferred syntax for using
+// implicit_cast is the same as for static_cast etc.:
+//
+// implicit_cast<ToType>(expr)
+//
+// implicit_cast would have been part of the C++ standard library,
+// but the proposal was submitted too late. It will probably make
+// its way into the language in the future.
+template<typename To, typename From>
+inline To implicit_cast(From const &f) {
+ return f;
+}
+
+
+// When you upcast (that is, cast a pointer from type Foo to type
+// SuperclassOfFoo), it's fine to use implicit_cast<>, since upcasts
+// always succeed. When you downcast (that is, cast a pointer from
+// type Foo to type SubclassOfFoo), static_cast<> isn't safe, because
+// how do you know the pointer is really of type SubclassOfFoo? It
+// could be a bare Foo, or of type DifferentSubclassOfFoo. Thus,
+// when you downcast, you should use this macro. In debug mode, we
+// use dynamic_cast<> to double-check the downcast is legal (we die
+// if it's not). In normal mode, we do the efficient static_cast<>
+// instead. Thus, it's important to test in debug mode to make sure
+// the cast is legal!
+// This is the only place in the code we should use dynamic_cast<>.
+// In particular, you SHOULDN'T be using dynamic_cast<> in order to
+// do RTTI (eg code like this:
+// if (dynamic_cast<Subclass1>(foo)) HandleASubclass1Object(foo);
+// if (dynamic_cast<Subclass2>(foo)) HandleASubclass2Object(foo);
+// You should design the code some other way not to need this.
+
+template<typename To, typename From> // use like this: down_cast<T*>(foo);
+inline To down_cast(From* f) { // so we only accept pointers
+ // Ensures that To is a sub-type of From *. This test is here only
+ // for compile-time type checking, and has no overhead in an
+ // optimized build at run-time, as it will be optimized away
+ // completely.
+
+ // TODO(user): This should use COMPILE_ASSERT.
+ if (false) {
+ implicit_cast<From*, To>(0);
+ }
+
+ // uses RTTI in dbg and fastbuild. asserts are disabled in opt builds.
+ assert(f == NULL || dynamic_cast<To>(f) != NULL);
+ return static_cast<To>(f);
+}
+
+// Overload of down_cast for references. Use like this: down_cast<T&>(foo).
+// The code is slightly convoluted because we're still using the pointer
+// form of dynamic cast. (The reference form throws an exception if it
+// fails.)
+//
+// There's no need for a special const overload either for the pointer
+// or the reference form. If you call down_cast with a const T&, the
+// compiler will just bind From to const T.
+template<typename To, typename From>
+inline To down_cast(From& f) {
+ COMPILE_ASSERT(base::is_reference<To>::value, target_type_not_a_reference);
+ typedef typename base::remove_reference<To>::type* ToAsPointer;
+ if (false) {
+ // Compile-time check that To inherits from From. See above for details.
+ implicit_cast<From*, ToAsPointer>(0);
+ }
+
+ assert(dynamic_cast<ToAsPointer>(&f) != NULL); // RTTI: debug mode only
+ return static_cast<To>(f);
+}
+
+// bit_cast<Dest,Source> is a template function that implements the
+// equivalent of "*reinterpret_cast<Dest*>(&source)". We need this in
+// very low-level functions like the protobuf library and fast math
+// support.
+//
+// float f = 3.14159265358979;
+// int i = bit_cast<int32>(f);
+// // i = 0x40490fdb
+//
+// The classical address-casting method is:
+//
+// // WRONG
+// float f = 3.14159265358979; // WRONG
+// int i = * reinterpret_cast<int*>(&f); // WRONG
+//
+// The address-casting method actually produces undefined behavior
+// according to ISO C++ specification section 3.10 -15 -. Roughly, this
+// section says: if an object in memory has one type, and a program
+// accesses it with a different type, then the result is undefined
+// behavior for most values of "different type".
+//
+// This is true for any cast syntax, either *(int*)&f or
+// *reinterpret_cast<int*>(&f). And it is particularly true for
+// conversions betweeen integral lvalues and floating-point lvalues.
+//
+// The purpose of 3.10 -15- is to allow optimizing compilers to assume
+// that expressions with different types refer to different memory. gcc
+// 4.0.1 has an optimizer that takes advantage of this. So a
+// non-conforming program quietly produces wildly incorrect output.
+//
+// The problem is not the use of reinterpret_cast. The problem is type
+// punning: holding an object in memory of one type and reading its bits
+// back using a different type.
+//
+// The C++ standard is more subtle and complex than this, but that
+// is the basic idea.
+//
+// Anyways ...
+//
+// bit_cast<> calls memcpy() which is blessed by the standard,
+// especially by the example in section 3.9 . Also, of course,
+// bit_cast<> wraps up the nasty logic in one place.
+//
+// Fortunately memcpy() is very fast. In optimized mode, with a
+// constant size, gcc 2.95.3, gcc 4.0.1, and msvc 7.1 produce inline
+// code with the minimal amount of data movement. On a 32-bit system,
+// memcpy(d,s,4) compiles to one load and one store, and memcpy(d,s,8)
+// compiles to two loads and two stores.
+//
+// I tested this code with gcc 2.95.3, gcc 4.0.1, icc 8.1, and msvc 7.1.
+//
+// WARNING: if Dest or Source is a non-POD type, the result of the memcpy
+// is likely to surprise you.
+//
+// Props to Bill Gibbons for the compile time assertion technique and
+// Art Komninos and Igor Tandetnik for the msvc experiments.
+//
+// -- mec 2005-10-17
+
+template <class Dest, class Source>
+inline Dest bit_cast(const Source& source) {
+ // Compile time assertion: sizeof(Dest) == sizeof(Source)
+ // A compile error here means your Dest and Source have different sizes.
+ typedef char VerifySizesAreEqual [sizeof(Dest) == sizeof(Source) ? 1 : -1];
+
+ Dest dest;
+ memcpy(&dest, &source, sizeof(dest));
+ return dest;
+}
+
+
+// **** Enumeration Casts and Tests
+//
+// C++ requires that the value of an integer that is converted to an
+// enumeration be within the value bounds of the enumeration. Modern
+// compilers can and do take advantage of this requirement to optimize
+// programs. So, using a raw static_cast with enums can be bad. See
+//
+// The following templates and macros enable casting from an int to an enum
+// with checking against the appropriate bounds. First, when defining an
+// enumeration, identify the limits of the values of its enumerators.
+//
+// enum A { A_min = -18, A_max = 33 };
+// MAKE_ENUM_LIMITS(A, A_min, A_max)
+//
+// Convert an enum to an int in one of two ways. The prefered way is a
+// tight conversion, which ensures that A_min <= value <= A_max.
+//
+// A var = tight_enum_cast<A>(3);
+//
+// However, the C++ language defines the set of possible values for an
+// enumeration to be essentially the range of a bitfield that can represent
+// all the enumerators, i.e. those within the nearest containing power
+// of two. In the example above, the nearest positive power of two is 64,
+// and so the upper bound is 63. The nearest negative power of two is
+// -32 and so the lower bound is -32 (two's complement), which is upgraded
+// to match the upper bound, becoming -64. The values within this range
+// of -64 to 63 are valid, according to the C++ standard. You can cast
+// values within this range as follows.
+//
+// A var = loose_enum_cast<A>(45);
+//
+// These casts will log a message if the value does not reside within the
+// specified range, and will be fatal when in debug mode.
+//
+// For those times when an assert too strong, there are test functions.
+//
+// bool var = tight_enum_test<A>(3);
+// bool var = loose_enum_test<A>(45);
+//
+// For code that needs to use the enumeration value if and only if
+// it is good, there is a function that both tests and casts.
+//
+// int i = ....;
+// A var;
+// if (tight_enum_test_cast<A>(i, &var))
+// .... // use valid var with value as indicated by i
+// else
+// .... // handle invalid enum cast
+//
+// The enum test/cast facility is currently limited to enumerations that
+// fit within an int. It is also limited to two's complement ints.
+
+// ** Implementation Description
+//
+// The enum_limits template class captures the minimum and maximum
+// enumerator. All uses of this template are intended to be of
+// specializations, so the generic has a field to identify itself as
+// not specialized. The test/cast templates assert specialization.
+
+template <typename Enum>
+class enum_limits {
+ public:
+ static const Enum min_enumerator = 0;
+ static const Enum max_enumerator = 0;
+ static const bool is_specialized = false;
+};
+
+// Now we define the macro to define the specialization for enum_limits.
+// The specialization checks that the enumerators fit within an int.
+// This checking relies on integral promotion.
+
+#define MAKE_ENUM_LIMITS(ENUM_TYPE, ENUM_MIN, ENUM_MAX) \
+template <> \
+class enum_limits<ENUM_TYPE> { \
+public: \
+ static const ENUM_TYPE min_enumerator = ENUM_MIN; \
+ static const ENUM_TYPE max_enumerator = ENUM_MAX; \
+ static const bool is_specialized = true; \
+ COMPILE_ASSERT(ENUM_MIN >= INT_MIN, enumerator_too_negative_for_int); \
+ COMPILE_ASSERT(ENUM_MAX <= INT_MAX, enumerator_too_positive_for_int); \
+};
+
+// The loose enum test/cast is actually the more complicated one,
+// because of the problem of finding the bounds.
+//
+// The unary upper bound, ub, on a positive number is its positive
+// saturation, i.e. for a value v within pow(2,k-1) <= v < pow(2,k),
+// the upper bound is pow(2,k)-1.
+//
+// The unary lower bound, lb, on a negative number is its negative
+// saturation, i.e. for a value v within -pow(2,k) <= v < -pow(2,k-1),
+// the lower bound is -pow(2,k).
+//
+// The actual bounds are (1) the binary upper bound over the maximum
+// enumerator and the one's complement of a negative minimum enumerator
+// and (2) the binary lower bound over the minimum enumerator and the
+// one's complement of the positive maximum enumerator, except that if no
+// enumerators are negative, the lower bound is zero.
+//
+// The algorithm relies heavily on the observation that
+//
+// a,b>0 then ub(a,b) == ub(a) | ub(b) == ub(a|b)
+// a,b<0 then lb(a,b) == lb(a) & lb(b) == lb(a&b)
+//
+// Note that the compiler will boil most of this code away
+// because of value propagation on the constant enumerator bounds.
+
+template <typename Enum>
+inline bool loose_enum_test(int e_val) {
+ COMPILE_ASSERT(enum_limits<Enum>::is_specialized, missing_MAKE_ENUM_LIMITS);
+ const Enum e_min = enum_limits<Enum>::min_enumerator;
+ const Enum e_max = enum_limits<Enum>::max_enumerator;
+ COMPILE_ASSERT(sizeof(e_val) == 4 || sizeof(e_val) == 8, unexpected_int_size);
+
+ // Find the unary bounding negative number of e_min and e_max.
+
+ // Find the unary bounding negative number of e_max.
+ // This would be b_min = e_max < 0 ? e_max : ~e_max,
+ // but we want to avoid branches to help the compiler.
+ int e_max_sign = e_max >> (sizeof(e_val)*8 - 1);
+ int b_min = ~e_max_sign ^ e_max;
+
+ // Find the binary bounding negative of both e_min and e_max.
+ b_min &= e_min;
+
+ // However, if e_min is postive, the result will be positive.
+ // Now clear all bits right of the most significant clear bit,
+ // which is a negative saturation for negative numbers.
+ // In the case of positive numbers, this is flush to zero.
+ b_min &= b_min >> 1;
+ b_min &= b_min >> 2;
+ b_min &= b_min >> 4;
+ b_min &= b_min >> 8;
+ b_min &= b_min >> 16;
+#if INT_MAX > 2147483647
+ b_min &= b_min >> 32;
+#endif
+
+ // Find the unary bounding positive number of e_max.
+ int b_max = e_max_sign ^ e_max;
+
+ // Find the binary bounding postive number of that
+ // and the unary bounding positive number of e_min.
+ int e_min_sign = e_min >> (sizeof(e_val)*8 - 1);
+ b_max |= e_min_sign ^ e_min;
+
+ // Now set all bits right of the most significant set bit,
+ // which is a postive saturation for positive numbers.
+ b_max |= b_max >> 1;
+ b_max |= b_max >> 2;
+ b_max |= b_max >> 4;
+ b_max |= b_max >> 8;
+ b_max |= b_max >> 16;
+#if INT_MAX > 2147483647
+ b_max |= b_max >> 32;
+#endif
+
+ // Finally test the bounds.
+ return b_min <= e_val && e_val <= b_max;
+}
+
+template <typename Enum>
+inline bool tight_enum_test(int e_val) {
+ COMPILE_ASSERT(enum_limits<Enum>::is_specialized, missing_MAKE_ENUM_LIMITS);
+ const Enum e_min = enum_limits<Enum>::min_enumerator;
+ const Enum e_max = enum_limits<Enum>::max_enumerator;
+ return e_min <= e_val && e_val <= e_max;
+}
+
+template <typename Enum>
+inline bool loose_enum_test_cast(int e_val, Enum* e_var) {
+ if (loose_enum_test<Enum>(e_val)) {
+ *e_var = static_cast<Enum>(e_val);
+ return true;
+ } else {
+ return false;
+ }
+}
+
+template <typename Enum>
+inline bool tight_enum_test_cast(int e_val, Enum* e_var) {
+ if (tight_enum_test<Enum>(e_val)) {
+ *e_var = static_cast<Enum>(e_val);
+ return true;
+ } else {
+ return false;
+ }
+}
+
+// The plain casts require logging, and we get header recursion if
+// it is done directly. So, we do it indirectly.
+// The following function is defined in logging.cc.
+
+namespace logging {
+
+void WarnEnumCastError(const char* name_of_type, int value_of_int);
+
+} // namespace logging
+
+template <typename Enum>
+inline Enum loose_enum_cast(int e_val) {
+ if (!loose_enum_test<Enum>(e_val)) {
+#if __GNUC__ && !__GXX_RTTI
+ // Gcc and -fno-rtti; can't issue a warning with enum name.
+ assert(false);
+#else
+ logging::WarnEnumCastError(typeid(Enum).name(), e_val);
+#endif
+ }
+ return static_cast<Enum>(e_val);
+}
+
+template <typename Enum>
+inline Enum tight_enum_cast(int e_val) {
+ if (!tight_enum_test<Enum>(e_val)) {
+#if __GNUC__ && !__GXX_RTTI
+ // Gcc and -fno-rtti; can't issue a warning with enum name.
+ assert(false);
+#else
+ logging::WarnEnumCastError(typeid(Enum).name(), e_val);
+#endif
+ }
+ return static_cast<Enum>(e_val);
+}
+
+#endif // BASE_CASTS_H_
diff --git a/src/third_party/s2/base/commandlineflags.h b/src/third_party/s2/base/commandlineflags.h
new file mode 100755
index 00000000000..70996ae4025
--- /dev/null
+++ b/src/third_party/s2/base/commandlineflags.h
@@ -0,0 +1,19 @@
+// Copyright 2010 Google
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef BASE_COMMANDLINEFLAGS_H
+#define BASE_COMMANDLINEFLAGS_H
+
+#include "gflags/gflags.h"
+
+#endif // BASE_COMMANDLINEFLAGS_H
diff --git a/src/third_party/s2/base/definer.h b/src/third_party/s2/base/definer.h
new file mode 100644
index 00000000000..d68ef1372fa
--- /dev/null
+++ b/src/third_party/s2/base/definer.h
@@ -0,0 +1,17 @@
+#ifndef BASE_DEFINER_H
+#define BASE_DEFINER_H
+
+#if defined __APPLE__ && defined __MACH__
+# define OS_MACOSX
+# define HASH_NAMESPACE __gnu_cxx
+#elif defined __linux__
+# define _GLIBCXX_PERMIT_BACKWARD_HASH
+# define OS_LINUX
+# define HASH_NAMESPACE __gnu_cxx
+#elif defined _WIN32
+# define OS_WINDOWS
+# define HASH_NAMESPACE std
+# define _USE_MATH_DEFINES
+#endif
+
+#endif // BASE_DEFINER_H
diff --git a/src/third_party/s2/base/docid.h b/src/third_party/s2/base/docid.h
new file mode 100755
index 00000000000..676618014a5
--- /dev/null
+++ b/src/third_party/s2/base/docid.h
@@ -0,0 +1,340 @@
+// Copyright 2001 and onwards Google Inc.
+
+#ifndef BASE_DOCID_H_
+#define BASE_DOCID_H_
+
+#include "base/definer.h"
+#include <assert.h>
+
+// sys/types.h is only needed by this file if !defined(NDEBUG),
+// but including it conditionally can cause hard-to-track-down
+// compilation failures that only happen when doing optimized builds.
+// Let's include it unconditionally to reduce the number of such breakages
+// we need to track down.
+// Note that uint is defined by sys/types.h only if _GNU_SOURCE or its ilk is
+// defined, and that mysql.h seems to define _GNU_SOURCE, so the problem
+// may only happen if sys/types.h is included after mysql.h.
+// We now define uint in base/port.h if needed, and in a way that won't clash.
+#include <sys/types.h> // for size_t
+
+#include "base/basictypes.h"
+
+#define DOCID_FORMAT "%llu"
+#define DOCID32BIT_FORMAT "%u"
+
+// The following help ensure type safety for docids. Use them when
+// you want to printf/scanf a docid. Note that even so, when the
+// type of docid changes you'll need to change all the format args
+// for these printf/scanf statements by hand (to be %qu, say).
+//
+// We do two kinds of docids to facilitate the transition from 32-bit
+// docids to 64-bit docids. We need both in the transition period
+// as the base index will use 32 bit docids and the incremental index
+// will use 64-bit docids.
+
+#if defined NDEBUG
+typedef uint64 DocId;
+const DocId kMaxDocId = DocId(GG_ULONGLONG(0xFFFFFFFFFFFFFFFF));
+
+static inline uint64 DocidForPrintf(const DocId& d) { return d; }
+static inline uint64* DocidForScanf(DocId* d) { return d; }
+// Used with the SparseBitmap class, primarily
+static inline uint64 DocidForBitmap(const DocId& d) { return d; }
+// Used with the docservercache stuff, for odd but reasonable reasons
+static inline uint64 DocidForFingerprinting(const DocId& d) { return d; }
+// Used with the protocol-buffer stuff
+static inline uint64 DocidForProtocolBuffer(const DocId& d) { return d; }
+// Used during anchor processing
+static inline uint64 DocidForAnchorPosition(const DocId& d) { return d; }
+// Used for checkpointing
+static inline uint64 DocidForCheckpointing(const DocId& d) { return d; }
+// Used for approximate dups detection
+static inline uint64 DocidForApproxDups(const DocId& d) { return d; }
+// Used for SWIG
+static inline uint64* DocidForSWIG(DocId* d) { return d; }
+
+// Used for miscellaneous arithmetic.
+static inline uint64 DocIdAsNumber(const DocId& d) { return d; }
+
+// ------------------------------------------------------------------
+// 32 bit docids
+// ------------------------------------------------------------------
+typedef uint32 DocId32Bit;
+const DocId32Bit kMaxDocId32Bit = static_cast<DocId32Bit>(0xFFFFFFFFul);
+static inline uint32 Docid32BitForPrintf(const DocId32Bit& d) { return d; }
+static inline uint32* Docid32BitForScanf(DocId32Bit* d) { return d; }
+static inline uint32 Docid32BitForBitmap(const DocId32Bit& d) { return d; }
+static inline uint32 Docid32BitForFingerprinting(const DocId32Bit& d) {
+ return d;
+}
+static inline uint32 Docid32BitForEncryption(const DocId32Bit &d) {
+ return d;
+}
+static inline uint32 Docid32BitForProtocolBuffer(const DocId32Bit& d) {
+ return d;
+}
+static inline uint32 Docid32BitForAnchorPosition(const DocId32Bit& d) {
+ return d;
+}
+static inline uint32 Docid32BitForCheckpointing(const DocId32Bit& d) {
+ return d;
+}
+static inline uint32 Docid32BitForApproxDups(const DocId32Bit& d) { return d; }
+
+static inline uint32 DocId32BitAsNumber(const DocId32Bit& d) { return d; }
+
+// return true if the value cannot fit in DocId32Bit
+static inline bool Is64BitDocId(const DocId& d) { return d > kMaxDocId32Bit; }
+
+#else
+// In debug mode, we make docid its own type so we can be sure of
+// type-safety. In particular, we're concerned with people who treat
+// docids as if they were signed, or who assume they're 32 bits long.
+// We don't define this always because it results in 14% bigger executables.
+//
+// DocId is thread-compatible.
+#define BINPRED_(pred) \
+ bool operator pred (const DocId& x) const { return docid_ pred x.docid_; }
+class DocId {
+ protected:
+ typedef uint64 value_type;
+ value_type docid_;
+
+ public:
+ DocId() { docid_ = 0; }
+ explicit DocId(value_type docid) { docid_ = docid; }
+ value_type docid() const { return docid_; } // ONLY use here
+ value_type* docidptr() { return &docid_; } // ie in this file
+ DocId& operator=(const DocId& x) {
+ docid_ = x.docid_;
+ return *this;
+ }
+ // These two are required for delta encoding
+ value_type operator+(const DocId& x) const { return docid_ + x.docid_; }
+ value_type operator-(const DocId& x) const { return docid_ - x.docid_; }
+
+ // needed in incrementalpr.cc
+ DocId operator+(uint64 x) const { return DocId(docid_ + x); }
+ DocId operator-(uint64 x) const { return DocId(docid_ - x); }
+ // Required for hashing, typically
+ value_type operator%(value_type m) const { return docid_ % m; }
+ // Required for sortedrepptrs.cc and partialindexreader.cc
+ DocId& operator+=(uint64 x) {
+ docid_ += x;
+ return *this;
+ }
+ // Required for moreoverreposwriter.cc & sortpageranks.cc
+ DocId& operator++() {
+ ++docid_;
+ return *this;
+ }
+ DocId& operator--() {
+ --docid_;
+ return *this;
+ }
+ // Required by dup_docid_categorizer.cc and some other twiddlers, who needs
+ // to convert 64-bit doc id into 32-bit category id. Now the only intended use
+ // of this operator is to mask off the top bits of a docid.
+ value_type operator&(value_type x) const { return docid_ & x; }
+ // Comparators
+ BINPRED_(==) BINPRED_(!=) BINPRED_(<) BINPRED_(>) BINPRED_(<=) BINPRED_(>=)
+};
+DECLARE_POD(DocId);
+#undef BINPRED_
+
+// Required for anchorbucket.cc
+inline double operator/(double a, const DocId& b) {
+ return a / static_cast<double>(b.docid()); }
+// Required for restrict-tool.cc
+inline uint64 operator/(const DocId& a, uint64 b) { return a.docid() / b; }
+// Required for index-request.cc
+inline double operator*(const DocId& a, double b) {
+ return static_cast<double>(a.docid()) * b; }
+// Required for linksreader.cc
+inline uint64 operator*(const DocId& a, uint64 b) { return a.docid() * b; }
+// Required for indexdefs.h (really should be HitPosition, not uint64)
+inline uint64 operator+(uint64 a, const DocId& b) { return a + b.docid(); }
+
+// Required for hashing docids. docservercache.cc needs to fingerprint them.
+#if !defined __SGI_STL_HASH_FUN_H // taken from stl_decl.h
+HASH_NAMESPACE_DECLARATION_START
+template <class Key> class hash;
+HASH_NAMESPACE_DECLARATION_END
+#endif
+HASH_NAMESPACE_DECLARATION_START
+template<> class hash<DocId> {
+ size_t operator()(const DocId& d) const {
+ return static_cast<size_t>(d.docid());
+ }
+};
+HASH_NAMESPACE_DECLARATION_END
+
+const DocId kMaxDocId = DocId(GG_ULONGLONG(0xFFFFFFFFFFFFFFFF));
+
+// These are defined in non-debug mode too; they're always-on type-safety
+static inline uint64 DocidForPrintf(const DocId& d) { return d.docid(); }
+static inline uint64* DocidForScanf(DocId* d) { return d->docidptr(); }
+static inline uint64 DocidForBitmap(const DocId& d) { return d.docid(); }
+static inline uint64 DocidForFingerprinting(const DocId& d)
+ { return d.docid(); }
+static inline uint64 DocidForProtocolBuffer(const DocId& d)
+ { return d.docid(); }
+static inline uint64 DocidForAnchorPosition(const DocId& d)
+ { return d.docid(); }
+static inline uint64 DocidForCheckpointing(const DocId& d)
+ { return d.docid(); }
+static inline uint64 DocidForApproxDups(const DocId& d) { return d.docid(); }
+static inline uint64 DocIdAsNumber(const DocId& d) { return d.docid(); }
+static inline uint64* DocidForSWIG(DocId* d) { return d->docidptr(); }
+
+// ---------------------------------------------------------------------
+// 32 bit docids
+//
+// ---------------------------------------------------------------------
+
+#define BINPRED32Bit_(pred) \
+ bool operator pred(const DocId32Bit& x) const { \
+ return docid_ pred x.docid_; \
+ }
+
+class DocId32Bit {
+ protected:
+ typedef uint32 value_type;
+ value_type docid_;
+
+ public:
+ DocId32Bit() { docid_ = 0; }
+ explicit DocId32Bit(value_type docid) { docid_ = docid; }
+ explicit DocId32Bit(DocId docid) {
+ // we can't use kMaxDocId32Bit as it is not yet defined
+ assert(DocIdAsNumber(docid) <= 0xFFFFFFFFul);
+ docid_ = static_cast<uint32> (DocIdAsNumber(docid));
+ }
+ value_type docid() const { return docid_; } // ONLY use here
+ value_type* docidptr() { return &docid_; } // ie in this file
+ DocId32Bit& operator=(const DocId32Bit& x) {
+ docid_ = x.docid_;
+ return *this;
+ }
+ // These two are required for delta encoding
+ value_type operator+(const DocId32Bit& x) const { return docid_ + x.docid_; }
+ value_type operator-(const DocId32Bit& x) const { return docid_ - x.docid_; }
+
+ // needed in incrementalpr.cc
+ DocId32Bit operator+(uint32 x) const { return DocId32Bit(docid_ + x); }
+ DocId32Bit operator-(uint32 x) const { return DocId32Bit(docid_ - x); }
+ // Required for hashing, typically
+ value_type operator%(value_type m) const { return docid_ % m; }
+ // Required for sortedrepptrs.cc and partialindexreader.cc
+ DocId32Bit& operator+=(uint32 x) {
+ docid_ += x;
+ return *this;
+ }
+ // Required for moreoverreposwriter.cc & sortpageranks.cc
+ DocId32Bit& operator++() {
+ ++docid_;
+ return *this;
+ }
+ DocId32Bit& operator--() {
+ --docid_;
+ return *this;
+ }
+ // Comparators
+ BINPRED32Bit_(==) BINPRED32Bit_(!=) BINPRED32Bit_(<) BINPRED32Bit_(>)
+ BINPRED32Bit_(<=) BINPRED32Bit_(>=)
+};
+DECLARE_POD(DocId32Bit);
+#undef BINPRED32Bit_
+
+const DocId32Bit kMaxDocId32Bit = DocId32Bit(0xFFFFFFFFul);
+static inline uint32 Docid32BitForBitmap(const DocId32Bit& d)
+ { return d.docid(); }
+static inline uint32 Docid32BitForPrintf(const DocId32Bit& d)
+ { return d.docid(); }
+static inline uint32* Docid32BitForScanf(DocId32Bit* d)
+ { return d->docidptr(); }
+static inline uint32 Docid32BitForFingerprinting(const DocId32Bit& d)
+ { return d.docid(); }
+static inline uint32 Docid32BitForEncryption(const DocId32Bit& d)
+ { return d.docid(); }
+static inline int32 Docid32BitForProtocolBuffer(const DocId32Bit& d)
+ { return d.docid(); }
+static inline uint32 Docid32BitForAnchorPosition(const DocId32Bit& d)
+ { return d.docid(); }
+static inline uint32 Docid32BitForCheckpointing(const DocId32Bit& d)
+ { return d.docid(); }
+static inline uint32 Docid32BitForApproxDups(const DocId32Bit& d)
+ { return d.docid(); }
+static inline uint32 DocId32BitAsNumber(const DocId32Bit& d)
+ { return d.docid(); }
+
+static inline bool Is64BitDocId(const DocId& d)
+ { return d.docid() > DocId32BitAsNumber(kMaxDocId32Bit); }
+
+inline double operator/(double a, const DocId32Bit& b)
+ { return a / b.docid(); }
+inline int operator/(const DocId32Bit& a, int b) { return a.docid() / b; }
+inline double operator*(const DocId32Bit& a, double b)
+ { return a.docid() * b; }
+inline uint64 operator*(const DocId32Bit& a, uint64 b)
+ { return a.docid() * b; }
+inline uint32 operator+(uint32 a, const DocId32Bit& b)
+ { return a + b.docid(); }
+
+HASH_NAMESPACE_DECLARATION_START
+template<> struct hash<DocId32Bit> {
+ size_t operator()(const DocId32Bit& d) const { return d.docid(); }
+};
+HASH_NAMESPACE_DECLARATION_END
+
+#endif
+
+// some definitions for 64 bit docids
+const DocId kIllegalDocId = DocId(0);
+const DocId kInitialDocId = DocId(1);
+inline DocId NextDocIdOnShard(DocId d, int shard, int num_shards) {
+ return DocId((((DocIdAsNumber(d) + num_shards - 1 - shard) /
+ num_shards) * num_shards) + shard);
+}
+
+// some definitions for 32 bit docids
+const DocId32Bit kIllegalDocId32Bit = DocId32Bit(0);
+const DocId32Bit kInitialDocId32Bit = DocId32Bit(1);
+
+// Type for index-localized docids (normal docid divided by # of
+// shards). This type is signed because 0 is a valid local docid (for
+// shard > 0), and we need an illegal value.
+typedef int32 LocalDocId;
+const LocalDocId kMaxLocalDocId = static_cast<LocalDocId>(0x7FFFFFFF);
+const LocalDocId kIllegalLocalDocId = static_cast<LocalDocId>(~0);
+
+// Conversion between local and global docids.
+// REQUIRES: the arguments should be neither Illegal nor Max.
+inline LocalDocId GlobalToLocalDocId(DocId d, int /*shard*/, int num_shards) {
+ assert(d > kIllegalDocId);
+ assert(d < kMaxDocId);
+ return static_cast<LocalDocId>(DocIdAsNumber(d) / num_shards);
+}
+inline DocId LocalToGlobalDocId(LocalDocId d, int shard, int num_shards) {
+ assert(d > kIllegalLocalDocId);
+ assert(d < kMaxLocalDocId);
+ return DocId((static_cast<uint32>(d)*num_shards) + shard);
+}
+
+// Equivalent to GlobalToLocalDocId(NextDocIdOnShard(d, sh, ns), sh, ns)
+inline LocalDocId NextLocalDocIdOnShard(DocId d, int shard, int num_shards) {
+ return GlobalToLocalDocId(NextDocIdOnShard(d, shard, num_shards),
+ shard, num_shards);
+}
+
+inline DocId DocIdFromUrlfp(Fprint urlfp) {
+ return DocId(urlfp);
+}
+
+// DocVersionId
+
+// For real time cache. A higher value means more recent.
+typedef uint32 DocVersionIdVal;
+const DocVersionIdVal kIllegalDocVersionId = static_cast<DocVersionIdVal>(0);
+
+#endif // BASE_DOCID_H_
diff --git a/src/third_party/s2/base/int128.cc b/src/third_party/s2/base/int128.cc
new file mode 100755
index 00000000000..12a338842ad
--- /dev/null
+++ b/src/third_party/s2/base/int128.cc
@@ -0,0 +1,19 @@
+// Copyright 2004 Google Inc.
+// All Rights Reserved.
+//
+//
+
+#include <iostream>
+using std::ostream;
+using std::cout;
+using std::endl;
+
+#include "int128.h"
+#include "integral_types.h"
+
+const uint128 kuint128max(static_cast<uint64>(GG_LONGLONG(0xFFFFFFFFFFFFFFFF)),
+ static_cast<uint64>(GG_LONGLONG(0xFFFFFFFFFFFFFFFF)));
+
+ostream& operator<<(ostream& o, const uint128& b) {
+ return (o << b.hi_ << "::" << b.lo_);
+}
diff --git a/src/third_party/s2/base/int128.h b/src/third_party/s2/base/int128.h
new file mode 100755
index 00000000000..13f3b73d3c5
--- /dev/null
+++ b/src/third_party/s2/base/int128.h
@@ -0,0 +1,239 @@
+// Copyright 2004 Google Inc.
+// All Rights Reserved.
+//
+
+#ifndef BASE_INT128_H_
+#define BASE_INT128_H_
+
+#include <iostream>
+using std::ostream;
+using std::cout;
+using std::endl;
+
+#include "integral_types.h"
+#include "logging.h"
+
+// An unsigned 128-bit integer type. Thread-compatible.
+class uint128 {
+public:
+ uint128(); // Sets to 0, but don't trust on this behavior.
+ uint128(uint64 top, uint64 bottom);
+#ifndef SWIG
+ uint128(int bottom);
+ uint128(uint32 bottom); // Top 96 bits = 0
+#endif
+ uint128(uint64 bottom); // hi_ = 0
+ uint128(const uint128 &val);
+
+ void Initialize(uint64 top, uint64 bottom);
+
+ bool operator==(const uint128& b) const;
+ bool operator!=(const uint128& b) const;
+ uint128& operator=(const uint128& b);
+
+ bool operator<(const uint128& b) const;
+ bool operator>(const uint128& b) const;
+ bool operator<=(const uint128& b) const;
+ bool operator>=(const uint128& b) const;
+
+ // Logical operators.
+ uint128 operator~() const;
+ uint128 operator|(const uint128& b) const;
+ uint128 operator&(const uint128& b) const;
+ uint128 operator^(const uint128& b) const;
+
+ // Shift operators.
+ uint128 operator<<(int amount) const;
+ uint128 operator>>(int amount) const;
+
+ // Arithmetic operators.
+ // TODO: multiplication, division, etc.
+ uint128 operator+(const uint128& b) const;
+ uint128 operator-(const uint128& b) const;
+ uint128 operator+=(const uint128& b);
+ uint128 operator-=(const uint128& b);
+ uint128 operator++(int);
+ uint128 operator--(int);
+ uint128 operator++();
+ uint128 operator--();
+
+ friend uint64 Uint128Low64(const uint128& v);
+ friend uint64 Uint128High64(const uint128& v);
+
+ friend ostream& operator<<(ostream& o, const uint128& b);
+
+private:
+ // Little-endian memory order optimizations can benefit from
+ // having lo_ first, hi_ last.
+ // See util/endian/endian.h and Load128/Store128 for storing a uint128.
+ uint64 lo_;
+ uint64 hi_;
+
+ // Not implemented, just declared for catching automatic type conversions.
+ uint128(uint8);
+ uint128(uint16);
+ uint128(float v);
+ uint128(double v);
+};
+
+extern const uint128 kuint128max;
+
+// allow uint128 to be logged
+extern ostream& operator<<(ostream& o, const uint128& b);
+
+// Methods to access low and high pieces of 128-bit value.
+// Defined externally from uint128 to facilitate conversion
+// to native 128-bit types when compilers support them.
+inline uint64 Uint128Low64(const uint128& v) { return v.lo_; }
+inline uint64 Uint128High64(const uint128& v) { return v.hi_; }
+
+// TODO: perhaps it would be nice to have int128, a signed 128-bit type?
+
+// --------------------------------------------------------------------------
+// Implementation details follow
+// --------------------------------------------------------------------------
+inline bool uint128::operator==(const uint128& b) const {
+ return (lo_ == b.lo_) && (hi_ == b.hi_);
+}
+inline bool uint128::operator!=(const uint128& b) const {
+ return !(*this == b);
+}
+inline uint128& uint128::operator=(const uint128& b) {
+ lo_ = b.lo_;
+ hi_ = b.hi_;
+ return *this;
+}
+
+inline uint128::uint128(): lo_(0), hi_(0) { }
+inline uint128::uint128(uint64 top, uint64 bottom) : lo_(bottom), hi_(top) { }
+inline uint128::uint128(const uint128 &v) : lo_(v.lo_), hi_(v.hi_) { }
+inline uint128::uint128(uint64 bottom) : lo_(bottom), hi_(0) { }
+#ifndef SWIG
+inline uint128::uint128(uint32 bottom) : lo_(bottom), hi_(0) { }
+inline uint128::uint128(int bottom) : lo_(bottom), hi_(0) {
+ if (bottom < 0) {
+ --hi_;
+ }
+}
+#endif
+inline void uint128::Initialize(uint64 top, uint64 bottom) {
+ hi_ = top;
+ lo_ = bottom;
+}
+
+// Comparison operators.
+
+#define CMP128(op) \
+inline bool uint128::operator op(const uint128& b) const { \
+ return (hi_ == b.hi_) ? (lo_ op b.lo_) : (hi_ op b.hi_); \
+}
+
+CMP128(<)
+CMP128(>)
+CMP128(>=)
+CMP128(<=)
+
+#undef CMP128
+
+// Logical operators.
+
+inline uint128 uint128::operator~() const {
+ return uint128(~hi_, ~lo_);
+}
+
+#define LOGIC128(op) \
+inline uint128 uint128::operator op(const uint128& b) const { \
+ return uint128(hi_ op b.hi_, lo_ op b.lo_); \
+}
+
+LOGIC128(|)
+LOGIC128(&)
+LOGIC128(^)
+
+#undef LOGIC128
+
+// Shift operators.
+
+inline uint128 uint128::operator<<(int amount) const {
+ DCHECK_GE(amount, 0);
+
+ // uint64 shifts of >= 64 are undefined, so we will need some special-casing.
+ if (amount < 64) {
+ if (amount == 0) {
+ return *this;
+ }
+ uint64 new_hi = (hi_ << amount) | (lo_ >> (64 - amount));
+ uint64 new_lo = lo_ << amount;
+ return uint128(new_hi, new_lo);
+ } else if (amount < 128) {
+ return uint128(lo_ << (amount - 64), 0);
+ } else {
+ return uint128(0, 0);
+ }
+}
+
+inline uint128 uint128::operator>>(int amount) const {
+ DCHECK_GE(amount, 0);
+
+ // uint64 shifts of >= 64 are undefined, so we will need some special-casing.
+ if (amount < 64) {
+ if (amount == 0) {
+ return *this;
+ }
+ uint64 new_hi = hi_ >> amount;
+ uint64 new_lo = (lo_ >> amount) | (hi_ << (64 - amount));
+ return uint128(new_hi, new_lo);
+ } else if (amount < 128) {
+ return uint128(0, hi_ >> (amount - 64));
+ } else {
+ return uint128(0, 0);
+ }
+}
+
+inline uint128 uint128::operator+(const uint128& b) const {
+ return uint128(*this) += b;
+}
+
+inline uint128 uint128::operator-(const uint128& b) const {
+ return uint128(*this) -= b;
+}
+
+inline uint128 uint128::operator+=(const uint128& b) {
+ hi_ += b.hi_;
+ lo_ += b.lo_;
+ if (lo_ < b.lo_)
+ ++hi_;
+ return *this;
+}
+
+inline uint128 uint128::operator-=(const uint128& b) {
+ hi_ -= b.hi_;
+ if (b.lo_ > lo_)
+ --hi_;
+ lo_ -= b.lo_;
+ return *this;
+}
+
+inline uint128 uint128::operator++(int) {
+ uint128 tmp(*this);
+ *this += 1;
+ return tmp;
+}
+
+inline uint128 uint128::operator--(int) {
+ uint128 tmp(*this);
+ *this -= 1;
+ return tmp;
+}
+
+inline uint128 uint128::operator++() {
+ *this += 1;
+ return *this;
+}
+
+inline uint128 uint128::operator--() {
+ *this -= 1;
+ return *this;
+}
+
+#endif // BASE_INT128_H_
diff --git a/src/third_party/s2/base/integral_types.h b/src/third_party/s2/base/integral_types.h
new file mode 100755
index 00000000000..96826148713
--- /dev/null
+++ b/src/third_party/s2/base/integral_types.h
@@ -0,0 +1,107 @@
+// Copyright 2008 Google Inc. All Rights Reserved.
+//
+// Basic integer type definitions for various platforms
+//
+// This code is compiled directly on many platforms, including client
+// platforms like Windows, Mac, and embedded systems. Before making
+// any changes here, make sure that you're not breaking any platforms.
+//
+
+#ifndef BASE_INT_TYPES_H_
+#define BASE_INT_TYPES_H_
+
+// These typedefs are also defined in base/google.swig. In the
+// SWIG environment, we use those definitions and avoid duplicate
+// definitions here with an ifdef. The definitions should be the
+// same in both files, and ideally be only defined in this file.
+#ifndef SWIG
+// Standard typedefs
+// All Google2 code is compiled with -funsigned-char to make "char"
+// unsigned. Google2 code therefore doesn't need a "uchar" type.
+typedef signed char schar;
+typedef signed char int8;
+typedef short int16;
+typedef int int32;
+#ifdef COMPILER_MSVC
+typedef __int64 int64;
+#else
+typedef long long int64;
+#endif /* COMPILER_MSVC */
+
+// NOTE: unsigned types are DANGEROUS in loops and other arithmetical
+// places. Use the signed types unless your variable represents a bit
+// pattern (eg a hash value) or you really need the extra bit. Do NOT
+// use 'unsigned' to express "this value should always be positive";
+// use assertions for this.
+
+typedef unsigned char uint8;
+typedef unsigned short uint16;
+typedef unsigned int uint32;
+#ifdef COMPILER_MSVC
+typedef unsigned __int64 uint64;
+#else
+typedef unsigned long long uint64;
+#endif /* COMPILER_MSVC */
+
+// A type to represent a Unicode code-point value. As of Unicode 4.0,
+// such values require up to 21 bits.
+// (For type-checking on pointers, make this explicitly signed,
+// and it should always be the signed version of whatever int32 is.)
+typedef signed int char32;
+
+// A type to represent a natural machine word (for e.g. efficiently
+// scanning through memory for checksums or index searching). Don't use
+// this for storing normal integers. Ideally this would be just
+// unsigned int, but our 64-bit architectures use the LP64 model
+// (http://www.opengroup.org/public/tech/aspen/lp64_wp.htm), hence
+// their ints are only 32 bits. We want to use the same fundamental
+// type on all archs if possible to preserve *printf() compatability.
+typedef unsigned long uword_t;
+
+// A signed natural machine word. In general you want to use "int"
+// rather than "sword_t"
+typedef long sword_t;
+
+#endif /* SWIG */
+
+// long long macros to be used because gcc and vc++ use different suffixes,
+// and different size specifiers in format strings
+#undef GG_LONGLONG
+#undef GG_ULONGLONG
+#undef GG_LL_FORMAT
+
+#ifdef COMPILER_MSVC /* if Visual C++ */
+
+// VC++ long long suffixes
+#define GG_LONGLONG(x) x##I64
+#define GG_ULONGLONG(x) x##UI64
+
+// Length modifier in printf format string for int64's (e.g. within %d)
+#define GG_LL_FORMAT "I64" // As in printf("%I64d", ...)
+#define GG_LL_FORMAT_W L"I64"
+
+#else /* not Visual C++ */
+
+#define GG_LONGLONG(x) x##LL
+#define GG_ULONGLONG(x) x##ULL
+#define GG_LL_FORMAT "ll" // As in "%lld". Note that "q" is poor form also.
+#define GG_LL_FORMAT_W L"ll"
+
+#endif // COMPILER_MSVC
+
+
+static const uint8 kuint8max = (( uint8) 0xFF);
+static const uint16 kuint16max = ((uint16) 0xFFFF);
+static const uint32 kuint32max = ((uint32) 0xFFFFFFFF);
+static const uint64 kuint64max = ((uint64) GG_LONGLONG(0xFFFFFFFFFFFFFFFF));
+static const int8 kint8min = (( int8) 0x80);
+static const int8 kint8max = (( int8) 0x7F);
+static const int16 kint16min = (( int16) 0x8000);
+static const int16 kint16max = (( int16) 0x7FFF);
+static const int32 kint32min = (( int32) 0x80000000);
+static const int32 kint32max = (( int32) 0x7FFFFFFF);
+static const int64 kint64min = (( int64) GG_LONGLONG(0x8000000000000000));
+static const int64 kint64max = (( int64) GG_LONGLONG(0x7FFFFFFFFFFFFFFF));
+
+
+#endif // BASE_INT_TYPES_H_
diff --git a/src/third_party/s2/base/logging.cc b/src/third_party/s2/base/logging.cc
new file mode 100755
index 00000000000..45acf2333fa
--- /dev/null
+++ b/src/third_party/s2/base/logging.cc
@@ -0,0 +1,38 @@
+// Copyright 2010 Google
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "stdio.h"
+#include "time.h"
+
+#include "logging.h"
+
+namespace google_base {
+DateLogger::DateLogger() {
+#if defined(_MSC_VER)
+ _tzset();
+#endif
+}
+
+char* const DateLogger::HumanDate() {
+#if defined(_MSC_VER)
+ _strtime_s(buffer_, sizeof(buffer_));
+#else
+ time_t time_value = time(NULL);
+ struct tm now;
+ localtime_r(&time_value, &now);
+ snprintf(buffer_, sizeof(buffer_), "%02d:%02d:%02d",
+ now.tm_hour, now.tm_min, now.tm_sec);
+#endif
+ return buffer_;
+}
+} // namespace google_base
diff --git a/src/third_party/s2/base/logging.h b/src/third_party/s2/base/logging.h
new file mode 100755
index 00000000000..28c513227f1
--- /dev/null
+++ b/src/third_party/s2/base/logging.h
@@ -0,0 +1,99 @@
+// Copyright 2010 Google
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef BASE_LOGGING_H
+#define BASE_LOGGING_H
+
+#include <stdlib.h>
+#include <stdlib.h>
+#include <iostream>
+using std::ostream;
+using std::cout;
+using std::endl;
+
+#include "macros.h"
+
+// Always-on checking
+#define CHECK(x) if(x){}else LogMessageFatal(__FILE__, __LINE__).stream() << "Check failed: " #x
+#define CHECK_LT(x, y) CHECK((x) < (y))
+#define CHECK_GT(x, y) CHECK((x) > (y))
+#define CHECK_LE(x, y) CHECK((x) <= (y))
+#define CHECK_GE(x, y) CHECK((x) >= (y))
+#define CHECK_EQ(x, y) CHECK((x) == (y))
+#define CHECK_NE(x, y) CHECK((x) != (y))
+#define CHECK_NOTNULL(x) CHECK((x) != NULL)
+
+#ifndef NDEBUG
+// Debug-only checking.
+#define DCHECK(condition) CHECK(condition)
+#define DCHECK_EQ(val1, val2) CHECK_EQ(val1, val2)
+#define DCHECK_NE(val1, val2) CHECK_NE(val1, val2)
+#define DCHECK_LE(val1, val2) CHECK_LE(val1, val2)
+#define DCHECK_LT(val1, val2) CHECK_LT(val1, val2)
+#define DCHECK_GE(val1, val2) CHECK_GE(val1, val2)
+#define DCHECK_GT(val1, val2) CHECK_GT(val1, val2)
+#else
+#define DCHECK(condition) CHECK(false)
+#define DCHECK_EQ(val1, val2) CHECK(false)
+#define DCHECK_NE(val1, val2) CHECK(false)
+#define DCHECK_LE(val1, val2) CHECK(false)
+#define DCHECK_LT(val1, val2) CHECK(false)
+#define DCHECK_GE(val1, val2) CHECK(false)
+#define DCHECK_GT(val1, val2) CHECK(false)
+#endif
+
+#include "base/port.h"
+#define INFO std::cout
+#define FATAL std::cerr
+#define DFATAL std::cerr
+
+#define S2LOG(x) x
+#define VLOG(x) if (x>0) {} else S2LOG(INFO)
+
+namespace google_base {
+class DateLogger {
+ public:
+ DateLogger();
+ char* const HumanDate();
+ private:
+ char buffer_[9];
+};
+} // namespace google_base
+
+class LogMessage {
+ public:
+ LogMessage(const char* file, int line) {
+ std::cerr << "[" << pretty_date_.HumanDate() << "] "
+ << file << ":" << line << ": ";
+ }
+ ~LogMessage() { std::cerr << "\n"; }
+ std::ostream& stream() { return std::cerr; }
+
+ private:
+ google_base::DateLogger pretty_date_;
+ DISALLOW_COPY_AND_ASSIGN(LogMessage);
+};
+
+class LogMessageFatal : public LogMessage {
+ public:
+ LogMessageFatal(const char* file, int line)
+ : LogMessage(file, line) { }
+ ~LogMessageFatal() {
+ std::cerr << "\n";
+ ::abort();
+ }
+ private:
+ DISALLOW_COPY_AND_ASSIGN(LogMessageFatal);
+};
+
+#endif // BASE_LOGGING_H
diff --git a/src/third_party/s2/base/macros.h b/src/third_party/s2/base/macros.h
new file mode 100755
index 00000000000..f273c1660e1
--- /dev/null
+++ b/src/third_party/s2/base/macros.h
@@ -0,0 +1,263 @@
+// Copyright 2008 Google Inc. All Rights Reserved.
+//
+// Various Google-specific macros.
+//
+// This code is compiled directly on many platforms, including client
+// platforms like Windows, Mac, and embedded systems. Before making
+// any changes here, make sure that you're not breaking any platforms.
+//
+
+#ifndef BASE_MACROS_H_
+#define BASE_MACROS_H_
+
+#include <stddef.h> // For size_t
+
+// We use our own local version of type traits while we're waiting
+// for TR1 type traits to be standardized. Define some macros so that
+// most google3 code doesn't have to work with type traits directly.
+#include "type_traits.h"
+
+// The swigged version of an abstract class must be concrete if any methods
+// return objects of the abstract type. We keep it abstract in C++ and
+// concrete for swig.
+#ifndef SWIG
+#define ABSTRACT = 0
+#endif
+
+// The COMPILE_ASSERT macro can be used to verify that a compile time
+// expression is true. For example, you could use it to verify the
+// size of a static array:
+//
+// COMPILE_ASSERT(ARRAYSIZE(content_type_names) == CONTENT_NUM_TYPES,
+// content_type_names_incorrect_size);
+//
+// or to make sure a struct is smaller than a certain size:
+//
+// COMPILE_ASSERT(sizeof(foo) < 128, foo_too_large);
+//
+// The second argument to the macro is the name of the variable. If
+// the expression is false, most compilers will issue a warning/error
+// containing the name of the variable.
+
+template <bool>
+struct CompileAssert {
+};
+
+#define COMPILE_ASSERT(expr, msg) \
+ typedef CompileAssert<(bool(expr))> msg[bool(expr) ? 1 : -1]
+
+// Implementation details of COMPILE_ASSERT:
+//
+// - COMPILE_ASSERT works by defining an array type that has -1
+// elements (and thus is invalid) when the expression is false.
+//
+// - The simpler definition
+//
+// #define COMPILE_ASSERT(expr, msg) typedef char msg[(expr) ? 1 : -1]
+//
+// does not work, as gcc supports variable-length arrays whose sizes
+// are determined at run-time (this is gcc's extension and not part
+// of the C++ standard). As a result, gcc fails to reject the
+// following code with the simple definition:
+//
+// int foo;
+// COMPILE_ASSERT(foo, msg); // not supposed to compile as foo is
+// // not a compile-time constant.
+//
+// - By using the type CompileAssert<(bool(expr))>, we ensures that
+// expr is a compile-time constant. (Template arguments must be
+// determined at compile-time.)
+//
+// - The outter parentheses in CompileAssert<(bool(expr))> are necessary
+// to work around a bug in gcc 3.4.4 and 4.0.1. If we had written
+//
+// CompileAssert<bool(expr)>
+//
+// instead, these compilers will refuse to compile
+//
+// COMPILE_ASSERT(5 > 0, some_message);
+//
+// (They seem to think the ">" in "5 > 0" marks the end of the
+// template argument list.)
+//
+// - The array size is (bool(expr) ? 1 : -1), instead of simply
+//
+// ((expr) ? 1 : -1).
+//
+// This is to avoid running into a bug in MS VC 7.1, which
+// causes ((0.0) ? 1 : -1) to incorrectly evaluate to 1.
+
+
+// A macro to disallow the copy constructor and operator= functions
+// This should be used in the private: declarations for a class
+//
+// For disallowing only assign or copy, write the code directly, but declare
+// the intend in a comment, for example:
+// void operator=(const TypeName&); // DISALLOW_ASSIGN
+// Note, that most uses of DISALLOW_ASSIGN and DISALLOW_COPY are broken
+// semantically, one should either use disallow both or neither. Try to
+// avoid these in new code.
+#define DISALLOW_COPY_AND_ASSIGN(TypeName) \
+ TypeName(const TypeName&); \
+ void operator=(const TypeName&)
+
+// An older, politically incorrect name for the above.
+// Prefer DISALLOW_COPY_AND_ASSIGN for new code.
+#define DISALLOW_EVIL_CONSTRUCTORS(TypeName) DISALLOW_COPY_AND_ASSIGN(TypeName)
+
+// A macro to disallow all the implicit constructors, namely the
+// default constructor, copy constructor and operator= functions.
+//
+// This should be used in the private: declarations for a class
+// that wants to prevent anyone from instantiating it. This is
+// especially useful for classes containing only static methods.
+#define DISALLOW_IMPLICIT_CONSTRUCTORS(TypeName) \
+ TypeName(); \
+ DISALLOW_COPY_AND_ASSIGN(TypeName)
+
+// The arraysize(arr) macro returns the # of elements in an array arr.
+// The expression is a compile-time constant, and therefore can be
+// used in defining new arrays, for example. If you use arraysize on
+// a pointer by mistake, you will get a compile-time error.
+//
+// One caveat is that arraysize() doesn't accept any array of an
+// anonymous type or a type defined inside a function. In these rare
+// cases, you have to use the unsafe ARRAYSIZE() macro below. This is
+// due to a limitation in C++'s template system. The limitation might
+// eventually be removed, but it hasn't happened yet.
+
+// This template function declaration is used in defining arraysize.
+// Note that the function doesn't need an implementation, as we only
+// use its type.
+template <typename T, size_t N>
+char (&ArraySizeHelper(T (&array)[N]))[N];
+
+// That gcc wants both of these prototypes seems mysterious. VC, for
+// its part, can't decide which to use (another mystery). Matching of
+// template overloads: the final frontier.
+#ifndef COMPILER_MSVC
+template <typename T, size_t N>
+char (&ArraySizeHelper(const T (&array)[N]))[N];
+#endif
+
+#define arraysize(array) (sizeof(ArraySizeHelper(array)))
+
+// ARRAYSIZE performs essentially the same calculation as arraysize,
+// but can be used on anonymous types or types defined inside
+// functions. It's less safe than arraysize as it accepts some
+// (although not all) pointers. Therefore, you should use arraysize
+// whenever possible.
+//
+// The expression ARRAYSIZE(a) is a compile-time constant of type
+// size_t.
+//
+// ARRAYSIZE catches a few type errors. If you see a compiler error
+//
+// "warning: division by zero in ..."
+//
+// when using ARRAYSIZE, you are (wrongfully) giving it a pointer.
+// You should only use ARRAYSIZE on statically allocated arrays.
+//
+// The following comments are on the implementation details, and can
+// be ignored by the users.
+//
+// ARRAYSIZE(arr) works by inspecting sizeof(arr) (the # of bytes in
+// the array) and sizeof(*(arr)) (the # of bytes in one array
+// element). If the former is divisible by the latter, perhaps arr is
+// indeed an array, in which case the division result is the # of
+// elements in the array. Otherwise, arr cannot possibly be an array,
+// and we generate a compiler error to prevent the code from
+// compiling.
+//
+// Since the size of bool is implementation-defined, we need to cast
+// !(sizeof(a) & sizeof(*(a))) to size_t in order to ensure the final
+// result has type size_t.
+//
+// This macro is not perfect as it wrongfully accepts certain
+// pointers, namely where the pointer size is divisible by the pointee
+// size. Since all our code has to go through a 32-bit compiler,
+// where a pointer is 4 bytes, this means all pointers to a type whose
+// size is 3 or greater than 4 will be (righteously) rejected.
+//
+// Kudos to Jorg Brown for this simple and elegant implementation.
+//
+// - wan 2005-11-16
+//
+// Starting with Visual C++ 2005, WinNT.h includes ARRAYSIZE.
+#ifndef OS_WINDOWS
+#if !defined(COMPILER_MSVC) || (defined(_MSC_VER) && _MSC_VER < 1400)
+#define ARRAYSIZE(a) \
+ ((sizeof(a) / sizeof(*(a))) / \
+ static_cast<size_t>(!(sizeof(a) % sizeof(*(a)))))
+#endif
+#endif
+
+// A macro to turn a symbol into a string
+#define AS_STRING(x) AS_STRING_INTERNAL(x)
+#define AS_STRING_INTERNAL(x) #x
+
+
+// One of the type traits, is_pod, makes it possible to query whether
+// a type is a POD type. It is impossible for type_traits.h to get
+// this right without compiler support, so it fails conservatively. It
+// knows that fundamental types and pointers are PODs, but it can't
+// tell whether user classes are PODs. The DECLARE_POD macro is used
+// to inform the type traits library that a user class is a POD.
+//
+// Implementation note: the typedef at the end is just to make it legal
+// to put a semicolon after DECLARE_POD(foo).
+//
+// The only reason this matters is that a few parts of the google3
+// code base either require their template arguments to be PODs
+// (e.g. compact_vector) or are able to use a more efficient code path
+// when their template arguments are PODs (e.g. sparse_hash_map). You
+// should use DECLARE_POD if you have written a class that you intend
+// to use with one of those components, and if you know that your
+// class satisfies all of the conditions to be a POD type.
+//
+// So what's a POD? The C++ standard (clause 9 paragraph 4) gives a
+// full definition, but a good rule of thumb is that a struct is a POD
+// ("plain old data") if it doesn't use any of the features that make
+// C++ different from C. A POD struct can't have constructors,
+// destructors, assignment operators, base classes, private or
+// protected members, or virtual functions, and all of its member
+// variables must themselves be PODs.
+
+#define DECLARE_POD(TypeName) \
+namespace base { \
+template<> struct is_pod<TypeName> : true_type { }; \
+} \
+typedef int Dummy_Type_For_DECLARE_POD \
+
+// We once needed a different technique to assert that a nested class
+// is a POD. This is no longer necessary, and DECLARE_NESTED_POD is
+// just a synonym for DECLARE_POD. We continue to provide
+// DECLARE_NESTED_POD only so we don't have to change client
+// code. Regardless of whether you use DECLARE_POD or
+// DECLARE_NESTED_POD: use it after the outer class. Using it within a
+// class definition will give a compiler error.
+#define DECLARE_NESTED_POD(TypeName) DECLARE_POD(TypeName)
+
+// Declare that TemplateName<T> is a POD whenever T is
+#define PROPAGATE_POD_FROM_TEMPLATE_ARGUMENT(TemplateName) \
+namespace base { \
+template <typename T> struct is_pod<TemplateName<T> > : is_pod<T> { }; \
+} \
+typedef int Dummy_Type_For_PROPAGATE_POD_FROM_TEMPLATE_ARGUMENT
+
+// Macro that does nothing if TypeName is a POD, and gives a compiler
+// error if TypeName is a non-POD. You should put a descriptive
+// comment right next to the macro call so that people can tell what
+// the compiler error is about.
+//
+// Implementation note: this works by taking the size of a type that's
+// complete when TypeName is a POD and incomplete otherwise.
+
+template <bool IsPod> struct ERROR_TYPE_MUST_BE_POD;
+template <> struct ERROR_TYPE_MUST_BE_POD<true> { };
+#define ENFORCE_POD(TypeName) \
+ enum { dummy_##TypeName \
+ = sizeof(ERROR_TYPE_MUST_BE_POD< \
+ base::is_pod<TypeName>::value>) }
+
+#endif // BASE_MACROS_H_
diff --git a/src/third_party/s2/base/port.h b/src/third_party/s2/base/port.h
new file mode 100755
index 00000000000..5b6514c19bf
--- /dev/null
+++ b/src/third_party/s2/base/port.h
@@ -0,0 +1,1081 @@
+//
+// Copyright (C) 1999 and onwards Google, Inc.
+//
+//
+// These are weird things we need to do to get this compiling on
+// random systems (and on SWIG).
+
+#ifndef BASE_PORT_H_
+#define BASE_PORT_H_
+
+#include "base/definer.h"
+
+#include <limits.h> // So we can set the bounds of our types
+#include <string.h> // for memcpy()
+#include <stdlib.h> // for free()
+
+#if defined(OS_MACOSX)
+#include <unistd.h> // for getpagesize() on mac
+#elif defined(OS_CYGWIN)
+#include <malloc.h> // for memalign()
+#endif
+
+#include "integral_types.h"
+
+// Must happens before inttypes.h inclusion */
+#if defined(OS_MACOSX)
+/* From MacOSX's inttypes.h:
+ * "C++ implementations should define these macros only when
+ * __STDC_FORMAT_MACROS is defined before <inttypes.h> is included." */
+#ifndef __STDC_FORMAT_MACROS
+#define __STDC_FORMAT_MACROS
+#endif /* __STDC_FORMAT_MACROS */
+#endif /* OS_MACOSX */
+
+/* Default for most OSes */
+/* We use SIGPWR since that seems unlikely to be used for other reasons. */
+#define GOOGLE_OBSCURE_SIGNAL SIGPWR
+
+#if defined OS_LINUX || defined OS_CYGWIN
+
+// _BIG_ENDIAN
+#include <endian.h>
+
+// The uint mess:
+// mysql.h sets _GNU_SOURCE which sets __USE_MISC in <features.h>
+// sys/types.h typedefs uint if __USE_MISC
+// mysql typedefs uint if HAVE_UINT not set
+// The following typedef is carefully considered, and should not cause
+// any clashes
+#if !defined(__USE_MISC)
+#if !defined(HAVE_UINT)
+#define HAVE_UINT 1
+typedef unsigned int uint;
+#endif
+#if !defined(HAVE_USHORT)
+#define HAVE_USHORT 1
+typedef unsigned short ushort;
+#endif
+#if !defined(HAVE_ULONG)
+#define HAVE_ULONG 1
+typedef unsigned long ulong;
+#endif
+#endif
+
+#if defined(__cplusplus)
+#include <cstddef> // For _GLIBCXX macros
+#endif
+
+#if !defined(HAVE_TLS) && defined(_GLIBCXX_HAVE_TLS) && defined(ARCH_K8)
+#define HAVE_TLS 1
+#endif
+
+#elif defined OS_FREEBSD
+
+// _BIG_ENDIAN
+#include <machine/endian.h>
+
+#elif defined OS_SOLARIS
+
+// _BIG_ENDIAN
+#include <sys/isa_defs.h>
+
+// Solaris doesn't define sig_t (function taking an int, returning void)
+typedef void (*sig_t)(int);
+
+// Solaris only defines strtoll, not strtoq
+#define strtoq strtoll
+#define strtouq strtoull
+
+// It doesn't define the posix-standard(?) u_int_16
+#include <sys/int_types.h>
+typedef uint16_t u_int16_t;
+
+#elif defined OS_MACOSX
+
+// BIG_ENDIAN
+#include <machine/endian.h>
+/* Let's try and follow the Linux convention */
+#define __BYTE_ORDER BYTE_ORDER
+#define __LITTLE_ENDIAN LITTLE_ENDIAN
+#define __BIG_ENDIAN BIG_ENDIAN
+
+#endif
+
+// The following guarenty declaration of the byte swap functions, and
+// define __BYTE_ORDER for MSVC
+#ifdef OS_WINDOWS
+#include <stdlib.h>
+#define __BYTE_ORDER __LITTLE_ENDIAN
+#define bswap_16(x) _byteswap_ushort(x)
+#define bswap_32(x) _byteswap_ulong(x)
+#define bswap_64(x) _byteswap_uint64(x)
+
+#elif defined(OS_MACOSX)
+// Mac OS X / Darwin features
+#include <libkern/OSByteOrder.h>
+#define bswap_16(x) OSSwapInt16(x)
+#define bswap_32(x) OSSwapInt32(x)
+#define bswap_64(x) OSSwapInt64(x)
+
+#else
+#include <byteswap.h>
+#endif
+
+
+// define the macros IS_LITTLE_ENDIAN or IS_BIG_ENDIAN
+// using the above endian defintions from endian.h if
+// endian.h was included
+#ifdef __BYTE_ORDER
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+#define IS_LITTLE_ENDIAN
+#endif
+
+#if __BYTE_ORDER == __BIG_ENDIAN
+#define IS_BIG_ENDIAN
+#endif
+
+#else
+
+#if defined(__LITTLE_ENDIAN__)
+#define IS_LITTLE_ENDIAN
+#elif defined(__BIG_ENDIAN__)
+#define IS_BIG_ENDIAN
+#endif
+
+// there is also PDP endian ...
+
+#endif // __BYTE_ORDER
+
+// Define the OS's path separator
+#ifdef __cplusplus // C won't merge duplicate const variables at link time
+// Some headers provide a macro for this (GCC's system.h), remove it so that we
+// can use our own.
+#undef PATH_SEPARATOR
+#ifdef OS_WINDOWS
+const char PATH_SEPARATOR = '\\';
+#else
+const char PATH_SEPARATOR = '/';
+#endif
+#endif
+
+// Windows has O_BINARY as a flag to open() (like "b" for fopen).
+// Linux doesn't need make this distinction.
+#if defined OS_LINUX && !defined O_BINARY
+#define O_BINARY 0
+#endif
+
+// va_copy portability definitions
+#ifdef COMPILER_MSVC
+// MSVC doesn't have va_copy yet.
+// This is believed to work for 32-bit msvc. This may not work at all for
+// other platforms.
+// If va_list uses the single-element-array trick, you will probably get
+// a compiler error here.
+//
+#include <stdarg.h>
+inline void va_copy(va_list& a, va_list& b) {
+ a = b;
+}
+
+// Nor does it have uid_t
+typedef int uid_t;
+
+#endif
+
+// Mac OS X / Darwin features
+
+#if defined(OS_MACOSX)
+
+// For mmap, Linux defines both MAP_ANONYMOUS and MAP_ANON and says MAP_ANON is
+// deprecated. In Darwin, MAP_ANON is all there is.
+#if !defined MAP_ANONYMOUS
+#define MAP_ANONYMOUS MAP_ANON
+#endif
+
+// Linux has this in <sys/cdefs.h>
+#define __ptr_t void *
+
+// Linux has this in <linux/errno.h>
+#define EXFULL ENOMEM // not really that great a translation...
+
+// Mach-O supports sections (albeit with small names), but doesn't have
+// vars at the beginning and end. Instead you should call the function
+// getsectdata("__DATA", name, &size).
+#define HAVE_ATTRIBUTE_SECTION 1
+
+// Any function with ATTRIBUTE_SECTION must not be inlined, or it will
+// be placed into whatever section its caller is placed into.
+#define ATTRIBUTE_SECTION(name) \
+ __attribute__ ((section ("__DATA, " #name))) __attribute__ ((noinline))
+
+#define ENUM_DYLD_BOOL // so that we don't pollute the global namespace
+extern "C" {
+ #include <mach-o/getsect.h>
+ #include <mach-o/dyld.h>
+}
+class AssignAttributeStartEnd {
+ public:
+ AssignAttributeStartEnd(const char* name, char** pstart, char** pend) {
+ // Find out what dynamic library name is defined in
+ for (int i = _dyld_image_count() - 1; i >= 0; --i) {
+ const mach_header* hdr = _dyld_get_image_header(i);
+ uint32_t len;
+ *pstart = getsectdatafromheader(hdr, "__DATA", name, &len);
+ if (*pstart) { // NULL if not defined in this dynamic library
+ *pstart += _dyld_get_image_vmaddr_slide(i); // correct for reloc
+ *pend = *pstart + len;
+ return;
+ }
+ }
+ // If we get here, not defined in a dll at all. See if defined statically.
+ unsigned long len; // don't ask me why this type isn't uint32_t too...
+ *pstart = getsectdata("__DATA", name, &len);
+ *pend = *pstart + len;
+ }
+};
+
+// 1) DEFINE_ATTRIBUTE_SECTION_VARS: must be called once per unique
+// name. You want to make sure this is executed before any
+// DECLARE_ATTRIBUTE_SECTION_VARS; the easiest way is to put them
+// in the same .cc file. Put this call at the global level.
+// 2) INIT_ATTRIBUTE_SECTION_VARS: you can scatter calls to this in
+// multiple places to help ensure execution before any
+// DECLARE_ATTRIBUTE_SECTION_VARS. You must have at least one
+// DEFINE, but you can have many INITs. Put each in its own scope.
+// 3) DECLARE_ATTRIBUTE_SECTION_VARS: must be called before using
+// ATTRIBUTE_SECTION_START or ATTRIBUTE_SECTION_STOP on a name.
+// Put this call at the global level.
+#define DECLARE_ATTRIBUTE_SECTION_VARS(name) \
+ extern char* __start_##name; \
+ extern char* __stop_##name;
+
+#define INIT_ATTRIBUTE_SECTION_VARS(name) \
+ DECLARE_ATTRIBUTE_SECTION_VARS(name); \
+ static const AssignAttributeStartEnd __assign_##name( \
+ #name, &__start_##name, &__stop_##name)
+
+#define DEFINE_ATTRIBUTE_SECTION_VARS(name) \
+ char* __start_##name, *__stop_##name; \
+ INIT_ATTRIBUTE_SECTION_VARS(name)
+
+// Darwin doesn't have strnlen. No comment.
+inline size_t strnlen(const char *s, size_t maxlen) {
+ const char* end = (const char *)memchr(s, '\0', maxlen);
+ if (end)
+ return end - s;
+ return maxlen;
+}
+
+using namespace std; // just like VC++, we need a using here
+
+// Doesn't exist on OSX; used in google.cc for send() to mean "no flags".
+#define MSG_NOSIGNAL 0
+
+// No SIGPWR on MacOSX. SIGINFO seems suitably obscure.
+#undef GOOGLE_OBSCURE_SIGNAL
+#define GOOGLE_OBSCURE_SIGNAL SIGINFO
+
+#elif defined(OS_CYGWIN) // Cygwin-specific behavior.
+
+#if defined(__CYGWIN32__)
+#define __WORDSIZE 32
+#else
+// It's probably possible to support 64-bit, but the #defines will need checked.
+#error "Cygwin is currently only 32-bit."
+#endif
+
+// No signalling on Windows.
+#undef GOOGLE_OBSCURE_SIGNAL
+#define GOOGLE_OBSCURE_SIGNAL 0
+
+struct stack_t {
+ void* ss_sp;
+ int ss_flags;
+ size_t ss_size;
+};
+inline int sigaltstack(stack_t* ss, stack_t* oss) { return 0; }
+
+#define PTHREAD_STACK_MIN 0 // Not provided by cygwin
+
+// Scans memory for a character.
+// memrchr is used in a few places, but it's linux-specific.
+inline void* memrchr(const void* bytes, int find_char, size_t len) {
+ const unsigned char* cursor =
+ reinterpret_cast<const unsigned char*>(bytes) + len - 1;
+ unsigned char actual_char = find_char;
+ for (; cursor >= bytes; --cursor) {
+ if (*cursor == actual_char) {
+ return const_cast<void*>(reinterpret_cast<const void*>(cursor));
+ }
+ }
+ return NULL;
+}
+
+#endif
+
+// Klocwork static analysis tool's C/C++ complier kwcc
+#if defined(__KLOCWORK__)
+#define STATIC_ANALYSIS
+#endif // __KLOCWORK__
+
+// GCC-specific features
+
+#if (defined(COMPILER_GCC3) || defined(COMPILER_ICC) || defined(OS_MACOSX)) && !defined(SWIG)
+
+//
+// Tell the compiler to do printf format string checking if the
+// compiler supports it; see the 'format' attribute in
+// <http://gcc.gnu.org/onlinedocs/gcc-4.3.0/gcc/Function-Attributes.html>.
+//
+// N.B.: As the GCC manual states, "[s]ince non-static C++ methods
+// have an implicit 'this' argument, the arguments of such methods
+// should be counted from two, not one."
+//
+#define PRINTF_ATTRIBUTE(string_index, first_to_check) \
+ __attribute__((__format__ (__printf__, string_index, first_to_check)))
+#define SCANF_ATTRIBUTE(string_index, first_to_check) \
+ __attribute__((__format__ (__scanf__, string_index, first_to_check)))
+
+//
+// Prevent the compiler from padding a structure to natural alignment
+//
+#define PACKED __attribute__ ((packed))
+
+// Cache line alignment
+#if defined(__i386__) || defined(__x86_64__)
+#define CACHELINE_SIZE 64
+#define CACHELINE_ALIGNED __attribute__((aligned(CACHELINE_SIZE)))
+#elif defined(__ARM_ARCH_5T__)
+#define CACHELINE_SIZE 32
+#define CACHELINE_ALIGNED
+#else
+#define CACHELINE_ALIGNED
+#endif
+
+//
+// Prevent the compiler from complaining about or optimizing away variables
+// that appear unused
+// (careful, others e.g. third_party/libxml/xmlversion.h also define this)
+#undef ATTRIBUTE_UNUSED
+#define ATTRIBUTE_UNUSED __attribute__ ((unused))
+
+//
+// For functions we want to force inline or not inline.
+// Introduced in gcc 3.1.
+#define ATTRIBUTE_ALWAYS_INLINE __attribute__ ((always_inline))
+#define HAVE_ATTRIBUTE_ALWAYS_INLINE 1
+#define ATTRIBUTE_NOINLINE __attribute__ ((noinline))
+#define HAVE_ATTRIBUTE_NOINLINE 1
+
+// For weak functions
+#undef ATTRIBUTE_WEAK
+#define ATTRIBUTE_WEAK __attribute__ ((weak))
+#define HAVE_ATTRIBUTE_WEAK 1
+
+// Tell the compiler to use "initial-exec" mode for a thread-local variable.
+// See http://people.redhat.com/drepper/tls.pdf for the gory details.
+#define ATTRIBUTE_INITIAL_EXEC __attribute__ ((tls_model ("initial-exec")))
+
+//
+// Tell the compiler that a given function never returns
+//
+#define ATTRIBUTE_NORETURN __attribute__((noreturn))
+
+// For deprecated functions, variables, and types.
+// gcc 3.1.1 and later provide this attribute.
+// gcc 3.1.1 and later provide -Wdeprecated-declarations, on by default,
+// and then -Werror converts such warning to an error
+// gcc 4.2.1 and later provide -Wno-error=deprecated-declarations,
+// so that use of a deprecated entity is a warning but not an error
+//
+// gcc 4.2.1 and gcc 4.2.2 ignore ATTRIBUTE_DEPRECATED on virtual functions.
+// this is fixed in gcc 4.3.1 (crosstool v12). -- mec, 2008-10-21
+//
+// 2010-05-19(mec): Failed.
+// Too many people started deprecations and then stopped working on them.
+// The deprecation messages just became build noise.
+// The two-part deletion plan:
+// change definition of ATTRIBUTE_DEPRECATED to an empty macro
+// then global change: ATTRIBUTE_DEPRECATED -> /* deprecated */
+// We may introduce a new facility like this in the future,
+// probably with a different name. See message from iant to c-style:
+#define ATTRIBUTE_DEPRECATED
+
+#ifndef HAVE_ATTRIBUTE_SECTION // may have been pre-set to 0, e.g. for Darwin
+#define HAVE_ATTRIBUTE_SECTION 1
+#endif
+
+#if HAVE_ATTRIBUTE_SECTION // define section support for the case of GCC
+
+//
+// Tell the compiler/linker to put a given function into a section and define
+// "__start_ ## name" and "__stop_ ## name" symbols to bracket the section.
+// Sections can not span more than none compilation unit.
+// This functionality is supported by GNU linker.
+// Any function with ATTRIBUTE_SECTION must not be inlined, or it will
+// be placed into whatever section its caller is placed into.
+//
+#ifndef ATTRIBUTE_SECTION
+#define ATTRIBUTE_SECTION(name) \
+ __attribute__ ((section (#name))) __attribute__ ((noinline))
+#endif
+
+//
+// Weak section declaration to be used as a global declaration
+// for ATTRIBUTE_SECTION_START|STOP(name) to compile and link
+// even without functions with ATTRIBUTE_SECTION(name).
+// DEFINE_ATTRIBUTE_SECTION should be in the exactly one file; it's
+// a no-op on ELF but not on Mach-O.
+//
+#ifndef DECLARE_ATTRIBUTE_SECTION_VARS
+#define DECLARE_ATTRIBUTE_SECTION_VARS(name) \
+ extern char __start_##name[] ATTRIBUTE_WEAK; \
+ extern char __stop_##name[] ATTRIBUTE_WEAK
+#endif
+#ifndef DEFINE_ATTRIBUTE_SECTION_VARS
+#define INIT_ATTRIBUTE_SECTION_VARS(name)
+#define DEFINE_ATTRIBUTE_SECTION_VARS(name)
+#endif
+
+//
+// Return void* pointers to start/end of a section of code with
+// functions having ATTRIBUTE_SECTION(name).
+// Returns 0 if no such functions exits.
+// One must DECLARE_ATTRIBUTE_SECTION_VARS(name) for this to compile and link.
+//
+#define ATTRIBUTE_SECTION_START(name) (reinterpret_cast<void*>(__start_##name))
+#define ATTRIBUTE_SECTION_STOP(name) (reinterpret_cast<void*>(__stop_##name))
+
+#endif // HAVE_ATTRIBUTE_SECTION
+
+//
+// The legacy prod71 libc does not provide the stack alignment required for use
+// of SSE intrinsics. In order to properly use the intrinsics you need to use
+// a trampoline function which aligns the stack prior to calling your code,
+// or as of crosstool v10 with gcc 4.2.0 there is an attribute which asks
+// gcc to do this for you.
+//
+// It has also been discovered that crosstool up to and including v10 does not
+// provide proper alignment for pthread_once() functions in x86-64 code either.
+// Unfortunately gcc does not provide force_align_arg_pointer as an option in
+// x86-64 code, so this requires us to always have a trampoline.
+//
+// For an example of using this see util/hash/adler32*
+
+#if defined(__i386__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 2))
+#define ATTRIBUTE_STACK_ALIGN_FOR_OLD_LIBC __attribute__((force_align_arg_pointer))
+#define REQUIRE_STACK_ALIGN_TRAMPOLINE (0)
+#elif defined(__i386__) || defined(__x86_64__)
+#define REQUIRE_STACK_ALIGN_TRAMPOLINE (1)
+#define ATTRIBUTE_STACK_ALIGN_FOR_OLD_LIBC
+#else
+#define REQUIRE_STACK_ALIGN_TRAMPOLINE (0)
+#define ATTRIBUTE_STACK_ALIGN_FOR_OLD_LIBC
+#endif
+
+
+//
+// Tell the compiler to warn about unused return values for functions declared
+// with this macro. The macro should be used on function declarations
+// following the argument list:
+//
+// Sprocket* AllocateSprocket() MUST_USE_RESULT;
+//
+#undef MUST_USE_RESULT
+#if (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) \
+ && !defined(COMPILER_ICC)
+#define MUST_USE_RESULT __attribute__ ((warn_unused_result))
+#else
+#define MUST_USE_RESULT
+#endif
+
+
+#if (defined(COMPILER_ICC) || defined(COMPILER_GCC3) || defined(__llvm__))
+// Defined behavior on some of the uarchs:
+// PREFETCH_HINT_T0:
+// prefetch to all levels of the hierarchy (except on p4: prefetch to L2)
+// PREFETCH_HINT_NTA:
+// p4: fetch to L2, but limit to 1 way (out of the 8 ways)
+// core: skip L2, go directly to L1
+// k8 rev E and later: skip L2, can go to either of the 2-ways in L1
+enum PrefetchHint {
+ PREFETCH_HINT_T0 = 3, // More temporal locality
+ PREFETCH_HINT_T1 = 2,
+ PREFETCH_HINT_T2 = 1, // Less temporal locality
+ PREFETCH_HINT_NTA = 0 // No temporal locality
+};
+#else
+// prefetch is a no-op for this target. Feel free to add more sections above.
+#endif
+
+extern inline void prefetch(const char *x, int hint) {
+#if defined(COMPILER_ICC) || defined(__llvm__)
+ // In the gcc version of prefetch(), hint is only a constant _after_ inlining
+ // (assumed to have been successful). icc views things differently, and
+ // checks constant-ness _before_ inlining. This leads to compilation errors
+ // with the gcc version in icc.
+ //
+ // One way round this is to use a switch statement to explicitly match
+ // prefetch hint enumerations, and invoke __builtin_prefetch for each valid
+ // value. icc's optimization removes the switch and unused case statements
+ // after inlining, so that this boils down in the end to the same as for gcc;
+ // that is, a single inlined prefetchX instruction. Demonstrate by compiling
+ // with icc options -xK -O2 and viewing assembly language output.
+ //
+ // Note that this version of prefetch() cannot verify constant-ness of hint.
+ // If client code calls prefetch() with a variable value for hint, it will
+ // receive the full expansion of the switch below, perhaps also not inlined.
+ // This should however not be a problem in the general case of well behaved
+ // caller code that uses the supplied prefetch hint enumerations.
+ switch (hint) {
+ case PREFETCH_HINT_T0:
+ __builtin_prefetch(x, 0, PREFETCH_HINT_T0);
+ break;
+ case PREFETCH_HINT_T1:
+ __builtin_prefetch(x, 0, PREFETCH_HINT_T1);
+ break;
+ case PREFETCH_HINT_T2:
+ __builtin_prefetch(x, 0, PREFETCH_HINT_T2);
+ break;
+ case PREFETCH_HINT_NTA:
+ __builtin_prefetch(x, 0, PREFETCH_HINT_NTA);
+ break;
+ default:
+ __builtin_prefetch(x);
+ break;
+ }
+#elif defined(COMPILER_GCC3)
+ #if !defined(ARCH_PIII) || defined(__SSE__)
+ if (__builtin_constant_p(hint)) {
+ __builtin_prefetch(x, 0, hint);
+ } else {
+ // Defaults to PREFETCH_HINT_T0
+ __builtin_prefetch(x);
+ }
+#else
+ // We want a __builtin_prefetch, but we build with the default -march=i386
+ // where __builtin_prefetch quietly turns into nothing.
+ // Once we crank up to -march=pentium3 or higher the __SSE__
+ // clause above will kick in with the builtin.
+ // -- mec 2006-06-06
+ if (hint == PREFETCH_HINT_NTA)
+ __asm__ __volatile__("prefetchnta (%0)" : : "r"(x));
+ #endif
+#else
+ // You get no effect. Feel free to add more sections above.
+#endif
+}
+
+#ifdef __cplusplus
+// prefetch intrinsic (bring data to L1 without polluting L2 cache)
+extern inline void prefetch(const char *x) {
+ return prefetch(x, 0);
+}
+#endif // ifdef __cplusplus
+
+//
+// GCC can be told that a certain branch is not likely to be taken (for
+// instance, a CHECK failure), and use that information in static analysis.
+// Giving it this information can help it optimize for the common case in
+// the absence of better information (ie. -fprofile-arcs).
+//
+#if defined(COMPILER_GCC3)
+#define PREDICT_FALSE(x) (__builtin_expect(x, 0))
+#define PREDICT_TRUE(x) (__builtin_expect(!!(x), 1))
+#else
+#define PREDICT_FALSE(x) x
+#define PREDICT_TRUE(x) x
+#endif
+
+#define FTELLO ftello
+#define FSEEKO fseeko
+
+#if !defined(__cplusplus) && !defined(OS_MACOSX) && !defined(OS_CYGWIN)
+// stdlib.h only declares this in C++, not in C, so we declare it here.
+// Also make sure to avoid declaring it on platforms which don't support it.
+extern int posix_memalign(void **memptr, size_t alignment, size_t size);
+#endif
+
+inline void *aligned_malloc(size_t size, int minimum_alignment) {
+#if defined(OS_MACOSX)
+ // mac lacks memalign(), posix_memalign(), however, according to
+ // http://stackoverflow.com/questions/196329/osx-lacks-memalign
+ // mac allocs are already 16-byte aligned.
+ if (minimum_alignment <= 16)
+ return malloc(size);
+ // next, try to return page-aligned memory. perhaps overkill
+ if (minimum_alignment <= getpagesize())
+ return valloc(size);
+ // give up
+ return NULL;
+#elif defined(OS_CYGWIN)
+ return memalign(minimum_alignment, size);
+#else // !OS_MACOSX && !OS_CYGWIN
+ void *ptr = NULL;
+ if (posix_memalign(&ptr, minimum_alignment, size) != 0)
+ return NULL;
+ else
+ return ptr;
+#endif
+}
+
+inline void aligned_free(void *aligned_memory) {
+ free(aligned_memory);
+}
+
+#else // not GCC
+
+#define PRINTF_ATTRIBUTE(string_index, first_to_check)
+#define SCANF_ATTRIBUTE(string_index, first_to_check)
+#define PACKED
+#define CACHELINE_ALIGNED
+#define ATTRIBUTE_UNUSED
+#define ATTRIBUTE_ALWAYS_INLINE
+#define ATTRIBUTE_NOINLINE
+#define ATTRIBUTE_WEAK
+#define HAVE_ATTRIBUTE_WEAK 0
+#define ATTRIBUTE_INITIAL_EXEC
+#define ATTRIBUTE_NORETURN
+#define ATTRIBUTE_DEPRECATED
+#define HAVE_ATTRIBUTE_SECTION 0
+#define ATTRIBUTE_STACK_ALIGN_FOR_OLD_LIBC
+#define REQUIRE_STACK_ALIGN_TRAMPOLINE (0)
+#define MUST_USE_RESULT
+extern inline void prefetch(const char *x) {}
+#define PREDICT_FALSE(x) x
+#define PREDICT_TRUE(x) x
+
+// These should be redefined appropriately if better alternatives to
+// ftell/fseek exist in the compiler
+#define FTELLO ftell
+#define FSEEKO fseek
+
+#endif // GCC
+
+#if !HAVE_ATTRIBUTE_SECTION // provide dummy definitions
+
+#define ATTRIBUTE_SECTION(name)
+#define INIT_ATTRIBUTE_SECTION_VARS(name)
+#define DEFINE_ATTRIBUTE_SECTION_VARS(name)
+#define DECLARE_ATTRIBUTE_SECTION_VARS(name)
+#define ATTRIBUTE_SECTION_START(name) (reinterpret_cast<void*>(0))
+#define ATTRIBUTE_SECTION_STOP(name) (reinterpret_cast<void*>(0))
+
+#endif // !HAVE_ATTRIBUTE_SECTION
+
+// HK's fun windows fixer-upper defines go here! Woo.
+#ifdef _WIN32
+#define strtoll _strtoi64
+#define strtoull _strtoui64
+#define safe_vsnprintf _vsnprintf
+#define snprintf _snprintf
+inline double drem(double x, double y) {
+ int quot = (x / y) + 0.5;
+ return x - ((double)quot) * y;
+}
+
+inline void va_copy(va_list& a, va_list& b) {
+ a = b;
+}
+using namespace std;
+#define isnan _isnan
+#define snprintf _snprintf
+#include "float.h"
+inline double sqrt(int x) { return sqrt((double)x); }
+inline int isinf(double x) {
+ const int float_point_class =_fpclass(x);
+ if (float_point_class == _FPCLASS_PINF) return 1;
+ if (float_point_class == _FPCLASS_NINF) return -1;
+ return 0;
+}
+#endif
+
+#ifdef COMPILER_MSVC /* if Visual C++ */
+
+// This compiler flag can be easily overlooked on MSVC.
+// _CHAR_UNSIGNED gets set with the /J flag.
+#ifndef _CHAR_UNSIGNED
+#error chars must be unsigned! Use the /J flag on the compiler command line.
+#endif
+
+// MSVC is a little hyper-active in it's warnings
+// Signed vs. unsigned comparison is ok.
+#pragma warning(disable : 4018 )
+// We know casting from a long to a char may lose data
+#pragma warning(disable : 4244 )
+// Don't need performance warnings about converting ints to bools
+#pragma warning(disable : 4800 )
+// Integral constant overflow is apparently ok too
+// for example:
+// short k; int n;
+// k = k + n;
+#pragma warning(disable : 4307 )
+// It's ok to use this* in constructor
+// Example:
+// class C {
+// Container cont_;
+// C() : cont_(this) { ...
+#pragma warning(disable : 4355 )
+// Truncating from double to float is ok
+#pragma warning(disable : 4305 )
+
+#include <winsock2.h>
+#include <assert.h>
+#include <windows.h>
+#undef ERROR
+#include "base/stl_decl.h"
+
+#include <float.h> // for nextafter functionality on windows
+#include <math.h> // for HUGE_VAL
+
+#ifndef HUGE_VALF
+#define HUGE_VALF (static_cast<float>(HUGE_VAL))
+#endif
+
+using namespace std;
+
+// VC++ doesn't understand "uint"
+#ifndef HAVE_UINT
+#define HAVE_UINT 1
+typedef unsigned int uint;
+#endif
+
+#define strtoq _strtoi64
+#define strtouq _strtoui64
+#define strtoll _strtoi64
+#define strtoull _strtoui64
+#define atoll _atoi64
+
+
+// VC++ 6 and before ship without an ostream << operator for 64-bit ints
+#if (_MSC_VER <= 1200)
+#include <iosfwd>
+using std::ostream;
+
+inline ostream& operator<< (ostream& os, const unsigned __int64& num ) {
+ // Fake operator; doesn't actually do anything.
+ LOG(FATAL) << "64-bit ostream operator << not supported in VC++ 6";
+ return os;
+}
+#endif
+
+// You say tomato, I say atotom
+#define PATH_MAX MAX_PATH
+
+// You say tomato, I say _tomato
+#define vsnprintf _vsnprintf
+#define snprintf _snprintf
+#define strcasecmp _stricmp
+#define strncasecmp _strnicmp
+
+#define nextafter _nextafter
+
+#define hypot _hypot
+#define hypotf _hypotf
+
+#define strdup _strdup
+#define tempnam _tempnam
+#define chdir _chdir
+#define getcwd _getcwd
+#define putenv _putenv
+
+
+// You say tomato, I say toma
+#define random() rand()
+#define srandom(x) srand(x)
+
+// You say juxtapose, I say transpose
+#define bcopy(s, d, n) memcpy(d, s, n)
+
+inline void *aligned_malloc(size_t size, int minimum_alignment) {
+ return _aligned_malloc(size, minimum_alignment);
+}
+
+inline void aligned_free(void *aligned_memory) {
+ _aligned_free(aligned_memory);
+}
+
+// ----- BEGIN VC++ STUBS & FAKE DEFINITIONS ---------------------------------
+
+// See http://en.wikipedia.org/wiki/IEEE_754 for details of
+// floating point format.
+
+enum {
+ FP_NAN, // is "Not a Number"
+ FP_INFINITE, // is either plus or minus infinity.
+ FP_ZERO,
+ FP_SUBNORMAL, // is too small to be represented in normalized format.
+ FP_NORMAL // if nothing of the above is correct that it must be a
+ // normal floating-point number.
+};
+
+inline int fpclassify_double(double x) {
+ const int float_point_class =_fpclass(x);
+ int c99_class;
+ switch (float_point_class) {
+ case _FPCLASS_SNAN: // Signaling NaN
+ case _FPCLASS_QNAN: // Quiet NaN
+ c99_class = FP_NAN;
+ break;
+ case _FPCLASS_NZ: // Negative zero ( -0)
+ case _FPCLASS_PZ: // Positive 0 (+0)
+ c99_class = FP_ZERO;
+ break;
+ case _FPCLASS_NINF: // Negative infinity ( -INF)
+ case _FPCLASS_PINF: // Positive infinity (+INF)
+ c99_class = FP_INFINITE;
+ break;
+ case _FPCLASS_ND: // Negative denormalized
+ case _FPCLASS_PD: // Positive denormalized
+ c99_class = FP_SUBNORMAL;
+ break;
+ case _FPCLASS_NN: // Negative normalized non-zero
+ case _FPCLASS_PN: // Positive normalized non-zero
+ c99_class = FP_NORMAL;
+ break;
+ default:
+ c99_class = FP_NAN; // Should never happen
+ break;
+ }
+ return c99_class;
+}
+
+// This function handle the special subnormal case for float; it will
+// become a normal number while casting to double.
+// bit_cast is avoided to simplify dependency and to create a code that is
+// easy to deploy in C code
+inline int fpclassify_float(float x) {
+ uint32 bitwise_representation;
+ memcpy(&bitwise_representation, &x, 4);
+ if ((bitwise_representation & 0x7f800000) == 0 &&
+ (bitwise_representation & 0x007fffff) != 0)
+ return FP_SUBNORMAL;
+ return fpclassify_double(x);
+}
+//
+// This define takes care of the denormalized float; the casting to
+// double make it a normal number
+#define fpclassify(x) ((sizeof(x) == sizeof(float)) ? fpclassify_float(x) : fpclassify_double(x))
+
+#define isnan _isnan
+
+inline int isinf(double x) {
+ const int float_point_class =_fpclass(x);
+ if (float_point_class == _FPCLASS_PINF) return 1;
+ if (float_point_class == _FPCLASS_NINF) return -1;
+ return 0;
+}
+
+// #include "conflict-signal.h"
+typedef void (*sig_t)(int);
+
+// These actually belong in errno.h but there's a name confilict in errno
+// on WinNT. They (and a ton more) are also found in Winsock2.h, but
+// if'd out under NT. We need this subset at minimum.
+#define EXFULL ENOMEM // not really that great a translation...
+//#define EWOULDBLOCK WSAEWOULDBLOCK
+//#ifndef PTHREADS_REDHAT_WIN32
+//#define ETIMEDOUT WSAETIMEDOUT
+//#endif
+//#define ENOTSOCK WSAENOTSOCK
+//#define EINPROGRESS WSAEINPROGRESS
+//#define ECONNRESET WSAECONNRESET
+
+
+#include <utility>
+using std::pair;
+using std::make_pair;
+
+#include <vector>
+using std::vector;
+
+
+typedef vector<pair<const char*, const char*> > KeyValVec;
+
+//
+// Really from <string.h>
+//
+
+inline void bzero(void *s, int n) {
+ memset(s, 0, n);
+}
+
+// From glob.h
+#define __ptr_t void *
+
+// Defined all over the place.
+typedef int pid_t;
+
+// From stat.h
+typedef unsigned int mode_t;
+
+// u_int16_t, int16_t don't exist in MSVC
+typedef unsigned short u_int16_t;
+typedef short int16_t;
+
+// ----- END VC++ STUBS & FAKE DEFINITIONS ----------------------------------
+
+#endif // COMPILER_MSVC
+
+#ifdef STL_MSVC // not always the same as COMPILER_MSVC
+#include "base/port_hash.h"
+#else
+struct PortableHashBase { };
+#endif
+
+// The SWIGged version of an abstract class must be concrete if any methods
+// return objects of the abstract type.
+//
+// This location is deprecated, the new preferred location is in base/macros.h.
+#ifndef SWIG
+#define ABSTRACT = 0
+#endif
+
+
+#if defined(OS_WINDOWS) || defined(OS_MACOSX)
+// gethostbyname() *is* thread-safe for Windows native threads. It is also
+// safe on Mac OS X, where it uses thread-local storage, even though the
+// manpages claim otherwise. For details, see
+// http://lists.apple.com/archives/Darwin-dev/2006/May/msg00008.html
+#else
+// gethostbyname() is not thread-safe. So disallow its use. People
+// should either use the HostLookup::Lookup*() methods, or gethostbyname_r()
+#define gethostbyname gethostbyname_is_not_thread_safe_DO_NOT_USE
+#endif
+
+// create macros in which the programmer should enclose all specializations
+// for hash_maps and hash_sets. This is necessary since these classes are not
+// STL standardized. Depending on the STL implementation they are in different
+// namespaces. Right now the right namespace is passed by the Makefile
+// Examples: gcc3: -DHASH_NAMESPACE=__gnu_cxx
+// icc: -DHASH_NAMESPACE=std
+// gcc2: empty
+
+#ifndef HASH_NAMESPACE
+# define HASH_NAMESPACE_DECLARATION_START
+# define HASH_NAMESPACE_DECLARATION_END
+#else
+# define HASH_NAMESPACE_DECLARATION_START namespace HASH_NAMESPACE {
+# define HASH_NAMESPACE_DECLARATION_END }
+#endif
+
+// Our STL-like classes use __STD.
+#if defined(COMPILER_GCC3) || defined(COMPILER_ICC) || defined(OS_MACOSX) || defined(COMPILER_MSVC)
+#define __STD std
+#endif
+
+#if defined COMPILER_GCC3 || defined COMPILER_ICC
+#define STREAM_SET(s, bit) (s).setstate(ios_base::bit)
+#define STREAM_SETF(s, flag) (s).setf(ios_base::flag)
+#else
+#define STREAM_SET(s, bit) (s).set(ios::bit)
+#define STREAM_SETF(s, flag) (s).setf(ios::flag)
+#endif
+
+// Portable handling of unaligned loads and stores
+
+#if defined(ARCH_PIII) || defined(ARCH_ATHLON) || defined(ARCH_K8) || defined(_ARCH_PPC)
+
+// x86 and x86-64 can perform unaligned loads/stores directly;
+// modern PowerPC hardware can also do unaligned integer loads and stores;
+// but note: the FPU still sends unaligned loads and stores to a trap handler!
+
+#define UNALIGNED_LOAD16(_p) (*reinterpret_cast<const uint16 *>(_p))
+#define UNALIGNED_LOAD32(_p) (*reinterpret_cast<const uint32 *>(_p))
+#define UNALIGNED_LOAD64(_p) (*reinterpret_cast<const uint64 *>(_p))
+
+#define UNALIGNED_STORE16(_p, _val) (*reinterpret_cast<uint16 *>(_p) = (_val))
+#define UNALIGNED_STORE32(_p, _val) (*reinterpret_cast<uint32 *>(_p) = (_val))
+#define UNALIGNED_STORE64(_p, _val) (*reinterpret_cast<uint64 *>(_p) = (_val))
+
+#else
+
+#define NEED_ALIGNED_LOADS
+
+// These functions are provided for architectures that don't support
+// unaligned loads and stores.
+
+inline uint16 UNALIGNED_LOAD16(const void *p) {
+ uint16 t;
+ memcpy(&t, p, sizeof t);
+ return t;
+}
+
+inline uint32 UNALIGNED_LOAD32(const void *p) {
+ uint32 t;
+ memcpy(&t, p, sizeof t);
+ return t;
+}
+
+inline uint64 UNALIGNED_LOAD64(const void *p) {
+ uint64 t;
+ memcpy(&t, p, sizeof t);
+ return t;
+}
+
+inline void UNALIGNED_STORE16(void *p, uint16 v) {
+ memcpy(p, &v, sizeof v);
+}
+
+inline void UNALIGNED_STORE32(void *p, uint32 v) {
+ memcpy(p, &v, sizeof v);
+}
+
+inline void UNALIGNED_STORE64(void *p, uint64 v) {
+ memcpy(p, &v, sizeof v);
+}
+
+#endif
+
+#ifdef _LP64
+#define UNALIGNED_LOADW(_p) UNALIGNED_LOAD64(_p)
+#define UNALIGNED_STOREW(_p, _val) UNALIGNED_STORE64(_p, _val)
+#else
+#define UNALIGNED_LOADW(_p) UNALIGNED_LOAD32(_p)
+#define UNALIGNED_STOREW(_p, _val) UNALIGNED_STORE32(_p, _val)
+#endif
+
+// printf macros for size_t, in the style of inttypes.h
+#ifdef _LP64
+#define __PRIS_PREFIX "z"
+#else
+#define __PRIS_PREFIX
+#endif
+
+// Use these macros after a % in a printf format string
+// to get correct 32/64 bit behavior, like this:
+// size_t size = records.size();
+// printf("%"PRIuS"\n", size);
+
+#define PRIdS __PRIS_PREFIX "d"
+#define PRIxS __PRIS_PREFIX "x"
+#define PRIuS __PRIS_PREFIX "u"
+#define PRIXS __PRIS_PREFIX "X"
+#define PRIoS __PRIS_PREFIX "o"
+
+#define GPRIuPTHREAD "lu"
+#define GPRIxPTHREAD "lx"
+#ifdef OS_CYGWIN
+#define PRINTABLE_PTHREAD(pthreadt) reinterpret_cast<uintptr_t>(pthreadt)
+#else
+#define PRINTABLE_PTHREAD(pthreadt) pthreadt
+#endif
+
+#define SIZEOF_MEMBER(t, f) sizeof(((t*) 4096)->f)
+
+#define OFFSETOF_MEMBER(t, f) \
+ (reinterpret_cast<char*>( \
+ &reinterpret_cast<t*>(16)->f) - \
+ reinterpret_cast<char*>(16))
+
+#ifdef PTHREADS_REDHAT_WIN32
+#include <iosfwd>
+using std::ostream;
+
+#include <pthread.h>
+// pthread_t is not a simple integer or pointer on Win32
+std::ostream& operator << (std::ostream& out, const pthread_t& thread_id);
+#endif
+
+#endif // BASE_PORT_H_
diff --git a/src/third_party/s2/base/scoped_ptr.h b/src/third_party/s2/base/scoped_ptr.h
new file mode 100755
index 00000000000..a6baf407661
--- /dev/null
+++ b/src/third_party/s2/base/scoped_ptr.h
@@ -0,0 +1,427 @@
+// Copyright 2007 Google Inc.
+// All Rights Reserved.
+//
+//
+#ifndef BASE_SCOPED_PTR_H__
+#define BASE_SCOPED_PTR_H__
+
+// This is an implementation designed to match the anticipated future TR2
+// implementation of the scoped_ptr class, and its closely-related brethren,
+// scoped_array, scoped_ptr_malloc, and make_scoped_ptr.
+//
+// file.
+
+#include <assert.h>
+#include <stdlib.h>
+#include <cstddef>
+
+#ifdef OS_EMBEDDED_QNX
+// NOTE(user):
+// The C++ standard says that <stdlib.h> declares both ::foo and std::foo
+// But this isn't done in QNX version 6.3.2 200709062316.
+using std::free;
+using std::malloc;
+using std::realloc;
+#endif
+
+template <class C> class scoped_ptr;
+template <class C, class Free> class scoped_ptr_malloc;
+template <class C> class scoped_array;
+
+template <class C>
+scoped_ptr<C> make_scoped_ptr(C *);
+
+// A scoped_ptr<T> is like a T*, except that the destructor of scoped_ptr<T>
+// automatically deletes the pointer it holds (if any).
+// That is, scoped_ptr<T> owns the T object that it points to.
+// Like a T*, a scoped_ptr<T> may hold either NULL or a pointer to a T object.
+// Also like T*, scoped_ptr<T> is thread-compatible, and once you
+// dereference it, you get the threadsafety guarantees of T.
+//
+// The size of a scoped_ptr is small:
+// sizeof(scoped_ptr<C>) == sizeof(C*)
+template <class C>
+class scoped_ptr {
+ public:
+
+ // The element type
+ typedef C element_type;
+
+ // Constructor. Defaults to intializing with NULL.
+ // There is no way to create an uninitialized scoped_ptr.
+ // The input parameter must be allocated with new.
+ explicit scoped_ptr(C* p = NULL) : ptr_(p) { }
+
+ // Destructor. If there is a C object, delete it.
+ // We don't need to test ptr_ == NULL because C++ does that for us.
+ ~scoped_ptr() {
+ enum { type_must_be_complete = sizeof(C) };
+ delete ptr_;
+ }
+
+ // Reset. Deletes the current owned object, if any.
+ // Then takes ownership of a new object, if given.
+ // this->reset(this->get()) works.
+ void reset(C* p = NULL) {
+ if (p != ptr_) {
+ enum { type_must_be_complete = sizeof(C) };
+ delete ptr_;
+ ptr_ = p;
+ }
+ }
+
+ // Accessors to get the owned object.
+ // operator* and operator-> will assert() if there is no current object.
+ C& operator*() const {
+ assert(ptr_ != NULL);
+ return *ptr_;
+ }
+ C* operator->() const {
+ assert(ptr_ != NULL);
+ return ptr_;
+ }
+ C* get() const { return ptr_; }
+
+ // Comparison operators.
+ // These return whether a scoped_ptr and a raw pointer refer to
+ // the same object, not just to two different but equal objects.
+ bool operator==(const C* p) const { return ptr_ == p; }
+ bool operator!=(const C* p) const { return ptr_ != p; }
+
+ // Swap two scoped pointers.
+ void swap(scoped_ptr& p2) {
+ C* tmp = ptr_;
+ ptr_ = p2.ptr_;
+ p2.ptr_ = tmp;
+ }
+
+ // Release a pointer.
+ // The return value is the current pointer held by this object.
+ // If this object holds a NULL pointer, the return value is NULL.
+ // After this operation, this object will hold a NULL pointer,
+ // and will not own the object any more.
+ C* release() {
+ C* retVal = ptr_;
+ ptr_ = NULL;
+ return retVal;
+ }
+
+ private:
+ C* ptr_;
+
+ // google3 friend class that can access copy ctor (although if it actually
+ // calls a copy ctor, there will be a problem) see below
+ friend scoped_ptr<C> make_scoped_ptr<C>(C *p);
+
+ // Forbid comparison of scoped_ptr types. If C2 != C, it totally doesn't
+ // make sense, and if C2 == C, it still doesn't make sense because you should
+ // never have the same object owned by two different scoped_ptrs.
+ template <class C2> bool operator==(scoped_ptr<C2> const& p2) const;
+ template <class C2> bool operator!=(scoped_ptr<C2> const& p2) const;
+
+ // Disallow evil constructors
+ scoped_ptr(const scoped_ptr&);
+ void operator=(const scoped_ptr&);
+};
+
+// Free functions
+template <class C>
+inline void swap(scoped_ptr<C>& p1, scoped_ptr<C>& p2) {
+ p1.swap(p2);
+}
+
+template <class C>
+inline bool operator==(const C* p1, const scoped_ptr<C>& p2) {
+ return p1 == p2.get();
+}
+
+template <class C>
+inline bool operator==(const C* p1, const scoped_ptr<const C>& p2) {
+ return p1 == p2.get();
+}
+
+template <class C>
+inline bool operator!=(const C* p1, const scoped_ptr<C>& p2) {
+ return p1 != p2.get();
+}
+
+template <class C>
+inline bool operator!=(const C* p1, const scoped_ptr<const C>& p2) {
+ return p1 != p2.get();
+}
+
+template <class C>
+scoped_ptr<C> make_scoped_ptr(C *p) {
+ // This does nothing but to return a scoped_ptr of the type that the passed
+ // pointer is of. (This eliminates the need to specify the name of T when
+ // making a scoped_ptr that is used anonymously/temporarily.) From an
+ // access control point of view, we construct an unnamed scoped_ptr here
+ // which we return and thus copy-construct. Hence, we need to have access
+ // to scoped_ptr::scoped_ptr(scoped_ptr const &). However, it is guaranteed
+ // that we never actually call the copy constructor, which is a good thing
+ // as we would call the temporary's object destructor (and thus delete p)
+ // if we actually did copy some object, here.
+ return scoped_ptr<C>(p);
+}
+
+// scoped_array<C> is like scoped_ptr<C>, except that the caller must allocate
+// with new [] and the destructor deletes objects with delete [].
+//
+// As with scoped_ptr<C>, a scoped_array<C> either points to an object
+// or is NULL. A scoped_array<C> owns the object that it points to.
+// scoped_array<T> is thread-compatible, and once you index into it,
+// the returned objects have only the threadsafety guarantees of T.
+//
+// Size: sizeof(scoped_array<C>) == sizeof(C*)
+template <class C>
+class scoped_array {
+ public:
+
+ // The element type
+ typedef C element_type;
+
+ // Constructor. Defaults to intializing with NULL.
+ // There is no way to create an uninitialized scoped_array.
+ // The input parameter must be allocated with new [].
+ explicit scoped_array(C* p = NULL) : array_(p) { }
+
+ // Destructor. If there is a C object, delete it.
+ // We don't need to test ptr_ == NULL because C++ does that for us.
+ ~scoped_array() {
+ enum { type_must_be_complete = sizeof(C) };
+ delete[] array_;
+ }
+
+ // Reset. Deletes the current owned object, if any.
+ // Then takes ownership of a new object, if given.
+ // this->reset(this->get()) works.
+ void reset(C* p = NULL) {
+ if (p != array_) {
+ enum { type_must_be_complete = sizeof(C) };
+ delete[] array_;
+ array_ = p;
+ }
+ }
+
+ // Get one element of the current object.
+ // Will assert() if there is no current object, or index i is negative.
+ C& operator[](std::ptrdiff_t i) const {
+ assert(i >= 0);
+ assert(array_ != NULL);
+ return array_[i];
+ }
+
+ // Get a pointer to the zeroth element of the current object.
+ // If there is no current object, return NULL.
+ C* get() const {
+ return array_;
+ }
+
+ // Comparison operators.
+ // These return whether a scoped_array and a raw pointer refer to
+ // the same array, not just to two different but equal arrays.
+ bool operator==(const C* p) const { return array_ == p; }
+ bool operator!=(const C* p) const { return array_ != p; }
+
+ // Swap two scoped arrays.
+ void swap(scoped_array& p2) {
+ C* tmp = array_;
+ array_ = p2.array_;
+ p2.array_ = tmp;
+ }
+
+ // Release an array.
+ // The return value is the current pointer held by this object.
+ // If this object holds a NULL pointer, the return value is NULL.
+ // After this operation, this object will hold a NULL pointer,
+ // and will not own the object any more.
+ C* release() {
+ C* retVal = array_;
+ array_ = NULL;
+ return retVal;
+ }
+
+ private:
+ C* array_;
+
+ // Forbid comparison of different scoped_array types.
+ template <class C2> bool operator==(scoped_array<C2> const& p2) const;
+ template <class C2> bool operator!=(scoped_array<C2> const& p2) const;
+
+ // Disallow evil constructors
+ scoped_array(const scoped_array&);
+ void operator=(const scoped_array&);
+};
+
+// Free functions
+template <class C>
+inline void swap(scoped_array<C>& p1, scoped_array<C>& p2) {
+ p1.swap(p2);
+}
+
+template <class C>
+inline bool operator==(const C* p1, const scoped_array<C>& p2) {
+ return p1 == p2.get();
+}
+
+template <class C>
+inline bool operator==(const C* p1, const scoped_array<const C>& p2) {
+ return p1 == p2.get();
+}
+
+template <class C>
+inline bool operator!=(const C* p1, const scoped_array<C>& p2) {
+ return p1 != p2.get();
+}
+
+template <class C>
+inline bool operator!=(const C* p1, const scoped_array<const C>& p2) {
+ return p1 != p2.get();
+}
+
+// This class wraps the c library function free() in a class that can be
+// passed as a template argument to scoped_ptr_malloc below.
+class ScopedPtrMallocFree {
+ public:
+ inline void operator()(void* x) const {
+ free(x);
+ }
+};
+
+// scoped_ptr_malloc<> is similar to scoped_ptr<>, but it accepts a
+// second template argument, the functor used to free the object.
+
+template<class C, class FreeProc = ScopedPtrMallocFree>
+class scoped_ptr_malloc {
+ public:
+
+ // The element type
+ typedef C element_type;
+
+ // Construction with no arguments sets ptr_ to NULL.
+ // There is no way to create an uninitialized scoped_ptr.
+ // The input parameter must be allocated with an allocator that matches the
+ // Free functor. For the default Free functor, this is malloc, calloc, or
+ // realloc.
+ explicit scoped_ptr_malloc(): ptr_(NULL) { }
+
+ // Construct with a C*, and provides an error with a D*.
+ template<class must_be_C>
+ explicit scoped_ptr_malloc(must_be_C* p): ptr_(p) { }
+
+ // Construct with a void*, such as you get from malloc.
+ explicit scoped_ptr_malloc(void *p): ptr_(static_cast<C*>(p)) { }
+
+ // Destructor. If there is a C object, call the Free functor.
+ ~scoped_ptr_malloc() {
+ free_(ptr_);
+ }
+
+ // Reset. Calls the Free functor on the current owned object, if any.
+ // Then takes ownership of a new object, if given.
+ // this->reset(this->get()) works.
+ void reset(C* p = NULL) {
+ if (ptr_ != p) {
+ free_(ptr_);
+ ptr_ = p;
+ }
+ }
+
+ // Reallocates the existing pointer, and returns 'true' if
+ // the reallcation is succesfull. If the reallocation failed, then
+ // the pointer remains in its previous state.
+ //
+ // Note: this calls realloc() directly, even if an alternate 'free'
+ // functor is provided in the template instantiation.
+ bool try_realloc(size_t new_size) {
+ C* new_ptr = static_cast<C*>(realloc(ptr_, new_size));
+ if (new_ptr == NULL) {
+ return false;
+ }
+ ptr_ = new_ptr;
+ return true;
+ }
+
+ // Get the current object.
+ // operator* and operator-> will cause an assert() failure if there is
+ // no current object.
+ C& operator*() const {
+ assert(ptr_ != NULL);
+ return *ptr_;
+ }
+
+ C* operator->() const {
+ assert(ptr_ != NULL);
+ return ptr_;
+ }
+
+ C* get() const {
+ return ptr_;
+ }
+
+ // Comparison operators.
+ // These return whether a scoped_ptr_malloc and a plain pointer refer
+ // to the same object, not just to two different but equal objects.
+ // For compatibility with the boost-derived implementation, these
+ // take non-const arguments.
+ bool operator==(C* p) const {
+ return ptr_ == p;
+ }
+
+ bool operator!=(C* p) const {
+ return ptr_ != p;
+ }
+
+ // Swap two scoped pointers.
+ void swap(scoped_ptr_malloc & b) {
+ C* tmp = b.ptr_;
+ b.ptr_ = ptr_;
+ ptr_ = tmp;
+ }
+
+ // Release a pointer.
+ // The return value is the current pointer held by this object.
+ // If this object holds a NULL pointer, the return value is NULL.
+ // After this operation, this object will hold a NULL pointer,
+ // and will not own the object any more.
+ C* release() {
+ C* tmp = ptr_;
+ ptr_ = NULL;
+ return tmp;
+ }
+
+ private:
+ C* ptr_;
+
+ // no reason to use these: each scoped_ptr_malloc should have its own object
+ template <class C2, class GP>
+ bool operator==(scoped_ptr_malloc<C2, GP> const& p) const;
+ template <class C2, class GP>
+ bool operator!=(scoped_ptr_malloc<C2, GP> const& p) const;
+
+ static FreeProc const free_;
+
+ // Disallow evil constructors
+ scoped_ptr_malloc(const scoped_ptr_malloc&);
+ void operator=(const scoped_ptr_malloc&);
+};
+
+template<class C, class FP>
+FP const scoped_ptr_malloc<C, FP>::free_ = FP();
+
+template<class C, class FP> inline
+void swap(scoped_ptr_malloc<C, FP>& a, scoped_ptr_malloc<C, FP>& b) {
+ a.swap(b);
+}
+
+template<class C, class FP> inline
+bool operator==(C* p, const scoped_ptr_malloc<C, FP>& b) {
+ return p == b.get();
+}
+
+template<class C, class FP> inline
+bool operator!=(C* p, const scoped_ptr_malloc<C, FP>& b) {
+ return p != b.get();
+}
+
+#endif // BASE_SCOPED_PTR_H__
diff --git a/src/third_party/s2/base/stl_decl.h b/src/third_party/s2/base/stl_decl.h
new file mode 100755
index 00000000000..bef39e02395
--- /dev/null
+++ b/src/third_party/s2/base/stl_decl.h
@@ -0,0 +1,34 @@
+// Copyright (C) 1999 and onwards Google, Inc.
+//
+// DEPRECATED: This file is deprecated. Do not use in new code.
+// Be careful about removing from old code, though, because your
+// header file might be included by higher-level code that is
+// accidentally depending on this. This file has no impact in linux
+// compilations; you can safely remove dependencies from linux code.
+//
+// Original file level comment:
+// In most .h files, we would rather include a declaration of an stl
+// rather than including the appropriate stl h file (which brings in
+// lots of crap). For many STL classes this is ok (eg pair), but for
+// some it's really annoying. We define those here, so you can
+// just include this file instead of having to deal with the annoyance.
+//
+// Most of the annoyance, btw, has to do with the default allocator.
+//
+
+#ifndef BASE_STL_DECL_H_
+#define BASE_STL_DECL_H_
+
+#include "base/definer.h"
+
+#if defined(OS_WINDOWS) /* If VC++'s STL */
+#include "base/stl_decl_msvc.h"
+
+#elif defined(__APPLE__) && defined(OS_MACOSX) /* gcc with a twist */
+#include "base/stl_decl_osx.h"
+
+#elif !defined(__GNUC__)
+#error "Unknown C++ compiler"
+#endif
+
+#endif // BASE_STL_DECL_H_
diff --git a/src/third_party/s2/base/stl_decl_msvc.h b/src/third_party/s2/base/stl_decl_msvc.h
new file mode 100755
index 00000000000..a183b5a7f10
--- /dev/null
+++ b/src/third_party/s2/base/stl_decl_msvc.h
@@ -0,0 +1,134 @@
+//
+// Copyright (C) 1999 and onwards Google, Inc.
+//
+//
+// In most .h files, we would rather include a declaration of an stl
+// rather than including the appropriate stl h file (which brings in
+// lots of crap). For many STL classes this is ok (eg pair), but for
+// some it's really annoying. We define those here, so you can
+// just include this file instead of having to deal with the annoyance.
+//
+// Most of the annoyance, btw, has to do with the default allocator.
+
+#ifndef _STL_DECL_MSVC_H
+#define _STL_DECL_MSVC_H
+
+// VC++ namespace / STL issues; make them explicit
+#include <wchar.h>
+#include <string>
+using std::string;
+
+#include <vector>
+using std::vector;
+
+#include <functional>
+using std::less;
+
+#include <utility>
+using std::pair;
+using std::make_pair;
+
+#include <set>
+using std::set;
+using std::multiset;
+
+#include <list>
+#define slist list
+#include <algorithm>
+using std::min;
+using std::max;
+using std::swap;
+using std::reverse;
+
+#include <deque>
+#include <iostream>
+using std::ostream;
+using std::cout;
+using std::endl;
+
+#include <map>
+using std::map;
+using std::multimap;
+
+#include <queue>
+using std::priority_queue;
+
+#include <stack>
+
+// copy_n isn't to be found anywhere in MSVC's STL
+template <typename InputIterator, typename Size, typename OutputIterator>
+std::pair<InputIterator, OutputIterator>
+copy_n(InputIterator in, Size count, OutputIterator out) {
+ for ( ; count > 0; --count) {
+ *out = *in;
+ ++out;
+ ++in;
+ }
+ return std::make_pair(in, out);
+}
+
+// Nor are the following selectors
+template <typename T>
+struct identity {
+ inline const T& operator()(const T& t) const { return t; }
+};
+
+// Copied from STLport
+template <class _Pair>
+struct select1st : public std::unary_function<_Pair, typename _Pair::first_type> {
+ const typename _Pair::first_type& operator()(const _Pair& __x) const {
+ return __x.first;
+ }
+};
+
+template <class _Pair>
+struct select2nd : public std::unary_function<_Pair, typename _Pair::second_type>
+{
+ const typename _Pair::second_type& operator()(const _Pair& __x) const {
+ return __x.second;
+ }
+};
+
+
+//#if _MSC_VER >= 1300
+#if 0 //_MSC_VER >= 1300
+
+// If you compile on Windows and get a compile-time error because
+// some google3 code specifies a 3rd or 4th parameter to one of
+// these template classes, then you have to put in some #ifdefs
+// and use the NATIVE_HASH_NAMESPACE::hash_(set|map) implementation.
+namespace msvchash {
+ template <typename Key>
+ struct hash;
+
+ template <class Key,
+ class HashFcn = hash<Key> >
+ class hash_set;
+
+ template <class Key, class Val,
+ class HashFcn = hash<Key> >
+ class hash_map;
+
+ template <class Key,
+ class HashFcn = hash<Key> >
+ class hash_multiset;
+
+ template <class Key, class Val,
+ class HashFcn = hash<Key> >
+ class hash_multimap;
+} // end namespace msvchash
+
+using msvchash::hash_set;
+using msvchash::hash_map;
+using msvchash::hash;
+using msvchash::hash_multimap;
+using msvchash::hash_multiset;
+
+#else
+#define hash_map map
+#define hash_set set
+#endif
+
+using namespace std;
+
+#endif /* #ifdef _STL_DECL_MSVC_H */
diff --git a/src/third_party/s2/base/stl_decl_osx.h b/src/third_party/s2/base/stl_decl_osx.h
new file mode 100755
index 00000000000..92a57333fa6
--- /dev/null
+++ b/src/third_party/s2/base/stl_decl_osx.h
@@ -0,0 +1,88 @@
+//
+// Copyright (C) 2007 and onwards Google, Inc.
+//
+//
+// MacOSX-specific STL help, mirroring examples in stl_decl_msvc.h et
+// al. Although this convention is apparently deprecated (see mec's
+// comments in stl_decl_msvc.h), it is the consistent way of getting
+// google3 happy on OSX.
+//
+// Don't include this directly.
+
+#ifndef _STL_DECL_OSX_H
+#define _STL_DECL_OSX_H
+
+#if !defined(__APPLE__) || !defined(OS_MACOSX)
+#error "This file is only for MacOSX."
+#endif
+
+#include <cstddef>
+#include <algorithm>
+using std::min;
+using std::max;
+using std::swap;
+using std::reverse;
+
+#include <string>
+using std::string;
+
+#include <vector>
+using std::vector;
+
+#include <functional>
+using std::less;
+
+#include <utility>
+using std::pair;
+using std::make_pair;
+
+#include <set>
+using std::set;
+using std::multiset;
+
+#include <list>
+#include <deque>
+#include <iostream>
+using std::ostream;
+using std::cout;
+using std::endl;
+
+#include <map>
+using std::map;
+using std::multimap;
+
+#include <queue>
+using std::priority_queue;
+
+#include <stack>
+#include <bits/stl_tempbuf.h>
+#include <ext/functional>
+#include <ext/hash_fun.h>
+#include <ext/hashtable.h>
+#include <ios>
+#include <string>
+using std::string;
+
+#include <ext/hash_set>
+#include <ext/hash_map>
+
+using namespace std;
+using __gnu_cxx::hash;
+using __gnu_cxx::hash_set;
+using __gnu_cxx::hash_map;
+using __gnu_cxx::select1st;
+
+/* On Linux (and gdrive on OSX), this comes from places like
+ google3/third_party/stl/gcc3/new. On OSX using "builtin"
+ stl headers, however, it does not get defined. */
+#ifndef __STL_USE_STD_ALLOCATORS
+#define __STL_USE_STD_ALLOCATORS 1
+#endif
+
+
+#ifndef HASH_NAMESPACE
+/* We can't define it here; it's too late. */
+#error "HASH_NAMESPACE needs to be defined in the Makefile".
+#endif
+
+#endif /* _STL_DECL_OSX_H */
diff --git a/src/third_party/s2/base/stringprintf.cc b/src/third_party/s2/base/stringprintf.cc
new file mode 100755
index 00000000000..96ba2dd024d
--- /dev/null
+++ b/src/third_party/s2/base/stringprintf.cc
@@ -0,0 +1,79 @@
+// Copyright 2002 and onwards Google Inc.
+
+#include <stdarg.h> // For va_list and related operations
+#include <stdio.h> // MSVC requires this for _vsnprintf
+#include <vector>
+using std::vector;
+
+#include "stringprintf.h"
+#include "logging.h"
+
+void StringAppendV(string* dst, const char* format, va_list ap) {
+ // First try with a small fixed size buffer
+ char space[1024];
+
+ // It's possible for methods that use a va_list to invalidate
+ // the data in it upon use. The fix is to make a copy
+ // of the structure before using it and use that copy instead.
+ va_list backup_ap;
+ va_copy(backup_ap, ap);
+ int result = vsnprintf(space, sizeof(space), format, backup_ap);
+ va_end(backup_ap);
+
+ if ((result >= 0) && ((size_t)result < sizeof(space))) {
+ // It fit
+ dst->append(space, result);
+ return;
+ }
+
+ // Repeatedly increase buffer size until it fits
+ size_t length = sizeof(space);
+ while (true) {
+ if (result < 0) {
+ // Older behavior: just try doubling the buffer size
+ length *= 2;
+ } else {
+ // We need exactly "result+1" characters
+ length = result+1;
+ }
+ char* buf = new char[length];
+
+ // Restore the va_list before we use it again
+ va_copy(backup_ap, ap);
+ result = vsnprintf(buf, length, format, backup_ap);
+ va_end(backup_ap);
+
+ if ((result >= 0) && ((size_t)result < length)) {
+ // It fit
+ dst->append(buf, result);
+ delete[] buf;
+ return;
+ }
+ delete[] buf;
+ }
+}
+
+string StringPrintf(const char* format, ...) {
+ va_list ap;
+ va_start(ap, format);
+ string result;
+ StringAppendV(&result, format, ap);
+ va_end(ap);
+ return result;
+}
+
+const string& SStringPrintf(string* dst, const char* format, ...) {
+ va_list ap;
+ va_start(ap, format);
+ dst->clear();
+ StringAppendV(dst, format, ap);
+ va_end(ap);
+ return *dst;
+}
+
+void StringAppendF(string* dst, const char* format, ...) {
+ va_list ap;
+ va_start(ap, format);
+ StringAppendV(dst, format, ap);
+ va_end(ap);
+}
diff --git a/src/third_party/s2/base/stringprintf.h b/src/third_party/s2/base/stringprintf.h
new file mode 100755
index 00000000000..2f69f9287eb
--- /dev/null
+++ b/src/third_party/s2/base/stringprintf.h
@@ -0,0 +1,42 @@
+// Copyright 2002 and onwards Google Inc.
+//
+// Printf variants that place their output in a C++ string.
+//
+// Usage:
+// string result = StringPrintf("%d %s\n", 10, "hello");
+// SStringPrintf(&result, "%d %s\n", 10, "hello");
+// StringAppendF(&result, "%d %s\n", 20, "there");
+
+#ifndef _BASE_STRINGPRINTF_H
+#define _BASE_STRINGPRINTF_H
+
+#include <stdarg.h>
+#include <string>
+using std::string;
+
+#include <vector>
+using std::vector;
+
+#include "stl_decl.h"
+#include "port.h"
+
+// Return a C++ string
+extern string StringPrintf(const char* format, ...)
+ // Tell the compiler to do printf format string checking.
+ PRINTF_ATTRIBUTE(1,2);
+
+// Store result into a supplied string and return it
+extern const string& SStringPrintf(string* dst, const char* format, ...)
+ // Tell the compiler to do printf format string checking.
+ PRINTF_ATTRIBUTE(2,3);
+
+// Append result to a supplied string
+extern void StringAppendF(string* dst, const char* format, ...)
+ // Tell the compiler to do printf format string checking.
+ PRINTF_ATTRIBUTE(2,3);
+
+// Lower-level routine that takes a va_list and appends to a specified
+// string. All other routines are just convenience wrappers around it.
+extern void StringAppendV(string* dst, const char* format, va_list ap);
+
+#endif /* _BASE_STRINGPRINTF_H */
diff --git a/src/third_party/s2/base/strtoint.cc b/src/third_party/s2/base/strtoint.cc
new file mode 100755
index 00000000000..a1381183be7
--- /dev/null
+++ b/src/third_party/s2/base/strtoint.cc
@@ -0,0 +1,48 @@
+// Copyright 2008 Google Inc. All Rights Reserved.
+//
+// Architecture-neutral plug compatible replacements for strtol() friends.
+// See strtoint.h for details on how to use this component.
+//
+
+#include <errno.h>
+#include "base/port.h"
+#include "base/basictypes.h"
+#include "base/strtoint.h"
+
+// Replacement strto[u]l functions that have identical overflow and underflow
+// characteristics for both ILP-32 and LP-64 platforms, including errno
+// preservation for error-free calls.
+int32 strto32_adapter(const char *nptr, char **endptr, int base) {
+ const int saved_errno = errno;
+ errno = 0;
+ const long result = strtol(nptr, endptr, base);
+ if (errno == ERANGE && result == LONG_MIN) {
+ return kint32min;
+ } else if (errno == ERANGE && result == LONG_MAX) {
+ return kint32max;
+ } else if (errno == 0 && result < kint32min) {
+ errno = ERANGE;
+ return kint32min;
+ } else if (errno == 0 && result > kint32max) {
+ errno = ERANGE;
+ return kint32max;
+ }
+ if (errno == 0)
+ errno = saved_errno;
+ return static_cast<int32>(result);
+}
+
+uint32 strtou32_adapter(const char *nptr, char **endptr, int base) {
+ const int saved_errno = errno;
+ errno = 0;
+ const unsigned long result = strtoul(nptr, endptr, base);
+ if (errno == ERANGE && result == ULONG_MAX) {
+ return kuint32max;
+ } else if (errno == 0 && result > kuint32max) {
+ errno = ERANGE;
+ return kuint32max;
+ }
+ if (errno == 0)
+ errno = saved_errno;
+ return static_cast<uint32>(result);
+}
diff --git a/src/third_party/s2/base/strtoint.h b/src/third_party/s2/base/strtoint.h
new file mode 100755
index 00000000000..2db327163e0
--- /dev/null
+++ b/src/third_party/s2/base/strtoint.h
@@ -0,0 +1,93 @@
+// Copyright 2008 Google Inc. All Rights Reserved.
+//
+// Architecture-neutral plug compatible replacements for strtol() friends.
+//
+// Long's have different lengths on ILP-32 and LP-64 platforms, and so overflow
+// behavior across the two varies when strtol() and similar are used to parse
+// 32-bit integers. Similar problems exist with atoi(), because although it
+// has an all-integer interface, it uses strtol() internally, and so suffers
+// from the same narrowing problems on assignments to int.
+//
+// Examples:
+// errno = 0;
+// i = strtol("3147483647", NULL, 10);
+// printf("%d, errno %d\n", i, errno);
+// // 32-bit platform: 2147483647, errno 34
+// // 64-bit platform: -1147483649, errno 0
+//
+// printf("%d\n", atoi("3147483647"));
+// // 32-bit platform: 2147483647
+// // 64-bit platform: -1147483649
+//
+// A way round this is to define local replacements for these, and use them
+// instead of the standard libc functions.
+//
+// In most 32-bit cases the replacements can be inlined away to a call to the
+// libc function. In a couple of 64-bit cases, however, adapters are required,
+// to provide the right overflow and errno behavior.
+//
+
+#ifndef BASE_STRTOINT_H_
+#define BASE_STRTOINT_H_
+
+#include <stdlib.h> // For strtol* functions.
+#include <string>
+using std::string;
+
+#include "base/port.h"
+#include "base/basictypes.h"
+
+// Adapter functions for handling overflow and errno.
+int32 strto32_adapter(const char *nptr, char **endptr, int base);
+uint32 strtou32_adapter(const char *nptr, char **endptr, int base);
+
+// Conversions to a 32-bit integer can pass the call to strto[u]l on 32-bit
+// platforms, but need a little extra work on 64-bit platforms.
+inline int32 strto32(const char *nptr, char **endptr, int base) {
+ if (sizeof(int32) == sizeof(long))
+ return strtol(nptr, endptr, base);
+ else
+ return strto32_adapter(nptr, endptr, base);
+}
+
+inline uint32 strtou32(const char *nptr, char **endptr, int base) {
+ if (sizeof(uint32) == sizeof(unsigned long))
+ return strtoul(nptr, endptr, base);
+ else
+ return strtou32_adapter(nptr, endptr, base);
+}
+
+// For now, long long is 64-bit on all the platforms we care about, so these
+// functions can simply pass the call to strto[u]ll.
+inline int64 strto64(const char *nptr, char **endptr, int base) {
+ COMPILE_ASSERT(sizeof(int64) == sizeof(long long),
+ sizeof_int64_is_not_sizeof_long_long);
+ return strtoll(nptr, endptr, base);
+}
+
+inline uint64 strtou64(const char *nptr, char **endptr, int base) {
+ COMPILE_ASSERT(sizeof(uint64) == sizeof(unsigned long long),
+ sizeof_uint64_is_not_sizeof_long_long);
+ return strtoull(nptr, endptr, base);
+}
+
+// Although it returns an int, atoi() is implemented in terms of strtol, and
+// so has differing overflow and underflow behavior. atol is the same.
+inline int32 atoi32(const char *nptr) {
+ return strto32(nptr, NULL, 10);
+}
+
+inline int64 atoi64(const char *nptr) {
+ return strto64(nptr, NULL, 10);
+}
+
+// Convenience versions of the above that take a string argument.
+inline int32 atoi32(const string &s) {
+ return atoi32(s.c_str());
+}
+
+inline int64 atoi64(const string &s) {
+ return atoi64(s.c_str());
+}
+
+#endif // BASE_STRTOINT_H_
diff --git a/src/third_party/s2/base/template_util.h b/src/third_party/s2/base/template_util.h
new file mode 100755
index 00000000000..4c83e89b759
--- /dev/null
+++ b/src/third_party/s2/base/template_util.h
@@ -0,0 +1,98 @@
+// Copyright 2005 Google Inc. All Rights Reserved.
+//
+// Template metaprogramming utility functions.
+//
+// This code is compiled directly on many platforms, including client
+// platforms like Windows, Mac, and embedded systems. Before making
+// any changes here, make sure that you're not breaking any platforms.
+//
+//
+// The names choosen here reflect those used in tr1 and the boost::mpl
+// library, there are similar operations used in the Loki library as
+// well. I prefer the boost names for 2 reasons:
+// 1. I think that portions of the Boost libraries are more likely to
+// be included in the c++ standard.
+// 2. It is not impossible that some of the boost libraries will be
+// included in our own build in the future.
+// Both of these outcomes means that we may be able to directly replace
+// some of these with boost equivalents.
+//
+#ifndef BASE_TEMPLATE_UTIL_H_
+#define BASE_TEMPLATE_UTIL_H_
+
+namespace base {
+
+// Types small_ and big_ are guaranteed such that sizeof(small_) <
+// sizeof(big_)
+typedef char small_;
+
+struct big_ {
+ char dummy[2];
+};
+
+// integral_constant, defined in tr1, is a wrapper for an integer
+// value. We don't really need this generality; we could get away
+// with hardcoding the integer type to bool. We use the fully
+// general integer_constant for compatibility with tr1.
+
+template<class T, T v>
+struct integral_constant {
+ static const T value = v;
+ typedef T value_type;
+ typedef integral_constant<T, v> type;
+};
+
+template <class T, T v> const T integral_constant<T, v>::value;
+
+
+// Abbreviations: true_type and false_type are structs that represent boolean
+// true and false values. Also define the boost::mpl versions of those names,
+// true_ and false_.
+typedef integral_constant<bool, true> true_type;
+typedef integral_constant<bool, false> false_type;
+typedef true_type true_;
+typedef false_type false_;
+
+// if_ is a templatized conditional statement.
+// if_<cond, A, B> is a compile time evaluation of cond.
+// if_<>::type contains A if cond is true, B otherwise.
+template<bool cond, typename A, typename B>
+struct if_{
+ typedef A type;
+};
+
+template<typename A, typename B>
+struct if_<false, A, B> {
+ typedef B type;
+};
+
+
+// type_equals_ is a template type comparator, similar to Loki IsSameType.
+// type_equals_<A, B>::value is true iff "A" is the same type as "B".
+//
+// New code should prefer base::is_same, defined in base/type_traits.h.
+// It is functionally identical, but is_same is the standard spelling.
+template<typename A, typename B>
+struct type_equals_ : public false_ {
+};
+
+template<typename A>
+struct type_equals_<A, A> : public true_ {
+};
+
+// and_ is a template && operator.
+// and_<A, B>::value evaluates "A::value && B::value".
+template<typename A, typename B>
+struct and_ : public integral_constant<bool, (A::value && B::value)> {
+};
+
+// or_ is a template || operator.
+// or_<A, B>::value evaluates "A::value || B::value".
+template<typename A, typename B>
+struct or_ : public integral_constant<bool, (A::value || B::value)> {
+};
+
+
+} // Close namespace base
+
+#endif // BASE_TEMPLATE_UTIL_H_
diff --git a/src/third_party/s2/base/type_traits.h b/src/third_party/s2/base/type_traits.h
new file mode 100755
index 00000000000..ffa70a18ea9
--- /dev/null
+++ b/src/third_party/s2/base/type_traits.h
@@ -0,0 +1,285 @@
+// Copyright 2006 Google Inc. All Rights Reserved.
+//
+// This code is compiled directly on many platforms, including client
+// platforms like Windows, Mac, and embedded systems. Before making
+// any changes here, make sure that you're not breaking any platforms.
+//
+//
+// Define a small subset of tr1 type traits. The traits we define are:
+// is_integral
+// is_floating_point
+// is_pointer
+// is_enum
+// is_reference
+// is_pod
+// has_trivial_constructor
+// has_trivial_copy
+// has_trivial_assign
+// has_trivial_destructor
+// remove_const
+// remove_volatile
+// remove_cv
+// remove_reference
+// add_reference
+// remove_pointer
+// is_same
+// is_convertible
+// We can add more type traits as required.
+
+#ifndef BASE_TYPE_TRAITS_H_
+#define BASE_TYPE_TRAITS_H_
+
+#include "template_util.h" // For true_type and false_type
+#include <utility>
+using std::pair;
+using std::make_pair;
+ // For pair
+
+namespace base {
+
+template <class T> struct is_integral;
+template <class T> struct is_floating_point;
+template <class T> struct is_pointer;
+// MSVC can't compile this correctly, and neither can gcc 3.3.5 (at least)
+#if !defined(_MSC_VER) && !(defined(__GNUC__) && __GNUC__ <= 3)
+// is_enum uses is_convertible, which is not available on MSVC.
+template <class T> struct is_enum;
+#endif
+template <class T> struct is_reference;
+template <class T> struct is_pod;
+template <class T> struct has_trivial_constructor;
+template <class T> struct has_trivial_copy;
+template <class T> struct has_trivial_assign;
+template <class T> struct has_trivial_destructor;
+template <class T> struct remove_const;
+template <class T> struct remove_volatile;
+template <class T> struct remove_cv;
+template <class T> struct remove_reference;
+template <class T> struct add_reference;
+template <class T> struct remove_pointer;
+template <class T, class U> struct is_same;
+#if !defined(_MSC_VER) && !(defined(__GNUC__) && __GNUC__ <= 3)
+template <class From, class To> struct is_convertible;
+#endif
+
+// is_integral is false except for the built-in integer types.
+template <class T> struct is_integral : false_type { };
+template<> struct is_integral<bool> : true_type { };
+template<> struct is_integral<char> : true_type { };
+template<> struct is_integral<unsigned char> : true_type { };
+template<> struct is_integral<signed char> : true_type { };
+#if defined(_MSC_VER)
+// wchar_t is not by default a distinct type from unsigned short in
+// Microsoft C.
+// See http://msdn2.microsoft.com/en-us/library/dh8che7s(VS.80).aspx
+template<> struct is_integral<__wchar_t> : true_type { };
+#else
+template<> struct is_integral<wchar_t> : true_type { };
+#endif
+template<> struct is_integral<short> : true_type { };
+template<> struct is_integral<unsigned short> : true_type { };
+template<> struct is_integral<int> : true_type { };
+template<> struct is_integral<unsigned int> : true_type { };
+template<> struct is_integral<long> : true_type { };
+template<> struct is_integral<unsigned long> : true_type { };
+template<> struct is_integral<long long> : true_type { };
+template<> struct is_integral<unsigned long long> : true_type { };
+
+
+// is_floating_point is false except for the built-in floating-point types.
+template <class T> struct is_floating_point : false_type { };
+template<> struct is_floating_point<float> : true_type { };
+template<> struct is_floating_point<double> : true_type { };
+template<> struct is_floating_point<long double> : true_type { };
+
+
+// is_pointer is false except for pointer types.
+template <class T> struct is_pointer : false_type { };
+template <class T> struct is_pointer<T*> : true_type { };
+
+#if !defined(_MSC_VER) && !(defined(__GNUC__) && __GNUC__ <= 3)
+
+namespace internal {
+
+template <class T> struct is_class_or_union {
+ template <class U> static small_ tester(void (U::*)());
+ template <class U> static big_ tester(...);
+ static const bool value = sizeof(tester<T>(0)) == sizeof(small_);
+};
+
+// is_convertible chokes if the first argument is an array. That's why
+// we use add_reference here.
+template <bool NotUnum, class T> struct is_enum_impl
+ : is_convertible<typename add_reference<T>::type, int> { };
+
+template <class T> struct is_enum_impl<true, T> : false_type { };
+
+} // namespace internal
+
+// Specified by TR1 [4.5.1] primary type categories.
+
+// Implementation note:
+//
+// Each type is either void, integral, floating point, array, pointer,
+// reference, member object pointer, member function pointer, enum,
+// union or class. Out of these, only integral, floating point, reference,
+// class and enum types are potentially convertible to int. Therefore,
+// if a type is not a reference, integral, floating point or class and
+// is convertible to int, it's a enum.
+//
+// Is-convertible-to-int check is done only if all other checks pass,
+// because it can't be used with some types (e.g. void or classes with
+// inaccessible conversion operators).
+template <class T> struct is_enum
+ : internal::is_enum_impl<
+ is_same<T, void>::value ||
+ is_integral<T>::value ||
+ is_floating_point<T>::value ||
+ is_reference<T>::value ||
+ internal::is_class_or_union<T>::value,
+ T> { };
+
+template <class T> struct is_enum<const T> : is_enum<T> { };
+template <class T> struct is_enum<volatile T> : is_enum<T> { };
+template <class T> struct is_enum<const volatile T> : is_enum<T> { };
+
+#endif
+
+// is_reference is false except for reference types.
+template<typename T> struct is_reference : false_type {};
+template<typename T> struct is_reference<T&> : true_type {};
+
+
+// We can't get is_pod right without compiler help, so fail conservatively.
+// We will assume it's false except for arithmetic types, enumerations,
+// pointers and const versions thereof. Note that std::pair is not a POD.
+template <class T> struct is_pod
+ : integral_constant<bool, (is_integral<T>::value ||
+ is_floating_point<T>::value ||
+#if !defined(_MSC_VER) && !(defined(__GNUC__) && __GNUC__ <= 3)
+ // is_enum is not available on MSVC.
+ is_enum<T>::value ||
+#endif
+ is_pointer<T>::value)> { };
+template <class T> struct is_pod<const T> : is_pod<T> { };
+
+
+// We can't get has_trivial_constructor right without compiler help, so
+// fail conservatively. We will assume it's false except for: (1) types
+// for which is_pod is true. (2) std::pair of types with trivial
+// constructors. (3) array of a type with a trivial constructor.
+// (4) const versions thereof.
+template <class T> struct has_trivial_constructor : is_pod<T> { };
+template <class T, class U> struct has_trivial_constructor<std::pair<T, U> >
+ : integral_constant<bool,
+ (has_trivial_constructor<T>::value &&
+ has_trivial_constructor<U>::value)> { };
+template <class A, int N> struct has_trivial_constructor<A[N]>
+ : has_trivial_constructor<A> { };
+template <class T> struct has_trivial_constructor<const T>
+ : has_trivial_constructor<T> { };
+
+// We can't get has_trivial_copy right without compiler help, so fail
+// conservatively. We will assume it's false except for: (1) types
+// for which is_pod is true. (2) std::pair of types with trivial copy
+// constructors. (3) array of a type with a trivial copy constructor.
+// (4) const versions thereof.
+template <class T> struct has_trivial_copy : is_pod<T> { };
+template <class T, class U> struct has_trivial_copy<std::pair<T, U> >
+ : integral_constant<bool,
+ (has_trivial_copy<T>::value &&
+ has_trivial_copy<U>::value)> { };
+template <class A, int N> struct has_trivial_copy<A[N]>
+ : has_trivial_copy<A> { };
+template <class T> struct has_trivial_copy<const T> : has_trivial_copy<T> { };
+
+// We can't get has_trivial_assign right without compiler help, so fail
+// conservatively. We will assume it's false except for: (1) types
+// for which is_pod is true. (2) std::pair of types with trivial copy
+// constructors. (3) array of a type with a trivial assign constructor.
+template <class T> struct has_trivial_assign : is_pod<T> { };
+template <class T, class U> struct has_trivial_assign<std::pair<T, U> >
+ : integral_constant<bool,
+ (has_trivial_assign<T>::value &&
+ has_trivial_assign<U>::value)> { };
+template <class A, int N> struct has_trivial_assign<A[N]>
+ : has_trivial_assign<A> { };
+
+// We can't get has_trivial_destructor right without compiler help, so
+// fail conservatively. We will assume it's false except for: (1) types
+// for which is_pod is true. (2) std::pair of types with trivial
+// destructors. (3) array of a type with a trivial destructor.
+// (4) const versions thereof.
+template <class T> struct has_trivial_destructor : is_pod<T> { };
+template <class T, class U> struct has_trivial_destructor<std::pair<T, U> >
+ : integral_constant<bool,
+ (has_trivial_destructor<T>::value &&
+ has_trivial_destructor<U>::value)> { };
+template <class A, int N> struct has_trivial_destructor<A[N]>
+ : has_trivial_destructor<A> { };
+template <class T> struct has_trivial_destructor<const T>
+ : has_trivial_destructor<T> { };
+
+// Specified by TR1 [4.7.1]
+template<typename T> struct remove_const { typedef T type; };
+template<typename T> struct remove_const<T const> { typedef T type; };
+template<typename T> struct remove_volatile { typedef T type; };
+template<typename T> struct remove_volatile<T volatile> { typedef T type; };
+template<typename T> struct remove_cv {
+ typedef typename remove_const<typename remove_volatile<T>::type>::type type;
+};
+
+
+// Specified by TR1 [4.7.2] Reference modifications.
+template<typename T> struct remove_reference { typedef T type; };
+template<typename T> struct remove_reference<T&> { typedef T type; };
+
+template <typename T> struct add_reference { typedef T& type; };
+template <typename T> struct add_reference<T&> { typedef T& type; };
+
+// Specified by TR1 [4.7.4] Pointer modifications.
+template<typename T> struct remove_pointer { typedef T type; };
+template<typename T> struct remove_pointer<T*> { typedef T type; };
+template<typename T> struct remove_pointer<T* const> { typedef T type; };
+template<typename T> struct remove_pointer<T* volatile> { typedef T type; };
+template<typename T> struct remove_pointer<T* const volatile> {
+ typedef T type; };
+
+// Specified by TR1 [4.6] Relationships between types
+template<typename T, typename U> struct is_same : public false_type { };
+template<typename T> struct is_same<T, T> : public true_type { };
+
+// Specified by TR1 [4.6] Relationships between types
+#if !defined(_MSC_VER) && !(defined(__GNUC__) && __GNUC__ <= 3)
+namespace internal {
+
+// This class is an implementation detail for is_convertible, and you
+// don't need to know how it works to use is_convertible. For those
+// who care: we declare two different functions, one whose argument is
+// of type To and one with a variadic argument list. We give them
+// return types of different size, so we can use sizeof to trick the
+// compiler into telling us which function it would have chosen if we
+// had called it with an argument of type From. See Alexandrescu's
+// _Modern C++ Design_ for more details on this sort of trick.
+
+template <typename From, typename To>
+struct ConvertHelper {
+ static small_ Test(To);
+ static big_ Test(...);
+ static From Create();
+};
+} // namespace internal
+
+// Inherits from true_type if From is convertible to To, false_type otherwise.
+template <typename From, typename To>
+struct is_convertible
+ : integral_constant<bool,
+ sizeof(internal::ConvertHelper<From, To>::Test(
+ internal::ConvertHelper<From, To>::Create()))
+ == sizeof(small_)> {
+};
+#endif
+
+} // Close namespace base
+
+#endif // BASE_TYPE_TRAITS_H_
diff --git a/src/third_party/s2/pywraps2_test.py b/src/third_party/s2/pywraps2_test.py
new file mode 100755
index 00000000000..5cd5e2e3f27
--- /dev/null
+++ b/src/third_party/s2/pywraps2_test.py
@@ -0,0 +1,51 @@
+#!/usr/bin/python2.4
+# Copyright 2006 Google Inc. All Rights Reserved.
+
+
+
+from google3.pyglib import app
+from google3.testing.pybase import googletest
+from google3.util.geometry.pywraps2 import *
+
+class PyWrapS2TestCase(googletest.TestCase):
+
+ def testContainsIsWrappedCorrectly(self):
+ london = S2LatLngRect(S2LatLng.FromDegrees(51.3368602, 0.4931979),
+ S2LatLng.FromDegrees(51.7323965, 0.1495211))
+ e14lj = S2LatLngRect(S2LatLng.FromDegrees(51.5213527, -0.0476026),
+ S2LatLng.FromDegrees(51.5213527, -0.0476026))
+ self.failUnless(london.Contains(e14lj))
+
+ def testS2CellIdEqualsIsWrappedCorrectly(self):
+ london = S2LatLng.FromDegrees(51.5001525, -0.1262355)
+ cell = S2CellId.FromLatLng(london)
+ same_cell = S2CellId.FromLatLng(london)
+ self.assertEquals(cell, same_cell)
+
+ def testS2CellIdComparsionIsWrappedCorrectly(self):
+ london = S2LatLng.FromDegrees(51.5001525, -0.1262355)
+ cell = S2CellId.FromLatLng(london)
+ self.failUnless(cell < cell.next())
+ self.failUnless(cell.next() > cell)
+
+ def testS2HashingIsWrappedCorrectly(self):
+ london = S2LatLng.FromDegrees(51.5001525, -0.1262355)
+ cell = S2CellId.FromLatLng(london)
+ same_cell = S2CellId.FromLatLng(london)
+ self.assertEquals(hash(cell), hash(same_cell))
+
+ def testCovererIsWrapperCorrectly(self):
+ london = S2LatLngRect(S2LatLng.FromDegrees(51.3368602, 0.4931979),
+ S2LatLng.FromDegrees(51.7323965, 0.1495211))
+ e14lj = S2LatLngRect(S2LatLng.FromDegrees(51.5213527, -0.0476026),
+ S2LatLng.FromDegrees(51.5213527, -0.0476026))
+ coverer = S2RegionCoverer()
+ covering = coverer.GetCovering(e14lj)
+ for cellid in covering:
+ self.failUnless(london.Contains(S2Cell(cellid)))
+
+def main(argv):
+ googletest.main()
+
+if __name__ == "__main__":
+ app.run()
diff --git a/src/third_party/s2/r1interval.h b/src/third_party/s2/r1interval.h
new file mode 100644
index 00000000000..504ebc7e154
--- /dev/null
+++ b/src/third_party/s2/r1interval.h
@@ -0,0 +1,186 @@
+// Copyright 2005 Google Inc. All Rights Reserved.
+
+#ifndef UTIL_GEOMETRY_R1INTERVAL_H_
+#define UTIL_GEOMETRY_R1INTERVAL_H_
+
+#include <math.h>
+
+#include <algorithm>
+using std::min;
+using std::max;
+using std::swap;
+using std::reverse;
+
+#include <iostream>
+using std::ostream;
+using std::cout;
+using std::endl;
+
+#include "base/basictypes.h"
+#include "base/logging.h"
+#include "util/math/vector2-inl.h"
+
+// An R1Interval represents a closed, bounded interval on the real line.
+// It is capable of representing the empty interval (containing no points)
+// and zero-length intervals (containing a single point).
+//
+// This class is intended to be copied by value as desired. It uses
+// the default copy constructor and assignment operator.
+class R1Interval {
+ public:
+ // Constructor. If lo > hi, the interval is empty.
+ R1Interval(double lo, double hi) : bounds_(lo, hi) {}
+
+ // The default constructor creates an empty interval. (Any interval where
+ // lo > hi is considered to be empty.)
+ //
+ // Note: Don't construct an interval using the default constructor and
+ // set_lo()/set_hi(), since this technique doesn't work with S1Interval and
+ // is bad programming style anyways. If you need to set both endpoints, use
+ // the constructor above:
+ //
+ // lat_bounds_ = R1Interval(lat_lo, lat_hi);
+ R1Interval() : bounds_(1, 0) {}
+
+ // Returns an empty interval.
+ static inline R1Interval Empty() { return R1Interval(); }
+
+ // Convenience method to construct an interval containing a single point.
+ static R1Interval FromPoint(double p) {
+ return R1Interval(p, p);
+ }
+
+ // Convenience method to construct the minimal interval containing
+ // the two given points. This is equivalent to starting with an empty
+ // interval and calling AddPoint() twice, but it is more efficient.
+ static R1Interval FromPointPair(double p1, double p2) {
+ if (p1 <= p2) {
+ return R1Interval(p1, p2);
+ } else {
+ return R1Interval(p2, p1);
+ }
+ }
+
+ double lo() const { return bounds_[0]; }
+ double hi() const { return bounds_[1]; }
+ double bound(int i) const { return bounds_[i]; }
+ Vector2_d const& bounds() const { return bounds_; }
+
+ // Methods to modify one endpoint of an existing R1Interval. Do not use
+ // these methods if you want to replace both endpoints of the interval; use
+ // a constructor instead. For example:
+ //
+ // *lat_bounds = R1Interval(lat_lo, lat_hi);
+ void set_lo(double p) { bounds_[0] = p; }
+ void set_hi(double p) { bounds_[1] = p; }
+
+ // Return true if the interval is empty, i.e. it contains no points.
+ bool is_empty() const { return lo() > hi(); }
+
+ // Return the center of the interval. For empty intervals,
+ // the result is arbitrary.
+ double GetCenter() const { return 0.5 * (lo() + hi()); }
+
+ // Return the length of the interval. The length of an empty interval
+ // is negative.
+ double GetLength() const { return hi() - lo(); }
+
+ bool Contains(double p) const {
+ return p >= lo() && p <= hi();
+ }
+
+ bool InteriorContains(double p) const {
+ return p > lo() && p < hi();
+ }
+
+ // Return true if this interval contains the interval 'y'.
+ bool Contains(R1Interval const& y) const {
+ if (y.is_empty()) return true;
+ return y.lo() >= lo() && y.hi() <= hi();
+ }
+
+ // Return true if the interior of this interval contains the entire
+ // interval 'y' (including its boundary).
+ bool InteriorContains(R1Interval const& y) const {
+ if (y.is_empty()) return true;
+ return y.lo() > lo() && y.hi() < hi();
+ }
+
+ // Return true if this interval intersects the given interval,
+ // i.e. if they have any points in common.
+ bool Intersects(R1Interval const& y) const {
+ if (lo() <= y.lo()) {
+ return y.lo() <= hi() && y.lo() <= y.hi();
+ } else {
+ return lo() <= y.hi() && lo() <= hi();
+ }
+ }
+
+ // Return true if the interior of this interval intersects
+ // any point of the given interval (including its boundary).
+ bool InteriorIntersects(R1Interval const& y) const {
+ return y.lo() < hi() && lo() < y.hi() && lo() < hi() && y.lo() <= y.hi();
+ }
+
+ // Return the Hausdorff distance to the given interval 'y'. For two
+ // R1Intervals x and y, this distance is defined as
+ // h(x, y) = max_{p in x} min_{q in y} d(p, q).
+ double GetDirectedHausdorffDistance(R1Interval const& y) const {
+ if (is_empty()) return 0.0;
+ if (y.is_empty()) return HUGE_VAL;
+ return max(0.0, max(hi() - y.hi(), y.lo() - lo()));
+ }
+
+ // Expand the interval so that it contains the given point "p".
+ void AddPoint(double p) {
+ if (is_empty()) { set_lo(p); set_hi(p); }
+ else if (p < lo()) { set_lo(p); }
+ else if (p > hi()) { set_hi(p); }
+ }
+
+ // Return an interval that contains all points with a distance "radius" of
+ // a point in this interval. Note that the expansion of an empty interval
+ // is always empty.
+ R1Interval Expanded(double radius) const {
+ DCHECK_GE(radius, 0);
+ if (is_empty()) return *this;
+ return R1Interval(lo() - radius, hi() + radius);
+ }
+
+ // Return the smallest interval that contains this interval and the
+ // given interval "y".
+ R1Interval Union(R1Interval const& y) const {
+ if (is_empty()) return y;
+ if (y.is_empty()) return *this;
+ return R1Interval(min(lo(), y.lo()), max(hi(), y.hi()));
+ }
+
+ // Return the intersection of this interval with the given interval.
+ // Empty intervals do not need to be special-cased.
+ R1Interval Intersection(R1Interval const& y) const {
+ return R1Interval(max(lo(), y.lo()), min(hi(), y.hi()));
+ }
+
+ // Return true if two intervals contain the same set of points.
+ bool operator==(R1Interval const& y) const {
+ return (lo() == y.lo() && hi() == y.hi()) || (is_empty() && y.is_empty());
+ }
+
+ // Return true if length of the symmetric difference between the two
+ // intervals is at most the given tolerance.
+ bool ApproxEquals(R1Interval const& y, double max_error = 1e-15) const {
+ if (is_empty()) return y.GetLength() <= max_error;
+ if (y.is_empty()) return GetLength() <= max_error;
+ return fabs(y.lo() - lo()) + fabs(y.hi() - hi()) <= max_error;
+ }
+
+ private:
+ Vector2_d bounds_;
+};
+DECLARE_POD(R1Interval);
+
+inline ostream& operator<<(ostream& os, R1Interval const& x) {
+ return os << "[" << x.lo() << ", " << x.hi() << "]";
+}
+
+#endif // UTIL_GEOMETRY_R1INTERVAL_H_
diff --git a/src/third_party/s2/r1interval_test.cc b/src/third_party/s2/r1interval_test.cc
new file mode 100644
index 00000000000..dbe2fa0dabc
--- /dev/null
+++ b/src/third_party/s2/r1interval_test.cc
@@ -0,0 +1,109 @@
+// Copyright 2005 Google Inc. All Rights Reserved.
+
+#include "r1interval.h"
+
+#include "gtest/gtest.h"
+
+static void TestIntervalOps(R1Interval const& x, R1Interval const& y,
+ const char* expected) {
+ // Test all of the interval operations on the given pair of intervals.
+ // "expected" is a sequence of "T" and "F" characters corresponding to
+ // the expected results of Contains(), InteriorContains(), Intersects(),
+ // and InteriorIntersects() respectively.
+
+ EXPECT_EQ(expected[0] == 'T', x.Contains(y));
+ EXPECT_EQ(expected[1] == 'T', x.InteriorContains(y));
+ EXPECT_EQ(expected[2] == 'T', x.Intersects(y));
+ EXPECT_EQ(expected[3] == 'T', x.InteriorIntersects(y));
+
+ EXPECT_EQ(x.Contains(y), x.Union(y) == x);
+ EXPECT_EQ(x.Intersects(y), !x.Intersection(y).is_empty());
+}
+
+TEST(R1Interval, TestBasic) {
+ // Constructors and accessors.
+ R1Interval unit(0, 1);
+ R1Interval negunit(-1, 0);
+ EXPECT_EQ(0, unit.lo());
+ EXPECT_EQ(1, unit.hi());
+ EXPECT_EQ(-1, negunit.bound(0));
+ EXPECT_EQ(0, negunit.bound(1));
+ R1Interval ten(0, 0);
+ ten.set_hi(10);
+ EXPECT_EQ(10, ten.hi());
+
+ // is_empty()
+ R1Interval half(0.5, 0.5);
+ EXPECT_FALSE(unit.is_empty());
+ EXPECT_FALSE(half.is_empty());
+ R1Interval empty = R1Interval::Empty();
+ EXPECT_TRUE(empty.is_empty());
+
+ // Check that the default R1Interval is identical to Empty().
+ R1Interval default_empty;
+ EXPECT_TRUE(default_empty.is_empty());
+ EXPECT_EQ(empty.lo(), default_empty.lo());
+ EXPECT_EQ(empty.hi(), default_empty.hi());
+
+ // GetCenter(), GetLength()
+ EXPECT_EQ(unit.GetCenter(), 0.5);
+ EXPECT_EQ(half.GetCenter(), 0.5);
+ EXPECT_EQ(negunit.GetLength(), 1.0);
+ EXPECT_EQ(half.GetLength(), 0);
+ EXPECT_LT(empty.GetLength(), 0);
+
+ // Contains(double), InteriorContains(double)
+ EXPECT_TRUE(unit.Contains(0.5));
+ EXPECT_TRUE(unit.InteriorContains(0.5));
+ EXPECT_TRUE(unit.Contains(0));
+ EXPECT_FALSE(unit.InteriorContains(0));
+ EXPECT_TRUE(unit.Contains(1));
+ EXPECT_FALSE(unit.InteriorContains(1));
+
+ // Contains(R1Interval), InteriorContains(R1Interval)
+ // Intersects(R1Interval), InteriorIntersects(R1Interval)
+ { SCOPED_TRACE(""); TestIntervalOps(empty, empty, "TTFF"); }
+ { SCOPED_TRACE(""); TestIntervalOps(empty, unit, "FFFF"); }
+ { SCOPED_TRACE(""); TestIntervalOps(unit, half, "TTTT"); }
+ { SCOPED_TRACE(""); TestIntervalOps(unit, unit, "TFTT"); }
+ { SCOPED_TRACE(""); TestIntervalOps(unit, empty, "TTFF"); }
+ { SCOPED_TRACE(""); TestIntervalOps(unit, negunit, "FFTF"); }
+ { SCOPED_TRACE(""); TestIntervalOps(unit, R1Interval(0, 0.5), "TFTT"); }
+ { SCOPED_TRACE(""); TestIntervalOps(half, R1Interval(0, 0.5), "FFTF"); }
+
+ // AddPoint()
+ R1Interval r = empty;
+ r.AddPoint(5);
+ EXPECT_EQ(5, r.lo());
+ EXPECT_EQ(5, r.hi());
+ r.AddPoint(-1);
+ EXPECT_EQ(-1, r.lo());
+ EXPECT_EQ(5, r.hi());
+ r.AddPoint(0);
+ EXPECT_EQ(-1, r.lo());
+ EXPECT_EQ(5, r.hi());
+
+ // FromPointPair()
+ EXPECT_EQ(R1Interval(4, 4), R1Interval::FromPointPair(4, 4));
+ EXPECT_EQ(R1Interval(-2, -1), R1Interval::FromPointPair(-1, -2));
+ EXPECT_EQ(R1Interval(-5, 3), R1Interval::FromPointPair(-5, 3));
+
+ // Expanded()
+ EXPECT_EQ(empty, empty.Expanded(0.45));
+ EXPECT_EQ(R1Interval(-0.5, 1.5), unit.Expanded(0.5));
+
+ // Union(), Intersection()
+ EXPECT_EQ(R1Interval(99, 100), R1Interval(99,100).Union(empty));
+ EXPECT_EQ(R1Interval(99, 100), empty.Union(R1Interval(99,100)));
+ EXPECT_TRUE(R1Interval(5,3).Union(R1Interval(0,-2)).is_empty());
+ EXPECT_TRUE(R1Interval(0,-2).Union(R1Interval(5,3)).is_empty());
+ EXPECT_EQ(unit, unit.Union(unit));
+ EXPECT_EQ(R1Interval(-1, 1), unit.Union(negunit));
+ EXPECT_EQ(R1Interval(-1, 1), negunit.Union(unit));
+ EXPECT_EQ(unit, half.Union(unit));
+ EXPECT_EQ(half, unit.Intersection(half));
+ EXPECT_EQ(R1Interval(0, 0), unit.Intersection(negunit));
+ EXPECT_TRUE(negunit.Intersection(half).is_empty());
+ EXPECT_TRUE(unit.Intersection(empty).is_empty());
+ EXPECT_TRUE(empty.Intersection(unit).is_empty());
+}
diff --git a/src/third_party/s2/s1angle.cc b/src/third_party/s2/s1angle.cc
new file mode 100644
index 00000000000..e299344fb59
--- /dev/null
+++ b/src/third_party/s2/s1angle.cc
@@ -0,0 +1,41 @@
+// Copyright 2005 Google Inc. All Rights Reserved.
+
+#include <math.h>
+#include <stdio.h>
+#include <iostream>
+using std::ostream;
+using std::cout;
+using std::endl;
+
+#include "s1angle.h"
+#include "s2latlng.h"
+
+S1Angle::S1Angle(S2Point const& x, S2Point const& y)
+ : radians_(x.Angle(y)) {
+}
+
+S1Angle::S1Angle(S2LatLng const& x, S2LatLng const& y)
+ : radians_(x.GetDistance(y).radians()) {
+}
+
+S1Angle S1Angle::Normalized() const {
+ S1Angle a(radians_);
+ a.Normalize();
+ return a;
+}
+
+void S1Angle::Normalize() {
+ radians_ = drem(radians_, 2.0 * M_PI);
+ if (radians_ <= -M_PI) radians_ = M_PI;
+}
+
+ostream& operator<<(ostream& os, S1Angle const& a) {
+ double degrees = a.degrees();
+ char buffer[13];
+ int sz = snprintf(buffer, sizeof(buffer), "%.7f", degrees);
+ if (sz >= 0 && (size_t)sz < sizeof(buffer)) {
+ return os << buffer;
+ } else {
+ return os << degrees;
+ }
+}
diff --git a/src/third_party/s2/s1angle.h b/src/third_party/s2/s1angle.h
new file mode 100644
index 00000000000..8020df2e41d
--- /dev/null
+++ b/src/third_party/s2/s1angle.h
@@ -0,0 +1,207 @@
+// Copyright 2005 Google Inc. All Rights Reserved.
+
+#ifndef UTIL_GEOMETRY_S1ANGLE_H_
+#define UTIL_GEOMETRY_S1ANGLE_H_
+
+#include <iosfwd>
+using std::ostream;
+ // to forward declare ostream
+#define _USE_MATH_DEFINES
+#include <cmath>
+#include "base/basictypes.h"
+#include "util/math/mathutil.h"
+#include "s2.h"
+
+class S2LatLng;
+
+// This class represents a one-dimensional angle (as opposed to a
+// two-dimensional solid angle). It has methods for converting angles to
+// or from radians, degrees, and the E5/E6/E7 representations (i.e. degrees
+// multiplied by 1e5/1e6/1e7 and rounded to the nearest integer).
+//
+// This class has built-in support for the E5, E6, and E7
+// representations. An E5 is the measure of an angle in degrees,
+// multiplied by 10**5.
+//
+// This class is intended to be copied by value as desired. It uses
+// the default copy constructor and assignment operator.
+class S1Angle {
+ public:
+ // These methods construct S1Angle objects from their measure in radians
+ // or degrees.
+ inline static S1Angle Radians(double radians);
+ inline static S1Angle Degrees(double degrees);
+ inline static S1Angle E5(int32 e5);
+ inline static S1Angle E6(int32 e6);
+ inline static S1Angle E7(int32 e7);
+
+ // Convenience functions -- to use when args have been fixed32s in protos.
+ //
+ // The arguments are static_cast into int32, so very large unsigned values
+ // are treated as negative numbers.
+ inline static S1Angle UnsignedE6(uint32 e6);
+ inline static S1Angle UnsignedE7(uint32 e7);
+
+ // The default constructor yields a zero angle. This is useful for STL
+ // containers and class methods with output arguments.
+ inline S1Angle() : radians_(0) {}
+
+ // Return the angle between two points, which is also equal to the distance
+ // between these points on the unit sphere. The points do not need to be
+ // normalized.
+ S1Angle(S2Point const& x, S2Point const& y);
+
+ // Like the constructor above, but return the angle (i.e., distance)
+ // between two S2LatLng points.
+ S1Angle(S2LatLng const& x, S2LatLng const& y);
+
+ double radians() const { return radians_; }
+ double degrees() const { return radians_ * (180 / M_PI); }
+
+ int32 e5() const { return MathUtil::FastIntRound(degrees() * 1e5); }
+ int32 e6() const { return MathUtil::FastIntRound(degrees() * 1e6); }
+ int32 e7() const { return MathUtil::FastIntRound(degrees() * 1e7); }
+
+ // Return the absolute value of an angle.
+ S1Angle abs() const { return S1Angle(fabs(radians_)); }
+
+ // Comparison operators.
+ friend inline bool operator==(S1Angle const& x, S1Angle const& y);
+ friend inline bool operator!=(S1Angle const& x, S1Angle const& y);
+ friend inline bool operator<(S1Angle const& x, S1Angle const& y);
+ friend inline bool operator>(S1Angle const& x, S1Angle const& y);
+ friend inline bool operator<=(S1Angle const& x, S1Angle const& y);
+ friend inline bool operator>=(S1Angle const& x, S1Angle const& y);
+
+ // Simple arithmetic operators for manipulating S1Angles.
+ friend inline S1Angle operator-(S1Angle const& a);
+ friend inline S1Angle operator+(S1Angle const& a, S1Angle const& b);
+ friend inline S1Angle operator-(S1Angle const& a, S1Angle const& b);
+ friend inline S1Angle operator*(double m, S1Angle const& a);
+ friend inline S1Angle operator*(S1Angle const& a, double m);
+ friend inline S1Angle operator/(S1Angle const& a, double m);
+ friend inline double operator/(S1Angle const& a, S1Angle const& b);
+ inline S1Angle& operator+=(S1Angle const& a);
+ inline S1Angle& operator-=(S1Angle const& a);
+ inline S1Angle& operator*=(double m);
+ inline S1Angle& operator/=(double m);
+
+ // Return the angle normalized to the range (-180, 180] degrees.
+ S1Angle Normalized() const;
+
+ // Normalize this angle to the range (-180, 180] degrees.
+ void Normalize();
+
+ private:
+ explicit S1Angle(double radians) : radians_(radians) {}
+ double radians_;
+};
+DECLARE_POD(S1Angle);
+
+inline bool operator==(S1Angle const& x, S1Angle const& y) {
+ return x.radians() == y.radians();
+}
+
+inline bool operator!=(S1Angle const& x, S1Angle const& y) {
+ return x.radians() != y.radians();
+}
+
+inline bool operator<(S1Angle const& x, S1Angle const& y) {
+ return x.radians() < y.radians();
+}
+
+inline bool operator>(S1Angle const& x, S1Angle const& y) {
+ return x.radians() > y.radians();
+}
+
+inline bool operator<=(S1Angle const& x, S1Angle const& y) {
+ return x.radians() <= y.radians();
+}
+
+inline bool operator>=(S1Angle const& x, S1Angle const& y) {
+ return x.radians() >= y.radians();
+}
+
+inline S1Angle operator-(S1Angle const& a) {
+ return S1Angle::Radians(-a.radians());
+}
+
+inline S1Angle operator+(S1Angle const& a, S1Angle const& b) {
+ return S1Angle::Radians(a.radians() + b.radians());
+}
+
+inline S1Angle operator-(S1Angle const& a, S1Angle const& b) {
+ return S1Angle::Radians(a.radians() - b.radians());
+}
+
+inline S1Angle operator*(double m, S1Angle const& a) {
+ return S1Angle::Radians(m * a.radians());
+}
+
+inline S1Angle operator*(S1Angle const& a, double m) {
+ return S1Angle::Radians(m * a.radians());
+}
+
+inline S1Angle operator/(S1Angle const& a, double m) {
+ return S1Angle::Radians(a.radians() / m);
+}
+
+inline double operator/(S1Angle const& a, S1Angle const& b) {
+ return a.radians() / b.radians();
+}
+
+inline S1Angle& S1Angle::operator+=(S1Angle const& a) {
+ radians_ += a.radians();
+ return *this;
+}
+
+inline S1Angle& S1Angle::operator-=(S1Angle const& a) {
+ radians_ -= a.radians();
+ return *this;
+}
+
+inline S1Angle& S1Angle::operator*=(double m) {
+ radians_ *= m;
+ return *this;
+}
+
+inline S1Angle& S1Angle::operator/=(double m) {
+ radians_ /= m;
+ return *this;
+}
+
+inline S1Angle S1Angle::Radians(double radians) {
+ return S1Angle(radians);
+}
+
+inline S1Angle S1Angle::Degrees(double degrees) {
+ return S1Angle(degrees * (M_PI / 180));
+}
+
+inline S1Angle S1Angle::E5(int32 e5) {
+ // Multiplying by 1e-5 isn't quite as accurate as dividing by 1e5,
+ // but it's about 10 times faster and more than accurate enough.
+ return Degrees(e5 * 1e-5);
+}
+
+inline S1Angle S1Angle::E6(int32 e6) {
+ return Degrees(e6 * 1e-6);
+}
+
+inline S1Angle S1Angle::E7(int32 e7) {
+ return Degrees(e7 * 1e-7);
+}
+
+inline S1Angle S1Angle::UnsignedE6(uint32 e6) {
+ return Degrees(static_cast<int32>(e6) * 1e-6);
+}
+
+inline S1Angle S1Angle::UnsignedE7(uint32 e7) {
+ return Degrees(static_cast<int32>(e7) * 1e-7);
+}
+
+// Writes the angle in degrees with 7 digits of precision after the
+// decimal point, e.g. "17.3745904".
+ostream& operator<<(ostream& os, S1Angle const& a);
+
+#endif // UTIL_GEOMETRY_S1ANGLE_H_
diff --git a/src/third_party/s2/s1angle_test.cc b/src/third_party/s2/s1angle_test.cc
new file mode 100644
index 00000000000..f7800758b4b
--- /dev/null
+++ b/src/third_party/s2/s1angle_test.cc
@@ -0,0 +1,173 @@
+// Copyright 2005 Google Inc. All Rights Reserved.
+
+#include "s1angle.h"
+
+#include <sstream>
+
+#include "base/commandlineflags.h"
+#include "base/integral_types.h"
+#include "base/logging.h"
+#include "gtest/gtest.h"
+#include "s2latlng.h"
+#include "s2testing.h"
+
+using namespace std;
+
+DEFINE_int32(iters, (DEBUG_MODE ? 100 : 1000) * (1000 * 1000),
+ "Run timing tests with this many iterations");
+
+TEST(S1Angle, DefaultConstructor) {
+ // Check that the default constructor returns an angle of 0.
+ S1Angle a;
+ EXPECT_EQ(0, a.radians());
+}
+
+TEST(S1Angle, PiRadiansExactly180Degrees) {
+ // Check that the conversion between Pi radians and 180 degrees is exact.
+ EXPECT_EQ(M_PI, S1Angle::Radians(M_PI).radians());
+ EXPECT_EQ(180.0, S1Angle::Radians(M_PI).degrees());
+ EXPECT_EQ(M_PI, S1Angle::Degrees(180).radians());
+ EXPECT_EQ(180.0, S1Angle::Degrees(180).degrees());
+
+ EXPECT_EQ(90.0, S1Angle::Radians(M_PI_2).degrees());
+
+ // Check negative angles.
+ EXPECT_EQ(-90.0, S1Angle::Radians(-M_PI_2).degrees());
+ EXPECT_EQ(-M_PI_4, S1Angle::Degrees(-45).radians());
+}
+
+TEST(S1Angle, E5E6E7Representations) {
+ // Check that E5/E6/E7 representations work as expected.
+ EXPECT_DOUBLE_EQ(S1Angle::Degrees(-45).radians(),
+ S1Angle::E5(-4500000).radians());
+ EXPECT_DOUBLE_EQ(S1Angle::Degrees(-60).radians(),
+ S1Angle::E6(-60000000).radians());
+ EXPECT_DOUBLE_EQ(S1Angle::Degrees(75).radians(),
+ S1Angle::E7(750000000).radians());
+ EXPECT_EQ(-17256123, S1Angle::Degrees(-172.56123).e5());
+ EXPECT_EQ(12345678, S1Angle::Degrees(12.345678).e6());
+ EXPECT_EQ(-123456789, S1Angle::Degrees(-12.3456789).e7());
+}
+
+TEST(S1Angle, E6E7RepresentationsUnsigned) {
+ // Check that unsigned E6/E7 representations work as expected.
+ EXPECT_DOUBLE_EQ(
+ S1Angle::Degrees(60).radians(),
+ S1Angle::UnsignedE6(static_cast<uint32>(60000000)).radians());
+ EXPECT_DOUBLE_EQ(
+ S1Angle::Degrees(-60).radians(),
+ S1Angle::UnsignedE6(static_cast<uint32>(-60000000)).radians());
+ EXPECT_DOUBLE_EQ(
+ S1Angle::Degrees(75).radians(),
+ S1Angle::UnsignedE7(static_cast<uint32>(750000000)).radians());
+ EXPECT_DOUBLE_EQ(
+ S1Angle::Degrees(-75).radians(),
+ S1Angle::UnsignedE7(static_cast<uint32>(-750000000)).radians());
+}
+
+TEST(S1Angle, NormalizeCorrectlyCanonicalizesAngles) {
+ EXPECT_DOUBLE_EQ(0.0, S1Angle::Degrees(360.0).Normalized().degrees());
+ EXPECT_DOUBLE_EQ(180.0, S1Angle::Degrees(-180.0).Normalized().degrees());
+ EXPECT_DOUBLE_EQ(180.0, S1Angle::Degrees(180.0).Normalized().degrees());
+ EXPECT_DOUBLE_EQ(180.0, S1Angle::Degrees(540.0).Normalized().degrees());
+ EXPECT_DOUBLE_EQ(90.0, S1Angle::Degrees(-270.0).Normalized().degrees());
+}
+
+TEST(S1Angle, ArithmeticOperationsOnAngles) {
+ EXPECT_DOUBLE_EQ(0.3, S1Angle::Radians(-0.3).abs().radians());
+ EXPECT_DOUBLE_EQ(-0.1, (-S1Angle::Radians(0.1)).radians());
+ EXPECT_DOUBLE_EQ(0.4,
+ (S1Angle::Radians(0.1) + S1Angle::Radians(0.3)).radians());
+ EXPECT_DOUBLE_EQ(-0.2,
+ (S1Angle::Radians(0.1) - S1Angle::Radians(0.3)).radians());
+ EXPECT_DOUBLE_EQ(0.6, (2 * S1Angle::Radians(0.3)).radians());
+ EXPECT_DOUBLE_EQ(0.6, (S1Angle::Radians(0.3) * 2).radians());
+ EXPECT_DOUBLE_EQ(0.15, (S1Angle::Radians(0.3) / 2).radians());
+ EXPECT_DOUBLE_EQ(0.5, (S1Angle::Radians(0.3) / S1Angle::Radians(0.6)));
+
+ S1Angle tmp = S1Angle::Radians(1.0);
+ tmp += S1Angle::Radians(0.5);
+ EXPECT_DOUBLE_EQ(1.5, tmp.radians());
+ tmp -= S1Angle::Radians(1.0);
+ EXPECT_DOUBLE_EQ(0.5, tmp.radians());
+ tmp *= 5;
+ EXPECT_DOUBLE_EQ(2.5, tmp.radians());
+ tmp /= 2;
+ EXPECT_DOUBLE_EQ(1.25, tmp.radians());
+}
+
+TEST(S1Angle, ConstructorsThatMeasureAngles) {
+ EXPECT_DOUBLE_EQ(M_PI_2,
+ S1Angle(S2Point(1, 0, 0), S2Point(0, 0, 2)).radians());
+ EXPECT_DOUBLE_EQ(0.0, S1Angle(S2Point(1, 0, 0), S2Point(1, 0, 0)).radians());
+ EXPECT_NEAR(50.0,
+ S1Angle(S2LatLng::FromDegrees(20, 20),
+ S2LatLng::FromDegrees(70, 20)).degrees(),
+ 1e-13);
+}
+
+TEST(S1Angle, TestFormatting) {
+ ostringstream ss;
+ ss << S1Angle::Degrees(180.0);
+ EXPECT_EQ("180.0000000", ss.str());
+}
+
+TEST(S1Angle, TestPerformance) {
+ // Verify that the conversion to E5/E6/E7 is not much slower than the
+ // conversion from E5/E6/E7. (Float-to-integer conversions can be quite
+ // slow on some platforms.) We only check the times for E6; the times for
+ // E5/E7 should be similar.
+
+ // To reduce the impact of loop overhead, we do kOpsPerLoop ops per loop.
+ static const int kOpsPerLoop = 8;
+
+ // Time conversion from E6 to radians.
+ double rad_sum = 0;
+ const double from_e6_start = S2Testing::GetCpuTime();
+ for (int i = FLAGS_iters; i > 0; i -= kOpsPerLoop) {
+ // We structure both loops so that all the conversions can be done in
+ // parallel. Otherwise on some platforms the optimizer happens to do a
+ // much better job of parallelizing one loop than the other.
+ double r0 = S1Angle::E6(i-0).radians();
+ double r1 = S1Angle::E6(i-1).radians();
+ double r2 = S1Angle::E6(i-2).radians();
+ double r3 = S1Angle::E6(i-3).radians();
+ double r4 = S1Angle::E6(i-4).radians();
+ double r5 = S1Angle::E6(i-5).radians();
+ double r6 = S1Angle::E6(i-6).radians();
+ double r7 = S1Angle::E6(i-7).radians();
+ rad_sum += ((r0 + r1) + (r2 + r3)) + ((r4 + r5) + (r6 + r7));
+ }
+ const double from_e6_time = S2Testing::GetCpuTime() - from_e6_start;
+ EXPECT_NE(rad_sum, 0); // Don't let the sum get optimized away.
+ LOG(INFO) << "From E6: "
+ << (FLAGS_iters / from_e6_time)
+ << " values per second";
+
+ // Time conversion from radians to E6.
+ const double delta = (2 * M_PI) / (FLAGS_iters - 1);
+ double angle = -M_PI;
+ long e6_sum = 0;
+ const double to_e6_start = S2Testing::GetCpuTime();
+ for (int i = FLAGS_iters; i > 0; i -= kOpsPerLoop) {
+ long r0 = S1Angle::Radians(angle).e6(); angle += delta;
+ long r1 = S1Angle::Radians(angle).e6(); angle += delta;
+ long r2 = S1Angle::Radians(angle).e6(); angle += delta;
+ long r3 = S1Angle::Radians(angle).e6(); angle += delta;
+ long r4 = S1Angle::Radians(angle).e6(); angle += delta;
+ long r5 = S1Angle::Radians(angle).e6(); angle += delta;
+ long r6 = S1Angle::Radians(angle).e6(); angle += delta;
+ long r7 = S1Angle::Radians(angle).e6(); angle += delta;
+ e6_sum += ((r0 + r1) + (r2 + r3)) + ((r4 + r5) + (r6 + r7));
+ }
+ const double to_e6_time = S2Testing::GetCpuTime() - to_e6_start;
+ EXPECT_NE(e6_sum + angle, 0); // Don't let them get optimized away.
+ LOG(INFO) << " To E6: "
+ << (FLAGS_iters / to_e6_time)
+ << " values per second";
+
+ // Make sure that the To/From E6 times are not much different.
+ // The difference factor slightly less than 2 on an x86_64.
+ EXPECT_LE(from_e6_time / to_e6_time, 3);
+ EXPECT_LE(to_e6_time / from_e6_time, 3);
+}
diff --git a/src/third_party/s2/s1interval.cc b/src/third_party/s2/s1interval.cc
new file mode 100644
index 00000000000..bf676e96482
--- /dev/null
+++ b/src/third_party/s2/s1interval.cc
@@ -0,0 +1,250 @@
+// Copyright 2005 Google Inc. All Rights Reserved.
+
+#include "s1interval.h"
+
+#include "base/logging.h"
+
+S1Interval S1Interval::FromPoint(double p) {
+ if (p == -M_PI) p = M_PI;
+ return S1Interval(p, p, ARGS_CHECKED);
+}
+
+double S1Interval::GetCenter() const {
+ double center = 0.5 * (lo() + hi());
+ if (!is_inverted()) return center;
+ // Return the center in the range (-Pi, Pi].
+ return (center <= 0) ? (center + M_PI) : (center - M_PI);
+}
+
+double S1Interval::GetLength() const {
+ double length = hi() - lo();
+ if (length >= 0) return length;
+ length += 2 * M_PI;
+ // Empty intervals have a negative length.
+ return (length > 0) ? length : -1;
+}
+
+S1Interval S1Interval::Complement() const {
+ if (lo() == hi()) return Full(); // Singleton.
+ return S1Interval(hi(), lo(), ARGS_CHECKED); // Handles empty and full.
+}
+
+double S1Interval::GetComplementCenter() const {
+ if (lo() != hi()) {
+ return Complement().GetCenter();
+ } else { // Singleton.
+ return (hi() <= 0) ? (hi() + M_PI) : (hi() - M_PI);
+ }
+}
+
+bool S1Interval::FastContains(double p) const {
+ if (is_inverted()) {
+ return (p >= lo() || p <= hi()) && !is_empty();
+ } else {
+ return p >= lo() && p <= hi();
+ }
+}
+
+bool S1Interval::Contains(double p) const {
+ // Works for empty, full, and singleton intervals.
+ DCHECK_LE(fabs(p), M_PI);
+ if (p == -M_PI) p = M_PI;
+ return FastContains(p);
+}
+
+bool S1Interval::InteriorContains(double p) const {
+ // Works for empty, full, and singleton intervals.
+ DCHECK_LE(fabs(p), M_PI);
+ if (p == -M_PI) p = M_PI;
+
+ if (is_inverted()) {
+ return p > lo() || p < hi();
+ } else {
+ return (p > lo() && p < hi()) || is_full();
+ }
+}
+
+bool S1Interval::Contains(S1Interval const& y) const {
+ // It might be helpful to compare the structure of these tests to
+ // the simpler Contains(double) method above.
+
+ if (is_inverted()) {
+ if (y.is_inverted()) return y.lo() >= lo() && y.hi() <= hi();
+ return (y.lo() >= lo() || y.hi() <= hi()) && !is_empty();
+ } else {
+ if (y.is_inverted()) return is_full() || y.is_empty();
+ return y.lo() >= lo() && y.hi() <= hi();
+ }
+}
+
+bool S1Interval::InteriorContains(S1Interval const& y) const {
+ if (is_inverted()) {
+ if (!y.is_inverted()) return y.lo() > lo() || y.hi() < hi();
+ return (y.lo() > lo() && y.hi() < hi()) || y.is_empty();
+ } else {
+ if (y.is_inverted()) return is_full() || y.is_empty();
+ return (y.lo() > lo() && y.hi() < hi()) || is_full();
+ }
+}
+
+bool S1Interval::Intersects(S1Interval const& y) const {
+ if (is_empty() || y.is_empty()) return false;
+ if (is_inverted()) {
+ // Every non-empty inverted interval contains Pi.
+ return y.is_inverted() || y.lo() <= hi() || y.hi() >= lo();
+ } else {
+ if (y.is_inverted()) return y.lo() <= hi() || y.hi() >= lo();
+ return y.lo() <= hi() && y.hi() >= lo();
+ }
+}
+
+bool S1Interval::InteriorIntersects(S1Interval const& y) const {
+ if (is_empty() || y.is_empty() || lo() == hi()) return false;
+ if (is_inverted()) {
+ return y.is_inverted() || y.lo() < hi() || y.hi() > lo();
+ } else {
+ if (y.is_inverted()) return y.lo() < hi() || y.hi() > lo();
+ return (y.lo() < hi() && y.hi() > lo()) || is_full();
+ }
+}
+
+inline static double PositiveDistance(double a, double b) {
+ // Compute the distance from "a" to "b" in the range [0, 2*Pi).
+ // This is equivalent to (drem(b - a - M_PI, 2 * M_PI) + M_PI),
+ // except that it is more numerically stable (it does not lose
+ // precision for very small positive distances).
+ double d = b - a;
+ if (d >= 0) return d;
+ // We want to ensure that if b == Pi and a == (-Pi + eps),
+ // the return result is approximately 2*Pi and not zero.
+ return (b + M_PI) - (a - M_PI);
+}
+
+double S1Interval::GetDirectedHausdorffDistance(S1Interval const& y) const {
+ if (y.Contains(*this)) return 0.0; // this includes the case *this is empty
+ if (y.is_empty()) return M_PI; // maximum possible distance on S1
+
+ double y_complement_center = y.GetComplementCenter();
+ if (Contains(y_complement_center)) {
+ return PositiveDistance(y.hi(), y_complement_center);
+ } else {
+ // The Hausdorff distance is realized by either two hi() endpoints or two
+ // lo() endpoints, whichever is farther apart.
+ double hi_hi = S1Interval(y.hi(), y_complement_center).Contains(hi()) ?
+ PositiveDistance(y.hi(), hi()) : 0;
+ double lo_lo = S1Interval(y_complement_center, y.lo()).Contains(lo()) ?
+ PositiveDistance(lo(), y.lo()) : 0;
+ DCHECK(hi_hi > 0 || lo_lo > 0);
+ return max(hi_hi, lo_lo);
+ }
+}
+
+void S1Interval::AddPoint(double p) {
+ DCHECK_LE(fabs(p), M_PI);
+ if (p == -M_PI) p = M_PI;
+
+ if (FastContains(p)) return;
+ if (is_empty()) {
+ set_hi(p);
+ set_lo(p);
+ } else {
+ // Compute distance from p to each endpoint.
+ double dlo = PositiveDistance(p, lo());
+ double dhi = PositiveDistance(hi(), p);
+ if (dlo < dhi) {
+ set_lo(p);
+ } else {
+ set_hi(p);
+ }
+ // Adding a point can never turn a non-full interval into a full one.
+ }
+}
+
+S1Interval S1Interval::FromPointPair(double p1, double p2) {
+ DCHECK_LE(fabs(p1), M_PI);
+ DCHECK_LE(fabs(p2), M_PI);
+ if (p1 == -M_PI) p1 = M_PI;
+ if (p2 == -M_PI) p2 = M_PI;
+ if (PositiveDistance(p1, p2) <= M_PI) {
+ return S1Interval(p1, p2, ARGS_CHECKED);
+ } else {
+ return S1Interval(p2, p1, ARGS_CHECKED);
+ }
+}
+
+S1Interval S1Interval::Expanded(double radius) const {
+ DCHECK_GE(radius, 0);
+ if (is_empty()) return *this;
+
+ // Check whether this interval will be full after expansion, allowing
+ // for a 1-bit rounding error when computing each endpoint.
+ if (GetLength() + 2 * radius >= 2 * M_PI - 1e-15) return Full();
+
+ S1Interval result(drem(lo() - radius, 2*M_PI), drem(hi() + radius, 2*M_PI));
+ if (result.lo() <= -M_PI) result.set_lo(M_PI);
+ return result;
+}
+
+S1Interval S1Interval::Union(S1Interval const& y) const {
+ // The y.is_full() case is handled correctly in all cases by the code
+ // below, but can follow three separate code paths depending on whether
+ // this interval is inverted, is non-inverted but contains Pi, or neither.
+
+ if (y.is_empty()) return *this;
+ if (FastContains(y.lo())) {
+ if (FastContains(y.hi())) {
+ // Either this interval contains y, or the union of the two
+ // intervals is the Full() interval.
+ if (Contains(y)) return *this; // is_full() code path
+ return Full();
+ }
+ return S1Interval(lo(), y.hi(), ARGS_CHECKED);
+ }
+ if (FastContains(y.hi())) return S1Interval(y.lo(), hi(), ARGS_CHECKED);
+
+ // This interval contains neither endpoint of y. This means that either y
+ // contains all of this interval, or the two intervals are disjoint.
+ if (is_empty() || y.FastContains(lo())) return y;
+
+ // Check which pair of endpoints are closer together.
+ double dlo = PositiveDistance(y.hi(), lo());
+ double dhi = PositiveDistance(hi(), y.lo());
+ if (dlo < dhi) {
+ return S1Interval(y.lo(), hi(), ARGS_CHECKED);
+ } else {
+ return S1Interval(lo(), y.hi(), ARGS_CHECKED);
+ }
+}
+
+S1Interval S1Interval::Intersection(S1Interval const& y) const {
+ // The y.is_full() case is handled correctly in all cases by the code
+ // below, but can follow three separate code paths depending on whether
+ // this interval is inverted, is non-inverted but contains Pi, or neither.
+
+ if (y.is_empty()) return Empty();
+ if (FastContains(y.lo())) {
+ if (FastContains(y.hi())) {
+ // Either this interval contains y, or the region of intersection
+ // consists of two disjoint subintervals. In either case, we want
+ // to return the shorter of the two original intervals.
+ if (y.GetLength() < GetLength()) return y; // is_full() code path
+ return *this;
+ }
+ return S1Interval(y.lo(), hi(), ARGS_CHECKED);
+ }
+ if (FastContains(y.hi())) return S1Interval(lo(), y.hi(), ARGS_CHECKED);
+
+ // This interval contains neither endpoint of y. This means that either y
+ // contains all of this interval, or the two intervals are disjoint.
+
+ if (y.FastContains(lo())) return *this; // is_empty() okay here
+ DCHECK(!Intersects(y));
+ return Empty();
+}
+
+bool S1Interval::ApproxEquals(S1Interval const& y, double max_error) const {
+ if (is_empty()) return y.GetLength() <= max_error;
+ if (y.is_empty()) return GetLength() <= max_error;
+ return (fabs(drem(y.lo() - lo(), 2 * M_PI)) +
+ fabs(drem(y.hi() - hi(), 2 * M_PI))) <= max_error;
+}
diff --git a/src/third_party/s2/s1interval.h b/src/third_party/s2/s1interval.h
new file mode 100644
index 00000000000..6ab68cdf26e
--- /dev/null
+++ b/src/third_party/s2/s1interval.h
@@ -0,0 +1,224 @@
+// Copyright 2005 Google Inc. All Rights Reserved.
+
+#ifndef UTIL_GEOMETRY_S1INTERVAL_H_
+#define UTIL_GEOMETRY_S1INTERVAL_H_
+
+#include <iostream>
+using std::ostream;
+using std::cout;
+using std::endl;
+#include "base/definer.h"
+
+#include <math.h>
+#include "base/basictypes.h"
+#include "base/logging.h"
+#include "util/math/vector2-inl.h"
+
+// An S1Interval represents a closed interval on a unit circle (also known
+// as a 1-dimensional sphere). It is capable of representing the empty
+// interval (containing no points), the full interval (containing all
+// points), and zero-length intervals (containing a single point).
+//
+// Points are represented by the angle they make with the positive x-axis in
+// the range [-Pi, Pi]. An interval is represented by its lower and upper
+// bounds (both inclusive, since the interval is closed). The lower bound may
+// be greater than the upper bound, in which case the interval is "inverted"
+// (i.e. it passes through the point (-1, 0)).
+//
+// Note that the point (-1, 0) has two valid representations, Pi and -Pi.
+// The normalized representation of this point internally is Pi, so that
+// endpoints of normal intervals are in the range (-Pi, Pi]. However, we
+// take advantage of the point -Pi to construct two special intervals:
+// the Full() interval is [-Pi, Pi], and the Empty() interval is [Pi, -Pi].
+//
+// This class is intended to be copied by value as desired. It uses
+// the default copy constructor and assignment operator.
+class S1Interval {
+ public:
+ // Constructor. Both endpoints must be in the range -Pi to Pi inclusive.
+ // The value -Pi is converted internally to Pi except for the Full()
+ // and Empty() intervals.
+ inline S1Interval(double lo, double hi);
+
+ // The default constructor creates an empty interval.
+ //
+ // Note: Don't construct an interval using the default constructor and
+ // set_lo()/set_hi(). If you need to set both endpoints, use the
+ // constructor above:
+ //
+ // lng_bounds_ = S1Interval(lng_lo, lng_hi);
+ inline S1Interval();
+
+ // Returns the empty interval.
+ static inline S1Interval Empty();
+
+ // Returns the full interval.
+ static inline S1Interval Full();
+
+ // Convenience method to construct an interval containing a single point.
+ static S1Interval FromPoint(double p);
+
+ // Convenience method to construct the minimal interval containing
+ // the two given points. This is equivalent to starting with an empty
+ // interval and calling AddPoint() twice, but it is more efficient.
+ static S1Interval FromPointPair(double p1, double p2);
+
+ double lo() const { return bounds_[0]; }
+ double hi() const { return bounds_[1]; }
+ double bound(int i) const { return bounds_[i]; }
+ Vector2_d const& bounds() const { return bounds_; }
+
+ // Methods to modify one endpoint of an existing S1Interval. Requires that
+ // the resulting S1Interval is valid. This implies you cannot call this
+ // method on an Empty() or Full() interval, since these intervals do not
+ // have any endpoints.
+ //
+ // Do not use these methods if you want to replace both endpoints of the
+ // interval; use a constructor instead. For example:
+ //
+ // *lng_bounds = S1Interval(lng_lo, lng_hi);
+ void set_lo(double p) { bounds_[0] = p; DCHECK(is_valid()); }
+ void set_hi(double p) { bounds_[1] = p; DCHECK(is_valid()); }
+
+ // An interval is valid if neither bound exceeds Pi in absolute value,
+ // and the value -Pi appears only in the Empty() and Full() intervals.
+ inline bool is_valid() const;
+
+ // Return true if the interval contains all points on the unit circle.
+ bool is_full() const { return hi() - lo() == 2 * M_PI; }
+
+ // Return true if the interval is empty, i.e. it contains no points.
+ bool is_empty() const { return lo() - hi() == 2 * M_PI; }
+
+ // Return true if lo() > hi(). (This is true for empty intervals.)
+ bool is_inverted() const { return lo() > hi(); }
+
+ // Return the midpoint of the interval. For full and empty intervals,
+ // the result is arbitrary.
+ double GetCenter() const;
+
+ // Return the length of the interval. The length of an empty interval
+ // is negative.
+ double GetLength() const;
+
+ // Return the complement of the interior of the interval. An interval and
+ // its complement have the same boundary but do not share any interior
+ // values. The complement operator is not a bijection, since the complement
+ // of a singleton interval (containing a single value) is the same as the
+ // complement of an empty interval.
+ S1Interval Complement() const;
+
+ // Return the midpoint of the complement of the interval. For full and empty
+ // intervals, the result is arbitrary. For a singleton interval (containing a
+ // single point), the result is its antipodal point on S1.
+ double GetComplementCenter() const;
+
+ // Return true if the interval (which is closed) contains the point 'p'.
+ bool Contains(double p) const;
+
+ // Return true if the interior of the interval contains the point 'p'.
+ bool InteriorContains(double p) const;
+
+ // Return true if the interval contains the given interval 'y'.
+ // Works for empty, full, and singleton intervals.
+ bool Contains(S1Interval const& y) const;
+
+ // Returns true if the interior of this interval contains the entire
+ // interval 'y'. Note that x.InteriorContains(x) is true only when
+ // x is the empty or full interval, and x.InteriorContains(S1Interval(p,p))
+ // is equivalent to x.InteriorContains(p).
+ bool InteriorContains(S1Interval const& y) const;
+
+ // Return true if the two intervals contain any points in common.
+ // Note that the point +/-Pi has two representations, so the intervals
+ // [-Pi,-3] and [2,Pi] intersect, for example.
+ bool Intersects(S1Interval const& y) const;
+
+ // Return true if the interior of this interval contains any point of the
+ // interval 'y' (including its boundary). Works for empty, full, and
+ // singleton intervals.
+ bool InteriorIntersects(S1Interval const& y) const;
+
+ // Return the Hausdorff distance to the given interval 'y'. For two
+ // S1Intervals x and y, this distance is defined by
+ // h(x, y) = max_{p in x} min_{q in y} d(p, q),
+ // where d(.,.) is measured along S1.
+ double GetDirectedHausdorffDistance(S1Interval const& y) const;
+
+ // Expand the interval by the minimum amount necessary so that it
+ // contains the given point "p" (an angle in the range [-Pi, Pi]).
+ void AddPoint(double p);
+
+ // Return an interval that contains all points with a distance "radius" of a
+ // point in this interval. Note that the expansion of an empty interval is
+ // always empty. The radius must be non-negative.
+ S1Interval Expanded(double radius) const;
+
+ // Return the smallest interval that contains this interval and the
+ // given interval "y".
+ S1Interval Union(S1Interval const& y) const;
+
+ // Return the smallest interval that contains the intersection of this
+ // interval with "y". Note that the region of intersection may
+ // consist of two disjoint intervals.
+ S1Interval Intersection(S1Interval const& y) const;
+
+ // Return true if two intervals contains the same set of points.
+ inline bool operator==(S1Interval const& y) const;
+
+ // Return true if the length of the symmetric difference between the two
+ // intervals is at most the given tolerance.
+ bool ApproxEquals(S1Interval const& y, double max_error = 1e-15) const;
+
+ private:
+ enum ArgsChecked { ARGS_CHECKED };
+
+ // Internal constructor that assumes that both arguments are in the
+ // correct range, i.e. normalization from -Pi to Pi is already done.
+ inline S1Interval(double lo, double hi, ArgsChecked dummy);
+
+ // Return true if the interval (which is closed) contains the point 'p'.
+ // Skips the normalization of 'p' from -Pi to Pi.
+ bool FastContains(double p) const;
+
+ Vector2_d bounds_;
+};
+DECLARE_POD(S1Interval);
+
+inline S1Interval::S1Interval(double lo, double hi) : bounds_(lo, hi) {
+ if (lo == -M_PI && hi != M_PI) set_lo(M_PI);
+ if (hi == -M_PI && lo != M_PI) set_hi(M_PI);
+ DCHECK(is_valid());
+}
+
+inline S1Interval::S1Interval(double lo, double hi, ArgsChecked dummy)
+ : bounds_(lo, hi) {
+ DCHECK(is_valid());
+}
+
+inline S1Interval::S1Interval() : bounds_(M_PI, -M_PI) {
+}
+
+inline S1Interval S1Interval::Empty() {
+ return S1Interval();
+}
+
+inline S1Interval S1Interval::Full() {
+ return S1Interval(-M_PI, M_PI, ARGS_CHECKED);
+}
+
+inline bool S1Interval::is_valid() const {
+ return (fabs(lo()) <= M_PI && fabs(hi()) <= M_PI &&
+ !(lo() == -M_PI && hi() != M_PI) &&
+ !(hi() == -M_PI && lo() != M_PI));
+}
+
+inline bool S1Interval::operator==(S1Interval const& y) const {
+ return lo() == y.lo() && hi() == y.hi();
+}
+
+inline ostream& operator<<(ostream& os, S1Interval const& x) {
+ return os << "[" << x.lo() << ", " << x.hi() << "]";
+}
+
+#endif // UTIL_GEOMETRY_S1INTERVAL_H_
diff --git a/src/third_party/s2/s1interval_test.cc b/src/third_party/s2/s1interval_test.cc
new file mode 100644
index 00000000000..0394bccc6a0
--- /dev/null
+++ b/src/third_party/s2/s1interval_test.cc
@@ -0,0 +1,371 @@
+// Copyright 2005 Google Inc. All Rights Reserved.
+
+#include "s1interval.h"
+#include "testing/base/public/gunit.h"
+
+class S1IntervalTestBase : public testing::Test {
+ public:
+ // Create some standard intervals to use in the tests. These include the
+ // empty and full intervals, intervals containing a single point, and
+ // intervals spanning one or more "quadrants" which are numbered as follows:
+ // quad1 == [0, Pi/2]
+ // quad2 == [Pi/2, Pi]
+ // quad3 == [-Pi, -Pi/2]
+ // quad4 == [-Pi/2, 0]
+ S1IntervalTestBase()
+ : empty(S1Interval::Empty()),
+ full(S1Interval::Full()),
+ // Single-point intervals:
+ zero(0, 0),
+ pi2(M_PI_2, M_PI_2),
+ pi(M_PI, M_PI),
+ mipi(-M_PI, -M_PI), // Same as "pi" after normalization.
+ mipi2(-M_PI_2, -M_PI_2),
+ // Single quadrants:
+ quad1(0, M_PI_2),
+ quad2(M_PI_2, -M_PI),
+ quad3(M_PI, -M_PI_2),
+ quad4(-M_PI_2, 0),
+ // Quadrant pairs:
+ quad12(0, -M_PI),
+ quad23(M_PI_2, -M_PI_2),
+ quad34(-M_PI, 0),
+ quad41(-M_PI_2, M_PI_2),
+ // Quadrant triples:
+ quad123(0, -M_PI_2),
+ quad234(M_PI_2, 0),
+ quad341(M_PI, M_PI_2),
+ quad412(-M_PI_2, -M_PI),
+ // Small intervals around the midpoints between quadrants, such that
+ // the center of each interval is offset slightly CCW from the midpoint.
+ mid12(M_PI_2 - 0.01, M_PI_2 + 0.02),
+ mid23(M_PI - 0.01, -M_PI + 0.02),
+ mid34(-M_PI_2 - 0.01, -M_PI_2 + 0.02),
+ mid41(-0.01, 0.02) {
+ }
+
+ protected:
+ const S1Interval empty, full;
+ const S1Interval zero, pi2, pi, mipi, mipi2;
+ const S1Interval quad1, quad2, quad3, quad4;
+ const S1Interval quad12, quad23, quad34, quad41;
+ const S1Interval quad123, quad234, quad341, quad412;
+ const S1Interval mid12, mid23, mid34, mid41;
+};
+
+TEST_F(S1IntervalTestBase, ConstructorsAndAccessors) {
+ // Spot-check the constructors and accessors.
+ EXPECT_EQ(quad12.lo(), 0);
+ EXPECT_EQ(quad12.hi(), M_PI);
+ EXPECT_EQ(quad34.bound(0), M_PI);
+ EXPECT_EQ(quad34.bound(1), 0);
+ EXPECT_EQ(pi.lo(), M_PI);
+ EXPECT_EQ(pi.hi(), M_PI);
+
+ // Check that [-Pi, -Pi] is normalized to [Pi, Pi].
+ EXPECT_EQ(mipi.lo(), M_PI);
+ EXPECT_EQ(mipi.hi(), M_PI);
+ EXPECT_EQ(quad23.lo(), M_PI_2);
+ EXPECT_EQ(quad23.hi(), -M_PI_2);
+
+ // Check that the default S1Interval is identical to Empty().
+ S1Interval default_empty;
+ EXPECT_TRUE(default_empty.is_valid());
+ EXPECT_TRUE(default_empty.is_empty());
+ EXPECT_EQ(empty.lo(), default_empty.lo());
+ EXPECT_EQ(empty.hi(), default_empty.hi());
+
+ // Check that intervals can be modified.
+ S1Interval r(0, 0);
+ r.set_hi(M_PI_2);
+ EXPECT_EQ(r.hi(), M_PI_2);
+}
+
+TEST_F(S1IntervalTestBase, SimplePredicates) {
+ // is_valid(), is_empty(), is_full(), is_inverted()
+ EXPECT_TRUE(zero.is_valid() && !zero.is_empty() && !zero.is_full());
+ EXPECT_TRUE(empty.is_valid() && empty.is_empty() && !empty.is_full());
+ EXPECT_TRUE(empty.is_inverted());
+ EXPECT_TRUE(full.is_valid() && !full.is_empty() && full.is_full());
+ EXPECT_TRUE(!quad12.is_empty() && !quad12.is_full() && !quad12.is_inverted());
+ EXPECT_TRUE(!quad23.is_empty() && !quad23.is_full() && quad23.is_inverted());
+ EXPECT_TRUE(pi.is_valid() && !pi.is_empty() && !pi.is_inverted());
+ EXPECT_TRUE(mipi.is_valid() && !mipi.is_empty() && !mipi.is_inverted());
+}
+
+TEST_F(S1IntervalTestBase, GetCenter) {
+ EXPECT_EQ(quad12.GetCenter(), M_PI_2);
+ EXPECT_DOUBLE_EQ(S1Interval(3.1, 2.9).GetCenter(), 3.0 - M_PI);
+ EXPECT_DOUBLE_EQ(S1Interval(-2.9, -3.1).GetCenter(), M_PI - 3.0);
+ EXPECT_DOUBLE_EQ(S1Interval(2.1, -2.1).GetCenter(), M_PI);
+ EXPECT_EQ(pi.GetCenter(), M_PI);
+ EXPECT_EQ(mipi.GetCenter(), M_PI);
+ EXPECT_EQ(fabs(quad23.GetCenter()), M_PI);
+ EXPECT_DOUBLE_EQ(quad123.GetCenter(), 0.75 * M_PI);
+}
+
+TEST_F(S1IntervalTestBase, GetLength) {
+ EXPECT_EQ(quad12.GetLength(), M_PI);
+ EXPECT_EQ(pi.GetLength(), 0);
+ EXPECT_EQ(mipi.GetLength(), 0);
+ EXPECT_DOUBLE_EQ(quad123.GetLength(), 1.5 * M_PI);
+ EXPECT_EQ(fabs(quad23.GetLength()), M_PI);
+ EXPECT_EQ(full.GetLength(), 2 * M_PI);
+ EXPECT_LT(empty.GetLength(), 0);
+}
+
+TEST_F(S1IntervalTestBase, Complement) {
+ EXPECT_TRUE(empty.Complement().is_full());
+ EXPECT_TRUE(full.Complement().is_empty());
+ EXPECT_TRUE(pi.Complement().is_full());
+ EXPECT_TRUE(mipi.Complement().is_full());
+ EXPECT_TRUE(zero.Complement().is_full());
+ EXPECT_TRUE(quad12.Complement().ApproxEquals(quad34));
+ EXPECT_TRUE(quad34.Complement().ApproxEquals(quad12));
+ EXPECT_TRUE(quad123.Complement().ApproxEquals(quad4));
+}
+
+TEST_F(S1IntervalTestBase, Contains) {
+ // Contains(double), InteriorContains(double)
+ EXPECT_TRUE(!empty.Contains(0) && !empty.Contains(M_PI) &&
+ !empty.Contains(-M_PI));
+ EXPECT_TRUE(!empty.InteriorContains(M_PI) && !empty.InteriorContains(-M_PI));
+ EXPECT_TRUE(full.Contains(0) && full.Contains(M_PI) && full.Contains(-M_PI));
+ EXPECT_TRUE(full.InteriorContains(M_PI) && full.InteriorContains(-M_PI));
+ EXPECT_TRUE(quad12.Contains(0) && quad12.Contains(M_PI) &&
+ quad12.Contains(-M_PI));
+ EXPECT_TRUE(quad12.InteriorContains(M_PI_2) && !quad12.InteriorContains(0));
+ EXPECT_TRUE(!quad12.InteriorContains(M_PI) &&
+ !quad12.InteriorContains(-M_PI));
+ EXPECT_TRUE(quad23.Contains(M_PI_2) && quad23.Contains(-M_PI_2));
+ EXPECT_TRUE(quad23.Contains(M_PI) && quad23.Contains(-M_PI));
+ EXPECT_TRUE(!quad23.Contains(0));
+ EXPECT_TRUE(!quad23.InteriorContains(M_PI_2) &&
+ !quad23.InteriorContains(-M_PI_2));
+ EXPECT_TRUE(quad23.InteriorContains(M_PI) && quad23.InteriorContains(-M_PI));
+ EXPECT_TRUE(!quad23.InteriorContains(0));
+ EXPECT_TRUE(pi.Contains(M_PI) && pi.Contains(-M_PI) && !pi.Contains(0));
+ EXPECT_TRUE(!pi.InteriorContains(M_PI) && !pi.InteriorContains(-M_PI));
+ EXPECT_TRUE(mipi.Contains(M_PI) && mipi.Contains(-M_PI) && !mipi.Contains(0));
+ EXPECT_TRUE(!mipi.InteriorContains(M_PI) && !mipi.InteriorContains(-M_PI));
+ EXPECT_TRUE(zero.Contains(0) && !zero.InteriorContains(0));
+}
+
+static void TestIntervalOps(S1Interval const& x, S1Interval const& y,
+ const char* expected_relation,
+ S1Interval const& expected_union,
+ S1Interval const& expected_intersection) {
+ // Test all of the interval operations on the given pair of intervals.
+ // "expected_relation" is a sequence of "T" and "F" characters corresponding
+ // to the expected results of Contains(), InteriorContains(), Intersects(),
+ // and InteriorIntersects() respectively.
+
+ EXPECT_EQ(x.Contains(y), expected_relation[0] == 'T');
+ EXPECT_EQ(x.InteriorContains(y), expected_relation[1] == 'T');
+ EXPECT_EQ(x.Intersects(y), expected_relation[2] == 'T');
+ EXPECT_EQ(x.InteriorIntersects(y), expected_relation[3] == 'T');
+
+ // bounds() returns a const reference to a member variable, so we need to
+ // make a copy when invoking it on a temporary object.
+ EXPECT_EQ(Vector2_d(x.Union(y).bounds()), expected_union.bounds());
+ EXPECT_EQ(Vector2_d(x.Intersection(y).bounds()),
+ expected_intersection.bounds());
+
+ EXPECT_EQ(x.Contains(y), x.Union(y) == x);
+ EXPECT_EQ(x.Intersects(y), !x.Intersection(y).is_empty());
+
+ if (y.lo() == y.hi()) {
+ S1Interval r = x;
+ r.AddPoint(y.lo());
+ EXPECT_EQ(r.bounds(), expected_union.bounds());
+ }
+}
+
+TEST_F(S1IntervalTestBase, IntervalOps) {
+ // Contains(S1Interval), InteriorContains(S1Interval),
+ // Intersects(), InteriorIntersects(), Union(), Intersection()
+ TestIntervalOps(empty, empty, "TTFF", empty, empty);
+ TestIntervalOps(empty, full, "FFFF", full, empty);
+ TestIntervalOps(empty, zero, "FFFF", zero, empty);
+ TestIntervalOps(empty, pi, "FFFF", pi, empty);
+ TestIntervalOps(empty, mipi, "FFFF", mipi, empty);
+
+ TestIntervalOps(full, empty, "TTFF", full, empty);
+ TestIntervalOps(full, full, "TTTT", full, full);
+ TestIntervalOps(full, zero, "TTTT", full, zero);
+ TestIntervalOps(full, pi, "TTTT", full, pi);
+ TestIntervalOps(full, mipi, "TTTT", full, mipi);
+ TestIntervalOps(full, quad12, "TTTT", full, quad12);
+ TestIntervalOps(full, quad23, "TTTT", full, quad23);
+
+ TestIntervalOps(zero, empty, "TTFF", zero, empty);
+ TestIntervalOps(zero, full, "FFTF", full, zero);
+ TestIntervalOps(zero, zero, "TFTF", zero, zero);
+ TestIntervalOps(zero, pi, "FFFF", S1Interval(0, M_PI), empty);
+ TestIntervalOps(zero, pi2, "FFFF", quad1, empty);
+ TestIntervalOps(zero, mipi, "FFFF", quad12, empty);
+ TestIntervalOps(zero, mipi2, "FFFF", quad4, empty);
+ TestIntervalOps(zero, quad12, "FFTF", quad12, zero);
+ TestIntervalOps(zero, quad23, "FFFF", quad123, empty);
+
+ TestIntervalOps(pi2, empty, "TTFF", pi2, empty);
+ TestIntervalOps(pi2, full, "FFTF", full, pi2);
+ TestIntervalOps(pi2, zero, "FFFF", quad1, empty);
+ TestIntervalOps(pi2, pi, "FFFF", S1Interval(M_PI_2, M_PI), empty);
+ TestIntervalOps(pi2, pi2, "TFTF", pi2, pi2);
+ TestIntervalOps(pi2, mipi, "FFFF", quad2, empty);
+ TestIntervalOps(pi2, mipi2, "FFFF", quad23, empty);
+ TestIntervalOps(pi2, quad12, "FFTF", quad12, pi2);
+ TestIntervalOps(pi2, quad23, "FFTF", quad23, pi2);
+
+ TestIntervalOps(pi, empty, "TTFF", pi, empty);
+ TestIntervalOps(pi, full, "FFTF", full, pi);
+ TestIntervalOps(pi, zero, "FFFF", S1Interval(M_PI, 0), empty);
+ TestIntervalOps(pi, pi, "TFTF", pi, pi);
+ TestIntervalOps(pi, pi2, "FFFF", S1Interval(M_PI_2, M_PI), empty);
+ TestIntervalOps(pi, mipi, "TFTF", pi, pi);
+ TestIntervalOps(pi, mipi2, "FFFF", quad3, empty);
+ TestIntervalOps(pi, quad12, "FFTF", S1Interval(0, M_PI), pi);
+ TestIntervalOps(pi, quad23, "FFTF", quad23, pi);
+
+ TestIntervalOps(mipi, empty, "TTFF", mipi, empty);
+ TestIntervalOps(mipi, full, "FFTF", full, mipi);
+ TestIntervalOps(mipi, zero, "FFFF", quad34, empty);
+ TestIntervalOps(mipi, pi, "TFTF", mipi, mipi);
+ TestIntervalOps(mipi, pi2, "FFFF", quad2, empty);
+ TestIntervalOps(mipi, mipi, "TFTF", mipi, mipi);
+ TestIntervalOps(mipi, mipi2, "FFFF", S1Interval(-M_PI, -M_PI_2), empty);
+ TestIntervalOps(mipi, quad12, "FFTF", quad12, mipi);
+ TestIntervalOps(mipi, quad23, "FFTF", quad23, mipi);
+
+ TestIntervalOps(quad12, empty, "TTFF", quad12, empty);
+ TestIntervalOps(quad12, full, "FFTT", full, quad12);
+ TestIntervalOps(quad12, zero, "TFTF", quad12, zero);
+ TestIntervalOps(quad12, pi, "TFTF", quad12, pi);
+ TestIntervalOps(quad12, mipi, "TFTF", quad12, mipi);
+ TestIntervalOps(quad12, quad12, "TFTT", quad12, quad12);
+ TestIntervalOps(quad12, quad23, "FFTT", quad123, quad2);
+ TestIntervalOps(quad12, quad34, "FFTF", full, quad12);
+
+ TestIntervalOps(quad23, empty, "TTFF", quad23, empty);
+ TestIntervalOps(quad23, full, "FFTT", full, quad23);
+ TestIntervalOps(quad23, zero, "FFFF", quad234, empty);
+ TestIntervalOps(quad23, pi, "TTTT", quad23, pi);
+ TestIntervalOps(quad23, mipi, "TTTT", quad23, mipi);
+ TestIntervalOps(quad23, quad12, "FFTT", quad123, quad2);
+ TestIntervalOps(quad23, quad23, "TFTT", quad23, quad23);
+ TestIntervalOps(quad23, quad34, "FFTT", quad234, S1Interval(-M_PI, -M_PI_2));
+
+ TestIntervalOps(quad1, quad23, "FFTF", quad123, S1Interval(M_PI_2, M_PI_2));
+ TestIntervalOps(quad2, quad3, "FFTF", quad23, mipi);
+ TestIntervalOps(quad3, quad2, "FFTF", quad23, pi);
+ TestIntervalOps(quad2, pi, "TFTF", quad2, pi);
+ TestIntervalOps(quad2, mipi, "TFTF", quad2, mipi);
+ TestIntervalOps(quad3, pi, "TFTF", quad3, pi);
+ TestIntervalOps(quad3, mipi, "TFTF", quad3, mipi);
+
+ TestIntervalOps(quad12, mid12, "TTTT", quad12, mid12);
+ TestIntervalOps(mid12, quad12, "FFTT", quad12, mid12);
+
+ S1Interval quad12eps(quad12.lo(), mid23.hi());
+ S1Interval quad2hi(mid23.lo(), quad12.hi());
+ TestIntervalOps(quad12, mid23, "FFTT", quad12eps, quad2hi);
+ TestIntervalOps(mid23, quad12, "FFTT", quad12eps, quad2hi);
+
+ // This test checks that the union of two disjoint intervals is the smallest
+ // interval that contains both of them. Note that the center of "mid34"
+ // slightly CCW of -Pi/2 so that there is no ambiguity about the result.
+ S1Interval quad412eps(mid34.lo(), quad12.hi());
+ TestIntervalOps(quad12, mid34, "FFFF", quad412eps, empty);
+ TestIntervalOps(mid34, quad12, "FFFF", quad412eps, empty);
+
+ S1Interval quadeps12(mid41.lo(), quad12.hi());
+ S1Interval quad1lo(quad12.lo(), mid41.hi());
+ TestIntervalOps(quad12, mid41, "FFTT", quadeps12, quad1lo);
+ TestIntervalOps(mid41, quad12, "FFTT", quadeps12, quad1lo);
+
+ S1Interval quad2lo(quad23.lo(), mid12.hi());
+ S1Interval quad3hi(mid34.lo(), quad23.hi());
+ S1Interval quadeps23(mid12.lo(), quad23.hi());
+ S1Interval quad23eps(quad23.lo(), mid34.hi());
+ S1Interval quadeps123(mid41.lo(), quad23.hi());
+ TestIntervalOps(quad23, mid12, "FFTT", quadeps23, quad2lo);
+ TestIntervalOps(mid12, quad23, "FFTT", quadeps23, quad2lo);
+ TestIntervalOps(quad23, mid23, "TTTT", quad23, mid23);
+ TestIntervalOps(mid23, quad23, "FFTT", quad23, mid23);
+ TestIntervalOps(quad23, mid34, "FFTT", quad23eps, quad3hi);
+ TestIntervalOps(mid34, quad23, "FFTT", quad23eps, quad3hi);
+ TestIntervalOps(quad23, mid41, "FFFF", quadeps123, empty);
+ TestIntervalOps(mid41, quad23, "FFFF", quadeps123, empty);
+}
+
+TEST_F(S1IntervalTestBase, AddPoint) {
+ S1Interval r = empty; r.AddPoint(0);
+ EXPECT_EQ(r, zero);
+ r = empty; r.AddPoint(M_PI);
+ EXPECT_EQ(r, pi);
+ r = empty; r.AddPoint(-M_PI);
+ EXPECT_EQ(r, mipi);
+ r = empty; r.AddPoint(M_PI); r.AddPoint(-M_PI);
+ EXPECT_EQ(r, pi);
+ r = empty; r.AddPoint(-M_PI); r.AddPoint(M_PI);
+ EXPECT_EQ(r, mipi);
+ r = empty; r.AddPoint(mid12.lo()); r.AddPoint(mid12.hi());
+ EXPECT_EQ(r, mid12);
+ r = empty; r.AddPoint(mid23.lo()); r.AddPoint(mid23.hi());
+ EXPECT_EQ(r, mid23);
+ r = quad1; r.AddPoint(-0.9*M_PI); r.AddPoint(-M_PI_2);
+ EXPECT_EQ(r, quad123);
+ r = full; r.AddPoint(0);
+ EXPECT_TRUE(r.is_full());
+ r = full; r.AddPoint(M_PI);
+ EXPECT_TRUE(r.is_full());
+ r = full; r.AddPoint(-M_PI);
+ EXPECT_TRUE(r.is_full());
+}
+
+TEST_F(S1IntervalTestBase, FromPointPair) {
+ EXPECT_EQ(S1Interval::FromPointPair(-M_PI, M_PI), pi);
+ EXPECT_EQ(S1Interval::FromPointPair(M_PI, -M_PI), pi);
+ EXPECT_EQ(S1Interval::FromPointPair(mid34.hi(), mid34.lo()), mid34);
+ EXPECT_EQ(S1Interval::FromPointPair(mid23.lo(), mid23.hi()), mid23);
+}
+
+TEST_F(S1IntervalTestBase, Expanded) {
+ EXPECT_EQ(empty.Expanded(1), empty);
+ EXPECT_EQ(full.Expanded(1), full);
+ EXPECT_EQ(zero.Expanded(1), S1Interval(-1, 1));
+ EXPECT_EQ(mipi.Expanded(0.01), S1Interval(M_PI - 0.01, -M_PI + 0.01));
+ EXPECT_EQ(pi.Expanded(27), full);
+ EXPECT_EQ(pi.Expanded(M_PI_2), quad23);
+ EXPECT_EQ(pi2.Expanded(M_PI_2), quad12);
+ EXPECT_EQ(mipi2.Expanded(M_PI_2), quad34);
+}
+
+TEST_F(S1IntervalTestBase, ApproxEquals) {
+ EXPECT_TRUE(empty.ApproxEquals(empty));
+ EXPECT_TRUE(zero.ApproxEquals(empty) && empty.ApproxEquals(zero));
+ EXPECT_TRUE(pi.ApproxEquals(empty) && empty.ApproxEquals(pi));
+ EXPECT_TRUE(mipi.ApproxEquals(empty) && empty.ApproxEquals(mipi));
+ EXPECT_TRUE(pi.ApproxEquals(mipi) && mipi.ApproxEquals(pi));
+ EXPECT_TRUE(pi.Union(mipi).ApproxEquals(pi));
+ EXPECT_TRUE(mipi.Union(pi).ApproxEquals(pi));
+ EXPECT_TRUE(pi.Union(mid12).Union(zero).ApproxEquals(quad12));
+ EXPECT_TRUE(quad2.Intersection(quad3).ApproxEquals(pi));
+ EXPECT_TRUE(quad3.Intersection(quad2).ApproxEquals(pi));
+}
+
+TEST_F(S1IntervalTestBase, GetDirectedHausdorffDistance) {
+ EXPECT_FLOAT_EQ(0.0, empty.GetDirectedHausdorffDistance(empty));
+ EXPECT_FLOAT_EQ(0.0, empty.GetDirectedHausdorffDistance(mid12));
+ EXPECT_FLOAT_EQ(M_PI, mid12.GetDirectedHausdorffDistance(empty));
+
+ EXPECT_EQ(0.0, quad12.GetDirectedHausdorffDistance(quad123));
+ S1Interval in(3.0, -3.0); // an interval whose complement center is 0.
+ EXPECT_FLOAT_EQ(3.0,
+ S1Interval(-0.1,0.2).GetDirectedHausdorffDistance(in));
+ EXPECT_FLOAT_EQ(3.0 - 0.1,
+ S1Interval(0.1, 0.2).GetDirectedHausdorffDistance(in));
+ EXPECT_FLOAT_EQ(3.0 - 0.1,
+ S1Interval(-0.2, -0.1).GetDirectedHausdorffDistance(in));
+}
diff --git a/src/third_party/s2/s2.cc b/src/third_party/s2/s2.cc
new file mode 100644
index 00000000000..a4cb8478c0f
--- /dev/null
+++ b/src/third_party/s2/s2.cc
@@ -0,0 +1,773 @@
+// Copyright 2005 Google Inc. All Rights Reserved.
+
+#include "s2.h"
+
+#include "base/commandlineflags.h"
+#include "base/integral_types.h"
+#include "base/logging.h"
+#include "util/math/matrix3x3-inl.h"
+#include "util/math/vector2-inl.h"
+
+// Define storage for header file constants (the values are not needed
+// here for integral constants).
+
+int const S2::kSwapMask = 0x01;
+int const S2::kInvertMask = 0x02;
+int const S2::kMaxCellLevel = 30;
+double const S2::kMaxDetError = 0.8e-15; // 14 * (2**-54)
+
+COMPILE_ASSERT(S2::kSwapMask == 0x01 && S2::kInvertMask == 0x02,
+ masks_changed);
+
+DEFINE_bool(s2debug, DEBUG_MODE, "Enable debugging checks in s2 code");
+
+static const uint32 MIX32 = 0x12b9b0a1UL;
+//#include<hash_set>
+namespace HASH_NAMESPACE {
+
+// The hash function due to Bob Jenkins (see
+// http://burtleburtle.net/bob/hash/index.html).
+static inline void mix(uint32& a, uint32& b, uint32& c) { // 32bit version
+ a -= b; a -= c; a ^= (c>>13);
+ b -= c; b -= a; b ^= (a<<8);
+ c -= a; c -= b; c ^= (b>>13);
+ a -= b; a -= c; a ^= (c>>12);
+ b -= c; b -= a; b ^= (a<<16);
+ c -= a; c -= b; c ^= (b>>5);
+ a -= b; a -= c; a ^= (c>>3);
+ b -= c; b -= a; b ^= (a<<10);
+ c -= a; c -= b; c ^= (b>>15);
+}
+
+inline uint32 CollapseZero(uint32 bits) {
+ // IEEE 754 has two representations for zero, positive zero and negative
+ // zero. These two values compare as equal, and therefore we need them to
+ // hash to the same value.
+ //
+ // We handle this by simply clearing the top bit of every 32-bit value,
+ // which clears the sign bit on both big-endian and little-endian
+ // architectures. This creates some additional hash collisions between
+ // points that differ only in the sign of their components, but this is
+ // rarely a problem with real data.
+ //
+ // The obvious alternative is to explicitly map all occurrences of positive
+ // zero to negative zero (or vice versa), but this is more expensive and
+ // makes the average case slower.
+ //
+ // We also mask off the low-bit because we've seen differences in
+ // some floating point operations (specifically 'fcos' on i386)
+ // between different implementations of the same architecure
+ // (e.g. 'Xeon 5345' vs. 'Opteron 270'). It's unknown how many bits
+ // of mask are sufficient to cover real world cases, but the intent
+ // is to be as conservative as possible in discarding bits.
+
+ return bits & 0x7ffffffe;
+}
+
+size_t hash<S2Point>::operator()(S2Point const& p) const {
+ // This function is significantly faster than calling HashTo32().
+ uint32 const* data = reinterpret_cast<uint32 const*>(p.Data());
+ DCHECK_EQ((6 * sizeof(*data)), sizeof(p));
+
+ // We call CollapseZero() on every 32-bit chunk to avoid having endian
+ // dependencies.
+ uint32 a = CollapseZero(data[0]);
+ uint32 b = CollapseZero(data[1]);
+ uint32 c = CollapseZero(data[2]) + 0x12b9b0a1UL; // An arbitrary number
+ mix(a, b, c);
+ a += CollapseZero(data[3]);
+ b += CollapseZero(data[4]);
+ c += CollapseZero(data[5]);
+ mix(a, b, c);
+ return c;
+}
+} // namespace __gnu_cxx
+
+#ifdef _WIN32
+template<> size_t stdext::hash_value<S2Point>(const S2Point &p) {
+ return hash<S2Point>()(p);
+}
+#endif
+
+bool S2::IsUnitLength(S2Point const& p) {
+
+ return fabs(p.Norm2() - 1) <= 1e-15;
+}
+
+S2Point S2::Ortho(S2Point const& a) {
+#ifdef S2_TEST_DEGENERACIES
+ // Vector3::Ortho() always returns a point on the X-Y, Y-Z, or X-Z planes.
+ // This leads to many more degenerate cases in polygon operations.
+ return a.Ortho();
+#else
+ int k = a.LargestAbsComponent() - 1;
+ if (k < 0) k = 2;
+ S2Point temp(0.012, 0.0053, 0.00457);
+ temp[k] = 1;
+ return a.CrossProd(temp).Normalize();
+#endif
+}
+
+void S2::GetFrame(S2Point const& z, Matrix3x3_d* m) {
+ DCHECK(IsUnitLength(z));
+ m->SetCol(2, z);
+ m->SetCol(1, Ortho(z));
+ m->SetCol(0, m->Col(1).CrossProd(z)); // Already unit-length.
+}
+
+S2Point S2::ToFrame(Matrix3x3_d const& m, S2Point const& p) {
+ // The inverse of an orthonormal matrix is its transpose.
+ return m.Transpose() * p;
+}
+
+S2Point S2::FromFrame(Matrix3x3_d const& m, S2Point const& q) {
+ return m * q;
+}
+
+bool S2::ApproxEquals(S2Point const& a, S2Point const& b, double max_error) {
+ return a.Angle(b) <= max_error;
+}
+
+S2Point S2::RobustCrossProd(S2Point const& a, S2Point const& b) {
+ // The direction of a.CrossProd(b) becomes unstable as (a + b) or (a - b)
+ // approaches zero. This leads to situations where a.CrossProd(b) is not
+ // very orthogonal to "a" and/or "b". We could fix this using Gram-Schmidt,
+ // but we also want b.RobustCrossProd(a) == -a.RobustCrossProd(b).
+ //
+ // The easiest fix is to just compute the cross product of (b+a) and (b-a).
+ // Mathematically, this cross product is exactly twice the cross product of
+ // "a" and "b", but it has the numerical advantage that (b+a) and (b-a)
+ // are always perpendicular (since "a" and "b" are unit length). This
+ // yields a result that is nearly orthogonal to both "a" and "b" even if
+ // these two values differ only in the lowest bit of one component.
+
+ DCHECK(IsUnitLength(a));
+ DCHECK(IsUnitLength(b));
+ S2Point x = (b + a).CrossProd(b - a);
+ if (x != S2Point(0, 0, 0)) return x;
+
+ // The only result that makes sense mathematically is to return zero, but
+ // we find it more convenient to return an arbitrary orthogonal vector.
+ return Ortho(a);
+}
+
+bool S2::SimpleCCW(S2Point const& a, S2Point const& b, S2Point const& c) {
+ // We compute the signed volume of the parallelepiped ABC. The usual
+ // formula for this is (AxB).C, but we compute it here using (CxA).B
+ // in order to ensure that ABC and CBA are not both CCW. This follows
+ // from the following identities (which are true numerically, not just
+ // mathematically):
+ //
+ // (1) x.CrossProd(y) == -(y.CrossProd(x))
+ // (2) (-x).DotProd(y) == -(x.DotProd(y))
+
+ return c.CrossProd(a).DotProd(b) > 0;
+}
+
+int S2::RobustCCW(S2Point const& a, S2Point const& b, S2Point const& c) {
+ // We don't need RobustCrossProd() here because RobustCCW() does its own
+ // error estimation and calls ExpensiveCCW() if there is any uncertainty
+ // about the result.
+ return RobustCCW(a, b, c, a.CrossProd(b));
+}
+
+// Below we define two versions of ExpensiveCCW(). The first version uses
+// arbitrary-precision arithmetic (MPFloat) and the "simulation of simplicity"
+// technique. It is completely robust (i.e., it returns consistent results
+// for all possible inputs). The second version uses normal double-precision
+// arithmetic. It is numerically stable and handles many degeneracies well,
+// but it is not perfectly robust. It exists mainly for testing purposes, so
+// that we can verify that certain tests actually require the more advanced
+// techniques implemented by the first version.
+
+#undef SIMULATION_OF_SIMPLICITY
+#ifdef SIMULATION_OF_SIMPLICITY
+
+// Below we define a floating-point type with enough precision so that it can
+// represent the exact determinant of any 3x3 matrix of floating-point
+// numbers. We support two options: MPFloat (which is based on MPFR and is
+// therefore subject to an LGPL license) and ExactFloat (which is based on the
+// OpenSSL Bignum library and therefore has a permissive BSD-style license).
+
+#ifdef S2_USE_EXACTFLOAT
+
+// ExactFloat only supports exact calculations with floating-point numbers.
+#include "util/math/exactfloat/exactfloat.h"
+
+#else // S2_USE_EXACTFLOAT
+
+// MPFloat requires a "maximum precision" to be specified.
+//
+// To figure out how much precision we need, first observe that any double
+// precision number can be represented as an integer by multiplying it by
+// 2**1074. This is because the minimum exponent is -1022, and denormalized
+// numbers have 52 bits after the leading "0". On the other hand, the largest
+// double precision value has the form 1.x * (2**1023), which is a 1024-bit
+// integer. Therefore any double precision value can be represented as a
+// (1074 + 1024) = 2098 bit integer.
+//
+// A 3x3 determinant is computed by adding together 6 values, each of which is
+// the product of 3 of the input values. When an m-bit integer is multiplied
+// by an n-bit integer, the result has at most (m+n) bits. When "k" m-bit
+// integers are added together, the result has at most m + ceil(log2(k)) bits.
+// Therefore the determinant of any 3x3 matrix can be represented exactly
+// using no more than (3*2098)+3 = 6297 bits.
+//
+// Note that MPFloat only uses as much precision as required to compute the
+// exact result, and that typically far fewer bits of precision are used. The
+// worst-case estimate above is only achieved for a matrix where every row
+// contains both the maximum and minimum possible double precision values
+// (i.e. approximately 1e308 and 1e-323). For randomly chosen unit-length
+// vectors, the average case uses only about 200 bits of precision.
+
+// The maximum precision must be at least (6297 + 1) so that we can assert
+// that the result of the determinant calculation is exact (by checking that
+// the actual precision of the result is less than the maximum precision
+// specified).
+
+#include "util/math/mpfloat/mpfloat.h"
+typedef MPFloat<6300> ExactFloat;
+
+#endif // S2_USE_EXACTFLOAT
+
+typedef Vector3<ExactFloat> Vector3_xf;
+
+// The following function returns the sign of the determinant of three points
+// A, B, C under a model where every possible S2Point is slightly perturbed by
+// a unique infinitesmal amount such that no three perturbed points are
+// collinear and no four points are coplanar. The perturbations are so small
+// that they do not change the sign of any determinant that was non-zero
+// before the perturbations, and therefore can be safely ignored unless the
+// determinant of three points is exactly zero (using multiple-precision
+// arithmetic).
+//
+// Since the symbolic perturbation of a given point is fixed (i.e., the
+// perturbation is the same for all calls to this method and does not depend
+// on the other two arguments), the results of this method are always
+// self-consistent. It will never return results that would correspond to an
+// "impossible" configuration of non-degenerate points.
+//
+// Requirements:
+// The 3x3 determinant of A, B, C must be exactly zero.
+// The points must be distinct, with A < B < C in lexicographic order.
+//
+// Returns:
+// +1 or -1 according to the sign of the determinant after the symbolic
+// perturbations are taken into account.
+//
+// Reference:
+// "Simulation of Simplicity" (Edelsbrunner and Muecke, ACM Transactions on
+// Graphics, 1990).
+//
+static int SymbolicallyPerturbedCCW(
+ Vector3_xf const& a, Vector3_xf const& b,
+ Vector3_xf const& c, Vector3_xf const& b_cross_c) {
+ // This method requires that the points are sorted in lexicographically
+ // increasing order. This is because every possible S2Point has its own
+ // symbolic perturbation such that if A < B then the symbolic perturbation
+ // for A is much larger than the perturbation for B.
+ //
+ // Alternatively, we could sort the points in this method and keep track of
+ // the sign of the permutation, but it is more efficient to do this before
+ // converting the inputs to the multi-precision representation, and this
+ // also lets us re-use the result of the cross product B x C.
+ DCHECK(a < b && b < c);
+
+ // Every input coordinate x[i] is assigned a symbolic perturbation dx[i].
+ // We then compute the sign of the determinant of the perturbed points,
+ // i.e.
+ // | a[0]+da[0] a[1]+da[1] a[2]+da[2] |
+ // | b[0]+db[0] b[1]+db[1] b[2]+db[2] |
+ // | c[0]+dc[0] c[1]+dc[1] c[2]+dc[2] |
+ //
+ // The perturbations are chosen such that
+ //
+ // da[2] > da[1] > da[0] > db[2] > db[1] > db[0] > dc[2] > dc[1] > dc[0]
+ //
+ // where each perturbation is so much smaller than the previous one that we
+ // don't even need to consider it unless the coefficients of all previous
+ // perturbations are zero. In fact, it is so small that we don't need to
+ // consider it unless the coefficient of all products of the previous
+ // perturbations are zero. For example, we don't need to consider the
+ // coefficient of db[1] unless the coefficient of db[2]*da[0] is zero.
+ //
+ // The follow code simply enumerates the coefficients of the perturbations
+ // (and products of perturbations) that appear in the determinant above, in
+ // order of decreasing perturbation magnitude. The first non-zero
+ // coefficient determines the sign of the result. The easiest way to
+ // enumerate the coefficients in the correct order is to pretend that each
+ // perturbation is some tiny value "eps" raised to a power of two:
+ //
+ // eps** 1 2 4 8 16 32 64 128 256
+ // da[2] da[1] da[0] db[2] db[1] db[0] dc[2] dc[1] dc[0]
+ //
+ // Essentially we can then just count in binary and test the corresponding
+ // subset of perturbations at each step. So for example, we must test the
+ // coefficient of db[2]*da[0] before db[1] because eps**12 > eps**16.
+ //
+ // Of course, not all products of these perturbations appear in the
+ // determinant above, since the determinant only contains the products of
+ // elements in distinct rows and columns. Thus we don't need to consider
+ // da[2]*da[1], db[1]*da[1], etc. Furthermore, sometimes different pairs of
+ // perturbations have the same coefficient in the determinant; for example,
+ // da[1]*db[0] and db[1]*da[0] have the same coefficient (c[2]). Therefore
+ // we only need to test this coefficient the first time we encounter it in
+ // the binary order above (which will be db[1]*da[0]).
+ //
+ // The sequence of tests below also appears in Table 4-ii of the paper
+ // referenced above, if you just want to look it up, with the following
+ // translations: [a,b,c] -> [i,j,k] and [0,1,2] -> [1,2,3]. Also note that
+ // some of the signs are different because the opposite cross product is
+ // used (e.g., B x C rather than C x B).
+
+ int det_sign = b_cross_c[2].sgn(); // da[2]
+ if (det_sign != 0) return det_sign;
+ det_sign = b_cross_c[1].sgn(); // da[1]
+ if (det_sign != 0) return det_sign;
+ det_sign = b_cross_c[0].sgn(); // da[0]
+ if (det_sign != 0) return det_sign;
+
+ det_sign = (c[0]*a[1] - c[1]*a[0]).sgn(); // db[2]
+ if (det_sign != 0) return det_sign;
+ det_sign = c[0].sgn(); // db[2] * da[1]
+ if (det_sign != 0) return det_sign;
+ det_sign = -(c[1].sgn()); // db[2] * da[0]
+ if (det_sign != 0) return det_sign;
+ det_sign = (c[2]*a[0] - c[0]*a[2]).sgn(); // db[1]
+ if (det_sign != 0) return det_sign;
+ det_sign = c[2].sgn(); // db[1] * da[0]
+ if (det_sign != 0) return det_sign;
+ // The following test is listed in the paper, but it is redundant because
+ // the previous tests guarantee that C == (0, 0, 0).
+ DCHECK_EQ(0, (c[1]*a[2] - c[2]*a[1]).sgn()); // db[0]
+
+ det_sign = (a[0]*b[1] - a[1]*b[0]).sgn(); // dc[2]
+ if (det_sign != 0) return det_sign;
+ det_sign = -(b[0].sgn()); // dc[2] * da[1]
+ if (det_sign != 0) return det_sign;
+ det_sign = b[1].sgn(); // dc[2] * da[0]
+ if (det_sign != 0) return det_sign;
+ det_sign = a[0].sgn(); // dc[2] * db[1]
+ if (det_sign != 0) return det_sign;
+ return 1; // dc[2] * db[1] * da[0]
+}
+
+int S2::ExpensiveCCW(S2Point const& a, S2Point const& b, S2Point const& c) {
+ // Return zero if and only if two points are the same. This ensures (1).
+ if (a == b || b == c || c == a) return 0;
+
+ // Sort the three points in lexicographic order, keeping track of the sign
+ // of the permutation. (Each exchange inverts the sign of the determinant.)
+ int perm_sign = 1;
+ S2Point pa = a, pb = b, pc = c;
+ if (pa > pb) { swap(pa, pb); perm_sign = -perm_sign; }
+ if (pb > pc) { swap(pb, pc); perm_sign = -perm_sign; }
+ if (pa > pb) { swap(pa, pb); perm_sign = -perm_sign; }
+ DCHECK(pa < pb && pb < pc);
+
+ // Construct multiple-precision versions of the sorted points and compute
+ // their exact 3x3 determinant.
+ Vector3_xf xa = Vector3_xf::Cast(pa);
+ Vector3_xf xb = Vector3_xf::Cast(pb);
+ Vector3_xf xc = Vector3_xf::Cast(pc);
+ Vector3_xf xb_cross_xc = xb.CrossProd(xc);
+ ExactFloat det = xa.DotProd(xb_cross_xc);
+
+ // The precision of ExactFloat is high enough that the result should always
+ // be exact (no rounding was performed).
+ DCHECK(!det.is_nan());
+ DCHECK_LT(det.prec(), det.max_prec());
+
+ // If the exact determinant is non-zero, we're done.
+ int det_sign = det.sgn();
+ if (det_sign == 0) {
+ // Otherwise, we need to resort to symbolic perturbations to resolve the
+ // sign of the determinant.
+ det_sign = SymbolicallyPerturbedCCW(xa, xb, xc, xb_cross_xc);
+ }
+ DCHECK(det_sign != 0);
+ return perm_sign * det_sign;
+}
+
+#else // SIMULATION_OF_SIMPLICITY
+
+static inline int PlanarCCW(Vector2_d const& a, Vector2_d const& b) {
+ // Return +1 if the edge AB is CCW around the origin, etc.
+ double sab = (a.DotProd(b) > 0) ? -1 : 1;
+ Vector2_d vab = a + sab * b;
+ double da = a.Norm2();
+ double db = b.Norm2();
+ double sign;
+ if (da < db || (da == db && a < b)) {
+ sign = a.CrossProd(vab) * sab;
+ } else {
+ sign = vab.CrossProd(b);
+ }
+ if (sign > 0) return 1;
+ if (sign < 0) return -1;
+ return 0;
+}
+
+static inline int PlanarOrderedCCW(Vector2_d const& a, Vector2_d const& b,
+ Vector2_d const& c) {
+ int sum = 0;
+ sum += PlanarCCW(a, b);
+ sum += PlanarCCW(b, c);
+ sum += PlanarCCW(c, a);
+ if (sum > 0) return 1;
+ if (sum < 0) return -1;
+ return 0;
+}
+
+int S2::ExpensiveCCW(S2Point const& a, S2Point const& b, S2Point const& c) {
+ // Return zero if and only if two points are the same. This ensures (1).
+ if (a == b || b == c || c == a) return 0;
+
+ // Now compute the determinant in a stable way. Since all three points are
+ // unit length and we know that the determinant is very close to zero, this
+ // means that points are very nearly collinear. Furthermore, the most common
+ // situation is where two points are nearly identical or nearly antipodal.
+ // To get the best accuracy in this situation, it is important to
+ // immediately reduce the magnitude of the arguments by computing either
+ // A+B or A-B for each pair of points. Note that even if A and B differ
+ // only in their low bits, A-B can be computed very accurately. On the
+ // other hand we can't accurately represent an arbitrary linear combination
+ // of two vectors as would be required for Gaussian elimination. The code
+ // below chooses the vertex opposite the longest edge as the "origin" for
+ // the calculation, and computes the different vectors to the other two
+ // vertices. This minimizes the sum of the lengths of these vectors.
+ //
+ // This implementation is very stable numerically, but it still does not
+ // return consistent results in all cases. For example, if three points are
+ // spaced far apart from each other along a great circle, the sign of the
+ // result will basically be random (although it will still satisfy the
+ // conditions documented in the header file). The only way to return
+ // consistent results in all cases is to compute the result using
+ // multiple-precision arithmetic. I considered using the Gnu MP library,
+ // but this would be very expensive (up to 2000 bits of precision may be
+ // needed to store the intermediate results) and seems like overkill for
+ // this problem. The MP library is apparently also quite particular about
+ // compilers and compilation options and would be a pain to maintain.
+
+ // We want to handle the case of nearby points and nearly antipodal points
+ // accurately, so determine whether A+B or A-B is smaller in each case.
+ double sab = (a.DotProd(b) > 0) ? -1 : 1;
+ double sbc = (b.DotProd(c) > 0) ? -1 : 1;
+ double sca = (c.DotProd(a) > 0) ? -1 : 1;
+ S2Point vab = a + sab * b;
+ S2Point vbc = b + sbc * c;
+ S2Point vca = c + sca * a;
+ double dab = vab.Norm2();
+ double dbc = vbc.Norm2();
+ double dca = vca.Norm2();
+
+ // Sort the difference vectors to find the longest edge, and use the
+ // opposite vertex as the origin. If two difference vectors are the same
+ // length, we break ties deterministically to ensure that the symmetry
+ // properties guaranteed in the header file will be true.
+ double sign;
+ if (dca < dbc || (dca == dbc && a < b)) {
+ if (dab < dbc || (dab == dbc && a < c)) {
+ // The "sab" factor converts A +/- B into B +/- A.
+ sign = vab.CrossProd(vca).DotProd(a) * sab; // BC is longest edge
+ } else {
+ sign = vca.CrossProd(vbc).DotProd(c) * sca; // AB is longest edge
+ }
+ } else {
+ if (dab < dca || (dab == dca && b < c)) {
+ sign = vbc.CrossProd(vab).DotProd(b) * sbc; // CA is longest edge
+ } else {
+ sign = vca.CrossProd(vbc).DotProd(c) * sca; // AB is longest edge
+ }
+ }
+ if (sign > 0) return 1;
+ if (sign < 0) return -1;
+
+ // The points A, B, and C are numerically indistinguishable from coplanar.
+ // This may be due to roundoff error, or the points may in fact be exactly
+ // coplanar. We handle this situation by perturbing all of the points by a
+ // vector (eps, eps**2, eps**3) where "eps" is an infinitesmally small
+ // positive number (e.g. 1 divided by a googolplex). The perturbation is
+ // done symbolically, i.e. we compute what would happen if the points were
+ // perturbed by this amount. It turns out that this is equivalent to
+ // checking whether the points are ordered CCW around the origin first in
+ // the Y-Z plane, then in the Z-X plane, and then in the X-Y plane.
+
+ int ccw = PlanarOrderedCCW(Vector2_d(a.y(), a.z()), Vector2_d(b.y(), b.z()),
+ Vector2_d(c.y(), c.z()));
+ if (ccw == 0) {
+ ccw = PlanarOrderedCCW(Vector2_d(a.z(), a.x()), Vector2_d(b.z(), b.x()),
+ Vector2_d(c.z(), c.x()));
+ if (ccw == 0) {
+ ccw = PlanarOrderedCCW(Vector2_d(a.x(), a.y()), Vector2_d(b.x(), b.y()),
+ Vector2_d(c.x(), c.y()));
+ // There are a few cases where "ccw" may still be zero despite our best
+ // efforts. For example, two input points may be exactly proportional
+ // to each other (where both still satisfy IsNormalized()).
+ }
+ }
+ return ccw;
+}
+
+#endif // SIMULATION_OF_SIMPLICITY
+
+double S2::Angle(S2Point const& a, S2Point const& b, S2Point const& c) {
+ return RobustCrossProd(a, b).Angle(RobustCrossProd(c, b));
+}
+
+double S2::TurnAngle(S2Point const& a, S2Point const& b, S2Point const& c) {
+ // This is a bit less efficient because we compute all 3 cross products, but
+ // it ensures that TurnAngle(a,b,c) == -TurnAngle(c,b,a) for all a,b,c.
+ double angle = RobustCrossProd(b, a).Angle(RobustCrossProd(c, b));
+ return (RobustCCW(a, b, c) > 0) ? angle : -angle;
+}
+
+double S2::Area(S2Point const& a, S2Point const& b, S2Point const& c) {
+ DCHECK(IsUnitLength(a));
+ DCHECK(IsUnitLength(b));
+ DCHECK(IsUnitLength(c));
+ // This method is based on l'Huilier's theorem,
+ //
+ // tan(E/4) = sqrt(tan(s/2) tan((s-a)/2) tan((s-b)/2) tan((s-c)/2))
+ //
+ // where E is the spherical excess of the triangle (i.e. its area),
+ // a, b, c, are the side lengths, and
+ // s is the semiperimeter (a + b + c) / 2 .
+ //
+ // The only significant source of error using l'Huilier's method is the
+ // cancellation error of the terms (s-a), (s-b), (s-c). This leads to a
+ // *relative* error of about 1e-16 * s / min(s-a, s-b, s-c). This compares
+ // to a relative error of about 1e-15 / E using Girard's formula, where E is
+ // the true area of the triangle. Girard's formula can be even worse than
+ // this for very small triangles, e.g. a triangle with a true area of 1e-30
+ // might evaluate to 1e-5.
+ //
+ // So, we prefer l'Huilier's formula unless dmin < s * (0.1 * E), where
+ // dmin = min(s-a, s-b, s-c). This basically includes all triangles
+ // except for extremely long and skinny ones.
+ //
+ // Since we don't know E, we would like a conservative upper bound on
+ // the triangle area in terms of s and dmin. It's possible to show that
+ // E <= k1 * s * sqrt(s * dmin), where k1 = 2*sqrt(3)/Pi (about 1).
+ // Using this, it's easy to show that we should always use l'Huilier's
+ // method if dmin >= k2 * s^5, where k2 is about 1e-2. Furthermore,
+ // if dmin < k2 * s^5, the triangle area is at most k3 * s^4, where
+ // k3 is about 0.1. Since the best case error using Girard's formula
+ // is about 1e-15, this means that we shouldn't even consider it unless
+ // s >= 3e-4 or so.
+
+ // We use volatile doubles to force the compiler to truncate all of these
+ // quantities to 64 bits. Otherwise it may compute a value of dmin > 0
+ // simply because it chose to spill one of the intermediate values to
+ // memory but not one of the others.
+ volatile double sa = b.Angle(c);
+ volatile double sb = c.Angle(a);
+ volatile double sc = a.Angle(b);
+ volatile double s = 0.5 * (sa + sb + sc);
+ if (s >= 3e-4) {
+ // Consider whether Girard's formula might be more accurate.
+ double s2 = s * s;
+ double dmin = s - max(sa, max(sb, sc));
+ if (dmin < 1e-2 * s * s2 * s2) {
+ // This triangle is skinny enough to consider Girard's formula.
+ double area = GirardArea(a, b, c);
+ if (dmin < s * (0.1 * area)) return area;
+ }
+ }
+ // Use l'Huilier's formula.
+ return 4 * atan(sqrt(max(0.0, tan(0.5 * s) * tan(0.5 * (s - sa)) *
+ tan(0.5 * (s - sb)) * tan(0.5 * (s - sc)))));
+}
+
+double S2::GirardArea(S2Point const& a, S2Point const& b, S2Point const& c) {
+ // This is equivalent to the usual Girard's formula but is slightly
+ // more accurate, faster to compute, and handles a == b == c without
+ // a special case. The use of RobustCrossProd() makes it much more
+ // accurate when two vertices are nearly identical or antipodal.
+
+ S2Point ab = RobustCrossProd(a, b);
+ S2Point bc = RobustCrossProd(b, c);
+ S2Point ac = RobustCrossProd(a, c);
+ return max(0.0, ab.Angle(ac) - ab.Angle(bc) + bc.Angle(ac));
+}
+
+double S2::SignedArea(S2Point const& a, S2Point const& b, S2Point const& c) {
+ return Area(a, b, c) * RobustCCW(a, b, c);
+}
+
+S2Point S2::PlanarCentroid(S2Point const& a, S2Point const& b,
+ S2Point const& c) {
+ return (1./3) * (a + b + c);
+}
+
+S2Point S2::TrueCentroid(S2Point const& a, S2Point const& b,
+ S2Point const& c) {
+ DCHECK(IsUnitLength(a));
+ DCHECK(IsUnitLength(b));
+ DCHECK(IsUnitLength(c));
+
+ // I couldn't find any references for computing the true centroid of a
+ // spherical triangle... I have a truly marvellous demonstration of this
+ // formula which this margin is too narrow to contain :)
+
+ // Use Angle() in order to get accurate results for small triangles.
+ double angle_a = b.Angle(c);
+ double angle_b = c.Angle(a);
+ double angle_c = a.Angle(b);
+ double ra = (angle_a == 0) ? 1 : (angle_a / sin(angle_a));
+ double rb = (angle_b == 0) ? 1 : (angle_b / sin(angle_b));
+ double rc = (angle_c == 0) ? 1 : (angle_c / sin(angle_c));
+
+ // Now compute a point M such that:
+ //
+ // [Ax Ay Az] [Mx] [ra]
+ // [Bx By Bz] [My] = 0.5 * det(A,B,C) * [rb]
+ // [Cx Cy Cz] [Mz] [rc]
+ //
+ // To improve the numerical stability we subtract the first row (A) from the
+ // other two rows; this reduces the cancellation error when A, B, and C are
+ // very close together. Then we solve it using Cramer's rule.
+ //
+ // TODO(user): This code still isn't as numerically stable as it could be.
+ // The biggest potential improvement is to compute B-A and C-A more
+ // accurately so that (B-A)x(C-A) is always inside triangle ABC.
+ S2Point x(a.x(), b.x() - a.x(), c.x() - a.x());
+ S2Point y(a.y(), b.y() - a.y(), c.y() - a.y());
+ S2Point z(a.z(), b.z() - a.z(), c.z() - a.z());
+ S2Point r(ra, rb - ra, rc - ra);
+ return 0.5 * S2Point(y.CrossProd(z).DotProd(r),
+ z.CrossProd(x).DotProd(r),
+ x.CrossProd(y).DotProd(r));
+}
+
+bool S2::OrderedCCW(S2Point const& a, S2Point const& b, S2Point const& c,
+ S2Point const& o) {
+ // The last inequality below is ">" rather than ">=" so that we return true
+ // if A == B or B == C, and otherwise false if A == C. Recall that
+ // RobustCCW(x,y,z) == -RobustCCW(z,y,x) for all x,y,z.
+
+ int sum = 0;
+ if (RobustCCW(b, o, a) >= 0) ++sum;
+ if (RobustCCW(c, o, b) >= 0) ++sum;
+ if (RobustCCW(a, o, c) > 0) ++sum;
+ return sum >= 2;
+}
+
+// kIJtoPos[orientation][ij] -> pos
+int const S2::kIJtoPos[4][4] = {
+ // (0,0) (0,1) (1,0) (1,1)
+ { 0, 1, 3, 2 }, // canonical order
+ { 0, 3, 1, 2 }, // axes swapped
+ { 2, 3, 1, 0 }, // bits inverted
+ { 2, 1, 3, 0 }, // swapped & inverted
+};
+
+// kPosToIJ[orientation][pos] -> ij
+int const S2::kPosToIJ[4][4] = {
+ // 0 1 2 3
+ { 0, 1, 3, 2 }, // canonical order: (0,0), (0,1), (1,1), (1,0)
+ { 0, 2, 3, 1 }, // axes swapped: (0,0), (1,0), (1,1), (0,1)
+ { 3, 2, 0, 1 }, // bits inverted: (1,1), (1,0), (0,0), (0,1)
+ { 3, 1, 0, 2 }, // swapped & inverted: (1,1), (0,1), (0,0), (1,0)
+};
+
+// kPosToOrientation[pos] -> orientation_modifier
+int const S2::kPosToOrientation[4] = {
+ kSwapMask,
+ 0,
+ 0,
+ kInvertMask + kSwapMask,
+};
+
+// All of the values below were obtained by a combination of hand analysis and
+// Mathematica. In general, S2_TAN_PROJECTION produces the most uniform
+// shapes and sizes of cells, S2_LINEAR_PROJECTION is considerably worse, and
+// S2_QUADRATIC_PROJECTION is somewhere in between (but generally closer to
+// the tangent projection than the linear one).
+
+S2::LengthMetric const S2::kMinAngleSpan(
+ S2_PROJECTION == S2_LINEAR_PROJECTION ? 1.0 : // 1.000
+ S2_PROJECTION == S2_TAN_PROJECTION ? M_PI / 2 : // 1.571
+ S2_PROJECTION == S2_QUADRATIC_PROJECTION ? 4. / 3 : // 1.333
+ 0);
+
+S2::LengthMetric const S2::kMaxAngleSpan(
+ S2_PROJECTION == S2_LINEAR_PROJECTION ? 2 : // 2.000
+ S2_PROJECTION == S2_TAN_PROJECTION ? M_PI / 2 : // 1.571
+ S2_PROJECTION == S2_QUADRATIC_PROJECTION ? 1.704897179199218452 : // 1.705
+ 0);
+
+S2::LengthMetric const S2::kAvgAngleSpan(M_PI / 2); // 1.571
+// This is true for all projections.
+
+S2::LengthMetric const S2::kMinWidth(
+ S2_PROJECTION == S2_LINEAR_PROJECTION ? sqrt(2. / 3) : // 0.816
+ S2_PROJECTION == S2_TAN_PROJECTION ? M_PI / (2 * sqrt(2)) : // 1.111
+ S2_PROJECTION == S2_QUADRATIC_PROJECTION ? 2 * sqrt(2) / 3 : // 0.943
+ 0);
+
+S2::LengthMetric const S2::kMaxWidth(S2::kMaxAngleSpan.deriv());
+// This is true for all projections.
+
+S2::LengthMetric const S2::kAvgWidth(
+ S2_PROJECTION == S2_LINEAR_PROJECTION ? 1.411459345844456965 : // 1.411
+ S2_PROJECTION == S2_TAN_PROJECTION ? 1.437318638925160885 : // 1.437
+ S2_PROJECTION == S2_QUADRATIC_PROJECTION ? 1.434523672886099389 : // 1.435
+ 0);
+
+S2::LengthMetric const S2::kMinEdge(
+ S2_PROJECTION == S2_LINEAR_PROJECTION ? 2 * sqrt(2) / 3 : // 0.943
+ S2_PROJECTION == S2_TAN_PROJECTION ? M_PI / (2 * sqrt(2)) : // 1.111
+ S2_PROJECTION == S2_QUADRATIC_PROJECTION ? 2 * sqrt(2) / 3 : // 0.943
+ 0);
+
+S2::LengthMetric const S2::kMaxEdge(S2::kMaxAngleSpan.deriv());
+// This is true for all projections.
+
+S2::LengthMetric const S2::kAvgEdge(
+ S2_PROJECTION == S2_LINEAR_PROJECTION ? 1.440034192955603643 : // 1.440
+ S2_PROJECTION == S2_TAN_PROJECTION ? 1.461667032546739266 : // 1.462
+ S2_PROJECTION == S2_QUADRATIC_PROJECTION ? 1.459213746386106062 : // 1.459
+ 0);
+
+S2::LengthMetric const S2::kMinDiag(
+ S2_PROJECTION == S2_LINEAR_PROJECTION ? 2 * sqrt(2) / 3 : // 0.943
+ S2_PROJECTION == S2_TAN_PROJECTION ? M_PI * sqrt(2) / 3 : // 1.481
+ S2_PROJECTION == S2_QUADRATIC_PROJECTION ? 8 * sqrt(2) / 9 : // 1.257
+ 0);
+
+S2::LengthMetric const S2::kMaxDiag(
+ S2_PROJECTION == S2_LINEAR_PROJECTION ? 2 * sqrt(2) : // 2.828
+ S2_PROJECTION == S2_TAN_PROJECTION ? M_PI * sqrt(2. / 3) : // 2.565
+ S2_PROJECTION == S2_QUADRATIC_PROJECTION ? 2.438654594434021032 : // 2.439
+ 0);
+
+S2::LengthMetric const S2::kAvgDiag(
+ S2_PROJECTION == S2_LINEAR_PROJECTION ? 2.031817866418812674 : // 2.032
+ S2_PROJECTION == S2_TAN_PROJECTION ? 2.063623197195635753 : // 2.064
+ S2_PROJECTION == S2_QUADRATIC_PROJECTION ? 2.060422738998471683 : // 2.060
+ 0);
+
+S2::AreaMetric const S2::kMinArea(
+ S2_PROJECTION == S2_LINEAR_PROJECTION ? 4 / (3 * sqrt(3)) : // 0.770
+ S2_PROJECTION == S2_TAN_PROJECTION ? (M_PI*M_PI) / (4*sqrt(2)) : // 1.745
+ S2_PROJECTION == S2_QUADRATIC_PROJECTION ? 8 * sqrt(2) / 9 : // 1.257
+ 0);
+
+S2::AreaMetric const S2::kMaxArea(
+ S2_PROJECTION == S2_LINEAR_PROJECTION ? 4 : // 4.000
+ S2_PROJECTION == S2_TAN_PROJECTION ? M_PI * M_PI / 4 : // 2.467
+ S2_PROJECTION == S2_QUADRATIC_PROJECTION ? 2.635799256963161491 : // 2.636
+ 0);
+
+S2::AreaMetric const S2::kAvgArea(4 * M_PI / 6); // 2.094
+// This is true for all projections.
+
+double const S2::kMaxEdgeAspect = (
+ S2_PROJECTION == S2_LINEAR_PROJECTION ? sqrt(2) : // 1.414
+ S2_PROJECTION == S2_TAN_PROJECTION ? sqrt(2) : // 1.414
+ S2_PROJECTION == S2_QUADRATIC_PROJECTION ? 1.442615274452682920 : // 1.443
+ 0);
+
+double const S2::kMaxDiagAspect = sqrt(3); // 1.732
+// This is true for all projections.
diff --git a/src/third_party/s2/s2.h b/src/third_party/s2/s2.h
new file mode 100644
index 00000000000..f0df0afe258
--- /dev/null
+++ b/src/third_party/s2/s2.h
@@ -0,0 +1,867 @@
+// Copyright 2005 Google Inc. All Rights Reserved.
+
+#ifndef UTIL_GEOMETRY_S2_H_
+#define UTIL_GEOMETRY_S2_H_
+
+#include <algorithm>
+using std::min;
+using std::max;
+using std::swap;
+using std::reverse;
+
+#include "base/definer.h"
+
+#ifdef OS_WINDOWS
+#define _USE_MATH_DEFINES
+#include <cmath>
+#endif
+
+#ifndef _GLIBCXX_PERMIT_BACKWARD_HASH
+#define _GLIBCXX_PERMIT_BACKWARD_HASH
+#endif
+
+#if defined OS_MACOSX
+#include <ext/hash_map>
+#else
+#include <hash_map>
+#endif
+#ifndef OS_WINDOWS
+using __gnu_cxx::hash_map;
+#endif
+
+#if defined OS_MACOSX
+#include <ext/hash_set>
+#else
+#include <hash_set>
+#endif
+#ifndef OS_WINDOWS
+using __gnu_cxx::hash_set;
+#endif
+
+// To have template struct hash<T> defined
+#include "third_party/s2/base/basictypes.h"
+#include "third_party/s2/base/logging.h"
+#include "third_party/s2/base/macros.h"
+#include "third_party/s2/base/port.h" // for HASH_NAMESPACE_DECLARATION_START
+#include "third_party/s2/util/math/vector3-inl.h"
+#include "third_party/s2/util/math/matrix3x3.h"
+
+
+// An S2Point represents a point on the unit sphere as a 3D vector. Usually
+// points are normalized to be unit length, but some methods do not require
+// this. See util/math/vector3-inl.h for the methods available. Among other
+// things, there are overloaded operators that make it convenient to write
+// arithmetic expressions (e.g. (1-x)*p1 + x*p2).
+
+typedef Vector3_d S2Point;
+
+namespace HASH_NAMESPACE {
+template<> class hash<S2Point> {
+public:
+ size_t operator()(S2Point const& p) const;
+};
+}
+#ifdef _WIN32
+template<> size_t stdext::hash_value<S2Point>(const S2Point &p);
+#endif
+
+// The S2 class is simply a namespace for constants and static utility
+// functions related to spherical geometry, such as area calculations and edge
+// intersection tests. The name "S2" is derived from the mathematical symbol
+// for the two-dimensional unit sphere (note that the "2" refers to the
+// dimension of the surface, not the space it is embedded in).
+//
+// This class also defines a framework for decomposing the unit sphere into a
+// hierarchy of "cells". Each cell is a quadrilateral bounded by four
+// geodesics. The top level of the hierarchy is obtained by projecting the
+// six faces of a cube onto the unit sphere, and lower levels are obtained by
+// subdividing each cell into four children recursively.
+//
+// This class specifies the details of how the cube faces are projected onto
+// the unit sphere. This includes getting the face ordering and orientation
+// correct so that sequentially increasing cell ids follow a continuous
+// space-filling curve over the entire sphere, and defining the
+// transformation from cell-space to cube-space in order to make the cells
+// more uniform in size.
+//
+// This file also contains documentation of the various coordinate systems
+// and conventions used.
+//
+// This class is not thread-safe for loops and objects that use loops.
+//
+class S2 {
+ public:
+ // Return a unique "origin" on the sphere for operations that need a fixed
+ // reference point. In particular, this is the "point at infinity" used for
+ // point-in-polygon testing (by counting the number of edge crossings).
+ //
+ // It should *not* be a point that is commonly used in edge tests in order
+ // to avoid triggering code to handle degenerate cases. (This rules out the
+ // north and south poles.) It should also not be on the boundary of any
+ // low-level S2Cell for the same reason.
+ inline static S2Point Origin();
+
+ // Return true if the given point is approximately unit length
+ // (this is mainly useful for assertions).
+ static bool IsUnitLength(S2Point const& p);
+
+ // Return a unit-length vector that is orthogonal to "a". Satisfies
+ // Ortho(-a) = -Ortho(a) for all a.
+ static S2Point Ortho(S2Point const& a);
+
+ // Given a point "z" on the unit sphere, extend this into a right-handed
+ // coordinate frame of unit-length column vectors m = (x,y,z). Note that
+ // the vectors (x,y) are an orthonormal frame for the tangent space at "z",
+ // while "z" itself is an orthonormal frame for the normal space at "z".
+ static void GetFrame(S2Point const& z, Matrix3x3_d* m);
+
+ // Given an orthonormal basis "m" of column vectors and a point "p", return
+ // the coordinates of "p" with respect to the basis "m". The resulting
+ // point "q" satisfies the identity (m * q == p).
+ static S2Point ToFrame(Matrix3x3_d const& m, S2Point const& p);
+
+ // Given an orthonormal basis "m" of column vectors and a point "q" with
+ // respect to that basis, return the equivalent point "p" with respect to
+ // the standard axis-aligned basis. The result satisfies (p == m * q).
+ static S2Point FromFrame(Matrix3x3_d const& m, S2Point const& q);
+
+ // the coordinates of "p" with respect to the basis "m". The resulting
+ // point "r" satisfies the identity (m * r == p).
+
+ // Return true if two points are within the given distance of each other
+ // (this is mainly useful for testing).
+ static bool ApproxEquals(S2Point const& a, S2Point const& b,
+ double max_error = 1e-15);
+
+ // Return a vector "c" that is orthogonal to the given unit-length vectors
+ // "a" and "b". This function is similar to a.CrossProd(b) except that it
+ // does a better job of ensuring orthogonality when "a" is nearly parallel
+ // to "b", and it returns a non-zero result even when a == b or a == -b.
+ //
+ // It satisfies the following properties (RCP == RobustCrossProd):
+ //
+ // (1) RCP(a,b) != 0 for all a, b
+ // (2) RCP(b,a) == -RCP(a,b) unless a == b or a == -b
+ // (3) RCP(-a,b) == -RCP(a,b) unless a == b or a == -b
+ // (4) RCP(a,-b) == -RCP(a,b) unless a == b or a == -b
+ static S2Point RobustCrossProd(S2Point const& a, S2Point const& b);
+
+ // Return true if the points A, B, C are strictly counterclockwise. Return
+ // false if the points are clockwise or collinear (i.e. if they are all
+ // contained on some great circle).
+ //
+ // Due to numerical errors, situations may arise that are mathematically
+ // impossible, e.g. ABC may be considered strictly CCW while BCA is not.
+ // However, the implementation guarantees the following:
+ //
+ // If SimpleCCW(a,b,c), then !SimpleCCW(c,b,a) for all a,b,c.
+ static bool SimpleCCW(S2Point const& a, S2Point const& b, S2Point const& c);
+
+ // Returns +1 if the points A, B, C are counterclockwise, -1 if the points
+ // are clockwise, and 0 if any two points are the same. This function is
+ // essentially like taking the sign of the determinant of ABC, except that
+ // it has additional logic to make sure that the above properties hold even
+ // when the three points are coplanar, and to deal with the limitations of
+ // floating-point arithmetic.
+ //
+ // RobustCCW satisfies the following conditions:
+ //
+ // (1) RobustCCW(a,b,c) == 0 if and only if a == b, b == c, or c == a
+ // (2) RobustCCW(b,c,a) == RobustCCW(a,b,c) for all a,b,c
+ // (3) RobustCCW(c,b,a) == -RobustCCW(a,b,c) for all a,b,c
+ //
+ // In other words:
+ //
+ // (1) The result is zero if and only if two points are the same.
+ // (2) Rotating the order of the arguments does not affect the result.
+ // (3) Exchanging any two arguments inverts the result.
+ //
+ // On the other hand, note that it is not true in general that
+ // RobustCCW(-a,b,c) == -RobustCCW(a,b,c), or any similar identities
+ // involving antipodal points.
+ static int RobustCCW(S2Point const& a, S2Point const& b, S2Point const& c);
+
+ // A more efficient version of RobustCCW that allows the precomputed
+ // cross-product of A and B to be specified. (Unlike the 3 argument
+ // version this method is also inlined.)
+ inline static int RobustCCW(S2Point const& a, S2Point const& b,
+ S2Point const& c, S2Point const& a_cross_b);
+
+ // This version of RobustCCW returns +1 if the points are definitely CCW,
+ // -1 if they are definitely CW, and 0 if two points are identical or the
+ // result is uncertain. Uncertain certain cases can be resolved, if
+ // desired, by calling ExpensiveCCW.
+ //
+ // The purpose of this method is to allow additional cheap tests to be done,
+ // where possible, in order to avoid calling ExpensiveCCW unnecessarily.
+ inline static int TriageCCW(S2Point const& a, S2Point const& b,
+ S2Point const& c, S2Point const& a_cross_b);
+
+ // This function is invoked by RobustCCW() if the sign of the determinant is
+ // uncertain. It always returns a non-zero result unless two of the input
+ // points are the same. It uses a combination of multiple-precision
+ // arithmetic and symbolic perturbations to ensure that its results are
+ // always self-consistent (cf. Simulation of Simplicity, Edelsbrunner and
+ // Muecke). The basic idea is to assign an infinitesmal symbolic
+ // perturbation to every possible S2Point such that no three S2Points are
+ // collinear and no four S2Points are coplanar. These perturbations are so
+ // small that they do not affect the sign of any determinant that was
+ // non-zero before the perturbations.
+ //
+ // Unlike RobustCCW(), this method does not require the input points to be
+ // normalized.
+ static int ExpensiveCCW(S2Point const& a, S2Point const& b,
+ S2Point const& c);
+
+ // Given 4 points on the unit sphere, return true if the edges OA, OB, and
+ // OC are encountered in that order while sweeping CCW around the point O.
+ // You can think of this as testing whether A <= B <= C with respect to the
+ // CCW ordering around O that starts at A, or equivalently, whether B is
+ // contained in the range of angles (inclusive) that starts at A and extends
+ // CCW to C. Properties:
+ //
+ // (1) If OrderedCCW(a,b,c,o) && OrderedCCW(b,a,c,o), then a == b
+ // (2) If OrderedCCW(a,b,c,o) && OrderedCCW(a,c,b,o), then b == c
+ // (3) If OrderedCCW(a,b,c,o) && OrderedCCW(c,b,a,o), then a == b == c
+ // (4) If a == b or b == c, then OrderedCCW(a,b,c,o) is true
+ // (5) Otherwise if a == c, then OrderedCCW(a,b,c,o) is false
+ static bool OrderedCCW(S2Point const& a, S2Point const& b, S2Point const& c,
+ S2Point const& o);
+
+ // Return the interior angle at the vertex B in the triangle ABC. The
+ // return value is always in the range [0, Pi]. The points do not need to
+ // be normalized. Ensures that Angle(a,b,c) == Angle(c,b,a) for all a,b,c.
+ //
+ // The angle is undefined if A or C is diametrically opposite from B, and
+ // becomes numerically unstable as the length of edge AB or BC approaches
+ // 180 degrees.
+ static double Angle(S2Point const& a, S2Point const& b, S2Point const& c);
+
+ // Return the exterior angle at the vertex B in the triangle ABC. The
+ // return value is positive if ABC is counterclockwise and negative
+ // otherwise. If you imagine an ant walking from A to B to C, this is the
+ // angle that the ant turns at vertex B (positive = left, negative = right).
+ // Ensures that TurnAngle(a,b,c) == -TurnAngle(c,b,a) for all a,b,c.
+ static double TurnAngle(S2Point const& a, S2Point const& b, S2Point const& c);
+
+ // Return the area of triangle ABC. The method used is about twice as
+ // expensive as Girard's formula, but it is numerically stable for both
+ // large and very small triangles. All points should be unit length.
+ // The area is always positive.
+ //
+ // The triangle area is undefined if it contains two antipodal points, and
+ // becomes numerically unstable as the length of any edge approaches 180
+ // degrees.
+ static double Area(S2Point const& a, S2Point const& b, S2Point const& c);
+
+ // Return the area of the triangle computed using Girard's formula. All
+ // points should be unit length. This is slightly faster than the Area()
+ // method above but is not accurate for very small triangles.
+ static double GirardArea(S2Point const& a, S2Point const& b,
+ S2Point const& c);
+
+ // Like Area(), but returns a positive value for counterclockwise triangles
+ // and a negative value otherwise.
+ static double SignedArea(S2Point const& a, S2Point const& b,
+ S2Point const& c);
+
+ // About centroids:
+ // ----------------
+ //
+ // There are several notions of the "centroid" of a triangle. First, there
+ // // is the planar centroid, which is simply the centroid of the ordinary
+ // (non-spherical) triangle defined by the three vertices. Second, there is
+ // the surface centroid, which is defined as the intersection of the three
+ // medians of the spherical triangle. It is possible to show that this
+ // point is simply the planar centroid projected to the surface of the
+ // sphere. Finally, there is the true centroid (mass centroid), which is
+ // defined as the area integral over the spherical triangle of (x,y,z)
+ // divided by the triangle area. This is the point that the triangle would
+ // rotate around if it was spinning in empty space.
+ //
+ // The best centroid for most purposes is the true centroid. Unlike the
+ // planar and surface centroids, the true centroid behaves linearly as
+ // regions are added or subtracted. That is, if you split a triangle into
+ // pieces and compute the average of their centroids (weighted by triangle
+ // area), the result equals the centroid of the original triangle. This is
+ // not true of the other centroids.
+ //
+ // Also note that the surface centroid may be nowhere near the intuitive
+ // "center" of a spherical triangle. For example, consider the triangle
+ // with vertices A=(1,eps,0), B=(0,0,1), C=(-1,eps,0) (a quarter-sphere).
+ // The surface centroid of this triangle is at S=(0, 2*eps, 1), which is
+ // within a distance of 2*eps of the vertex B. Note that the median from A
+ // (the segment connecting A to the midpoint of BC) passes through S, since
+ // this is the shortest path connecting the two endpoints. On the other
+ // hand, the true centroid is at M=(0, 0.5, 0.5), which when projected onto
+ // the surface is a much more reasonable interpretation of the "center" of
+ // this triangle.
+
+ // Return the centroid of the planar triangle ABC. This can be normalized
+ // to unit length to obtain the "surface centroid" of the corresponding
+ // spherical triangle, i.e. the intersection of the three medians. However,
+ // note that for large spherical triangles the surface centroid may be
+ // nowhere near the intuitive "center" (see example above).
+ static S2Point PlanarCentroid(S2Point const& a, S2Point const& b,
+ S2Point const& c);
+
+ // Returns the true centroid of the spherical triangle ABC multiplied by the
+ // signed area of spherical triangle ABC. The reasons for multiplying by
+ // the signed area are (1) this is the quantity that needs to be summed to
+ // compute the centroid of a union or difference of triangles, and (2) it's
+ // actually easier to calculate this way.
+ static S2Point TrueCentroid(S2Point const& a, S2Point const& b,
+ S2Point const& c);
+
+ ////////////////////////// S2Cell Decomposition /////////////////////////
+ //
+ // The following methods define the cube-to-sphere projection used by
+ // the S2Cell decomposition.
+ //
+ // In the process of converting a latitude-longitude pair to a 64-bit cell
+ // id, the following coordinate systems are used:
+ //
+ // (id)
+ // An S2CellId is a 64-bit encoding of a face and a Hilbert curve position
+ // on that face. The Hilbert curve position implicitly encodes both the
+ // position of a cell and its subdivision level (see s2cellid.h).
+ //
+ // (face, i, j)
+ // Leaf-cell coordinates. "i" and "j" are integers in the range
+ // [0,(2**30)-1] that identify a particular leaf cell on the given face.
+ // The (i, j) coordinate system is right-handed on each face, and the
+ // faces are oriented such that Hilbert curves connect continuously from
+ // one face to the next.
+ //
+ // (face, s, t)
+ // Cell-space coordinates. "s" and "t" are real numbers in the range
+ // [0,1] that identify a point on the given face. For example, the point
+ // (s, t) = (0.5, 0.5) corresponds to the center of the top-level face
+ // cell. This point is also a vertex of exactly four cells at each
+ // subdivision level greater than zero.
+ //
+ // (face, si, ti)
+ // Discrete cell-space coordinates. These are obtained by multiplying
+ // "s" and "t" by 2**31 and rounding to the nearest unsigned integer.
+ // Discrete coordinates lie in the range [0,2**31]. This coordinate
+ // system can represent the edge and center positions of all cells with
+ // no loss of precision (including non-leaf cells).
+ //
+ // (face, u, v)
+ // Cube-space coordinates. To make the cells at each level more uniform
+ // in size after they are projected onto the sphere, we apply apply a
+ // nonlinear transformation of the form u=f(s), v=f(t). The (u, v)
+ // coordinates after this transformation give the actual coordinates on
+ // the cube face (modulo some 90 degree rotations) before it is projected
+ // onto the unit sphere.
+ //
+ // (x, y, z)
+ // Direction vector (S2Point). Direction vectors are not necessarily unit
+ // length, and are often chosen to be points on the biunit cube
+ // [-1,+1]x[-1,+1]x[-1,+1]. They can be be normalized to obtain the
+ // corresponding point on the unit sphere.
+ //
+ // (lat, lng)
+ // Latitude and longitude (S2LatLng). Latitudes must be between -90 and
+ // 90 degrees inclusive, and longitudes must be between -180 and 180
+ // degrees inclusive.
+ //
+ // Note that the (i, j), (s, t), (si, ti), and (u, v) coordinate systems are
+ // right-handed on all six faces.
+
+ // Convert an s or t value to the corresponding u or v value. This is
+ // a non-linear transformation from [-1,1] to [-1,1] that attempts to
+ // make the cell sizes more uniform.
+ inline static double STtoUV(double s);
+
+ // The inverse of the STtoUV transformation. Note that it is not always
+ // true that UVtoST(STtoUV(x)) == x due to numerical errors.
+ inline static double UVtoST(double u);
+
+ // Convert (face, u, v) coordinates to a direction vector (not
+ // necessarily unit length).
+ inline static S2Point FaceUVtoXYZ(int face, double u, double v);
+
+ // If the dot product of p with the given face normal is positive,
+ // set the corresponding u and v values (which may lie outside the range
+ // [-1,1]) and return true. Otherwise return false.
+ inline static bool FaceXYZtoUV(int face, S2Point const& p,
+ double* pu, double* pv);
+
+ // Convert a direction vector (not necessarily unit length) to
+ // (face, u, v) coordinates.
+ inline static int XYZtoFaceUV(S2Point const& p, double* pu, double* pv);
+
+ // Return the right-handed normal (not necessarily unit length) for an
+ // edge in the direction of the positive v-axis at the given u-value on
+ // the given face. (This vector is perpendicular to the plane through
+ // the sphere origin that contains the given edge.)
+ inline static S2Point GetUNorm(int face, double u);
+
+ // Return the right-handed normal (not necessarily unit length) for an
+ // edge in the direction of the positive u-axis at the given v-value on
+ // the given face.
+ inline static S2Point GetVNorm(int face, double v);
+
+ // Return the unit-length normal, u-axis, or v-axis for the given face.
+ inline static S2Point GetNorm(int face);
+ inline static S2Point GetUAxis(int face);
+ inline static S2Point GetVAxis(int face);
+
+ ////////////////////////////////////////////////////////////////////////
+ // The canonical Hilbert traversal order looks like an inverted 'U':
+ // the subcells are visited in the order (0,0), (0,1), (1,1), (1,0).
+ // The following tables encode the traversal order for various
+ // orientations of the Hilbert curve (axes swapped and/or directions
+ // of the axes reversed).
+
+ // Together these flags define a cell orientation. If 'kSwapMask'
+ // is true, then canonical traversal order is flipped around the
+ // diagonal (i.e. i and j are swapped with each other). If
+ // 'kInvertMask' is true, then the traversal order is rotated by 180
+ // degrees (i.e. the bits of i and j are inverted, or equivalently,
+ // the axis directions are reversed).
+ static int const kSwapMask;
+ static int const kInvertMask;
+
+ // This is the number of levels needed to specify a leaf cell. This
+ // constant is defined here so that the S2::Metric class can be
+ // implemented without including s2cellid.h.
+ static int const kMaxCellLevel;
+
+ // kIJtoPos[orientation][ij] -> pos
+ //
+ // Given a cell orientation and the (i,j)-index of a subcell (0=(0,0),
+ // 1=(0,1), 2=(1,0), 3=(1,1)), return the order in which this subcell is
+ // visited by the Hilbert curve (a position in the range [0..3]).
+ static int const kIJtoPos[4][4];
+
+ // kPosToIJ[orientation][pos] -> ij
+ //
+ // Return the (i,j) index of the subcell at the given position 'pos' in the
+ // Hilbert curve traversal order with the given orientation. This is the
+ // inverse of the previous table:
+ //
+ // kPosToIJ[r][kIJtoPos[r][ij]] == ij
+ static int const kPosToIJ[4][4];
+
+ // kPosToOrientation[pos] -> orientation_modifier
+ //
+ // Return a modifier indicating how the orientation of the child subcell
+ // with the given traversal position [0..3] is related to the orientation
+ // of the parent cell. The modifier should be XOR-ed with the parent
+ // orientation to obtain the curve orientation in the child.
+ static int const kPosToOrientation[4];
+
+ ////////////////////////// S2Cell Metrics //////////////////////////////
+ //
+ // The following are various constants that describe the shapes and sizes of
+ // cells. They are useful for deciding which cell level to use in order to
+ // satisfy a given condition (e.g. that cell vertices must be no further
+ // than "x" apart). All of the raw constants are differential quantities;
+ // you can use the GetValue(level) method to compute the corresponding length
+ // or area on the unit sphere for cells at a given level. The minimum and
+ // maximum bounds are valid for cells at all levels, but they may be
+ // somewhat conservative for very large cells (e.g. face cells).
+
+ // Defines a cell metric of the given dimension (1 == length, 2 == area).
+ template <int dim> class Metric {
+ public:
+ explicit Metric(double deriv) : deriv_(deriv) {}
+
+ // The "deriv" value of a metric is a derivative, and must be multiplied by
+ // a length or area in (s,t)-space to get a useful value.
+ double deriv() const { return deriv_; }
+
+ // Return the value of a metric for cells at the given level. The value is
+ // either a length or an area on the unit sphere, depending on the
+ // particular metric.
+ double GetValue(int level) const { return ldexp(deriv_, - dim * level); }
+
+ // Return the level at which the metric has approximately the given
+ // value. For example, S2::kAvgEdge.GetClosestLevel(0.1) returns the
+ // level at which the average cell edge length is approximately 0.1.
+ // The return value is always a valid level.
+ int GetClosestLevel(double value) const;
+
+ // Return the minimum level such that the metric is at most the given
+ // value, or S2CellId::kMaxLevel if there is no such level. For example,
+ // S2::kMaxDiag.GetMinLevel(0.1) returns the minimum level such that all
+ // cell diagonal lengths are 0.1 or smaller. The return value is always a
+ // valid level.
+ int GetMinLevel(double value) const;
+
+ // Return the maximum level such that the metric is at least the given
+ // value, or zero if there is no such level. For example,
+ // S2::kMinWidth.GetMaxLevel(0.1) returns the maximum level such that all
+ // cells have a minimum width of 0.1 or larger. The return value is
+ // always a valid level.
+ int GetMaxLevel(double value) const;
+
+ private:
+ double const deriv_;
+ DISALLOW_EVIL_CONSTRUCTORS(Metric);
+ };
+ typedef Metric<1> LengthMetric;
+ typedef Metric<2> AreaMetric;
+
+ // Each cell is bounded by four planes passing through its four edges and
+ // the center of the sphere. These metrics relate to the angle between each
+ // pair of opposite bounding planes, or equivalently, between the planes
+ // corresponding to two different s-values or two different t-values. For
+ // example, the maximum angle between opposite bounding planes for a cell at
+ // level k is kMaxAngleSpan.GetValue(k), and the average angle span for all
+ // cells at level k is approximately kAvgAngleSpan.GetValue(k).
+ static LengthMetric const kMinAngleSpan;
+ static LengthMetric const kMaxAngleSpan;
+ static LengthMetric const kAvgAngleSpan;
+
+ // The width of geometric figure is defined as the distance between two
+ // parallel bounding lines in a given direction. For cells, the minimum
+ // width is always attained between two opposite edges, and the maximum
+ // width is attained between two opposite vertices. However, for our
+ // purposes we redefine the width of a cell as the perpendicular distance
+ // between a pair of opposite edges. A cell therefore has two widths, one
+ // in each direction. The minimum width according to this definition agrees
+ // with the classic geometric one, but the maximum width is different. (The
+ // maximum geometric width corresponds to kMaxDiag defined below.)
+ //
+ // For a cell at level k, the distance between opposite edges is at least
+ // kMinWidth.GetValue(k) and at most kMaxWidth.GetValue(k). The average
+ // width in both directions for all cells at level k is approximately
+ // kAvgWidth.GetValue(k).
+ //
+ // The width is useful for bounding the minimum or maximum distance from a
+ // point on one edge of a cell to the closest point on the opposite edge.
+ // For example, this is useful when "growing" regions by a fixed distance.
+ static LengthMetric const kMinWidth;
+ static LengthMetric const kMaxWidth;
+ static LengthMetric const kAvgWidth;
+
+ // The minimum edge length of any cell at level k is at least
+ // kMinEdge.GetValue(k), and the maximum is at most kMaxEdge.GetValue(k).
+ // The average edge length is approximately kAvgEdge.GetValue(k).
+ //
+ // The edge length metrics can also be used to bound the minimum, maximum,
+ // or average distance from the center of one cell to the center of one of
+ // its edge neighbors. In particular, it can be used to bound the distance
+ // between adjacent cell centers along the space-filling Hilbert curve for
+ // cells at any given level.
+ static LengthMetric const kMinEdge;
+ static LengthMetric const kMaxEdge;
+ static LengthMetric const kAvgEdge;
+
+ // The minimum diagonal length of any cell at level k is at least
+ // kMinDiag.GetValue(k), and the maximum is at most kMaxDiag.GetValue(k).
+ // The average diagonal length is approximately kAvgDiag.GetValue(k).
+ //
+ // The maximum diagonal also happens to be the maximum diameter of any cell,
+ // and also the maximum geometric width (see the discussion above). So for
+ // example, the distance from an arbitrary point to the closest cell center
+ // at a given level is at most half the maximum diagonal length.
+ static LengthMetric const kMinDiag;
+ static LengthMetric const kMaxDiag;
+ static LengthMetric const kAvgDiag;
+
+ // The minimum area of any cell at level k is at least kMinArea.GetValue(k),
+ // and the maximum is at most kMaxArea.GetValue(k). The average area of all
+ // cells at level k is exactly kAvgArea.GetValue(k).
+ static AreaMetric const kMinArea;
+ static AreaMetric const kMaxArea;
+ static AreaMetric const kAvgArea;
+
+ // This is the maximum edge aspect ratio over all cells at any level, where
+ // the edge aspect ratio of a cell is defined as the ratio of its longest
+ // edge length to its shortest edge length.
+ static double const kMaxEdgeAspect;
+
+ // This is the maximum diagonal aspect ratio over all cells at any level,
+ // where the diagonal aspect ratio of a cell is defined as the ratio of its
+ // longest diagonal length to its shortest diagonal length.
+ static double const kMaxDiagAspect;
+
+ private:
+ // Given a *valid* face for the given point p (meaning that dot product
+ // of p with the face normal is positive), return the corresponding
+ // u and v values (which may lie outside the range [-1,1]).
+ inline static void ValidFaceXYZtoUV(int face, S2Point const& p,
+ double* pu, double* pv);
+
+ // The value below is the maximum error in computing the determinant
+ // a.CrossProd(b).DotProd(c). To derive this, observe that computing the
+ // determinant in this way requires 14 multiplications and additions. Since
+ // all three points are normalized, none of the intermediate results in this
+ // calculation exceed 1.0 in magnitude. The maximum rounding error for an
+ // operation whose result magnitude does not exceed 1.0 (before rounding) is
+ // 2**-54 (i.e., half of the difference between 1.0 and the next
+ // representable value below 1.0). Therefore, the total error in computing
+ // the determinant does not exceed 14 * (2**-54).
+ //
+ // The C++ standard requires to initialize kMaxDetError outside of
+ // the class definition, even though GCC doesn't enforce it.
+ static double const kMaxDetError;
+
+ DISALLOW_IMPLICIT_CONSTRUCTORS(S2); // Contains only static methods.
+};
+
+// Uncomment the following line for testing purposes only. It greatly
+// increases the number of degenerate cases that need to be handled using
+// ExpensiveCCW().
+// #define S2_TEST_DEGENERACIES
+
+inline S2Point S2::Origin() {
+#ifdef S2_TEST_DEGENERACIES
+ return S2Point(0, 0, 1); // This makes polygon operations much slower.
+#else
+ return S2Point(0.00457, 1, 0.0321).Normalize();
+#endif
+}
+
+inline int S2::TriageCCW(S2Point const& a, S2Point const& b,
+ S2Point const& c, S2Point const& a_cross_b) {
+ DCHECK(IsUnitLength(a));
+ DCHECK(IsUnitLength(b));
+ DCHECK(IsUnitLength(c));
+ double det = a_cross_b.DotProd(c);
+
+ // Double-check borderline cases in debug mode.
+ DCHECK(fabs(det) < kMaxDetError ||
+ fabs(det) > 100 * kMaxDetError ||
+ det * ExpensiveCCW(a, b, c) > 0);
+
+ if (det > kMaxDetError) return 1;
+ if (det < -kMaxDetError) return -1;
+ return 0;
+}
+
+inline int S2::RobustCCW(S2Point const& a, S2Point const& b,
+ S2Point const& c, S2Point const& a_cross_b) {
+ int ccw = TriageCCW(a, b, c, a_cross_b);
+ if (ccw == 0) ccw = ExpensiveCCW(a, b, c);
+ return ccw;
+}
+
+// We have implemented three different projections from cell-space (s,t) to
+// cube-space (u,v): linear, quadratic, and tangent. They have the following
+// tradeoffs:
+//
+// Linear - This is the fastest transformation, but also produces the least
+// uniform cell sizes. Cell areas vary by a factor of about 5.2, with the
+// largest cells at the center of each face and the smallest cells in
+// the corners.
+//
+// Tangent - Transforming the coordinates via atan() makes the cell sizes
+// more uniform. The areas vary by a maximum ratio of 1.4 as opposed to a
+// maximum ratio of 5.2. However, each call to atan() is about as expensive
+// as all of the other calculations combined when converting from points to
+// cell ids, i.e. it reduces performance by a factor of 3.
+//
+// Quadratic - This is an approximation of the tangent projection that
+// is much faster and produces cells that are almost as uniform in size.
+// It is about 3 times faster than the tangent projection for converting
+// cell ids to points or vice versa. Cell areas vary by a maximum ratio of
+// about 2.1.
+//
+// Here is a table comparing the cell uniformity using each projection. "Area
+// ratio" is the maximum ratio over all subdivision levels of the largest cell
+// area to the smallest cell area at that level, "edge ratio" is the maximum
+// ratio of the longest edge of any cell to the shortest edge of any cell at
+// the same level, and "diag ratio" is the ratio of the longest diagonal of
+// any cell to the shortest diagonal of any cell at the same level. "ToPoint"
+// and "FromPoint" are the times in microseconds required to convert cell ids
+// to and from points (unit vectors) respectively. "ToPointRaw" is the time
+// to convert to a non-unit-length vector, which is all that is needed for
+// some purposes.
+//
+// Area Edge Diag ToPointRaw ToPoint FromPoint
+// Ratio Ratio Ratio (microseconds)
+// -------------------------------------------------------------------
+// Linear: 5.200 2.117 2.959 0.020 0.087 0.085
+// Tangent: 1.414 1.414 1.704 0.237 0.299 0.258
+// Quadratic: 2.082 1.802 1.932 0.033 0.096 0.108
+//
+// The worst-case cell aspect ratios are about the same with all three
+// projections. The maximum ratio of the longest edge to the shortest edge
+// within the same cell is about 1.4 and the maximum ratio of the diagonals
+// within the same cell is about 1.7.
+//
+// This data was produced using s2cell_unittest and s2cellid_unittest.
+
+#define S2_LINEAR_PROJECTION 0
+#define S2_TAN_PROJECTION 1
+#define S2_QUADRATIC_PROJECTION 2
+
+#define S2_PROJECTION S2_QUADRATIC_PROJECTION
+
+#if S2_PROJECTION == S2_LINEAR_PROJECTION
+
+inline double S2::STtoUV(double s) {
+ return 2 * s - 1;
+}
+
+inline double S2::UVtoST(double u) {
+ return 0.5 * (u + 1);
+}
+
+#elif S2_PROJECTION == S2_TAN_PROJECTION
+
+inline double S2::STtoUV(double s) {
+ // Unfortunately, tan(M_PI_4) is slightly less than 1.0. This isn't due to
+ // a flaw in the implementation of tan(), it's because the derivative of
+ // tan(x) at x=pi/4 is 2, and it happens that the two adjacent floating
+ // point numbers on either side of the infinite-precision value of pi/4 have
+ // tangents that are slightly below and slightly above 1.0 when rounded to
+ // the nearest double-precision result.
+
+ s = tan(M_PI_2 * s - M_PI_4);
+ return s + (1.0 / (GG_LONGLONG(1) << 53)) * s;
+}
+
+inline double S2::UVtoST(double u) {
+ volatile double a = atan(u);
+ return (2 * M_1_PI) * (a + M_PI_4);
+}
+
+#elif S2_PROJECTION == S2_QUADRATIC_PROJECTION
+
+inline double S2::STtoUV(double s) {
+ if (s >= 0.5) return (1/3.) * (4*s*s - 1);
+ else return (1/3.) * (1 - 4*(1-s)*(1-s));
+}
+
+inline double S2::UVtoST(double u) {
+ if (u >= 0) return 0.5 * sqrt(1 + 3*u);
+ else return 1 - 0.5 * sqrt(1 - 3*u);
+}
+
+#else
+
+#error Unknown value for S2_PROJECTION
+
+#endif
+
+inline S2Point S2::FaceUVtoXYZ(int face, double u, double v) {
+ switch (face) {
+ case 0: return S2Point( 1, u, v);
+ case 1: return S2Point(-u, 1, v);
+ case 2: return S2Point(-u, -v, 1);
+ case 3: return S2Point(-1, -v, -u);
+ case 4: return S2Point( v, -1, -u);
+ default: return S2Point( v, u, -1);
+ }
+}
+
+inline void S2::ValidFaceXYZtoUV(int face, S2Point const& p,
+ double* pu, double* pv) {
+ DCHECK_GT(p.DotProd(FaceUVtoXYZ(face, 0, 0)), 0);
+ switch (face) {
+ case 0: *pu = p[1] / p[0]; *pv = p[2] / p[0]; break;
+ case 1: *pu = -p[0] / p[1]; *pv = p[2] / p[1]; break;
+ case 2: *pu = -p[0] / p[2]; *pv = -p[1] / p[2]; break;
+ case 3: *pu = p[2] / p[0]; *pv = p[1] / p[0]; break;
+ case 4: *pu = p[2] / p[1]; *pv = -p[0] / p[1]; break;
+ default: *pu = -p[1] / p[2]; *pv = -p[0] / p[2]; break;
+ }
+}
+
+inline int S2::XYZtoFaceUV(S2Point const& p, double* pu, double* pv) {
+ int face = p.LargestAbsComponent();
+ if (p[face] < 0) face += 3;
+ ValidFaceXYZtoUV(face, p, pu, pv);
+ return face;
+}
+
+inline bool S2::FaceXYZtoUV(int face, S2Point const& p,
+ double* pu, double* pv) {
+ if (face < 3) {
+ if (p[face] <= 0) return false;
+ } else {
+ if (p[face-3] >= 0) return false;
+ }
+ ValidFaceXYZtoUV(face, p, pu, pv);
+ return true;
+}
+
+inline S2Point S2::GetUNorm(int face, double u) {
+ switch (face) {
+ case 0: return S2Point( u, -1, 0);
+ case 1: return S2Point( 1, u, 0);
+ case 2: return S2Point( 1, 0, u);
+ case 3: return S2Point(-u, 0, 1);
+ case 4: return S2Point( 0, -u, 1);
+ default: return S2Point( 0, -1, -u);
+ }
+}
+
+inline S2Point S2::GetVNorm(int face, double v) {
+ switch (face) {
+ case 0: return S2Point(-v, 0, 1);
+ case 1: return S2Point( 0, -v, 1);
+ case 2: return S2Point( 0, -1, -v);
+ case 3: return S2Point( v, -1, 0);
+ case 4: return S2Point( 1, v, 0);
+ default: return S2Point( 1, 0, v);
+ }
+}
+
+inline S2Point S2::GetNorm(int face) {
+ return S2::FaceUVtoXYZ(face, 0, 0);
+}
+
+inline S2Point S2::GetUAxis(int face) {
+ switch (face) {
+ case 0: return S2Point( 0, 1, 0);
+ case 1: return S2Point(-1, 0, 0);
+ case 2: return S2Point(-1, 0, 0);
+ case 3: return S2Point( 0, 0, -1);
+ case 4: return S2Point( 0, 0, -1);
+ default: return S2Point( 0, 1, 0);
+ }
+}
+
+inline S2Point S2::GetVAxis(int face) {
+ switch (face) {
+ case 0: return S2Point( 0, 0, 1);
+ case 1: return S2Point( 0, 0, 1);
+ case 2: return S2Point( 0, -1, 0);
+ case 3: return S2Point( 0, -1, 0);
+ case 4: return S2Point( 1, 0, 0);
+ default: return S2Point( 1, 0, 0);
+ }
+}
+
+template <int dim>
+int S2::Metric<dim>::GetMinLevel(double value) const {
+ if (value <= 0) return S2::kMaxCellLevel;
+
+ // This code is equivalent to computing a floating-point "level"
+ // value and rounding up. frexp() returns a fraction in the
+ // range [0.5,1) and the corresponding exponent.
+ int level;
+ frexp(value / deriv_, &level);
+ level = max(0, min(S2::kMaxCellLevel, -((level - 1) >> (dim - 1))));
+ DCHECK(level == S2::kMaxCellLevel || GetValue(level) <= value);
+ DCHECK(level == 0 || GetValue(level - 1) > value);
+ return level;
+}
+
+template <int dim>
+int S2::Metric<dim>::GetMaxLevel(double value) const {
+ if (value <= 0) return S2::kMaxCellLevel;
+
+ // This code is equivalent to computing a floating-point "level"
+ // value and rounding down.
+ int level;
+ frexp(deriv_ / value, &level);
+ level = max(0, min(S2::kMaxCellLevel, (level - 1) >> (dim - 1)));
+ DCHECK(level == 0 || GetValue(level) >= value);
+ DCHECK(level == S2::kMaxCellLevel || GetValue(level + 1) < value);
+ return level;
+}
+
+template <int dim>
+int S2::Metric<dim>::GetClosestLevel(double value) const {
+ return GetMinLevel((dim == 1 ? M_SQRT2 : 2) * value);
+}
+
+#endif // UTIL_GEOMETRY_S2_H_
diff --git a/src/third_party/s2/s2.swig b/src/third_party/s2/s2.swig
new file mode 100644
index 00000000000..47f731a2bd4
--- /dev/null
+++ b/src/third_party/s2/s2.swig
@@ -0,0 +1,120 @@
+// Copyright 2006 Google Inc. All Rights Reserved.
+// Author: Andrew Eland (andrewe@google.com)
+
+%include base/google.swig
+
+%{
+#include <strstream>
+
+#include "util/geometry/s2cellid.h"
+#include "util/geometry/s2region.h"
+#include "util/geometry/s2cap.h"
+#include "util/geometry/s2latlng.h"
+#include "util/geometry/s2latlngrect.h"
+#include "util/geometry/s2regioncoverer.h"
+#include "util/geometry/s2cell.h"
+#include "util/geometry/s2cellunion.h"
+%}
+
+// The PACKED macro makes SWIG think that we're declaring a variable of type
+// S2CellId named PACKED. We don't need it so we clobber it with an empty body.
+#define PACKED
+
+// The DECLARE_POD macro makes SWIG think the specified type's defined twice.
+// We don't need it, so we can just remove it.
+#define DECLARE_POD(TypeName)
+
+// Warning 510 is "friend function 'operator +' ignored.". We can't do anything
+// about that.
+#pragma SWIG nowarn=510
+
+// If we don't ignore this, the wrapper ends up assigning to None
+%ignore S2CellId::None;
+
+#ifdef SWIGPYTHON
+
+%inline %{
+ static PyObject *FromS2CellId(const S2CellId &cell_id) {
+ return SWIG_NewPointerObj(new S2CellId(cell_id), SWIGTYPE_p_S2CellId, 1);
+ }
+%}
+
+%typemap(in, numinputs=0)
+vector<S2CellId> *OUTPUT(vector<S2CellId> temp) {
+ $1 = &temp;
+}
+
+%typemap(argout, fragment="t_output_helper")
+vector<S2CellId> *OUTPUT {
+ $result = t_output_helper($result, vector_output_helper($1, &FromS2CellId));
+}
+
+%apply vector<S2CellId> *OUTPUT {vector<S2CellId> *covering};
+%apply vector<S2CellId> *OUTPUT {vector<S2CellId> *output};
+
+#endif
+
+%include "util/geometry/r1interval.h"
+%include "util/geometry/s1angle.h"
+%include "util/geometry/s1interval.h"
+%include "util/geometry/s2cellid.h"
+%include "util/geometry/s2region.h"
+%include "util/geometry/s2cap.h"
+%include "util/geometry/s2latlng.h"
+%include "util/geometry/s2latlngrect.h"
+%include "util/geometry/s2regioncoverer.h"
+%include "util/geometry/s2cell.h"
+%include "util/geometry/s2cellunion.h"
+
+%define USE_STREAM_INSERTOR_FOR_STR(type)
+ %extend type {
+ string __str__() {
+ ostrstream output;
+ output << *self << std::ends;
+ return output.str();
+ }
+ }
+%enddef
+
+%define USE_EQUALS_FOR_EQ_AND_NE(type)
+ %extend type {
+ bool __eq__(const type& other) {
+ return *self == other;
+ }
+
+ bool __ne__(const type& other) {
+ return *self != other;
+ }
+ }
+%enddef
+
+%define USE_COMPARISON_FOR_LT_AND_GT(type)
+ %extend type {
+ bool __lt__(const type& other) {
+ return *self < other;
+ }
+
+ bool __gt__(const type& other) {
+ return *self > other;
+ }
+ }
+%enddef
+
+%define USE_STD_HASH_FOR_HASH(type)
+ %extend type {
+ size_t __hash__() {
+ return HASH_NAMESPACE::hash<type>()(*self);
+ }
+ }
+%enddef
+
+USE_STREAM_INSERTOR_FOR_STR(S1Angle)
+USE_STREAM_INSERTOR_FOR_STR(S1Interval)
+USE_STREAM_INSERTOR_FOR_STR(S2CellId)
+USE_STREAM_INSERTOR_FOR_STR(S2Cap)
+USE_STREAM_INSERTOR_FOR_STR(S2LatLng)
+USE_STREAM_INSERTOR_FOR_STR(S2LatLngRect)
+
+USE_EQUALS_FOR_EQ_AND_NE(S2CellId)
+USE_COMPARISON_FOR_LT_AND_GT(S2CellId)
+USE_STD_HASH_FOR_HASH(S2CellId)
diff --git a/src/third_party/s2/s2_test.cc b/src/third_party/s2/s2_test.cc
new file mode 100644
index 00000000000..0ff629c351d
--- /dev/null
+++ b/src/third_party/s2/s2_test.cc
@@ -0,0 +1,743 @@
+// Copyright 2005 Google Inc. All Rights Reserved.
+
+#include <algorithm>
+#include <functional>
+using namespace std;
+using std::min;
+using std::max;
+using std::swap;
+using std::reverse;
+
+#include <hash_set>
+#include <hash_map>
+using __gnu_cxx::hash_set;
+
+#include "s2.h"
+#include "base/logging.h"
+#include "s2latlng.h"
+#include "s2testing.h"
+#include "util/math/matrix3x3-inl.h"
+#include "gtest/gtest.h"
+
+static inline int SwapAxes(int ij) {
+ return ((ij >> 1) & 1) + ((ij & 1) << 1);
+}
+
+static inline int InvertBits(int ij) {
+ return ij ^ 3;
+}
+
+TEST(S2, TraversalOrder) {
+ for (int r = 0; r < 4; ++r) {
+ for (int i = 0; i < 4; ++i) {
+ // Check consistency with respect to swapping axes.
+ EXPECT_EQ(S2::kIJtoPos[r][i],
+ S2::kIJtoPos[r ^ S2::kSwapMask][SwapAxes(i)]);
+ EXPECT_EQ(S2::kPosToIJ[r][i],
+ SwapAxes(S2::kPosToIJ[r ^ S2::kSwapMask][i]));
+
+ // Check consistency with respect to reversing axis directions.
+ EXPECT_EQ(S2::kIJtoPos[r][i],
+ S2::kIJtoPos[r ^ S2::kInvertMask][InvertBits(i)]);
+ EXPECT_EQ(S2::kPosToIJ[r][i],
+ InvertBits(S2::kPosToIJ[r ^ S2::kInvertMask][i]));
+
+ // Check that the two tables are inverses of each other.
+ EXPECT_EQ(S2::kIJtoPos[r][S2::kPosToIJ[r][i]], i);
+ EXPECT_EQ(S2::kPosToIJ[r][S2::kIJtoPos[r][i]], i);
+ }
+ }
+}
+
+TEST(S2, ST_UV_Conversions) {
+ // Check boundary conditions.
+ for (double s = 0; s <= 1; s += 0.5) {
+ volatile double u = S2::STtoUV(s);
+ EXPECT_EQ(u, 2 * s - 1);
+ }
+ for (double u = -1; u <= 1; ++u) {
+ volatile double s = S2::UVtoST(u);
+ EXPECT_EQ(s, 0.5 * (u + 1));
+ }
+ // Check that UVtoST and STtoUV are inverses.
+ for (double x = 0; x <= 1; x += 0.0001) {
+ EXPECT_NEAR(S2::UVtoST(S2::STtoUV(x)), x, 1e-15);
+ EXPECT_NEAR(S2::STtoUV(S2::UVtoST(2*x-1)), 2*x-1, 1e-15);
+ }
+}
+
+TEST(S2, FaceUVtoXYZ) {
+ // Check that each face appears exactly once.
+ S2Point sum;
+ for (int face = 0; face < 6; ++face) {
+ S2Point center = S2::FaceUVtoXYZ(face, 0, 0);
+ EXPECT_EQ(S2::GetNorm(face), center);
+ EXPECT_EQ(fabs(center[center.LargestAbsComponent()]), 1);
+ sum += center.Fabs();
+ }
+ EXPECT_EQ(sum, S2Point(2, 2, 2));
+
+ // Check that each face has a right-handed coordinate system.
+ for (int face = 0; face < 6; ++face) {
+ EXPECT_EQ(S2::GetUAxis(face).CrossProd(S2::GetVAxis(face))
+ .DotProd(S2::FaceUVtoXYZ(face, 0, 0)), 1);
+ }
+
+ // Check that the Hilbert curves on each face combine to form a
+ // continuous curve over the entire cube.
+ for (int face = 0; face < 6; ++face) {
+ // The Hilbert curve on each face starts at (-1,-1) and terminates
+ // at either (1,-1) (if axes not swapped) or (-1,1) (if swapped).
+ int sign = (face & S2::kSwapMask) ? -1 : 1;
+ EXPECT_EQ(S2::FaceUVtoXYZ(face, sign, -sign),
+ S2::FaceUVtoXYZ((face + 1) % 6, -1, -1));
+ }
+}
+
+TEST(S2, UVNorms) {
+ // Check that GetUNorm and GetVNorm compute right-handed normals for
+ // an edge in the increasing U or V direction.
+ for (int face = 0; face < 6; ++face) {
+ for (double x = -1; x <= 1; x += 1/1024.) {
+ EXPECT_DOUBLE_EQ(S2::FaceUVtoXYZ(face, x, -1)
+ .CrossProd(S2::FaceUVtoXYZ(face, x, 1))
+ .Angle(S2::GetUNorm(face, x)), 0);
+ EXPECT_DOUBLE_EQ(S2::FaceUVtoXYZ(face, -1, x)
+ .CrossProd(S2::FaceUVtoXYZ(face, 1, x))
+ .Angle(S2::GetVNorm(face, x)), 0);
+ }
+ }
+}
+
+TEST(S2, UVAxes) {
+ // Check that axes are consistent with FaceUVtoXYZ.
+ for (int face = 0; face < 6; ++face) {
+ EXPECT_EQ(S2::GetUAxis(face),
+ S2::FaceUVtoXYZ(face, 1, 0) - S2::FaceUVtoXYZ(face, 0, 0));
+ EXPECT_EQ(S2::GetVAxis(face),
+ S2::FaceUVtoXYZ(face, 0, 1) - S2::FaceUVtoXYZ(face, 0, 0));
+ }
+}
+
+TEST(S2, AnglesAreas) {
+ S2Point pz(0, 0, 1);
+ S2Point p000(1, 0, 0);
+ S2Point p045 = S2Point(1, 1, 0).Normalize();
+ S2Point p090(0, 1, 0);
+ S2Point p180(-1, 0, 0);
+
+ EXPECT_DOUBLE_EQ(S2::Angle(p000, pz, p045), M_PI_4);
+ EXPECT_DOUBLE_EQ(S2::Angle(p045, pz, p180), 3 * M_PI_4);
+ EXPECT_DOUBLE_EQ(S2::Angle(p000, pz, p180), M_PI);
+ EXPECT_DOUBLE_EQ(S2::Angle(pz, p000, pz), 0);
+ EXPECT_DOUBLE_EQ(S2::Angle(pz, p000, p045), M_PI_2);
+
+ EXPECT_DOUBLE_EQ(S2::TurnAngle(p000, pz, p045), -3 * M_PI_4);
+ EXPECT_DOUBLE_EQ(S2::TurnAngle(p045, pz, p180), -M_PI_4);
+ EXPECT_DOUBLE_EQ(S2::TurnAngle(p180, pz, p045), M_PI_4);
+ EXPECT_DOUBLE_EQ(S2::TurnAngle(p000, pz, p180), 0);
+ EXPECT_DOUBLE_EQ(fabs(S2::TurnAngle(pz, p000, pz)), M_PI);
+ EXPECT_DOUBLE_EQ(S2::TurnAngle(pz, p000, p045), M_PI_2);
+
+ EXPECT_DOUBLE_EQ(S2::Area(p000, p090, pz), M_PI_2);
+ EXPECT_DOUBLE_EQ(S2::Area(p045, pz, p180), 3 * M_PI_4);
+
+ // Make sure that Area() has good *relative* accuracy even for
+ // very small areas.
+ static double const eps = 1e-10;
+ S2Point pepsx = S2Point(eps, 0, 1).Normalize();
+ S2Point pepsy = S2Point(0, eps, 1).Normalize();
+ double expected1 = 0.5 * eps * eps;
+ EXPECT_NEAR(S2::Area(pepsx, pepsy, pz), expected1, 1e-14 * expected1);
+
+ // Make sure that it can handle degenerate triangles.
+ S2Point pr = S2Point(0.257, -0.5723, 0.112).Normalize();
+ S2Point pq = S2Point(-0.747, 0.401, 0.2235).Normalize();
+ EXPECT_EQ(S2::Area(pr, pr, pr), 0);
+ // TODO: The following test is not exact in optimized mode because the
+ // compiler chooses to mix 64-bit and 80-bit intermediate results.
+ EXPECT_NEAR(S2::Area(pr, pq, pr), 0, 1e-15);
+ EXPECT_EQ(S2::Area(p000, p045, p090), 0);
+
+ double max_girard = 0;
+ for (int i = 0; i < 10000; ++i) {
+ S2Point p0 = S2Testing::RandomPoint();
+ S2Point d1 = S2Testing::RandomPoint();
+ S2Point d2 = S2Testing::RandomPoint();
+ S2Point p1 = (p0 + 1e-15 * d1).Normalize();
+ S2Point p2 = (p0 + 1e-15 * d2).Normalize();
+ // The actual displacement can be as much as 1.2e-15 due to roundoff.
+ // This yields a maximum triangle area of about 0.7e-30.
+ EXPECT_LE(S2::Area(p0, p1, p2), 0.7e-30);
+ max_girard = max(max_girard, S2::GirardArea(p0, p1, p2));
+ }
+ // This check only passes if GirardArea() uses RobustCrossProd().
+ LOG(INFO) << "Worst case Girard for triangle area 1e-30: " << max_girard;
+ EXPECT_LE(max_girard, 1e-14);
+
+ // Try a very long and skinny triangle.
+ S2Point p045eps = S2Point(1, 1, eps).Normalize();
+ double expected2 = 5.8578643762690495119753e-11; // Mathematica.
+ EXPECT_NEAR(S2::Area(p000, p045eps, p090), expected2, 1e-9 * expected2);
+
+ // Triangles with near-180 degree edges that sum to a quarter-sphere.
+ static double const eps2 = 1e-14;
+ S2Point p000eps2 = S2Point(1, 0.1*eps2, eps2).Normalize();
+ double quarter_area1 = S2::Area(p000eps2, p000, p045) +
+ S2::Area(p000eps2, p045, p180) +
+ S2::Area(p000eps2, p180, pz) +
+ S2::Area(p000eps2, pz, p000);
+ EXPECT_DOUBLE_EQ(quarter_area1, M_PI);
+
+ // Four other triangles that sum to a quarter-sphere.
+ S2Point p045eps2 = S2Point(1, 1, eps2).Normalize();
+ double quarter_area2 = S2::Area(p045eps2, p000, p045) +
+ S2::Area(p045eps2, p045, p180) +
+ S2::Area(p045eps2, p180, pz) +
+ S2::Area(p045eps2, pz, p000);
+ EXPECT_DOUBLE_EQ(quarter_area2, M_PI);
+
+ // Compute the area of a hemisphere using four triangles with one near-180
+ // degree edge and one near-degenerate edge. This test fails in optimized
+ // mode unless GirardArea uses RobustCrossProd(), because the compiler
+ // doesn't compute all the inlined CrossProd() calls with the same level of
+ // accuracy (some intermediate values are spilled to 64-bit temporaries).
+ for (int i = 0; i < 100; ++i) {
+ double lng = 2 * M_PI * S2Testing::rnd.RandDouble();
+ S2Point p0 = S2LatLng::FromRadians(1e-12, lng).Normalized().ToPoint();
+ S2Point p1 = S2LatLng::FromRadians(0, lng).Normalized().ToPoint();
+ double p2_lng = lng + S2Testing::rnd.RandDouble();
+ S2Point p2 = S2LatLng::FromRadians(0, p2_lng).Normalized().ToPoint();
+ S2Point p3 = S2LatLng::FromRadians(0, lng + M_PI).Normalized().ToPoint();
+ S2Point p4 = S2LatLng::FromRadians(0, lng + 4.0).Normalized().ToPoint();
+ double area = (S2::Area(p0, p1, p2) + S2::Area(p0, p2, p3) +
+ S2::Area(p0, p3, p4) + S2::Area(p0, p4, p1));
+ EXPECT_NEAR(area, 2 * M_PI, 1e-14);
+ }
+}
+
+TEST(S2, TrueCentroid) {
+ // Test TrueCentroid() with very small triangles. This test assumes that
+ // the triangle is small enough so that it is nearly planar.
+ for (int i = 0; i < 100; ++i) {
+ S2Point p, x, y;
+ S2Testing::GetRandomFrame(&p, &x, &y);
+ double d = 1e-4 * pow(1e-4, S2Testing::rnd.RandDouble());
+ S2Point p0 = (p - d * x).Normalize();
+ S2Point p1 = (p + d * x).Normalize();
+ S2Point p2 = (p + 3 * d * y).Normalize();
+ S2Point centroid = S2::TrueCentroid(p0, p1, p2).Normalize();
+
+ // The centroid of a planar triangle is at the intersection of its
+ // medians, which is two-thirds of the way along each median.
+ S2Point expected_centroid = (p + d * y).Normalize();
+ EXPECT_LE(centroid.Angle(expected_centroid), 2e-8);
+ }
+}
+
+TEST(RobustCCW, ColinearPoints) {
+ // The following points happen to be *exactly collinear* along a line that it
+ // approximate tangent to the surface of the unit sphere. In fact, C is the
+ // exact midpoint of the line segment AB. All of these points are close
+ // enough to unit length to satisfy S2::IsUnitLength().
+ S2Point a(0.72571927877036835, 0.46058825605889098, 0.51106749730504852);
+ S2Point b(0.7257192746638208, 0.46058826573818168, 0.51106749441312738);
+ S2Point c(0.72571927671709457, 0.46058826089853633, 0.51106749585908795);
+ EXPECT_EQ(c - a, b - c);
+ EXPECT_NE(0, S2::RobustCCW(a, b, c));
+ EXPECT_EQ(S2::RobustCCW(a, b, c), S2::RobustCCW(b, c, a));
+ EXPECT_EQ(S2::RobustCCW(a, b, c), -S2::RobustCCW(c, b, a));
+
+ // The points "x1" and "x2" are exactly proportional, i.e. they both lie
+ // on a common line through the origin. Both points are considered to be
+ // normalized, and in fact they both satisfy (x == x.Normalize()).
+ // Therefore the triangle (x1, x2, -x1) consists of three distinct points
+ // that all lie on a common line through the origin.
+ S2Point x1(0.99999999999999989, 1.4901161193847655e-08, 0);
+ S2Point x2(1, 1.4901161193847656e-08, 0);
+ EXPECT_EQ(x1, x1.Normalize());
+ EXPECT_EQ(x2, x2.Normalize());
+ EXPECT_NE(0, S2::RobustCCW(x1, x2, -x1));
+ EXPECT_EQ(S2::RobustCCW(x1, x2, -x1), S2::RobustCCW(x2, -x1, x1));
+ EXPECT_EQ(S2::RobustCCW(x1, x2, -x1), -S2::RobustCCW(-x1, x2, x1));
+
+ // Here are two more points that are distinct, exactly proportional, and
+ // that satisfy (x == x.Normalize()).
+ S2Point x3 = S2Point(1, 1, 1).Normalize();
+ S2Point x4 = 0.99999999999999989 * x3;
+ EXPECT_EQ(x3, x3.Normalize());
+ EXPECT_EQ(x4, x4.Normalize());
+ EXPECT_NE(x3, x4);
+ EXPECT_NE(0, S2::RobustCCW(x3, x4, -x3));
+
+ // The following two points demonstrate that Normalize() is not idempotent,
+ // i.e. y0.Normalize() != y0.Normalize().Normalize(). Both points satisfy
+ // S2::IsNormalized(), though, and the two points are exactly proportional.
+ S2Point y0 = S2Point(1, 1, 0);
+ S2Point y1 = y0.Normalize();
+ S2Point y2 = y1.Normalize();
+ EXPECT_NE(y1, y2);
+ EXPECT_EQ(y2, y2.Normalize());
+ EXPECT_NE(0, S2::RobustCCW(y1, y2, -y1));
+ EXPECT_EQ(S2::RobustCCW(y1, y2, -y1), S2::RobustCCW(y2, -y1, y1));
+ EXPECT_EQ(S2::RobustCCW(y1, y2, -y1), -S2::RobustCCW(-y1, y2, y1));
+}
+
+// Given 3 points A, B, C that are exactly coplanar with the origin and where
+// A < B < C in lexicographic order, verify that ABC is counterclockwise (if
+// expected == 1) or clockwise (if expected == -1) using S2::ExpensiveCCW().
+//
+// This method is intended specifically for checking the cases where
+// symbolic perturbations are needed to break ties.
+static void CheckSymbolicCCW(int expected, S2Point const& a,
+ S2Point const& b, S2Point const& c) {
+ CHECK_LT(a, b);
+ CHECK_LT(b, c);
+ CHECK_EQ(0, a.DotProd(b.CrossProd(c)));
+
+ // Use ASSERT rather than EXPECT to suppress spurious error messages.
+ ASSERT_EQ(expected, S2::ExpensiveCCW(a, b, c));
+ ASSERT_EQ(expected, S2::ExpensiveCCW(b, c, a));
+ ASSERT_EQ(expected, S2::ExpensiveCCW(c, a, b));
+ ASSERT_EQ(-expected, S2::ExpensiveCCW(c, b, a));
+ ASSERT_EQ(-expected, S2::ExpensiveCCW(b, a, c));
+ ASSERT_EQ(-expected, S2::ExpensiveCCW(a, c, b));
+}
+
+TEST(RobustCCW, SymbolicPerturbationCodeCoverage) {
+ // The purpose of this test is simply to get code coverage of
+ // SymbolicallyPerturbedCCW(). Let M_1, M_2, ... be the sequence of
+ // submatrices whose determinant sign is tested by that function. Then the
+ // i-th test below is a 3x3 matrix M (with rows A, B, C) such that:
+ //
+ // det(M) = 0
+ // det(M_j) = 0 for j < i
+ // det(M_i) != 0
+ // A < B < C in lexicographic order.
+ //
+ // I checked that reversing the sign of any of the "return" statements in
+ // SymbolicallyPerturbedCCW() will cause this test to fail.
+
+ // det(M_1) = b0*c1 - b1*c0
+ CheckSymbolicCCW(1, S2Point(-3, -1, 0), S2Point(-2, 1, 0), S2Point(1, -2, 0));
+
+ // det(M_2) = b2*c0 - b0*c2
+ CheckSymbolicCCW(1, S2Point(-6, 3, 3), S2Point(-4, 2, -1), S2Point(-2, 1, 4));
+
+ // det(M_3) = b1*c2 - b2*c1
+ CheckSymbolicCCW(1, S2Point(0, -1, -1), S2Point(0, 1, -2), S2Point(0, 2, 1));
+ // From this point onward, B or C must be zero, or B is proportional to C.
+
+ // det(M_4) = c0*a1 - c1*a0
+ CheckSymbolicCCW(1, S2Point(-1, 2, 7), S2Point(2, 1, -4), S2Point(4, 2, -8));
+
+ // det(M_5) = c0
+ CheckSymbolicCCW(1, S2Point(-4, -2, 7), S2Point(2, 1, -4), S2Point(4, 2, -8));
+
+ // det(M_6) = -c1
+ CheckSymbolicCCW(1, S2Point(0, -5, 7), S2Point(0, -4, 8), S2Point(0, -2, 4));
+
+ // det(M_7) = c2*a0 - c0*a2
+ CheckSymbolicCCW(1, S2Point(-5, -2, 7), S2Point(0, 0, -2), S2Point(0, 0, -1));
+
+ // det(M_8) = c2
+ CheckSymbolicCCW(1, S2Point(0, -2, 7), S2Point(0, 0, 1), S2Point(0, 0, 2));
+ // From this point onward, C must be zero.
+
+ // det(M_9) = a0*b1 - a1*b0
+ CheckSymbolicCCW(1, S2Point(-3, 1, 7), S2Point(-1, -4, 1), S2Point(0, 0, 0));
+
+ // det(M_10) = -b0
+ CheckSymbolicCCW(1, S2Point(-6, -4, 7), S2Point(-3, -2, 1), S2Point(0, 0, 0));
+
+ // det(M_11) = b1
+ CheckSymbolicCCW(-1, S2Point(0, -4, 7), S2Point(0, -2, 1), S2Point(0, 0, 0));
+
+ // det(M_12) = a0
+ CheckSymbolicCCW(-1, S2Point(-1, -4, 5), S2Point(0, 0, -3), S2Point(0, 0, 0));
+
+ // det(M_13) = 1
+ CheckSymbolicCCW(1, S2Point(0, -4, 5), S2Point(0, 0, -5), S2Point(0, 0, 0));
+}
+
+// This test repeatedly constructs some number of points that are on or nearly
+// on a given great circle. Then it chooses one of these points as the
+// "origin" and sorts the other points in CCW order around it. Of course,
+// since the origin is on the same great circle as the points being sorted,
+// nearly all of these tests are degenerate. It then does various consistency
+// checks to verify that the points are indeed sorted in CCW order.
+//
+// It is easier to think about what this test is doing if you imagine that the
+// points are in general position rather than on a great circle.
+class RobustCCWTest : public testing::Test {
+ protected:
+ // The following method is used to sort a collection of points in CCW order
+ // around a given origin. It returns true if A comes before B in the CCW
+ // ordering (starting at an arbitrary fixed direction).
+ class LessCCW : public binary_function<S2Point const&, S2Point const&, bool> {
+ public:
+ LessCCW(S2Point const& origin, S2Point const& start)
+ : origin_(origin), start_(start) {
+ }
+ bool operator()(S2Point const& a, S2Point const& b) {
+ // OrderedCCW() acts like "<=", so we need to invert the comparison.
+ return !S2::OrderedCCW(start_, b, a, origin_);
+ }
+ private:
+ S2Point const origin_;
+ S2Point const start_;
+ };
+
+ // Given a set of points with no duplicates, first remove "origin" from
+ // "points" (if it exists) and then sort the remaining points in CCW order
+ // around "origin" putting the result in "sorted".
+ static void SortCCW(vector<S2Point> const& points, S2Point const& origin,
+ vector<S2Point>* sorted) {
+ // Make a copy of the points with "origin" removed.
+ sorted->clear();
+ remove_copy(points.begin(), points.end(), back_inserter(*sorted), origin);
+
+ // Sort the points CCW around the origin starting at (*sorted)[0].
+ LessCCW less(origin, (*sorted)[0]);
+ sort(sorted->begin(), sorted->end(), less);
+ }
+
+ // Given a set of points sorted circularly CCW around "origin", and the
+ // index "start" of a point A, count the number of CCW triangles OAB over
+ // all sorted points B not equal to A. Also check that the results of the
+ // CCW tests are consistent with the hypothesis that the points are sorted.
+ static int CountCCW(vector<S2Point> const& sorted, S2Point const& origin,
+ int start) {
+ int num_ccw = 0;
+ int last_ccw = 1;
+ int const n = sorted.size();
+ for (int j = 1; j < n; ++j) {
+ int ccw = S2::RobustCCW(origin, sorted[start], sorted[(start + j) % n]);
+ EXPECT_NE(0, ccw);
+ if (ccw > 0) ++num_ccw;
+
+ // Since the points are sorted around the origin, we expect to see a
+ // (possibly empty) sequence of CCW triangles followed by a (possibly
+ // empty) sequence of CW triangles.
+ EXPECT_FALSE(ccw > 0 && last_ccw < 0);
+ last_ccw = ccw;
+ }
+ return num_ccw;
+ }
+
+ // Test exhaustively whether the points in "sorted" are sorted circularly
+ // CCW around "origin".
+ static void TestCCW(vector<S2Point> const& sorted, S2Point const& origin) {
+ int const n = sorted.size();
+ int total_num_ccw = 0;
+ int last_num_ccw = CountCCW(sorted, origin, n - 1);
+ for (int start = 0; start < n; ++start) {
+ int num_ccw = CountCCW(sorted, origin, start);
+ // Each iteration we increase the start index by 1, therefore the number
+ // of CCW triangles should decrease by at most 1.
+ EXPECT_GE(num_ccw, last_num_ccw - 1);
+ total_num_ccw += num_ccw;
+ last_num_ccw = num_ccw;
+ }
+ // We have tested all triangles of the form OAB. Exactly half of these
+ // should be CCW.
+ EXPECT_EQ(n * (n-1) / 2, total_num_ccw);
+ }
+
+ static void AddNormalized(S2Point const& a, vector<S2Point>* points) {
+ points->push_back(a.Normalize());
+ }
+
+ // Add two points A1 and A2 that are slightly offset from A along the
+ // tangent toward B, and such that A, A1, and A2 are exactly collinear
+ // (i.e. even with infinite-precision arithmetic).
+ static void AddTangentPoints(S2Point const& a, S2Point const& b,
+ vector<S2Point>* points) {
+ S2Point dir = S2::RobustCrossProd(a, b).CrossProd(a).Normalize();
+ if (dir == S2Point(0, 0, 0)) return;
+ for (;;) {
+ S2Point delta = 1e-15 * S2Testing::rnd.RandDouble() * dir;
+ if ((a + delta) != a && (a + delta) - a == a - (a - delta) &&
+ S2::IsUnitLength(a + delta) && S2::IsUnitLength(a - delta)) {
+ points->push_back(a + delta);
+ points->push_back(a - delta);
+ return;
+ }
+ }
+ }
+
+ // Add zero or more (but usually one) point that is likely to trigger
+ // RobustCCW() degeneracies among the given points.
+ static void AddDegeneracy(vector<S2Point>* points) {
+ S2Testing::Random* rnd = &S2Testing::rnd;
+ S2Point a = (*points)[rnd->Uniform(points->size())];
+ S2Point b = (*points)[rnd->Uniform(points->size())];
+ int coord = rnd->Uniform(3);
+ switch (rnd->Uniform(8)) {
+ case 0:
+ // Add a random point (not uniformly distributed) along the great
+ // circle AB.
+ AddNormalized((2 * rnd->RandDouble() - 1) * a +
+ (2 * rnd->RandDouble() - 1) * b, points);
+ break;
+ case 1:
+ // Perturb one coordinate by the minimum amount possible.
+ a[coord] = nextafter(a[coord], rnd->OneIn(2) ? 2 : -2);
+ AddNormalized(a, points);
+ break;
+ case 2:
+ // Perturb one coordinate by up to 1e-15.
+ a[coord] += 1e-15 * (2 * rnd->RandDouble() - 1);
+ AddNormalized(a, points);
+ break;
+ case 3:
+ // Scale a point just enough so that it is different while still being
+ // considered normalized.
+ a *= rnd->OneIn(2) ? (1 + 2e-16) : (1 - 1e-16);
+ if (S2::IsUnitLength(a)) points->push_back(a);
+ break;
+ case 4: {
+ // Add the intersection point of AB with X=0, Y=0, or Z=0.
+ S2Point dir(0, 0, 0);
+ dir[coord] = rnd->OneIn(2) ? 1 : -1;
+ S2Point norm = S2::RobustCrossProd(a, b).Normalize();
+ if (norm.Norm2() > 0) {
+ AddNormalized(S2::RobustCrossProd(dir, norm), points);
+ }
+ break;
+ }
+ case 5:
+ // Add two closely spaced points along the tangent at A to the great
+ // circle through AB.
+ AddTangentPoints(a, b, points);
+ break;
+ case 6:
+ // Add two closely spaced points along the tangent at A to the great
+ // circle through A and the X-axis.
+ AddTangentPoints(a, S2Point(1, 0, 0), points);
+ break;
+ case 7:
+ // Add the negative of a point.
+ points->push_back(-a);
+ break;
+ }
+ }
+
+ // Sort the points around the given origin, and then do some consistency
+ // checks to verify that they are actually sorted.
+ static void SortAndTest(vector<S2Point> const& points,
+ S2Point const& origin) {
+ vector<S2Point> sorted;
+ SortCCW(points, origin, &sorted);
+ TestCCW(sorted, origin);
+ }
+
+ // Construct approximately "n" points near the great circle through A and B,
+ // then sort them and test whether they are sorted.
+ static void TestGreatCircle(S2Point a, S2Point b, int n) {
+ a = a.Normalize();
+ b = b.Normalize();
+ vector<S2Point> points;
+ points.push_back(a);
+ points.push_back(b);
+ while (points.size() < (size_t)n) {
+ AddDegeneracy(&points);
+ }
+ // Remove any (0, 0, 0) points that were accidentically created, then sort
+ // the points and remove duplicates.
+ points.erase(remove(points.begin(), points.end(), S2Point(0, 0, 0)),
+ points.end());
+ sort(points.begin(), points.end());
+ points.erase(unique(points.begin(), points.end()), points.end());
+ EXPECT_GE((int)points.size(), n / 2);
+
+ SortAndTest(points, a);
+ SortAndTest(points, b);
+ for (size_t k = 0; k < points.size(); ++k) {
+ SortAndTest(points, points[k]);
+ }
+ }
+};
+
+TEST_F(RobustCCWTest, StressTest) {
+ // The run time of this test is *cubic* in the parameter below.
+ static int const kNumPointsPerCircle = 20;
+
+ // This test is randomized, so it is beneficial to run it several times.
+ for (int iter = 0; iter < 3; ++iter) {
+ // The most difficult great circles are the ones in the X-Y, Y-Z, and X-Z
+ // planes, for two reasons. First, when one or more coordinates are close
+ // to zero then the perturbations can be much smaller, since floating
+ // point numbers are spaced much more closely together near zero. (This
+ // tests the handling of things like underflow.) The second reason is
+ // that most of the cases of SymbolicallyPerturbedCCW() can only be
+ // reached when one or more input point coordinates are zero.
+ TestGreatCircle(S2Point(1, 0, 0), S2Point(0, 1, 0), kNumPointsPerCircle);
+ TestGreatCircle(S2Point(1, 0, 0), S2Point(0, 0, 1), kNumPointsPerCircle);
+ TestGreatCircle(S2Point(0, -1, 0), S2Point(0, 0, 1), kNumPointsPerCircle);
+
+ // This tests a great circle where at least some points have X, Y, and Z
+ // coordinates with exactly the same mantissa. One useful property of
+ // such points is that when they are scaled (e.g. multiplying by 1+eps),
+ // all such points are exactly collinear with the origin.
+ TestGreatCircle(S2Point(1 << 25, 1, -8), S2Point(-4, -(1 << 20), 1),
+ kNumPointsPerCircle);
+ }
+}
+
+// Note: obviously, I could have defined a bundle of metrics like this in the
+// S2 class itself rather than just for testing. However, it's not clear that
+// this is useful other than for testing purposes, and I find
+// S2::kMinWidth.GetMaxLevel(width) to be slightly more readable than
+// than S2::kWidth.min().GetMaxLevel(width). Also, there is no fundamental
+// reason that we need to analyze the minimum, maximum, and average values of
+// every metric; it would be perfectly reasonable to just define one of these.
+
+template<int dim>
+class MetricBundle {
+ public:
+ typedef S2::Metric<dim> Metric;
+ MetricBundle(Metric const& min, Metric const& max, Metric const& avg) :
+ min_(min), max_(max), avg_(avg) {}
+ Metric const& min_;
+ Metric const& max_;
+ Metric const& avg_;
+};
+
+template<int dim>
+static void CheckMinMaxAvg(MetricBundle<dim> const& bundle) {
+ EXPECT_LE(bundle.min_.deriv(), bundle.avg_.deriv());
+ EXPECT_LE(bundle.avg_.deriv(), bundle.max_.deriv());
+}
+
+template<int dim>
+static void CheckLessOrEqual(MetricBundle<dim> const& a,
+ MetricBundle<dim> const& b) {
+ EXPECT_LE(a.min_.deriv(), b.min_.deriv());
+ EXPECT_LE(a.max_.deriv(), b.max_.deriv());
+ EXPECT_LE(a.avg_.deriv(), b.avg_.deriv());
+}
+
+TEST(S2, Metrics) {
+ MetricBundle<1> angle_span(S2::kMinAngleSpan, S2::kMaxAngleSpan,
+ S2::kAvgAngleSpan);
+ MetricBundle<1> width(S2::kMinWidth, S2::kMaxWidth, S2::kAvgWidth);
+ MetricBundle<1> edge(S2::kMinEdge, S2::kMaxEdge, S2::kAvgEdge);
+ MetricBundle<1> diag(S2::kMinDiag, S2::kMaxDiag, S2::kAvgDiag);
+ MetricBundle<2> area(S2::kMinArea, S2::kMaxArea, S2::kAvgArea);
+
+ // First, check that min <= avg <= max for each metric.
+ CheckMinMaxAvg(angle_span);
+ CheckMinMaxAvg(width);
+ CheckMinMaxAvg(edge);
+ CheckMinMaxAvg(diag);
+ CheckMinMaxAvg(area);
+
+ // Check that the maximum aspect ratio of an individual cell is consistent
+ // with the global minimums and maximums.
+ EXPECT_GE(S2::kMaxEdgeAspect, 1);
+ EXPECT_LE(S2::kMaxEdgeAspect, S2::kMaxEdge.deriv() / S2::kMinEdge.deriv());
+ EXPECT_GE(S2::kMaxDiagAspect, 1);
+ EXPECT_LE(S2::kMaxDiagAspect, S2::kMaxDiag.deriv() / S2::kMinDiag.deriv());
+
+ // Check various conditions that are provable mathematically.
+ CheckLessOrEqual(width, angle_span);
+ CheckLessOrEqual(width, edge);
+ CheckLessOrEqual(edge, diag);
+
+ EXPECT_GE(S2::kMinArea.deriv(),
+ S2::kMinWidth.deriv() * S2::kMinEdge.deriv() - 1e-15);
+ EXPECT_LE(S2::kMaxArea.deriv(),
+ S2::kMaxWidth.deriv() * S2::kMaxEdge.deriv() + 1e-15);
+
+ // GetMinLevelForLength() and friends have built-in assertions, we just need
+ // to call these functions to test them.
+ //
+ // We don't actually check that the metrics are correct here, e.g. that
+ // GetMinWidth(10) is a lower bound on the width of cells at level 10.
+ // It is easier to check these properties in s2cell_unittest, since
+ // S2Cell has methods to compute the cell vertices, etc.
+
+ for (int level = -2; level <= S2CellId::kMaxLevel + 3; ++level) {
+ double width = S2::kMinWidth.deriv() * pow(2, -level);
+ if (level >= S2CellId::kMaxLevel + 3) width = 0;
+
+ // Check boundary cases (exactly equal to a threshold value).
+ int expected_level = max(0, min(S2CellId::kMaxLevel, level));
+ cout << "width " << width << " has expected level " << expected_level << endl;
+ EXPECT_EQ(S2::kMinWidth.GetMinLevel(width), expected_level);
+ EXPECT_EQ(S2::kMinWidth.GetMaxLevel(width), expected_level);
+ EXPECT_EQ(S2::kMinWidth.GetClosestLevel(width), expected_level);
+
+ // Also check non-boundary cases.
+ EXPECT_EQ(S2::kMinWidth.GetMinLevel(1.2 * width), expected_level);
+ EXPECT_EQ(S2::kMinWidth.GetMaxLevel(0.8 * width), expected_level);
+ EXPECT_EQ(S2::kMinWidth.GetClosestLevel(1.2 * width), expected_level);
+ EXPECT_EQ(S2::kMinWidth.GetClosestLevel(0.8 * width), expected_level);
+
+ // Same thing for area.
+ double area = S2::kMinArea.deriv() * pow(4, -level);
+ if (level <= -3) area = 0;
+ EXPECT_EQ(S2::kMinArea.GetMinLevel(area), expected_level);
+ EXPECT_EQ(S2::kMinArea.GetMaxLevel(area), expected_level);
+ EXPECT_EQ(S2::kMinArea.GetClosestLevel(area), expected_level);
+ EXPECT_EQ(S2::kMinArea.GetMinLevel(1.2 * area), expected_level);
+ EXPECT_EQ(S2::kMinArea.GetMaxLevel(0.8 * area), expected_level);
+ EXPECT_EQ(S2::kMinArea.GetClosestLevel(1.2 * area), expected_level);
+ EXPECT_EQ(S2::kMinArea.GetClosestLevel(0.8 * area), expected_level);
+ }
+}
+
+TEST(S2, Frames) {
+ Matrix3x3_d m;
+ S2Point z = S2Point(0.2, 0.5, -3.3).Normalize();
+ S2::GetFrame(z, &m);
+ EXPECT_TRUE(S2::ApproxEquals(m.Col(2), z));
+ EXPECT_TRUE(S2::IsUnitLength(m.Col(0)));
+ EXPECT_TRUE(S2::IsUnitLength(m.Col(1)));
+ EXPECT_DOUBLE_EQ(m.Det(), 1);
+
+ EXPECT_TRUE(S2::ApproxEquals(S2::ToFrame(m, m.Col(0)), S2Point(1, 0, 0)));
+ EXPECT_TRUE(S2::ApproxEquals(S2::ToFrame(m, m.Col(1)), S2Point(0, 1, 0)));
+ EXPECT_TRUE(S2::ApproxEquals(S2::ToFrame(m, m.Col(2)), S2Point(0, 0, 1)));
+
+ EXPECT_TRUE(S2::ApproxEquals(S2::FromFrame(m, S2Point(1, 0, 0)), m.Col(0)));
+ EXPECT_TRUE(S2::ApproxEquals(S2::FromFrame(m, S2Point(0, 1, 0)), m.Col(1)));
+ EXPECT_TRUE(S2::ApproxEquals(S2::FromFrame(m, S2Point(0, 0, 1)), m.Col(2)));
+}
+
+#if 0
+TEST(S2, S2PointHashSpreads) {
+ int kTestPoints = 1 << 16;
+ hash_set<size_t> set;
+ hash_set<S2Point> points;
+ hash<S2Point> hasher;
+ S2Point base = S2Point(1, 1, 1);
+ for (int i = 0; i < kTestPoints; ++i) {
+ // All points in a tiny cap to test avalanche property of hash
+ // function (the cap would be of radius 1mm on Earth (4*10^9/2^35).
+ S2Point perturbed = base + S2Testing::RandomPoint() / (1ULL << 35);
+ perturbed = perturbed.Normalize();
+ set.insert(hasher(perturbed));
+ points.insert(perturbed);
+ }
+ // A real collision is extremely unlikely.
+ EXPECT_EQ((size_t)0, kTestPoints - points.size());
+ // Allow a few for the hash.
+ EXPECT_GE((size_t)10, kTestPoints - set.size());
+}
+#endif
+
+TEST(S2, S2PointHashCollapsesZero) {
+ double zero = 0;
+ double minus_zero = -zero;
+ EXPECT_NE(*reinterpret_cast<uint64 const*>(&zero),
+ *reinterpret_cast<uint64 const*>(&minus_zero));
+ hash_map<S2Point, int> map;
+ S2Point zero_pt(zero, zero, zero);
+ S2Point minus_zero_pt(minus_zero, minus_zero, minus_zero);
+
+ map[zero_pt] = 1;
+ map[minus_zero_pt] = 2;
+ ASSERT_EQ((size_t)1, map.size());
+}
diff --git a/src/third_party/s2/s2cap.cc b/src/third_party/s2/s2cap.cc
new file mode 100644
index 00000000000..edfde6e20de
--- /dev/null
+++ b/src/third_party/s2/s2cap.cc
@@ -0,0 +1,262 @@
+// Copyright 2005 Google Inc. All Rights Reserved.
+
+#include "base/integral_types.h"
+#include "base/logging.h"
+#include "s2.h"
+#include "s2cap.h"
+#include "s2cell.h"
+#include "s2latlngrect.h"
+
+namespace {
+
+// Multiply a positive number by this constant to ensure that the result
+// of a floating point operation is at least as large as the true
+// infinite-precision result.
+double const kRoundUp = 1.0 + 1.0 / (uint64(1) << 52);
+
+// Return the cap height corresponding to the given non-negative cap angle in
+// radians. Cap angles of Pi radians or larger yield a full cap.
+double GetHeightForAngle(double radians) {
+ DCHECK_GE(radians, 0);
+
+ // Caps of Pi radians or more are full.
+ if (radians >= M_PI) return 2;
+
+ // The height of the cap can be computed as 1 - cos(radians), but this isn't
+ // very accurate for angles close to zero (where cos(radians) is almost 1).
+ // Computing it as 2 * (sin(radians / 2) ** 2) gives much better precision.
+ double d = sin(0.5 * radians);
+ return 2 * d * d;
+}
+
+} // namespace
+
+S2Cap S2Cap::FromAxisAngle(S2Point const& axis, S1Angle const& angle) {
+ DCHECK(S2::IsUnitLength(axis));
+ DCHECK_GE(angle.radians(), 0);
+ return S2Cap(axis, GetHeightForAngle(angle.radians()));
+}
+
+S1Angle S2Cap::angle() const {
+ // This could also be computed as acos(1 - height_), but the following
+ // formula is much more accurate when the cap height is small. It
+ // follows from the relationship h = 1 - cos(theta) = 2 sin^2(theta/2).
+ if (is_empty()) return S1Angle::Radians(-1);
+ return S1Angle::Radians(2 * asin(sqrt(0.5 * height_)));
+}
+
+S2Cap S2Cap::Complement() const {
+ // The complement of a full cap is an empty cap, not a singleton.
+ // Also make sure that the complement of an empty cap has height 2.
+ double height = is_full() ? -1 : 2 - max(height_, 0.0);
+ return S2Cap::FromAxisHeight(-axis_, height);
+}
+
+bool S2Cap::Contains(S2Cap const& other) const {
+ if (is_full() || other.is_empty()) return true;
+ return angle().radians() >= axis_.Angle(other.axis_) +
+ other.angle().radians();
+}
+
+bool S2Cap::Intersects(S2Cap const& other) const {
+ if (is_empty() || other.is_empty()) return false;
+
+ return (angle().radians() + other.angle().radians() >=
+ axis_.Angle(other.axis_));
+}
+
+bool S2Cap::InteriorIntersects(S2Cap const& other) const {
+ // Make sure this cap has an interior and the other cap is non-empty.
+ if (height_ <= 0 || other.is_empty()) return false;
+
+ return (angle().radians() + other.angle().radians() >
+ axis_.Angle(other.axis_));
+}
+
+void S2Cap::AddPoint(S2Point const& p) {
+ // Compute the squared chord length, then convert it into a height.
+ DCHECK(S2::IsUnitLength(p));
+ if (is_empty()) {
+ axis_ = p;
+ height_ = 0;
+ } else {
+ // To make sure that the resulting cap actually includes this point,
+ // we need to round up the distance calculation. That is, after
+ // calling cap.AddPoint(p), cap.Contains(p) should be true.
+ double dist2 = (axis_ - p).Norm2();
+ height_ = max(height_, kRoundUp * 0.5 * dist2);
+ }
+}
+
+void S2Cap::AddCap(S2Cap const& other) {
+ if (is_empty()) {
+ *this = other;
+ } else {
+ // See comments for AddPoint(). This could be optimized by doing the
+ // calculation in terms of cap heights rather than cap opening angles.
+ double radians = axis_.Angle(other.axis_) + other.angle().radians();
+ height_ = max(height_, kRoundUp * GetHeightForAngle(radians));
+ }
+}
+
+S2Cap S2Cap::Expanded(S1Angle const& distance) const {
+ DCHECK_GE(distance.radians(), 0);
+ if (is_empty()) return Empty();
+ return FromAxisAngle(axis_, angle() + distance);
+}
+
+S2Cap* S2Cap::Clone() const {
+ return new S2Cap(*this);
+}
+
+S2Cap S2Cap::GetCapBound() const {
+ return *this;
+}
+
+S2LatLngRect S2Cap::GetRectBound() const {
+ if (is_empty()) return S2LatLngRect::Empty();
+
+ // Convert the axis to a (lat,lng) pair, and compute the cap angle.
+ S2LatLng axis_ll(axis_);
+ double cap_angle = angle().radians();
+
+ bool all_longitudes = false;
+ double lat[2], lng[2];
+ lng[0] = -M_PI;
+ lng[1] = M_PI;
+
+ // Check whether cap includes the south pole.
+ lat[0] = axis_ll.lat().radians() - cap_angle;
+ if (lat[0] <= -M_PI_2) {
+ lat[0] = -M_PI_2;
+ all_longitudes = true;
+ }
+ // Check whether cap includes the north pole.
+ lat[1] = axis_ll.lat().radians() + cap_angle;
+ if (lat[1] >= M_PI_2) {
+ lat[1] = M_PI_2;
+ all_longitudes = true;
+ }
+ if (!all_longitudes) {
+ // Compute the range of longitudes covered by the cap. We use the law
+ // of sines for spherical triangles. Consider the triangle ABC where
+ // A is the north pole, B is the center of the cap, and C is the point
+ // of tangency between the cap boundary and a line of longitude. Then
+ // C is a right angle, and letting a,b,c denote the sides opposite A,B,C,
+ // we have sin(a)/sin(A) = sin(c)/sin(C), or sin(A) = sin(a)/sin(c).
+ // Here "a" is the cap angle, and "c" is the colatitude (90 degrees
+ // minus the latitude). This formula also works for negative latitudes.
+ //
+ // The formula for sin(a) follows from the relationship h = 1 - cos(a).
+
+ double sin_a = sqrt(height_ * (2 - height_));
+ double sin_c = cos(axis_ll.lat().radians());
+ if (sin_a <= sin_c) {
+ double angle_A = asin(sin_a / sin_c);
+ lng[0] = drem(axis_ll.lng().radians() - angle_A, 2 * M_PI);
+ lng[1] = drem(axis_ll.lng().radians() + angle_A, 2 * M_PI);
+ }
+ }
+ return S2LatLngRect(R1Interval(lat[0], lat[1]),
+ S1Interval(lng[0], lng[1]));
+}
+
+bool S2Cap::Intersects(S2Cell const& cell, S2Point const* vertices) const {
+ // Return true if this cap intersects any point of 'cell' excluding its
+ // vertices (which are assumed to already have been checked).
+
+ // If the cap is a hemisphere or larger, the cell and the complement of the
+ // cap are both convex. Therefore since no vertex of the cell is contained,
+ // no other interior point of the cell is contained either.
+ if (height_ >= 1) return false;
+
+ // We need to check for empty caps due to the axis check just below.
+ if (is_empty()) return false;
+
+ // Optimization: return true if the cell contains the cap axis. (This
+ // allows half of the edge checks below to be skipped.)
+ if (cell.Contains(axis_)) return true;
+
+ // At this point we know that the cell does not contain the cap axis,
+ // and the cap does not contain any cell vertex. The only way that they
+ // can intersect is if the cap intersects the interior of some edge.
+
+ double sin2_angle = height_ * (2 - height_); // sin^2(cap_angle)
+ for (int k = 0; k < 4; ++k) {
+ S2Point edge = cell.GetEdgeRaw(k);
+ double dot = axis_.DotProd(edge);
+ if (dot > 0) {
+ // The axis is in the interior half-space defined by the edge. We don't
+ // need to consider these edges, since if the cap intersects this edge
+ // then it also intersects the edge on the opposite side of the cell
+ // (because we know the axis is not contained with the cell).
+ continue;
+ }
+ // The Norm2() factor is necessary because "edge" is not normalized.
+ if (dot * dot > sin2_angle * edge.Norm2()) {
+ return false; // Entire cap is on the exterior side of this edge.
+ }
+ // Otherwise, the great circle containing this edge intersects
+ // the interior of the cap. We just need to check whether the point
+ // of closest approach occurs between the two edge endpoints.
+ S2Point dir = edge.CrossProd(axis_);
+ if (dir.DotProd(vertices[k]) < 0 && dir.DotProd(vertices[(k+1)&3]) > 0)
+ return true;
+ }
+ return false;
+}
+
+bool S2Cap::Contains(S2Cell const& cell) const {
+ // If the cap does not contain all cell vertices, return false.
+ // We check the vertices before taking the Complement() because we can't
+ // accurately represent the complement of a very small cap (a height
+ // of 2-epsilon is rounded off to 2).
+ S2Point vertices[4];
+ for (int k = 0; k < 4; ++k) {
+ vertices[k] = cell.GetVertex(k);
+ if (!Contains(vertices[k])) return false;
+ }
+ // Otherwise, return true if the complement of the cap does not intersect
+ // the cell. (This test is slightly conservative, because technically we
+ // want Complement().InteriorIntersects() here.)
+ return !Complement().Intersects(cell, vertices);
+}
+
+bool S2Cap::MayIntersect(S2Cell const& cell) const {
+ // If the cap contains any cell vertex, return true.
+ S2Point vertices[4];
+ for (int k = 0; k < 4; ++k) {
+ vertices[k] = cell.GetVertex(k);
+ if (Contains(vertices[k])) return true;
+ }
+ return Intersects(cell, vertices);
+}
+
+bool S2Cap::Contains(S2Point const& p) const {
+ DCHECK(S2::IsUnitLength(p));
+ return (axis_ - p).Norm2() <= 2 * height_;
+}
+
+bool S2Cap::InteriorContains(S2Point const& p) const {
+ DCHECK(S2::IsUnitLength(p));
+ return is_full() || (axis_ - p).Norm2() < 2 * height_;
+}
+
+bool S2Cap::operator==(S2Cap const& other) const {
+ return (axis_ == other.axis_ && height_ == other.height_) ||
+ (is_empty() && other.is_empty()) ||
+ (is_full() && other.is_full());
+}
+
+bool S2Cap::ApproxEquals(S2Cap const& other, double max_error) {
+ return (S2::ApproxEquals(axis_, other.axis_, max_error) &&
+ fabs(height_ - other.height_) <= max_error) ||
+ (is_empty() && other.height_ <= max_error) ||
+ (other.is_empty() && height_ <= max_error) ||
+ (is_full() && other.height_ >= 2 - max_error) ||
+ (other.is_full() && height_ >= 2 - max_error);
+}
+
+ostream& operator<<(ostream& os, S2Cap const& cap) {
+ return os << "[Axis=" << cap.axis() << ", Angle=" << cap.angle() << "]";
+}
diff --git a/src/third_party/s2/s2cap.h b/src/third_party/s2/s2cap.h
new file mode 100644
index 00000000000..021fb3ae0dd
--- /dev/null
+++ b/src/third_party/s2/s2cap.h
@@ -0,0 +1,175 @@
+// Copyright 2005 Google Inc. All Rights Reserved.
+
+#ifndef UTIL_GEOMETRY_S2CAP_H_
+#define UTIL_GEOMETRY_S2CAP_H_
+
+#include "base/basictypes.h"
+#include "base/logging.h"
+#include "s1angle.h"
+#include "s2region.h"
+
+// This class represents a spherical cap, i.e. a portion of a sphere cut off
+// by a plane. The cap is defined by its axis and height. This
+// representation has good numerical accuracy for very small caps (unlike the
+// (axis, min-distance-from-origin) representation), and is also efficient for
+// containment tests (unlike the (axis, angle) representation).
+//
+// Here are some useful relationships between the cap height (h), the cap
+// opening angle (theta), the maximum chord length from the cap's center (d),
+// and the radius of cap's base (a). All formulas assume a unit radius.
+//
+// h = 1 - cos(theta)
+// = 2 sin^2(theta/2)
+// d^2 = 2 h
+// = a^2 + h^2
+//
+// Caps may be constructed from either an axis and a height, or an axis and
+// an angle. To avoid ambiguity, there are no public constructors except
+// the default constructor.
+//
+// This class is intended to be copied by value as desired. It uses
+// the default copy constructor and assignment operator, however it is
+// not a "plain old datatype" (POD) because it has virtual functions.
+class S2Cap : public S2Region {
+ public:
+ // The default constructor returns an empty S2Cap.
+ S2Cap() : axis_(1, 0, 0), height_(-1) {}
+
+ // Create a cap given its axis and the cap height, i.e. the maximum
+ // projected distance along the cap axis from the cap center.
+ // 'axis' should be a unit-length vector.
+ inline static S2Cap FromAxisHeight(S2Point const& axis, double height);
+
+ // Create a cap given its axis and the cap opening angle, i.e. maximum
+ // angle between the axis and a point on the cap. 'axis' should be a
+ // unit-length vector, and 'angle' should be non-negative. If 'angle' is
+ // 180 degrees or larger, the cap will contain the entire unit sphere.
+ static S2Cap FromAxisAngle(S2Point const& axis, S1Angle const& angle);
+
+ // Create a cap given its axis and its area in steradians. 'axis' should be
+ // a unit-length vector, and 'area' should be between 0 and 4 * M_PI.
+ inline static S2Cap FromAxisArea(S2Point const& axis, double area);
+
+ // Return an empty cap, i.e. a cap that contains no points.
+ static S2Cap Empty() { return S2Cap(); }
+
+ // Return a full cap, i.e. a cap that contains all points.
+ static S2Cap Full() { return S2Cap(S2Point(1, 0, 0), 2); }
+
+ ~S2Cap() {}
+
+ // Accessor methods.
+ S2Point const& axis() const { return axis_; }
+ double height() const { return height_; }
+ double area() const { return 2 * M_PI * max(0.0, height_); }
+
+ // Return the cap opening angle in radians, or a negative number for
+ // empty caps.
+ S1Angle angle() const;
+
+ // We allow negative heights (to represent empty caps) but not heights
+ // greater than 2.
+ bool is_valid() const { return S2::IsUnitLength(axis_) && height_ <= 2; }
+
+ // Return true if the cap is empty, i.e. it contains no points.
+ bool is_empty() const { return height_ < 0; }
+
+ // Return true if the cap is full, i.e. it contains all points.
+ bool is_full() const { return height_ >= 2; }
+
+ // Return the complement of the interior of the cap. A cap and its
+ // complement have the same boundary but do not share any interior points.
+ // The complement operator is not a bijection, since the complement of a
+ // singleton cap (containing a single point) is the same as the complement
+ // of an empty cap.
+ S2Cap Complement() const;
+
+ // Return true if and only if this cap contains the given other cap
+ // (in a set containment sense, e.g. every cap contains the empty cap).
+ bool Contains(S2Cap const& other) const;
+
+ // Return true if and only if this cap intersects the given other cap,
+ // i.e. whether they have any points in common.
+ bool Intersects(S2Cap const& other) const;
+
+ // Return true if and only if the interior of this cap intersects the
+ // given other cap. (This relationship is not symmetric, since only
+ // the interior of this cap is used.)
+ bool InteriorIntersects(S2Cap const& other) const;
+
+ // Return true if and only if the given point is contained in the interior
+ // of the region (i.e. the region excluding its boundary). 'p' should be
+ // be a unit-length vector.
+ bool InteriorContains(S2Point const& p) const;
+
+ // Increase the cap height if necessary to include the given point.
+ // If the cap is empty the axis is set to the given point, but otherwise
+ // it is left unchanged. 'p' should be a unit-length vector.
+ void AddPoint(S2Point const& p);
+
+ // Increase the cap height if necessary to include "other". If the current
+ // cap is empty it is set to the given other cap.
+ void AddCap(S2Cap const& other);
+
+ // Return a cap that contains all points within a given distance of this
+ // cap. Note that any expansion of the empty cap is still empty.
+ S2Cap Expanded(S1Angle const& distance) const;
+
+ ////////////////////////////////////////////////////////////////////////
+ // S2Region interface (see s2region.h for details):
+
+ virtual S2Cap* Clone() const;
+ virtual S2Cap GetCapBound() const;
+ virtual S2LatLngRect GetRectBound() const;
+ virtual bool Contains(S2Cell const& cell) const;
+ virtual bool MayIntersect(S2Cell const& cell) const;
+ virtual bool VirtualContainsPoint(S2Point const& p) const {
+ return Contains(p); // The same as Contains() below, just virtual.
+ }
+
+ // The point 'p' should be a unit-length vector.
+ bool Contains(S2Point const& p) const;
+
+ virtual void Encode(Encoder* const encoder) const {
+ S2LOG(FATAL) << "Unimplemented";
+ }
+ virtual bool Decode(Decoder* const decoder) { return false; }
+
+ ///////////////////////////////////////////////////////////////////////
+ // The following static methods are convenience functions for assertions
+ // and testing purposes only.
+
+ // Return true if two caps are identical.
+ bool operator==(S2Cap const& other) const;
+
+ // Return true if the cap axis and height differ by at most "max_error"
+ // from the given cap "other".
+ bool ApproxEquals(S2Cap const& other, double max_error = 1e-14);
+
+ private:
+ S2Cap(S2Point const& axis, double height)
+ : axis_(axis), height_(height) {
+ DCHECK(is_valid());
+ }
+
+ // Return true if the cap intersects 'cell', given that the cap
+ // vertices have alrady been checked.
+ bool Intersects(S2Cell const& cell, S2Point const* vertices) const;
+
+ S2Point axis_;
+ double height_;
+};
+
+inline S2Cap S2Cap::FromAxisHeight(S2Point const& axis, double height) {
+ DCHECK(S2::IsUnitLength(axis));
+ return S2Cap(axis, height);
+}
+
+inline S2Cap S2Cap::FromAxisArea(S2Point const& axis, double area) {
+ DCHECK(S2::IsUnitLength(axis));
+ return S2Cap(axis, area / (2 * M_PI));
+}
+
+ostream& operator<<(ostream& os, S2Cap const& cap);
+
+#endif // UTIL_GEOMETRY_S2CAP_H_
diff --git a/src/third_party/s2/s2cap_test.cc b/src/third_party/s2/s2cap_test.cc
new file mode 100644
index 00000000000..eb6abd1d1fc
--- /dev/null
+++ b/src/third_party/s2/s2cap_test.cc
@@ -0,0 +1,253 @@
+// Copyright 2005 Google Inc. All Rights Reserved.
+
+#include "s2cap.h"
+
+#include "base/commandlineflags.h"
+#include "base/logging.h"
+#include "testing/base/public/gunit.h"
+#include "s2.h"
+#include "s2cell.h"
+#include "s2latlng.h"
+#include "s2latlngrect.h"
+
+static S2Point GetLatLngPoint(double lat_degrees, double lng_degrees) {
+ return S2LatLng::FromDegrees(lat_degrees, lng_degrees).ToPoint();
+}
+
+// About 9 times the double-precision roundoff relative error.
+static const double kEps = 1e-15;
+
+TEST(S2Cap, Basic) {
+ // Test basic properties of empty and full caps.
+ S2Cap empty = S2Cap::Empty();
+ S2Cap full = S2Cap::Full();
+ EXPECT_TRUE(empty.is_valid());
+ EXPECT_TRUE(empty.is_empty());
+ EXPECT_TRUE(empty.Complement().is_full());
+ EXPECT_TRUE(full.is_valid());
+ EXPECT_TRUE(full.is_full());
+ EXPECT_TRUE(full.Complement().is_empty());
+ EXPECT_EQ(2, full.height());
+ EXPECT_DOUBLE_EQ(180.0, full.angle().degrees());
+
+ // Check that the default S2Cap is identical to Empty().
+ S2Cap default_empty;
+ EXPECT_TRUE(default_empty.is_valid());
+ EXPECT_TRUE(default_empty.is_empty());
+ EXPECT_EQ(empty.axis(), default_empty.axis());
+ EXPECT_EQ(empty.height(), default_empty.height());
+
+ // Containment and intersection of empty and full caps.
+ EXPECT_TRUE(empty.Contains(empty));
+ EXPECT_TRUE(full.Contains(empty));
+ EXPECT_TRUE(full.Contains(full));
+ EXPECT_FALSE(empty.InteriorIntersects(empty));
+ EXPECT_TRUE(full.InteriorIntersects(full));
+ EXPECT_FALSE(full.InteriorIntersects(empty));
+
+ // Singleton cap containing the x-axis.
+ S2Cap xaxis = S2Cap::FromAxisHeight(S2Point(1, 0, 0), 0);
+ EXPECT_TRUE(xaxis.Contains(S2Point(1, 0, 0)));
+ EXPECT_TRUE(xaxis.VirtualContainsPoint(S2Point(1, 0, 0)));
+ EXPECT_FALSE(xaxis.Contains(S2Point(1, 1e-20, 0)));
+ EXPECT_FALSE(xaxis.VirtualContainsPoint(S2Point(1, 1e-20, 0)));
+ EXPECT_EQ(0, xaxis.angle().radians());
+
+ // Singleton cap containing the y-axis.
+ S2Cap yaxis = S2Cap::FromAxisAngle(S2Point(0, 1, 0), S1Angle::Radians(0));
+ EXPECT_FALSE(yaxis.Contains(xaxis.axis()));
+ EXPECT_EQ(0, xaxis.height());
+
+ // Check that the complement of a singleton cap is the full cap.
+ S2Cap xcomp = xaxis.Complement();
+ EXPECT_TRUE(xcomp.is_valid());
+ EXPECT_TRUE(xcomp.is_full());
+ EXPECT_TRUE(xcomp.Contains(xaxis.axis()));
+
+ // Check that the complement of the complement is *not* the original.
+ EXPECT_TRUE(xcomp.Complement().is_valid());
+ EXPECT_TRUE(xcomp.Complement().is_empty());
+ EXPECT_FALSE(xcomp.Complement().Contains(xaxis.axis()));
+
+ // Check that very small caps can be represented accurately.
+ // Here "kTinyRad" is small enough that unit vectors perturbed by this
+ // amount along a tangent do not need to be renormalized.
+ static const double kTinyRad = 1e-10;
+ S2Cap tiny = S2Cap::FromAxisAngle(S2Point(1, 2, 3).Normalize(),
+ S1Angle::Radians(kTinyRad));
+ S2Point tangent = tiny.axis().CrossProd(S2Point(3, 2, 1)).Normalize();
+ EXPECT_TRUE(tiny.Contains(tiny.axis() + 0.99 * kTinyRad * tangent));
+ EXPECT_FALSE(tiny.Contains(tiny.axis() + 1.01 * kTinyRad * tangent));
+
+ // Basic tests on a hemispherical cap.
+ S2Cap hemi = S2Cap::FromAxisHeight(S2Point(1, 0, 1).Normalize(), 1);
+ EXPECT_EQ(-hemi.axis(), S2Point(hemi.Complement().axis()));
+ EXPECT_EQ(1, hemi.Complement().height());
+ EXPECT_TRUE(hemi.Contains(S2Point(1, 0, 0)));
+ EXPECT_FALSE(hemi.Complement().Contains(S2Point(1, 0, 0)));
+ EXPECT_TRUE(hemi.Contains(S2Point(1, 0, -(1-kEps)).Normalize()));
+ EXPECT_FALSE(hemi.InteriorContains(S2Point(1, 0, -(1+kEps)).Normalize()));
+
+ // A concave cap.
+ S2Cap concave = S2Cap::FromAxisAngle(GetLatLngPoint(80, 10),
+ S1Angle::Degrees(150));
+ EXPECT_TRUE(concave.Contains(GetLatLngPoint(-70 * (1 - kEps), 10)));
+ EXPECT_FALSE(concave.Contains(GetLatLngPoint(-70 * (1 + kEps), 10)));
+ EXPECT_TRUE(concave.Contains(GetLatLngPoint(-50 * (1 - kEps), -170)));
+ EXPECT_FALSE(concave.Contains(GetLatLngPoint(-50 * (1 + kEps), -170)));
+
+ // Cap containment tests.
+ EXPECT_FALSE(empty.Contains(xaxis));
+ EXPECT_FALSE(empty.InteriorIntersects(xaxis));
+ EXPECT_TRUE(full.Contains(xaxis));
+ EXPECT_TRUE(full.InteriorIntersects(xaxis));
+ EXPECT_FALSE(xaxis.Contains(full));
+ EXPECT_FALSE(xaxis.InteriorIntersects(full));
+ EXPECT_TRUE(xaxis.Contains(xaxis));
+ EXPECT_FALSE(xaxis.InteriorIntersects(xaxis));
+ EXPECT_TRUE(xaxis.Contains(empty));
+ EXPECT_FALSE(xaxis.InteriorIntersects(empty));
+ EXPECT_TRUE(hemi.Contains(tiny));
+ EXPECT_TRUE(hemi.Contains(
+ S2Cap::FromAxisAngle(S2Point(1, 0, 0),
+ S1Angle::Radians(M_PI_4 - kEps))));
+ EXPECT_FALSE(hemi.Contains(
+ S2Cap::FromAxisAngle(S2Point(1, 0, 0),
+ S1Angle::Radians(M_PI_4 + kEps))));
+ EXPECT_TRUE(concave.Contains(hemi));
+ EXPECT_TRUE(concave.InteriorIntersects(hemi.Complement()));
+ EXPECT_FALSE(concave.Contains(S2Cap::FromAxisHeight(-concave.axis(), 0.1)));
+}
+
+TEST(S2Cap, GetRectBound) {
+ // Empty and full caps.
+ EXPECT_TRUE(S2Cap::Empty().GetRectBound().is_empty());
+ EXPECT_TRUE(S2Cap::Full().GetRectBound().is_full());
+
+ static const double kDegreeEps = 1e-13;
+ // Maximum allowable error for latitudes and longitudes measured in
+ // degrees. (EXPECT_DOUBLE_EQ isn't sufficient.)
+
+ // Cap that includes the south pole.
+ S2LatLngRect rect = S2Cap::FromAxisAngle(GetLatLngPoint(-45, 57),
+ S1Angle::Degrees(50)).GetRectBound();
+ EXPECT_NEAR(rect.lat_lo().degrees(), -90, kDegreeEps);
+ EXPECT_NEAR(rect.lat_hi().degrees(), 5, kDegreeEps);
+ EXPECT_TRUE(rect.lng().is_full());
+
+ // Cap that is tangent to the north pole.
+ rect = S2Cap::FromAxisAngle(S2Point(1, 0, 1).Normalize(),
+ S1Angle::Radians(M_PI_4 + 1e-16)).GetRectBound();
+ EXPECT_NEAR(rect.lat().lo(), 0, kEps);
+ EXPECT_NEAR(rect.lat().hi(), M_PI_2, kEps);
+ EXPECT_TRUE(rect.lng().is_full());
+
+ rect = S2Cap::FromAxisAngle(S2Point(1, 0, 1).Normalize(),
+ S1Angle::Degrees(45 + 5e-15)).GetRectBound();
+ EXPECT_NEAR(rect.lat_lo().degrees(), 0, kDegreeEps);
+ EXPECT_NEAR(rect.lat_hi().degrees(), 90, kDegreeEps);
+ EXPECT_TRUE(rect.lng().is_full());
+
+ // The eastern hemisphere.
+ rect = S2Cap::FromAxisAngle(S2Point(0, 1, 0),
+ S1Angle::Radians(M_PI_2 + 2e-16)).GetRectBound();
+ EXPECT_NEAR(rect.lat_lo().degrees(), -90, kDegreeEps);
+ EXPECT_NEAR(rect.lat_hi().degrees(), 90, kDegreeEps);
+ EXPECT_TRUE(rect.lng().is_full());
+
+ // A cap centered on the equator.
+ rect = S2Cap::FromAxisAngle(GetLatLngPoint(0, 50),
+ S1Angle::Degrees(20)).GetRectBound();
+ EXPECT_NEAR(rect.lat_lo().degrees(), -20, kDegreeEps);
+ EXPECT_NEAR(rect.lat_hi().degrees(), 20, kDegreeEps);
+ EXPECT_NEAR(rect.lng_lo().degrees(), 30, kDegreeEps);
+ EXPECT_NEAR(rect.lng_hi().degrees(), 70, kDegreeEps);
+
+ // A cap centered on the north pole.
+ rect = S2Cap::FromAxisAngle(GetLatLngPoint(90, 123),
+ S1Angle::Degrees(10)).GetRectBound();
+ EXPECT_NEAR(rect.lat_lo().degrees(), 80, kDegreeEps);
+ EXPECT_NEAR(rect.lat_hi().degrees(), 90, kDegreeEps);
+ EXPECT_TRUE(rect.lng().is_full());
+}
+
+TEST(S2Cap, S2CellMethods) {
+ // For each cube face, we construct some cells on
+ // that face and some caps whose positions are relative to that face,
+ // and then check for the expected intersection/containment results.
+
+ // The distance from the center of a face to one of its vertices.
+ static const double kFaceRadius = atan(sqrt(2));
+
+ for (int face = 0; face < 6; ++face) {
+ // The cell consisting of the entire face.
+ S2Cell root_cell = S2Cell::FromFacePosLevel(face, 0, 0);
+
+ // A leaf cell at the midpoint of the v=1 edge.
+ S2Cell edge_cell(S2::FaceUVtoXYZ(face, 0, 1 - kEps));
+
+ // A leaf cell at the u=1, v=1 corner.
+ S2Cell corner_cell(S2::FaceUVtoXYZ(face, 1 - kEps, 1 - kEps));
+
+ // Quick check for full and empty caps.
+ EXPECT_TRUE(S2Cap::Full().Contains(root_cell));
+ EXPECT_FALSE(S2Cap::Empty().MayIntersect(root_cell));
+
+ // Check intersections with the bounding caps of the leaf cells that are
+ // adjacent to 'corner_cell' along the Hilbert curve. Because this corner
+ // is at (u=1,v=1), the curve stays locally within the same cube face.
+ S2CellId first = corner_cell.id().advance(-3);
+ S2CellId last = corner_cell.id().advance(4);
+ for (S2CellId id = first; id < last; id = id.next()) {
+ S2Cell cell(id);
+ EXPECT_EQ(id == corner_cell.id(),
+ cell.GetCapBound().Contains(corner_cell));
+ EXPECT_EQ(id.parent().contains(corner_cell.id()),
+ cell.GetCapBound().MayIntersect(corner_cell));
+ }
+
+ int anti_face = (face + 3) % 6; // Opposite face.
+ for (int cap_face = 0; cap_face < 6; ++cap_face) {
+ // A cap that barely contains all of 'cap_face'.
+ S2Point center = S2::GetNorm(cap_face);
+ S2Cap covering = S2Cap::FromAxisAngle(
+ center, S1Angle::Radians(kFaceRadius + kEps));
+ EXPECT_EQ(cap_face == face, covering.Contains(root_cell));
+ EXPECT_EQ(cap_face != anti_face, covering.MayIntersect(root_cell));
+ EXPECT_EQ(center.DotProd(edge_cell.GetCenter()) > 0.1,
+ covering.Contains(edge_cell));
+ EXPECT_EQ(covering.MayIntersect(edge_cell), covering.Contains(edge_cell));
+ EXPECT_EQ(cap_face == face, covering.Contains(corner_cell));
+ EXPECT_EQ(center.DotProd(corner_cell.GetCenter()) > 0,
+ covering.MayIntersect(corner_cell));
+
+ // A cap that barely intersects the edges of 'cap_face'.
+ S2Cap bulging = S2Cap::FromAxisAngle(
+ center, S1Angle::Radians(M_PI_4 + kEps));
+ EXPECT_FALSE(bulging.Contains(root_cell));
+ EXPECT_EQ(cap_face != anti_face, bulging.MayIntersect(root_cell));
+ EXPECT_EQ(cap_face == face, bulging.Contains(edge_cell));
+ EXPECT_EQ(center.DotProd(edge_cell.GetCenter()) > 0.1,
+ bulging.MayIntersect(edge_cell));
+ EXPECT_FALSE(bulging.Contains(corner_cell));
+ EXPECT_FALSE(bulging.MayIntersect(corner_cell));
+
+ // A singleton cap.
+ S2Cap singleton = S2Cap::FromAxisAngle(center, S1Angle::Radians(0));
+ EXPECT_EQ(cap_face == face, singleton.MayIntersect(root_cell));
+ EXPECT_FALSE(singleton.MayIntersect(edge_cell));
+ EXPECT_FALSE(singleton.MayIntersect(corner_cell));
+ }
+ }
+}
+
+TEST(S2Cap, Expanded) {
+ EXPECT_TRUE(S2Cap::Empty().Expanded(S1Angle::Radians(2)).is_empty());
+ EXPECT_TRUE(S2Cap::Full().Expanded(S1Angle::Radians(2)).is_full());
+ S2Cap cap50 = S2Cap::FromAxisAngle(S2Point(1, 0, 0), S1Angle::Degrees(50));
+ S2Cap cap51 = S2Cap::FromAxisAngle(S2Point(1, 0, 0), S1Angle::Degrees(51));
+ EXPECT_TRUE(cap50.Expanded(S1Angle::Radians(0)).ApproxEquals(cap50));
+ EXPECT_TRUE(cap50.Expanded(S1Angle::Degrees(1)).ApproxEquals(cap51));
+ EXPECT_FALSE(cap50.Expanded(S1Angle::Degrees(129.99)).is_full());
+ EXPECT_TRUE(cap50.Expanded(S1Angle::Degrees(130.01)).is_full());
+}
diff --git a/src/third_party/s2/s2cell.cc b/src/third_party/s2/s2cell.cc
new file mode 100644
index 00000000000..f01782fefe3
--- /dev/null
+++ b/src/third_party/s2/s2cell.cc
@@ -0,0 +1,223 @@
+// Copyright 2005 Google Inc. All Rights Reserved.
+
+#include "s2cell.h"
+
+#include "base/integral_types.h"
+#include "base/logging.h"
+#include "s2.h"
+#include "s2cap.h"
+#include "s2latlngrect.h"
+#include "util/math/vector2-inl.h"
+
+// Since S2Cells are copied by value, the following assertion is a reminder
+// not to add fields unnecessarily. An S2Cell currently consists of 43 data
+// bytes, one vtable pointer, plus alignment overhead. This works out to 48
+// bytes on 32 bit architectures and 56 bytes on 64 bit architectures.
+//
+// The expression below rounds up (43 + sizeof(void*)) to the nearest
+// multiple of sizeof(void*).
+COMPILE_ASSERT(sizeof(S2Cell) <= ((43+2*sizeof(void*)-1) & -sizeof(void*)),
+ S2Cell_is_getting_bloated);
+
+S2Point S2Cell::GetVertexRaw(int k) const {
+ // Vertices are returned in the order SW, SE, NE, NW.
+ return S2::FaceUVtoXYZ(face_, uv_[0][(k>>1) ^ (k&1)], uv_[1][k>>1]);
+}
+
+S2Point S2Cell::GetEdgeRaw(int k) const {
+ switch (k) {
+ case 0: return S2::GetVNorm(face_, uv_[1][0]); // South
+ case 1: return S2::GetUNorm(face_, uv_[0][1]); // East
+ case 2: return -S2::GetVNorm(face_, uv_[1][1]); // North
+ default: return -S2::GetUNorm(face_, uv_[0][0]); // West
+ }
+}
+
+void S2Cell::Init(S2CellId const& id) {
+ id_ = id;
+ int ij[2], orientation;
+ face_ = id.ToFaceIJOrientation(&ij[0], &ij[1], &orientation);
+ orientation_ = orientation; // Compress int to a byte.
+ level_ = id.level();
+ int cellSize = GetSizeIJ(); // Depends on level_.
+ for (int d = 0; d < 2; ++d) {
+ int ij_lo = ij[d] & -cellSize;
+ int ij_hi = ij_lo + cellSize;
+ uv_[d][0] = S2::STtoUV((1.0 / S2CellId::kMaxSize) * ij_lo);
+ uv_[d][1] = S2::STtoUV((1.0 / S2CellId::kMaxSize) * ij_hi);
+ }
+}
+
+bool S2Cell::Subdivide(S2Cell children[4]) const {
+ // This function is equivalent to just iterating over the child cell ids
+ // and calling the S2Cell constructor, but it is about 2.5 times faster.
+
+ if (id_.is_leaf()) return false;
+
+ // Compute the cell midpoint in uv-space.
+ Vector2_d uv_mid = id_.GetCenterUV();
+
+ // Create four children with the appropriate bounds.
+ S2CellId id = id_.child_begin();
+ for (int pos = 0; pos < 4; ++pos, id = id.next()) {
+ S2Cell *child = &children[pos];
+ child->face_ = face_;
+ child->level_ = level_ + 1;
+ child->orientation_ = orientation_ ^ S2::kPosToOrientation[pos];
+ child->id_ = id;
+ // We want to split the cell in half in "u" and "v". To decide which
+ // side to set equal to the midpoint value, we look at cell's (i,j)
+ // position within its parent. The index for "i" is in bit 1 of ij.
+ int ij = S2::kPosToIJ[orientation_][pos];
+ int i = ij >> 1;
+ int j = ij & 1;
+ child->uv_[0][i] = uv_[0][i];
+ child->uv_[0][1-i] = uv_mid[0];
+ child->uv_[1][j] = uv_[1][j];
+ child->uv_[1][1-j] = uv_mid[1];
+ }
+ return true;
+}
+
+S2Point S2Cell::GetCenterRaw() const {
+ return id_.ToPointRaw();
+}
+
+double S2Cell::AverageArea(int level) {
+ return S2::kAvgArea.GetValue(level);
+}
+
+double S2Cell::ApproxArea() const {
+ // All cells at the first two levels have the same area.
+ if (level_ < 2) return AverageArea(level_);
+
+ // First, compute the approximate area of the cell when projected
+ // perpendicular to its normal. The cross product of its diagonals gives
+ // the normal, and the length of the normal is twice the projected area.
+ double flat_area = 0.5 * (GetVertex(2) - GetVertex(0)).
+ CrossProd(GetVertex(3) - GetVertex(1)).Norm();
+
+ // Now, compensate for the curvature of the cell surface by pretending
+ // that the cell is shaped like a spherical cap. The ratio of the
+ // area of a spherical cap to the area of its projected disc turns out
+ // to be 2 / (1 + sqrt(1 - r*r)) where "r" is the radius of the disc.
+ // For example, when r=0 the ratio is 1, and when r=1 the ratio is 2.
+ // Here we set Pi*r*r == flat_area to find the equivalent disc.
+ return flat_area * 2 / (1 + sqrt(1 - min(M_1_PI * flat_area, 1.0)));
+}
+
+double S2Cell::ExactArea() const {
+ S2Point v0 = GetVertex(0);
+ S2Point v1 = GetVertex(1);
+ S2Point v2 = GetVertex(2);
+ S2Point v3 = GetVertex(3);
+ return S2::Area(v0, v1, v2) + S2::Area(v0, v2, v3);
+}
+
+S2Cell* S2Cell::Clone() const {
+ return new S2Cell(*this);
+}
+
+S2Cap S2Cell::GetCapBound() const {
+ // Use the cell center in (u,v)-space as the cap axis. This vector is
+ // very close to GetCenter() and faster to compute. Neither one of these
+ // vectors yields the bounding cap with minimal surface area, but they
+ // are both pretty close.
+ //
+ // It's possible to show that the two vertices that are furthest from
+ // the (u,v)-origin never determine the maximum cap size (this is a
+ // possible future optimization).
+
+ double u = 0.5 * (uv_[0][0] + uv_[0][1]);
+ double v = 0.5 * (uv_[1][0] + uv_[1][1]);
+ S2Cap cap = S2Cap::FromAxisHeight(S2::FaceUVtoXYZ(face_,u,v).Normalize(), 0);
+ for (int k = 0; k < 4; ++k) {
+ cap.AddPoint(GetVertex(k));
+ }
+ return cap;
+}
+
+inline double S2Cell::GetLatitude(int i, int j) const {
+ S2Point p = S2::FaceUVtoXYZ(face_, uv_[0][i], uv_[1][j]);
+ return S2LatLng::Latitude(p).radians();
+}
+
+inline double S2Cell::GetLongitude(int i, int j) const {
+ S2Point p = S2::FaceUVtoXYZ(face_, uv_[0][i], uv_[1][j]);
+ return S2LatLng::Longitude(p).radians();
+}
+
+S2LatLngRect S2Cell::GetRectBound() const {
+ if (level_ > 0) {
+ // Except for cells at level 0, the latitude and longitude extremes are
+ // attained at the vertices. Furthermore, the latitude range is
+ // determined by one pair of diagonally opposite vertices and the
+ // longitude range is determined by the other pair.
+ //
+ // We first determine which corner (i,j) of the cell has the largest
+ // absolute latitude. To maximize latitude, we want to find the point in
+ // the cell that has the largest absolute z-coordinate and the smallest
+ // absolute x- and y-coordinates. To do this we look at each coordinate
+ // (u and v), and determine whether we want to minimize or maximize that
+ // coordinate based on the axis direction and the cell's (u,v) quadrant.
+ double u = uv_[0][0] + uv_[0][1];
+ double v = uv_[1][0] + uv_[1][1];
+ int i = S2::GetUAxis(face_)[2] == 0 ? (u < 0) : (u > 0);
+ int j = S2::GetVAxis(face_)[2] == 0 ? (v < 0) : (v > 0);
+
+ // We grow the bounds slightly to make sure that the bounding rectangle
+ // also contains the normalized versions of the vertices. Note that the
+ // maximum result magnitude is Pi, with a floating-point exponent of 1.
+ // Therefore adding or subtracting 2**-51 will always change the result.
+ static double const kMaxError = 1.0 / (int64(1) << 51);
+ R1Interval lat = R1Interval::FromPointPair(GetLatitude(i, j),
+ GetLatitude(1-i, 1-j));
+ lat = lat.Expanded(kMaxError).Intersection(S2LatLngRect::FullLat());
+ if (lat.lo() == -M_PI_2 || lat.hi() == M_PI_2) {
+ return S2LatLngRect(lat, S1Interval::Full());
+ }
+ S1Interval lng = S1Interval::FromPointPair(GetLongitude(i, 1-j),
+ GetLongitude(1-i, j));
+ return S2LatLngRect(lat, lng.Expanded(kMaxError));
+ }
+
+ // The 4 cells around the equator extend to +/-45 degrees latitude at the
+ // midpoints of their top and bottom edges. The two cells covering the
+ // poles extend down to +/-35.26 degrees at their vertices.
+ static double const kPoleMinLat = asin(sqrt(1./3)); // 35.26 degrees
+
+ // The face centers are the +X, +Y, +Z, -X, -Y, -Z axes in that order.
+ DCHECK_EQ(((face_ < 3) ? 1 : -1), S2::GetNorm(face_)[face_ % 3]);
+ switch (face_) {
+ case 0: return S2LatLngRect(R1Interval(-M_PI_4, M_PI_4),
+ S1Interval(-M_PI_4, M_PI_4));
+ case 1: return S2LatLngRect(R1Interval(-M_PI_4, M_PI_4),
+ S1Interval(M_PI_4, 3*M_PI_4));
+ case 2: return S2LatLngRect(R1Interval(kPoleMinLat, M_PI_2),
+ S1Interval(-M_PI, M_PI));
+ case 3: return S2LatLngRect(R1Interval(-M_PI_4, M_PI_4),
+ S1Interval(3*M_PI_4, -3*M_PI_4));
+ case 4: return S2LatLngRect(R1Interval(-M_PI_4, M_PI_4),
+ S1Interval(-3*M_PI_4, -M_PI_4));
+ default: return S2LatLngRect(R1Interval(-M_PI_2, -kPoleMinLat),
+ S1Interval(-M_PI, M_PI));
+ }
+}
+
+bool S2Cell::MayIntersect(S2Cell const& cell) const {
+ return id_.intersects(cell.id_);
+}
+
+bool S2Cell::Contains(S2Cell const& cell) const {
+ return id_.contains(cell.id_);
+}
+
+bool S2Cell::Contains(S2Point const& p) const {
+ // We can't just call XYZtoFaceUV, because for points that lie on the
+ // boundary between two faces (i.e. u or v is +1/-1) we need to return
+ // true for both adjacent cells.
+ double u, v;
+ if (!S2::FaceXYZtoUV(face_, p, &u, &v)) return false;
+ return (u >= uv_[0][0] && u <= uv_[0][1] &&
+ v >= uv_[1][0] && v <= uv_[1][1]);
+}
diff --git a/src/third_party/s2/s2cell.h b/src/third_party/s2/s2cell.h
new file mode 100644
index 00000000000..4642cd3f041
--- /dev/null
+++ b/src/third_party/s2/s2cell.h
@@ -0,0 +1,143 @@
+// Copyright 2005 Google Inc. All Rights Reserved.
+
+#ifndef UTIL_GEOMETRY_S2CELL_H_
+#define UTIL_GEOMETRY_S2CELL_H_
+
+#include "base/basictypes.h"
+#include "base/logging.h"
+#include "s2.h"
+#include "s2cellid.h"
+#include "s2region.h"
+#include "util/math/vector2.h"
+
+// An S2Cell is an S2Region object that represents a cell. Unlike S2CellIds,
+// it supports efficient containment and intersection tests. However, it is
+// also a more expensive representation (currently 48 bytes rather than 8).
+
+// This class is intended to be copied by value as desired. It uses
+// the default copy constructor and assignment operator, however it is
+// not a "plain old datatype" (POD) because it has virtual functions.
+class S2Cell : public S2Region {
+ public:
+ // The default constructor is required in order to use freelists.
+ // Cells should otherwise always be constructed explicitly.
+ S2Cell() {}
+
+ // An S2Cell always corresponds to a particular S2CellId. The other
+ // constructors are just convenience methods.
+ explicit S2Cell(S2CellId const& id) { Init(id); }
+
+ static S2Cell FromFacePosLevel(int face, uint64 pos, int level) {
+ // This is a static method in order to provide named parameters.
+ return S2Cell(S2CellId::FromFacePosLevel(face, pos, level));
+ }
+ // Convenience methods. The S2LatLng must be normalized.
+ explicit S2Cell(S2Point const& p) { Init(S2CellId::FromPoint(p)); }
+ explicit S2Cell(S2LatLng const& ll) { Init(S2CellId::FromLatLng(ll)); }
+
+ inline S2CellId id() const { return id_; }
+ inline int face() const { return face_; }
+ inline int level() const { return level_; }
+ inline int orientation() const { return orientation_; }
+ inline bool is_leaf() const { return level_ == S2CellId::kMaxLevel; }
+
+ // These are equivalent to the S2CellId methods, but have a more efficient
+ // implementation since the level has been precomputed.
+ int GetSizeIJ() const;
+ double GetSizeST() const;
+
+ // Return the k-th vertex of the cell (k = 0,1,2,3). Vertices are returned
+ // in CCW order. The points returned by GetVertexRaw are not necessarily
+ // unit length.
+ S2Point GetVertex(int k) const { return GetVertexRaw(k).Normalize(); }
+ S2Point GetVertexRaw(int k) const;
+
+ // Return the inward-facing normal of the great circle passing through
+ // the edge from vertex k to vertex k+1 (mod 4). The normals returned
+ // by GetEdgeRaw are not necessarily unit length.
+ S2Point GetEdge(int k) const { return GetEdgeRaw(k).Normalize(); }
+ S2Point GetEdgeRaw(int k) const;
+
+ // If this is not a leaf cell, set children[0..3] to the four children of
+ // this cell (in traversal order) and return true. Otherwise returns false.
+ // This method is equivalent to the following:
+ //
+ // for (pos=0, id=child_begin(); id != child_end(); id = id.next(), ++pos)
+ // children[i] = S2Cell(id);
+ //
+ // except that it is more than two times faster.
+ bool Subdivide(S2Cell children[4]) const;
+
+ // Return the direction vector corresponding to the center in (s,t)-space of
+ // the given cell. This is the point at which the cell is divided into four
+ // subcells; it is not necessarily the centroid of the cell in (u,v)-space
+ // or (x,y,z)-space. The point returned by GetCenterRaw is not necessarily
+ // unit length.
+ S2Point GetCenter() const { return GetCenterRaw().Normalize(); }
+ S2Point GetCenterRaw() const;
+
+ // Return the average area for cells at the given level.
+ static double AverageArea(int level);
+
+ // Return the average area of cells at this level. This is accurate to
+ // within a factor of 1.7 (for S2_QUADRATIC_PROJECTION) and is extremely
+ // cheap to compute.
+ double AverageArea() const { return AverageArea(level_); }
+
+ // Return the approximate area of this cell. This method is accurate to
+ // within 3% percent for all cell sizes and accurate to within 0.1% for
+ // cells at level 5 or higher (i.e. squares 350km to a side or smaller
+ // on the Earth's surface). It is moderately cheap to compute.
+ double ApproxArea() const;
+
+ // Return the area of this cell as accurately as possible. This method is
+ // more expensive but it is accurate to 6 digits of precision even for leaf
+ // cells (whose area is approximately 1e-18).
+ double ExactArea() const;
+
+ ////////////////////////////////////////////////////////////////////////
+ // S2Region interface (see s2region.h for details):
+
+ virtual S2Cell* Clone() const;
+ virtual S2Cap GetCapBound() const;
+ virtual S2LatLngRect GetRectBound() const;
+ virtual bool Contains(S2Cell const& cell) const;
+ virtual bool MayIntersect(S2Cell const& cell) const;
+ virtual bool VirtualContainsPoint(S2Point const& p) const {
+ return Contains(p); // The same as Contains() below, just virtual.
+ }
+
+ // The point 'p' does not need to be normalized.
+ bool Contains(S2Point const& p) const;
+
+ virtual void Encode(Encoder* const encoder) const {
+ S2LOG(FATAL) << "Unimplemented";
+ }
+ virtual bool Decode(Decoder* const decoder) { return false; }
+
+ private:
+ // Internal method that does the actual work in the constructors.
+ void Init(S2CellId const& id);
+
+ // Return the latitude or longitude of the cell vertex given by (i,j),
+ // where "i" and "j" are either 0 or 1.
+ inline double GetLatitude(int i, int j) const;
+ inline double GetLongitude(int i, int j) const;
+
+ // This structure occupies 44 bytes plus one pointer for the vtable.
+ int8 face_;
+ int8 level_;
+ int8 orientation_;
+ S2CellId id_;
+ double uv_[2][2];
+};
+
+inline int S2Cell::GetSizeIJ() const {
+ return S2CellId::GetSizeIJ(level());
+}
+
+inline double S2Cell::GetSizeST() const {
+ return S2CellId::GetSizeST(level());
+}
+
+#endif // UTIL_GEOMETRY_S2CELL_H_
diff --git a/src/third_party/s2/s2cell_test.cc b/src/third_party/s2/s2cell_test.cc
new file mode 100644
index 00000000000..d235b1b34b9
--- /dev/null
+++ b/src/third_party/s2/s2cell_test.cc
@@ -0,0 +1,382 @@
+// Copyright 2005 Google Inc. All Rights Reserved.
+
+#include "s2cell.h"
+
+#include <cstdio>
+#include <map>
+using std::map;
+using std::multimap;
+
+#include <vector>
+using std::vector;
+
+
+#include "base/commandlineflags.h"
+#include "base/logging.h"
+#include "testing/base/public/gunit.h"
+#include "s2.h"
+#include "s2cap.h"
+#include "s2latlngrect.h"
+#include "s2testing.h"
+
+TEST(S2Cell, TestFaces) {
+ map<S2Point, int> edge_counts;
+ map<S2Point, int> vertex_counts;
+ for (int face = 0; face < 6; ++face) {
+ S2CellId id = S2CellId::FromFacePosLevel(face, 0, 0);
+ S2Cell cell(id);
+ EXPECT_EQ(id, cell.id());
+ EXPECT_EQ(face, cell.face());
+ EXPECT_EQ(0, cell.level());
+ // Top-level faces have alternating orientations to get RHS coordinates.
+ EXPECT_EQ(face & S2::kSwapMask, cell.orientation());
+ EXPECT_FALSE(cell.is_leaf());
+ for (int k = 0; k < 4; ++k) {
+ edge_counts[cell.GetEdgeRaw(k)] += 1;
+ vertex_counts[cell.GetVertexRaw(k)] += 1;
+ EXPECT_DOUBLE_EQ(0.0, cell.GetVertexRaw(k).DotProd(cell.GetEdgeRaw(k)));
+ EXPECT_DOUBLE_EQ(0.0,
+ cell.GetVertexRaw((k+1)&3).DotProd(cell.GetEdgeRaw(k)));
+ EXPECT_DOUBLE_EQ(1.0,
+ cell.GetVertexRaw(k)
+ .CrossProd(cell.GetVertexRaw((k+1)&3))
+ .Normalize().DotProd(cell.GetEdge(k)));
+ }
+ }
+ // Check that edges have multiplicity 2 and vertices have multiplicity 3.
+ for (map<S2Point, int>::iterator i = edge_counts.begin();
+ i != edge_counts.end(); ++i) {
+ EXPECT_EQ(2, i->second);
+ }
+ for (map<S2Point, int>::iterator i = vertex_counts.begin();
+ i != vertex_counts.end(); ++i) {
+ EXPECT_EQ(3, i->second);
+ }
+}
+
+struct LevelStats {
+ double count;
+ double min_area, max_area, avg_area;
+ double min_width, max_width, avg_width;
+ double min_edge, max_edge, avg_edge, max_edge_aspect;
+ double min_diag, max_diag, avg_diag, max_diag_aspect;
+ double min_angle_span, max_angle_span, avg_angle_span;
+ double min_approx_ratio, max_approx_ratio;
+ LevelStats()
+ : count(0), min_area(100), max_area(0), avg_area(0),
+ min_width(100), max_width(0), avg_width(0),
+ min_edge(100), max_edge(0), avg_edge(0), max_edge_aspect(0),
+ min_diag(100), max_diag(0), avg_diag(0), max_diag_aspect(0),
+ min_angle_span(100), max_angle_span(0), avg_angle_span(0),
+ min_approx_ratio(100), max_approx_ratio(0) {}
+};
+static vector<LevelStats> level_stats(S2CellId::kMaxLevel+1);
+
+static void GatherStats(S2Cell const& cell) {
+ LevelStats* s = &level_stats[cell.level()];
+ double exact_area = cell.ExactArea();
+ double approx_area = cell.ApproxArea();
+ double min_edge = 100, max_edge = 0, avg_edge = 0;
+ double min_diag = 100, max_diag = 0;
+ double min_width = 100, max_width = 0;
+ double min_angle_span = 100, max_angle_span = 0;
+ for (int i = 0; i < 4; ++i) {
+ double edge = cell.GetVertexRaw(i).Angle(cell.GetVertexRaw((i+1)&3));
+ min_edge = min(edge, min_edge);
+ max_edge = max(edge, max_edge);
+ avg_edge += 0.25 * edge;
+ S2Point mid = cell.GetVertexRaw(i) + cell.GetVertexRaw((i+1)&3);
+ double width = M_PI_2 - mid.Angle(cell.GetEdgeRaw(i^2));
+ min_width = min(width, min_width);
+ max_width = max(width, max_width);
+ if (i < 2) {
+ double diag = cell.GetVertexRaw(i).Angle(cell.GetVertexRaw(i^2));
+ min_diag = min(diag, min_diag);
+ max_diag = max(diag, max_diag);
+ double angle_span = cell.GetEdgeRaw(i).Angle(-cell.GetEdgeRaw(i^2));
+ min_angle_span = min(angle_span, min_angle_span);
+ max_angle_span = max(angle_span, max_angle_span);
+ }
+ }
+ s->count += 1;
+ s->min_area = min(exact_area, s->min_area);
+ s->max_area = max(exact_area, s->max_area);
+ s->avg_area += exact_area;
+ s->min_width = min(min_width, s->min_width);
+ s->max_width = max(max_width, s->max_width);
+ s->avg_width += 0.5 * (min_width + max_width);
+ s->min_edge = min(min_edge, s->min_edge);
+ s->max_edge = max(max_edge, s->max_edge);
+ s->avg_edge += avg_edge;
+ s->max_edge_aspect = max(max_edge / min_edge, s->max_edge_aspect);
+ s->min_diag = min(min_diag, s->min_diag);
+ s->max_diag = max(max_diag, s->max_diag);
+ s->avg_diag += 0.5 * (min_diag + max_diag);
+ s->max_diag_aspect = max(max_diag / min_diag, s->max_diag_aspect);
+ s->min_angle_span = min(min_angle_span, s->min_angle_span);
+ s->max_angle_span = max(max_angle_span, s->max_angle_span);
+ s->avg_angle_span += 0.5 * (min_angle_span + max_angle_span);
+ double approx_ratio = approx_area / exact_area;
+ s->min_approx_ratio = min(approx_ratio, s->min_approx_ratio);
+ s->max_approx_ratio = max(approx_ratio, s->max_approx_ratio);
+}
+
+static void TestSubdivide(S2Cell const& cell) {
+ GatherStats(cell);
+ if (cell.is_leaf()) return;
+
+ S2Cell children[4];
+ CHECK(cell.Subdivide(children));
+ S2CellId child_id = cell.id().child_begin();
+ double exact_area = 0;
+ double approx_area = 0;
+ double average_area = 0;
+ for (int i = 0; i < 4; ++i, child_id = child_id.next()) {
+ exact_area += children[i].ExactArea();
+ approx_area += children[i].ApproxArea();
+ average_area += children[i].AverageArea();
+
+ // Check that the child geometry is consistent with its cell ID.
+ EXPECT_EQ(child_id, children[i].id());
+ EXPECT_TRUE(S2::ApproxEquals(children[i].GetCenter(), child_id.ToPoint()));
+ S2Cell direct(child_id);
+ EXPECT_EQ(direct.face(), children[i].face());
+ EXPECT_EQ(direct.level(), children[i].level());
+ EXPECT_EQ(direct.orientation(), children[i].orientation());
+ EXPECT_EQ(direct.GetCenterRaw(), children[i].GetCenterRaw());
+ for (int k = 0; k < 4; ++k) {
+ EXPECT_EQ(direct.GetVertexRaw(k), children[i].GetVertexRaw(k));
+ EXPECT_EQ(direct.GetEdgeRaw(k), children[i].GetEdgeRaw(k));
+ }
+
+ // Test Contains() and MayIntersect().
+ EXPECT_TRUE(cell.Contains(children[i]));
+ EXPECT_TRUE(cell.MayIntersect(children[i]));
+ EXPECT_FALSE(children[i].Contains(cell));
+ EXPECT_TRUE(cell.Contains(children[i].GetCenterRaw()));
+ EXPECT_TRUE(cell.VirtualContainsPoint(children[i].GetCenterRaw()));
+ for (int j = 0; j < 4; ++j) {
+ EXPECT_TRUE(cell.Contains(children[i].GetVertexRaw(j)));
+ if (j != i) {
+ EXPECT_FALSE(children[i].Contains(children[j].GetCenterRaw()));
+ EXPECT_FALSE(
+ children[i].VirtualContainsPoint(children[j].GetCenterRaw()));
+ EXPECT_FALSE(children[i].MayIntersect(children[j]));
+ }
+ }
+
+ // Test GetCapBound and GetRectBound.
+ S2Cap parent_cap = cell.GetCapBound();
+ S2LatLngRect parent_rect = cell.GetRectBound();
+ if (cell.Contains(S2Point(0, 0, 1)) || cell.Contains(S2Point(0, 0, -1))) {
+ EXPECT_TRUE(parent_rect.lng().is_full());
+ }
+ S2Cap child_cap = children[i].GetCapBound();
+ S2LatLngRect child_rect = children[i].GetRectBound();
+ EXPECT_TRUE(child_cap.Contains(children[i].GetCenter()));
+ EXPECT_TRUE(child_rect.Contains(children[i].GetCenterRaw()));
+ EXPECT_TRUE(parent_cap.Contains(children[i].GetCenter()));
+ EXPECT_TRUE(parent_rect.Contains(children[i].GetCenterRaw()));
+ for (int j = 0; j < 4; ++j) {
+ EXPECT_TRUE(child_cap.Contains(children[i].GetVertex(j)));
+ EXPECT_TRUE(child_rect.Contains(children[i].GetVertex(j)));
+ EXPECT_TRUE(child_rect.Contains(children[i].GetVertexRaw(j)));
+ EXPECT_TRUE(parent_cap.Contains(children[i].GetVertex(j)));
+ EXPECT_TRUE(parent_rect.Contains(children[i].GetVertex(j)));
+ EXPECT_TRUE(parent_rect.Contains(children[i].GetVertexRaw(j)));
+ if (j != i) {
+ // The bounding caps and rectangles should be tight enough so that
+ // they exclude at least two vertices of each adjacent cell.
+ int cap_count = 0;
+ int rect_count = 0;
+ for (int k = 0; k < 4; ++k) {
+ if (child_cap.Contains(children[j].GetVertex(k)))
+ ++cap_count;
+ if (child_rect.Contains(children[j].GetVertexRaw(k)))
+ ++rect_count;
+ }
+ EXPECT_LE(cap_count, 2);
+ if (child_rect.lat_lo().radians() > -M_PI_2 &&
+ child_rect.lat_hi().radians() < M_PI_2) {
+ // Bounding rectangles may be too large at the poles because the
+ // pole itself has an arbitrary fixed longitude.
+ EXPECT_LE(rect_count, 2);
+ }
+ }
+ }
+
+ // Check all children for the first few levels, and then sample randomly.
+ // Also subdivide one corner cell, one edge cell, and one center cell
+ // so that we have a better chance of sample the minimum metric values.
+ bool force_subdivide = false;
+ S2Point center = S2::GetNorm(children[i].face());
+ S2Point edge = center + S2::GetUAxis(children[i].face());
+ S2Point corner = edge + S2::GetVAxis(children[i].face());
+ for (int j = 0; j < 4; ++j) {
+ S2Point p = children[i].GetVertexRaw(j);
+ if (p == center || p == edge || p == corner)
+ force_subdivide = true;
+ }
+ if (force_subdivide || cell.level() < (DEBUG_MODE ? 5 : 6) ||
+ S2Testing::rnd.OneIn(DEBUG_MODE ? 5 : 4)) {
+ TestSubdivide(children[i]);
+ }
+ }
+
+ // Check sum of child areas equals parent area.
+ //
+ // For ExactArea(), the best relative error we can expect is about 1e-6
+ // because the precision of the unit vector coordinates is only about 1e-15
+ // and the edge length of a leaf cell is about 1e-9.
+ //
+ // For ApproxArea(), the areas are accurate to within a few percent.
+ //
+ // For AverageArea(), the areas themselves are not very accurate, but
+ // the average area of a parent is exactly 4 times the area of a child.
+
+ EXPECT_LE(fabs(log(exact_area / cell.ExactArea())), fabs(log(1 + 1e-6)));
+ EXPECT_LE(fabs(log(approx_area / cell.ApproxArea())), fabs(log(1.03)));
+ EXPECT_LE(fabs(log(average_area / cell.AverageArea())), fabs(log(1 + 1e-15)));
+}
+
+template <int dim>
+static void CheckMinMaxAvg(
+ char const* label, int level, double count, double abs_error,
+ double min_value, double max_value, double avg_value,
+ S2::Metric<dim> const& min_metric,
+ S2::Metric<dim> const& max_metric,
+ S2::Metric<dim> const& avg_metric) {
+
+ // All metrics are minimums, maximums, or averages of differential
+ // quantities, and therefore will not be exact for cells at any finite
+ // level. The differential minimum is always a lower bound, and the maximum
+ // is always an upper bound, but these minimums and maximums may not be
+ // achieved for two different reasons. First, the cells at each level are
+ // sampled and we may miss the most extreme examples. Second, the actual
+ // metric for a cell is obtained by integrating the differential quantity,
+ // which is not constant across the cell. Therefore cells at low levels
+ // (bigger cells) have smaller variations.
+ //
+ // The "tolerance" below is an attempt to model both of these effects.
+ // At low levels, error is dominated by the variation of differential
+ // quantities across the cells, while at high levels error is dominated by
+ // the effects of random sampling.
+ double tolerance = (max_metric.GetValue(level) - min_metric.GetValue(level)) /
+ sqrt(min(count, 0.5 * double(1 << level)));
+ if (tolerance == 0) tolerance = abs_error;
+
+ double min_error = min_value - min_metric.GetValue(level);
+ double max_error = max_metric.GetValue(level) - max_value;
+ double avg_error = fabs(avg_metric.GetValue(level) - avg_value);
+ printf("%-10s (%6.0f samples, tolerance %8.3g) - min (%9.3g : %9.3g) "
+ "max (%9.3g : %9.3g), avg (%9.3g : %9.3g)\n",
+ label, count, tolerance,
+ min_error / min_value, min_error / tolerance,
+ max_error / max_value, max_error / tolerance,
+ avg_error / avg_value, avg_error / tolerance);
+
+ EXPECT_LE(min_metric.GetValue(level), min_value + abs_error);
+ EXPECT_GE(min_metric.GetValue(level), min_value - tolerance);
+ EXPECT_LE(max_metric.GetValue(level), max_value + tolerance);
+ EXPECT_GE(max_metric.GetValue(level), max_value - abs_error);
+ EXPECT_NEAR(avg_metric.GetValue(level), avg_value, 10 * tolerance);
+}
+
+TEST(S2Cell, TestSubdivide) {
+ for (int face = 0; face < 6; ++face) {
+ TestSubdivide(S2Cell::FromFacePosLevel(face, 0, 0));
+ }
+
+ // The maximum edge *ratio* is the ratio of the longest edge of any cell to
+ // the shortest edge of any cell at the same level (and similarly for the
+ // maximum diagonal ratio).
+ //
+ // The maximum edge *aspect* is the maximum ratio of the longest edge of a
+ // cell to the shortest edge of that same cell (and similarly for the
+ // maximum diagonal aspect).
+
+ printf("Level Area Edge Diag Approx Average\n");
+ printf(" Ratio Ratio Aspect Ratio Aspect Min Max Min Max\n");
+ for (int i = 0; i <= S2CellId::kMaxLevel; ++i) {
+ LevelStats* s = &level_stats[i];
+ if (s->count > 0) {
+ s->avg_area /= s->count;
+ s->avg_width /= s->count;
+ s->avg_edge /= s->count;
+ s->avg_diag /= s->count;
+ s->avg_angle_span /= s->count;
+ }
+ printf("%5d %6.3f %6.3f %6.3f %6.3f %6.3f %6.3f %6.3f %6.3f %6.3f\n",
+ i, s->max_area / s->min_area,
+ s->max_edge / s->min_edge, s->max_edge_aspect,
+ s->max_diag / s->min_diag, s->max_diag_aspect,
+ s->min_approx_ratio, s->max_approx_ratio,
+ S2Cell::AverageArea(i) / s->max_area,
+ S2Cell::AverageArea(i) / s->min_area);
+ }
+
+ // Now check the validity of the S2 length and area metrics.
+ for (int i = 0; i <= S2CellId::kMaxLevel; ++i) {
+ LevelStats const* s = &level_stats[i];
+ if (s->count == 0) continue;
+
+ printf("Level %2d - metric (error/actual : error/tolerance)\n", i);
+
+ // The various length calculations are only accurate to 1e-15 or so,
+ // so we need to allow for this amount of discrepancy with the theoretical
+ // minimums and maximums. The area calculation is accurate to about 1e-15
+ // times the cell width.
+ CheckMinMaxAvg("area", i, s->count, 1e-15 * s->min_width,
+ s->min_area, s->max_area, s->avg_area,
+ S2::kMinArea, S2::kMaxArea, S2::kAvgArea);
+ CheckMinMaxAvg("width", i, s->count, 1e-15,
+ s->min_width, s->max_width, s->avg_width,
+ S2::kMinWidth, S2::kMaxWidth, S2::kAvgWidth);
+ CheckMinMaxAvg("edge", i, s->count, 1e-15,
+ s->min_edge, s->max_edge, s->avg_edge,
+ S2::kMinEdge, S2::kMaxEdge, S2::kAvgEdge);
+ CheckMinMaxAvg("diagonal", i, s->count, 1e-15,
+ s->min_diag, s->max_diag, s->avg_diag,
+ S2::kMinDiag, S2::kMaxDiag, S2::kAvgDiag);
+ CheckMinMaxAvg("angle span", i, s->count, 1e-15,
+ s->min_angle_span, s->max_angle_span, s->avg_angle_span,
+ S2::kMinAngleSpan, S2::kMaxAngleSpan, S2::kAvgAngleSpan);
+
+ // The aspect ratio calculations are ratios of lengths and are therefore
+ // less accurate at higher subdivision levels.
+ EXPECT_LE(s->max_edge_aspect, S2::kMaxEdgeAspect + 1e-15 * (1 << i));
+ EXPECT_LE(s->max_diag_aspect, S2::kMaxDiagAspect + 1e-15 * (1 << i));
+ }
+}
+
+static int const kMaxLevel = DEBUG_MODE ? 6 : 11;
+
+static void ExpandChildren1(S2Cell const& cell) {
+ S2Cell children[4];
+ CHECK(cell.Subdivide(children));
+ if (children[0].level() < kMaxLevel) {
+ for (int pos = 0; pos < 4; ++pos) {
+ ExpandChildren1(children[pos]);
+ }
+ }
+}
+
+static void ExpandChildren2(S2Cell const& cell) {
+ S2CellId id = cell.id().child_begin();
+ for (int pos = 0; pos < 4; ++pos, id = id.next()) {
+ S2Cell child(id);
+ if (child.level() < kMaxLevel) ExpandChildren2(child);
+ }
+}
+
+TEST(S2Cell, TestPerformance) {
+ double subdivide_start = S2Testing::GetCpuTime();
+ ExpandChildren1(S2Cell::FromFacePosLevel(0, 0, 0));
+ double subdivide_time = S2Testing::GetCpuTime() - subdivide_start;
+ fprintf(stderr, "Subdivide: %.3f seconds\n", subdivide_time);
+
+ double constructor_start = S2Testing::GetCpuTime();
+ ExpandChildren2(S2Cell::FromFacePosLevel(0, 0, 0));
+ double constructor_time = S2Testing::GetCpuTime() - constructor_start;
+ fprintf(stderr, "Constructor: %.3f seconds\n", constructor_time);
+}
diff --git a/src/third_party/s2/s2cellid.cc b/src/third_party/s2/s2cellid.cc
new file mode 100644
index 00000000000..d9da5075c2d
--- /dev/null
+++ b/src/third_party/s2/s2cellid.cc
@@ -0,0 +1,536 @@
+// Copyright 2005 Google Inc. All Rights Reserved.
+
+#include "s2cellid.h"
+
+#ifndef _WIN32
+#include <pthread.h>
+#endif
+
+#include <algorithm>
+using std::min;
+using std::max;
+using std::swap;
+using std::reverse;
+
+#include <iomanip>
+using std::setprecision;
+
+#include <vector>
+using std::vector;
+
+
+#include "base/integral_types.h"
+#include "base/logging.h"
+#include "strings/strutil.h"
+#include "s2.h"
+#include "s2latlng.h"
+#include "util/math/mathutil.h"
+#include "util/math/vector2-inl.h"
+
+// The following lookup tables are used to convert efficiently between an
+// (i,j) cell index and the corresponding position along the Hilbert curve.
+// "lookup_pos" maps 4 bits of "i", 4 bits of "j", and 2 bits representing the
+// orientation of the current cell into 8 bits representing the order in which
+// that subcell is visited by the Hilbert curve, plus 2 bits indicating the
+// new orientation of the Hilbert curve within that subcell. (Cell
+// orientations are represented as combination of kSwapMask and kInvertMask.)
+//
+// "lookup_ij" is an inverted table used for mapping in the opposite
+// direction.
+//
+// We also experimented with looking up 16 bits at a time (14 bits of position
+// plus 2 of orientation) but found that smaller lookup tables gave better
+// performance. (2KB fits easily in the primary cache.)
+
+
+// Values for these constants are *declared* in the *.h file. Even though
+// the declaration specifies a value for the constant, that declaration
+// is not a *definition* of storage for the value. Because the values are
+// supplied in the declaration, we don't need the values here. Failing to
+// define storage causes link errors for any code that tries to take the
+// address of one of these values.
+int const S2CellId::kFaceBits = 3;
+int const S2CellId::kNumFaces = 6;
+int const S2CellId::kMaxLevel = S2::kMaxCellLevel;
+int const S2CellId::kPosBits = 2 * kMaxLevel + 1;
+int const S2CellId::kMaxSize = 1 << kMaxLevel;
+uint64 const S2CellId::kWrapOffset = uint64(kNumFaces) << kPosBits;
+
+static int const kLookupBits = 4;
+static int const kSwapMask = 0x01;
+static int const kInvertMask = 0x02;
+
+static uint16 lookup_pos[1 << (2 * kLookupBits + 2)];
+static uint16 lookup_ij[1 << (2 * kLookupBits + 2)];
+
+static void InitLookupCell(int level, int i, int j, int orig_orientation,
+ int pos, int orientation) {
+ if (level == kLookupBits) {
+ int ij = (i << kLookupBits) + j;
+ lookup_pos[(ij << 2) + orig_orientation] = (pos << 2) + orientation;
+ lookup_ij[(pos << 2) + orig_orientation] = (ij << 2) + orientation;
+ } else {
+ level++;
+ i <<= 1;
+ j <<= 1;
+ pos <<= 2;
+ int const* r = S2::kPosToIJ[orientation];
+ InitLookupCell(level, i + (r[0] >> 1), j + (r[0] & 1), orig_orientation,
+ pos, orientation ^ S2::kPosToOrientation[0]);
+ InitLookupCell(level, i + (r[1] >> 1), j + (r[1] & 1), orig_orientation,
+ pos + 1, orientation ^ S2::kPosToOrientation[1]);
+ InitLookupCell(level, i + (r[2] >> 1), j + (r[2] & 1), orig_orientation,
+ pos + 2, orientation ^ S2::kPosToOrientation[2]);
+ InitLookupCell(level, i + (r[3] >> 1), j + (r[3] & 1), orig_orientation,
+ pos + 3, orientation ^ S2::kPosToOrientation[3]);
+ }
+}
+
+static int Init() {
+ InitLookupCell(0, 0, 0, 0, 0, 0);
+ InitLookupCell(0, 0, 0, kSwapMask, 0, kSwapMask);
+ InitLookupCell(0, 0, 0, kInvertMask, 0, kInvertMask);
+ InitLookupCell(0, 0, 0, kSwapMask|kInvertMask, 0, kSwapMask|kInvertMask);
+ return 5;
+}
+
+#ifndef _WIN32
+static pthread_once_t init_once = PTHREAD_ONCE_INIT;
+static void voidInit() { (void)Init(); }
+inline static void MaybeInit() {
+ pthread_once(&init_once, voidInit);
+}
+#else
+static const int foo = Init();
+inline static void MaybeInit() {}
+#endif
+
+int S2CellId::level() const {
+ // Fast path for leaf cells.
+ if (is_leaf()) return kMaxLevel;
+
+ uint32 x = static_cast<uint32>(id_);
+ int level = -1;
+ if (x != 0) {
+ level += 16;
+ } else {
+ x = static_cast<uint32>(id_ >> 32);
+ }
+ // We only need to look at even-numbered bits to determine the
+ // level of a valid cell id.
+ x &= -x; // Get lowest bit.
+ if (x & 0x00005555) level += 8;
+ if (x & 0x00550055) level += 4;
+ if (x & 0x05050505) level += 2;
+ if (x & 0x11111111) level += 1;
+ DCHECK_GE(level, 0);
+ DCHECK_LE(level, kMaxLevel);
+ return level;
+}
+
+S2CellId S2CellId::advance(int64 steps) const {
+ if (steps == 0) return *this;
+
+ // We clamp the number of steps if necessary to ensure that we do not
+ // advance past the End() or before the Begin() of this level. Note that
+ // min_steps and max_steps always fit in a signed 64-bit integer.
+
+ int step_shift = 2 * (kMaxLevel - level()) + 1;
+ if (steps < 0) {
+ int64 min_steps = -static_cast<int64>(id_ >> step_shift);
+ if (steps < min_steps) steps = min_steps;
+ } else {
+ int64 max_steps = (kWrapOffset + lsb() - id_) >> step_shift;
+ if (steps > max_steps) steps = max_steps;
+ }
+ return S2CellId(id_ + (steps << step_shift));
+}
+
+S2CellId S2CellId::advance_wrap(int64 steps) const {
+ DCHECK(is_valid());
+ if (steps == 0) return *this;
+
+ int step_shift = 2 * (kMaxLevel - level()) + 1;
+ if (steps < 0) {
+ int64 min_steps = -static_cast<int64>(id_ >> step_shift);
+ if (steps < min_steps) {
+ int64 step_wrap = kWrapOffset >> step_shift;
+ steps %= step_wrap;
+ if (steps < min_steps) steps += step_wrap;
+ }
+ } else {
+ // Unlike advance(), we don't want to return End(level).
+ int64 max_steps = (kWrapOffset - id_) >> step_shift;
+ if (steps > max_steps) {
+ int64 step_wrap = kWrapOffset >> step_shift;
+ steps %= step_wrap;
+ if (steps > max_steps) steps -= step_wrap;
+ }
+ }
+ return S2CellId(id_ + (steps << step_shift));
+}
+
+S2CellId S2CellId::FromFacePosLevel(int face, uint64 pos, int level) {
+ S2CellId cell((static_cast<uint64>(face) << kPosBits) + (pos | 1));
+ return cell.parent(level);
+}
+
+string S2CellId::ToToken() const {
+ // Simple implementation: convert the id to hex and strip trailing zeros.
+ // Using hex has the advantage that the tokens are case-insensitive, all
+ // characters are alphanumeric, no characters require any special escaping
+ // in Mustang queries, and it's easy to compare cell tokens against the
+ // feature ids of the corresponding features.
+ //
+ // Using base 64 would produce slightly shorter tokens, but for typical cell
+ // sizes used during indexing (up to level 15 or so) the average savings
+ // would be less than 2 bytes per cell which doesn't seem worth it.
+
+ char digits[17];
+ FastHex64ToBuffer(id_, digits);
+ for (int len = 16; len > 0; --len) {
+ if (digits[len-1] != '0') {
+ return string(digits, len);
+ }
+ }
+ return "X"; // Invalid hex string.
+}
+
+S2CellId S2CellId::FromToken(string const& token) {
+ if (token.size() > 16) return S2CellId::None();
+ char digits[17] = "0000000000000000";
+ memcpy(digits, token.data(), token.size());
+ return S2CellId(ParseLeadingHex64Value(digits, 0));
+}
+
+inline int S2CellId::STtoIJ(double s) {
+ // Converting from floating-point to integers via static_cast is very slow
+ // on Intel processors because it requires changing the rounding mode.
+ // Rounding to the nearest integer using FastIntRound() is much faster.
+
+ return max(0, min(kMaxSize - 1, MathUtil::FastIntRound(kMaxSize * s - 0.5)));
+}
+
+
+S2CellId S2CellId::FromFaceIJ(int face, int i, int j) {
+ // Initialization if not done yet
+ MaybeInit();
+
+ // Optimization notes:
+ // - Non-overlapping bit fields can be combined with either "+" or "|".
+ // Generally "+" seems to produce better code, but not always.
+
+ // gcc doesn't have very good code generation for 64-bit operations.
+ // We optimize this by computing the result as two 32-bit integers
+ // and combining them at the end. Declaring the result as an array
+ // rather than local variables helps the compiler to do a better job
+ // of register allocation as well. Note that the two 32-bits halves
+ // get shifted one bit to the left when they are combined.
+ uint32 n[2] = { 0, face << (kPosBits - 33) };
+
+ // Alternating faces have opposite Hilbert curve orientations; this
+ // is necessary in order for all faces to have a right-handed
+ // coordinate system.
+ int bits = (face & kSwapMask);
+
+ // Each iteration maps 4 bits of "i" and "j" into 8 bits of the Hilbert
+ // curve position. The lookup table transforms a 10-bit key of the form
+ // "iiiijjjjoo" to a 10-bit value of the form "ppppppppoo", where the
+ // letters [ijpo] denote bits of "i", "j", Hilbert curve position, and
+ // Hilbert curve orientation respectively.
+#define GET_BITS(k) do { \
+ int const mask = (1 << kLookupBits) - 1; \
+ bits += ((i >> (k * kLookupBits)) & mask) << (kLookupBits + 2); \
+ bits += ((j >> (k * kLookupBits)) & mask) << 2; \
+ bits = lookup_pos[bits]; \
+ n[k >> 2] |= (bits >> 2) << ((k & 3) * 2 * kLookupBits); \
+ bits &= (kSwapMask | kInvertMask); \
+ } while (0)
+
+ GET_BITS(7);
+ GET_BITS(6);
+ GET_BITS(5);
+ GET_BITS(4);
+ GET_BITS(3);
+ GET_BITS(2);
+ GET_BITS(1);
+ GET_BITS(0);
+#undef GET_BITS
+
+ return S2CellId(((static_cast<uint64>(n[1]) << 32) + n[0]) * 2 + 1);
+}
+
+S2CellId S2CellId::FromPoint(S2Point const& p) {
+ double u, v;
+ int face = S2::XYZtoFaceUV(p, &u, &v);
+ int i = STtoIJ(S2::UVtoST(u));
+ int j = STtoIJ(S2::UVtoST(v));
+ return FromFaceIJ(face, i, j);
+}
+
+S2CellId S2CellId::FromLatLng(S2LatLng const& ll) {
+ return FromPoint(ll.ToPoint());
+}
+
+int S2CellId::ToFaceIJOrientation(int* pi, int* pj, int* orientation) const {
+ // Initialization if not done yet
+ MaybeInit();
+
+ int i = 0, j = 0;
+ int face = this->face();
+ int bits = (face & kSwapMask);
+
+ // Each iteration maps 8 bits of the Hilbert curve position into
+ // 4 bits of "i" and "j". The lookup table transforms a key of the
+ // form "ppppppppoo" to a value of the form "iiiijjjjoo", where the
+ // letters [ijpo] represents bits of "i", "j", the Hilbert curve
+ // position, and the Hilbert curve orientation respectively.
+ //
+ // On the first iteration we need to be careful to clear out the bits
+ // representing the cube face.
+#define GET_BITS(k) do { \
+ int const nbits = (k == 7) ? (kMaxLevel - 7 * kLookupBits) : kLookupBits; \
+ bits += (static_cast<int>(id_ >> (k * 2 * kLookupBits + 1)) \
+ & ((1 << (2 * nbits)) - 1)) << 2; \
+ bits = lookup_ij[bits]; \
+ i += (bits >> (kLookupBits + 2)) << (k * kLookupBits); \
+ j += ((bits >> 2) & ((1 << kLookupBits) - 1)) << (k * kLookupBits); \
+ bits &= (kSwapMask | kInvertMask); \
+ } while (0)
+
+ GET_BITS(7);
+ GET_BITS(6);
+ GET_BITS(5);
+ GET_BITS(4);
+ GET_BITS(3);
+ GET_BITS(2);
+ GET_BITS(1);
+ GET_BITS(0);
+#undef GET_BITS
+
+ *pi = i;
+ *pj = j;
+
+ if (orientation != NULL) {
+ // The position of a non-leaf cell at level "n" consists of a prefix of
+ // 2*n bits that identifies the cell, followed by a suffix of
+ // 2*(kMaxLevel-n)+1 bits of the form 10*. If n==kMaxLevel, the suffix is
+ // just "1" and has no effect. Otherwise, it consists of "10", followed
+ // by (kMaxLevel-n-1) repetitions of "00", followed by "0". The "10" has
+ // no effect, while each occurrence of "00" has the effect of reversing
+ // the kSwapMask bit.
+ DCHECK_EQ(0, S2::kPosToOrientation[2]);
+ DCHECK_EQ(S2::kSwapMask, S2::kPosToOrientation[0]);
+ if (lsb() & GG_ULONGLONG(0x1111111111111110)) {
+ bits ^= S2::kSwapMask;
+ }
+ *orientation = bits;
+ }
+ return face;
+}
+
+inline int S2CellId::GetCenterSiTi(int* psi, int* pti) const {
+ // First we compute the discrete (i,j) coordinates of a leaf cell contained
+ // within the given cell. Given that cells are represented by the Hilbert
+ // curve position corresponding at their center, it turns out that the cell
+ // returned by ToFaceIJOrientation is always one of two leaf cells closest
+ // to the center of the cell (unless the given cell is a leaf cell itself,
+ // in which case there is only one possibility).
+ //
+ // Given a cell of size s >= 2 (i.e. not a leaf cell), and letting (imin,
+ // jmin) be the coordinates of its lower left-hand corner, the leaf cell
+ // returned by ToFaceIJOrientation() is either (imin + s/2, jmin + s/2)
+ // (imin + s/2 - 1, jmin + s/2 - 1). The first case is the one we want.
+ // We can distinguish these two cases by looking at the low bit of "i" or
+ // "j". In the second case the low bit is one, unless s == 2 (i.e. the
+ // level just above leaf cells) in which case the low bit is zero.
+ //
+ // In the code below, the expression ((i ^ (int(id_) >> 2)) & 1) is true
+ // if we are in the second case described above.
+ int i, j;
+ int face = ToFaceIJOrientation(&i, &j, NULL);
+ int delta = is_leaf() ? 1 : ((i ^ (static_cast<int>(id_) >> 2)) & 1) ? 2 : 0;
+
+ // Note that (2 * {i,j} + delta) will never overflow a 32-bit integer.
+ *psi = 2 * i + delta;
+ *pti = 2 * j + delta;
+ return face;
+}
+
+S2Point S2CellId::ToPointRaw() const {
+ // This code would be slightly shorter if we called GetCenterUV(),
+ // but this method is heavily used and it's 25% faster to include
+ // the method inline.
+ int si, ti;
+ int face = GetCenterSiTi(&si, &ti);
+ return S2::FaceUVtoXYZ(face,
+ S2::STtoUV((0.5 / kMaxSize) * si),
+ S2::STtoUV((0.5 / kMaxSize) * ti));
+}
+
+S2LatLng S2CellId::ToLatLng() const {
+ return S2LatLng(ToPointRaw());
+}
+
+Vector2_d S2CellId::GetCenterST() const {
+ int si, ti;
+ GetCenterSiTi(&si, &ti);
+ return Vector2_d((0.5 / kMaxSize) * si, (0.5 / kMaxSize) * ti);
+}
+
+Vector2_d S2CellId::GetCenterUV() const {
+ int si, ti;
+ GetCenterSiTi(&si, &ti);
+ return Vector2_d(S2::STtoUV((0.5 / kMaxSize) * si),
+ S2::STtoUV((0.5 / kMaxSize) * ti));
+}
+
+S2CellId S2CellId::FromFaceIJWrap(int face, int i, int j) {
+ // Convert i and j to the coordinates of a leaf cell just beyond the
+ // boundary of this face. This prevents 32-bit overflow in the case
+ // of finding the neighbors of a face cell.
+ i = max(-1, min(kMaxSize, i));
+ j = max(-1, min(kMaxSize, j));
+
+ // Find the (u,v) coordinates corresponding to the center of cell (i,j).
+ // For our purposes it's sufficient to always use the linear projection
+ // from (s,t) to (u,v): u=2*s-1 and v=2*t-1.
+ static const double kScale = 1.0 / kMaxSize;
+ double u = kScale * ((i << 1) + 1 - kMaxSize);
+ double v = kScale * ((j << 1) + 1 - kMaxSize);
+
+ // Find the leaf cell coordinates on the adjacent face, and convert
+ // them to a cell id at the appropriate level. We convert from (u,v)
+ // back to (s,t) using s=0.5*(u+1), t=0.5*(v+1).
+ face = S2::XYZtoFaceUV(S2::FaceUVtoXYZ(face, u, v), &u, &v);
+ return FromFaceIJ(face, STtoIJ(0.5*(u+1)), STtoIJ(0.5*(v+1)));
+}
+
+inline S2CellId S2CellId::FromFaceIJSame(int face, int i, int j,
+ bool same_face) {
+ if (same_face)
+ return S2CellId::FromFaceIJ(face, i, j);
+ else
+ return S2CellId::FromFaceIJWrap(face, i, j);
+}
+
+void S2CellId::GetEdgeNeighbors(S2CellId neighbors[4]) const {
+ int i, j;
+ int level = this->level();
+ int size = GetSizeIJ(level);
+ int face = ToFaceIJOrientation(&i, &j, NULL);
+
+ // Edges 0, 1, 2, 3 are in the S, E, N, W directions.
+ neighbors[0] = FromFaceIJSame(face, i, j - size, j - size >= 0)
+ .parent(level);
+ neighbors[1] = FromFaceIJSame(face, i + size, j, i + size < kMaxSize)
+ .parent(level);
+ neighbors[2] = FromFaceIJSame(face, i, j + size, j + size < kMaxSize)
+ .parent(level);
+ neighbors[3] = FromFaceIJSame(face, i - size, j, i - size >= 0)
+ .parent(level);
+}
+
+void S2CellId::AppendVertexNeighbors(int level,
+ vector<S2CellId>* output) const {
+ // "level" must be strictly less than this cell's level so that we can
+ // determine which vertex this cell is closest to.
+ DCHECK_LT(level, this->level());
+ int i, j;
+ int face = ToFaceIJOrientation(&i, &j, NULL);
+
+ // Determine the i- and j-offsets to the closest neighboring cell in each
+ // direction. This involves looking at the next bit of "i" and "j" to
+ // determine which quadrant of this->parent(level) this cell lies in.
+ int halfsize = GetSizeIJ(level + 1);
+ int size = halfsize << 1;
+ bool isame, jsame;
+ int ioffset, joffset;
+ if (i & halfsize) {
+ ioffset = size;
+ isame = (i + size) < kMaxSize;
+ } else {
+ ioffset = -size;
+ isame = (i - size) >= 0;
+ }
+ if (j & halfsize) {
+ joffset = size;
+ jsame = (j + size) < kMaxSize;
+ } else {
+ joffset = -size;
+ jsame = (j - size) >= 0;
+ }
+
+ output->push_back(parent(level));
+ output->push_back(FromFaceIJSame(face, i + ioffset, j, isame).parent(level));
+ output->push_back(FromFaceIJSame(face, i, j + joffset, jsame).parent(level));
+ // If i- and j- edge neighbors are *both* on a different face, then this
+ // vertex only has three neighbors (it is one of the 8 cube vertices).
+ if (isame || jsame) {
+ output->push_back(FromFaceIJSame(face, i + ioffset, j + joffset,
+ isame && jsame).parent(level));
+ }
+}
+
+void S2CellId::AppendAllNeighbors(int nbr_level,
+ vector<S2CellId>* output) const {
+ int i, j;
+ int face = ToFaceIJOrientation(&i, &j, NULL);
+
+ // Find the coordinates of the lower left-hand leaf cell. We need to
+ // normalize (i,j) to a known position within the cell because nbr_level
+ // may be larger than this cell's level.
+ int size = GetSizeIJ();
+ i &= -size;
+ j &= -size;
+
+ int nbr_size = GetSizeIJ(nbr_level);
+ DCHECK_LE(nbr_size, size);
+
+ // We compute the N-S, E-W, and diagonal neighbors in one pass.
+ // The loop test is at the end of the loop to avoid 32-bit overflow.
+ for (int k = -nbr_size; ; k += nbr_size) {
+ bool same_face;
+ if (k < 0) {
+ same_face = (j + k >= 0);
+ } else if (k >= size) {
+ same_face = (j + k < kMaxSize);
+ } else {
+ same_face = true;
+ // North and South neighbors.
+ output->push_back(FromFaceIJSame(face, i + k, j - nbr_size,
+ j - size >= 0).parent(nbr_level));
+ output->push_back(FromFaceIJSame(face, i + k, j + size,
+ j + size < kMaxSize).parent(nbr_level));
+ }
+ // East, West, and Diagonal neighbors.
+ output->push_back(FromFaceIJSame(face, i - nbr_size, j + k,
+ same_face && i - size >= 0)
+ .parent(nbr_level));
+ output->push_back(FromFaceIJSame(face, i + size, j + k,
+ same_face && i + size < kMaxSize)
+ .parent(nbr_level));
+ if (k >= size) break;
+ }
+}
+
+string S2CellId::ToString() const {
+ if (!is_valid()) {
+ return StringPrintf("Invalid: %016llx", id());
+ }
+ string out = IntToString(face(), "%d/");
+ for (int current_level = 1; current_level <= level(); ++current_level) {
+ out += IntToString(child_position(current_level), "%d");
+ }
+ return out;
+}
+
+ostream& operator<<(ostream& os, S2CellId const& id) {
+ return os << id.ToString();
+}
+
+#ifdef OS_WINDOWS
+template<> size_t stdext::hash_value<S2CellId>(const S2CellId &id) {
+ return static_cast<size_t>(id.id() >> 32) + static_cast<size_t>(id.id());
+}
+#endif
diff --git a/src/third_party/s2/s2cellid.h b/src/third_party/s2/s2cellid.h
new file mode 100644
index 00000000000..aa84fc7db60
--- /dev/null
+++ b/src/third_party/s2/s2cellid.h
@@ -0,0 +1,518 @@
+// Copyright 2005 Google Inc. All Rights Reserved.
+
+#ifndef UTIL_GEOMETRY_S2CELLID_H_
+#define UTIL_GEOMETRY_S2CELLID_H_
+
+#include <iostream>
+using std::ostream;
+using std::cout;
+using std::endl;
+
+#include <string>
+using std::string;
+
+#include <vector>
+using std::vector;
+
+#include "base/basictypes.h"
+#include "base/logging.h"
+#include "base/port.h" // for HASH_NAMESPACE_DECLARATION_START
+#include "s2.h"
+#include "util/math/vector2.h"
+
+class S2LatLng;
+
+// An S2CellId is a 64-bit unsigned integer that uniquely identifies a
+// cell in the S2 cell decomposition. It has the following format:
+//
+// id = [face][face_pos]
+//
+// face: a 3-bit number (range 0..5) encoding the cube face.
+//
+// face_pos: a 61-bit number encoding the position of the center of this
+// cell along the Hilbert curve over this face (see the Wiki
+// pages for details).
+//
+// Sequentially increasing cell ids follow a continuous space-filling curve
+// over the entire sphere. They have the following properties:
+//
+// - The id of a cell at level k consists of a 3-bit face number followed
+// by k bit pairs that recursively select one of the four children of
+// each cell. The next bit is always 1, and all other bits are 0.
+// Therefore, the level of a cell is determined by the position of its
+// lowest-numbered bit that is turned on (for a cell at level k, this
+// position is 2 * (kMaxLevel - k).)
+//
+// - The id of a parent cell is at the midpoint of the range of ids spanned
+// by its children (or by its descendants at any level).
+//
+// Leaf cells are often used to represent points on the unit sphere, and
+// this class provides methods for converting directly between these two
+// representations. For cells that represent 2D regions rather than
+// discrete point, it is better to use the S2Cell class.
+//
+// This class is intended to be copied by value as desired. It uses
+// the default copy constructor and assignment operator.
+class S2CellId {
+ public:
+ // Although only 60 bits are needed to represent the index of a leaf
+ // cell, we need an extra bit in order to represent the position of
+ // the center of the leaf cell along the Hilbert curve.
+ static int const kFaceBits; // = 3;
+ static int const kNumFaces; // = 6;
+ static int const kMaxLevel; // = S2::kMaxCellLevel; // Valid levels: 0..kMaxLevel
+ static int const kPosBits; // = 2 * kMaxLevel + 1;
+ static int const kMaxSize; // = 1 << kMaxLevel;
+
+ inline explicit S2CellId(uint64 id) : id_(id) {}
+
+ // The default constructor returns an invalid cell id.
+ inline S2CellId() : id_(0) {}
+ inline static S2CellId None() { return S2CellId(); }
+
+ // Returns an invalid cell id guaranteed to be larger than any
+ // valid cell id. Useful for creating indexes.
+ inline static S2CellId Sentinel() { return S2CellId(~uint64(0)); }
+
+ // Return a cell given its face (range 0..5), 61-bit Hilbert curve position
+ // within that face, and level (range 0..kMaxLevel). The given position
+ // will be modified to correspond to the Hilbert curve position at the
+ // center of the returned cell. This is a static function rather than a
+ // constructor in order to give names to the arguments.
+ static S2CellId FromFacePosLevel(int face, uint64 pos, int level);
+
+ // Return the leaf cell containing the given point (a direction
+ // vector, not necessarily unit length).
+ static S2CellId FromPoint(S2Point const& p);
+
+ // Return the leaf cell containing the given normalized S2LatLng.
+ static S2CellId FromLatLng(S2LatLng const& ll);
+
+ // Return the direction vector corresponding to the center of the given
+ // cell. The vector returned by ToPointRaw is not necessarily unit length.
+ S2Point ToPoint() const { return ToPointRaw().Normalize(); }
+ S2Point ToPointRaw() const;
+
+ // Return the center of the cell in (s,t) coordinates (see s2.h).
+ Vector2_d GetCenterST() const;
+
+ // Return the center of the cell in (u,v) coordinates (see s2.h). Note that
+ // the center of the cell is defined as the point at which it is recursively
+ // subdivided into four children; in general, it is not at the midpoint of
+ // the (u,v) rectangle covered by the cell.
+ Vector2_d GetCenterUV() const;
+
+ // Return the S2LatLng corresponding to the center of the given cell.
+ S2LatLng ToLatLng() const;
+
+ // The 64-bit unique identifier for this cell.
+ inline uint64 id() const { return id_; }
+
+ // Return true if id() represents a valid cell.
+ inline bool is_valid() const;
+
+ // Which cube face this cell belongs to, in the range 0..5.
+ inline int face() const;
+
+ // The position of the cell center along the Hilbert curve over this face,
+ // in the range 0..(2**kPosBits-1).
+ inline uint64 pos() const;
+
+ // Return the subdivision level of the cell (range 0..kMaxLevel).
+ int level() const;
+
+ // Return the edge length of this cell in (i,j)-space.
+ inline int GetSizeIJ() const;
+
+ // Return the edge length of this cell in (s,t)-space.
+ inline double GetSizeST() const;
+
+ // Like the above, but return the size of cells at the given level.
+ inline static int GetSizeIJ(int level);
+ inline static double GetSizeST(int level);
+
+ // Return true if this is a leaf cell (more efficient than checking
+ // whether level() == kMaxLevel).
+ inline bool is_leaf() const;
+
+ // Return true if this is a top-level face cell (more efficient than
+ // checking whether level() == 0).
+ inline bool is_face() const;
+
+ // Return the child position (0..3) of this cell's ancestor at the given
+ // level, relative to its parent. The argument should be in the range
+ // 1..kMaxLevel. For example, child_position(1) returns the position of
+ // this cell's level-1 ancestor within its top-level face cell.
+ inline int child_position(int level) const;
+
+ // Methods that return the range of cell ids that are contained
+ // within this cell (including itself). The range is *inclusive*
+ // (i.e. test using >= and <=) and the return values of both
+ // methods are valid leaf cell ids.
+ //
+ // These methods should not be used for iteration. If you want to
+ // iterate through all the leaf cells, call child_begin(kMaxLevel) and
+ // child_end(kMaxLevel) instead.
+ //
+ // It would in fact be error-prone to define a range_end() method,
+ // because (range_max().id() + 1) is not always a valid cell id, and the
+ // iterator would need to be tested using "<" rather that the usual "!=".
+ inline S2CellId range_min() const;
+ inline S2CellId range_max() const;
+
+ // Return true if the given cell is contained within this one.
+ inline bool contains(S2CellId const& other) const;
+
+ // Return true if the given cell intersects this one.
+ inline bool intersects(S2CellId const& other) const;
+
+ // Return the cell at the previous level or at the given level (which must
+ // be less than or equal to the current level).
+ inline S2CellId parent() const;
+ inline S2CellId parent(int level) const;
+
+ // Return the immediate child of this cell at the given traversal order
+ // position (in the range 0 to 3). This cell must not be a leaf cell.
+ inline S2CellId child(int position) const;
+
+ // Iterator-style methods for traversing the immediate children of a cell or
+ // all of the children at a given level (greater than or equal to the current
+ // level). Note that the end value is exclusive, just like standard STL
+ // iterators, and may not even be a valid cell id. You should iterate using
+ // code like this:
+ //
+ // for(S2CellId c = id.child_begin(); c != id.child_end(); c = c.next())
+ // ...
+ //
+ // The convention for advancing the iterator is "c = c.next()" rather
+ // than "++c" to avoid possible confusion with incrementing the
+ // underlying 64-bit cell id.
+ inline S2CellId child_begin() const;
+ inline S2CellId child_begin(int level) const;
+ inline S2CellId child_end() const;
+ inline S2CellId child_end(int level) const;
+
+ // Return the next/previous cell at the same level along the Hilbert curve.
+ // Works correctly when advancing from one face to the next, but
+ // does *not* wrap around from the last face to the first or vice versa.
+ inline S2CellId next() const;
+ inline S2CellId prev() const;
+
+ // This method advances or retreats the indicated number of steps along the
+ // Hilbert curve at the current level, and returns the new position. The
+ // position is never advanced past End() or before Begin().
+ S2CellId advance(int64 steps) const;
+
+ // Like next() and prev(), but these methods wrap around from the last face
+ // to the first and vice versa. They should *not* be used for iteration in
+ // conjunction with child_begin(), child_end(), Begin(), or End(). The
+ // input must be a valid cell id.
+ inline S2CellId next_wrap() const;
+ inline S2CellId prev_wrap() const;
+
+ // This method advances or retreats the indicated number of steps along the
+ // Hilbert curve at the current level, and returns the new position. The
+ // position wraps between the first and last faces as necessary. The input
+ // must be a valid cell id.
+ S2CellId advance_wrap(int64 steps) const;
+
+ // Iterator-style methods for traversing all the cells along the Hilbert
+ // curve at a given level (across all 6 faces of the cube). Note that the
+ // end value is exclusive (just like standard STL iterators), and is not a
+ // valid cell id.
+ inline static S2CellId Begin(int level);
+ inline static S2CellId End(int level);
+
+ // Methods to encode and decode cell ids to compact text strings suitable
+ // for display or indexing. Cells at lower levels (i.e. larger cells) are
+ // encoded into fewer characters. The maximum token length is 16.
+ //
+ // ToToken() returns a string by value for convenience; the compiler
+ // does this without intermediate copying in most cases.
+ //
+ // These methods guarantee that FromToken(ToToken(x)) == x even when
+ // "x" is an invalid cell id. All tokens are alphanumeric strings.
+ // FromToken() returns S2CellId::None() for malformed inputs.
+ string ToToken() const;
+ static S2CellId FromToken(string const& token);
+
+ // Creates a debug human readable string. Used for << and available for direct
+ // usage as well.
+ string ToString() const;
+ string toString() const { return ToString(); }
+
+ // Return the four cells that are adjacent across the cell's four edges.
+ // Neighbors are returned in the order defined by S2Cell::GetEdge. All
+ // neighbors are guaranteed to be distinct.
+ void GetEdgeNeighbors(S2CellId neighbors[4]) const;
+
+ // Return the neighbors of closest vertex to this cell at the given level,
+ // by appending them to "output". Normally there are four neighbors, but
+ // the closest vertex may only have three neighbors if it is one of the 8
+ // cube vertices.
+ //
+ // Requires: level < this->level(), so that we can determine which vertex is
+ // closest (in particular, level == kMaxLevel is not allowed).
+ void AppendVertexNeighbors(int level, vector<S2CellId>* output) const;
+
+ // Append all neighbors of this cell at the given level to "output". Two
+ // cells X and Y are neighbors if their boundaries intersect but their
+ // interiors do not. In particular, two cells that intersect at a single
+ // point are neighbors.
+ //
+ // Requires: nbr_level >= this->level(). Note that for cells adjacent to a
+ // face vertex, the same neighbor may be appended more than once.
+ void AppendAllNeighbors(int nbr_level, vector<S2CellId>* output) const;
+
+ /////////////////////////////////////////////////////////////////////
+ // Low-level methods.
+
+ // Return a leaf cell given its cube face (range 0..5) and
+ // i- and j-coordinates (see s2.h).
+ static S2CellId FromFaceIJ(int face, int i, int j);
+
+ // Return the (face, i, j) coordinates for the leaf cell corresponding to
+ // this cell id. Since cells are represented by the Hilbert curve position
+ // at the center of the cell, the returned (i,j) for non-leaf cells will be
+ // a leaf cell adjacent to the cell center. If "orientation" is non-NULL,
+ // also return the Hilbert curve orientation for the current cell.
+ int ToFaceIJOrientation(int* pi, int* pj, int* orientation) const;
+
+ // Return the lowest-numbered bit that is on for this cell id, which is
+ // equal to (uint64(1) << (2 * (kMaxLevel - level))). So for example,
+ // a.lsb() <= b.lsb() if and only if a.level() >= b.level(), but the
+ // first test is more efficient.
+ uint64 lsb() const { return id_ & -id_; }
+
+ // Return the lowest-numbered bit that is on for cells at the given level.
+ inline static uint64 lsb_for_level(int level) {
+ return uint64(1) << (2 * (kMaxLevel - level));
+ }
+
+ private:
+ // This is the offset required to wrap around from the beginning of the
+ // Hilbert curve to the end or vice versa; see next_wrap() and prev_wrap().
+ static uint64 const kWrapOffset; // = uint64(kNumFaces) << kPosBits;
+
+ // Return the i- or j-index of the leaf cell containing the given
+ // s- or t-value. Values are clamped appropriately.
+ inline static int STtoIJ(double s);
+
+ // Return the (face, si, ti) coordinates of the center of the cell. Note
+ // that although (si,ti) coordinates span the range [0,2**31] in general,
+ // the cell center coordinates are always in the range [1,2**31-1] and
+ // therefore can be represented using a signed 32-bit integer.
+ inline int GetCenterSiTi(int* psi, int* pti) const;
+
+ // Given (i, j) coordinates that may be out of bounds, normalize them by
+ // returning the corresponding neighbor cell on an adjacent face.
+ static S2CellId FromFaceIJWrap(int face, int i, int j);
+
+ // Inline helper function that calls FromFaceIJ if "same_face" is true,
+ // or FromFaceIJWrap if "same_face" is false.
+ inline static S2CellId FromFaceIJSame(int face, int i, int j, bool same_face);
+
+ uint64 id_;
+} PACKED; // Necessary so that structures containing S2CellId's can be PACKED.
+DECLARE_POD(S2CellId);
+
+inline bool operator==(S2CellId const& x, S2CellId const& y) {
+ return x.id() == y.id();
+}
+
+inline bool operator!=(S2CellId const& x, S2CellId const& y) {
+ return x.id() != y.id();
+}
+
+inline bool operator<(S2CellId const& x, S2CellId const& y) {
+ return x.id() < y.id();
+}
+
+inline bool operator>(S2CellId const& x, S2CellId const& y) {
+ return x.id() > y.id();
+}
+
+inline bool operator<=(S2CellId const& x, S2CellId const& y) {
+ return x.id() <= y.id();
+}
+
+inline bool operator>=(S2CellId const& x, S2CellId const& y) {
+ return x.id() >= y.id();
+}
+
+inline bool S2CellId::is_valid() const {
+ return (face() < kNumFaces && (lsb() & GG_ULONGLONG(0x1555555555555555)));
+}
+
+inline int S2CellId::face() const {
+ return id_ >> kPosBits;
+}
+
+inline uint64 S2CellId::pos() const {
+ return id_ & (~uint64(0) >> kFaceBits);
+}
+
+inline int S2CellId::GetSizeIJ() const {
+ return GetSizeIJ(level());
+}
+
+inline double S2CellId::GetSizeST() const {
+ return GetSizeST(level());
+}
+
+inline int S2CellId::GetSizeIJ(int level) {
+ return 1 << (kMaxLevel - level);
+}
+
+inline double S2CellId::GetSizeST(int level) {
+ // Floating-point multiplication is much faster than division.
+ return GetSizeIJ(level) * (1.0 / kMaxSize);
+}
+
+inline bool S2CellId::is_leaf() const {
+ return int(id_) & 1;
+}
+
+inline bool S2CellId::is_face() const {
+ return (id_ & (lsb_for_level(0) - 1)) == 0;
+}
+
+inline int S2CellId::child_position(int level) const {
+ DCHECK(is_valid());
+ return static_cast<int>(id_ >> (2 * (kMaxLevel - level) + 1)) & 3;
+}
+
+inline S2CellId S2CellId::range_min() const {
+ return S2CellId(id_ - (lsb() - 1));
+}
+
+inline S2CellId S2CellId::range_max() const {
+ return S2CellId(id_ + (lsb() - 1));
+}
+
+inline bool S2CellId::contains(S2CellId const& other) const {
+ DCHECK(is_valid());
+ DCHECK(other.is_valid());
+ return other >= range_min() && other <= range_max();
+}
+
+inline bool S2CellId::intersects(S2CellId const& other) const {
+ DCHECK(is_valid());
+ DCHECK(other.is_valid());
+ return other.range_min() <= range_max() && other.range_max() >= range_min();
+}
+
+inline S2CellId S2CellId::parent(int level) const {
+ DCHECK(is_valid());
+ DCHECK_GE(level, 0);
+ DCHECK_LE(level, this->level());
+ uint64 new_lsb = lsb_for_level(level);
+ return S2CellId((id_ & -new_lsb) | new_lsb);
+}
+
+inline S2CellId S2CellId::parent() const {
+ DCHECK(is_valid());
+ DCHECK(!is_face());
+ uint64 new_lsb = lsb() << 2;
+ return S2CellId((id_ & -new_lsb) | new_lsb);
+}
+
+inline S2CellId S2CellId::child(int position) const {
+ DCHECK(is_valid());
+ DCHECK(!is_leaf());
+ // To change the level, we need to move the least-significant bit two
+ // positions downward. We do this by subtracting (4 * new_lsb) and adding
+ // new_lsb. Then to advance to the given child cell, we add
+ // (2 * position * new_lsb).
+ uint64 new_lsb = lsb() >> 2;
+ return S2CellId(id_ + (2 * position + 1 - 4) * new_lsb);
+}
+
+inline S2CellId S2CellId::child_begin() const {
+ DCHECK(is_valid());
+ DCHECK(!is_leaf());
+ uint64 old_lsb = lsb();
+ return S2CellId(id_ - old_lsb + (old_lsb >> 2));
+}
+
+inline S2CellId S2CellId::child_begin(int level) const {
+ DCHECK(is_valid());
+ DCHECK_GE(level, this->level());
+ DCHECK_LE(level, kMaxLevel);
+ return S2CellId(id_ - lsb() + lsb_for_level(level));
+}
+
+inline S2CellId S2CellId::child_end() const {
+ DCHECK(is_valid());
+ DCHECK(!is_leaf());
+ uint64 old_lsb = lsb();
+ return S2CellId(id_ + old_lsb + (old_lsb >> 2));
+}
+
+inline S2CellId S2CellId::child_end(int level) const {
+ DCHECK(is_valid());
+ DCHECK_GE(level, this->level());
+ DCHECK_LE(level, kMaxLevel);
+ return S2CellId(id_ + lsb() + lsb_for_level(level));
+}
+
+inline S2CellId S2CellId::next() const {
+ return S2CellId(id_ + (lsb() << 1));
+}
+
+inline S2CellId S2CellId::prev() const {
+ return S2CellId(id_ - (lsb() << 1));
+}
+
+inline S2CellId S2CellId::next_wrap() const {
+ DCHECK(is_valid());
+ S2CellId n = next();
+ if (n.id_ < kWrapOffset) return n;
+ return S2CellId(n.id_ - kWrapOffset);
+}
+
+inline S2CellId S2CellId::prev_wrap() const {
+ DCHECK(is_valid());
+ S2CellId p = prev();
+ if (p.id_ < kWrapOffset) return p;
+ return S2CellId(p.id_ + kWrapOffset);
+}
+
+inline S2CellId S2CellId::Begin(int level) {
+ return FromFacePosLevel(0, 0, 0).child_begin(level);
+}
+
+inline S2CellId S2CellId::End(int level) {
+ return FromFacePosLevel(5, 0, 0).child_end(level);
+}
+
+ostream& operator<<(ostream& os, S2CellId const& id);
+
+#ifndef SWIG
+
+#if defined OS_MACOSX
+#include <ext/hash_set>
+#else
+#include <hash_set>
+#endif
+#ifndef OS_WINDOWS
+namespace __gnu_cxx {
+#endif
+
+template<> struct hash<S2CellId> {
+ size_t operator()(S2CellId const& id) const {
+ return static_cast<size_t>(id.id() >> 32) + static_cast<size_t>(id.id());
+ }
+};
+
+#ifdef OS_WINDOWS
+template<> size_t stdext::hash_value<S2CellId>(const S2CellId &id);
+#endif
+
+#ifndef OS_WINDOWS
+} // namespace __gnu_cxx
+#endif
+
+#endif // SWIG
+
+#endif // UTIL_GEOMETRY_S2CELLID_H_
diff --git a/src/third_party/s2/s2cellid_test.cc b/src/third_party/s2/s2cellid_test.cc
new file mode 100644
index 00000000000..cd0695f904d
--- /dev/null
+++ b/src/third_party/s2/s2cellid_test.cc
@@ -0,0 +1,477 @@
+// Copyright 2005 Google Inc. All Rights Reserved.
+
+#include "s2cellid.h"
+
+#include <algorithm>
+using std::min;
+using std::max;
+using std::swap;
+using std::reverse;
+
+#include <cstdio>
+#include <hash_map>
+using __gnu_cxx::hash_map;
+
+#include <sstream>
+#include <vector>
+using std::vector;
+
+
+#include "base/commandlineflags.h"
+#include "base/integral_types.h"
+#include "base/logging.h"
+#include "base/malloc_interface.h"
+#include "base/sysinfo.h"
+#include "testing/base/public/gunit.h"
+#include "s2.h"
+#include "s2latlng.h"
+#include "s2testing.h"
+#include "util/math/mathutil.h"
+
+#define int8 HTM_int8 // To avoid conflicts with our own 'int8'
+#include "third_party/htm/include/SpatialIndex.h"
+#include "third_party/htm/include/RangeConvex.h"
+#undef int8
+
+DEFINE_int32(iters, 20000000,
+ "Number of iterations for timing tests with optimized build");
+
+DEFINE_int32(htm_level, 29, "Maximum HTM level to use");
+DEFINE_int32(build_level, 5, "HTM build level to use");
+
+static S2CellId GetCellId(double lat_degrees, double lng_degrees) {
+ S2CellId id = S2CellId::FromLatLng(S2LatLng::FromDegrees(lat_degrees,
+ lng_degrees));
+ LOG(INFO) << hex << id.id();
+ return id;
+}
+
+TEST(S2CellId, DefaultConstructor) {
+ S2CellId id;
+ EXPECT_EQ(id.id(), 0);
+ EXPECT_FALSE(id.is_valid());
+}
+
+TEST(S2CellId, FaceDefinitions) {
+ EXPECT_EQ(GetCellId(0, 0).face(), 0);
+ EXPECT_EQ(GetCellId(0, 90).face(), 1);
+ EXPECT_EQ(GetCellId(90, 0).face(), 2);
+ EXPECT_EQ(GetCellId(0, 180).face(), 3);
+ EXPECT_EQ(GetCellId(0, -90).face(), 4);
+ EXPECT_EQ(GetCellId(-90, 0).face(), 5);
+}
+
+TEST(S2CellId, ParentChildRelationships) {
+ S2CellId id = S2CellId::FromFacePosLevel(3, 0x12345678,
+ S2CellId::kMaxLevel - 4);
+ EXPECT_TRUE(id.is_valid());
+ EXPECT_EQ(id.face(), 3);
+ EXPECT_EQ(id.pos(), 0x12345700);
+ EXPECT_EQ(id.level(), S2CellId::kMaxLevel - 4);
+ EXPECT_FALSE(id.is_leaf());
+
+ EXPECT_EQ(id.child_begin(id.level() + 2).pos(), 0x12345610);
+ EXPECT_EQ(id.child_begin().pos(), 0x12345640);
+ EXPECT_EQ(id.parent().pos(), 0x12345400);
+ EXPECT_EQ(id.parent(id.level() - 2).pos(), 0x12345000);
+
+ // Check ordering of children relative to parents.
+ EXPECT_LT(id.child_begin(), id);
+ EXPECT_GT(id.child_end(), id);
+ EXPECT_EQ(id.child_begin().next().next().next().next(), id.child_end());
+ EXPECT_EQ(id.child_begin(S2CellId::kMaxLevel), id.range_min());
+ EXPECT_EQ(id.child_end(S2CellId::kMaxLevel), id.range_max().next());
+
+ // Check that cells are represented by the position of their center
+ // along the Hilbert curve.
+ EXPECT_EQ(id.range_min().id() + id.range_max().id(), 2 * id.id());
+}
+
+TEST(S2CellId, Wrapping) {
+ // Check wrapping from beginning of Hilbert curve to end and vice versa.
+ EXPECT_EQ(S2CellId::Begin(0).prev_wrap(), S2CellId::End(0).prev());
+
+ EXPECT_EQ(S2CellId::Begin(S2CellId::kMaxLevel).prev_wrap(),
+ S2CellId::FromFacePosLevel(
+ 5, ~static_cast<uint64>(0) >> S2CellId::kFaceBits,
+ S2CellId::kMaxLevel));
+ EXPECT_EQ(S2CellId::Begin(S2CellId::kMaxLevel).advance_wrap(-1),
+ S2CellId::FromFacePosLevel(
+ 5, ~static_cast<uint64>(0) >> S2CellId::kFaceBits,
+ S2CellId::kMaxLevel));
+
+ EXPECT_EQ(S2CellId::End(4).prev().next_wrap(), S2CellId::Begin(4));
+ EXPECT_EQ(S2CellId::End(4).advance(-1).advance_wrap(1), S2CellId::Begin(4));
+
+ EXPECT_EQ(S2CellId::End(S2CellId::kMaxLevel).prev().next_wrap(),
+ S2CellId::FromFacePosLevel(0, 0, S2CellId::kMaxLevel));
+ EXPECT_EQ(S2CellId::End(S2CellId::kMaxLevel).advance(-1).advance_wrap(1),
+ S2CellId::FromFacePosLevel(0, 0, S2CellId::kMaxLevel));
+}
+
+TEST(S2CellId, Advance) {
+ S2CellId id = S2CellId::FromFacePosLevel(3, 0x12345678,
+ S2CellId::kMaxLevel - 4);
+ // Check basic properties of advance().
+ EXPECT_EQ(S2CellId::Begin(0).advance(7), S2CellId::End(0));
+ EXPECT_EQ(S2CellId::Begin(0).advance(12), S2CellId::End(0));
+ EXPECT_EQ(S2CellId::End(0).advance(-7), S2CellId::Begin(0));
+ EXPECT_EQ(S2CellId::End(0).advance(-12000000), S2CellId::Begin(0));
+ int num_level_5_cells = 6 << (2 * 5);
+ EXPECT_EQ(S2CellId::Begin(5).advance(500),
+ S2CellId::End(5).advance(500 - num_level_5_cells));
+ EXPECT_EQ(id.child_begin(S2CellId::kMaxLevel).advance(256),
+ id.next().child_begin(S2CellId::kMaxLevel));
+ EXPECT_EQ(S2CellId::FromFacePosLevel(1, 0, S2CellId::kMaxLevel)
+ .advance(static_cast<int64>(4) << (2 * S2CellId::kMaxLevel)),
+ S2CellId::FromFacePosLevel(5, 0, S2CellId::kMaxLevel));
+
+ // Check basic properties of advance_wrap().
+ EXPECT_EQ(S2CellId::Begin(0).advance_wrap(7),
+ S2CellId::FromFacePosLevel(1, 0, 0));
+ EXPECT_EQ(S2CellId::Begin(0).advance_wrap(12), S2CellId::Begin(0));
+ EXPECT_EQ(S2CellId::FromFacePosLevel(5, 0, 0).advance_wrap(-7),
+ S2CellId::FromFacePosLevel(4, 0, 0));
+ EXPECT_EQ(S2CellId::Begin(0).advance_wrap(-12000000), S2CellId::Begin(0));
+ EXPECT_EQ(S2CellId::Begin(5).advance_wrap(6644),
+ S2CellId::Begin(5).advance_wrap(-11788));
+ EXPECT_EQ(id.child_begin(S2CellId::kMaxLevel).advance_wrap(256),
+ id.next().child_begin(S2CellId::kMaxLevel));
+ EXPECT_EQ(S2CellId::FromFacePosLevel(5, 0, S2CellId::kMaxLevel)
+ .advance_wrap(static_cast<int64>(2) << (2 * S2CellId::kMaxLevel)),
+ S2CellId::FromFacePosLevel(1, 0, S2CellId::kMaxLevel));
+}
+
+TEST(S2CellId, Inverses) {
+ // Check the conversion of random leaf cells to S2LatLngs and back.
+ for (int i = 0; i < 200000; ++i) {
+ S2CellId id = S2Testing::GetRandomCellId(S2CellId::kMaxLevel);
+ EXPECT_TRUE(id.is_leaf());
+ EXPECT_EQ(id.level(), S2CellId::kMaxLevel);
+ S2LatLng center = id.ToLatLng();
+ EXPECT_EQ(S2CellId::FromLatLng(center).id(), id.id());
+ }
+}
+
+TEST(S2CellId, Tokens) {
+ // Test random cell ids at all levels.
+ for (int i = 0; i < 10000; ++i) {
+ S2CellId id = S2Testing::GetRandomCellId();
+ string token = id.ToToken();
+ EXPECT_LE(token.size(), 16);
+ EXPECT_EQ(S2CellId::FromToken(token), id);
+ }
+ // Check that invalid cell ids can be encoded.
+ string token = S2CellId::None().ToToken();
+ EXPECT_EQ(S2CellId::FromToken(token), S2CellId::None());
+}
+
+
+static const int kMaxExpandLevel = 3;
+
+static void ExpandCell(S2CellId const& parent, vector<S2CellId>* cells,
+ hash_map<S2CellId, S2CellId>* parent_map) {
+ cells->push_back(parent);
+ if (parent.level() == kMaxExpandLevel) return;
+ int i, j, orientation;
+ int face = parent.ToFaceIJOrientation(&i, &j, &orientation);
+ EXPECT_EQ(face, parent.face());
+
+ S2CellId child = parent.child_begin();
+ for (int pos = 0; child != parent.child_end(); child = child.next(), ++pos) {
+ // Do some basic checks on the children
+ EXPECT_EQ(parent.child(pos), child);
+ EXPECT_EQ(child.level(), parent.level() + 1);
+ EXPECT_FALSE(child.is_leaf());
+ int child_orientation;
+ EXPECT_EQ(child.ToFaceIJOrientation(&i, &j, &child_orientation), face);
+ EXPECT_EQ(child_orientation, orientation ^ S2::kPosToOrientation[pos]);
+
+ (*parent_map)[child] = parent;
+ ExpandCell(child, cells, parent_map);
+ }
+}
+
+TEST(S2CellId, Containment) {
+ // Test contains() and intersects().
+ hash_map<S2CellId, S2CellId> parent_map;
+ vector<S2CellId> cells;
+ for (int face = 0; face < 6; ++face) {
+ ExpandCell(S2CellId::FromFacePosLevel(face, 0, 0), &cells, &parent_map);
+ }
+ for (int i = 0; i < cells.size(); ++i) {
+ for (int j = 0; j < cells.size(); ++j) {
+ bool contained = true;
+ for (S2CellId id = cells[j]; id != cells[i]; id = parent_map[id]) {
+ if (parent_map.find(id) == parent_map.end()) {
+ contained = false;
+ break;
+ }
+ }
+ EXPECT_EQ(cells[i].contains(cells[j]), contained);
+ EXPECT_EQ(cells[j] >= cells[i].range_min() &&
+ cells[j] <= cells[i].range_max(), contained);
+ EXPECT_EQ(cells[i].intersects(cells[j]),
+ cells[i].contains(cells[j]) || cells[j].contains(cells[i]));
+ }
+ }
+}
+
+static int const kMaxWalkLevel = 8;
+
+TEST(S2CellId, Continuity) {
+ // Make sure that sequentially increasing cell ids form a continuous
+ // path over the surface of the sphere, i.e. there are no
+ // discontinuous jumps from one region to another.
+
+ double max_dist = S2::kMaxEdge.GetValue(kMaxWalkLevel);
+ S2CellId end = S2CellId::End(kMaxWalkLevel);
+ S2CellId id = S2CellId::Begin(kMaxWalkLevel);
+ for (; id != end; id = id.next()) {
+ EXPECT_LE(id.ToPointRaw().Angle(id.next_wrap().ToPointRaw()), max_dist);
+ EXPECT_EQ(id.advance_wrap(1), id.next_wrap());
+ EXPECT_EQ(id.next_wrap().advance_wrap(-1), id);
+
+ // Check that the ToPointRaw() returns the center of each cell
+ // in (s,t) coordinates.
+ double u, v;
+ S2::XYZtoFaceUV(id.ToPointRaw(), &u, &v);
+ static double const kCellSize = 1.0 / (1 << kMaxWalkLevel);
+ EXPECT_NEAR(drem(S2::UVtoST(u), 0.5 * kCellSize), 0.0, 1e-15);
+ EXPECT_NEAR(drem(S2::UVtoST(v), 0.5 * kCellSize), 0.0, 1e-15);
+ }
+}
+
+TEST(S2CellId, Coverage) {
+ // Make sure that random points on the sphere can be represented to the
+ // expected level of accuracy, which in the worst case is sqrt(2/3) times
+ // the maximum arc length between the points on the sphere associated with
+ // adjacent values of "i" or "j". (It is sqrt(2/3) rather than 1/2 because
+ // the cells at the corners of each face are stretched -- they have 60 and
+ // 120 degree angles.)
+
+ double max_dist = 0.5 * S2::kMaxDiag.GetValue(S2CellId::kMaxLevel);
+ for (int i = 0; i < 1000000; ++i) {
+ S2Point p = S2Testing::RandomPoint();
+ S2Point q = S2CellId::FromPoint(p).ToPointRaw();
+ EXPECT_LE(p.Angle(q), max_dist);
+ }
+}
+
+static void TestAllNeighbors(S2CellId const& id, int level) {
+ DCHECK_GE(level, id.level());
+ DCHECK_LT(level, S2CellId::kMaxLevel);
+
+ // We compute AppendAllNeighbors, and then add in all the children of "id"
+ // at the given level. We then compare this against the result of finding
+ // all the vertex neighbors of all the vertices of children of "id" at the
+ // given level. These should give the same result.
+ vector<S2CellId> all, expected;
+ id.AppendAllNeighbors(level, &all);
+ S2CellId end = id.child_end(level + 1);
+ for (S2CellId c = id.child_begin(level + 1); c != end; c = c.next()) {
+ all.push_back(c.parent());
+ c.AppendVertexNeighbors(level, &expected);
+ }
+ // Sort the results and eliminate duplicates.
+ sort(all.begin(), all.end());
+ sort(expected.begin(), expected.end());
+ all.erase(unique(all.begin(), all.end()), all.end());
+ expected.erase(unique(expected.begin(), expected.end()), expected.end());
+ EXPECT_EQ(expected, all);
+}
+
+TEST(S2CellId, Neighbors) {
+ // Check the edge neighbors of face 1.
+ static int out_faces[] = { 5, 3, 2, 0 };
+ S2CellId face_nbrs[4];
+ S2CellId::FromFacePosLevel(1, 0, 0).GetEdgeNeighbors(face_nbrs);
+ for (int i = 0; i < 4; ++i) {
+ EXPECT_TRUE(face_nbrs[i].is_face());
+ EXPECT_EQ(face_nbrs[i].face(), out_faces[i]);
+ }
+
+ // Check the vertex neighbors of the center of face 2 at level 5.
+ vector<S2CellId> nbrs;
+ S2CellId::FromPoint(S2Point(0, 0, 1)).AppendVertexNeighbors(5, &nbrs);
+ sort(nbrs.begin(), nbrs.end());
+ for (int i = 0; i < 4; ++i) {
+ EXPECT_EQ(nbrs[i], S2CellId::FromFaceIJ(
+ 2, (1 << 29) - (i < 2), (1 << 29) - (i == 0 || i == 3))
+ .parent(5));
+ }
+ nbrs.clear();
+
+ // Check the vertex neighbors of the corner of faces 0, 4, and 5.
+ S2CellId id = S2CellId::FromFacePosLevel(0, 0, S2CellId::kMaxLevel);
+ id.AppendVertexNeighbors(0, &nbrs);
+ sort(nbrs.begin(), nbrs.end());
+ EXPECT_EQ(nbrs.size(), 3);
+ EXPECT_EQ(nbrs[0], S2CellId::FromFacePosLevel(0, 0, 0));
+ EXPECT_EQ(nbrs[1], S2CellId::FromFacePosLevel(4, 0, 0));
+ EXPECT_EQ(nbrs[2], S2CellId::FromFacePosLevel(5, 0, 0));
+
+ // Check that AppendAllNeighbors produces results that are consistent
+ // with AppendVertexNeighbors for a bunch of random cells.
+ for (int i = 0; i < 1000; ++i) {
+ S2CellId id = S2Testing::GetRandomCellId();
+ if (id.is_leaf()) id = id.parent();
+
+ // TestAllNeighbors computes approximately 2**(2*(diff+1)) cell ids,
+ // so it's not reasonable to use large values of "diff".
+ int max_diff = min(6, S2CellId::kMaxLevel - id.level() - 1);
+ int level = id.level() + S2Testing::rnd.Uniform(max_diff);
+ TestAllNeighbors(id, level);
+ }
+}
+
+TEST(S2CellId, OutputOperator) {
+ S2CellId cell(0xbb04000000000000ULL);
+ ostringstream s;
+ s << cell;
+ EXPECT_EQ("5/31200", s.str());
+}
+
+TEST(S2CellId, ToPointBenchmark) {
+ // This "test" is really a benchmark, so skip it unless we're optimized.
+ if (DEBUG_MODE) return;
+
+ // Test speed of conversions from points to leaf cells.
+ double control_start = S2Testing::GetCpuTime();
+ S2CellId begin = S2CellId::Begin(S2CellId::kMaxLevel);
+ S2CellId end = S2CellId::End(S2CellId::kMaxLevel);
+ uint64 delta = (begin.id() - end.id()) / FLAGS_iters;
+ delta &= ~static_cast<uint64>(1); // Make sure all ids are leaf cells.
+
+ S2CellId id = begin;
+ double sum = 0;
+ for (int i = FLAGS_iters; i > 0; --i) {
+ sum += static_cast<double>(id.id());
+ id = S2CellId(id.id() + delta);
+ }
+ double control_time = S2Testing::GetCpuTime() - control_start;
+ printf("\tControl: %8.3f usecs\n", 1e6 * control_time / FLAGS_iters);
+ EXPECT_NE(sum, 0); // Don't let the loop get optimized away.
+
+ double test_start = S2Testing::GetCpuTime();
+ sum = 0;
+ id = begin;
+ for (int i = FLAGS_iters; i > 0; --i) {
+ sum += id.ToPointRaw()[0];
+ id = S2CellId(id.id() + delta);
+ }
+ double test_time = S2Testing::GetCpuTime() - test_start - control_time;
+ printf("\tToPointRaw: %8.3f usecs\n", 1e6 * test_time / FLAGS_iters);
+ EXPECT_NE(sum, 0); // Don't let the loop get optimized away.
+
+ test_start = S2Testing::GetCpuTime();
+ sum = 0;
+ id = begin;
+ for (int i = FLAGS_iters; i > 0; --i) {
+ sum += id.ToPoint()[0];
+ id = S2CellId(id.id() + delta);
+ }
+ test_time = S2Testing::GetCpuTime() - test_start - control_time;
+ printf("\tToPoint: %8.3f usecs\n", 1e6 * test_time / FLAGS_iters);
+ EXPECT_NE(sum, 0); // Don't let the loop get optimized away.
+}
+
+TEST(S2CellId, FromPointBenchmark) {
+ // This "test" is really a benchmark, so skip it unless we're optimized.
+ if (DEBUG_MODE) return;
+
+ // The sample points follow a spiral curve that completes one revolution
+ // around the z-axis every 1/dt samples. The z-coordinate increases
+ // from -4 to +4 over FLAGS_iters samples.
+
+ S2Point start(1, 0, -4);
+ double dz = (-2 * start.z()) / FLAGS_iters;
+ double dt = 1.37482937133e-4;
+
+ // Test speed of conversions from leaf cells to points.
+ double control_start = S2Testing::GetCpuTime();
+ uint64 isum = 0;
+ S2Point p = start;
+ for (int i = FLAGS_iters; i > 0; --i) {
+ // Cheap rotation around the z-axis (spirals inward slightly
+ // each revolution).
+ p += S2Point(-dt * p.y(), dt * p.x(), dz);
+ isum += MathUtil::FastIntRound(p[0] + p[1] + p[2]);
+ }
+ double control_time = S2Testing::GetCpuTime() - control_start;
+ printf("\tControl: %8.3f usecs\n", 1e6 * control_time / FLAGS_iters);
+ EXPECT_NE(isum, 0); // Don't let the loop get optimized away.
+
+ double test_start = S2Testing::GetCpuTime();
+ isum = 0;
+ p = start;
+ for (int i = FLAGS_iters; i > 0; --i) {
+ p += S2Point(-dt * p.y(), dt * p.x(), dz);
+ isum += S2CellId::FromPoint(p).id();
+ }
+ double test_time = S2Testing::GetCpuTime() - test_start - control_time;
+ printf("\tFromPoint: %8.3f usecs\n", 1e6 * test_time / FLAGS_iters);
+ EXPECT_NE(isum, 0); // Don't let the loop get optimized away.
+}
+
+TEST(S2CellId, HtmBenchmark) {
+ // This "test" is really a benchmark, so skip it unless we're optimized.
+ if (DEBUG_MODE) return;
+
+ // The HTM methods are about 100 times slower than the S2CellId methods,
+ // so we adjust the number of iterations accordingly.
+ int htm_iters = FLAGS_iters / 100;
+
+ SpatialVector start(1, 0, -4);
+ double dz = (-2 * start.z()) / htm_iters;
+ double dt = 1.37482937133e-4;
+
+ double test_start = S2Testing::GetCpuTime();
+ uint64 mem_start = MemoryUsage(0);
+ MallocInterface* mi = MallocInterface::instance();
+ size_t heap_start, heap_end;
+ CHECK(mi->GetNumericProperty("generic.current_allocated_bytes", &heap_start));
+ SpatialIndex htm(FLAGS_htm_level, FLAGS_build_level);
+ double constructor_time = S2Testing::GetCpuTime() - test_start;
+ printf("\tHTM constructor time: %12.3f ms\n", 1e3 * constructor_time);
+ printf("\tHTM heap size increase: %9lld\n", MemoryUsage(0) - mem_start);
+ CHECK(mi->GetNumericProperty("generic.current_allocated_bytes", &heap_end));
+ printf("\tHTM heap bytes allocated: %9u\n", heap_end - heap_start);
+
+ test_start = S2Testing::GetCpuTime();
+ double sum = 0;
+ SpatialVector v = start;
+ for (int i = htm_iters; i > 0; --i) {
+ v.set(v.x() - dt * v.y(), v.y() + dt * v.x(), v.z() + dz);
+ sum += v.x();
+ }
+ double htm_control = S2Testing::GetCpuTime() - test_start;
+ printf("\tHTM Control: %8.3f usecs\n", 1e6 * htm_control / htm_iters);
+ EXPECT_NE(sum, 0); // Don't let the loop get optimized away.
+
+ // Keeping the returned ids in a vector adds a negligible amount of time
+ // to the idByPoint test and makes it much easier to test pointById.
+ vector<uint64> ids(htm_iters);
+ test_start = S2Testing::GetCpuTime();
+ v = start;
+ for (int i = htm_iters; i > 0; --i) {
+ v.set(v.x() - dt * v.y(), v.y() + dt * v.x(), v.z() + dz);
+ ids[i-1] = htm.idByPoint(v);
+ }
+ double idByPoint_time = S2Testing::GetCpuTime() - test_start - htm_control;
+ printf("\tHTM FromPoint: %8.3f usecs\n",
+ 1e6 * idByPoint_time / htm_iters);
+
+ test_start = S2Testing::GetCpuTime();
+ sum = 0;
+ v = start;
+ for (int i = htm_iters; i > 0; --i) {
+ SpatialVector v2;
+ htm.pointById(v2, ids[i-1]);
+ sum += v2.x();
+ }
+ double pointById_time = S2Testing::GetCpuTime() - test_start;
+ printf("\tHTM ToPoint: %8.3f usecs\n",
+ 1e6 * pointById_time / htm_iters);
+ EXPECT_NE(sum, 0); // Don't let the loop get optimized away.
+}
diff --git a/src/third_party/s2/s2cellunion.cc b/src/third_party/s2/s2cellunion.cc
new file mode 100644
index 00000000000..a7e3d67812e
--- /dev/null
+++ b/src/third_party/s2/s2cellunion.cc
@@ -0,0 +1,454 @@
+// Copyright 2005 Google Inc. All Rights Reserved.
+
+#include "s2cellunion.h"
+
+#include <algorithm>
+using std::min;
+using std::max;
+using std::swap;
+using std::reverse;
+
+#include <vector>
+using std::vector;
+
+
+#include "base/integral_types.h"
+#include "base/logging.h"
+#include "s2.h"
+#include "s2cap.h"
+#include "s2cell.h"
+#include "s2cellid.h"
+#include "s2latlngrect.h"
+
+// Returns true if the vector of cell_ids is sorted. Used only in
+// DCHECKs.
+extern bool IsSorted(vector<S2CellId> const& cell_ids) {
+ for (size_t i = 0; i + 1 < cell_ids.size(); ++i) {
+ if (cell_ids[i + 1] < cell_ids[i]) {
+ return false;
+ }
+ }
+ return true;
+}
+
+void S2CellUnion::Init(vector<S2CellId> const& cell_ids) {
+ InitRaw(cell_ids);
+ Normalize();
+}
+
+void S2CellUnion::Init(vector<uint64> const& cell_ids) {
+ InitRaw(cell_ids);
+ Normalize();
+}
+
+void S2CellUnion::InitSwap(vector<S2CellId>* cell_ids) {
+ InitRawSwap(cell_ids);
+ Normalize();
+}
+
+void S2CellUnion::InitRaw(vector<S2CellId> const& cell_ids) {
+ cell_ids_ = cell_ids;
+}
+
+void S2CellUnion::InitRaw(vector<uint64> const& cell_ids) {
+ cell_ids_.resize(cell_ids.size());
+ for (int i = 0; i < num_cells(); ++i) {
+ cell_ids_[i] = S2CellId(cell_ids[i]);
+ }
+}
+
+void S2CellUnion::InitRawSwap(vector<S2CellId>* cell_ids) {
+ cell_ids_.swap(*cell_ids);
+ cell_ids->clear();
+}
+
+void S2CellUnion::Detach(vector<S2CellId>* cell_ids) {
+ cell_ids_.swap(*cell_ids);
+ cell_ids_.clear();
+}
+
+void S2CellUnion::Pack(int excess) {
+ if (cell_ids_.capacity() - cell_ids_.size() > (size_t)excess) {
+ vector<S2CellId> packed = cell_ids_;
+ cell_ids_.swap(packed);
+ }
+}
+
+S2CellUnion* S2CellUnion::Clone() const {
+ S2CellUnion* copy = new S2CellUnion;
+ copy->InitRaw(cell_ids_);
+ return copy;
+}
+
+bool S2CellUnion::Normalize() {
+ // Optimize the representation by looking for cases where all subcells
+ // of a parent cell are present.
+
+ vector<S2CellId> output;
+ output.reserve(cell_ids_.size());
+ sort(cell_ids_.begin(), cell_ids_.end());
+
+ for (int i = 0; i < num_cells(); ++i) {
+ S2CellId id = cell_id(i);
+
+ // Check whether this cell is contained by the previous cell.
+ if (!output.empty() && output.back().contains(id)) continue;
+
+ // Discard any previous cells contained by this cell.
+ while (!output.empty() && id.contains(output.back())) {
+ output.pop_back();
+ }
+
+ // Check whether the last 3 elements of "output" plus "id" can be
+ // collapsed into a single parent cell.
+ while (output.size() >= 3) {
+ // A necessary (but not sufficient) condition is that the XOR of the
+ // four cells must be zero. This is also very fast to test.
+ if ((output.end()[-3].id() ^ output.end()[-2].id() ^ output.back().id())
+ != id.id())
+ break;
+
+ // Now we do a slightly more expensive but exact test. First, compute a
+ // mask that blocks out the two bits that encode the child position of
+ // "id" with respect to its parent, then check that the other three
+ // children all agree with "mask.
+ uint64 mask = id.lsb() << 1;
+ mask = ~(mask + (mask << 1));
+ uint64 id_masked = (id.id() & mask);
+ if ((output.end()[-3].id() & mask) != id_masked ||
+ (output.end()[-2].id() & mask) != id_masked ||
+ (output.end()[-1].id() & mask) != id_masked ||
+ id.is_face())
+ break;
+
+ // Replace four children by their parent cell.
+ output.erase(output.end() - 3, output.end());
+ id = id.parent();
+ }
+ output.push_back(id);
+ }
+ if (output.size() < (size_t)num_cells()) {
+ InitRawSwap(&output);
+ return true;
+ }
+ return false;
+}
+
+void S2CellUnion::Denormalize(int min_level, int level_mod,
+ vector<S2CellId>* output) const {
+ DCHECK_GE(min_level, 0);
+ DCHECK_LE(min_level, S2CellId::kMaxLevel);
+ DCHECK_GE(level_mod, 1);
+ DCHECK_LE(level_mod, 3);
+
+ output->clear();
+ output->reserve(num_cells());
+ for (int i = 0; i < num_cells(); ++i) {
+ S2CellId id = cell_id(i);
+ int level = id.level();
+ int new_level = max(min_level, level);
+ if (level_mod > 1) {
+ // Round up so that (new_level - min_level) is a multiple of level_mod.
+ // (Note that S2CellId::kMaxLevel is a multiple of 1, 2, and 3.)
+ new_level += (S2CellId::kMaxLevel - (new_level - min_level)) % level_mod;
+ new_level = min(S2CellId::kMaxLevel, new_level);
+ }
+ if (new_level == level) {
+ output->push_back(id);
+ } else {
+ S2CellId end = id.child_end(new_level);
+ for (id = id.child_begin(new_level); id != end; id = id.next()) {
+ output->push_back(id);
+ }
+ }
+ }
+}
+
+S2Cap S2CellUnion::GetCapBound() const {
+ // Compute the approximate centroid of the region. This won't produce the
+ // bounding cap of minimal area, but it should be close enough.
+ if (cell_ids_.empty()) return S2Cap::Empty();
+ S2Point centroid(0, 0, 0);
+ for (int i = 0; i < num_cells(); ++i) {
+ double area = S2Cell::AverageArea(cell_id(i).level());
+ centroid += area * cell_id(i).ToPoint();
+ }
+ if (centroid == S2Point(0, 0, 0)) {
+ centroid = S2Point(1, 0, 0);
+ } else {
+ centroid = centroid.Normalize();
+ }
+
+ // Use the centroid as the cap axis, and expand the cap angle so that it
+ // contains the bounding caps of all the individual cells. Note that it is
+ // *not* sufficient to just bound all the cell vertices because the bounding
+ // cap may be concave (i.e. cover more than one hemisphere).
+ S2Cap cap = S2Cap::FromAxisHeight(centroid, 0);
+ for (int i = 0; i < num_cells(); ++i) {
+ cap.AddCap(S2Cell(cell_id(i)).GetCapBound());
+ }
+ return cap;
+}
+
+S2LatLngRect S2CellUnion::GetRectBound() const {
+ S2LatLngRect bound = S2LatLngRect::Empty();
+ for (int i = 0; i < num_cells(); ++i) {
+ bound = bound.Union(S2Cell(cell_id(i)).GetRectBound());
+ }
+ return bound;
+}
+
+bool S2CellUnion::Contains(S2CellId const& id) const {
+ // This function requires that Normalize has been called first.
+ //
+ // This is an exact test. Each cell occupies a linear span of the S2
+ // space-filling curve, and the cell id is simply the position at the center
+ // of this span. The cell union ids are sorted in increasing order along
+ // the space-filling curve. So we simply find the pair of cell ids that
+ // surround the given cell id (using binary search). There is containment
+ // if and only if one of these two cell ids contains this cell.
+
+ vector<S2CellId>::const_iterator i =
+ lower_bound(cell_ids_.begin(), cell_ids_.end(), id);
+ if (i != cell_ids_.end() && i->range_min() <= id) return true;
+ return i != cell_ids_.begin() && (--i)->range_max() >= id;
+}
+
+bool S2CellUnion::Intersects(S2CellId const& id) const {
+ // This function requires that Normalize has been called first.
+ // This is an exact test; see the comments for Contains() above.
+
+ vector<S2CellId>::const_iterator i =
+ lower_bound(cell_ids_.begin(), cell_ids_.end(), id);
+ if (i != cell_ids_.end() && i->range_min() <= id.range_max()) return true;
+ return i != cell_ids_.begin() && (--i)->range_max() >= id.range_min();
+}
+
+bool S2CellUnion::Contains(S2CellUnion const* y) const {
+ // TODO: A divide-and-conquer or alternating-skip-search approach may be
+ // sigificantly faster in both the average and worst case.
+
+ for (int i = 0; i < y->num_cells(); ++i) {
+ if (!Contains(y->cell_id(i))) return false;
+ }
+ return true;
+}
+
+bool S2CellUnion::Intersects(S2CellUnion const* y) const {
+ // TODO: A divide-and-conquer or alternating-skip-search approach may be
+ // sigificantly faster in both the average and worst case.
+
+ for (int i = 0; i < y->num_cells(); ++i) {
+ if (Intersects(y->cell_id(i))) return true;
+ }
+ return false;
+}
+
+void S2CellUnion::GetUnion(S2CellUnion const* x, S2CellUnion const* y) {
+ DCHECK_NE(this, x);
+ DCHECK_NE(this, y);
+ cell_ids_.reserve(x->num_cells() + y->num_cells());
+ cell_ids_ = x->cell_ids_;
+ cell_ids_.insert(cell_ids_.end(), y->cell_ids_.begin(), y->cell_ids_.end());
+ Normalize();
+}
+
+void S2CellUnion::GetIntersection(S2CellUnion const* x, S2CellId const& id) {
+ DCHECK_NE(this, x);
+ cell_ids_.clear();
+ if (x->Contains(id)) {
+ cell_ids_.push_back(id);
+ } else {
+ vector<S2CellId>::const_iterator i =
+ lower_bound(x->cell_ids_.begin(), x->cell_ids_.end(), id.range_min());
+ S2CellId idmax = id.range_max();
+ while (i != x->cell_ids_.end() && *i <= idmax)
+ cell_ids_.push_back(*i++);
+ }
+}
+
+void S2CellUnion::GetIntersection(S2CellUnion const* x, S2CellUnion const* y) {
+ DCHECK_NE(this, x);
+ DCHECK_NE(this, y);
+
+ // This is a fairly efficient calculation that uses binary search to skip
+ // over sections of both input vectors. It takes constant time if all the
+ // cells of "x" come before or after all the cells of "y" in S2CellId order.
+
+ cell_ids_.clear();
+ vector<S2CellId>::const_iterator i = x->cell_ids_.begin();
+ vector<S2CellId>::const_iterator j = y->cell_ids_.begin();
+ while (i != x->cell_ids_.end() && j != y->cell_ids_.end()) {
+ S2CellId imin = i->range_min();
+ S2CellId jmin = j->range_min();
+ if (imin > jmin) {
+ // Either j->contains(*i) or the two cells are disjoint.
+ if (*i <= j->range_max()) {
+ cell_ids_.push_back(*i++);
+ } else {
+ // Advance "j" to the first cell possibly contained by *i.
+ j = lower_bound(j + 1, y->cell_ids_.end(), imin);
+ // The previous cell *(j-1) may now contain *i.
+ if (*i <= (j - 1)->range_max()) --j;
+ }
+ } else if (jmin > imin) {
+ // Identical to the code above with "i" and "j" reversed.
+ if (*j <= i->range_max()) {
+ cell_ids_.push_back(*j++);
+ } else {
+ i = lower_bound(i + 1, x->cell_ids_.end(), jmin);
+ if (*j <= (i - 1)->range_max()) --i;
+ }
+ } else {
+ // "i" and "j" have the same range_min(), so one contains the other.
+ if (*i < *j)
+ cell_ids_.push_back(*i++);
+ else
+ cell_ids_.push_back(*j++);
+ }
+ }
+ // The output is generated in sorted order, and there should not be any
+ // cells that can be merged (provided that both inputs were normalized).
+ DCHECK(IsSorted(cell_ids_));
+ DCHECK(!Normalize());
+}
+
+static void GetDifferenceInternal(S2CellId cell,
+ S2CellUnion const* y,
+ vector<S2CellId>* cell_ids) {
+ // Add the difference between cell and y to cell_ids.
+ // If they intersect but the difference is non-empty, divides and conquers.
+
+ if (!y->Intersects(cell)) {
+ cell_ids->push_back(cell);
+ } else if (!y->Contains(cell)) {
+ S2CellId child = cell.child_begin();
+ for (int i = 0; ; ++i) {
+ GetDifferenceInternal(child, y, cell_ids);
+ if (i == 3) break; // Avoid unnecessary next() computation.
+ child = child.next();
+ }
+ }
+}
+
+void S2CellUnion::GetDifference(S2CellUnion const* x, S2CellUnion const* y) {
+ DCHECK_NE(this, x);
+ DCHECK_NE(this, y);
+ // TODO: this is approximately O(N*log(N)), but could probably use similar
+ // techniques as GetIntersection() to be more efficient.
+
+ cell_ids_.clear();
+ for (int i = 0; i < x->num_cells(); ++i) {
+ GetDifferenceInternal(x->cell_id(i), y, &cell_ids_);
+ }
+ // The output is generated in sorted order, and there should not be any
+ // cells that can be merged (provided that both inputs were normalized).
+ DCHECK(IsSorted(cell_ids_));
+ DCHECK(!Normalize());
+}
+
+void S2CellUnion::Expand(int level) {
+ vector<S2CellId> output;
+ uint64 level_lsb = S2CellId::lsb_for_level(level);
+ for (int i = num_cells() - 1; i >= 0; --i) {
+ S2CellId id = cell_id(i);
+ if (id.lsb() < level_lsb) {
+ id = id.parent(level);
+ // Optimization: skip over any cells contained by this one. This is
+ // especially important when very small regions are being expanded.
+ while (i > 0 && id.contains(cell_id(i-1))) --i;
+ }
+ output.push_back(id);
+ id.AppendAllNeighbors(level, &output);
+ }
+ InitSwap(&output);
+}
+
+void S2CellUnion::Expand(S1Angle const& min_radius, int max_level_diff) {
+ int min_level = S2CellId::kMaxLevel;
+ for (int i = 0; i < num_cells(); ++i) {
+ min_level = min(min_level, cell_id(i).level());
+ }
+ // Find the maximum level such that all cells are at least "min_radius" wide.
+ int radius_level = S2::kMinWidth.GetMaxLevel(min_radius.radians());
+ if (radius_level == 0 && min_radius.radians() > S2::kMinWidth.GetValue(0)) {
+ // The requested expansion is greater than the width of a face cell.
+ // The easiest way to handle this is to expand twice.
+ Expand(0);
+ }
+ Expand(min(min_level + max_level_diff, radius_level));
+}
+
+void S2CellUnion::InitFromRange(S2CellId const& min_id,
+ S2CellId const& max_id) {
+ DCHECK(min_id.is_leaf());
+ DCHECK(max_id.is_leaf());
+ DCHECK_LE(min_id, max_id);
+
+ // We repeatedly add the largest cell we can.
+ cell_ids_.clear();
+ for (S2CellId next_min_id = min_id; next_min_id <= max_id; ) {
+ DCHECK(next_min_id.is_leaf());
+
+ // Find the largest cell that starts at "next_min_id" and doesn't extend
+ // beyond "max_id".
+ S2CellId next_id = next_min_id;
+ while (!next_id.is_face() &&
+ next_id.parent().range_min() == next_min_id &&
+ next_id.parent().range_max() <= max_id) {
+ next_id = next_id.parent();
+ }
+ cell_ids_.push_back(next_id);
+ next_min_id = next_id.range_max().next();
+ }
+
+ // The output is already normalized.
+ DCHECK(IsSorted(cell_ids_));
+ DCHECK(!Normalize());
+}
+
+uint64 S2CellUnion::LeafCellsCovered() const {
+ uint64 num_leaves = 0;
+ for (int i = 0; i < num_cells(); ++i) {
+ const int inverted_level =
+ S2CellId::kMaxLevel - cell_id(i).level();
+ num_leaves += (1ULL << (inverted_level << 1));
+ }
+ return num_leaves;
+}
+
+double S2CellUnion::AverageBasedArea() const {
+ return S2Cell::AverageArea(S2CellId::kMaxLevel) * LeafCellsCovered();
+}
+
+double S2CellUnion::ApproxArea() const {
+ double area = 0;
+ for (int i = 0; i < num_cells(); ++i) {
+ area += S2Cell(cell_id(i)).ApproxArea();
+ }
+ return area;
+}
+
+double S2CellUnion::ExactArea() const {
+ double area = 0;
+ for (int i = 0; i < num_cells(); ++i) {
+ area += S2Cell(cell_id(i)).ExactArea();
+ }
+ return area;
+}
+
+bool operator==(S2CellUnion const& x, S2CellUnion const& y) {
+ return x.cell_ids() == y.cell_ids();
+}
+
+bool S2CellUnion::Contains(S2Cell const& cell) const {
+ return Contains(cell.id());
+}
+
+bool S2CellUnion::MayIntersect(S2Cell const& cell) const {
+ return Intersects(cell.id());
+}
+
+bool S2CellUnion::Contains(S2Point const& p) const {
+ return Contains(S2CellId::FromPoint(p));
+}
diff --git a/src/third_party/s2/s2cellunion.h b/src/third_party/s2/s2cellunion.h
new file mode 100644
index 00000000000..c3d3658ad56
--- /dev/null
+++ b/src/third_party/s2/s2cellunion.h
@@ -0,0 +1,207 @@
+// Copyright 2005 Google Inc. All Rights Reserved.
+
+#ifndef UTIL_GEOMETRY_S2CELLUNION_H_
+#define UTIL_GEOMETRY_S2CELLUNION_H_
+
+#include <vector>
+using std::vector;
+
+#include "base/integral_types.h"
+#include "base/logging.h"
+#include "base/macros.h"
+#include "s2region.h"
+#include "s2cellid.h"
+
+class S1Angle;
+class S2Cell;
+
+// An S2CellUnion is a region consisting of cells of various sizes. Typically
+// a cell union is used to approximate some other shape. There is a tradeoff
+// between the accuracy of the approximation and how many cells are used.
+// Unlike polygons, cells have a fixed hierarchical structure. This makes
+// them more suitable for optimizations based on preprocessing.
+class S2CellUnion : public S2Region {
+ public:
+ // The default constructor does nothing. The cell union cannot be used
+ // until one of the Init() methods is called.
+ S2CellUnion() {}
+
+ // Populates a cell union with the given S2CellIds or 64-bit cells ids, and
+ // then calls Normalize(). The InitSwap() version takes ownership of the
+ // vector data without copying and clears the given vector. These methods
+ // may be called multiple times.
+ void Init(vector<S2CellId> const& cell_ids);
+ void Init(vector<uint64> const& cell_ids);
+ void InitSwap(vector<S2CellId>* cell_ids);
+
+ // Like Init(), but does not call Normalize(). The cell union *must* be
+ // normalized before doing any calculations with it, so it is the caller's
+ // responsibility to make sure that the input is normalized. This method is
+ // useful when converting cell unions to another representation and back.
+ // These methods may be called multiple times.
+ void InitRaw(vector<S2CellId> const& cell_ids);
+ void InitRaw(vector<uint64> const& cell_ids);
+ void InitRawSwap(vector<S2CellId>* cell_ids);
+
+ // Gives ownership of the vector data to the client without copying, and
+ // clears the content of the cell union. The original data in cell_ids
+ // is lost if there was any. This is the opposite of InitRawSwap().
+ void Detach(vector<S2CellId>* cell_ids);
+
+ // Convenience methods for accessing the individual cell ids.
+ int num_cells() const { return cell_ids_.size(); }
+ S2CellId const& cell_id(int i) const { return cell_ids_[i]; }
+
+ // Direct access to the underlying vector for STL algorithms.
+ vector<S2CellId> const& cell_ids() const { return cell_ids_; }
+
+ // Normalizes the cell union by discarding cells that are contained by other
+ // cells, replacing groups of 4 child cells by their parent cell whenever
+ // possible, and sorting all the cell ids in increasing order. Returns true
+ // if the number of cells was reduced.
+ //
+ // This method *must* be called before doing any calculations on the cell
+ // union, such as Intersects() or Contains().
+ bool Normalize();
+
+ // Replaces "output" with an expanded version of the cell union where any
+ // cells whose level is less than "min_level" or where (level - min_level)
+ // is not a multiple of "level_mod" are replaced by their children, until
+ // either both of these conditions are satisfied or the maximum level is
+ // reached.
+ //
+ // This method allows a covering generated by S2RegionCoverer using
+ // min_level() or level_mod() constraints to be stored as a normalized cell
+ // union (which allows various geometric computations to be done) and then
+ // converted back to the original list of cell ids that satisfies the
+ // desired constraints.
+ void Denormalize(int min_level, int level_mod,
+ vector<S2CellId>* output) const;
+
+ // If there are more than "excess" elements of the cell_ids() vector that
+ // are allocated but unused, reallocate the array to eliminate the excess
+ // space. This reduces memory usage when many cell unions need to be held
+ // in memory at once.
+ void Pack(int excess = 0);
+
+ // Return true if the cell union contains the given cell id. Containment is
+ // defined with respect to regions, e.g. a cell contains its 4 children.
+ // This is a fast operation (logarithmic in the size of the cell union).
+ bool Contains(S2CellId const& id) const;
+
+ // Return true if the cell union intersects the given cell id.
+ // This is a fast operation (logarithmic in the size of the cell union).
+ bool Intersects(S2CellId const& id) const;
+
+ // Return true if this cell union contain/intersects the given other cell
+ // union.
+ bool Contains(S2CellUnion const* y) const;
+ bool Intersects(S2CellUnion const* y) const;
+
+ // Initialize this cell union to the union, intersection, or
+ // difference (x - y) of the two given cell unions.
+ // Requires: x != this and y != this.
+ void GetUnion(S2CellUnion const* x, S2CellUnion const* y);
+ void GetIntersection(S2CellUnion const* x, S2CellUnion const* y);
+ void GetDifference(S2CellUnion const* x, S2CellUnion const* y);
+
+ // Specialized version of GetIntersection() that gets the intersection of a
+ // cell union with the given cell id. This can be useful for "splitting" a
+ // cell union into chunks.
+ void GetIntersection(S2CellUnion const* x, S2CellId const& id);
+
+ // Expands the cell union by adding a "rim" of cells on expand_level
+ // around the union boundary.
+ //
+ // For each cell c in the union, we add all cells at level
+ // expand_level that abut c. There are typically eight of those
+ // (four edge-abutting and four sharing a vertex). However, if c is
+ // finer than expand_level, we add all cells abutting
+ // c.parent(expand_level) as well as c.parent(expand_level) itself,
+ // as an expand_level cell rarely abuts a smaller cell.
+ //
+ // Note that the size of the output is exponential in
+ // "expand_level". For example, if expand_level == 20 and the input
+ // has a cell at level 10, there will be on the order of 4000
+ // adjacent cells in the output. For most applications the
+ // Expand(min_radius, max_level_diff) method below is easier to use.
+ void Expand(int expand_level);
+
+ // Expand the cell union such that it contains all points whose distance to
+ // the cell union is at most "min_radius", but do not use cells that are
+ // more than "max_level_diff" levels higher than the largest cell in the
+ // input. The second parameter controls the tradeoff between accuracy and
+ // output size when a large region is being expanded by a small amount
+ // (e.g. expanding Canada by 1km). For example, if max_level_diff == 4 the
+ // region will always be expanded by approximately 1/16 the width of its
+ // largest cell. Note that in the worst case, the number of cells in the
+ // output can be up to 4 * (1 + 2 ** max_level_diff) times larger than the
+ // number of cells in the input.
+ void Expand(S1Angle const& min_radius, int max_level_diff);
+
+ // Create a cell union that corresponds to a continuous range of cell ids.
+ // The output is a normalized collection of cell ids that covers the leaf
+ // cells between "min_id" and "max_id" inclusive.
+ // Requires: min_id.is_leaf(), max_id.is_leaf(), min_id <= max_id.
+ void InitFromRange(S2CellId const& min_id, S2CellId const& max_id);
+
+ // The number of leaf cells covered by the union.
+ // This will be no more than 6*2^60 for the whole sphere.
+ uint64 LeafCellsCovered() const;
+
+ // Approximate this cell union's area by summing the average area of
+ // each contained cell's average area, using the AverageArea method
+ // from the S2Cell class.
+ // This is equivalent to the number of leaves covered, multiplied by
+ // the average area of a leaf.
+ // Note that AverageArea does not take into account distortion of cell, and
+ // thus may be off by up to a factor of 1.7.
+ // NOTE: Since this is proportional to LeafCellsCovered(), it is
+ // always better to use the other function if all you care about is
+ // the relative average area between objects.
+ double AverageBasedArea() const;
+
+ // Calculates this cell union's area by summing the approximate area for each
+ // contained cell, using the ApproxArea method from the S2Cell class.
+ double ApproxArea() const;
+
+ // Calculates this cell union's area by summing the exact area for each
+ // contained cell, using the Exact method from the S2Cell class.
+ double ExactArea() const;
+
+ ////////////////////////////////////////////////////////////////////////
+ // S2Region interface (see s2region.h for details):
+
+ virtual S2CellUnion* Clone() const;
+ virtual S2Cap GetCapBound() const;
+ virtual S2LatLngRect GetRectBound() const;
+
+ // This is a fast operation (logarithmic in the size of the cell union).
+ virtual bool Contains(S2Cell const& cell) const;
+
+ // This is a fast operation (logarithmic in the size of the cell union).
+ virtual bool MayIntersect(S2Cell const& cell) const;
+
+ virtual bool VirtualContainsPoint(S2Point const& p) const {
+ return Contains(p); // The same as Contains() below, just virtual.
+ }
+
+ virtual void Encode(Encoder* const encoder) const {
+ S2LOG(FATAL) << "Unimplemented";
+ }
+ virtual bool Decode(Decoder* const decoder) { return false; }
+
+ // The point 'p' does not need to be normalized.
+ // This is a fast operation (logarithmic in the size of the cell union).
+ bool Contains(S2Point const& p) const;
+
+ private:
+ vector<S2CellId> cell_ids_;
+
+ DISALLOW_EVIL_CONSTRUCTORS(S2CellUnion);
+};
+
+// Return true if two cell unions are identical.
+bool operator==(S2CellUnion const& x, S2CellUnion const& y);
+
+#endif // UTIL_GEOMETRY_S2CELLUNION_H_
diff --git a/src/third_party/s2/s2cellunion_test.cc b/src/third_party/s2/s2cellunion_test.cc
new file mode 100644
index 00000000000..a8841d463a1
--- /dev/null
+++ b/src/third_party/s2/s2cellunion_test.cc
@@ -0,0 +1,449 @@
+// Copyright 2005 Google Inc. All Rights Reserved.
+
+#include "s2cellunion.h"
+
+#include <algorithm>
+using std::min;
+using std::max;
+using std::swap;
+using std::reverse;
+
+#include <vector>
+using std::vector;
+
+
+#include "base/integral_types.h"
+#include "base/logging.h"
+#include "testing/base/public/gunit.h"
+#include "s2cellid.h"
+#include "s2cell.h"
+#include "s2cap.h"
+#include "s2testing.h"
+#include "s2regioncoverer.h"
+
+TEST(S2CellUnion, Basic) {
+ S2CellUnion empty;
+ vector<S2CellId> ids;
+ empty.Init(ids);
+ EXPECT_EQ(0, empty.num_cells());
+
+ S2CellId face1_id = S2CellId::FromFacePosLevel(1, 0, 0);
+ S2CellUnion face1_union;
+ ids.push_back(face1_id);
+ face1_union.Init(ids);
+ EXPECT_EQ(1, face1_union.num_cells());
+ EXPECT_EQ(face1_id, face1_union.cell_id(0));
+
+ S2CellId face2_id = S2CellId::FromFacePosLevel(2, 0, 0);
+ S2CellUnion face2_union;
+ vector<uint64> cell_ids;
+ cell_ids.push_back(face2_id.id());
+ face2_union.Init(cell_ids);
+ EXPECT_EQ(1, face2_union.num_cells());
+ EXPECT_EQ(face2_id, face2_union.cell_id(0));
+
+ S2Cell face1_cell(face1_id);
+ S2Cell face2_cell(face2_id);
+ EXPECT_TRUE(face1_union.Contains(face1_cell));
+ EXPECT_TRUE(!face1_union.Contains(face2_cell));
+}
+
+static S2Testing::Random& rnd = S2Testing::rnd;
+
+static void AddCells(S2CellId const& id, bool selected,
+ vector<S2CellId> *input, vector<S2CellId> *expected) {
+ // Decides whether to add "id" and/or some of its descendants to the
+ // test case. If "selected" is true, then the region covered by "id"
+ // *must* be added to the test case (either by adding "id" itself, or
+ // some combination of its descendants, or both). If cell ids are to
+ // the test case "input", then the corresponding expected result after
+ // simplification is added to "expected".
+
+ if (id == S2CellId::None()) {
+ // Initial call: decide whether to add cell(s) from each face.
+ for (int face = 0; face < 6; ++face) {
+ AddCells(S2CellId::FromFacePosLevel(face, 0, 0), false, input, expected);
+ }
+ return;
+ }
+ if (id.is_leaf()) {
+ // The rnd.OneIn() call below ensures that the parent of a leaf cell
+ // will always be selected (if we make it that far down the hierarchy).
+ DCHECK(selected);
+ input->push_back(id);
+ return;
+ }
+ // The following code ensures that the probability of selecting a cell
+ // at each level is approximately the same, i.e. we test normalization
+ // of cells at all levels.
+ if (!selected && rnd.OneIn(S2CellId::kMaxLevel - id.level())) {
+ // Once a cell has been selected, the expected output is predetermined.
+ // We then make sure that cells are selected that will normalize to
+ // the desired output.
+ expected->push_back(id);
+ selected = true;
+ }
+
+ // With the rnd.OneIn() constants below, this function adds an average
+ // of 5/6 * (kMaxLevel - level) cells to "input" where "level" is the
+ // level at which the cell was first selected (level 15 on average).
+ // Therefore the average number of input cells in a test case is about
+ // (5/6 * 15 * 6) = 75. The average number of output cells is about 6.
+
+ // If a cell is selected, we add it to "input" with probability 5/6.
+ bool added = false;
+ if (selected && !rnd.OneIn(6)) {
+ input->push_back(id);
+ added = true;
+ }
+ int num_children = 0;
+ S2CellId child = id.child_begin();
+ for (int pos = 0; pos < 4; ++pos, child = child.next()) {
+ // If the cell is selected, on average we recurse on 4/12 = 1/3 child.
+ // This intentionally may result in a cell and some of its children
+ // being included in the test case.
+ //
+ // If the cell is not selected, on average we recurse on one child.
+ // We also make sure that we do not recurse on all 4 children, since
+ // then we might include all 4 children in the input case by accident
+ // (in which case the expected output would not be correct).
+ if (rnd.OneIn(selected ? 12 : 4) && num_children < 3) {
+ AddCells(child, selected, input, expected);
+ ++num_children;
+ }
+ // If this cell was selected but the cell itself was not added, we
+ // must ensure that all 4 children (or some combination of their
+ // descendants) are added.
+ if (selected && !added) AddCells(child, selected, input, expected);
+ }
+}
+
+TEST(S2CellUnion, Normalize) {
+ // Try a bunch of random test cases, and keep track of average
+ // statistics for normalization (to see if they agree with the
+ // analysis above).
+ S2CellUnion cellunion;
+ double in_sum = 0, out_sum = 0;
+ static int const kIters = 2000;
+ for (int i = 0; i < kIters; ++i) {
+ vector<S2CellId> input, expected;
+ AddCells(S2CellId::None(), false, &input, &expected);
+ in_sum += input.size();
+ out_sum += expected.size();
+ cellunion.Init(input);
+ EXPECT_EQ(expected.size(), cellunion.num_cells());
+ for (int i = 0; i < expected.size(); ++i) {
+ EXPECT_EQ(expected[i], cellunion.cell_id(i));
+ }
+
+ // Test GetCapBound().
+ S2Cap cap = cellunion.GetCapBound();
+ for (int i = 0; i < cellunion.num_cells(); ++i) {
+ EXPECT_TRUE(cap.Contains(S2Cell(cellunion.cell_id(i))));
+ }
+
+ // Test Contains(S2CellId) and Intersects(S2CellId).
+ for (int j = 0; j < input.size(); ++j) {
+ EXPECT_TRUE(cellunion.Contains(input[j]));
+ EXPECT_TRUE(cellunion.Contains(input[j].ToPoint()));
+ EXPECT_TRUE(cellunion.VirtualContainsPoint(input[j].ToPoint()));
+ EXPECT_TRUE(cellunion.Intersects(input[j]));
+ if (!input[j].is_face()) {
+ EXPECT_TRUE(cellunion.Intersects(input[j].parent()));
+ if (input[j].level() > 1) {
+ EXPECT_TRUE(cellunion.Intersects(input[j].parent().parent()));
+ EXPECT_TRUE(cellunion.Intersects(input[j].parent(0)));
+ }
+ }
+ if (!input[j].is_leaf()) {
+ EXPECT_TRUE(cellunion.Contains(input[j].child_begin()));
+ EXPECT_TRUE(cellunion.Intersects(input[j].child_begin()));
+ EXPECT_TRUE(cellunion.Contains(input[j].child_end().prev()));
+ EXPECT_TRUE(cellunion.Intersects(input[j].child_end().prev()));
+ EXPECT_TRUE(cellunion.Contains(
+ input[j].child_begin(S2CellId::kMaxLevel)));
+ EXPECT_TRUE(cellunion.Intersects(
+ input[j].child_begin(S2CellId::kMaxLevel)));
+ }
+ }
+ for (int j = 0; j < expected.size(); ++j) {
+ if (!expected[j].is_face()) {
+ EXPECT_TRUE(!cellunion.Contains(expected[j].parent()));
+ EXPECT_TRUE(!cellunion.Contains(expected[j].parent(0)));
+ }
+ }
+
+ // Test Contains(S2CellUnion*), Intersects(S2CellUnion*),
+ // GetUnion(), GetIntersection(), and GetDifference().
+ vector<S2CellId> x, y, x_or_y, x_and_y;
+ for (int j = 0; j < input.size(); ++j) {
+ bool in_x = rnd.OneIn(2);
+ bool in_y = rnd.OneIn(2);
+ if (in_x) x.push_back(input[j]);
+ if (in_y) y.push_back(input[j]);
+ if (in_x || in_y) x_or_y.push_back(input[j]);
+ }
+ S2CellUnion xcells, ycells, x_or_y_expected, x_and_y_expected;
+ xcells.Init(x);
+ ycells.Init(y);
+ x_or_y_expected.Init(x_or_y);
+
+ S2CellUnion x_or_y_cells;
+ x_or_y_cells.GetUnion(&xcells, &ycells);
+ EXPECT_TRUE(x_or_y_cells == x_or_y_expected);
+
+ // Compute the intersection of "x" with each cell of "y",
+ // check that this intersection is correct, and append the
+ // results to x_and_y_expected.
+ for (int j = 0; j < ycells.num_cells(); ++j) {
+ S2CellId yid = ycells.cell_id(j);
+ S2CellUnion u;
+ u.GetIntersection(&xcells, yid);
+ for (int k = 0; k < xcells.num_cells(); ++k) {
+ S2CellId xid = xcells.cell_id(k);
+ if (xid.contains(yid)) {
+ EXPECT_TRUE(u.num_cells() == 1 && u.cell_id(0) == yid);
+ } else if (yid.contains(xid)) {
+ EXPECT_TRUE(u.Contains(xid));
+ }
+ }
+ for (int k = 0; k < u.num_cells(); ++k) {
+ EXPECT_TRUE(xcells.Contains(u.cell_id(k)));
+ EXPECT_TRUE(yid.contains(u.cell_id(k)));
+ }
+ x_and_y.insert(x_and_y.end(), u.cell_ids().begin(), u.cell_ids().end());
+ }
+ x_and_y_expected.Init(x_and_y);
+
+ S2CellUnion x_and_y_cells;
+ x_and_y_cells.GetIntersection(&xcells, &ycells);
+ EXPECT_TRUE(x_and_y_cells == x_and_y_expected);
+
+ S2CellUnion x_minus_y_cells, y_minus_x_cells;
+ x_minus_y_cells.GetDifference(&xcells, &ycells);
+ y_minus_x_cells.GetDifference(&ycells, &xcells);
+ EXPECT_TRUE(xcells.Contains(&x_minus_y_cells));
+ EXPECT_TRUE(!x_minus_y_cells.Intersects(&ycells));
+ EXPECT_TRUE(ycells.Contains(&y_minus_x_cells));
+ EXPECT_TRUE(!y_minus_x_cells.Intersects(&xcells));
+ EXPECT_TRUE(!x_minus_y_cells.Intersects(&y_minus_x_cells));
+ S2CellUnion diff_union;
+ diff_union.GetUnion(&x_minus_y_cells, &y_minus_x_cells);
+ S2CellUnion diff_intersection_union;
+ diff_intersection_union.GetUnion(&diff_union, &x_and_y_cells);
+ EXPECT_TRUE(diff_intersection_union == x_or_y_cells);
+
+ vector<S2CellId> test, dummy;
+ AddCells(S2CellId::None(), false, &test, &dummy);
+ for (int j = 0; j < test.size(); ++j) {
+ bool contains = false, intersects = false;
+ for (int k = 0; k < expected.size(); ++k) {
+ if (expected[k].contains(test[j])) contains = true;
+ if (expected[k].intersects(test[j])) intersects = true;
+ }
+ EXPECT_EQ(contains, cellunion.Contains(test[j]));
+ EXPECT_EQ(intersects, cellunion.Intersects(test[j]));
+ }
+
+ }
+ printf("avg in %.2f, avg out %.2f\n", in_sum / kIters, out_sum / kIters);
+}
+
+static double GetMaxAngle(S2CellUnion const& covering, S2Point const& axis) {
+ double max_angle = 0;
+ for (int i = 0; i < covering.num_cells(); ++i) {
+ S2Cell cell(covering.cell_id(i));
+ S2Cap cell_cap = cell.GetCapBound();
+ double angle = axis.Angle(cell_cap.axis()) + cell_cap.angle().radians();
+ max_angle = max(max_angle, angle);
+ }
+ return max_angle;
+}
+
+TEST(S2CellUnion, Expand) {
+ // This test generates coverings for caps of random sizes, and expands
+ // the coverings by a random radius, and then make sure that the new
+ // covering covers the expanded cap. It also makes sure that the
+ // new covering is not too much larger than expected.
+
+ S2RegionCoverer coverer;
+ for (int i = 0; i < 1000; ++i) {
+ S2Cap cap = S2Testing::GetRandomCap(
+ S2Cell::AverageArea(S2CellId::kMaxLevel), 4 * M_PI);
+
+ // Expand the cap by a random factor whose log is uniformly distributed
+ // between 0 and log(1e2).
+ S2Cap expanded_cap = S2Cap::FromAxisHeight(
+ cap.axis(), min(2.0, pow(1e2, rnd.RandDouble()) * cap.height()));
+
+ double radius = expanded_cap.angle().radians() - cap.angle().radians();
+ int max_level_diff = rnd.Uniform(8);
+
+ S2CellUnion covering;
+ coverer.set_max_cells(1 + rnd.Skewed(10));
+ coverer.GetCellUnion(cap, &covering);
+ S2Testing::CheckCovering(cap, covering, true);
+
+ double max_angle = GetMaxAngle(covering, cap.axis());
+ int min_level = S2CellId::kMaxLevel;
+ for (int i = 0; i < covering.num_cells(); ++i) {
+ min_level = min(min_level, covering.cell_id(i).level());
+ }
+ covering.Expand(S1Angle::Radians(radius), max_level_diff);
+ S2Testing::CheckCovering(expanded_cap, covering, false);
+
+ int expand_level = min(min_level + max_level_diff,
+ S2::kMinWidth.GetMaxLevel(radius));
+ double expanded_max_angle = GetMaxAngle(covering, cap.axis());
+
+ // If the covering includes a tiny cell along the boundary, in theory the
+ // maximum angle of the covering from the cap axis can increase by up to
+ // twice the maximum length of a cell diagonal. We allow for an increase
+ // of slightly more than this because cell bounding caps are not exact.
+ EXPECT_LE(expanded_max_angle - max_angle,
+ 2.02 * S2::kMaxDiag.GetValue(expand_level));
+ // TODO(user): This fails for some random seeds,
+ // e.g. initialize the random seed to 3 in s2testing.cc. This
+ // means the assumption above is incorrect and needs to be
+ // revisited.
+ }
+}
+
+static void TestInitFromRange(S2CellId const& min_id,
+ S2CellId const& max_id) {
+ S2CellUnion cell_union;
+ cell_union.InitFromRange(min_id, max_id);
+ vector<S2CellId> const& cell_ids = cell_union.cell_ids();
+
+ EXPECT_GT(cell_ids.size(), 0);
+ EXPECT_EQ(min_id, cell_ids.front().range_min());
+ EXPECT_EQ(max_id, cell_ids.back().range_max());
+ for (int i = 1; i < cell_ids.size(); ++i) {
+ EXPECT_EQ(cell_ids[i].range_min(), cell_ids[i-1].range_max().next());
+ }
+ EXPECT_FALSE(cell_union.Normalize());
+}
+
+TEST(S2CellUnion, InitFromRange) {
+ // Check the very first leaf cell and face cell.
+ S2CellId face1_id = S2CellId::FromFacePosLevel(0, 0, 0);
+ TestInitFromRange(face1_id.range_min(), face1_id.range_min());
+ TestInitFromRange(face1_id.range_min(), face1_id.range_max());
+
+ // Check the very last leaf cell and face cell.
+ S2CellId face5_id = S2CellId::FromFacePosLevel(5, 0, 0);
+ TestInitFromRange(face1_id.range_min(), face1_id.range_max());
+ TestInitFromRange(face1_id.range_max(), face1_id.range_max());
+
+ // Check random ranges of leaf cells.
+ for (int i = 0; i < 100; ++i) {
+ S2CellId x = S2Testing::GetRandomCellId(S2CellId::kMaxLevel);
+ S2CellId y = S2Testing::GetRandomCellId(S2CellId::kMaxLevel);
+ if (x > y) swap(x, y);
+ TestInitFromRange(x, y);
+ }
+}
+
+TEST(S2CellUnion, Empty) {
+ S2CellUnion empty_cell_union;
+ S2CellId face1_id = S2CellId::FromFacePosLevel(1, 0, 0);
+
+ // Normalize()
+ empty_cell_union.Normalize();
+ EXPECT_EQ(0, empty_cell_union.num_cells());
+
+ // Denormalize(...)
+ vector<S2CellId> output;
+ empty_cell_union.Denormalize(0, 2, &output);
+ EXPECT_EQ(0, empty_cell_union.num_cells());
+
+ // Pack(...)
+ empty_cell_union.Pack();
+
+ // Contains(...)
+ EXPECT_FALSE(empty_cell_union.Contains(face1_id));
+ EXPECT_TRUE(empty_cell_union.Contains(&empty_cell_union));
+
+ // Intersects(...)
+ EXPECT_FALSE(empty_cell_union.Intersects(face1_id));
+ EXPECT_FALSE(empty_cell_union.Intersects(&empty_cell_union));
+
+ // GetUnion(...)
+ S2CellUnion cell_union;
+ cell_union.GetUnion(&empty_cell_union, &empty_cell_union);
+ EXPECT_EQ(0, cell_union.num_cells());
+
+ // GetIntersection(...)
+ S2CellUnion intersection;
+ intersection.GetIntersection(&empty_cell_union, face1_id);
+ EXPECT_EQ(0, intersection.num_cells());
+ intersection.GetIntersection(&empty_cell_union, &empty_cell_union);
+ EXPECT_EQ(0, intersection.num_cells());
+
+ // GetDifference(...)
+ S2CellUnion difference;
+ difference.GetDifference(&empty_cell_union, &empty_cell_union);
+ EXPECT_EQ(0, difference.num_cells());
+
+ // Expand(...)
+ empty_cell_union.Expand(S1Angle::Radians(1), 20);
+ EXPECT_EQ(0, empty_cell_union.num_cells());
+ empty_cell_union.Expand(10);
+ EXPECT_EQ(0, empty_cell_union.num_cells());
+}
+
+TEST(S2CellUnion, Detach) {
+ S2CellId face1_id = S2CellId::FromFacePosLevel(1, 0, 0);
+ S2CellUnion face1_union;
+ vector<S2CellId> ids;
+ ids.push_back(face1_id);
+ face1_union.Init(ids);
+ ASSERT_EQ(1, face1_union.num_cells());
+ EXPECT_EQ(face1_id, face1_union.cell_id(0));
+
+ vector<S2CellId> retrieve;
+ retrieve.push_back(S2CellId::Sentinel());
+ face1_union.Detach(&retrieve);
+ ASSERT_EQ(1, retrieve.size());
+ EXPECT_EQ(face1_id, retrieve[0]);
+ EXPECT_EQ(0, face1_union.num_cells());
+}
+
+TEST(S2CellUnion, LeafCellsCovered) {
+ S2CellUnion cell_union;
+
+ // empty union
+ EXPECT_EQ(0, cell_union.LeafCellsCovered());
+
+
+ vector<S2CellId> ids;
+ ids.push_back(S2CellId::FromFacePosLevel(
+ 0, (1ULL << ((S2CellId::kMaxLevel << 1) - 1)), S2CellId::kMaxLevel));
+ // One leaf on face 0.
+ cell_union.Init(ids);
+ EXPECT_EQ(1ULL, cell_union.LeafCellsCovered());
+
+ // Face 0.
+ ids.push_back(S2CellId::FromFacePosLevel(0, 0, 0));
+ cell_union.Init(ids);
+ EXPECT_EQ(1ULL << 60, cell_union.LeafCellsCovered());
+ // Five faces.
+ cell_union.Expand(0);
+ EXPECT_EQ(5ULL << 60, cell_union.LeafCellsCovered());
+ // Whole world.
+ cell_union.Expand(0);
+ EXPECT_EQ(6ULL << 60, cell_union.LeafCellsCovered());
+
+ // Add some disjoint cells.
+ ids.push_back(S2CellId::FromFacePosLevel(1, 0, 1));
+ ids.push_back(S2CellId::FromFacePosLevel(2, 0, 2));
+ ids.push_back(S2CellId::FromFacePosLevel(2, (1ULL << 60), 2));
+ ids.push_back(S2CellId::FromFacePosLevel(3, 0, 14));
+ ids.push_back(S2CellId::FromFacePosLevel(4, (1ULL << 60), 15));
+ ids.push_back(S2CellId::FromFacePosLevel(4, 0, 27));
+ ids.push_back(S2CellId::FromFacePosLevel(5, 0, 30));
+ cell_union.Init(ids);
+ uint64 expected = 1ULL + (1ULL << 6) + (1ULL << 30) + (1ULL << 32) +
+ (2ULL << 56) + (1ULL << 58) + (1ULL << 60);
+ EXPECT_EQ(expected, cell_union.LeafCellsCovered());
+}
diff --git a/src/third_party/s2/s2edgeindex.cc b/src/third_party/s2/s2edgeindex.cc
new file mode 100644
index 00000000000..27c241f96c5
--- /dev/null
+++ b/src/third_party/s2/s2edgeindex.cc
@@ -0,0 +1,450 @@
+// Copyright 2009 Google Inc. All Rights Reserved.
+// julienbasch@google.com (Julien Basch)
+
+// Implementation of class S2EdgeIndex, a fast lookup structure for edges in S2.
+//
+// An object of this class contains a set S of edges called the test edges.
+// For a query edge q, you want to compute a superset of all test edges that
+// intersect q.
+//
+// The idea is roughly that of
+// Each edge is covered by one or several S2 cells, stored in a multimap
+// cell -> edge*.
+// To perform a query, you cover the query edge with a set of cells. For
+// each such cell c, you find all test edges that are in c,in an ancestor of c
+// or in a child of c.
+//
+// This is simple, but there are two complications:
+//
+// 1. For containment queries, the query edge is very long (from S2::Origin()
+// to the query point). A standard cell covering of q is either useless or
+// too large. The covering needs to be adapted to S: if a cell contains too
+// many edges from S, you subdivide it and keep only the subcells that
+// intersect q. See comments for FindCandidateCrossings().
+//
+// 2. To decide if edge q could possibly cross edge e, we end up comparing
+// both with edges that bound s2 cells. Numerical inaccuracies
+// can lead to inconcistencies, e.g.: there may be an edge b at the
+// boundary of two cells such that q and e are on opposite sides of b,
+// yet they cross each other. This special case happens a lot if your
+// test and query edges are cell boundaries themselves, and this in turn
+// is a common case when regions are approximated by cell unions.
+//
+// We expand here on the solution to the second problem. Two components:
+//
+// 1. Each test edge is thickened to a rectangle before it is S2-covered.
+// See the comment for GetThickenedEdgeCovering().
+//
+// 2. When recursing through the children of a cell c for a query edge q,
+// we test q against the boundaries of c's children in a 'lenient'
+// way. That is, instead of testing e.g. area(abc)*area(abd) < 0,
+// we check if it is 'approximately negative'.
+//
+// To see how the second point is necessary, imagine that your query
+// edge q is the North boundary of cell x. We recurse into the four
+// children a,b,c,d of x. To do so, we check if q crosses or touches any
+// of a,b,c or d boundaries. As all the situations are degenerate, it is
+// possible that all crossing tests return false, thus making q suddenly
+// 'disappear'. Using the lenient crossing test, we are guaranteed that q
+// will intersect one of the four edges of the cross that bounds a,b,c,d.
+// The same holds true if q passes through the cell center of x.
+
+
+
+#include "s2edgeindex.h"
+
+#include <algorithm>
+using std::min;
+using std::max;
+using std::swap;
+using std::reverse;
+
+#include <set>
+using std::set;
+using std::multiset;
+
+#include <utility>
+using std::pair;
+using std::make_pair;
+
+
+#include "base/commandlineflags.h"
+#include "base/logging.h"
+#include "s2cell.h"
+#include "s2edgeutil.h"
+#include "s2polyline.h"
+#include "s2regioncoverer.h"
+
+
+DEFINE_bool(always_recurse_on_children, false,
+ "When we test a query edge against a cell, we don't "
+ "recurse if there are only a few test edges in it. "
+ "For testing, it is useful to always recurse to the end. "
+ "You don't want to use this flag anywhere but in tests.");
+
+void S2EdgeIndex::Reset() {
+ minimum_s2_level_used_ = S2CellId::kMaxLevel;
+ index_computed_ = false;
+ query_count_ = 0;
+ mapping_.clear();
+}
+
+void S2EdgeIndex::ComputeIndex() {
+ DCHECK(!index_computed_);
+
+ for (int i = 0; i < num_edges(); ++i) {
+ S2Point from, to;
+ vector<S2CellId> cover;
+ int level = GetCovering(*edge_from(i), *edge_to(i),
+ true, &cover);
+ minimum_s2_level_used_ = min(minimum_s2_level_used_, level);
+
+ for (vector<S2CellId>::const_iterator it = cover.begin(); it != cover.end();
+ ++it) {
+ mapping_.insert(make_pair(*it, i));
+ }
+ }
+ index_computed_ = true;
+}
+
+bool S2EdgeIndex::IsIndexComputed() const {
+ return index_computed_;
+}
+
+void S2EdgeIndex::IncrementQueryCount() {
+ query_count_++;
+}
+
+
+// If we have m data edges and n query edges, then the brute force cost is
+// m * n * test_cost
+// where test_cost is taken to be the cost of EdgeCrosser::RobustCrossing,
+// measured to be about 30ns at the time of this writing.
+//
+// If we compute the index, the cost becomes:
+// m * cost_insert + n * cost_find(m)
+//
+// - cost_insert can be expected to be reasonably stable, and was measured
+// at 1200ns with the BM_QuadEdgeInsertionCost benchmark.
+//
+// - cost_find depends on the length of the edge . For m=1000 edges,
+// we got timings ranging from 1ms (edge the length of the polygon) to
+// 40ms. The latter is for very long query edges, and needs to be
+// optimized. We will assume for the rest of the discussion that
+// cost_find is roughly 3ms.
+//
+// When doing one additional query, the differential cost is
+// m * test_cost - cost_find(m)
+// With the numbers above, it is better to use the quad tree (if we have it)
+// if m >= 100.
+//
+// If m = 100, 30 queries will give m*n*test_cost = m*cost_insert = 100ms,
+// while the marginal cost to find is 3ms. Thus, this is a reasonable
+// thing to do.
+void S2EdgeIndex::PredictAdditionalCalls(int n) {
+ if (index_computed_) return;
+ if (num_edges() > 100 && (query_count_ + n) > 30) {
+ ComputeIndex();
+ }
+}
+
+void S2EdgeIndex::GetEdgesInParentCells(
+ const vector<S2CellId>& cover,
+ const CellEdgeMultimap& mapping,
+ int minimum_s2_level_used,
+ vector<int>* candidate_crossings) {
+ // Find all parent cells of covering cells.
+ set<S2CellId> parent_cells;
+ for (vector<S2CellId>::const_iterator it = cover.begin(); it != cover.end();
+ ++it) {
+ for (int parent_level = it->level() - 1;
+ parent_level >= minimum_s2_level_used;
+ --parent_level) {
+ if (!parent_cells.insert(it->parent(parent_level)).second) {
+ break; // cell is already in => parents are too.
+ }
+ }
+ }
+
+ // Put parent cell edge references into result.
+ for (set<S2CellId>::const_iterator it = parent_cells.begin(); it
+ != parent_cells.end(); ++it) {
+ pair<CellEdgeMultimap::const_iterator,
+ CellEdgeMultimap::const_iterator> range =
+ mapping.equal_range(*it);
+ for (CellEdgeMultimap::const_iterator it2 = range.first;
+ it2 != range.second; ++it2) {
+ candidate_crossings->push_back(it2->second);
+ }
+ }
+}
+
+// Returns true if ab possibly crosses cd, by clipping tiny angles to
+// zero.
+static bool LenientCrossing(S2Point const& a, S2Point const& b,
+ S2Point const& c, S2Point const& d) {
+ DCHECK(S2::IsUnitLength(a));
+ DCHECK(S2::IsUnitLength(b));
+ DCHECK(S2::IsUnitLength(c));
+ // See comment for RobustCCW() in s2.h
+ const double kMaxDetError = 1.e-14;
+ double acb = a.CrossProd(c).DotProd(b);
+ double bda = b.CrossProd(d).DotProd(a);
+ if (fabs(acb) < kMaxDetError || fabs(bda) < kMaxDetError) {
+ return true;
+ }
+ if (acb * bda < 0) return false;
+ double cbd = c.CrossProd(b).DotProd(d);
+ double dac = d.CrossProd(a).DotProd(c);
+ if (fabs(cbd) < kMaxDetError || fabs(dac) < kMaxDetError) {
+ return true;
+ }
+ return (acb * cbd >= 0) && (acb * dac >= 0);
+}
+
+bool S2EdgeIndex::EdgeIntersectsCellBoundary(
+ S2Point const& a, S2Point const& b, const S2Cell& cell) {
+ //S2Point start_vertex = cell.GetVertex(0);
+
+ S2Point vertices[4];
+ for (int i = 0; i < 4; ++i) {
+ vertices[i] = cell.GetVertex(i);
+ }
+ for (int i = 0; i < 4; ++i) {
+ S2Point from_point = vertices[i];
+ S2Point to_point = vertices[(i+1) % 4];
+ if (LenientCrossing(a, b, from_point, to_point)) {
+ return true;
+ }
+ }
+ return false;
+}
+
+void S2EdgeIndex::GetEdgesInChildrenCells(
+ S2Point const& a, S2Point const& b,
+ vector<S2CellId>* cover,
+ const CellEdgeMultimap& mapping,
+ vector<int>* candidate_crossings) {
+ CellEdgeMultimap::const_iterator it, start, end;
+
+ int num_cells = 0;
+
+ // Put all edge references of (covering cells + descendant cells) into result.
+ // This relies on the natural ordering of S2CellIds.
+ while (!cover->empty()) {
+ S2CellId cell = cover->back();
+ cover->pop_back();
+ num_cells++;
+ start = mapping.lower_bound(cell.range_min());
+ end = mapping.upper_bound(cell.range_max());
+ int num_edges = 0;
+ bool rewind = FLAGS_always_recurse_on_children;
+ // TODO(user): Maybe distinguish between edges in current cell, that
+ // are going to be added anyhow, and edges in subcells, and rewind only
+ // those.
+ if (!rewind) {
+ for (it = start; it != end; ++it) {
+ candidate_crossings->push_back(it->second);
+ ++num_edges;
+ if (num_edges == 16 && !cell.is_leaf()) {
+ rewind = true;
+ break;
+ }
+ }
+ }
+ // If there are too many to insert, uninsert and recurse.
+ if (rewind) {
+ for (int i = 0; i < num_edges; ++i) {
+ candidate_crossings->pop_back();
+ }
+ // Add cells at this level
+ pair<CellEdgeMultimap::const_iterator,
+ CellEdgeMultimap::const_iterator> eq =
+ mapping.equal_range(cell);
+ for (it = eq.first; it != eq.second; ++it) {
+ candidate_crossings->push_back(it->second);
+ }
+ // Recurse on the children -- hopefully some will be empty.
+ if (eq.first != start || eq.second != end) {
+ S2Cell children[4];
+ S2Cell c(cell);
+ c.Subdivide(children);
+ for (int i = 0; i < 4; ++i) {
+ // TODO(user): Do the check for the four cells at once,
+ // as it is enough to check the four edges between the cells. At
+ // this time, we are checking 16 edges, 4 times too many.
+ //
+ // Note that given the guarantee of AppendCovering, it is enough
+ // to check that the edge intersect with the cell boundary as it
+ // cannot be fully contained in a cell.
+ if (EdgeIntersectsCellBoundary(a, b, children[i])) {
+ cover->push_back(children[i].id());
+ }
+ }
+ }
+ }
+ }
+ VLOG(1) << "Num cells traversed: " << num_cells;
+}
+
+// Appends to "candidate_crossings" all edge references which may cross the
+// given edge. This is done by covering the edge and then finding all
+// references of edges whose coverings overlap this covering. Parent cells
+// are checked level by level. Child cells are checked all at once by taking
+// advantage of the natural ordering of S2CellIds.
+void S2EdgeIndex::FindCandidateCrossings(
+ S2Point const& a, S2Point const& b,
+ vector<int>* candidate_crossings) const {
+ DCHECK(index_computed_);
+ vector<S2CellId> cover;
+ GetCovering(a, b, false, &cover);
+ GetEdgesInParentCells(cover, mapping_, minimum_s2_level_used_,
+ candidate_crossings);
+
+ // TODO(user): An important optimization for long query
+ // edges (Contains queries): keep a bounding cap and clip the query
+ // edge to the cap before starting the descent.
+ GetEdgesInChildrenCells(a, b, &cover, mapping_, candidate_crossings);
+
+ // Remove duplicates: This is necessary because edge references are
+ // inserted into the map once for each covering cell. (Testing shows
+ // this to be at least as fast as using a set.)
+ sort(candidate_crossings->begin(), candidate_crossings->end());
+ candidate_crossings->erase(
+ unique(candidate_crossings->begin(), candidate_crossings->end()),
+ candidate_crossings->end());
+}
+
+
+// Returns the smallest cell containing all four points, or Sentinel
+// if they are not all on the same face.
+// The points don't need to be normalized.
+static S2CellId ContainingCell(S2Point const& pa, S2Point const& pb,
+ S2Point const& pc, S2Point const& pd) {
+ S2CellId a = S2CellId::FromPoint(pa);
+ S2CellId b = S2CellId::FromPoint(pb);
+ S2CellId c = S2CellId::FromPoint(pc);
+ S2CellId d = S2CellId::FromPoint(pd);
+
+ if (a.face() != b.face() || a.face() != c.face() || a.face() != d.face()) {
+ return S2CellId::Sentinel();
+ }
+
+ while (a != b || a != c || a != d) {
+ a = a.parent();
+ b = b.parent();
+ c = c.parent();
+ d = d.parent();
+ }
+ return a;
+}
+
+// Returns the smallest cell containing both points, or Sentinel
+// if they are not all on the same face.
+// The points don't need to be normalized.
+static S2CellId ContainingCell(S2Point const& pa, S2Point const& pb) {
+ S2CellId a = S2CellId::FromPoint(pa);
+ S2CellId b = S2CellId::FromPoint(pb);
+
+ if (a.face() != b.face()) return S2CellId::Sentinel();
+
+ while (a != b) {
+ a = a.parent();
+ b = b.parent();
+ }
+ return a;
+}
+
+int S2EdgeIndex::GetCovering(
+ S2Point const& a, S2Point const& b,
+ bool thicken_edge,
+ vector<S2CellId>* edge_covering) const {
+ edge_covering->clear();
+
+ // Thicken the edge in all directions by roughly 1% of the edge length when
+ // thicken_edge is true.
+ static const double kThickening = 0.01;
+
+ // Selects the ideal s2 level at which to cover the edge, this will be the
+ // level whose S2 cells have a width roughly commensurate to the length of
+ // the edge. We multiply the edge length by 2*kThickening to guarantee the
+ // thickening is honored (it's not a big deal if we honor it when we don't
+ // request it) when doing the covering-by-cap trick.
+ const double edge_length = a.Angle(b);
+ const int ideal_level = S2::kMinWidth.GetMaxLevel(
+ edge_length * (1 + 2 * kThickening));
+
+ S2CellId containing_cell;
+ if (!thicken_edge) {
+ containing_cell = ContainingCell(a, b);
+ } else {
+ if (ideal_level == S2CellId::kMaxLevel) {
+ // If the edge is tiny, instabilities are more likely, so we
+ // want to limit the number of operations.
+ // We pretend we are in a cell much larger so as to trigger the
+ // 'needs covering' case, so we won't try to thicken the edge.
+ containing_cell = S2CellId(0xFFF0).parent(3);
+ } else {
+ S2Point pq = (b - a) * kThickening;
+ S2Point ortho = pq.CrossProd(a).Normalize() *
+ edge_length * kThickening;
+ S2Point p = a - pq;
+ S2Point q = b + pq;
+ // If p and q were antipodal, the edge wouldn't be lengthened,
+ // and it could even flip! This is not a problem because
+ // ideal_level != 0 here. The farther p and q can be is roughly
+ // a quarter Earth away from each other, so we remain
+ // Theta(kThickening).
+ containing_cell = ContainingCell(p - ortho, p + ortho,
+ q - ortho, q + ortho);
+ }
+ }
+
+ // Best case: edge is fully contained in a cell that's not too big.
+ if (containing_cell != S2CellId::Sentinel() &&
+ containing_cell.level() >= ideal_level - 2) {
+ edge_covering->push_back(containing_cell);
+ return containing_cell.level();
+ }
+
+ if (ideal_level == 0) {
+ // Edge is very long, maybe even longer than a face width, so the
+ // trick below doesn't work. For now, we will add the whole S2 sphere.
+ // TODO(user): Do something a tad smarter (and beware of the
+ // antipodal case).
+ for (S2CellId cellid = S2CellId::Begin(0); cellid != S2CellId::End(0);
+ cellid = cellid.next()) {
+ edge_covering->push_back(cellid);
+ }
+ return 0;
+ }
+ // TODO(user): Check trick below works even when vertex is at interface
+ // between three faces.
+
+ // Use trick as in S2PolygonBuilder::PointIndex::FindNearbyPoint:
+ // Cover the edge by a cap centered at the edge midpoint, then cover
+ // the cap by four big-enough cells around the cell vertex closest to the
+ // cap center.
+ S2Point middle = ((a + b) / 2.0).Normalize();
+ int actual_level = min(ideal_level, S2CellId::kMaxLevel-1);
+ S2CellId::FromPoint(middle).AppendVertexNeighbors(
+ actual_level, edge_covering);
+ return actual_level;
+}
+
+void S2EdgeIndex::Iterator::GetCandidates(S2Point const& a, S2Point const& b) {
+ edge_index_->PredictAdditionalCalls(1);
+ is_brute_force_ = !edge_index_->IsIndexComputed();
+ if (is_brute_force_) {
+ edge_index_->IncrementQueryCount();
+ current_index_ = 0;
+ num_edges_ = edge_index_->num_edges();
+ } else {
+ candidates_.clear();
+ edge_index_->FindCandidateCrossings(a, b, &candidates_);
+ current_index_in_candidates_ = 0;
+ if (!candidates_.empty()) {
+ current_index_ = candidates_[0];
+ }
+ }
+}
diff --git a/src/third_party/s2/s2edgeindex.h b/src/third_party/s2/s2edgeindex.h
new file mode 100644
index 00000000000..e9b9e966eca
--- /dev/null
+++ b/src/third_party/s2/s2edgeindex.h
@@ -0,0 +1,258 @@
+// Copyright 2009 Google Inc. All Rights Reserved.
+
+// Defines the class S2EdgeIndex, a fast lookup structure for edges in S2.
+
+#ifndef UTIL_GEOMETRY_S2EDGEINDEX_H_
+#define UTIL_GEOMETRY_S2EDGEINDEX_H_
+
+#include <map>
+using std::map;
+using std::multimap;
+
+#include <utility>
+using std::pair;
+using std::make_pair;
+
+#include <vector>
+using std::vector;
+
+
+#include "base/logging.h"
+#include "base/macros.h"
+#include "s2cellid.h"
+#include "s2edgeutil.h"
+
+class S2Cell;
+
+// This class structures a set S of data edges, so that one can quickly
+// find which edges of S may potentially intersect or touch a query edge.
+//
+// The set S is assumed to be indexable by a consecutive sequence of
+// integers in the range [0..num_edges()-1]. You subclass this class by
+// defining the three virtual functions num_edges(), edge_from(),
+// edge_to(). Then you use it as follows for a query edge (a,b):
+//
+// MyS2EdgeIndex edge_index;
+// MyS2EdgeIndex::Iterator it(&edge_index);
+// S2Point const* from;
+// S2Point const* to;
+// for (it.GetCandidates(a, b); !it.Done(); it.Next()) {
+// edge_index.GetEdge(it.Index(), &from, &to);
+// ... RobustCrossing(a,b, from,to) ...
+// }
+//
+// What is this GetEdge()? You don't want to use edge_from() and
+// edge_to() in your own code: these are virtual functions that will
+// add a lot of overhead. The most efficient way is as above: you
+// define GetEdge() in your S2EdgeIndex subclass that access the edge
+// points as efficiently as possible.
+//
+// The function GetCandidates initializes the iterator to return a set
+// of candidate edges from S, such that we are sure that any data edge
+// that touches or crosses (a,b) is a candidate.
+//
+// This class returns all edges until it finds that it is worth it to compute
+// a quad tree on the data set. Chance my have it that you compute the quad
+// tree exactly when it's too late and all the work is done, If this happens,
+// we only double the total running time.
+//
+// You can help the class by declaring in advance that you will make a
+// certain number of calls to GetCandidates():
+// MyS2EdgeIndex::Iterator it(&edge_index)
+// edge_index.PredictAdditionalCalls(n);
+// for (int i = 0; i < n; ++i) {
+// for (it.GetCandidates(v(i), v(i+1)); !it.Done(); it.Next()) {
+// ... RobustCrossing(v(i), v(i+1), it.From(), it.To()) ...
+// }
+// }
+//
+// Here, we say that we will call GetCandidates() n times. If we have
+// 1000 data edges and n=1000, then we will compute the quad tree
+// immediately instead of waiting till we've wasted enough time to
+// justify the cost.
+//
+// The tradeoff between brute force and quad tree depends on many
+// things, we use a very approximate trade-off.
+//
+// See examples in S2Loop.cc and S2Polygon.cc, in particular, look at
+// the optimization that allows one to use the EdgeCrosser.
+//
+// TODO(user): Get a better API without the clumsy GetCandidates().
+// Maybe edge_index.GetIterator()?
+class S2EdgeIndex {
+ public:
+ S2EdgeIndex() { Reset(); }
+
+ virtual ~S2EdgeIndex() { }
+
+ // An iterator on data edges that may cross a query edge (a,b).
+ // Create the iterator, call GetCandidates(), then Done()/Next()
+ // repeatedly.
+ //
+ // The current edge in the iteration has index Index(), goes between
+ // From() and To().
+ class Iterator {
+ public:
+ explicit Iterator(S2EdgeIndex* edge_index): edge_index_(edge_index) {}
+
+ // Initializes the iterator to iterate over a set of candidates that may
+ // cross the edge (a,b).
+ void GetCandidates(S2Point const& a, S2Point const& b);
+
+ // Index of the current edge in the iteration.
+ int Index() const;
+
+ // True if there is no more candidate.
+ bool Done() const;
+
+ // Iterate to the next available candidate.
+ void Next();
+
+ private:
+ // The structure containing the data edges.
+ S2EdgeIndex* edge_index_;
+
+ // Tells whether GetCandidates() obtained the candidates through brute
+ // force iteration or using the quad tree structure.
+ bool is_brute_force_;
+
+ // Index of the current edge and of the edge before the last Next() call.
+ int current_index_;
+
+ // Cache of edge_index_->num_edges() so that Done() doesn't call a virtual
+ int num_edges_;
+
+ // All the candidates obtained by GetCandidates() when we are
+ // using a quad-tree (i.e. is_brute_force = false).
+ vector<int> candidates_;
+
+ // Index within array above.
+ // We have: current_index_ = candidates_[current_index_in_candidates_].
+ int current_index_in_candidates_;
+
+ DISALLOW_COPY_AND_ASSIGN(Iterator);
+ };
+
+ // Empties the index in case it already contained something.
+ void Reset();
+
+ // Computes the index if not yet done and tells if the index has
+ // been computed.
+ void ComputeIndex();
+ bool IsIndexComputed() const;
+
+ // If the index hasn't been computed yet, looks at how much work has
+ // gone into iterating using the brute force method, and how much
+ // more work is planned as defined by 'cost'. If it were to have been
+ // cheaper to use a quad tree from the beginning, then compute it
+ // now. This guarantees that we will never use more than twice the
+ // time we would have used had we known in advance exactly how many
+ // edges we would have wanted to test. It is the theoretical best.
+ //
+ // The value 'n' is the number of iterators we expect to request from
+ // this edge index.
+ void PredictAdditionalCalls(int n);
+
+ // Overwrite these functions to give access to the underlying data.
+ // The function num_edges() returns the number of edges in the
+ // index, while edge_from(index) and edge_to(index) return the
+ // "from" and "to" endpoints of the edge at the given index.
+ virtual int num_edges() const = 0;
+ virtual S2Point const* edge_from(int index) const = 0;
+ virtual S2Point const* edge_to(int index) const = 0;
+
+ protected:
+ // Appends to result all edge references in the map that cross the
+ // query edge, and possibly some more.
+ void FindCandidateCrossings(S2Point const& a, S2Point const& b,
+ vector<int>* result) const;
+
+ // Tell the index that we just received a new request for candidates.
+ // Useful to compute when to switch to quad tree.
+ void IncrementQueryCount();
+
+ private:
+ typedef multimap<S2CellId, int> CellEdgeMultimap;
+
+ // Inserts the given directed edge into the quad tree.
+ void Insert(S2Point const& a, S2Point const& b, int reference);
+
+ // Computes a cell covering of an edge. Returns the level of the s2 cells
+ // used in the covering (only one level is ever used for each call).
+ //
+ // If thicken_edge is true, the edge is thickened and extended
+ // by 1% of its length.
+ //
+ // It is guaranteed that no child of a covering cell will fully contain
+ // the covered edge.
+ int GetCovering(S2Point const& a, S2Point const& b,
+ bool thicken_edge,
+ vector<S2CellId>* result) const;
+
+ // Adds to candidate_crossings all the edges present in any ancestor of any
+ // cell of cover, down to minimum_s2_level_used. The cell->edge map
+ // is in the variable mapping.
+ static void GetEdgesInParentCells(
+ const vector<S2CellId>& cover,
+ const CellEdgeMultimap& mapping,
+ int minimum_s2_level_used,
+ vector<int>* candidate_crossings);
+
+ // Returns true if the edge and the cell (including boundary) intersect.
+ static bool EdgeIntersectsCellBoundary(
+ S2Point const& a, S2Point const& b,
+ const S2Cell& cell);
+
+ // Appends to candidate_crossings the edges that are fully contained in an
+ // S2 covering of edge. The covering of edge used is initially cover, but
+ // is refined to eliminate quickly subcells that contain many edges but do
+ // not intersect with edge.
+ static void GetEdgesInChildrenCells(
+ S2Point const& a, S2Point const& b,
+ vector<S2CellId>* cover,
+ const CellEdgeMultimap& mapping,
+ vector<int>* candidate_crossings);
+
+ // Maps cell ids to covered edges; has the property that the set of all cell
+ // ids mapping to a particular edge forms a covering of that edge.
+ CellEdgeMultimap mapping_;
+
+ // No cell strictly below this level appears in mapping_. Initially leaf
+ // level, that's the minimum level at which we will ever look for test edges.
+ int minimum_s2_level_used_;
+
+ // Has the index been computed already?
+ bool index_computed_;
+
+ // Number of queries so far
+ int query_count_;
+
+ DISALLOW_COPY_AND_ASSIGN(S2EdgeIndex);
+};
+
+inline bool S2EdgeIndex::Iterator::Done() const {
+ if (is_brute_force_) {
+ return (current_index_ >= num_edges_);
+ } else {
+ return (size_t)current_index_in_candidates_ >= candidates_.size();
+ }
+}
+
+inline int S2EdgeIndex::Iterator::Index() const {
+ DCHECK(!Done());
+ return current_index_;
+}
+
+inline void S2EdgeIndex::Iterator::Next() {
+ DCHECK(!Done());
+ if (is_brute_force_) {
+ current_index_++;
+ } else {
+ current_index_in_candidates_++;
+ if ((size_t)current_index_in_candidates_ < candidates_.size()) {
+ current_index_ = candidates_[current_index_in_candidates_];
+ }
+ }
+}
+
+#endif // UTIL_GEOMETRY_S2EDGEINDEX_H_
diff --git a/src/third_party/s2/s2edgeindex_test.cc b/src/third_party/s2/s2edgeindex_test.cc
new file mode 100644
index 00000000000..9440cd224ac
--- /dev/null
+++ b/src/third_party/s2/s2edgeindex_test.cc
@@ -0,0 +1,388 @@
+// Copyright 2009 Google Inc. All Rights Reserved.
+
+#include "s2edgeindex.h"
+
+#include <set>
+using std::set;
+using std::multiset;
+
+#include <string>
+using std::string;
+
+#include <vector>
+using std::vector;
+
+
+#include "base/commandlineflags.h"
+#include "base/stringprintf.h"
+#include "base/logging.h"
+#include "testing/base/public/benchmark.h"
+#include "testing/base/public/gunit.h"
+#include "s2cap.h"
+#include "s2cell.h"
+#include "s2cellid.h"
+#include "s2edgeutil.h"
+#include "s2loop.h"
+#include "s2testing.h"
+#include "util/math/vector3-inl.h"
+#include "util/math/matrix3x3-inl.h"
+
+DECLARE_bool(always_recurse_on_children);
+
+typedef pair<S2Point, S2Point> S2Edge;
+
+static const double kEarthRadiusMeters = 6371000;
+
+
+
+// Generates a random edge whose center is in the given cap.
+static S2Edge RandomEdgeCrossingCap(double max_length_meters,
+ const S2Cap& cap) {
+ // Pick the edge center at random.
+ S2Point edge_center = S2Testing::SamplePoint(cap);
+ // Pick two random points in a suitably sized cap about the edge center.
+ S2Cap edge_cap = S2Cap::FromAxisAngle(
+ edge_center,
+ S1Angle::Radians(max_length_meters / kEarthRadiusMeters / 2));
+ S2Point p1 = S2Testing::SamplePoint(edge_cap);
+ S2Point p2 = S2Testing::SamplePoint(edge_cap);
+ return S2Edge(p1, p2);
+}
+
+// Generates "num_edges" random edges, of length at most
+// "edge_length_meters_max" and each of whose center is in a randomly located
+// cap with radius "cap_span_meters", and puts results into "edges".
+static void GenerateRandomEarthEdges(double edge_length_meters_max,
+ double cap_span_meters,
+ int num_edges,
+ vector<S2Edge>* edges) {
+ S2Cap cap = S2Cap::FromAxisAngle(
+ S2Testing::RandomPoint(),
+ S1Angle::Radians(cap_span_meters / kEarthRadiusMeters));
+ for (int i = 0; i < num_edges; ++i) {
+ edges->push_back(RandomEdgeCrossingCap(edge_length_meters_max, cap));
+ }
+}
+
+static string ToString(const S2Edge& e1, const S2Edge& e2) {
+ double u1, v1, u2, v2, u3, v3, u4, v4;
+ S2::XYZtoFaceUV(e1.first, &u1, &v1);
+ S2::XYZtoFaceUV(e1.second, &u2, &v2);
+ S2::XYZtoFaceUV(e2.first, &u3, &v3);
+ S2::XYZtoFaceUV(e2.second, &u4, &v4);
+ u2 = u2 - u1;
+ u3 = u3 - u1;
+ u4 = u4 - u1;
+ v2 = v2 - v1;
+ v3 = v3 - v1;
+ v4 = v4 - v1;
+ return StringPrintf("[%6.2f,%6.2f] 0,0 -> %3.3e,%3.3e) --"
+ " (%3.3e,%3.3e -> %3.3e %3.3e)",
+ u1, v1, u2, v2, u3, v3, u4, v4);
+}
+
+class EdgeVectorIndex: public S2EdgeIndex {
+ public:
+ explicit EdgeVectorIndex(vector<S2Edge> const* edges):
+ edges_(edges) {}
+
+ virtual int num_edges() const { return edges_->size(); }
+ virtual S2Point const* edge_from(int index) const {
+ return &((*edges_)[index].first);
+ }
+ virtual S2Point const* edge_to(int index) const {
+ return &((*edges_)[index].second);
+ }
+ private:
+ vector<S2Edge> const* edges_;
+};
+
+static void TestAllCrossings(vector<S2Edge> const& all_edges,
+ int min_crossings,
+ int max_checks_crossings_ratio) {
+ EdgeVectorIndex index(&all_edges);
+ index.ComputeIndex();
+ EdgeVectorIndex::Iterator it(&index);
+ double total_crossings = 0;
+ double total_index_checks = 0;
+
+ VLOG(1) << "start detailed checking\n";
+ for (int in = 0; in < all_edges.size(); ++in) {
+ S2Edge e = all_edges[in];
+
+ set<int> candidate_set;
+
+ for (it.GetCandidates(e.first, e.second); !it.Done(); it.Next()) {
+ candidate_set.insert(it.Index());
+ total_index_checks++;
+ }
+
+ for (int i = 0; i < all_edges.size(); ++i) {
+ int crossing = S2EdgeUtil::RobustCrossing(e.first, e.second,
+ all_edges[i].first,
+ all_edges[i].second);
+ if (crossing >= 0) {
+ EXPECT_EQ(1, candidate_set.count(i))
+ << "Edge " << i << " is not a candidate of edge " << in
+ << " (" << ToString(all_edges[i], e) << ")";
+ ++total_crossings;
+ }
+ }
+ }
+
+ VLOG(1) << "Pairs/num crossings/check crossing ratio: "
+ << all_edges.size() * all_edges.size() << "/"
+ << total_crossings << "/"
+ << total_index_checks / total_crossings;
+ EXPECT_LE(min_crossings, total_crossings);
+ EXPECT_GE(total_crossings * max_checks_crossings_ratio, total_index_checks);
+}
+
+
+// Generates random edges and tests, for each edge,
+// that all those that cross are candidates.
+static void TestCrossingsRandomInCap(int num_edges,
+ double edge_length_max,
+ double cap_span_meters,
+ int min_crossings,
+ int max_checks_crossings_ratio) {
+ vector<S2Edge> all_edges;
+ GenerateRandomEarthEdges(edge_length_max, cap_span_meters, num_edges,
+ &all_edges);
+ TestAllCrossings(all_edges, min_crossings, max_checks_crossings_ratio);
+}
+
+
+TEST(S2EdgeIndex, LoopCandidateOfItself) {
+ vector<S2Point> ps; // A diamond loop around 0,180.
+ ps.push_back(S2Testing::MakePoint("0:178"));
+ ps.push_back(S2Testing::MakePoint("-1:180"));
+ ps.push_back(S2Testing::MakePoint("0:-179"));
+ ps.push_back(S2Testing::MakePoint("1:-180"));
+ vector<S2Edge> all_edges;
+ for (int i = 0; i < 4; ++i) {
+ all_edges.push_back(make_pair(ps[i], ps[(i+1)%4]));
+ }
+ TestAllCrossings(all_edges, 0, 16);
+}
+
+TEST(S2EdgeIndex, RandomEdgeCrossings) {
+ TestCrossingsRandomInCap(2000, 30, 5000, 500, 2);
+ TestCrossingsRandomInCap(1000, 100, 5000, 500, 3);
+ TestCrossingsRandomInCap(1000, 1000, 5000, 1000, 40);
+ TestCrossingsRandomInCap(500, 5000, 5000, 5000, 20);
+}
+
+TEST(S2EdgeIndex, RandomEdgeCrossingsSparse) {
+ for (int i = 0; i < 5; ++i) {
+ TestCrossingsRandomInCap(2000, 100, 5000, 500, 8);
+ TestCrossingsRandomInCap(2000, 300, 50000, 1000, 10);
+ }
+}
+
+TEST(S2EdgeIndex, DegenerateEdgeOnCellVertexIsItsOwnCandidate) {
+ for (int i = 0; i < 100; ++i) {
+ S2Cell cell(S2Testing::GetRandomCellId());
+ S2Edge e = make_pair(cell.GetVertex(0), cell.GetVertex(0));
+ vector<S2Edge> all_edges;
+ all_edges.push_back(e);
+ EdgeVectorIndex index(&all_edges);
+ index.ComputeIndex();
+ EdgeVectorIndex::Iterator it(&index);
+ it.GetCandidates(e.first, e.second);
+ ASSERT_FALSE(it.Done());
+ it.Next();
+ ASSERT_TRUE(it.Done());
+ }
+}
+
+TEST(S2EdgeIndex, LongEdgeCrossesLoop) {
+ vector<S2Edge> all_edges;
+ S2Point loop_center = S2Testing::MakePoint("42:107");
+ pair<S2Point, S2Point> test_edge = make_pair(S2::Origin(), loop_center);
+
+ S2Loop* loop = S2Testing::MakeRegularLoop(loop_center, 4,
+ 7e-3); // = 5km/6400km
+ for (int i = 0; i < loop->num_vertices(); ++i) {
+ all_edges.push_back(make_pair(loop->vertex(i), loop->vertex(i+1)));
+ }
+ delete loop;
+ EdgeVectorIndex index(&all_edges);
+ index.ComputeIndex();
+ EdgeVectorIndex::Iterator it(&index);
+ it.GetCandidates(test_edge.first, test_edge.second);
+
+ ASSERT_FALSE(it.Done()); // At least one candidate
+}
+
+TEST(S2EdgeIndex, CollinearEdgesOnCellBoundaries) {
+ FLAGS_always_recurse_on_children = true;
+ const int kNumPointsOnEdge = 8; // About 32 edges
+ for (int level = 0; level <= S2CellId::kMaxLevel; ++level) {
+ S2Cell cell(S2Testing::GetRandomCellId(level));
+ int v1 = S2Testing::rnd.Uniform(4);
+ int v2 = (v1 + 1) & 3;
+ S2Point p1 = cell.GetVertex(v1);
+ S2Point p2 = cell.GetVertex(v2);
+ S2Point p2_p1 = (p2 - p1) / kNumPointsOnEdge;
+ vector<S2Edge> all_edges;
+ S2Point points[kNumPointsOnEdge+1];
+ for (int i = 0; i <= kNumPointsOnEdge; ++i) {
+ points[i] = (p1 + i * p2_p1).Normalize();
+ for (int j = 0; j < i; ++j) {
+ all_edges.push_back(make_pair(points[i], points[j]));
+ }
+ }
+ TestAllCrossings(all_edges, kNumPointsOnEdge*kNumPointsOnEdge,
+ kNumPointsOnEdge*kNumPointsOnEdge);
+ }
+}
+
+TEST(S2EdgeIndex, QuadTreeGetsComputedAutomatically) {
+ int const kNumVertices = 200;
+ S2Point loop_center = S2Testing::MakePoint("42:107");
+ S2Loop* loop = S2Testing::MakeRegularLoop(loop_center, kNumVertices,
+ 7e-3); // = 5km/6400km
+ S2Point q = S2Testing::MakePoint("5:5");
+
+ S2LoopIndex index(loop);
+ S2LoopIndex::Iterator it(&index);
+
+ int num_candidates = 0;
+ it.GetCandidates(q, q);
+ for (; !it.Done(); it.Next()) {
+ num_candidates++;
+ }
+ EXPECT_EQ(kNumVertices, num_candidates);
+
+ bool computed = false;
+ for (int i = 0; i < 500; ++i) { // Trigger the quad tree computation
+ num_candidates = 0;
+ for (it.GetCandidates(q, q); !it.Done(); it.Next()) num_candidates++;
+ if (!computed && num_candidates == 0) {
+ LOG(INFO) << "Index was computed at iteration " << i;
+ computed = true;
+ }
+ }
+
+ num_candidates = 0;
+ for (it.GetCandidates(q, q); !it.Done(); it.Next()) num_candidates++;
+ EXPECT_EQ(0, num_candidates);
+
+ delete loop;
+}
+
+
+// MICROBENCHMARKS (and related structures)
+
+// Generates a bunch of random edges and tests each against all others for
+// crossings. This is just for benchmarking; there's no correctness testing in
+// this function. Set "cutoff_level" negative to apply brute force checking.
+static void ComputeCrossings(int num_edges,
+ double edge_length_max,
+ double cap_span_meters,
+ int brute_force) {
+ StopBenchmarkTiming();
+ vector<S2Edge> all_edges;
+ GenerateRandomEarthEdges(edge_length_max, cap_span_meters, num_edges,
+ &all_edges);
+ StartBenchmarkTiming();
+ if (brute_force) {
+ for (vector<S2Edge>::const_iterator it = all_edges.begin();
+ it != all_edges.end(); ++it) {
+ for (vector<S2Edge>::const_iterator it2 = all_edges.begin();
+ it2 != all_edges.end(); ++it2) {
+ S2EdgeUtil::RobustCrossing(it->first, it->second,
+ it2->first, it2->second);
+ }
+ }
+ } else {
+ EdgeVectorIndex index(&all_edges);
+ index.ComputeIndex();
+ EdgeVectorIndex::Iterator can_it(&index);
+ for (vector<S2Edge>::const_iterator it = all_edges.begin();
+ it != all_edges.end(); ++it) {
+ for (can_it.GetCandidates(it->first, it->second);
+ !can_it.Done(); can_it.Next()) {
+ int in = can_it.Index();
+ S2EdgeUtil::RobustCrossing(all_edges[in].first, all_edges[in].second,
+ it->first,
+ it->second);
+ }
+ }
+ }
+}
+
+// "Sparse" tests are those where we expect relatively few segment crossings.
+// In general the segment lengths are short (< 300m) and the random segments
+// are distributed over caps of radius 5-50km.
+
+static void BM_TestCrossingsSparse(int iters, int num_edges, int brute_force) {
+ for (int i = 0; i < iters; ++i) {
+ ComputeCrossings(num_edges, 30, 5000, brute_force);
+ ComputeCrossings(num_edges, 100, 5000, brute_force);
+ }
+}
+BENCHMARK(BM_TestCrossingsSparse)
+ ->ArgPair(10, true)
+ ->ArgPair(10, false)
+ ->ArgPair(50, true)
+ ->ArgPair(50, false)
+ ->ArgPair(100, true)
+ ->ArgPair(100, false)
+ ->ArgPair(300, true)
+ ->ArgPair(300, false)
+ ->ArgPair(600, true)
+ ->ArgPair(600, false)
+ ->ArgPair(1000, true)
+ ->ArgPair(1000, false)
+ ->ArgPair(2000, false)
+ ->ArgPair(5000, false)
+ ->ArgPair(10000, false)
+ ->ArgPair(20000, false)
+ ->ArgPair(50000, false)
+ ->ArgPair(100000, false);
+
+// These benchmarks are used to find the right trade-off between brute force
+// and quad tree.
+
+// To compute kQuadTreeInsertionCost
+static void BM_QuadTreeInsertionCost(int iters) {
+ const int kNumVertices = 1000;
+ StopBenchmarkTiming();
+ S2Point loop_center = S2Testing::MakePoint("42:107");
+ S2Loop* loop = S2Testing::MakeRegularLoop(loop_center, kNumVertices,
+ 7e-3); // = 5km/6400km
+ StartBenchmarkTiming();
+
+ for (int i = 0; i < iters; ++i) {
+ S2LoopIndex index(loop);
+ index.ComputeIndex();
+ }
+ delete loop;
+}
+BENCHMARK(BM_QuadTreeInsertionCost);
+
+// To compute kQuadTreeFindCost
+static void BM_QuadTreeFindCost(int iters, int num_vertices) {
+ StopBenchmarkTiming();
+ S2Point loop_center = S2Testing::MakePoint("42:107");
+ S2Loop* loop = S2Testing::MakeRegularLoop(loop_center, num_vertices,
+ 7e-3); // = 5km/6400km
+ S2Point p(S2Testing::MakePoint("42:106.99"));
+ S2Point q(S2Testing::MakePoint("42:107.01"));
+ S2LoopIndex index(loop);
+ index.ComputeIndex();
+ EdgeVectorIndex::Iterator can_it(&index);
+ StartBenchmarkTiming();
+
+ for (int i = 0; i < iters; ++i) {
+ can_it.GetCandidates(p, q);
+ }
+ delete loop;
+}
+BENCHMARK(BM_QuadTreeFindCost)
+ ->Arg(10)
+ ->Arg(100)
+ ->Arg(1000)
+ ->Arg(10000);
diff --git a/src/third_party/s2/s2edgeutil.cc b/src/third_party/s2/s2edgeutil.cc
new file mode 100644
index 00000000000..9626b384bc2
--- /dev/null
+++ b/src/third_party/s2/s2edgeutil.cc
@@ -0,0 +1,448 @@
+// Copyright 2005 Google Inc. All Rights Reserved.
+
+#include <algorithm>
+using std::min;
+using std::max;
+using std::swap;
+using std::reverse;
+
+#include "s2edgeutil.h"
+
+#include "base/logging.h"
+
+bool S2EdgeUtil::SimpleCrossing(S2Point const& a, S2Point const& b,
+ S2Point const& c, S2Point const& d) {
+ // We compute SimpleCCW() for triangles ACB, CBD, BDA, and DAC. All
+ // of these triangles need to have the same orientation (CW or CCW)
+ // for an intersection to exist. Note that this is slightly more
+ // restrictive than the corresponding definition for planar edges,
+ // since we need to exclude pairs of line segments that would
+ // otherwise "intersect" by crossing two antipodal points.
+
+ S2Point ab = a.CrossProd(b);
+ double acb = -(ab.DotProd(c));
+ double bda = ab.DotProd(d);
+ if (acb * bda <= 0) return false;
+
+ S2Point cd = c.CrossProd(d);
+ double cbd = -(cd.DotProd(b));
+ double dac = cd.DotProd(a);
+ return (acb * cbd > 0) && (acb * dac > 0);
+}
+
+int S2EdgeUtil::RobustCrossing(S2Point const& a, S2Point const& b,
+ S2Point const& c, S2Point const& d) {
+ S2EdgeUtil::EdgeCrosser crosser(&a, &b, &c);
+ return crosser.RobustCrossing(&d);
+}
+
+bool S2EdgeUtil::VertexCrossing(S2Point const& a, S2Point const& b,
+ S2Point const& c, S2Point const& d) {
+ // If A == B or C == D there is no intersection. We need to check this
+ // case first in case 3 or more input points are identical.
+ if (a == b || c == d) return false;
+
+ // If any other pair of vertices is equal, there is a crossing if and only
+ // if OrderedCCW() indicates that the edge AB is further CCW around the
+ // shared vertex O (either A or B) than the edge CD, starting from an
+ // arbitrary fixed reference point.
+ if (a == d) return S2::OrderedCCW(S2::Ortho(a), c, b, a);
+ if (b == c) return S2::OrderedCCW(S2::Ortho(b), d, a, b);
+ if (a == c) return S2::OrderedCCW(S2::Ortho(a), d, b, a);
+ if (b == d) return S2::OrderedCCW(S2::Ortho(b), c, a, b);
+
+ S2LOG(DFATAL) << "VertexCrossing called with 4 distinct vertices";
+ return false;
+}
+
+bool S2EdgeUtil::EdgeOrVertexCrossing(S2Point const& a, S2Point const& b,
+ S2Point const& c, S2Point const& d) {
+ int crossing = RobustCrossing(a, b, c, d);
+ if (crossing < 0) return false;
+ if (crossing > 0) return true;
+ return VertexCrossing(a, b, c, d);
+}
+
+static void ReplaceIfCloser(S2Point const& x, S2Point const& y,
+ double *dmin2, S2Point* vmin) {
+ // If the squared distance from x to y is less than dmin2, then replace
+ // vmin by y and update dmin2 accordingly.
+
+ double d2 = (x - y).Norm2();
+ if (d2 < *dmin2 || (d2 == *dmin2 && y < *vmin)) {
+ *dmin2 = d2;
+ *vmin = y;
+ }
+}
+
+S2Point S2EdgeUtil::GetIntersection(S2Point const& a0, S2Point const& a1,
+ S2Point const& b0, S2Point const& b1) {
+ DCHECK_GT(RobustCrossing(a0, a1, b0, b1), 0);
+
+ // We use RobustCrossProd() to get accurate results even when two endpoints
+ // are close together, or when the two line segments are nearly parallel.
+
+ S2Point a_norm = S2::RobustCrossProd(a0, a1).Normalize();
+ S2Point b_norm = S2::RobustCrossProd(b0, b1).Normalize();
+ S2Point x = S2::RobustCrossProd(a_norm, b_norm).Normalize();
+
+ // Make sure the intersection point is on the correct side of the sphere.
+ // Since all vertices are unit length, and edges are less than 180 degrees,
+ // (a0 + a1) and (b0 + b1) both have positive dot product with the
+ // intersection point. We use the sum of all vertices to make sure that the
+ // result is unchanged when the edges are reversed or exchanged.
+
+ if (x.DotProd((a0 + a1) + (b0 + b1)) < 0) x = -x;
+
+ // The calculation above is sufficient to ensure that "x" is within
+ // kIntersectionTolerance of the great circles through (a0,a1) and (b0,b1).
+ // However, if these two great circles are very close to parallel, it is
+ // possible that "x" does not lie between the endpoints of the given line
+ // segments. In other words, "x" might be on the great circle through
+ // (a0,a1) but outside the range covered by (a0,a1). In this case we do
+ // additional clipping to ensure that it does.
+
+ if (S2::OrderedCCW(a0, x, a1, a_norm) && S2::OrderedCCW(b0, x, b1, b_norm))
+ return x;
+
+ // Find the acceptable endpoint closest to x and return it. An endpoint is
+ // acceptable if it lies between the endpoints of the other line segment.
+ double dmin2 = 10;
+ S2Point vmin = x;
+ if (S2::OrderedCCW(b0, a0, b1, b_norm)) ReplaceIfCloser(x, a0, &dmin2, &vmin);
+ if (S2::OrderedCCW(b0, a1, b1, b_norm)) ReplaceIfCloser(x, a1, &dmin2, &vmin);
+ if (S2::OrderedCCW(a0, b0, a1, a_norm)) ReplaceIfCloser(x, b0, &dmin2, &vmin);
+ if (S2::OrderedCCW(a0, b1, a1, a_norm)) ReplaceIfCloser(x, b1, &dmin2, &vmin);
+
+ DCHECK(S2::OrderedCCW(a0, vmin, a1, a_norm));
+ DCHECK(S2::OrderedCCW(b0, vmin, b1, b_norm));
+ return vmin;
+}
+
+// IEEE floating-point operations have a maximum error of 0.5 ULPS (units in
+// the last place). For double-precision numbers, this works out to 2**-53
+// (about 1.11e-16) times the magnitude of the result. It is possible to
+// analyze the calculation done by GetIntersection() and work out the
+// worst-case rounding error. I have done a rough version of this, and my
+// estimate is that the worst case distance from the intersection point X to
+// the great circle through (a0, a1) is about 12 ULPS, or about 1.3e-15.
+// This needs to be increased by a factor of (1/0.866) to account for the
+// edge_splice_fraction() in S2PolygonBuilder. Note that the maximum error
+// measured by the unittest in 1,000,000 trials is less than 3e-16.
+S1Angle const S2EdgeUtil::kIntersectionTolerance = S1Angle::Radians(1.5e-15);
+
+double S2EdgeUtil::GetDistanceFraction(S2Point const& x,
+ S2Point const& a0, S2Point const& a1) {
+ DCHECK_NE(a0, a1);
+ double d0 = x.Angle(a0);
+ double d1 = x.Angle(a1);
+ return d0 / (d0 + d1);
+}
+
+S2Point S2EdgeUtil::InterpolateAtDistance(S1Angle const& ax,
+ S2Point const& a, S2Point const& b,
+ S1Angle const& ab) {
+ DCHECK(S2::IsUnitLength(a));
+ DCHECK(S2::IsUnitLength(b));
+
+ // As of crosstool v14, gcc tries to calculate sin(ax_radians),
+ // cos(ax_radians), sin(ab_radians), cos(ab_radians) in the
+ // following section by two sincos() calls. However, for some
+ // inputs, sincos() returns significantly different values between
+ // AMD and Intel.
+ //
+ // As a temporary workaround, "volatile" is added to ax_radians and
+ // ab_radians, to prohibit the compiler to use such sincos() call,
+ // because sin() and cos() don't seem to have the problem. See
+ // b/3088321 for details.
+ volatile double ax_radians = ax.radians();
+ volatile double ab_radians = ab.radians();
+
+ // The result X is some linear combination X = e*A + f*B of the input
+ // points. The fractions "e" and "f" can be derived by looking at the
+ // components of this equation that are parallel and perpendicular to A.
+ // Let E = e*A and F = f*B. Then OEXF is a parallelogram. You can obtain
+ // the distance f = OF by considering the similar triangles produced by
+ // dropping perpendiculars from the segments OF and OB to OA.
+ double f = sin(ax_radians) / sin(ab_radians);
+
+ // Form the dot product of the first equation with A to obtain
+ // A.X = e*A.A + f*A.B. Since A, B, and X are all unit vectors,
+ // cos(ax) = e*1 + f*cos(ab), so
+ double e = cos(ax_radians) - f * cos(ab_radians);
+
+ // Mathematically speaking, if "a" and "b" are unit length then the result
+ // is unit length as well. But we normalize it anyway to prevent points
+ // from drifting away from unit length when multiple interpolations are done
+ // in succession (i.e. the result of one interpolation is fed into another).
+ return (e * a + f * b).Normalize();
+}
+
+S2Point S2EdgeUtil::InterpolateAtDistance(S1Angle const& ax,
+ S2Point const& a, S2Point const& b) {
+ return InterpolateAtDistance(ax, a, b, S1Angle(a, b));
+}
+
+S2Point S2EdgeUtil::Interpolate(double t, S2Point const& a, S2Point const& b) {
+ if (t == 0) return a;
+ if (t == 1) return b;
+ S1Angle ab(a, b);
+ return InterpolateAtDistance(t * ab, a, b, ab);
+}
+
+S1Angle S2EdgeUtil::GetDistance(S2Point const& x,
+ S2Point const& a, S2Point const& b,
+ S2Point const& a_cross_b) {
+ DCHECK(S2::IsUnitLength(a));
+ DCHECK(S2::IsUnitLength(b));
+ DCHECK(S2::IsUnitLength(x));
+
+ // There are three cases. If X is located in the spherical wedge defined by
+ // A, B, and the axis A x B, then the closest point is on the segment AB.
+ // Otherwise the closest point is either A or B; the dividing line between
+ // these two cases is the great circle passing through (A x B) and the
+ // midpoint of AB.
+
+ if (S2::SimpleCCW(a_cross_b, a, x) && S2::SimpleCCW(x, b, a_cross_b)) {
+ // The closest point to X lies on the segment AB. We compute the distance
+ // to the corresponding great circle. The result is accurate for small
+ // distances but not necessarily for large distances (approaching Pi/2).
+
+ DCHECK_NE(a, b); // Due to the guarantees of SimpleCCW().
+ double sin_dist = fabs(x.DotProd(a_cross_b)) / a_cross_b.Norm();
+ return S1Angle::Radians(asin(min(1.0, sin_dist)));
+ }
+ // Otherwise, the closest point is either A or B. The cheapest method is
+ // just to compute the minimum of the two linear (as opposed to spherical)
+ // distances and convert the result to an angle. Again, this method is
+ // accurate for small but not large distances (approaching Pi).
+
+ double linear_dist2 = min((x-a).Norm2(), (x-b).Norm2());
+ return S1Angle::Radians(2 * asin(min(1.0, 0.5 * sqrt(linear_dist2))));
+}
+
+S1Angle S2EdgeUtil::GetDistance(S2Point const& x,
+ S2Point const& a, S2Point const& b) {
+ return GetDistance(x, a, b, S2::RobustCrossProd(a, b));
+}
+
+S2Point S2EdgeUtil::GetClosestPoint(S2Point const& x,
+ S2Point const& a, S2Point const& b,
+ S2Point const& a_cross_b) {
+ DCHECK(S2::IsUnitLength(a));
+ DCHECK(S2::IsUnitLength(b));
+ DCHECK(S2::IsUnitLength(x));
+
+ // Find the closest point to X along the great circle through AB.
+ S2Point p = x - (x.DotProd(a_cross_b) / a_cross_b.Norm2()) * a_cross_b;
+
+ // If this point is on the edge AB, then it's the closest point.
+ if (S2::SimpleCCW(a_cross_b, a, p) && S2::SimpleCCW(p, b, a_cross_b))
+ return p.Normalize();
+
+ // Otherwise, the closest point is either A or B.
+ return ((x - a).Norm2() <= (x - b).Norm2()) ? a : b;
+}
+
+S2Point S2EdgeUtil::GetClosestPoint(S2Point const& x,
+ S2Point const& a, S2Point const& b) {
+ return GetClosestPoint(x, a, b, S2::RobustCrossProd(a, b));
+}
+
+bool S2EdgeUtil::IsEdgeBNearEdgeA(S2Point const& a0, S2Point const& a1,
+ S2Point const& b0, S2Point const& b1,
+ S1Angle const& tolerance) {
+ DCHECK_LT(tolerance.radians(), M_PI / 2);
+ DCHECK_GT(tolerance.radians(), 0);
+ // The point on edge B=b0b1 furthest from edge A=a0a1 is either b0, b1, or
+ // some interior point on B. If it is an interior point on B, then it must be
+ // one of the two points where the great circle containing B (circ(B)) is
+ // furthest from the great circle containing A (circ(A)). At these points,
+ // the distance between circ(B) and circ(A) is the angle between the planes
+ // containing them.
+
+ S2Point a_ortho = S2::RobustCrossProd(a0, a1).Normalize();
+ S2Point const a_nearest_b0 = GetClosestPoint(b0, a0, a1, a_ortho);
+ S2Point const a_nearest_b1 = GetClosestPoint(b1, a0, a1, a_ortho);
+ // If a_nearest_b0 and a_nearest_b1 have opposite orientation from a0 and a1,
+ // we invert a_ortho so that it points in the same direction as a_nearest_b0 x
+ // a_nearest_b1. This helps us handle the case where A and B are oppositely
+ // oriented but otherwise might be near each other. We check orientation and
+ // invert rather than computing a_nearest_b0 x a_nearest_b1 because those two
+ // points might be equal, and have an unhelpful cross product.
+ if (S2::RobustCCW(a_ortho, a_nearest_b0, a_nearest_b1) < 0)
+ a_ortho *= -1;
+
+ // To check if all points on B are within tolerance of A, we first check to
+ // see if the endpoints of B are near A. If they are not, B is not near A.
+ S1Angle const b0_distance(b0, a_nearest_b0);
+ S1Angle const b1_distance(b1, a_nearest_b1);
+ if (b0_distance > tolerance || b1_distance > tolerance)
+ return false;
+
+ // If b0 and b1 are both within tolerance of A, we check to see if the angle
+ // between the planes containing B and A is greater than tolerance. If it is
+ // not, no point on B can be further than tolerance from A (recall that we
+ // already know that b0 and b1 are close to A, and S2Edges are all shorter
+ // than 180 degrees). The angle between the planes containing circ(A) and
+ // circ(B) is the angle between their normal vectors.
+ S2Point const b_ortho = S2::RobustCrossProd(b0, b1).Normalize();
+ S1Angle const planar_angle(a_ortho, b_ortho);
+ if (planar_angle <= tolerance)
+ return true;
+
+
+ // As planar_angle approaches M_PI, the projection of a_ortho onto the plane
+ // of B approaches the null vector, and normalizing it is numerically
+ // unstable. This makes it unreliable or impossible to identify pairs of
+ // points where circ(A) is furthest from circ(B). At this point in the
+ // algorithm, this can only occur for two reasons:
+ //
+ // 1.) b0 and b1 are closest to A at distinct endpoints of A, in which case
+ // the opposite orientation of a_ortho and b_ortho means that A and B are
+ // in opposite hemispheres and hence not close to each other.
+ //
+ // 2.) b0 and b1 are closest to A at the same endpoint of A, in which case
+ // the orientation of a_ortho was chosen arbitrarily to be that of a0
+ // cross a1. B must be shorter than 2*tolerance and all points in B are
+ // close to one endpoint of A, and hence to A.
+ //
+ // The logic applies when planar_angle is robustly greater than M_PI/2, but
+ // may be more computationally expensive than the logic beyond, so we choose a
+ // value close to M_PI.
+ if (planar_angle >= S1Angle::Radians(M_PI - 0.01)) {
+ return (S1Angle(b0, a0) < S1Angle(b0, a1)) ==
+ (S1Angle(b1, a0) < S1Angle(b1, a1));
+ }
+
+ // Finally, if either of the two points on circ(B) where circ(B) is furthest
+ // from circ(A) lie on edge B, edge B is not near edge A.
+ //
+ // The normalized projection of a_ortho onto the plane of circ(B) is one of
+ // the two points along circ(B) where it is furthest from circ(A). The other
+ // is -1 times the normalized projection.
+ S2Point furthest = (a_ortho - a_ortho.DotProd(b_ortho) * b_ortho).Normalize();
+ DCHECK(S2::IsUnitLength(furthest));
+ S2Point furthest_inv = -1 * furthest;
+
+ // A point p lies on B if you can proceed from b_ortho to b0 to p to b1 and
+ // back to b_ortho without ever turning right. We test this for furthest and
+ // furthest_inv, and return true if neither point lies on B.
+ return !((S2::RobustCCW(b_ortho, b0, furthest) > 0 &&
+ S2::RobustCCW(furthest, b1, b_ortho) > 0) ||
+ (S2::RobustCCW(b_ortho, b0, furthest_inv) > 0 &&
+ S2::RobustCCW(furthest_inv, b1, b_ortho) > 0));
+}
+
+
+bool S2EdgeUtil::WedgeContains(S2Point const& a0, S2Point const& ab1,
+ S2Point const& a2, S2Point const& b0,
+ S2Point const& b2) {
+ // For A to contain B (where each loop interior is defined to be its left
+ // side), the CCW edge order around ab1 must be a2 b2 b0 a0. We split
+ // this test into two parts that test three vertices each.
+ return S2::OrderedCCW(a2, b2, b0, ab1) && S2::OrderedCCW(b0, a0, a2, ab1);
+}
+
+bool S2EdgeUtil::WedgeIntersects(S2Point const& a0, S2Point const& ab1,
+ S2Point const& a2, S2Point const& b0,
+ S2Point const& b2) {
+ // For A not to intersect B (where each loop interior is defined to be
+ // its left side), the CCW edge order around ab1 must be a0 b2 b0 a2.
+ // Note that it's important to write these conditions as negatives
+ // (!OrderedCCW(a,b,c,o) rather than Ordered(c,b,a,o)) to get correct
+ // results when two vertices are the same.
+ return !(S2::OrderedCCW(a0, b2, b0, ab1) && S2::OrderedCCW(b0, a2, a0, ab1));
+}
+
+S2EdgeUtil::WedgeRelation S2EdgeUtil::GetWedgeRelation(
+ S2Point const& a0, S2Point const& ab1, S2Point const& a2,
+ S2Point const& b0, S2Point const& b2) {
+ // There are 6 possible edge orderings at a shared vertex (all
+ // of these orderings are circular, i.e. abcd == bcda):
+ //
+ // (1) a2 b2 b0 a0: A contains B
+ // (2) a2 a0 b0 b2: B contains A
+ // (3) a2 a0 b2 b0: A and B are disjoint
+ // (4) a2 b0 a0 b2: A and B intersect in one wedge
+ // (5) a2 b2 a0 b0: A and B intersect in one wedge
+ // (6) a2 b0 b2 a0: A and B intersect in two wedges
+ //
+ // We do not distinguish between 4, 5, and 6.
+ // We pay extra attention when some of the edges overlap.When edges
+ // overlap, several of these orderings can be satisfied, and we take
+ // the most specific.
+ if (a0 == b0 && a2 == b2) return WEDGE_EQUALS;
+
+ if (S2::OrderedCCW(a0, a2, b2, ab1)) {
+ // The cases with this vertex ordering are 1, 5, and 6,
+ // although case 2 is also possible if a2 == b2.
+ if (S2::OrderedCCW(b2, b0, a0, ab1)) return WEDGE_PROPERLY_CONTAINS;
+
+ // We are in case 5 or 6, or case 2 if a2 == b2.
+ return (a2 == b2) ? WEDGE_IS_PROPERLY_CONTAINED : WEDGE_PROPERLY_OVERLAPS;
+ }
+
+ // We are in case 2, 3, or 4.
+ if (S2::OrderedCCW(a0, b0, b2, ab1)) return WEDGE_IS_PROPERLY_CONTAINED;
+ return S2::OrderedCCW(a0, b0, a2, ab1) ?
+ WEDGE_IS_DISJOINT : WEDGE_PROPERLY_OVERLAPS;
+}
+
+int S2EdgeUtil::EdgeCrosser::RobustCrossingInternal(S2Point const* d) {
+ // ACB and BDA have the appropriate orientations, so now we check the
+ // triangles CBD and DAC.
+ S2Point c_cross_d = c_->CrossProd(*d);
+ int cbd = -S2::RobustCCW(*c_, *d, *b_, c_cross_d);
+ if (cbd != acb_) return -1;
+
+ int dac = S2::RobustCCW(*c_, *d, *a_, c_cross_d);
+ return (dac == acb_) ? 1 : -1;
+}
+
+void S2EdgeUtil::RectBounder::AddPoint(S2Point const* b) {
+ DCHECK(S2::IsUnitLength(*b));
+ S2LatLng b_latlng(*b);
+ if (bound_.is_empty()) {
+ bound_.AddPoint(b_latlng);
+ } else {
+ // We can't just call bound_.AddPoint(b_latlng) here, since we need to
+ // ensure that all the longitudes between "a" and "b" are included.
+ bound_ = bound_.Union(S2LatLngRect::FromPointPair(a_latlng_, b_latlng));
+
+ // Check whether the min/max latitude occurs in the edge interior. We find
+ // the normal to the plane containing AB, and then a vector "dir" in this
+ // plane that also passes through the equator. We use RobustCrossProd to
+ // ensure that the edge normal is accurate even when the two points are very
+ // close together.
+ S2Point a_cross_b = S2::RobustCrossProd(*a_, *b);
+ S2Point dir = a_cross_b.CrossProd(S2Point(0, 0, 1));
+ double da = dir.DotProd(*a_);
+ double db = dir.DotProd(*b);
+ if (da * db < 0) {
+ // Minimum/maximum latitude occurs in the edge interior.
+ double abs_lat = acos(fabs(a_cross_b[2] / a_cross_b.Norm()));
+ if (da < 0) {
+ // It's possible that abs_lat < lat_.lo() due to numerical errors.
+ bound_.mutable_lat()->set_hi(max(abs_lat, bound_.lat().hi()));
+ } else {
+ bound_.mutable_lat()->set_lo(min(-abs_lat, bound_.lat().lo()));
+ }
+
+ // If the edge comes very close to the north or south pole then we may
+ // not be certain which side of the pole it is on. We handle this by
+ // expanding the longitude bounds if the maximum absolute latitude is
+ // approximately Pi/2.
+ if (abs_lat >= M_PI_2 - 1e-15) {
+ *bound_.mutable_lng() = S1Interval::Full();
+ }
+ }
+ }
+ a_ = b;
+ a_latlng_ = b_latlng;
+}
+
+S2EdgeUtil::LongitudePruner::LongitudePruner(S1Interval const& interval,
+ S2Point const& v0)
+ : interval_(interval), lng0_(S2LatLng::Longitude(v0).radians()) {
+}
diff --git a/src/third_party/s2/s2edgeutil.h b/src/third_party/s2/s2edgeutil.h
new file mode 100644
index 00000000000..47bdb8dafe3
--- /dev/null
+++ b/src/third_party/s2/s2edgeutil.h
@@ -0,0 +1,336 @@
+// Copyright 2005 Google Inc. All Rights Reserved.
+
+#ifndef UTIL_GEOMETRY_S2EDGEUTIL_H__
+#define UTIL_GEOMETRY_S2EDGEUTIL_H__
+
+#include "base/logging.h"
+#include "base/macros.h"
+#include "s2.h"
+#include "s2latlngrect.h"
+
+class S2LatLngRect;
+
+// This class contains various utility functions related to edges. It
+// collects together common code that is needed to implement polygonal
+// geometry such as polylines, loops, and general polygons.
+class S2EdgeUtil {
+ public:
+ // This class allows a vertex chain v0, v1, v2, ... to be efficiently
+ // tested for intersection with a given fixed edge AB.
+ class EdgeCrosser {
+ public:
+ // AB is the given fixed edge, and C is the first vertex of the vertex
+ // chain. All parameters must point to fixed storage that persists for
+ // the lifetime of the EdgeCrosser object.
+ inline EdgeCrosser(S2Point const* a, S2Point const* b, S2Point const* c);
+
+ // Call this function when your chain 'jumps' to a new place.
+ inline void RestartAt(S2Point const* c);
+
+ // This method is equivalent to calling the S2EdgeUtil::RobustCrossing()
+ // function (defined below) on the edges AB and CD. It returns +1 if
+ // there is a crossing, -1 if there is no crossing, and 0 if two points
+ // from different edges are the same. Returns 0 or -1 if either edge is
+ // degenerate. As a side effect, it saves vertex D to be used as the next
+ // vertex C.
+ inline int RobustCrossing(S2Point const* d);
+
+ // This method is equivalent to the S2EdgeUtil::EdgeOrVertexCrossing()
+ // method defined below. It is similar to RobustCrossing, but handles
+ // cases where two vertices are identical in a way that makes it easy to
+ // implement point-in-polygon containment tests.
+ inline bool EdgeOrVertexCrossing(S2Point const* d);
+
+ private:
+ // This function handles the "slow path" of RobustCrossing(), which does
+ // not need to be inlined.
+ int RobustCrossingInternal(S2Point const* d);
+
+ // The fields below are all constant.
+ S2Point const* const a_;
+ S2Point const* const b_;
+ S2Point const a_cross_b_;
+
+ // The fields below are updated for each vertex in the chain.
+ S2Point const* c_; // Previous vertex in the vertex chain.
+ int acb_; // The orientation of the triangle ACB.
+ };
+
+ // This class computes a bounding rectangle that contains all edges
+ // defined by a vertex chain v0, v1, v2, ... All vertices must be unit
+ // length. Note that the bounding rectangle of an edge can be larger than
+ // the bounding rectangle of its endpoints, e.g. consider an edge that
+ // passes through the north pole.
+ class RectBounder {
+ public:
+ RectBounder() : bound_(S2LatLngRect::Empty()) {}
+
+ // This method is called to add each vertex to the chain. 'b'
+ // must point to fixed storage that persists through the next call
+ // to AddPoint. This means that if you don't store all of your
+ // points for the lifetime of the bounder, you must at least store
+ // the last two points and alternate which one you use for the
+ // next point.
+ void AddPoint(S2Point const* b);
+
+ // Return the bounding rectangle of the edge chain that connects the
+ // vertices defined so far.
+ S2LatLngRect GetBound() const { return bound_; }
+
+ private:
+ S2Point const* a_; // The previous vertex in the chain.
+ S2LatLng a_latlng_; // The corresponding latitude-longitude.
+ S2LatLngRect bound_; // The current bounding rectangle.
+ };
+
+ // The purpose of this class is to find edges that intersect a given
+ // longitude interval. It can be used as an efficient rejection test when
+ // attempting to find edges that intersect a given region. It accepts a
+ // vertex chain v0, v1, v2, ... and returns a boolean value indicating
+ // whether each edge intersects the specified longitude interval.
+ class LongitudePruner {
+ public:
+ // 'interval' is the longitude interval to be tested against, and
+ // 'v0' is the first vertex of edge chain.
+ LongitudePruner(S1Interval const& interval, S2Point const& v0);
+
+ // Returns true if the edge (v0, v1) intersects the given longitude
+ // interval, and then saves 'v1' to be used as the next 'v0'.
+ inline bool Intersects(S2Point const& v1);
+
+ private:
+ S1Interval interval_; // The interval to be tested against.
+ double lng0_; // The longitude of the next v0.
+ };
+
+ // Return true if edge AB crosses CD at a point that is interior
+ // to both edges. Properties:
+ //
+ // (1) SimpleCrossing(b,a,c,d) == SimpleCrossing(a,b,c,d)
+ // (2) SimpleCrossing(c,d,a,b) == SimpleCrossing(a,b,c,d)
+ static bool SimpleCrossing(S2Point const& a, S2Point const& b,
+ S2Point const& c, S2Point const& d);
+
+ // Like SimpleCrossing, except that points that lie exactly on a line are
+ // arbitrarily classified as being on one side or the other (according to
+ // the rules of S2::RobustCCW). It returns +1 if there is a crossing, -1
+ // if there is no crossing, and 0 if any two vertices from different edges
+ // are the same. Returns 0 or -1 if either edge is degenerate.
+ // Properties of RobustCrossing:
+ //
+ // (1) RobustCrossing(b,a,c,d) == RobustCrossing(a,b,c,d)
+ // (2) RobustCrossing(c,d,a,b) == RobustCrossing(a,b,c,d)
+ // (3) RobustCrossing(a,b,c,d) == 0 if a==c, a==d, b==c, b==d
+ // (3) RobustCrossing(a,b,c,d) <= 0 if a==b or c==d
+ //
+ // Note that if you want to check an edge against a *chain* of other
+ // edges, it is much more efficient to use an EdgeCrosser (above).
+ static int RobustCrossing(S2Point const& a, S2Point const& b,
+ S2Point const& c, S2Point const& d);
+
+ // Given two edges AB and CD where at least two vertices are identical
+ // (i.e. RobustCrossing(a,b,c,d) == 0), this function defines whether the
+ // two edges "cross" in a such a way that point-in-polygon containment tests
+ // can be implemented by counting the number of edge crossings. The basic
+ // rule is that a "crossing" occurs if AB is encountered after CD during a
+ // CCW sweep around the shared vertex starting from a fixed reference point.
+ //
+ // Note that according to this rule, if AB crosses CD then in general CD
+ // does not cross AB. However, this leads to the correct result when
+ // counting polygon edge crossings. For example, suppose that A,B,C are
+ // three consecutive vertices of a CCW polygon. If we now consider the edge
+ // crossings of a segment BP as P sweeps around B, the crossing number
+ // changes parity exactly when BP crosses BA or BC.
+ //
+ // Useful properties of VertexCrossing (VC):
+ //
+ // (1) VC(a,a,c,d) == VC(a,b,c,c) == false
+ // (2) VC(a,b,a,b) == VC(a,b,b,a) == true
+ // (3) VC(a,b,c,d) == VC(a,b,d,c) == VC(b,a,c,d) == VC(b,a,d,c)
+ // (3) If exactly one of a,b equals one of c,d, then exactly one of
+ // VC(a,b,c,d) and VC(c,d,a,b) is true
+ //
+ // It is an error to call this method with 4 distinct vertices.
+ static bool VertexCrossing(S2Point const& a, S2Point const& b,
+ S2Point const& c, S2Point const& d);
+
+ // A convenience function that calls RobustCrossing() to handle cases
+ // where all four vertices are distinct, and VertexCrossing() to handle
+ // cases where two or more vertices are the same. This defines a crossing
+ // function such that point-in-polygon containment tests can be implemented
+ // by simply counting edge crossings.
+ static bool EdgeOrVertexCrossing(S2Point const& a, S2Point const& b,
+ S2Point const& c, S2Point const& d);
+
+ // Given two edges AB and CD such that RobustCrossing() is true, return
+ // their intersection point. Useful properties of GetIntersection (GI):
+ //
+ // (1) GI(b,a,c,d) == GI(a,b,d,c) == GI(a,b,c,d)
+ // (2) GI(c,d,a,b) == GI(a,b,c,d)
+ //
+ // The returned intersection point X is guaranteed to be close to the edges
+ // AB and CD, but if the edges intersect at a very small angle then X may
+ // not be close to the true mathematical intersection point P. See the
+ // description of "kIntersectionTolerance" below for details.
+ static S2Point GetIntersection(S2Point const& a, S2Point const& b,
+ S2Point const& c, S2Point const& d);
+
+ // This distance is an upper bound on the distance from the intersection
+ // point returned by GetIntersection() to either of the two edges that were
+ // intersected. In particular, if "x" is the intersection point, then
+ // GetDistance(x, a, b) and GetDistance(x, c, d) will both be smaller than
+ // this value. The intersection tolerance is also large enough such if it
+ // is passed as the "vertex_merge_radius" of an S2PolygonBuilder, then the
+ // intersection point will be spliced into the edges AB and/or CD if they
+ // are also supplied to the S2PolygonBuilder.
+ static S1Angle const kIntersectionTolerance;
+
+ // Given a point X and an edge AB, return the distance ratio AX / (AX + BX).
+ // If X happens to be on the line segment AB, this is the fraction "t" such
+ // that X == Interpolate(A, B, t). Requires that A and B are distinct.
+ static double GetDistanceFraction(S2Point const& x,
+ S2Point const& a, S2Point const& b);
+
+ // Return the point X along the line segment AB whose distance from A is the
+ // given fraction "t" of the distance AB. Does NOT require that "t" be
+ // between 0 and 1. Note that all distances are measured on the surface of
+ // the sphere, so this is more complicated than just computing (1-t)*a + t*b
+ // and normalizing the result.
+ static S2Point Interpolate(double t, S2Point const& a, S2Point const& b);
+
+ // Like Interpolate(), except that the parameter "ax" represents the desired
+ // distance from A to the result X rather than a fraction between 0 and 1.
+ static S2Point InterpolateAtDistance(S1Angle const& ax,
+ S2Point const& a, S2Point const& b);
+
+ // A slightly more efficient version of InterpolateAtDistance() that can be
+ // used when the distance AB is already known.
+ static S2Point InterpolateAtDistance(S1Angle const& ax,
+ S2Point const& a, S2Point const& b,
+ S1Angle const& ab);
+
+ // Return the minimum distance from X to any point on the edge AB. All
+ // arguments should be unit length. The result is very accurate for small
+ // distances but may have some numerical error if the distance is large
+ // (approximately Pi/2 or greater). The case A == B is handled correctly.
+ static S1Angle GetDistance(S2Point const& x,
+ S2Point const& a, S2Point const& b);
+
+ // A slightly more efficient version of GetDistance() where the cross
+ // product of the two endpoints has been precomputed. The cross product
+ // does not need to be normalized, but should be computed using
+ // S2::RobustCrossProd() for the most accurate results.
+ static S1Angle GetDistance(S2Point const& x,
+ S2Point const& a, S2Point const& b,
+ S2Point const& a_cross_b);
+
+ // Return the point along the edge AB that is closest to the point X.
+ // The fractional distance of this point along the edge AB can be obtained
+ // using GetDistanceFraction() above.
+ static S2Point GetClosestPoint(S2Point const& x,
+ S2Point const& a, S2Point const& b);
+
+ // A slightly more efficient version of GetClosestPoint() where the cross
+ // product of the two endpoints has been precomputed. The cross product
+ // does not need to be normalized, but should be computed using
+ // S2::RobustCrossProd() for the most accurate results.
+ static S2Point GetClosestPoint(S2Point const& x,
+ S2Point const& a, S2Point const& b,
+ S2Point const& a_cross_b);
+
+ // Return true if every point on edge B=b0b1 is no further than "tolerance"
+ // from some point on edge A=a0a1.
+ // Requires that tolerance is less than 90 degrees.
+ static bool IsEdgeBNearEdgeA(S2Point const& a0, S2Point const& a1,
+ S2Point const& b0, S2Point const& b1,
+ S1Angle const& tolerance);
+
+ // For an edge chain (x0, x1, x2), a wedge is the region to the left
+ // of the edges. More precisely, it is the union of all the rays
+ // from x1x0 to x1x2, clockwise.
+ // The following are Wedge comparison functions for two wedges A =
+ // (a0, ab1, a2) and B = (b0, a12, b2). These are used in S2Loops.
+
+ // Returns true if wedge A fully contains or is equal to wedge B.
+ static bool WedgeContains(S2Point const& a0, S2Point const& ab1,
+ S2Point const& a2, S2Point const& b0,
+ S2Point const& b2);
+
+ // Returns true if the intersection of the two wedges is not empty.
+ static bool WedgeIntersects(S2Point const& a0, S2Point const& ab1,
+ S2Point const& a2, S2Point const& b0,
+ S2Point const& b2);
+
+ // Detailed relation from wedges A to wedge B.
+ enum WedgeRelation {
+ WEDGE_EQUALS,
+ WEDGE_PROPERLY_CONTAINS, // A is a strict superset of B.
+ WEDGE_IS_PROPERLY_CONTAINED, // A is a strict subset of B.
+ WEDGE_PROPERLY_OVERLAPS, // All of A intsect B, A-B and B-A are non-empty.
+ WEDGE_IS_DISJOINT, // A is disjoint from B
+ };
+
+ // Return the relation from wedge A to B.
+ static WedgeRelation GetWedgeRelation(
+ S2Point const& a0, S2Point const& ab1, S2Point const& a2,
+ S2Point const& b0, S2Point const& b2);
+
+ DISALLOW_IMPLICIT_CONSTRUCTORS(S2EdgeUtil); // Contains only static methods.
+};
+
+inline S2EdgeUtil::EdgeCrosser::EdgeCrosser(
+ S2Point const* a, S2Point const* b, S2Point const* c)
+ : a_(a), b_(b), a_cross_b_(a_->CrossProd(*b_)) {
+ RestartAt(c);
+}
+
+inline void S2EdgeUtil::EdgeCrosser::RestartAt(S2Point const* c) {
+ c_ = c;
+ acb_ = -S2::RobustCCW(*a_, *b_, *c_, a_cross_b_);
+}
+
+inline int S2EdgeUtil::EdgeCrosser::RobustCrossing(S2Point const* d) {
+ // For there to be an edge crossing, the triangles ACB, CBD, BDA, DAC must
+ // all be oriented the same way (CW or CCW). We keep the orientation of ACB
+ // as part of our state. When each new point D arrives, we compute the
+ // orientation of BDA and check whether it matches ACB. This checks whether
+ // the points C and D are on opposite sides of the great circle through AB.
+
+ // Recall that RobustCCW is invariant with respect to rotating its
+ // arguments, i.e. ABC has the same orientation as BDA.
+ int bda = S2::RobustCCW(*a_, *b_, *d, a_cross_b_);
+ int result;
+ if (bda == -acb_ && bda != 0) {
+ result = -1; // Most common case -- triangles have opposite orientations.
+ } else if ((bda & acb_) == 0) {
+ result = 0; // At least one value is zero -- two vertices are identical.
+ } else { // Slow path.
+ DCHECK_EQ(acb_, bda);
+ DCHECK_NE(0, bda);
+ result = RobustCrossingInternal(d);
+ }
+ // Now save the current vertex D as the next vertex C, and also save the
+ // orientation of the new triangle ACB (which is opposite to the current
+ // triangle BDA).
+ c_ = d;
+ acb_ = -bda;
+ return result;
+}
+
+inline bool S2EdgeUtil::EdgeCrosser::EdgeOrVertexCrossing(S2Point const* d) {
+ // We need to copy c_ since it is clobbered by RobustCrossing().
+ S2Point const* c = c_;
+ int crossing = RobustCrossing(d);
+ if (crossing < 0) return false;
+ if (crossing > 0) return true;
+ return VertexCrossing(*a_, *b_, *c, *d);
+}
+
+inline bool S2EdgeUtil::LongitudePruner::Intersects(S2Point const& v1) {
+ double lng1 = S2LatLng::Longitude(v1).radians();
+ bool result = interval_.Intersects(S1Interval::FromPointPair(lng0_, lng1));
+ lng0_ = lng1;
+ return result;
+}
+
+#endif // UTIL_GEOMETRY_S2EDGEUTIL_H__
diff --git a/src/third_party/s2/s2edgeutil_test.cc b/src/third_party/s2/s2edgeutil_test.cc
new file mode 100644
index 00000000000..6f5ea5ec6ad
--- /dev/null
+++ b/src/third_party/s2/s2edgeutil_test.cc
@@ -0,0 +1,651 @@
+// Copyright 2005 Google Inc. All Rights Reserved.
+
+#include "s2edgeutil.h"
+
+#include <algorithm>
+using std::min;
+using std::max;
+using std::swap;
+using std::reverse;
+
+#include <string>
+using std::string;
+
+#include <vector>
+using std::vector;
+
+
+#include "base/commandlineflags.h"
+#include "base/logging.h"
+#include "base/scoped_ptr.h"
+#include "testing/base/public/benchmark.h"
+#include "testing/base/public/gunit.h"
+#include "s2cap.h"
+#include "s2polyline.h"
+#include "s2testing.h"
+
+DECLARE_bool(s2debug);
+
+namespace {
+
+const int kDegen = -2;
+void CompareResult(int actual, int expected) {
+ // HACK ALERT: RobustCrossing() is allowed to return 0 or -1 if either edge
+ // is degenerate. We use the value kDegen to represent this possibility.
+ if (expected == kDegen) {
+ EXPECT_LE(actual, 0);
+ } else {
+ EXPECT_EQ(expected, actual);
+ }
+}
+
+void TestCrossing(S2Point a, S2Point b, S2Point c, S2Point d,
+ int robust, bool edge_or_vertex, bool simple) {
+ a = a.Normalize();
+ b = b.Normalize();
+ c = c.Normalize();
+ d = d.Normalize();
+ CompareResult(S2EdgeUtil::RobustCrossing(a, b, c, d), robust);
+ if (simple) {
+ EXPECT_EQ(robust > 0, S2EdgeUtil::SimpleCrossing(a, b, c, d));
+ }
+ S2EdgeUtil::EdgeCrosser crosser(&a, &b, &c);
+ CompareResult(crosser.RobustCrossing(&d), robust);
+ CompareResult(crosser.RobustCrossing(&c), robust);
+
+ EXPECT_EQ(edge_or_vertex, S2EdgeUtil::EdgeOrVertexCrossing(a, b, c, d));
+ EXPECT_EQ(edge_or_vertex, crosser.EdgeOrVertexCrossing(&d));
+ EXPECT_EQ(edge_or_vertex, crosser.EdgeOrVertexCrossing(&c));
+}
+
+void TestCrossings(S2Point a, S2Point b, S2Point c, S2Point d,
+ int robust, bool edge_or_vertex, bool simple) {
+ TestCrossing(a, b, c, d, robust, edge_or_vertex, simple);
+ TestCrossing(b, a, c, d, robust, edge_or_vertex, simple);
+ TestCrossing(a, b, d, c, robust, edge_or_vertex, simple);
+ TestCrossing(b, a, d, c, robust, edge_or_vertex, simple);
+ TestCrossing(a, a, c, d, kDegen, 0, false);
+ TestCrossing(a, b, c, c, kDegen, 0, false);
+ TestCrossing(a, b, a, b, 0, 1, false);
+ TestCrossing(c, d, a, b, robust, edge_or_vertex ^ (robust == 0), simple);
+}
+
+TEST(S2EdgeUtil, Crossings) {
+ // The real tests of edge crossings are in s2{loop,polygon}_unittest,
+ // but we do a few simple tests here.
+
+ // Two regular edges that cross.
+ TestCrossings(S2Point(1, 2, 1), S2Point(1, -3, 0.5),
+ S2Point(1, -0.5, -3), S2Point(0.1, 0.5, 3), 1, true, true);
+
+ // Two regular edges that cross antipodal points.
+ TestCrossings(S2Point(1, 2, 1), S2Point(1, -3, 0.5),
+ S2Point(-1, 0.5, 3), S2Point(-0.1, -0.5, -3), -1, false, true);
+
+ // Two edges on the same great circle.
+ TestCrossings(S2Point(0, 0, -1), S2Point(0, 1, 0),
+ S2Point(0, 1, 1), S2Point(0, 0, 1), -1, false, true);
+
+ // Two edges that cross where one vertex is S2::Origin().
+ TestCrossings(S2Point(1, 0, 0), S2::Origin(),
+ S2Point(1, -0.1, 1), S2Point(1, 1, -0.1), 1, true, true);
+
+ // Two edges that cross antipodal points where one vertex is S2::Origin().
+ TestCrossings(S2Point(1, 0, 0), S2Point(0, 1, 0),
+ S2Point(0, 0, -1), S2Point(-1, -1, 1), -1, false, true);
+
+ // Two edges that share an endpoint. The Ortho() direction is (-4,0,2),
+ // and edge CD is further CCW around (2,3,4) than AB.
+ TestCrossings(S2Point(2, 3, 4), S2Point(-1, 2, 5),
+ S2Point(7, -2, 3), S2Point(2, 3, 4), 0, false, true);
+
+ // Two edges that barely cross each other near the middle of one edge. The
+ // edge AB is approximately in the x=y plane, while CD is approximately
+ // perpendicular to it and ends exactly at the x=y plane.
+ TestCrossings(S2Point(1, 1, 1), S2Point(1, nextafter(1, 0), -1),
+ S2Point(11, -12, -1), S2Point(10, 10, 1), 1, true, false);
+
+ // In this version, the edges are separated by a distance of about 1e-15.
+ TestCrossings(S2Point(1, 1, 1), S2Point(1, nextafter(1, 2), -1),
+ S2Point(1, -1, 0), S2Point(1, 1, 0), -1, false, false);
+
+ // Two edges that barely cross each other near the end of both edges. This
+ // example cannot be handled using regular double-precision arithmetic due
+ // to floating-point underflow.
+ TestCrossings(S2Point(0, 0, 1), S2Point(2, -1e-323, 1),
+ S2Point(1, -1, 1), S2Point(1e-323, 0, 1), 1, true, false);
+
+ // In this version, the edges are separated by a distance of about 1e-640.
+ TestCrossings(S2Point(0, 0, 1), S2Point(2, 1e-323, 1),
+ S2Point(1, -1, 1), S2Point(1e-323, 0, 1), -1, false, false);
+
+ // Two edges that barely cross each other near the middle of one edge.
+ // Computing the exact determinant of some of the triangles in this test
+ // requires more than 2000 bits of precision.
+ TestCrossings(S2Point(1, -1e-323, -1e-323), S2Point(1e-323, 1, 1e-323),
+ S2Point(1, -1, 1e-323), S2Point(1, 1, 0),
+ 1, true, false);
+
+ // In this version, the edges are separated by a distance of about 1e-640.
+ TestCrossings(S2Point(1, 1e-323, -1e-323), S2Point(-1e-323, 1, 1e-323),
+ S2Point(1, -1, 1e-323), S2Point(1, 1, 0),
+ -1, false, false);
+}
+
+typedef bool CrossingFunction(S2Point const&, S2Point const&,
+ S2Point const&, S2Point const&);
+void BenchmarkCrossing(CrossingFunction crossing, int iters) {
+ StopBenchmarkTiming();
+ // We want to avoid cache effects, so kNumPoints should be small enough so
+ // that the points can be in L1 cache. sizeof(S2Point) == 24, so 400 will
+ // only take ~9KiB of 64KiB L1 cache.
+ static const int kNumPoints = 400;
+ vector<S2Point> p(kNumPoints);
+ for (int i = 0; i < kNumPoints; ++i)
+ p[i] = S2Testing::RandomPoint();
+ StartBenchmarkTiming();
+
+ int num_crossings = 0;
+ for (int i = 0; i < iters; ++i) {
+ const S2Point& a = p[(i + 0) % kNumPoints];
+ const S2Point& b = p[(i + 1) % kNumPoints];
+ const S2Point& c = p[(i + 2) % kNumPoints];
+ const S2Point& d = p[(i + 3) % kNumPoints];
+
+ if (crossing(a, b, c, d))
+ ++num_crossings;
+ }
+ VLOG(5) << "Fraction crossing = " << 1.0 * num_crossings / iters;
+ VLOG(5) << "iters: " << iters;
+}
+
+void BM_EdgeOrVertexCrossing(int iters) {
+ BenchmarkCrossing(&S2EdgeUtil::EdgeOrVertexCrossing, iters);
+}
+BENCHMARK(BM_EdgeOrVertexCrossing);
+
+bool RobustCrossingBool(S2Point const& a, S2Point const& b,
+ S2Point const& c, S2Point const& d) {
+ return S2EdgeUtil::RobustCrossing(a, b, c, d) > 0;
+}
+void BM_RobustCrossing(int iters) {
+ BenchmarkCrossing(&RobustCrossingBool, iters);
+}
+BENCHMARK(BM_RobustCrossing);
+
+S2LatLngRect GetEdgeBound(double x1, double y1, double z1,
+ double x2, double y2, double z2) {
+ S2EdgeUtil::RectBounder bounder;
+ S2Point p1 = S2Point(x1, y1, z1).Normalize();
+ S2Point p2 = S2Point(x2, y2, z2).Normalize();
+ bounder.AddPoint(&p1);
+ bounder.AddPoint(&p2);
+ return bounder.GetBound();
+}
+
+TEST(S2EdgeUtil, RectBounder) {
+ // Check cases where min/max latitude is not at a vertex.
+ EXPECT_DOUBLE_EQ(M_PI_4,
+ GetEdgeBound(1,1,1, 1,-1,1).lat().hi()); // Max, CW
+ EXPECT_DOUBLE_EQ(M_PI_4,
+ GetEdgeBound(1,-1,1, 1,1,1).lat().hi()); // Max, CCW
+ EXPECT_DOUBLE_EQ(-M_PI_4,
+ GetEdgeBound(1,-1,-1, -1,-1,-1).lat().lo()); // Min, CW
+ EXPECT_DOUBLE_EQ(-M_PI_4,
+ GetEdgeBound(-1,1,-1, -1,-1,-1).lat().lo()); // Min, CCW
+
+ // Check cases where the edge passes through one of the poles.
+ EXPECT_DOUBLE_EQ(M_PI_2, GetEdgeBound(.3,.4,1, -.3,-.4,1).lat().hi());
+ EXPECT_DOUBLE_EQ(-M_PI_2, GetEdgeBound(.3,.4,-1, -.3,-.4,-1).lat().lo());
+
+ // Check cases where the min/max latitude is attained at a vertex.
+ static double const kCubeLat = asin(sqrt(1./3)); // 35.26 degrees
+ EXPECT_TRUE(GetEdgeBound(1,1,1, 1,-1,-1).lat().
+ ApproxEquals(R1Interval(-kCubeLat, kCubeLat)));
+ EXPECT_TRUE(GetEdgeBound(1,-1,1, 1,1,-1).lat().
+ ApproxEquals(R1Interval(-kCubeLat, kCubeLat)));
+}
+
+TEST(S2EdgeUtil, LongitudePruner) {
+ S2EdgeUtil::LongitudePruner pruner1(S1Interval(0.75 * M_PI, -0.75 * M_PI),
+ S2Point(0, 1, 2));
+ EXPECT_FALSE(pruner1.Intersects(S2Point(1, 1, 3)));
+ EXPECT_TRUE(pruner1.Intersects(S2Point(-1 - 1e-15, -1, 0)));
+ EXPECT_TRUE(pruner1.Intersects(S2Point(-1, 0, 0)));
+ EXPECT_TRUE(pruner1.Intersects(S2Point(-1, 0, 0)));
+ EXPECT_TRUE(pruner1.Intersects(S2Point(1, -1, 8)));
+ EXPECT_FALSE(pruner1.Intersects(S2Point(1, 0, -2)));
+ EXPECT_TRUE(pruner1.Intersects(S2Point(-1, -1e-15, 0)));
+
+ S2EdgeUtil::LongitudePruner pruner2(S1Interval(0.25 * M_PI, 0.25 * M_PI),
+ S2Point(1, 0, 0));
+ EXPECT_FALSE(pruner2.Intersects(S2Point(2, 1, 2)));
+ EXPECT_TRUE(pruner2.Intersects(S2Point(1, 2, 3)));
+ EXPECT_FALSE(pruner2.Intersects(S2Point(0, 1, 4)));
+ EXPECT_FALSE(pruner2.Intersects(S2Point(-1e-15, -1, -1)));
+}
+
+void TestWedge(S2Point a0, S2Point ab1, S2Point a2, S2Point b0, S2Point b2,
+ bool contains, bool intersects,
+ S2EdgeUtil::WedgeRelation wedge_relation) {
+ a0 = a0.Normalize();
+ ab1 = ab1.Normalize();
+ a2 = a2.Normalize();
+ b0 = b0.Normalize();
+ b2 = b2.Normalize();
+ EXPECT_EQ(contains, S2EdgeUtil::WedgeContains(a0, ab1, a2, b0, b2));
+ EXPECT_EQ(intersects, S2EdgeUtil::WedgeIntersects(a0, ab1, a2, b0, b2));
+ EXPECT_EQ(wedge_relation, S2EdgeUtil::GetWedgeRelation(a0, ab1, a2, b0, b2));
+}
+
+TEST(S2EdgeUtil, Wedges) {
+ // For simplicity, all of these tests use an origin of (0, 0, 1).
+ // This shouldn't matter as long as the lower-level primitives are
+ // implemented correctly.
+
+ // Intersection in one wedge.
+ TestWedge(S2Point(-1, 0, 10), S2Point(0, 0, 1), S2Point(1, 2, 10),
+ S2Point(0, 1, 10), S2Point(1, -2, 10),
+ false, true, S2EdgeUtil::WEDGE_PROPERLY_OVERLAPS);
+ // Intersection in two wedges.
+ TestWedge(S2Point(-1, -1, 10), S2Point(0, 0, 1), S2Point(1, -1, 10),
+ S2Point(1, 0, 10), S2Point(-1, 1, 10),
+ false, true, S2EdgeUtil::WEDGE_PROPERLY_OVERLAPS);
+
+ // Normal containment.
+ TestWedge(S2Point(-1, -1, 10), S2Point(0, 0, 1), S2Point(1, -1, 10),
+ S2Point(-1, 0, 10), S2Point(1, 0, 10),
+ true, true, S2EdgeUtil::WEDGE_PROPERLY_CONTAINS);
+ // Containment with equality on one side.
+ TestWedge(S2Point(2, 1, 10), S2Point(0, 0, 1), S2Point(-1, -1, 10),
+ S2Point(2, 1, 10), S2Point(1, -5, 10),
+ true, true, S2EdgeUtil::WEDGE_PROPERLY_CONTAINS);
+ // Containment with equality on the other side.
+ TestWedge(S2Point(2, 1, 10), S2Point(0, 0, 1), S2Point(-1, -1, 10),
+ S2Point(1, -2, 10), S2Point(-1, -1, 10),
+ true, true, S2EdgeUtil::WEDGE_PROPERLY_CONTAINS);
+
+ // Containment with equality on both sides.
+ TestWedge(S2Point(-2, 3, 10), S2Point(0, 0, 1), S2Point(4, -5, 10),
+ S2Point(-2, 3, 10), S2Point(4, -5, 10),
+ true, true, S2EdgeUtil::WEDGE_EQUALS);
+
+ // Disjoint with equality on one side.
+ TestWedge(S2Point(-2, 3, 10), S2Point(0, 0, 1), S2Point(4, -5, 10),
+ S2Point(4, -5, 10), S2Point(-2, -3, 10),
+ false, false, S2EdgeUtil::WEDGE_IS_DISJOINT);
+ // Disjoint with equality on the other side.
+ TestWedge(S2Point(-2, 3, 10), S2Point(0, 0, 1), S2Point(0, 5, 10),
+ S2Point(4, -5, 10), S2Point(-2, 3, 10),
+ false, false, S2EdgeUtil::WEDGE_IS_DISJOINT);
+ // Disjoint with equality on both sides.
+ TestWedge(S2Point(-2, 3, 10), S2Point(0, 0, 1), S2Point(4, -5, 10),
+ S2Point(4, -5, 10), S2Point(-2, 3, 10),
+ false, false, S2EdgeUtil::WEDGE_IS_DISJOINT);
+
+ // B contains A with equality on one side.
+ TestWedge(S2Point(2, 1, 10), S2Point(0, 0, 1), S2Point(1, -5, 10),
+ S2Point(2, 1, 10), S2Point(-1, -1, 10),
+ false, true, S2EdgeUtil::WEDGE_IS_PROPERLY_CONTAINED);
+ // B contains A with equality on the other side.
+ TestWedge(S2Point(2, 1, 10), S2Point(0, 0, 1), S2Point(1, -5, 10),
+ S2Point(-2, 1, 10), S2Point(1, -5, 10),
+ false, true, S2EdgeUtil::WEDGE_IS_PROPERLY_CONTAINED);
+}
+
+// Given a point X and an edge AB, check that the distance from X to AB is
+// "distance_radians" and the closest point on AB is "expected_closest".
+void CheckDistance(S2Point x, S2Point a, S2Point b,
+ double distance_radians, S2Point expected_closest) {
+ x = x.Normalize();
+ a = a.Normalize();
+ b = b.Normalize();
+ expected_closest = expected_closest.Normalize();
+ EXPECT_DOUBLE_EQ(distance_radians,
+ S2EdgeUtil::GetDistance(x, a, b).radians());
+ S2Point closest = S2EdgeUtil::GetClosestPoint(x, a, b);
+ if (expected_closest == S2Point(0, 0, 0)) {
+ // This special value says that the result should be A or B.
+ EXPECT_TRUE(closest == a || closest == b);
+ } else {
+ EXPECT_TRUE(S2::ApproxEquals(closest, expected_closest));
+ }
+}
+
+TEST(S2EdgeUtil, Distance) {
+ CheckDistance(S2Point(1, 0, 0), S2Point(1, 0, 0), S2Point(0, 1, 0),
+ 0, S2Point(1, 0, 0));
+ CheckDistance(S2Point(0, 1, 0), S2Point(1, 0, 0), S2Point(0, 1, 0),
+ 0, S2Point(0, 1, 0));
+ CheckDistance(S2Point(1, 3, 0), S2Point(1, 0, 0), S2Point(0, 1, 0),
+ 0, S2Point(1, 3, 0));
+ CheckDistance(S2Point(0, 0, 1), S2Point(1, 0, 0), S2Point(0, 1, 0),
+ M_PI_2, S2Point(1, 0, 0));
+ CheckDistance(S2Point(0, 0, -1), S2Point(1, 0, 0), S2Point(0, 1, 0),
+ M_PI_2, S2Point(1, 0, 0));
+ CheckDistance(S2Point(-1, -1, 0), S2Point(1, 0, 0), S2Point(0, 1, 0),
+ 0.75 * M_PI, S2Point(0, 0, 0));
+
+ CheckDistance(S2Point(0, 1, 0), S2Point(1, 0, 0), S2Point(1, 1, 0),
+ M_PI_4, S2Point(1, 1, 0));
+ CheckDistance(S2Point(0, -1, 0), S2Point(1, 0, 0), S2Point(1, 1, 0),
+ M_PI_2, S2Point(1, 0, 0));
+
+ CheckDistance(S2Point(0, -1, 0), S2Point(1, 0, 0), S2Point(-1, 1, 0),
+ M_PI_2, S2Point(1, 0, 0));
+ CheckDistance(S2Point(-1, -1, 0), S2Point(1, 0, 0), S2Point(-1, 1, 0),
+ M_PI_2, S2Point(-1, 1, 0));
+
+ CheckDistance(S2Point(1, 1, 1), S2Point(1, 0, 0), S2Point(0, 1, 0),
+ asin(sqrt(1./3)), S2Point(1, 1, 0));
+ CheckDistance(S2Point(1, 1, -1), S2Point(1, 0, 0), S2Point(0, 1, 0),
+ asin(sqrt(1./3)), S2Point(1, 1, 0));
+
+ CheckDistance(S2Point(-1, 0, 0), S2Point(1, 1, 0), S2Point(1, 1, 0),
+ 0.75 * M_PI, S2Point(1, 1, 0));
+ CheckDistance(S2Point(0, 0, -1), S2Point(1, 1, 0), S2Point(1, 1, 0),
+ M_PI_2, S2Point(1, 1, 0));
+ CheckDistance(S2Point(-1, 0, 0), S2Point(1, 0, 0), S2Point(1, 0, 0),
+ M_PI, S2Point(1, 0, 0));
+}
+
+void CheckInterpolate(double t, S2Point a, S2Point b, S2Point expected) {
+ a = a.Normalize();
+ b = b.Normalize();
+ expected = expected.Normalize();
+ S2Point actual = S2EdgeUtil::Interpolate(t, a, b);
+
+ // We allow a bit more than the usual 1e-15 error tolerance because
+ // Interpolate() uses trig functions.
+ EXPECT_TRUE(S2::ApproxEquals(expected, actual, 3e-15))
+ << "Expected: " << expected << ", actual: " << actual;
+}
+
+TEST(S2EdgeUtil, Interpolate) {
+ // A zero-length edge.
+ CheckInterpolate(0, S2Point(1, 0, 0), S2Point(1, 0, 0), S2Point(1, 0, 0));
+ CheckInterpolate(1, S2Point(1, 0, 0), S2Point(1, 0, 0), S2Point(1, 0, 0));
+
+ // Start, end, and middle of a medium-length edge.
+ CheckInterpolate(0, S2Point(1, 0, 0), S2Point(0, 1, 0), S2Point(1, 0, 0));
+ CheckInterpolate(1, S2Point(1, 0, 0), S2Point(0, 1, 0), S2Point(0, 1, 0));
+ CheckInterpolate(0.5, S2Point(1, 0, 0), S2Point(0, 1, 0), S2Point(1, 1, 0));
+
+ // Test that interpolation is done using distances on the sphere rather than
+ // linear distances.
+ CheckInterpolate(1./3, S2Point(1, 0, 0), S2Point(0, 1, 0),
+ S2Point(sqrt(3), 1, 0));
+ CheckInterpolate(2./3, S2Point(1, 0, 0), S2Point(0, 1, 0),
+ S2Point(1, sqrt(3), 0));
+
+ // Test that interpolation is accurate on a long edge (but not so long that
+ // the definition of the edge itself becomes too unstable).
+ {
+ double const kLng = M_PI - 1e-2;
+ S2Point a = S2LatLng::FromRadians(0, 0).ToPoint();
+ S2Point b = S2LatLng::FromRadians(0, kLng).ToPoint();
+ for (double f = 0.4; f > 1e-15; f *= 0.1) {
+ CheckInterpolate(f, a, b,
+ S2LatLng::FromRadians(0, f * kLng).ToPoint());
+ CheckInterpolate(1 - f, a, b,
+ S2LatLng::FromRadians(0, (1 - f) * kLng).ToPoint());
+ }
+ }
+}
+
+TEST(S2EdgeUtil, InterpolateCanExtrapolate) {
+ const S2Point i(1, 0, 0);
+ const S2Point j(0, 1, 0);
+ // Initial vectors at 90 degrees.
+ CheckInterpolate(0, i, j, S2Point(1, 0, 0));
+ CheckInterpolate(1, i, j ,S2Point(0, 1, 0));
+ CheckInterpolate(1.5, i, j ,S2Point(-1, 1, 0));
+ CheckInterpolate(2, i, j, S2Point(-1, 0, 0));
+ CheckInterpolate(3, i, j, S2Point(0, -1, 0));
+ CheckInterpolate(4, i, j, S2Point(1, 0, 0));
+
+ // Negative values of t.
+ CheckInterpolate(-1, i, j, S2Point(0, -1, 0));
+ CheckInterpolate(-2, i, j, S2Point(-1, 0, 0));
+ CheckInterpolate(-3, i, j ,S2Point(0, 1, 0));
+ CheckInterpolate(-4, i, j, S2Point(1, 0, 0));
+
+ // Initial vectors at 45 degrees.
+ CheckInterpolate(2, i, S2Point(1, 1, 0), S2Point(0, 1, 0));
+ CheckInterpolate(3, i, S2Point(1, 1, 0), S2Point(-1, 1, 0));
+ CheckInterpolate(4, i, S2Point(1, 1, 0), S2Point(-1, 0, 0));
+
+ // Initial vectors at 135 degrees.
+ CheckInterpolate(2, i, S2Point(-1, 1, 0), S2Point(0, -1, 0));
+
+ // Take a small fraction along the curve.
+ S2Point p(S2EdgeUtil::Interpolate(0.001, i, j));
+ // We should get back where we started.
+ CheckInterpolate(1000, i, p, j);
+
+}
+
+
+TEST(S2EdgeUtil, RepeatedInterpolation) {
+ // Check that points do not drift away from unit length when repeated
+ // interpolations are done.
+ for (int i = 0; i < 100; ++i) {
+ S2Point a = S2Testing::RandomPoint();
+ S2Point b = S2Testing::RandomPoint();
+ for (int j = 0; j < 1000; ++j) {
+ a = S2EdgeUtil::Interpolate(0.01, a, b);
+ }
+ EXPECT_TRUE(S2::IsUnitLength(a));
+ }
+}
+
+TEST(S2EdgeUtil, IntersectionTolerance) {
+ // We repeatedly construct two edges that cross near a random point "p",
+ // and measure the distance from the actual intersection point "x" to the
+ // the expected intersection point "p" and also to the edges that cross
+ // near "p".
+ //
+ // Note that GetIntersection() does not guarantee that "x" and "p" will be
+ // close together (since the intersection point is numerically unstable
+ // when the edges cross at a very small angle), but it does guarantee that
+ // "x" will be close to both of the edges that cross.
+
+ S1Angle max_point_dist, max_edge_dist;
+ S2Testing::Random* rnd = &S2Testing::rnd;
+ for (int i = 0; i < 1000; ++i) {
+ // We construct two edges AB and CD that intersect near "p". The angle
+ // between AB and CD (expressed as a slope) is chosen randomly between
+ // 1e-15 and 1.0 such that its logarithm is uniformly distributed. This
+ // implies that small values are much more likely to be chosen.
+ //
+ // Once the slope is chosen, the four points ABCD must be offset from P
+ // by at least (1e-15 / slope) so that the points are guaranteed to have
+ // the correct circular ordering around P. This is the distance from P
+ // at which the two edges are separated by about 1e-15, which is
+ // approximately the minimum distance at which we can expect computed
+ // points on the two lines to be distinct and have the correct ordering.
+ //
+ // The actual offset distance from P is chosen randomly in the range
+ // [1e-15 / slope, 1.0], again uniformly distributing the logarithm.
+ // This ensures that we test both long and very short segments that
+ // intersect at both large and very small angles.
+
+ S2Point p, d1, d2;
+ S2Testing::GetRandomFrame(&p, &d1, &d2);
+ double slope = pow(1e-15, rnd->RandDouble());
+ d2 = d1 + slope * d2;
+ S2Point a = (p + pow(1e-15 / slope, rnd->RandDouble()) * d1).Normalize();
+ S2Point b = (p - pow(1e-15 / slope, rnd->RandDouble()) * d1).Normalize();
+ S2Point c = (p + pow(1e-15 / slope, rnd->RandDouble()) * d2).Normalize();
+ S2Point d = (p - pow(1e-15 / slope, rnd->RandDouble()) * d2).Normalize();
+ S2Point x = S2EdgeUtil::GetIntersection(a, b, c, d);
+ S1Angle dist_ab = S2EdgeUtil::GetDistance(x, a, b);
+ S1Angle dist_cd = S2EdgeUtil::GetDistance(x, c, d);
+ EXPECT_LE(dist_ab, S2EdgeUtil::kIntersectionTolerance);
+ EXPECT_LE(dist_cd, S2EdgeUtil::kIntersectionTolerance);
+ max_edge_dist = max(max_edge_dist, max(dist_ab, dist_cd));
+ max_point_dist = max(max_point_dist, S1Angle(p, x));
+ }
+ LOG(INFO) << "Max distance to either edge being intersected: "
+ << max_edge_dist.radians();
+ LOG(INFO) << "Maximum distance to expected intersection point: "
+ << max_point_dist.radians();
+}
+
+bool IsEdgeBNearEdgeA(string const& a_str, const string& b_str,
+ double max_error_degrees) {
+ scoped_ptr<S2Polyline> a(S2Testing::MakePolyline(a_str));
+ EXPECT_EQ(2, a->num_vertices());
+ scoped_ptr<S2Polyline> b(S2Testing::MakePolyline(b_str));
+ EXPECT_EQ(2, b->num_vertices());
+ return S2EdgeUtil::IsEdgeBNearEdgeA(a->vertex(0), a->vertex(1),
+ b->vertex(0), b->vertex(1),
+ S1Angle::Degrees(max_error_degrees));
+}
+
+TEST(S2EdgeUtil, EdgeBNearEdgeA) {
+ // Edge is near itself.
+ EXPECT_TRUE(IsEdgeBNearEdgeA("5:5, 10:-5", "5:5, 10:-5", 1e-6));
+
+ // Edge is near its reverse
+ EXPECT_TRUE(IsEdgeBNearEdgeA("5:5, 10:-5", "10:-5, 5:5", 1e-6));
+
+ // Short edge is near long edge.
+ EXPECT_TRUE(IsEdgeBNearEdgeA("10:0, -10:0", "2:1, -2:1", 1.0));
+
+ // Long edges cannot be near shorter edges.
+ EXPECT_FALSE(IsEdgeBNearEdgeA("2:1, -2:1", "10:0, -10:0", 1.0));
+
+ // Orthogonal crossing edges are not near each other...
+ EXPECT_FALSE(IsEdgeBNearEdgeA("10:0, -10:0", "0:1.5, 0:-1.5", 1.0));
+
+ // ... unless all points on B are within tolerance of A.
+ EXPECT_TRUE(IsEdgeBNearEdgeA("10:0, -10:0", "0:1.5, 0:-1.5", 2.0));
+
+ // Very long edges whose endpoints are close may have interior points that are
+ // far apart. An implementation that only considers the vertices of polylines
+ // will incorrectly consider such edges as "close" when they are not.
+ // Consider, for example, two consecutive lines of longitude. As they
+ // approach the poles, they become arbitrarily close together, but along the
+ // equator they bow apart.
+ EXPECT_FALSE(IsEdgeBNearEdgeA("89:1, -89:1", "89:2, -89:2", 0.5));
+ EXPECT_TRUE(IsEdgeBNearEdgeA("89:1, -89:1", "89:2, -89:2", 1.5));
+
+ // The two arcs here are nearly as long as S2 edges can be (just shy of 180
+ // degrees), and their endpoints are less than 1 degree apart. Their
+ // midpoints, however, are at opposite ends of the sphere along its equator.
+ EXPECT_FALSE(IsEdgeBNearEdgeA(
+ "0:-179.75, 0:-0.25", "0:179.75, 0:0.25", 1.0));
+
+ // At the equator, the second arc here is 9.75 degrees from the first, and
+ // closer at all other points. However, the southern point of the second arc
+ // (-1, 9.75) is too far from the first arc for the short-circuiting logic in
+ // IsEdgeBNearEdgeA to apply.
+ EXPECT_TRUE(IsEdgeBNearEdgeA("40:0, -5:0", "39:0.975, -1:0.975", 1.0));
+
+ // Same as above, but B's orientation is reversed, causing the angle between
+ // the normal vectors of circ(B) and circ(A) to be (180-9.75) = 170.5 degrees,
+ // not 9.75 degrees. The greatest separation between the planes is still 9.75
+ // degrees.
+ EXPECT_TRUE(IsEdgeBNearEdgeA("10:0, -10:0", "-.4:0.975, 0.4:0.975", 1.0));
+
+ // A and B are on the same great circle, A and B partially overlap, but the
+ // only part of B that does not overlap A is shorter than tolerance.
+ EXPECT_TRUE(IsEdgeBNearEdgeA("0:0, 1:0", "0.9:0, 1.1:0", 0.25));
+
+ // A and B are on the same great circle, all points on B are close to A at its
+ // second endpoint, (1,0).
+ EXPECT_TRUE(IsEdgeBNearEdgeA("0:0, 1:0", "1.1:0, 1.2:0", 0.25));
+
+ // Same as above, but B's orientation is reversed. This case is special
+ // because the projection of the normal defining A onto the plane containing B
+ // is the null vector, and must be handled by a special case.
+ EXPECT_TRUE(IsEdgeBNearEdgeA("0:0, 1:0", "1.2:0, 1.1:0", 0.25));
+}
+
+
+TEST(S2EdgeUtil, CollinearEdgesThatDontTouch) {
+ const int kIters = 1000;
+ for (int iter = 0; iter < kIters; ++iter) {
+ S2Point a = S2Testing::RandomPoint();
+ S2Point d = S2Testing::RandomPoint();
+ S2Point b = S2EdgeUtil::Interpolate(0.05, a, d);
+ S2Point c = S2EdgeUtil::Interpolate(0.95, a, d);
+ EXPECT_GT(0, S2EdgeUtil::RobustCrossing(a, b, c, d));
+ EXPECT_GT(0, S2EdgeUtil::RobustCrossing(a, b, c, d));
+ S2EdgeUtil::EdgeCrosser crosser(&a, &b, &c);
+ EXPECT_GT(0, crosser.RobustCrossing(&d));
+ EXPECT_GT(0, crosser.RobustCrossing(&c));
+ }
+}
+
+
+TEST(S2EdgeUtil, CoincidentZeroLengthEdgesThatDontTouch) {
+ // Since normalization is not perfect, and vertices are not always perfectly
+ // normalized anyway for various reasons, it is important that the edge
+ // primitives can handle vertices that exactly coincident when projected
+ // onto the unit sphere but that are not identical.
+ //
+ // This test checks pairs of edges AB and CD where A,B,C,D are exactly
+ // coincident on the sphere and the norms of A,B,C,D are monotonically
+ // increasing. Such edge pairs should never intersect. (This is not
+ // obvious, since it depends on the particular symbolic perturbations used
+ // by S2::RobustCCW(). It would be better to replace this with a test that
+ // says that the CCW results must be consistent with each other.)
+ const int kIters = 1000;
+ for (int iter = 0; iter < kIters; ++iter) {
+ // Construct a point P where every component is zero or a power of 2.
+ S2Point p;
+ for (int i = 0; i < 2; ++i) {
+ int binary_exp = S2Testing::rnd.Skewed(11);
+ p[i] = (binary_exp > 1022) ? 0 : pow(2, -binary_exp);
+ }
+ // If all components were zero, try again. Note that normalization may
+ // convert a non-zero point into a zero one due to underflow (!)
+ p = p.Normalize();
+ if (p == S2Point(0, 0, 0)) { --iter; continue; }
+
+ // Now every non-zero component should have exactly the same mantissa.
+ // This implies that if we scale the point by an arbitrary factor, every
+ // non-zero component will still have the same mantissa. Scale the points
+ // so that they are all distinct and yet still satisfy S2::IsNormalized().
+ S2Point a = (1-3e-16) * p;
+ S2Point b = (1-1e-16) * p;
+ S2Point c = p;
+ S2Point d = (1+2e-16) * p;
+
+ // Verify that the expected edges do not cross.
+ EXPECT_GT(0, S2EdgeUtil::RobustCrossing(a, b, c, d));
+ S2EdgeUtil::EdgeCrosser crosser(&a, &b, &c);
+ EXPECT_GT(0, crosser.RobustCrossing(&d));
+ EXPECT_GT(0, crosser.RobustCrossing(&c));
+ }
+}
+
+
+static void BM_RobustCrosserEdgesCross(int iters) {
+ // Copied from BenchmarkCrossing() above.
+ StopBenchmarkTiming();
+ static const int kNumPoints = 400;
+ vector<S2Point> p(kNumPoints);
+ for (int i = 0; i < kNumPoints; ++i) p[i] = S2Testing::RandomPoint();
+ // 1/4th of the points will cross ab.
+ const S2Point& a = S2Testing::RandomPoint();
+ const S2Point& b = (-a + S2Point(0.1, 0.1, 0.1)).Normalize();
+ StartBenchmarkTiming();
+
+ S2EdgeUtil::EdgeCrosser crosser(&a, &b, &p[0]);
+ int num_crossings = 0;
+ for (int i = 0; i < iters; ++i) {
+ const S2Point& d = p[i % kNumPoints];
+
+ if (crosser.RobustCrossing(&d) > 0)
+ ++num_crossings;
+ }
+ VLOG(5) << "Fraction crossing = " << 1.0 * num_crossings / iters;
+ VLOG(5) << "num_crossings = " << num_crossings;
+}
+BENCHMARK(BM_RobustCrosserEdgesCross);
+
+
+} // namespace
diff --git a/src/third_party/s2/s2latlng.cc b/src/third_party/s2/s2latlng.cc
new file mode 100644
index 00000000000..d0fab58668e
--- /dev/null
+++ b/src/third_party/s2/s2latlng.cc
@@ -0,0 +1,71 @@
+// Copyright 2005 Google Inc. All Rights Reserved.
+#include "s2.h"
+#include "base/logging.h"
+#include "strings/stringprintf.h"
+#include "s2latlng.h"
+
+S2LatLng S2LatLng::Normalized() const {
+ // drem(x, 2 * M_PI) reduces its argument to the range [-M_PI, M_PI]
+ // inclusive, which is what we want here.
+ return S2LatLng(max(-M_PI_2, min(M_PI_2, lat().radians())),
+ drem(lng().radians(), 2 * M_PI));
+}
+
+S2Point S2LatLng::ToPoint() const {
+ DCHECK(is_valid());
+ // As of crosstool v14, gcc tries to calculate sin(phi), cos(phi),
+ // sin(theta), cos(theta) on the following section by two sincos()
+ // calls. However, for some inputs, sincos() returns significantly
+ // different values between AMD and Intel.
+ //
+ // As a temporary workaround, "volatile" is added to phi and theta
+ // to prohibit the compiler to use such sincos() call, because sin()
+ // and cos() don't seem to have the problem. See b/3088321 for
+ // details.
+ volatile double phi = lat().radians();
+ volatile double theta = lng().radians();
+ double cosphi = cos(phi);
+ return S2Point(cos(theta) * cosphi, sin(theta) * cosphi, sin(phi));
+}
+
+S2LatLng::S2LatLng(S2Point const& p)
+ : coords_(Latitude(p).radians(), Longitude(p).radians()) {
+ // The latitude and longitude are already normalized.
+ DCHECK(is_valid());
+}
+
+S1Angle S2LatLng::GetDistance(S2LatLng const& o) const {
+ // This implements the Haversine formula, which is numerically stable for
+ // small distances but only gets about 8 digits of precision for very large
+ // distances (e.g. antipodal points). Note that 8 digits is still accurate
+ // to within about 10cm for a sphere the size of the Earth.
+ //
+ // This could be fixed with another sin() and cos() below, but at that point
+ // you might as well just convert both arguments to S2Points and compute the
+ // distance that way (which gives about 15 digits of accuracy for all
+ // distances).
+
+ DCHECK(is_valid());
+ DCHECK(o.is_valid());
+ double lat1 = lat().radians();
+ double lat2 = o.lat().radians();
+ double lng1 = lng().radians();
+ double lng2 = o.lng().radians();
+ double dlat = sin(0.5 * (lat2 - lat1));
+ double dlng = sin(0.5 * (lng2 - lng1));
+ double x = dlat * dlat + dlng * dlng * cos(lat1) * cos(lat2);
+ return S1Angle::Radians(2 * atan2(sqrt(x), sqrt(max(0.0, 1.0 - x))));
+}
+
+string S2LatLng::ToStringInDegrees() const {
+ S2LatLng pt = Normalized();
+ return StringPrintf("%f,%f", pt.lat().degrees(), pt.lng().degrees());
+}
+
+void S2LatLng::ToStringInDegrees(string* s) const {
+ *s = ToStringInDegrees();
+}
+
+ostream& operator<<(ostream& os, S2LatLng const& ll) {
+ return os << "[" << ll.lat() << ", " << ll.lng() << "]";
+}
diff --git a/src/third_party/s2/s2latlng.h b/src/third_party/s2/s2latlng.h
new file mode 100644
index 00000000000..88f1214b8f3
--- /dev/null
+++ b/src/third_party/s2/s2latlng.h
@@ -0,0 +1,191 @@
+// Copyright 2005 Google Inc. All Rights Reserved.
+
+#ifndef UTIL_GEOMETRY_S2LATLNG_H__
+#define UTIL_GEOMETRY_S2LATLNG_H__
+
+#include <string>
+using std::string;
+
+#include <ostream>
+#include "base/basictypes.h"
+#include "s1angle.h"
+#include "s2.h"
+#include "util/math/vector2-inl.h"
+
+// This class represents a point on the unit sphere as a pair
+// of latitude-longitude coordinates. Like the rest of the "geometry"
+// package, the intent is to represent spherical geometry as a mathematical
+// abstraction, so functions that are specifically related to the Earth's
+// geometry (e.g. easting/northing conversions) should be put elsewhere.
+//
+// This class is intended to be copied by value as desired. It uses
+// the default copy constructor and assignment operator.
+class S2LatLng {
+ public:
+ // Constructor. The latitude and longitude are allowed to be outside
+ // the is_valid() range. However, note that most methods that accept
+ // S2LatLngs expect them to be normalized (see Normalized() below).
+ inline S2LatLng(S1Angle const& lat, S1Angle const& lng);
+
+ // The default constructor sets the latitude and longitude to zero. This is
+ // mainly useful when declaring arrays, STL containers, etc.
+ inline S2LatLng();
+
+ // Convert a direction vector (not necessarily unit length) to an S2LatLng.
+ explicit S2LatLng(S2Point const& p);
+
+ // Returns an S2LatLng for which is_valid() will return false.
+ inline static S2LatLng Invalid();
+
+ // Convenience functions -- shorter than calling S1Angle::Radians(), etc.
+ inline static S2LatLng FromRadians(double lat_radians, double lng_radians);
+ inline static S2LatLng FromDegrees(double lat_degrees, double lng_degrees);
+ inline static S2LatLng FromE5(int32 lat_e5, int32 lng_e5);
+ inline static S2LatLng FromE6(int32 lat_e6, int32 lng_e6);
+ inline static S2LatLng FromE7(int32 lat_e7, int32 lng_e7);
+
+ // Convenience functions -- to use when args have been fixed32s in protos.
+ //
+ // The arguments are static_cast into int32, so very large unsigned values
+ // are treated as negative numbers.
+ inline static S2LatLng FromUnsignedE6(uint32 lat_e6, uint32 lng_e6);
+ inline static S2LatLng FromUnsignedE7(uint32 lat_e7, uint32 lng_e7);
+
+ // Methods to compute the latitude and longitude of a point separately.
+ inline static S1Angle Latitude(S2Point const& p);
+ inline static S1Angle Longitude(S2Point const& p);
+
+ // Accessor methods.
+ S1Angle lat() const { return S1Angle::Radians(coords_[0]); }
+ S1Angle lng() const { return S1Angle::Radians(coords_[1]); }
+ Vector2_d const& coords() const { return coords_; }
+
+ // Return true if the latitude is between -90 and 90 degrees inclusive
+ // and the longitude is between -180 and 180 degrees inclusive.
+ inline bool is_valid() const;
+
+ // Clamps the latitude to the range [-90, 90] degrees, and adds or subtracts
+ // a multiple of 360 degrees to the longitude if necessary to reduce it to
+ // the range [-180, 180].
+ S2LatLng Normalized() const;
+
+ // Convert a normalized S2LatLng to the equivalent unit-length vector.
+ S2Point ToPoint() const;
+
+ // Return the distance (measured along the surface of the sphere) to the
+ // given S2LatLng. This is mathematically equivalent to:
+ //
+ // S1Angle::Radians(ToPoint().Angle(o.ToPoint()))
+ //
+ // but this implementation is slightly more efficient. Both S2LatLngs
+ // must be normalized.
+ S1Angle GetDistance(S2LatLng const& o) const;
+
+ // Simple arithmetic operations for manipulating latitude-longitude pairs.
+ // The results are not normalized (see Normalized()).
+ friend inline S2LatLng operator+(S2LatLng const& a, S2LatLng const& b);
+ friend inline S2LatLng operator-(S2LatLng const& a, S2LatLng const& b);
+ friend inline S2LatLng operator*(double m, S2LatLng const& a);
+ friend inline S2LatLng operator*(S2LatLng const& a, double m);
+
+ bool operator==(S2LatLng const& o) const { return coords_ == o.coords_; }
+ bool operator!=(S2LatLng const& o) const { return coords_ != o.coords_; }
+ bool operator<(S2LatLng const& o) const { return coords_ < o.coords_; }
+ bool operator>(S2LatLng const& o) const { return coords_ > o.coords_; }
+ bool operator<=(S2LatLng const& o) const { return coords_ <= o.coords_; }
+ bool operator>=(S2LatLng const& o) const { return coords_ >= o.coords_; }
+
+ bool ApproxEquals(S2LatLng const& o, double max_error = 1e-15) const {
+ return coords_.aequal(o.coords_, max_error);
+ }
+
+ // Export the latitude and longitude in degrees, separated by a comma.
+ // e.g. "94.518000,150.300000"
+ string ToStringInDegrees() const;
+ void ToStringInDegrees(string* s) const;
+ string toString() const { return ToStringInDegrees(); }
+
+ private:
+ // Internal constructor.
+ inline S2LatLng(Vector2_d const& coords) : coords_(coords) {}
+
+ // This is internal to avoid ambiguity about which units are expected.
+ inline S2LatLng(double lat_radians, double lng_radians)
+ : coords_(lat_radians, lng_radians) {}
+
+ Vector2_d coords_;
+};
+DECLARE_POD(S2LatLng);
+
+inline S2LatLng::S2LatLng(S1Angle const& lat, S1Angle const& lng)
+ : coords_(lat.radians(), lng.radians()) {}
+
+inline S2LatLng::S2LatLng() : coords_(0, 0) {}
+
+inline S2LatLng S2LatLng::FromRadians(double lat_radians, double lng_radians) {
+ return S2LatLng(lat_radians, lng_radians);
+}
+
+inline S2LatLng S2LatLng::FromDegrees(double lat_degrees, double lng_degrees) {
+ return S2LatLng(S1Angle::Degrees(lat_degrees), S1Angle::Degrees(lng_degrees));
+}
+
+inline S2LatLng S2LatLng::FromE5(int32 lat_e5, int32 lng_e5) {
+ return S2LatLng(S1Angle::E5(lat_e5), S1Angle::E5(lng_e5));
+}
+
+inline S2LatLng S2LatLng::FromE6(int32 lat_e6, int32 lng_e6) {
+ return S2LatLng(S1Angle::E6(lat_e6), S1Angle::E6(lng_e6));
+}
+
+inline S2LatLng S2LatLng::FromE7(int32 lat_e7, int32 lng_e7) {
+ return S2LatLng(S1Angle::E7(lat_e7), S1Angle::E7(lng_e7));
+}
+
+inline S2LatLng S2LatLng::FromUnsignedE6(uint32 lat_e6, uint32 lng_e6) {
+ return S2LatLng(S1Angle::UnsignedE6(lat_e6), S1Angle::UnsignedE6(lng_e6));
+}
+
+inline S2LatLng S2LatLng::FromUnsignedE7(uint32 lat_e7, uint32 lng_e7) {
+ return S2LatLng(S1Angle::UnsignedE7(lat_e7), S1Angle::UnsignedE7(lng_e7));
+}
+
+inline S2LatLng S2LatLng::Invalid() {
+ // These coordinates are outside the bounds allowed by is_valid().
+ return S2LatLng(M_PI, 2 * M_PI);
+}
+
+inline S1Angle S2LatLng::Latitude(S2Point const& p) {
+ // We use atan2 rather than asin because the input vector is not necessarily
+ // unit length, and atan2 is much more accurate than asin near the poles.
+ return S1Angle::Radians(atan2(p[2], sqrt(p[0]*p[0] + p[1]*p[1])));
+}
+
+inline S1Angle S2LatLng::Longitude(S2Point const& p) {
+ // Note that atan2(0, 0) is defined to be zero.
+ return S1Angle::Radians(atan2(p[1], p[0]));
+}
+
+inline bool S2LatLng::is_valid() const {
+ return fabs(lat().radians()) <= M_PI_2 && fabs(lng().radians()) <= M_PI;
+}
+
+inline S2LatLng operator+(S2LatLng const& a, S2LatLng const& b) {
+ return S2LatLng(a.coords_ + b.coords_);
+}
+
+inline S2LatLng operator-(S2LatLng const& a, S2LatLng const& b) {
+ return S2LatLng(a.coords_ - b.coords_);
+}
+
+inline S2LatLng operator*(double m, S2LatLng const& a) {
+ return S2LatLng(m * a.coords_);
+}
+
+inline S2LatLng operator*(S2LatLng const& a, double m) {
+ return S2LatLng(m * a.coords_);
+}
+
+ostream& operator<<(ostream& os, S2LatLng const& ll);
+
+#endif // UTIL_GEOMETRY_S2LATLNG_H__
diff --git a/src/third_party/s2/s2latlng_test.cc b/src/third_party/s2/s2latlng_test.cc
new file mode 100644
index 00000000000..68ae7739a70
--- /dev/null
+++ b/src/third_party/s2/s2latlng_test.cc
@@ -0,0 +1,136 @@
+// Copyright 2005 Google Inc. All Rights Reserved.
+
+#include "s2latlng.h"
+#include "base/macros.h"
+#include "base/stringprintf.h"
+#include "strings/split.h"
+#include "testing/base/public/gunit.h"
+#include "testing/base/public/benchmark.h"
+#include "s2testing.h"
+
+TEST(S2LatLng, TestBasic) {
+ S2LatLng ll_rad = S2LatLng::FromRadians(M_PI_4, M_PI_2);
+ EXPECT_EQ(M_PI_4, ll_rad.lat().radians());
+ EXPECT_EQ(M_PI_2, ll_rad.lng().radians());
+ EXPECT_TRUE(ll_rad.is_valid());
+ S2LatLng ll_deg = S2LatLng::FromDegrees(45, 90);
+ EXPECT_EQ(ll_rad, ll_deg);
+ EXPECT_TRUE(ll_deg.is_valid());
+ EXPECT_FALSE(S2LatLng::FromDegrees(-91, 0).is_valid());
+ EXPECT_FALSE(S2LatLng::FromDegrees(0, 181).is_valid());
+
+ S2LatLng bad = S2LatLng::FromDegrees(120, 200);
+ EXPECT_FALSE(bad.is_valid());
+ S2LatLng better = bad.Normalized();
+ EXPECT_TRUE(better.is_valid());
+ EXPECT_EQ(S1Angle::Degrees(90), better.lat());
+ EXPECT_DOUBLE_EQ(S1Angle::Degrees(-160).radians(), better.lng().radians());
+
+ bad = S2LatLng::FromDegrees(-100, -360);
+ EXPECT_FALSE(bad.is_valid());
+ better = bad.Normalized();
+ EXPECT_TRUE(better.is_valid());
+ EXPECT_EQ(S1Angle::Degrees(-90), better.lat());
+ EXPECT_DOUBLE_EQ(0.0, better.lng().radians());
+
+ EXPECT_TRUE((S2LatLng::FromDegrees(10, 20) + S2LatLng::FromDegrees(20, 30)).
+ ApproxEquals(S2LatLng::FromDegrees(30, 50)));
+ EXPECT_TRUE((S2LatLng::FromDegrees(10, 20) - S2LatLng::FromDegrees(20, 30)).
+ ApproxEquals(S2LatLng::FromDegrees(-10, -10)));
+ EXPECT_TRUE((0.5 * S2LatLng::FromDegrees(10, 20)).
+ ApproxEquals(S2LatLng::FromDegrees(5, 10)));
+
+ // Check that Invalid() returns an invalid point.
+ S2LatLng invalid = S2LatLng::Invalid();
+ EXPECT_FALSE(invalid.is_valid());
+
+ // Check that the default constructor sets latitude and longitude to 0.
+ S2LatLng default_ll;
+ EXPECT_TRUE(default_ll.is_valid());
+ EXPECT_EQ(0, default_ll.lat().radians());
+ EXPECT_EQ(0, default_ll.lng().radians());
+}
+
+TEST(S2LatLng, TestConversion) {
+ // Test special cases: poles, "date line"
+ EXPECT_DOUBLE_EQ(90.0,
+ S2LatLng(S2LatLng::FromDegrees(90.0, 65.0).ToPoint())
+ .lat().degrees());
+ EXPECT_EQ(-M_PI_2,
+ S2LatLng(S2LatLng::FromRadians(-M_PI_2, 1).ToPoint())
+ .lat().radians());
+ EXPECT_DOUBLE_EQ(180.0,
+ fabs(S2LatLng(S2LatLng::FromDegrees(12.2, 180.0).ToPoint())
+ .lng().degrees()));
+ EXPECT_EQ(M_PI,
+ fabs(S2LatLng(S2LatLng::FromRadians(0.1, -M_PI).ToPoint())
+ .lng().radians()));
+
+ // Test a bunch of random points.
+ for (int i = 0; i < 100000; ++i) {
+ S2Point p = S2Testing::RandomPoint();
+ EXPECT_TRUE(S2::ApproxEquals(p, S2LatLng(p).ToPoint())) << p;
+ }
+}
+
+TEST(S2LatLng, TestDistance) {
+ EXPECT_EQ(0.0,
+ S2LatLng::FromDegrees(90, 0).GetDistance(
+ S2LatLng::FromDegrees(90, 0)).radians());
+ EXPECT_NEAR(77.0,
+ S2LatLng::FromDegrees(-37, 25).GetDistance(
+ S2LatLng::FromDegrees(-66, -155)).degrees(),
+ 1e-13);
+ EXPECT_NEAR(115.0,
+ S2LatLng::FromDegrees(0, 165).GetDistance(
+ S2LatLng::FromDegrees(0, -80)).degrees(),
+ 1e-13);
+ EXPECT_NEAR(180.0,
+ S2LatLng::FromDegrees(47, -127).GetDistance(
+ S2LatLng::FromDegrees(-47, 53)).degrees(),
+ 2e-6);
+}
+
+TEST(S2LatLng, TestToString) {
+ struct {
+ double lat, lng;
+ double expected_lat, expected_lng;
+ } values[] = {
+ {0, 0, 0, 0},
+ {1.5, 91.7, 1.5, 91.7},
+ {9.9, -0.31, 9.9, -0.31},
+ {sqrt(2), -sqrt(5), 1.414214, -2.236068},
+ {91.3, 190.4, 90, -169.6},
+ {-100, -710, -90, 10},
+ };
+ for (int i = 0; i < ARRAYSIZE(values); ++i) {
+ SCOPED_TRACE(StringPrintf("Iteration %d", i));
+ S2LatLng p = S2LatLng::FromDegrees(values[i].lat, values[i].lng);
+ string output;
+ p.ToStringInDegrees(&output);
+
+ const char *ptr = output.c_str();
+ double lat, lng;
+ EXPECT_TRUE(SplitOneDoubleToken(&ptr, ",", &lat));
+ ASSERT_TRUE(ptr != NULL);
+ EXPECT_TRUE(SplitOneDoubleToken(&ptr, ",", &lng));
+ EXPECT_NEAR(values[i].expected_lat, lat, 1e-8);
+ EXPECT_NEAR(values[i].expected_lng, lng, 1e-8);
+ }
+}
+
+// Test the variant that returns a string.
+TEST(S2LatLng, TestToStringReturnsString) {
+ string s;
+ S2LatLng::FromDegrees(0, 1).ToStringInDegrees(&s);
+ EXPECT_EQ(S2LatLng::FromDegrees(0, 1).ToStringInDegrees(), s);
+}
+
+
+static void BM_ToPoint(int iters) {
+ S2LatLng ll(S1Angle::E7(0x150bc888), S1Angle::E7(0x5099d63f));
+ for (int i = 0; i < iters; i++) {
+ ll.ToPoint();
+ }
+}
+BENCHMARK(BM_ToPoint);
diff --git a/src/third_party/s2/s2latlngrect.cc b/src/third_party/s2/s2latlngrect.cc
new file mode 100644
index 00000000000..26e34bb14a8
--- /dev/null
+++ b/src/third_party/s2/s2latlngrect.cc
@@ -0,0 +1,591 @@
+// Copyright 2005 Google Inc. All Rights Reserved.
+
+#include <algorithm>
+using std::min;
+using std::max;
+using std::swap;
+using std::reverse;
+
+
+#include "s2latlngrect.h"
+
+#include "base/logging.h"
+#include "util/coding/coder.h"
+#include "s2cap.h"
+#include "s2cell.h"
+#include "s2edgeutil.h"
+#include "util/math/mathutil.h"
+
+static const unsigned char kCurrentEncodingVersionNumber = 1;
+
+S2LatLngRect S2LatLngRect::FromCenterSize(S2LatLng const& center,
+ S2LatLng const& size) {
+ return FromPoint(center).Expanded(0.5 * size);
+}
+
+S2LatLngRect S2LatLngRect::FromPoint(S2LatLng const& p) {
+ DCHECK(p.is_valid());
+ return S2LatLngRect(p, p);
+}
+
+S2LatLngRect S2LatLngRect::FromPointPair(S2LatLng const& p1,
+ S2LatLng const& p2) {
+ DCHECK(p1.is_valid()) << p1;
+ DCHECK(p2.is_valid()) << p2;
+ return S2LatLngRect(R1Interval::FromPointPair(p1.lat().radians(),
+ p2.lat().radians()),
+ S1Interval::FromPointPair(p1.lng().radians(),
+ p2.lng().radians()));
+}
+
+S2LatLngRect* S2LatLngRect::Clone() const {
+ return new S2LatLngRect(*this);
+}
+
+S2LatLng S2LatLngRect::GetVertex(int k) const {
+ // Twiddle bits to return the points in CCW order (SW, SE, NE, NW).
+ return S2LatLng::FromRadians(lat_.bound(k>>1), lng_.bound((k>>1) ^ (k&1)));
+}
+
+S2LatLng S2LatLngRect::GetCenter() const {
+ return S2LatLng::FromRadians(lat_.GetCenter(), lng_.GetCenter());
+}
+
+S2LatLng S2LatLngRect::GetSize() const {
+ return S2LatLng::FromRadians(lat_.GetLength(), lng_.GetLength());
+}
+
+double S2LatLngRect::Area() const {
+ if (is_empty()) return 0.0;
+ // This is the size difference of the two spherical caps, multiplied by
+ // the longitude ratio.
+ return lng().GetLength()* fabs(sin(lat_hi().radians()) -
+ sin(lat_lo().radians()));
+}
+
+bool S2LatLngRect::Contains(S2LatLng const& ll) const {
+ DCHECK(ll.is_valid());
+ return (lat_.Contains(ll.lat().radians()) &&
+ lng_.Contains(ll.lng().radians()));
+}
+
+bool S2LatLngRect::InteriorContains(S2Point const& p) const {
+ return InteriorContains(S2LatLng(p));
+}
+
+bool S2LatLngRect::InteriorContains(S2LatLng const& ll) const {
+ DCHECK(ll.is_valid());
+ return (lat_.InteriorContains(ll.lat().radians()) &&
+ lng_.InteriorContains(ll.lng().radians()));
+}
+
+bool S2LatLngRect::Contains(S2LatLngRect const& other) const {
+ return lat_.Contains(other.lat_) && lng_.Contains(other.lng_);
+}
+
+bool S2LatLngRect::InteriorContains(S2LatLngRect const& other) const {
+ return (lat_.InteriorContains(other.lat_) &&
+ lng_.InteriorContains(other.lng_));
+}
+
+bool S2LatLngRect::Intersects(S2LatLngRect const& other) const {
+ return lat_.Intersects(other.lat_) && lng_.Intersects(other.lng_);
+}
+
+bool S2LatLngRect::InteriorIntersects(S2LatLngRect const& other) const {
+ return (lat_.InteriorIntersects(other.lat_) &&
+ lng_.InteriorIntersects(other.lng_));
+}
+
+void S2LatLngRect::AddPoint(S2Point const& p) {
+ AddPoint(S2LatLng(p));
+}
+
+void S2LatLngRect::AddPoint(S2LatLng const& ll) {
+ DCHECK(ll.is_valid());
+ lat_.AddPoint(ll.lat().radians());
+ lng_.AddPoint(ll.lng().radians());
+}
+
+S2LatLngRect S2LatLngRect::Expanded(S2LatLng const& margin) const {
+ DCHECK_GE(margin.lat().radians(), 0);
+ DCHECK_GE(margin.lng().radians(), 0);
+ return S2LatLngRect(
+ lat_.Expanded(margin.lat().radians()).Intersection(FullLat()),
+ lng_.Expanded(margin.lng().radians()));
+}
+
+S2LatLngRect S2LatLngRect::Union(S2LatLngRect const& other) const {
+ return S2LatLngRect(lat_.Union(other.lat_),
+ lng_.Union(other.lng_));
+}
+
+S2LatLngRect S2LatLngRect::Intersection(S2LatLngRect const& other) const {
+ R1Interval lat = lat_.Intersection(other.lat_);
+ S1Interval lng = lng_.Intersection(other.lng_);
+ if (lat.is_empty() || lng.is_empty()) {
+ // The lat/lng ranges must either be both empty or both non-empty.
+ return Empty();
+ }
+ return S2LatLngRect(lat, lng);
+}
+
+S2LatLngRect S2LatLngRect::ConvolveWithCap(S1Angle const& angle) const {
+ // The most straightforward approach is to build a cap centered on each
+ // vertex and take the union of all the bounding rectangles (including the
+ // original rectangle; this is necessary for very large rectangles).
+
+ // Optimization: convert the angle to a height exactly once.
+ S2Cap cap = S2Cap::FromAxisAngle(S2Point(1, 0, 0), angle);
+
+ S2LatLngRect r = *this;
+ for (int k = 0; k < 4; ++k) {
+ S2Cap vertex_cap = S2Cap::FromAxisHeight(GetVertex(k).ToPoint(),
+ cap.height());
+ r = r.Union(vertex_cap.GetRectBound());
+ }
+ return r;
+}
+
+S2Cap S2LatLngRect::GetCapBound() const {
+ // We consider two possible bounding caps, one whose axis passes
+ // through the center of the lat-long rectangle and one whose axis
+ // is the north or south pole. We return the smaller of the two caps.
+
+ if (is_empty()) return S2Cap::Empty();
+
+ double pole_z, pole_angle;
+ if (lat_.lo() + lat_.hi() < 0) {
+ // South pole axis yields smaller cap.
+ pole_z = -1;
+ pole_angle = M_PI_2 + lat_.hi();
+ } else {
+ pole_z = 1;
+ pole_angle = M_PI_2 - lat_.lo();
+ }
+ S2Cap pole_cap = S2Cap::FromAxisAngle(S2Point(0, 0, pole_z),
+ S1Angle::Radians(pole_angle));
+
+ // For bounding rectangles that span 180 degrees or less in longitude, the
+ // maximum cap size is achieved at one of the rectangle vertices. For
+ // rectangles that are larger than 180 degrees, we punt and always return a
+ // bounding cap centered at one of the two poles.
+ double lng_span = lng_.hi() - lng_.lo();
+ if (drem(lng_span, 2 * M_PI) >= 0) {
+ if (lng_span < 2 * M_PI) {
+ S2Cap mid_cap = S2Cap::FromAxisAngle(GetCenter().ToPoint(),
+ S1Angle::Radians(0));
+ for (int k = 0; k < 4; ++k) {
+ mid_cap.AddPoint(GetVertex(k).ToPoint());
+ }
+ if (mid_cap.height() < pole_cap.height())
+ return mid_cap;
+ }
+ }
+ return pole_cap;
+}
+
+S2LatLngRect S2LatLngRect::GetRectBound() const {
+ return *this;
+}
+
+bool S2LatLngRect::Contains(S2Cell const& cell) const {
+ // A latitude-longitude rectangle contains a cell if and only if it contains
+ // the cell's bounding rectangle. This test is exact from a mathematical
+ // point of view, assuming that the bounds returned by S2Cell::GetRectBound()
+ // are tight. However, note that there can be a loss of precision when
+ // converting between representations -- for example, if an S2Cell is
+ // converted to a polygon, the polygon's bounding rectangle may not contain
+ // the cell's bounding rectangle. This has some slightly unexpected side
+ // effects; for instance, if one creates an S2Polygon from an S2Cell, the
+ // polygon will contain the cell, but the polygon's bounding box will not.
+ return Contains(cell.GetRectBound());
+}
+
+bool S2LatLngRect::MayIntersect(S2Cell const& cell) const {
+ // This test is cheap but is NOT exact (see s2latlngrect.h).
+ return Intersects(cell.GetRectBound());
+}
+
+void S2LatLngRect::Encode(Encoder* encoder) const {
+ encoder->Ensure(40); // sufficient
+
+ encoder->put8(kCurrentEncodingVersionNumber);
+ encoder->putdouble(lat_.lo());
+ encoder->putdouble(lat_.hi());
+ encoder->putdouble(lng_.lo());
+ encoder->putdouble(lng_.hi());
+
+ DCHECK_GE(encoder->avail(), 0);
+}
+
+bool S2LatLngRect::Decode(Decoder* decoder) {
+ unsigned char version = decoder->get8();
+ if (version > kCurrentEncodingVersionNumber) return false;
+
+ double lat_lo = decoder->getdouble();
+ double lat_hi = decoder->getdouble();
+ lat_ = R1Interval(lat_lo, lat_hi);
+ double lng_lo = decoder->getdouble();
+ double lng_hi = decoder->getdouble();
+ lng_ = S1Interval(lng_lo, lng_hi);
+
+ DCHECK(is_valid());
+
+ return decoder->avail() >= 0;
+}
+
+bool S2LatLngRect::IntersectsLngEdge(S2Point const& a, S2Point const& b,
+ R1Interval const& lat, double lng) {
+ // Return true if the segment AB intersects the given edge of constant
+ // longitude. The nice thing about edges of constant longitude is that
+ // they are straight lines on the sphere (geodesics).
+
+ return S2EdgeUtil::SimpleCrossing(
+ a, b, S2LatLng::FromRadians(lat.lo(), lng).ToPoint(),
+ S2LatLng::FromRadians(lat.hi(), lng).ToPoint());
+}
+
+bool S2LatLngRect::IntersectsLatEdge(S2Point const& a, S2Point const& b,
+ double lat, S1Interval const& lng) {
+ // Return true if the segment AB intersects the given edge of constant
+ // latitude. Unfortunately, lines of constant latitude are curves on
+ // the sphere. They can intersect a straight edge in 0, 1, or 2 points.
+ DCHECK(S2::IsUnitLength(a));
+ DCHECK(S2::IsUnitLength(b));
+
+ // First, compute the normal to the plane AB that points vaguely north.
+ S2Point z = S2::RobustCrossProd(a, b).Normalize();
+ if (z[2] < 0) z = -z;
+
+ // Extend this to an orthonormal frame (x,y,z) where x is the direction
+ // where the great circle through AB achieves its maximium latitude.
+ S2Point y = S2::RobustCrossProd(z, S2Point(0, 0, 1)).Normalize();
+ S2Point x = y.CrossProd(z);
+ DCHECK(S2::IsUnitLength(x));
+ DCHECK_GE(x[2], 0);
+
+ // Compute the angle "theta" from the x-axis (in the x-y plane defined
+ // above) where the great circle intersects the given line of latitude.
+ double sin_lat = sin(lat);
+ if (fabs(sin_lat) >= x[2]) {
+ return false; // The great circle does not reach the given latitude.
+ }
+ DCHECK_GT(x[2], 0);
+ double cos_theta = sin_lat / x[2];
+ double sin_theta = sqrt(1 - cos_theta * cos_theta);
+ double theta = atan2(sin_theta, cos_theta);
+
+ // The candidate intersection points are located +/- theta in the x-y
+ // plane. For an intersection to be valid, we need to check that the
+ // intersection point is contained in the interior of the edge AB and
+ // also that it is contained within the given longitude interval "lng".
+
+ // Compute the range of theta values spanned by the edge AB.
+ S1Interval ab_theta = S1Interval::FromPointPair(
+ atan2(a.DotProd(y), a.DotProd(x)),
+ atan2(b.DotProd(y), b.DotProd(x)));
+
+ if (ab_theta.Contains(theta)) {
+ // Check if the intersection point is also in the given "lng" interval.
+ S2Point isect = x * cos_theta + y * sin_theta;
+ if (lng.Contains(atan2(isect[1], isect[0]))) return true;
+ }
+ if (ab_theta.Contains(-theta)) {
+ // Check if the intersection point is also in the given "lng" interval.
+ S2Point isect = x * cos_theta - y * sin_theta;
+ if (lng.Contains(atan2(isect[1], isect[0]))) return true;
+ }
+ return false;
+}
+
+bool S2LatLngRect::Intersects(S2Cell const& cell) const {
+ // First we eliminate the cases where one region completely contains the
+ // other. Once these are disposed of, then the regions will intersect
+ // if and only if their boundaries intersect.
+
+ if (is_empty()) return false;
+ if (Contains(cell.GetCenterRaw())) return true;
+ if (cell.Contains(GetCenter().ToPoint())) return true;
+
+ // Quick rejection test (not required for correctness).
+ if (!Intersects(cell.GetRectBound())) return false;
+
+ // Precompute the cell vertices as points and latitude-longitudes. We also
+ // check whether the S2Cell contains any corner of the rectangle, or
+ // vice-versa, since the edge-crossing tests only check the edge interiors.
+
+ S2Point cell_v[4];
+ S2LatLng cell_ll[4];
+ for (int i = 0; i < 4; ++i) {
+ cell_v[i] = cell.GetVertex(i); // Must be normalized.
+ cell_ll[i] = S2LatLng(cell_v[i]);
+ if (Contains(cell_ll[i])) return true;
+ if (cell.Contains(GetVertex(i).ToPoint())) return true;
+ }
+
+ // Now check whether the boundaries intersect. Unfortunately, a
+ // latitude-longitude rectangle does not have straight edges -- two edges
+ // are curved, and at least one of them is concave.
+
+ for (int i = 0; i < 4; ++i) {
+ S1Interval edge_lng = S1Interval::FromPointPair(
+ cell_ll[i].lng().radians(), cell_ll[(i+1)&3].lng().radians());
+ if (!lng_.Intersects(edge_lng)) continue;
+
+ S2Point const& a = cell_v[i];
+ S2Point const& b = cell_v[(i+1)&3];
+ if (edge_lng.Contains(lng_.lo())) {
+ if (IntersectsLngEdge(a, b, lat_, lng_.lo())) return true;
+ }
+ if (edge_lng.Contains(lng_.hi())) {
+ if (IntersectsLngEdge(a, b, lat_, lng_.hi())) return true;
+ }
+ if (IntersectsLatEdge(a, b, lat_.lo(), lng_)) return true;
+ if (IntersectsLatEdge(a, b, lat_.hi(), lng_)) return true;
+ }
+ return false;
+}
+
+S1Angle S2LatLngRect::GetDistance(S2LatLngRect const& other) const {
+ S2LatLngRect const& a = *this;
+ S2LatLngRect const& b = other;
+ DCHECK(!a.is_empty());
+ DCHECK(!b.is_empty());
+
+ // First, handle the trivial cases where the longitude intervals overlap.
+ if (a.lng().Intersects(b.lng())) {
+ if (a.lat().Intersects(b.lat()))
+ return S1Angle::Radians(0); // Intersection between a and b.
+
+ // We found an overlap in the longitude interval, but not in the latitude
+ // interval. This means the shortest path travels along some line of
+ // longitude connecting the high-latitude of the lower rect with the
+ // low-latitude of the higher rect.
+ S1Angle lo, hi;
+ if (a.lat().lo() > b.lat().hi()) {
+ lo = b.lat_hi();
+ hi = a.lat_lo();
+ } else {
+ lo = a.lat_hi();
+ hi = b.lat_lo();
+ }
+ return hi - lo;
+ }
+
+ // The longitude intervals don't overlap. In this case, the closest points
+ // occur somewhere on the pair of longitudinal edges which are nearest in
+ // longitude-space.
+ S1Angle a_lng, b_lng;
+ S1Interval lo_hi = S1Interval::FromPointPair(a.lng().lo(), b.lng().hi());
+ S1Interval hi_lo = S1Interval::FromPointPair(a.lng().hi(), b.lng().lo());
+ if (lo_hi.GetLength() < hi_lo.GetLength()) {
+ a_lng = a.lng_lo();
+ b_lng = b.lng_hi();
+ } else {
+ a_lng = a.lng_hi();
+ b_lng = b.lng_lo();
+ }
+
+ // The shortest distance between the two longitudinal segments will include at
+ // least one segment endpoint. We could probably narrow this down further to a
+ // single point-edge distance by comparing the relative latitudes of the
+ // endpoints, but for the sake of clarity, we'll do all four point-edge
+ // distance tests.
+ S2Point a_lo = S2LatLng(a.lat_lo(), a_lng).ToPoint();
+ S2Point a_hi = S2LatLng(a.lat_hi(), a_lng).ToPoint();
+ S2Point a_lo_cross_hi =
+ S2LatLng::FromRadians(0, a_lng.radians() - M_PI_2).Normalized().ToPoint();
+ S2Point b_lo = S2LatLng(b.lat_lo(), b_lng).ToPoint();
+ S2Point b_hi = S2LatLng(b.lat_hi(), b_lng).ToPoint();
+ S2Point b_lo_cross_hi =
+ S2LatLng::FromRadians(0, b_lng.radians() - M_PI_2).Normalized().ToPoint();
+ return min(S2EdgeUtil::GetDistance(a_lo, b_lo, b_hi, b_lo_cross_hi),
+ min(S2EdgeUtil::GetDistance(a_hi, b_lo, b_hi, b_lo_cross_hi),
+ min(S2EdgeUtil::GetDistance(b_lo, a_lo, a_hi, a_lo_cross_hi),
+ S2EdgeUtil::GetDistance(b_hi, a_lo, a_hi, a_lo_cross_hi))));
+}
+
+S1Angle S2LatLngRect::GetDistance(S2LatLng const& p) const {
+ // The algorithm here is the same as in GetDistance(S2LagLngRect), only
+ // with simplified calculations.
+ S2LatLngRect const& a = *this;
+ DCHECK(!a.is_empty());
+ DCHECK(p.is_valid());
+
+ if (a.lng().Contains(p.lng().radians())) {
+ return S1Angle::Radians(max(0.0, max(p.lat().radians() - a.lat().hi(),
+ a.lat().lo() - p.lat().radians())));
+ }
+
+ S1Interval interval(a.lng().hi(), a.lng().GetComplementCenter());
+ double a_lng;
+ if (interval.Contains(p.lng().radians())) {
+ a_lng = a.lng().hi();
+ } else {
+ a_lng = a.lng().lo();
+ }
+ S2Point lo = S2LatLng::FromRadians(a.lat().lo(), a_lng).ToPoint();
+ S2Point hi = S2LatLng::FromRadians(a.lat().hi(), a_lng).ToPoint();
+ S2Point lo_cross_hi =
+ S2LatLng::FromRadians(0, a_lng - M_PI_2).Normalized().ToPoint();
+ return S2EdgeUtil::GetDistance(p.ToPoint(), lo, hi, lo_cross_hi);
+}
+
+S1Angle S2LatLngRect::GetHausdorffDistance(S2LatLngRect const& other) const {
+ return max(GetDirectedHausdorffDistance(other),
+ other.GetDirectedHausdorffDistance(*this));
+}
+
+S1Angle S2LatLngRect::GetDirectedHausdorffDistance(
+ S2LatLngRect const& other) const {
+ if (is_empty()) {
+ return S1Angle::Radians(0);
+ }
+ if (other.is_empty()) {
+ return S1Angle::Radians(M_PI); // maximum possible distance on S2
+ }
+
+ double lng_distance = lng().GetDirectedHausdorffDistance(other.lng());
+ DCHECK_GE(lng_distance, 0);
+ return GetDirectedHausdorffDistance(lng_distance, lat(), other.lat());
+}
+
+// Return the directed Hausdorff distance from one longitudinal edge spanning
+// latitude range 'a_lat' to the other longitudinal edge spanning latitude
+// range 'b_lat', with their longitudinal difference given by 'lng_diff'.
+S1Angle S2LatLngRect::GetDirectedHausdorffDistance(
+ double lng_diff, R1Interval const& a, R1Interval const& b) {
+ // By symmetry, we can assume a's longtitude is 0 and b's longtitude is
+ // lng_diff. Call b's two endpoints b_lo and b_hi. Let H be the hemisphere
+ // containing a and delimited by the longitude line of b. The Voronoi diagram
+ // of b on H has three edges (portions of great circles) all orthogonal to b
+ // and meeting at b_lo_cross_b_hi.
+ // E1: (b_lo, b_lo_cross_b_hi)
+ // E2: (b_hi, b_lo_cross_b_hi)
+ // E3: (-b_mid, b_lo_cross_b_hi), where b_mid is the midpoint of b
+ //
+ // They subdivide H into three Voronoi regions. Depending on how longitude 0
+ // (which contains edge a) intersects these regions, we distinguish two cases:
+ // Case 1: it intersects three regions. This occurs when lng_diff <= M_PI_2.
+ // Case 2: it intersects only two regions. This occurs when lng_diff > M_PI_2.
+ //
+ // In the first case, the directed Hausdorff distance to edge b can only be
+ // realized by the following points on a:
+ // A1: two endpoints of a.
+ // A2: intersection of a with the equator, if b also intersects the equator.
+ //
+ // In the second case, the directed Hausdorff distance to edge b can only be
+ // realized by the following points on a:
+ // B1: two endpoints of a.
+ // B2: intersection of a with E3
+ // B3: farthest point from b_lo to the interior of D, and farthest point from
+ // b_hi to the interior of U, if any, where D (resp. U) is the portion
+ // of edge a below (resp. above) the intersection point from B2.
+
+ DCHECK_GE(lng_diff, 0);
+ DCHECK_LE(lng_diff, M_PI);
+
+ if (lng_diff == 0) {
+ return S1Angle::Radians(a.GetDirectedHausdorffDistance(b));
+ }
+
+ // Assumed longtitude of b.
+ double b_lng = lng_diff;
+ // Two endpoints of b.
+ S2Point b_lo = S2LatLng::FromRadians(b.lo(), b_lng).ToPoint();
+ S2Point b_hi = S2LatLng::FromRadians(b.hi(), b_lng).ToPoint();
+ // Cross product of b_lo and b_hi.
+ const S2Point& b_lo_cross_b_hi =
+ S2LatLng::FromRadians(0, b_lng - M_PI_2).ToPoint();
+
+ // Handling of each case outlined at the top of the function starts here.
+ // This is initialized a few lines below.
+ S1Angle max_distance;
+
+ // Cases A1 and B1.
+ S2Point a_lo = S2LatLng::FromRadians(a.lo(), 0).ToPoint();
+ S2Point a_hi = S2LatLng::FromRadians(a.hi(), 0).ToPoint();
+ max_distance = S2EdgeUtil::GetDistance(a_lo, b_lo, b_hi, b_lo_cross_b_hi);
+ max_distance = max(
+ max_distance, S2EdgeUtil::GetDistance(a_hi, b_lo, b_hi, b_lo_cross_b_hi));
+
+ if (lng_diff <= M_PI_2) {
+ // Case A2.
+ if (a.Contains(0) && b.Contains(0)) {
+ max_distance = max(max_distance, S1Angle::Radians(lng_diff));
+ }
+ } else {
+ // Case B2.
+ const S2Point& p = GetBisectorIntersection(b, b_lng);
+ double p_lat = S2LatLng::Latitude(p).radians();
+ if (a.Contains(p_lat)) {
+ max_distance = max(max_distance, S1Angle::Radians(p.Angle(b_lo)));
+ }
+
+ // Case B3.
+ if (p_lat > a.lo()) {
+ max_distance = max(max_distance, GetInteriorMaxDistance(
+ R1Interval(a.lo(), min(p_lat, a.hi())), b_lo));
+ }
+ if (p_lat < a.hi()) {
+ max_distance = max(max_distance, GetInteriorMaxDistance(
+ R1Interval(max(p_lat, a.lo()), a.hi()), b_hi));
+ }
+ }
+
+ return max_distance;
+}
+
+// Return the intersection of longitude 0 with the bisector of an edge
+// on longitude 'lng' and spanning latitude range 'lat'.
+S2Point S2LatLngRect::GetBisectorIntersection(R1Interval const& lat,
+ double lng) {
+ lng = fabs(lng);
+ double lat_center = lat.GetCenter();
+ // A vector orthogonal to the bisector of the given longitudinal edge.
+ S2LatLng ortho_bisector;
+ if (lat_center >= 0) {
+ ortho_bisector = S2LatLng::FromRadians(lat_center - M_PI_2, lng);
+ } else {
+ ortho_bisector = S2LatLng::FromRadians(-lat_center - M_PI_2, lng - M_PI);
+ }
+ // A vector orthogonal to longitude 0.
+ static const S2Point ortho_lng = S2Point(0, -1, 0);
+ return S2::RobustCrossProd(ortho_lng, ortho_bisector.ToPoint());
+}
+
+// Return max distance from a point b to the segment spanning latitude range
+// a_lat on longitude 0, if the max occurs in the interior of a_lat. Otherwise
+// return -1.
+S1Angle S2LatLngRect::GetInteriorMaxDistance(R1Interval const& a_lat,
+ S2Point const& b) {
+ // Longitude 0 is in the y=0 plane. b.x() >= 0 implies that the maximum
+ // does not occur in the interior of a_lat.
+ if (a_lat.is_empty() || b.x() >= 0) return S1Angle::Radians(-1);
+
+ // Project b to the y=0 plane. The antipodal of the normalized projection is
+ // the point at which the maxium distance from b occurs, if it is contained
+ // in a_lat.
+ S2Point intersection_point = S2Point(-b.x(), 0, -b.z()).Normalize();
+ if (a_lat.InteriorContains(
+ S2LatLng::Latitude(intersection_point).radians())) {
+ return S1Angle::Radians(b.Angle(intersection_point));
+ } else {
+ return S1Angle::Radians(-1);
+ }
+}
+
+bool S2LatLngRect::Contains(S2Point const& p) const {
+ return Contains(S2LatLng(p));
+}
+
+bool S2LatLngRect::ApproxEquals(S2LatLngRect const& other,
+ double max_error) const {
+ return (lat_.ApproxEquals(other.lat_, max_error) &&
+ lng_.ApproxEquals(other.lng_, max_error));
+}
+
+ostream& operator<<(ostream& os, S2LatLngRect const& r) {
+ return os << "[Lo" << r.lo() << ", Hi" << r.hi() << "]";
+}
diff --git a/src/third_party/s2/s2latlngrect.h b/src/third_party/s2/s2latlngrect.h
new file mode 100644
index 00000000000..c2324123699
--- /dev/null
+++ b/src/third_party/s2/s2latlngrect.h
@@ -0,0 +1,320 @@
+// Copyright 2005 Google Inc. All Rights Reserved.
+
+#ifndef UTIL_GEOMETRY_S2LATLNGRECT_H_
+#define UTIL_GEOMETRY_S2LATLNGRECT_H_
+
+#include <iostream>
+using std::ostream;
+using std::cout;
+using std::endl;
+
+
+#include "base/basictypes.h"
+#include "base/logging.h"
+#include "s1angle.h"
+#include "r1interval.h"
+#include "s1interval.h"
+#include "s2region.h"
+#include "s2latlng.h"
+
+// An S2LatLngRect represents a closed latitude-longitude rectangle. It is
+// capable of representing the empty and full rectangles as well as
+// single points.
+//
+// This class is intended to be copied by value as desired. It uses
+// the default copy constructor and assignment operator, however it is
+// not a "plain old datatype" (POD) because it has virtual functions.
+class S2LatLngRect : public S2Region {
+ public:
+ // Construct a rectangle from minimum and maximum latitudes and longitudes.
+ // If lo.lng() > hi.lng(), the rectangle spans the 180 degree longitude
+ // line. Both points must be normalized, with lo.lat() <= hi.lat().
+ // The rectangle contains all the points p such that 'lo' <= p <= 'hi',
+ // where '<=' is defined in the obvious way.
+ inline S2LatLngRect(S2LatLng const& lo, S2LatLng const& hi);
+
+ // Construct a rectangle from latitude and longitude intervals. The two
+ // intervals must either be both empty or both non-empty, and the latitude
+ // interval must not extend outside [-90, +90] degrees.
+ // Note that both intervals (and hence the rectangle) are closed.
+ inline S2LatLngRect(R1Interval const& lat, S1Interval const& lng);
+
+ // The default constructor creates an empty S2LatLngRect.
+ inline S2LatLngRect();
+
+ // Construct a rectangle of the given size centered around the given point.
+ // "center" needs to be normalized, but "size" does not. The latitude
+ // interval of the result is clamped to [-90,90] degrees, and the longitude
+ // interval of the result is Full() if and only if the longitude size is
+ // 360 degrees or more. Examples of clamping (in degrees):
+ //
+ // center=(80,170), size=(40,60) -> lat=[60,90], lng=[140,-160]
+ // center=(10,40), size=(210,400) -> lat=[-90,90], lng=[-180,180]
+ // center=(-90,180), size=(20,50) -> lat=[-90,-80], lng=[155,-155]
+ static S2LatLngRect FromCenterSize(S2LatLng const& center,
+ S2LatLng const& size);
+
+ // Construct a rectangle containing a single (normalized) point.
+ static S2LatLngRect FromPoint(S2LatLng const& p);
+
+ // Construct the minimal bounding rectangle containing the two given
+ // normalized points. This is equivalent to starting with an empty
+ // rectangle and calling AddPoint() twice. Note that it is different than
+ // the S2LatLngRect(lo, hi) constructor, where the first point is always
+ // used as the lower-left corner of the resulting rectangle.
+ static S2LatLngRect FromPointPair(S2LatLng const& p1, S2LatLng const& p2);
+
+ // Accessor methods.
+ S1Angle lat_lo() const { return S1Angle::Radians(lat_.lo()); }
+ S1Angle lat_hi() const { return S1Angle::Radians(lat_.hi()); }
+ S1Angle lng_lo() const { return S1Angle::Radians(lng_.lo()); }
+ S1Angle lng_hi() const { return S1Angle::Radians(lng_.hi()); }
+ R1Interval const& lat() const { return lat_; }
+ S1Interval const& lng() const { return lng_; }
+ R1Interval *mutable_lat() { return &lat_; }
+ S1Interval *mutable_lng() { return &lng_; }
+ S2LatLng lo() const { return S2LatLng(lat_lo(), lng_lo()); }
+ S2LatLng hi() const { return S2LatLng(lat_hi(), lng_hi()); }
+
+ // The canonical empty and full rectangles.
+ static inline S2LatLngRect Empty();
+ static inline S2LatLngRect Full();
+
+ // The full allowable range of latitudes and longitudes.
+ static R1Interval FullLat() { return R1Interval(-M_PI_2, M_PI_2); }
+ static S1Interval FullLng() { return S1Interval::Full(); }
+
+ // Return true if the rectangle is valid, which essentially just means
+ // that the latitude bounds do not exceed Pi/2 in absolute value and
+ // the longitude bounds do not exceed Pi in absolute value. Also, if
+ // either the latitude or longitude bound is empty then both must be.
+ inline bool is_valid() const;
+
+ // Return true if the rectangle is empty, i.e. it contains no points at all.
+ inline bool is_empty() const;
+
+ // Return true if the rectangle is full, i.e. it contains all points.
+ inline bool is_full() const;
+
+ // Return true if the rectangle is a point, i.e. lo() == hi()
+ inline bool is_point() const;
+
+ // Return true if lng_.lo() > lng_.hi(), i.e. the rectangle crosses
+ // the 180 degree longitude line.
+ bool is_inverted() const { return lng_.is_inverted(); }
+
+ // Return the k-th vertex of the rectangle (k = 0,1,2,3) in CCW order.
+ S2LatLng GetVertex(int k) const;
+
+ // Return the center of the rectangle in latitude-longitude space
+ // (in general this is not the center of the region on the sphere).
+ S2LatLng GetCenter() const;
+
+ // Return the width and height of this rectangle in latitude-longitude
+ // space. Empty rectangles have a negative width and height.
+ S2LatLng GetSize() const;
+
+ // Returns the surface area of this rectangle on the unit sphere.
+ double Area() const;
+
+ // More efficient version of Contains() that accepts a S2LatLng rather than
+ // an S2Point. The argument must be normalized.
+ bool Contains(S2LatLng const& ll) const;
+
+ // Return true if and only if the given point is contained in the interior
+ // of the region (i.e. the region excluding its boundary). The point 'p'
+ // does not need to be normalized.
+ bool InteriorContains(S2Point const& p) const;
+
+ // More efficient version of InteriorContains() that accepts a S2LatLng
+ // rather than an S2Point. The argument must be normalized.
+ bool InteriorContains(S2LatLng const& ll) const;
+
+ // Return true if and only if the rectangle contains the given other
+ // rectangle.
+ bool Contains(S2LatLngRect const& other) const;
+
+ // Return true if and only if the interior of this rectangle contains all
+ // points of the given other rectangle (including its boundary).
+ bool InteriorContains(S2LatLngRect const& other) const;
+
+ // Return true if this rectangle and the given other rectangle have any
+ // points in common.
+ bool Intersects(S2LatLngRect const& other) const;
+
+ // Returns true if this rectangle intersects the given cell. (This is an
+ // exact test and may be fairly expensive, see also MayIntersect below.)
+ bool Intersects(S2Cell const& cell) const;
+
+ // Return true if and only if the interior of this rectangle intersects
+ // any point (including the boundary) of the given other rectangle.
+ bool InteriorIntersects(S2LatLngRect const& other) const;
+
+ // Increase the size of the bounding rectangle to include the given point.
+ // The rectangle is expanded by the minimum amount possible. The S2LatLng
+ // argument must be normalized.
+ void AddPoint(S2Point const& p);
+ void AddPoint(S2LatLng const& ll);
+
+ // Return a rectangle that contains all points whose latitude distance from
+ // this rectangle is at most margin.lat(), and whose longitude distance
+ // from this rectangle is at most margin.lng(). In particular, latitudes
+ // are clamped while longitudes are wrapped. Note that any expansion of an
+ // empty interval remains empty, and both components of the given margin
+ // must be non-negative. "margin" does not need to be normalized.
+ //
+ // NOTE: If you are trying to grow a rectangle by a certain *distance* on
+ // the sphere (e.g. 5km), use the ConvolveWithCap() method instead.
+ S2LatLngRect Expanded(S2LatLng const& margin) const;
+
+ // Return the smallest rectangle containing the union of this rectangle and
+ // the given rectangle.
+ S2LatLngRect Union(S2LatLngRect const& other) const;
+
+ // Return the smallest rectangle containing the intersection of this
+ // rectangle and the given rectangle. Note that the region of intersection
+ // may consist of two disjoint rectangles, in which case a single rectangle
+ // spanning both of them is returned.
+ S2LatLngRect Intersection(S2LatLngRect const& other) const;
+
+ // Return a rectangle that contains the convolution of this rectangle with a
+ // cap of the given angle. This expands the rectangle by a fixed distance
+ // (as opposed to growing the rectangle in latitude-longitude space). The
+ // returned rectangle includes all points whose minimum distance to the
+ // original rectangle is at most the given angle.
+ S2LatLngRect ConvolveWithCap(S1Angle const& angle) const;
+
+ // Returns the minimum distance (measured along the surface of the sphere) to
+ // the given S2LatLngRect. Both S2LatLngRects must be non-empty.
+ S1Angle GetDistance(S2LatLngRect const& other) const;
+
+ // Returns the minimum distance (measured along the surface of the sphere)
+ // from a given point to the rectangle (both its boundary and its interior).
+ // The latlng must be valid.
+ S1Angle GetDistance(S2LatLng const& p) const;
+
+ // Returns the (directed or undirected) Hausdorff distance (measured along the
+ // surface of the sphere) to the given S2LatLngRect. The directed Hausdorff
+ // distance from rectangle A to rectangle B is given by
+ // h(A, B) = max_{p in A} min_{q in B} d(p, q).
+ // The Hausdorff distance between rectangle A and rectangle B is given by
+ // H(A, B) = max{h(A, B), h(B, A)}.
+ S1Angle GetDirectedHausdorffDistance(S2LatLngRect const& other) const;
+ S1Angle GetHausdorffDistance(S2LatLngRect const& other) const;
+
+ // Return true if two rectangles contains the same set of points.
+ inline bool operator==(S2LatLngRect const& other) const;
+
+ // Return the opposite of what operator == returns.
+ inline bool operator!=(S2LatLngRect const& other) const;
+
+ // Return true if the latitude and longitude intervals of the two rectangles
+ // are the same up to the given tolerance (see r1interval.h and s1interval.h
+ // for details).
+ bool ApproxEquals(S2LatLngRect const& other, double max_error = 1e-15) const;
+
+ ////////////////////////////////////////////////////////////////////////
+ // S2Region interface (see s2region.h for details):
+
+ virtual S2LatLngRect* Clone() const;
+ virtual S2Cap GetCapBound() const;
+ virtual S2LatLngRect GetRectBound() const;
+ virtual bool Contains(S2Cell const& cell) const;
+ virtual bool VirtualContainsPoint(S2Point const& p) const {
+ return Contains(p); // The same as Contains() below, just virtual.
+ }
+
+ // This test is cheap but is NOT exact. Use Intersects() if you want a more
+ // accurate and more expensive test. Note that when this method is used by
+ // an S2RegionCoverer, the accuracy isn't all that important since if a cell
+ // may intersect the region then it is subdivided, and the accuracy of this
+ // method goes up as the cells get smaller.
+ virtual bool MayIntersect(S2Cell const& cell) const;
+
+ // The point 'p' does not need to be normalized.
+ bool Contains(S2Point const& p) const;
+
+ virtual void Encode(Encoder* const encoder) const;
+ virtual bool Decode(Decoder* const decoder);
+
+ private:
+ // Return true if the edge AB intersects the given edge of constant
+ // longitude.
+ static bool IntersectsLngEdge(S2Point const& a, S2Point const& b,
+ R1Interval const& lat, double lng);
+
+ // Return true if the edge AB intersects the given edge of constant
+ // latitude.
+ static bool IntersectsLatEdge(S2Point const& a, S2Point const& b,
+ double lat, S1Interval const& lng);
+
+ // Helper function. See .cc for description.
+ static S1Angle GetDirectedHausdorffDistance(double lng_diff,
+ R1Interval const& a_lat,
+ R1Interval const& b_lat);
+
+ // Helper function. See .cc for description.
+ static S1Angle GetInteriorMaxDistance(R1Interval const& a_lat,
+ S2Point const& b);
+
+ // Helper function. See .cc for description.
+ static S2Point GetBisectorIntersection(R1Interval const& lat, double lng);
+
+ R1Interval lat_;
+ S1Interval lng_;
+};
+
+inline S2LatLngRect::S2LatLngRect(S2LatLng const& lo, S2LatLng const& hi)
+ : lat_(lo.lat().radians(), hi.lat().radians()),
+ lng_(lo.lng().radians(), hi.lng().radians()) {
+ DCHECK(is_valid()) << lo << ", " << hi;
+}
+
+inline S2LatLngRect::S2LatLngRect(R1Interval const& lat, S1Interval const& lng)
+ : lat_(lat), lng_(lng) {
+ DCHECK(is_valid()) << lat << ", " << lng;
+}
+
+inline S2LatLngRect::S2LatLngRect()
+ : lat_(R1Interval::Empty()), lng_(S1Interval::Empty()) {
+}
+
+inline S2LatLngRect S2LatLngRect::Empty() {
+ return S2LatLngRect();
+}
+
+inline S2LatLngRect S2LatLngRect::Full() {
+ return S2LatLngRect(FullLat(), FullLng());
+}
+
+inline bool S2LatLngRect::is_valid() const {
+ // The lat/lng ranges must either be both empty or both non-empty.
+ return (fabs(lat_.lo()) <= M_PI_2 &&
+ fabs(lat_.hi()) <= M_PI_2 &&
+ lng_.is_valid() &&
+ lat_.is_empty() == lng_.is_empty());
+}
+
+inline bool S2LatLngRect::is_empty() const {
+ return lat_.is_empty();
+}
+
+inline bool S2LatLngRect::is_full() const {
+ return lat_ == FullLat() && lng_.is_full();
+}
+
+inline bool S2LatLngRect::is_point() const {
+ return lat_.lo() == lat_.hi() && lng_.lo() == lng_.hi();
+}
+
+inline bool S2LatLngRect::operator==(S2LatLngRect const& other) const {
+ return lat() == other.lat() && lng() == other.lng();
+}
+
+inline bool S2LatLngRect::operator!=(S2LatLngRect const& other) const {
+ return !operator==(other);
+}
+
+ostream& operator<<(ostream& os, S2LatLngRect const& r);
+
+#endif // UTIL_GEOMETRY_S2LATLNGRECT_H_
diff --git a/src/third_party/s2/s2latlngrect_test.cc b/src/third_party/s2/s2latlngrect_test.cc
new file mode 100644
index 00000000000..33408944a00
--- /dev/null
+++ b/src/third_party/s2/s2latlngrect_test.cc
@@ -0,0 +1,720 @@
+// Copyright 2005 Google Inc. All Rights Reserved.
+//
+// Most of the S2LatLngRect methods have trivial implementations that
+// use the R1Interval and S1Interval classes, so most of the testing
+// is done in those unit tests.
+
+#include "s2latlngrect.h"
+#include "util/coding/coder.h"
+#include "s2edgeutil.h"
+#include "s2cap.h"
+#include "s2cell.h"
+#include "s2testing.h"
+#include "testing/base/public/gunit.h"
+
+static S2LatLngRect RectFromDegrees(double lat_lo, double lng_lo,
+ double lat_hi, double lng_hi) {
+ // Convenience method to construct a rectangle. This method is
+ // intentionally *not* in the S2LatLngRect interface because the
+ // argument order is ambiguous, but hopefully it's not too confusing
+ // within the context of this unit test.
+
+ return S2LatLngRect(S2LatLng::FromDegrees(lat_lo, lng_lo).Normalized(),
+ S2LatLng::FromDegrees(lat_hi, lng_hi).Normalized());
+}
+
+TEST(S2LatLngRect, EmptyAndFull) {
+ // Test basic properties of empty and full rectangles.
+ S2LatLngRect empty = S2LatLngRect::Empty();
+ S2LatLngRect full = S2LatLngRect::Full();
+ EXPECT_TRUE(empty.is_valid());
+ EXPECT_TRUE(empty.is_empty());
+ EXPECT_FALSE(empty.is_point());
+ EXPECT_TRUE(full.is_valid());
+ EXPECT_TRUE(full.is_full());
+ EXPECT_FALSE(full.is_point());
+ // Check that the default S2LatLngRect is identical to Empty().
+ S2LatLngRect default_empty;
+ EXPECT_TRUE(default_empty.is_valid());
+ EXPECT_TRUE(default_empty.is_empty());
+ EXPECT_EQ(empty.lat().bounds(), default_empty.lat().bounds());
+ EXPECT_EQ(empty.lng().bounds(), default_empty.lng().bounds());
+}
+
+TEST(S2LatLngRect, Accessors) {
+ // Check various accessor methods.
+ S2LatLngRect d1 = RectFromDegrees(-90, 0, -45, 180);
+ EXPECT_DOUBLE_EQ(d1.lat_lo().degrees(), -90);
+ EXPECT_DOUBLE_EQ(d1.lat_hi().degrees(), -45);
+ EXPECT_DOUBLE_EQ(d1.lng_lo().degrees(), 0);
+ EXPECT_DOUBLE_EQ(d1.lng_hi().degrees(), 180);
+ EXPECT_EQ(d1.lat(), R1Interval(-M_PI_2, -M_PI_4));
+ EXPECT_EQ(d1.lng(), S1Interval(0, M_PI));
+}
+
+TEST(S2LatLngRect, FromCenterSize) {
+ EXPECT_TRUE(S2LatLngRect::FromCenterSize(S2LatLng::FromDegrees(80, 170),
+ S2LatLng::FromDegrees(40, 60)).
+ ApproxEquals(RectFromDegrees(60, 140, 90, -160)));
+ EXPECT_TRUE(S2LatLngRect::FromCenterSize(S2LatLng::FromDegrees(10, 40),
+ S2LatLng::FromDegrees(210, 400)).
+ is_full());
+ EXPECT_TRUE(S2LatLngRect::FromCenterSize(S2LatLng::FromDegrees(-90, 180),
+ S2LatLng::FromDegrees(20, 50)).
+ ApproxEquals(RectFromDegrees(-90, 155, -80, -155)));
+}
+
+TEST(S2LatLngRect, FromPoint) {
+ S2LatLng p = S2LatLng::FromDegrees(23, 47);
+ EXPECT_EQ(S2LatLngRect::FromPoint(p), S2LatLngRect(p, p));
+ EXPECT_TRUE(S2LatLngRect::FromPoint(p).is_point());
+}
+
+TEST(S2LatLngRect, FromPointPair) {
+ EXPECT_EQ(S2LatLngRect::FromPointPair(S2LatLng::FromDegrees(-35, -140),
+ S2LatLng::FromDegrees(15, 155)),
+ RectFromDegrees(-35, 155, 15, -140));
+ EXPECT_EQ(S2LatLngRect::FromPointPair(S2LatLng::FromDegrees(25, -70),
+ S2LatLng::FromDegrees(-90, 80)),
+ RectFromDegrees(-90, -70, 25, 80));
+}
+
+TEST(S2LatLngRect, GetCenterSize) {
+ S2LatLngRect r1(R1Interval(0, M_PI_2), S1Interval(-M_PI, 0));
+ EXPECT_EQ(r1.GetCenter(), S2LatLng::FromRadians(M_PI_4, -M_PI_2));
+ EXPECT_EQ(r1.GetSize(), S2LatLng::FromRadians(M_PI_2, M_PI));
+ EXPECT_LT(S2LatLngRect::Empty().GetSize().lat().radians(), 0);
+ EXPECT_LT(S2LatLngRect::Empty().GetSize().lng().radians(), 0);
+}
+
+TEST(S2LatLngRect, GetVertex) {
+ S2LatLngRect r1(R1Interval(0, M_PI_2), S1Interval(-M_PI, 0));
+ EXPECT_EQ(r1.GetVertex(0), S2LatLng::FromRadians(0, M_PI));
+ EXPECT_EQ(r1.GetVertex(1), S2LatLng::FromRadians(0, 0));
+ EXPECT_EQ(r1.GetVertex(2), S2LatLng::FromRadians(M_PI_2, 0));
+ EXPECT_EQ(r1.GetVertex(3), S2LatLng::FromRadians(M_PI_2, M_PI));
+
+ // Make sure that GetVertex() returns vertices in CCW order.
+ for (int i = 0; i < 4; ++i) {
+ double lat = M_PI_4 * (i - 2);
+ double lng = M_PI_2 * (i - 2) + 0.2;
+ S2LatLngRect r(R1Interval(lat, lat + M_PI_4),
+ S1Interval(drem(lng, 2*M_PI), drem(lng + M_PI_2, 2*M_PI)));
+ for (int k = 0; k < 4; ++k) {
+ EXPECT_TRUE(S2::SimpleCCW(r.GetVertex((k - 1) & 3).ToPoint(),
+ r.GetVertex(k).ToPoint(),
+ r.GetVertex((k + 1) & 3).ToPoint()));
+ }
+ }
+}
+
+TEST(S2LatLngRect, Contains) {
+ // Contains(S2LatLng), InteriorContains(S2LatLng), VirtualContainsPoint()
+ S2LatLng eq_m180 = S2LatLng::FromRadians(0, -M_PI);
+ S2LatLng north_pole = S2LatLng::FromRadians(M_PI_2, 0);
+ S2LatLngRect r1(eq_m180, north_pole);
+
+ EXPECT_TRUE(r1.Contains(S2LatLng::FromDegrees(30, -45)));
+ EXPECT_TRUE(r1.InteriorContains(S2LatLng::FromDegrees(30, -45)));
+ EXPECT_FALSE(r1.Contains(S2LatLng::FromDegrees(30, 45)));
+ EXPECT_FALSE(r1.InteriorContains(S2LatLng::FromDegrees(30, 45)));
+ EXPECT_TRUE(r1.Contains(eq_m180));
+ EXPECT_FALSE(r1.InteriorContains(eq_m180));
+ EXPECT_TRUE(r1.Contains(north_pole));
+ EXPECT_FALSE(r1.InteriorContains(north_pole));
+ EXPECT_TRUE(r1.Contains(S2Point(0.5, -0.3, 0.1)));
+ EXPECT_TRUE(r1.VirtualContainsPoint(S2Point(0.5, -0.3, 0.1)));
+ EXPECT_FALSE(r1.Contains(S2Point(0.5, 0.2, 0.1)));
+ EXPECT_FALSE(r1.VirtualContainsPoint(S2Point(0.5, 0.2, 0.1)));
+}
+
+static void TestIntervalOps(S2LatLngRect const& x, S2LatLngRect const& y,
+ const char* expected_relation,
+ S2LatLngRect const& expected_union,
+ S2LatLngRect const& expected_intersection) {
+ // Test all of the interval operations on the given pair of intervals.
+ // "expected_relation" is a sequence of "T" and "F" characters corresponding
+ // to the expected results of Contains(), InteriorContains(), Intersects(),
+ // and InteriorIntersects() respectively.
+
+ EXPECT_EQ(x.Contains(y), expected_relation[0] == 'T');
+ EXPECT_EQ(x.InteriorContains(y), expected_relation[1] == 'T');
+ EXPECT_EQ(x.Intersects(y), expected_relation[2] == 'T');
+ EXPECT_EQ(x.InteriorIntersects(y), expected_relation[3] == 'T');
+
+ EXPECT_EQ(x.Contains(y), x.Union(y) == x);
+ EXPECT_EQ(x.Intersects(y), !x.Intersection(y).is_empty());
+
+ EXPECT_EQ(x.Union(y), expected_union);
+ EXPECT_EQ(x.Intersection(y), expected_intersection);
+
+ if (y.GetSize() == S2LatLng::FromRadians(0, 0)) {
+ S2LatLngRect r = x;
+ r.AddPoint(y.lo());
+ EXPECT_EQ(r, expected_union);
+ }
+}
+
+TEST(S2LatLngRect, IntervalOps) {
+ // Contains(S2LatLngRect), InteriorContains(S2LatLngRect),
+ // Intersects(), InteriorIntersects(), Union(), Intersection().
+ //
+ // Much more testing of these methods is done in s1interval_unittest
+ // and r1interval_unittest.
+
+ // Rectangle "r1" covers one-quarter of the sphere.
+ S2LatLngRect r1 = RectFromDegrees(0, -180, 90, 0);
+
+ // Test operations where one rectangle consists of a single point.
+ S2LatLngRect r1_mid = RectFromDegrees(45, -90, 45, -90);
+ TestIntervalOps(r1, r1_mid, "TTTT", r1, r1_mid);
+
+ S2LatLngRect req_m180 = RectFromDegrees(0, -180, 0, -180);
+ TestIntervalOps(r1, req_m180, "TFTF", r1, req_m180);
+
+ S2LatLngRect rnorth_pole = RectFromDegrees(90, 0, 90, 0);
+ TestIntervalOps(r1, rnorth_pole, "TFTF", r1, rnorth_pole);
+
+ TestIntervalOps(r1, RectFromDegrees(-10, -1, 1, 20), "FFTT",
+ RectFromDegrees(-10, 180, 90, 20),
+ RectFromDegrees(0, -1, 1, 0));
+ TestIntervalOps(r1, RectFromDegrees(-10, -1, 0, 20), "FFTF",
+ RectFromDegrees(-10, 180, 90, 20),
+ RectFromDegrees(0, -1, 0, 0));
+ TestIntervalOps(r1, RectFromDegrees(-10, 0, 1, 20), "FFTF",
+ RectFromDegrees(-10, 180, 90, 20),
+ RectFromDegrees(0, 0, 1, 0));
+
+ TestIntervalOps(RectFromDegrees(-15, -160, -15, -150),
+ RectFromDegrees(20, 145, 25, 155), "FFFF",
+ RectFromDegrees(-15, 145, 25, -150),
+ S2LatLngRect::Empty());
+ TestIntervalOps(RectFromDegrees(70, -10, 90, -140),
+ RectFromDegrees(60, 175, 80, 5), "FFTT",
+ RectFromDegrees(60, -180, 90, 180),
+ RectFromDegrees(70, 175, 80, 5));
+
+ // Check that the intersection of two rectangles that overlap in latitude
+ // but not longitude is valid, and vice versa.
+ TestIntervalOps(RectFromDegrees(12, 30, 60, 60),
+ RectFromDegrees(0, 0, 30, 18), "FFFF",
+ RectFromDegrees(0, 0, 60, 60), S2LatLngRect::Empty());
+ TestIntervalOps(RectFromDegrees(0, 0, 18, 42),
+ RectFromDegrees(30, 12, 42, 60), "FFFF",
+ RectFromDegrees(0, 0, 42, 60), S2LatLngRect::Empty());
+}
+
+TEST(S2LatLngRect, AddPoint) {
+ S2LatLngRect p = S2LatLngRect::Empty();
+ p.AddPoint(S2LatLng::FromDegrees(0, 0));
+ EXPECT_TRUE(p.is_point());
+ p.AddPoint(S2LatLng::FromRadians(0, -M_PI_2));
+ EXPECT_FALSE(p.is_point());
+ p.AddPoint(S2LatLng::FromRadians(M_PI_4, -M_PI));
+ p.AddPoint(S2Point(0, 0, 1));
+ EXPECT_EQ(p, RectFromDegrees(0, -180, 90, 0));
+}
+
+TEST(S2LatLngRect, Expanded) {
+ EXPECT_TRUE(RectFromDegrees(70, 150, 80, 170).
+ Expanded(S2LatLng::FromDegrees(20, 30)).
+ ApproxEquals(RectFromDegrees(50, 120, 90, -160)));
+ EXPECT_TRUE(S2LatLngRect::Empty().Expanded(S2LatLng::FromDegrees(20, 30)).
+ is_empty());
+ EXPECT_TRUE(S2LatLngRect::Full().Expanded(S2LatLng::FromDegrees(20, 30)).
+ is_full());
+ EXPECT_TRUE(RectFromDegrees(-90, 170, 10, 20).
+ Expanded(S2LatLng::FromDegrees(30, 80)).
+ ApproxEquals(RectFromDegrees(-90, -180, 40, 180)));
+}
+
+TEST(S2LatLngRect, ConvolveWithCap) {
+ EXPECT_TRUE(RectFromDegrees(0, 170, 0, -170).
+ ConvolveWithCap(S1Angle::Degrees(15)).ApproxEquals(
+ RectFromDegrees(-15, 155, 15, -155)));
+ EXPECT_TRUE(RectFromDegrees(60, 150, 80, 10).
+ ConvolveWithCap(S1Angle::Degrees(15)).ApproxEquals(
+ RectFromDegrees(45, -180, 90, 180)));
+}
+
+TEST(S2LatLngRect, GetCapBound) {
+ // Bounding cap at center is smaller:
+ EXPECT_TRUE(RectFromDegrees(-45, -45, 45, 45).GetCapBound().
+ ApproxEquals(S2Cap::FromAxisHeight(S2Point(1, 0, 0), 0.5)));
+
+ // Bounding cap at north pole is smaller:
+ EXPECT_TRUE(RectFromDegrees(88, -80, 89, 80).GetCapBound().
+ ApproxEquals(S2Cap::FromAxisAngle(S2Point(0, 0, 1),
+ S1Angle::Degrees(2))));
+
+ // Longitude span > 180 degrees:
+ EXPECT_TRUE(RectFromDegrees(-30, -150, -10, 50).GetCapBound().
+ ApproxEquals(S2Cap::FromAxisAngle(S2Point(0, 0, -1),
+ S1Angle::Degrees(80))));
+}
+
+static void TestCellOps(S2LatLngRect const& r, S2Cell const& cell,
+ int level) {
+ // Test the relationship between the given rectangle and cell:
+ // 0 == no intersection, 1 == MayIntersect, 2 == Intersects,
+ // 3 == Vertex Containment, 4 == Contains
+
+ bool vertex_contained = false;
+ for (int i = 0; i < 4; ++i) {
+ if (r.Contains(cell.GetVertexRaw(i)) ||
+ (!r.is_empty() && cell.Contains(r.GetVertex(i).ToPoint())))
+ vertex_contained = true;
+ }
+ EXPECT_EQ(r.MayIntersect(cell), level >= 1);
+ EXPECT_EQ(r.Intersects(cell), level >= 2);
+ EXPECT_EQ(vertex_contained, level >= 3);
+ EXPECT_EQ(r.Contains(cell), level >= 4);
+}
+
+TEST(S2LatLngRect, CellOps) {
+ // Contains(S2Cell), MayIntersect(S2Cell), Intersects(S2Cell)
+
+ // Special cases.
+ TestCellOps(S2LatLngRect::Empty(), S2Cell::FromFacePosLevel(3, 0, 0), 0);
+ TestCellOps(S2LatLngRect::Full(), S2Cell::FromFacePosLevel(2, 0, 0), 4);
+ TestCellOps(S2LatLngRect::Full(), S2Cell::FromFacePosLevel(5, 0, 25), 4);
+
+ // This rectangle includes the first quadrant of face 0. It's expanded
+ // slightly because cell bounding rectangles are slightly conservative.
+ S2LatLngRect r4 = RectFromDegrees(-45.1, -45.1, 0.1, 0.1);
+ TestCellOps(r4, S2Cell::FromFacePosLevel(0, 0, 0), 3);
+ TestCellOps(r4, S2Cell::FromFacePosLevel(0, 0, 1), 4);
+ TestCellOps(r4, S2Cell::FromFacePosLevel(1, 0, 1), 0);
+
+ // This rectangle intersects the first quadrant of face 0.
+ S2LatLngRect r5 = RectFromDegrees(-10, -45, 10, 0);
+ TestCellOps(r5, S2Cell::FromFacePosLevel(0, 0, 0), 3);
+ TestCellOps(r5, S2Cell::FromFacePosLevel(0, 0, 1), 3);
+ TestCellOps(r5, S2Cell::FromFacePosLevel(1, 0, 1), 0);
+
+ // Rectangle consisting of a single point.
+ TestCellOps(RectFromDegrees(4, 4, 4, 4),
+ S2Cell::FromFacePosLevel(0, 0, 0), 3);
+
+ // Rectangles that intersect the bounding rectangle of a face
+ // but not the face itself.
+ TestCellOps(RectFromDegrees(41, -87, 42, -79),
+ S2Cell::FromFacePosLevel(2, 0, 0), 1);
+ TestCellOps(RectFromDegrees(-41, 160, -40, -160),
+ S2Cell::FromFacePosLevel(5, 0, 0), 1);
+
+ // This is the leaf cell at the top right hand corner of face 0.
+ // It has two angles of 60 degrees and two of 120 degrees.
+ S2Cell cell0tr(S2Point(1 + 1e-12, 1, 1));
+ S2LatLngRect bound0tr = cell0tr.GetRectBound();
+ S2LatLng v0(cell0tr.GetVertexRaw(0));
+ TestCellOps(RectFromDegrees(v0.lat().degrees() - 1e-8,
+ v0.lng().degrees() - 1e-8,
+ v0.lat().degrees() - 2e-10,
+ v0.lng().degrees() + 1e-10),
+ cell0tr, 1);
+
+ // Rectangles that intersect a face but where no vertex of one region
+ // is contained by the other region. The first one passes through
+ // a corner of one of the face cells.
+ TestCellOps(RectFromDegrees(-37, -70, -36, -20),
+ S2Cell::FromFacePosLevel(5, 0, 0), 2);
+
+ // These two intersect like a diamond and a square.
+ S2Cell cell202 = S2Cell::FromFacePosLevel(2, 0, 2);
+ S2LatLngRect bound202 = cell202.GetRectBound();
+ TestCellOps(RectFromDegrees(bound202.lo().lat().degrees() + 3,
+ bound202.lo().lng().degrees() + 3,
+ bound202.hi().lat().degrees() - 3,
+ bound202.hi().lng().degrees() - 3),
+ cell202, 2);
+}
+
+TEST(S2LatLngRect, EncodeDecode) {
+ S2LatLngRect r = RectFromDegrees(-20, -80, 10, 20);
+ Encoder encoder;
+ r.Encode(&encoder);
+ Decoder decoder(encoder.base(), encoder.length());
+ S2LatLngRect decoded_rect = S2LatLngRect::Empty();
+ EXPECT_TRUE(decoded_rect.Decode(&decoder));
+ EXPECT_EQ(r, decoded_rect);
+}
+
+TEST(S2LatLngRect, Area) {
+ EXPECT_EQ(S2LatLngRect::Empty().Area(), 0.0);
+ EXPECT_DOUBLE_EQ(S2LatLngRect::Full().Area(), 4 * M_PI);
+ EXPECT_DOUBLE_EQ(RectFromDegrees(0, 0, 90, 90).Area(), M_PI / 2);
+}
+
+// Returns the minimum distance from X to the latitude line segment defined by
+// the given latitude and longitude interval.
+S1Angle GetDistance(const S2LatLng& x,
+ const S1Angle& lat,
+ const S1Interval& interval) {
+ EXPECT_TRUE(x.is_valid());
+ EXPECT_TRUE(interval.is_valid());
+
+ // Is X inside the longitude interval?
+ if (interval.Contains(x.lng().radians()))
+ return (x.lat() - lat).abs();
+
+ // Return the distance to the closer endpoint.
+ return min(x.GetDistance(S2LatLng(lat, S1Angle::Radians(interval.lo()))),
+ x.GetDistance(S2LatLng(lat, S1Angle::Radians(interval.hi()))));
+}
+
+static S1Angle BruteForceDistance(const S2LatLngRect& a,
+ const S2LatLngRect& b) {
+ if (a.Intersects(b))
+ return S1Angle::Radians(0);
+
+ // Compare every point in 'a' against every latitude edge and longitude edge
+ // in 'b', and vice-versa, for a total of 16 point-vs-latitude-edge tests and
+ // 16 point-vs-longitude-edge tests.
+ S2LatLng pnt_a[4], pnt_b[4];
+ pnt_a[0] = S2LatLng(a.lat_lo(), a.lng_lo());
+ pnt_a[1] = S2LatLng(a.lat_lo(), a.lng_hi());
+ pnt_a[2] = S2LatLng(a.lat_hi(), a.lng_hi());
+ pnt_a[3] = S2LatLng(a.lat_hi(), a.lng_lo());
+ pnt_b[0] = S2LatLng(b.lat_lo(), b.lng_lo());
+ pnt_b[1] = S2LatLng(b.lat_lo(), b.lng_hi());
+ pnt_b[2] = S2LatLng(b.lat_hi(), b.lng_hi());
+ pnt_b[3] = S2LatLng(b.lat_hi(), b.lng_lo());
+
+ // Make arrays containing the lo/hi latitudes and the lo/hi longitude edges.
+ S1Angle lat_a[2] = { a.lat_lo(), a.lat_hi() };
+ S1Angle lat_b[2] = { b.lat_lo(), b.lat_hi() };
+ S2Point lng_edge_a[2][2] = { { pnt_a[0].ToPoint(), pnt_a[3].ToPoint() },
+ { pnt_a[1].ToPoint(), pnt_a[2].ToPoint() } };
+ S2Point lng_edge_b[2][2] = { { pnt_b[0].ToPoint(), pnt_b[3].ToPoint() },
+ { pnt_b[1].ToPoint(), pnt_b[2].ToPoint() } };
+
+ S1Angle min_distance = S1Angle::Degrees(180.0);
+ for (int i = 0; i < 4; ++i) {
+ // For each point in a and b.
+ const S2LatLng& current_a = pnt_a[i];
+ const S2LatLng& current_b = pnt_b[i];
+
+ for (int j = 0; j < 2; ++j) {
+ // Get distances to latitude and longitude edges.
+ S1Angle a_to_lat = GetDistance(current_a, lat_b[j], b.lng());
+ S1Angle b_to_lat = GetDistance(current_b, lat_a[j], a.lng());
+ S1Angle a_to_lng = S2EdgeUtil::GetDistance(
+ current_a.ToPoint(), lng_edge_b[j][0], lng_edge_b[j][1]);
+ S1Angle b_to_lng = S2EdgeUtil::GetDistance(
+ current_b.ToPoint(), lng_edge_a[j][0], lng_edge_a[j][1]);
+
+ min_distance = min(min_distance,
+ min(a_to_lat, min(b_to_lat, min(a_to_lng, b_to_lng))));
+ }
+ }
+ return min_distance;
+}
+
+static S1Angle BruteForceRectPointDistance(const S2LatLngRect& a,
+ const S2LatLng& b) {
+ if (a.Contains(b)) {
+ return S1Angle::Radians(0);
+ }
+
+ S1Angle b_to_lo_lat = GetDistance(b, a.lat_lo(), a.lng());
+ S1Angle b_to_hi_lat = GetDistance(b, a.lat_hi(), a.lng());
+ S1Angle b_to_lo_lng = S2EdgeUtil::GetDistance(
+ b.ToPoint(),
+ S2LatLng(a.lat_lo(), a.lng_lo()).ToPoint(),
+ S2LatLng(a.lat_hi(), a.lng_lo()).ToPoint());
+ S1Angle b_to_hi_lng = S2EdgeUtil::GetDistance(
+ b.ToPoint(),
+ S2LatLng(a.lat_lo(), a.lng_hi()).ToPoint(),
+ S2LatLng(a.lat_hi(), a.lng_hi()).ToPoint());
+ return min(b_to_lo_lat, min(b_to_hi_lat, min(b_to_lo_lng, b_to_hi_lng)));
+}
+
+// This method verifies a.GetDistance(b) by comparing its result against a
+// brute-force implementation. The correctness of the brute-force version is
+// much easier to verify by inspection.
+static void VerifyGetDistance(const S2LatLngRect& a, const S2LatLngRect& b) {
+ S1Angle distance1 = BruteForceDistance(a, b);
+ S1Angle distance2 = a.GetDistance(b);
+ EXPECT_NEAR(distance1.radians() - distance2.radians(), 0, 1e-10)
+ << a << ":" << b;
+}
+
+static S2LatLngRect PointRectFromDegrees(double lat, double lng) {
+ return S2LatLngRect::FromPoint(
+ S2LatLng::FromDegrees(lat, lng).Normalized());
+}
+
+// This method verifies a.GetDistance(b), where b is a S2LatLng, by comparing
+// its result against a.GetDistance(c), c being the point rectangle created
+// from b.
+static void VerifyGetRectPointDistance(
+ const S2LatLngRect& a, const S2LatLng& p) {
+ S1Angle distance1 = BruteForceRectPointDistance(a, p.Normalized());
+ S1Angle distance2 = a.GetDistance(p.Normalized());
+ EXPECT_NEAR(fabs(distance1.radians() - distance2.radians()), 0, 1e-10)
+ << a << ":" << p;
+}
+
+TEST(S2LatLngRect, GetDistanceOverlapping) {
+ // Check pairs of rectangles that overlap: (should all return 0):
+ S2LatLngRect a = RectFromDegrees(0, 0, 2, 2);
+ S2LatLngRect b = PointRectFromDegrees(0, 0);
+ EXPECT_EQ(S1Angle::Radians(0), a.GetDistance(a));
+ EXPECT_EQ(S1Angle::Radians(0), a.GetDistance(b));
+ EXPECT_EQ(S1Angle::Radians(0), b.GetDistance(b));
+ EXPECT_EQ(S1Angle::Radians(0), a.GetDistance(S2LatLng::FromDegrees(0, 0)));
+ EXPECT_EQ(S1Angle::Radians(0), a.GetDistance(RectFromDegrees(0, 1, 2, 3)));
+ EXPECT_EQ(S1Angle::Radians(0), a.GetDistance(RectFromDegrees(0, 2, 2, 4)));
+ EXPECT_EQ(S1Angle::Radians(0), a.GetDistance(RectFromDegrees(1, 0, 3, 2)));
+ EXPECT_EQ(S1Angle::Radians(0), a.GetDistance(RectFromDegrees(2, 0, 4, 2)));
+ EXPECT_EQ(S1Angle::Radians(0), a.GetDistance(RectFromDegrees(1, 1, 3, 3)));
+ EXPECT_EQ(S1Angle::Radians(0), a.GetDistance(RectFromDegrees(2, 2, 4, 4)));
+}
+
+TEST(S2LatLngRect, GetDistanceRectVsPoint) {
+ // Rect that spans 180.
+ S2LatLngRect a = RectFromDegrees(-1, -1, 2, 1);
+ VerifyGetDistance(a, PointRectFromDegrees(-2, -1));
+ VerifyGetDistance(a, PointRectFromDegrees(1, 2));
+
+ VerifyGetDistance(PointRectFromDegrees(-2, -1), a);
+ VerifyGetDistance(PointRectFromDegrees(1, 2), a);
+
+ VerifyGetRectPointDistance(a, S2LatLng::FromDegrees(-2, -1));
+ VerifyGetRectPointDistance(a, S2LatLng::FromDegrees(1, 2));
+
+ // Tests near the north pole.
+ S2LatLngRect b = RectFromDegrees(86, 0, 88, 2);
+ VerifyGetDistance(b, PointRectFromDegrees(87, 3));
+ VerifyGetDistance(b, PointRectFromDegrees(87, -1));
+ VerifyGetDistance(b, PointRectFromDegrees(89, 1));
+ VerifyGetDistance(b, PointRectFromDegrees(89, 181));
+ VerifyGetDistance(b, PointRectFromDegrees(85, 1));
+ VerifyGetDistance(b, PointRectFromDegrees(85, 181));
+ VerifyGetDistance(b, PointRectFromDegrees(90, 0));
+
+ VerifyGetDistance(PointRectFromDegrees(87, 3), b);
+ VerifyGetDistance(PointRectFromDegrees(87, -1), b);
+ VerifyGetDistance(PointRectFromDegrees(89, 1), b);
+ VerifyGetDistance(PointRectFromDegrees(89, 181), b);
+ VerifyGetDistance(PointRectFromDegrees(85, 1), b);
+ VerifyGetDistance(PointRectFromDegrees(85, 181), b);
+ VerifyGetDistance(PointRectFromDegrees(90, 0), b);
+
+ VerifyGetRectPointDistance(b, S2LatLng::FromDegrees(87, 3));
+ VerifyGetRectPointDistance(b, S2LatLng::FromDegrees(87, -1));
+ VerifyGetRectPointDistance(b, S2LatLng::FromDegrees(89, 1));
+ VerifyGetRectPointDistance(b, S2LatLng::FromDegrees(89, 181));
+ VerifyGetRectPointDistance(b, S2LatLng::FromDegrees(85, 1));
+ VerifyGetRectPointDistance(b, S2LatLng::FromDegrees(85, 181));
+ VerifyGetRectPointDistance(b, S2LatLng::FromDegrees(90, 0));
+
+ // Rect that touches the north pole.
+ S2LatLngRect c = RectFromDegrees(88, 0, 90, 2);
+ VerifyGetDistance(c, PointRectFromDegrees(89, 3));
+ VerifyGetDistance(c, PointRectFromDegrees(89, 90));
+ VerifyGetDistance(c, PointRectFromDegrees(89, 181));
+ VerifyGetDistance(PointRectFromDegrees(89, 3), c);
+ VerifyGetDistance(PointRectFromDegrees(89, 90), c);
+ VerifyGetDistance(PointRectFromDegrees(89, 181), c);
+}
+
+TEST(S2LatLngRect, GetDistanceRectVsRect) {
+ // Rect that spans 180.
+ S2LatLngRect a = RectFromDegrees(-1, -1, 2, 1);
+ VerifyGetDistance(a, RectFromDegrees(0, 2, 1, 3));
+ VerifyGetDistance(a, RectFromDegrees(-2, -3, -1, -2));
+
+ // Tests near the south pole.
+ S2LatLngRect b = RectFromDegrees(-87, 0, -85, 3);
+ VerifyGetDistance(b, RectFromDegrees(-89, 1, -88, 2));
+ VerifyGetDistance(b, RectFromDegrees(-84, 1, -83, 2));
+ VerifyGetDistance(b, RectFromDegrees(-88, 90, -86, 91));
+ VerifyGetDistance(b, RectFromDegrees(-84, -91, -83, -90));
+ VerifyGetDistance(b, RectFromDegrees(-90, 181, -89, 182));
+ VerifyGetDistance(b, RectFromDegrees(-84, 181, -83, 182));
+}
+
+TEST(S2LatLngRect, GetDistanceRandomPairs) {
+ // Test random pairs.
+ for (int i = 0; i < 10000; ++i) {
+ S2LatLngRect a =
+ S2LatLngRect::FromPointPair(S2LatLng(S2Testing::RandomPoint()),
+ S2LatLng(S2Testing::RandomPoint()));
+ S2LatLngRect b =
+ S2LatLngRect::FromPointPair(S2LatLng(S2Testing::RandomPoint()),
+ S2LatLng(S2Testing::RandomPoint()));
+ VerifyGetDistance(a, b);
+
+
+ S2LatLng c(S2Testing::RandomPoint());
+ VerifyGetRectPointDistance(a, c);
+ VerifyGetRectPointDistance(b, c);
+ }
+}
+
+// This function assumes that GetDirectedHausdorffDistance() always returns
+// a distance from some point in a to b. So the function mainly tests whether
+// the returned distance is large enough, and only does a weak test on whether
+// it is small enough.
+static void VerifyGetDirectedHausdorffDistance(const S2LatLngRect& a,
+ const S2LatLngRect& b) {
+ S1Angle hausdorff_distance = a.GetDirectedHausdorffDistance(b);
+
+ static const double kResolution = 0.1;
+ // Record the max sample distance as well as the sample point realizing the
+ // max for easier debugging.
+ S1Angle max_distance;
+ double lat_max, lng_max;
+
+ int sample_size_on_lat =
+ static_cast<int>(a.lat().GetLength() / kResolution) + 1;
+ int sample_size_on_lng =
+ static_cast<int>(a.lng().GetLength() / kResolution) + 1;
+ double delta_on_lat = a.lat().GetLength() / sample_size_on_lat;
+ double delta_on_lng = a.lng().GetLength() / sample_size_on_lng;
+
+ double lng = a.lng().lo();
+ for (int i = 0; i <= sample_size_on_lng; ++i, lng += delta_on_lng) {
+ double lat = a.lat().lo();
+ for (int j = 0; j <= sample_size_on_lat; ++j, lat += delta_on_lat) {
+ S2LatLng latlng = S2LatLng::FromRadians(lat, lng).Normalized();
+ S1Angle distance_to_b = b.GetDistance(latlng);
+
+ if (distance_to_b >= max_distance) {
+ max_distance = distance_to_b;
+ lat_max = lat;
+ lng_max = lng;
+ }
+ }
+ }
+
+ EXPECT_LE(max_distance.radians(), hausdorff_distance.radians() + 1e-10)
+ << a << ":" << b;
+ EXPECT_GE(max_distance.radians(), hausdorff_distance.radians() - kResolution)
+ << a << ":" << b;
+}
+
+
+TEST(S2LatLngRect, GetDirectedHausdorffDistanceRandomPairs) {
+ // Test random pairs.
+ for (int i = 0; i < 5000; ++i) {
+ S2LatLngRect a =
+ S2LatLngRect::FromPointPair(S2LatLng(S2Testing::RandomPoint()),
+ S2LatLng(S2Testing::RandomPoint()));
+ S2LatLngRect b =
+ S2LatLngRect::FromPointPair(S2LatLng(S2Testing::RandomPoint()),
+ S2LatLng(S2Testing::RandomPoint()));
+ // a and b are *minimum* bounding rectangles of two random points, in
+ // particular, their Voronoi diagrams are always of the same topology. We
+ // take the "complements" of a and b for more thorough testing.
+ S2LatLngRect a2(a.lat(), a.lng().Complement());
+ S2LatLngRect b2(b.lat(), b.lng().Complement());
+
+ VerifyGetDirectedHausdorffDistance(a, b);
+ VerifyGetDirectedHausdorffDistance(b, a);
+
+ VerifyGetDirectedHausdorffDistance(a, b2);
+ VerifyGetDirectedHausdorffDistance(b2, a);
+
+ VerifyGetDirectedHausdorffDistance(a2, b);
+ VerifyGetDirectedHausdorffDistance(b, a2);
+
+ VerifyGetDirectedHausdorffDistance(a2, b2);
+ VerifyGetDirectedHausdorffDistance(b2, a2);
+ }
+}
+
+TEST(S2LatLngRect, GetDirectedHausdorffDistanceContained) {
+ // Caller rect is contained in callee rect. Should return 0.
+ S2LatLngRect a = RectFromDegrees(-10, 20, -5, 90);
+ EXPECT_EQ(S1Angle::Radians(0),
+ a.GetDirectedHausdorffDistance(RectFromDegrees(-10, 20, -5, 90)));
+ EXPECT_EQ(S1Angle::Radians(0),
+ a.GetDirectedHausdorffDistance(RectFromDegrees(-10, 19, -5, 91)));
+ EXPECT_EQ(S1Angle::Radians(0),
+ a.GetDirectedHausdorffDistance(RectFromDegrees(-11, 20, -4, 90)));
+ EXPECT_EQ(S1Angle::Radians(0),
+ a.GetDirectedHausdorffDistance(RectFromDegrees(-11, 19, -4, 91)));
+}
+
+TEST(S2LatLngRect, GetDirectHausdorffDistancePointToRect) {
+ // The Hausdorff distance from a point to a rect should be the same as its
+ // distance to the rect.
+ S2LatLngRect a1 = PointRectFromDegrees(5, 8);
+ S2LatLngRect a2 = PointRectFromDegrees(90, 10); // north pole
+
+ S2LatLngRect b = RectFromDegrees(-85, -50, -80, 10);
+ EXPECT_DOUBLE_EQ(a1.GetDirectedHausdorffDistance(b).radians(),
+ a1.GetDistance(b).radians());
+ EXPECT_DOUBLE_EQ(a2.GetDirectedHausdorffDistance(b).radians(),
+ a2.GetDistance(b).radians());
+
+ b = RectFromDegrees(4, -10, 80, 10);
+ EXPECT_DOUBLE_EQ(a1.GetDirectedHausdorffDistance(b).radians(),
+ a1.GetDistance(b).radians());
+ EXPECT_DOUBLE_EQ(a2.GetDirectedHausdorffDistance(b).radians(),
+ a2.GetDistance(b).radians());
+
+ b = RectFromDegrees(70, 170, 80, -170);
+ EXPECT_DOUBLE_EQ(a1.GetDirectedHausdorffDistance(b).radians(),
+ a1.GetDistance(b).radians());
+ EXPECT_DOUBLE_EQ(a2.GetDirectedHausdorffDistance(b).radians(),
+ a2.GetDistance(b).radians());
+}
+
+TEST(S2LatLngRect, GetDirectedHausdorffDistanceRectToPoint) {
+ S2LatLngRect a = RectFromDegrees(1, -8, 10, 20);
+ VerifyGetDirectedHausdorffDistance(a, PointRectFromDegrees(5, 8));
+ VerifyGetDirectedHausdorffDistance(a, PointRectFromDegrees(-6, -100));
+ // south pole
+ VerifyGetDirectedHausdorffDistance(a, PointRectFromDegrees(-90, -20));
+ // north pole
+ VerifyGetDirectedHausdorffDistance(a, PointRectFromDegrees(90, 0));
+}
+
+TEST(S2LatLngRect, GetDirectedHausdorffDistanceRectToRectNearPole) {
+ // Tests near south pole.
+ S2LatLngRect a = RectFromDegrees(-87, 0, -85, 3);
+ VerifyGetDirectedHausdorffDistance(a, RectFromDegrees(-89, 1, -88, 2));
+ VerifyGetDirectedHausdorffDistance(a, RectFromDegrees(-84, 1, -83, 2));
+ VerifyGetDirectedHausdorffDistance(a, RectFromDegrees(-88, 90, -86, 91));
+ VerifyGetDirectedHausdorffDistance(a, RectFromDegrees(-84, -91, -83, -90));
+ VerifyGetDirectedHausdorffDistance(a, RectFromDegrees(-90, 181, -89, 182));
+ VerifyGetDirectedHausdorffDistance(a, RectFromDegrees(-84, 181, -83, 182));
+}
+
+TEST(S2LatLngRect, GetDirectedHausdorffDistanceRectToRectDegenerateCases) {
+ // Rectangles that contain poles.
+ VerifyGetDirectedHausdorffDistance(
+ RectFromDegrees(0, 10, 90, 20), RectFromDegrees(-4, -10, 4, 0));
+ VerifyGetDirectedHausdorffDistance(
+ RectFromDegrees(-4, -10, 4, 0), RectFromDegrees(0, 10, 90, 20));
+
+ // Two rectangles share same or complement longitudinal intervals.
+ S2LatLngRect a = RectFromDegrees(-50, -10, 50, 10);
+ S2LatLngRect b = RectFromDegrees(30, -10, 60, 10);
+ VerifyGetDirectedHausdorffDistance(a, b);
+ S2LatLngRect c(a.lat(), a.lng().Complement());
+ VerifyGetDirectedHausdorffDistance(c, b);
+
+ // rectangle a touches b_opposite_lng.
+ VerifyGetDirectedHausdorffDistance(
+ RectFromDegrees(10, 170, 30, 180), RectFromDegrees(-50, -10, 50, 10));
+ VerifyGetDirectedHausdorffDistance(
+ RectFromDegrees(10, -180, 30, -170), RectFromDegrees(-50, -10, 50, 10));
+
+ // rectangle b's Voronoi diagram is degenerate (lng interval spans 180
+ // degrees), and a touches the degenerate Voronoi vertex.
+ VerifyGetDirectedHausdorffDistance(
+ RectFromDegrees(-30, 170, 30, 180), RectFromDegrees(-10, -90, 10, 90));
+ VerifyGetDirectedHausdorffDistance(
+ RectFromDegrees(-30, -180, 30, -170), RectFromDegrees(-10, -90, 10, 90));
+
+ // rectangle a touches a voronoi vertex of rectangle b.
+ VerifyGetDirectedHausdorffDistance(
+ RectFromDegrees(-20, 105, 20, 110), RectFromDegrees(-30, 5, 30, 15));
+ VerifyGetDirectedHausdorffDistance(
+ RectFromDegrees(-20, 95, 20, 105), RectFromDegrees(-30, 5, 30, 15));
+}
diff --git a/src/third_party/s2/s2loop.cc b/src/third_party/s2/s2loop.cc
new file mode 100644
index 00000000000..6d802a86353
--- /dev/null
+++ b/src/third_party/s2/s2loop.cc
@@ -0,0 +1,818 @@
+// Copyright 2005 Google Inc. All Rights Reserved.
+
+#include <algorithm>
+using std::min;
+using std::max;
+using std::swap;
+using std::reverse;
+
+#include <set>
+using std::set;
+using std::multiset;
+
+#include <vector>
+using std::vector;
+
+#include "s2.h"
+
+#if defined OS_MACOSX
+#include <ext/hash_map>
+#else
+#include <hash_map>
+#endif
+#ifndef _WIN32
+using __gnu_cxx::hash_map;
+#endif
+
+#include <utility>
+using std::pair;
+using std::make_pair;
+
+
+#include "s2loop.h"
+
+#include "base/commandlineflags.h"
+#include "base/logging.h"
+#include "base/scoped_ptr.h"
+#include "util/coding/coder.h"
+#include "s2cap.h"
+#include "s2cell.h"
+#include "s2edgeindex.h"
+
+static const unsigned char kCurrentEncodingVersionNumber = 1;
+
+DECLARE_bool(s2debug); // defined in s2.cc
+
+S2Point const* S2LoopIndex::edge_from(int index) const {
+ return &loop_->vertex(index);
+}
+
+S2Point const* S2LoopIndex::edge_to(int index) const {
+ return &loop_->vertex(index+1);
+}
+
+int S2LoopIndex::num_edges() const {
+ return loop_->num_vertices();
+}
+
+S2Loop::S2Loop()
+ : num_vertices_(0),
+ vertices_(NULL),
+ owns_vertices_(false),
+ bound_(S2LatLngRect::Empty()),
+ depth_(0),
+ index_(this),
+ num_find_vertex_calls_(0) {
+}
+
+S2Loop::S2Loop(vector<S2Point> const& vertices)
+ : num_vertices_(0),
+ vertices_(NULL),
+ owns_vertices_(false),
+ bound_(S2LatLngRect::Full()),
+ depth_(0),
+ index_(this),
+ num_find_vertex_calls_(0) {
+ Init(vertices);
+}
+
+void S2Loop::ResetMutableFields() {
+ index_.Reset();
+ num_find_vertex_calls_ = 0;
+ vertex_to_index_.clear();
+}
+
+void S2Loop::Init(vector<S2Point> const& vertices) {
+ ResetMutableFields();
+
+ if (owns_vertices_) delete[] vertices_;
+ num_vertices_ = vertices.size();
+ if (vertices.empty()) {
+ vertices_ = NULL;
+ } else {
+ vertices_ = new S2Point[num_vertices_];
+ memcpy(vertices_, &vertices[0], num_vertices_ * sizeof(vertices_[0]));
+ }
+ owns_vertices_ = true;
+ bound_ = S2LatLngRect::Full();
+
+ // InitOrigin() must be called before InitBound() because the latter
+ // function expects Contains() to work properly.
+ InitOrigin();
+ InitBound();
+}
+
+bool S2Loop::IsValid() const {
+ // Loops must have at least 3 vertices.
+ if (num_vertices() < 3) {
+ VLOG(2) << "Degenerate loop";
+ return false;
+ }
+ // All vertices must be unit length.
+ for (int i = 0; i < num_vertices(); ++i) {
+ if (!S2::IsUnitLength(vertex(i))) {
+ VLOG(2) << "Vertex " << i << " is not unit length";
+ return false;
+ }
+ }
+ // Loops are not allowed to have any duplicate vertices.
+ hash_map<S2Point, int> vmap;
+ for (int i = 0; i < num_vertices(); ++i) {
+ if (!vmap.insert(make_pair(vertex(i), i)).second) {
+ VLOG(2) << "Duplicate vertices: " << vmap[vertex(i)] << " and " << i;
+ return false;
+ }
+ }
+ // Non-adjacent edges are not allowed to intersect.
+ bool crosses = false;
+ index_.PredictAdditionalCalls(num_vertices());
+ S2EdgeIndex::Iterator it(&index_);
+ for (int i = 0; i < num_vertices(); ++i) {
+ S2EdgeUtil::EdgeCrosser crosser(&vertex(i), &vertex(i+1), &vertex(0));
+ int previous_index = -2;
+ for (it.GetCandidates(vertex(i), vertex(i+1)); !it.Done(); it.Next()) {
+ int ai = it.Index();
+ // There is no need to test the same thing twice. Moreover, two edges
+ // that abut at ai+1 will have been tested for equality above.
+ if (ai > i+1) {
+ if (previous_index != ai) crosser.RestartAt(&vertex(ai));
+ // Beware, this may return the loop is valid if there is a
+ // "vertex crossing".
+ // TODO(user): Fix that.
+ crosses = crosser.RobustCrossing(&vertex(ai+1)) > 0;
+ previous_index = ai + 1;
+ if (crosses) {
+ VLOG(2) << "Edges " << i << " and " << ai << " cross";
+ // additional debugging information:
+ VLOG(2) << "Edge locations in degrees: "
+ << S2LatLng(vertex(i)) << "-" << S2LatLng(vertex(i+1))
+ << " and "
+ << S2LatLng(vertex(ai)) << "-" << S2LatLng(vertex(ai+1));
+ break;
+ }
+ }
+ }
+ if (crosses) break;
+ }
+
+ return !crosses;
+}
+
+bool S2Loop::IsValid(vector<S2Point> const& vertices, int max_adjacent) {
+ if (vertices.size() < 3) return false;
+
+ S2Loop loop(vertices);
+ return loop.IsValid();
+}
+
+bool S2Loop::IsValid(int max_adjacent) const {
+ return IsValid();
+}
+
+void S2Loop::InitOrigin() {
+ // The bounding box does not need to be correct before calling this
+ // function, but it must at least contain vertex(1) since we need to
+ // do a Contains() test on this point below.
+ DCHECK(bound_.Contains(vertex(1)));
+
+ // To ensure that every point is contained in exactly one face of a
+ // subdivision of the sphere, all containment tests are done by counting the
+ // edge crossings starting at a fixed point on the sphere (S2::Origin()).
+ // We need to know whether this point is inside or outside of the loop.
+ // We do this by first guessing that it is outside, and then seeing whether
+ // we get the correct containment result for vertex 1. If the result is
+ // incorrect, the origin must be inside the loop.
+ //
+ // A loop with consecutive vertices A,B,C contains vertex B if and only if
+ // the fixed vector R = S2::Ortho(B) is on the left side of the wedge ABC.
+ // The test below is written so that B is inside if C=R but not if A=R.
+
+ origin_inside_ = false; // Initialize before calling Contains().
+ bool v1_inside = S2::OrderedCCW(S2::Ortho(vertex(1)), vertex(0), vertex(2),
+ vertex(1));
+ if (v1_inside != Contains(vertex(1)))
+ origin_inside_ = true;
+}
+
+void S2Loop::InitBound() {
+ // The bounding rectangle of a loop is not necessarily the same as the
+ // bounding rectangle of its vertices. First, the loop may wrap entirely
+ // around the sphere (e.g. a loop that defines two revolutions of a
+ // candy-cane stripe). Second, the loop may include one or both poles.
+ // Note that a small clockwise loop near the equator contains both poles.
+
+ S2EdgeUtil::RectBounder bounder;
+ for (int i = 0; i <= num_vertices(); ++i) {
+ bounder.AddPoint(&vertex(i));
+ }
+ S2LatLngRect b = bounder.GetBound();
+ // Note that we need to initialize bound_ with a temporary value since
+ // Contains() does a bounding rectangle check before doing anything else.
+ bound_ = S2LatLngRect::Full();
+ if (Contains(S2Point(0, 0, 1))) {
+ b = S2LatLngRect(R1Interval(b.lat().lo(), M_PI_2), S1Interval::Full());
+ }
+ // If a loop contains the south pole, then either it wraps entirely
+ // around the sphere (full longitude range), or it also contains the
+ // north pole in which case b.lng().is_full() due to the test above.
+ // Either way, we only need to do the south pole containment test if
+ // b.lng().is_full().
+ if (b.lng().is_full() && Contains(S2Point(0, 0, -1))) {
+ b.mutable_lat()->set_lo(-M_PI_2);
+ }
+ bound_ = b;
+}
+
+S2Loop::S2Loop(S2Cell const& cell)
+ : bound_(cell.GetRectBound()),
+ index_(this),
+ num_find_vertex_calls_(0) {
+ num_vertices_ = 4;
+ vertices_ = new S2Point[num_vertices_];
+ depth_ = 0;
+ for (int i = 0; i < 4; ++i) {
+ vertices_[i] = cell.GetVertex(i);
+ }
+ owns_vertices_ = true;
+ InitOrigin();
+ InitBound();
+}
+
+S2Loop::~S2Loop() {
+ if (owns_vertices_) {
+ delete[] vertices_;
+ }
+}
+
+S2Loop::S2Loop(S2Loop const* src)
+ : num_vertices_(src->num_vertices_),
+ vertices_(new S2Point[num_vertices_]),
+ owns_vertices_(true),
+ bound_(src->bound_),
+ origin_inside_(src->origin_inside_),
+ depth_(src->depth_),
+ index_(this),
+ num_find_vertex_calls_(0) {
+ memcpy(vertices_, src->vertices_, num_vertices_ * sizeof(vertices_[0]));
+}
+
+S2Loop* S2Loop::Clone() const {
+ return new S2Loop(this);
+}
+
+int S2Loop::FindVertex(S2Point const& p) const {
+ num_find_vertex_calls_++;
+ if (num_vertices() < 10 || num_find_vertex_calls_ < 20) {
+ // Exhaustive search
+ for (int i = 1; i <= num_vertices(); ++i) {
+ if (vertex(i) == p) return i;
+ }
+ return -1;
+ }
+
+ if (vertex_to_index_.empty()) { // We haven't computed it yet.
+ for (int i = num_vertices(); i > 0; --i) {
+ vertex_to_index_[vertex(i)] = i;
+ }
+ }
+
+ map<S2Point, int>::const_iterator it;
+ it = vertex_to_index_.find(p);
+ if (it == vertex_to_index_.end()) return -1;
+ return it->second;
+}
+
+
+bool S2Loop::IsNormalized() const {
+ // Optimization: if the longitude span is less than 180 degrees, then the
+ // loop covers less than half the sphere and is therefore normalized.
+ if (bound_.lng().GetLength() < M_PI) return true;
+
+ // We allow some error so that hemispheres are always considered normalized.
+ // TODO(user): This might not be necessary once S2Polygon is enhanced so
+ // that it does not require its input loops to be normalized.
+ return GetTurningAngle() >= -1e-14;
+}
+
+void S2Loop::Normalize() {
+ CHECK(owns_vertices_);
+ if (!IsNormalized()) Invert();
+ DCHECK(IsNormalized());
+}
+
+void S2Loop::Invert() {
+ CHECK(owns_vertices_);
+
+ ResetMutableFields();
+ reverse(vertices_, vertices_ + num_vertices());
+ origin_inside_ ^= true;
+ if (bound_.lat().lo() > -M_PI_2 && bound_.lat().hi() < M_PI_2) {
+ // The complement of this loop contains both poles.
+ bound_ = S2LatLngRect::Full();
+ } else {
+ InitBound();
+ }
+}
+
+double S2Loop::GetArea() const {
+ double area = GetSurfaceIntegral(S2::SignedArea);
+ // The signed area should be between approximately -4*Pi and 4*Pi.
+ DCHECK_LE(fabs(area), 4 * M_PI + 1e-12);
+ if (area < 0) {
+ // We have computed the negative of the area of the loop exterior.
+ area += 4 * M_PI;
+ }
+ return max(0.0, min(4 * M_PI, area));
+}
+
+S2Point S2Loop::GetCentroid() const {
+ // GetSurfaceIntegral() returns either the integral of position over loop
+ // interior, or the negative of the integral of position over the loop
+ // exterior. But these two values are the same (!), because the integral of
+ // position over the entire sphere is (0, 0, 0).
+ return GetSurfaceIntegral(S2::TrueCentroid);
+}
+
+// Return (first, dir) such that first..first+n*dir are valid indices.
+int S2Loop::GetCanonicalFirstVertex(int* dir) const {
+ int first = 0;
+ int n = num_vertices();
+ for (int i = 1; i < n; ++i) {
+ if (vertex(i) < vertex(first)) first = i;
+ }
+ if (vertex(first + 1) < vertex(first + n - 1)) {
+ *dir = 1;
+ // 0 <= first <= n-1, so (first+n*dir) <= 2*n-1.
+ } else {
+ *dir = -1;
+ first += n;
+ // n <= first <= 2*n-1, so (first+n*dir) >= 0.
+ }
+ return first;
+}
+
+double S2Loop::GetTurningAngle() const {
+ // Don't crash even if the loop is not well-defined.
+ if (num_vertices() < 3) return 0;
+
+ // To ensure that we get the same result when the loop vertex order is
+ // rotated, and that we get the same result with the opposite sign when the
+ // vertices are reversed, we need to be careful to add up the individual
+ // turn angles in a consistent order. In general, adding up a set of
+ // numbers in a different order can change the sum due to rounding errors.
+ int n = num_vertices();
+ int dir, i = GetCanonicalFirstVertex(&dir);
+ double angle = S2::TurnAngle(vertex((i + n - dir) % n), vertex(i),
+ vertex((i + dir) % n));
+ while (--n > 0) {
+ i += dir;
+ angle += S2::TurnAngle(vertex(i - dir), vertex(i), vertex(i + dir));
+ }
+ return dir * angle;
+}
+
+S2Cap S2Loop::GetCapBound() const {
+ return bound_.GetCapBound();
+}
+
+bool S2Loop::Contains(S2Cell const& cell) const {
+ // A future optimization could also take advantage of the fact than an S2Cell
+ // is convex.
+
+ // It's not necessarily true that bound_.Contains(cell.GetRectBound())
+ // because S2Cell bounds are slightly conservative.
+ if (!bound_.Contains(cell.GetCenter())) return false;
+ S2Loop cell_loop(cell);
+ return Contains(&cell_loop);
+}
+
+bool S2Loop::MayIntersect(S2Cell const& cell) const {
+ // It is faster to construct a bounding rectangle for an S2Cell than for
+ // a general polygon. A future optimization could also take advantage of
+ // the fact than an S2Cell is convex.
+
+ if (!bound_.Intersects(cell.GetRectBound())) return false;
+ return S2Loop(cell).Intersects(this);
+}
+
+bool S2Loop::Contains(S2Point const& p) const {
+ if (!bound_.Contains(p)) return false;
+
+ bool inside = origin_inside_;
+ S2Point origin = S2::Origin();
+ S2EdgeUtil::EdgeCrosser crosser(&origin, &p, &vertex(0));
+
+ // The s2edgeindex library is not optimized yet for long edges,
+ // so the tradeoff to using it comes later.
+ if (num_vertices() < 2000) {
+ for (int i = 1; i <= num_vertices(); ++i) {
+ inside ^= crosser.EdgeOrVertexCrossing(&vertex(i));
+ }
+ return inside;
+ }
+
+ S2EdgeIndex::Iterator it(&index_);
+ int previous_index = -2;
+ for (it.GetCandidates(origin, p); !it.Done(); it.Next()) {
+ int ai = it.Index();
+ if (previous_index != ai - 1) crosser.RestartAt(&vertex(ai));
+ previous_index = ai;
+ inside ^= crosser.EdgeOrVertexCrossing(&vertex(ai+1));
+ }
+ return inside;
+}
+
+void S2Loop::Encode(Encoder* const encoder) const {
+ encoder->Ensure(num_vertices_ * sizeof(*vertices_) + 20); // sufficient
+
+ encoder->put8(kCurrentEncodingVersionNumber);
+ encoder->put32(num_vertices_);
+ encoder->putn(vertices_, sizeof(*vertices_) * num_vertices_);
+ encoder->put8(origin_inside_);
+ encoder->put32(depth_);
+ DCHECK_GE(encoder->avail(), 0);
+
+ bound_.Encode(encoder);
+}
+
+bool S2Loop::Decode(Decoder* const decoder) {
+ return DecodeInternal(decoder, false);
+}
+
+bool S2Loop::DecodeWithinScope(Decoder* const decoder) {
+ return DecodeInternal(decoder, true);
+}
+
+bool S2Loop::DecodeInternal(Decoder* const decoder,
+ bool within_scope) {
+ unsigned char version = decoder->get8();
+ if (version > kCurrentEncodingVersionNumber) return false;
+
+ num_vertices_ = decoder->get32();
+ if (owns_vertices_) delete[] vertices_;
+ if (within_scope) {
+ vertices_ = const_cast<S2Point *>(reinterpret_cast<S2Point const*>(
+ decoder->ptr()));
+ decoder->skip(num_vertices_ * sizeof(*vertices_));
+ owns_vertices_ = false;
+ } else {
+ vertices_ = new S2Point[num_vertices_];
+ decoder->getn(vertices_, num_vertices_ * sizeof(*vertices_));
+ owns_vertices_ = true;
+ }
+ origin_inside_ = decoder->get8();
+ depth_ = decoder->get32();
+ if (!bound_.Decode(decoder)) return false;
+
+ DCHECK(IsValid());
+
+ return decoder->avail() >= 0;
+}
+
+// This is a helper class for the AreBoundariesCrossing function.
+// Each time there is a point in common between the two loops passed
+// as parameters, the two associated wedges centered at this point are
+// passed to the ProcessWedge function of this processor. The function
+// updates an internal state based on the wedges, and returns true to
+// signal that no further processing is needed.
+//
+// To use AreBoundariesCrossing, subclass this class and keep an
+// internal state that you update each time ProcessWedge is called,
+// then query this internal state in the function that called
+// AreBoundariesCrossing.
+class WedgeProcessor {
+ public:
+ virtual ~WedgeProcessor() { }
+
+ virtual bool ProcessWedge(S2Point const& a0, S2Point const& ab1,
+ S2Point const& a2, S2Point const& b0,
+ S2Point const& b2) = 0;
+};
+
+bool S2Loop::AreBoundariesCrossing(
+ S2Loop const* b, WedgeProcessor* wedge_processor) const {
+ // See the header file for a description of what this method does.
+ index_.PredictAdditionalCalls(b->num_vertices());
+ S2EdgeIndex::Iterator it(&index_);
+ for (int j = 0; j < b->num_vertices(); ++j) {
+ S2EdgeUtil::EdgeCrosser crosser(&b->vertex(j), &b->vertex(j+1),
+ &b->vertex(0));
+ int previous_index = -2;
+ for (it.GetCandidates(b->vertex(j), b->vertex(j+1));
+ !it.Done(); it.Next()) {
+ int ai = it.Index();
+ if (previous_index != ai - 1) crosser.RestartAt(&vertex(ai));
+ previous_index = ai;
+ int crossing = crosser.RobustCrossing(&vertex(ai + 1));
+ if (crossing < 0) continue;
+ if (crossing > 0) return true;
+ // We only need to check each shared vertex once, so we only
+ // consider the case where vertex(i+1) == b->vertex(j+1).
+ if (vertex(ai+1) == b->vertex(j+1) &&
+ wedge_processor->ProcessWedge(vertex(ai), vertex(ai+1), vertex(ai+2),
+ b->vertex(j), b->vertex(j+2))) {
+ return false;
+ }
+ }
+ }
+ return false;
+}
+
+// WedgeProcessor to be used to check if loop A contains loop B.
+// DoesntContain() then returns true if there is a wedge of B not
+// contained in the associated wedge of A (and hence loop B is not
+// contained in loop A).
+class ContainsWedgeProcessor: public WedgeProcessor {
+ public:
+ ContainsWedgeProcessor(): doesnt_contain_(false) {}
+ bool DoesntContain() { return doesnt_contain_; }
+
+ protected:
+ virtual bool ProcessWedge(S2Point const& a0, S2Point const& ab1,
+ S2Point const& a2, S2Point const& b0,
+ S2Point const& b2) {
+ doesnt_contain_ = !S2EdgeUtil::WedgeContains(a0, ab1, a2, b0, b2);
+ return doesnt_contain_;
+ }
+
+ private:
+ bool doesnt_contain_;
+};
+
+bool S2Loop::Contains(S2Loop const* b) const {
+ // For this loop A to contains the given loop B, all of the following must
+ // be true:
+ //
+ // (1) There are no edge crossings between A and B except at vertices.
+ //
+ // (2) At every vertex that is shared between A and B, the local edge
+ // ordering implies that A contains B.
+ //
+ // (3) If there are no shared vertices, then A must contain a vertex of B
+ // and B must not contain a vertex of A. (An arbitrary vertex may be
+ // chosen in each case.)
+ //
+ // The second part of (3) is necessary to detect the case of two loops whose
+ // union is the entire sphere, i.e. two loops that contains each other's
+ // boundaries but not each other's interiors.
+
+ if (!bound_.Contains(b->bound_)) return false;
+
+ // Unless there are shared vertices, we need to check whether A contains a
+ // vertex of B. Since shared vertices are rare, it is more efficient to do
+ // this test up front as a quick rejection test.
+ if (!Contains(b->vertex(0)) && FindVertex(b->vertex(0)) < 0)
+ return false;
+
+ // Now check whether there are any edge crossings, and also check the loop
+ // relationship at any shared vertices.
+ ContainsWedgeProcessor p_wedge;
+ if (AreBoundariesCrossing(b, &p_wedge) || p_wedge.DoesntContain()) {
+ return false;
+ }
+
+ // At this point we know that the boundaries of A and B do not intersect,
+ // and that A contains a vertex of B. However we still need to check for
+ // the case mentioned above, where (A union B) is the entire sphere.
+ // Normally this check is very cheap due to the bounding box precondition.
+ if (bound_.Union(b->bound_).is_full()) {
+ if (b->Contains(vertex(0)) && b->FindVertex(vertex(0)) < 0) return false;
+ }
+ return true;
+}
+
+// WedgeProcessor to be used to check if loop A intersects loop B.
+// Intersects() then returns true when A and B have at least one pair
+// of associated wedges that intersect.
+class IntersectsWedgeProcessor: public WedgeProcessor {
+ public:
+ IntersectsWedgeProcessor(): intersects_(false) {}
+ bool Intersects() { return intersects_; }
+
+ protected:
+ virtual bool ProcessWedge(S2Point const& a0, S2Point const& ab1,
+ S2Point const& a2, S2Point const& b0,
+ S2Point const& b2) {
+ intersects_ = S2EdgeUtil::WedgeIntersects(a0, ab1, a2, b0, b2);
+ return intersects_;
+ }
+
+ private:
+ bool intersects_;
+};
+
+bool S2Loop::Intersects(S2Loop const* b) const {
+ // a->Intersects(b) if and only if !a->Complement()->Contains(b).
+ // This code is similar to Contains(), but is optimized for the case
+ // where both loops enclose less than half of the sphere.
+
+ // The largest of the two loops should be edgeindex'd.
+ if (b->num_vertices() > num_vertices()) return b->Intersects(this);
+
+ if (!bound_.Intersects(b->bound_)) return false;
+
+ // Unless there are shared vertices, we need to check whether A contains a
+ // vertex of B. Since shared vertices are rare, it is more efficient to do
+ // this test up front as a quick acceptance test.
+ if (Contains(b->vertex(0)) && FindVertex(b->vertex(0)) < 0)
+ return true;
+
+ // Now check whether there are any edge crossings, and also check the loop
+ // relationship at any shared vertices.
+ IntersectsWedgeProcessor p_wedge;
+ if (AreBoundariesCrossing(b, &p_wedge) || p_wedge.Intersects()) {
+ return true;
+ }
+
+ // We know that A does not contain a vertex of B, and that there are no edge
+ // crossings. Therefore the only way that A can intersect B is if B
+ // entirely contains A. We can check this by testing whether B contains an
+ // arbitrary non-shared vertex of A. Note that this check is usually cheap
+ // because of the bounding box precondition.
+ if (b->bound_.Contains(bound_)) {
+ if (b->Contains(vertex(0)) && b->FindVertex(vertex(0)) < 0) return true;
+ }
+ return false;
+}
+
+// WedgeProcessor to be used to check if the interior of loop A
+// contains the interior of loop B, or their boundaries cross each
+// other (therefore they have a proper intersection).
+// CrossesOrMayContain() then returns -1 if A crossed B, 0 if it is
+// not possible for A to contain B, and 1 otherwise.
+class ContainsOrCrossesProcessor: public WedgeProcessor {
+ public:
+ ContainsOrCrossesProcessor():
+ has_boundary_crossing_(false),
+ a_has_strictly_super_wedge_(false), b_has_strictly_super_wedge_(false),
+ has_disjoint_wedge_(false) {}
+
+ int CrossesOrMayContain() {
+ if (has_boundary_crossing_) return -1;
+ if (has_disjoint_wedge_ || b_has_strictly_super_wedge_) return 0;
+ return 1;
+ }
+
+ protected:
+ virtual bool ProcessWedge(S2Point const& a0, S2Point const& ab1,
+ S2Point const& a2, S2Point const& b0,
+ S2Point const& b2) {
+ const S2EdgeUtil::WedgeRelation wedge_relation =
+ S2EdgeUtil::GetWedgeRelation(a0, ab1, a2, b0, b2);
+ if (wedge_relation == S2EdgeUtil::WEDGE_PROPERLY_OVERLAPS) {
+ has_boundary_crossing_ = true;
+ return true;
+ }
+
+ a_has_strictly_super_wedge_ |=
+ (wedge_relation == S2EdgeUtil::WEDGE_PROPERLY_CONTAINS);
+ b_has_strictly_super_wedge_ |=
+ (wedge_relation == S2EdgeUtil::WEDGE_IS_PROPERLY_CONTAINED);
+ if (a_has_strictly_super_wedge_ && b_has_strictly_super_wedge_) {
+ has_boundary_crossing_ = true;
+ return true;
+ }
+
+ has_disjoint_wedge_ |= (wedge_relation == S2EdgeUtil::WEDGE_IS_DISJOINT);
+ return false;
+ }
+
+ private:
+ // True if any crossing on the boundary is discovered.
+ bool has_boundary_crossing_;
+ // True if A (B) has a strictly superwedge on a pair of wedges that
+ // share a common center point.
+ bool a_has_strictly_super_wedge_;
+ bool b_has_strictly_super_wedge_;
+ // True if there is a pair of disjoint wedges with common center
+ // point.
+ bool has_disjoint_wedge_;
+};
+
+int S2Loop::ContainsOrCrosses(S2Loop const* b) const {
+ // There can be containment or crossing only if the bounds intersect.
+ if (!bound_.Intersects(b->bound_)) return 0;
+
+ // Now check whether there are any edge crossings, and also check the loop
+ // relationship at any shared vertices. Note that unlike Contains() or
+ // Intersects(), we can't do a point containment test as a shortcut because
+ // we need to detect whether there are any edge crossings.
+ ContainsOrCrossesProcessor p_wedge;
+ if (AreBoundariesCrossing(b, &p_wedge)) {
+ return -1;
+ }
+ const int result = p_wedge.CrossesOrMayContain();
+ if (result <= 0) return result;
+
+ // At this point we know that the boundaries do not intersect, and we are
+ // given that (A union B) is a proper subset of the sphere. Furthermore
+ // either A contains B, or there are no shared vertices (due to the check
+ // above). So now we just need to distinguish the case where A contains B
+ // from the case where B contains A or the two loops are disjoint.
+ if (!bound_.Contains(b->bound_)) return 0;
+ if (!Contains(b->vertex(0)) && FindVertex(b->vertex(0)) < 0) return 0;
+ return 1;
+}
+
+bool S2Loop::ContainsNested(S2Loop const* b) const {
+ if (!bound_.Contains(b->bound_)) return false;
+
+ // We are given that A and B do not share any edges, and that either one
+ // loop contains the other or they do not intersect.
+ int m = FindVertex(b->vertex(1));
+ if (m < 0) {
+ // Since b->vertex(1) is not shared, we can check whether A contains it.
+ return Contains(b->vertex(1));
+ }
+ // Check whether the edge order around b->vertex(1) is compatible with
+ // A containing B.
+ return S2EdgeUtil::WedgeContains(vertex(m-1), vertex(m), vertex(m+1),
+ b->vertex(0), b->vertex(2));
+}
+
+bool S2Loop::BoundaryEquals(S2Loop const* b) const {
+ if (num_vertices() != b->num_vertices()) return false;
+ for (int offset = 0; offset < num_vertices(); ++offset) {
+ if (vertex(offset) == b->vertex(0)) {
+ // There is at most one starting offset since loop vertices are unique.
+ for (int i = 0; i < num_vertices(); ++i) {
+ if (vertex(i + offset) != b->vertex(i)) return false;
+ }
+ return true;
+ }
+ }
+ return false;
+}
+
+bool S2Loop::BoundaryApproxEquals(S2Loop const* b, double max_error) const {
+ if (num_vertices() != b->num_vertices()) return false;
+ for (int offset = 0; offset < num_vertices(); ++offset) {
+ if (S2::ApproxEquals(vertex(offset), b->vertex(0), max_error)) {
+ bool success = true;
+ for (int i = 0; i < num_vertices(); ++i) {
+ if (!S2::ApproxEquals(vertex(i + offset), b->vertex(i), max_error)) {
+ success = false;
+ break;
+ }
+ }
+ if (success) return true;
+ // Otherwise continue looping. There may be more than one candidate
+ // starting offset since vertices are only matched approximately.
+ }
+ }
+ return false;
+}
+
+static bool MatchBoundaries(S2Loop const* a, S2Loop const* b, int a_offset,
+ double max_error) {
+ // The state consists of a pair (i,j). A state transition consists of
+ // incrementing either "i" or "j". "i" can be incremented only if
+ // a(i+1+a_offset) is near the edge from b(j) to b(j+1), and a similar rule
+ // applies to "j". The function returns true iff we can proceed all the way
+ // around both loops in this way.
+ //
+ // Note that when "i" and "j" can both be incremented, sometimes only one
+ // choice leads to a solution. We handle this using a stack and
+ // backtracking. We also keep track of which states have already been
+ // explored to avoid duplicating work.
+
+ vector<pair<int, int> > pending;
+ set<pair<int, int> > done;
+ pending.push_back(make_pair(0, 0));
+ while (!pending.empty()) {
+ int i = pending.back().first;
+ int j = pending.back().second;
+ pending.pop_back();
+ if (i == a->num_vertices() && j == b->num_vertices()) {
+ return true;
+ }
+ done.insert(make_pair(i, j));
+
+ // If (i == na && offset == na-1) where na == a->num_vertices(), then
+ // then (i+1+offset) overflows the [0, 2*na-1] range allowed by vertex().
+ // So we reduce the range if necessary.
+ int io = i + a_offset;
+ if (io >= a->num_vertices()) io -= a->num_vertices();
+
+ if (i < a->num_vertices() && done.count(make_pair(i+1, j)) == 0 &&
+ S2EdgeUtil::GetDistance(a->vertex(io+1),
+ b->vertex(j),
+ b->vertex(j+1)).radians() <= max_error) {
+ pending.push_back(make_pair(i+1, j));
+ }
+ if (j < b->num_vertices() && done.count(make_pair(i, j+1)) == 0 &&
+ S2EdgeUtil::GetDistance(b->vertex(j+1),
+ a->vertex(io),
+ a->vertex(io+1)).radians() <= max_error) {
+ pending.push_back(make_pair(i, j+1));
+ }
+ }
+ return false;
+}
+
+bool S2Loop::BoundaryNear(S2Loop const* b, double max_error) const {
+ for (int a_offset = 0; a_offset < num_vertices(); ++a_offset) {
+ if (MatchBoundaries(this, b, a_offset, max_error)) return true;
+ }
+ return false;
+}
diff --git a/src/third_party/s2/s2loop.h b/src/third_party/s2/s2loop.h
new file mode 100644
index 00000000000..85dbd70d914
--- /dev/null
+++ b/src/third_party/s2/s2loop.h
@@ -0,0 +1,431 @@
+// Copyright 2005 Google Inc. All Rights Reserved.
+
+#ifndef UTIL_GEOMETRY_S2LOOP_H__
+#define UTIL_GEOMETRY_S2LOOP_H__
+
+#include <map>
+using std::map;
+using std::multimap;
+
+#include <vector>
+using std::vector;
+
+
+#include "base/logging.h"
+#include "base/macros.h"
+#include "s2edgeindex.h"
+#include "s2region.h"
+#include "s2latlngrect.h"
+#include "s2edgeutil.h"
+
+class S2Loop;
+// Defined in the cc file. A helper class for AreBoundariesCrossing.
+class WedgeProcessor;
+
+// Indexing structure to efficiently compute intersections.
+class S2LoopIndex: public S2EdgeIndex {
+ public:
+ explicit S2LoopIndex(S2Loop const* loop): loop_(loop) {}
+ virtual ~S2LoopIndex() {}
+
+ // There is no need to overwrite Reset(), as the only data that's
+ // used to implement this class is all contained in the loop data.
+ // void Reset();
+
+ virtual S2Point const* edge_from(int index) const;
+ virtual S2Point const* edge_to(int index) const;
+ virtual int num_edges() const;
+
+ private:
+ S2Loop const* loop_;
+};
+
+// An S2Loop represents a simple spherical polygon. It consists of a single
+// chain of vertices where the first vertex is implicitly connected to the
+// last. All loops are defined to have a CCW orientation, i.e. the interior
+// of the polygon is on the left side of the edges. This implies that a
+// clockwise loop enclosing a small area is interpreted to be a CCW loop
+// enclosing a very large area.
+//
+// Loops are not allowed to have any duplicate vertices (whether adjacent or
+// not), and non-adjacent edges are not allowed to intersect. Loops must have
+// at least 3 vertices. Although these restrictions are not enforced in
+// optimized code, you may get unexpected results if they are violated.
+//
+// Point containment is defined such that if the sphere is subdivided into
+// faces (loops), every point is contained by exactly one face. This implies
+// that loops do not necessarily contain all (or any) of their vertices.
+//
+// TODO(user): When doing operations on two loops, always create the
+// edgeindex for the bigger of the two. Same for polygons.
+class S2Loop : public S2Region {
+ public:
+ // Create an empty S2Loop that should be initialized by calling Init() or
+ // Decode().
+ S2Loop();
+
+ // Convenience constructor that calls Init() with the given vertices.
+ explicit S2Loop(vector<S2Point> const& vertices);
+
+ // Initialize a loop connecting the given vertices. The last vertex is
+ // implicitly connected to the first. All points should be unit length.
+ // Loops must have at least 3 vertices.
+ void Init(vector<S2Point> const& vertices);
+
+ // This parameter should be removed as soon as people stop using the
+ // deprecated version of IsValid.
+ static int const kDefaultMaxAdjacent = 0;
+
+ // Check whether this loop is valid. Note that in debug mode, validity
+ // is checked at loop creation time, so IsValid()
+ // should always return true.
+ bool IsValid() const;
+
+
+ // These two versions are deprecated and ignore max_adjacent.
+ // DEPRECATED.
+ static bool IsValid(vector<S2Point> const& vertices, int max_adjacent);
+ // DEPRECATED.
+ bool IsValid(int max_adjacent) const;
+
+ // Initialize a loop corresponding to the given cell.
+ explicit S2Loop(S2Cell const& cell);
+
+ ~S2Loop();
+
+ // The depth of a loop is defined as its nesting level within its containing
+ // polygon. "Outer shell" loops have depth 0, holes within those loops have
+ // depth 1, shells within those holes have depth 2, etc. This field is only
+ // used by the S2Polygon implementation.
+ int depth() const { return depth_; }
+ void set_depth(int depth) { depth_ = depth; }
+
+ // Return true if this loop represents a hole in its containing polygon.
+ bool is_hole() const { return (depth_ & 1) != 0; }
+
+ // The sign of a loop is -1 if the loop represents a hole in its containing
+ // polygon, and +1 otherwise.
+ int sign() const { return is_hole() ? -1 : 1; }
+
+ int num_vertices() const { return num_vertices_; }
+
+ // For convenience, we make two entire copies of the vertex list available:
+ // vertex(n..2*n-1) is mapped to vertex(0..n-1), where n == num_vertices().
+ S2Point const& vertex(int i) const {
+ DCHECK_GE(i, 0);
+ DCHECK_LT(i, (2 * num_vertices_));
+ int j = i - num_vertices();
+ return vertices_[j >= 0 ? j : i];
+ }
+
+ // Return true if the loop area is at most 2*Pi. Degenerate loops are
+ // handled consistently with S2::RobustCCW(), i.e., if a loop can be
+ // expressed as the union of degenerate or nearly-degenerate CCW triangles,
+ // then it will always be considered normalized.
+ bool IsNormalized() const;
+
+ // Invert the loop if necessary so that the area enclosed by the loop is at
+ // most 2*Pi.
+ void Normalize();
+
+ // Reverse the order of the loop vertices, effectively complementing
+ // the region represented by the loop.
+ void Invert();
+
+ // Return the area of the loop interior, i.e. the region on the left side of
+ // the loop. The return value is between 0 and 4*Pi. (Note that the return
+ // value is not affected by whether this loop is a "hole" or a "shell".)
+ double GetArea() const;
+
+ // Return the true centroid of the loop multiplied by the area of the loop
+ // (see s2.h for details on centroids). The result is not unit length, so
+ // you may want to normalize it. Also note that in general, the centroid
+ // may not be contained by the loop.
+ //
+ // We prescale by the loop area for two reasons: (1) it is cheaper to
+ // compute this way, and (2) it makes it easier to compute the centroid of
+ // more complicated shapes (by splitting them into disjoint regions and
+ // adding their centroids).
+ //
+ // Note that the return value is not affected by whether this loop is a
+ // "hole" or a "shell".
+ S2Point GetCentroid() const;
+
+ // Return the sum of the turning angles at each vertex. The return value is
+ // positive if the loop is counter-clockwise, negative if the loop is
+ // clockwise, and zero if the loop is a great circle. Degenerate and
+ // nearly-degenerate loops are handled consistently with S2::RobustCCW().
+ // So for example, if a loop has zero area (i.e., it is a very small CCW
+ // loop) then the turning angle will always be negative.
+ //
+ // This quantity is also called the "geodesic curvature" of the loop.
+ double GetTurningAngle() const;
+
+ // Return true if the region contained by this loop is a superset of the
+ // region contained by the given other loop.
+ bool Contains(S2Loop const* b) const;
+
+ // Return true if the region contained by this loop intersects the region
+ // contained by the given other loop.
+ bool Intersects(S2Loop const* b) const;
+
+ // Given two loops of a polygon (see s2polygon.h for requirements), return
+ // true if A contains B. This version of Contains() is much cheaper since
+ // it does not need to check whether the boundaries of the two loops cross.
+ bool ContainsNested(S2Loop const* b) const;
+
+ // Return +1 if A contains B (i.e. the interior of B is a subset of the
+ // interior of A), -1 if the boundaries of A and B cross, and 0 otherwise.
+ // Requires that A does not properly contain the complement of B, i.e.
+ // A and B do not contain each other's boundaries. This method is used
+ // for testing whether multi-loop polygons contain each other.
+ //
+ // WARNING: there is a bug in this function - it does not detect loop
+ // crossings in certain situations involving shared edges. CL 2926852 works
+ // around this bug for polygon intersection, but it probably effects other
+ // tests. TODO: fix ContainsOrCrosses() and revert CL 2926852.
+ int ContainsOrCrosses(S2Loop const* b) const;
+
+ // Return true if two loops have the same boundary. This is true if and
+ // only if the loops have the same vertices in the same cyclic order.
+ // (For testing purposes.)
+ bool BoundaryEquals(S2Loop const* b) const;
+
+ // Return true if two loops have the same boundary except for vertex
+ // perturbations. More precisely, the vertices in the two loops must be in
+ // the same cyclic order, and corresponding vertex pairs must be separated
+ // by no more than "max_error". (For testing purposes.)
+ bool BoundaryApproxEquals(S2Loop const* b, double max_error = 1e-15) const;
+
+ // Return true if the two loop boundaries are within "max_error" of each
+ // other along their entire lengths. The two loops may have different
+ // numbers of vertices. More precisely, this method returns true if the two
+ // loops have parameterizations a:[0,1] -> S^2, b:[0,1] -> S^2 such that
+ // distance(a(t), b(t)) <= max_error for all t. You can think of this as
+ // testing whether it is possible to drive two cars all the way around the
+ // two loops such that no car ever goes backward and the cars are always
+ // within "max_error" of each other. (For testing purposes.)
+ bool BoundaryNear(S2Loop const* b, double max_error = 1e-15) const;
+
+ // This method computes the oriented surface integral of some quantity f(x)
+ // over the loop interior, given a function f_tri(A,B,C) that returns the
+ // corresponding integral over the spherical triangle ABC. Here "oriented
+ // surface integral" means:
+ //
+ // (1) f_tri(A,B,C) must be the integral of f if ABC is counterclockwise,
+ // and the integral of -f if ABC is clockwise.
+ //
+ // (2) The result of this function is *either* the integral of f over the
+ // loop interior, or the integral of (-f) over the loop exterior.
+ //
+ // Note that there are at least two common situations where it easy to work
+ // around property (2) above:
+ //
+ // - If the integral of f over the entire sphere is zero, then it doesn't
+ // matter which case is returned because they are always equal.
+ //
+ // - If f is non-negative, then it is easy to detect when the integral over
+ // the loop exterior has been returned, and the integral over the loop
+ // interior can be obtained by adding the integral of f over the entire
+ // unit sphere (a constant) to the result.
+ //
+ // Also requires that the default constructor for T must initialize the
+ // value to zero. (This is true for built-in types such as "double".)
+ template <class T>
+ T GetSurfaceIntegral(T f_tri(S2Point const&, S2Point const&, S2Point const&))
+ const;
+
+ ////////////////////////////////////////////////////////////////////////
+ // S2Region interface (see s2region.h for details):
+
+ // GetRectBound() is guaranteed to return exact results, while GetCapBound()
+ // is conservative.
+ virtual S2Loop* Clone() const;
+ virtual S2Cap GetCapBound() const;
+ virtual S2LatLngRect GetRectBound() const { return bound_; }
+
+ virtual bool Contains(S2Cell const& cell) const;
+ virtual bool MayIntersect(S2Cell const& cell) const;
+ virtual bool VirtualContainsPoint(S2Point const& p) const {
+ return Contains(p); // The same as Contains() below, just virtual.
+ }
+
+ // The point 'p' does not need to be normalized.
+ bool Contains(S2Point const& p) const;
+
+ virtual void Encode(Encoder* const encoder) const;
+ virtual bool Decode(Decoder* const decoder);
+ virtual bool DecodeWithinScope(Decoder* const decoder);
+
+ private:
+ // Internal constructor used only by Clone() that makes a deep copy of
+ // its argument.
+ explicit S2Loop(S2Loop const* src);
+
+ void InitOrigin();
+ void InitBound();
+
+ // Internal implementation of the Decode and DecodeWithinScope methods above.
+ // If within_scope is true, memory is allocated for vertices_ and data
+ // is copied from the decoder using memcpy. If it is false, vertices_
+ // will point to the memory area inside the decoder, and the field
+ // owns_vertices_ is set to false.
+ bool DecodeInternal(Decoder* const decoder,
+ bool within_scope);
+
+ // Internal implementation of the Intersects() method above.
+ bool IntersectsInternal(S2Loop const* b) const;
+
+ // Return an index "first" and a direction "dir" (either +1 or -1) such that
+ // the vertex sequence (first, first+dir, ..., first+(n-1)*dir) does not
+ // change when the loop vertex order is rotated or inverted. This allows
+ // the loop vertices to be traversed in a canonical order. The return
+ // values are chosen such that (first, ..., first+n*dir) are in the range
+ // [0, 2*n-1] as expected by the vertex() method.
+ int GetCanonicalFirstVertex(int* dir) const;
+
+ // Return the index of a vertex at point "p", or -1 if not found.
+ // The return value is in the range 1..num_vertices_ if found.
+ int FindVertex(S2Point const& p) const;
+
+ // This method checks all edges of this loop (A) for intersection
+ // against all edges of B. If there is any shared vertex , the
+ // wedges centered at this vertex are sent to wedge_processor.
+ //
+ // Returns true only when the edges intersect in the sense of
+ // S2EdgeUtil::RobustCrossing, returns false immediately when the
+ // wedge_processor returns true: this means the wedge processor
+ // knows the value of the property that the caller wants to compute,
+ // and no further inspection is needed. For instance, if the
+ // property is "loops intersect", then a wedge intersection is all
+ // it takes to return true.
+ //
+ // See Contains(), Intersects() and ContainsOrCrosses() for the
+ // three uses of this function.
+ bool AreBoundariesCrossing(
+ S2Loop const* b, WedgeProcessor* wedge_processor) const;
+
+ // When the loop is modified (the only cae being Invert() at this time),
+ // the indexing structures need to be deleted as they become invalid.
+ void ResetMutableFields();
+
+ // We store the vertices in an array rather than a vector because we don't
+ // need any STL methods, and computing the number of vertices using size()
+ // would be relatively expensive (due to division by sizeof(S2Point) == 24).
+ // When DecodeWithinScope is used to initialize the loop, we do not
+ // take ownership of the memory for vertices_, and the owns_vertices_ field
+ // is used to prevent deallocation and overwriting.
+ int num_vertices_;
+ S2Point* vertices_;
+ bool owns_vertices_;
+
+ S2LatLngRect bound_;
+ bool origin_inside_;
+ int depth_;
+
+ // Quadtree index structure of this loop's edges.
+ mutable S2LoopIndex index_;
+
+ // Map for speeding up FindVertex: We will compute a map from vertex to
+ // index in the vertex array as soon as there has been enough calls.
+ mutable int num_find_vertex_calls_;
+ mutable map<S2Point, int> vertex_to_index_;
+
+ DISALLOW_EVIL_CONSTRUCTORS(S2Loop);
+};
+
+//////////////////// Implementation Details Follow ////////////////////////
+
+// Since this method is templatized and public, the implementation needs to be
+// in the .h file.
+
+template <class T>
+T S2Loop::GetSurfaceIntegral(T f_tri(S2Point const&, S2Point const&,
+ S2Point const&)) const {
+ // We sum "f_tri" over a collection T of oriented triangles, possibly
+ // overlapping. Let the sign of a triangle be +1 if it is CCW and -1
+ // otherwise, and let the sign of a point "x" be the sum of the signs of the
+ // triangles containing "x". Then the collection of triangles T is chosen
+ // such that either:
+ //
+ // (1) Each point in the loop interior has sign +1, and sign 0 otherwise; or
+ // (2) Each point in the loop exterior has sign -1, and sign 0 otherwise.
+ //
+ // The triangles basically consist of a "fan" from vertex 0 to every loop
+ // edge that does not include vertex 0. These triangles will always satisfy
+ // either (1) or (2). However, what makes this a bit tricky is that
+ // spherical edges become numerically unstable as their length approaches
+ // 180 degrees. Of course there is not much we can do if the loop itself
+ // contains such edges, but we would like to make sure that all the triangle
+ // edges under our control (i.e., the non-loop edges) are stable. For
+ // example, consider a loop around the equator consisting of four equally
+ // spaced points. This is a well-defined loop, but we cannot just split it
+ // into two triangles by connecting vertex 0 to vertex 2.
+ //
+ // We handle this type of situation by moving the origin of the triangle fan
+ // whenever we are about to create an unstable edge. We choose a new
+ // location for the origin such that all relevant edges are stable. We also
+ // create extra triangles with the appropriate orientation so that the sum
+ // of the triangle signs is still correct at every point.
+
+ // The maximum length of an edge for it to be considered numerically stable.
+ // The exact value is fairly arbitrary since it depends on the stability of
+ // the "f_tri" function. The value below is quite conservative but could be
+ // reduced further if desired.
+ static double const kMaxLength = M_PI - 1e-5;
+
+ // The default constructor for T must initialize the value to zero.
+ // (This is true for built-in types such as "double".)
+ T sum = T();
+ S2Point origin = vertex(0);
+ for (int i = 1; i + 1 < num_vertices(); ++i) {
+ // Let V_i be vertex(i), let O be the current origin, and let length(A,B)
+ // be the length of edge (A,B). At the start of each loop iteration, the
+ // "leading edge" of the triangle fan is (O,V_i), and we want to extend
+ // the triangle fan so that the leading edge is (O,V_i+1).
+ //
+ // Invariants:
+ // 1. length(O,V_i) < kMaxLength for all (i > 1).
+ // 2. Either O == V_0, or O is approximately perpendicular to V_0.
+ // 3. "sum" is the oriented integral of f over the area defined by
+ // (O, V_0, V_1, ..., V_i).
+ DCHECK(i == 1 || origin.Angle(vertex(i)) < kMaxLength);
+ DCHECK(origin == vertex(0) || fabs(origin.DotProd(vertex(0))) < 1e-15);
+
+ if (vertex(i+1).Angle(origin) > kMaxLength) {
+ // We are about to create an unstable edge, so choose a new origin O'
+ // for the triangle fan.
+ S2Point old_origin = origin;
+ if (origin == vertex(0)) {
+ // The following point is well-separated from V_i and V_0 (and
+ // therefore V_i+1 as well).
+ origin = S2::RobustCrossProd(vertex(0), vertex(i)).Normalize();
+ } else if (vertex(i).Angle(vertex(0)) < kMaxLength) {
+ // All edges of the triangle (O, V_0, V_i) are stable, so we can
+ // revert to using V_0 as the origin.
+ origin = vertex(0);
+ } else {
+ // (O, V_i+1) and (V_0, V_i) are antipodal pairs, and O and V_0 are
+ // perpendicular. Therefore V_0.CrossProd(O) is approximately
+ // perpendicular to all of {O, V_0, V_i, V_i+1}, and we can choose
+ // this point O' as the new origin.
+ origin = vertex(0).CrossProd(old_origin);
+
+ // Advance the edge (V_0,O) to (V_0,O').
+ sum += f_tri(vertex(0), old_origin, origin);
+ }
+ // Advance the edge (O,V_i) to (O',V_i).
+ sum += f_tri(old_origin, vertex(i), origin);
+ }
+ // Advance the edge (O,V_i) to (O,V_i+1).
+ sum += f_tri(origin, vertex(i), vertex(i+1));
+ }
+ // If the origin is not V_0, we need to sum one more triangle.
+ if (origin != vertex(0)) {
+ // Advance the edge (O,V_n-1) to (O,V_0).
+ sum += f_tri(origin, vertex(num_vertices() - 1), vertex(0));
+ }
+ return sum;
+}
+
+#endif // UTIL_GEOMETRY_S2LOOP_H__
diff --git a/src/third_party/s2/s2loop_test.cc b/src/third_party/s2/s2loop_test.cc
new file mode 100644
index 00000000000..972e3940391
--- /dev/null
+++ b/src/third_party/s2/s2loop_test.cc
@@ -0,0 +1,767 @@
+// Copyright 2005 Google Inc. All Rights Reserved.
+
+#include <stdio.h>
+
+#include <algorithm>
+using std::min;
+using std::max;
+using std::swap;
+using std::reverse;
+
+#include <map>
+using std::map;
+using std::multimap;
+
+#include <set>
+using std::set;
+using std::multiset;
+
+#include <vector>
+using std::vector;
+
+
+#include "base/commandlineflags.h"
+#include "base/logging.h"
+#include "base/scoped_ptr.h"
+#include "testing/base/public/benchmark.h"
+#include "testing/base/public/gunit.h"
+#include "util/coding/coder.h"
+#include "s2cell.h"
+#include "s2edgeindex.h"
+#include "s2edgeutil.h"
+#include "s2loop.h"
+#include "s2testing.h"
+#include "util/math/matrix3x3.h"
+#include "util/math/matrix3x3-inl.h"
+
+DECLARE_bool(s2debug);
+
+class S2LoopTestBase : public testing::Test {
+ protected:
+ // Some standard loops to use in the tests (see descriptions below). The
+ // heap-checker ignores memory that is reachable from static variables, so
+ // it is not necessary to free these loops.
+ S2Loop const* const north_hemi;
+ S2Loop const* const north_hemi3;
+ S2Loop const* const south_hemi;
+ S2Loop const* const west_hemi;
+ S2Loop const* const east_hemi;
+ S2Loop const* const near_hemi;
+ S2Loop const* const far_hemi;
+ S2Loop const* const candy_cane;
+ S2Loop const* const small_ne_cw;
+ S2Loop const* const arctic_80;
+ S2Loop const* const antarctic_80;
+ S2Loop const* const line_triangle;
+ S2Loop const* const skinny_chevron;
+ S2Loop const* const loop_a;
+ S2Loop const* const loop_b;
+ S2Loop const* const a_intersect_b;
+ S2Loop const* const a_union_b;
+ S2Loop const* const a_minus_b;
+ S2Loop const* const b_minus_a;
+ S2Loop const* const loop_c;
+ S2Loop const* const loop_d;
+
+ public:
+ S2LoopTestBase():
+ // The northern hemisphere, defined using two pairs of antipodal points.
+ north_hemi(S2Testing::MakeLoop("0:-180, 0:-90, 0:0, 0:90")),
+
+ // The northern hemisphere, defined using three points 120 degrees apart.
+ north_hemi3(S2Testing::MakeLoop("0:-180, 0:-60, 0:60")),
+
+ // The southern hemisphere, defined using two pairs of antipodal points.
+ south_hemi(S2Testing::MakeLoop("0:90, 0:0, 0:-90, 0:-180")),
+
+ // The western hemisphere, defined using two pairs of antipodal points.
+ west_hemi(S2Testing::MakeLoop("0:-180, -90:0, 0:0, 90:0")),
+
+ // The eastern hemisphere, defined using two pairs of antipodal points.
+ east_hemi(S2Testing::MakeLoop("90:0, 0:0, -90:0, 0:-180")),
+
+ // The "near" hemisphere, defined using two pairs of antipodal points.
+ near_hemi(S2Testing::MakeLoop("0:-90, -90:0, 0:90, 90:0")),
+
+ // The "far" hemisphere, defined using two pairs of antipodal points.
+ far_hemi(S2Testing::MakeLoop("90:0, 0:90, -90:0, 0:-90")),
+
+ // A spiral stripe that slightly over-wraps the equator.
+ candy_cane(S2Testing::MakeLoop("-20:150, -20:-70, 0:70, 10:-150, "
+ "10:70, -10:-70")),
+
+ // A small clockwise loop in the northern & eastern hemisperes.
+ small_ne_cw(S2Testing::MakeLoop("35:20, 45:20, 40:25")),
+
+ // Loop around the north pole at 80 degrees.
+ arctic_80(S2Testing::MakeLoop("80:-150, 80:-30, 80:90")),
+
+ // Loop around the south pole at 80 degrees.
+ antarctic_80(S2Testing::MakeLoop("-80:120, -80:0, -80:-120")),
+
+ // A completely degenerate triangle along the equator that RobustCCW()
+ // considers to be CCW.
+ line_triangle(S2Testing::MakeLoop("0:1, 0:3, 0:2")),
+
+ // A nearly-degenerate CCW chevron near the equator with very long sides
+ // (about 80 degrees). Its area is less than 1e-640, which is too small
+ // to represent in double precision.
+ skinny_chevron(S2Testing::MakeLoop("0:0, -1e-320:80, 0:1e-320, 1e-320:80")),
+
+ // A diamond-shaped loop around the point 0:180.
+ loop_a(S2Testing::MakeLoop("0:178, -1:180, 0:-179, 1:-180")),
+
+ // Another diamond-shaped loop around the point 0:180.
+ loop_b(S2Testing::MakeLoop("0:179, -1:180, 0:-178, 1:-180")),
+
+ // The intersection of A and B.
+ a_intersect_b(S2Testing::MakeLoop("0:179, -1:180, 0:-179, 1:-180")),
+
+ // The union of A and B.
+ a_union_b(S2Testing::MakeLoop("0:178, -1:180, 0:-178, 1:-180")),
+
+ // A minus B (concave).
+ a_minus_b(S2Testing::MakeLoop("0:178, -1:180, 0:179, 1:-180")),
+
+ // B minus A (concave).
+ b_minus_a(S2Testing::MakeLoop("0:-179, -1:180, 0:-178, 1:-180")),
+
+ // A shape gotten from a by adding one triangle to one edge, and
+ // subtracting another triangle on an opposite edge.
+ loop_c(S2Testing::MakeLoop(
+ "0:178, 0:180, -1:180, 0:-179, 1:-179, 1:-180")),
+
+ // A shape gotten from a by adding one triangle to one edge, and
+ // adding another triangle on an opposite edge.
+ loop_d(S2Testing::MakeLoop(
+ "0:178, -1:178, -1:180, 0:-179, 1:-179, 1:-180"))
+
+ {}
+
+ ~S2LoopTestBase() {
+ delete north_hemi;
+ delete north_hemi3;
+ delete south_hemi;
+ delete west_hemi;
+ delete east_hemi;
+ delete near_hemi;
+ delete far_hemi;
+ delete candy_cane;
+ delete small_ne_cw;
+ delete arctic_80;
+ delete antarctic_80;
+ delete line_triangle;
+ delete skinny_chevron;
+ delete loop_a;
+ delete loop_b;
+ delete a_intersect_b;
+ delete a_union_b;
+ delete a_minus_b;
+ delete b_minus_a;
+ delete loop_c;
+ delete loop_d;
+ }
+};
+
+TEST_F(S2LoopTestBase, GetRectBound) {
+ EXPECT_TRUE(candy_cane->GetRectBound().lng().is_full());
+ EXPECT_LT(candy_cane->GetRectBound().lat_lo().degrees(), -20);
+ EXPECT_GT(candy_cane->GetRectBound().lat_hi().degrees(), 10);
+ EXPECT_TRUE(small_ne_cw->GetRectBound().is_full());
+ EXPECT_EQ(arctic_80->GetRectBound(),
+ S2LatLngRect(S2LatLng::FromDegrees(80, -180),
+ S2LatLng::FromDegrees(90, 180)));
+ EXPECT_EQ(antarctic_80->GetRectBound(),
+ S2LatLngRect(S2LatLng::FromDegrees(-90, -180),
+ S2LatLng::FromDegrees(-80, 180)));
+
+ // Create a loop that contains the complement of the "arctic_80" loop.
+ scoped_ptr<S2Loop> arctic_80_inv(arctic_80->Clone());
+ arctic_80_inv->Invert();
+ // The highest latitude of each edge is attained at its midpoint.
+ S2Point mid = 0.5 * (arctic_80_inv->vertex(0) + arctic_80_inv->vertex(1));
+ EXPECT_DOUBLE_EQ(arctic_80_inv->GetRectBound().lat_hi().radians(),
+ S2LatLng(mid).lat().radians());
+
+ EXPECT_TRUE(south_hemi->GetRectBound().lng().is_full());
+ EXPECT_EQ(south_hemi->GetRectBound().lat(), R1Interval(-M_PI_2, 0));
+}
+
+TEST_F(S2LoopTestBase, GetAreaAndCentroid) {
+ EXPECT_DOUBLE_EQ(north_hemi->GetArea(), 2 * M_PI);
+ EXPECT_LE(east_hemi->GetArea(), 2 * M_PI + 1e-12);
+ EXPECT_GE(east_hemi->GetArea(), 2 * M_PI - 1e-12);
+
+ // Construct spherical caps of random height, and approximate their boundary
+ // with closely spaces vertices. Then check that the area and centroid are
+ // correct.
+
+ for (int i = 0; i < 100; ++i) {
+ // Choose a coordinate frame for the spherical cap.
+ S2Point x, y, z;
+ S2Testing::GetRandomFrame(&x, &y, &z);
+
+ // Given two points at latitude phi and whose longitudes differ by dtheta,
+ // the geodesic between the two points has a maximum latitude of
+ // atan(tan(phi) / cos(dtheta/2)). This can be derived by positioning
+ // the two points at (-dtheta/2, phi) and (dtheta/2, phi).
+ //
+ // We want to position the vertices close enough together so that their
+ // maximum distance from the boundary of the spherical cap is kMaxDist.
+ // Thus we want fabs(atan(tan(phi) / cos(dtheta/2)) - phi) <= kMaxDist.
+ static double const kMaxDist = 1e-6;
+ double height = 2 * S2Testing::rnd.RandDouble();
+ double phi = asin(1 - height);
+ double max_dtheta = 2 * acos(tan(fabs(phi)) / tan(fabs(phi) + kMaxDist));
+ max_dtheta = min(M_PI, max_dtheta); // At least 3 vertices.
+
+ vector<S2Point> vertices;
+ for (double theta = 0; theta < 2 * M_PI;
+ theta += S2Testing::rnd.RandDouble() * max_dtheta) {
+ vertices.push_back(cos(theta) * cos(phi) * x +
+ sin(theta) * cos(phi) * y +
+ sin(phi) * z);
+ }
+ S2Loop loop(vertices);
+ double area = loop.GetArea();
+ S2Point centroid = loop.GetCentroid();
+ double expected_area = 2 * M_PI * height;
+ EXPECT_LE(fabs(area - expected_area), 2 * M_PI * kMaxDist);
+ EXPECT_GE(fabs(area - expected_area), 0.01 * kMaxDist); // high probability
+ S2Point expected_centroid = expected_area * (1 - 0.5 * height) * z;
+ EXPECT_LE((centroid - expected_centroid).Norm(), 2 * kMaxDist);
+ }
+}
+
+static void Rotate(scoped_ptr<S2Loop>* ptr) {
+ S2Loop* loop = ptr->get();
+ vector<S2Point> vertices;
+ for (int i = 1; i <= loop->num_vertices(); ++i) {
+ vertices.push_back(loop->vertex(i));
+ }
+ ptr->reset(new S2Loop(vertices));
+}
+
+// Check that the turning angle is *identical* when the vertex order is
+// rotated, and that the sign is inverted when the vertices are reversed.
+static void CheckTurningAngleInvariants(S2Loop const* loop) {
+ double expected = loop->GetTurningAngle();
+ scoped_ptr<S2Loop> loop_copy(loop->Clone());
+ for (int i = 0; i < loop->num_vertices(); ++i) {
+ loop_copy->Invert();
+ EXPECT_EQ(-expected, loop_copy->GetTurningAngle());
+ loop_copy->Invert();
+ Rotate(&loop_copy);
+ EXPECT_EQ(expected, loop_copy->GetTurningAngle());
+ }
+}
+
+TEST_F(S2LoopTestBase, GetTurningAngle) {
+ EXPECT_NEAR(0, north_hemi3->GetTurningAngle(), 1e-15);
+ CheckTurningAngleInvariants(north_hemi3);
+
+ EXPECT_NEAR(0, west_hemi->GetTurningAngle(), 1e-15);
+ CheckTurningAngleInvariants(west_hemi);
+
+ // We don't have an easy way to estimate the turning angle of this loop, but
+ // we can still check that the expected invariants hold.
+ CheckTurningAngleInvariants(candy_cane);
+
+ EXPECT_DOUBLE_EQ(-2 * M_PI, line_triangle->GetTurningAngle());
+ CheckTurningAngleInvariants(line_triangle);
+
+ EXPECT_DOUBLE_EQ(2 * M_PI, skinny_chevron->GetTurningAngle());
+ CheckTurningAngleInvariants(skinny_chevron);
+}
+
+// Checks that if a loop is normalized, it doesn't contain a
+// point outside of it, and vice versa.
+static void CheckNormalizeAndContain(S2Loop const* loop) {
+ S2Point p = S2Testing::MakePoint("40:40");
+
+ scoped_ptr<S2Loop> flip(loop->Clone());
+ flip->Invert();
+ EXPECT_TRUE(loop->IsNormalized() ^ loop->Contains(p));
+ EXPECT_TRUE(flip->IsNormalized() ^ flip->Contains(p));
+
+ EXPECT_TRUE(loop->IsNormalized() ^ flip->IsNormalized());
+
+ flip->Normalize();
+ EXPECT_FALSE(flip->Contains(p));
+}
+
+TEST_F(S2LoopTestBase, NormalizedCompatibleWithContains) {
+ CheckNormalizeAndContain(line_triangle);
+ CheckNormalizeAndContain(skinny_chevron);
+}
+
+extern void DeleteLoop(S2Loop* loop) {
+ delete loop;
+}
+
+TEST_F(S2LoopTestBase, Contains) {
+ EXPECT_TRUE(candy_cane->Contains(S2LatLng::FromDegrees(5, 71).ToPoint()));
+
+ // Create copies of these loops so that we can change the vertex order.
+ scoped_ptr<S2Loop> north_copy(north_hemi->Clone());
+ scoped_ptr<S2Loop> south_copy(south_hemi->Clone());
+ scoped_ptr<S2Loop> west_copy(west_hemi->Clone());
+ scoped_ptr<S2Loop> east_copy(east_hemi->Clone());
+ for (int i = 0; i < 4; ++i) {
+ EXPECT_TRUE(north_copy->Contains(S2Point(0, 0, 1)));
+ EXPECT_FALSE(north_copy->Contains(S2Point(0, 0, -1)));
+ EXPECT_FALSE(south_copy->Contains(S2Point(0, 0, 1)));
+ EXPECT_TRUE(south_copy->Contains(S2Point(0, 0, -1)));
+ EXPECT_FALSE(west_copy->Contains(S2Point(0, 1, 0)));
+ EXPECT_TRUE(west_copy->Contains(S2Point(0, -1, 0)));
+ EXPECT_TRUE(east_copy->Contains(S2Point(0, 1, 0)));
+ EXPECT_FALSE(east_copy->Contains(S2Point(0, -1, 0)));
+ Rotate(&north_copy);
+ Rotate(&south_copy);
+ Rotate(&east_copy);
+ Rotate(&west_copy);
+ }
+
+ // This code checks each cell vertex is contained by exactly one of
+ // the adjacent cells.
+ for (int level = 0; level < 3; ++level) {
+ vector<S2Loop*> loops;
+ vector<S2Point> loop_vertices;
+ set<S2Point> points;
+ for (S2CellId id = S2CellId::Begin(level);
+ id != S2CellId::End(level); id = id.next()) {
+ S2Cell cell(id);
+ points.insert(cell.GetCenter());
+ for (int k = 0; k < 4; ++k) {
+ loop_vertices.push_back(cell.GetVertex(k));
+ points.insert(cell.GetVertex(k));
+ }
+ loops.push_back(new S2Loop(loop_vertices));
+ loop_vertices.clear();
+ }
+ for (set<S2Point>::const_iterator i = points.begin();
+ i != points.end(); ++i) {
+ int count = 0;
+ for (int j = 0; j < loops.size(); ++j) {
+ if (loops[j]->Contains(*i)) ++count;
+ // Contains and VirtualContainsPoint should have identical
+ // implementation.
+ EXPECT_EQ(loops[j]->Contains(*i), loops[j]->VirtualContainsPoint(*i));
+ }
+ EXPECT_EQ(count, 1);
+ }
+
+ for_each(loops.begin(), loops.end(), DeleteLoop);
+ loops.clear();
+ }
+}
+
+static void TestRelationWithDesc(S2Loop const* a, S2Loop const* b,
+ int contains_or_crosses, bool intersects,
+ bool nestable,
+ const char* test_description) {
+ SCOPED_TRACE(test_description);
+ EXPECT_EQ(a->Contains(b), contains_or_crosses == 1);
+ EXPECT_EQ(a->Intersects(b), intersects);
+ if (nestable) EXPECT_EQ(a->ContainsNested(b), a->Contains(b));
+ if (contains_or_crosses >= -1) {
+ EXPECT_EQ(a->ContainsOrCrosses(b), contains_or_crosses);
+ }
+}
+
+TEST_F(S2LoopTestBase, LoopRelations) {
+#define TestRelation(a, b, contains, intersects, nestable) \
+ TestRelationWithDesc(a, b, contains, intersects, nestable, "args " #a ", " #b)
+
+ TestRelation(north_hemi, north_hemi, 1, true, false);
+ TestRelation(north_hemi, south_hemi, 0, false, false);
+ TestRelation(north_hemi, east_hemi, -1, true, false);
+ TestRelation(north_hemi, arctic_80, 1, true, true);
+ TestRelation(north_hemi, antarctic_80, 0, false, true);
+ TestRelation(north_hemi, candy_cane, -1, true, false);
+
+ // We can't compare north_hemi3 vs. north_hemi or south_hemi.
+ TestRelation(north_hemi3, north_hemi3, 1, true, false);
+ TestRelation(north_hemi3, east_hemi, -1, true, false);
+ TestRelation(north_hemi3, arctic_80, 1, true, true);
+ TestRelation(north_hemi3, antarctic_80, 0, false, true);
+ TestRelation(north_hemi3, candy_cane, -1, true, false);
+
+ TestRelation(south_hemi, north_hemi, 0, false, false);
+ TestRelation(south_hemi, south_hemi, 1, true, false);
+ TestRelation(south_hemi, far_hemi, -1, true, false);
+ TestRelation(south_hemi, arctic_80, 0, false, true);
+ TestRelation(south_hemi, antarctic_80, 1, true, true);
+ TestRelation(south_hemi, candy_cane, -1, true, false);
+
+ TestRelation(candy_cane, north_hemi, -1, true, false);
+ TestRelation(candy_cane, south_hemi, -1, true, false);
+ TestRelation(candy_cane, arctic_80, 0, false, true);
+ TestRelation(candy_cane, antarctic_80, 0, false, true);
+ TestRelation(candy_cane, candy_cane, 1, true, false);
+
+ TestRelation(near_hemi, west_hemi, -1, true, false);
+
+ TestRelation(small_ne_cw, south_hemi, 1, true, false);
+ TestRelation(small_ne_cw, west_hemi, 1, true, false);
+ TestRelation(small_ne_cw, north_hemi, -2, true, false);
+ TestRelation(small_ne_cw, east_hemi, -2, true, false);
+
+ TestRelation(loop_a, loop_a, 1, true, false);
+ TestRelation(loop_a, loop_b, -1, true, false);
+ TestRelation(loop_a, a_intersect_b, 1, true, false);
+ TestRelation(loop_a, a_union_b, 0, true, false);
+ TestRelation(loop_a, a_minus_b, 1, true, false);
+ TestRelation(loop_a, b_minus_a, 0, false, false);
+
+ TestRelation(loop_b, loop_a, -1, true, false);
+ TestRelation(loop_b, loop_b, 1, true, false);
+ TestRelation(loop_b, a_intersect_b, 1, true, false);
+ TestRelation(loop_b, a_union_b, 0, true, false);
+ TestRelation(loop_b, a_minus_b, 0, false, false);
+ TestRelation(loop_b, b_minus_a, 1, true, false);
+
+ TestRelation(a_intersect_b, loop_a, 0, true, false);
+ TestRelation(a_intersect_b, loop_b, 0, true, false);
+ TestRelation(a_intersect_b, a_intersect_b, 1, true, false);
+ TestRelation(a_intersect_b, a_union_b, 0, true, true);
+ TestRelation(a_intersect_b, a_minus_b, 0, false, false);
+ TestRelation(a_intersect_b, b_minus_a, 0, false, false);
+
+ TestRelation(a_union_b, loop_a, 1, true, false);
+ TestRelation(a_union_b, loop_b, 1, true, false);
+ TestRelation(a_union_b, a_intersect_b, 1, true, true);
+ TestRelation(a_union_b, a_union_b, 1, true, false);
+ TestRelation(a_union_b, a_minus_b, 1, true, false);
+ TestRelation(a_union_b, b_minus_a, 1, true, false);
+
+ TestRelation(a_minus_b, loop_a, 0, true, false);
+ TestRelation(a_minus_b, loop_b, 0, false, false);
+ TestRelation(a_minus_b, a_intersect_b, 0, false, false);
+ TestRelation(a_minus_b, a_union_b, 0, true, false);
+ TestRelation(a_minus_b, a_minus_b, 1, true, false);
+ TestRelation(a_minus_b, b_minus_a, 0, false, true);
+
+ TestRelation(b_minus_a, loop_a, 0, false, false);
+ TestRelation(b_minus_a, loop_b, 0, true, false);
+ TestRelation(b_minus_a, a_intersect_b, 0, false, false);
+ TestRelation(b_minus_a, a_union_b, 0, true, false);
+ TestRelation(b_minus_a, a_minus_b, 0, false, true);
+ TestRelation(b_minus_a, b_minus_a, 1, true, false);
+
+ // Added in 2010/08: Make sure the relations are correct if the loop
+ // crossing happens on two ends of a shared boundary segment.
+ TestRelation(loop_a, loop_c, -1, true, false);
+ TestRelation(loop_c, loop_a, -1, true, false);
+ TestRelation(loop_a, loop_d, 0, true, false);
+ TestRelation(loop_d, loop_a, 1, true, false);
+}
+
+static S2Loop* MakeCellLoop(S2CellId const& begin, S2CellId const& end) {
+ // Construct a CCW polygon whose boundary is the union of the cell ids
+ // in the range [begin, end). We add the edges one by one, removing
+ // any edges that are already present in the opposite direction.
+
+ map<S2Point, set<S2Point> > edges;
+ for (S2CellId id = begin; id != end; id = id.next()) {
+ S2Cell cell(id);
+ for (int k = 0; k < 4; ++k) {
+ S2Point a = cell.GetVertex(k);
+ S2Point b = cell.GetVertex((k + 1) & 3);
+ if (edges[b].erase(a) == 0) {
+ edges[a].insert(b);
+ } else if (edges[b].empty()) {
+ edges.erase(b);
+ }
+ }
+ }
+
+ // The remaining edges form a single loop. We simply follow it starting
+ // at an arbitrary vertex and build up a list of vertices.
+
+ vector<S2Point> vertices;
+ S2Point p = edges.begin()->first;
+ while (!edges.empty()) {
+ DCHECK_EQ(1, edges[p].size());
+ S2Point next = *edges[p].begin();
+ vertices.push_back(p);
+ edges.erase(p);
+ p = next;
+ }
+
+ return new S2Loop(vertices);
+}
+
+TEST(S2Loop, LoopRelations2) {
+ // Construct polygons consisting of a sequence of adjacent cell ids
+ // at some fixed level. Comparing two polygons at the same level
+ // ensures that there are no T-vertices.
+ for (int iter = 0; iter < 1000; ++iter) {
+ S2Testing::Random& rnd = S2Testing::rnd;
+ S2CellId begin = S2CellId(rnd.Rand64() | 1);
+ if (!begin.is_valid()) continue;
+ begin = begin.parent(rnd.Uniform(S2CellId::kMaxLevel));
+ S2CellId a_begin = begin.advance(rnd.Skewed(6));
+ S2CellId a_end = a_begin.advance(rnd.Skewed(6) + 1);
+ S2CellId b_begin = begin.advance(rnd.Skewed(6));
+ S2CellId b_end = b_begin.advance(rnd.Skewed(6) + 1);
+ if (!a_end.is_valid() || !b_end.is_valid()) continue;
+
+ scoped_ptr<S2Loop> a(MakeCellLoop(a_begin, a_end));
+ scoped_ptr<S2Loop> b(MakeCellLoop(b_begin, b_end));
+ if (a.get() && b.get()) {
+ bool contained = (a_begin <= b_begin && b_end <= a_end);
+ bool intersects = (a_begin < b_end && b_begin < a_end);
+ VLOG(1) << "Checking " << a->num_vertices() << " vs. "
+ << b->num_vertices() << ", contained = " << contained
+ << ", intersects = " << intersects;
+ EXPECT_EQ(a->Contains(b.get()), contained);
+ EXPECT_EQ(a->Intersects(b.get()), intersects);
+ } else {
+ VLOG(1) << "MakeCellLoop failed to create a loop.";
+ }
+ }
+}
+
+void DebugDumpCrossings(S2Loop const* loop) {
+ // This function is useful for debugging.
+
+ LOG(INFO) << "Ortho(v1): " << S2::Ortho(loop->vertex(1));
+ printf("Contains(kOrigin): %d\n", loop->Contains(S2::Origin()));
+ for (int i = 1; i <= loop->num_vertices(); ++i) {
+ S2Point a = S2::Ortho(loop->vertex(i));
+ S2Point b = loop->vertex(i-1);
+ S2Point c = loop->vertex(i+1);
+ S2Point o = loop->vertex(i);
+ printf("Vertex %d: [%.17g, %.17g, %.17g], "
+ "%d%dR=%d, %d%d%d=%d, R%d%d=%d, inside: %d\n",
+ i, loop->vertex(i).x(), loop->vertex(i).y(), loop->vertex(i).z(),
+ i-1, i, S2::RobustCCW(b, o, a),
+ i+1, i, i-1, S2::RobustCCW(c, o, b),
+ i, i+1, S2::RobustCCW(a, o, c),
+ S2::OrderedCCW(a, b, c, o));
+ }
+ for (int i = 0; i < loop->num_vertices() + 2; ++i) {
+ S2Point orig = S2::Origin();
+ S2Point dest;
+ if (i < loop->num_vertices()) {
+ dest = loop->vertex(i);
+ printf("Origin->%d crosses:", i);
+ } else {
+ dest = S2Point(0, 0, 1);
+ if (i == loop->num_vertices() + 1) orig = loop->vertex(1);
+ printf("Case %d:", i);
+ }
+ for (int j = 0; j < loop->num_vertices(); ++j) {
+ printf(" %d", S2EdgeUtil::EdgeOrVertexCrossing(
+ orig, dest, loop->vertex(j), loop->vertex(j+1)));
+ }
+ printf("\n");
+ }
+ for (int i = 0; i <= 2; i += 2) {
+ printf("Origin->v1 crossing v%d->v1: ", i);
+ S2Point a = S2::Ortho(loop->vertex(1));
+ S2Point b = loop->vertex(i);
+ S2Point c = S2::Origin();
+ S2Point o = loop->vertex(1);
+ printf("%d1R=%d, M1%d=%d, R1M=%d, crosses: %d\n",
+ i, S2::RobustCCW(b, o, a),
+ i, S2::RobustCCW(c, o, b),
+ S2::RobustCCW(a, o, c),
+ S2EdgeUtil::EdgeOrVertexCrossing(c, o, b, a));
+ }
+}
+
+static void TestNear(char const* a_str, char const* b_str,
+ double max_error, bool expected) {
+ scoped_ptr<S2Loop> a(S2Testing::MakeLoop(a_str));
+ scoped_ptr<S2Loop> b(S2Testing::MakeLoop(b_str));
+ EXPECT_EQ(a->BoundaryNear(b.get(), max_error), expected);
+ EXPECT_EQ(b->BoundaryNear(a.get(), max_error), expected);
+}
+
+TEST(S2Loop, BoundaryNear) {
+ double degree = S1Angle::Degrees(1).radians();
+
+ TestNear("0:0, 0:10, 5:5",
+ "0:0.1, -0.1:9.9, 5:5.2",
+ 0.5 * degree, true);
+ TestNear("0:0, 0:3, 0:7, 0:10, 3:7, 5:5",
+ "0:0, 0:10, 2:8, 5:5, 4:4, 3:3, 1:1",
+ 1e-3, true);
+
+ // All vertices close to some edge, but not equivalent.
+ TestNear("0:0, 0:2, 2:2, 2:0",
+ "0:0, 1.9999:1, 0:2, 2:2, 2:0",
+ 0.5 * degree, false);
+
+ // Two triangles that backtrack a bit on different edges. A simple
+ // greedy matching algorithm would fail on this example.
+ const char* t1 = "0.1:0, 0.1:1, 0.1:2, 0.1:3, 0.1:4, 1:4, 2:4, 3:4, "
+ "2:4.1, 1:4.1, 2:4.2, 3:4.2, 4:4.2, 5:4.2";
+ char const* t2 = "0:0, 0:1, 0:2, 0:3, 0.1:2, 0.1:1, 0.2:2, 0.2:3, "
+ "0.2:4, 1:4.1, 2:4, 3:4, 4:4, 5:4";
+ TestNear(t1, t2, 1.5 * degree, true);
+ TestNear(t1, t2, 0.5 * degree, false);
+}
+
+TEST(S2Loop, EncodeDecode) {
+ scoped_ptr<S2Loop> l(S2Testing::MakeLoop("30:20, 40:20, 39:43, 33:35"));
+ l->set_depth(3);
+
+ Encoder encoder;
+ l->Encode(&encoder);
+
+ Decoder decoder(encoder.base(), encoder.length());
+
+ S2Loop decoded_loop;
+ ASSERT_TRUE(decoded_loop.Decode(&decoder));
+ EXPECT_TRUE(l->BoundaryEquals(&decoded_loop));
+ EXPECT_EQ(l->depth(), decoded_loop.depth());
+ EXPECT_EQ(l->GetRectBound(), decoded_loop.GetRectBound());
+}
+
+TEST(S2Loop, EncodeDecodeWithinScope) {
+ scoped_ptr<S2Loop> l(S2Testing::MakeLoop("30:20, 40:20, 39:43, 33:35"));
+ l->set_depth(3);
+ Encoder encoder;
+ l->Encode(&encoder);
+ Decoder decoder1(encoder.base(), encoder.length());
+
+ // Initialize the loop using DecodeWithinScope and check that it is the
+ // same as the original loop.
+ S2Loop loop1;
+ ASSERT_TRUE(loop1.DecodeWithinScope(&decoder1));
+ EXPECT_TRUE(l->BoundaryEquals(&loop1));
+ EXPECT_EQ(l->depth(), loop1.depth());
+ EXPECT_EQ(l->GetRectBound(), loop1.GetRectBound());
+
+ // Initialize the same loop using Init with a vector of vertices, and
+ // check that it doesn't deallocate the original memory.
+ vector<S2Point> vertices;
+ vertices.push_back(loop1.vertex(0));
+ vertices.push_back(loop1.vertex(2));
+ vertices.push_back(loop1.vertex(3));
+ loop1.Init(vertices);
+ Decoder decoder2(encoder.base(), encoder.length());
+ S2Loop loop2;
+ ASSERT_TRUE(loop2.DecodeWithinScope(&decoder2));
+ EXPECT_TRUE(l->BoundaryEquals(&loop2));
+ EXPECT_EQ(l->vertex(1), loop2.vertex(1));
+ EXPECT_NE(loop1.vertex(1), loop2.vertex(1));
+
+ // Initialize loop2 using Decode with a decoder on different data.
+ // Check that the original memory is not deallocated or overwritten.
+ scoped_ptr<S2Loop> l2(S2Testing::MakeLoop("30:40, 40:75, 39:43, 80:35"));
+ l2->set_depth(2);
+ Encoder encoder2;
+ l2->Encode(&encoder2);
+ Decoder decoder3(encoder2.base(), encoder2.length());
+ ASSERT_TRUE(loop2.Decode(&decoder3));
+ Decoder decoder4(encoder.base(), encoder.length());
+ ASSERT_TRUE(loop1.DecodeWithinScope(&decoder4));
+ EXPECT_TRUE(l->BoundaryEquals(&loop1));
+ EXPECT_EQ(l->vertex(1), loop1.vertex(1));
+ EXPECT_NE(loop1.vertex(1), loop2.vertex(1));
+}
+
+// This test checks that S2Loops created directly from S2Cells behave
+// identically to S2Loops created from the vertices of those cells; this
+// previously was not the case, because S2Cells calculate their bounding
+// rectangles slightly differently, and S2Loops created from them just copied
+// the S2Cell bounds.
+TEST(S2Loop, S2CellConstructorAndContains) {
+ S2Cell cell(S2CellId::FromLatLng(S2LatLng::FromE6(40565459, -74645276)));
+ S2Loop cell_as_loop(cell);
+
+ vector<S2Point> vertices;
+ for (int i = 0; i < cell_as_loop.num_vertices(); ++i) {
+ vertices.push_back(cell_as_loop.vertex(i));
+ }
+ S2Loop loop_copy(vertices);
+ EXPECT_TRUE(loop_copy.Contains(&cell_as_loop));
+ EXPECT_TRUE(cell_as_loop.Contains(&loop_copy));
+ EXPECT_TRUE(loop_copy.Contains(cell));
+
+ // Demonstrates the reason for this test; the cell bounds are more
+ // conservative than the resulting loop bounds.
+ EXPECT_FALSE(loop_copy.GetRectBound().Contains(cell.GetRectBound()));
+}
+
+TEST(s2loop, IsValidDetectsInvalidLoops) {
+ // Only two vertices
+ S2Loop* l1 = S2Testing::MakeLoop("20:20, 21:21");
+ ASSERT_FALSE(l1->IsValid());
+ delete l1;
+
+ // Even if you disable s2debug, non-unit-length vertices break RobustCCW,
+ // so there is no point in testing it here.
+ // TODO(user): Check if the unit length test in IsValid is redundant
+ // and remove it if so.
+
+ // There is a duplicate vertex
+ S2Loop* l2 = S2Testing::MakeLoop("20:20, 21:21, 21:20, 20:20, 20:21");
+ ASSERT_FALSE(l2->IsValid());
+ delete l2;
+
+ // Some edges intersect
+ S2Loop* l3 = S2Testing::MakeLoop("20:20, 21:21, 21:20.5, 21:20, 20:21");
+ ASSERT_FALSE(l3->IsValid());
+ delete l3;
+}
+
+TEST(s2loop, IsValidDetectsLargeInvalidLoops) {
+}
+
+static void BM_ContainsOrCrosses(int iters, int num_vertices) {
+ StopBenchmarkTiming();
+ S2Loop* p1 = S2Testing::MakeRegularLoop(S2::Origin(), num_vertices, 0.005);
+ S2Loop* p2 = S2Testing::MakeRegularLoop(
+ (S2::Origin() + S2Point(0, 0, 0.003)).Normalize(),
+ num_vertices,
+ 0.005);
+ StartBenchmarkTiming();
+ for (int i = 0; i < iters; ++i) {
+ p1->ContainsOrCrosses(p2);
+ }
+ StopBenchmarkTiming();
+ delete p1;
+ delete p2;
+}
+BENCHMARK_RANGE(BM_ContainsOrCrosses, 8, 8192);
+
+static void BM_IsValid(int iters, int num_vertices) {
+ StopBenchmarkTiming();
+ S2Loop* l = S2Testing::MakeRegularLoop(S2::Origin(), num_vertices, 0.001);
+ StartBenchmarkTiming();
+ int r = 0;
+ for (int i = 0; i < iters; ++i) {
+ r += l->IsValid();
+ }
+ CHECK(r != INT_MAX);
+ delete l;
+}
+BENCHMARK(BM_IsValid)
+ ->Arg(32)
+ ->Arg(64)
+ ->Arg(128)
+ ->Arg(256)
+ ->Arg(512)
+ ->Arg(4096)
+ ->Arg(32768);
+
+static void BM_ContainsQuery(int iters, int num_vertices) {
+ StopBenchmarkTiming();
+ S2Point loop_center = S2Testing::MakePoint("42:10");
+ S2Loop* loop = S2Testing::MakeRegularLoop(loop_center,
+ num_vertices,
+ 7e-3); // = 5km/6400km
+ StartBenchmarkTiming();
+ int count = 0;
+ for (int i = 0; i < iters; ++i) {
+ count += 1 + loop->Contains(loop_center);
+ }
+ CHECK_LE(0, count);
+ delete loop;
+}
+BENCHMARK_RANGE(BM_ContainsQuery, 4, 1 << 16);
diff --git a/src/third_party/s2/s2pointregion.cc b/src/third_party/s2/s2pointregion.cc
new file mode 100644
index 00000000000..0ad23665a3a
--- /dev/null
+++ b/src/third_party/s2/s2pointregion.cc
@@ -0,0 +1,52 @@
+// Copyright 2005 Google Inc. All Rights Reserved.
+
+#include "s2pointregion.h"
+#include "base/logging.h"
+#include "util/coding/coder.h"
+#include "s2cap.h"
+#include "s2cell.h"
+#include "s2latlngrect.h"
+
+static const unsigned char kCurrentEncodingVersionNumber = 1;
+
+S2PointRegion::~S2PointRegion() {
+}
+
+S2PointRegion* S2PointRegion::Clone() const {
+ return new S2PointRegion(point_);
+}
+
+S2Cap S2PointRegion::GetCapBound() const {
+ return S2Cap::FromAxisHeight(point_, 0);
+}
+
+S2LatLngRect S2PointRegion::GetRectBound() const {
+ S2LatLng ll(point_);
+ return S2LatLngRect(ll, ll);
+}
+
+bool S2PointRegion::MayIntersect(S2Cell const& cell) const {
+ return cell.Contains(point_);
+}
+
+void S2PointRegion::Encode(Encoder* encoder) const {
+ encoder->Ensure(30); // sufficient
+
+ encoder->put8(kCurrentEncodingVersionNumber);
+ for (int i = 0; i < 3; ++i) {
+ encoder->putdouble(point_[i]);
+ }
+ DCHECK_GE(encoder->avail(), 0);
+}
+
+bool S2PointRegion::Decode(Decoder* decoder) {
+ unsigned char version = decoder->get8();
+ if (version > kCurrentEncodingVersionNumber) return false;
+
+ for (int i = 0; i < 3; ++i) {
+ point_[i] = decoder->getdouble();
+ }
+ DCHECK(S2::IsUnitLength(point_));
+
+ return decoder->avail() >= 0;
+}
diff --git a/src/third_party/s2/s2pointregion.h b/src/third_party/s2/s2pointregion.h
new file mode 100644
index 00000000000..54c25670309
--- /dev/null
+++ b/src/third_party/s2/s2pointregion.h
@@ -0,0 +1,47 @@
+// Copyright 2005 Google Inc. All Rights Reserved.
+
+#ifndef UTIL_GEOMETRY_S2POINTREGION_H__
+#define UTIL_GEOMETRY_S2POINTREGION_H__
+
+#include "base/logging.h"
+#include "base/macros.h"
+#include "s2.h"
+#include "s2region.h"
+
+// An S2PointRegion is a region that contains a single point. It is more
+// expensive than the raw S2Point type and is useful mainly for completeness.
+class S2PointRegion : public S2Region {
+ public:
+ // Create a region containing the given point, which must be unit length.
+ inline explicit S2PointRegion(S2Point const& point);
+
+ ~S2PointRegion();
+
+ S2Point const& point() const { return point_; }
+
+ ////////////////////////////////////////////////////////////////////////
+ // S2Region interface (see s2region.h for details):
+
+ virtual S2PointRegion* Clone() const;
+ virtual S2Cap GetCapBound() const;
+ virtual S2LatLngRect GetRectBound() const;
+ virtual bool Contains(S2Cell const& cell) const { return false; }
+ virtual bool MayIntersect(S2Cell const& cell) const;
+ virtual bool VirtualContainsPoint(S2Point const& p) const {
+ return Contains(p);
+ }
+ bool Contains(S2Point const& p) const { return (point_ == p); }
+ virtual void Encode(Encoder* const encoder) const;
+ virtual bool Decode(Decoder* const decoder);
+
+ private:
+ S2Point point_;
+
+ DISALLOW_EVIL_CONSTRUCTORS(S2PointRegion);
+};
+
+S2PointRegion::S2PointRegion(S2Point const& point) : point_(point) {
+ DCHECK(S2::IsUnitLength(point));
+}
+
+#endif // UTIL_GEOMETRY_S2POINTREGION_H__
diff --git a/src/third_party/s2/s2pointregion_test.cc b/src/third_party/s2/s2pointregion_test.cc
new file mode 100644
index 00000000000..a402f232aa4
--- /dev/null
+++ b/src/third_party/s2/s2pointregion_test.cc
@@ -0,0 +1,50 @@
+// Copyright 2005 Google Inc. All Rights Reserved.
+
+#include "s2pointregion.h"
+
+#include "testing/base/public/gunit.h"
+#include "util/coding/coder.h"
+#include "s2cap.h"
+#include "s2cell.h"
+#include "s2latlngrect.h"
+
+namespace {
+
+TEST(S2PointRegionTest, Basic) {
+ S2Point p(1, 0, 0);
+ S2PointRegion r0(p);
+ EXPECT_EQ(r0.point(), p);
+ EXPECT_TRUE(r0.Contains(p));
+ EXPECT_TRUE(r0.VirtualContainsPoint(p));
+ EXPECT_TRUE(r0.VirtualContainsPoint(r0.point()));
+ EXPECT_FALSE(r0.VirtualContainsPoint(S2Point(1, 0, 1)));
+ scoped_ptr<S2PointRegion> r0_clone(r0.Clone());
+ EXPECT_EQ(r0_clone->point(), r0.point());
+ EXPECT_EQ(r0.GetCapBound(), S2Cap::FromAxisHeight(p, 0));
+ S2LatLng ll(p);
+ EXPECT_EQ(r0.GetRectBound(), S2LatLngRect(ll, ll));
+
+ // The leaf cell containing a point is still much larger than the point.
+ S2Cell cell(p);
+ EXPECT_FALSE(r0.Contains(cell));
+ EXPECT_TRUE(r0.MayIntersect(cell));
+}
+
+TEST(S2PointRegionTest, EncodeAndDecode) {
+ S2Point p(.6, .8, 0);
+ S2PointRegion r(p);
+
+ Encoder encoder;
+ r.Encode(&encoder);
+
+ Decoder decoder(encoder.base(), encoder.length());
+ S2PointRegion decoded_r(S2Point(1, 0, 0));
+ decoded_r.Decode(&decoder);
+ S2Point decoded_p = decoded_r.point();
+
+ EXPECT_EQ(0.6, decoded_p[0]);
+ EXPECT_EQ(0.8, decoded_p[1]);
+ EXPECT_EQ(0.0, decoded_p[2]);
+}
+
+} // namespace
diff --git a/src/third_party/s2/s2polygon.cc b/src/third_party/s2/s2polygon.cc
new file mode 100644
index 00000000000..4f887bd9bd7
--- /dev/null
+++ b/src/third_party/s2/s2polygon.cc
@@ -0,0 +1,1228 @@
+// Copyright 2005 Google Inc. All Rights Reserved.
+
+#include <algorithm>
+using std::min;
+using std::max;
+using std::swap;
+using std::reverse;
+
+#include "base/definer.h"
+#include "s2.h"
+#if defined OS_MACOSX
+#include <ext/hash_map>
+#else
+#include <hash_map>
+#endif
+#ifndef _WIN32
+using __gnu_cxx::hash_map;
+#endif
+
+#include <set>
+using std::set;
+using std::multiset;
+
+#include <vector>
+using std::vector;
+
+
+#include "base/commandlineflags.h"
+#include "s2polygon.h"
+
+#include "base/port.h" // for HASH_NAMESPACE_DECLARATION_START
+#include "util/coding/coder.h"
+#include "s2edgeindex.h"
+#include "s2cap.h"
+#include "s2cell.h"
+#include "s2cellunion.h"
+#include "s2latlngrect.h"
+#include "s2polygonbuilder.h"
+#include "s2polyline.h"
+
+DECLARE_bool(s2debug); // defined in s2.cc
+
+static const unsigned char kCurrentEncodingVersionNumber = 1;
+
+typedef pair<S2Point, S2Point> S2Edge;
+
+S2Polygon::S2Polygon()
+ : loops_(),
+ bound_(S2LatLngRect::Empty()),
+ owns_loops_(true),
+ has_holes_(false),
+ num_vertices_(0) {
+}
+
+S2Polygon::S2Polygon(vector<S2Loop*>* loops)
+ : bound_(S2LatLngRect::Empty()),
+ owns_loops_(true) {
+ Init(loops);
+}
+
+S2Polygon::S2Polygon(S2Cell const& cell)
+ : bound_(S2LatLngRect::Empty()),
+ owns_loops_(true),
+ has_holes_(false),
+ num_vertices_(4) {
+ S2Loop* loop = new S2Loop(cell);
+ bound_ = loop->GetRectBound();
+ loops_.push_back(loop);
+}
+
+S2Polygon::S2Polygon(S2Loop* loop)
+ : bound_(loop->GetRectBound()),
+ owns_loops_(false),
+ has_holes_(false),
+ num_vertices_(loop->num_vertices()) {
+ loops_.push_back(loop);
+}
+
+void S2Polygon::Copy(S2Polygon const* src) {
+ DCHECK_EQ(0, num_loops());
+ for (int i = 0; i < src->num_loops(); ++i) {
+ loops_.push_back(src->loop(i)->Clone());
+ }
+ bound_ = src->bound_;
+ owns_loops_ = true;
+ has_holes_ = src->has_holes_;
+ num_vertices_ = src->num_vertices();
+}
+
+S2Polygon* S2Polygon::Clone() const {
+ S2Polygon* result = new S2Polygon;
+ result->Copy(this);
+ return result;
+}
+
+void S2Polygon::Release(vector<S2Loop*>* loops) {
+ if (loops != NULL) {
+ loops->insert(loops->end(), loops_.begin(), loops_.end());
+ }
+ loops_.clear();
+ bound_ = S2LatLngRect::Empty();
+ has_holes_ = false;
+}
+
+static void DeleteLoopsInVector(vector<S2Loop*>* loops) {
+ for (size_t i = 0; i < loops->size(); ++i) {
+ delete loops->at(i);
+ }
+ loops->clear();
+}
+
+S2Polygon::~S2Polygon() {
+ if (owns_loops_) DeleteLoopsInVector(&loops_);
+}
+
+typedef pair<S2Point, S2Point> S2PointPair;
+
+#if defined OS_MACOSX
+#include <ext/hash_set>
+#else
+#include <hash_set>
+#endif
+namespace HASH_NAMESPACE {
+
+template<> class hash<S2PointPair> {
+public:
+ size_t operator()(S2PointPair const& p) const {
+ hash<S2Point> h;
+ return h(p.first) + (h(p.second) << 1);
+ }
+};
+
+} // namespace __gnu_cxx
+
+#ifdef _WIN32
+template<> size_t stdext::hash_value<S2PointPair>(const S2PointPair &p) {
+ hash<S2Point> h;
+ return h(p.first) + (h(p.second)<<1);
+}
+// XXX: implement this
+#endif
+
+
+bool S2Polygon::IsValid(const vector<S2Loop*>& loops) {
+ // If a loop contains an edge AB, then no other loop may contain AB or BA.
+ if (loops.size() > 1) {
+ hash_map<S2PointPair, pair<int, int> > edges;
+ for (size_t i = 0; i < loops.size(); ++i) {
+ S2Loop* lp = loops[i];
+ for (int j = 0; j < lp->num_vertices(); ++j) {
+ S2PointPair key = make_pair(lp->vertex(j), lp->vertex(j + 1));
+ if (edges.insert(make_pair(key, make_pair(i, j))).second) {
+ key = make_pair(lp->vertex(j + 1), lp->vertex(j));
+ if (edges.insert(make_pair(key, make_pair(i, j))).second)
+ continue;
+ }
+ pair<int, int> other = edges[key];
+ VLOG(2) << "Duplicate edge: loop " << i << ", edge " << j
+ << " and loop " << other.first << ", edge " << other.second;
+ return false;
+ }
+ }
+ }
+
+ // Verify that no loop covers more than half of the sphere, and that no
+ // two loops cross.
+ for (size_t i = 0; i < loops.size(); ++i) {
+ if (!loops[i]->IsNormalized()) {
+ VLOG(2) << "Loop " << i << " encloses more than half the sphere";
+ return false;
+ }
+ for (size_t j = i + 1; j < loops.size(); ++j) {
+ // This test not only checks for edge crossings, it also detects
+ // cases where the two boundaries cross at a shared vertex.
+ if (loops[i]->ContainsOrCrosses(loops[j]) < 0) {
+ VLOG(2) << "Loop " << i << " crosses loop " << j;
+ return false;
+ }
+ }
+ }
+
+ return true;
+}
+
+bool S2Polygon::IsValid() const {
+ for (int i = 0; i < num_loops(); ++i) {
+ if (!loop(i)->IsValid()) {
+ return false;
+ }
+ }
+ return IsValid(loops_);
+}
+
+bool S2Polygon::IsValid(bool check_loops, int max_adjacent) const {
+ return IsValid();
+}
+
+void S2Polygon::InsertLoop(S2Loop* new_loop, S2Loop* parent,
+ LoopMap* loop_map) {
+ vector<S2Loop*>* children = &(*loop_map)[parent];
+ for (size_t i = 0; i < children->size(); ++i) {
+ S2Loop* child = (*children)[i];
+ if (child->ContainsNested(new_loop)) {
+ InsertLoop(new_loop, child, loop_map);
+ return;
+ }
+ }
+ // No loop may contain the complement of another loop. (Handling this case
+ // is significantly more complicated.)
+ DCHECK(parent == NULL || !new_loop->ContainsNested(parent));
+
+ // Some of the children of the parent loop may now be children of
+ // the new loop.
+ vector<S2Loop*>* new_children = &(*loop_map)[new_loop];
+ for (size_t i = 0; i < children->size();) {
+ S2Loop* child = (*children)[i];
+ if (new_loop->ContainsNested(child)) {
+ new_children->push_back(child);
+ children->erase(children->begin() + i);
+ } else {
+ ++i;
+ }
+ }
+ children->push_back(new_loop);
+}
+
+void S2Polygon::InitLoop(S2Loop* loop, int depth, LoopMap* loop_map) {
+ if (loop) {
+ loop->set_depth(depth);
+ loops_.push_back(loop);
+ }
+ vector<S2Loop*> const& children = (*loop_map)[loop];
+ for (size_t i = 0; i < children.size(); ++i) {
+ InitLoop(children[i], depth + 1, loop_map);
+ }
+}
+
+bool S2Polygon::ContainsChild(S2Loop* a, S2Loop* b, LoopMap const& loop_map) {
+ // This function is just used to verify that the loop map was
+ // constructed correctly.
+
+ if (a == b) return true;
+ vector<S2Loop*> const& children = loop_map.find(a)->second;
+ for (size_t i = 0; i < children.size(); ++i) {
+ if (ContainsChild(children[i], b, loop_map)) return true;
+ }
+ return false;
+}
+
+void S2Polygon::Init(vector<S2Loop*>* loops) {
+ if (FLAGS_s2debug) {
+ CHECK(IsValid(*loops));
+ }
+ DCHECK(loops_.empty());
+ loops_.swap(*loops);
+
+ num_vertices_ = 0;
+ for (int i = 0; i < num_loops(); ++i) {
+ num_vertices_ += loop(i)->num_vertices();
+ }
+
+ LoopMap loop_map;
+ for (int i = 0; i < num_loops(); ++i) {
+ InsertLoop(loop(i), NULL, &loop_map);
+ }
+ // Reorder the loops in depth-first traversal order.
+ loops_.clear();
+ InitLoop(NULL, -1, &loop_map);
+
+ if (FLAGS_s2debug) {
+ // Check that the LoopMap is correct (this is fairly cheap).
+ for (int i = 0; i < num_loops(); ++i) {
+ for (int j = 0; j < num_loops(); ++j) {
+ if (i == j) continue;
+ CHECK_EQ(ContainsChild(loop(i), loop(j), loop_map),
+ loop(i)->ContainsNested(loop(j)));
+ }
+ }
+ }
+
+ // Compute the bounding rectangle of the entire polygon.
+ has_holes_ = false;
+ bound_ = S2LatLngRect::Empty();
+ for (int i = 0; i < num_loops(); ++i) {
+ if (loop(i)->sign() < 0) {
+ has_holes_ = true;
+ } else {
+ bound_ = bound_.Union(loop(i)->GetRectBound());
+ }
+ }
+}
+
+int S2Polygon::GetParent(int k) const {
+ int depth = loop(k)->depth();
+ if (depth == 0) return -1; // Optimization.
+ while (--k >= 0 && loop(k)->depth() >= depth) continue;
+ return k;
+}
+
+int S2Polygon::GetLastDescendant(int k) const {
+ if (k < 0) return num_loops() - 1;
+ int depth = loop(k)->depth();
+ while (++k < num_loops() && loop(k)->depth() > depth) continue;
+ return k - 1;
+}
+
+double S2Polygon::GetArea() const {
+ double area = 0;
+ for (int i = 0; i < num_loops(); ++i) {
+ area += loop(i)->sign() * loop(i)->GetArea();
+ }
+ return area;
+}
+
+S2Point S2Polygon::GetCentroid() const {
+ S2Point centroid;
+ for (int i = 0; i < num_loops(); ++i) {
+ centroid += loop(i)->sign() * loop(i)->GetCentroid();
+ }
+ return centroid;
+}
+
+int S2Polygon::ContainsOrCrosses(S2Loop const* b) const {
+ bool inside = false;
+ for (int i = 0; i < num_loops(); ++i) {
+ int result = loop(i)->ContainsOrCrosses(b);
+ if (result < 0) return -1; // The loop boundaries intersect.
+ if (result > 0) inside ^= true;
+ }
+ return static_cast<int>(inside); // True if loop B is contained by the
+ // polygon.
+}
+
+bool S2Polygon::AnyLoopContains(S2Loop const* b) const {
+ // Return true if any loop contains the given loop.
+ for (int i = 0; i < num_loops(); ++i) {
+ if (loop(i)->Contains(b)) return true;
+ }
+ return false;
+}
+
+bool S2Polygon::ContainsAllShells(S2Polygon const* b) const {
+ // Return true if this polygon (A) contains all the shells of B.
+ for (int j = 0; j < b->num_loops(); ++j) {
+ if (b->loop(j)->sign() < 0) continue;
+ if (ContainsOrCrosses(b->loop(j)) <= 0) {
+ // Shell of B is not contained by A, or the boundaries intersect.
+ return false;
+ }
+ }
+ return true;
+}
+
+bool S2Polygon::ExcludesAllHoles(S2Polygon const* b) const {
+ // Return true if this polygon (A) excludes (i.e. does not intersect)
+ // all holes of B.
+ for (int j = 0; j < b->num_loops(); ++j) {
+ if (b->loop(j)->sign() > 0) continue;
+ if (ContainsOrCrosses(b->loop(j)) != 0) {
+ // Hole of B is contained by A, or the boundaries intersect.
+ return false;
+ }
+ }
+ return true;
+}
+
+bool S2Polygon::IntersectsAnyShell(S2Polygon const* b) const {
+ // Return true if this polygon (A) intersects any shell of B.
+ for (int j = 0; j < b->num_loops(); ++j) {
+ if (b->loop(j)->sign() < 0) continue;
+ if (IntersectsShell(b->loop(j)) != 0)
+ return true;
+ }
+ return false;
+}
+
+bool S2Polygon::IntersectsShell(S2Loop const* b) const {
+ bool inside = false;
+ for (int i = 0; i < num_loops(); ++i) {
+ if (loop(i)->Contains(b)) {
+ inside ^= true;
+ } else if (!b->Contains(loop(i)) && loop(i)->Intersects(b)) {
+ // We definitely have an intersection if the loops intersect AND one
+ // is not properly contained in the other. If A (this) is properly
+ // contained in a loop of B, we don't know yet if it may be actually
+ // inside a hole within B.
+ return true;
+ }
+ }
+ return inside;
+}
+
+bool S2Polygon::Contains(S2Polygon const* b) const {
+ // If both polygons have one loop, use the more efficient S2Loop method.
+ // Note that S2Loop::Contains does its own bounding rectangle check.
+ if (num_loops() == 1 && b->num_loops() == 1) {
+ return loop(0)->Contains(b->loop(0));
+ }
+
+ // Otherwise if neither polygon has holes, we can still use the more
+ // efficient S2Loop::Contains method (rather than ContainsOrCrosses),
+ // but it's worthwhile to do our own bounds check first.
+ if (!bound_.Contains(b->bound_)) {
+ // If the union of the bounding boxes spans the full longitude range,
+ // it is still possible that polygon A contains B. (This is only
+ // possible if at least one polygon has multiple shells.)
+ if (!bound_.lng().Union(b->bound_.lng()).is_full()) return false;
+ }
+ if (!has_holes_ && !b->has_holes_) {
+ for (int j = 0; j < b->num_loops(); ++j) {
+ if (!AnyLoopContains(b->loop(j))) return false;
+ }
+ return true;
+ }
+
+ // This could be implemented more efficiently for polygons with lots of
+ // holes by keeping a copy of the LoopMap computed during initialization.
+ // However, in practice most polygons are one loop, and multiloop polygons
+ // tend to consist of many shells rather than holes. In any case, the real
+ // way to get more efficiency is to implement a sub-quadratic algorithm
+ // such as building a trapezoidal map.
+
+ // Every shell of B must be contained by an odd number of loops of A,
+ // and every hole of A must be contained by an even number of loops of B.
+ return ContainsAllShells(b) && b->ExcludesAllHoles(this);
+}
+
+bool S2Polygon::Intersects(S2Polygon const* b) const {
+ // A.Intersects(B) if and only if !Complement(A).Contains(B). However,
+ // implementing a Complement() operation is trickier than it sounds,
+ // and in any case it's more efficient to test for intersection directly.
+
+ // If both polygons have one loop, use the more efficient S2Loop method.
+ // Note that S2Loop::Intersects does its own bounding rectangle check.
+ if (num_loops() == 1 && b->num_loops() == 1) {
+ return loop(0)->Intersects(b->loop(0));
+ }
+
+ // Otherwise if neither polygon has holes, we can still use the more
+ // efficient S2Loop::Intersects method. The polygons intersect if and
+ // only if some pair of loop regions intersect.
+ if (!bound_.Intersects(b->bound_)) return false;
+ if (!has_holes_ && !b->has_holes_) {
+ for (int i = 0; i < num_loops(); ++i) {
+ for (int j = 0; j < b->num_loops(); ++j) {
+ if (loop(i)->Intersects(b->loop(j))) return true;
+ }
+ }
+ return false;
+ }
+
+ // Otherwise if any shell of B is contained by an odd number of loops of A,
+ // or any shell of A is contained by an odd number of loops of B, or there is
+ // an intersection without containment, then there is an intersection.
+ return IntersectsAnyShell(b) || b->IntersectsAnyShell(this);
+}
+
+S2Cap S2Polygon::GetCapBound() const {
+ return bound_.GetCapBound();
+}
+
+bool S2Polygon::Contains(S2Cell const& cell) const {
+ if (num_loops() == 1) {
+ return loop(0)->Contains(cell);
+ }
+
+ // We can't check bound_.Contains(cell.GetRectBound()) because S2Cell's
+ // GetRectBound() calculation is not precise.
+ if (!bound_.Contains(cell.GetCenter())) return false;
+
+ S2Loop cell_loop(cell);
+ S2Polygon cell_poly(&cell_loop);
+ bool contains = Contains(&cell_poly);
+ if (contains) {
+ DCHECK(Contains(cell.GetCenter()));
+ }
+ return contains;
+}
+
+bool S2Polygon::ApproxContains(S2Polygon const* b,
+ S1Angle vertex_merge_radius) const {
+ S2Polygon difference;
+ difference.InitToDifferenceSloppy(b, this, vertex_merge_radius);
+ return difference.num_loops() == 0;
+}
+
+bool S2Polygon::MayIntersect(S2Cell const& cell) const {
+ if (num_loops() == 1) {
+ return loop(0)->MayIntersect(cell);
+ }
+ if (!bound_.Intersects(cell.GetRectBound())) return false;
+
+ S2Loop cell_loop(cell);
+ S2Polygon cell_poly(&cell_loop);
+ bool intersects = Intersects(&cell_poly);
+ if (!intersects) {
+ DCHECK(!Contains(cell.GetCenter()));
+ }
+ return intersects;
+}
+
+bool S2Polygon::VirtualContainsPoint(S2Point const& p) const {
+ return Contains(p); // The same as Contains() below, just virtual.
+}
+
+bool S2Polygon::Contains(S2Point const& p) const {
+ if (num_loops() == 1) {
+ return loop(0)->Contains(p); // Optimization.
+ }
+ if (!bound_.Contains(p)) return false;
+ bool inside = false;
+ for (int i = 0; i < num_loops(); ++i) {
+ inside ^= loop(i)->Contains(p);
+ if (inside && !has_holes_) break; // Shells are disjoint.
+ }
+ return inside;
+}
+
+void S2Polygon::Encode(Encoder* const encoder) const {
+ encoder->Ensure(10); // Sufficient
+ encoder->put8(kCurrentEncodingVersionNumber);
+ encoder->put8(owns_loops_);
+ encoder->put8(has_holes_);
+ encoder->put32(loops_.size());
+ DCHECK_GE(encoder->avail(), 0);
+
+ for (int i = 0; i < num_loops(); ++i) {
+ loop(i)->Encode(encoder);
+ }
+ bound_.Encode(encoder);
+}
+
+bool S2Polygon::Decode(Decoder* const decoder) {
+ return DecodeInternal(decoder, false);
+}
+
+bool S2Polygon::DecodeWithinScope(Decoder* const decoder) {
+ return DecodeInternal(decoder, true);
+}
+
+bool S2Polygon::DecodeInternal(Decoder* const decoder, bool within_scope) {
+ unsigned char version = decoder->get8();
+ if (version > kCurrentEncodingVersionNumber) return false;
+
+ if (owns_loops_) DeleteLoopsInVector(&loops_);
+
+ owns_loops_ = decoder->get8();
+ has_holes_ = decoder->get8();
+ int num_loops = decoder->get32();
+ loops_.clear();
+ loops_.reserve(num_loops);
+ num_vertices_ = 0;
+ for (int i = 0; i < num_loops; ++i) {
+ loops_.push_back(new S2Loop);
+ if (within_scope) {
+ if (!loops_.back()->DecodeWithinScope(decoder)) return false;
+ } else {
+ if (!loops_.back()->Decode(decoder)) return false;
+ }
+ num_vertices_ += loops_.back()->num_vertices();
+ }
+ if (!bound_.Decode(decoder)) return false;
+
+ DCHECK(IsValid(loops_));
+
+ return decoder->avail() >= 0;
+}
+
+// Indexing structure to efficiently ClipEdge() of a polygon. This is
+// an abstract class because we need to use if for both polygons (for
+// InitToIntersection() and friends) and for sets of vectors of points
+// (for InitToSimplified()).
+//
+// Usage -- in your subclass:
+// - Call AddLoop() for each of your loops -- and keep them accessible in
+// your subclass.
+// - Overwrite EdgeFromTo(), calling DecodeIndex() and accessing your
+// underlying data with the resulting two indices.
+class S2LoopSequenceIndex: public S2EdgeIndex {
+ public:
+ S2LoopSequenceIndex(): num_edges_(0), num_loops_(0) {}
+ ~S2LoopSequenceIndex() {}
+
+ void AddLoop(int num_vertices) {
+ int vertices_so_far = num_edges_;
+ loop_to_first_index_.push_back(vertices_so_far);
+ index_to_loop_.resize(vertices_so_far + num_vertices);
+ for (int i = 0; i < num_vertices; ++i) {
+ index_to_loop_[vertices_so_far] = num_loops_;
+ vertices_so_far++;
+ }
+ num_edges_ += num_vertices;
+ num_loops_++;
+ }
+
+ inline void DecodeIndex(int index,
+ int* loop_index, int* vertex_in_loop) const {
+ *loop_index = index_to_loop_[index];
+ *vertex_in_loop = index - loop_to_first_index_[*loop_index];
+ }
+
+ // It is faster to return both vertices at once. It makes a difference
+ // for small polygons.
+ virtual void EdgeFromTo(int index,
+ S2Point const* * from, S2Point const* * to) const = 0;
+
+ int num_edges() const { return num_edges_; }
+
+ virtual S2Point const* edge_from(int index) const {
+ S2Point const* from;
+ S2Point const* to;
+ EdgeFromTo(index, &from, &to);
+ return from;
+ }
+
+ virtual S2Point const* edge_to(int index) const {
+ S2Point const* from;
+ S2Point const* to;
+ EdgeFromTo(index, &from, &to);
+ return to;
+ }
+
+ protected:
+ // Map from the unidimensional edge index to the loop this edge
+ // belongs to.
+ vector<int> index_to_loop_;
+
+ // Reverse of index_to_loop_: maps a loop index to the
+ // unidimensional index of the first edge in the loop.
+ vector<int> loop_to_first_index_;
+
+ // Total number of edges.
+ int num_edges_;
+
+ // Total number of loops.
+ int num_loops_;
+};
+
+// Indexing structure for an S2Polygon.
+class S2PolygonIndex: public S2LoopSequenceIndex {
+ public:
+ S2PolygonIndex(S2Polygon const* poly, bool reverse):
+ poly_(poly),
+ reverse_(reverse) {
+ for (int iloop = 0; iloop < poly_->num_loops(); ++iloop) {
+ AddLoop(poly_->loop(iloop)->num_vertices());
+ }
+ }
+
+ virtual ~S2PolygonIndex() {}
+
+ virtual void EdgeFromTo(int index,
+ S2Point const* * from, S2Point const* * to) const {
+ int loop_index;
+ int vertex_in_loop;
+ DecodeIndex(index, &loop_index, &vertex_in_loop);
+ S2Loop const* loop(poly_->loop(loop_index));
+ int from_index, to_index;
+ if (loop->is_hole() ^ reverse_) {
+ from_index = loop->num_vertices() - 1 - vertex_in_loop;
+ to_index = 2 * loop->num_vertices() - 2 - vertex_in_loop;
+ } else {
+ from_index = vertex_in_loop;
+ to_index = vertex_in_loop + 1;
+ }
+ *from = &(loop->vertex(from_index));
+ *to = &(loop->vertex(to_index));
+ }
+
+ private:
+ S2Polygon const* poly_;
+ bool reverse_;
+};
+
+// Indexing structure for a sequence of loops (not in the sense of S2:
+// the loops can self-intersect). Each loop is given in a vector<S2Point>
+// where, as in S2Loop, the last vertex is implicitely joined to the first.
+// Add each loop individually with AddVector(). The caller owns
+// the vector<S2Point>'s.
+class S2LoopsAsVectorsIndex: public S2LoopSequenceIndex {
+ public:
+ S2LoopsAsVectorsIndex() {}
+ ~S2LoopsAsVectorsIndex() {}
+
+ void AddVector(vector<S2Point> const* v) {
+ loops_.push_back(v);
+ AddLoop(v->size());
+ }
+
+ virtual void EdgeFromTo(int index,
+ S2Point const* *from, S2Point const* *to) const {
+ int loop_index;
+ int vertex_in_loop;
+ DecodeIndex(index, &loop_index, &vertex_in_loop);
+ vector<S2Point> const* loop = loops_[loop_index];
+ *from = &loop->at(vertex_in_loop);
+ *to = &loop->at((size_t)vertex_in_loop == loop->size() - 1
+ ? 0
+ : vertex_in_loop + 1);
+ }
+
+ private:
+ vector< vector<S2Point> const* > loops_;
+};
+
+typedef vector<pair<double, S2Point> > IntersectionSet;
+
+static void AddIntersection(S2Point const& a0, S2Point const& a1,
+ S2Point const& b0, S2Point const& b1,
+ bool add_shared_edges, int crossing,
+ IntersectionSet* intersections) {
+ if (crossing > 0) {
+ // There is a proper edge crossing.
+ S2Point x = S2EdgeUtil::GetIntersection(a0, a1, b0, b1);
+ double t = S2EdgeUtil::GetDistanceFraction(x, a0, a1);
+ intersections->push_back(make_pair(t, x));
+
+ } else if (S2EdgeUtil::VertexCrossing(a0, a1, b0, b1)) {
+ // There is a crossing at one of the vertices. The basic rule is simple:
+ // if a0 equals one of the "b" vertices, the crossing occurs at t=0;
+ // otherwise, it occurs at t=1.
+ //
+ // This has the effect that when two symmetric edges are
+ // encountered (an edge an its reverse), neither one is included
+ // in the output. When two duplicate edges are encountered, both
+ // are included in the output. The "add_shared_edges" flag allows
+ // one of these two copies to be removed by changing its
+ // intersection parameter from 0 to 1.
+
+ double t = (a0 == b0 || a0 == b1) ? 0 : 1;
+ if (!add_shared_edges && a1 == b1) t = 1;
+ intersections->push_back(make_pair(t, t == 0 ? a0 : a1));
+ }
+}
+
+static void ClipEdge(S2Point const& a0, S2Point const& a1,
+ S2LoopSequenceIndex* b_index,
+ bool add_shared_edges, IntersectionSet* intersections) {
+ // Find all points where the polygon B intersects the edge (a0,a1),
+ // and add the corresponding parameter values (in the range [0,1]) to
+ // "intersections".
+ S2LoopSequenceIndex::Iterator it(b_index);
+ it.GetCandidates(a0, a1);
+ S2EdgeUtil::EdgeCrosser crosser(&a0, &a1, &a0);
+ S2Point const* from;
+ S2Point const* to = NULL;
+ for (; !it.Done(); it.Next()) {
+ S2Point const* const previous_to = to;
+ b_index->EdgeFromTo(it.Index(), &from, &to);
+ if (previous_to != from) crosser.RestartAt(from);
+ int crossing = crosser.RobustCrossing(to);
+ if (crossing < 0) continue;
+ AddIntersection(a0, a1, *from, *to,
+ add_shared_edges, crossing, intersections);
+ }
+}
+
+
+static void ClipBoundary(S2Polygon const* a, bool reverse_a,
+ S2Polygon const* b, bool reverse_b, bool invert_b,
+ bool add_shared_edges, S2PolygonBuilder* builder) {
+ // Clip the boundary of A to the interior of B, and add the resulting edges
+ // to "builder". Shells are directed CCW and holes are directed clockwise,
+ // unless "reverse_a" or "reverse_b" is true in which case these directions
+ // in the corresponding polygon are reversed. If "invert_b" is true, the
+ // boundary of A is clipped to the exterior rather than the interior of B.
+ // If "add_shared_edges" is true, then the output will include any edges
+ // that are shared between A and B (both edges must be in the same direction
+ // after any edge reversals are taken into account).
+
+ S2PolygonIndex b_index(b, reverse_b);
+ b_index.PredictAdditionalCalls(a->num_vertices());
+
+ IntersectionSet intersections;
+ for (int i = 0; i < a->num_loops(); ++i) {
+ S2Loop* a_loop = a->loop(i);
+ int n = a_loop->num_vertices();
+ int dir = (a_loop->is_hole() ^ reverse_a) ? -1 : 1;
+ bool inside = b->Contains(a_loop->vertex(0)) ^ invert_b;
+ for (int j = (dir > 0) ? 0 : n; n > 0; --n, j += dir) {
+ S2Point const& a0 = a_loop->vertex(j);
+ S2Point const& a1 = a_loop->vertex(j + dir);
+ intersections.clear();
+ ClipEdge(a0, a1, &b_index, add_shared_edges, &intersections);
+
+ if (inside) intersections.push_back(make_pair(0, a0));
+ inside = (intersections.size() & 1);
+ DCHECK_EQ((b->Contains(a1) ^ invert_b), inside);
+ if (inside) intersections.push_back(make_pair(1, a1));
+ sort(intersections.begin(), intersections.end());
+ for (size_t k = 0; k < intersections.size(); k += 2) {
+ if (intersections[k] == intersections[k+1]) continue;
+ builder->AddEdge(intersections[k].second, intersections[k+1].second);
+ }
+ }
+ }
+}
+
+void S2Polygon::InitToIntersection(S2Polygon const* a, S2Polygon const* b) {
+ InitToIntersectionSloppy(a, b, S2EdgeUtil::kIntersectionTolerance);
+}
+
+void S2Polygon::InitToIntersectionSloppy(S2Polygon const* a, S2Polygon const* b,
+ S1Angle vertex_merge_radius) {
+ DCHECK_EQ(0, num_loops());
+ if (!a->bound_.Intersects(b->bound_)) return;
+
+ // We want the boundary of A clipped to the interior of B,
+ // plus the boundary of B clipped to the interior of A,
+ // plus one copy of any directed edges that are in both boundaries.
+
+ S2PolygonBuilderOptions options(S2PolygonBuilderOptions::DIRECTED_XOR());
+ options.set_vertex_merge_radius(vertex_merge_radius);
+ S2PolygonBuilder builder(options);
+ ClipBoundary(a, false, b, false, false, true, &builder);
+ ClipBoundary(b, false, a, false, false, false, &builder);
+ if (!builder.AssemblePolygon(this, NULL)) {
+ S2LOG(DFATAL) << "Bad directed edges in InitToIntersection";
+ }
+}
+
+void S2Polygon::InitToUnion(S2Polygon const* a, S2Polygon const* b) {
+ InitToUnionSloppy(a, b, S2EdgeUtil::kIntersectionTolerance);
+}
+
+void S2Polygon::InitToUnionSloppy(S2Polygon const* a, S2Polygon const* b,
+ S1Angle vertex_merge_radius) {
+ DCHECK_EQ(0, num_loops());
+
+ // We want the boundary of A clipped to the exterior of B,
+ // plus the boundary of B clipped to the exterior of A,
+ // plus one copy of any directed edges that are in both boundaries.
+
+ S2PolygonBuilderOptions options(S2PolygonBuilderOptions::DIRECTED_XOR());
+ options.set_vertex_merge_radius(vertex_merge_radius);
+ S2PolygonBuilder builder(options);
+ ClipBoundary(a, false, b, false, true, true, &builder);
+ ClipBoundary(b, false, a, false, true, false, &builder);
+ if (!builder.AssemblePolygon(this, NULL)) {
+ S2LOG(DFATAL) << "Bad directed edges";
+ }
+}
+
+void S2Polygon::InitToDifference(S2Polygon const* a, S2Polygon const* b) {
+ InitToDifferenceSloppy(a, b, S2EdgeUtil::kIntersectionTolerance);
+}
+
+void S2Polygon::InitToDifferenceSloppy(S2Polygon const* a, S2Polygon const* b,
+ S1Angle vertex_merge_radius) {
+ DCHECK_EQ(0, num_loops());
+
+ // We want the boundary of A clipped to the exterior of B,
+ // plus the reversed boundary of B clipped to the interior of A,
+ // plus one copy of any edge in A that is also a reverse edge in B.
+
+ S2PolygonBuilderOptions options(S2PolygonBuilderOptions::DIRECTED_XOR());
+ options.set_vertex_merge_radius(vertex_merge_radius);
+ S2PolygonBuilder builder(options);
+ ClipBoundary(a, false, b, true, true, true, &builder);
+ ClipBoundary(b, true, a, false, false, false, &builder);
+ if (!builder.AssemblePolygon(this, NULL)) {
+ S2LOG(DFATAL) << "Bad directed edges in InitToDifference";
+ }
+}
+
+// Takes a loop and simplifies it. This may return a self-intersecting
+// polyline. Always keeps the first vertex from the loop.
+vector<S2Point>* SimplifyLoopAsPolyline(S2Loop const* loop, S1Angle tolerance) {
+ vector<S2Point> points(loop->num_vertices() + 1);
+ // Add the first vertex at the beginning and at the end.
+ for (int i = 0; i <= loop->num_vertices(); ++i) {
+ points[i] = loop->vertex(i);
+ }
+ S2Polyline line(points);
+ vector<int> indices;
+ line.SubsampleVertices(tolerance, &indices);
+ if (indices.size() <= 2) return NULL;
+ // Add them all except the last: it is the same as the first.
+ vector<S2Point>* simplified_line = new vector<S2Point>(indices.size() - 1);
+ VLOG(4) << "Now simplified to: ";
+ for (size_t i = 0; i + 1 < indices.size(); ++i) {
+ (*simplified_line)[i] = line.vertex(indices[i]);
+ VLOG(4) << S2LatLng(line.vertex(indices[i]));
+ }
+ return simplified_line;
+}
+
+// Takes a set of possibly intersecting edges, stored in an
+// S2EdgeIndex. Breaks the edges into small pieces so that there is
+// no intersection anymore, and adds all these edges to the builder.
+void BreakEdgesAndAddToBuilder(S2LoopsAsVectorsIndex* edge_index,
+ S2PolygonBuilder* builder) {
+ // If there are self intersections, we add the pieces separately.
+ for (int i = 0; i < edge_index->num_edges(); ++i) {
+ S2Point const* from;
+ S2Point const* to;
+ edge_index->EdgeFromTo(i, &from, &to);
+
+ IntersectionSet intersections;
+ intersections.push_back(make_pair(0, *from));
+ // add_shared_edges can be false or true: it makes no difference
+ // due to the way we call ClipEdge.
+ ClipEdge(*from, *to, edge_index, false, &intersections);
+ intersections.push_back(make_pair(1, *to));
+ sort(intersections.begin(), intersections.end());
+ for (size_t k = 0; k + 1 < intersections.size(); ++k) {
+ if (intersections[k] == intersections[k+1]) continue;
+ builder->AddEdge(intersections[k].second, intersections[k+1].second);
+ }
+ }
+}
+
+// Simplifies the polygon. The algorithm is straightforward and naive:
+// 1. Simplify each loop by removing points while staying in the
+// tolerance zone. This uses S2Polyline::SubsampleVertices(),
+// which is not guaranteed to be optimal in terms of number of
+// points.
+// 2. Break any edge in pieces such that no piece intersects any
+// other.
+// 3. Use the polygon builder to regenerate the full polygon.
+void S2Polygon::InitToSimplified(S2Polygon const* a, S1Angle tolerance) {
+ S2PolygonBuilderOptions builder_options =
+ S2PolygonBuilderOptions::UNDIRECTED_XOR();
+ builder_options.set_validate(false);
+ // Ideally, we would want to set the vertex_merge_radius of the
+ // builder roughly to tolerance (and in fact forego the edge
+ // splitting step). Alas, if we do that, we are liable to the
+ // 'chain effect', where vertices are merged with closeby vertices
+ // and so on, so that a vertex can move by an arbitrary distance.
+ // So we remain conservative:
+ builder_options.set_vertex_merge_radius(tolerance * 0.10);
+ S2PolygonBuilder builder(builder_options);
+
+ // Simplify each loop separately and add to the edge index
+ S2LoopsAsVectorsIndex index;
+ vector<vector<S2Point>*> simplified_loops;
+ for (int i = 0; i < a->num_loops(); ++i) {
+ vector<S2Point>* simpler = SimplifyLoopAsPolyline(a->loop(i), tolerance);
+ if (NULL == simpler) continue;
+ simplified_loops.push_back(simpler);
+ index.AddVector(simpler);
+ }
+ if (0 != index.num_edges()) {
+ BreakEdgesAndAddToBuilder(&index, &builder);
+
+ if (!builder.AssemblePolygon(this, NULL)) {
+ S2LOG(DFATAL) << "Bad edges in InitToSimplified.";
+ }
+ }
+
+ for (size_t i = 0; i < simplified_loops.size(); ++i) {
+ delete simplified_loops[i];
+ }
+ simplified_loops.clear();
+}
+
+void S2Polygon::InternalClipPolyline(bool invert,
+ S2Polyline const* a,
+ vector<S2Polyline*> *out,
+ S1Angle merge_radius) const {
+ // Clip the polyline A to the interior of this polygon.
+ // The resulting polyline(s) will be appended to 'out'.
+ // If invert is true, we clip A to the exterior of this polygon instead.
+ // Vertices will be dropped such that adjacent vertices will not
+ // be closer than 'merge_radius'.
+ //
+ // We do the intersection/subtraction by walking the polyline edges.
+ // For each edge, we compute all intersections with the polygon boundary
+ // and sort them in increasing order of distance along that edge.
+ // We then divide the intersection points into pairs, and output a
+ // clipped polyline segment for each one.
+ // We keep track of whether we're inside or outside of the polygon at
+ // all times to decide which segments to output.
+
+ CHECK(out->empty());
+
+ IntersectionSet intersections;
+ vector<S2Point> vertices;
+ S2PolygonIndex poly_index(this, false);
+ int n = a->num_vertices();
+ bool inside = Contains(a->vertex(0)) ^ invert;
+ for (int j = 0; j < n-1; j++) {
+ S2Point const& a0 = a->vertex(j);
+ S2Point const& a1 = a->vertex(j + 1);
+ ClipEdge(a0, a1, &poly_index, true, &intersections);
+ if (inside) intersections.push_back(make_pair(0, a0));
+ inside = (intersections.size() & 1);
+ DCHECK_EQ((Contains(a1) ^ invert), inside);
+ if (inside) intersections.push_back(make_pair(1, a1));
+ sort(intersections.begin(), intersections.end());
+ // At this point we have a sorted array of vertex pairs representing
+ // the edge(s) obtained after clipping (a0,a1) against the polygon.
+ for (size_t k = 0; k < intersections.size(); k += 2) {
+ if (intersections[k] == intersections[k+1]) continue;
+ S2Point const& v0 = intersections[k].second;
+ S2Point const& v1 = intersections[k+1].second;
+
+ // If the gap from the previous vertex to this one is large
+ // enough, start a new polyline.
+ if (!vertices.empty() &&
+ vertices.back().Angle(v0) > merge_radius.radians()) {
+ out->push_back(new S2Polyline(vertices));
+ vertices.clear();
+ }
+ // Append this segment to the current polyline, ignoring any
+ // vertices that are too close to the previous vertex.
+ if (vertices.empty()) vertices.push_back(v0);
+ if (vertices.back().Angle(v1) > merge_radius.radians()) {
+ vertices.push_back(v1);
+ }
+ }
+ intersections.clear();
+ }
+ if (!vertices.empty()) {
+ out->push_back(new S2Polyline(vertices));
+ }
+}
+
+void S2Polygon::IntersectWithPolyline(
+ S2Polyline const* a,
+ vector<S2Polyline*> *out) const {
+ IntersectWithPolylineSloppy(a, out, S2EdgeUtil::kIntersectionTolerance);
+}
+
+void S2Polygon::IntersectWithPolylineSloppy(
+ S2Polyline const* a,
+ vector<S2Polyline*> *out,
+ S1Angle vertex_merge_radius) const {
+ InternalClipPolyline(false, a, out, vertex_merge_radius);
+}
+
+void S2Polygon::SubtractFromPolyline(S2Polyline const* a,
+ vector<S2Polyline*> *out) const {
+ SubtractFromPolylineSloppy(a, out, S2EdgeUtil::kIntersectionTolerance);
+}
+
+void S2Polygon::SubtractFromPolylineSloppy(
+ S2Polyline const* a,
+ vector<S2Polyline*> *out,
+ S1Angle vertex_merge_radius) const {
+ InternalClipPolyline(true, a, out, vertex_merge_radius);
+}
+
+
+S2Polygon* S2Polygon::DestructiveUnion(vector<S2Polygon*>* polygons) {
+ return DestructiveUnionSloppy(polygons, S2EdgeUtil::kIntersectionTolerance);
+}
+
+S2Polygon* S2Polygon::DestructiveUnionSloppy(vector<S2Polygon*>* polygons,
+ S1Angle vertex_merge_radius) {
+ // Effectively create a priority queue of polygons in order of number of
+ // vertices. Repeatedly union the two smallest polygons and add the result
+ // to the queue until we have a single polygon to return.
+ typedef multimap<int, S2Polygon*> QueueType;
+ QueueType queue; // Map from # of vertices to polygon.
+ for (size_t i = 0; i < polygons->size(); ++i)
+ queue.insert(make_pair((*polygons)[i]->num_vertices(), (*polygons)[i]));
+ polygons->clear();
+
+ while (queue.size() > 1) {
+ // Pop two simplest polygons from queue.
+ QueueType::iterator smallest_it = queue.begin();
+ int a_size = smallest_it->first;
+ S2Polygon* a_polygon = smallest_it->second;
+ queue.erase(smallest_it);
+ smallest_it = queue.begin();
+ int b_size = smallest_it->first;
+ S2Polygon* b_polygon = smallest_it->second;
+ queue.erase(smallest_it);
+
+ // Union and add result back to queue.
+ S2Polygon* union_polygon = new S2Polygon();
+ union_polygon->InitToUnionSloppy(a_polygon, b_polygon, vertex_merge_radius);
+ delete a_polygon;
+ delete b_polygon;
+ queue.insert(make_pair(a_size + b_size, union_polygon));
+ // We assume that the number of vertices in the union polygon is the
+ // sum of the number of vertices in the original polygons, which is not
+ // always true, but will almost always be a decent approximation, and
+ // faster than recomputing.
+ }
+
+ if (queue.empty())
+ return new S2Polygon();
+ else
+ return queue.begin()->second;
+}
+
+void S2Polygon::InitToCellUnionBorder(S2CellUnion const& cells) {
+ // Use a polygon builder to union the cells in the union. Due to rounding
+ // errors, we can't do an exact union - when a small cell is adjacent to a
+ // larger cell, the shared edges can fail to line up exactly. Two cell edges
+ // cannot come closer then kMinWidth, so if we have the polygon builder merge
+ // edges within half that distance, we should always merge shared edges
+ // without merging different edges.
+ S2PolygonBuilderOptions options(S2PolygonBuilderOptions::DIRECTED_XOR());
+ double min_cell_angle = S2::kMinWidth.GetValue(S2CellId::kMaxLevel);
+ options.set_vertex_merge_radius(S1Angle::Radians(min_cell_angle / 2));
+ S2PolygonBuilder builder(options);
+ for (int i = 0; i < cells.num_cells(); ++i) {
+ S2Loop cell_loop(S2Cell(cells.cell_id(i)));
+ builder.AddLoop(&cell_loop);
+ }
+ if (!builder.AssemblePolygon(this, NULL)) {
+ S2LOG(DFATAL) << "AssemblePolygon failed in InitToCellUnionBorder";
+ }
+}
+
+bool S2Polygon::IsNormalized() const {
+ set<S2Point> vertices;
+ S2Loop* last_parent = NULL;
+ for (int i = 0; i < num_loops(); ++i) {
+ S2Loop* child = loop(i);
+ if (child->depth() == 0) continue;
+ S2Loop* parent = loop(GetParent(i));
+ if (parent != last_parent) {
+ vertices.clear();
+ for (int j = 0; j < parent->num_vertices(); ++j) {
+ vertices.insert(parent->vertex(j));
+ }
+ last_parent = parent;
+ }
+ int count = 0;
+ for (int j = 0; j < child->num_vertices(); ++j) {
+ if (vertices.count(child->vertex(j)) > 0) ++count;
+ }
+ if (count > 1) return false;
+ }
+ return true;
+}
+
+bool S2Polygon::BoundaryEquals(S2Polygon const* b) const {
+ if (num_loops() != b->num_loops()) return false;
+
+ for (int i = 0; i < num_loops(); ++i) {
+ S2Loop* a_loop = loop(i);
+ bool success = false;
+ for (int j = 0; j < num_loops(); ++j) {
+ S2Loop* b_loop = b->loop(j);
+ if ((b_loop->depth() == a_loop->depth()) &&
+ b_loop->BoundaryEquals(a_loop)) {
+ success = true;
+ break;
+ }
+ }
+ if (!success) return false;
+ }
+ return true;
+}
+
+bool S2Polygon::BoundaryApproxEquals(S2Polygon const* b,
+ double max_error) const {
+ if (num_loops() != b->num_loops()) return false;
+
+ // For now, we assume that there is at most one candidate match for each
+ // loop. (So far this method is just used for testing.)
+
+ for (int i = 0; i < num_loops(); ++i) {
+ S2Loop* a_loop = loop(i);
+ bool success = false;
+ for (int j = 0; j < num_loops(); ++j) {
+ S2Loop* b_loop = b->loop(j);
+ if (b_loop->depth() == a_loop->depth() &&
+ b_loop->BoundaryApproxEquals(a_loop, max_error)) {
+ success = true;
+ break;
+ }
+ }
+ if (!success) return false;
+ }
+ return true;
+}
+
+bool S2Polygon::BoundaryNear(S2Polygon const* b, double max_error) const {
+ if (num_loops() != b->num_loops()) return false;
+
+ // For now, we assume that there is at most one candidate match for each
+ // loop. (So far this method is just used for testing.)
+
+ for (int i = 0; i < num_loops(); ++i) {
+ S2Loop* a_loop = loop(i);
+ bool success = false;
+ for (int j = 0; j < num_loops(); ++j) {
+ S2Loop* b_loop = b->loop(j);
+ if (b_loop->depth() == a_loop->depth() &&
+ b_loop->BoundaryNear(a_loop, max_error)) {
+ success = true;
+ break;
+ }
+ }
+ if (!success) return false;
+ }
+ return true;
+}
+
+S2Point S2Polygon::Project(S2Point const& point) const {
+ DCHECK(!loops_.empty());
+
+ if (Contains(point)) {
+ return point;
+ }
+
+ S1Angle min_distance = S1Angle::Radians(10);
+ int min_loop_index = 0;
+ int min_vertex_index = 0;
+
+ for (int l = 0; l < num_loops(); ++l) {
+ S2Loop *a_loop = loop(l);
+ for (int v = 0; v < a_loop->num_vertices(); ++v) {
+ S1Angle distance_to_segment =
+ S2EdgeUtil::GetDistance(point,
+ a_loop->vertex(v),
+ a_loop->vertex(v + 1));
+ if (distance_to_segment < min_distance) {
+ min_distance = distance_to_segment;
+ min_loop_index = l;
+ min_vertex_index = v;
+ }
+ }
+ }
+
+ S2Point closest_point = S2EdgeUtil::GetClosestPoint(
+ point,
+ loop(min_loop_index)->vertex(min_vertex_index),
+ loop(min_loop_index)->vertex(min_vertex_index + 1));
+
+ return closest_point;
+}
diff --git a/src/third_party/s2/s2polygon.h b/src/third_party/s2/s2polygon.h
new file mode 100644
index 00000000000..084eb0d88d0
--- /dev/null
+++ b/src/third_party/s2/s2polygon.h
@@ -0,0 +1,311 @@
+// Copyright 2005 Google Inc. All Rights Reserved.
+
+#ifndef UTIL_GEOMETRY_S2POLYGON_H_
+#define UTIL_GEOMETRY_S2POLYGON_H_
+
+#include <map>
+using std::map;
+using std::multimap;
+
+#include <vector>
+using std::vector;
+
+
+#include "base/definer.h"
+#include "base/basictypes.h"
+#include "base/macros.h"
+#include "s2.h"
+#include "s2region.h"
+#include "s2loop.h"
+#include "s2polyline.h"
+
+class S2CellUnion;
+
+// An S2Polygon is an S2Region object that represents a polygon. A polygon
+// consists of zero or more loops representing "shells" and "holes". All
+// loops should be oriented CCW, i.e. the shell or hole is on the left side of
+// the loop. Loops may be specified in any order. A point is defined to be
+// inside the polygon if it is contained by an odd number of loops.
+//
+// Polygons have the following restrictions:
+//
+// - Loops may not cross, i.e. the boundary of a loop may not intersect
+// both the interior and exterior of any other loop.
+//
+// - Loops may not share edges, i.e. if a loop contains an edge AB, then
+// no other loop may contain AB or BA.
+//
+// - No loop may cover more than half the area of the sphere. This ensures
+// that no loop properly contains the complement of any other loop, even
+// if the loops are from different polygons. (Loops that represent exact
+// hemispheres are allowed.)
+//
+// Loops may share vertices, however no vertex may appear twice in a single
+// loop (see s2loop.h).
+class S2Polygon : public S2Region {
+ public:
+ // Creates an empty polygon that should be initialized by calling Init() or
+ // Decode().
+ S2Polygon();
+
+ // Convenience constructor that calls Init() with the given loops. Takes
+ // ownership of the loops and clears the given vector.
+ explicit S2Polygon(vector<S2Loop*>* loops);
+
+ // Convenience constructor that creates a polygon with a single loop
+ // corresponding to the given cell.
+ explicit S2Polygon(S2Cell const& cell);
+
+ // Initialize a polygon by taking ownership of the given loops and clearing
+ // the given vector. This method figures out the loop nesting hierarchy and
+ // then reorders the loops by following a preorder traversal. This implies
+ // that each loop is immediately followed by its descendants in the nesting
+ // hierarchy. (See also GetParent and GetLastDescendant.)
+ void Init(vector<S2Loop*>* loops);
+
+ // Release ownership of the loops of this polygon, and appends them to
+ // "loops" if non-NULL. Resets the polygon to be empty.
+ void Release(vector<S2Loop*>* loops);
+
+ // Makes a deep copy of the given source polygon. Requires that the
+ // destination polygon is empty.
+ void Copy(S2Polygon const* src);
+
+ // Destroys the polygon and frees its loops.
+ ~S2Polygon();
+
+ // Return true if the given loops form a valid polygon. Assumes that
+ // all of the given loops have already been validated.
+ static bool IsValid(const vector<S2Loop*>& loops);
+
+ // Return true if this is a valid polygon. Note that in debug mode,
+ // validity is checked at polygon creation time, so IsValid() should always
+ // return true.
+ bool IsValid() const;
+
+ // DEPRECATED.
+ bool IsValid(bool check_loops, int max_adjacent) const;
+
+ int num_loops() const { return loops_.size(); }
+
+ // Total number of vertices in all loops.
+ int num_vertices() const { return num_vertices_; }
+
+ S2Loop* loop(int k) const { return loops_[k]; }
+
+ // Return the index of the parent of loop k, or -1 if it has no parent.
+ int GetParent(int k) const;
+
+ // Return the index of the last loop that is contained within loop k.
+ // Returns num_loops() - 1 if k < 0. Note that loops are indexed according
+ // to a preorder traversal of the nesting hierarchy, so the immediate
+ // children of loop k can be found by iterating over loops
+ // (k+1)..GetLastDescendant(k) and selecting those whose depth is equal to
+ // (loop(k)->depth() + 1).
+ int GetLastDescendant(int k) const;
+
+ // Return the area of the polygon interior, i.e. the region on the left side
+ // of an odd number of loops. The return value is between 0 and 4*Pi.
+ double GetArea() const;
+
+ // Return the true centroid of the polygon multiplied by the area of the
+ // polygon (see s2.h for details on centroids). The result is not unit
+ // length, so you may want to normalize it. Also note that in general, the
+ // centroid may not be contained by the polygon.
+ //
+ // We prescale by the polygon area for two reasons: (1) it is cheaper to
+ // compute this way, and (2) it makes it easier to compute the centroid of
+ // more complicated shapes (by splitting them into disjoint regions and
+ // adding their centroids).
+ S2Point GetCentroid() const;
+
+ // Return true if this polygon contains the given other polygon, i.e.
+ // if polygon A contains all points contained by polygon B.
+ bool Contains(S2Polygon const* b) const;
+
+ // Returns true if this polgyon (A) approximately contains the given other
+ // polygon (B). This is true if it is possible to move the vertices of B
+ // no further than "vertex_merge_radius" such that A contains the modified B.
+ //
+ // For example, the empty polygon will contain any polygon whose maximum
+ // width is no more than vertex_merge_radius.
+ bool ApproxContains(S2Polygon const* b, S1Angle vertex_merge_radius) const;
+
+ // Return true if this polygon intersects the given other polygon, i.e.
+ // if there is a point that is contained by both polygons.
+ bool Intersects(S2Polygon const* b) const;
+
+ // Initialize this polygon to the intersection, union, or difference
+ // (A - B) of the given two polygons. The "vertex_merge_radius" determines
+ // how close two vertices must be to be merged together and how close a
+ // vertex must be to an edge in order to be spliced into it (see
+ // S2PolygonBuilder for details). By default, the merge radius is just
+ // large enough to compensate for errors that occur when computing
+ // intersection points between edges (S2EdgeUtil::kIntersectionTolerance).
+ //
+ // If you are going to convert the resulting polygon to a lower-precision
+ // format, it is necessary to increase the merge radius in order to get a
+ // valid result after rounding (i.e. no duplicate vertices, etc). For
+ // example, if you are going to convert them to geostore::PolygonProto
+ // format, then S1Angle::E7(1) is a good value for "vertex_merge_radius".
+ void InitToIntersection(S2Polygon const* a, S2Polygon const* b);
+ void InitToIntersectionSloppy(S2Polygon const* a, S2Polygon const* b,
+ S1Angle vertex_merge_radius);
+ void InitToUnion(S2Polygon const* a, S2Polygon const* b);
+ void InitToUnionSloppy(S2Polygon const* a, S2Polygon const* b,
+ S1Angle vertex_merge_radius);
+ void InitToDifference(S2Polygon const* a, S2Polygon const* b);
+ void InitToDifferenceSloppy(S2Polygon const* a, S2Polygon const* b,
+ S1Angle vertex_merge_radius);
+
+ // Initializes this polygon to a polygon that contains fewer vertices and is
+ // within tolerance of the polygon a, with some caveats.
+ //
+ // - If there is a very small island in the original polygon, it may
+ // disappear completely. Thus some parts of the original polygon
+ // may not be close to the simplified polygon. Those parts are small,
+ // though, and arguably don't need to be kept.
+ // - However, if there are dense islands, they may all disappear, instead
+ // of replacing them by a big simplified island.
+ // - For small tolerances (compared to the polygon size), it may happen that
+ // the simplified polygon has more vertices than the original, if the
+ // first step of the simplification creates too many self-intersections.
+ // One can construct irrealistic cases where that happens to an extreme
+ // degree.
+ void InitToSimplified(S2Polygon const* a, S1Angle tolerance);
+
+ // Intersect this polygon with the polyline "in" and append the resulting
+ // zero or more polylines to "out" (which must be empty). The polylines
+ // are appended in the order they would be encountered by traversing "in"
+ // from beginning to end. Note that the output may include polylines with
+ // only one vertex, but there will not be any zero-vertex polylines.
+ //
+ // This is equivalent to calling IntersectWithPolylineSloppy() with the
+ // "vertex_merge_radius" set to S2EdgeUtil::kIntersectionTolerance.
+ void IntersectWithPolyline(S2Polyline const* in,
+ vector<S2Polyline*> *out) const;
+
+ // Similar to IntersectWithPolyline(), except that vertices will be
+ // dropped as necessary to ensure that all adjacent vertices in the
+ // sequence obtained by concatenating the output polylines will be
+ // farther than "vertex_merge_radius" apart. Note that this can change
+ // the number of output polylines and/or yield single-vertex polylines.
+ void IntersectWithPolylineSloppy(S2Polyline const* in,
+ vector<S2Polyline*> *out,
+ S1Angle vertex_merge_radius) const;
+
+ // Same as IntersectWithPolyline, but subtracts this polygon from
+ // the given polyline.
+ void SubtractFromPolyline(S2Polyline const* in,
+ vector<S2Polyline*> *out) const;
+
+ // Same as IntersectWithPolylineSloppy, but subtracts this polygon
+ // from the given polyline.
+ void SubtractFromPolylineSloppy(S2Polyline const* in,
+ vector<S2Polyline*> *out,
+ S1Angle vertex_merge_radius) const;
+
+ // Return a polygon which is the union of the given polygons.
+ // Clears the vector and deletes the polygons!
+ static S2Polygon* DestructiveUnion(vector<S2Polygon*>* polygons);
+ static S2Polygon* DestructiveUnionSloppy(vector<S2Polygon*>* polygons,
+ S1Angle vertex_merge_radius);
+
+ // Initialize this polygon to the outline of the given cell union.
+ // In principle this polygon should exactly contain the cell union and
+ // this polygon's inverse should not intersect the cell union, but rounding
+ // issues may cause this not to be the case.
+ // Does not work correctly if the union covers more than half the sphere.
+ void InitToCellUnionBorder(S2CellUnion const& cells);
+
+ // Return true if every loop of this polygon shares at most one vertex with
+ // its parent loop. Every polygon has a unique normalized form. Normalized
+ // polygons are useful for testing since it is easy to compare whether two
+ // polygons represent the same region.
+ bool IsNormalized() const;
+
+ // Return true if two polygons have the same boundary. More precisely, this
+ // method requires that both polygons have loops with the same cyclic vertex
+ // order and the same nesting hierarchy.
+ bool BoundaryEquals(S2Polygon const* b) const;
+
+ // Return true if two polygons have the same boundary except for vertex
+ // perturbations. Both polygons must have loops with the same cyclic vertex
+ // order and the same nesting hierarchy, but the vertex locations are
+ // allowed to differ by up to "max_error".
+ bool BoundaryApproxEquals(S2Polygon const* b, double max_error = 1e-15) const;
+
+ // Return true if two polygons have boundaries that are within "max_error"
+ // of each other along their entire lengths. More precisely, there must be
+ // a bijection between the two sets of loops such that for each pair of
+ // loops, "a_loop->BoundaryNear(b_loop)" is true.
+ bool BoundaryNear(S2Polygon const* b, double max_error = 1e-15) const;
+
+ // If the point is not contained by the polygon returns a point on the
+ // polygon closest to the given point. Otherwise returns the point itself.
+ // The polygon must not be empty.
+ S2Point Project(S2Point const& point) const;
+
+ ////////////////////////////////////////////////////////////////////////
+ // S2Region interface (see s2region.h for details):
+
+ // GetRectBound() guarantees that it will return exact bounds. GetCapBound()
+ // does not.
+ virtual S2Polygon* Clone() const;
+ virtual S2Cap GetCapBound() const; // Cap surrounding rect bound.
+ virtual S2LatLngRect GetRectBound() const { return bound_; }
+
+ virtual bool Contains(S2Cell const& cell) const;
+ virtual bool MayIntersect(S2Cell const& cell) const;
+ virtual bool VirtualContainsPoint(S2Point const& p) const;
+
+ // The point 'p' does not need to be normalized.
+ bool Contains(S2Point const& p) const;
+
+ virtual void Encode(Encoder* const encoder) const;
+ virtual bool Decode(Decoder* const decoder);
+ virtual bool DecodeWithinScope(Decoder* const decoder);
+
+ private:
+ // Internal constructor that does *not* take ownership of its argument.
+ explicit S2Polygon(S2Loop* loop);
+
+ // A map from each loop to its immediate children with respect to nesting.
+ // This map is built during initialization of multi-loop polygons to
+ // determine which are shells and which are holes, and then discarded.
+ typedef map<S2Loop*, vector<S2Loop*> > LoopMap;
+
+ // Internal implementation of the Decode and DecodeWithinScope methods above.
+ // The within_scope parameter specifies whether to call DecodeWithinScope
+ // on the loops.
+ bool DecodeInternal(Decoder* const decoder, bool within_scope);
+
+ // Internal implementation of intersect/subtract polyline functions above.
+ void InternalClipPolyline(bool invert,
+ S2Polyline const* a,
+ vector<S2Polyline*> *out,
+ S1Angle vertex_merge_radius) const;
+
+ static void InsertLoop(S2Loop* new_loop, S2Loop* parent, LoopMap* loop_map);
+ static bool ContainsChild(S2Loop* a, S2Loop* b, LoopMap const& loop_map);
+ void InitLoop(S2Loop* loop, int depth, LoopMap* loop_map);
+
+ int ContainsOrCrosses(S2Loop const* b) const;
+ bool AnyLoopContains(S2Loop const* b) const;
+ bool ContainsAllShells(S2Polygon const* b) const;
+ bool ExcludesAllHoles(S2Polygon const* b) const;
+ bool IntersectsAnyShell(S2Polygon const* b) const;
+ bool IntersectsShell(S2Loop const* b) const;
+
+ vector<S2Loop*> loops_;
+ S2LatLngRect bound_;
+ char owns_loops_;
+ char has_holes_;
+
+ // Cache for num_vertices().
+ int num_vertices_;
+
+ DISALLOW_EVIL_CONSTRUCTORS(S2Polygon);
+};
+
+#endif // UTIL_GEOMETRY_S2POLYGON_H_
diff --git a/src/third_party/s2/s2polygon_test.cc b/src/third_party/s2/s2polygon_test.cc
new file mode 100644
index 00000000000..e044777873f
--- /dev/null
+++ b/src/third_party/s2/s2polygon_test.cc
@@ -0,0 +1,1226 @@
+// Copyright 2005 Google Inc. All Rights Reserved.
+//
+// To run the benchmarks, use:
+
+#include "s2polygon.h"
+
+#include <algorithm>
+using std::min;
+using std::max;
+using std::swap;
+using std::reverse;
+
+#include <cstdio>
+#include <string>
+using std::string;
+
+#include <vector>
+using std::vector;
+
+
+#include "base/commandlineflags.h"
+#include "base/logging.h"
+#include "base/macros.h"
+#include "base/scoped_ptr.h"
+#include "strings/stringprintf.h"
+#include "testing/base/public/benchmark.h"
+#include "testing/base/public/gunit.h"
+#include "util/coding/coder.h"
+#include "s2.h"
+#include "s2cap.h"
+#include "s2cellunion.h"
+#include "s2latlng.h"
+#include "s2loop.h"
+#include "s2polygonbuilder.h"
+#include "s2polyline.h"
+#include "s2regioncoverer.h"
+#include "s2testing.h"
+#include "util/math/matrix3x3.h"
+#include "util/math/matrix3x3-inl.h"
+
+DEFINE_int32(num_loops_per_polygon_for_bm,
+ 10,
+ "Number of loops per polygon to use for an s2polygon "
+ "encode/decode benchmark. Can be a maximum of 90.");
+
+// A set of nested loops around the point 0:0 (lat:lng).
+// Every vertex of kNear0 is a vertex of kNear1.
+char const kNearPoint[] = "0:0";
+string const kNear0 = "-1:0, 0:1, 1:0, 0:-1;";
+string const kNear1 = "-1:-1, -1:0, -1:1, 0:1, 1:1, 1:0, 1:-1, 0:-1;";
+string const kNear2 = "5:-2, -2:5, -1:-2;";
+string const kNear3 = "6:-3, -3:6, -2:-2;";
+string const kNearHemi = "0:-90, -90:0, 0:90, 90:0;";
+
+// A set of nested loops around the point 0:180 (lat:lng).
+// Every vertex of kFar0 and kFar2 belongs to kFar1, and all
+// the loops except kFar2 are non-convex.
+string const kFar0 = "0:179, 1:180, 0:-179, 2:-180;";
+string const kFar1 =
+ "0:179, -1:179, 1:180, -1:-179, 0:-179, 3:-178, 2:-180, 3:178;";
+string const kFar2 = "-1:-179, -1:179, 3:178, 3:-178;"; // opposite direction
+string const kFar3 = "-3:-178, -2:179, -3:178, 4:177, 4:-177;";
+string const kFarHemi = "0:-90, 60:90, -60:90;";
+
+// A set of nested loops around the point -90:0 (lat:lng).
+string const kSouthPoint = "-89.9999:0.001";
+string const kSouth0a = "-90:0, -89.99:0, -89.99:0.01;";
+string const kSouth0b = "-90:0, -89.99:0.02, -89.99:0.03;";
+string const kSouth0c = "-90:0, -89.99:0.04, -89.99:0.05;";
+string const kSouth1 = "-90:0, -89.9:-0.1, -89.9:0.1;";
+string const kSouth2 = "-90:0, -89.8:-0.2, -89.8:0.2;";
+string const kSouthHemi = "0:-180, 0:60, 0:-60;";
+
+// Two different loops that surround all the Near and Far loops except
+// for the hemispheres.
+string const kNearFar1 = "-1:-9, -9:-9, -9:9, 9:9, 9:-9, 1:-9, "
+ "1:-175, 9:-175, 9:175, -9:175, -9:-175, -1:-175;";
+string const kNearFar2 = "-8:-4, 8:-4, 2:15, 2:170, "
+ "8:-175, -8:-175, -2:170, -2:15;";
+
+// Loops that result from intersection of other loops.
+string const kFarHSouthH = "0:-180, 0:90, -60:90, 0:-90;";
+
+// Rectangles that form a cross, with only shared vertices, no crossing edges.
+// Optional holes outside the intersecting region.
+string const kCross1 = "-2:1, -1:1, 1:1, 2:1, 2:-1, 1:-1, -1:-1, -2:-1;";
+string const kCross1SideHole = "-1.5:0.5, -1.2:0.5, -1.2:-0.5, -1.5:-0.5;";
+string const kCross2 = "1:-2, 1:-1, 1:1, 1:2, -1:2, -1:1, -1:-1, -1:-2;";
+string const kCross2SideHole = "0.5:-1.5, 0.5:-1.2, -0.5:-1.2, -0.5:-1.5;";
+string const kCrossCenterHole = "-0.5:0.5, 0.5:0.5, 0.5:-0.5, -0.5:-0.5;";
+
+// Two rectangles that intersect, but no edges cross and there's always
+// local containment (rather than crossing) at each shared vertex.
+// In this ugly ASCII art, 1 is A+B, 2 is B+C:
+// +---+---+---+
+// | A | B | C |
+// +---+---+---+
+string const kOverlap1 = "0:1, 1:1, 2:1, 2:0, 1:0, 0:0;";
+string const kOverlap1SideHole = "0.2:0.8, 0.8:0.8, 0.8:0.2, 0.2:0.2;";
+string const kOverlap2 = "1:1, 2:1, 3:1, 3:0, 2:0, 1:0;";
+string const kOverlap2SideHole = "2.2:0.8, 2.8:0.8, 2.8:0.2, 2.2:0.2;";
+string const kOverlapCenterHole = "1.2:0.8, 1.8:0.8, 1.8:0.2, 1.2:0.2;";
+
+class S2PolygonTestBase : public testing::Test {
+ public:
+ S2PolygonTestBase();
+ ~S2PolygonTestBase();
+ protected:
+ // Some standard polygons to use in the tests.
+ S2Polygon const* const near_0;
+ S2Polygon const* const near_10;
+ S2Polygon const* const near_30;
+ S2Polygon const* const near_32;
+ S2Polygon const* const near_3210;
+ S2Polygon const* const near_H3210;
+
+ S2Polygon const* const far_10;
+ S2Polygon const* const far_21;
+ S2Polygon const* const far_321;
+ S2Polygon const* const far_H20;
+ S2Polygon const* const far_H3210;
+
+ S2Polygon const* const south_0ab;
+ S2Polygon const* const south_2;
+ S2Polygon const* const south_210b;
+ S2Polygon const* const south_H21;
+ S2Polygon const* const south_H20abc;
+
+ S2Polygon const* const nf1_n10_f2_s10abc;
+
+ S2Polygon const* const nf2_n2_f210_s210ab;
+
+ S2Polygon const* const f32_n0;
+ S2Polygon const* const n32_s0b;
+
+ S2Polygon const* const cross1;
+ S2Polygon const* const cross1_side_hole;
+ S2Polygon const* const cross1_center_hole;
+ S2Polygon const* const cross2;
+ S2Polygon const* const cross2_side_hole;
+ S2Polygon const* const cross2_center_hole;
+
+ S2Polygon const* const overlap1;
+ S2Polygon const* const overlap1_side_hole;
+ S2Polygon const* const overlap1_center_hole;
+ S2Polygon const* const overlap2;
+ S2Polygon const* const overlap2_side_hole;
+ S2Polygon const* const overlap2_center_hole;
+
+ S2Polygon const* const far_H;
+ S2Polygon const* const south_H;
+ S2Polygon const* const far_H_south_H;
+};
+
+static S2Polygon* MakePolygon(string const& str) {
+ scoped_ptr<S2Polygon> polygon(S2Testing::MakePolygon(str));
+ Encoder encoder;
+ polygon->Encode(&encoder);
+ Decoder decoder(encoder.base(), encoder.length());
+ scoped_ptr<S2Polygon> decoded_polygon(new S2Polygon);
+ decoded_polygon->Decode(&decoder);
+ return decoded_polygon.release();
+}
+
+static void CheckContains(string const& a_str, string const& b_str) {
+ S2Polygon* a = MakePolygon(a_str);
+ S2Polygon* b = MakePolygon(b_str);
+ scoped_ptr<S2Polygon> delete_a(a);
+ scoped_ptr<S2Polygon> delete_b(b);
+ EXPECT_TRUE(a->Contains(b));
+ EXPECT_TRUE(a->ApproxContains(b, S1Angle::Radians(1e-15)));
+}
+
+static void CheckContainsPoint(string const& a_str, string const& b_str) {
+ scoped_ptr<S2Polygon> a(S2Testing::MakePolygon(a_str));
+ EXPECT_TRUE(a->VirtualContainsPoint(S2Testing::MakePoint(b_str)))
+ << " " << a_str << " did not contain " << b_str;
+}
+
+TEST(S2Polygon, Init) {
+ CheckContains(kNear1, kNear0);
+ CheckContains(kNear2, kNear1);
+ CheckContains(kNear3, kNear2);
+ CheckContains(kNearHemi, kNear3);
+ CheckContains(kFar1, kFar0);
+ CheckContains(kFar2, kFar1);
+ CheckContains(kFar3, kFar2);
+ CheckContains(kFarHemi, kFar3);
+ CheckContains(kSouth1, kSouth0a);
+ CheckContains(kSouth1, kSouth0b);
+ CheckContains(kSouth1, kSouth0c);
+ CheckContains(kSouthHemi, kSouth2);
+ CheckContains(kNearFar1, kNear3);
+ CheckContains(kNearFar1, kFar3);
+ CheckContains(kNearFar2, kNear3);
+ CheckContains(kNearFar2, kFar3);
+
+ CheckContainsPoint(kNear0, kNearPoint);
+ CheckContainsPoint(kNear1, kNearPoint);
+ CheckContainsPoint(kNear2, kNearPoint);
+ CheckContainsPoint(kNear3, kNearPoint);
+ CheckContainsPoint(kNearHemi, kNearPoint);
+ CheckContainsPoint(kSouth0a, kSouthPoint);
+ CheckContainsPoint(kSouth1, kSouthPoint);
+ CheckContainsPoint(kSouth2, kSouthPoint);
+ CheckContainsPoint(kSouthHemi, kSouthPoint);
+}
+
+S2PolygonTestBase::S2PolygonTestBase():
+ near_0(MakePolygon(kNear0)),
+ near_10(MakePolygon(kNear0 + kNear1)),
+ near_30(MakePolygon(kNear3 + kNear0)),
+ near_32(MakePolygon(kNear2 + kNear3)),
+ near_3210(MakePolygon(kNear0 + kNear2 + kNear3 + kNear1)),
+ near_H3210(MakePolygon(kNear0 + kNear2 + kNear3 + kNearHemi + kNear1)),
+
+ far_10(MakePolygon(kFar0 + kFar1)),
+ far_21(MakePolygon(kFar2 + kFar1)),
+ far_321(MakePolygon(kFar2 + kFar3 + kFar1)),
+ far_H20(MakePolygon(kFar2 + kFarHemi + kFar0)),
+ far_H3210(MakePolygon(kFar2 + kFarHemi + kFar0 + kFar1 + kFar3)),
+
+ south_0ab(MakePolygon(kSouth0a + kSouth0b)),
+ south_2(MakePolygon(kSouth2)),
+ south_210b(MakePolygon(kSouth2 + kSouth0b + kSouth1)),
+ south_H21(MakePolygon(kSouth2 + kSouthHemi + kSouth1)),
+ south_H20abc(MakePolygon(
+ kSouth2 + kSouth0b + kSouthHemi + kSouth0a + kSouth0c)),
+
+ nf1_n10_f2_s10abc(MakePolygon(kSouth0c + kFar2 + kNear1 + kNearFar1 +
+ kNear0 + kSouth1 + kSouth0b + kSouth0a)),
+
+ nf2_n2_f210_s210ab(MakePolygon(kFar2 + kSouth0a + kFar1 + kSouth1 + kFar0 +
+ kSouth0b + kNearFar2 + kSouth2 + kNear2)),
+
+ f32_n0(MakePolygon(kFar2 + kNear0 + kFar3)),
+ n32_s0b(MakePolygon(kNear3 + kSouth0b + kNear2)),
+
+ cross1(MakePolygon(kCross1)),
+ cross1_side_hole(MakePolygon(kCross1 + kCross1SideHole)),
+ cross1_center_hole(MakePolygon(kCross1 + kCrossCenterHole)),
+ cross2(MakePolygon(kCross2)),
+ cross2_side_hole(MakePolygon(kCross2 + kCross2SideHole)),
+ cross2_center_hole(MakePolygon(kCross2 + kCrossCenterHole)),
+
+ overlap1(MakePolygon(kOverlap1)),
+ overlap1_side_hole(MakePolygon(kOverlap1 + kOverlap1SideHole)),
+ overlap1_center_hole(MakePolygon(kOverlap1 + kOverlapCenterHole)),
+ overlap2(MakePolygon(kOverlap2)),
+ overlap2_side_hole(MakePolygon(kOverlap2 + kOverlap2SideHole)),
+ overlap2_center_hole(MakePolygon(kOverlap2 + kOverlapCenterHole)),
+
+ far_H(MakePolygon(kFarHemi)),
+ south_H(MakePolygon(kSouthHemi)),
+ far_H_south_H(MakePolygon(kFarHSouthH))
+{}
+
+S2PolygonTestBase::~S2PolygonTestBase() {
+ delete near_0;
+ delete near_10;
+ delete near_30;
+ delete near_32;
+ delete near_3210;
+ delete near_H3210;
+
+ delete far_10;
+ delete far_21;
+ delete far_321;
+ delete far_H20;
+ delete far_H3210;
+
+ delete south_0ab;
+ delete south_2;
+ delete south_210b;
+ delete south_H21;
+ delete south_H20abc;
+
+ delete nf1_n10_f2_s10abc;
+
+ delete nf2_n2_f210_s210ab;
+
+ delete f32_n0;
+ delete n32_s0b;
+
+ delete cross1;
+ delete cross1_side_hole;
+ delete cross1_center_hole;
+ delete cross2;
+ delete cross2_side_hole;
+ delete cross2_center_hole;
+
+ delete overlap1;
+ delete overlap1_side_hole;
+ delete overlap1_center_hole;
+ delete overlap2;
+ delete overlap2_side_hole;
+ delete overlap2_center_hole;
+
+ delete far_H;
+ delete south_H;
+ delete far_H_south_H;
+}
+
+static void CheckEqual(S2Polygon const* a, S2Polygon const* b,
+ double max_error = 1e-31) {
+ if (a->IsNormalized() && b->IsNormalized()) {
+ ASSERT_TRUE(a->BoundaryApproxEquals(b, max_error));
+ } else {
+ S2PolygonBuilder builder(S2PolygonBuilderOptions::DIRECTED_XOR());
+ S2Polygon a2, b2;
+ builder.AddPolygon(a);
+ ASSERT_TRUE(builder.AssemblePolygon(&a2, NULL));
+ builder.AddPolygon(b);
+ ASSERT_TRUE(builder.AssemblePolygon(&b2, NULL));
+ ASSERT_TRUE(a2.BoundaryApproxEquals(&b2, max_error));
+ }
+}
+
+static void TestUnion(S2Polygon const* a, S2Polygon const* b) {
+ S2Polygon c_union;
+ c_union.InitToUnion(a, b);
+
+ vector<S2Polygon*> polygons;
+ polygons.push_back(new S2Polygon);
+ polygons.back()->Copy(a);
+ polygons.push_back(new S2Polygon);
+ polygons.back()->Copy(b);
+ scoped_ptr<S2Polygon> c_destructive_union(
+ S2Polygon::DestructiveUnion(&polygons));
+
+ CheckEqual(&c_union, c_destructive_union.get());
+}
+
+static void TestContains(S2Polygon const* a, S2Polygon const* b) {
+ S2Polygon c, d, e;
+ c.InitToUnion(a, b);
+ CheckEqual(&c, a);
+ TestUnion(a, b);
+
+ d.InitToIntersection(a, b);
+ CheckEqual(&d, b);
+
+ e.InitToDifference(b, a);
+ EXPECT_EQ(0, e.num_loops());
+}
+
+TEST(S2Polygon, TestApproxContains) {
+ // Get a random S2Cell as a polygon.
+ S2CellId id = S2CellId::FromLatLng(S2LatLng::FromE6(40565459, -74645276));
+ S2Cell cell(id.parent(10));
+ S2Polygon cell_as_polygon(cell);
+
+ // We want to roughly bisect the polygon, so we make a rectangle that is the
+ // top half of the current polygon's bounding rectangle.
+ S2LatLngRect const& bounds = cell_as_polygon.GetRectBound();
+ S2LatLngRect upper_half = bounds;
+ upper_half.mutable_lat()->set_lo(bounds.lat().GetCenter());
+
+ // Turn the S2LatLngRect into an S2Polygon
+ vector<S2Point> points;
+ for (int i = 0; i < 4; i++)
+ points.push_back(upper_half.GetVertex(i).ToPoint());
+ vector<S2Loop*> loops;
+ loops.push_back(new S2Loop(points));
+ S2Polygon upper_half_polygon(&loops);
+
+ // Get the intersection. There is no guarantee that the intersection will be
+ // contained by A or B.
+ S2Polygon intersection;
+ intersection.InitToIntersection(&cell_as_polygon, &upper_half_polygon);
+ EXPECT_FALSE(cell_as_polygon.Contains(&intersection));
+
+ EXPECT_TRUE(
+ cell_as_polygon.ApproxContains(&intersection,
+ S2EdgeUtil::kIntersectionTolerance));
+}
+
+static void TestDisjoint(S2Polygon const* a, S2Polygon const* b) {
+ S2PolygonBuilder builder(S2PolygonBuilderOptions::DIRECTED_XOR());
+ builder.AddPolygon(a);
+ builder.AddPolygon(b);
+ S2Polygon ab;
+ ASSERT_TRUE(builder.AssemblePolygon(&ab, NULL));
+
+ S2Polygon c, d, e, f;
+ c.InitToUnion(a, b);
+ CheckEqual(&c, &ab);
+ TestUnion(a, b);
+
+ d.InitToIntersection(a, b);
+ EXPECT_EQ(0, d.num_loops());
+
+ e.InitToDifference(a, b);
+ CheckEqual(&e, a);
+
+ f.InitToDifference(b, a);
+ CheckEqual(&f, b);
+}
+
+static void TestRelationWithDesc(S2Polygon const* a, S2Polygon const* b,
+ int contains, bool intersects,
+ const char *test_description) {
+ SCOPED_TRACE(test_description);
+ EXPECT_EQ(contains > 0, a->Contains(b));
+ EXPECT_EQ(contains < 0, b->Contains(a));
+ EXPECT_EQ(intersects, a->Intersects(b));
+ if (contains > 0) {
+ TestContains(a, b);
+ } else if (contains < 0) {
+ TestContains(b, a);
+ }
+ if (!intersects) {
+ TestDisjoint(a, b);
+ }
+}
+
+TEST_F(S2PolygonTestBase, Relations) {
+#define TestRelation(a, b, contains, intersects) \
+ TestRelationWithDesc(a, b, contains, intersects, "args " #a ", " #b)
+ TestRelation(near_10, near_30, -1, true);
+ TestRelation(near_10, near_32, 0, false);
+ TestRelation(near_10, near_3210, -1, true);
+ TestRelation(near_10, near_H3210, 0, false);
+ TestRelation(near_30, near_32, 1, true);
+ TestRelation(near_30, near_3210, 1, true);
+ TestRelation(near_30, near_H3210, 0, true);
+ TestRelation(near_32, near_3210, -1, true);
+ TestRelation(near_32, near_H3210, 0, false);
+ TestRelation(near_3210, near_H3210, 0, false);
+
+ TestRelation(far_10, far_21, 0, false);
+ TestRelation(far_10, far_321, -1, true);
+ TestRelation(far_10, far_H20, 0, false);
+ TestRelation(far_10, far_H3210, 0, false);
+ TestRelation(far_21, far_321, 0, false);
+ TestRelation(far_21, far_H20, 0, false);
+ TestRelation(far_21, far_H3210, -1, true);
+ TestRelation(far_321, far_H20, 0, true);
+ TestRelation(far_321, far_H3210, 0, true);
+ TestRelation(far_H20, far_H3210, 0, true);
+
+ TestRelation(south_0ab, south_2, -1, true);
+ TestRelation(south_0ab, south_210b, 0, true);
+ TestRelation(south_0ab, south_H21, -1, true);
+ TestRelation(south_0ab, south_H20abc, -1, true);
+ TestRelation(south_2, south_210b, 1, true);
+ TestRelation(south_2, south_H21, 0, true);
+ TestRelation(south_2, south_H20abc, 0, true);
+ TestRelation(south_210b, south_H21, 0, true);
+ TestRelation(south_210b, south_H20abc, 0, true);
+ TestRelation(south_H21, south_H20abc, 1, true);
+
+ TestRelation(nf1_n10_f2_s10abc, nf2_n2_f210_s210ab, 0, true);
+ TestRelation(nf1_n10_f2_s10abc, near_32, 1, true);
+ TestRelation(nf1_n10_f2_s10abc, far_21, 0, false);
+ TestRelation(nf1_n10_f2_s10abc, south_0ab, 0, false);
+ TestRelation(nf1_n10_f2_s10abc, f32_n0, 1, true);
+
+ TestRelation(nf2_n2_f210_s210ab, near_10, 0, false);
+ TestRelation(nf2_n2_f210_s210ab, far_10, 1, true);
+ TestRelation(nf2_n2_f210_s210ab, south_210b, 1, true);
+ TestRelation(nf2_n2_f210_s210ab, south_0ab, 1, true);
+ TestRelation(nf2_n2_f210_s210ab, n32_s0b, 1, true);
+
+ TestRelation(cross1, cross2, 0, true);
+ TestRelation(cross1_side_hole, cross2, 0, true);
+ TestRelation(cross1_center_hole, cross2, 0, true);
+ TestRelation(cross1, cross2_side_hole, 0, true);
+ TestRelation(cross1, cross2_center_hole, 0, true);
+ TestRelation(cross1_side_hole, cross2_side_hole, 0, true);
+ TestRelation(cross1_center_hole, cross2_side_hole, 0, true);
+ TestRelation(cross1_side_hole, cross2_center_hole, 0, true);
+ TestRelation(cross1_center_hole, cross2_center_hole, 0, true);
+
+ // These cases, when either polygon has a hole, test a different code path
+ // from the other cases.
+ TestRelation(overlap1, overlap2, 0, true);
+ TestRelation(overlap1_side_hole, overlap2, 0, true);
+ TestRelation(overlap1_center_hole, overlap2, 0, true);
+ TestRelation(overlap1, overlap2_side_hole, 0, true);
+ TestRelation(overlap1, overlap2_center_hole, 0, true);
+ TestRelation(overlap1_side_hole, overlap2_side_hole, 0, true);
+ TestRelation(overlap1_center_hole, overlap2_side_hole, 0, true);
+ TestRelation(overlap1_side_hole, overlap2_center_hole, 0, true);
+ TestRelation(overlap1_center_hole, overlap2_center_hole, 0, true);
+#undef TestRelation
+}
+
+struct TestCase {
+ char const* a;
+ char const* b;
+ char const* a_and_b;
+ char const* a_or_b;
+ char const* a_minus_b;
+};
+
+TestCase test_cases[] = {
+ // Two triangles that share an edge.
+ { "4:2, 3:1, 3:3;",
+
+ "3:1, 2:2, 3:3;",
+
+ "",
+
+ "4:2, 3:1, 2:2, 3:3;",
+
+ "4:2, 3:1, 3:3;"
+ },
+
+ // Two vertical bars and a horizontal bar connecting them.
+ { "0:0, 0:2, 3:2, 3:0; 0:3, 0:5, 3:5, 3:3;",
+
+ "1:1, 1:4, 2:4, 2:1;",
+
+ "1:1, 1:2, 2:2, 2:1; 1:3, 1:4, 2:4, 2:3;",
+
+ "0:0, 0:2, 1:2, 1:3, 0:3, 0:5, 3:5, 3:3, 2:3, 2:2, 3:2, 3:0;",
+
+ "0:0, 0:2, 1:2, 1:1, 2:1, 2:2, 3:2, 3:0; "
+ "0:3, 0:5, 3:5, 3:3, 2:3, 2:4, 1:4, 1:3;"
+ },
+
+ // Two vertical bars and two horizontal bars centered around S2::Origin().
+ { "1:88, 1:93, 2:93, 2:88; -1:88, -1:93, 0:93, 0:88;",
+
+ "-2:89, -2:90, 3:90, 3:89; -2:91, -2:92, 3:92, 3:91;",
+
+ "1:89, 1:90, 2:90, 2:89; 1:91, 1:92, 2:92, 2:91; "
+ "-1:89, -1:90, 0:90, 0:89; -1:91, -1:92, 0:92, 0:91;",
+
+ "-1:88, -1:89, -2:89, -2:90, -1:90, -1:91, -2:91, -2:92, -1:92, -1:93,"
+ "0:93, 0:92, 1:92, 1:93, 2:93, 2:92, 3:92, 3:91, 2:91, 2:90, 3:90,"
+ "3:89, 2:89, 2:88, 1:88, 1:89, 0:89, 0:88; "
+ "0:90, 0:91, 1:91, 1:90;",
+
+ "1:88, 1:89, 2:89, 2:88; 1:90, 1:91, 2:91, 2:90; "
+ "1:92, 1:93, 2:93, 2:92; -1:88, -1:89, 0:89, 0:88; "
+ "-1:90, -1:91, 0:91, 0:90; -1:92, -1:93, 0:93, 0:92;"
+ },
+
+ // Two interlocking square doughnuts centered around -S2::Origin().
+ { "-1:-93, -1:-89, 3:-89, 3:-93; 0:-92, 0:-90, 2:-90, 2:-92;",
+
+ "-3:-91, -3:-87, 1:-87, 1:-91; -2:-90, -2:-88, 0:-88, 0:-90;",
+
+ "-1:-91, -1:-90, 0:-90, 0:-91; 0:-90, 0:-89, 1:-89, 1:-90;",
+
+ "-1:-93, -1:-91, -3:-91, -3:-87, 1:-87, 1:-89, 3:-89, 3:-93; "
+ "0:-92, 0:-91, 1:-91, 1:-90, 2:-90, 2:-92; "
+ "-2:-90, -2:-88, 0:-88, 0:-89, -1:-89, -1:-90;",
+
+ "-1:-93, -1:-91, 0:-91, 0:-92, 2:-92, 2:-90, 1:-90, 1:-89, 3:-89, 3:-93; "
+ "-1:-90, -1:-89, 0:-89, 0:-90;"
+ },
+
+ // An incredibly thin triangle intersecting a square, such that the two
+ // intersection points of the triangle with the square are identical.
+ // This results in a degenerate loop that needs to be handled correctly.
+ { "10:44, 10:46, 12:46, 12:44;",
+
+ "11:45, 89:45.00000000000001, 90:45;",
+
+ "", // Empty intersection!
+
+ // Original square with extra vertex, and triangle disappears (due to
+ // default vertex_merge_radius of S2EdgeUtil::kIntersectionTolerance).
+ "10:44, 10:46, 12:46, 12:45, 12:44;",
+
+ "10:44, 10:46, 12:46, 12:45, 12:44;"
+ },
+};
+
+TEST_F(S2PolygonTestBase, Operations) {
+ S2Polygon far_south;
+ far_south.InitToIntersection(far_H, south_H);
+ CheckEqual(&far_south, far_H_south_H);
+
+ for (int i = 0; i < arraysize(test_cases); ++i) {
+ SCOPED_TRACE(StringPrintf("Polygon operation test case %d", i));
+ TestCase* test = test_cases + i;
+ scoped_ptr<S2Polygon> a(MakePolygon(test->a));
+ scoped_ptr<S2Polygon> b(MakePolygon(test->b));
+ scoped_ptr<S2Polygon> expected_a_and_b(MakePolygon(test->a_and_b));
+ scoped_ptr<S2Polygon> expected_a_or_b(MakePolygon(test->a_or_b));
+ scoped_ptr<S2Polygon> expected_a_minus_b(MakePolygon(test->a_minus_b));
+
+ // The intersections in the "expected" data were computed in lat-lng
+ // space, while the actual intersections are computed using geodesics.
+ // The error due to this depends on the length and direction of the line
+ // segment being intersected, and how close the intersection is to the
+ // endpoints of the segment. The worst case is for a line segment between
+ // two points at the same latitude, where the intersection point is in the
+ // middle of the segment. In this case the error is approximately
+ // (p * t^2) / 8, where "p" is the absolute latitude in radians, "t" is
+ // the longitude difference in radians, and both "p" and "t" are small.
+ // The test cases all have small latitude and longitude differences.
+ // If "p" and "t" are converted to degrees, the following error bound is
+ // valid as long as (p * t^2 < 150).
+
+ static double const kMaxError = 1e-4;
+
+ S2Polygon a_and_b, a_or_b, a_minus_b;
+ a_and_b.InitToIntersection(a.get(), b.get());
+ CheckEqual(&a_and_b, expected_a_and_b.get(), kMaxError);
+ a_or_b.InitToUnion(a.get(), b.get());
+ TestUnion(a.get(), b.get());
+ CheckEqual(&a_or_b, expected_a_or_b.get(), kMaxError);
+ a_minus_b.InitToDifference(a.get(), b.get());
+ CheckEqual(&a_minus_b, expected_a_minus_b.get(), kMaxError);
+ }
+}
+
+void ClearPolylineVector(vector<S2Polyline*>* polylines) {
+ for (vector<S2Polyline*>::const_iterator it = polylines->begin();
+ it != polylines->end(); ++it) {
+ delete *it;
+ }
+ polylines->clear();
+}
+
+static void PolylineIntersectionSharedEdgeTest(const S2Polygon *p,
+ int start_vertex,
+ int direction) {
+ SCOPED_TRACE(StringPrintf("Polyline intersection shared edge test "
+ " start=%d direction=%d",
+ start_vertex, direction));
+ vector<S2Point> points;
+ points.push_back(p->loop(0)->vertex(start_vertex));
+ points.push_back(p->loop(0)->vertex(start_vertex + direction));
+ S2Polyline polyline(points);
+ vector<S2Polyline*> polylines;
+ if (direction < 0) {
+ p->IntersectWithPolyline(&polyline, &polylines);
+ EXPECT_EQ(0, polylines.size());
+ ClearPolylineVector(&polylines);
+ p->SubtractFromPolyline(&polyline, &polylines);
+ ASSERT_EQ(1, polylines.size());
+ ASSERT_EQ(2, polylines[0]->num_vertices());
+ EXPECT_EQ(points[0], polylines[0]->vertex(0));
+ EXPECT_EQ(points[1], polylines[0]->vertex(1));
+ } else {
+ p->IntersectWithPolyline(&polyline, &polylines);
+ ASSERT_EQ(1, polylines.size());
+ ASSERT_EQ(2, polylines[0]->num_vertices());
+ EXPECT_EQ(points[0], polylines[0]->vertex(0));
+ EXPECT_EQ(points[1], polylines[0]->vertex(1));
+ ClearPolylineVector(&polylines);
+ p->SubtractFromPolyline(&polyline, &polylines);
+ EXPECT_EQ(0, polylines.size());
+ }
+ ClearPolylineVector(&polylines);
+}
+
+// This tests polyline-polyline intersections.
+// It covers the same edge cases as TestOperations and also adds some
+// extra tests for shared edges.
+TEST_F(S2PolygonTestBase, PolylineIntersection) {
+ for (int v = 0; v < 3; ++v) {
+ PolylineIntersectionSharedEdgeTest(cross1, v, 1);
+ PolylineIntersectionSharedEdgeTest(cross1, v + 1, -1);
+ PolylineIntersectionSharedEdgeTest(cross1_side_hole, v, 1);
+ PolylineIntersectionSharedEdgeTest(cross1_side_hole, v + 1, -1);
+ }
+
+ // See comments in TestOperations about the vlue of this constant.
+ static double const kMaxError = 1e-4;
+
+ // This duplicates some of the tests in TestOperations by
+ // converting the outline of polygon A to a polyline then intersecting
+ // it with the polygon B. It then converts B to a polyline and intersects
+ // it with A. It then feeds all of the results into a polygon builder and
+ // tests that the output is equal to doing an intersection between A and B.
+ for (int i = 0; i < arraysize(test_cases); ++i) {
+ SCOPED_TRACE(StringPrintf("Polyline intersection test case %d", i));
+ TestCase* test = test_cases + i;
+ scoped_ptr<S2Polygon> a(MakePolygon(test->a));
+ scoped_ptr<S2Polygon> b(MakePolygon(test->b));
+ scoped_ptr<S2Polygon> expected_a_and_b(MakePolygon(test->a_and_b));
+
+ vector<S2Point> points;
+ vector<S2Polyline *> polylines;
+ for (int ab = 0; ab < 2; ab++) {
+ S2Polygon *tmp = ab ? a.get() : b.get();
+ S2Polygon *tmp2 = ab ? b.get() : a.get();
+ for (int l = 0; l < tmp->num_loops(); l++) {
+ points.clear();
+ if (tmp->loop(l)->is_hole()) {
+ for (int v = tmp->loop(l)->num_vertices(); v >=0 ; v--) {
+ points.push_back(tmp->loop(l)->vertex(v));
+ }
+ } else {
+ for (int v = 0; v <= tmp->loop(l)->num_vertices(); v++) {
+ points.push_back(tmp->loop(l)->vertex(v));
+ }
+ }
+ S2Polyline polyline(points);
+ vector<S2Polyline *> tmp;
+ tmp2->IntersectWithPolyline(&polyline, &tmp);
+ polylines.insert(polylines.end(), tmp.begin(), tmp.end());
+ }
+ }
+
+ S2PolygonBuilder builder(S2PolygonBuilderOptions::DIRECTED_XOR());
+ for (int i = 0; i < polylines.size(); i++) {
+ for (int j = 0; j < polylines[i]->num_vertices() - 1; j++) {
+ builder.AddEdge(polylines[i]->vertex(j), polylines[i]->vertex(j + 1));
+ VLOG(3) << " ... Adding edge: " << polylines[i]->vertex(j) << " - " <<
+ polylines[i]->vertex(j + 1);
+ }
+ }
+ ClearPolylineVector(&polylines);
+
+ S2Polygon a_and_b;
+ ASSERT_TRUE(builder.AssemblePolygon(&a_and_b, NULL));
+ CheckEqual(&a_and_b, expected_a_and_b.get(), kMaxError);
+ }
+}
+
+// Remove a random polygon from "pieces" and return it.
+static S2Polygon* ChoosePiece(vector<S2Polygon*> *pieces) {
+ int i = S2Testing::rnd.Uniform(pieces->size());
+ S2Polygon* result = (*pieces)[i];
+ pieces->erase(pieces->begin() + i);
+ return result;
+}
+
+static void SplitAndAssemble(S2Polygon const* polygon) {
+ S2PolygonBuilder builder(S2PolygonBuilderOptions::DIRECTED_XOR());
+ S2Polygon expected;
+ builder.AddPolygon(polygon);
+ ASSERT_TRUE(builder.AssemblePolygon(&expected, NULL));
+
+ for (int iter = 0; iter < 10; ++iter) {
+ S2RegionCoverer coverer;
+ // Compute the minimum level such that the polygon's bounding
+ // cap is guaranteed to be cut.
+ double diameter = 2 * polygon->GetCapBound().angle().radians();
+ int min_level = S2::kMaxWidth.GetMinLevel(diameter);
+
+ // TODO: Choose a level that will have up to 256 cells in the covering.
+ int level = min_level + S2Testing::rnd.Uniform(4);
+ coverer.set_min_level(min_level);
+ coverer.set_max_level(level);
+ coverer.set_max_cells(500);
+
+ vector<S2CellId> cells;
+ coverer.GetCovering(*polygon, &cells);
+ S2CellUnion covering;
+ covering.Init(cells);
+ S2Testing::CheckCovering(*polygon, covering, false);
+ VLOG(2) << cells.size() << " cells in covering";
+ vector<S2Polygon*> pieces;
+ for (int i = 0; i < cells.size(); ++i) {
+ S2Cell cell(cells[i]);
+ S2Polygon window(cell);
+ S2Polygon* piece = new S2Polygon;
+ piece->InitToIntersection(polygon, &window);
+ pieces.push_back(piece);
+ VLOG(4) << "\nPiece " << i << ":\n Window: "
+ << S2Testing::ToString(&window)
+ << "\n Piece: " << S2Testing::ToString(piece);
+ }
+
+ // Now we repeatedly remove two random pieces, compute their union, and
+ // insert the result as a new piece until only one piece is left.
+ //
+ // We don't use S2Polygon::DestructiveUnion() because it joins the pieces
+ // in a mostly deterministic order. We don't just call random_shuffle()
+ // on the pieces and repeatedly join the last two pieces in the vector
+ // because this always joins a single original piece to the current union
+ // rather than doing the unions according to a random tree structure.
+ while (pieces.size() > 1) {
+ scoped_ptr<S2Polygon> a(ChoosePiece(&pieces));
+ scoped_ptr<S2Polygon> b(ChoosePiece(&pieces));
+ S2Polygon* c = new S2Polygon;
+ c->InitToUnion(a.get(), b.get());
+ pieces.push_back(c);
+ VLOG(4) << "\nJoining piece a: " << S2Testing::ToString(a.get())
+ << "\n With piece b: " << S2Testing::ToString(b.get())
+ << "\n To get piece c: " << S2Testing::ToString(c);
+ }
+ scoped_ptr<S2Polygon> result(pieces[0]);
+ pieces.pop_back();
+
+ // The moment of truth!
+ EXPECT_TRUE(expected.BoundaryNear(result.get()))
+ << "\nActual:\n" << S2Testing::ToString(result.get())
+ << "\nExpected:\n" << S2Testing::ToString(&expected);
+ }
+}
+
+TEST_F(S2PolygonTestBase, Splitting) {
+ // It takes too long to test all the polygons in debug mode, so we just pick
+ // out some of the more interesting ones.
+
+ SplitAndAssemble(near_H3210);
+ SplitAndAssemble(far_H3210);
+ SplitAndAssemble(south_0ab);
+ SplitAndAssemble(south_210b);
+ SplitAndAssemble(south_H20abc);
+ SplitAndAssemble(nf1_n10_f2_s10abc);
+ SplitAndAssemble(nf2_n2_f210_s210ab);
+ SplitAndAssemble(far_H);
+ SplitAndAssemble(south_H);
+ SplitAndAssemble(far_H_south_H);
+}
+
+TEST(S2Polygon, InitToCellUnionBorder) {
+ // Test S2Polygon::InitToCellUnionBorder().
+ // The main thing to check is that adjacent cells of different sizes get
+ // merged correctly. To do this we generate two random adjacent cells,
+ // convert to polygon, and make sure the polygon only has a single loop.
+ for (int iter = 0; iter < 500; ++iter) {
+ SCOPED_TRACE(StringPrintf("Iteration %d", iter));
+
+ // Choose a random non-leaf cell.
+ S2CellId big_cell =
+ S2Testing::GetRandomCellId(S2Testing::rnd.Uniform(S2CellId::kMaxLevel));
+ // Get all neighbors at some smaller level.
+ int small_level = big_cell.level() +
+ S2Testing::rnd.Uniform(min(16, S2CellId::kMaxLevel - big_cell.level()));
+ vector<S2CellId> neighbors;
+ big_cell.AppendAllNeighbors(small_level, &neighbors);
+ // Pick one at random.
+ S2CellId small_cell = neighbors[S2Testing::rnd.Uniform(neighbors.size())];
+ // If it's diagonally adjacent, bail out.
+ S2CellId edge_neighbors[4];
+ big_cell.GetEdgeNeighbors(edge_neighbors);
+ bool diagonal = true;
+ for (int i = 0; i < 4; ++i) {
+ if (edge_neighbors[i].contains(small_cell)) {
+ diagonal = false;
+ }
+ }
+ VLOG(3) << iter << ": big_cell " << big_cell <<
+ " small_cell " << small_cell;
+ if (diagonal) {
+ VLOG(3) << " diagonal - bailing out!";
+ continue;
+ }
+
+ vector<S2CellId> cells;
+ cells.push_back(big_cell);
+ cells.push_back(small_cell);
+ S2CellUnion cell_union;
+ cell_union.Init(cells);
+ EXPECT_EQ(2, cell_union.num_cells());
+ S2Polygon poly;
+ poly.InitToCellUnionBorder(cell_union);
+ EXPECT_EQ(1, poly.num_loops());
+ // If the conversion were perfect we could test containment, but due to
+ // rounding the polygon won't always exactly contain both cells. We can
+ // at least test intersection.
+ EXPECT_TRUE(poly.MayIntersect(S2Cell(big_cell)));
+ EXPECT_TRUE(poly.MayIntersect(S2Cell(small_cell)));
+ }
+}
+
+TEST_F(S2PolygonTestBase, TestEncodeDecode) {
+ Encoder encoder;
+ cross1->Encode(&encoder);
+ Decoder decoder(encoder.base(), encoder.length());
+ S2Polygon decoded_polygon;
+ ASSERT_TRUE(decoded_polygon.Decode(&decoder));
+ EXPECT_TRUE(cross1->BoundaryEquals(&decoded_polygon));
+ EXPECT_EQ(cross1->GetRectBound(), decoded_polygon.GetRectBound());
+}
+
+// This test checks that S2Polygons created directly from S2Cells behave
+// identically to S2Polygons created from the vertices of those cells; this
+// previously was not the case, because S2Cells calculate their bounding
+// rectangles slightly differently, and S2Polygons created from them just
+// copied the S2Cell bounds.
+TEST(S2Polygon, TestS2CellConstructorAndContains) {
+ S2LatLng latlng(S1Angle::E6(40565459), S1Angle::E6(-74645276));
+ S2Cell cell(S2CellId::FromLatLng(latlng));
+ S2Polygon cell_as_polygon(cell);
+ S2Polygon empty;
+ S2Polygon polygon_copy;
+ polygon_copy.InitToUnion(&cell_as_polygon, &empty);
+ EXPECT_TRUE(polygon_copy.Contains(&cell_as_polygon));
+ EXPECT_TRUE(polygon_copy.Contains(cell));
+}
+
+TEST(S2PolygonTest, Project) {
+ scoped_ptr<S2Polygon> polygon(MakePolygon(kNear0 + kNear2));
+ S2Point point;
+ S2Point projected;
+
+ // The point inside the polygon should be projected into itself.
+ point = S2Testing::MakePoint("1.1:0");
+ projected = polygon->Project(point);
+ EXPECT_TRUE(S2::ApproxEquals(point, projected));
+
+ // The point is on the outside of the polygon.
+ point = S2Testing::MakePoint("5.1:-2");
+ projected = polygon->Project(point);
+ EXPECT_TRUE(S2::ApproxEquals(S2Testing::MakePoint("5:-2"), projected));
+
+ // The point is inside the hole in the polygon.
+ point = S2Testing::MakePoint("-0.49:-0.49");
+ projected = polygon->Project(point);
+ EXPECT_TRUE(S2::ApproxEquals(S2Testing::MakePoint("-0.5:-0.5"),
+ projected, 1e-6));
+
+ point = S2Testing::MakePoint("0:-3");
+ projected = polygon->Project(point);
+ EXPECT_TRUE(S2::ApproxEquals(S2Testing::MakePoint("0:-2"), projected));
+}
+
+// Returns the distance of a point to a polygon (distance is 0 if the
+// point is in the polygon).
+double DistanceToPolygonInDegrees(S2Point point, S2Polygon const& poly) {
+ S1Angle distance = S1Angle(poly.Project(point), point);
+ return distance.degrees();
+}
+
+// Returns the diameter of a loop (maximum distance between any two
+// points in the loop).
+S1Angle LoopDiameter(S2Loop const& loop) {
+ S1Angle diameter = S1Angle();
+ for (int i = 0; i < loop.num_vertices(); ++i) {
+ S2Point test_point = loop.vertex(i);
+ for (int j = i + 1; j < loop.num_vertices(); ++j) {
+ diameter = max(diameter,
+ S2EdgeUtil::GetDistance(test_point, loop.vertex(j),
+ loop.vertex(j+1)));
+ }
+ }
+ return diameter;
+}
+
+// Returns the maximum distance from any vertex of poly_a to poly_b, that is,
+// the directed Haussdorf distance of the set of vertices of poly_a to the
+// boundary of poly_b.
+//
+// Doesn't consider loops from poly_a that have diameter less than min_diameter
+// in degrees.
+double MaximumDistanceInDegrees(S2Polygon const& poly_a,
+ S2Polygon const& poly_b,
+ double min_diameter_in_degrees) {
+ double min_distance = 360;
+ bool has_big_loops = false;
+ for (int l = 0; l < poly_a.num_loops(); ++l) {
+ S2Loop* a_loop = poly_a.loop(l);
+ if (LoopDiameter(*a_loop).degrees() <= min_diameter_in_degrees) {
+ continue;
+ }
+ has_big_loops = true;
+ for (int v = 0; v < a_loop->num_vertices(); ++v) {
+ double distance =
+ DistanceToPolygonInDegrees(a_loop->vertex(v), poly_b);
+ if (distance < min_distance) {
+ min_distance = distance;
+ }
+ }
+ }
+ if (has_big_loops) {
+ return min_distance;
+ } else {
+ return 0.; // As if the first polygon were empty.
+ }
+}
+
+class S2PolygonSimplifierTest : public ::testing::Test {
+ protected:
+ S2PolygonSimplifierTest() {
+ simplified = NULL;
+ original = NULL;
+ }
+
+ ~S2PolygonSimplifierTest() {
+ delete simplified;
+ delete original;
+ }
+
+ // Owns poly.
+ void SetInput(S2Polygon* poly, double tolerance_in_degrees) {
+ delete original;
+ delete simplified;
+ original = poly;
+
+ simplified = new S2Polygon();
+ return simplified->InitToSimplified(original,
+ S1Angle::Degrees(tolerance_in_degrees));
+ }
+
+ void SetInput(string const& poly, double tolerance_in_degrees) {
+ SetInput(S2Testing::MakePolygon(poly), tolerance_in_degrees);
+ }
+
+ S2Polygon* simplified;
+ S2Polygon* original;
+};
+
+TEST_F(S2PolygonSimplifierTest, NoSimplification) {
+ SetInput("0:0, 0:20, 20:20, 20:0", 1.0);
+ EXPECT_EQ(4, simplified->num_vertices());
+
+ EXPECT_EQ(0, MaximumDistanceInDegrees(*simplified, *original, 0));
+ EXPECT_EQ(0, MaximumDistanceInDegrees(*original, *simplified, 0));
+}
+
+// Here, 10:-2 will be removed and 0:0-20:0 will intersect two edges.
+// (The resulting polygon will in fact probably have more edges.)
+TEST_F(S2PolygonSimplifierTest, SimplifiedLoopSelfIntersects) {
+ SetInput("0:0, 0:20, 10:-0.1, 20:20, 20:0, 10:-0.2", 0.22);
+
+ // To make sure that this test does something, we check
+ // that the vertex 10:-0.2 is not in the simplification anymore.
+ S2Point test_point = S2Testing::MakePoint("10:-0.2");
+ EXPECT_LT(0.05, DistanceToPolygonInDegrees(test_point, *simplified));
+
+ EXPECT_GE(0.22, MaximumDistanceInDegrees(*simplified, *original, 0));
+ EXPECT_GE(0.22, MaximumDistanceInDegrees(*original, *simplified, 0.22));
+}
+
+TEST_F(S2PolygonSimplifierTest, NoSimplificationManyLoops) {
+ SetInput("0:0, 0:1, 1:0; 0:20, 0:21, 1:20; "
+ "20:20, 20:21, 21:20; 20:0, 20:1, 21:0", 0.01);
+ EXPECT_EQ(0, MaximumDistanceInDegrees(*simplified, *original, 0));
+ EXPECT_EQ(0, MaximumDistanceInDegrees(*original, *simplified, 0));
+}
+
+TEST_F(S2PolygonSimplifierTest, TinyLoopDisappears) {
+ SetInput("0:0, 0:1, 1:1, 1:0", 1.1);
+ EXPECT_EQ(0, simplified->num_vertices());
+}
+
+TEST_F(S2PolygonSimplifierTest, StraightLinesAreSimplified) {
+ SetInput("0:0, 1:0, 2:0, 3:0, 4:0, 5:0, 6:0,"
+ "6:1, 5:1, 4:1, 3:1, 2:1, 1:1, 0:1", 0.01);
+ EXPECT_EQ(4, simplified->num_vertices());
+}
+
+TEST_F(S2PolygonSimplifierTest, EdgeSplitInManyPieces) {
+ // near_square's right four-point side will be simplified to a vertical
+ // line at lng=7.9, that will cut the 9 teeth of the saw (the edge will
+ // therefore be broken into 19 pieces).
+ const string saw =
+ "1:1, 1:8, 2:2, 2:8, 3:2, 3:8, 4:2, 4:8, 5:2, 5:8,"
+ "6:2, 6:8, 7:2, 7:8, 8:2, 8:8, 9:2, 9:8, 10:1";
+ const string near_square =
+ "0:0, 0:7.9, 1:8.1, 10:8.1, 11:7.9, 11:0";
+ SetInput(saw + ";" + near_square, 0.21);
+
+ EXPECT_TRUE(simplified->IsValid());
+ EXPECT_GE(0.11, MaximumDistanceInDegrees(*simplified, *original, 0));
+ EXPECT_GE(0.11, MaximumDistanceInDegrees(*original, *simplified, 0));
+ // The resulting polygon's 9 little teeth are very small and disappear
+ // due to the vertex_merge_radius of the polygon builder. There remains
+ // nine loops.
+ EXPECT_EQ(9, simplified->num_loops());
+}
+
+TEST_F(S2PolygonSimplifierTest, EdgesOverlap) {
+ // Two loops, One edge of the second one ([0:1 - 0:2]) is part of an
+ // edge of the first one..
+ SetInput("0:0, 0:3, 1:0; 0:1, -1:1, 0:2", 0.01);
+ scoped_ptr<S2Polygon> true_poly(
+ S2Testing::MakePolygon("0:3, 1:0, 0:0, 0:1, -1:1, 0:2"));
+ EXPECT_TRUE(simplified->BoundaryApproxEquals(true_poly.get()));
+}
+
+S2Polygon* MakeRegularPolygon(const string& center,
+ int num_points, double radius_in_degrees) {
+
+ double radius_in_radians = S1Angle::Degrees(radius_in_degrees).radians();
+ S2Loop* l = S2Testing::MakeRegularLoop(S2Testing::MakePoint(center),
+ num_points,
+ radius_in_radians);
+ vector<S2Loop*> loops;
+ loops.push_back(l);
+ return new S2Polygon(&loops);
+}
+
+// Tests that a regular polygon with many points gets simplified
+// enough.
+TEST_F(S2PolygonSimplifierTest, LargeRegularPolygon) {
+ const double kRadius = 2.; // in degrees
+ const int num_initial_points = 1000;
+ const int num_desired_points = 250;
+ double tolerance = 1.05 * kRadius * (1 - cos(M_PI / num_desired_points));
+
+ S2Polygon* p = MakeRegularPolygon("0:0", num_initial_points, kRadius);
+ SetInput(p, tolerance);
+
+ EXPECT_GE(tolerance, MaximumDistanceInDegrees(*simplified, *original, 0));
+ EXPECT_GE(tolerance, MaximumDistanceInDegrees(*original, *simplified, 0));
+ EXPECT_GE(250, simplified->num_vertices());
+ EXPECT_LE(200, simplified->num_vertices());
+}
+
+string GenerateInputForBenchmark(int num_vertices_per_loop_for_bm) {
+ CHECK_LE(FLAGS_num_loops_per_polygon_for_bm, 90);
+ vector<S2Loop*> loops;
+ for (int li = 0; li < FLAGS_num_loops_per_polygon_for_bm; ++li) {
+ vector<S2Point> vertices;
+ double radius_degrees =
+ 1.0 + (50.0 * li) / FLAGS_num_loops_per_polygon_for_bm;
+ for (int vi = 0; vi < num_vertices_per_loop_for_bm; ++vi) {
+ double angle_radians = (2 * M_PI * vi) / num_vertices_per_loop_for_bm;
+ double lat = radius_degrees * cos(angle_radians);
+ double lng = radius_degrees * sin(angle_radians);
+ vertices.push_back(S2LatLng::FromDegrees(lat, lng).ToPoint());
+ }
+ loops.push_back(new S2Loop(vertices));
+ }
+ S2Polygon polygon_to_encode(&loops);
+
+ Encoder encoder;
+ polygon_to_encode.Encode(&encoder);
+ string encoded(encoder.base(), encoder.length());
+
+ return encoded;
+}
+
+static void BM_S2Decoding(int iters, int num_vertices_per_loop_for_bm) {
+ StopBenchmarkTiming();
+ string encoded = GenerateInputForBenchmark(num_vertices_per_loop_for_bm);
+ StartBenchmarkTiming();
+ for (int i = 0; i < iters; ++i) {
+ Decoder decoder(encoded.data(), encoded.size());
+ S2Polygon decoded_polygon;
+ decoded_polygon.Decode(&decoder);
+ }
+}
+BENCHMARK_RANGE(BM_S2Decoding, 8, 131072);
+
+static void BM_S2DecodingWithinScope(int iters,
+ int num_vertices_per_loop_for_bm) {
+ StopBenchmarkTiming();
+ string encoded = GenerateInputForBenchmark(num_vertices_per_loop_for_bm);
+ StartBenchmarkTiming();
+ for (int i = 0; i < iters; ++i) {
+ Decoder decoder(encoded.data(), encoded.size());
+ S2Polygon decoded_polygon;
+ decoded_polygon.DecodeWithinScope(&decoder);
+ }
+}
+BENCHMARK_RANGE(BM_S2DecodingWithinScope, 8, 131072);
+
+
+void ConcentricLoops(S2Point center,
+ int num_loops,
+ int num_vertices_per_loop,
+ S2Polygon* poly) {
+ Matrix3x3_d m;
+ S2::GetFrame(center, &m);
+ vector<S2Loop*> loops;
+ for (int li = 0; li < num_loops; ++li) {
+ vector<S2Point> vertices;
+ double radius = 0.005 * (li + 1) / num_loops;
+ double radian_step = 2 * M_PI / num_vertices_per_loop;
+ for (int vi = 0; vi < num_vertices_per_loop; ++vi) {
+ double angle = vi * radian_step;
+ S2Point p(radius * cos(angle), radius * sin(angle), 1);
+ vertices.push_back(S2::FromFrame(m, p.Normalize()));
+ }
+ loops.push_back(new S2Loop(vertices));
+ }
+ poly->Init(&loops);
+}
+
+static void UnionOfPolygons(int iters,
+ int num_vertices_per_loop,
+ double second_polygon_offset) {
+ for (int i = 0; i < iters; ++i) {
+ StopBenchmarkTiming();
+ S2Polygon p1, p2;
+ S2Point center = S2Testing::RandomPoint();
+ ConcentricLoops(center,
+ FLAGS_num_loops_per_polygon_for_bm,
+ num_vertices_per_loop,
+ &p1);
+ ConcentricLoops(
+ (center + S2Point(second_polygon_offset,
+ second_polygon_offset,
+ second_polygon_offset)).Normalize(),
+ FLAGS_num_loops_per_polygon_for_bm,
+ num_vertices_per_loop,
+ &p2);
+ StartBenchmarkTiming();
+ S2Polygon p_result;
+ p_result.InitToUnion(&p1, &p2);
+ }
+}
+
+static void BM_DeepPolygonUnion(int iters, int num_vertices_per_loop) {
+ UnionOfPolygons(iters, num_vertices_per_loop, 0.000001);
+}
+BENCHMARK(BM_DeepPolygonUnion)
+ ->Arg(8)
+ ->Arg(64)
+ ->Arg(128)
+ ->Arg(256)
+ ->Arg(512)
+ ->Arg(1024)
+ ->Arg(4096)
+ ->Arg(8192);
+
+static void BM_ShallowPolygonUnion(int iters, int num_vertices_per_loop) {
+ UnionOfPolygons(iters, num_vertices_per_loop, 0.004);
+}
+BENCHMARK(BM_ShallowPolygonUnion)
+ ->Arg(8)
+ ->Arg(64)
+ ->Arg(128)
+ ->Arg(256)
+ ->Arg(512)
+ ->Arg(1024)
+ ->Arg(4096)
+ ->Arg(8192);
+
+static void BM_DisjointPolygonUnion(int iters, int num_vertices_per_loop) {
+ UnionOfPolygons(iters, num_vertices_per_loop, 0.3);
+}
+BENCHMARK(BM_DisjointPolygonUnion)
+ ->Arg(8)
+ ->Arg(64)
+ ->Arg(128)
+ ->Arg(256)
+ ->Arg(512)
+ ->Arg(1024)
+ ->Arg(4096)
+ ->Arg(8192);
diff --git a/src/third_party/s2/s2polygonbuilder.cc b/src/third_party/s2/s2polygonbuilder.cc
new file mode 100644
index 00000000000..cc8077b1c62
--- /dev/null
+++ b/src/third_party/s2/s2polygonbuilder.cc
@@ -0,0 +1,574 @@
+// Copyright 2006 Google Inc. All Rights Reserved.
+
+#include "s2polygonbuilder.h"
+
+#include "s2.h"
+#include <algorithm>
+using std::min;
+using std::max;
+using std::swap;
+using std::reverse;
+
+#if defined OS_MACOSX
+#include <ext/hash_map>
+#else
+#include <hash_map>
+#endif
+#ifndef OS_WINDOWS
+using __gnu_cxx::hash_map;
+#endif
+
+#if defined OS_MACOSX
+#include <ext/hash_set>
+#else
+#include <hash_set>
+#endif
+#ifndef OS_WINDOWS
+using __gnu_cxx::hash_set;
+#endif
+
+#include <iomanip>
+using std::setprecision;
+
+#include <iostream>
+using std::ostream;
+using std::cout;
+using std::endl;
+
+#include <map>
+using std::map;
+using std::multimap;
+
+#include <set>
+using std::set;
+using std::multiset;
+
+#include <vector>
+using std::vector;
+
+
+#include "base/logging.h"
+#include "base/macros.h"
+#include "s2.h"
+#include "s2cellid.h"
+#include "s2polygon.h"
+#include "util/math/matrix3x3-inl.h"
+
+void S2PolygonBuilderOptions::set_undirected_edges(bool undirected_edges) {
+ undirected_edges_ = undirected_edges;
+}
+
+void S2PolygonBuilderOptions::set_xor_edges(bool xor_edges) {
+ xor_edges_ = xor_edges;
+}
+
+void S2PolygonBuilderOptions::set_validate(bool validate) {
+ validate_ = validate;
+}
+
+void S2PolygonBuilderOptions::set_vertex_merge_radius(S1Angle const& angle) {
+ vertex_merge_radius_ = angle;
+}
+
+void S2PolygonBuilderOptions::set_edge_splice_fraction(double fraction) {
+ CHECK(fraction < sqrt(3) / 2);
+ edge_splice_fraction_ = fraction;
+}
+
+S2PolygonBuilder::S2PolygonBuilder(S2PolygonBuilderOptions const& options)
+ : options_(options), edges_(new EdgeSet) {
+}
+
+S2PolygonBuilder::~S2PolygonBuilder() {
+}
+
+bool S2PolygonBuilder::HasEdge(S2Point const& v0, S2Point const& v1) {
+ EdgeSet::const_iterator candidates = edges_->find(v0);
+ return (candidates != edges_->end() &&
+ candidates->second.find(v1) != candidates->second.end());
+}
+
+bool S2PolygonBuilder::AddEdge(S2Point const& v0, S2Point const& v1) {
+ // If xor_edges is true, we look for an existing edge in the opposite
+ // direction. We either delete that edge or insert a new one.
+
+ if (v0 == v1) return false;
+ if (options_.xor_edges() && HasEdge(v1, v0)) {
+ EraseEdge(v1, v0);
+ return false;
+ }
+ if (edges_->find(v0) == edges_->end()) starting_vertices_.push_back(v0);
+ (*edges_)[v0].insert(v1);
+ if (options_.undirected_edges()) {
+ if (edges_->find(v1) == edges_->end()) starting_vertices_.push_back(v1);
+ (*edges_)[v1].insert(v0);
+ }
+ return true;
+}
+
+void S2PolygonBuilder::AddLoop(S2Loop const* loop) {
+ int sign = loop->sign();
+ for (int i = loop->num_vertices(); i > 0; --i) {
+ // Vertex indices need to be in the range [0, 2*num_vertices()-1].
+ AddEdge(loop->vertex(i), loop->vertex(i + sign));
+ }
+}
+
+void S2PolygonBuilder::AddPolygon(S2Polygon const* polygon) {
+ for (int i = 0; i < polygon->num_loops(); ++i) {
+ AddLoop(polygon->loop(i));
+ }
+}
+
+void S2PolygonBuilder::EraseEdge(S2Point const& v0, S2Point const& v1) {
+ // Note that there may be more than one copy of an edge if we are not XORing
+ // them, so a VertexSet is a multiset.
+
+ VertexSet* vset = &(*edges_)[v0];
+ DCHECK(vset->find(v1) != vset->end());
+ vset->erase(vset->find(v1));
+ if (vset->empty()) edges_->erase(v0);
+
+ if (options_.undirected_edges()) {
+ vset = &(*edges_)[v1];
+ DCHECK(vset->find(v0) != vset->end());
+ vset->erase(vset->find(v0));
+ if (vset->empty()) edges_->erase(v1);
+ }
+}
+
+void S2PolygonBuilder::set_debug_matrix(Matrix3x3_d const& m) {
+ debug_matrix_.reset(new Matrix3x3_d(m));
+}
+
+void S2PolygonBuilder::DumpVertex(S2Point const& v) const {
+ if (debug_matrix_.get()) {
+ // For orthonormal matrices, Inverse() == Transpose().
+ cout << S2LatLng(debug_matrix_->Transpose() * v);
+ } else {
+ cout << setprecision(17) << v << setprecision(6);
+ }
+}
+
+void S2PolygonBuilder::DumpEdges(S2Point const& v0) const {
+ DumpVertex(v0);
+ cout << ":\n";
+ EdgeSet::const_iterator candidates = edges_->find(v0);
+ if (candidates != edges_->end()) {
+ VertexSet const& vset = candidates->second;
+ for (VertexSet::const_iterator i = vset.begin(); i != vset.end(); ++i) {
+ cout << " ";
+ DumpVertex(*i);
+ cout << "\n";
+ }
+ }
+}
+
+void S2PolygonBuilder::Dump() const {
+ for (EdgeSet::const_iterator i = edges_->begin(); i != edges_->end(); ++i) {
+ DumpEdges(i->first);
+ }
+}
+
+void S2PolygonBuilder::EraseLoop(S2Point const* v, int n) {
+ for (int i = n - 1, j = 0; j < n; i = j++) {
+ EraseEdge(v[i], v[j]);
+ }
+}
+
+void S2PolygonBuilder::RejectLoop(S2Point const* v, int n,
+ EdgeList* unused_edges) {
+ for (int i = n - 1, j = 0; j < n; i = j++) {
+ unused_edges->push_back(make_pair(v[i], v[j]));
+ }
+}
+
+S2Loop* S2PolygonBuilder::AssembleLoop(S2Point const& v0, S2Point const& v1,
+ EdgeList* unused_edges) {
+ // We start at the given edge and assemble a loop taking left turns
+ // whenever possible. We stop the loop as soon as we encounter any
+ // vertex that we have seen before *except* for the first vertex (v0).
+ // This ensures that only CCW loops are constructed when possible.
+
+ vector<S2Point> path; // The path so far.
+ hash_map<S2Point, int> index; // Maps a vertex to its index in "path".
+ path.push_back(v0);
+ path.push_back(v1);
+ index[v1] = 1;
+ while (path.size() >= 2) {
+ // Note that "v0" and "v1" become invalid if "path" is modified.
+ S2Point const& v0 = path.end()[-2];
+ S2Point const& v1 = path.end()[-1];
+ S2Point v2;
+ bool v2_found = false;
+ EdgeSet::const_iterator candidates = edges_->find(v1);
+ if (candidates != edges_->end()) {
+ VertexSet const& vset = candidates->second;
+ for (VertexSet::const_iterator i = vset.begin(); i != vset.end(); ++i) {
+ // We prefer the leftmost outgoing edge, ignoring any reverse edges.
+ if (*i == v0) continue;
+ if (!v2_found || S2::OrderedCCW(v0, v2, *i, v1)) { v2 = *i; }
+ v2_found = true;
+ }
+ }
+ if (!v2_found) {
+ // We've hit a dead end. Remove this edge and backtrack.
+ unused_edges->push_back(make_pair(v0, v1));
+ EraseEdge(v0, v1);
+ index.erase(v1);
+ path.pop_back();
+ } else if (index.insert(make_pair(v2, path.size())).second) {
+ // This is the first time we've visited this vertex.
+ path.push_back(v2);
+ } else {
+ // We've completed a loop. Throw away any initial vertices that
+ // are not part of the loop.
+ path.erase(path.begin(), path.begin() + index[v2]);
+
+ // In the case of undirected edges, we may have assembled a clockwise
+ // loop while trying to assemble a CCW loop. To fix this, we assemble
+ // a new loop starting with an arbitrary edge in the reverse direction.
+ // This is guaranteed to assemble a loop that is interior to the previous
+ // one and will therefore eventually terminate.
+
+ S2Loop* loop = new S2Loop(path);
+ if (options_.validate() && !loop->IsValid()) {
+ // We've constructed a loop that crosses itself, which can only
+ // happen if there is bad input data. Throw away the whole loop.
+ RejectLoop(&path[0], path.size(), unused_edges);
+ EraseLoop(&path[0], path.size());
+ delete loop;
+ return NULL;
+ }
+
+ if (options_.undirected_edges() && !loop->IsNormalized()) {
+ scoped_ptr<S2Loop> deleter(loop); // XXX for debugging
+ return AssembleLoop(path[1], path[0], unused_edges);
+ }
+ return loop;
+ }
+ }
+ return NULL;
+}
+
+class S2PolygonBuilder::PointIndex {
+ // A PointIndex is a cheap spatial index to help us find mergeable
+ // vertices. Given a set of points, it can efficiently find all of the
+ // points within a given search radius of an arbitrary query location.
+ // It is essentially just a hash map from cell ids at a given fixed level to
+ // the set of points contained by that cell id.
+ //
+ // This class is not suitable for general use because it only supports
+ // fixed-radius queries and has various special-purpose operations to avoid
+ // the need for additional data structures.
+
+ private:
+ typedef multimap<S2CellId, S2Point> Map;
+ Map map_;
+
+ double vertex_radius_;
+ double edge_fraction_;
+ int level_;
+ vector<S2CellId> ids_; // Allocated here for efficiency.
+
+ public:
+ PointIndex(double vertex_radius, double edge_fraction)
+ : vertex_radius_(vertex_radius),
+ edge_fraction_(edge_fraction),
+ // We compute an S2CellId level such that the vertex neighbors at that
+ // level of any point A are a covering for spherical cap (i.e. "disc")
+ // of the given search radius centered at A. This requires that the
+ // minimum cell width at that level must be twice the search radius.
+ level_(min(S2::kMinWidth.GetMaxLevel(2 * vertex_radius),
+ S2CellId::kMaxLevel - 1)) {
+ // We insert a sentinel so that we don't need to test for map_.end().
+ map_.insert(make_pair(S2CellId::Sentinel(), S2Point()));
+ }
+
+ void Insert(S2Point const& p) {
+ S2CellId::FromPoint(p).AppendVertexNeighbors(level_, &ids_);
+ for (int i = ids_.size(); --i >= 0; ) {
+ map_.insert(make_pair(ids_[i], p));
+ }
+ ids_.clear();
+ }
+
+ void Erase(S2Point const& p) {
+ S2CellId::FromPoint(p).AppendVertexNeighbors(level_, &ids_);
+ for (int i = ids_.size(); --i >= 0; ) {
+ Map::iterator j = map_.lower_bound(ids_[i]);
+ for (; j->second != p; ++j) {
+ DCHECK_EQ(ids_[i], j->first);
+ }
+ map_.erase(j);
+ }
+ ids_.clear();
+ }
+
+ void QueryCap(S2Point const& axis, vector<S2Point>* output) {
+ // Return the set the points whose distance to "axis" is less than
+ // vertex_radius_.
+
+ output->clear();
+ S2CellId id = S2CellId::FromPoint(axis).parent(level_);
+ for (Map::const_iterator i = map_.lower_bound(id); i->first == id; ++i) {
+ S2Point const& p = i->second;
+ if (axis.Angle(p) < vertex_radius_) {
+ output->push_back(p);
+ }
+ }
+ }
+
+ bool FindNearbyPoint(S2Point const& v0, S2Point const& v1,
+ S2Point* nearby) {
+ // Return a point whose distance from the edge (v0,v1) is less than
+ // vertex_radius_, and which is not equal to v0 or v1. The current
+ // implementation returns the closest such point.
+ //
+ // Strategy: we compute a very cheap covering by approximating the edge as
+ // two spherical caps, one around each endpoint, and then computing a
+ // 4-cell covering of each one. We could improve the quality of the
+ // covering by using some intermediate points along the edge as well.
+
+ double length = v0.Angle(v1);
+ S2Point normal = S2::RobustCrossProd(v0, v1);
+ int level = min(level_, S2::kMinWidth.GetMaxLevel(length));
+ S2CellId::FromPoint(v0).AppendVertexNeighbors(level, &ids_);
+ S2CellId::FromPoint(v1).AppendVertexNeighbors(level, &ids_);
+
+ // Sort the cell ids so that we can skip duplicates in the loop below.
+ sort(ids_.begin(), ids_.end());
+
+ double best_dist = 2 * vertex_radius_;
+ for (int i = ids_.size(); --i >= 0; ) {
+ if (i > 0 && ids_[i-1] == ids_[i]) continue; // Skip duplicates.
+
+ S2CellId const& max_id = ids_[i].range_max();
+ for (Map::const_iterator j = map_.lower_bound(ids_[i].range_min());
+ j->first <= max_id; ++j) {
+ S2Point const& p = j->second;
+ if (p == v0 || p == v1) continue;
+ double dist = S2EdgeUtil::GetDistance(p, v0, v1, normal).radians();
+ if (dist < best_dist) {
+ best_dist = dist;
+ *nearby = p;
+ }
+ }
+ }
+ ids_.clear();
+ return (best_dist < edge_fraction_ * vertex_radius_);
+ }
+
+ private:
+ DISALLOW_EVIL_CONSTRUCTORS(PointIndex);
+};
+
+void S2PolygonBuilder::BuildMergeMap(PointIndex* index, MergeMap* merge_map) {
+ // The overall strategy is to start from each vertex and grow a maximal
+ // cluster of mergeable vertices. In graph theoretic terms, we find the
+ // connected components of the undirected graph whose edges connect pairs of
+ // vertices that are separated by at most vertex_merge_radius().
+ //
+ // We then choose a single representative vertex for each cluster, and
+ // update "merge_map" appropriately. We choose an arbitrary existing
+ // vertex rather than computing the centroid of all the vertices to avoid
+ // creating new vertex pairs that need to be merged. (We guarantee that all
+ // vertex pairs are separated by at least the merge radius in the output.)
+
+ // First, we build the set of all the distinct vertices in the input.
+ // We need to include the source and destination of every edge.
+ hash_set<S2Point> vertices;
+ for (EdgeSet::const_iterator i = edges_->begin(); i != edges_->end(); ++i) {
+ vertices.insert(i->first);
+ VertexSet const& vset = i->second;
+ for (VertexSet::const_iterator j = vset.begin(); j != vset.end(); ++j)
+ vertices.insert(*j);
+ }
+
+ // Build a spatial index containing all the distinct vertices.
+ for (hash_set<S2Point>::const_iterator i = vertices.begin();
+ i != vertices.end(); ++i) {
+ index->Insert(*i);
+ }
+
+ // Next, we loop through all the vertices and attempt to grow a maximial
+ // mergeable group starting from each vertex.
+ vector<S2Point> frontier, mergeable;
+ for (hash_set<S2Point>::const_iterator vstart = vertices.begin();
+ vstart != vertices.end(); ++vstart) {
+ // Skip any vertices that have already been merged with another vertex.
+ if (merge_map->find(*vstart) != merge_map->end()) continue;
+
+ // Grow a maximal mergeable component starting from "vstart", the
+ // canonical representative of the mergeable group.
+ frontier.push_back(*vstart);
+ while (!frontier.empty()) {
+ index->QueryCap(frontier.back(), &mergeable);
+ frontier.pop_back(); // Do this before entering the loop below.
+ for (int j = mergeable.size(); --j >= 0; ) {
+ S2Point const& v1 = mergeable[j];
+ if (v1 != *vstart) {
+ // Erase from the index any vertices that will be merged. This
+ // ensures that we won't try to merge the same vertex twice.
+ index->Erase(v1);
+ frontier.push_back(v1);
+ (*merge_map)[v1] = *vstart;
+ }
+ }
+ }
+ }
+}
+
+void S2PolygonBuilder::MoveVertices(MergeMap const& merge_map) {
+ if (merge_map.empty()) return;
+
+ // We need to copy the set of edges affected by the move, since
+ // edges_ could be reallocated when we start modifying it.
+ vector<pair<S2Point, S2Point> > edges;
+ for (EdgeSet::const_iterator i = edges_->begin(); i != edges_->end(); ++i) {
+ S2Point const& v0 = i->first;
+ VertexSet const& vset = i->second;
+ for (VertexSet::const_iterator j = vset.begin(); j != vset.end(); ++j) {
+ S2Point const& v1 = *j;
+ if (merge_map.find(v0) != merge_map.end() ||
+ merge_map.find(v1) != merge_map.end()) {
+ // We only need to modify one copy of each undirected edge.
+ if (!options_.undirected_edges() || v0 < v1) {
+ edges.push_back(make_pair(v0, v1));
+ }
+ }
+ }
+ }
+
+ // Now erase all the old edges, and add all the new edges. This will
+ // automatically take care of any XORing that needs to be done, because
+ // EraseEdge also erases the sibling of undirected edges.
+ for (size_t i = 0; i < edges.size(); ++i) {
+ S2Point v0 = edges[i].first;
+ S2Point v1 = edges[i].second;
+ EraseEdge(v0, v1);
+ MergeMap::const_iterator new0 = merge_map.find(v0);
+ if (new0 != merge_map.end()) v0 = new0->second;
+ MergeMap::const_iterator new1 = merge_map.find(v1);
+ if (new1 != merge_map.end()) v1 = new1->second;
+ AddEdge(v0, v1);
+ }
+}
+
+void S2PolygonBuilder::SpliceEdges(PointIndex* index) {
+ // We keep a stack of unprocessed edges. Initially all edges are
+ // pushed onto the stack.
+ vector<pair<S2Point, S2Point> > edges;
+ for (EdgeSet::const_iterator i = edges_->begin(); i != edges_->end(); ++i) {
+ S2Point const& v0 = i->first;
+ VertexSet const& vset = i->second;
+ for (VertexSet::const_iterator j = vset.begin(); j != vset.end(); ++j) {
+ S2Point const& v1 = *j;
+ // We only need to modify one copy of each undirected edge.
+ if (!options_.undirected_edges() || v0 < v1) {
+ edges.push_back(make_pair(v0, v1));
+ }
+ }
+ }
+
+ // For each edge, we check whether there are any nearby vertices that should
+ // be spliced into it. If there are, we choose one such vertex, split
+ // the edge into two pieces, and iterate on each piece.
+ while (!edges.empty()) {
+ S2Point v0 = edges.back().first;
+ S2Point v1 = edges.back().second;
+ edges.pop_back(); // Do this before pushing new edges.
+
+ // If we are xoring, edges may be erased before we get to them.
+ if (options_.xor_edges() && !HasEdge(v0, v1)) continue;
+
+ S2Point vmid;
+ if (!index->FindNearbyPoint(v0, v1, &vmid)) continue;
+
+ EraseEdge(v0, v1);
+ if (AddEdge(v0, vmid)) edges.push_back(make_pair(v0, vmid));
+ if (AddEdge(vmid, v1)) edges.push_back(make_pair(vmid, v1));
+ }
+}
+
+bool S2PolygonBuilder::AssembleLoops(vector<S2Loop*>* loops,
+ EdgeList* unused_edges) {
+ if (options_.vertex_merge_radius().radians() > 0) {
+ PointIndex index(options_.vertex_merge_radius().radians(),
+ options_.edge_splice_fraction());
+ MergeMap merge_map;
+ BuildMergeMap(&index, &merge_map);
+ MoveVertices(merge_map);
+ if (options_.edge_splice_fraction() > 0) {
+ SpliceEdges(&index);
+ }
+ }
+
+ EdgeList dummy_unused_edges;
+ if (unused_edges == NULL) unused_edges = &dummy_unused_edges;
+
+ // We repeatedly choose an edge and attempt to assemble a loop
+ // starting from that edge. (This is always possible unless the
+ // input includes extra edges that are not part of any loop.) To
+ // maintain a consistent scanning order over edges_ between
+ // different machine architectures (e.g. 'clovertown' vs. 'opteron'),
+ // we follow the order they were added to the builder.
+ unused_edges->clear();
+ for (size_t i = 0; i < starting_vertices_.size(); ) {
+ S2Point const& v0 = starting_vertices_[i];
+ EdgeSet::const_iterator candidates = edges_->find(v0);
+ if (candidates == edges_->end()) {
+ ++i;
+ continue;
+ }
+ // NOTE(user): If we have such two S2Points a, b that:
+ //
+ // a.x = b.x, a.y = b.y and
+ // -- a.z = b.z if CPU is Intel
+ // -- a.z <> b.z if CPU is AMD
+ //
+ // then the order of points picked up as v1 on the following line
+ // can be inconsistent between different machine architectures.
+ //
+ // As of b/3088321 and of cl/17847332, it's not clear if such
+ // input really exists in our input and probably it's O.K. not to
+ // address it in favor of the speed.
+ S2Point const& v1 = *(candidates->second.begin());
+ S2Loop* loop = AssembleLoop(v0, v1, unused_edges);
+ if (loop != NULL) {
+ loops->push_back(loop);
+ EraseLoop(&loop->vertex(0), loop->num_vertices());
+ }
+ }
+ return unused_edges->empty();
+}
+
+bool S2PolygonBuilder::AssemblePolygon(S2Polygon* polygon,
+ EdgeList* unused_edges) {
+ vector<S2Loop*> loops;
+ bool success = AssembleLoops(&loops, unused_edges);
+
+ // If edges are undirected, then all loops are already CCW. Otherwise we
+ // need to make sure the loops are normalized.
+ if (!options_.undirected_edges()) {
+ for (size_t i = 0; i < loops.size(); ++i) {
+ loops[i]->Normalize();
+ }
+ }
+ if (options_.validate() && !S2Polygon::IsValid(loops)) {
+ if (unused_edges != NULL) {
+ for (size_t i = 0; i < loops.size(); ++i) {
+ RejectLoop(&loops[i]->vertex(0), loops[i]->num_vertices(),
+ unused_edges);
+ }
+ }
+
+ for (size_t i = 0; i < loops.size(); ++i) {
+ delete loops[i];
+ }
+ loops.clear();
+ return false;
+ }
+ polygon->Init(&loops);
+ return success;
+}
diff --git a/src/third_party/s2/s2polygonbuilder.h b/src/third_party/s2/s2polygonbuilder.h
new file mode 100644
index 00000000000..93469129fb6
--- /dev/null
+++ b/src/third_party/s2/s2polygonbuilder.h
@@ -0,0 +1,318 @@
+// Copyright 2006 Google Inc. All Rights Reserved.
+
+#ifndef UTIL_GEOMETRY_S2POLYGONBUILDER_H__
+#define UTIL_GEOMETRY_S2POLYGONBUILDER_H__
+
+#include "base/definer.h"
+
+#if defined OS_MACOSX
+#include <ext/hash_map>
+#else
+#include <hash_map>
+#endif
+#ifndef OS_WINDOWS
+using __gnu_cxx::hash_map;
+#endif
+
+#include <set>
+using std::set;
+using std::multiset;
+
+#include <utility>
+using std::pair;
+using std::make_pair;
+
+#include <vector>
+using std::vector;
+
+#include <boost/scoped_ptr.hpp>
+using boost::scoped_ptr;
+#include "base/basictypes.h"
+#include "s2.h"
+#include "s1angle.h"
+#include "util/math/matrix3x3.h"
+
+class S2Loop;
+class S2Polygon;
+
+// This is a simple class for assembling polygons out of edges. It requires
+// that no two edges cross. It can handle both directed and undirected edges,
+// and optionally it can also remove duplicate edge pairs (consisting of two
+// identical edges or an edge and its reverse edge). This is useful for
+// computing seamless unions of polygons that have been cut into pieces.
+//
+// Here are some of the situations this class was designed to handle:
+//
+// 1. Computing the union of disjoint polygons that may share part of their
+// boundaries. For example, reassembling a lake that has been split into
+// two loops by a state boundary.
+//
+// 2. Constructing polygons from input data that does not follow S2
+// conventions, i.e. where loops may have repeated vertices, or distinct
+// loops may share edges, or shells and holes have opposite or unspecified
+// orientations.
+//
+// 3. Computing the symmetric difference of a set of polygons whose edges
+// intersect only at vertices. This can be used to implement a limited
+// form of polygon intersection or subtraction as well as unions.
+//
+// 4. As a tool for implementing other polygon operations by generating a
+// collection of directed edges and then assembling them into loops.
+class S2PolygonBuilderOptions {
+ public:
+ S2PolygonBuilderOptions() :
+ undirected_edges_(false), xor_edges_(true), validate_(false),
+ vertex_merge_radius_(S1Angle::Radians(0)),
+ edge_splice_fraction_(0.866) {}
+
+ // These are the options that should be used for assembling well-behaved
+ // input data into polygons. All edges should be directed such that
+ // "shells" and "holes" have opposite orientations (typically CCW shells and
+ // clockwise holes), unless it is known that shells and holes do not share
+ // any edges.
+ inline static S2PolygonBuilderOptions DIRECTED_XOR();
+
+ // These are the options that should be used for assembling polygons that do
+ // not follow the conventions above, e.g. where edge directions may vary
+ // within a single loop, or shells and holes are not oppositely oriented and
+ // may share edges.
+ inline static S2PolygonBuilderOptions UNDIRECTED_XOR();
+
+ // These are the options that should be used for assembling edges where the
+ // desired output is a collection of loops rather than a polygon, and edges
+ // may occur more than once. Edges are treated as undirected and are not
+ // XORed together.
+ inline static S2PolygonBuilderOptions UNDIRECTED_UNION();
+
+ // Default value: false.
+ //
+ // If "undirected_edges" is false, then the input is assumed to consist of
+ // edges that can be assembled into oriented loops without reversing any of
+ // the edges. Otherwise, "undirected_edges" should be set to true.
+ bool undirected_edges() const { return undirected_edges_; }
+ void set_undirected_edges(bool undirected_edges);
+
+ // Default value: true.
+ //
+ // If "xor_edges" is true, then any duplicate edge pairs are removed. This
+ // is useful for computing the union of a collection of polygons whose
+ // interiors are disjoint but whose boundaries may share some common edges
+ // (e.g. computing the union of South Africa, Lesotho, and Swaziland).
+ //
+ // Note that for directed edges, a "duplicate edge pair" consists of an edge
+ // and its corresponding reverse edge. This means that either (a) "shells"
+ // and "holes" must have opposite orientations, or (b) shells and holes do
+ // not share edges. Otherwise undirected_edges() should be specified.
+ //
+ // There are only two reasons to turn off xor_edges():
+ //
+ // (1) AssemblePolygon() will be called, and you want to assert that there
+ // are no duplicate edge pairs in the input.
+ //
+ // (2) AssembleLoops() will be called, and you want to keep abutting loops
+ // separate in the output rather than merging their regions together
+ // (e.g. assembling loops for Kansas City, KS and Kansas City, MO
+ // simultaneously).
+ bool xor_edges() const { return xor_edges_; }
+ void set_xor_edges(bool xor_edges);
+
+ // Default value: false.
+ //
+ // If true, IsValid() is called on all loops and polygons before
+ // constructing them. If any loop is invalid (e.g. self-intersecting), it
+ // is rejected and returned as a set of "unused edges". Any remaining valid
+ // loops are kept. If the entire polygon is invalid (e.g. two loops
+ // intersect), then all loops are rejected and returned as unused edges.
+ bool validate() const { return validate_; }
+ void set_validate(bool validate);
+
+ // Default value: 0.
+ //
+ // If set to a positive value, all vertex pairs that are separated by less
+ // than this distance will be merged together. Note that vertices can move
+ // arbitrarily far if there is a long chain of vertices separated by less
+ // than this distance.
+ //
+ // This method is useful for assembling polygons out of input data where
+ // vertices and/or edges may not be perfectly aligned.
+ S1Angle vertex_merge_radius() const { return vertex_merge_radius_; }
+ void set_vertex_merge_radius(S1Angle const& vertex_merge_radius);
+
+ // Default value: 0.866 (approximately sqrt(3)/2).
+ //
+ // The edge splice radius is automatically set to this fraction of the vertex
+ // merge radius. If the edge splice radius is positive, then all vertices
+ // that are closer than this distance to an edge are spliced into that edge.
+ // Note that edges can move arbitrarily far if there is a long chain of
+ // vertices in just the right places.
+ //
+ // You can turn off edge splicing by setting this value to zero. This will
+ // save some time if you don't need this feature, or you don't want vertices
+ // to be spliced into nearby edges for some reason.
+ //
+ // Note that the edge splice fraction must be less than sqrt(3)/2 in order to
+ // avoid infinite loops in the merge algorithm. The default value is very
+ // close to this maximum and therefore results in the maximum amount of edge
+ // splicing for a given vertex merge radius.
+ //
+ // The only reason to reduce the edge splice fraction is if you want to limit
+ // changes in edge direction due to splicing. The direction of an edge can
+ // change by up to asin(edge_splice_fraction) due to each splice. Thus by
+ // default, edges are allowed to change direction by up to 60 degrees per
+ // splice. However, note that most direction changes are much smaller than
+ // this: the worst case occurs only if the vertex being spliced is just
+ // outside the vertex merge radius from one of the edge endpoints.
+ double edge_splice_fraction() const { return edge_splice_fraction_; }
+ void set_edge_splice_fraction(double edge_splice_fraction);
+
+ private:
+ bool undirected_edges_;
+ bool xor_edges_;
+ bool validate_;
+ S1Angle vertex_merge_radius_;
+ double edge_splice_fraction_;
+};
+
+class S2PolygonBuilder {
+ public:
+ explicit S2PolygonBuilder(S2PolygonBuilderOptions const& options);
+ ~S2PolygonBuilder();
+
+ S2PolygonBuilderOptions const& options() const { return options_; }
+
+ // Add the given edge to the polygon builder. This method should be used
+ // for input data that may not follow S2 polygon conventions. Note that
+ // edges are not allowed to cross each other. Also note that as a
+ // convenience, edges where v0 == v1 are ignored.
+ //
+ // Returns true if an edge was added, and false if an edge was erased
+ // (due to XORing) or not added (if both endpoints were the same).
+ bool AddEdge(S2Point const& v0, S2Point const& v1);
+
+ // Add all edges in the given loop. If the sign() of the loop is negative
+ // (i.e. this loop represents a hole), the reverse edges are added instead.
+ // This implies that "shells" are CCW and "holes" are CW, as required for
+ // the directed edges convention described above.
+ //
+ // This method does not take ownership of the loop.
+ void AddLoop(S2Loop const* loop);
+
+ // Add all loops in the given polygon. Shells and holes are added with
+ // opposite orientations as described for AddLoop().
+ //
+ // This method does not take ownership of the polygon.
+ void AddPolygon(S2Polygon const* polygon);
+
+ // This type is used to return any edges that could not be assembled.
+ typedef vector<pair<S2Point, S2Point> > EdgeList;
+
+ // Assembles the given edges into as many non-crossing loops as possible.
+ // When there is a choice about how to assemble the loops, then CCW loops
+ // are preferred. Returns true if all edges were assembled. If
+ // "unused_edges" is not NULL, it is initialized to the set of edges that
+ // could not be assembled into loops.
+ //
+ // Note that if xor_edges() is false and duplicate edge pairs may be
+ // present, then undirected_edges() should be specified unless all loops can
+ // be assembled in a counter-clockwise direction. Otherwise this method may
+ // not be able to assemble all loops due to its preference for CCW loops.
+ //
+ // This method resets the S2PolygonBuilder state so that it can be reused.
+ bool AssembleLoops(vector<S2Loop*>* loops, EdgeList* unused_edges);
+
+ // Like AssembleLoops, but normalizes all the loops so that they enclose
+ // less than half the sphere, and then assembles the loops into a polygon.
+ //
+ // For this method to succeed, there should be no duplicate edges in the
+ // input. If this is not known to be true, then the "xor_edges" option
+ // should be set (which is true by default).
+ //
+ // Note that S2Polygons cannot represent arbitrary regions on the sphere,
+ // because of the limitation that no loop encloses more than half of the
+ // sphere. For example, an S2Polygon cannot represent a 100km wide band
+ // around the equator. In such cases, this method will return the
+ // *complement* of the expected region. So for example if all the world's
+ // coastlines were assembled, the output S2Polygon would represent the land
+ // area (irrespective of the input edge or loop orientations).
+ bool AssemblePolygon(S2Polygon* polygon, EdgeList* unused_edges);
+
+ // This function is only for debugging. If it is called, then points will
+ // be transformed by the inverse of the given matrix before being printed as
+ // lat-lng coordinates in degrees. "m" should be orthonormal.
+ void set_debug_matrix(Matrix3x3_d const& m);
+
+ protected:
+ // These functions print either a single vertex, all edges from a single
+ // vertex, or all edges in the builder.
+ void DumpVertex(S2Point const& v) const;
+ void DumpEdges(S2Point const& v0) const;
+ void Dump() const;
+
+ private:
+
+ // Return true if the given edge exists.
+ bool HasEdge(S2Point const& v0, S2Point const& v1);
+
+ // Erase an edge or an entire loop. The edge/loop must exist.
+ void EraseEdge(S2Point const& v0, S2Point const& v1);
+ void EraseLoop(S2Point const* v, int n);
+
+ // Assembles and returns a single loop starting with the given edge.
+ // If a loop cannot be assembled starting from this edge, returns NULL
+ // and updates "unused_edges".
+ S2Loop* AssembleLoop(S2Point const& v0, S2Point const& v1,
+ EdgeList* unused_edges);
+
+ // Adds all the given edges to "unused_edges".
+ void RejectLoop(S2Point const* v, int n, EdgeList* unused_edges);
+
+ // Builds a map indicating which vertices need to be moved from their
+ // current position to a new position, and also returns a spatial index
+ // containing all of the vertices that do not need to be moved.
+ class PointIndex;
+ typedef hash_map<S2Point, S2Point> MergeMap;
+ void BuildMergeMap(PointIndex* index, MergeMap* merge_map);
+
+ // Moves a set of vertices from old to new positions.
+ void MoveVertices(MergeMap const& merge_map);
+
+ // Modifies each edge by splicing in any vertices whose distance to the edge
+ // is at most (edge_splice_fraction() * vertex_merge_radius()).
+ void SpliceEdges(PointIndex* index);
+
+ S2PolygonBuilderOptions options_;
+
+ // This is only used for debugging purposes.
+ scoped_ptr<Matrix3x3_d> debug_matrix_;
+
+ // The current set of edges, grouped by origin. The set of destination
+ // vertices is a multiset so that the same edge can be present more than
+ // once. We could have also used a multiset<pair<S2Point, S2Point> >,
+ // but this representation is a bit more convenient.
+ typedef multiset<S2Point> VertexSet;
+ typedef hash_map<S2Point, VertexSet> EdgeSet;
+ scoped_ptr<EdgeSet> edges_;
+
+ // Unique collection of the starting (first) vertex of all edges,
+ // in the order they are added to edges_.
+ vector<S2Point> starting_vertices_;
+};
+
+inline S2PolygonBuilderOptions S2PolygonBuilderOptions::DIRECTED_XOR() {
+ return S2PolygonBuilderOptions();
+}
+
+inline S2PolygonBuilderOptions S2PolygonBuilderOptions::UNDIRECTED_XOR() {
+ S2PolygonBuilderOptions options;
+ options.set_undirected_edges(true);
+ return options;
+}
+
+inline S2PolygonBuilderOptions S2PolygonBuilderOptions::UNDIRECTED_UNION() {
+ S2PolygonBuilderOptions options;
+ options.set_undirected_edges(true);
+ options.set_xor_edges(false);
+ return options;
+}
+
+#endif // UTIL_GEOMETRY_S2POLYGONBUILDER_H__
diff --git a/src/third_party/s2/s2polygonbuilder_test.cc b/src/third_party/s2/s2polygonbuilder_test.cc
new file mode 100644
index 00000000000..15097686a60
--- /dev/null
+++ b/src/third_party/s2/s2polygonbuilder_test.cc
@@ -0,0 +1,555 @@
+// Copyright 2006 Google Inc. All Rights Reserved.
+
+#include "s2polygonbuilder.h"
+
+#include <set>
+using std::set;
+using std::multiset;
+
+
+#include "base/logging.h"
+#include "base/macros.h"
+#include "base/scoped_ptr.h"
+#include "strings/stringprintf.h"
+#include "testing/base/public/gunit.h"
+#include "s2cap.h"
+#include "s2polygon.h"
+#include "s2polyline.h"
+#include "s2testing.h"
+#include "util/math/matrix3x3-inl.h"
+
+namespace {
+
+struct Chain {
+ // A chain represents either a polyline or a loop, depending
+ // on whether "closed" is true.
+ char const* str;
+ bool closed;
+};
+
+struct TestCase {
+ int undirected_edges;
+ // +1 = undirected, -1 = directed, 0 = either one
+
+ int xor_edges;
+ // +1 = XOR, -1 = don't XOR, 0 = either one
+
+ bool can_split;
+ // Can edges be split for this test case?
+
+ double min_merge, max_merge;
+ // Min and max vertex merge radius for this test case in degrees.
+
+ double min_vertex_angle;
+ // Minimum angle in degrees between any two edges *after* vertex merging.
+
+ Chain chains_in[20];
+ // Each test case consists of a set of input loops and polylines.
+
+ char const* loops_out[10];
+ // The expected set of output loops, directed appropriately.
+
+ int num_unused_edges;
+ // The expected number of unused edges.
+};
+
+TestCase test_cases[] = {
+ // 0: No loops.
+ { 0, 0, true, 0.0, 10.0, 90.0,
+ { { NULL, false } },
+ { NULL }, 0 },
+
+ // 1: One loop with some extra edges.
+ { 0, 0, true, 0.0, 4.0, 15.0,
+ { { "0:0, 0:10, 10:5", true },
+ { "0:0, 5:5", false },
+ { "10:5, 20:7, 30:10, 40:15, 50:3, 60:-20", false } },
+ { "0:0, 0:10, 10:5" }, 6 },
+
+ // 2: One loop that has an edge removed by XORing, plus lots of extra edges.
+ { 0, 1, true, 0.0, 1.0, 45.0, // XOR
+ { { "0:0, 0:10, 5:15, 10:10, 10:0", true },
+ { "10:10, 12:12, 14:14, 16:16, 18:18", false },
+ { "14:14, 14:16, 14:18, 14:20", false },
+ { "14:18, 16:20, 18:22", false },
+ { "18:12, 16:12, 14:12, 12:12", false },
+ { "20:18, 18:16, 16:14, 14:12", false },
+ { "20:14, 18:14, 16:14", false },
+ { "5:15, 0:10", false } },
+ { NULL }, 21 },
+
+ // 3: Three loops (two shells and one hole) that combine into one.
+ { 0, 1, true, 0.0, 4.0, 90.0, // XOR
+ { { "0:0, 0:10, 5:10, 10:10, 10:5, 10:0", true },
+ { "0:10, 0:15, 5:15, 5:10", true },
+ { "10:10, 5:10, 5:5, 10:5", true } },
+ { "0:0, 0:10, 0:15, 5:15, 5:10, 5:5, 10:5, 10:0" }, 0 },
+
+ // 4: A big CCW triangle contained 3 CW triangular holes. The whole thing
+ // looks like a pyramid of nine small triangles (with two extra edges).
+ { -1, 0, true, 0.0, 0.9, 30.0, // Directed edges required for unique result.
+ { { "0:0, 0:2, 0:4, 0:6, 1:5, 2:4, 3:3, 2:2, 1:1", true },
+ { "0:2, 1:1, 1:3", true },
+ { "0:4, 1:3, 1:5", true },
+ { "1:3, 2:2, 2:4", true },
+ { "0:0, -1:1", false },
+ { "3:3, 5:5", false } },
+ { "0:0, 0:2, 1:1",
+ "0:2, 0:4, 1:3",
+ "0:4, 0:6, 1:5",
+ "1:1, 1:3, 2:2",
+ "1:3, 1:5, 2:4",
+ "2:2, 2:4, 3:3" }, 2 },
+
+ // 5: A square divided into four subsquares. In this case we want
+ // to extract the four loops rather than taking their union.
+ // There are four extra edges as well.
+ { 0, -1, true, 0.0, 4.0, 90.0, // Don't XOR
+ { { "0:0, 0:5, 5:5, 5:0", true },
+ { "0:5, 0:10, 5:10, 5:5", true },
+ { "5:0, 5:5, 10:5, 10:0", true },
+ { "5:5, 5:10, 10:10, 10:5", true },
+ { "0:10, 0:15, 0:20", false },
+ { "20:0, 15:0, 10:0", false } },
+ { "0:0, 0:5, 5:5, 5:0",
+ "0:5, 0:10, 5:10, 5:5",
+ "5:0, 5:5, 10:5, 10:0",
+ "5:5, 5:10, 10:10, 10:5" }, 4 },
+
+ // 6: Five nested loops that touch at a point.
+ { 0, 0, true, 0.0, 0.8, 5.0,
+ { { "0:0, 0:10, 10:10, 10:0", true },
+ { "0:0, 1:9, 9:9, 9:1", true },
+ { "0:0, 2:8, 8:8, 8:2", true },
+ { "0:0, 3:7, 7:7, 7:3", true },
+ { "0:0, 4:6, 6:6, 6:4", true } },
+ { "0:0, 0:10, 10:10, 10:0",
+ "0:0, 1:9, 9:9, 9:1",
+ "0:0, 2:8, 8:8, 8:2",
+ "0:0, 3:7, 7:7, 7:3",
+ "0:0, 4:6, 6:6, 6:4" }, 0 },
+
+ // 7: Four diamonds nested within each other touching at two points.
+ { -1, 0, true, 0.0, 4.0, 15.0, // Directed edges required for unique result.
+ { { "0:-20, -10:0, 0:20, 10:0", true },
+ { "0:10, -10:0, 0:-10, 10:0", true },
+ { "0:-10, -5:0, 0:10, 5:0", true },
+ { "0:5, -5:0, 0:-5, 5:0", true } },
+ { "0:-20, -10:0, 0:-10, 10:0",
+ "0:-10, -5:0, 0:-5, 5:0",
+ "0:5, -5:0, 0:10, 5:0",
+ "0:10, -10:0, 0:20, 10:0" }, 0 },
+
+ // 8: Seven diamonds nested within each other touching at one
+ // point between each nested pair.
+ { 0, 0, true, 0.0, 9.0, 4.0,
+ { { "0:-70, -70:0, 0:70, 70:0", true },
+ { "0:-70, -60:0, 0:60, 60:0", true },
+ { "0:-50, -60:0, 0:50, 50:0", true },
+ { "0:-40, -40:0, 0:50, 40:0", true },
+ { "0:-30, -30:0, 0:30, 40:0", true },
+ { "0:-20, -20:0, 0:30, 20:0", true },
+ { "0:-10, -20:0, 0:10, 10:0", true } },
+ { "0:-70, -70:0, 0:70, 70:0",
+ "0:-70, -60:0, 0:60, 60:0",
+ "0:-50, -60:0, 0:50, 50:0",
+ "0:-40, -40:0, 0:50, 40:0",
+ "0:-30, -30:0, 0:30, 40:0",
+ "0:-20, -20:0, 0:30, 20:0",
+ "0:-10, -20:0, 0:10, 10:0" }, 0 },
+
+ // 9: A triangle and a self-intersecting bowtie.
+ { 0, 0, false, 0.0, 4.0, 45.0,
+ { { "0:0, 0:10, 5:5", true },
+ { "0:20, 0:30, 10:20", false },
+ { "10:20, 10:30, 0:20", false } },
+ { "0:0, 0:10, 5:5" }, 4 },
+
+ // 10: Two triangles that intersect each other.
+ { 0, 0, false, 0.0, 2.0, 45.0,
+ { { "0:0, 0:12, 6:6", true },
+ { "3:6, 3:18, 9:12", true } },
+ { NULL }, 6 },
+
+ // 11: Four squares that combine to make a big square. The nominal edges of
+ // the square are at +/-8.5 degrees in latitude and longitude. All vertices
+ // except the center vertex are perturbed by up to 0.5 degrees in latitude
+ // and/or longitude. The various copies of the center vertex are misaligned
+ // by more than this (i.e. they are structured as a tree where adjacent
+ // vertices are separated by at most 1 degree in latitude and/or longitude)
+ // so that the clustering algorithm needs more than one iteration to find
+ // them all. Note that the merged position of this vertex doesn't matter
+ // because it is XORed away in the output. However, it's important that
+ // all edge pairs that need to be XORed are separated by no more than
+ // 'min_merge' below.
+
+ { 0, 1, true, 1.7, 5.8, 70.0, // XOR, min_merge > sqrt(2), max_merge < 6.
+ { { "-8:-8, -8:0", false },
+ { "-8:1, -8:8", false },
+ { "0:-9, 1:-1", false },
+ { "1:2, 1:9", false },
+ { "0:8, 2:2", false },
+ { "0:-2, 1:-8", false },
+ { "8:9, 9:1", false },
+ { "9:0, 8:-9", false },
+ { "9:-9, 0:-8", false },
+ { "1:-9, -9:-9", false },
+ { "8:0, 1:0", false },
+ { "-1:1, -8:0", false },
+ { "-8:1, -2:0", false },
+ { "0:1, 8:1", false },
+ { "-9:8, 1:8", false },
+ { "0:9, 8:8", false } },
+ { "8.5:8.5, 8.5:0.5, 8.5:-8.5, 0.5:-8.5, "
+ "-8.5:-8.5, -8.5:0.5, -8.5:8.5, 0.5:8.5" }, 0 },
+};
+
+S2Point Perturb(S2Point const& x, double max_perturb) {
+ // Perturb the point "x" randomly within a radius of max_perturb.
+
+ if (max_perturb == 0) return x;
+ return S2Testing::SamplePoint(
+ S2Cap::FromAxisAngle(x.Normalize(),
+ S1Angle::Radians(max_perturb)));
+}
+
+void GetVertices(char const* str, Matrix3x3_d const& m,
+ vector<S2Point>* vertices) {
+ // Parse the vertices and transform them into the given frame.
+
+ scoped_ptr<S2Polyline> line(S2Testing::MakePolyline(str));
+ for (int i = 0; i < line->num_vertices(); ++i) {
+ vertices->push_back((m * line->vertex(i)).Normalize());
+ }
+}
+
+void AddEdge(S2Point const& v0, S2Point const& v1,
+ int max_splits, double max_perturb, double min_edge,
+ S2PolygonBuilder* builder) {
+ // Adds an edge from "v0" to "v1", possibly splitting it recursively up to
+ // "max_splits" times, and perturbing each vertex up to a distance of
+ // "max_perturb". No edge shorter than "min_edge" will be created due to
+ // splitting.
+
+ double length = v0.Angle(v1);
+ if (max_splits > 0 && S2Testing::rnd.OneIn(2) && length >= 2 * min_edge) {
+ // Choose an interpolation parameter such that the length of each
+ // piece is at least min_edge.
+ double f = min_edge / length;
+ double t = f + (1 - 2 * f) * S2Testing::rnd.RandDouble();
+
+ // Now add the two sub-edges recursively.
+ S2Point vmid = S2EdgeUtil::Interpolate(t, v0, v1);
+ AddEdge(v0, vmid, max_splits - 1, max_perturb, min_edge, builder);
+ AddEdge(vmid, v1, max_splits - 1, max_perturb, min_edge, builder);
+ } else {
+ builder->AddEdge(Perturb(v0, max_perturb),
+ Perturb(v1, max_perturb));
+ }
+}
+
+void AddChain(Chain const& chain, Matrix3x3_d const& m,
+ int max_splits, double max_perturb, double min_edge,
+ S2PolygonBuilder* builder) {
+ // Transform the given edge chain to the frame (x,y,z), optionally split
+ // each edge into pieces and/or perturb the vertices up to the given
+ // radius, and add them to the builder.
+
+ vector<S2Point> vertices;
+ GetVertices(chain.str, m, &vertices);
+ if (chain.closed) vertices.push_back(vertices[0]);
+ for (int i = 1; i < vertices.size(); ++i) {
+ AddEdge(vertices[i-1], vertices[i], max_splits, max_perturb, min_edge,
+ builder);
+ }
+}
+
+bool FindLoop(S2Loop const* loop, vector<S2Loop*> const& candidates,
+ int max_splits, double max_error) {
+ // Return true if "loop" matches any of the given candidates. The type
+ // of matching depends on whether any edge splitting was done.
+
+ for (int i = 0; i < candidates.size(); ++i) {
+ if (max_splits == 0) {
+ // The two loops should match except for vertex perturbations.
+ if (loop->BoundaryApproxEquals(candidates[i], max_error)) return true;
+ } else {
+ // The two loops may have different numbers of vertices.
+ if (loop->BoundaryNear(candidates[i], max_error)) return true;
+ }
+ }
+ return false;
+}
+
+bool FindMissingLoops(vector<S2Loop*> const& actual,
+ vector<S2Loop*> const& expected,
+ Matrix3x3_d const& m,
+ int max_splits, double max_error,
+ char const* label) {
+ // Dump any loops from "actual" that are not present in "expected".
+ bool found = false;
+ for (int i = 0; i < actual.size(); ++i) {
+ if (FindLoop(actual[i], expected, max_splits, max_error))
+ continue;
+
+ fprintf(stderr, "%s loop %d:\n", label, i);
+ S2Loop* loop = actual[i];
+ for (int j = 0; j < loop->num_vertices(); ++j) {
+ S2LatLng ll(m.Transpose() * loop->vertex(j));
+ fprintf(stderr, " [%.6f, %.6f]\n",
+ ll.lat().degrees(), ll.lng().degrees());
+ }
+ found = true;
+ }
+ return found;
+}
+
+bool UnexpectedUnusedEdgeCount(int num_actual, int num_expected,
+ int max_splits) {
+ // Return true if the actual number of unused edges is inconsistent
+ // with the expected number of unused edges.
+ //
+ // If there are no splits, the number of unused edges should match exactly.
+ // Otherwise, both values should be zero or both should be non-zero.
+ if (max_splits == 0) {
+ return num_actual != num_expected;
+ } else {
+ return (num_actual > 0) != (num_expected > 0);
+ }
+}
+
+void DumpUnusedEdges(vector<pair<S2Point, S2Point> > const& unused_edges,
+ Matrix3x3_d const& m, int num_expected) {
+
+ // Print the unused edges, transformed back into their original
+ // latitude-longitude space in degrees.
+
+ if (unused_edges.size() == num_expected) return;
+ fprintf(stderr,
+ "Wrong number of unused edges (%d expected, %"PRIuS" actual):\n",
+ num_expected, unused_edges.size());
+ for (int i = 0; i < unused_edges.size(); ++i) {
+ S2LatLng p0(m.Transpose() * unused_edges[i].first);
+ S2LatLng p1(m.Transpose() * unused_edges[i].second);
+ fprintf(stderr, " [%.6f, %.6f] -> [%.6f, %.5f]\n",
+ p0.lat().degrees(), p0.lng().degrees(),
+ p1.lat().degrees(), p1.lng().degrees());
+ }
+}
+
+bool EvalTristate(int state) {
+ return (state > 0) ? true : (state < 0) ? false : S2Testing::rnd.OneIn(2);
+}
+
+double SmallFraction() {
+ // Returns a fraction between 0 and 1 where small values are more
+ // likely. In particular it often returns exactly 0, and often
+ // returns a fraction whose logarithm is uniformly distributed
+ // over some interval.
+
+ double r = S2Testing::rnd.RandDouble();
+ double u = S2Testing::rnd.RandDouble();
+ if (r < 0.3) return 0.0;
+ if (r < 0.6) return u;
+ return pow(1e-10, u);
+}
+
+extern void DeleteLoop(S2Loop* loop) {
+ delete loop;
+}
+extern void DeleteLoopsInVector(vector<S2Loop*>* loops) {
+ for_each(loops->begin(), loops->end(), DeleteLoop);
+ loops->clear();
+}
+
+bool TestBuilder(TestCase const* test) {
+ for (int iter = 0; iter < 250; ++iter) {
+ S2PolygonBuilderOptions options;
+ options.set_undirected_edges(EvalTristate(test->undirected_edges));
+ options.set_xor_edges(EvalTristate(test->xor_edges));
+
+ // Each test has a minimum and a maximum merge radius. The merge
+ // radius must be at least the given minimum to ensure that all expected
+ // merging will take place, and it must be at most the given maximum to
+ // ensure that no unexpected merging takes place.
+ //
+ // If the minimum and maximum values are different, we have some latitude
+ // to perturb the vertices as long as the merge radius is adjusted
+ // appropriately. If "p" is the maximum perturbation radius, "m" and
+ // "M" are the min/max merge radii, and "v" is the vertex merge radius
+ // for this test, we require that
+ //
+ // v >= m + 2*p and v <= M - 2*p .
+ //
+ // This implies that we can choose "v" in the range [m,M], and then choose
+ //
+ // p <= 0.5 * min(v - m, M - v) .
+ //
+ // Things get more complicated when we turn on edge splicing. Since the
+ // min/max merge radii apply to vertices, we need to adjust them to ensure
+ // that vertices are not accidentally spliced into nearby edges. Recall
+ // that the edge splice radius is defined as (e = v * f) where "f" is the
+ // edge splice fraction. Letting "a" be the minimum angle between two
+ // edges at a vertex, we need to ensure that
+ //
+ // e <= M * sin(a) - 2*p .
+ //
+ // The right-hand side is a lower bound on the distance from a vertex to a
+ // non-incident edge. (To simplify things, we ignore this case and fold
+ // it into the case below.)
+ //
+ // If we also split edges by introducing new vertices, things get even
+ // more complicated. First, the vertex merge radius "v" must be chosen
+ // such that
+ //
+ // e >= m + 2*p and v <= M * sin(a) - 2*p .
+ //
+ // Note that the right-hand inequality now applies to "v" rather than "e",
+ // since a new vertex can be introduced anywhere along a split edge.
+ //
+ // Finally, we need to ensure that the new edges created by splitting an
+ // edge are not too short, otherwise unbounded vertex merging and/or edge
+ // splicing can occur. Letting "g" be the minimum distance (gap) between
+ // vertices along a split edge, we require that
+ //
+ // 2 * sin(a/2) * (g - m) - 2*p >= v
+ //
+ // which is satisfied whenever
+ //
+ // g >= m + (v + 2*p) / sin(a)
+ //
+ // This inequality is derived by considering two edges of length "g"
+ // meeting at an angle "a", where both vertices are perturbed by distance
+ // "p" toward each other, and the shared vertex is perturbed by the
+ // minimum merge radius "m" along one of the two edges.
+
+ double min_merge = S1Angle::Degrees(test->min_merge).radians();
+ double max_merge = S1Angle::Degrees(test->max_merge).radians();
+ double min_sin = sin(S1Angle::Degrees(test->min_vertex_angle).radians());
+
+ // Half of the time we allow edges to be split into smaller pieces
+ // (up to 5 levels, i.e. up to 32 pieces).
+ int max_splits = max(0, S2Testing::rnd.Uniform(10) - 4);
+ if (!test->can_split) max_splits = 0;
+
+ // We choosen randomly among two different values for the edge fraction,
+ // just to exercise that code.
+ double edge_fraction = options.edge_splice_fraction();
+ double vertex_merge, max_perturb;
+ if (min_sin < edge_fraction && S2Testing::rnd.OneIn(2)) {
+ edge_fraction = min_sin;
+ }
+ if (max_splits == 0 && S2Testing::rnd.OneIn(2)) {
+ // Turn off edge splicing completely.
+ edge_fraction = 0;
+ vertex_merge = min_merge + SmallFraction() * (max_merge - min_merge);
+ max_perturb = 0.5 * min(vertex_merge - min_merge,
+ max_merge - vertex_merge);
+ } else {
+ // Splice edges. These bounds also assume that edges may be split
+ // (see detailed comments above).
+ //
+ // If edges are actually split, need to bump up the minimum merge radius
+ // to ensure that split edges in opposite directions are unified.
+ // Otherwise there will be tiny degenerate loops created.
+ if (max_splits > 0) min_merge += 1e-15;
+ min_merge /= edge_fraction;
+ max_merge *= min_sin;
+ DCHECK_GE(max_merge, min_merge);
+
+ vertex_merge = min_merge + SmallFraction() * (max_merge - min_merge);
+ max_perturb = 0.5 * min(edge_fraction * (vertex_merge - min_merge),
+ max_merge - vertex_merge);
+ }
+
+ // We can perturb by any amount up to the maximum, but choosing a
+ // lower maximum decreases the error bounds when checking the output.
+ max_perturb *= SmallFraction();
+
+ // This is the minimum length of a split edge to prevent unexpected
+ // merging and/or splicing (the "g" value mentioned above).
+ double min_edge = min_merge + (vertex_merge + 2 * max_perturb) / min_sin;
+
+ options.set_vertex_merge_radius(S1Angle::Radians(vertex_merge));
+ options.set_edge_splice_fraction(edge_fraction);
+ options.set_validate(true);
+ S2PolygonBuilder builder(options);
+
+ // On each iteration we randomly rotate the test case around the sphere.
+ // This causes the S2PolygonBuilder to choose different first edges when
+ // trying to build loops.
+ S2Point x, y, z;
+ S2Testing::GetRandomFrame(&x, &y, &z);
+ Matrix3x3_d m = Matrix3x3_d::FromCols(x, y, z);
+ builder.set_debug_matrix(m);
+
+ for (int i = 0; test->chains_in[i].str; ++i) {
+ AddChain(test->chains_in[i], m, max_splits, max_perturb, min_edge,
+ &builder);
+ }
+ vector<S2Loop*> loops;
+ S2PolygonBuilder::EdgeList unused_edges;
+ if (test->xor_edges < 0) {
+ builder.AssembleLoops(&loops, &unused_edges);
+ } else {
+ S2Polygon polygon;
+ builder.AssemblePolygon(&polygon, &unused_edges);
+ polygon.Release(&loops);
+ }
+ vector<S2Loop*> expected;
+ for (int i = 0; test->loops_out[i]; ++i) {
+ vector<S2Point> vertices;
+ GetVertices(test->loops_out[i], m, &vertices);
+ expected.push_back(new S2Loop(vertices));
+ }
+ // We assume that the vertex locations in the expected output polygon
+ // are separated from the corresponding vertex locations in the input
+ // edges by at most half of the minimum merge radius. Essentially
+ // this means that the expected output vertices should be near the
+ // centroid of the various input vertices.
+ //
+ // If any edges were split, we need to allow a bit more error due to
+ // inaccuracies in the interpolated positions. Similarly, if any vertices
+ // were perturbed, we need to bump up the error to allow for numerical
+ // errors in the actual perturbation.
+ double max_error = 0.5 * min_merge + max_perturb;
+ if (max_splits > 0 || max_perturb > 0) max_error += 1e-15;
+
+ // Note the single "|" below so that we print both sets of loops.
+ if (FindMissingLoops(loops, expected, m,
+ max_splits, max_error, "Actual") |
+ FindMissingLoops(expected, loops, m,
+ max_splits, max_error, "Expected") |
+ UnexpectedUnusedEdgeCount(unused_edges.size(), test->num_unused_edges,
+ max_splits)) {
+
+ // We found a problem. Print out the relevant parameters.
+ DumpUnusedEdges(unused_edges, m, test->num_unused_edges);
+ fprintf(stderr, "During iteration %d:\n undirected: %d\n xor: %d\n"
+ " max_splits: %d\n max_perturb: %.6g\n"
+ " vertex_merge_radius: %.6g\n edge_splice_fraction: %.6g\n"
+ " min_edge: %.6g\n max_error: %.6g\n\n",
+ iter, options.undirected_edges(), options.xor_edges(),
+ max_splits, S1Angle::Radians(max_perturb).degrees(),
+ options.vertex_merge_radius().degrees(),
+ options.edge_splice_fraction(),
+ S1Angle::Radians(min_edge).degrees(),
+ S1Angle::Radians(max_error).degrees());
+ DeleteLoopsInVector(&loops);
+ DeleteLoopsInVector(&expected);
+ return false;
+ }
+ DeleteLoopsInVector(&loops);
+ DeleteLoopsInVector(&expected);
+ }
+ return true;
+}
+
+TEST(S2PolygonBuilder, AssembleLoops) {
+ for (int i = 0; i < arraysize(test_cases); ++i) {
+ SCOPED_TRACE(StringPrintf("Test case %d", i));
+ EXPECT_TRUE(TestBuilder(&test_cases[i]));
+ }
+}
+
+} // namespace
diff --git a/src/third_party/s2/s2polyline.cc b/src/third_party/s2/s2polyline.cc
new file mode 100644
index 00000000000..85c63ddbbee
--- /dev/null
+++ b/src/third_party/s2/s2polyline.cc
@@ -0,0 +1,578 @@
+// Copyright 2005 Google Inc. All Rights Reserved.
+
+#include <set>
+using std::set;
+using std::multiset;
+
+#include <vector>
+using std::vector;
+
+#include "base/commandlineflags.h"
+#include "base/logging.h"
+#include "util/math/matrix3x3-inl.h"
+#include "s2polyline.h"
+
+#include "util/coding/coder.h"
+#include "s2cap.h"
+#include "s2cell.h"
+#include "s2latlng.h"
+#include "s2edgeutil.h"
+
+DECLARE_bool(s2debug); // defined in s2.cc
+
+static const unsigned char kCurrentEncodingVersionNumber = 1;
+
+S2Polyline::S2Polyline()
+ : num_vertices_(0),
+ vertices_(NULL) {
+}
+
+S2Polyline::S2Polyline(vector<S2Point> const& vertices)
+ : num_vertices_(0),
+ vertices_(NULL) {
+ Init(vertices);
+}
+
+S2Polyline::S2Polyline(vector<S2LatLng> const& vertices)
+ : num_vertices_(0),
+ vertices_(NULL) {
+ Init(vertices);
+}
+
+S2Polyline::~S2Polyline() {
+ delete[] vertices_;
+}
+
+void S2Polyline::Init(vector<S2Point> const& vertices) {
+ if (FLAGS_s2debug) {
+ CHECK(IsValid(vertices));
+ }
+
+ delete[] vertices_;
+ num_vertices_ = vertices.size();
+ vertices_ = new S2Point[num_vertices_];
+ // Check (num_vertices_ > 0) to avoid invalid reference to vertices[0].
+ if (num_vertices_ > 0) {
+ memcpy(vertices_, &vertices[0], num_vertices_ * sizeof(vertices_[0]));
+ }
+}
+
+void S2Polyline::Init(vector<S2LatLng> const& vertices) {
+ delete[] vertices_;
+ num_vertices_ = vertices.size();
+ vertices_ = new S2Point[num_vertices_];
+ for (int i = 0; i < num_vertices_; ++i) {
+ vertices_[i] = vertices[i].ToPoint();
+ }
+ if (FLAGS_s2debug) {
+ vector<S2Point> vertex_vector(vertices_, vertices_ + num_vertices_);
+ CHECK(IsValid(vertex_vector));
+ }
+}
+
+bool S2Polyline::IsValid(vector<S2Point> const& v) {
+ // All vertices must be unit length.
+ int n = v.size();
+ for (int i = 0; i < n; ++i) {
+ if (!S2::IsUnitLength(v[i])) {
+ S2LOG(INFO) << "Vertex " << i << " is not unit length";
+ return false;
+ }
+ }
+
+ // Adjacent vertices must not be identical or antipodal.
+ for (int i = 1; i < n; ++i) {
+ if (v[i-1] == v[i] || v[i-1] == -v[i]) {
+ S2LOG(INFO) << "Vertices " << (i - 1) << " and " << i
+ << " are identical or antipodal";
+ return false;
+ }
+ }
+ return true;
+}
+
+
+S2Polyline::S2Polyline(S2Polyline const* src)
+ : num_vertices_(src->num_vertices_),
+ vertices_(new S2Point[num_vertices_]) {
+ memcpy(vertices_, src->vertices_, num_vertices_ * sizeof(vertices_[0]));
+}
+
+S2Polyline* S2Polyline::Clone() const {
+ return new S2Polyline(this);
+}
+
+S1Angle S2Polyline::GetLength() const {
+ S1Angle length;
+ for (int i = 1; i < num_vertices(); ++i) {
+ length += S1Angle(vertex(i-1), vertex(i));
+ }
+ return length;
+}
+
+S2Point S2Polyline::GetCentroid() const {
+ S2Point centroid;
+ for (int i = 1; i < num_vertices(); ++i) {
+ // The centroid (multiplied by length) is a vector toward the midpoint
+ // of the edge, whose length is twice the sin of half the angle between
+ // the two vertices. Defining theta to be this angle, we have:
+ S2Point vsum = vertex(i-1) + vertex(i); // Length == 2*cos(theta)
+ S2Point vdiff = vertex(i-1) - vertex(i); // Length == 2*sin(theta)
+ double cos2 = vsum.Norm2();
+ double sin2 = vdiff.Norm2();
+ DCHECK_GT(cos2, 0); // Otherwise edge is undefined, and result is NaN.
+ centroid += sqrt(sin2 / cos2) * vsum; // Length == 2*sin(theta)
+ }
+ return centroid;
+}
+
+S2Point S2Polyline::GetSuffix(double fraction, int* next_vertex) const {
+ DCHECK_GT(num_vertices(), 0);
+ // We intentionally let the (fraction >= 1) case fall through, since
+ // we need to handle it in the loop below in any case because of
+ // possible roundoff errors.
+ if (fraction <= 0) {
+ *next_vertex = 1;
+ return vertex(0);
+ }
+ S1Angle length_sum;
+ for (int i = 1; i < num_vertices(); ++i) {
+ length_sum += S1Angle(vertex(i-1), vertex(i));
+ }
+ S1Angle target = fraction * length_sum;
+ for (int i = 1; i < num_vertices(); ++i) {
+ S1Angle length(vertex(i-1), vertex(i));
+ if (target < length) {
+ // This interpolates with respect to arc length rather than
+ // straight-line distance, and produces a unit-length result.
+ S2Point result = S2EdgeUtil::InterpolateAtDistance(target, vertex(i-1),
+ vertex(i), length);
+ // It is possible that (result == vertex(i)) due to rounding errors.
+ *next_vertex = (result == vertex(i)) ? (i + 1) : i;
+ return result;
+ }
+ target -= length;
+ }
+ *next_vertex = num_vertices();
+ return vertex(num_vertices() - 1);
+}
+
+S2Point S2Polyline::Interpolate(double fraction) const {
+ int next_vertex;
+ return GetSuffix(fraction, &next_vertex);
+}
+
+double S2Polyline::UnInterpolate(S2Point const& point, int next_vertex) const {
+ DCHECK_GT(num_vertices(), 0);
+ if (num_vertices() < 2) {
+ return 0;
+ }
+ S1Angle length_sum;
+ for (int i = 1; i < next_vertex; ++i) {
+ length_sum += S1Angle(vertex(i-1), vertex(i));
+ }
+ S1Angle length_to_point = length_sum + S1Angle(vertex(next_vertex-1), point);
+ for (int i = next_vertex; i < num_vertices(); ++i) {
+ length_sum += S1Angle(vertex(i-1), vertex(i));
+ }
+ // The ratio can be greater than 1.0 due to rounding errors or because the
+ // point is not exactly on the polyline.
+ return min(1.0, length_to_point / length_sum);
+}
+
+S2Point S2Polyline::Project(S2Point const& point, int* next_vertex) const {
+ DCHECK_GT(num_vertices(), 0);
+
+ if (num_vertices() == 1) {
+ // If there is only one vertex, it is always closest to any given point.
+ *next_vertex = 1;
+ return vertex(0);
+ }
+
+ // Initial value larger than any possible distance on the unit sphere.
+ S1Angle min_distance = S1Angle::Radians(10);
+ int min_index = -1;
+
+ // Find the line segment in the polyline that is closest to the point given.
+ for (int i = 1; i < num_vertices(); ++i) {
+ S1Angle distance_to_segment = S2EdgeUtil::GetDistance(point, vertex(i-1),
+ vertex(i));
+ if (distance_to_segment < min_distance) {
+ min_distance = distance_to_segment;
+ min_index = i;
+ }
+ }
+ DCHECK_NE(min_index, -1);
+
+ // Compute the point on the segment found that is closest to the point given.
+ S2Point closest_point = S2EdgeUtil::GetClosestPoint(
+ point, vertex(min_index-1), vertex(min_index));
+
+ *next_vertex = min_index + (closest_point == vertex(min_index) ? 1 : 0);
+ return closest_point;
+}
+
+bool S2Polyline::IsOnRight(S2Point const& point) const {
+ DCHECK_GE(num_vertices(), 2);
+
+ int next_vertex;
+ S2Point closest_point = Project(point, &next_vertex);
+
+ DCHECK_GE(next_vertex, 1);
+ DCHECK_LE(next_vertex, num_vertices());
+
+ // If the closest point C is an interior vertex of the polyline, let B and D
+ // be the previous and next vertices. The given point P is on the right of
+ // the polyline (locally) if B, P, D are ordered CCW around vertex C.
+ if (closest_point == vertex(next_vertex-1) && next_vertex > 1 &&
+ next_vertex < num_vertices()) {
+ if (point == vertex(next_vertex-1))
+ return false; // Polyline vertices are not on the RHS.
+ return S2::OrderedCCW(vertex(next_vertex-2), point, vertex(next_vertex),
+ vertex(next_vertex-1));
+ }
+
+ // Otherwise, the closest point C is incident to exactly one polyline edge.
+ // We test the point P against that edge.
+ if (next_vertex == num_vertices())
+ --next_vertex;
+
+ return S2::RobustCCW(point, vertex(next_vertex), vertex(next_vertex-1)) > 0;
+}
+
+bool S2Polyline::Intersects(S2Polyline const* line) const {
+ if (num_vertices() <= 0 || line->num_vertices() <= 0) {
+ return false;
+ }
+
+ if (!GetRectBound().Intersects(line->GetRectBound())) {
+ return false;
+ }
+
+ // TODO(user) look into S2EdgeIndex to make this near linear in performance.
+ for (int i = 1; i < num_vertices(); ++i) {
+ S2EdgeUtil::EdgeCrosser crosser(
+ &vertex(i - 1), &vertex(i), &line->vertex(0));
+ for (int j = 1; j < line->num_vertices(); ++j) {
+ if (crosser.RobustCrossing(&line->vertex(j)) >= 0) {
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+void S2Polyline::Reverse() {
+ reverse(vertices_, vertices_ + num_vertices_);
+}
+
+S2LatLngRect S2Polyline::GetRectBound() const {
+ S2EdgeUtil::RectBounder bounder;
+ for (int i = 0; i < num_vertices(); ++i) {
+ bounder.AddPoint(&vertex(i));
+ }
+ return bounder.GetBound();
+}
+
+S2Cap S2Polyline::GetCapBound() const {
+ return GetRectBound().GetCapBound();
+}
+
+bool S2Polyline::MayIntersect(S2Cell const& cell) const {
+ if (num_vertices() == 0) return false;
+
+ // We only need to check whether the cell contains vertex 0 for correctness,
+ // but these tests are cheap compared to edge crossings so we might as well
+ // check all the vertices.
+ for (int i = 0; i < num_vertices(); ++i) {
+ if (cell.Contains(vertex(i))) return true;
+ }
+ S2Point cell_vertices[4];
+ for (int i = 0; i < 4; ++i) {
+ cell_vertices[i] = cell.GetVertex(i);
+ }
+ for (int j = 0; j < 4; ++j) {
+ S2EdgeUtil::EdgeCrosser crosser(&cell_vertices[j], &cell_vertices[(j+1)&3],
+ &vertex(0));
+ for (int i = 1; i < num_vertices(); ++i) {
+ if (crosser.RobustCrossing(&vertex(i)) >= 0) {
+ // There is a proper crossing, or two vertices were the same.
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+void S2Polyline::Encode(Encoder* const encoder) const {
+ encoder->Ensure(num_vertices_ * sizeof(*vertices_) + 10); // sufficient
+
+ encoder->put8(kCurrentEncodingVersionNumber);
+ encoder->put32(num_vertices_);
+ encoder->putn(vertices_, sizeof(*vertices_) * num_vertices_);
+
+ DCHECK_GE(encoder->avail(), 0);
+}
+
+bool S2Polyline::Decode(Decoder* const decoder) {
+ unsigned char version = decoder->get8();
+ if (version > kCurrentEncodingVersionNumber) return false;
+
+ num_vertices_ = decoder->get32();
+ delete[] vertices_;
+ vertices_ = new S2Point[num_vertices_];
+ decoder->getn(vertices_, num_vertices_ * sizeof(*vertices_));
+
+ if (FLAGS_s2debug) {
+ vector<S2Point> vertex_vector(vertices_, vertices_ + num_vertices_);
+ CHECK(IsValid(vertex_vector));
+ }
+
+ return decoder->avail() >= 0;
+}
+
+namespace {
+
+// Given a polyline, a tolerance distance, and a start index, this function
+// returns the maximal end index such that the line segment between these two
+// vertices passes within "tolerance" of all interior vertices, in order.
+int FindEndVertex(S2Polyline const& polyline,
+ S1Angle const& tolerance, int index) {
+ DCHECK_GE(tolerance.radians(), 0);
+ DCHECK_LT((index + 1), polyline.num_vertices());
+
+ // The basic idea is to keep track of the "pie wedge" of angles from the
+ // starting vertex such that a ray from the starting vertex at that angle
+ // will pass through the discs of radius "tolerance" centered around all
+ // vertices processed so far.
+
+ // First we define a "coordinate frame" for the tangent and normal spaces
+ // at the starting vertex. Essentially this means picking three
+ // orthonormal vectors X,Y,Z such that X and Y span the tangent plane at
+ // the starting vertex, and Z is "up". We use the coordinate frame to
+ // define a mapping from 3D direction vectors to a one-dimensional "ray
+ // angle" in the range (-Pi, Pi]. The angle of a direction vector is
+ // computed by transforming it into the X,Y,Z basis, and then calculating
+ // atan2(y,x). This mapping allows us to represent a wedge of angles as a
+ // 1D interval. Since the interval wraps around, we represent it as an
+ // S1Interval, i.e. an interval on the unit circle.
+ Matrix3x3_d frame;
+ S2Point const& origin = polyline.vertex(index);
+ S2::GetFrame(origin, &frame);
+
+ // As we go along, we keep track of the current wedge of angles and the
+ // distance to the last vertex (which must be non-decreasing).
+ S1Interval current_wedge = S1Interval::Full();
+ double last_distance = 0;
+
+ for (++index; index < polyline.num_vertices(); ++index) {
+ S2Point const& candidate = polyline.vertex(index);
+ double distance = origin.Angle(candidate);
+
+ // We don't allow simplification to create edges longer than 90 degrees,
+ // to avoid numeric instability as lengths approach 180 degrees. (We do
+ // need to allow for original edges longer than 90 degrees, though.)
+ if (distance > M_PI/2 && last_distance > 0) break;
+
+ // Vertices must be in increasing order along the ray, except for the
+ // initial disc around the origin.
+ if (distance < last_distance && last_distance > tolerance.radians()) break;
+ last_distance = distance;
+
+ // Points that are within the tolerance distance of the origin do not
+ // constrain the ray direction, so we can ignore them.
+ if (distance <= tolerance.radians()) continue;
+
+ // If the current wedge of angles does not contain the angle to this
+ // vertex, then stop right now. Note that the wedge of possible ray
+ // angles is not necessarily empty yet, but we can't continue unless we
+ // are willing to backtrack to the last vertex that was contained within
+ // the wedge (since we don't create new vertices). This would be more
+ // complicated and also make the worst-case running time more than linear.
+ S2Point direction = S2::ToFrame(frame, candidate);
+ double center = atan2(direction.y(), direction.x());
+ if (!current_wedge.Contains(center)) break;
+
+ // To determine how this vertex constrains the possible ray angles,
+ // consider the triangle ABC where A is the origin, B is the candidate
+ // vertex, and C is one of the two tangent points between A and the
+ // spherical cap of radius "tolerance" centered at B. Then from the
+ // spherical law of sines, sin(a)/sin(A) = sin(c)/sin(C), where "a" and
+ // "c" are the lengths of the edges opposite A and C. In our case C is a
+ // 90 degree angle, therefore A = asin(sin(a) / sin(c)). Angle A is the
+ // half-angle of the allowable wedge.
+
+ double half_angle = asin(sin(tolerance.radians()) / sin(distance));
+ S1Interval target = S1Interval::FromPoint(center).Expanded(half_angle);
+ current_wedge = current_wedge.Intersection(target);
+ DCHECK(!current_wedge.is_empty());
+ }
+ // We break out of the loop when we reach a vertex index that can't be
+ // included in the line segment, so back up by one vertex.
+ return index - 1;
+}
+}
+
+void S2Polyline::SubsampleVertices(S1Angle const& tolerance,
+ vector<int>* indices) const {
+ indices->clear();
+ if (num_vertices() == 0) return;
+
+ indices->push_back(0);
+ S1Angle clamped_tolerance = max(tolerance, S1Angle::Radians(0));
+ for (int index = 0; index + 1 < num_vertices(); ) {
+ int next_index = FindEndVertex(*this, clamped_tolerance, index);
+ // Don't create duplicate adjacent vertices.
+ if (vertex(next_index) != vertex(index)) {
+ indices->push_back(next_index);
+ }
+ index = next_index;
+ }
+}
+
+bool S2Polyline::ApproxEquals(S2Polyline const* b, double max_error) const {
+ if (num_vertices() != b->num_vertices()) return false;
+ for (int offset = 0; offset < num_vertices(); ++offset) {
+ if (!S2::ApproxEquals(vertex(offset), b->vertex(offset), max_error)) {
+ return false;
+ }
+ }
+ return true;
+}
+
+namespace {
+// Return the first i > "index" such that the ith vertex of "pline" is not at
+// the same point as the "index"th vertex. Returns pline.num_vertices() if
+// there is no such value of i.
+inline int NextDistinctVertex(S2Polyline const& pline, int index) {
+ S2Point const& initial = pline.vertex(index);
+ do {
+ ++index;
+ } while (index < pline.num_vertices() && pline.vertex(index) == initial);
+ return index;
+}
+
+// This struct represents a search state in the NearlyCoversPolyline algorithm
+// below. See the description of the algorithm for details.
+struct SearchState {
+ inline SearchState(int i_val, int j_val, bool i_in_progress_val)
+ : i(i_val), j(j_val), i_in_progress(i_in_progress_val) {}
+
+ int i;
+ int j;
+ bool i_in_progress;
+};
+} // namespace
+
+namespace std {
+template<>
+struct less<SearchState> {
+ // This operator is needed for storing SearchStates in a set. The ordering
+ // chosen has no special meaning.
+ inline bool operator()(SearchState const& lhs, SearchState const& rhs) const {
+ if (lhs.i < rhs.i) return true;
+ if (lhs.i > rhs.i) return false;
+ if (lhs.j < rhs.j) return true;
+ if (lhs.j > rhs.j) return false;
+ return !lhs.i_in_progress && rhs.i_in_progress;
+ }
+};
+} // namespace std
+
+bool S2Polyline::NearlyCoversPolyline(S2Polyline const& covered,
+ S1Angle const& max_error) const {
+ // NOTE: This algorithm is described assuming that adjacent vertices in a
+ // polyline are never at the same point. That is, the ith and i+1th vertices
+ // of a polyline are never at the same point in space. The implementation
+ // does not make this assumption.
+
+ // DEFINITIONS:
+ // - edge "i" of a polyline is the edge from the ith to i+1th vertex.
+ // - covered_j is a polyline consisting of edges 0 through j of "covered."
+ // - this_i is a polyline consisting of edges 0 through i of this polyline.
+ //
+ // A search state is represented as an (int, int, bool) tuple, (i, j,
+ // i_in_progress). Using the "drive a car" analogy from the header comment, a
+ // search state signifies that you can drive one car along "covered" from its
+ // first vertex through a point on its jth edge, and another car along this
+ // polyline from some point on or before its ith edge to a to a point on its
+ // ith edge, such that no car ever goes backward, and the cars are always
+ // within "max_error" of each other. If i_in_progress is true, it means that
+ // you can definitely drive along "covered" through the jth vertex (beginning
+ // of the jth edge). Otherwise, you can definitely drive along "covered"
+ // through the point on the jth edge of "covered" closest to the ith vertex of
+ // this polyline.
+ //
+ // The algorithm begins by finding all edges of this polyline that are within
+ // "max_error" of the first vertex of "covered," and adding search states
+ // representing all of these possible starting states to the stack of
+ // "pending" states.
+ //
+ // The algorithm proceeds by popping the next pending state,
+ // (i,j,i_in_progress), off of the stack. First it checks to see if that
+ // state represents finding a valid covering of "covered" and returns true if
+ // so. Next, if the state represents reaching the end of this polyline
+ // without finding a successful covering, the algorithm moves on to the next
+ // state in the stack. Otherwise, if state (i+1,j,false) is valid, it is
+ // added to the stack of pending states. Same for state (i,j+1,true).
+ //
+ // We need the stack because when "i" and "j" can both be incremented,
+ // sometimes only one choice leads to a solution. We use a set to keep track
+ // of visited states to avoid duplicating work. With the set, the worst-case
+ // number of states examined is O(n+m) where n = this->num_vertices() and m =
+ // covered.num_vertices(). Without it, the amount of work could be as high as
+ // O((n*m)^2). Using set, the running time is O((n*m) log (n*m)).
+ //
+ // TODO(user): Benchmark this, and see if the set is worth it.
+ vector<SearchState> pending;
+ set<SearchState> done;
+
+ // Find all possible starting states.
+ for (int i = 0, next_i = NextDistinctVertex(*this, 0);
+ next_i < this->num_vertices();
+ i = next_i, next_i = NextDistinctVertex(*this, next_i)) {
+ S2Point closest_point = S2EdgeUtil::GetClosestPoint(
+ covered.vertex(0), this->vertex(i), this->vertex(next_i));
+ if (closest_point != this->vertex(next_i) &&
+ S1Angle(closest_point, covered.vertex(0)) <= max_error) {
+ pending.push_back(SearchState(i, 0, true));
+ }
+ }
+
+ while (!pending.empty()) {
+ SearchState const state = pending.back();
+ pending.pop_back();
+ if (!done.insert(state).second) continue;
+
+ int const next_i = NextDistinctVertex(*this, state.i);
+ int const next_j = NextDistinctVertex(covered, state.j);
+ if (next_j == covered.num_vertices()) {
+ return true;
+ } else if (next_i == this->num_vertices()) {
+ continue;
+ }
+
+ S2Point i_begin, j_begin;
+ if (state.i_in_progress) {
+ j_begin = covered.vertex(state.j);
+ i_begin = S2EdgeUtil::GetClosestPoint(
+ j_begin, this->vertex(state.i), this->vertex(next_i));
+ } else {
+ i_begin = this->vertex(state.i);
+ j_begin = S2EdgeUtil::GetClosestPoint(
+ i_begin, covered.vertex(state.j), covered.vertex(next_j));
+ }
+
+ if (S2EdgeUtil::IsEdgeBNearEdgeA(j_begin, covered.vertex(next_j),
+ i_begin, this->vertex(next_i),
+ max_error)) {
+ pending.push_back(SearchState(next_i, state.j, false));
+ }
+ if (S2EdgeUtil::IsEdgeBNearEdgeA(i_begin, this->vertex(next_i),
+ j_begin, covered.vertex(next_j),
+ max_error)) {
+ pending.push_back(SearchState(state.i, next_j, true));
+ }
+ }
+ return false;
+}
diff --git a/src/third_party/s2/s2polyline.h b/src/third_party/s2/s2polyline.h
new file mode 100644
index 00000000000..26f476b29a4
--- /dev/null
+++ b/src/third_party/s2/s2polyline.h
@@ -0,0 +1,194 @@
+// Copyright 2005 Google Inc. All Rights Reserved.
+
+#ifndef UTIL_GEOMETRY_S2POLYLINE_H__
+#define UTIL_GEOMETRY_S2POLYLINE_H__
+
+#include <vector>
+using std::vector;
+
+#include "base/logging.h"
+#include "base/macros.h"
+#include "s2.h"
+#include "s2region.h"
+#include "s2latlngrect.h"
+
+class S1Angle;
+
+// An S2Polyline represents a sequence of zero or more vertices connected by
+// straight edges (geodesics). Edges of length 0 and 180 degrees are not
+// allowed, i.e. adjacent vertices should not be identical or antipodal.
+class S2Polyline : public S2Region {
+ public:
+ // Creates an empty S2Polyline that should be initialized by calling Init()
+ // or Decode().
+ S2Polyline();
+
+ // Convenience constructors that call Init() with the given vertices.
+ S2Polyline(vector<S2Point> const& vertices);
+ S2Polyline(vector<S2LatLng> const& vertices);
+
+ // Initialize a polyline that connects the given vertices. Empty polylines are
+ // allowed. Adjacent vertices should not be identical or antipodal. All
+ // vertices should be unit length.
+ void Init(vector<S2Point> const& vertices);
+
+ // Convenience initialization function that accepts latitude-longitude
+ // coordinates rather than S2Points.
+ void Init(vector<S2LatLng> const& vertices);
+
+ ~S2Polyline();
+
+ // Return true if the given vertices form a valid polyline.
+ static bool IsValid(vector<S2Point> const& vertices);
+
+ int num_vertices() const { return num_vertices_; }
+ S2Point const& vertex(int k) const {
+ DCHECK_GE(k, 0);
+ DCHECK_LT(k, num_vertices_);
+ return vertices_[k];
+ }
+
+ // Return the length of the polyline.
+ S1Angle GetLength() const;
+
+ // Return the true centroid of the polyline multiplied by the length of the
+ // polyline (see s2.h for details on centroids). The result is not unit
+ // length, so you may want to normalize it.
+ //
+ // Prescaling by the polyline length makes it easy to compute the centroid
+ // of several polylines (by simply adding up their centroids).
+ S2Point GetCentroid() const;
+
+ // Return the point whose distance from vertex 0 along the polyline is the
+ // given fraction of the polyline's total length. Fractions less than zero
+ // or greater than one are clamped. The return value is unit length. This
+ // cost of this function is currently linear in the number of vertices.
+ // The polyline must not be empty.
+ S2Point Interpolate(double fraction) const;
+
+ // Like Interpolate(), but also return the index of the next polyline
+ // vertex after the interpolated point P. This allows the caller to easily
+ // construct a given suffix of the polyline by concatenating P with the
+ // polyline vertices starting at "next_vertex". Note that P is guaranteed
+ // to be different than vertex(*next_vertex), so this will never result in
+ // a duplicate vertex.
+ //
+ // The polyline must not be empty. Note that if "fraction" >= 1.0, then
+ // "next_vertex" will be set to num_vertices() (indicating that no vertices
+ // from the polyline need to be appended). The value of "next_vertex" is
+ // always between 1 and num_vertices().
+ //
+ // This method can also be used to construct a prefix of the polyline, by
+ // taking the polyline vertices up to "next_vertex - 1" and appending the
+ // returned point P if it is different from the last vertex (since in this
+ // case there is no guarantee of distinctness).
+ S2Point GetSuffix(double fraction, int* next_vertex) const;
+
+ // The inverse operation of GetSuffix/Interpolate. Given a point on the
+ // polyline, returns the ratio of the distance to the point from the
+ // beginning of the polyline over the length of the polyline. The return
+ // value is always betwen 0 and 1 inclusive. See GetSuffix() for the
+ // meaning of "next_vertex".
+ //
+ // The polyline should not be empty. If it has fewer than 2 vertices, the
+ // return value is zero.
+ double UnInterpolate(S2Point const& point, int next_vertex) const;
+
+ // Given a point, returns a point on the polyline that is closest to the given
+ // point. See GetSuffix() for the meaning of "next_vertex", which is chosen
+ // here w.r.t. the projected point as opposed to the interpolated point in
+ // GetSuffix().
+ //
+ // The polyline must be non-empty.
+ S2Point Project(S2Point const& point, int* next_vertex) const;
+
+ // Returns true if the point given is on the right hand side of the polyline,
+ // using a naive definition of "right-hand-sideness" where the point is on
+ // the RHS of the polyline iff the point is on the RHS of the line segment in
+ // the polyline which it is closest to.
+ //
+ // The polyline must have at least 2 vertices.
+ bool IsOnRight(S2Point const& point) const;
+
+ // Return true if this polyline intersects the given polyline. If the
+ // polylines share a vertex they are considered to be intersecting. When a
+ // polyline endpoint is the only intersection with the other polyline, the
+ // function may return true or false arbitrarily.
+ //
+ // The running time is quadratic in the number of vertices.
+ bool Intersects(S2Polyline const* line) const;
+
+ // Reverse the order of the polyline vertices.
+ void Reverse();
+
+ // Return a subsequence of vertex indices such that the polyline connecting
+ // these vertices is never further than "tolerance" from the original
+ // polyline. The first and last vertices are always preserved.
+ //
+ // Some useful properties of the algorithm:
+ //
+ // - It runs in linear time.
+ //
+ // - The output is always a valid polyline. In particular, adjacent
+ // output vertices are never identical or antipodal.
+ //
+ // - The method is not optimal, but it tends to produce 2-3% fewer
+ // vertices than the Douglas-Peucker algorithm with the same tolerance.
+ //
+ // - The output is *parametrically* equivalent to the original polyline to
+ // within the given tolerance. For example, if a polyline backtracks on
+ // itself and then proceeds onwards, the backtracking will be preserved
+ // (to within the given tolerance). This is different than the
+ // Douglas-Peucker algorithm used in maps/util/geoutil-inl.h, which only
+ // guarantees geometric equivalence.
+ void SubsampleVertices(S1Angle const& tolerance, vector<int>* indices) const;
+
+ // Return true if two polylines have the same number of vertices, and
+ // corresponding vertex pairs are separated by no more than "max_error".
+ // (For testing purposes.)
+ bool ApproxEquals(S2Polyline const* b, double max_error = 1e-15) const;
+
+ // Return true if "covered" is within "max_error" of a contiguous subpath of
+ // this polyline over its entire length. Specifically, this method returns
+ // true if this polyline has parameterization a:[0,1] -> S^2, "covered" has
+ // parameterization b:[0,1] -> S^2, and there is a non-decreasing function
+ // f:[0,1] -> [0,1] such that distance(a(f(t)), b(t)) <= max_error for all t.
+ //
+ // You can think of this as testing whether it is possible to drive a car
+ // along "covered" and a car along some subpath of this polyline such that no
+ // car ever goes backward, and the cars are always within "max_error" of each
+ // other.
+ bool NearlyCoversPolyline(S2Polyline const& covered,
+ S1Angle const& max_error) const;
+
+ ////////////////////////////////////////////////////////////////////////
+ // S2Region interface (see s2region.h for details):
+
+ virtual S2Polyline* Clone() const;
+ virtual S2Cap GetCapBound() const;
+ virtual S2LatLngRect GetRectBound() const;
+ virtual bool Contains(S2Cell const& cell) const { return false; }
+ virtual bool MayIntersect(S2Cell const& cell) const;
+
+ // Polylines do not have a Contains(S2Point) method, because "containment"
+ // is not numerically well-defined except at the polyline vertices.
+ virtual bool VirtualContainsPoint(S2Point const& p) const { return false; }
+
+ virtual void Encode(Encoder* const encoder) const;
+ virtual bool Decode(Decoder* const decoder);
+
+ private:
+ // Internal constructor used only by Clone() that makes a deep copy of
+ // its argument.
+ S2Polyline(S2Polyline const* src);
+
+ // We store the vertices in an array rather than a vector because we don't
+ // need any STL methods, and computing the number of vertices using size()
+ // would be relatively expensive (due to division by sizeof(S2Point) == 24).
+ int num_vertices_;
+ S2Point* vertices_;
+
+ DISALLOW_EVIL_CONSTRUCTORS(S2Polyline);
+};
+
+#endif // UTIL_GEOMETRY_S2POLYLINE_H__
diff --git a/src/third_party/s2/s2polyline_test.cc b/src/third_party/s2/s2polyline_test.cc
new file mode 100644
index 00000000000..3856a5eca11
--- /dev/null
+++ b/src/third_party/s2/s2polyline_test.cc
@@ -0,0 +1,462 @@
+// Copyright 2005 Google Inc. All Rights Reserved.
+
+#include "s2polyline.h"
+
+#include <vector>
+using std::vector;
+
+
+#include "base/commandlineflags.h"
+#include "base/scoped_ptr.h"
+#include "base/stringprintf.h"
+#include "testing/base/public/gunit.h"
+#include "util/coding/coder.h"
+#include "s2cell.h"
+#include "s2latlng.h"
+#include "s2testing.h"
+
+DECLARE_bool(s2debug);
+
+namespace {
+
+S2Polyline* MakePolyline(string const& str) {
+ scoped_ptr<S2Polyline> polyline(S2Testing::MakePolyline(str));
+ Encoder encoder;
+ polyline->Encode(&encoder);
+ Decoder decoder(encoder.base(), encoder.length());
+ scoped_ptr<S2Polyline> decoded_polyline(new S2Polyline);
+ decoded_polyline->Decode(&decoder);
+ return decoded_polyline.release();
+}
+
+TEST(S2Polyline, Basic) {
+ vector<S2Point> vertices;
+ S2Polyline empty(vertices);
+ EXPECT_EQ(S2LatLngRect::Empty(), empty.GetRectBound());
+ empty.Reverse();
+ EXPECT_EQ(0, empty.num_vertices());
+
+ vector<S2LatLng> latlngs;
+ latlngs.push_back(S2LatLng::FromDegrees(0, 0));
+ latlngs.push_back(S2LatLng::FromDegrees(0, 90));
+ latlngs.push_back(S2LatLng::FromDegrees(0, 180));
+ S2Polyline semi_equator(latlngs);
+ EXPECT_TRUE(S2::ApproxEquals(semi_equator.Interpolate(0.5),
+ S2Point(0, 1, 0)));
+ semi_equator.Reverse();
+ EXPECT_EQ(S2Point(1, 0, 0), semi_equator.vertex(2));
+}
+
+TEST(S2Polyline, GetLengthAndCentroid) {
+ // Construct random great circles and divide them randomly into segments.
+ // Then make sure that the length and centroid are correct. Note that
+ // because of the way the centroid is computed, it does not matter how
+ // we split the great circle into segments.
+
+ for (int i = 0; i < 100; ++i) {
+ // Choose a coordinate frame for the great circle.
+ S2Point x, y, z;
+ S2Testing::GetRandomFrame(&x, &y, &z);
+
+ vector<S2Point> vertices;
+ for (double theta = 0; theta < 2 * M_PI;
+ theta += pow(S2Testing::rnd.RandDouble(), 10)) {
+ S2Point p = cos(theta) * x + sin(theta) * y;
+ if (vertices.empty() || p != vertices.back())
+ vertices.push_back(p);
+ }
+ // Close the circle.
+ vertices.push_back(vertices[0]);
+ S2Polyline line(vertices);
+ S1Angle length = line.GetLength();
+ EXPECT_LE(fabs(length.radians() - 2 * M_PI), 2e-14);
+ S2Point centroid = line.GetCentroid();
+ EXPECT_LE(centroid.Norm(), 2e-14);
+ }
+}
+
+TEST(S2Polyline, MayIntersect) {
+ vector<S2Point> vertices;
+ vertices.push_back(S2Point(1, -1.1, 0.8).Normalize());
+ vertices.push_back(S2Point(1, -0.8, 1.1).Normalize());
+ S2Polyline line(vertices);
+ for (int face = 0; face < 6; ++face) {
+ S2Cell cell = S2Cell::FromFacePosLevel(face, 0, 0);
+ EXPECT_EQ((face & 1) == 0, line.MayIntersect(cell));
+ }
+}
+
+TEST(S2Polyline, Interpolate) {
+ vector<S2Point> vertices;
+ vertices.push_back(S2Point(1, 0, 0));
+ vertices.push_back(S2Point(0, 1, 0));
+ vertices.push_back(S2Point(0, 1, 1).Normalize());
+ vertices.push_back(S2Point(0, 0, 1));
+ S2Polyline line(vertices);
+ EXPECT_EQ(vertices[0], line.Interpolate(-0.1));
+ EXPECT_TRUE(S2::ApproxEquals(line.Interpolate(0.1),
+ S2Point(1, tan(0.2 * M_PI / 2), 0).Normalize()));
+ EXPECT_TRUE(S2::ApproxEquals(line.Interpolate(0.25),
+ S2Point(1, 1, 0).Normalize()));
+ EXPECT_EQ(vertices[1], line.Interpolate(0.5));
+ EXPECT_TRUE(S2::ApproxEquals(vertices[2], line.Interpolate(0.75)));
+ int next_vertex;
+ EXPECT_EQ(vertices[0], line.GetSuffix(-0.1, &next_vertex));
+ EXPECT_EQ(1, next_vertex);
+ EXPECT_TRUE(S2::ApproxEquals(vertices[2],
+ line.GetSuffix(0.75, &next_vertex)));
+ EXPECT_EQ(3, next_vertex);
+ EXPECT_EQ(vertices[3], line.GetSuffix(1.1, &next_vertex));
+ EXPECT_EQ(4, next_vertex);
+
+ // Check the case where the interpolation fraction is so close to 1 that
+ // the interpolated point is identical to the last vertex.
+ vertices.clear();
+ vertices.push_back(S2Point(1, 1, 1).Normalize());
+ vertices.push_back(S2Point(1, 1, 1 + 1e-15).Normalize());
+ vertices.push_back(S2Point(1, 1, 1 + 2e-15).Normalize());
+ S2Polyline short_line(vertices);
+ EXPECT_EQ(vertices[2], short_line.GetSuffix(1.0 - 2e-16, &next_vertex));
+ EXPECT_EQ(3, next_vertex);
+}
+
+TEST(S2Polyline, UnInterpolate) {
+ vector<S2Point> vertices;
+ vertices.push_back(S2Point(1, 0, 0));
+ S2Polyline point_line(vertices);
+ EXPECT_DOUBLE_EQ(0.0, point_line.UnInterpolate(S2Point (0, 1, 0), 1));
+
+ vertices.push_back(S2Point(0, 1, 0));
+ vertices.push_back(S2Point(0, 1, 1).Normalize());
+ vertices.push_back(S2Point(0, 0, 1));
+ S2Polyline line(vertices);
+
+ S2Point interpolated;
+ int next_vertex;
+ interpolated = line.GetSuffix(-0.1, &next_vertex);
+ EXPECT_DOUBLE_EQ(0.0, line.UnInterpolate(interpolated, next_vertex));
+ interpolated = line.GetSuffix(0.0, &next_vertex);
+ EXPECT_DOUBLE_EQ(0.0, line.UnInterpolate(interpolated, next_vertex));
+ interpolated = line.GetSuffix(0.5, &next_vertex);
+ EXPECT_DOUBLE_EQ(0.5, line.UnInterpolate(interpolated, next_vertex));
+ interpolated = line.GetSuffix(0.75, &next_vertex);
+ EXPECT_DOUBLE_EQ(0.75, line.UnInterpolate(interpolated, next_vertex));
+ interpolated = line.GetSuffix(1.1, &next_vertex);
+ EXPECT_DOUBLE_EQ(1.0, line.UnInterpolate(interpolated, next_vertex));
+
+ // Check that the return value is clamped to 1.0.
+ EXPECT_DOUBLE_EQ(1.0, line.UnInterpolate(S2Point(0, 1, 0), vertices.size()));
+}
+
+TEST(S2Polyline, Project) {
+ vector<S2LatLng> latlngs;
+ latlngs.push_back(S2LatLng::FromDegrees(0, 0));
+ latlngs.push_back(S2LatLng::FromDegrees(0, 1));
+ latlngs.push_back(S2LatLng::FromDegrees(0, 2));
+ latlngs.push_back(S2LatLng::FromDegrees(1, 2));
+ S2Polyline line(latlngs);
+
+ int next_vertex;
+ EXPECT_TRUE(S2::ApproxEquals(line.Project(
+ S2LatLng::FromDegrees(0.5, -0.5).ToPoint(),
+ &next_vertex),
+ S2LatLng::FromDegrees(0, 0).ToPoint()));
+ EXPECT_EQ(1, next_vertex);
+ EXPECT_TRUE(S2::ApproxEquals(line.Project(
+ S2LatLng::FromDegrees(0.5, 0.5).ToPoint(),
+ &next_vertex),
+ S2LatLng::FromDegrees(0, 0.5).ToPoint()));
+ EXPECT_EQ(1, next_vertex);
+ EXPECT_TRUE(S2::ApproxEquals(line.Project(
+ S2LatLng::FromDegrees(0.5, 1).ToPoint(),
+ &next_vertex),
+ S2LatLng::FromDegrees(0, 1).ToPoint()));
+ EXPECT_EQ(2, next_vertex);
+ EXPECT_TRUE(S2::ApproxEquals(line.Project(
+ S2LatLng::FromDegrees(-0.5, 2.5).ToPoint(),
+ &next_vertex),
+ S2LatLng::FromDegrees(0, 2).ToPoint()));
+ EXPECT_EQ(3, next_vertex);
+ EXPECT_TRUE(S2::ApproxEquals(line.Project(
+ S2LatLng::FromDegrees(2, 2).ToPoint(),
+ &next_vertex),
+ S2LatLng::FromDegrees(1, 2).ToPoint()));
+ EXPECT_EQ(4, next_vertex);
+}
+
+TEST(S2Polyline, IsOnRight) {
+ vector<S2LatLng> latlngs;
+ latlngs.push_back(S2LatLng::FromDegrees(0, 0));
+ latlngs.push_back(S2LatLng::FromDegrees(0, 1));
+ latlngs.push_back(S2LatLng::FromDegrees(0, 2));
+ latlngs.push_back(S2LatLng::FromDegrees(1, 2));
+ S2Polyline line(latlngs);
+
+ EXPECT_TRUE(line.IsOnRight(S2LatLng::FromDegrees(-0.5, 0.5).ToPoint()));
+ EXPECT_FALSE(line.IsOnRight(S2LatLng::FromDegrees(0.5, -0.5).ToPoint()));
+ EXPECT_FALSE(line.IsOnRight(S2LatLng::FromDegrees(0.5, 0.5).ToPoint()));
+ EXPECT_FALSE(line.IsOnRight(S2LatLng::FromDegrees(0.5, 1).ToPoint()));
+ EXPECT_TRUE(line.IsOnRight(S2LatLng::FromDegrees(-0.5, 2.5).ToPoint()));
+ EXPECT_TRUE(line.IsOnRight(S2LatLng::FromDegrees(1.5, 2.5).ToPoint()));
+
+ // Explicitly test the case where the closest point is an interior vertex.
+ latlngs.clear();
+ latlngs.push_back(S2LatLng::FromDegrees(0, 0));
+ latlngs.push_back(S2LatLng::FromDegrees(0, 1));
+ latlngs.push_back(S2LatLng::FromDegrees(-1, 0));
+ S2Polyline line2(latlngs);
+
+ // The points are chosen such that they are on different sides of the two
+ // edges that the interior vertex is on.
+ EXPECT_FALSE(line2.IsOnRight(S2LatLng::FromDegrees(-0.5, 5).ToPoint()));
+ EXPECT_FALSE(line2.IsOnRight(S2LatLng::FromDegrees(5.5, 5).ToPoint()));
+}
+
+TEST(S2Polyline, IntersectsEmptyPolyline) {
+ scoped_ptr<S2Polyline> line1(S2Testing::MakePolyline("1:1, 4:4"));
+ S2Polyline empty_polyline;
+ EXPECT_FALSE(empty_polyline.Intersects(line1.get()));
+}
+
+TEST(S2Polyline, IntersectsOnePointPolyline) {
+ scoped_ptr<S2Polyline> line1(S2Testing::MakePolyline("1:1, 4:4"));
+ scoped_ptr<S2Polyline> line2(S2Testing::MakePolyline("1:1"));
+ EXPECT_FALSE(line1->Intersects(line2.get()));
+}
+
+TEST(S2Polyline, Intersects) {
+ scoped_ptr<S2Polyline> line1(S2Testing::MakePolyline("1:1, 4:4"));
+ scoped_ptr<S2Polyline> small_crossing(S2Testing::MakePolyline("1:2, 2:1"));
+ scoped_ptr<S2Polyline> small_noncrossing(S2Testing::MakePolyline("1:2, 2:3"));
+ scoped_ptr<S2Polyline> big_crossing(S2Testing::MakePolyline("1:2, 2:3, 4:3"));
+
+ EXPECT_TRUE(line1->Intersects(small_crossing.get()));
+ EXPECT_FALSE(line1->Intersects(small_noncrossing.get()));
+ EXPECT_TRUE(line1->Intersects(big_crossing.get()));
+}
+
+TEST(S2Polyline, IntersectsAtVertex) {
+ scoped_ptr<S2Polyline> line1(S2Testing::MakePolyline("1:1, 4:4, 4:6"));
+ scoped_ptr<S2Polyline> line2(S2Testing::MakePolyline("1:1, 1:2"));
+ scoped_ptr<S2Polyline> line3(S2Testing::MakePolyline("5:1, 4:4, 2:2"));
+ EXPECT_TRUE(line1->Intersects(line2.get()));
+ EXPECT_TRUE(line1->Intersects(line3.get()));
+}
+
+TEST(S2Polyline, IntersectsVertexOnEdge) {
+ scoped_ptr<S2Polyline> horizontal_left_to_right(
+ S2Testing::MakePolyline("0:1, 0:3"));
+ scoped_ptr<S2Polyline> vertical_bottom_to_top(
+ S2Testing::MakePolyline("-1:2, 0:2, 1:2"));
+ scoped_ptr<S2Polyline> horizontal_right_to_left(
+ S2Testing::MakePolyline("0:3, 0:1"));
+ scoped_ptr<S2Polyline> vertical_top_to_bottom(
+ S2Testing::MakePolyline("1:2, 0:2, -1:2"));
+ EXPECT_TRUE(horizontal_left_to_right->Intersects(
+ vertical_bottom_to_top.get()));
+ EXPECT_TRUE(horizontal_left_to_right->Intersects(
+ vertical_top_to_bottom.get()));
+ EXPECT_TRUE(horizontal_right_to_left->Intersects(
+ vertical_bottom_to_top.get()));
+ EXPECT_TRUE(horizontal_right_to_left->Intersects(
+ vertical_top_to_bottom.get()));
+}
+
+static string JoinInts(const vector<int>& ints) {
+ string result;
+ int n = ints.size();
+ for (int i = 0; i + 1 < n; ++i) {
+ StringAppendF(&result, "%d,", ints[i]);
+ }
+ if (n > 0) {
+ StringAppendF(&result, "%d", ints[n - 1]);
+ }
+ return result;
+}
+
+void CheckSubsample(char const* polyline_str, double tolerance_degrees,
+ char const* expected_str) {
+ SCOPED_TRACE(StringPrintf("\"%s\", tolerance %f",
+ polyline_str, tolerance_degrees));
+ scoped_ptr<S2Polyline> polyline(MakePolyline(polyline_str));
+ vector<int> indices;
+ polyline->SubsampleVertices(S1Angle::Degrees(tolerance_degrees), &indices);
+ EXPECT_EQ(expected_str, JoinInts(indices));
+}
+
+TEST(S2Polyline, SubsampleVerticesTrivialInputs) {
+ // No vertices.
+ CheckSubsample("", 1.0, "");
+ // One vertex.
+ CheckSubsample("0:1", 1.0, "0");
+ // Two vertices.
+ CheckSubsample("10:10, 11:11", 5.0, "0,1");
+ // Three points on a straight line.
+ // In theory, zero tolerance should work, but in practice there are floating
+ // point errors.
+ CheckSubsample("-1:0, 0:0, 1:0", 1e-15, "0,2");
+ // Zero tolerance on a non-straight line.
+ CheckSubsample("-1:0, 0:0, 1:1", 0.0, "0,1,2");
+ // Negative tolerance should return all vertices.
+ CheckSubsample("-1:0, 0:0, 1:1", -1.0, "0,1,2");
+ // Non-zero tolerance with a straight line.
+ CheckSubsample("0:1, 0:2, 0:3, 0:4, 0:5", 1.0, "0,4");
+
+ // And finally, verify that we still do something reasonable if the client
+ // passes in an invalid polyline with two or more adjacent vertices.
+ FLAGS_s2debug = false;
+ CheckSubsample("0:1, 0:1, 0:1, 0:2", 0.0, "0,3");
+ FLAGS_s2debug = true;
+}
+
+TEST(S2Polyline, SubsampleVerticesSimpleExample) {
+ char const* poly_str("0:0, 0:1, -1:2, 0:3, 0:4, 1:4, 2:4.5, 3:4, 3.5:4, 4:4");
+ CheckSubsample(poly_str, 3.0, "0,9");
+ CheckSubsample(poly_str, 2.0, "0,6,9");
+ CheckSubsample(poly_str, 0.9, "0,2,6,9");
+ CheckSubsample(poly_str, 0.4, "0,1,2,3,4,6,9");
+ CheckSubsample(poly_str, 0, "0,1,2,3,4,5,6,7,8,9");
+}
+
+TEST(S2Polyline, SubsampleVerticesGuarantees) {
+ // Check that duplicate vertices are never generated.
+ CheckSubsample("10:10, 12:12, 10:10", 5.0, "0");
+ CheckSubsample("0:0, 1:1, 0:0, 0:120, 0:130", 5.0, "0,3,4");
+
+ // Check that points are not collapsed if they would create a line segment
+ // longer than 90 degrees, and also that the code handles original polyline
+ // segments longer than 90 degrees.
+ CheckSubsample("90:0, 50:180, 20:180, -20:180, -50:180, -90:0, 30:0, 90:0",
+ 5.0, "0,2,4,5,6,7");
+
+ // Check that the output polyline is parametrically equivalent and not just
+ // geometrically equivalent, i.e. that backtracking is preserved. The
+ // algorithm achieves this by requiring that the points must be encountered
+ // in increasing order of distance along each output segment, except for
+ // points that are within "tolerance" of the first vertex of each segment.
+ CheckSubsample("10:10, 10:20, 10:30, 10:15, 10:40", 5.0, "0,2,3,4");
+ CheckSubsample("10:10, 10:20, 10:30, 10:10, 10:30, 10:40", 5.0, "0,2,3,5");
+ CheckSubsample("10:10, 12:12, 9:9, 10:20, 10:30", 5.0, "0,4");
+}
+
+
+static bool TestEquals(char const* a_str,
+ char const* b_str,
+ double max_error) {
+ scoped_ptr<S2Polyline> a(MakePolyline(a_str));
+ scoped_ptr<S2Polyline> b(MakePolyline(b_str));
+ return a->ApproxEquals(b.get(), max_error);
+}
+
+TEST(S2Polyline, ApproxEquals) {
+ double degree = S1Angle::Degrees(1).radians();
+
+ // Close lines, differences within max_error.
+ EXPECT_TRUE(TestEquals("0:0, 0:10, 5:5",
+ "0:0.1, -0.1:9.9, 5:5.2",
+ 0.5 * degree));
+
+ // Close lines, differences outside max_error.
+ EXPECT_FALSE(TestEquals("0:0, 0:10, 5:5",
+ "0:0.1, -0.1:9.9, 5:5.2",
+ 0.01 * degree));
+
+ // Same line, but different number of vertices.
+ EXPECT_FALSE(TestEquals("0:0, 0:10, 0:20", "0:0, 0:20", 0.1 * degree));
+
+ // Same vertices, in different order.
+ EXPECT_FALSE(TestEquals("0:0, 5:5, 0:10", "5:5, 0:10, 0:0", 0.1 * degree));
+}
+
+TEST(S2Polyline, EncodeDecode) {
+ scoped_ptr<S2Polyline> polyline(MakePolyline("0:0, 0:10, 10:20, 20:30"));
+ Encoder encoder;
+ polyline->Encode(&encoder);
+ Decoder decoder(encoder.base(), encoder.length());
+ S2Polyline decoded_polyline;
+ EXPECT_TRUE(decoded_polyline.Decode(&decoder));
+ EXPECT_TRUE(decoded_polyline.ApproxEquals(polyline.get(), 0));
+}
+
+void TestNearlyCovers(string const& a_str, string const& b_str,
+ double max_error_degrees, bool expect_b_covers_a,
+ bool expect_a_covers_b) {
+ SCOPED_TRACE(StringPrintf("a=\"%s\", b=\"%s\", max error=%f",
+ a_str.c_str(), b_str.c_str(), max_error_degrees));
+ scoped_ptr<S2Polyline> a(S2Testing::MakePolyline(a_str));
+ scoped_ptr<S2Polyline> b(S2Testing::MakePolyline(b_str));
+ S1Angle max_error = S1Angle::Degrees(max_error_degrees);
+ EXPECT_EQ(expect_b_covers_a, b->NearlyCoversPolyline(*a, max_error));
+ EXPECT_EQ(expect_a_covers_b, a->NearlyCoversPolyline(*b, max_error));
+}
+
+TEST(S2PolylineCoveringTest, PolylineOverlapsSelf) {
+ string pline = "1:1, 2:2, -1:10";
+ TestNearlyCovers(pline, pline, 1e-10, true, true);
+}
+
+TEST(S2PolylineCoveringTest, PolylineDoesNotOverlapReverse) {
+ TestNearlyCovers("1:1, 2:2, -1:10", "-1:10, 2:2, 1:1", 1e-10, false, false);
+}
+
+TEST(S2PolylineCoveringTest, PolylineOverlapsEquivalent) {
+ // These two polylines trace the exact same polyline, but the second one uses
+ // three points instead of two.
+ TestNearlyCovers("1:1, 2:1", "1:1, 1.5:1, 2:1", 1e-10, true, true);
+}
+
+TEST(S2PolylineCoveringTest, ShortCoveredByLong) {
+ // The second polyline is always within 0.001 degrees of the first polyline,
+ // but the first polyline is too long to be covered by the second.
+ TestNearlyCovers(
+ "-5:1, 10:1, 10:5, 5:10", "9:1, 9.9995:1, 10.0005:5", 1e-3, false, true);
+}
+
+TEST(S2PolylineCoveringTest, PartialOverlapOnly) {
+ // These two polylines partially overlap each other, but neither fully
+ // overlaps the other.
+ TestNearlyCovers("-5:1, 10:1", "0:1, 20:1", 1.0, false, false);
+}
+
+TEST(S2PolylineCoveringTest, ShortBacktracking) {
+ // Two lines that backtrack a bit (less than 1.5 degrees) on different edges.
+ // A simple greedy matching algorithm would fail on this example.
+ string const& t1 = "0:0, 0:2, 0:1, 0:4, 0:5";
+ string const& t2 = "0:0, 0:2, 0:4, 0:3, 0:5";
+ TestNearlyCovers(t1, t2, 1.5, true, true);
+ TestNearlyCovers(t1, t2, 0.5, false, false);
+}
+
+TEST(S2PolylineCoveringTest, LongBacktracking) {
+ // Two arcs with opposite direction do not overlap if the shorter arc is
+ // longer than max_error, but do if the shorter arc is shorter than max-error.
+ TestNearlyCovers("5:1, -5:1", "1:1, 3:1", 1.0, false, false);
+ TestNearlyCovers("5:1, -5:1", "1:1, 3:1", 2.5, false, true);
+}
+
+TEST(S2PolylineCoveringTest, IsResilientToDuplicatePoints) {
+ // S2Polyines are not generally supposed to contain adjacent, identical
+ // points, but it happens in practice. When --s2debug=true, debug-mode
+ // binaries abort on such polylines, so we also set --s2debug=false.
+ FLAGS_s2debug = false;
+ TestNearlyCovers("0:1, 0:2, 0:2, 0:3", "0:1, 0:1, 0:1, 0:3",
+ 1e-10, true, true);
+}
+
+TEST(S2PolylineCoveringTest, CanChooseBetweenTwoPotentialStartingPoints) {
+ // Can handle two possible starting points, only one of which leads to finding
+ // a correct path. In the first polyline, the edge from 0:1.1 to 0:0 and the
+ // edge from 0:0.9 to 0:2 might be lucrative starting states for covering the
+ // second polyline, because both edges are with the max_error of 1.5 degrees
+ // from 0:10. However, only the latter is actually effective.
+ TestNearlyCovers("0:11, 0:0, 0:9, 0:20", "0:10, 0:15", 1.5, false, true);
+}
+
+TEST(S2PolylineCoveringTest, StraightAndWigglyPolylinesCoverEachOther) {
+ TestNearlyCovers("40:1, 20:1",
+ "39.9:0.9, 40:1.1, 30:1.15, 29:0.95, 28:1.1, 27:1.15, "
+ "26:1.05, 25:0.85, 24:1.1, 23:0.9, 20:0.99",
+ 0.2, true, true);
+}
+
+} // namespace
diff --git a/src/third_party/s2/s2r2rect.cc b/src/third_party/s2/s2r2rect.cc
new file mode 100644
index 00000000000..3b2328c2405
--- /dev/null
+++ b/src/third_party/s2/s2r2rect.cc
@@ -0,0 +1,152 @@
+// Copyright 2005 Google Inc. All Rights Reserved.
+
+#include "s2r2rect.h"
+
+#include "base/logging.h"
+#include "r1interval.h"
+#include "s2.h"
+#include "s2cap.h"
+#include "s2cell.h"
+#include "s2latlngrect.h"
+
+S2R2Rect S2R2Rect::FromCell(S2Cell const& cell) {
+ // S2Cells have a more efficient GetSizeST() method than S2CellIds.
+ double size = cell.GetSizeST();
+ return FromCenterSize(cell.id().GetCenterST(), R2Point(size, size));
+}
+
+S2R2Rect S2R2Rect::FromCellId(S2CellId const& id) {
+ double size = id.GetSizeST();
+ return FromCenterSize(id.GetCenterST(), R2Point(size, size));
+}
+
+S2R2Rect S2R2Rect::FromCenterSize(R2Point const& center, R2Point const& size) {
+ return S2R2Rect(R1Interval(center.x() - 0.5 * size.x(),
+ center.x() + 0.5 * size.x()),
+ R1Interval(center.y() - 0.5 * size.y(),
+ center.y() + 0.5 * size.y()));
+}
+
+S2R2Rect S2R2Rect::FromPoint(R2Point const& p) {
+ return S2R2Rect(p, p);
+}
+
+S2R2Rect S2R2Rect::FromPointPair(R2Point const& p1, R2Point const& p2) {
+ return S2R2Rect(R1Interval::FromPointPair(p1.x(), p2.x()),
+ R1Interval::FromPointPair(p1.y(), p2.y()));
+}
+
+S2R2Rect* S2R2Rect::Clone() const {
+ return new S2R2Rect(*this);
+}
+
+R2Point S2R2Rect::GetVertex(int k) const {
+ // Twiddle bits to return the points in CCW order (SW, SE, NE, NW).
+ return R2Point(x_.bound((k>>1) ^ (k&1)), y_.bound(k>>1));
+}
+
+R2Point S2R2Rect::GetCenter() const {
+ return R2Point(x_.GetCenter(), y_.GetCenter());
+}
+
+R2Point S2R2Rect::GetSize() const {
+ return R2Point(x_.GetLength(), y_.GetLength());
+}
+
+bool S2R2Rect::Contains(R2Point const& p) const {
+ return x_.Contains(p.x()) && y_.Contains(p.y());
+}
+
+bool S2R2Rect::InteriorContains(R2Point const& p) const {
+ return x_.InteriorContains(p.x()) && y_.InteriorContains(p.y());
+}
+
+bool S2R2Rect::Contains(S2R2Rect const& other) const {
+ return x_.Contains(other.x_) && y_.Contains(other.y_);
+}
+
+bool S2R2Rect::InteriorContains(S2R2Rect const& other) const {
+ return x_.InteriorContains(other.x_) && y_.InteriorContains(other.y_);
+}
+
+bool S2R2Rect::Intersects(S2R2Rect const& other) const {
+ return x_.Intersects(other.x_) && y_.Intersects(other.y_);
+}
+
+bool S2R2Rect::InteriorIntersects(S2R2Rect const& other) const {
+ return x_.InteriorIntersects(other.x_) && y_.InteriorIntersects(other.y_);
+}
+
+void S2R2Rect::AddPoint(R2Point const& p) {
+ x_.AddPoint(p.x());
+ y_.AddPoint(p.y());
+}
+
+S2R2Rect S2R2Rect::Expanded(R2Point const& margin) const {
+ DCHECK_GE(margin.x(), 0);
+ DCHECK_GE(margin.y(), 0);
+ return S2R2Rect(x_.Expanded(margin.x()), y_.Expanded(margin.y()));
+}
+
+S2R2Rect S2R2Rect::Union(S2R2Rect const& other) const {
+ return S2R2Rect(x_.Union(other.x_), y_.Union(other.y_));
+}
+
+S2R2Rect S2R2Rect::Intersection(S2R2Rect const& other) const {
+ R1Interval x = x_.Intersection(other.x_);
+ R1Interval y = y_.Intersection(other.y_);
+ if (x.is_empty() || y.is_empty()) {
+ // The x/y ranges must either be both empty or both non-empty.
+ return Empty();
+ }
+ return S2R2Rect(x, y);
+}
+
+bool S2R2Rect::ApproxEquals(S2R2Rect const& other, double max_error) const {
+ return (x_.ApproxEquals(other.x_, max_error) &&
+ y_.ApproxEquals(other.y_, max_error));
+}
+
+S2Point S2R2Rect::ToS2Point(R2Point const& p) {
+ return S2::FaceUVtoXYZ(0, S2::STtoUV(p.x()), S2::STtoUV(p.y())).Normalize();
+}
+
+S2Cap S2R2Rect::GetCapBound() const {
+ if (is_empty()) return S2Cap::Empty();
+
+ // The rectangle is a convex polygon on the sphere, since it is a subset of
+ // one cube face. Its bounding cap is also a convex region on the sphere,
+ // and therefore we can bound the rectangle by just bounding its vertices.
+ // We use the rectangle's center in (s,t)-space as the cap axis. This
+ // doesn't yield the minimal cap but it's pretty close.
+ S2Cap cap = S2Cap::FromAxisHeight(ToS2Point(GetCenter()), 0);
+ for (int k = 0; k < 4; ++k) {
+ cap.AddPoint(ToS2Point(GetVertex(k)));
+ }
+ return cap;
+}
+
+S2LatLngRect S2R2Rect::GetRectBound() const {
+ // This is not very tight but hopefully good enough.
+ return GetCapBound().GetRectBound();
+}
+
+bool S2R2Rect::Contains(S2Point const& p) const {
+ S2CellId cellid = S2CellId::FromPoint(p);
+ if (cellid.face() != 0) return false;
+ return Contains(cellid.GetCenterST());
+}
+
+bool S2R2Rect::Contains(S2Cell const& cell) const {
+ if (cell.face() != 0) return false;
+ return Contains(S2R2Rect::FromCell(cell));
+}
+
+bool S2R2Rect::MayIntersect(S2Cell const& cell) const {
+ if (cell.face() != 0) return false;
+ return Intersects(S2R2Rect::FromCell(cell));
+}
+
+ostream& operator<<(ostream& os, S2R2Rect const& r) {
+ return os << "[Lo" << r.lo() << ", Hi" << r.hi() << "]";
+}
diff --git a/src/third_party/s2/s2r2rect.h b/src/third_party/s2/s2r2rect.h
new file mode 100644
index 00000000000..fab55e76da8
--- /dev/null
+++ b/src/third_party/s2/s2r2rect.h
@@ -0,0 +1,205 @@
+// Copyright 2005 Google Inc. All Rights Reserved.
+
+#ifndef UTIL_GEOMETRY_S2R2RECT_H_
+#define UTIL_GEOMETRY_S2R2RECT_H_
+
+#include "base/basictypes.h"
+#include "base/logging.h"
+#include "r1interval.h"
+#include "s2region.h"
+#include "util/math/vector2-inl.h"
+
+class S2CellId;
+class S2Cell;
+
+// TODO: Create an r2.h and move this definition into it.
+typedef Vector2_d R2Point;
+
+// This class is a stopgap measure that allows some of the S2 spherical
+// geometry machinery to be applied to planar geometry. An S2R2Rect
+// represents a closed axis-aligned rectangle in the (x,y) plane, but it also
+// happens to be a subtype of S2Region, which means that you can use an
+// S2RegionCoverer to approximate it as a collection of S2CellIds.
+//
+// With respect to the S2Cell decomposition, an S2R2Rect is interpreted as a
+// region of (s,t)-space on face 0. In particular, the rectangle [0,1]x[0,1]
+// corresponds to the S2CellId that covers all of face 0. This means that
+// only rectangles that are subsets of [0,1]x[0,1] can be approximated using
+// the S2RegionCoverer interface.
+//
+// The S2R2Rect class is also a convenient way to find the (s,t)-region
+// covered by a given S2CellId (see the FromCell and FromCellId methods).
+//
+// TODO: If the geometry library is extended to have better support for planar
+// geometry, then this class should no longer be necessary.
+//
+// This class is intended to be copied by value as desired. It uses
+// the default copy constructor and assignment operator, however it is
+// not a "plain old datatype" (POD) because it has virtual functions.
+class S2R2Rect : public S2Region {
+ public:
+ // Construct a rectangle from the given lower-left and upper-right points.
+ inline S2R2Rect(R2Point const& lo, R2Point const& hi);
+
+ // Construct a rectangle from the given intervals in x and y. The two
+ // intervals must either be both empty or both non-empty.
+ inline S2R2Rect(R1Interval const& x, R1Interval const& y);
+
+ // Construct a rectangle that corresponds to the boundary of the given cell
+ // is (s,t)-space. Such rectangles are always a subset of [0,1]x[0,1].
+ static S2R2Rect FromCell(S2Cell const& cell);
+ static S2R2Rect FromCellId(S2CellId const& id);
+
+ // Construct a rectangle from a center point and size in each dimension.
+ // Both components of size should be non-negative, i.e. this method cannot
+ // be used to create an empty rectangle.
+ static S2R2Rect FromCenterSize(R2Point const& center,
+ R2Point const& size);
+
+ // Convenience method to construct a rectangle containing a single point.
+ static S2R2Rect FromPoint(R2Point const& p);
+
+ // Convenience method to construct the minimal bounding rectangle containing
+ // the two given points. This is equivalent to starting with an empty
+ // rectangle and calling AddPoint() twice. Note that it is different than
+ // the S2R2Rect(lo, hi) constructor, where the first point is always
+ // used as the lower-left corner of the resulting rectangle.
+ static S2R2Rect FromPointPair(R2Point const& p1, R2Point const& p2);
+
+ // Accessor methods.
+ R1Interval const& x() const { return x_; }
+ R1Interval const& y() const { return y_; }
+ R1Interval *mutable_x() { return &x_; }
+ R1Interval *mutable_y() { return &y_; }
+ R2Point lo() const { return R2Point(x_.lo(), y_.lo()); }
+ R2Point hi() const { return R2Point(x_.hi(), y_.hi()); }
+
+ // The canonical empty rectangle. Use is_empty() to test for empty
+ // rectangles, since they have more than one representation.
+ static inline S2R2Rect Empty();
+
+ // Return true if the rectangle is valid, which essentially just means
+ // that if the bound for either axis is empty then both must be.
+ inline bool is_valid() const;
+
+ // Return true if the rectangle is empty, i.e. it contains no points at all.
+ inline bool is_empty() const;
+
+ // Return the k-th vertex of the rectangle (k = 0,1,2,3) in CCW order.
+ // Vertex 0 is in the lower-left corner.
+ R2Point GetVertex(int k) const;
+
+ // Return the center of the rectangle in (x,y)-space
+ // (in general this is not the center of the region on the sphere).
+ R2Point GetCenter() const;
+
+ // Return the width and height of this rectangle in (x,y)-space. Empty
+ // rectangles have a negative width and height.
+ R2Point GetSize() const;
+
+ // Return true if the rectangle contains the given point. Note that
+ // rectangles are closed regions, i.e. they contain their boundary.
+ bool Contains(R2Point const& p) const;
+
+ // Return true if and only if the given point is contained in the interior
+ // of the region (i.e. the region excluding its boundary).
+ bool InteriorContains(R2Point const& p) const;
+
+ // Return true if and only if the rectangle contains the given other
+ // rectangle.
+ bool Contains(S2R2Rect const& other) const;
+
+ // Return true if and only if the interior of this rectangle contains all
+ // points of the given other rectangle (including its boundary).
+ bool InteriorContains(S2R2Rect const& other) const;
+
+ // Return true if this rectangle and the given other rectangle have any
+ // points in common.
+ bool Intersects(S2R2Rect const& other) const;
+
+ // Return true if and only if the interior of this rectangle intersects
+ // any point (including the boundary) of the given other rectangle.
+ bool InteriorIntersects(S2R2Rect const& other) const;
+
+ // Increase the size of the bounding rectangle to include the given point.
+ // The rectangle is expanded by the minimum amount possible.
+ void AddPoint(R2Point const& p);
+
+ // Return a rectangle that contains all points whose x-distance from this
+ // rectangle is at most margin.x(), and whose y-distance from this rectangle
+ // is at most margin.y(). Note that any expansion of an empty interval
+ // remains empty, and both components of the given margin must be
+ // non-negative.
+ S2R2Rect Expanded(R2Point const& margin) const;
+
+ // Return the smallest rectangle containing the union of this rectangle and
+ // the given rectangle.
+ S2R2Rect Union(S2R2Rect const& other) const;
+
+ // Return the smallest rectangle containing the intersection of this
+ // rectangle and the given rectangle.
+ S2R2Rect Intersection(S2R2Rect const& other) const;
+
+ // Return true if two rectangles contains the same set of points.
+ inline bool operator==(S2R2Rect const& other) const;
+
+ // Return true if the x- and y-intervals of the two rectangles are the same
+ // up to the given tolerance (see r1interval.h for details).
+ bool ApproxEquals(S2R2Rect const& other, double max_error = 1e-15) const;
+
+ // Return the unit-length S2Point corresponding to the given point "p" in
+ // the (s,t)-plane. "p" need not be restricted to the range [0,1]x[0,1].
+ static S2Point ToS2Point(R2Point const& p);
+
+ ////////////////////////////////////////////////////////////////////////
+ // S2Region interface (see s2region.h for details):
+
+ virtual S2R2Rect* Clone() const;
+ virtual S2Cap GetCapBound() const;
+ virtual S2LatLngRect GetRectBound() const;
+ virtual bool VirtualContainsPoint(S2Point const& p) const {
+ return Contains(p); // The same as Contains() below, just virtual.
+ }
+ bool Contains(S2Point const& p) const;
+ virtual bool Contains(S2Cell const& cell) const;
+ virtual bool MayIntersect(S2Cell const& cell) const;
+ virtual void Encode(Encoder* const encoder) const {
+ S2LOG(FATAL) << "Unimplemented";
+ }
+ virtual bool Decode(Decoder* const decoder) { return false; }
+
+ private:
+ R1Interval x_;
+ R1Interval y_;
+};
+
+inline S2R2Rect::S2R2Rect(R2Point const& lo, R2Point const& hi)
+ : x_(lo.x(), hi.x()), y_(lo.y(), hi.y()) {
+ DCHECK(is_valid());
+}
+
+inline S2R2Rect::S2R2Rect(R1Interval const& x, R1Interval const& y)
+ : x_(x), y_(y) {
+ DCHECK(is_valid());
+}
+
+inline S2R2Rect S2R2Rect::Empty() {
+ return S2R2Rect(R1Interval::Empty(), R1Interval::Empty());
+}
+
+inline bool S2R2Rect::is_valid() const {
+ // The x/y ranges must either be both empty or both non-empty.
+ return x_.is_empty() == y_.is_empty();
+}
+
+inline bool S2R2Rect::is_empty() const {
+ return x_.is_empty();
+}
+
+inline bool S2R2Rect::operator==(S2R2Rect const& other) const {
+ return x_ == other.x_ && y_ == other.y_;
+}
+
+ostream& operator<<(ostream& os, S2R2Rect const& r);
+
+#endif // UTIL_GEOMETRY_S2R2RECT_H_
diff --git a/src/third_party/s2/s2r2rect_test.cc b/src/third_party/s2/s2r2rect_test.cc
new file mode 100644
index 00000000000..cad3aa32e9a
--- /dev/null
+++ b/src/third_party/s2/s2r2rect_test.cc
@@ -0,0 +1,272 @@
+// Copyright 2005 Google Inc. All Rights Reserved.
+//
+// Most of the S2R2Rect methods have trivial implementations in terms of the
+// R1Interval class, so most of the testing is done in that unit test.
+
+#include "s2r2rect.h"
+
+#include "strings/stringprintf.h"
+#include "testing/base/public/gunit.h"
+#include "s2.h"
+#include "s2cap.h"
+#include "s2cell.h"
+#include "s2latlngrect.h"
+#include "s2testing.h"
+
+static S2R2Rect MakeRect(double x_lo, double y_lo, double x_hi, double y_hi) {
+ // Convenience method to construct a rectangle. This method is
+ // intentionally *not* in the S2R2Rect interface because the
+ // argument order is ambiguous, but hopefully it's not too confusing
+ // within the context of this unit test.
+ return S2R2Rect(R2Point(x_lo, y_lo), R2Point(x_hi, y_hi));
+}
+
+static void TestIntervalOps(S2R2Rect const& x, S2R2Rect const& y,
+ const char* expected_rexion,
+ S2R2Rect const& expected_union,
+ S2R2Rect const& expected_intersection) {
+ // Test all of the interval operations on the given pair of intervals.
+ // "expected_rexion" is a sequence of "T" and "F" characters corresponding
+ // to the expected results of Contains(), InteriorContains(), Intersects(),
+ // and InteriorIntersects() respectively.
+
+ EXPECT_EQ(expected_rexion[0] == 'T', x.Contains(y));
+ EXPECT_EQ(expected_rexion[1] == 'T', x.InteriorContains(y));
+ EXPECT_EQ(expected_rexion[2] == 'T', x.Intersects(y));
+ EXPECT_EQ(expected_rexion[3] == 'T', x.InteriorIntersects(y));
+
+ EXPECT_EQ(x.Union(y) == x, x.Contains(y));
+ EXPECT_EQ(!x.Intersection(y).is_empty(), x.Intersects(y));
+
+ EXPECT_EQ(expected_union, x.Union(y));
+ EXPECT_EQ(expected_intersection, x.Intersection(y));
+
+ if (y.GetSize() == R2Point(0, 0)) {
+ S2R2Rect r = x;
+ r.AddPoint(y.lo());
+ EXPECT_EQ(expected_union, r);
+ }
+}
+
+static void TestCellOps(S2R2Rect const& r, S2Cell const& cell, int level) {
+ // Test the relationship between the given rectangle and cell:
+ // 0 == no intersection, 2 == Intersects,
+ // 3 == Intersects and one region contains a vertex of the other,
+ // 4 == Contains
+
+ bool vertex_contained = false;
+ for (int i = 0; i < 4; ++i) {
+ // This would be easier to do by constructing an S2R2Rect from the cell,
+ // but that would defeat the purpose of testing this code independently.
+ double u, v;
+ if (S2::FaceXYZtoUV(0, cell.GetVertexRaw(i), &u, &v)) {
+ if (r.Contains(R2Point(S2::UVtoST(u), S2::UVtoST(v))))
+ vertex_contained = true;
+ }
+ if (!r.is_empty() && cell.Contains(S2R2Rect::ToS2Point(r.GetVertex(i))))
+ vertex_contained = true;
+ }
+ EXPECT_EQ(level >= 2, r.MayIntersect(cell));
+ EXPECT_EQ(level >= 3, vertex_contained);
+ EXPECT_EQ(level >= 4, r.Contains(cell));
+}
+
+TEST(S2R2Rect, EmptyRectangles) {
+ // Test basic properties of empty rectangles.
+ S2R2Rect empty = S2R2Rect::Empty();
+ EXPECT_TRUE(empty.is_valid());
+ EXPECT_TRUE(empty.is_empty());
+}
+
+TEST(S2R2Rect, ConstructorsAndAccessors) {
+ // Check various constructors and accessor methods.
+ S2R2Rect d1 = MakeRect(0.1, 0, 0.25, 1);
+ EXPECT_EQ(0.1, d1.x().lo());
+ EXPECT_EQ(0.25, d1.x().hi());
+ EXPECT_EQ(0.0, d1.y().lo());
+ EXPECT_EQ(1.0, d1.y().hi());
+ EXPECT_EQ(R1Interval(0.1, 0.25), d1.x());
+ EXPECT_EQ(R1Interval(0, 1), d1.y());
+}
+
+TEST(S2R2Rect, FromCell) {
+ // FromCell, FromCellId
+ EXPECT_EQ(MakeRect(0, 0, 0.5, 0.5),
+ S2R2Rect::FromCell(S2Cell::FromFacePosLevel(0, 0, 1)));
+ EXPECT_EQ(MakeRect(0, 0, 1, 1),
+ S2R2Rect::FromCellId(S2CellId::FromFacePosLevel(0, 0, 0)));
+}
+
+TEST(S2R2Rect, FromCenterSize) {
+ // FromCenterSize()
+ EXPECT_TRUE(S2R2Rect::FromCenterSize(R2Point(0.3, 0.5), R2Point(0.2, 0.4)).
+ ApproxEquals(MakeRect(0.2, 0.3, 0.4, 0.7)));
+ EXPECT_TRUE(S2R2Rect::FromCenterSize(R2Point(1, 0.1), R2Point(0, 2)).
+ ApproxEquals(MakeRect(1, -0.9, 1, 1.1)));
+}
+
+TEST(S2R2Rect, FromPoint) {
+ // FromPoint(), FromPointPair()
+ S2R2Rect d1 = MakeRect(0.1, 0, 0.25, 1);
+ EXPECT_EQ(S2R2Rect(d1.lo(), d1.lo()), S2R2Rect::FromPoint(d1.lo()));
+ EXPECT_EQ(MakeRect(0.15, 0.3, 0.35, 0.9),
+ S2R2Rect::FromPointPair(R2Point(0.15, 0.9), R2Point(0.35, 0.3)));
+ EXPECT_EQ(MakeRect(0.12, 0, 0.83, 0.5),
+ S2R2Rect::FromPointPair(R2Point(0.83, 0), R2Point(0.12, 0.5)));
+}
+
+TEST(S2R2Rect, SimplePredicates) {
+ // GetCenter(), GetVertex(), Contains(R2Point), InteriorContains(R2Point).
+ R2Point sw1 = R2Point(0, 0.25);
+ R2Point ne1 = R2Point(0.5, 0.75);
+ S2R2Rect r1(sw1, ne1);
+
+ EXPECT_EQ(R2Point(0.25, 0.5), r1.GetCenter());
+ EXPECT_EQ(R2Point(0, 0.25), r1.GetVertex(0));
+ EXPECT_EQ(R2Point(0.5, 0.25), r1.GetVertex(1));
+ EXPECT_EQ(R2Point(0.5, 0.75), r1.GetVertex(2));
+ EXPECT_EQ(R2Point(0, 0.75), r1.GetVertex(3));
+ EXPECT_TRUE(r1.Contains(R2Point(0.2, 0.4)));
+ EXPECT_FALSE(r1.Contains(R2Point(0.2, 0.8)));
+ EXPECT_FALSE(r1.Contains(R2Point(-0.1, 0.4)));
+ EXPECT_FALSE(r1.Contains(R2Point(0.6, 0.1)));
+ EXPECT_TRUE(r1.Contains(sw1));
+ EXPECT_TRUE(r1.Contains(ne1));
+ EXPECT_FALSE(r1.InteriorContains(sw1));
+ EXPECT_FALSE(r1.InteriorContains(ne1));
+
+ // Make sure that GetVertex() returns vertices in CCW order.
+ for (int k = 0; k < 4; ++k) {
+ SCOPED_TRACE(StringPrintf("k=%d", k));
+ EXPECT_TRUE(S2::SimpleCCW(S2R2Rect::ToS2Point(r1.GetVertex((k-1)&3)),
+ S2R2Rect::ToS2Point(r1.GetVertex(k)),
+ S2R2Rect::ToS2Point(r1.GetVertex((k+1)&3))));
+ }
+}
+
+TEST(S2R2Rect, IntervalOperations) {
+ // Contains(S2R2Rect), InteriorContains(S2R2Rect),
+ // Intersects(), InteriorIntersects(), Union(), Intersection().
+ //
+ // Much more testing of these methods is done in s1interval_unittest
+ // and r1interval_unittest.
+
+ S2R2Rect empty = S2R2Rect::Empty();
+ R2Point sw1 = R2Point(0, 0.25);
+ R2Point ne1 = R2Point(0.5, 0.75);
+ S2R2Rect r1(sw1, ne1);
+ S2R2Rect r1_mid = MakeRect(0.25, 0.5, 0.25, 0.5);
+ S2R2Rect r_sw1(sw1, sw1);
+ S2R2Rect r_ne1(ne1, ne1);
+
+ TestIntervalOps(r1, r1_mid, "TTTT", r1, r1_mid);
+ TestIntervalOps(r1, r_sw1, "TFTF", r1, r_sw1);
+ TestIntervalOps(r1, r_ne1, "TFTF", r1, r_ne1);
+
+ EXPECT_EQ(MakeRect(0, 0.25, 0.5, 0.75), r1);
+ TestIntervalOps(r1, MakeRect(0.45, 0.1, 0.75, 0.3), "FFTT",
+ MakeRect(0, 0.1, 0.75, 0.75),
+ MakeRect(0.45, 0.25, 0.5, 0.3));
+ TestIntervalOps(r1, MakeRect(0.5, 0.1, 0.7, 0.3), "FFTF",
+ MakeRect(0, 0.1, 0.7, 0.75),
+ MakeRect(0.5, 0.25, 0.5, 0.3));
+ TestIntervalOps(r1, MakeRect(0.45, 0.1, 0.7, 0.25), "FFTF",
+ MakeRect(0, 0.1, 0.7, 0.75),
+ MakeRect(0.45, 0.25, 0.5, 0.25));
+
+ TestIntervalOps(MakeRect(0.1, 0.2, 0.1, 0.3),
+ MakeRect(0.15, 0.7, 0.2, 0.8), "FFFF",
+ MakeRect(0.1, 0.2, 0.2, 0.8),
+ empty);
+
+ // Check that the intersection of two rectangles that overlap in x but not y
+ // is valid, and vice versa.
+ TestIntervalOps(MakeRect(0.1, 0.2, 0.4, 0.5),
+ MakeRect(0, 0, 0.2, 0.1), "FFFF",
+ MakeRect(0, 0, 0.4, 0.5), empty);
+ TestIntervalOps(MakeRect(0, 0, 0.1, 0.3),
+ MakeRect(0.2, 0.1, 0.3, 0.4), "FFFF",
+ MakeRect(0, 0, 0.3, 0.4), empty);
+}
+
+TEST(S2R2Rect, AddPoint) {
+ // AddPoint()
+ R2Point sw1 = R2Point(0, 0.25);
+ R2Point ne1 = R2Point(0.5, 0.75);
+ S2R2Rect r1(sw1, ne1);
+
+ S2R2Rect r2 = S2R2Rect::Empty();
+ r2.AddPoint(R2Point(0, 0.25));
+ r2.AddPoint(R2Point(0.5, 0.25));
+ r2.AddPoint(R2Point(0, 0.75));
+ r2.AddPoint(R2Point(0.1, 0.4));
+ EXPECT_EQ(r1, r2);
+}
+
+TEST(S2R2Rect, Expanded) {
+ // Expanded()
+ EXPECT_TRUE(MakeRect(0.2, 0.4, 0.3, 0.7).Expanded(R2Point(0.1, 0.3)).
+ ApproxEquals(MakeRect(0.1, 0.1, 0.4, 1.0)));
+ EXPECT_TRUE(S2R2Rect::Empty().Expanded(R2Point(0.1, 0.3)).is_empty());
+}
+
+TEST(S2R2Rect, Bounds) {
+ // GetCapBound(), GetRectBound()
+ S2R2Rect empty = S2R2Rect::Empty();
+ EXPECT_TRUE(empty.GetCapBound().is_empty());
+ EXPECT_TRUE(empty.GetRectBound().is_empty());
+ EXPECT_EQ(S2Cap::FromAxisHeight(S2Point(1, 0, 0), 0),
+ MakeRect(0.5, 0.5, 0.5, 0.5).GetCapBound());
+ EXPECT_EQ(S2LatLngRect::FromPoint(S2LatLng::FromDegrees(0, 0)),
+ MakeRect(0.5, 0.5, 0.5, 0.5).GetRectBound());
+
+ for (int i = 0; i < 10; ++i) {
+ SCOPED_TRACE(StringPrintf("i=%d", i));
+ S2R2Rect rect = S2R2Rect::FromCellId(S2Testing::GetRandomCellId());
+ S2Cap cap = rect.GetCapBound();
+ S2LatLngRect llrect = rect.GetRectBound();
+ for (int k = 0; k < 4; ++k) {
+ S2Point v = S2R2Rect::ToS2Point(rect.GetVertex(k));
+ // v2 is a point that is well outside the rectangle.
+ S2Point v2 = (cap.axis() + 2 * (v - cap.axis())).Normalize();
+ EXPECT_TRUE(cap.Contains(v));
+ EXPECT_FALSE(cap.Contains(v2));
+ EXPECT_TRUE(llrect.Contains(v));
+ EXPECT_FALSE(llrect.Contains(v2));
+ }
+ }
+}
+
+TEST(S2R2Rect, CellOperations) {
+ // Contains(S2Cell), MayIntersect(S2Cell)
+
+ S2R2Rect empty = S2R2Rect::Empty();
+ TestCellOps(empty, S2Cell::FromFacePosLevel(3, 0, 0), 0);
+
+ // This rectangle includes the first quadrant of face 0. It's expanded
+ // slightly because cell bounding rectangles are slightly conservative.
+ S2R2Rect r4 = MakeRect(0, 0, 0.5, 0.5);
+ TestCellOps(r4, S2Cell::FromFacePosLevel(0, 0, 0), 3);
+ TestCellOps(r4, S2Cell::FromFacePosLevel(0, 0, 1), 4);
+ TestCellOps(r4, S2Cell::FromFacePosLevel(1, 0, 1), 0);
+
+ // This rectangle intersects the first quadrant of face 0.
+ S2R2Rect r5 = MakeRect(0, 0.45, 0.5, 0.55);
+ TestCellOps(r5, S2Cell::FromFacePosLevel(0, 0, 0), 3);
+ TestCellOps(r5, S2Cell::FromFacePosLevel(0, 0, 1), 3);
+ TestCellOps(r5, S2Cell::FromFacePosLevel(1, 0, 1), 0);
+
+ // Rectangle consisting of a single point.
+ TestCellOps(MakeRect(0.51, 0.51, 0.51, 0.51),
+ S2Cell::FromFacePosLevel(0, 0, 0), 3);
+
+ // Rectangle that intersects the bounding rectangle of face 0
+ // but not the face itself.
+ TestCellOps(MakeRect(0.01, 1.001, 0.02, 1.002),
+ S2Cell::FromFacePosLevel(0, 0, 0), 0);
+
+ // Rectangle that intersects one corner of face 0.
+ TestCellOps(MakeRect(0.99, -0.01, 1.01, 0.01),
+ S2Cell::FromFacePosLevel(0, ~uint64(0) >> S2CellId::kFaceBits, 5),
+ 3);
+}
diff --git a/src/third_party/s2/s2region.cc b/src/third_party/s2/s2region.cc
new file mode 100644
index 00000000000..f2d7c02d921
--- /dev/null
+++ b/src/third_party/s2/s2region.cc
@@ -0,0 +1,10 @@
+// Copyright 2005 Google Inc. All Rights Reserved.
+
+#include "s2region.h"
+
+S2Region::~S2Region() {
+}
+
+bool S2Region::DecodeWithinScope(Decoder* const decoder) {
+ return Decode(decoder);
+}
diff --git a/src/third_party/s2/s2region.h b/src/third_party/s2/s2region.h
new file mode 100644
index 00000000000..afa7dcd9f5d
--- /dev/null
+++ b/src/third_party/s2/s2region.h
@@ -0,0 +1,101 @@
+// Copyright 2005 Google Inc. All Rights Reserved.
+
+#ifndef UTIL_GEOMETRY_S2REGION_H_
+#define UTIL_GEOMETRY_S2REGION_H_
+
+#include "s2.h"
+
+class Decoder;
+class Encoder;
+
+class S2Cap;
+class S2Cell;
+class S2LatLngRect;
+
+// An S2Region represents a two-dimensional region over the unit sphere.
+// It is an abstract interface with various concrete subtypes.
+//
+// The main purpose of this interface is to allow complex regions to be
+// approximated as simpler regions. So rather than having a wide variety
+// of virtual methods that are implemented by all subtypes, the interface
+// is restricted to methods that are useful for computing approximations.
+class S2Region {
+ public:
+ virtual ~S2Region();
+
+ // Return a deep copy of this region. If you want to narrow the result to a
+ // specific known region type, use down_cast<T*> from basictypes.h.
+ // Subtypes return pointers to that subtype from their Clone() methods.
+ virtual S2Region* Clone() const = 0;
+
+ // Return a bounding spherical cap. This is not guaranteed to be exact.
+ virtual S2Cap GetCapBound() const = 0;
+
+ // Return a bounding latitude-longitude rectangle that contains the region.
+ // The bounds are not guaranteed to be tight.
+ virtual S2LatLngRect GetRectBound() const = 0;
+
+ // If this method returns true, the region completely contains the given
+ // cell. Otherwise, either the region does not contain the cell or the
+ // containment relationship could not be determined.
+ virtual bool Contains(S2Cell const& cell) const = 0;
+
+ // If this method returns false, the region does not intersect the given
+ // cell. Otherwise, either region intersects the cell, or the intersection
+ // relationship could not be determined.
+ virtual bool MayIntersect(S2Cell const& cell) const = 0;
+
+ // Return true if and only if the given point is contained by the region.
+ // The point 'p' is generally required to be unit length, although some
+ // subtypes may relax this restriction.
+ // NOTE: If you will be calling this function on one specific subtype only,
+ // or if performance is a consideration, please use the non-virtual
+ // method Contains(S2Point const& p) declared below!
+ virtual bool VirtualContainsPoint(S2Point const& p) const = 0;
+
+ // Use encoder to generate a serialized representation of this region.
+ // Assumes that encoder can be enlarged using calls to Ensure(int).
+ //
+ // The representation chosen is left up to the sub-classes but it should
+ // satisfy the following constraints:
+ // - It should encode a version number.
+ // - It should be deserializable using the corresponding Decode method.
+ // - Performance, not space, should be the chief consideration. Encode() and
+ // Decode() should be implemented such that the combination is equivalent
+ // to calling Clone().
+ virtual void Encode(Encoder* const encoder) const = 0;
+
+ // Reconstruct a region from the serialized representation generated by
+ // Encode(). Note that since this method is virtual, it requires that a
+ // Region object of the appropriate concrete type has already been
+ // constructed. It is not possible to decode regions of unknown type.
+ //
+ // Whenever the Decode method is changed to deal with new serialized
+ // representations, it should be done so in a manner that allows for
+ // older versions to be decoded i.e. the version number in the serialized
+ // representation should be used to decide how to decode the data.
+ //
+ // Returns true on success.
+ virtual bool Decode(Decoder* const decoder) = 0;
+
+ // Provide the same functionality as Decode, except that decoded regions are
+ // allowed to point directly into the Decoder's memory buffer rather than
+ // copying the data. This method can be much faster for regions that have
+ // a lot of data (such as polygons), but the decoded region is only valid
+ // within the scope (lifetime) of the Decoder's memory buffer.
+ // Default implementation just calls Decode.
+ virtual bool DecodeWithinScope(Decoder* const decoder);
+
+ /////////////////////////////////////////////////////////////////////////
+ // The following are NON-VIRTUAL methods (for efficiency reasons) that
+ // happen to be implemented by all subclasses. You cannot call these
+ // methods unless you have an object of a particular subtype.
+ //
+ // bool Contains(S2Point const& p) const;
+ //
+ // Return true if and only if the given point is contained by the region.
+ // The point 'p' is generally required to be unit length, although some
+ // subtypes may relax this restriction.
+};
+
+#endif // UTIL_GEOMETRY_S2REGION_H_
diff --git a/src/third_party/s2/s2regioncoverer.cc b/src/third_party/s2/s2regioncoverer.cc
new file mode 100644
index 00000000000..0d01be43561
--- /dev/null
+++ b/src/third_party/s2/s2regioncoverer.cc
@@ -0,0 +1,359 @@
+// Copyright 2005 Google Inc. All Rights Reserved.
+
+#include "s2regioncoverer.h"
+
+#ifndef OS_WINDOWS
+#include <pthread.h>
+#endif
+
+#include <algorithm>
+using std::min;
+using std::max;
+using std::swap;
+using std::reverse;
+
+#include <functional>
+using std::less;
+
+#include <queue>
+using std::priority_queue;
+
+#include <vector>
+using std::vector;
+
+
+#include "base/logging.h"
+#include "s2.h"
+#include "s2cap.h"
+#include "s2cellunion.h"
+
+// Define storage for header file constants (the values are not needed here).
+int const S2RegionCoverer::kDefaultMaxCells = 8;
+
+// We define our own own comparison function on QueueEntries in order to
+// make the results deterministic. Using the default less<QueueEntry>,
+// entries of equal priority would be sorted according to the memory address
+// of the candidate.
+
+struct S2RegionCoverer::CompareQueueEntries : public less<QueueEntry> {
+ bool operator()(QueueEntry const& x, QueueEntry const& y) {
+ return x.first < y.first;
+ }
+};
+
+static S2Cell face_cells[6];
+
+static int Init() {
+ for (int face = 0; face < 6; ++face) {
+ face_cells[face] = S2Cell::FromFacePosLevel(face, 0, 0);
+ }
+ // arbitrary value. We want this to be called without pthread_once, so we populate
+ // a variable with the return value of this function.
+ return 5;
+}
+
+#ifndef _WIN32
+static pthread_once_t init_once = PTHREAD_ONCE_INIT;
+static void voidInit() { Init(); }
+inline static void MaybeInit() {
+ pthread_once(&init_once, voidInit);
+}
+#else
+static const int foo = Init();
+inline static void MaybeInit() { }
+#endif
+
+S2RegionCoverer::S2RegionCoverer() :
+ min_level_(0),
+ max_level_(S2CellId::kMaxLevel),
+ level_mod_(1),
+ max_cells_(kDefaultMaxCells),
+ region_(NULL),
+ result_(new vector<S2CellId>),
+ pq_(new CandidateQueue) {
+ // Initialize the constants
+ MaybeInit();
+}
+
+S2RegionCoverer::~S2RegionCoverer() {
+ // Need to declare explicitly because of scoped pointers.
+}
+
+void S2RegionCoverer::set_min_level(int min_level) {
+ DCHECK_GE(min_level, 0);
+ DCHECK_LE(min_level, S2CellId::kMaxLevel);
+ min_level_ = max(0, min(S2CellId::kMaxLevel, min_level));
+}
+
+void S2RegionCoverer::set_max_level(int max_level) {
+ DCHECK_GE(max_level, 0);
+ DCHECK_LE(max_level, S2CellId::kMaxLevel);
+ max_level_ = max(0, min(S2CellId::kMaxLevel, max_level));
+}
+
+void S2RegionCoverer::set_level_mod(int level_mod) {
+ DCHECK_GE(level_mod, 1);
+ DCHECK_LE(level_mod, 3);
+ level_mod_ = max(1, min(3, level_mod));
+}
+
+void S2RegionCoverer::set_max_cells(int max_cells) {
+ max_cells_ = max_cells;
+}
+
+S2RegionCoverer::Candidate* S2RegionCoverer::NewCandidate(S2Cell const& cell) {
+ if (!region_->MayIntersect(cell)) return NULL;
+
+ bool is_terminal = false;
+ size_t size = sizeof(Candidate);
+ if (cell.level() >= min_level_) {
+ if (interior_covering_) {
+ if (region_->Contains(cell)) {
+ is_terminal = true;
+ } else if (cell.level() + level_mod_ > max_level_) {
+ return NULL;
+ }
+ } else {
+ if (cell.level() + level_mod_ > max_level_ || region_->Contains(cell)) {
+ is_terminal = true;
+ }
+ }
+ }
+ if (!is_terminal) {
+ size += sizeof(Candidate*) << max_children_shift();
+ }
+ Candidate* candidate = static_cast<Candidate*>(malloc(size));
+ memset(candidate, 0, size);
+ candidate->cell = cell;
+ candidate->is_terminal = is_terminal;
+ ++candidates_created_counter_;
+ return candidate;
+}
+
+void S2RegionCoverer::DeleteCandidate(Candidate* candidate,
+ bool delete_children) {
+ if (delete_children) {
+ for (int i = 0; i < candidate->num_children; ++i)
+ DeleteCandidate(candidate->children[i], true);
+ }
+ free(candidate);
+}
+
+int S2RegionCoverer::ExpandChildren(Candidate* candidate,
+ S2Cell const& cell, int num_levels) {
+ num_levels--;
+ S2Cell child_cells[4];
+ cell.Subdivide(child_cells);
+ int num_terminals = 0;
+ for (int i = 0; i < 4; ++i) {
+ if (num_levels > 0) {
+ if (region_->MayIntersect(child_cells[i])) {
+ num_terminals += ExpandChildren(candidate, child_cells[i], num_levels);
+ }
+ continue;
+ }
+ Candidate* child = NewCandidate(child_cells[i]);
+ if (child) {
+ candidate->children[candidate->num_children++] = child;
+ if (child->is_terminal) ++num_terminals;
+ }
+ }
+ return num_terminals;
+}
+
+void S2RegionCoverer::AddCandidate(Candidate* candidate) {
+ if (candidate == NULL) return;
+
+ if (candidate->is_terminal) {
+ result_->push_back(candidate->cell.id());
+ DeleteCandidate(candidate, true);
+ return;
+ }
+ DCHECK_EQ(0, candidate->num_children);
+
+ // Expand one level at a time until we hit min_level_ to ensure that
+ // we don't skip over it.
+ int num_levels = (candidate->cell.level() < min_level_) ? 1 : level_mod_;
+ int num_terminals = ExpandChildren(candidate, candidate->cell, num_levels);
+
+ if (candidate->num_children == 0) {
+ DeleteCandidate(candidate, false);
+
+ } else if (!interior_covering_ &&
+ num_terminals == 1 << max_children_shift() &&
+ candidate->cell.level() >= min_level_) {
+ // Optimization: add the parent cell rather than all of its children.
+ // We can't do this for interior coverings, since the children just
+ // intersect the region, but may not be contained by it - we need to
+ // subdivide them further.
+ candidate->is_terminal = true;
+ AddCandidate(candidate);
+
+ } else {
+ // We negate the priority so that smaller absolute priorities are returned
+ // first. The heuristic is designed to refine the largest cells first,
+ // since those are where we have the largest potential gain. Among cells
+ // at the same level, we prefer the cells with the smallest number of
+ // intersecting children. Finally, we prefer cells that have the smallest
+ // number of children that cannot be refined any further.
+ int priority = -((((candidate->cell.level() << max_children_shift())
+ + candidate->num_children) << max_children_shift())
+ + num_terminals);
+ pq_->push(make_pair(priority, candidate));
+ VLOG(2) << "Push: " << candidate->cell.id() << " (" << priority << ") ";
+ }
+}
+
+void S2RegionCoverer::GetInitialCandidates() {
+ // Optimization: if at least 4 cells are desired (the normal case),
+ // start with a 4-cell covering of the region's bounding cap. This
+ // lets us skip quite a few levels of refinement when the region to
+ // be covered is relatively small.
+ if (max_cells() >= 4) {
+ // Find the maximum level such that the bounding cap contains at most one
+ // cell vertex at that level.
+ S2Cap cap = region_->GetCapBound();
+ int level = min(S2::kMinWidth.GetMaxLevel(2 * cap.angle().radians()),
+ min(max_level(), S2CellId::kMaxLevel - 1));
+ if (level_mod() > 1 && level > min_level()) {
+ level -= (level - min_level()) % level_mod();
+ }
+ // We don't bother trying to optimize the level == 0 case, since more than
+ // four face cells may be required.
+ if (level > 0) {
+ // Find the leaf cell containing the cap axis, and determine which
+ // subcell of the parent cell contains it.
+ vector<S2CellId> base;
+ base.reserve(4);
+ S2CellId id = S2CellId::FromPoint(cap.axis());
+ id.AppendVertexNeighbors(level, &base);
+ for (size_t i = 0; i < base.size(); ++i) {
+ AddCandidate(NewCandidate(S2Cell(base[i])));
+ }
+ return;
+ }
+ }
+ // Default: start with all six cube faces.
+ for (size_t face = 0; face < 6; ++face) {
+ AddCandidate(NewCandidate(face_cells[face]));
+ }
+}
+
+void S2RegionCoverer::GetCoveringInternal(S2Region const& region) {
+ // Strategy: Start with the 6 faces of the cube. Discard any
+ // that do not intersect the shape. Then repeatedly choose the
+ // largest cell that intersects the shape and subdivide it.
+ //
+ // result_ contains the cells that will be part of the output, while pq_
+ // contains cells that we may still subdivide further. Cells that are
+ // entirely contained within the region are immediately added to the output,
+ // while cells that do not intersect the region are immediately discarded.
+ // Therefore pq_ only contains cells that partially intersect the region.
+ // Candidates are prioritized first according to cell size (larger cells
+ // first), then by the number of intersecting children they have (fewest
+ // children first), and then by the number of fully contained children
+ // (fewest children first).
+
+ DCHECK(pq_->empty());
+ DCHECK(result_->empty());
+ region_ = &region;
+ candidates_created_counter_ = 0;
+
+ GetInitialCandidates();
+ while (!pq_->empty() &&
+ (!interior_covering_ || result_->size() < (size_t)max_cells_)) {
+ Candidate* candidate = pq_->top().second;
+ pq_->pop();
+ VLOG(2) << "Pop: " << candidate->cell.id();
+ if (candidate->cell.level() < min_level_ ||
+ candidate->num_children == 1 ||
+ (int)result_->size() + (int)(interior_covering_ ? 0 : (int)pq_->size()) +
+ candidate->num_children <= max_cells_) {
+ // Expand this candidate into its children.
+ for (int i = 0; i < candidate->num_children; ++i) {
+ AddCandidate(candidate->children[i]);
+ }
+ DeleteCandidate(candidate, false);
+ } else if (interior_covering_) {
+ DeleteCandidate(candidate, true);
+ } else {
+ candidate->is_terminal = true;
+ AddCandidate(candidate);
+ }
+ }
+ VLOG(2) << "Created " << result_->size() << " cells, " <<
+ candidates_created_counter_ << " candidates created, " <<
+ pq_->size() << " left";
+ while (!pq_->empty()) {
+ DeleteCandidate(pq_->top().second, true);
+ pq_->pop();
+ }
+ region_ = NULL;
+}
+
+void S2RegionCoverer::GetCovering(S2Region const& region,
+ vector<S2CellId>* covering) {
+
+ // Rather than just returning the raw list of cell ids generated by
+ // GetCoveringInternal(), we construct a cell union and then denormalize it.
+ // This has the effect of replacing four child cells with their parent
+ // whenever this does not violate the covering parameters specified
+ // (min_level, level_mod, etc). This strategy significantly reduces the
+ // number of cells returned in many cases, and it is cheap compared to
+ // computing the covering in the first place.
+
+ S2CellUnion tmp;
+ GetCellUnion(region, &tmp);
+ tmp.Denormalize(min_level(), level_mod(), covering);
+}
+
+void S2RegionCoverer::GetInteriorCovering(S2Region const& region,
+ vector<S2CellId>* interior) {
+ S2CellUnion tmp;
+ GetInteriorCellUnion(region, &tmp);
+ tmp.Denormalize(min_level(), level_mod(), interior);
+}
+
+void S2RegionCoverer::GetCellUnion(S2Region const& region,
+ S2CellUnion* covering) {
+ interior_covering_ = false;
+ GetCoveringInternal(region);
+ covering->InitSwap(result_.get());
+}
+
+void S2RegionCoverer::GetInteriorCellUnion(S2Region const& region,
+ S2CellUnion* interior) {
+ interior_covering_ = true;
+ GetCoveringInternal(region);
+ interior->InitSwap(result_.get());
+}
+
+void S2RegionCoverer::FloodFill(
+ S2Region const& region, S2CellId const& start, vector<S2CellId>* output) {
+ hash_set<S2CellId> all;
+ vector<S2CellId> frontier;
+ output->clear();
+ all.insert(start);
+ frontier.push_back(start);
+ while (!frontier.empty()) {
+ S2CellId id = frontier.back();
+ frontier.pop_back();
+ if (!region.MayIntersect(S2Cell(id))) continue;
+ output->push_back(id);
+
+ S2CellId neighbors[4];
+ id.GetEdgeNeighbors(neighbors);
+ for (int edge = 0; edge < 4; ++edge) {
+ S2CellId nbr = neighbors[edge];
+ if (all.insert(nbr).second) {
+ frontier.push_back(nbr);
+ }
+ }
+ }
+}
+
+void S2RegionCoverer::GetSimpleCovering(
+ S2Region const& region, S2Point const& start,
+ int level, vector<S2CellId>* output) {
+ return FloodFill(region, S2CellId::FromPoint(start).parent(level), output);
+}
diff --git a/src/third_party/s2/s2regioncoverer.h b/src/third_party/s2/s2regioncoverer.h
new file mode 100644
index 00000000000..728a1d08f9f
--- /dev/null
+++ b/src/third_party/s2/s2regioncoverer.h
@@ -0,0 +1,211 @@
+// Copyright 2005 Google Inc. All Rights Reserved.
+
+#ifndef UTIL_GEOMETRY_S2REGION_COVERER_H_
+#define UTIL_GEOMETRY_S2REGION_COVERER_H_
+
+#include <queue>
+using std::priority_queue;
+
+#include <utility>
+using std::pair;
+using std::make_pair;
+
+#include <vector>
+using std::vector;
+
+#include "base/macros.h"
+#include <boost/scoped_ptr.hpp>
+using boost::scoped_ptr;
+//#include "base/scoped_ptr.h"
+#include "s2cell.h"
+#include "s2cellid.h"
+
+class S2CellUnion;
+
+// An S2RegionCoverer is a class that allows arbitrary regions to be
+// approximated as unions of cells (S2CellUnion). This is useful for
+// implementing various sorts of search and precomputation operations.
+//
+// Typical usage:
+//
+// S2RegionCoverer coverer;
+// coverer.set_max_cells(5);
+// S2Cap cap = S2Cap::FromAxisAngle(...);
+// vector<S2CellId> covering;
+// coverer.GetCovering(cap, &covering);
+//
+// This yields a vector of at most 5 cells that is guaranteed to cover the
+// given cap (a disc-shaped region on the sphere).
+//
+// The approximation algorithm is not optimal but does a pretty good job in
+// practice. The output does not always use the maximum number of cells
+// allowed, both because this would not always yield a better approximation,
+// and because max_cells() is a limit on how much work is done exploring the
+// possible covering as well as a limit on the final output size.
+//
+// One can also generate interior coverings, which are sets of cells which
+// are entirely contained within a region. Interior coverings can be
+// empty, even for non-empty regions, if there are no cells that satisfy
+// the provided constraints and are contained by the region. Note that for
+// performance reasons, it is wise to specify a max_level when computing
+// interior coverings - otherwise for regions with small or zero area, the
+// algorithm may spend a lot of time subdividing cells all the way to leaf
+// level to try to find contained cells.
+class S2RegionCoverer {
+ public:
+ // By default, the covering uses at most 8 cells at any level. This gives
+ // a reasonable tradeoff between the number of cells used and the accuracy
+ // of the approximation (see table below).
+ static int const kDefaultMaxCells;
+
+ S2RegionCoverer();
+ ~S2RegionCoverer();
+
+ // Set the minimum and maximum cell level to be used. The default is to use
+ // all cell levels. Requires: max_level() >= min_level().
+ //
+ // To find the cell level corresponding to a given physical distance, use
+ // the S2Cell metrics defined in s2.h. For example, to find the cell
+ // level that corresponds to an average edge length of 10km, use:
+ //
+ // int level = S2::kAvgEdge.GetClosestLevel(
+ // geostore::S2Earth::KmToRadians(length_km));
+ //
+ // Note: min_level() takes priority over max_cells(), i.e. cells below the
+ // given level will never be used even if this causes a large number of
+ // cells to be returned.
+ void set_min_level(int min_level);
+ void set_max_level(int max_level);
+ int min_level() const { return min_level_; }
+ int max_level() const { return max_level_; }
+
+ // If specified, then only cells where (level - min_level) is a multiple of
+ // "level_mod" will be used (default 1). This effectively allows the
+ // branching factor of the S2CellId hierarchy to be increased. Currently
+ // the only parameter values allowed are 1, 2, or 3, corresponding to
+ // branching factors of 4, 16, and 64 respectively.
+ void set_level_mod(int level_mod);
+ int level_mod() const { return level_mod_; }
+
+ // Sets the maximum desired number of cells in the approximation (defaults
+ // to kDefaultMaxCells). Note the following:
+ //
+ // - For any setting of max_cells(), up to 6 cells may be returned if that
+ // is the minimum number of cells required (e.g. if the region intersects
+ // all six face cells). Up to 3 cells may be returned even for very tiny
+ // convex regions if they happen to be located at the intersection of
+ // three cube faces.
+ //
+ // - For any setting of max_cells(), an arbitrary number of cells may be
+ // returned if min_level() is too high for the region being approximated.
+ //
+ // - If max_cells() is less than 4, the area of the covering may be
+ // arbitrarily large compared to the area of the original region even if
+ // the region is convex (e.g. an S2Cap or S2LatLngRect).
+ //
+ // Accuracy is measured by dividing the area of the covering by the area of
+ // the original region. The following table shows the median and worst case
+ // values for this area ratio on a test case consisting of 100,000 spherical
+ // caps of random size (generated using s2regioncoverer_unittest):
+ //
+ // max_cells: 3 4 5 6 8 12 20 100 1000
+ // median ratio: 5.33 3.32 2.73 2.34 1.98 1.66 1.42 1.11 1.01
+ // worst case: 215518 14.41 9.72 5.26 3.91 2.75 1.92 1.20 1.02
+ void set_max_cells(int max_cells);
+ int max_cells() const { return max_cells_; }
+
+ // Return a vector of cell ids that covers (GetCovering) or is contained
+ // within (GetInteriorCovering) the given region and satisfies the various
+ // restrictions specified above.
+ void GetCovering(S2Region const& region, vector<S2CellId>* covering);
+ void GetInteriorCovering(S2Region const& region, vector<S2CellId>* interior);
+
+ // Return a normalized cell union that covers (GetCellUnion) or is contained
+ // within (GetInteriorCellUnion) the given region and satisfies the
+ // restrictions *EXCEPT* for min_level() and level_mod(). These criteria
+ // cannot be satisfied using a cell union because cell unions are
+ // automatically normalized by replacing four child cells with their parent
+ // whenever possible. (Note that the list of cell ids passed to the cell
+ // union constructor does in fact satisfy all the given restrictions.)
+ void GetCellUnion(S2Region const& region, S2CellUnion* covering);
+ void GetInteriorCellUnion(S2Region const& region, S2CellUnion* interior);
+
+ // Given a connected region and a starting point, return a set of cells at
+ // the given level that cover the region.
+ static void GetSimpleCovering(S2Region const& region, S2Point const& start,
+ int level, vector<S2CellId>* output);
+
+ private:
+ struct Candidate {
+ S2Cell cell;
+ bool is_terminal; // Cell should not be expanded further.
+ int num_children; // Number of children that intersect the region.
+ Candidate* children[0]; // Actual size may be 0, 4, 16, or 64 elements.
+ };
+
+ // If the cell intersects the given region, return a new candidate with no
+ // children, otherwise return NULL. Also marks the candidate as "terminal"
+ // if it should not be expanded further.
+ Candidate* NewCandidate(S2Cell const& cell);
+
+ // Return the log base 2 of the maximum number of children of a candidate.
+ inline int max_children_shift() const { return 2 * level_mod_; }
+
+ // Free the memory associated with a candidate.
+ static void DeleteCandidate(Candidate* candidate, bool delete_children);
+
+ // Process a candidate by either adding it to the result_ vector or
+ // expanding its children and inserting it into the priority queue.
+ // Passing an argument of NULL does nothing.
+ void AddCandidate(Candidate* candidate);
+
+ // Populate the children of "candidate" by expanding the given number of
+ // levels from the given cell. Returns the number of children that were
+ // marked "terminal".
+ int ExpandChildren(Candidate* candidate, S2Cell const& cell, int num_levels);
+
+ // Computes a set of initial candidates that cover the given region.
+ void GetInitialCandidates();
+
+ // Generates a covering and stores it in result_.
+ void GetCoveringInternal(S2Region const& region);
+
+ // Given a region and a starting cell, return the set of all the
+ // edge-connected cells at the same level that intersect "region".
+ // The output cells are returned in arbitrary order.
+ static void FloodFill(S2Region const& region, S2CellId const& start,
+ vector<S2CellId>* output);
+
+ int min_level_;
+ int max_level_;
+ int level_mod_;
+ int max_cells_;
+
+ // We save a temporary copy of the pointer passed to GetCovering() in order
+ // to avoid passing this parameter around internally. It is only used (and
+ // only valid) for the duration of a single GetCovering() call.
+ S2Region const* region_;
+
+ // A temporary variable used by GetCovering() that holds the cell ids that
+ // have been added to the covering so far.
+ scoped_ptr<vector<S2CellId> > result_;
+
+ // We keep the candidates in a priority queue. We specify a vector to hold
+ // the queue entries since for some reason priority_queue<> uses a deque by
+ // default.
+ struct CompareQueueEntries;
+ typedef pair<int, Candidate*> QueueEntry;
+ typedef priority_queue<QueueEntry, vector<QueueEntry>,
+ CompareQueueEntries> CandidateQueue;
+ scoped_ptr<CandidateQueue> pq_;
+
+ // True if we're computing an interior covering.
+ bool interior_covering_;
+
+ // Counter of number of candidates created, for performance evaluation.
+ int candidates_created_counter_;
+
+ DISALLOW_EVIL_CONSTRUCTORS(S2RegionCoverer);
+};
+
+#endif // UTIL_GEOMETRY_S2REGION_COVERER_H_
diff --git a/src/third_party/s2/s2regioncoverer_test.cc b/src/third_party/s2/s2regioncoverer_test.cc
new file mode 100644
index 00000000000..d2ad9f5cd5e
--- /dev/null
+++ b/src/third_party/s2/s2regioncoverer_test.cc
@@ -0,0 +1,290 @@
+// Copyright 2005 Google Inc. All Rights Reserved.
+
+#include "s2regioncoverer.h"
+
+#include <stdio.h>
+
+#include <algorithm>
+using std::min;
+using std::max;
+using std::swap;
+using std::reverse;
+
+#include <hash_map>
+using __gnu_cxx::hash_map;
+
+#include <queue>
+using std::priority_queue;
+
+#include <string>
+using std::string;
+
+#include <vector>
+using std::vector;
+
+
+#include "base/commandlineflags.h"
+#include "base/logging.h"
+#include "base/strtoint.h"
+#include "strings/split.h"
+#include "strings/stringprintf.h"
+#include "testing/base/public/benchmark.h"
+#include "testing/base/public/gunit.h"
+#include "s2cap.h"
+#include "s2cell.h"
+#include "s2cellid.h"
+#include "s2cellunion.h"
+#include "s2latlng.h"
+#include "s2loop.h"
+#include "s2testing.h"
+
+DEFINE_string(max_cells, "4,8",
+ "Comma-separated list of values to use for 'max_cells'");
+
+DEFINE_int32(iters, DEBUG_MODE ? 1000 : 100000,
+ "Number of random caps to try for each max_cells value");
+
+TEST(S2RegionCoverer, RandomCells) {
+ S2RegionCoverer coverer;
+ coverer.set_max_cells(1);
+
+ // Test random cell ids at all levels.
+ for (int i = 0; i < 10000; ++i) {
+ S2CellId id = S2Testing::GetRandomCellId();
+ SCOPED_TRACE(StringPrintf("Iteration %d, cell ID token %s",
+ i, id.ToToken().c_str()));
+ vector<S2CellId> covering;
+ coverer.GetCovering(S2Cell(id), &covering);
+ EXPECT_EQ(covering.size(), 1);
+ EXPECT_EQ(covering[0], id);
+ }
+}
+
+static void CheckCovering(S2RegionCoverer const& coverer,
+ S2Region const& region,
+ vector<S2CellId> const& covering,
+ bool interior) {
+ // Keep track of how many cells have the same coverer.min_level() ancestor.
+ hash_map<S2CellId, int> min_level_cells;
+ for (int i = 0; i < covering.size(); ++i) {
+ int level = covering[i].level();
+ EXPECT_GE(level, coverer.min_level());
+ EXPECT_LE(level, coverer.max_level());
+ EXPECT_EQ((level - coverer.min_level()) % coverer.level_mod(), 0);
+ min_level_cells[covering[i].parent(coverer.min_level())] += 1;
+ }
+ if (covering.size() > coverer.max_cells()) {
+ // If the covering has more than the requested number of cells, then check
+ // that the cell count cannot be reduced by using the parent of some cell.
+ for (hash_map<S2CellId, int>::const_iterator i = min_level_cells.begin();
+ i != min_level_cells.end(); ++i) {
+ EXPECT_EQ(i->second, 1);
+ }
+ }
+ if (interior) {
+ for (int i = 0; i < covering.size(); ++i) {
+ EXPECT_TRUE(region.Contains(S2Cell(covering[i])));
+ }
+ } else {
+ S2CellUnion cell_union;
+ cell_union.Init(covering);
+ S2Testing::CheckCovering(region, cell_union, true);
+ }
+}
+
+TEST(S2RegionCoverer, RandomCaps) {
+ static int const kMaxLevel = S2CellId::kMaxLevel;
+ S2RegionCoverer coverer;
+ for (int i = 0; i < 1000; ++i) {
+ do {
+ coverer.set_min_level(S2Testing::rnd.Uniform(kMaxLevel + 1));
+ coverer.set_max_level(S2Testing::rnd.Uniform(kMaxLevel + 1));
+ } while (coverer.min_level() > coverer.max_level());
+ coverer.set_max_cells(S2Testing::rnd.Skewed(10));
+ coverer.set_level_mod(1 + S2Testing::rnd.Uniform(3));
+ double max_area = min(4 * M_PI, (3 * coverer.max_cells() + 1) *
+ S2Cell::AverageArea(coverer.min_level()));
+ S2Cap cap = S2Testing::GetRandomCap(0.1 * S2Cell::AverageArea(kMaxLevel),
+ max_area);
+ vector<S2CellId> covering, interior;
+ coverer.GetCovering(cap, &covering);
+ CheckCovering(coverer, cap, covering, false);
+ coverer.GetInteriorCovering(cap, &interior);
+ CheckCovering(coverer, cap, interior, true);
+
+ // Check that GetCovering is deterministic.
+ vector<S2CellId> covering2;
+ coverer.GetCovering(cap, &covering2);
+ EXPECT_EQ(covering, covering2);
+
+ // Also check S2CellUnion::Denormalize(). The denormalized covering
+ // may still be different and smaller than "covering" because
+ // S2RegionCoverer does not guarantee that it will not output all four
+ // children of the same parent.
+ S2CellUnion cells;
+ cells.Init(covering);
+ vector<S2CellId> denormalized;
+ cells.Denormalize(coverer.min_level(), coverer.level_mod(), &denormalized);
+ CheckCovering(coverer, cap, denormalized, false);
+ }
+}
+
+TEST(S2RegionCoverer, SimpleCoverings) {
+ static int const kMaxLevel = S2CellId::kMaxLevel;
+ S2RegionCoverer coverer;
+ coverer.set_max_cells(kint32max);
+ for (int i = 0; i < 1000; ++i) {
+ int level = S2Testing::rnd.Uniform(kMaxLevel + 1);
+ coverer.set_min_level(level);
+ coverer.set_max_level(level);
+ double max_area = min(4 * M_PI, 1000 * S2Cell::AverageArea(level));
+ S2Cap cap = S2Testing::GetRandomCap(0.1 * S2Cell::AverageArea(kMaxLevel),
+ max_area);
+ vector<S2CellId> covering;
+ S2RegionCoverer::GetSimpleCovering(cap, cap.axis(), level, &covering);
+ CheckCovering(coverer, cap, covering, false);
+ }
+}
+
+// We keep a priority queue of the caps that had the worst approximation
+// ratios so that we can print them at the end.
+struct WorstCap {
+ double ratio;
+ S2Cap cap;
+ int num_cells;
+ bool operator<(WorstCap const& o) const { return ratio > o.ratio; }
+ WorstCap(double r, S2Cap c, int n) : ratio(r), cap(c), num_cells(n) {}
+};
+
+static void TestAccuracy(int max_cells) {
+ SCOPED_TRACE(StringPrintf("%d cells", max_cells));
+
+ static int const kNumMethods = 1;
+ // This code is designed to evaluate several approximation algorithms and
+ // figure out which one works better. The way to do this is to hack the
+ // S2RegionCoverer interface to add a global variable to control which
+ // algorithm (or variant of an algorithm) is selected, and then assign to
+ // this variable in the "method" loop below. The code below will then
+ // collect statistics on all methods, including how often each one wins in
+ // terms of cell count and approximation area.
+
+ S2RegionCoverer coverer;
+ coverer.set_max_cells(max_cells);
+
+ double ratio_total[kNumMethods] = {0};
+ double min_ratio[kNumMethods]; // initialized in loop below
+ double max_ratio[kNumMethods] = {0};
+ vector<double> ratios[kNumMethods];
+ int cell_total[kNumMethods] = {0};
+ int area_winner_tally[3] = {0};
+ int cell_winner_tally[3] = {0};
+ for (int method = 0; method < kNumMethods; ++method) {
+ min_ratio[method] = 1e20;
+ }
+
+ priority_queue<WorstCap> worst_caps;
+ static int const kMaxWorstCaps = 10;
+
+ for (int i = 0; i < FLAGS_iters; ++i) {
+ // Choose the log of the cap area to be uniformly distributed over
+ // the allowable range. Don't try to approximate regions that are so
+ // small they can't use the given maximum number of cells efficiently.
+ double const min_cap_area = S2Cell::AverageArea(S2CellId::kMaxLevel)
+ * max_cells * max_cells;
+ S2Cap cap = S2Testing::GetRandomCap(min_cap_area, 4 * M_PI);
+ double cap_area = cap.area();
+
+ double min_area = 1e30;
+ int min_cells = 1 << 30;
+ double area[kNumMethods];
+ int cells[kNumMethods];
+ for (int method = 0; method < kNumMethods; ++method) {
+ // If you want to play with different methods, do this:
+ // S2RegionCoverer::method_number = method;
+
+ vector<S2CellId> covering;
+ coverer.GetCovering(cap, &covering);
+
+ double union_area = 0;
+ for (int j = 0; j < covering.size(); ++j) {
+ union_area += S2Cell(covering[j]).ExactArea();
+ }
+ cells[method] = covering.size();
+ min_cells = min(cells[method], min_cells);
+ area[method] = union_area;
+ min_area = min(area[method], min_area);
+ cell_total[method] += cells[method];
+ double ratio = area[method] / cap_area;
+ ratio_total[method] += ratio;
+ min_ratio[method] = min(ratio, min_ratio[method]);
+ max_ratio[method] = max(ratio, max_ratio[method]);
+ ratios[method].push_back(ratio);
+ if (worst_caps.size() < kMaxWorstCaps) {
+ worst_caps.push(WorstCap(ratio, cap, cells[method]));
+ } else if (ratio > worst_caps.top().ratio) {
+ worst_caps.pop();
+ worst_caps.push(WorstCap(ratio, cap, cells[method]));
+ }
+ }
+ for (int method = 0; method < kNumMethods; ++method) {
+ if (area[method] == min_area) ++area_winner_tally[method];
+ if (cells[method] == min_cells) ++cell_winner_tally[method];
+ }
+ }
+ for (int method = 0; method < kNumMethods; ++method) {
+ printf("\nMax cells %d, method %d:\n", max_cells, method);
+ printf(" Average cells: %.4f\n", cell_total[method] /
+ static_cast<double>(FLAGS_iters));
+ printf(" Average area ratio: %.4f\n", ratio_total[method] / FLAGS_iters);
+ vector<double>& mratios = ratios[method];
+ sort(mratios.begin(), mratios.end());
+ printf(" Median ratio: %.4f\n", mratios[mratios.size() / 2]);
+ printf(" Max ratio: %.4f\n", max_ratio[method]);
+ printf(" Min ratio: %.4f\n", min_ratio[method]);
+ if (kNumMethods > 1) {
+ printf(" Cell winner probability: %.4f\n",
+ cell_winner_tally[method] / static_cast<double>(FLAGS_iters));
+ printf(" Area winner probability: %.4f\n",
+ area_winner_tally[method] / static_cast<double>(FLAGS_iters));
+ }
+ printf(" Caps with worst approximation ratios:\n");
+ for (; !worst_caps.empty(); worst_caps.pop()) {
+ WorstCap const& w = worst_caps.top();
+ S2LatLng ll(w.cap.axis());
+ printf(" Ratio %.4f, Cells %d, "
+ "Center (%.8f, %.8f), Km %.6f\n",
+ w.ratio, w.num_cells,
+ ll.lat().degrees(), ll.lng().degrees(),
+ w.cap.angle().radians() * 6367.0);
+ }
+ }
+}
+
+TEST(S2RegionCoverer, Accuracy) {
+ vector<string> max_cells;
+ SplitStringUsing(FLAGS_max_cells, ",", &max_cells);
+ for (int i = 0; i < max_cells.size(); ++i) {
+ TestAccuracy(atoi32(max_cells[i].c_str()));
+ }
+}
+
+
+// Two concentric loops don't cross so there is no 'fast exit'
+static void BM_Covering(int iters, int max_cells, int num_vertices) {
+ StopBenchmarkTiming();
+ S2RegionCoverer coverer;
+ coverer.set_max_cells(max_cells);
+
+ for (int i = 0; i < iters; ++i) {
+ S2Point center = S2Testing::RandomPoint();
+ S2Loop* loop = S2Testing::MakeRegularLoop(center, num_vertices, 0.005);
+
+ StartBenchmarkTiming();
+ vector<S2CellId> covering;
+ coverer.GetCovering(*loop, &covering);
+ StopBenchmarkTiming();
+
+ delete loop;
+ }
+}
+BENCHMARK(BM_Covering)->RangePair(8, 1024, 8, 1<<17);
diff --git a/src/third_party/s2/s2regionintersection.cc b/src/third_party/s2/s2regionintersection.cc
new file mode 100644
index 00000000000..d4c435f195b
--- /dev/null
+++ b/src/third_party/s2/s2regionintersection.cc
@@ -0,0 +1,84 @@
+// Copyright 2006 Google Inc. All Rights Reserved.
+
+#include "s2regionintersection.h"
+
+#include "s2cap.h"
+#include "s2cell.h"
+#include "s2latlngrect.h"
+
+S2RegionIntersection::S2RegionIntersection() { }
+
+S2RegionIntersection::S2RegionIntersection(vector<S2Region*>* regions) {
+ Init(regions);
+}
+
+S2RegionIntersection::~S2RegionIntersection() {
+ for (size_t i = 0; i < regions_.size(); ++i) {
+ delete regions_[i];
+ }
+ regions_.clear();
+}
+
+void S2RegionIntersection::Init(vector<S2Region*>* regions) {
+ DCHECK(regions_.empty());
+ // We copy the vector rather than calling swap() to optimize storage.
+ regions_ = *regions;
+ regions->clear();
+}
+
+S2RegionIntersection::S2RegionIntersection(S2RegionIntersection const* src)
+ : regions_(src->num_regions()) {
+ for (int i = 0; i < num_regions(); ++i) {
+ regions_[i] = src->region(i)->Clone();
+ }
+}
+
+void S2RegionIntersection::Release(vector<S2Region*>* regions) {
+ if (regions != NULL) {
+ regions->insert(regions->end(), regions_.begin(), regions_.end());
+ }
+ regions_.clear();
+}
+
+S2RegionIntersection* S2RegionIntersection::Clone() const {
+ return new S2RegionIntersection(this);
+}
+
+S2Cap S2RegionIntersection::GetCapBound() const {
+ // TODO: This could be optimized to return a tighter bound, but doesn't
+ // seem worth it unless profiling shows otherwise.
+ return GetRectBound().GetCapBound();
+}
+
+S2LatLngRect S2RegionIntersection::GetRectBound() const {
+ S2LatLngRect result = S2LatLngRect::Full();
+ for (int i = 0; i < num_regions(); ++i) {
+ result = result.Intersection(region(i)->GetRectBound());
+ }
+ return result;
+}
+
+bool S2RegionIntersection::VirtualContainsPoint(S2Point const& p) const {
+ return Contains(p); // The same as Contains(), just virtual.
+}
+
+bool S2RegionIntersection::Contains(S2Cell const& cell) const {
+ for (int i = 0; i < num_regions(); ++i) {
+ if (!region(i)->Contains(cell)) return false;
+ }
+ return true;
+}
+
+bool S2RegionIntersection::Contains(S2Point const& p) const {
+ for (int i = 0; i < num_regions(); ++i) {
+ if (!region(i)->VirtualContainsPoint(p)) return false;
+ }
+ return true;
+}
+
+bool S2RegionIntersection::MayIntersect(S2Cell const& cell) const {
+ for (int i = 0; i < num_regions(); ++i) {
+ if (!region(i)->MayIntersect(cell)) return false;
+ }
+ return true;
+}
diff --git a/src/third_party/s2/s2regionintersection.h b/src/third_party/s2/s2regionintersection.h
new file mode 100644
index 00000000000..c5902668b7b
--- /dev/null
+++ b/src/third_party/s2/s2regionintersection.h
@@ -0,0 +1,69 @@
+// Copyright 2006 Google Inc. All Rights Reserved.
+
+#ifndef UTIL_GEOMETRY_S2REGIONINTERSECTION_H__
+#define UTIL_GEOMETRY_S2REGIONINTERSECTION_H__
+
+#include <vector>
+using std::vector;
+
+#include "base/basictypes.h"
+#include "base/logging.h"
+#include "base/macros.h"
+#include "s2region.h"
+
+class S2Cap;
+class S2Cell;
+class S2LatLngRect;
+
+// An S2RegionIntersection represents the intersection of a set of regions.
+// It is convenient for computing a covering of the intersection of a set of
+// regions.
+class S2RegionIntersection : public S2Region {
+ public:
+ // Creates an empty intersection that should be initialized by calling Init().
+ // Note: an intersection of no regions covers the entire sphere.
+ S2RegionIntersection();
+
+ // Create a region representing the intersection of the given regions.
+ // Takes ownership of all regions and clears the given vector.
+ S2RegionIntersection(vector<S2Region*>* regions);
+
+ virtual ~S2RegionIntersection();
+
+ // Initialize region by taking ownership of the given regions.
+ void Init(vector<S2Region*>* regions);
+
+ // Release ownership of the regions of this union, and appends them to
+ // "regions" if non-NULL. Resets the region to be empty.
+ void Release(vector<S2Region*>* regions);
+
+ // Accessor methods.
+ int num_regions() const { return regions_.size(); }
+ inline S2Region* region(int i) const { return regions_[i]; }
+
+ ////////////////////////////////////////////////////////////////////////
+ // S2Region interface (see s2region.h for details):
+
+ virtual S2RegionIntersection* Clone() const;
+ virtual S2Cap GetCapBound() const;
+ virtual S2LatLngRect GetRectBound() const;
+ virtual bool VirtualContainsPoint(S2Point const& p) const;
+ bool Contains(S2Point const& p) const;
+ virtual bool Contains(S2Cell const& cell) const;
+ virtual bool MayIntersect(S2Cell const& cell) const;
+ virtual void Encode(Encoder* const encoder) const {
+ S2LOG(FATAL) << "Unimplemented";
+ }
+ virtual bool Decode(Decoder* const decoder) { return false; }
+
+ private:
+ // Internal constructor used only by Clone() that makes a deep copy of
+ // its argument.
+ S2RegionIntersection(S2RegionIntersection const* src);
+
+ vector<S2Region*> regions_;
+
+ DISALLOW_EVIL_CONSTRUCTORS(S2RegionIntersection);
+};
+
+#endif // UTIL_GEOMETRY_S2REGIONINTERSECTION_H__
diff --git a/src/third_party/s2/s2regionunion.cc b/src/third_party/s2/s2regionunion.cc
new file mode 100644
index 00000000000..fa774de5ac8
--- /dev/null
+++ b/src/third_party/s2/s2regionunion.cc
@@ -0,0 +1,90 @@
+// Copyright 2005 Google Inc. All Rights Reserved.
+
+#include "s2regionunion.h"
+
+#include "s2cap.h"
+#include "s2cell.h"
+#include "s2latlngrect.h"
+
+S2RegionUnion::S2RegionUnion() { }
+
+S2RegionUnion::S2RegionUnion(vector<S2Region*>* regions) {
+ Init(regions);
+}
+
+S2RegionUnion::~S2RegionUnion() {
+ for (size_t i = 0; i < regions_.size(); ++i) {
+ delete regions_[i];
+ }
+ regions_.clear();
+}
+
+void S2RegionUnion::Init(vector<S2Region*>* regions) {
+ DCHECK(regions_.empty());
+ // We copy the vector rather than calling swap() to optimize storage.
+ regions_ = *regions;
+ regions->clear();
+}
+
+S2RegionUnion::S2RegionUnion(S2RegionUnion const* src)
+ : regions_(src->num_regions()) {
+ for (int i = 0; i < num_regions(); ++i) {
+ regions_[i] = src->region(i)->Clone();
+ }
+}
+
+void S2RegionUnion::Release(vector<S2Region*>* regions) {
+ if (regions != NULL) {
+ regions->insert(regions->end(), regions_.begin(), regions_.end());
+ }
+ regions_.clear();
+}
+
+void S2RegionUnion::Add(S2Region* region) {
+ regions_.push_back(region);
+}
+
+S2RegionUnion* S2RegionUnion::Clone() const {
+ return new S2RegionUnion(this);
+}
+
+S2Cap S2RegionUnion::GetCapBound() const {
+ // TODO: This could be optimized to return a tighter bound, but doesn't
+ // seem worth it unless profiling shows otherwise.
+ return GetRectBound().GetCapBound();
+}
+
+S2LatLngRect S2RegionUnion::GetRectBound() const {
+ S2LatLngRect result = S2LatLngRect::Empty();
+ for (int i = 0; i < num_regions(); ++i) {
+ result = result.Union(region(i)->GetRectBound());
+ }
+ return result;
+}
+
+bool S2RegionUnion::VirtualContainsPoint(S2Point const& p) const {
+ return Contains(p); // The same as Contains(), just virtual.
+}
+
+bool S2RegionUnion::Contains(S2Cell const& cell) const {
+ // Note that this method is allowed to return false even if the cell
+ // is contained by the region.
+ for (int i = 0; i < num_regions(); ++i) {
+ if (region(i)->Contains(cell)) return true;
+ }
+ return false;
+}
+
+bool S2RegionUnion::Contains(S2Point const& p) const {
+ for (int i = 0; i < num_regions(); ++i) {
+ if (region(i)->VirtualContainsPoint(p)) return true;
+ }
+ return false;
+}
+
+bool S2RegionUnion::MayIntersect(S2Cell const& cell) const {
+ for (int i = 0; i < num_regions(); ++i) {
+ if (region(i)->MayIntersect(cell)) return true;
+ }
+ return false;
+}
diff --git a/src/third_party/s2/s2regionunion.h b/src/third_party/s2/s2regionunion.h
new file mode 100644
index 00000000000..632130b4667
--- /dev/null
+++ b/src/third_party/s2/s2regionunion.h
@@ -0,0 +1,72 @@
+// Copyright 2005 Google Inc. All Rights Reserved.
+
+#ifndef UTIL_GEOMETRY_S2REGIONUNION_H__
+#define UTIL_GEOMETRY_S2REGIONUNION_H__
+
+#include <vector>
+using std::vector;
+
+#include "base/basictypes.h"
+#include "base/logging.h"
+#include "base/macros.h"
+#include "s2region.h"
+
+class S2Cap;
+class S2Cell;
+class S2LatLngRect;
+
+// An S2RegionUnion represents a union of possibly overlapping regions.
+// It is convenient for computing a covering of a set of regions.
+class S2RegionUnion : public S2Region {
+ public:
+ // Create an empty region. Can be made non-empty by calling Init() or Add().
+ S2RegionUnion();
+
+ // Create a region representing the union of the given regions.
+ // Takes ownership of all regions and clears the given vector.
+ S2RegionUnion(vector<S2Region*>* regions);
+
+ virtual ~S2RegionUnion();
+
+ // Initialize region by taking ownership of the given regions.
+ void Init(vector<S2Region*>* regions);
+
+ // Release ownership of the regions of this union, and appends them to
+ // "regions" if non-NULL. Resets the region to be empty.
+ void Release(vector<S2Region*>* regions);
+
+ // Add the given region to the union. This method can be called repeatedly
+ // as an alternative to Init().
+ // Takes ownership of the pointer.
+ void Add(S2Region* region);
+
+ // Accessor methods.
+ int num_regions() const { return regions_.size(); }
+ inline S2Region* region(int i) const { return regions_[i]; }
+
+ ////////////////////////////////////////////////////////////////////////
+ // S2Region interface (see s2region.h for details):
+
+ virtual S2RegionUnion* Clone() const;
+ virtual S2Cap GetCapBound() const;
+ virtual S2LatLngRect GetRectBound() const;
+ virtual bool VirtualContainsPoint(S2Point const& p) const;
+ bool Contains(S2Point const& p) const;
+ virtual bool Contains(S2Cell const& cell) const;
+ virtual bool MayIntersect(S2Cell const& cell) const;
+ virtual void Encode(Encoder* const encoder) const {
+ S2LOG(FATAL) << "Unimplemented";
+ }
+ virtual bool Decode(Decoder* const decoder) { return false; }
+
+ private:
+ // Internal constructor used only by Clone() that makes a deep copy of
+ // its argument.
+ S2RegionUnion(S2RegionUnion const* src);
+
+ vector<S2Region*> regions_;
+
+ DISALLOW_EVIL_CONSTRUCTORS(S2RegionUnion);
+};
+
+#endif // UTIL_GEOMETRY_S2REGIONUNION_H__
diff --git a/src/third_party/s2/s2regionunion_test.cc b/src/third_party/s2/s2regionunion_test.cc
new file mode 100644
index 00000000000..eccd5d85e4e
--- /dev/null
+++ b/src/third_party/s2/s2regionunion_test.cc
@@ -0,0 +1,65 @@
+// Copyright 2005 Google Inc. All Rights Reserved.
+
+#include "s2regionunion.h"
+
+#include <vector>
+using std::vector;
+
+
+#include "base/scoped_ptr.h"
+#include "testing/base/public/gunit.h"
+#include "s2cap.h"
+#include "s2cell.h"
+#include "s2latlngrect.h"
+#include "s2pointregion.h"
+#include "s2regioncoverer.h"
+
+namespace {
+
+TEST(S2RegionUnionTest, Basic) {
+ vector<S2Region*> regions;
+ S2RegionUnion ru_empty(&regions);
+ EXPECT_EQ(0, ru_empty.num_regions());
+ EXPECT_EQ(S2Cap::Empty(), ru_empty.GetCapBound());
+ EXPECT_EQ(S2LatLngRect::Empty(), ru_empty.GetRectBound());
+ scoped_ptr<S2Region> empty_clone(ru_empty.Clone());
+
+ regions.push_back(new S2PointRegion(S2LatLng::FromDegrees(35, 40)
+ .ToPoint()));
+ regions.push_back(new S2PointRegion(S2LatLng::FromDegrees(-35, -40)
+ .ToPoint()));
+
+ // Check that Clone() returns a deep copy.
+ S2RegionUnion* two_points_orig = new S2RegionUnion(&regions);
+ EXPECT_TRUE(regions.empty());
+
+ scoped_ptr<S2RegionUnion> two_points(two_points_orig->Clone());
+ delete two_points_orig;
+ EXPECT_EQ(S2LatLngRect(S2LatLng::FromDegrees(-35, -40),
+ S2LatLng::FromDegrees(35, 40)),
+ two_points->GetRectBound());
+
+ S2Cell face0 = S2Cell::FromFacePosLevel(0, 0, 0);
+ EXPECT_TRUE(two_points->MayIntersect(face0));
+ EXPECT_FALSE(two_points->Contains(face0));
+
+ EXPECT_TRUE(two_points->Contains(S2LatLng::FromDegrees(35, 40).ToPoint()));
+ EXPECT_TRUE(two_points->Contains(S2LatLng::FromDegrees(-35, -40).ToPoint()));
+ EXPECT_FALSE(two_points->Contains(S2LatLng::FromDegrees(0, 0).ToPoint()));
+
+ // Check that we can Add() another region.
+ scoped_ptr<S2RegionUnion> three_points(two_points->Clone());
+ EXPECT_FALSE(three_points->Contains(S2LatLng::FromDegrees(10, 10).ToPoint()));
+ three_points->Add(new S2PointRegion(S2LatLng::FromDegrees(10, 10)
+ .ToPoint()));
+ EXPECT_TRUE(three_points->Contains(S2LatLng::FromDegrees(10, 10).ToPoint()));
+
+ S2RegionCoverer coverer;
+ coverer.set_max_cells(1);
+ vector<S2CellId> covering;
+ coverer.GetCovering(*two_points.get(), &covering);
+ EXPECT_EQ(1, covering.size());
+ EXPECT_EQ(face0.id(), covering[0]);
+}
+
+} // namespace
diff --git a/src/third_party/s2/s2testing.cc b/src/third_party/s2/s2testing.cc
new file mode 100644
index 00000000000..80f84b404df
--- /dev/null
+++ b/src/third_party/s2/s2testing.cc
@@ -0,0 +1,313 @@
+// Copyright 2005 Google Inc. All Rights Reserved.
+
+#include <stdlib.h>
+#include <sys/resource.h> // for rusage, RUSAGE_SELF
+#include <limits.h>
+
+#include <vector>
+using std::vector;
+
+
+#include "base/integral_types.h"
+#include "base/logging.h"
+#include "base/stringprintf.h"
+#include "util/math/matrix3x3-inl.h"
+#include "s2testing.h"
+#include "s2loop.h"
+#include "s2latlng.h"
+#include "s2latlngrect.h"
+#include "s2polygon.h"
+#include "s2polyline.h"
+#include "s2cellunion.h"
+#include "s2cell.h"
+#include "s2cap.h"
+#include "strings/split.h"
+#include "strings/strutil.h"
+
+S2Testing::Random::Random() {
+ srandom(4);
+}
+
+uint64 S2Testing::Random::Rand64() {
+ int bits_of_rand = log2(1ULL + RAND_MAX);
+ uint64 result = 0;
+ for (size_t num_bits = 0; num_bits < 8 * sizeof(uint64);
+ num_bits += bits_of_rand) {
+ result <<= bits_of_rand;
+ result += random();
+ }
+ return result;
+}
+
+uint32 S2Testing::Random::Rand32() {
+ return Rand64() & ((1ULL << 32) - 1);
+}
+
+double S2Testing::Random::RandDouble() {
+ const int NUMBITS = 53;
+ return ldexp(Rand64() & ((1ULL << NUMBITS) - 1ULL), -NUMBITS);
+}
+
+int S2Testing::Random::Uniform(int upper_bound) {
+ return static_cast<uint32>(RandDouble() * upper_bound);
+}
+
+bool S2Testing::Random::OneIn(int x) {
+ return Uniform(x) == 0;
+}
+
+int32 S2Testing::Random::Skewed(int max_log) {
+ const int32 base = Rand32() % (max_log + 1);
+ return Rand32() & ((1u << base) - 1);
+}
+
+int32 S2Testing::Random::PlusOrMinus(int32 value, float multiplier) {
+ const int32 range = static_cast<int32>(value * multiplier);
+ const int32 rand_val = Uniform(range * 2);
+ return value - range + rand_val;
+}
+
+S2Testing::Random S2Testing::rnd;
+
+static double ParseDouble(const string& str) {
+ char* end_ptr = NULL;
+ double value = strtod(str.c_str(), &end_ptr);
+ CHECK(end_ptr && *end_ptr == 0) << ": str == \"" << str << "\"";
+ return value;
+}
+
+void S2Testing::ParseLatLngs(string const& str, vector<S2LatLng>* latlngs) {
+ vector<pair<string, string> > p;
+ CHECK(DictionaryParse(str, &p)) << ": str == \"" << str << "\"";
+ latlngs->clear();
+ for (size_t i = 0; i < p.size(); ++i) {
+ latlngs->push_back(S2LatLng::FromDegrees(ParseDouble(p[i].first),
+ ParseDouble(p[i].second)));
+ }
+}
+
+void S2Testing::ParsePoints(string const& str, vector<S2Point>* vertices) {
+ vector<S2LatLng> latlngs;
+ S2Testing::ParseLatLngs(str, &latlngs);
+ vertices->clear();
+ for (size_t i = 0; i < latlngs.size(); ++i) {
+ vertices->push_back(latlngs[i].ToPoint());
+ }
+}
+
+S2Point S2Testing::MakePoint(string const& str) {
+ vector<S2Point> vertices;
+ ParsePoints(str, &vertices);
+ CHECK_EQ(vertices.size(), 1);
+ return vertices[0];
+}
+
+S2LatLngRect S2Testing::MakeLatLngRect(string const& str) {
+ vector<S2LatLng> latlngs;
+ ParseLatLngs(str, &latlngs);
+ CHECK_GT(latlngs.size(), 0);
+ S2LatLngRect rect = S2LatLngRect::FromPoint(latlngs[0]);
+ for (size_t i = 1; i < latlngs.size(); ++i) {
+ rect.AddPoint(latlngs[i]);
+ }
+ return rect;
+}
+
+S2Loop* S2Testing::MakeLoop(string const& str) {
+ vector<S2Point> vertices;
+ ParsePoints(str, &vertices);
+ return new S2Loop(vertices);
+}
+
+S2Polyline* S2Testing::MakePolyline(string const& str) {
+ vector<S2Point> vertices;
+ ParsePoints(str, &vertices);
+ return new S2Polyline(vertices);
+}
+
+S2Polygon* S2Testing::MakePolygon(string const& str) {
+ vector<string> loop_strs;
+ SplitStringUsing(str, ";", &loop_strs);
+ vector<S2Loop*> loops;
+ for (size_t i = 0; i < loop_strs.size(); ++i) {
+ S2Loop* loop = MakeLoop(loop_strs[i]);
+ loop->Normalize();
+ loops.push_back(loop);
+ }
+ return new S2Polygon(&loops); // Takes ownership.
+}
+
+
+S2Loop* S2Testing::MakeRegularLoop(S2Point const& center,
+ int num_vertices,
+ double angle_radius) {
+ Matrix3x3_d m;
+ S2::GetFrame(center, &m);
+ vector<S2Point> vertices;
+ double radian_step = 2 * M_PI / num_vertices;
+ // We create the vertices on the plane tangent to center, so the
+ // radius on that plane is larger.
+ double planar_radius = tan(angle_radius);
+ for (int vi = 0; vi < num_vertices; ++vi) {
+ double angle = vi * radian_step;
+ S2Point p(planar_radius * cos(angle), planar_radius * sin(angle), 1);
+ vertices.push_back(S2::FromFrame(m, p.Normalize()));
+ }
+ return new S2Loop(vertices);
+}
+
+static void AppendVertex(S2Point const& p, string* out) {
+ S2LatLng ll(p);
+ StringAppendF(out, "%.17g:%.17g", ll.lat().degrees(), ll.lng().degrees());
+}
+
+static void AppendVertices(S2Point const* v, int n, string* out) {
+ for (int i = 0; i < n; ++i) {
+ if (i > 0) *out += ", ";
+ AppendVertex(v[i], out);
+ }
+}
+
+string S2Testing::ToString(S2Point const& point) {
+ string out;
+ AppendVertex(point, &out);
+ return out;
+}
+
+string S2Testing::ToString(S2LatLngRect const& rect) {
+ string out;
+ AppendVertex(rect.lo().ToPoint(), &out);
+ out += ", ";
+ AppendVertex(rect.hi().ToPoint(), &out);
+ return out;
+}
+
+string S2Testing::ToString(S2Loop const* loop) {
+ string out;
+ AppendVertices(&loop->vertex(0), loop->num_vertices(), &out);
+ return out;
+}
+
+string S2Testing::ToString(S2Polyline const* polyline) {
+ string out;
+ AppendVertices(&polyline->vertex(0), polyline->num_vertices(), &out);
+ return out;
+}
+
+string S2Testing::ToString(S2Polygon const* polygon) {
+ string out;
+ for (int i = 0; i < polygon->num_loops(); ++i) {
+ if (i > 0) out += ";\n";
+ S2Loop* loop = polygon->loop(i);
+ AppendVertices(&loop->vertex(0), loop->num_vertices(), &out);
+ }
+ return out;
+}
+
+void DumpLoop(S2Loop const* loop) {
+ // Only for calling from a debugger.
+ cout << S2Testing::ToString(loop) << "\n";
+}
+
+void DumpPolyline(S2Polyline const* polyline) {
+ // Only for calling from a debugger.
+ cout << S2Testing::ToString(polyline) << "\n";
+}
+
+void DumpPolygon(S2Polygon const* polygon) {
+ // Only for calling from a debugger.
+ cout << S2Testing::ToString(polygon) << "\n";
+}
+
+S2Point S2Testing::RandomPoint() {
+ // The order of evaluation of function arguments is unspecified,
+ // so we may not just call S2Point with three RandDouble-based args.
+ // Use temporaries to induce sequence points between calls.
+ double x = 2 * rnd.RandDouble() - 1;
+ double y = 2 * rnd.RandDouble() - 1;
+ double z = 2 * rnd.RandDouble() - 1;
+ return S2Point(x, y, z).Normalize();
+}
+
+void S2Testing::GetRandomFrame(S2Point* x, S2Point* y, S2Point* z) {
+ *x = RandomPoint();
+ *y = x->CrossProd(RandomPoint()).Normalize();
+ *z = x->CrossProd(*y).Normalize();
+}
+
+S2CellId S2Testing::GetRandomCellId(int level) {
+ int face = rnd.Uniform(S2CellId::kNumFaces);
+ uint64 pos = rnd.Rand64() & ((1ULL << (2 * S2CellId::kMaxLevel)) - 1);
+ return S2CellId::FromFacePosLevel(face, pos, level);
+}
+
+S2CellId S2Testing::GetRandomCellId() {
+ return GetRandomCellId(rnd.Uniform(S2CellId::kMaxLevel + 1));
+}
+
+S2Cap S2Testing::GetRandomCap(double min_area, double max_area) {
+ double cap_area = max_area * pow(min_area / max_area, rnd.RandDouble());
+ DCHECK_GE(cap_area, min_area);
+ DCHECK_LE(cap_area, max_area);
+
+ // The surface area of a cap is 2*Pi times its height.
+ return S2Cap::FromAxisArea(RandomPoint(), cap_area);
+}
+
+S2Point S2Testing::SamplePoint(S2Cap const& cap) {
+ // We consider the cap axis to be the "z" axis. We choose two other axes to
+ // complete the coordinate frame.
+
+ Matrix3x3_d m;
+ S2::GetFrame(cap.axis(), &m);
+
+ // The surface area of a spherical cap is directly proportional to its
+ // height. First we choose a random height, and then we choose a random
+ // point along the circle at that height.
+
+ double h = rnd.RandDouble() * cap.height();
+ double theta = 2 * M_PI * rnd.RandDouble();
+ double r = sqrt(h * (2 - h)); // Radius of circle.
+
+ // The result should already be very close to unit-length, but we might as
+ // well make it accurate as possible.
+ return S2::FromFrame(m, S2Point(cos(theta) * r, sin(theta) * r, 1 - h))
+ .Normalize();
+}
+
+void S2Testing::CheckCovering(S2Region const& region,
+ S2CellUnion const& covering,
+ bool check_tight,
+ S2CellId const& id) {
+ if (!id.is_valid()) {
+ for (int face = 0; face < 6; ++face) {
+ CheckCovering(region, covering, check_tight,
+ S2CellId::FromFacePosLevel(face, 0, 0));
+ }
+ return;
+ }
+
+ if (!region.MayIntersect(S2Cell(id))) {
+ // If region does not intersect id, then neither should the covering.
+ if (check_tight) {
+ CHECK(!covering.Intersects(id));
+ }
+ } else if (!covering.Contains(id)) {
+ // The region may intersect id, but we can't assert that the covering
+ // intersects id because we may discover that the region does not actually
+ // intersect upon further subdivision. (MayIntersect is not exact.)
+ CHECK(!region.Contains(S2Cell(id)));
+ CHECK(!id.is_leaf());
+ S2CellId end = id.child_end();
+ S2CellId child;
+ for (child = id.child_begin(); child != end; child = child.next()) {
+ CheckCovering(region, covering, check_tight, child);
+ }
+ }
+}
+
+double S2Testing::GetCpuTime() {
+ struct rusage ru;
+ CHECK_EQ(getrusage(RUSAGE_SELF, &ru), 0);
+ return ru.ru_utime.tv_sec + ru.ru_utime.tv_usec / 1e6;
+}
diff --git a/src/third_party/s2/s2testing.h b/src/third_party/s2/s2testing.h
new file mode 100644
index 00000000000..0f9696ff1a8
--- /dev/null
+++ b/src/third_party/s2/s2testing.h
@@ -0,0 +1,154 @@
+// Copyright 2005 Google Inc. All Rights Reserved.
+
+#ifndef UTIL_GEOMETRY_S2TESTING_H__
+#define UTIL_GEOMETRY_S2TESTING_H__
+
+#include <string>
+using std::string;
+
+#include <vector>
+using std::vector;
+
+#include "s2.h"
+#include "s2cellid.h"
+
+class S2LatLngRect;
+class S2Loop;
+class S2Polygon;
+class S2Polyline;
+class S2Region;
+class S2CellUnion;
+class S2Cap;
+
+// This class defines various static functions that are useful for writing
+// unit tests.
+class S2Testing {
+ public:
+ class Random;
+
+ // Given a latitude-longitude coordinate in degrees,
+ // return a newly allocated point. Example of the input format:
+ // "-20:150"
+ static S2Point MakePoint(string const& str);
+
+ // Given a string of one or more latitude-longitude coordinates in degrees,
+ // return the minimal bounding S2LatLngRect that contains the coordinates.
+ // Example of the input format:
+ // "-20:150" // one point
+ // "-20:150, -20:151, -19:150" // three points
+ static S2LatLngRect MakeLatLngRect(string const& str);
+
+ // Given a string of latitude-longitude coordinates in degrees,
+ // return a newly allocated loop. Example of the input format:
+ // "-20:150, 10:-120, 0.123:-170.652"
+ static S2Loop* MakeLoop(string const& str);
+
+ // Similar to MakeLoop(), but returns an S2Polyline rather than an S2Loop.
+ static S2Polyline* MakePolyline(string const& str);
+
+ // Given a sequence of loops separated by semicolons, return a newly
+ // allocated polygon. Loops are automatically inverted if necessary so
+ // that they enclose at most half of the unit sphere.
+ static S2Polygon* MakePolygon(string const& str);
+
+
+ // Returns a newly allocated loop (owned by caller) shaped as a
+ // regular polygon with num_vertices vertices, all on a circle of
+ // radius radius_angle around the center. The radius is the actual
+ // distance from the center to the circle along the sphere.
+ static S2Loop* MakeRegularLoop(S2Point const& center,
+ int num_vertices,
+ double radius_angle);
+
+ // Examples of the input format:
+ // "10:20, 90:0, 20:30" // one loop
+ // "10:20, 90:0, 20:30; 5.5:6.5, -90:-180, -15.2:20.3" // two loops
+
+ // Parse a string in the same format as MakeLatLngRect, and return the
+ // corresponding vector of S2LatLng points.
+ static void ParseLatLngs(string const& str, vector<S2LatLng>* latlngs);
+
+ // Parse a string in the same format as MakeLatLngRect, and return the
+ // corresponding vector of S2Point values.
+ static void ParsePoints(string const& str, vector<S2Point>* vertices);
+
+ // Convert a point, lat-lng rect, loop, polyline, or polygon to the string
+ // format above.
+ static string ToString(S2Point const& point);
+ static string ToString(S2LatLngRect const& rect);
+ static string ToString(S2Loop const* loop);
+ static string ToString(S2Polyline const* polyline);
+ static string ToString(S2Polygon const* polygon);
+
+ // A deterministically-seeded random number generator.
+ static Random rnd;
+
+ // Return a random unit-length vector.
+ static S2Point RandomPoint();
+
+ // Return a right-handed coordinate frame (three orthonormal vectors).
+ static void GetRandomFrame(S2Point* x, S2Point* y, S2Point* z);
+
+ // Return a cap with a random axis such that the log of its area is
+ // uniformly distributed between the logs of the two given values.
+ // (The log of the cap angle is also approximately uniformly distributed.)
+ static S2Cap GetRandomCap(double min_area, double max_area);
+
+ // Return a point chosen uniformly at random (with respect to area)
+ // from the given cap.
+ static S2Point SamplePoint(S2Cap const& cap);
+
+ // Return a random cell id at the given level or at a randomly chosen
+ // level. The distribution is uniform over the space of cell ids,
+ // but only approximately uniform over the surface of the sphere.
+ static S2CellId GetRandomCellId(int level);
+ static S2CellId GetRandomCellId();
+
+ // Checks that "covering" completely covers the given region. If
+ // "check_tight" is true, also checks that it does not contain any cells
+ // that do not intersect the given region. ("id" is only used internally.)
+ static void CheckCovering(S2Region const& region,
+ S2CellUnion const& covering,
+ bool check_tight,
+ S2CellId const& id = S2CellId());
+
+ // Returns the user time consumed by this process, in seconds.
+ static double GetCpuTime();
+};
+
+// Functions in this class return random numbers that are as good as
+// rand() is. The results will be reproducible as the seed is
+// deterministic.
+class S2Testing::Random {
+ public:
+ Random();
+ uint64 Rand64();
+ uint32 Rand32();
+ double RandDouble();
+ int32 Uniform(int32 upper_bound);
+ int32 operator() (int32 n) {
+ return Uniform(n);
+ }
+ bool OneIn(int x);
+
+ // Skewed: pick "base" uniformly from range [0,max_log] and then
+ // return "base" random bits. The effect is to pick a number in the
+ // range [0,2^max_log-1] with bias towards smaller numbers.
+ int32 Skewed(int max_log);
+
+ // PlusOrMinus: return a uniformly distributed value in the range
+ // [value - (value * multiplier), value + (value * multiplier) )
+ // (i.e. inclusive on the lower end and exclusive on the upper end).
+ //
+ // Be careful of floating point rounding, e.g., 1.0/29 is inexactly
+ // represented, and so we get:
+ //
+ // PlusOrMinus(2 * 29, 1.0/29) is
+ // PlusOrMinus(58, 0.0344827849223) which gives
+ // range = static_cast<int32>(1.999999992549) = 1, rand_val \in [0, 2)
+ // and return result \in [57, 59) rather than [56, 60) as probably
+ // intended. (This holds for IEEE754 floating point.)
+ int32 PlusOrMinus(int32 value, float multiplier);
+};
+
+#endif // UTIL_GEOMETRY_S2TESTING_H__
diff --git a/src/third_party/s2/strings/SConscript b/src/third_party/s2/strings/SConscript
new file mode 100755
index 00000000000..91e9414ade6
--- /dev/null
+++ b/src/third_party/s2/strings/SConscript
@@ -0,0 +1,17 @@
+# -*- mode: python -*-
+
+Import("env windows linux darwin solaris")
+
+env = env.Clone()
+
+env.Append(CCFLAGS=['-Isrc/third_party/s2'])
+env.Append(CCFLAGS=['-Isrc/third_party/gflags-2.0/src'])
+
+env.StaticLibrary(
+ "strings",
+ [
+ "ascii_ctype.cc",
+ "split.cc",
+ "stringprintf.cc",
+ "strutil.cc",
+ ])
diff --git a/src/third_party/s2/strings/ascii_ctype.cc b/src/third_party/s2/strings/ascii_ctype.cc
new file mode 100755
index 00000000000..58b7e655169
--- /dev/null
+++ b/src/third_party/s2/strings/ascii_ctype.cc
@@ -0,0 +1,86 @@
+// Copyright 2007 Google Inc. All Rights Reserved.
+
+#include "ascii_ctype.h"
+
+// # Table generated by this Python code (bit 0x02 is currently unused):
+// def Hex2(n):
+// return '0x' + hex(n/16)[2:] + hex(n%16)[2:]
+// def IsPunct(ch):
+// return (ord(ch) >= 32 and ord(ch) < 127 and
+// not ch.isspace() and not ch.isalnum())
+// def IsBlank(ch):
+// return ch in ' \t'
+// def IsCntrl(ch):
+// return ord(ch) < 32 or ord(ch) == 127
+// def IsXDigit(ch):
+// return ch.isdigit() or ch.lower() in 'abcdef'
+// for i in range(128):
+// ch = chr(i)
+// mask = ((ch.isalpha() and 0x01 or 0) |
+// (ch.isalnum() and 0x04 or 0) |
+// (ch.isspace() and 0x08 or 0) |
+// (IsPunct(ch) and 0x10 or 0) |
+// (IsBlank(ch) and 0x20 or 0) |
+// (IsCntrl(ch) and 0x40 or 0) |
+// (IsXDigit(ch) and 0x80 or 0))
+// print Hex2(mask) + ',',
+// if i % 16 == 7:
+// print ' //', Hex2(i & 0x78)
+// elif i % 16 == 15:
+// print
+const uint8 kAsciiPropertyBits[256] = {
+ 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, // 0x00
+ 0x40, 0x68, 0x48, 0x48, 0x48, 0x48, 0x40, 0x40,
+ 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, // 0x10
+ 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
+ 0x28, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, // 0x20
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, // 0x30
+ 0x84, 0x84, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x10, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x05, // 0x40
+ 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
+ 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, // 0x50
+ 0x05, 0x05, 0x05, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x10, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x05, // 0x60
+ 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
+ 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, // 0x70
+ 0x05, 0x05, 0x05, 0x10, 0x10, 0x10, 0x10, 0x40,
+};
+
+const char kAsciiToLower[256] = {
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
+ 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
+ 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
+ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
+ 64, 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
+ 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 91, 92, 93, 94, 95,
+ 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
+ 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127,
+ 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143,
+ 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159,
+ 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175,
+ 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191,
+ 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207,
+ 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223,
+ 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239,
+ 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255
+};
+
+const char kAsciiToUpper[256] = {
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
+ 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
+ 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
+ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
+ 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
+ 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
+ 96, 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
+ 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 123, 124, 125, 126, 127,
+ 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143,
+ 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159,
+ 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175,
+ 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191,
+ 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207,
+ 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223,
+ 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239,
+ 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255
+};
diff --git a/src/third_party/s2/strings/ascii_ctype.h b/src/third_party/s2/strings/ascii_ctype.h
new file mode 100755
index 00000000000..56fc2d5204f
--- /dev/null
+++ b/src/third_party/s2/strings/ascii_ctype.h
@@ -0,0 +1,95 @@
+// Copyright 2007 Google Inc. All Rights Reserved.
+
+#ifndef STRINGS_ASCII_CTYPE_H__
+#define STRINGS_ASCII_CTYPE_H__
+
+#include "base/basictypes.h"
+
+// ----------------------------------------------------------------------
+// ascii_isalpha()
+// ascii_isdigit()
+// ascii_isalnum()
+// ascii_isspace()
+// ascii_ispunct()
+// ascii_isblank()
+// ascii_iscntrl()
+// ascii_isxdigit()
+// ascii_isprint()
+// ascii_isgraph()
+// ascii_isupper()
+// ascii_islower()
+// ascii_tolower()
+// ascii_toupper()
+// The ctype.h versions of these routines are slow with some
+// compilers and/or architectures, perhaps because of locale
+// issues. These versions work for ascii only: they return
+// false for everything above \x7f (which means they return
+// false for any byte from any non-ascii UTF8 character).
+//
+// The individual bits do not have names because the array definition
+// is already tightly coupled to this, and names would make it harder
+// to read and debug.
+//
+// This is an example of the benchmark times from the unittest:
+// $ ascii_ctype_test --benchmarks=all --heap_check=
+// Benchmark Time(ns) CPU(ns) Iterations
+// --------------------------------------------------
+// BM_Identity 121 120 5785985 2027.0 MB/s
+// BM_isalpha 1603 1597 511027 152.9 MB/s
+// BM_ascii_isalpha 223 224 3111595 1088.5 MB/s
+// BM_isdigit 181 183 3825722 1336.4 MB/s
+// BM_ascii_isdigit 236 239 2929312 1023.3 MB/s
+// BM_isalnum 1623 1615 460596 151.2 MB/s
+// BM_ascii_isalnum 253 255 2745518 959.1 MB/s
+// BM_isspace 1264 1258 555639 194.1 MB/s
+// BM_ascii_isspace 253 255 2745507 959.1 MB/s
+// BM_ispunct 1324 1317 555639 185.3 MB/s
+// BM_ascii_ispunct 252 255 2745507 959.1 MB/s
+// BM_isblank 1433 1426 511027 171.2 MB/s
+// BM_ascii_isblank 253 254 2745518 960.5 MB/s
+// BM_iscntrl 1643 1634 530383 149.4 MB/s
+// BM_ascii_iscntrl 252 255 2745518 959.1 MB/s
+// BM_isxdigit 1826 1817 414265 134.3 MB/s
+// BM_ascii_isxdigit 258 260 2692712 939.3 MB/s
+// BM_isprint 1677 1669 419224 146.2 MB/s
+// BM_ascii_isprint 237 239 2929312 1021.8 MB/s
+// BM_isgraph 1436 1429 507324 170.9 MB/s
+// BM_ascii_isgraph 237 239 2929312 1021.8 MB/s
+// BM_isupper 1550 1544 463647 158.1 MB/s
+// BM_ascii_isupper 237 239 2929312 1021.8 MB/s
+// BM_islower 1301 1294 538544 188.7 MB/s
+// BM_ascii_islower 237 239 2929312 1023.3 MB/s
+// BM_isascii 182 181 3846746 1345.7 MB/s
+// BM_ascii_isascii 209 211 3318039 1159.1 MB/s
+// BM_tolower 1743 1764 397786 138.4 MB/s
+// BM_ascii_tolower 210 211 3318039 1155.8 MB/s
+// BM_toupper 1742 1764 397788 138.4 MB/s
+// BM_ascii_toupper 212 211 3302401 1156.9 MB/s
+//
+// ----------------------------------------------------------------------
+
+#define kApb kAsciiPropertyBits
+extern const uint8 kAsciiPropertyBits[256];
+static inline bool ascii_isalpha(unsigned char c) { return kApb[c] & 0x01; }
+static inline bool ascii_isalnum(unsigned char c) { return kApb[c] & 0x04; }
+static inline bool ascii_isspace(unsigned char c) { return kApb[c] & 0x08; }
+static inline bool ascii_ispunct(unsigned char c) { return kApb[c] & 0x10; }
+static inline bool ascii_isblank(unsigned char c) { return kApb[c] & 0x20; }
+static inline bool ascii_iscntrl(unsigned char c) { return kApb[c] & 0x40; }
+static inline bool ascii_isxdigit(unsigned char c) { return kApb[c] & 0x80; }
+static inline bool ascii_isdigit(unsigned char c) { return c >= '0' && c <= '9'; }
+static inline bool ascii_isprint(unsigned char c) { return c >= 32 && c < 127; }
+static inline bool ascii_isgraph(unsigned char c) { return c > 32 && c < 127; }
+static inline bool ascii_isupper(unsigned char c) { return c >= 'A' && c <= 'Z'; }
+static inline bool ascii_islower(unsigned char c) { return c >= 'a' && c <= 'z'; }
+static inline bool ascii_isascii(unsigned char c) {
+ return static_cast<signed char>(c) >= 0;
+}
+#undef kApb
+
+extern const char kAsciiToLower[256];
+static inline char ascii_tolower(unsigned char c) { return kAsciiToLower[c]; }
+extern const char kAsciiToUpper[256];
+static inline char ascii_toupper(unsigned char c) { return kAsciiToUpper[c]; }
+
+#endif // STRINGS_ASCII_CTYPE_H__
diff --git a/src/third_party/s2/strings/split.cc b/src/third_party/s2/strings/split.cc
new file mode 100755
index 00000000000..136b6b36a5f
--- /dev/null
+++ b/src/third_party/s2/strings/split.cc
@@ -0,0 +1,504 @@
+// Copyright 2008 and onwards Google Inc. All rights reserved.
+
+#include <limits>
+using std::numeric_limits;
+
+
+#include "base/commandlineflags.h"
+#include "base/integral_types.h"
+#include "base/logging.h"
+#include "base/macros.h"
+#include "base/strtoint.h"
+#include "split.h"
+#include "strutil.h"
+#include "util/hash/hash_jenkins_lookup2.h"
+
+static const uint32 MIX32 = 0x12b9b0a1UL; // pi; an arbitrary number
+static const uint64 MIX64 = GG_ULONGLONG(0x2b992ddfa23249d6); // more of pi
+
+// ----------------------------------------------------------------------
+// Hash32StringWithSeed()
+// Hash64StringWithSeed()
+// Hash32NumWithSeed()
+// Hash64NumWithSeed()
+// These are Bob Jenkins' hash functions, one for 32 bit numbers
+// and one for 64 bit numbers. Each takes a string as input and
+// a start seed. Hashing the same string with two different seeds
+// should give two independent hash values.
+// The *Num*() functions just do a single mix, in order to
+// convert the given number into something *random*.
+//
+// Note that these methods may return any value for the given size, while
+// the corresponding HashToXX() methods avoids certain reserved values.
+// ----------------------------------------------------------------------
+
+// These slow down a lot if inlined, so do not inline them --Sanjay
+//extern uint32 Hash32StringWithSeed(const char *s, uint32 len, uint32 c);
+// Once again, not included, but copied from:
+// http://szl.googlecode.com/svn-history/r40/trunk/src/utilities/hashutils.cc
+// This is an Apache license...make sure this is ok
+const uint32 kPrimes32[16] ={
+ 65537, 65539, 65543, 65551, 65557, 65563, 65579, 65581,
+ 65587, 65599, 65609, 65617, 65629, 65633, 65647, 65651,
+};
+uint32 Hash32StringWithSeed(const char *s, uint32 len, uint32 seed) {
+ uint32 n = seed;
+ size_t prime1 = 0, prime2 = 8; // Indices into kPrimes32
+ union {
+ uint16 n;
+ char bytes[sizeof(uint16)];
+ } chunk;
+ for (const char *i = s, *const end = s + len; i != end; ) {
+ chunk.bytes[0] = *i++;
+ chunk.bytes[1] = i == end ? 0 : *i++;
+ n = n * kPrimes32[prime1++] ^ chunk.n * kPrimes32[prime2++];
+ prime1 &= 0x0F;
+ prime2 &= 0x0F;
+ }
+ return n;
+}
+extern uint64 Hash64StringWithSeed(const char *s, uint32 len, uint64 c);
+extern uint32 Hash32StringWithSeedReferenceImplementation(const char *s,
+ uint32 len, uint32 c);
+// ----------------------------------------------------------------------
+// HashTo32()
+// HashTo16()
+// HashTo8()
+// These functions take various types of input (through operator
+// overloading) and return 32, 16, and 8 bit quantities, respectively.
+// The basic rule of our hashing is: always mix(). Thus, even for
+// char outputs we cast to a uint32 and mix with two arbitrary numbers.
+// As indicated in basictypes.h, there are a few illegal hash
+// values to watch out for.
+//
+// Note that these methods avoid returning certain reserved values, while
+// the corresponding HashXXStringWithSeed() methdos may return any value.
+// ----------------------------------------------------------------------
+
+// This macro defines the HashTo32, To16, and To8 versions all in one go.
+// It takes the argument list and a command that hashes your number.
+// (For 16 and 8, we just mod retval before returning it.) Example:
+// HASH_TO((char c), Hash32NumWithSeed(c, MIX32_1))
+// evaluates to
+// uint32 retval;
+// retval = Hash32NumWithSeed(c, MIX32_1);
+// return retval == kIllegalHash32 ? retval-1 : retval;
+//
+
+inline uint32 Hash32NumWithSeed(uint32 num, uint32 c) {
+ uint32 b = 0x9e3779b9UL; // the golden ratio; an arbitrary value
+ mix(num, b, c);
+ return c;
+}
+
+inline uint64 Hash64NumWithSeed(uint64 num, uint64 c) {
+ uint64 b = GG_ULONGLONG(0xe08c1d668b756f82); // more of the golden ratio
+ mix(num, b, c);
+ return c;
+}
+
+#define HASH_TO(arglist, command) \
+inline uint32 HashTo32 arglist { \
+ uint32 retval = command; \
+ return retval == kIllegalHash32 ? retval-1 : retval; \
+} \
+inline uint16 HashTo16 arglist { \
+ uint16 retval16 = command >> 16; /* take upper 16 bits */ \
+ return retval16 == kIllegalHash16 ? retval16-1 : retval16; \
+} \
+inline unsigned char HashTo8 arglist { \
+ unsigned char retval8 = command >> 24; /* take upper 8 bits */ \
+ return retval8 == kIllegalHash8 ? retval8-1 : retval8; \
+}
+
+// This defines:
+// HashToXX(char *s, int slen);
+// HashToXX(char c);
+// etc
+
+HASH_TO((const char *s, uint32 slen), Hash32StringWithSeed(s, slen, MIX32))
+HASH_TO((const wchar_t *s, uint32 slen),
+ Hash32StringWithSeed(reinterpret_cast<const char*>(s),
+ sizeof(wchar_t) * slen,
+ MIX32))
+HASH_TO((char c), Hash32NumWithSeed(static_cast<uint32>(c), MIX32))
+HASH_TO((schar c), Hash32NumWithSeed(static_cast<uint32>(c), MIX32))
+HASH_TO((uint16 c), Hash32NumWithSeed(static_cast<uint32>(c), MIX32))
+HASH_TO((int16 c), Hash32NumWithSeed(static_cast<uint32>(c), MIX32))
+HASH_TO((uint32 c), Hash32NumWithSeed(static_cast<uint32>(c), MIX32))
+HASH_TO((int32 c), Hash32NumWithSeed(static_cast<uint32>(c), MIX32))
+HASH_TO((uint64 c), static_cast<uint32>(Hash64NumWithSeed(c, MIX64) >> 32))
+HASH_TO((int64 c), static_cast<uint32>(Hash64NumWithSeed(c, MIX64) >> 32))
+#ifdef _LP64
+HASH_TO((intptr_t c), static_cast<uint32>(Hash64NumWithSeed(c, MIX64) >> 32))
+#endif
+
+#undef HASH_TO // clean up the macro space
+
+
+// HASH_NAMESPACE_DECLARATION_START
+namespace __gnu_cxx {
+
+#if defined(__GNUC__)
+// Use our nice hash function for strings
+template<class _CharT, class _Traits, class _Alloc>
+struct hash<basic_string<_CharT, _Traits, _Alloc> > {
+ size_t operator()(const basic_string<_CharT, _Traits, _Alloc>& k) const {
+ return HashTo32(k.data(), static_cast<uint32>(k.length()));
+ }
+};
+
+// they don't define a hash for const string at all
+template<> struct hash<const string> {
+ size_t operator()(const string& k) const {
+ return HashTo32(k.data(), static_cast<uint32>(k.length()));
+ }
+};
+#endif // __GNUC__
+
+// MSVC's STL requires an ever-so slightly different decl
+#if defined STL_MSVC
+template<> struct hash<char const*> : PortableHashBase {
+ size_t operator()(char const* const k) const {
+ return HashTo32(k, strlen(k));
+ }
+ // Less than operator:
+ bool operator()(char const* const a, char const* const b) const {
+ return strcmp(a, b) < 0;
+ }
+};
+
+template<> struct hash<string> : PortableHashBase {
+ size_t operator()(const string& k) const {
+ return HashTo32(k.data(), k.length());
+ }
+ // Less than operator:
+ bool operator()(const string& a, const string& b) const {
+ return a < b;
+ }
+};
+
+#endif
+
+} // hash namespace
+
+
+namespace {
+// NOTE(user): we have to implement our own interator because
+// insert_iterator<set<string> > does not instantiate without
+// errors, perhaps since string != std::string.
+// This is not a fully functional iterator, but is
+// sufficient for SplitStringToIteratorUsing().
+template <typename T>
+struct simple_insert_iterator {
+ T* t_;
+ simple_insert_iterator(T* t) : t_(t) { }
+
+ simple_insert_iterator<T>& operator=(const typename T::value_type& value) {
+ t_->insert(value);
+ return *this;
+ }
+
+ simple_insert_iterator<T>& operator*() { return *this; }
+ simple_insert_iterator<T>& operator++() { return *this; }
+ simple_insert_iterator<T>& operator++(int) { return *this; }
+};
+
+// Used to populate a hash_map out of pairs of consecutive strings in
+// SplitStringToIterator{Using|AllowEmpty}().
+template <typename T>
+struct simple_hash_map_iterator {
+ typedef hash_map<T, T> hashmap;
+ hashmap* t;
+ bool even;
+ typename hashmap::iterator curr;
+
+ simple_hash_map_iterator(hashmap* t_init) : t(t_init), even(true) {
+ curr = t->begin();
+ }
+
+ simple_hash_map_iterator<T>& operator=(const T& value) {
+ if (even) {
+ curr = t->insert(make_pair(value, T())).first;
+ } else {
+ curr->second = value;
+ }
+ even = !even;
+ return *this;
+ }
+
+ simple_hash_map_iterator<T>& operator*() { return *this; }
+ simple_hash_map_iterator<T>& operator++() { return *this; }
+ simple_hash_map_iterator<T>& operator++(int i) { return *this; }
+};
+
+} // anonymous namespace
+
+// ----------------------------------------------------------------------
+// SplitStringIntoNPiecesAllowEmpty()
+// SplitStringToIteratorAllowEmpty()
+// Split a string using a character delimiter. Append the components
+// to 'result'. If there are consecutive delimiters, this function
+// will return corresponding empty strings. The string is split into
+// at most the specified number of pieces greedily. This means that the
+// last piece may possibly be split further. To split into as many pieces
+// as possible, specify 0 as the number of pieces.
+//
+// If "full" is the empty string, yields an empty string as the only value.
+//
+// If "pieces" is negative for some reason, it returns the whole string
+// ----------------------------------------------------------------------
+template <typename StringType, typename ITR>
+static inline
+void SplitStringToIteratorAllowEmpty(const StringType& full,
+ const char* delim,
+ int pieces,
+ ITR& result) {
+ string::size_type begin_index, end_index;
+ begin_index = 0;
+
+ for (int i=0; (i < pieces-1) || (pieces == 0); i++) {
+ end_index = full.find_first_of(delim, begin_index);
+ if (end_index == string::npos) {
+ *result++ = full.substr(begin_index);
+ return;
+ }
+ *result++ = full.substr(begin_index, (end_index - begin_index));
+ begin_index = end_index + 1;
+ }
+ *result++ = full.substr(begin_index);
+}
+
+#ifdef _WIN32
+#include <iterator>
+//#define back_insert_iterator Platform::Collections::BackInsertIterator
+#endif
+
+void SplitStringIntoNPiecesAllowEmpty(const string& full,
+ const char* delim,
+ int pieces,
+ vector<string>* result) {
+ back_insert_iterator<vector<string> > it(*result);
+ SplitStringToIteratorAllowEmpty(full, delim, pieces, it);
+}
+
+// ----------------------------------------------------------------------
+// SplitStringAllowEmpty
+// SplitStringToHashsetAllowEmpty
+// SplitStringToSetAllowEmpty
+// SplitStringToHashmapAllowEmpty
+// Split a string using a character delimiter. Append the components
+// to 'result'. If there are consecutive delimiters, this function
+// will return corresponding empty strings.
+// ----------------------------------------------------------------------
+void SplitStringAllowEmpty(const string& full, const char* delim,
+ vector<string>* result) {
+ back_insert_iterator<vector<string> > it(*result);
+ SplitStringToIteratorAllowEmpty(full, delim, 0, it);
+}
+
+void SplitStringToHashsetAllowEmpty(const string& full, const char* delim,
+ hash_set<string>* result) {
+ simple_insert_iterator<hash_set<string> > it(result);
+ SplitStringToIteratorAllowEmpty(full, delim, 0, it);
+}
+
+void SplitStringToSetAllowEmpty(const string& full, const char* delim,
+ set<string>* result) {
+ simple_insert_iterator<set<string> > it(result);
+ SplitStringToIteratorAllowEmpty(full, delim, 0, it);
+}
+
+void SplitStringToHashmapAllowEmpty(const string& full, const char* delim,
+ hash_map<string, string>* result) {
+ simple_hash_map_iterator<string> it(result);
+ SplitStringToIteratorAllowEmpty(full, delim, 0, it);
+}
+
+// If we know how much to allocate for a vector of strings, we can
+// allocate the vector<string> only once and directly to the right size.
+// This saves in between 33-66 % of memory space needed for the result,
+// and runs faster in the microbenchmarks.
+//
+// The reserve is only implemented for the single character delim.
+//
+// The implementation for counting is cut-and-pasted from
+// SplitStringToIteratorUsing. I could have written my own counting iterator,
+// and use the existing template function, but probably this is more clear
+// and more sure to get optimized to reasonable code.
+static int CalculateReserveForVector(const string& full, const char* delim) {
+ int count = 0;
+ if (delim[0] != '\0' && delim[1] == '\0') {
+ // Optimize the common case where delim is a single character.
+ char c = delim[0];
+ const char* p = full.data();
+ const char* end = p + full.size();
+ while (p != end) {
+ if (*p == c) { // This could be optimized with hasless(v,1) trick.
+ ++p;
+ } else {
+ while (++p != end && *p != c) {
+ // Skip to the next occurence of the delimiter.
+ }
+ ++count;
+ }
+ }
+ }
+ return count;
+}
+
+// ----------------------------------------------------------------------
+// SplitStringUsing()
+// SplitStringToHashsetUsing()
+// SplitStringToSetUsing()
+// SplitStringToHashmapUsing()
+// Split a string using a character delimiter. Append the components
+// to 'result'.
+//
+// Note: For multi-character delimiters, this routine will split on *ANY* of
+// the characters in the string, not the entire string as a single delimiter.
+// ----------------------------------------------------------------------
+template <typename StringType, typename ITR>
+static inline
+void SplitStringToIteratorUsing(const StringType& full,
+ const char* delim,
+ ITR& result) {
+ // Optimize the common case where delim is a single character.
+ if (delim[0] != '\0' && delim[1] == '\0') {
+ char c = delim[0];
+ const char* p = full.data();
+ const char* end = p + full.size();
+ while (p != end) {
+ if (*p == c) {
+ ++p;
+ } else {
+ const char* start = p;
+ while (++p != end && *p != c) {
+ // Skip to the next occurence of the delimiter.
+ }
+ *result++ = StringType(start, p - start);
+ }
+ }
+ return;
+ }
+
+ string::size_type begin_index, end_index;
+ begin_index = full.find_first_not_of(delim);
+ while (begin_index != string::npos) {
+ end_index = full.find_first_of(delim, begin_index);
+ if (end_index == string::npos) {
+ *result++ = full.substr(begin_index);
+ return;
+ }
+ *result++ = full.substr(begin_index, (end_index - begin_index));
+ begin_index = full.find_first_not_of(delim, end_index);
+ }
+}
+
+void SplitStringUsing(const string& full,
+ const char* delim,
+ vector<string>* result) {
+ result->reserve(result->size() + CalculateReserveForVector(full, delim));
+ back_insert_iterator< vector<string> > it(*result);
+ SplitStringToIteratorUsing(full, delim, it);
+}
+
+void SplitStringToHashsetUsing(const string& full, const char* delim,
+ hash_set<string>* result) {
+ simple_insert_iterator<hash_set<string> > it(result);
+ SplitStringToIteratorUsing(full, delim, it);
+}
+
+void SplitStringToSetUsing(const string& full, const char* delim,
+ set<string>* result) {
+ simple_insert_iterator<set<string> > it(result);
+ SplitStringToIteratorUsing(full, delim, it);
+}
+
+void SplitStringToHashmapUsing(const string& full, const char* delim,
+ hash_map<string, string>* result) {
+ simple_hash_map_iterator<string> it(result);
+ SplitStringToIteratorUsing(full, delim, it);
+}
+
+// ----------------------------------------------------------------------
+// SplitOneIntToken()
+// SplitOneInt32Token()
+// SplitOneUint32Token()
+// SplitOneInt64Token()
+// SplitOneUint64Token()
+// SplitOneDoubleToken()
+// SplitOneFloatToken()
+// SplitOneDecimalIntToken()
+// SplitOneDecimalInt32Token()
+// SplitOneDecimalUint32Token()
+// SplitOneDecimalInt64Token()
+// SplitOneDecimalUint64Token()
+// SplitOneHexUint32Token()
+// SplitOneHexUint64Token()
+// Mainly a stringified wrapper around strtol/strtoul/strtod
+// ----------------------------------------------------------------------
+// Curried functions for the macro below
+static inline long strto32_0(const char * source, char ** end) {
+ return strto32(source, end, 0); }
+static inline unsigned long strtou32_0(const char * source, char ** end) {
+ return strtou32(source, end, 0); }
+static inline int64 strto64_0(const char * source, char ** end) {
+ return strto64(source, end, 0); }
+static inline uint64 strtou64_0(const char * source, char ** end) {
+ return strtou64(source, end, 0); }
+static inline long strto32_10(const char * source, char ** end) {
+ return strto32(source, end, 10); }
+static inline unsigned long strtou32_10(const char * source, char ** end) {
+ return strtou32(source, end, 10); }
+static inline int64 strto64_10(const char * source, char ** end) {
+ return strto64(source, end, 10); }
+static inline uint64 strtou64_10(const char * source, char ** end) {
+ return strtou64(source, end, 10); }
+static inline uint32 strtou32_16(const char * source, char ** end) {
+ return strtou32(source, end, 16); }
+static inline uint64 strtou64_16(const char * source, char ** end) {
+ return strtou64(source, end, 16); }
+
+#define DEFINE_SPLIT_ONE_NUMBER_TOKEN(name, type, function) \
+bool SplitOne##name##Token(const char ** source, const char * delim, \
+ type * value) { \
+ assert(source); \
+ assert(delim); \
+ assert(value); \
+ if (!*source) \
+ return false; \
+ /* Parse int */ \
+ char * end; \
+ *value = function(*source, &end); \
+ if (end == *source) \
+ return false; /* number not present at start of string */ \
+ if (end[0] && !strchr(delim, end[0])) \
+ return false; /* Garbage characters after int */ \
+ /* Advance past token */ \
+ if (*end != '\0') \
+ *source = const_cast<const char *>(end+1); \
+ else \
+ *source = NULL; \
+ return true; \
+}
+
+DEFINE_SPLIT_ONE_NUMBER_TOKEN(Int, int, strto32_0)
+DEFINE_SPLIT_ONE_NUMBER_TOKEN(Int32, int32, strto32_0)
+DEFINE_SPLIT_ONE_NUMBER_TOKEN(Uint32, uint32, strtou32_0)
+DEFINE_SPLIT_ONE_NUMBER_TOKEN(Int64, int64, strto64_0)
+DEFINE_SPLIT_ONE_NUMBER_TOKEN(Uint64, uint64, strtou64_0)
+DEFINE_SPLIT_ONE_NUMBER_TOKEN(Double, double, strtod)
+#ifdef _WIN32 // has no strtof()
+// Note: does an implicit cast to float.
+DEFINE_SPLIT_ONE_NUMBER_TOKEN(Float, float, strtod)
+#else
+DEFINE_SPLIT_ONE_NUMBER_TOKEN(Float, float, strtof)
+#endif
+DEFINE_SPLIT_ONE_NUMBER_TOKEN(DecimalInt, int, strto32_10)
+DEFINE_SPLIT_ONE_NUMBER_TOKEN(DecimalInt32, int32, strto32_10)
+DEFINE_SPLIT_ONE_NUMBER_TOKEN(DecimalUint32, uint32, strtou32_10)
+DEFINE_SPLIT_ONE_NUMBER_TOKEN(DecimalInt64, int64, strto64_10)
+DEFINE_SPLIT_ONE_NUMBER_TOKEN(DecimalUint64, uint64, strtou64_10)
+DEFINE_SPLIT_ONE_NUMBER_TOKEN(HexUint32, uint32, strtou32_16)
+DEFINE_SPLIT_ONE_NUMBER_TOKEN(HexUint64, uint64, strtou64_16)
diff --git a/src/third_party/s2/strings/split.h b/src/third_party/s2/strings/split.h
new file mode 100755
index 00000000000..d623f7b21ad
--- /dev/null
+++ b/src/third_party/s2/strings/split.h
@@ -0,0 +1,177 @@
+// Copyright 2008 and onwards Google, Inc.
+//
+// Functions for splitting and parsing strings. Functions may be migrated
+// to this file from strutil.h in the future.
+//
+#ifndef STRINGS_SPLIT_H_
+#define STRINGS_SPLIT_H_
+
+#include <string>
+using std::string;
+
+#include <vector>
+using std::vector;
+
+#include <set>
+using std::set;
+using std::multiset;
+
+#include <utility>
+using std::pair;
+using std::make_pair;
+
+#include "base/definer.h"
+#if defined OS_MACOSX
+#include <ext/hash_map>
+#else
+#include <hash_map>
+#endif
+#ifndef _WIN32
+using __gnu_cxx::hash_map;
+#endif
+
+#if defined OS_MACOSX
+#include <ext/hash_set>
+#else
+#include <hash_set>
+#endif
+#ifndef _WIN32
+using __gnu_cxx::hash_set;
+using namespace __gnu_cxx;
+#endif
+
+using namespace std;
+
+
+// ----------------------------------------------------------------------
+// SplitStringAllowEmpty()
+// SplitStringToHashsetAllowEmpty()
+// SplitStringToSetAllowEmpty()
+// SplitStringToHashmapAllowEmpty()
+
+// Split a string using one or more character delimiters, presented
+// as a nul-terminated c string. Append the components to 'result'.
+// If there are consecutive delimiters, this function will return
+// corresponding empty strings.
+//
+// If "full" is the empty string, yields an empty string as the only value.
+// ----------------------------------------------------------------------
+void SplitStringAllowEmpty(const string& full, const char* delim,
+ vector<string>* res);
+void SplitStringToHashsetAllowEmpty(const string& full, const char* delim,
+ hash_set<string>* res);
+void SplitStringToSetAllowEmpty(const string& full, const char* delim,
+ set<string>* res);
+// The even-positioned (0-based) components become the keys for the
+// odd-positioned components that follow them. When there is an odd
+// number of components, the value for the last key will be unchanged
+// if the key was already present in the hash table, or will be the
+// empty string if the key is a newly inserted key.
+void SplitStringToHashmapAllowEmpty(const string& full, const char* delim,
+ hash_map<string, string>* result);
+
+// ----------------------------------------------------------------------
+// SplitStringUsing()
+// SplitStringToHashsetUsing()
+// SplitStringToSetUsing()
+// SplitStringToHashmapUsing()
+
+// Split a string using one or more character delimiters, presented
+// as a nul-terminated c string. Append the components to 'result'.
+// If there are consecutive delimiters, this function skips over
+// all of them.
+// ----------------------------------------------------------------------
+void SplitStringUsing(const string& full, const char* delim,
+ vector<string>* res);
+void SplitStringToHashsetUsing(const string& full, const char* delim,
+ hash_set<string>* res);
+void SplitStringToSetUsing(const string& full, const char* delim,
+ set<string>* res);
+// The even-positioned (0-based) components become the keys for the
+// odd-positioned components that follow them. When there is an odd
+// number of components, the value for the last key will be unchanged
+// if the key was already present in the hash table, or will be the
+// empty string if the key is a newly inserted key.
+void SplitStringToHashmapUsing(const string& full, const char* delim,
+ hash_map<string, string>* result);
+
+// ----------------------------------------------------------------------
+// SplitOneIntToken()
+// SplitOneInt32Token()
+// SplitOneUint32Token()
+// SplitOneInt64Token()
+// SplitOneUint64Token()
+// SplitOneDoubleToken()
+// SplitOneFloatToken()
+// Parse a single "delim" delimited number from "*source" into "*value".
+// Modify *source to point after the delimiter.
+// If no delimiter is present after the number, set *source to NULL.
+//
+// If the start of *source is not an number, return false.
+// If the int is followed by the null character, return true.
+// If the int is not followed by a character from delim, return false.
+// If *source is NULL, return false.
+//
+// They cannot handle decimal numbers with leading 0s, since they will be
+// treated as octal.
+// ----------------------------------------------------------------------
+bool SplitOneIntToken(const char** source, const char* delim,
+ int* value);
+bool SplitOneInt32Token(const char** source, const char* delim,
+ int32* value);
+bool SplitOneUint32Token(const char** source, const char* delim,
+ uint32* value);
+bool SplitOneInt64Token(const char** source, const char* delim,
+ int64* value);
+bool SplitOneUint64Token(const char** source, const char* delim,
+ uint64* value);
+bool SplitOneDoubleToken(const char** source, const char* delim,
+ double* value);
+bool SplitOneFloatToken(const char** source, const char* delim,
+ float* value);
+
+// Some aliases, so that the function names are standardized against the names
+// of the reflection setters/getters in proto2. This makes it easier to use
+// certain macros with reflection when creating custom text formats for protos.
+
+inline bool SplitOneUInt32Token(const char** source, const char* delim,
+ uint32* value) {
+ return SplitOneUint32Token(source, delim, value);
+}
+
+inline bool SplitOneUInt64Token(const char** source, const char* delim,
+ uint64* value) {
+ return SplitOneUint64Token(source, delim, value);
+}
+
+// ----------------------------------------------------------------------
+// SplitOneDecimalIntToken()
+// SplitOneDecimalInt32Token()
+// SplitOneDecimalUint32Token()
+// SplitOneDecimalInt64Token()
+// SplitOneDecimalUint64Token()
+// Parse a single "delim"-delimited number from "*source" into "*value".
+// Unlike SplitOneIntToken, etc., this function always interprets
+// the numbers as decimal.
+bool SplitOneDecimalIntToken(const char** source, const char* delim,
+ int* value);
+bool SplitOneDecimalInt32Token(const char** source, const char* delim,
+ int32* value);
+bool SplitOneDecimalUint32Token(const char** source, const char* delim,
+ uint32* value);
+bool SplitOneDecimalInt64Token(const char** source, const char* delim,
+ int64* value);
+bool SplitOneDecimalUint64Token(const char** source, const char* delim,
+ uint64* value);
+
+// ----------------------------------------------------------------------
+// SplitOneHexUint32Token()
+// SplitOneHexUint64Token()
+// Once more, for hexadecimal numbers (unsigned only).
+bool SplitOneHexUint32Token(const char** source, const char* delim,
+ uint32* value);
+bool SplitOneHexUint64Token(const char** source, const char* delim,
+ uint64* value);
+
+
+#endif // STRINGS_SPLIT_H_
diff --git a/src/third_party/s2/strings/stringprintf.cc b/src/third_party/s2/strings/stringprintf.cc
new file mode 100755
index 00000000000..99b955bcfd4
--- /dev/null
+++ b/src/third_party/s2/strings/stringprintf.cc
@@ -0,0 +1,52 @@
+// Copyright 2002 and onwards Google Inc.
+
+#include <stdarg.h> // For va_list and related operations
+#include <stdio.h> // MSVC requires this for _vsnprintf
+#include <vector>
+using std::vector;
+
+#include <string>
+using std::string;
+#include "stringprintf.h"
+#include "base/logging.h"
+// Max arguments supported by StringPrintVector
+const int kStringPrintfVectorMaxArgs = 32;
+
+// An empty block of zero for filler arguments. This is const so that if
+// printf tries to write to it (via %n) then the program gets a SIGSEGV
+// and we can fix the problem or protect against an attack.
+static const char string_printf_empty_block [256] = { '\0' };
+
+string StringPrintfVector(const char* format, const vector<string>& v) {
+ CHECK_LE(v.size(), kStringPrintfVectorMaxArgs)
+ << "StringPrintfVector currently only supports up to "
+ << kStringPrintfVectorMaxArgs << " arguments. "
+ << "Feel free to add support for more if you need it.";
+
+ // Add filler arguments so that bogus format+args have a harder time
+ // crashing the program, corrupting the program (%n),
+ // or displaying random chunks of memory to users.
+
+ const char* cstr[kStringPrintfVectorMaxArgs];
+ for (size_t i = 0; i < v.size(); ++i) {
+ cstr[i] = v[i].c_str();
+ }
+ for (size_t i = v.size(); i < arraysize(cstr); ++i) {
+ cstr[i] = &string_printf_empty_block[0];
+ }
+
+ // I do not know any way to pass kStringPrintfVectorMaxArgs arguments,
+ // or any way to build a va_list by hand, or any API for printf
+ // that accepts an array of arguments. The best I can do is stick
+ // this COMPILE_ASSERT right next to the actual statement.
+
+ COMPILE_ASSERT(kStringPrintfVectorMaxArgs == 32, arg_count_mismatch);
+ return StringPrintf(format,
+ cstr[0], cstr[1], cstr[2], cstr[3], cstr[4],
+ cstr[5], cstr[6], cstr[7], cstr[8], cstr[9],
+ cstr[10], cstr[11], cstr[12], cstr[13], cstr[14],
+ cstr[15], cstr[16], cstr[17], cstr[18], cstr[19],
+ cstr[20], cstr[21], cstr[22], cstr[23], cstr[24],
+ cstr[25], cstr[26], cstr[27], cstr[28], cstr[29],
+ cstr[30], cstr[31]);
+}
diff --git a/src/third_party/s2/strings/stringprintf.h b/src/third_party/s2/strings/stringprintf.h
new file mode 100755
index 00000000000..4cb6e360106
--- /dev/null
+++ b/src/third_party/s2/strings/stringprintf.h
@@ -0,0 +1,40 @@
+// Copyright 2002 and onwards Google Inc.
+//
+// Printf variants that place their output in a C++ string.
+//
+// Usage:
+// string result = StringPrintf("%d %s\n", 10, "hello");
+// SStringPrintf(&result, "%d %s\n", 10, "hello");
+// StringAppendF(&result, "%d %s\n", 20, "there");
+
+#ifndef _STRINGS_STRINGPRINTF_H
+#define _STRINGS_STRINGPRINTF_H
+
+#include <stdarg.h>
+#include <string>
+using std::string;
+
+#include <vector>
+using std::vector;
+
+#include "base/stl_decl.h"
+#include "base/port.h"
+#include "base/stringprintf.h"
+
+// This file formerly contained
+// StringPrintf, SStringPrintf, StringAppendF, and StringAppendV.
+// These routines have moved to base/stringprintf.{h,cc} to allow
+// using them from files in base. We include base/stringprintf.h
+// in this file since so many clients were dependent on these
+// routines being defined in stringprintf.h.
+
+
+// The max arguments supported by StringPrintfVector
+extern const int kStringPrintfVectorMaxArgs;
+
+// You can use this version when all your arguments are strings, but
+// you don't know how many arguments you'll have at compile time.
+// StringPrintfVector will LOG(FATAL) if v.size() > kStringPrintfVectorMaxArgs
+extern string StringPrintfVector(const char* format, const vector<string>& v);
+
+#endif /* _STRINGS_STRINGPRINTF_H */
diff --git a/src/third_party/s2/strings/strutil.cc b/src/third_party/s2/strings/strutil.cc
new file mode 100755
index 00000000000..a6c6160cd99
--- /dev/null
+++ b/src/third_party/s2/strings/strutil.cc
@@ -0,0 +1,526 @@
+//
+// Copyright (C) 1999-2005 Google, Inc.
+//
+
+#include "strutil.h"
+
+#include <ctype.h>
+#include <errno.h>
+#include <float.h> // for DBL_DIG and FLT_DIG
+#include <math.h> // for HUGE_VAL
+#include <stdarg.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <time.h> // for FastTimeToBuffer()
+
+#include <algorithm>
+using std::min;
+using std::max;
+using std::swap;
+using std::reverse;
+
+#if defined OS_MACOSX
+#include <ext/hash_map>
+#else
+#include <hash_map>
+#endif
+#ifndef _WIN32
+using __gnu_cxx::hash_map;
+#endif
+
+#if defined OS_MACOSX
+#include <ext/hash_set>
+#else
+#include <hash_set>
+#endif
+#ifndef _WIN32
+using __gnu_cxx::hash_set;
+#endif
+
+#include <iterator>
+#include <limits>
+using std::numeric_limits;
+
+#include <set>
+using std::set;
+using std::multiset;
+
+#include <string>
+using std::string;
+
+#include <vector>
+using std::vector;
+
+
+#include "base/logging.h"
+#include "base/scoped_ptr.h"
+//#include "strutil-inl.h"
+//#include "third_party/utf/utf.h" // for runetochar
+//#include "util/gtl/stl_util-inl.h" // for string_as_array
+//#include "util/hash/hash.h"
+#include "split.h"
+
+#ifdef OS_WINDOWS
+#ifdef min // windows.h defines this to something silly
+#undef min
+#endif
+#endif
+
+// ----------------------------------------------------------------------
+// FpToString()
+// FloatToString()
+// IntToString()
+// Convert various types to their string representation. These
+// all do the obvious, trivial thing.
+// ----------------------------------------------------------------------
+
+string FpToString(Fprint fp) {
+ char buf[17];
+ snprintf(buf, sizeof(buf), "%016llx", fp);
+ return string(buf);
+}
+
+string FloatToString(float f, const char* format) {
+ char buf[80];
+ snprintf(buf, sizeof(buf), format, f);
+ return string(buf);
+}
+
+string IntToString(int i, const char* format) {
+ char buf[80];
+ snprintf(buf, sizeof(buf), format, i);
+ return string(buf);
+}
+
+string Int64ToString(int64 i64, const char* format) {
+ char buf[80];
+ snprintf(buf, sizeof(buf), format, i64);
+ return string(buf);
+}
+
+string UInt64ToString(uint64 ui64, const char* format) {
+ char buf[80];
+ snprintf(buf, sizeof(buf), format, ui64);
+ return string(buf);
+}
+
+// Default arguments
+string FloatToString(float f) { return FloatToString(f, "%7f"); }
+string IntToString(int i) { return IntToString(i, "%7d"); }
+string Int64ToString(int64 i64) {
+ return Int64ToString(i64, "%7" GG_LL_FORMAT "d");
+}
+string UInt64ToString(uint64 ui64) {
+ return UInt64ToString(ui64, "%7" GG_LL_FORMAT "u");
+}
+
+// ----------------------------------------------------------------------
+// FastIntToBuffer()
+// FastInt64ToBuffer()
+// FastHexToBuffer()
+// FastHex64ToBuffer()
+// FastHex32ToBuffer()
+// FastTimeToBuffer()
+// These are intended for speed. FastHexToBuffer() assumes the
+// integer is non-negative. FastHexToBuffer() puts output in
+// hex rather than decimal. FastTimeToBuffer() puts the output
+// into RFC822 format. If time is 0, uses the current time.
+//
+// FastHex64ToBuffer() puts a 64-bit unsigned value in hex-format,
+// padded to exactly 16 bytes (plus one byte for '\0')
+//
+// FastHex32ToBuffer() puts a 32-bit unsigned value in hex-format,
+// padded to exactly 8 bytes (plus one byte for '\0')
+//
+// All functions take the output buffer as an arg. FastInt()
+// uses at most 22 bytes, FastTime() uses exactly 30 bytes.
+// They all return a pointer to the beginning of the output,
+// which may not be the beginning of the input buffer. (Though
+// for FastTimeToBuffer(), we guarantee that it is.)
+// ----------------------------------------------------------------------
+
+char *FastInt64ToBuffer(int64 i, char* buffer) {
+ FastInt64ToBufferLeft(i, buffer);
+ return buffer;
+}
+
+// Sigh, also not actually defined here, copied from:
+// https://github.com/splitfeed/android-market-api-php/blob/master/proto/protoc-gen-php/strutil.cc
+
+static const char two_ASCII_digits[100][2] = {
+ {'0','0'}, {'0','1'}, {'0','2'}, {'0','3'}, {'0','4'},
+ {'0','5'}, {'0','6'}, {'0','7'}, {'0','8'}, {'0','9'},
+ {'1','0'}, {'1','1'}, {'1','2'}, {'1','3'}, {'1','4'},
+ {'1','5'}, {'1','6'}, {'1','7'}, {'1','8'}, {'1','9'},
+ {'2','0'}, {'2','1'}, {'2','2'}, {'2','3'}, {'2','4'},
+ {'2','5'}, {'2','6'}, {'2','7'}, {'2','8'}, {'2','9'},
+ {'3','0'}, {'3','1'}, {'3','2'}, {'3','3'}, {'3','4'},
+ {'3','5'}, {'3','6'}, {'3','7'}, {'3','8'}, {'3','9'},
+ {'4','0'}, {'4','1'}, {'4','2'}, {'4','3'}, {'4','4'},
+ {'4','5'}, {'4','6'}, {'4','7'}, {'4','8'}, {'4','9'},
+ {'5','0'}, {'5','1'}, {'5','2'}, {'5','3'}, {'5','4'},
+ {'5','5'}, {'5','6'}, {'5','7'}, {'5','8'}, {'5','9'},
+ {'6','0'}, {'6','1'}, {'6','2'}, {'6','3'}, {'6','4'},
+ {'6','5'}, {'6','6'}, {'6','7'}, {'6','8'}, {'6','9'},
+ {'7','0'}, {'7','1'}, {'7','2'}, {'7','3'}, {'7','4'},
+ {'7','5'}, {'7','6'}, {'7','7'}, {'7','8'}, {'7','9'},
+ {'8','0'}, {'8','1'}, {'8','2'}, {'8','3'}, {'8','4'},
+ {'8','5'}, {'8','6'}, {'8','7'}, {'8','8'}, {'8','9'},
+ {'9','0'}, {'9','1'}, {'9','2'}, {'9','3'}, {'9','4'},
+ {'9','5'}, {'9','6'}, {'9','7'}, {'9','8'}, {'9','9'}
+};
+
+char* FastUInt32ToBufferLeft(uint32 u, char* buffer) {
+ int digits;
+ const char *ASCII_digits = NULL;
+ // The idea of this implementation is to trim the number of divides to as few
+ // as possible by using multiplication and subtraction rather than mod (%),
+ // and by outputting two digits at a time rather than one.
+ // The huge-number case is first, in the hopes that the compiler will output
+ // that case in one branch-free block of code, and only output conditional
+ // branches into it from below.
+ if (u >= 1000000000) { // >= 1,000,000,000
+ digits = u / 100000000; // 100,000,000
+ ASCII_digits = two_ASCII_digits[digits];
+ buffer[0] = ASCII_digits[0];
+ buffer[1] = ASCII_digits[1];
+ buffer += 2;
+sublt100_000_000:
+ u -= digits * 100000000; // 100,000,000
+lt100_000_000:
+ digits = u / 1000000; // 1,000,000
+ ASCII_digits = two_ASCII_digits[digits];
+ buffer[0] = ASCII_digits[0];
+ buffer[1] = ASCII_digits[1];
+ buffer += 2;
+sublt1_000_000:
+ u -= digits * 1000000; // 1,000,000
+lt1_000_000:
+ digits = u / 10000; // 10,000
+ ASCII_digits = two_ASCII_digits[digits];
+ buffer[0] = ASCII_digits[0];
+ buffer[1] = ASCII_digits[1];
+ buffer += 2;
+sublt10_000:
+ u -= digits * 10000; // 10,000
+lt10_000:
+ digits = u / 100;
+ ASCII_digits = two_ASCII_digits[digits];
+ buffer[0] = ASCII_digits[0];
+ buffer[1] = ASCII_digits[1];
+ buffer += 2;
+sublt100:
+ u -= digits * 100;
+lt100:
+ digits = u;
+ ASCII_digits = two_ASCII_digits[digits];
+ buffer[0] = ASCII_digits[0];
+ buffer[1] = ASCII_digits[1];
+ buffer += 2;
+done:
+ *buffer = 0;
+ return buffer;
+ }
+
+ if (u < 100) {
+ digits = u;
+ if (u >= 10) goto lt100;
+ *buffer++ = '0' + digits;
+ goto done;
+ }
+ if (u < 10000) { // 10,000
+ if (u >= 1000) goto lt10_000;
+ digits = u / 100;
+ *buffer++ = '0' + digits;
+ goto sublt100;
+ }
+ if (u < 1000000) { // 1,000,000
+ if (u >= 100000) goto lt1_000_000;
+ digits = u / 10000; // 10,000
+ *buffer++ = '0' + digits;
+ goto sublt10_000;
+ }
+ if (u < 100000000) { // 100,000,000
+ if (u >= 10000000) goto lt100_000_000;
+ digits = u / 1000000; // 1,000,000
+ *buffer++ = '0' + digits;
+ goto sublt1_000_000;
+ }
+ // we already know that u < 1,000,000,000
+ digits = u / 100000000; // 100,000,000
+ *buffer++ = '0' + digits;
+ goto sublt100_000_000;
+}
+char* FastUInt64ToBufferLeft(uint64 u64, char* buffer) {
+ int digits;
+ const char *ASCII_digits = NULL;
+
+ uint32 u = static_cast<uint32>(u64);
+ if (u == u64) return FastUInt32ToBufferLeft(u, buffer);
+
+ uint64 top_11_digits = u64 / 1000000000;
+ buffer = FastUInt64ToBufferLeft(top_11_digits, buffer);
+ u = u64 - (top_11_digits * 1000000000);
+
+ digits = u / 10000000; // 10,000,000
+ DCHECK_LT(digits, 100);
+ ASCII_digits = two_ASCII_digits[digits];
+ buffer[0] = ASCII_digits[0];
+ buffer[1] = ASCII_digits[1];
+ buffer += 2;
+ u -= digits * 10000000; // 10,000,000
+ digits = u / 100000; // 100,000
+ ASCII_digits = two_ASCII_digits[digits];
+ buffer[0] = ASCII_digits[0];
+ buffer[1] = ASCII_digits[1];
+ buffer += 2;
+ u -= digits * 100000; // 100,000
+ digits = u / 1000; // 1,000
+ ASCII_digits = two_ASCII_digits[digits];
+ buffer[0] = ASCII_digits[0];
+ buffer[1] = ASCII_digits[1];
+ buffer += 2;
+ u -= digits * 1000; // 1,000
+ digits = u / 10;
+ ASCII_digits = two_ASCII_digits[digits];
+ buffer[0] = ASCII_digits[0];
+ buffer[1] = ASCII_digits[1];
+ buffer += 2;
+ u -= digits * 10;
+ digits = u;
+ *buffer++ = '0' + digits;
+ *buffer = 0;
+ return buffer;
+}
+
+char* FastInt64ToBufferLeft(int64 i, char* buffer) {
+ uint64 u = i;
+ if (i < 0) {
+ *buffer++ = '-';
+ u = -i;
+ }
+ return FastUInt64ToBufferLeft(u, buffer);
+}
+
+// Offset into buffer where FastInt32ToBuffer places the end of string
+// null character. Also used by FastInt32ToBufferLeft
+static const int kFastInt32ToBufferOffset = 11;
+
+// This used to call out to FastInt32ToBufferLeft but that wasn't defined.
+// Copied from http://gears.googlecode.com/svn-history/r395/trunk/gears/base/common/string16.cc
+char *FastInt32ToBuffer(int32 i, char* buffer) {
+ // We could collapse the positive and negative sections, but that
+ // would be slightly slower for positive numbers...
+ // 12 bytes is enough to store -2**32, -4294967296.
+ char* p = buffer + kFastInt32ToBufferOffset;
+ *p-- = '\0';
+ if (i >= 0) {
+ do {
+ *p-- = '0' + i % 10;
+ i /= 10;
+ } while (i > 0);
+ return p + 1;
+ } else {
+ // On different platforms, % and / have different behaviors for
+ // negative numbers, so we need to jump through hoops to make sure
+ // we don't divide negative numbers.
+ if (i > -10) {
+ i = -i;
+ *p-- = '0' + i;
+ *p = '-';
+ return p;
+ } else {
+ // Make sure we aren't at MIN_INT, in which case we can't say i = -i
+ i = i + 10;
+ i = -i;
+ *p-- = '0' + i % 10;
+ // Undo what we did a moment ago
+ i = i / 10 + 1;
+ do {
+ *p-- = '0' + i % 10;
+ i /= 10;
+ } while (i > 0);
+ *p = '-';
+ return p;
+ }
+ }
+}
+
+char *FastHexToBuffer(int i, char* buffer) {
+ CHECK(i >= 0) << "FastHexToBuffer() wants non-negative integers, not " << i;
+
+ static const char *hexdigits = "0123456789abcdef";
+ char *p = buffer + 21;
+ *p-- = '\0';
+ do {
+ *p-- = hexdigits[i & 15]; // mod by 16
+ i >>= 4; // divide by 16
+ } while (i > 0);
+ return p + 1;
+}
+
+char *InternalFastHexToBuffer(uint64 value, char* buffer, int num_byte) {
+ static const char *hexdigits = "0123456789abcdef";
+ buffer[num_byte] = '\0';
+ for (int i = num_byte - 1; i >= 0; i--) {
+ buffer[i] = hexdigits[uint32(value) & 0xf];
+ value >>= 4;
+ }
+ return buffer;
+}
+
+char *FastHex64ToBuffer(uint64 value, char* buffer) {
+ return InternalFastHexToBuffer(value, buffer, 16);
+}
+
+char *FastHex32ToBuffer(uint32 value, char* buffer) {
+ return InternalFastHexToBuffer(value, buffer, 8);
+}
+
+static inline void PutTwoDigits(int i, char* p) {
+ DCHECK_GE(i, 0);
+ DCHECK_LT(i, 100);
+ p[0] = two_ASCII_digits[i][0];
+ p[1] = two_ASCII_digits[i][1];
+}
+
+#if 0
+char* FastTimeToBuffer(time_t s, char* buffer) {
+ if (s == 0) {
+ time(&s);
+ }
+
+ struct tm tm;
+ if (gmtime_r(&s, &tm) == NULL) {
+ // Error message must fit in 30-char buffer.
+ memcpy(buffer, "Invalid:", sizeof("Invalid:"));
+ FastInt64ToBufferLeft(s, buffer+strlen(buffer));
+ return buffer;
+ }
+
+ // strftime format: "%a, %d %b %Y %H:%M:%S GMT",
+ // but strftime does locale stuff which we do not want
+ // plus strftime takes > 10x the time of hard code
+
+ const char* weekday_name = "Xxx";
+ switch (tm.tm_wday) {
+ default: { DCHECK(false); } break;
+ case 0: weekday_name = "Sun"; break;
+ case 1: weekday_name = "Mon"; break;
+ case 2: weekday_name = "Tue"; break;
+ case 3: weekday_name = "Wed"; break;
+ case 4: weekday_name = "Thu"; break;
+ case 5: weekday_name = "Fri"; break;
+ case 6: weekday_name = "Sat"; break;
+ }
+
+ const char* month_name = "Xxx";
+ switch (tm.tm_mon) {
+ default: { DCHECK(false); } break;
+ case 0: month_name = "Jan"; break;
+ case 1: month_name = "Feb"; break;
+ case 2: month_name = "Mar"; break;
+ case 3: month_name = "Apr"; break;
+ case 4: month_name = "May"; break;
+ case 5: month_name = "Jun"; break;
+ case 6: month_name = "Jul"; break;
+ case 7: month_name = "Aug"; break;
+ case 8: month_name = "Sep"; break;
+ case 9: month_name = "Oct"; break;
+ case 10: month_name = "Nov"; break;
+ case 11: month_name = "Dec"; break;
+ }
+
+ // Write out the buffer.
+
+ memcpy(buffer+0, weekday_name, 3);
+ buffer[3] = ',';
+ buffer[4] = ' ';
+
+ PutTwoDigits(tm.tm_mday, buffer+5);
+ buffer[7] = ' ';
+
+ memcpy(buffer+8, month_name, 3);
+ buffer[11] = ' ';
+
+ int32 year = tm.tm_year + 1900;
+ PutTwoDigits(year/100, buffer+12);
+ PutTwoDigits(year%100, buffer+14);
+ buffer[16] = ' ';
+
+ PutTwoDigits(tm.tm_hour, buffer+17);
+ buffer[19] = ':';
+
+ PutTwoDigits(tm.tm_min, buffer+20);
+ buffer[22] = ':';
+
+ PutTwoDigits(tm.tm_sec, buffer+23);
+
+ // includes ending NUL
+ memcpy(buffer+25, " GMT", 5);
+
+ return buffer;
+}
+#endif
+
+// ----------------------------------------------------------------------
+// ParseLeadingUInt64Value
+// ParseLeadingInt64Value
+// ParseLeadingHex64Value
+// A simple parser for long long values. Returns the parsed value if a
+// valid integer is found; else returns deflt
+// UInt64 and Int64 cannot handle decimal numbers with leading 0s.
+// --------------------------------------------------------------------
+uint64 ParseLeadingUInt64Value(const char *str, uint64 deflt) {
+ char *error = NULL;
+ const uint64 value = strtoull(str, &error, 0);
+ return (error == str) ? deflt : value;
+}
+
+int64 ParseLeadingInt64Value(const char *str, int64 deflt) {
+ char *error = NULL;
+ const int64 value = strtoll(str, &error, 0);
+ return (error == str) ? deflt : value;
+}
+
+uint64 ParseLeadingHex64Value(const char *str, uint64 deflt) {
+ char *error = NULL;
+ const uint64 value = strtoull(str, &error, 16);
+ return (error == str) ? deflt : value;
+}
+
+// ----------------------------------------------------------------------
+// ParseLeadingDec64Value
+// ParseLeadingUDec64Value
+// A simple parser for [u]int64 values. Returns the parsed value
+// if a valid value is found; else returns deflt
+// The string passed in is treated as *10 based*.
+// This can handle strings with leading 0s.
+// --------------------------------------------------------------------
+
+int64 ParseLeadingDec64Value(const char *str, int64 deflt) {
+ char *error = NULL;
+ const int64 value = strtoll(str, &error, 10);
+ return (error == str) ? deflt : value;
+}
+
+uint64 ParseLeadingUDec64Value(const char *str, uint64 deflt) {
+ char *error = NULL;
+ const uint64 value = strtoull(str, &error, 10);
+ return (error == str) ? deflt : value;
+}
+
+bool DictionaryParse(const string& encoded_str,
+ vector<pair<string, string> >* items) {
+ vector<string> entries;
+ SplitStringUsing(encoded_str, ",", &entries);
+ for (size_t i = 0; i < entries.size(); ++i) {
+ vector<string> fields;
+ SplitStringAllowEmpty(entries[i], ":", &fields);
+ if (fields.size() != 2) // parsing error
+ return false;
+ items->push_back(make_pair(fields[0], fields[1]));
+ }
+ return true;
+}
diff --git a/src/third_party/s2/strings/strutil.h b/src/third_party/s2/strings/strutil.h
new file mode 100755
index 00000000000..a15f51a98a9
--- /dev/null
+++ b/src/third_party/s2/strings/strutil.h
@@ -0,0 +1,325 @@
+//
+// Copyright 1999-2006 and onwards Google, Inc.
+//
+// Useful string functions and so forth. This is a grab-bag file.
+//
+// You might also want to look at memutil.h, which holds mem*()
+// equivalents of a lot of the str*() functions in string.h,
+// eg memstr, mempbrk, etc.
+//
+// If you need to process UTF8 strings, take a look at files in i18n/utf8.
+
+#ifndef STRINGS_STRUTIL_H_
+#define STRINGS_STRUTIL_H_
+
+#include "base/definer.h"
+#if defined OS_MACOSX
+#include <ext/hash_map>
+#else
+#include <hash_map>
+#endif
+#ifndef _WIN32
+using __gnu_cxx::hash_map;
+#endif
+
+#if defined OS_MACOSX
+#include <ext/hash_set>
+#else
+#include <hash_set>
+#endif
+#ifndef _WIN32
+using __gnu_cxx::hash_set;
+#endif
+
+
+#include <functional>
+using std::less;
+#include <set>
+using std::set;
+using std::multiset;
+
+#include <string>
+using std::string;
+
+#include <utility>
+using std::pair;
+using std::make_pair;
+
+#include <vector>
+using std::vector;
+
+#include <string.h>
+#include <stdlib.h>
+
+// for strcasecmp (check SuSv3 -- this is the only header it's in!)
+// MSVC doesn't have <strings.h>. Luckily, it defines equivalent
+// functions (see port.h)
+#ifndef _WIN32
+#include <strings.h>
+#endif
+#include <ctype.h> // not needed, but removing it will break the build
+
+using namespace std;
+#ifndef _WIN32
+using namespace __gnu_cxx;
+#endif
+
+// A buffer size which is large enough for all the FastToBuffer functions, as
+// well as DoubleToBuffer and FloatToBuffer. We define this here in case other
+// string headers depend on it.
+static const int kFastToBufferSize = 32;
+
+#include "base/basictypes.h"
+#include "base/logging.h" // for CHECK
+#include "base/strtoint.h"
+#include "base/int128.h"
+#include "ascii_ctype.h"
+//#include "charset.h"
+//#include "escaping.h"
+//#include "host_port.h"
+#include "stringprintf.h"
+#include "base/stl_decl.h"
+#include "base/port.h"
+#include "util/endian/endian.h"
+
+// ----------------------------------------------------------------------
+// FpToString()
+// FloatToString()
+// IntToString()
+// Int64ToString()
+// UInt64ToString()
+// Convert various types to their string representation, possibly padded
+// with spaces, using snprintf format specifiers.
+// "Fp" here stands for fingerprint: a 64-bit entity
+// represented in 16 hex digits.
+// ----------------------------------------------------------------------
+
+string FpToString(Fprint fp);
+string FloatToString(float f, const char* format);
+string IntToString(int i, const char* format);
+string Int64ToString(int64 i64, const char* format);
+string UInt64ToString(uint64 ui64, const char* format);
+
+// The default formats are %7f, %7d, and %7u respectively
+string FloatToString(float f);
+string IntToString(int i);
+string Int64ToString(int64 i64);
+string UInt64ToString(uint64 ui64);
+
+// ----------------------------------------------------------------------
+// FastIntToBuffer()
+// FastHexToBuffer()
+// FastHex64ToBuffer()
+// FastHex32ToBuffer()
+// FastTimeToBuffer()
+// These are intended for speed. FastIntToBuffer() assumes the
+// integer is non-negative. FastHexToBuffer() puts output in
+// hex rather than decimal. FastTimeToBuffer() puts the output
+// into RFC822 format.
+//
+// FastHex64ToBuffer() puts a 64-bit unsigned value in hex-format,
+// padded to exactly 16 bytes (plus one byte for '\0')
+//
+// FastHex32ToBuffer() puts a 32-bit unsigned value in hex-format,
+// padded to exactly 8 bytes (plus one byte for '\0')
+//
+// All functions take the output buffer as an arg. FastInt()
+// uses at most 22 bytes, FastTime() uses exactly 30 bytes.
+// They all return a pointer to the beginning of the output,
+// which may not be the beginning of the input buffer. (Though
+// for FastTimeToBuffer(), we guarantee that it is.)
+//
+// NOTE: In 64-bit land, sizeof(time_t) is 8, so it is possible
+// to pass to FastTimeToBuffer() a time whose year cannot be
+// represented in 4 digits. In this case, the output buffer
+// will contain the string "Invalid:<value>"
+// ----------------------------------------------------------------------
+
+// Previously documented minimums -- the buffers provided must be at least this
+// long, though these numbers are subject to change:
+// Int32, UInt32: 12 bytes
+// Int64, UInt64, Hex: 22 bytes
+// Time: 30 bytes
+// Hex32: 9 bytes
+// Hex64: 17 bytes
+// Use kFastToBufferSize rather than hardcoding constants.
+
+char* FastInt32ToBuffer(int32 i, char* buffer);
+char* FastInt64ToBuffer(int64 i, char* buffer);
+char* FastUInt32ToBuffer(uint32 i, char* buffer);
+char* FastUInt64ToBuffer(uint64 i, char* buffer);
+char* FastHexToBuffer(int i, char* buffer);
+char* FastTimeToBuffer(time_t t, char* buffer);
+char* FastHex64ToBuffer(uint64 i, char* buffer);
+char* FastHex32ToBuffer(uint32 i, char* buffer);
+
+// at least 22 bytes long
+inline char* FastIntToBuffer(int i, char* buffer) {
+ return (sizeof(i) == 4 ?
+ FastInt32ToBuffer(i, buffer) : FastInt64ToBuffer(i, buffer));
+}
+inline char* FastUIntToBuffer(unsigned int i, char* buffer) {
+ return (sizeof(i) == 4 ?
+ FastUInt32ToBuffer(i, buffer) : FastUInt64ToBuffer(i, buffer));
+}
+inline char* FastLongToBuffer(long i, char* buffer) {
+ return (sizeof(i) == 4 ?
+ FastInt32ToBuffer(i, buffer) : FastInt64ToBuffer(i, buffer));
+}
+inline char* FastULongToBuffer(unsigned long i, char* buffer) {
+ return (sizeof(i) == 4 ?
+ FastUInt32ToBuffer(i, buffer) : FastUInt64ToBuffer(i, buffer));
+}
+
+// A generic "number type" to buffer template and specializations.
+//
+// The specialization of FastNumToBuffer<>() should always be made explicit:
+// FastNumToBuffer<int32>(mynums); // yes
+// FastNumToBuffer(mynums); // no
+template<typename T> char* FastNumToBuffer(T, char*);
+template<> inline char* FastNumToBuffer<int32>(int32 i, char* buffer) {
+ return FastInt32ToBuffer(i, buffer);
+}
+template<> inline char* FastNumToBuffer<int64>(int64 i, char* buffer) {
+ return FastInt64ToBuffer(i, buffer);
+}
+template<> inline char* FastNumToBuffer<uint32>(uint32 i, char* buffer) {
+ return FastUInt32ToBuffer(i, buffer);
+}
+template<> inline char* FastNumToBuffer<uint64>(uint64 i, char* buffer) {
+ return FastUInt64ToBuffer(i, buffer);
+}
+
+// ----------------------------------------------------------------------
+// FastInt32ToBufferLeft()
+// FastUInt32ToBufferLeft()
+// FastInt64ToBufferLeft()
+// FastUInt64ToBufferLeft()
+//
+// Like the Fast*ToBuffer() functions above, these are intended for speed.
+// Unlike the Fast*ToBuffer() functions, however, these functions write
+// their output to the beginning of the buffer (hence the name, as the
+// output is left-aligned). The caller is responsible for ensuring that
+// the buffer has enough space to hold the output.
+//
+// Returns a pointer to the end of the string (i.e. the null character
+// terminating the string).
+// ----------------------------------------------------------------------
+
+char* FastInt32ToBufferLeft(int32 i, char* buffer); // at least 12 bytes
+char* FastUInt32ToBufferLeft(uint32 i, char* buffer); // at least 12 bytes
+char* FastInt64ToBufferLeft(int64 i, char* buffer); // at least 22 bytes
+char* FastUInt64ToBufferLeft(uint64 i, char* buffer); // at least 22 bytes
+
+// Just define these in terms of the above.
+inline char* FastUInt32ToBuffer(uint32 i, char* buffer) {
+ FastUInt32ToBufferLeft(i, buffer);
+ return buffer;
+}
+inline char* FastUInt64ToBuffer(uint64 i, char* buffer) {
+ FastUInt64ToBufferLeft(i, buffer);
+ return buffer;
+}
+
+// ----------------------------------------------------------------------
+// ConsumeStrayLeadingZeroes
+// Eliminates all leading zeroes (unless the string itself is composed
+// of nothing but zeroes, in which case one is kept: 0...0 becomes 0).
+void ConsumeStrayLeadingZeroes(string* str);
+
+// ----------------------------------------------------------------------
+// ParseLeadingInt32Value
+// A simple parser for int32 values. Returns the parsed value
+// if a valid integer is found; else returns deflt. It does not
+// check if str is entirely consumed.
+// This cannot handle decimal numbers with leading 0s, since they will be
+// treated as octal. If you know it's decimal, use ParseLeadingDec32Value.
+// --------------------------------------------------------------------
+int32 ParseLeadingInt32Value(const char* str, int32 deflt);
+inline int32 ParseLeadingInt32Value(const string& str, int32 deflt) {
+ return ParseLeadingInt32Value(str.c_str(), deflt);
+}
+
+// ParseLeadingUInt32Value
+// A simple parser for uint32 values. Returns the parsed value
+// if a valid integer is found; else returns deflt. It does not
+// check if str is entirely consumed.
+// This cannot handle decimal numbers with leading 0s, since they will be
+// treated as octal. If you know it's decimal, use ParseLeadingUDec32Value.
+// --------------------------------------------------------------------
+uint32 ParseLeadingUInt32Value(const char* str, uint32 deflt);
+inline uint32 ParseLeadingUInt32Value(const string& str, uint32 deflt) {
+ return ParseLeadingUInt32Value(str.c_str(), deflt);
+}
+
+// ----------------------------------------------------------------------
+// ParseLeadingDec32Value
+// A simple parser for decimal int32 values. Returns the parsed value
+// if a valid integer is found; else returns deflt. It does not
+// check if str is entirely consumed.
+// The string passed in is treated as *10 based*.
+// This can handle strings with leading 0s.
+// See also: ParseLeadingDec64Value
+// --------------------------------------------------------------------
+int32 ParseLeadingDec32Value(const char* str, int32 deflt);
+inline int32 ParseLeadingDec32Value(const string& str, int32 deflt) {
+ return ParseLeadingDec32Value(str.c_str(), deflt);
+}
+
+// ParseLeadingUDec32Value
+// A simple parser for decimal uint32 values. Returns the parsed value
+// if a valid integer is found; else returns deflt. It does not
+// check if str is entirely consumed.
+// The string passed in is treated as *10 based*.
+// This can handle strings with leading 0s.
+// See also: ParseLeadingUDec64Value
+// --------------------------------------------------------------------
+uint32 ParseLeadingUDec32Value(const char* str, uint32 deflt);
+inline uint32 ParseLeadingUDec32Value(const string& str, uint32 deflt) {
+ return ParseLeadingUDec32Value(str.c_str(), deflt);
+}
+
+// ----------------------------------------------------------------------
+// ParseLeadingUInt64Value
+// ParseLeadingInt64Value
+// ParseLeadingHex64Value
+// ParseLeadingDec64Value
+// ParseLeadingUDec64Value
+// A simple parser for long long values.
+// Returns the parsed value if a
+// valid integer is found; else returns deflt
+// --------------------------------------------------------------------
+uint64 ParseLeadingUInt64Value(const char* str, uint64 deflt);
+inline uint64 ParseLeadingUInt64Value(const string& str, uint64 deflt) {
+ return ParseLeadingUInt64Value(str.c_str(), deflt);
+}
+int64 ParseLeadingInt64Value(const char* str, int64 deflt);
+inline int64 ParseLeadingInt64Value(const string& str, int64 deflt) {
+ return ParseLeadingInt64Value(str.c_str(), deflt);
+}
+uint64 ParseLeadingHex64Value(const char* str, uint64 deflt);
+inline uint64 ParseLeadingHex64Value(const string& str, uint64 deflt) {
+ return ParseLeadingHex64Value(str.c_str(), deflt);
+}
+int64 ParseLeadingDec64Value(const char* str, int64 deflt);
+inline int64 ParseLeadingDec64Value(const string& str, int64 deflt) {
+ return ParseLeadingDec64Value(str.c_str(), deflt);
+}
+uint64 ParseLeadingUDec64Value(const char* str, uint64 deflt);
+inline uint64 ParseLeadingUDec64Value(const string& str, uint64 deflt) {
+ return ParseLeadingUDec64Value(str.c_str(), deflt);
+}
+
+// -------------------------------------------------------------------------
+// DictionaryParse
+// This routine parses a common dictionary format (key and value separated
+// by ':', entries separated by commas). This format is used for many
+// complex commandline flags. It is also used to encode dictionaries for
+// exporting them or writing them to a checkpoint. Returns a vector of
+// <key, value> pairs. Returns true if there if no error in parsing, false
+// otherwise.
+// -------------------------------------------------------------------------
+bool DictionaryParse(const string& encoded_str,
+ vector<pair<string, string> >* items);
+
+#endif /* #ifndef STRINGS_STRUTIL_H_ */
diff --git a/src/third_party/s2/util/coding/SConscript b/src/third_party/s2/util/coding/SConscript
new file mode 100755
index 00000000000..15f77f28ad3
--- /dev/null
+++ b/src/third_party/s2/util/coding/SConscript
@@ -0,0 +1,15 @@
+# -*- mode: python -*-
+
+Import("env windows linux darwin solaris")
+
+env = env.Clone()
+
+env.Append(CCFLAGS=['-Isrc/third_party/s2'])
+env.Append(CCFLAGS=['-Isrc/third_party/gflags-2.0/src'])
+
+env.StaticLibrary(
+ "coding",
+ [
+ "coder.cc",
+ "varint.cc",
+ ])
diff --git a/src/third_party/s2/util/coding/coder.cc b/src/third_party/s2/util/coding/coder.cc
new file mode 100755
index 00000000000..32b0b372678
--- /dev/null
+++ b/src/third_party/s2/util/coding/coder.cc
@@ -0,0 +1,107 @@
+//
+// Copyright 2000 - 2003 Google Inc.
+//
+//
+
+#include "base/logging.h"
+#include "util/coding/coder.h"
+
+// An initialization value used when we are allowed to
+unsigned char Encoder::kEmptyBuffer = 0;
+const int Encoder::kVarintMax32 = Varint::kMax32;
+const int Encoder::kVarintMax64 = Varint::kMax64;
+
+Encoder::Encoder()
+ : orig_(NULL),
+ buf_(NULL),
+ limit_(NULL),
+ underlying_buffer_(&kEmptyBuffer) {
+}
+
+Encoder::~Encoder() {
+ if (underlying_buffer_ != &kEmptyBuffer) {
+ delete[] underlying_buffer_;
+ }
+}
+
+int Encoder::varint32_length(uint32 v) {
+ return Varint::Length32(v);
+}
+
+int Encoder::varint64_length(uint64 v) {
+ return Varint::Length64(v);
+}
+
+void Encoder::EnsureSlowPath(int N) {
+ CHECK(ensure_allowed());
+ assert(avail() < N);
+ assert(length() == 0 || orig_ == underlying_buffer_);
+
+ // Double buffer size, but make sure we always have at least N extra bytes
+ int current_len = length();
+ int new_capacity = max(current_len + N, 2 * current_len);
+
+ unsigned char* new_buffer = new unsigned char[new_capacity];
+ memcpy(new_buffer, underlying_buffer_, current_len);
+ if (underlying_buffer_ != &kEmptyBuffer) {
+ delete[] underlying_buffer_;
+ }
+ underlying_buffer_ = new_buffer;
+
+ orig_ = new_buffer;
+ limit_ = new_buffer + new_capacity;
+ buf_ = orig_ + current_len;
+ CHECK(avail() >= N);
+}
+
+void Encoder::RemoveLast(int N) {
+ CHECK(length() >= N);
+ buf_ -= N;
+}
+
+void Encoder::Resize(int N) {
+ CHECK(length() >= N);
+ buf_ = orig_ + N;
+ assert(length() == N);
+}
+
+// Special optimized version: does not use Varint
+bool Decoder::get_varint32(uint32* v) {
+ const char* r = Varint::Parse32WithLimit(
+ reinterpret_cast<const char*>(buf_),
+ reinterpret_cast<const char*>(limit_), v);
+ if (r == NULL) { return false; }
+ buf_ = reinterpret_cast<const unsigned char*>(r);
+ return true;
+}
+
+// Special optimized version: does not use Varint
+bool Decoder::get_varint64(uint64* v) {
+ uint64 result = 0;
+
+ if (buf_ + Varint::kMax64 <= limit_) {
+ const char* r = Varint::Parse64(reinterpret_cast<const char*>(buf_), v);
+ if (r == NULL) {
+ return false;
+ } else {
+ buf_ = reinterpret_cast<const unsigned char*>(r);
+ return true;
+ }
+ } else {
+ int shift = 0; // How much to shift next set of bits
+ unsigned char byte;
+ do {
+ if ((shift >= 64) || (buf_ >= limit_)) {
+ // Out of range
+ return false;
+ }
+
+ // Get 7 bits from next byte
+ byte = *(buf_++);
+ result |= static_cast<uint64>(byte & 127) << shift;
+ shift += 7;
+ } while ((byte & 128) != 0);
+ *v = result;
+ return true;
+ }
+}
diff --git a/src/third_party/s2/util/coding/coder.h b/src/third_party/s2/util/coding/coder.h
new file mode 100755
index 00000000000..a295613260d
--- /dev/null
+++ b/src/third_party/s2/util/coding/coder.h
@@ -0,0 +1,444 @@
+//
+// Copyright 2000 - 2003 Google Inc.
+//
+//
+// This holds the encoding/decoding routines that used to live in netutil
+
+#ifndef UTIL_CODING_CODER_H__
+#define UTIL_CODING_CODER_H__
+
+#include <algorithm>
+using std::min;
+using std::max;
+using std::swap;
+using std::reverse;
+ // for min
+#include "util/coding/varint.h"
+#include "base/logging.h"
+#include "base/port.h"
+#include "util/endian/endian.h"
+
+/* Class for encoding data into a memory buffer */
+class Encoder {
+ public:
+ // Creates an empty Encoder with no room that is enlarged
+ // (if necessary) when "Encoder::Ensure(N)" is called.
+ Encoder();
+ ~Encoder();
+
+ // Initialize encoder to encode into "buf"
+ explicit Encoder(void* buf, int maxn);
+ void reset(void* buf, int maxn);
+ void clear();
+
+ // Encoding routines. Note that these do not check bounds
+ void put8(unsigned char v);
+ void put16(uint16 v);
+ void put32(uint32 v);
+ void put64(uint64 v);
+ void putword(uword_t v);
+ void putn(const void* mem, int n);
+
+ // put no more than n bytes, stopping when c is put
+ void putcn(const void* mem, int c, int n);
+
+ void puts(const void* mem); // put a c-string including \0
+ void puts_without_null(const char* mem); // put a c-string without \0
+ void putfloat(float f);
+ void putdouble(double d);
+
+ // Support for variable length encoding with 7 bits per byte
+ // (these are just simple wrappers around the Varint module)
+ static const int kVarintMax32; // = Varint::kMax32;
+ static const int kVarintMax64; // = Varint::kMax64;
+
+ void put_varint32(uint32 v);
+ void put_varint64(uint64 v);
+ static int varint32_length(uint32 v); // Length of var encoding of "v"
+ static int varint64_length(uint64 v); // Length of var encoding of "v"
+
+ // DEPRECATED
+ //
+ // For new code use put_varint32(ZigZagEncode(signed_value));
+ // ZigZag coding is defined in utils/coding/transforms.h
+ void put_varsigned32(int32 v);
+
+ // Support for a few special types we don't want to restrict size of
+ void put_docid(DocId d);
+
+ // Return number of bytes encoded so far
+ int length() const;
+
+ // Return number of bytes of space remaining in buffer
+ int avail() const;
+
+ // REQUIRES: Encoder was created with the 0-argument constructor interface.
+ //
+ // This interface ensures that at least "N" more bytes are available
+ // in the underlying buffer by resizing the buffer (if necessary).
+ //
+ // Note that no bounds checking is done on any of the put routines,
+ // so it is the client's responsibility to call Ensure() at
+ // appropriate intervals to ensure that enough space is available
+ // for the data being added.
+ void Ensure(int N);
+
+ // Returns true if Ensure is allowed to be called on "this"
+ bool ensure_allowed() const { return underlying_buffer_ != NULL; }
+
+ // Return ptr to start of encoded data. This pointer remains valid
+ // until reset or Ensure is called.
+ const char* base() const { return (const char*)orig_; }
+
+ // Advances the write pointer by "N" bytes.
+ void skip(int N) { buf_ += N; }
+
+ // REQUIRES: length() >= N
+ // Removes the last N bytes out of the encoded buffer
+ void RemoveLast(int N);
+
+ // REQUIRES: length() >= N
+ // Removes the last length()-N bytes to make the encoded buffer have length N
+ void Resize(int N);
+
+ private:
+ void EnsureSlowPath(int N);
+
+ unsigned char* orig_;
+ unsigned char* buf_;
+ unsigned char* limit_;
+
+ // If constructed with the zero-argument constructor, we're allowed
+ // to use Ensure; otherwise we're not. If Ensure is allowed,
+ // underlying_buffer_ is non-NULL; otherwise it is set to NULL.
+ unsigned char* underlying_buffer_;
+
+ static unsigned char kEmptyBuffer;
+
+ DISALLOW_EVIL_CONSTRUCTORS(Encoder);
+};
+
+/* Class for decoding data from a memory buffer */
+class Decoder {
+ public:
+ // Empty constructor to create uninitialized decoder
+ inline Decoder() { }
+
+ // NOTE: for efficiency reasons, this is not virtual. so don't add
+ // any members that really need to be destructed, and be careful about
+ // inheritance.
+ ~Decoder() { }
+
+ // Initialize decoder to decode from "buf"
+ explicit Decoder(const void* buf, int maxn);
+ void reset(const void* buf, int maxn);
+
+ // Decoding routines. Note that these do not check bounds
+ unsigned char get8();
+ uint16 get16();
+ uint32 get32();
+ uint64 get64();
+ uword_t getword();
+ float getfloat();
+ double getdouble();
+ void getn(void* mem, int n);
+ void getcn(void* mem, int c, int n); // get no more than n bytes,
+ // stopping after c is got
+ void gets(void* mem, int n); // get a c-string no more than
+ // n bytes. always appends '\0'
+ void skip(int n);
+ unsigned char const* ptr(); // Return ptr to current position in buffer
+
+ // "get_varint" actually checks bounds
+ bool get_varint32(uint32* v);
+ bool get_varint64(uint64* v);
+
+ // DEPRECATED
+ //
+ // For new code use
+ // get_varint32(&unsigned_temp);
+ // signed_value = ZigZagDecode(unsigned_temp);
+ // ZigZag coding is defined in utils/coding/transforms.h
+ bool get_varsigned32(int32* v);
+
+ // Support for a few special types we don't want to restrict size of
+ DocId get_docid();
+
+ // This is used for transitioning docids from 32bits to 64bits
+ DocId32Bit get_docid_32bit();
+
+ int pos() const;
+ // Return number of bytes decoded so far
+
+ int avail() const;
+ // Return number of available bytes to read
+
+ private:
+ friend class IndexBlockDecoder;
+ const unsigned char* orig_;
+ const unsigned char* buf_;
+ const unsigned char* limit_;
+};
+DECLARE_POD(Decoder); // so then we might as well be a POD
+
+/***** Implementation details. Clients should ignore them. *****/
+
+inline Encoder::Encoder(void* b, int maxn) {
+ orig_ = buf_ = reinterpret_cast<unsigned char*>(b);
+ limit_ = orig_ + maxn;
+ underlying_buffer_ = NULL;
+}
+
+inline void Encoder::reset(void* b, int maxn) {
+ orig_ = buf_ = reinterpret_cast<unsigned char*>(b);
+ limit_ = orig_ + maxn;
+ // Can't use the underlying buffer anymore
+ if (underlying_buffer_ != &kEmptyBuffer) {
+ delete[] underlying_buffer_;
+ }
+ underlying_buffer_ = NULL;
+}
+
+inline void Encoder::clear() {
+ buf_ = orig_;
+}
+
+inline void Encoder::Ensure(int N) {
+ DCHECK(ensure_allowed());
+ if (avail() < N) {
+ EnsureSlowPath(N);
+ }
+}
+
+inline int Encoder::length() const {
+ return (buf_ - orig_);
+}
+
+inline int Encoder::avail() const {
+ return (limit_ - buf_);
+}
+
+inline void Encoder::putn(const void* src, int n) {
+ memcpy(buf_, src, n);
+ buf_ += n;
+}
+
+inline void Encoder::putcn(const void* src, int c, int n) {
+ unsigned char *old = buf_;
+ buf_ = static_cast<unsigned char *>(memccpy(buf_, src, c, n));
+ if (buf_ == NULL)
+ buf_ = old + n;
+}
+
+inline void Encoder::puts(const void* src) {
+ putcn(src, '\0', limit_ - buf_);
+}
+
+inline void Encoder::puts_without_null(const char* mem) {
+ while (*mem != '\0' && buf_ < limit_) {
+ *buf_++ = *mem++;
+ }
+}
+
+inline void Encoder::put_varint32(uint32 v) {
+ buf_ = reinterpret_cast<unsigned char*>
+ (Varint::Encode32(reinterpret_cast<char*>(buf_), v));
+}
+
+inline void Encoder::put_varint64(uint64 v) {
+ buf_ = reinterpret_cast<unsigned char*>
+ (Varint::Encode64(reinterpret_cast<char*>(buf_), v));
+}
+
+// DEPRECATED
+//
+// For new code use put_varint32(ZigZagEncode(signed_value));
+// ZigZag coding is defined in utils/coding/transforms.h
+inline void Encoder::put_varsigned32(int32 n) {
+ // Encode sign in low-bit
+ int sign = (n < 0) ? 1 : 0;
+ uint32 mag = (n < 0) ? -n : n;
+ put_varint32((mag << 1) | sign);
+}
+
+inline Decoder::Decoder(const void* b, int maxn) {
+ orig_ = buf_ = reinterpret_cast<const unsigned char*>(b);
+ limit_ = orig_ + maxn;
+}
+
+inline void Decoder::reset(const void* b, int maxn) {
+ orig_ = buf_ = reinterpret_cast<const unsigned char*>(b);
+ limit_ = orig_ + maxn;
+}
+
+inline int Decoder::pos() const {
+ return (buf_ - orig_);
+}
+
+inline int Decoder::avail() const {
+ return (limit_ - buf_);
+}
+
+inline void Decoder::getn(void* dst, int n) {
+ memcpy(dst, buf_, n);
+ buf_ += n;
+}
+
+inline void Decoder::getcn(void* dst, int c, int n) {
+ void *ptr;
+ ptr = memccpy(dst, buf_, c, n);
+ if (ptr == NULL)
+ buf_ = buf_ + n;
+ else
+ buf_ = buf_ + (reinterpret_cast<unsigned char *>(ptr) -
+ reinterpret_cast<unsigned char *>(dst));
+}
+
+inline void Decoder::gets(void* dst, int n) {
+ int len = min<int>((n - 1), (limit_ - buf_));
+ (reinterpret_cast<char *>(dst))[len] = '\0';
+ getcn(dst, '\0', len);
+}
+
+inline void Decoder::skip(int n) {
+ buf_ += n;
+}
+
+inline unsigned char const* Decoder::ptr() {
+ return buf_;
+}
+
+
+// DEPRECATED
+//
+// For new code use
+// get_varint32(&unsigned_temp);
+// signed_value = ZigZagDecode(unsigned_temp);
+// ZigZag coding is defined in utils/coding/transforms.h
+inline bool Decoder::get_varsigned32(int32* v) {
+ uint32 coding;
+ if (get_varint32(&coding)) {
+ int sign = coding & 1;
+ int32 mag = coding >> 1;
+ if (sign) {
+ // Special handling for encoding of kint32min
+ *v = (mag == 0) ? kint32min : -mag;
+ } else {
+ *v = mag;
+ }
+ return true;
+ } else {
+ return false;
+ }
+}
+
+inline void Encoder::put8(unsigned char v) {
+ DCHECK_GE((size_t)avail(), sizeof(v));
+ *buf_ = v;
+ buf_ += sizeof(v);
+}
+
+inline void Encoder::put16(uint16 v) {
+ DCHECK_GE((size_t)avail(), sizeof(v));
+ LittleEndian::Store16(buf_, v);
+ buf_ += sizeof(v);
+}
+
+inline void Encoder::put32(uint32 v) {
+ DCHECK_GE((size_t)avail(), sizeof(v));
+ LittleEndian::Store32(buf_, v);
+ buf_ += sizeof(v);
+}
+
+inline void Encoder::put64(uint64 v) {
+ DCHECK_GE((size_t)avail(), sizeof(v));
+ LittleEndian::Store64(buf_, v);
+ buf_ += sizeof(v);
+}
+
+inline void Encoder::putword(uword_t v) {
+#ifdef _LP64
+ LittleEndian::Store64(buf_, v);
+#else
+ LittleEndian::Store32(buf_, v);
+#endif /* _LP64 */
+ buf_ += sizeof(v);
+}
+
+inline void Encoder::put_docid(DocId d) {
+ put64(DocIdAsNumber(d));
+}
+
+inline void Encoder::putfloat(float f) {
+ uint32 v;
+ typedef char VerifySizesAreEqual[sizeof(f) == sizeof(v) ? 1 : -1];
+ memcpy(&v, &f, sizeof(f));
+ put32(v);
+}
+
+inline void Encoder::putdouble(double d) {
+ uint64 v;
+ typedef char VerifySizesAreEqual[sizeof(d) == sizeof(v) ? 1 : -1];
+ memcpy(&v, &d, sizeof(d));
+ put64(v);
+}
+
+inline unsigned char Decoder::get8() {
+ const unsigned char v = *buf_;
+ buf_ += sizeof(v);
+ return v;
+}
+
+inline uint16 Decoder::get16() {
+ const uint16 v = LittleEndian::Load16(buf_);
+ buf_ += sizeof(v);
+ return v;
+}
+
+inline uint32 Decoder::get32() {
+ const uint32 v = LittleEndian::Load32(buf_);
+ buf_ += sizeof(v);
+ return v;
+}
+
+inline uint64 Decoder::get64() {
+ const uint64 v = LittleEndian::Load64(buf_);
+ buf_ += sizeof(v);
+ return v;
+}
+
+inline uword_t Decoder::getword() {
+#ifdef _LP64
+ const uword_t v = LittleEndian::Load64(buf_);
+#else
+ const uword_t v = LittleEndian::Load32(buf_);
+#endif /* _LP64 */
+ buf_ += sizeof(v);
+ return v;
+}
+
+inline DocId Decoder::get_docid() {
+ return DocId(get64());
+}
+
+inline DocId32Bit Decoder::get_docid_32bit() {
+ return DocId32Bit(get32());
+}
+
+inline float Decoder::getfloat() {
+ uint32 v = get32();
+ float f;
+ typedef char VerifySizesAreEqual[sizeof(f) == sizeof(v) ? 1 : -1];
+ memcpy(&f, &v, sizeof(f));
+ return f;
+}
+
+inline double Decoder::getdouble() {
+ uint64 v = get64();
+ double d;
+ typedef char VerifySizesAreEqual[sizeof(d) == sizeof(v) ? 1 : -1];
+ memcpy(&d, &v, sizeof(d));
+ return d;
+}
+
+#endif // UTIL_CODING_CODER_H__
diff --git a/src/third_party/s2/util/coding/varint.cc b/src/third_party/s2/util/coding/varint.cc
new file mode 100755
index 00000000000..cbd739fbd99
--- /dev/null
+++ b/src/third_party/s2/util/coding/varint.cc
@@ -0,0 +1,264 @@
+// Copyright 2001 and onwards Google Inc.
+
+#include <string>
+using std::string;
+
+#include "util/coding/varint.h"
+
+const int Varint::kMax32 = 5;
+const int Varint::kMax64 = 10;
+
+char* Varint::Encode32(char* sptr, uint32 v) {
+ return Encode32Inline(sptr, v);
+}
+
+char* Varint::Encode64(char* sptr, uint64 v) {
+ if (v < (1u << 28)) {
+ return Varint::Encode32(sptr, v);
+ } else {
+ // Operate on characters as unsigneds
+ unsigned char* ptr = reinterpret_cast<unsigned char*>(sptr);
+ static const int B = 128;
+ uint32 v32 = v;
+ *(ptr++) = v32 | B;
+ *(ptr++) = (v32 >> 7) | B;
+ *(ptr++) = (v32 >> 14) | B;
+ *(ptr++) = (v32 >> 21) | B;
+ if (v < (1ull << 35)) {
+ *(ptr++) = (v >> 28);
+ return reinterpret_cast<char*>(ptr);
+ } else {
+ *(ptr++) = (v >> 28) | B;
+ return Varint::Encode32(reinterpret_cast<char*>(ptr), v >> 35);
+ }
+ }
+}
+
+const char* Varint::Parse32Fallback(const char* ptr, uint32* OUTPUT) {
+ return Parse32FallbackInline(ptr, OUTPUT);
+}
+
+const char* Varint::Parse64Fallback(const char* p, uint64* OUTPUT) {
+ const unsigned char* ptr = reinterpret_cast<const unsigned char*>(p);
+ // Fast path: need to accumulate data in upto three result fragments
+ // res1 bits 0..27
+ // res2 bits 28..55
+ // res3 bits 56..63
+
+ uint32 byte, res1, res2=0, res3=0;
+ byte = *(ptr++); res1 = byte & 127;
+ byte = *(ptr++); res1 |= (byte & 127) << 7; if (byte < 128) goto done1;
+ byte = *(ptr++); res1 |= (byte & 127) << 14; if (byte < 128) goto done1;
+ byte = *(ptr++); res1 |= (byte & 127) << 21; if (byte < 128) goto done1;
+
+ byte = *(ptr++); res2 = byte & 127; if (byte < 128) goto done2;
+ byte = *(ptr++); res2 |= (byte & 127) << 7; if (byte < 128) goto done2;
+ byte = *(ptr++); res2 |= (byte & 127) << 14; if (byte < 128) goto done2;
+ byte = *(ptr++); res2 |= (byte & 127) << 21; if (byte < 128) goto done2;
+
+ byte = *(ptr++); res3 = byte & 127; if (byte < 128) goto done3;
+ byte = *(ptr++); res3 |= (byte & 127) << 7; if (byte < 128) goto done3;
+
+ return NULL; // Value is too long to be a varint64
+
+ done1:
+ assert(res2 == 0);
+ assert(res3 == 0);
+ *OUTPUT = res1;
+ return reinterpret_cast<const char*>(ptr);
+
+done2:
+ assert(res3 == 0);
+ *OUTPUT = res1 | (uint64(res2) << 28);
+ return reinterpret_cast<const char*>(ptr);
+
+done3:
+ *OUTPUT = res1 | (uint64(res2) << 28) | (uint64(res3) << 56);
+ return reinterpret_cast<const char*>(ptr);
+}
+
+const char* Varint::Parse32BackwardSlow(const char* ptr, const char* base,
+ uint32* OUTPUT) {
+ // Since this method is rarely called, for simplicity, we just skip backward
+ // and then parse forward.
+ const char* prev = Skip32BackwardSlow(ptr, base);
+ if (prev == NULL)
+ return NULL; // no value before 'ptr'
+
+ Parse32(prev, OUTPUT);
+ return prev;
+}
+
+const char* Varint::Parse64BackwardSlow(const char* ptr, const char* base,
+ uint64* OUTPUT) {
+ // Since this method is rarely called, for simplicity, we just skip backward
+ // and then parse forward.
+ const char* prev = Skip64BackwardSlow(ptr, base);
+ if (prev == NULL)
+ return NULL; // no value before 'ptr'
+
+ Parse64(prev, OUTPUT);
+ return prev;
+}
+
+const char* Varint::Parse64WithLimit(const char* p,
+ const char* l,
+ uint64* OUTPUT) {
+ if (p + kMax64 <= l) {
+ return Parse64(p, OUTPUT);
+ } else {
+ const unsigned char* ptr = reinterpret_cast<const unsigned char*>(p);
+ const unsigned char* limit = reinterpret_cast<const unsigned char*>(l);
+ uint64 b, result;
+ if (ptr >= limit) return NULL;
+ b = *(ptr++); result = b & 127; if (b < 128) goto done;
+ if (ptr >= limit) return NULL;
+ b = *(ptr++); result |= (b & 127) << 7; if (b < 128) goto done;
+ if (ptr >= limit) return NULL;
+ b = *(ptr++); result |= (b & 127) << 14; if (b < 128) goto done;
+ if (ptr >= limit) return NULL;
+ b = *(ptr++); result |= (b & 127) << 21; if (b < 128) goto done;
+ if (ptr >= limit) return NULL;
+ b = *(ptr++); result |= (b & 127) << 28; if (b < 128) goto done;
+ if (ptr >= limit) return NULL;
+ b = *(ptr++); result |= (b & 127) << 35; if (b < 128) goto done;
+ if (ptr >= limit) return NULL;
+ b = *(ptr++); result |= (b & 127) << 42; if (b < 128) goto done;
+ if (ptr >= limit) return NULL;
+ b = *(ptr++); result |= (b & 127) << 49; if (b < 128) goto done;
+ if (ptr >= limit) return NULL;
+ b = *(ptr++); result |= (b & 127) << 56; if (b < 128) goto done;
+ if (ptr >= limit) return NULL;
+ b = *(ptr++); result |= (b & 127) << 63; if (b < 2) goto done;
+ return NULL; // Value is too long to be a varint64
+ done:
+ *OUTPUT = result;
+ return reinterpret_cast<const char*>(ptr);
+ }
+}
+
+const char* Varint::Skip32BackwardSlow(const char* p, const char* b) {
+ const unsigned char* ptr = reinterpret_cast<const unsigned char*>(p);
+ const unsigned char* base = reinterpret_cast<const unsigned char*>(b);
+ assert(ptr >= base);
+
+ // If the initial pointer is at the base or if the previous byte is not
+ // the last byte of a varint, we return NULL since there is nothing to skip.
+ if (ptr == base) return NULL;
+ if (*(--ptr) > 127) return NULL;
+
+ for (int i = 0; i < 5; i++) {
+ if (ptr == base) return reinterpret_cast<const char*>(ptr);
+ if (*(--ptr) < 128) return reinterpret_cast<const char*>(ptr + 1);
+ }
+
+ return NULL; // value is too long to be a varint32
+}
+
+const char* Varint::Skip64BackwardSlow(const char* p, const char* b) {
+ const unsigned char* ptr = reinterpret_cast<const unsigned char*>(p);
+ const unsigned char* base = reinterpret_cast<const unsigned char*>(b);
+ assert(ptr >= base);
+
+ // If the initial pointer is at the base or if the previous byte is not
+ // the last byte of a varint, we return NULL since there is nothing to skip.
+ if (ptr == base) return NULL;
+ if (*(--ptr) > 127) return NULL;
+
+ for (int i = 0; i < 10; i++) {
+ if (ptr == base) return reinterpret_cast<const char*>(ptr);
+ if (*(--ptr) < 128) return reinterpret_cast<const char*>(ptr + 1);
+ }
+
+ return NULL; // value is too long to be a varint64
+}
+
+void Varint::Append32Slow(string* s, uint32 value) {
+ char buf[Varint::kMax32];
+ const char* p = Varint::Encode32(buf, value);
+ s->append(buf, p - buf);
+}
+
+void Varint::Append64Slow(string* s, uint64 value) {
+ char buf[Varint::kMax64];
+ const char* p = Varint::Encode64(buf, value);
+ s->append(buf, p - buf);
+}
+
+void Varint::EncodeTwo32Values(string* s, uint32 a, uint32 b) {
+ uint64 v = 0;
+ int shift = 0;
+ while ((a > 0) || (b > 0)) {
+ uint8 one_byte = (a & 0xf) | ((b & 0xf) << 4);
+ v |= ((static_cast<uint64>(one_byte)) << shift);
+ shift += 8;
+ a >>= 4;
+ b >>= 4;
+ }
+ Append64(s, v);
+}
+
+const char* Varint::DecodeTwo32ValuesSlow(const char* ptr,
+ uint32* a, uint32* b) {
+ uint64 v = 0;
+ const char* result = Varint::Parse64(ptr, &v);
+ *a = 0;
+ *b = 0;
+ int shift = 0;
+ while (v > 0) {
+ *a |= ((v & 0xf) << shift);
+ *b |= (((v >> 4) & 0xf) << shift);
+ v >>= 8;
+ shift += 4;
+ }
+ return result;
+}
+
+inline int FastLength32(uint32 v) {
+ if (v < (1u << 14)) {
+ if (v < (1u << 7)) {
+ return 1;
+ } else {
+ return 2;
+ }
+ } else {
+ if (v < (1u << 28)) {
+ if (v < (1u << 21)) {
+ return 3;
+ } else {
+ return 4;
+ }
+ } else {
+ return 5;
+ }
+ }
+}
+
+const char Varint::length32_bytes_required[33] =
+{
+ 1, // Entry for "-1", which happens when the value is 0
+ 1,1,1,1,1,1,1,
+ 2,2,2,2,2,2,2,
+ 3,3,3,3,3,3,3,
+ 4,4,4,4,4,4,4,
+ 5,5,5,5
+};
+
+int Varint::Length32NonInline(uint32 v) {
+ return FastLength32(v);
+}
+
+int Varint::Length64(uint64 v) {
+ uint32 tmp;
+ int nb; // Number of bytes we've determined from our tests
+ if (v < (1u << 28)) {
+ tmp = v;
+ nb = 0;
+ } else if (v < (1ull << 35)) {
+ return 5;
+ } else {
+ tmp = v >> 35;
+ nb = 5;
+ }
+ return nb + Varint::Length32(tmp);
+}
diff --git a/src/third_party/s2/util/coding/varint.h b/src/third_party/s2/util/coding/varint.h
new file mode 100755
index 00000000000..0890d4711c9
--- /dev/null
+++ b/src/third_party/s2/util/coding/varint.h
@@ -0,0 +1,508 @@
+// Copyright 2001 and onwards Google Inc.
+//
+// Raw support for varint encoding. Higher level interfaces are
+// provided by Encoder/Decoder/IOBuffer. Clients should typically use
+// those interfaces, unless speed is paramount.
+//
+// If decoding speed is very important, consider using PrefixVarint instead.
+// It has the same compression ratio, but generally faster decoding.
+//
+// Provided routines:
+// vi_parse32_unchecked
+// vi_parse64_unchecked
+// vi_encode32_unchecked
+// vi_encode64_unchecked
+
+#ifndef _VARINT_H
+#define _VARINT_H
+
+#include <string>
+using std::string;
+
+#include "base/basictypes.h"
+
+// Just a namespace, not a real class
+class Varint {
+ public:
+ // Maximum lengths of varint encoding of uint32 and uint64
+ static const int kMax32; // = 5;
+ static const int kMax64; // = 10;
+
+ // REQUIRES "ptr" points to a buffer of length at least kMaxXX
+ // EFFECTS Scan next varint from "ptr" and store in OUTPUT.
+ // Returns pointer just past last read byte. Returns
+ // NULL if a valid varint value was not found.
+ static const char* Parse32(const char* ptr, uint32* OUTPUT);
+ static const char* Parse64(const char* ptr, uint64* OUTPUT);
+
+ // A fully inlined version of Parse32: useful in the most time critical
+ // routines, but its code size is large
+ static const char* Parse32Inline(const char* ptr, uint32* OUTPUT);
+
+ // REQUIRES "ptr" points just past the last byte of a varint-encoded value.
+ // REQUIRES A second varint must be encoded just before the one we parse,
+ // OR "base" must point to the first byte of the one we parse.
+ // REQUIRES Bytes [base, ptr-1] are readable
+ //
+ // EFFECTS Scan backwards from "ptr" and store in OUTPUT. Stop at the last
+ // byte of the previous varint, OR at "base", whichever one comes
+ // first. Returns pointer to the first byte of the decoded varint
+ // NULL if a valid varint value was not found.
+ static const char* Parse32Backward(const char* ptr, const char* base,
+ uint32* OUTPUT);
+ static const char* Parse64Backward(const char* ptr, const char* base,
+ uint64* OUTPUT);
+
+ // Attempts to parse a varint32 from a prefix of the bytes in [ptr,limit-1].
+ // Never reads a character at or beyond limit. If a valid/terminated varint32
+ // was found in the range, stores it in *OUTPUT and returns a pointer just
+ // past the last byte of the varint32. Else returns NULL. On success,
+ // "result <= limit".
+ static const char* Parse32WithLimit(const char* ptr, const char* limit,
+ uint32* OUTPUT);
+ static const char* Parse64WithLimit(const char* ptr, const char* limit,
+ uint64* OUTPUT);
+
+ // REQUIRES "ptr" points to the first byte of a varint-encoded value.
+ // EFFECTS Scans until the end of the varint and returns a pointer just
+ // past the last byte. Returns NULL if "ptr" does not point to
+ // a valid varint value.
+ static const char* Skip32(const char* ptr);
+ static const char* Skip64(const char* ptr);
+
+ // REQUIRES "ptr" points just past the last byte of a varint-encoded value.
+ // REQUIRES A second varint must be encoded just before the one we parse,
+ // OR "base" must point to the first byte of the one we parse.
+ // REQUIRES Bytes [base, ptr-1] are readable
+ //
+ // EFFECTS Scan backwards from "ptr" and stop at the last byte of the
+ // previous varint, OR at "base", whichever one comes first.
+ // Returns pointer to the first byte of the skipped varint or
+ // NULL if a valid varint value was not found.
+ static const char* Skip32Backward(const char* ptr, const char* base);
+ static const char* Skip64Backward(const char* ptr, const char* base);
+
+ // REQUIRES "ptr" points to a buffer of length sufficient to hold "v".
+ // EFFECTS Encodes "v" into "ptr" and returns a pointer to the
+ // byte just past the last encoded byte.
+ static char* Encode32(char* ptr, uint32 v);
+ static char* Encode64(char* ptr, uint64 v);
+
+ // A fully inlined version of Encode32: useful in the most time critical
+ // routines, but its code size is large
+ static char* Encode32Inline(char* ptr, uint32 v);
+
+ // EFFECTS Returns the encoding length of the specified value.
+ static int Length32(uint32 v);
+ static int Length64(uint64 v);
+
+ static int Length32NonInline(uint32 v);
+
+ // EFFECTS Appends the varint representation of "value" to "*s".
+ static void Append32(string* s, uint32 value);
+ static void Append64(string* s, uint64 value);
+
+ // EFFECTS Encodes a pair of values to "*s". The encoding
+ // is done by weaving together 4 bit groups of
+ // each number into a single 64 bit value, and then
+ // encoding this value as a Varint64 value. This means
+ // that if both a and b are small, both values can be
+ // encoded in a single byte.
+ static void EncodeTwo32Values(string* s, uint32 a, uint32 b);
+ static const char* DecodeTwo32Values(const char* ptr, uint32* a, uint32* b);
+
+ // Decode and sum up a sequence of deltas until the sum >= goal.
+ // It is significantly faster than calling ParseXXInline in a loop.
+ // NOTE(user): The code does NO error checking, it assumes all the
+ // deltas are valid and the sum of deltas will never exceed kint64max. The
+ // code works for both 32bits and 64bits varint, and on 64 bits machines,
+ // the 64 bits version is almost always faster. Thus we only have a 64 bits
+ // interface here. The interface is slightly different from the other
+ // functions in that it requires *signed* integers.
+ // REQUIRES "ptr" points to the first byte of a varint-encoded delta.
+ // The sum of deltas >= goal (the code does NO boundary check).
+ // goal is positive and fit into a signed int64.
+ // EFFECTS Returns a pointer just past last read byte.
+ // "out" stores the actual sum.
+ static const char* FastDecodeDeltas(const char* ptr, int64 goal, int64* out);
+
+ private:
+ static const char* Parse32FallbackInline(const char* p, uint32* val);
+ static const char* Parse32Fallback(const char* p, uint32* val);
+ static const char* Parse64Fallback(const char* p, uint64* val);
+
+ static char* Encode32Fallback(char* ptr, uint32 v);
+
+ static const char* DecodeTwo32ValuesSlow(const char* p, uint32* a, uint32* b);
+ static const char* Parse32BackwardSlow(const char* ptr, const char* base,
+ uint32* OUTPUT);
+ static const char* Parse64BackwardSlow(const char* ptr, const char* base,
+ uint64* OUTPUT);
+ static const char* Skip32BackwardSlow(const char* ptr, const char* base);
+ static const char* Skip64BackwardSlow(const char* ptr, const char* base);
+
+ static void Append32Slow(string* s, uint32 value);
+ static void Append64Slow(string* s, uint64 value);
+
+ // Mapping from rightmost bit set to the number of bytes required
+ static const char length32_bytes_required[33];
+};
+
+/***** Implementation details; clients should ignore *****/
+
+inline const char* Varint::Parse32FallbackInline(const char* p,
+ uint32* OUTPUT) {
+ // Fast path
+ const unsigned char* ptr = reinterpret_cast<const unsigned char*>(p);
+ uint32 byte, result;
+ byte = *(ptr++); result = byte & 127;
+ assert(byte >= 128); // Already checked in inlined prelude
+ byte = *(ptr++); result |= (byte & 127) << 7; if (byte < 128) goto done;
+ byte = *(ptr++); result |= (byte & 127) << 14; if (byte < 128) goto done;
+ byte = *(ptr++); result |= (byte & 127) << 21; if (byte < 128) goto done;
+ byte = *(ptr++); result |= (byte & 127) << 28; if (byte < 128) goto done;
+ return NULL; // Value is too long to be a varint32
+ done:
+ *OUTPUT = result;
+ return reinterpret_cast<const char*>(ptr);
+}
+
+inline const char* Varint::Parse32(const char* p, uint32* OUTPUT) {
+ // Fast path for inlining
+ const unsigned char* ptr = reinterpret_cast<const unsigned char*>(p);
+ uint32 byte = *ptr;
+ if (byte < 128) {
+ *OUTPUT = byte;
+ return reinterpret_cast<const char*>(ptr) + 1;
+ } else {
+ return Parse32Fallback(p, OUTPUT);
+ }
+}
+
+inline const char* Varint::Parse32Inline(const char* p, uint32* OUTPUT) {
+ // Fast path for inlining
+ const unsigned char* ptr = reinterpret_cast<const unsigned char*>(p);
+ uint32 byte = *ptr;
+ if (byte < 128) {
+ *OUTPUT = byte;
+ return reinterpret_cast<const char*>(ptr) + 1;
+ } else {
+ return Parse32FallbackInline(p, OUTPUT);
+ }
+}
+
+inline const char* Varint::Skip32(const char* p) {
+ const unsigned char* ptr = reinterpret_cast<const unsigned char*>(p);
+ if (*ptr++ < 128) return reinterpret_cast<const char*>(ptr);
+ if (*ptr++ < 128) return reinterpret_cast<const char*>(ptr);
+ if (*ptr++ < 128) return reinterpret_cast<const char*>(ptr);
+ if (*ptr++ < 128) return reinterpret_cast<const char*>(ptr);
+ if (*ptr++ < 128) return reinterpret_cast<const char*>(ptr);
+ return NULL; // value is too long to be a varint32
+}
+
+inline const char* Varint::Parse32Backward(const char* p, const char* base,
+ uint32* OUTPUT) {
+ if (p > base + kMax32) {
+ // Fast path
+ const unsigned char* ptr = reinterpret_cast<const unsigned char*>(p);
+ uint32 byte, result;
+ byte = *(--ptr); if (byte > 127) return NULL;
+ result = byte;
+ byte = *(--ptr); if (byte < 128) goto done;
+ result <<= 7; result |= (byte & 127);
+ byte = *(--ptr); if (byte < 128) goto done;
+ result <<= 7; result |= (byte & 127);
+ byte = *(--ptr); if (byte < 128) goto done;
+ result <<= 7; result |= (byte & 127);
+ byte = *(--ptr); if (byte < 128) goto done;
+ result <<= 7; result |= (byte & 127);
+ byte = *(--ptr); if (byte < 128) goto done;
+ return NULL; // Value is too long to be a varint32
+ done:
+ *OUTPUT = result;
+ return reinterpret_cast<const char*>(ptr+1);
+ } else {
+ return Parse32BackwardSlow(p, base, OUTPUT);
+ }
+}
+
+inline const char* Varint::Skip32Backward(const char* p, const char* base) {
+ if (p > base + kMax32) {
+ const unsigned char* ptr = reinterpret_cast<const unsigned char*>(p);
+ if (*(--ptr) > 127) return NULL;
+ if (*(--ptr) < 128) return reinterpret_cast<const char*>(ptr+1);
+ if (*(--ptr) < 128) return reinterpret_cast<const char*>(ptr+1);
+ if (*(--ptr) < 128) return reinterpret_cast<const char*>(ptr+1);
+ if (*(--ptr) < 128) return reinterpret_cast<const char*>(ptr+1);
+ if (*(--ptr) < 128) return reinterpret_cast<const char*>(ptr+1);
+ return NULL; // value is too long to be a varint32
+ } else {
+ return Skip32BackwardSlow(p, base);
+ }
+}
+
+inline const char* Varint::Parse32WithLimit(const char* p,
+ const char* l,
+ uint32* OUTPUT) {
+ if (p + kMax32 <= l) {
+ return Parse32(p, OUTPUT);
+ } else {
+ // Slow version with bounds checks
+ const unsigned char* ptr = reinterpret_cast<const unsigned char*>(p);
+ const unsigned char* limit = reinterpret_cast<const unsigned char*>(l);
+ uint32 b, result;
+ if (ptr >= limit) return NULL;
+ b = *(ptr++); result = b & 127; if (b < 128) goto done;
+ if (ptr >= limit) return NULL;
+ b = *(ptr++); result |= (b & 127) << 7; if (b < 128) goto done;
+ if (ptr >= limit) return NULL;
+ b = *(ptr++); result |= (b & 127) << 14; if (b < 128) goto done;
+ if (ptr >= limit) return NULL;
+ b = *(ptr++); result |= (b & 127) << 21; if (b < 128) goto done;
+ if (ptr >= limit) return NULL;
+ b = *(ptr++); result |= (b & 127) << 28; if (b < 16) goto done;
+ return NULL; // Value is too long to be a varint32
+ done:
+ *OUTPUT = result;
+ return reinterpret_cast<const char*>(ptr);
+ }
+
+}
+
+inline const char* Varint::Parse64(const char* p, uint64* OUTPUT) {
+ const unsigned char* ptr = reinterpret_cast<const unsigned char*>(p);
+ uint32 byte = *ptr;
+ if (byte < 128) {
+ *OUTPUT = byte;
+ return reinterpret_cast<const char*>(ptr) + 1;
+ } else {
+ return Parse64Fallback(p, OUTPUT);
+ }
+}
+
+inline const char* Varint::Skip64(const char* p) {
+ const unsigned char* ptr = reinterpret_cast<const unsigned char*>(p);
+ if (*ptr++ < 128) return reinterpret_cast<const char*>(ptr);
+ if (*ptr++ < 128) return reinterpret_cast<const char*>(ptr);
+ if (*ptr++ < 128) return reinterpret_cast<const char*>(ptr);
+ if (*ptr++ < 128) return reinterpret_cast<const char*>(ptr);
+ if (*ptr++ < 128) return reinterpret_cast<const char*>(ptr);
+ if (*ptr++ < 128) return reinterpret_cast<const char*>(ptr);
+ if (*ptr++ < 128) return reinterpret_cast<const char*>(ptr);
+ if (*ptr++ < 128) return reinterpret_cast<const char*>(ptr);
+ if (*ptr++ < 128) return reinterpret_cast<const char*>(ptr);
+ if (*ptr++ < 128) return reinterpret_cast<const char*>(ptr);
+ return NULL; // value is too long to be a varint64
+}
+
+inline const char* Varint::Parse64Backward(const char* p, const char* b,
+ uint64* OUTPUT) {
+ if (p > b + kMax64) {
+ // Fast path
+ const unsigned char* ptr = reinterpret_cast<const unsigned char*>(p);
+ uint32 byte;
+ uint64 res;
+
+ byte = *(--ptr); if (byte > 127) return NULL;
+
+ res = byte;
+ byte = *(--ptr); if (byte < 128) goto done;
+ res <<= 7; res |= (byte & 127);
+ byte = *(--ptr); if (byte < 128) goto done;
+ res <<= 7; res |= (byte & 127);
+ byte = *(--ptr); if (byte < 128) goto done;
+ res <<= 7; res |= (byte & 127);
+ byte = *(--ptr); if (byte < 128) goto done;
+ res <<= 7; res |= (byte & 127);
+ byte = *(--ptr); if (byte < 128) goto done;
+ res <<= 7; res |= (byte & 127);
+ byte = *(--ptr); if (byte < 128) goto done;
+ res <<= 7; res |= (byte & 127);
+ byte = *(--ptr); if (byte < 128) goto done;
+ res <<= 7; res |= (byte & 127);
+ byte = *(--ptr); if (byte < 128) goto done;
+ res <<= 7; res |= (byte & 127);
+ byte = *(--ptr); if (byte < 128) goto done;
+ res <<= 7; res |= (byte & 127);
+ byte = *(--ptr); if (byte < 128) goto done;
+
+ return NULL; // Value is too long to be a varint64
+
+ done:
+ *OUTPUT = res;
+ return reinterpret_cast<const char*>(ptr + 1);
+ } else {
+ return Parse64BackwardSlow(p, b, OUTPUT);
+ }
+}
+
+inline const char* Varint::Skip64Backward(const char* p, const char* b) {
+ if (p > b + kMax64) {
+ // Fast path
+ const unsigned char* ptr = reinterpret_cast<const unsigned char*>(p);
+ if (*(--ptr) > 127) return NULL;
+ if (*(--ptr) < 128) return reinterpret_cast<const char*>(ptr+1);
+ if (*(--ptr) < 128) return reinterpret_cast<const char*>(ptr+1);
+ if (*(--ptr) < 128) return reinterpret_cast<const char*>(ptr+1);
+ if (*(--ptr) < 128) return reinterpret_cast<const char*>(ptr+1);
+ if (*(--ptr) < 128) return reinterpret_cast<const char*>(ptr+1);
+ if (*(--ptr) < 128) return reinterpret_cast<const char*>(ptr+1);
+ if (*(--ptr) < 128) return reinterpret_cast<const char*>(ptr+1);
+ if (*(--ptr) < 128) return reinterpret_cast<const char*>(ptr+1);
+ if (*(--ptr) < 128) return reinterpret_cast<const char*>(ptr+1);
+ if (*(--ptr) < 128) return reinterpret_cast<const char*>(ptr+1);
+ return NULL; // value is too long to be a varint64
+ } else {
+ return Skip64BackwardSlow(p, b);
+ }
+}
+
+inline const char* Varint::DecodeTwo32Values(const char* p,
+ uint32* a, uint32* b) {
+ const unsigned char* ptr = reinterpret_cast<const unsigned char*>(p);
+ if (*ptr < 128) {
+ // Special case for small values
+ *a = (*ptr & 0xf);
+ *b = *ptr >> 4;
+ return reinterpret_cast<const char*>(ptr) + 1;
+ } else {
+ return DecodeTwo32ValuesSlow(p, a, b);
+ }
+}
+
+#if (defined __i386__ || defined __x86_64__) && defined __GNUC__
+inline int Varint::Length32(uint32 v) {
+ // Find the rightmost bit set, and index into a small table
+
+ // "ro" for the input spec means the input can come from either a
+ // register ("r") or offsetable memory ("o").
+ //
+ // If "n == 0", the "bsr" instruction sets the "Z" flag, so we
+ // conditionally move "-1" into the result.
+ //
+ // Note: the cmovz was introduced on PIII's, and may not work on
+ // older machines.
+ int bits;
+ const int neg1 = -1;
+ __asm__("bsr %1, %0\n\t"
+ "cmovz %2, %0"
+ : "=&r" (bits) // Output spec, early clobber
+ : "ro" (v), "r" (neg1) // Input spec
+ : "cc" // Clobbers condition-codes
+ );
+ return Varint::length32_bytes_required[bits+1];
+}
+
+#else
+inline int Varint::Length32(uint32 v) {
+ /*
+ The following version is about 1.5X the code size, but is faster than
+ the loop below.
+
+ if (v < (1u << 14)) {
+ if (v < (1u << 7)) {
+ return 1;
+ } else {
+ return 2;
+ }
+ } else {
+ if (v < (1u << 28)) {
+ if (v < (1u << 21)) {
+ return 3;
+ } else {
+ return 4;
+ }
+ } else {
+ return 5;
+ }
+ }
+ */
+
+ // Each byte of output stores 7 bits of "v" until "v" becomes zero
+ int nbytes = 0;
+ do {
+ nbytes++;
+ v >>= 7;
+ } while (v != 0);
+ return nbytes;
+}
+#endif
+
+inline void Varint::Append32(string* s, uint32 value) {
+ // Inline the fast-path for single-character output, but fall back to the .cc
+ // file for the full version. The size<capacity check is so the compiler can
+ // optimize out the string resize code.
+ if (value < 128 && s->size() < s->capacity()) {
+ s->push_back((unsigned char)value);
+ } else {
+ Append32Slow(s, value);
+ }
+}
+
+inline void Varint::Append64(string* s, uint64 value) {
+ // Inline the fast-path for single-character output, but fall back to the .cc
+ // file for the full version. The size<capacity check is so the compiler can
+ // optimize out the string resize code.
+ if (value < 128 && s->size() < s->capacity()) {
+ s->push_back((unsigned char)value);
+ } else {
+ Append64Slow(s, value);
+ }
+}
+
+inline char* Varint::Encode32Inline(char* sptr, uint32 v) {
+ // Operate on characters as unsigneds
+ unsigned char* ptr = reinterpret_cast<unsigned char*>(sptr);
+ static const int B = 128;
+ if (v < (1<<7)) {
+ *(ptr++) = v;
+ } else if (v < (1<<14)) {
+ *(ptr++) = v | B;
+ *(ptr++) = v>>7;
+ } else if (v < (1<<21)) {
+ *(ptr++) = v | B;
+ *(ptr++) = (v>>7) | B;
+ *(ptr++) = v>>14;
+ } else if (v < (1<<28)) {
+ *(ptr++) = v | B;
+ *(ptr++) = (v>>7) | B;
+ *(ptr++) = (v>>14) | B;
+ *(ptr++) = v>>21;
+ } else {
+ *(ptr++) = v | B;
+ *(ptr++) = (v>>7) | B;
+ *(ptr++) = (v>>14) | B;
+ *(ptr++) = (v>>21) | B;
+ *(ptr++) = v>>28;
+ }
+ return reinterpret_cast<char*>(ptr);
+}
+
+#if (-1 >> 1) != -1
+#error FastDecodeDeltas() needs right-shift to sign-extend.
+#endif
+inline const char* Varint::FastDecodeDeltas(const char* ptr,
+ int64 goal,
+ int64* out) {
+ int64 value;
+ int64 sum = - goal;
+ int64 shift = 0;
+ // Make decoding faster by eliminating unpredictable branching.
+ do {
+ value = static_cast<int8>(*ptr++); // sign extend one byte of data
+ sum += (value & 0x7F) << shift;
+ shift += 7;
+ // (value >> 7) is either -1(continuation byte) or 0 (stop byte)
+ shift &= value >> 7;
+ // Loop if we haven't reached goal (sum < 0) or we haven't finished
+ // parsing current delta (value < 0). We write it in the form of
+ // (a | b) < 0 as opposed to (a < 0 || b < 0) as the former one is
+ // usually as fast as a test for (a < 0).
+ } while ((sum | value) < 0);
+
+ *out = goal + sum;
+ return ptr;
+}
+
+#endif /* _VARINT_H */
diff --git a/src/third_party/s2/util/endian/endian.h b/src/third_party/s2/util/endian/endian.h
new file mode 100755
index 00000000000..9def73f365a
--- /dev/null
+++ b/src/third_party/s2/util/endian/endian.h
@@ -0,0 +1,191 @@
+// Copyright 2005 Google, Inc
+//
+// Utility functions that depend on bytesex. We define htonll and ntohll,
+// as well as "Google" versions of all the standards: ghtonl, ghtons, and
+// so on. These functions do exactly the same as their standard variants,
+// but don't require including the dangerous netinet/in.h.
+
+#ifndef UTIL_ENDIAN_ENDIAN_H_
+#define UTIL_ENDIAN_ENDIAN_H_
+
+#include "base/integral_types.h"
+#include "base/logging.h"
+#include "base/port.h"
+#include "base/int128.h"
+
+inline uint64 gbswap_64(uint64 host_int) {
+#if defined(COMPILER_GCC3) && defined(__x86_64__)
+ // Adapted from /usr/include/byteswap.h.
+ if (__builtin_constant_p(host_int)) {
+ return __bswap_constant_64(host_int);
+ } else {
+ register uint64 result;
+ __asm__ ("bswap %0" : "=r" (result) : "0" (host_int));
+ return result;
+ }
+#elif defined(bswap_64)
+ return bswap_64(host_int);
+#else
+ return static_cast<uint64>(bswap_32(static_cast<uint32>(host_int >> 32))) |
+ (static_cast<uint64>(bswap_32(static_cast<uint32>(host_int))) << 32);
+#endif // bswap_64
+}
+
+#ifdef IS_LITTLE_ENDIAN
+
+// Definitions for ntohl etc. that don't require us to include
+// netinet/in.h. We wrap bswap_32 and bswap_16 in functions rather
+// than just #defining them because in debug mode, gcc doesn't
+// correctly handle the (rather involved) definitions of bswap_32.
+// gcc guarantees that inline functions are as fast as macros, so
+// this isn't a performance hit.
+inline uint16 ghtons(uint16 x) { return bswap_16(x); }
+inline uint32 ghtonl(uint32 x) { return bswap_32(x); }
+inline uint64 ghtonll(uint64 x) { return gbswap_64(x); }
+
+#elif defined IS_BIG_ENDIAN
+
+// These definitions are a lot simpler on big-endian machines
+#define ghtons(x) (x)
+#define ghtonl(x) (x)
+#define ghtonll(x) (x)
+
+#else
+#error "Unsupported bytesex: Either IS_BIG_ENDIAN or IS_LITTLE_ENDIAN must be defined"
+#endif // bytesex
+
+// Convert to little-endian storage, opposite of network format.
+// Convert x from host to little endian: x = LittleEndian.FromHost(x);
+// convert x from little endian to host: x = LittleEndian.ToHost(x);
+//
+// Store values into unaligned memory converting to little endian order:
+// LittleEndian.Store16(p, x);
+//
+// Load unaligned values stored in little endian coverting to host order:
+// x = LittleEndian.Load16(p);
+class LittleEndian {
+ public:
+ // Conversion functions.
+#ifdef IS_LITTLE_ENDIAN
+
+ static uint16 FromHost16(uint16 x) { return x; }
+ static uint16 ToHost16(uint16 x) { return x; }
+
+ static uint32 FromHost32(uint32 x) { return x; }
+ static uint32 ToHost32(uint32 x) { return x; }
+
+ static uint64 FromHost64(uint64 x) { return x; }
+ static uint64 ToHost64(uint64 x) { return x; }
+
+ static bool IsLittleEndian() { return true; }
+
+#elif defined IS_BIG_ENDIAN
+
+ static uint16 FromHost16(uint16 x) { return bswap_16(x); }
+ static uint16 ToHost16(uint16 x) { return bswap_16(x); }
+
+ static uint32 FromHost32(uint32 x) { return bswap_32(x); }
+ static uint32 ToHost32(uint32 x) { return bswap_32(x); }
+
+ static uint64 FromHost64(uint64 x) { return gbswap_64(x); }
+ static uint64 ToHost64(uint64 x) { return gbswap_64(x); }
+
+ static bool IsLittleEndian() { return false; }
+
+#endif /* ENDIAN */
+
+ // Functions to do unaligned loads and stores in little-endian order.
+ static uint16 Load16(const void *p) {
+ return ToHost16(UNALIGNED_LOAD16(p));
+ }
+
+ static void Store16(void *p, uint16 v) {
+ UNALIGNED_STORE16(p, FromHost16(v));
+ }
+
+ static uint32 Load32(const void *p) {
+ return ToHost32(UNALIGNED_LOAD32(p));
+ }
+
+ static void Store32(void *p, uint32 v) {
+ UNALIGNED_STORE32(p, FromHost32(v));
+ }
+
+ static uint64 Load64(const void *p) {
+ return ToHost64(UNALIGNED_LOAD64(p));
+ }
+
+ // Build a uint64 from 1-8 bytes.
+ // 8 * len least significant bits are loaded from the memory with
+ // LittleEndian order. The 64 - 8 * len most significant bits are
+ // set all to 0.
+ // In latex-friendly words, this function returns:
+ // $\sum_{i=0}^{len-1} p[i] 256^{i}$, where p[i] is unsigned.
+ //
+ // This function is equivalent with:
+ // uint64 val = 0;
+ // memcpy(&val, p, len);
+ // return ToHost64(val);
+ // TODO(user): write a small benchmark and benchmark the speed
+ // of a memcpy based approach.
+ //
+ // For speed reasons this function does not work for len == 0.
+ // The caller needs to guarantee that 1 <= len <= 8.
+ static uint64 Load64VariableLength(const void * const p, int len) {
+ DCHECK_GE(len, 1);
+ DCHECK_LE(len, 8);
+ const char * const buf = static_cast<const char * const>(p);
+ uint64 val = 0;
+ --len;
+ do {
+ val = (val << 8) | buf[len];
+ // (--len >= 0) is about 10 % faster than (len--) in some benchmarks.
+ } while (--len >= 0);
+ // No ToHost64(...) needed. The bytes are accessed in little-endian manner
+ // on every architecture.
+ return val;
+ }
+
+ static void Store64(void *p, uint64 v) {
+ UNALIGNED_STORE64(p, FromHost64(v));
+ }
+
+ static uint128 Load128(const void *p) {
+ return uint128(
+ ToHost64(UNALIGNED_LOAD64(reinterpret_cast<const uint64 *>(p) + 1)),
+ ToHost64(UNALIGNED_LOAD64(p)));
+ }
+
+ static void Store128(void *p, const uint128 v) {
+ UNALIGNED_STORE64(p, FromHost64(Uint128Low64(v)));
+ UNALIGNED_STORE64(reinterpret_cast<uint64 *>(p) + 1,
+ FromHost64(Uint128High64(v)));
+ }
+
+ // Build a uint128 from 1-16 bytes.
+ // 8 * len least significant bits are loaded from the memory with
+ // LittleEndian order. The 128 - 8 * len most significant bits are
+ // set all to 0.
+ static uint128 Load128VariableLength(const void *p, int len) {
+ if (len <= 8) {
+ return uint128(Load64VariableLength(p, len));
+ } else {
+ return uint128(
+ Load64VariableLength(static_cast<const char *>(p) + 8, len - 8),
+ Load64(p));
+ }
+ }
+};
+
+
+// This one is safe to take as it's an extension
+#define htonll(x) ghtonll(x)
+
+// ntoh* and hton* are the same thing for any size and bytesex,
+// since the function is an involution, i.e., its own inverse.
+#define gntohl(x) ghtonl(x)
+#define gntohs(x) ghtons(x)
+#define gntohll(x) ghtonll(x)
+#define ntohll(x) htonll(x)
+
+#endif // UTIL_ENDIAN_ENDIAN_H_
diff --git a/src/third_party/s2/util/hash/hash_jenkins_lookup2.h b/src/third_party/s2/util/hash/hash_jenkins_lookup2.h
new file mode 100755
index 00000000000..9cf5bce4804
--- /dev/null
+++ b/src/third_party/s2/util/hash/hash_jenkins_lookup2.h
@@ -0,0 +1,153 @@
+// Copyright (C) 1999 and onwards Google, Inc.
+//
+//
+// This file contains the core of Bob Jenkins lookup2 algorithm.
+//
+// This file contains the basic hash "mix" code which is widely referenced.
+//
+// This file also contains routines used to load an unaligned little-endian
+// word from memory. This relatively generic functionality probably
+// shouldn't live in this file.
+
+#ifndef UTIL_HASH_JENKINS_LOOKUP2_H__
+#define UTIL_HASH_JENKINS_LOOKUP2_H__
+
+#include "base/port.h"
+
+// ----------------------------------------------------------------------
+// mix()
+// The hash function I use is due to Bob Jenkins (see
+// http://burtleburtle.net/bob/hash/index.html).
+// Each mix takes 36 instructions, in 18 cycles if you're lucky.
+//
+// On x86 architectures, this requires 45 instructions in 27 cycles,
+// if you're lucky.
+// ----------------------------------------------------------------------
+
+static inline void mix(uint32& a, uint32& b, uint32& c) { // 32bit version
+ a -= b; a -= c; a ^= (c>>13);
+ b -= c; b -= a; b ^= (a<<8);
+ c -= a; c -= b; c ^= (b>>13);
+ a -= b; a -= c; a ^= (c>>12);
+ b -= c; b -= a; b ^= (a<<16);
+ c -= a; c -= b; c ^= (b>>5);
+ a -= b; a -= c; a ^= (c>>3);
+ b -= c; b -= a; b ^= (a<<10);
+ c -= a; c -= b; c ^= (b>>15);
+}
+
+static inline void mix(uint64& a, uint64& b, uint64& c) { // 64bit version
+ a -= b; a -= c; a ^= (c>>43);
+ b -= c; b -= a; b ^= (a<<9);
+ c -= a; c -= b; c ^= (b>>8);
+ a -= b; a -= c; a ^= (c>>38);
+ b -= c; b -= a; b ^= (a<<23);
+ c -= a; c -= b; c ^= (b>>5);
+ a -= b; a -= c; a ^= (c>>35);
+ b -= c; b -= a; b ^= (a<<49);
+ c -= a; c -= b; c ^= (b>>11);
+ a -= b; a -= c; a ^= (c>>12);
+ b -= c; b -= a; b ^= (a<<18);
+ c -= a; c -= b; c ^= (b>>22);
+}
+
+
+// Load an unaligned little endian word from memory.
+//
+// These routines are named Word32At(), Word64At() and Google1At().
+// Long ago, the 32-bit version of this operation was implemented using
+// signed characters. The hash function that used this variant creates
+// persistent hash values. The hash routine needs to remain backwards
+// compatible, so we renamed the word loading function 'Google1At' to
+// make it clear this implements special functionality.
+//
+// If a machine has alignment constraints or is big endian, we must
+// load the word a byte at a time. Otherwise we can load the whole word
+// from memory.
+//
+// [Plausibly, Word32At() and Word64At() should really be called
+// UNALIGNED_LITTLE_ENDIAN_LOAD32() and UNALIGNED_LITTLE_ENDIAN_LOAD64()
+// but that seems overly verbose.]
+
+#if !defined(NEED_ALIGNED_LOADS) && defined(IS_LITTLE_ENDIAN)
+static inline uint64 Word64At(const char *ptr) {
+ return UNALIGNED_LOAD64(ptr);
+}
+
+static inline uint32 Word32At(const char *ptr) {
+ return UNALIGNED_LOAD32(ptr);
+}
+
+// This produces the same results as the byte-by-byte version below.
+// Here, we mask off the sign bits and subtract off two copies. To
+// see why this is the same as adding together the sign extensions,
+// start by considering the low-order byte. If we loaded an unsigned
+// word and wanted to sign extend it, we isolate the sign bit and subtract
+// that from zero which gives us a sequence of bits matching the sign bit
+// at and above the sign bit. If we remove (subtract) the sign bit and
+// add in the low order byte, we now have a sign-extended byte as desired.
+// We can then operate on all four bytes in parallel because addition
+// is associative and commutative.
+//
+// For example, consider sign extending the bytes 0x01 and 0x81. For 0x01,
+// the sign bit is zero, and 0x01 - 0 -0 = 1. For 0x81, the sign bit is 1
+// and we are computing 0x81 - 0x80 + (-0x80) == 0x01 + 0xFFFFFF80.
+//
+// Similarily, if we start with 0x8200 and want to sign extend that,
+// we end up calculating 0x8200 - 0x8000 + (-0x8000) == 0xFFFF8000 + 0x0200
+//
+// Suppose we have two bytes at the same time. Doesn't the adding of all
+// those F's generate something wierd? Ignore the F's and reassociate
+// the addition. For 0x8281, processing the bytes one at a time (like
+// we used to do) calculates
+// [0x8200 - 0x8000 + (-0x8000)] + [0x0081 - 0x80 + (-0x80)]
+// == 0x8281 - 0x8080 - 0x8000 - 0x80
+// == 0x8281 - 0x8080 - 0x8080
+
+static inline uint32 Google1At(const char *ptr) {
+ uint32 t = UNALIGNED_LOAD32(ptr);
+ uint32 masked = t & 0x80808080;
+ return t - masked - masked;
+}
+
+#else
+
+// NOTE: This code is not normally used or tested.
+
+static inline uint64 Word64At(const char *ptr) {
+ return (static_cast<uint64>(ptr[0]) +
+ (static_cast<uint64>(ptr[1]) << 8) +
+ (static_cast<uint64>(ptr[2]) << 16) +
+ (static_cast<uint64>(ptr[3]) << 24) +
+ (static_cast<uint64>(ptr[4]) << 32) +
+ (static_cast<uint64>(ptr[5]) << 40) +
+ (static_cast<uint64>(ptr[6]) << 48) +
+ (static_cast<uint64>(ptr[7]) << 56));
+}
+
+static inline uint32 Word32At(const char *ptr) {
+ return (static_cast<uint32>(ptr[0]) +
+ (static_cast<uint32>(ptr[1]) << 8) +
+ (static_cast<uint32>(ptr[2]) << 16) +
+ (static_cast<uint32>(ptr[3]) << 24));
+}
+
+static inline uint32 Google1At(const char *ptr2) {
+ const schar * ptr = reinterpret_cast<const schar *>(ptr2);
+ return (static_cast<schar>(ptr[0]) +
+ (static_cast<uint32>(ptr[1]) << 8) +
+ (static_cast<uint32>(ptr[2]) << 16) +
+ (static_cast<uint32>(ptr[3]) << 24));
+}
+
+#endif /* !NEED_ALIGNED_LOADS && IS_LITTLE_ENDIAN */
+
+// Historically, WORD_HASH has always been defined as we always run on
+// machines that don't NEED_ALIGNED_LOADS and which IS_LITTLE_ENDIAN.
+//
+// TODO(user): find occurences of WORD_HASH and adjust the code to
+// use more meaningful concepts.
+# define WORD_HASH
+
+#endif // UTIL_HASH_JENKINS_LOOKUP2_H__
+
diff --git a/src/third_party/s2/util/math/SConscript b/src/third_party/s2/util/math/SConscript
new file mode 100755
index 00000000000..8ad3ee125f1
--- /dev/null
+++ b/src/third_party/s2/util/math/SConscript
@@ -0,0 +1,13 @@
+# -*- mode: python -*-
+
+Import("env windows linux darwin solaris")
+
+env = env.Clone()
+
+env.Append(CCFLAGS=['-Isrc/third_party/s2'])
+env.Append(CCFLAGS=['-Isrc/third_party/gflags-2.0/src'])
+
+env.StaticLibrary("math",
+ [ "mathutil.cc",
+ # "mathlimits.cc",
+ ])
diff --git a/src/third_party/s2/util/math/exactfloat/exactfloat.cc b/src/third_party/s2/util/math/exactfloat/exactfloat.cc
new file mode 100755
index 00000000000..1b30d7e4a9b
--- /dev/null
+++ b/src/third_party/s2/util/math/exactfloat/exactfloat.cc
@@ -0,0 +1,749 @@
+// Copyright 2009 Google Inc. All Rights Reserved.
+
+#include "util/math/exactfloat/exactfloat.h"
+#include <cstring>
+
+#include <math.h>
+#include <algorithm>
+using std::min;
+using std::max;
+using std::swap;
+using std::reverse;
+
+#include <limits>
+using std::numeric_limits;
+
+#include "base/integral_types.h"
+#include "base/logging.h"
+#include "openssl/crypto.h"
+
+// Define storage for constants.
+const int ExactFloat::kMinExp;
+const int ExactFloat::kMaxExp;
+const int ExactFloat::kMaxPrec;
+const int32 ExactFloat::kExpNaN;
+const int32 ExactFloat::kExpInfinity;
+const int32 ExactFloat::kExpZero;
+const int ExactFloat::kDoubleMantissaBits;
+
+// To simplify the overflow/underflow logic, we limit the exponent and
+// precision range so that (2 * bn_exp_) does not overflow an "int". We take
+// advantage of this, for example, by only checking for overflow/underflow
+// *after* multiplying two numbers.
+COMPILE_ASSERT(
+ ExactFloat::kMaxExp <= INT_MAX / 2 &&
+ ExactFloat::kMinExp - ExactFloat::kMaxPrec >= INT_MIN / 2,
+ exactfloat_exponent_might_overflow);
+
+// We define a few simple extensions to the BIGNUM interface. In some cases
+// these depend on BIGNUM internal fields, so they might require tweaking if
+// the BIGNUM implementation changes significantly.
+
+// Set a BIGNUM to the given unsigned 64-bit value.
+inline static void BN_ext_set_uint64(BIGNUM* bn, uint64 v) {
+#if BN_BITS2 == 64
+ CHECK(BN_set_word(bn, v));
+#else
+ COMPILE_ASSERT(BN_BITS2 == 32, at_least_32_bit_openssl_build_needed);
+ CHECK(BN_set_word(bn, static_cast<uint32>(v >> 32)));
+ CHECK(BN_lshift(bn, bn, 32));
+ CHECK(BN_add_word(bn, static_cast<uint32>(v)));
+#endif
+}
+
+// Return the absolute value of a BIGNUM as a 64-bit unsigned integer.
+// Requires that BIGNUM fits into 64 bits.
+inline static uint64 BN_ext_get_uint64(const BIGNUM* bn) {
+ DCHECK_LE(BN_num_bytes(bn), sizeof(uint64));
+#if BN_BITS2 == 64
+ return BN_get_word(bn);
+#else
+ COMPILE_ASSERT(BN_BITS2 == 32, at_least_32_bit_openssl_build_needed);
+ if (bn->top == 0) return 0;
+ if (bn->top == 1) return BN_get_word(bn);
+ DCHECK_EQ(bn->top, 2);
+ return (static_cast<uint64>(bn->d[1]) << 32) + bn->d[0];
+#endif
+}
+
+// Count the number of low-order zero bits in the given BIGNUM (ignoring its
+// sign). Returns 0 if the argument is zero.
+static int BN_ext_count_low_zero_bits(const BIGNUM* bn) {
+ int count = 0;
+ for (int i = 0; i < bn->top; ++i) {
+ BN_ULONG w = bn->d[i];
+ if (w == 0) {
+ count += 8 * sizeof(BN_ULONG);
+ } else {
+ for (; (w & 1) == 0; w >>= 1) {
+ ++count;
+ }
+ break;
+ }
+ }
+ return count;
+}
+
+ExactFloat::ExactFloat(double v) {
+ BN_init(&bn_);
+ sign_ = signbit(v) ? -1 : 1;
+ if (isnan(v)) {
+ set_nan();
+ } else if (isinf(v)) {
+ set_inf(sign_);
+ } else {
+ // The following code is much simpler than messing about with bit masks,
+ // has the advantage of handling denormalized numbers and zero correctly,
+ // and is actually quite efficient (at least compared to the rest of this
+ // code). "f" is a fraction in the range [0.5, 1), so if we shift it left
+ // by the number of mantissa bits in a double (53, including the leading
+ // "1") then the result is always an integer.
+ int exp;
+ double f = frexp(fabs(v), &exp);
+ uint64 m = static_cast<uint64>(ldexp(f, kDoubleMantissaBits));
+ BN_ext_set_uint64(&bn_, m);
+ bn_exp_ = exp - kDoubleMantissaBits;
+ Canonicalize();
+ }
+}
+
+ExactFloat::ExactFloat(int v) {
+ BN_init(&bn_);
+ sign_ = (v >= 0) ? 1 : -1;
+ // Note that this works even for INT_MIN because the parameter type for
+ // BN_set_word() is unsigned.
+ CHECK(BN_set_word(&bn_, abs(v)));
+ bn_exp_ = 0;
+ Canonicalize();
+}
+
+ExactFloat::ExactFloat(const ExactFloat& b)
+ : sign_(b.sign_),
+ bn_exp_(b.bn_exp_) {
+ BN_init(&bn_);
+ BN_copy(&bn_, &b.bn_);
+}
+
+ExactFloat ExactFloat::SignedZero(int sign) {
+ ExactFloat r;
+ r.set_zero(sign);
+ return r;
+}
+
+ExactFloat ExactFloat::Infinity(int sign) {
+ ExactFloat r;
+ r.set_inf(sign);
+ return r;
+}
+
+ExactFloat ExactFloat::NaN() {
+ ExactFloat r;
+ r.set_nan();
+ return r;
+}
+
+int ExactFloat::prec() const {
+ return BN_num_bits(&bn_);
+}
+
+int ExactFloat::exp() const {
+ DCHECK(is_normal());
+ return bn_exp_ + BN_num_bits(&bn_);
+}
+
+void ExactFloat::set_zero(int sign) {
+ sign_ = sign;
+ bn_exp_ = kExpZero;
+ if (!BN_is_zero(&bn_)) BN_zero(&bn_);
+}
+
+void ExactFloat::set_inf(int sign) {
+ sign_ = sign;
+ bn_exp_ = kExpInfinity;
+ if (!BN_is_zero(&bn_)) BN_zero(&bn_);
+}
+
+void ExactFloat::set_nan() {
+ sign_ = 1;
+ bn_exp_ = kExpNaN;
+ if (!BN_is_zero(&bn_)) BN_zero(&bn_);
+}
+
+double ExactFloat::ToDouble() const {
+ // If the mantissa has too many bits, we need to round it.
+ if (prec() <= kDoubleMantissaBits) {
+ return ToDoubleHelper();
+ } else {
+ ExactFloat r = RoundToMaxPrec(kDoubleMantissaBits, kRoundTiesToEven);
+ return r.ToDoubleHelper();
+ }
+}
+
+double ExactFloat::ToDoubleHelper() const {
+ DCHECK_LE(BN_num_bits(&bn_), kDoubleMantissaBits);
+ if (!is_normal()) {
+ if (is_zero()) return copysign(0, sign_);
+ if (is_inf()) return copysign(INFINITY, sign_);
+ return copysign(NAN, sign_);
+ }
+ uint64 d_mantissa = BN_ext_get_uint64(&bn_);
+ // We rely on ldexp() to handle overflow and underflow. (It will return a
+ // signed zero or infinity if the result is too small or too large.)
+ return sign_ * ldexp(static_cast<double>(d_mantissa), bn_exp_);
+}
+
+ExactFloat ExactFloat::RoundToMaxPrec(int max_prec, RoundingMode mode) const {
+ // The "kRoundTiesToEven" mode requires at least 2 bits of precision
+ // (otherwise both adjacent representable values may be odd).
+ DCHECK_GE(max_prec, 2);
+ DCHECK_LE(max_prec, kMaxPrec);
+
+ // The following test also catches zero, infinity, and NaN.
+ int shift = prec() - max_prec;
+ if (shift <= 0) return *this;
+
+ // Round by removing the appropriate number of bits from the mantissa. Note
+ // that if the value is rounded up to a power of 2, the high-order bit
+ // position may increase, but in that case Canonicalize() will remove at
+ // least one zero bit and so the output will still have prec() <= max_prec.
+ return RoundToPowerOf2(bn_exp_ + shift, mode);
+}
+
+ExactFloat ExactFloat::RoundToPowerOf2(int bit_exp, RoundingMode mode) const {
+ DCHECK_GE(bit_exp, kMinExp - kMaxPrec);
+ DCHECK_LE(bit_exp, kMaxExp);
+
+ // If the exponent is already large enough, or the value is zero, infinity,
+ // or NaN, then there is nothing to do.
+ int shift = bit_exp - bn_exp_;
+ if (shift <= 0) return *this;
+ DCHECK(is_normal());
+
+ // Convert rounding up/down to toward/away from zero, so that we don't need
+ // to consider the sign of the number from this point onward.
+ if (mode == kRoundTowardPositive) {
+ mode = (sign_ > 0) ? kRoundAwayFromZero : kRoundTowardZero;
+ } else if (mode == kRoundTowardNegative) {
+ mode = (sign_ > 0) ? kRoundTowardZero : kRoundAwayFromZero;
+ }
+
+ // Rounding consists of right-shifting the mantissa by "shift", and then
+ // possibly incrementing the result (depending on the rounding mode, the
+ // bits that were discarded, and sometimes the lowest kept bit). The
+ // following code figures out whether we need to increment.
+ ExactFloat r;
+ bool increment = false;
+ if (mode == kRoundTowardZero) {
+ // Never increment.
+ } else if (mode == kRoundTiesAwayFromZero) {
+ // Increment if the highest discarded bit is 1.
+ if (BN_is_bit_set(&bn_, shift - 1))
+ increment = true;
+ } else if (mode == kRoundAwayFromZero) {
+ // Increment unless all discarded bits are zero.
+ if (BN_ext_count_low_zero_bits(&bn_) < shift)
+ increment = true;
+ } else {
+ DCHECK_EQ(mode, kRoundTiesToEven);
+ // Let "w/xyz" denote a mantissa where "w" is the lowest kept bit and
+ // "xyz" are the discarded bits. Then using regexp notation:
+ // ./0.* -> Don't increment (fraction < 1/2)
+ // 0/10* -> Don't increment (fraction = 1/2, kept part even)
+ // 1/10* -> Increment (fraction = 1/2, kept part odd)
+ // ./1.*1.* -> Increment (fraction > 1/2)
+ if (BN_is_bit_set(&bn_, shift - 1) &&
+ ((BN_is_bit_set(&bn_, shift) ||
+ BN_ext_count_low_zero_bits(&bn_) < shift - 1))) {
+ increment = true;
+ }
+ }
+ r.bn_exp_ = bn_exp_ + shift;
+ CHECK(BN_rshift(&r.bn_, &bn_, shift));
+ if (increment) {
+ CHECK(BN_add_word(&r.bn_, 1));
+ }
+ r.sign_ = sign_;
+ r.Canonicalize();
+ return r;
+}
+
+int ExactFloat::NumSignificantDigitsForPrec(int prec) {
+ // The simplest bound is
+ //
+ // d <= 1 + ceil(prec * log10(2))
+ //
+ // The following bound is tighter by 0.5 digits on average, but requires
+ // the exponent to be known as well:
+ //
+ // d <= ceil(exp * log10(2)) - floor((exp - prec) * log10(2))
+ //
+ // Since either of these bounds can be too large by 0, 1, or 2 digits, we
+ // stick with the simpler first bound.
+ return static_cast<int>(1 + ceil(prec * (M_LN2 / M_LN10)));
+}
+
+// Numbers are always formatted with at least this many significant digits.
+// This prevents small integers from being formatted in exponential notation
+// (e.g. 1024 formatted as 1e+03), and also avoids the confusion of having
+// supposedly "high precision" numbers formatted with just 1 or 2 digits
+// (e.g. 1/512 == 0.001953125 formatted as 0.002).
+static const int kMinSignificantDigits = 10;
+
+string ExactFloat::ToString() const {
+ int max_digits = max(kMinSignificantDigits,
+ NumSignificantDigitsForPrec(prec()));
+ return ToStringWithMaxDigits(max_digits);
+}
+
+string ExactFloat::ToStringWithMaxDigits(int max_digits) const {
+ DCHECK_GT(max_digits, 0);
+ if (!is_normal()) {
+ if (is_nan()) return "nan";
+ if (is_zero()) return (sign_ < 0) ? "-0" : "0";
+ return (sign_ < 0) ? "-inf" : "inf";
+ }
+ string digits;
+ int exp10 = GetDecimalDigits(max_digits, &digits);
+ string str;
+ if (sign_ < 0) str.push_back('-');
+
+ // We use the standard '%g' formatting rules. If the exponent is less than
+ // -4 or greater than or equal to the requested precision (i.e., max_digits)
+ // then we use exponential notation.
+ //
+ // But since "exp10" is the base-10 exponent corresponding to a mantissa in
+ // the range [0.1, 1), whereas the '%g' rules assume a mantissa in the range
+ // [1.0, 10), we need to adjust these parameters by 1.
+ if (exp10 <= -4 || exp10 > max_digits) {
+ // Use exponential format.
+ str.push_back(digits[0]);
+ if (digits.size() > 1) {
+ str.push_back('.');
+ str.append(digits.begin() + 1, digits.end());
+ }
+ char exp_buf[20];
+ sprintf(exp_buf, "e%+02d", exp10 - 1);
+ str += exp_buf;
+ } else {
+ // Use fixed format. We split this into two cases depending on whether
+ // the integer portion is non-zero or not.
+ if (exp10 > 0) {
+ if ((size_t)exp10 >= digits.size()) {
+ str += digits;
+ for (int i = exp10 - digits.size(); i > 0; --i) {
+ str.push_back('0');
+ }
+ } else {
+ str.append(digits.begin(), digits.begin() + exp10);
+ str.push_back('.');
+ str.append(digits.begin() + exp10, digits.end());
+ }
+ } else {
+ str += "0.";
+ for (int i = exp10; i < 0; ++i) {
+ str.push_back('0');
+ }
+ str += digits;
+ }
+ }
+ return str;
+}
+
+// Increment an unsigned integer represented as a string of ASCII digits.
+static void IncrementDecimalDigits(string* digits) {
+ string::iterator pos = digits->end();
+ while (--pos >= digits->begin()) {
+ if (*pos < '9') { ++*pos; return; }
+ *pos = '0';
+ }
+ digits->insert(0, "1");
+}
+
+int ExactFloat::GetDecimalDigits(int max_digits, string* digits) const {
+ DCHECK(is_normal());
+ // Convert the value to the form (bn * (10 ** bn_exp10)) where "bn" is a
+ // positive integer (BIGNUM).
+ BIGNUM* bn = BN_new();
+ int bn_exp10;
+ if (bn_exp_ >= 0) {
+ // The easy case: bn = bn_ * (2 ** bn_exp_)), bn_exp10 = 0.
+ CHECK(BN_lshift(bn, &bn_, bn_exp_));
+ bn_exp10 = 0;
+ } else {
+ // Set bn = bn_ * (5 ** -bn_exp_) and bn_exp10 = bn_exp_. This is
+ // equivalent to the original value of (bn_ * (2 ** bn_exp_)).
+ BIGNUM* power = BN_new();
+ CHECK(BN_set_word(power, -bn_exp_));
+ CHECK(BN_set_word(bn, 5));
+ BN_CTX* ctx = BN_CTX_new();
+ CHECK(BN_exp(bn, bn, power, ctx));
+ CHECK(BN_mul(bn, bn, &bn_, ctx));
+ BN_CTX_free(ctx);
+ BN_free(power);
+ bn_exp10 = bn_exp_;
+ }
+ // Now convert "bn" to a decimal string.
+ char* all_digits = BN_bn2dec(bn);
+ DCHECK(all_digits != NULL);
+ BN_free(bn);
+ // Check whether we have too many digits and round if necessary.
+ int num_digits = strlen(all_digits);
+ if (num_digits <= max_digits) {
+ *digits = all_digits;
+ } else {
+ digits->assign(all_digits, max_digits);
+ // Standard "printf" formatting rounds ties to an even number. This means
+ // that we round up (away from zero) if highest discarded digit is '5' or
+ // more, unless all other discarded digits are zero in which case we round
+ // up only if the lowest kept digit is odd.
+ if (all_digits[max_digits] >= '5' &&
+ ((all_digits[max_digits-1] & 1) == 1 ||
+ strpbrk(all_digits + max_digits + 1, "123456789") != NULL)) {
+ // This can increase the number of digits by 1, but in that case at
+ // least one trailing zero will be stripped off below.
+ IncrementDecimalDigits(digits);
+ }
+ // Adjust the base-10 exponent to reflect the digits we have removed.
+ bn_exp10 += num_digits - max_digits;
+ }
+ OPENSSL_free(all_digits);
+
+ // Now strip any trailing zeros.
+ DCHECK_NE((*digits)[0], '0');
+ string::iterator pos = digits->end();
+ while (pos[-1] == '0') --pos;
+ if (pos < digits->end()) {
+ bn_exp10 += digits->end() - pos;
+ digits->erase(pos, digits->end());
+ }
+ DCHECK_LE(digits->size(), max_digits);
+
+ // Finally, we adjust the base-10 exponent so that the mantissa is a
+ // fraction in the range [0.1, 1) rather than an integer.
+ return bn_exp10 + digits->size();
+}
+
+string ExactFloat::ToUniqueString() const {
+ char prec_buf[20];
+ sprintf(prec_buf, "<%d>", prec());
+ return ToString() + prec_buf;
+}
+
+ExactFloat& ExactFloat::operator=(const ExactFloat& b) {
+ if (this != &b) {
+ sign_ = b.sign_;
+ bn_exp_ = b.bn_exp_;
+ BN_copy(&bn_, &b.bn_);
+ }
+ return *this;
+}
+
+ExactFloat ExactFloat::operator-() const {
+ return CopyWithSign(-sign_);
+}
+
+ExactFloat operator+(const ExactFloat& a, const ExactFloat& b) {
+ return ExactFloat::SignedSum(a.sign_, &a, b.sign_, &b);
+}
+
+ExactFloat operator-(const ExactFloat& a, const ExactFloat& b) {
+ return ExactFloat::SignedSum(a.sign_, &a, -b.sign_, &b);
+}
+
+ExactFloat ExactFloat::SignedSum(int a_sign, const ExactFloat* a,
+ int b_sign, const ExactFloat* b) {
+ if (!a->is_normal() || !b->is_normal()) {
+ // Handle zero, infinity, and NaN according to IEEE 754-2008.
+ if (a->is_nan()) return *a;
+ if (b->is_nan()) return *b;
+ if (a->is_inf()) {
+ // Adding two infinities with opposite sign yields NaN.
+ if (b->is_inf() && a_sign != b_sign) return NaN();
+ return Infinity(a_sign);
+ }
+ if (b->is_inf()) return Infinity(b_sign);
+ if (a->is_zero()) {
+ if (!b->is_zero()) return b->CopyWithSign(b_sign);
+ // Adding two zeros with the same sign preserves the sign.
+ if (a_sign == b_sign) return SignedZero(a_sign);
+ // Adding two zeros of opposite sign produces +0.
+ return SignedZero(+1);
+ }
+ DCHECK(b->is_zero());
+ return a->CopyWithSign(a_sign);
+ }
+ // Swap the numbers if necessary so that "a" has the larger bn_exp_.
+ if (a->bn_exp_ < b->bn_exp_) {
+ swap(a_sign, b_sign);
+ swap(a, b);
+ }
+ // Shift "a" if necessary so that both values have the same bn_exp_.
+ ExactFloat r;
+ if (a->bn_exp_ > b->bn_exp_) {
+ CHECK(BN_lshift(&r.bn_, &a->bn_, a->bn_exp_ - b->bn_exp_));
+ a = &r; // The only field of "a" used below is bn_.
+ }
+ r.bn_exp_ = b->bn_exp_;
+ if (a_sign == b_sign) {
+ CHECK(BN_add(&r.bn_, &a->bn_, &b->bn_));
+ r.sign_ = a_sign;
+ } else {
+ // Note that the BIGNUM documentation is out of date -- all methods now
+ // allow the result to be the same as any input argument, so it is okay if
+ // (a == &r) due to the shift above.
+ CHECK(BN_sub(&r.bn_, &a->bn_, &b->bn_));
+ if (BN_is_zero(&r.bn_)) {
+ r.sign_ = +1;
+ } else if (BN_is_negative(&r.bn_)) {
+ // The magnitude of "b" was larger.
+ r.sign_ = b_sign;
+ BN_set_negative(&r.bn_, false);
+ } else {
+ // They were equal, or the magnitude of "a" was larger.
+ r.sign_ = a_sign;
+ }
+ }
+ r.Canonicalize();
+ return r;
+}
+
+void ExactFloat::Canonicalize() {
+ if (!is_normal()) return;
+
+ // Underflow/overflow occurs if exp() is not in [kMinExp, kMaxExp].
+ // We also convert a zero mantissa to signed zero.
+ int my_exp = exp();
+ if (my_exp < kMinExp || BN_is_zero(&bn_)) {
+ set_zero(sign_);
+ } else if (my_exp > kMaxExp) {
+ set_inf(sign_);
+ } else if (!BN_is_odd(&bn_)) {
+ // Remove any low-order zero bits from the mantissa.
+ DCHECK(!BN_is_zero(&bn_));
+ int shift = BN_ext_count_low_zero_bits(&bn_);
+ if (shift > 0) {
+ CHECK(BN_rshift(&bn_, &bn_, shift));
+ bn_exp_ += shift;
+ }
+ }
+ // If the mantissa has too many bits, we replace it by NaN to indicate
+ // that an inexact calculation has occurred.
+ if (prec() > kMaxPrec) {
+ set_nan();
+ }
+}
+
+ExactFloat operator*(const ExactFloat& a, const ExactFloat& b) {
+ int result_sign = a.sign_ * b.sign_;
+ if (!a.is_normal() || !b.is_normal()) {
+ // Handle zero, infinity, and NaN according to IEEE 754-2008.
+ if (a.is_nan()) return a;
+ if (b.is_nan()) return b;
+ if (a.is_inf()) {
+ // Infinity times zero yields NaN.
+ if (b.is_zero()) return ExactFloat::NaN();
+ return ExactFloat::Infinity(result_sign);
+ }
+ if (b.is_inf()) {
+ if (a.is_zero()) return ExactFloat::NaN();
+ return ExactFloat::Infinity(result_sign);
+ }
+ DCHECK(a.is_zero() || b.is_zero());
+ return ExactFloat::SignedZero(result_sign);
+ }
+ ExactFloat r;
+ r.sign_ = result_sign;
+ r.bn_exp_ = a.bn_exp_ + b.bn_exp_;
+ BN_CTX* ctx = BN_CTX_new();
+ CHECK(BN_mul(&r.bn_, &a.bn_, &b.bn_, ctx));
+ BN_CTX_free(ctx);
+ r.Canonicalize();
+ return r;
+}
+
+bool operator==(const ExactFloat& a, const ExactFloat& b) {
+ // NaN is not equal to anything, not even itself.
+ if (a.is_nan() || b.is_nan()) return false;
+
+ // Since Canonicalize() strips low-order zero bits, all other cases
+ // (including non-normal values) require bn_exp_ to be equal.
+ if (a.bn_exp_ != b.bn_exp_) return false;
+
+ // Positive and negative zero are equal.
+ if (a.is_zero() && b.is_zero()) return true;
+
+ // Otherwise, the signs and mantissas must match. Note that non-normal
+ // values such as infinity have a mantissa of zero.
+ return a.sign_ == b.sign_ && BN_ucmp(&a.bn_, &b.bn_) == 0;
+}
+
+int ExactFloat::ScaleAndCompare(const ExactFloat& b) const {
+ DCHECK(is_normal() && b.is_normal() && bn_exp_ >= b.bn_exp_);
+ ExactFloat tmp = *this;
+ CHECK(BN_lshift(&tmp.bn_, &tmp.bn_, bn_exp_ - b.bn_exp_));
+ return BN_ucmp(&tmp.bn_, &b.bn_);
+}
+
+bool ExactFloat::UnsignedLess(const ExactFloat& b) const {
+ // Handle the zero/infinity cases (NaN has already been done).
+ if (is_inf() || b.is_zero()) return false;
+ if (is_zero() || b.is_inf()) return true;
+ // If the high-order bit positions differ, we are done.
+ int cmp = exp() - b.exp();
+ if (cmp != 0) return cmp < 0;
+ // Otherwise shift one of the two values so that they both have the same
+ // bn_exp_ and then compare the mantissas.
+ return (bn_exp_ >= b.bn_exp_ ?
+ ScaleAndCompare(b) < 0 : b.ScaleAndCompare(*this) > 0);
+}
+
+bool operator<(const ExactFloat& a, const ExactFloat& b) {
+ // NaN is unordered compared to everything, including itself.
+ if (a.is_nan() || b.is_nan()) return false;
+ // Positive and negative zero are equal.
+ if (a.is_zero() && b.is_zero()) return false;
+ // Otherwise, anything negative is less than anything positive.
+ if (a.sign_ != b.sign_) return a.sign_ < b.sign_;
+ // Now we just compare absolute values.
+ return (a.sign_ > 0) ? a.UnsignedLess(b) : b.UnsignedLess(a);
+}
+
+ExactFloat fabs(const ExactFloat& a) {
+ return a.CopyWithSign(+1);
+}
+
+ExactFloat fmax(const ExactFloat& a, const ExactFloat& b) {
+ // If one argument is NaN, return the other argument.
+ if (a.is_nan()) return b;
+ if (b.is_nan()) return a;
+ // Not required by IEEE 754, but we prefer +0 over -0.
+ if (a.sign_ != b.sign_) {
+ return (a.sign_ < b.sign_) ? b : a;
+ }
+ return (a < b) ? b : a;
+}
+
+ExactFloat fmin(const ExactFloat& a, const ExactFloat& b) {
+ // If one argument is NaN, return the other argument.
+ if (a.is_nan()) return b;
+ if (b.is_nan()) return a;
+ // Not required by IEEE 754, but we prefer -0 over +0.
+ if (a.sign_ != b.sign_) {
+ return (a.sign_ < b.sign_) ? a : b;
+ }
+ return (a < b) ? a : b;
+}
+
+ExactFloat fdim(const ExactFloat& a, const ExactFloat& b) {
+ // This formulation has the correct behavior for NaNs.
+ return (a <= b) ? 0 : (a - b);
+}
+
+ExactFloat ceil(const ExactFloat& a) {
+ return a.RoundToPowerOf2(0, ExactFloat::kRoundTowardPositive);
+}
+
+ExactFloat floor(const ExactFloat& a) {
+ return a.RoundToPowerOf2(0, ExactFloat::kRoundTowardNegative);
+}
+
+ExactFloat trunc(const ExactFloat& a) {
+ return a.RoundToPowerOf2(0, ExactFloat::kRoundTowardZero);
+}
+
+ExactFloat round(const ExactFloat& a) {
+ return a.RoundToPowerOf2(0, ExactFloat::kRoundTiesAwayFromZero);
+}
+
+ExactFloat rint(const ExactFloat& a) {
+ return a.RoundToPowerOf2(0, ExactFloat::kRoundTiesToEven);
+}
+
+template <class T>
+T ExactFloat::ToInteger(RoundingMode mode) const {
+ COMPILE_ASSERT(sizeof(T) <= sizeof(uint64), max_64_bits_supported);
+ COMPILE_ASSERT(numeric_limits<T>::is_signed, only_signed_types_supported);
+ const int64 kMinValue = numeric_limits<T>::min();
+ const int64 kMaxValue = numeric_limits<T>::max();
+
+ ExactFloat r = RoundToPowerOf2(0, mode);
+ if (r.is_nan()) return kMaxValue;
+ if (r.is_zero()) return 0;
+ if (!r.is_inf()) {
+ // If the unsigned value has more than 63 bits it is always clamped.
+ if (r.exp() < 64) {
+ int64 value = BN_ext_get_uint64(&r.bn_) << r.bn_exp_;
+ if (r.sign_ < 0) value = -value;
+ return max(kMinValue, min(kMaxValue, value));
+ }
+ }
+ return (r.sign_ < 0) ? kMinValue : kMaxValue;
+}
+
+long lrint(const ExactFloat& a) {
+ return a.ToInteger<long>(ExactFloat::kRoundTiesToEven);
+}
+
+long long llrint(const ExactFloat& a) {
+ return a.ToInteger<long long>(ExactFloat::kRoundTiesToEven);
+}
+
+long lround(const ExactFloat& a) {
+ return a.ToInteger<long>(ExactFloat::kRoundTiesAwayFromZero);
+}
+
+long long llround(const ExactFloat& a) {
+ return a.ToInteger<long long>(ExactFloat::kRoundTiesAwayFromZero);
+}
+
+ExactFloat copysign(const ExactFloat& a, const ExactFloat& b) {
+ return a.CopyWithSign(b.sign_);
+}
+
+ExactFloat frexp(const ExactFloat& a, int* exp) {
+ if (!a.is_normal()) {
+ // If a == 0, exp should be zero. If a.is_inf() or a.is_nan(), exp is not
+ // defined but the glibc implementation returns zero.
+ *exp = 0;
+ return a;
+ }
+ *exp = a.exp();
+ return ldexp(a, -a.exp());
+}
+
+ExactFloat ldexp(const ExactFloat& a, int exp) {
+ if (!a.is_normal()) return a;
+
+ // To prevent integer overflow, we first clamp "exp" so that
+ // (kMinExp - 1) <= (a_exp + exp) <= (kMaxExp + 1).
+ int a_exp = a.exp();
+ exp = min(ExactFloat::kMaxExp + 1 - a_exp,
+ max(ExactFloat::kMinExp - 1 + a_exp, exp));
+
+ // Now modify the exponent and check for overflow/underflow.
+ ExactFloat r = a;
+ r.bn_exp_ += exp;
+ r.Canonicalize();
+ return r;
+}
+
+int ilogb(const ExactFloat& a) {
+ if (a.is_zero()) return FP_ILOGB0;
+ if (a.is_inf()) return INT_MAX;
+ if (a.is_nan()) return FP_ILOGBNAN;
+ // a.exp() assumes the significand is in the range [0.5, 1).
+ return a.exp() - 1;
+}
+
+ExactFloat logb(const ExactFloat& a) {
+ if (a.is_zero()) return ExactFloat::Infinity(-1);
+ if (a.is_inf()) return ExactFloat::Infinity(+1); // Even if a < 0.
+ if (a.is_nan()) return a;
+ // exp() assumes the significand is in the range [0.5,1).
+ return ExactFloat(a.exp() - 1);
+}
+
+ExactFloat ExactFloat::Unimplemented() {
+ LOG(FATAL) << "Unimplemented ExactFloat method called";
+ return NaN();
+}
diff --git a/src/third_party/s2/util/math/exactfloat/exactfloat.h b/src/third_party/s2/util/math/exactfloat/exactfloat.h
new file mode 100755
index 00000000000..b6af9a89489
--- /dev/null
+++ b/src/third_party/s2/util/math/exactfloat/exactfloat.h
@@ -0,0 +1,605 @@
+// Copyright 2009 Google Inc. All Rights Reserved.
+//
+// ExactFloat is a multiple-precision floating point type based on the OpenSSL
+// Bignum library. It has the same interface as the built-in "float" and
+// "double" types, but only supports the subset of operators and intrinsics
+// where it is possible to compute the result exactly. So for example,
+// ExactFloat supports addition and multiplication but not division (since in
+// general, the quotient of two floating-point numbers cannot be represented
+// exactly). Exact arithmetic is useful for geometric algorithms, especially
+// for disambiguating cases where ordinary double-precision arithmetic yields
+// an uncertain result.
+//
+// ExactFloat is a subset of the faster and more capable MPFloat class (which
+// is based on the GNU MPFR library). The main reason to use this class
+// rather than MPFloat is that it is subject to a BSD-style license rather
+// than the much restrictive LGPL license.
+//
+// It has the following features:
+//
+// - ExactFloat uses the same syntax as the built-in "float" and "double"
+// types, for example: x += 4 + fabs(2*y*y - z*z). There are a few
+// differences (see below), but the syntax is compatible enough so that
+// ExactFloat can be used as a template argument to templatized classes
+// such as Vector2, VectorN, Matrix3x3, etc.
+//
+// - Results are not rounded; instead, precision is increased so that the
+// result can be represented exactly. An inexact result is returned only
+// in the case of underflow or overflow (yielding signed zero or infinity
+// respectively), or if the maximum allowed precision is exceeded (yielding
+// NaN). ExactFloat uses IEEE 754-2008 rules for handling infinities, NaN,
+// rounding to integers, etc.
+//
+// - ExactFloat only supports calculations where the result can be
+// represented exactly. Therefore it supports intrinsics such as fabs()
+// but not transcendentals such as sin(), sqrt(), etc.
+//
+// Syntax Compatibility with "float" and "double"
+// ----------------------------------------------
+//
+// ExactFloat supports a subset of the operators and intrinsics for the
+// built-in "double" type. (Thus it supports fabs() but not fabsf(), for
+// example.) The syntax is different only in the following cases:
+//
+// - Casts and implicit conversions to built-in types (including "bool") are
+// not supported. So for example, the following will not compile:
+//
+// ExactFloat x = 7.5;
+// double y = x; // ERROR: use x.ToDouble() instead
+// long z = x; // ERROR: use x.ToDouble() or lround(trunc(x))
+// q = static_cast<int>(x); // ERROR: use x.ToDouble() or lround(trunc(x))
+// if (x) { ... } // ERROR: use (x != 0) instead
+//
+// - The glibc floating-point classification macros (fpclassify, isfinite,
+// isnormal, isnan, isinf) are not supported. Instead there are
+// zero-argument methods:
+//
+// ExactFloat x;
+// if (isnan(x)) { ... } // ERROR: use (x.is_nan()) instead
+// if (isinf(x)) { ... } // ERROR: use (x.is_inf()) instead
+//
+// Using ExactFloat with Vector3, etc.
+// -----------------------------------
+//
+// ExactFloat can be used with templatized classes such as Vector2 and Vector3
+// (see "util/math/vector3-inl.h"), with the following limitations:
+//
+// - Cast() can be used to convert other vector types to an ExactFloat vector
+// type, but not the other way around. This is because there are no
+// implicit conversions from ExactFloat to built-in types. You can work
+// around this by calling an explicit conversion method such as
+// ToDouble(). For example:
+//
+// typedef Vector3<ExactFloat> Vector3_xf;
+// Vector3_xf x;
+// Vector3_d y;
+// x = Vector3_xf::Cast(y); // This works.
+// y = Vector3_d::Cast(x); // This doesn't.
+// y = Vector3_d(x[0].ToDouble(), x[1].ToDouble(), x[2].ToDouble()); // OK
+//
+// - IsNaN() is not supported because it calls isnan(), which is defined as a
+// macro in <math.h> and therefore can't easily be overrided.
+//
+// Precision Semantics
+// -------------------
+//
+// Unlike MPFloat, ExactFloat does not allow a maximum precision to be
+// specified (it is always unbounded). Therefore it does not have any of the
+// corresponding constructors.
+//
+// The current precision of an ExactFloat (i.e., the number of bits in its
+// mantissa) is returned by prec(). The precision is increased as necessary
+// so that the result of every operation can be represented exactly.
+
+#ifndef UTIL_MATH_EXACTFLOAT_EXACTFLOAT_H_
+#define UTIL_MATH_EXACTFLOAT_EXACTFLOAT_H_
+
+#include <math.h>
+#include <limits.h>
+#include <iostream>
+using std::ostream;
+using std::cout;
+using std::endl;
+
+#include <string>
+using std::string;
+
+#include "base/logging.h"
+#include "base/integral_types.h"
+#include "openssl/bn.h"
+
+class ExactFloat {
+ public:
+ // The following limits are imposed by OpenSSL.
+
+ // The maximum exponent supported. If a value has an exponent larger than
+ // this, it is replaced by infinity (with the appropriate sign).
+ static const int kMaxExp = 200*1000*1000; // About 10**(60 million)
+
+ // The minimum exponent supported. If a value has an exponent less than
+ // this, it is replaced by zero (with the appropriate sign).
+ static const int kMinExp = -kMaxExp; // About 10**(-60 million)
+
+ // The maximum number of mantissa bits supported. If a value has more
+ // mantissa bits than this, it is replaced with NaN. (It is expected that
+ // users of this class will never want this much precision.)
+ static const int kMaxPrec = 64 << 20; // About 20 million digits
+
+ // Rounding modes. kRoundTiesToEven and kRoundTiesAwayFromZero both round
+ // to the nearest representable value unless two values are equally close.
+ // In that case kRoundTiesToEven rounds to the nearest even value, while
+ // kRoundTiesAwayFromZero always rounds away from zero.
+ enum RoundingMode {
+ kRoundTiesToEven,
+ kRoundTiesAwayFromZero,
+ kRoundTowardZero,
+ kRoundAwayFromZero,
+ kRoundTowardPositive,
+ kRoundTowardNegative
+ };
+
+ /////////////////////////////////////////////////////////////////////////////
+ // Constructors
+
+ // The default constructor initializes the value to zero. (The initial
+ // value must be zero rather than NaN for compatibility with the built-in
+ // float types.)
+ inline ExactFloat();
+
+ // Construct an ExactFloat from a "double". The constructor is implicit so
+ // that this class can be used as a replacement for "float" or "double" in
+ // templatized libraries. (With an explicit constructor, code such as
+ // "ExactFloat f = 2.5;" would not compile.) All double-precision values are
+ // supported, including denormalized numbers, infinities, and NaNs.
+ ExactFloat(double v);
+
+ // Construct an ExactFloat from an "int". Note that in general, ints are
+ // automatically converted to doubles and so would be handled by the
+ // constructor above. However, the particular argument (0) is ambiguous; the
+ // compiler doesn't know whether to treat it as a "double" or "NULL"
+ // (invoking the const char* constructor below).
+ //
+ // We do not provide constructors for "unsigned", "long", "unsigned long",
+ // "long long", or "unsigned long long", since these types are not typically
+ // used in floating-point calculations and it is safer to require them to be
+ // explicitly cast.
+ ExactFloat(int v);
+
+ // Construct an ExactFloat from a string (such as "1.2e50"). Requires that
+ // the value is exactly representable as a floating-point number (so for
+ // example, "0.125" is allowed but "0.1" is not).
+ explicit ExactFloat(const char* s) { Unimplemented(); }
+
+ // Copy constructor.
+ ExactFloat(const ExactFloat& b);
+
+ // The destructor is not virtual for efficiency reasons. Therefore no
+ // subclass should declare additional fields that require destruction.
+ inline ~ExactFloat();
+
+ /////////////////////////////////////////////////////////////////////
+ // Constants
+ //
+ // As an alternative to the constants below, you can also just use the
+ // constants defined in <math.h>, for example:
+ //
+ // ExactFloat x = NAN, y = -INFINITY;
+
+ // Return an ExactFloat equal to positive zero (if sign >= 0) or
+ // negative zero (if sign < 0).
+ static ExactFloat SignedZero(int sign);
+
+ // Return an ExactFloat equal to positive infinity (if sign >= 0) or
+ // negative infinity (if sign < 0).
+ static ExactFloat Infinity(int sign);
+
+ // Return an ExactFloat that is NaN (Not-a-Number).
+ static ExactFloat NaN();
+
+ /////////////////////////////////////////////////////////////////////////////
+ // Accessor Methods
+
+ // Return the maximum precision of the ExactFloat. This method exists only
+ // for compatibility with MPFloat.
+ int max_prec() const { return kMaxPrec; }
+
+ // Return the actual precision of this ExactFloat (the current number of
+ // bits in its mantissa). Returns 0 for non-normal numbers such as NaN.
+ int prec() const;
+
+ // Return the exponent of this ExactFloat given that the mantissa is in the
+ // range [0.5, 1). It is an error to call this method if the value is zero,
+ // infinity, or NaN.
+ int exp() const;
+
+ // Set the value of the ExactFloat to +0 (if sign >= 0) or -0 (if sign < 0).
+ void set_zero(int sign);
+
+ // Set the value of the ExactFloat to positive infinity (if sign >= 0) or
+ // negative infinity (if sign < 0).
+ void set_inf(int sign);
+
+ // Set the value of the ExactFloat to NaN (Not-a-Number).
+ void set_nan();
+
+ // Unfortunately, isinf(x), isnan(x), isnormal(x), and isfinite(x) are
+ // defined as macros in <math.h>. Therefore we can't easily extend them
+ // here. Instead we provide methods with underscores in their names that do
+ // the same thing: x.is_inf(), etc.
+ //
+ // These macros are not implemented: signbit(x), fpclassify(x).
+
+ // Return true if this value is zero (including negative zero).
+ inline bool is_zero() const;
+
+ // Return true if this value is infinity (positive or negative).
+ inline bool is_inf() const;
+
+ // Return true if this value is NaN (Not-a-Number).
+ inline bool is_nan() const;
+
+ // Return true if this value is a normal floating-point number. Non-normal
+ // values (zero, infinity, and NaN) often need to be handled separately
+ // because they are represented using special exponent values and their
+ // mantissa is not defined.
+ inline bool is_normal() const;
+
+ // Return true if this value is a normal floating-point number or zero,
+ // i.e. it is not infinity or NaN.
+ inline bool is_finite() const;
+
+ // Return true if the sign bit is set (this includes negative zero).
+ inline bool sign_bit() const;
+
+ // Return +1 if this ExactFloat is positive, -1 if it is negative, and 0
+ // if it is zero or NaN. Note that unlike sign_bit(), sgn() returns 0 for
+ // both positive and negative zero.
+ inline int sgn() const;
+
+ /////////////////////////////////////////////////////////////////////////////
+ // Conversion Methods
+ //
+ // Note that some conversions are defined as functions further below,
+ // e.g. to convert to an integer you can use lround(), llrint(), etc.
+
+ // Round to double precision. Note that since doubles have a much smaller
+ // exponent range than ExactFloats, very small values may be rounded to
+ // (positive or negative) zero, and very large values may be rounded to
+ // infinity.
+ //
+ // It is very important to make this a named method rather than an implicit
+ // conversion, because otherwise there would be a silent loss of precision
+ // whenever some desired operator or function happens not to be implemented.
+ // For example, if fabs() were not implemented and "x" and "y" were
+ // ExactFloats, then x = fabs(y) would silently convert "y" to a "double",
+ // take its absolute value, and convert it back to an ExactFloat.
+ double ToDouble() const;
+
+ // Return a human-readable string such that if two values with the same
+ // precision are different, then their string representations are different.
+ // The format is similar to printf("%g"), except that the number of
+ // significant digits depends on the precision (with a minimum of 10).
+ // Trailing zeros are stripped (just like "%g").
+ //
+ // Note that if two values have different precisions, they may have the same
+ // ToString() value even though their values are slightly different. If you
+ // need to distinguish such values, use ToUniqueString() intead.
+ string ToString() const;
+
+ // Return a string formatted according to printf("%Ng") where N is the given
+ // maximum number of significant digits.
+ string ToStringWithMaxDigits(int max_digits) const;
+
+ // Return a human-readable string such that if two ExactFloats have different
+ // values, then their string representations are always different. This
+ // method is useful for debugging. The string has the form "value<prec>",
+ // where "prec" is the actual precision of the ExactFloat (e.g., "0.215<50>").
+ string ToUniqueString() const;
+
+ // Return an upper bound on the number of significant digits required to
+ // distinguish any two floating-point numbers with the given precision when
+ // they are formatted as decimal strings in exponential format.
+ static int NumSignificantDigitsForPrec(int prec);
+
+ // Output the ExactFloat in human-readable format, e.g. for logging.
+ friend ostream& operator<<(ostream& o, ExactFloat const& f) {
+ return o << f.ToString();
+ }
+
+ /////////////////////////////////////////////////////////////////////////////
+ // Other Methods
+
+ // Round the ExactFloat so that its mantissa has at most "max_prec" bits
+ // using the given rounding mode. Requires "max_prec" to be at least 2
+ // (since kRoundTiesToEven doesn't make sense with fewer bits than this).
+ ExactFloat RoundToMaxPrec(int max_prec, RoundingMode mode) const;
+
+ /////////////////////////////////////////////////////////////////////////////
+ // Operators
+
+ // Assignment operator.
+ ExactFloat& operator=(const ExactFloat& b);
+
+ // Unary plus.
+ ExactFloat operator+() const { return *this; }
+
+ // Unary minus.
+ ExactFloat operator-() const;
+
+ // Addition.
+ friend ExactFloat operator+(const ExactFloat& a, const ExactFloat& b);
+
+ // Subtraction.
+ friend ExactFloat operator-(const ExactFloat& a, const ExactFloat& b);
+
+ // Multiplication.
+ friend ExactFloat operator*(const ExactFloat& a, const ExactFloat& b);
+
+ // Division is not implemented because the result cannot be represented
+ // exactly in general. Doing this properly would require extending all the
+ // operations to support rounding to a specified precision.
+
+ // Arithmetic assignment operators (+=, -=, *=).
+ ExactFloat& operator+=(const ExactFloat& b) { return (*this = *this + b); }
+ ExactFloat& operator-=(const ExactFloat& b) { return (*this = *this - b); }
+ ExactFloat& operator*=(const ExactFloat& b) { return (*this = *this * b); }
+
+ // Comparison operators (==, !=, <, <=, >, >=).
+ friend bool operator==(const ExactFloat& a, const ExactFloat& b);
+ friend bool operator<(const ExactFloat& a, const ExactFloat& b);
+ // These don't need to be friends but are declared here for completeness.
+ inline friend bool operator!=(const ExactFloat& a, const ExactFloat& b);
+ inline friend bool operator<=(const ExactFloat& a, const ExactFloat& b);
+ inline friend bool operator>(const ExactFloat& a, const ExactFloat& b);
+ inline friend bool operator>=(const ExactFloat& a, const ExactFloat& b);
+
+ /////////////////////////////////////////////////////////////////////
+ // Math Intrinsics
+ //
+ // The math intrinsics currently supported by ExactFloat are listed below.
+ // Except as noted, they behave identically to the usual glibc intrinsics
+ // except that they have greater precision. See the man pages for more
+ // information.
+
+ //////// Miscellaneous simple arithmetic functions.
+
+ // Absolute value.
+ friend ExactFloat fabs(const ExactFloat& a);
+
+ // Maximum of two values.
+ friend ExactFloat fmax(const ExactFloat& a, const ExactFloat& b);
+
+ // Minimum of two values.
+ friend ExactFloat fmin(const ExactFloat& a, const ExactFloat& b);
+
+ // Positive difference: max(a - b, 0).
+ friend ExactFloat fdim(const ExactFloat& a, const ExactFloat& b);
+
+ //////// Integer rounding functions that return ExactFloat values.
+
+ // Round up to the nearest integer.
+ friend ExactFloat ceil(const ExactFloat& a);
+
+ // Round down to the nearest integer.
+ friend ExactFloat floor(const ExactFloat& a);
+
+ // Round to the nearest integer not larger in absolute value.
+ // For example: f(-1.9) = -1, f(2.9) = 2.
+ friend ExactFloat trunc(const ExactFloat& a);
+
+ // Round to the nearest integer, rounding halfway cases away from zero.
+ // For example: f(-0.5) = -1, f(0.5) = 1, f(1.5) = 2, f(2.5) = 3.
+ friend ExactFloat round(const ExactFloat& a);
+
+ // Round to the nearest integer, rounding halfway cases to an even integer.
+ // For example: f(-0.5) = 0, f(0.5) = 0, f(1.5) = 2, f(2.5) = 2.
+ friend ExactFloat rint(const ExactFloat& a);
+
+ // A synonym for rint().
+ friend ExactFloat nearbyint(const ExactFloat& a) { return rint(a); }
+
+ //////// Integer rounding functions that return C++ integer types.
+
+ // Like rint(), but rounds to the nearest "long" value. Returns the
+ // minimum/maximum possible integer if the value is out of range.
+ friend long lrint(const ExactFloat& a);
+
+ // Like rint(), but rounds to the nearest "long long" value. Returns the
+ // minimum/maximum possible integer if the value is out of range.
+ friend long long llrint(const ExactFloat& a);
+
+ // Like round(), but rounds to the nearest "long" value. Returns the
+ // minimum/maximum possible integer if the value is out of range.
+ friend long lround(const ExactFloat& a);
+
+ // Like round(), but rounds to the nearest "long long" value. Returns the
+ // minimum/maximum possible integer if the value is out of range.
+ friend long long llround(const ExactFloat& a);
+
+ //////// Remainder functions.
+
+ // The remainder of dividing "a" by "b", where the quotient is rounded toward
+ // zero to the nearest integer. Similar to (a - trunc(a / b) * b).
+ friend ExactFloat fmod(const ExactFloat& a, const ExactFloat& b) {
+ // Note that it is possible to implement this operation exactly, it just
+ // hasn't been done.
+ return Unimplemented();
+ }
+
+ // The remainder of dividing "a" by "b", where the quotient is rounded to the
+ // nearest integer, rounding halfway cases to an even integer. Similar to
+ // (a - rint(a / b) * b).
+ friend ExactFloat remainder(const ExactFloat& a, const ExactFloat& b) {
+ // Note that it is possible to implement this operation exactly, it just
+ // hasn't been done.
+ return Unimplemented();
+ }
+
+ // A synonym for remainder().
+ friend ExactFloat drem(const ExactFloat& a, const ExactFloat& b) {
+ return remainder(a, b);
+ }
+
+ // Break the argument "a" into integer and fractional parts, each of which
+ // has the same sign as "a". The fractional part is returned, and the
+ // integer part is stored in the output parameter "i_ptr". Both output
+ // values are set to have the same maximum precision as "a".
+ friend ExactFloat modf(const ExactFloat& a, ExactFloat* i_ptr) {
+ // Note that it is possible to implement this operation exactly, it just
+ // hasn't been done.
+ return Unimplemented();
+ }
+
+ //////// Floating-point manipulation functions.
+
+ // Return an ExactFloat with the magnitude of "a" and the sign bit of "b".
+ // (Note that an IEEE zero can be either positive or negative.)
+ friend ExactFloat copysign(const ExactFloat& a, const ExactFloat& b);
+
+ // Convert "a" to a normalized fraction in the range [0.5, 1) times a power
+ // of two. Return the fraction and set "exp" to the exponent. If "a" is
+ // zero, infinity, or NaN then return "a" and set "exp" to zero.
+ friend ExactFloat frexp(const ExactFloat& a, int* exp);
+
+ // Return "a" multiplied by 2 raised to the power "exp".
+ friend ExactFloat ldexp(const ExactFloat& a, int exp);
+
+ // A synonym for ldexp().
+ friend ExactFloat scalbn(const ExactFloat& a, int exp) {
+ return ldexp(a, exp);
+ }
+
+ // A version of ldexp() where "exp" is a long integer.
+ friend ExactFloat scalbln(const ExactFloat& a, long exp) {
+ return ldexp(a, exp);
+ }
+
+ // Convert "a" to a normalized fraction in the range [1,2) times a power of
+ // two, and return the exponent value as an integer. This is equivalent to
+ // lrint(floor(log2(fabs(a)))) but it is computed more efficiently. Returns
+ // the constants documented in the man page for zero, infinity, or NaN.
+ friend int ilogb(const ExactFloat& a);
+
+ // Convert "a" to a normalized fraction in the range [1,2) times a power of
+ // two, and return the exponent value as an ExactFloat. This is equivalent to
+ // floor(log2(fabs(a))) but it is computed more efficiently.
+ friend ExactFloat logb(const ExactFloat& a);
+
+ protected:
+ // Non-normal numbers are represented using special exponent values and a
+ // mantissa of zero. Do not change these values; methods such as
+ // is_normal() make assumptions about their ordering. Non-normal numbers
+ // can have either a positive or negative sign (including zero and NaN).
+ static const int32 kExpNaN = INT_MAX;
+ static const int32 kExpInfinity = INT_MAX - 1;
+ static const int32 kExpZero = INT_MAX - 2;
+
+ // Normal numbers are represented as (sign_ * bn_ * (2 ** bn_exp_)), where:
+ // - sign_ is either +1 or -1
+ // - bn_ is a BIGNUM with a positive value
+ // - bn_exp_ is the base-2 exponent applied to bn_.
+ int32 sign_;
+ int32 bn_exp_;
+ BIGNUM bn_;
+
+ // A standard IEEE "double" has a 53-bit mantissa consisting of a 52-bit
+ // fraction plus an implicit leading "1" bit.
+ static const int kDoubleMantissaBits = 53;
+
+ // Convert an ExactFloat with no more than 53 bits in its mantissa to a
+ // "double". This method handles non-normal values (NaN, etc).
+ double ToDoubleHelper() const;
+
+ // Round an ExactFloat so that it is a multiple of (2 ** bit_exp), using the
+ // given rounding mode.
+ ExactFloat RoundToPowerOf2(int bit_exp, RoundingMode mode) const;
+
+ // Convert the ExactFloat to a decimal value of the form 0.ddd * (10 ** x),
+ // with at most "max_digits" significant digits (trailing zeros are removed).
+ // Set (*digits) to the ASCII digits and return the decimal exponent "x".
+ int GetDecimalDigits(int max_digits, string* digits) const;
+
+ // Return a_sign * fabs(a) + b_sign * fabs(b). Used to implement addition
+ // and subtraction.
+ static ExactFloat SignedSum(int a_sign, const ExactFloat* a,
+ int b_sign, const ExactFloat* b);
+
+ // Convert an ExactFloat to its canonical form. Underflow results in signed
+ // zero, overflow results in signed infinity, and precision overflow results
+ // in NaN. A zero mantissa is converted to the canonical zero value with
+ // the given sign; otherwise the mantissa is normalized so that its low bit
+ // is 1. Non-normal numbers are left unchanged.
+ void Canonicalize();
+
+ // Scale the mantissa of this ExactFloat so that it has the same bn_exp_ as
+ // "b", then return -1, 0, or 1 according to whether the scaled mantissa is
+ // less, equal, or greater than the mantissa of "b". Requires that both
+ // values are normal.
+ int ScaleAndCompare(const ExactFloat& b) const;
+
+ // Return true if the magnitude of this ExactFloat is less than the
+ // magnitude of "b". Requires that neither value is NaN.
+ bool UnsignedLess(const ExactFloat& b) const;
+
+ // Return an ExactFloat with the magnitude of this ExactFloat and the given
+ // sign. (Similar to copysign, except that the sign is given explicitly
+ // rather than being copied from another ExactFloat.)
+ inline ExactFloat CopyWithSign(int sign) const;
+
+ // Convert an ExactFloat to an integer of type "T" using the given rounding
+ // mode. The type "T" must be signed. Returns the largest possible integer
+ // for NaN, and clamps out of range values to the largest or smallest
+ // possible values.
+ template <class T> T ToInteger(RoundingMode mode) const;
+
+ // Log a fatal error message (used for unimplemented methods).
+ static ExactFloat Unimplemented();
+};
+
+/////////////////////////////////////////////////////////////////////////
+// Implementation details follow:
+
+inline ExactFloat::ExactFloat() : sign_(1), bn_exp_(kExpZero) {
+ BN_init(&bn_);
+}
+
+inline ExactFloat::~ExactFloat() {
+ BN_free(&bn_);
+}
+
+inline bool ExactFloat::is_zero() const { return bn_exp_ == kExpZero; }
+inline bool ExactFloat::is_inf() const { return bn_exp_ == kExpInfinity; }
+inline bool ExactFloat::is_nan() const { return bn_exp_ == kExpNaN; }
+inline bool ExactFloat::is_normal() const { return bn_exp_ < kExpZero; }
+inline bool ExactFloat::is_finite() const { return bn_exp_ <= kExpZero; }
+inline bool ExactFloat::sign_bit() const { return sign_ < 0; }
+
+inline int ExactFloat::sgn() const {
+ return (is_nan() || is_zero()) ? 0 : sign_;
+}
+
+inline bool operator!=(const ExactFloat& a, const ExactFloat& b) {
+ return !(a == b);
+}
+
+inline bool operator<=(const ExactFloat& a, const ExactFloat& b) {
+ // NaN is unordered compared to everything, including itself.
+ if (a.is_nan() || b.is_nan()) return false;
+ return !(b < a);
+}
+
+inline bool operator>(const ExactFloat& a, const ExactFloat& b) {
+ return b < a;
+}
+
+inline bool operator>=(const ExactFloat& a, const ExactFloat& b) {
+ return b <= a;
+}
+
+inline ExactFloat ExactFloat::CopyWithSign(int sign) const {
+ ExactFloat r = *this;
+ r.sign_ = sign;
+ return r;
+}
+
+#endif // UTIL_MATH_EXACTFLOAT_EXACTFLOAT_H_
diff --git a/src/third_party/s2/util/math/mathlimits.cc b/src/third_party/s2/util/math/mathlimits.cc
new file mode 100755
index 00000000000..2d7f0e5151d
--- /dev/null
+++ b/src/third_party/s2/util/math/mathlimits.cc
@@ -0,0 +1,81 @@
+// Copyright 2005 Google Inc.
+// All Rights Reserved.
+//
+//
+
+#include "util/math/mathlimits.h"
+#include "base/integral_types.h"
+
+// MSVC++ 2005 thinks the header declaration was a definition, and
+// erroneously flags these as a duplicate definition.
+#ifdef COMPILER_MSVC
+
+#define DEF_COMMON_LIMITS(Type)
+#define DEF_UNSIGNED_INT_LIMITS(Type)
+#define DEF_SIGNED_INT_LIMITS(Type)
+#define DEF_PRECISION_LIMITS(Type)
+
+#else
+
+#define DEF_COMMON_LIMITS(Type) \
+const bool MathLimits<Type>::kIsSigned; \
+const bool MathLimits<Type>::kIsInteger; \
+const int MathLimits<Type>::kMin10Exp; \
+const int MathLimits<Type>::kMax10Exp;
+
+#define DEF_UNSIGNED_INT_LIMITS(Type) \
+DEF_COMMON_LIMITS(Type) \
+const Type MathLimits<Type>::kPosMin; \
+const Type MathLimits<Type>::kPosMax; \
+const Type MathLimits<Type>::kMin; \
+const Type MathLimits<Type>::kMax; \
+const Type MathLimits<Type>::kEpsilon; \
+const Type MathLimits<Type>::kStdError;
+
+#define DEF_SIGNED_INT_LIMITS(Type) \
+DEF_UNSIGNED_INT_LIMITS(Type) \
+const Type MathLimits<Type>::kNegMin; \
+const Type MathLimits<Type>::kNegMax;
+
+#define DEF_PRECISION_LIMITS(Type) \
+const int MathLimits<Type>::kPrecisionDigits;
+
+#endif // not COMPILER_MSVC
+
+#define DEF_FP_LIMITS(Type, PREFIX) \
+DEF_COMMON_LIMITS(Type) \
+const Type MathLimits<Type>::kPosMin = PREFIX##_MIN; \
+const Type MathLimits<Type>::kPosMax = PREFIX##_MAX; \
+const Type MathLimits<Type>::kMin = -MathLimits<Type>::kPosMax; \
+const Type MathLimits<Type>::kMax = MathLimits<Type>::kPosMax; \
+const Type MathLimits<Type>::kNegMin = -MathLimits<Type>::kPosMin; \
+const Type MathLimits<Type>::kNegMax = -MathLimits<Type>::kPosMax; \
+const Type MathLimits<Type>::kEpsilon = PREFIX##_EPSILON; \
+/* 32 is 5 bits of mantissa error; should be adequate for common errors */ \
+const Type MathLimits<Type>::kStdError = MathLimits<Type>::kEpsilon * 32; \
+DEF_PRECISION_LIMITS(Type) \
+const Type MathLimits<Type>::kNaN = HUGE_VAL - HUGE_VAL; \
+const Type MathLimits<Type>::kPosInf = HUGE_VAL; \
+const Type MathLimits<Type>::kNegInf = -HUGE_VAL;
+
+DEF_SIGNED_INT_LIMITS(int8)
+DEF_SIGNED_INT_LIMITS(int16)
+DEF_SIGNED_INT_LIMITS(int32)
+DEF_SIGNED_INT_LIMITS(int64)
+DEF_UNSIGNED_INT_LIMITS(uint8)
+DEF_UNSIGNED_INT_LIMITS(uint16)
+DEF_UNSIGNED_INT_LIMITS(uint32)
+DEF_UNSIGNED_INT_LIMITS(uint64)
+
+DEF_SIGNED_INT_LIMITS(long int)
+DEF_UNSIGNED_INT_LIMITS(unsigned long int)
+
+DEF_FP_LIMITS(float, FLT)
+DEF_FP_LIMITS(double, DBL)
+DEF_FP_LIMITS(long double, LDBL);
+
+#undef DEF_COMMON_LIMITS
+#undef DEF_SIGNED_INT_LIMITS
+#undef DEF_UNSIGNED_INT_LIMITS
+#undef DEF_FP_LIMITS
+#undef DEF_PRECISION_LIMITS
diff --git a/src/third_party/s2/util/math/mathlimits.h b/src/third_party/s2/util/math/mathlimits.h
new file mode 100755
index 00000000000..634b4531b0d
--- /dev/null
+++ b/src/third_party/s2/util/math/mathlimits.h
@@ -0,0 +1,238 @@
+// Copyright 2005 Google Inc.
+// All Rights Reserved.
+//
+//
+// Useful integer and floating point limits and type traits.
+//
+// This partially replaces/duplictes numeric_limits<> from <limits>.
+// We get a Google-style class that we have a greater control over
+// and thus can add new features to it or fix whatever happens to be broken in
+// numeric_limits for the compilers we use.
+//
+
+#ifndef UTIL_MATH_MATHLIMITS_H__
+#define UTIL_MATH_MATHLIMITS_H__
+
+#include <string.h>
+#include <math.h>
+#include <cfloat>
+#include "base/basictypes.h"
+
+// ========================================================================= //
+
+// Useful integer and floating point limits and type traits.
+// This is just for the documentation;
+// real members are defined in our specializations below.
+template<typename T> struct MathLimits {
+ // Type name.
+ typedef T Type;
+ // Unsigned version of the Type with the same byte size.
+ // Same as Type for floating point and unsigned types.
+ typedef T UnsignedType;
+ // If the type supports negative values.
+ static const bool kIsSigned;
+ // If the type supports only integer values.
+ static const bool kIsInteger;
+ // Magnitude-wise smallest representable positive value.
+ static const Type kPosMin;
+ // Magnitude-wise largest representable positive value.
+ static const Type kPosMax;
+ // Smallest representable value.
+ static const Type kMin;
+ // Largest representable value.
+ static const Type kMax;
+ // Magnitude-wise smallest representable negative value.
+ // Present only if kIsSigned.
+ static const Type kNegMin;
+ // Magnitude-wise largest representable negative value.
+ // Present only if kIsSigned.
+ static const Type kNegMax;
+ // Smallest integer x such that 10^x is representable.
+ static const int kMin10Exp;
+ // Largest integer x such that 10^x is representable.
+ static const int kMax10Exp;
+ // Smallest positive value such that Type(1) + kEpsilon != Type(1)
+ static const Type kEpsilon;
+ // Typical rounding error that is enough to cover
+ // a few simple floating-point operations.
+ // Slightly larger than kEpsilon to account for a few rounding errors.
+ // Is zero if kIsInteger.
+ static const Type kStdError;
+ // Number of decimal digits of mantissa precision.
+ // Present only if !kIsInteger.
+ static const int kPrecisionDigits;
+ // Not a number, i.e. result of 0/0.
+ // Present only if !kIsInteger.
+ static const Type kNaN;
+ // Positive infinity, i.e. result of 1/0.
+ // Present only if !kIsInteger.
+ static const Type kPosInf;
+ // Negative infinity, i.e. result of -1/0.
+ // Present only if !kIsInteger.
+ static const Type kNegInf;
+
+ // NOTE: Special floating point values behave
+ // in a special (but mathematically-logical) way
+ // in terms of (in)equalty comparison and mathematical operations
+ // -- see out unittest for examples.
+
+ // Special floating point value testers.
+ // Present in integer types for convenience.
+ static bool IsFinite(const Type x);
+ static bool IsNaN(const Type x);
+ static bool IsInf(const Type x);
+ static bool IsPosInf(const Type x);
+ static bool IsNegInf(const Type x);
+};
+
+// ========================================================================= //
+
+// All #define-s below are simply to refactor the declarations of
+// MathLimits template specializations.
+// They are all #undef-ined below.
+
+// The hoop-jumping in *_INT_(MAX|MIN) below is so that the compiler does not
+// get an overflow while computing the constants.
+
+#define SIGNED_INT_MAX(Type) \
+ (((Type(1) << (sizeof(Type)*8 - 2)) - 1) + (Type(1) << (sizeof(Type)*8 - 2)))
+
+#define SIGNED_INT_MIN(Type) \
+ (-(Type(1) << (sizeof(Type)*8 - 2)) - (Type(1) << (sizeof(Type)*8 - 2)))
+
+#define UNSIGNED_INT_MAX(Type) \
+ (((Type(1) << (sizeof(Type)*8 - 1)) - 1) + (Type(1) << (sizeof(Type)*8 - 1)))
+
+// Compile-time selected log10-related constants for integer types.
+#define SIGNED_MAX_10_EXP(Type) \
+ (sizeof(Type) == 1 ? 2 : ( \
+ sizeof(Type) == 2 ? 4 : ( \
+ sizeof(Type) == 4 ? 9 : ( \
+ sizeof(Type) == 8 ? 18 : -1))))
+
+#define UNSIGNED_MAX_10_EXP(Type) \
+ (sizeof(Type) == 1 ? 2 : ( \
+ sizeof(Type) == 2 ? 4 : ( \
+ sizeof(Type) == 4 ? 9 : ( \
+ sizeof(Type) == 8 ? 19 : -1))))
+
+#define DECL_INT_LIMIT_FUNCS \
+ static bool IsFinite(const Type x) { return true; } \
+ static bool IsNaN(const Type x) { return false; } \
+ static bool IsInf(const Type x) { return false; } \
+ static bool IsPosInf(const Type x) { return false; } \
+ static bool IsNegInf(const Type x) { return false; }
+
+#define DECL_SIGNED_INT_LIMITS(IntType, UnsignedIntType) \
+template<> \
+struct MathLimits<IntType> { \
+ typedef IntType Type; \
+ typedef UnsignedIntType UnsignedType; \
+ static const bool kIsSigned = true; \
+ static const bool kIsInteger = true; \
+ static const Type kPosMin = 1; \
+ static const Type kPosMax = SIGNED_INT_MAX(Type); \
+ static const Type kMin = SIGNED_INT_MIN(Type); \
+ static const Type kMax = kPosMax; \
+ static const Type kNegMin = -1; \
+ static const Type kNegMax = kMin; \
+ static const int kMin10Exp = 0; \
+ static const int kMax10Exp = SIGNED_MAX_10_EXP(Type); \
+ static const Type kEpsilon = 1; \
+ static const Type kStdError = 0; \
+ DECL_INT_LIMIT_FUNCS \
+};
+
+#define DECL_UNSIGNED_INT_LIMITS(IntType) \
+template<> \
+struct MathLimits<IntType> { \
+ typedef IntType Type; \
+ typedef IntType UnsignedType; \
+ static const bool kIsSigned = false; \
+ static const bool kIsInteger = true; \
+ static const Type kPosMin = 1; \
+ static const Type kPosMax = UNSIGNED_INT_MAX(Type); \
+ static const Type kMin = 0; \
+ static const Type kMax = kPosMax; \
+ static const int kMin10Exp = 0; \
+ static const int kMax10Exp = UNSIGNED_MAX_10_EXP(Type); \
+ static const Type kEpsilon = 1; \
+ static const Type kStdError = 0; \
+ DECL_INT_LIMIT_FUNCS \
+};
+
+DECL_SIGNED_INT_LIMITS(signed char, unsigned char)
+DECL_SIGNED_INT_LIMITS(signed short int, unsigned short int)
+DECL_SIGNED_INT_LIMITS(signed int, unsigned int)
+DECL_SIGNED_INT_LIMITS(signed long int, unsigned long int)
+DECL_SIGNED_INT_LIMITS(signed long long int, unsigned long long int)
+DECL_UNSIGNED_INT_LIMITS(unsigned char)
+DECL_UNSIGNED_INT_LIMITS(unsigned short int)
+DECL_UNSIGNED_INT_LIMITS(unsigned int)
+DECL_UNSIGNED_INT_LIMITS(unsigned long int)
+DECL_UNSIGNED_INT_LIMITS(unsigned long long int)
+
+#undef DECL_SIGNED_INT_LIMITS
+#undef DECL_UNSIGNED_INT_LIMITS
+#undef SIGNED_INT_MAX
+#undef SIGNED_INT_MIN
+#undef UNSIGNED_INT_MAX
+#undef SIGNED_MAX_10_EXP
+#undef UNSIGNED_MAX_10_EXP
+#undef DECL_INT_LIMIT_FUNCS
+
+// ========================================================================= //
+#ifdef WIN32 // Lacks built-in isnan() and isinf()
+#define DECL_FP_LIMIT_FUNCS \
+ static bool IsFinite(const Type x) { return _finite(x); } \
+ static bool IsNaN(const Type x) { return _isnan(x); } \
+ static bool IsInf(const Type x) { return (_fpclass(x) & (_FPCLASS_NINF | _FPCLASS_PINF)) != 0; } \
+ static bool IsPosInf(const Type x) { return _fpclass(x) == _FPCLASS_PINF; } \
+ static bool IsNegInf(const Type x) { return _fpclass(x) == _FPCLASS_NINF; }
+#else
+#define DECL_FP_LIMIT_FUNCS \
+ static bool IsFinite(const Type x) { return !isinf(x) && !isnan(x); } \
+ static bool IsNaN(const Type x) { return isnan(x); } \
+ static bool IsInf(const Type x) { return isinf(x); } \
+ static bool IsPosInf(const Type x) { return isinf(x) && x > 0; } \
+ static bool IsNegInf(const Type x) { return isinf(x) && x < 0; }
+#endif
+
+// We can't put floating-point constant values in the header here because
+// such constants are not considered to be primitive-type constants by gcc.
+// CAVEAT: Hence, they are going to be initialized only during
+// the global objects construction time.
+#define DECL_FP_LIMITS(FP_Type, PREFIX) \
+template<> \
+struct MathLimits<FP_Type> { \
+ typedef FP_Type Type; \
+ typedef FP_Type UnsignedType; \
+ static const bool kIsSigned = true; \
+ static const bool kIsInteger = false; \
+ static const Type kPosMin; \
+ static const Type kPosMax; \
+ static const Type kMin; \
+ static const Type kMax; \
+ static const Type kNegMin; \
+ static const Type kNegMax; \
+ static const int kMin10Exp = PREFIX##_MIN_10_EXP; \
+ static const int kMax10Exp = PREFIX##_MAX_10_EXP; \
+ static const Type kEpsilon; \
+ static const Type kStdError; \
+ static const int kPrecisionDigits = PREFIX##_DIG; \
+ static const Type kNaN; \
+ static const Type kPosInf; \
+ static const Type kNegInf; \
+ DECL_FP_LIMIT_FUNCS \
+};
+
+DECL_FP_LIMITS(float, FLT)
+DECL_FP_LIMITS(double, DBL)
+DECL_FP_LIMITS(long double, LDBL)
+
+#undef DECL_FP_LIMITS
+#undef DECL_FP_LIMIT_FUNCS
+
+// ========================================================================= //
+
+#endif // UTIL_MATH_MATHLIMITS_H__
diff --git a/src/third_party/s2/util/math/mathutil.cc b/src/third_party/s2/util/math/mathutil.cc
new file mode 100755
index 00000000000..3e4f9899c0d
--- /dev/null
+++ b/src/third_party/s2/util/math/mathutil.cc
@@ -0,0 +1,232 @@
+// Copyright 2008 Google Inc. All Rights Reserved.
+
+#include "util/math/mathlimits.h"
+#include "util/math/mathlimits.cc"
+#include "util/math/mathutil.h"
+#include <vector>
+using std::vector;
+
+#include "base/integral_types.h"
+#include "base/logging.h"
+
+ template <class IntOut, class FloatIn>
+ IntOut MathUtil::Round(FloatIn x) {
+ COMPILE_ASSERT(!MathLimits<FloatIn>::kIsInteger, FloatIn_is_integer);
+ COMPILE_ASSERT(MathLimits<IntOut>::kIsInteger, IntOut_is_not_integer);
+
+ // We don't use sgn(x) below because there is no need to distinguish the
+ // (x == 0) case. Also note that there are specialized faster versions
+ // of this function for Intel processors at the bottom of this file.
+ return static_cast<IntOut>(x < 0 ? (x - 0.5) : (x + 0.5));
+ }
+
+template int MathUtil::Round<int,double>(double x);
+
+MathUtil::QuadraticRootType MathUtil::RealRootsForQuadratic(long double a,
+ long double b,
+ long double c,
+ long double *r1,
+ long double *r2) {
+ // Deal with degenerate cases where leading coefficients vanish.
+ if (a == 0.0) {
+ return DegenerateQuadraticRoots(b, c, r1, r2);
+ }
+
+ // General case: the quadratic formula, rearranged for greater numerical
+ // stability.
+
+ // If the discriminant is zero to numerical precision, regardless of
+ // sign, treat it as zero and return kAmbiguous. We use the double
+ // rather than long double value for epsilon because in practice inputs
+ // are generally calculated in double precision.
+ const long double discriminant = QuadraticDiscriminant(a, b, c);
+ if (QuadraticIsAmbiguous(a, b, c, discriminant,
+ MathLimits<double>::kEpsilon)) {
+ *r2 = *r1 = -b / 2 / a; // The quadratic is (2*a*x + b)^2 = 0.
+ return kAmbiguous;
+ }
+
+ if (discriminant < 0) {
+ // The discriminant is definitely negative so there are no real roots.
+ return kNoRealRoots;
+ }
+
+ RealQuadraticRoots(a, b, c, discriminant, r1, r2);
+ return kTwoRealRoots;
+ }
+
+MathUtil::QuadraticRootType MathUtil::DegenerateQuadraticRoots(
+ long double b,
+ long double c,
+ long double *r1,
+ long double *r2) {
+ // This degenerate quadratic is really a linear equation b * x = -c.
+ if (b == 0.0) {
+ // The equation is constant, c == 0.
+ if (c == 0.0) {
+ // Quadratic equation is 0==0; treat as ambiguous, as if a==epsilon.
+ *r1 = *r2 = 0.0;
+ return kAmbiguous;
+ }
+ return kNoRealRoots;
+ }
+ // The linear equation has a single root at x = -c / b, not a double
+ // one. Respond as if a==epsilon: The other root is at "infinity",
+ // which we signal with HUGE_VAL so that the behavior stays consistent
+ // as a->0.
+ *r1 = -c / b;
+ *r2 = HUGE_VAL;
+ return kTwoRealRoots;
+}
+
+bool MathUtil::RealRootsForCubic(long double const a,
+ long double const b,
+ long double const c,
+ long double *const r1,
+ long double *const r2,
+ long double *const r3) {
+ // According to Numerical Recipes (pp. 184-5), what
+ // follows is an arrangement of computations to
+ // compute the roots of a cubic that minimizes
+ // roundoff error (as pointed out by A.J. Glassman).
+
+ long double const a_squared = a*a, a_third = a/3.0, b_tripled = 3.0*b;
+ long double const Q = (a_squared - b_tripled) / 9.0;
+ long double const R = (2.0*a_squared*a - 3.0*a*b_tripled + 27.0*c) / 54.0;
+
+ long double const R_squared = R*R;
+ long double const Q_cubed = Q*Q*Q;
+ long double const root_Q = sqrt(Q);
+
+ if (R_squared < Q_cubed) {
+ long double const two_pi_third = 2.0 * M_PI / 3.0;
+ long double const theta_third = acos(R / sqrt(Q_cubed)) / 3.0;
+ long double const minus_two_root_Q = -2.0 * root_Q;
+
+ *r1 = minus_two_root_Q * cos(theta_third) - a_third;
+ *r2 = minus_two_root_Q * cos(theta_third + two_pi_third) - a_third;
+ *r3 = minus_two_root_Q * cos(theta_third - two_pi_third) - a_third;
+
+ return true;
+ }
+
+ long double const A =
+ -sgn(R) * pow(fabs(R) + sqrt(R_squared - Q_cubed), 1.0/3.0L);
+
+ if (A != 0.0) { // in which case, B from NR is zero
+ *r1 = A + Q / A - a_third;
+ return false;
+ }
+
+ *r1 = *r2 = *r3 = -a_third;
+ return true;
+}
+
+// Returns the greatest common divisor of two unsigned integers x and y,
+// and assigns a, and b such that a*x + b*y = gcd(x, y).
+unsigned int MathUtil::ExtendedGCD(unsigned int x, unsigned int y,
+ int* a, int* b) {
+ *a = 1;
+ *b = 0;
+ int c = 0;
+ int d = 1;
+ // before and after each loop:
+ // current_x == a * original_x + b * original_y
+ // current_y == c * original_x + d * original_y
+ while (y != 0) {
+ // div() takes int parameters; there is no version that takes unsigned int
+ div_t r = div(static_cast<int>(x), static_cast<int>(y));
+ x = y;
+ y = r.rem;
+
+ int tmp = c;
+ c = *a - r.quot * c;
+ *a = tmp;
+
+ tmp = d;
+ d = *b - r.quot * d;
+ *b = tmp;
+ }
+ return x;
+}
+
+
+void MathUtil::ShardsToRead(const vector<bool>& shards_to_write,
+ vector<bool>* shards_to_read) {
+ const int N = shards_to_read->size();
+ const int M = shards_to_write.size();
+ CHECK(N > 0 || M == 0) << ": have shards to write but not to read";
+
+ // Input shard n of N can contribute to output shard m of M if there
+ // exists a record with sharding hash x s.t. n = x % N and m = x % M.
+ // Equivalently, there must exist s and t s.t. x = tN + n = sM + m,
+ // i.e., tN - sM = m - n. Since G = gcd(N, M) evenly divides tN - sM,
+ // G must also evenly divide m - n. Proof in the other direction is
+ // left as an exercise.
+ // Given output shard m, we should, therefore, read input shards n
+ // that satisfy (n - m) = kG, i.e., n = m + kG. Let 0 <= n < N.
+ // Then, 0 <= m + kG < N and, finally, -m / G <= k < (N - m) / G.
+
+ const int G = GCD(N, M);
+ shards_to_read->assign(N, false);
+ for (int m = 0; m < M; m++) {
+ if (!shards_to_write[m]) continue;
+ const int k_min = -m / G;
+ const int k_max = k_min + N / G;
+ for (int k = k_min; k < k_max; k++) {
+ (*shards_to_read)[m + k * G] = true;
+ }
+ }
+}
+
+double MathUtil::Harmonic(int64 const n, double *const e) {
+ CHECK_GT(n, 0);
+
+ // Hn ~ ln(n) + 0.5772156649 +
+ // + 1/(2n) - 1/(12n^2) + 1/(120n^4) - error,
+ // with 0 < error < 1/(256*n^4).
+
+ double const
+ d = static_cast<double>(n),
+ d2 = d * d,
+ d4 = d2 * d2;
+
+ return (log(d) + 0.5772156649) // ln + Gamma constant
+ + 1 / (2 * d) - 1 / (12 * d2) + 1 / (120 * d4)
+ - (*e = 1 / (256 * d4));
+}
+
+// The formula is extracted from the following page
+// http://en.wikipedia.org/w/index.php?title=Stirling%27s_approximation
+double MathUtil::Stirling(double n) {
+ static const double kLog2Pi = log(2 * M_PI);
+ const double logN = log(n);
+ return (n * logN
+ - n
+ + 0.5 * (kLog2Pi + logN) // 0.5 * log(2 * M_PI * n)
+ + 1 / (12 * n)
+ - 1 / (360 * n * n * n));
+}
+
+double MathUtil::LogCombinations(int n, int k) {
+ CHECK_GE(n, k);
+ CHECK_GT(n, 0);
+ CHECK_GE(k, 0);
+
+ // use symmetry to pick the shorter calculation
+ if (k > n / 2) {
+ k = n - k;
+ }
+
+ // If we have more than 30 logarithms to calculate, we'll use
+ // Stirling's approximation for log(n!).
+ if (k > 15) {
+ return Stirling(n) - Stirling(k) - Stirling(n - k);
+ } else {
+ double result = 0;
+ for (int i = 1; i <= k; i++) {
+ result += log(static_cast<double>(n) - k + i) - log(static_cast<double>(i));
+ }
+ return result;
+ }
+}
diff --git a/src/third_party/s2/util/math/mathutil.h b/src/third_party/s2/util/math/mathutil.h
new file mode 100755
index 00000000000..05159121826
--- /dev/null
+++ b/src/third_party/s2/util/math/mathutil.h
@@ -0,0 +1,749 @@
+// Copyright 2001 and onwards Google Inc.
+//
+// This class is intended to contain a collection of useful (static)
+// mathematical functions, properly coded (by consulting numerical
+// recipes or another authoritative source first).
+
+#ifndef UTIL_MATH_MATHUTIL_H__
+#define UTIL_MATH_MATHUTIL_H__
+
+#include <math.h>
+#include <algorithm>
+using std::min;
+using std::max;
+using std::swap;
+using std::reverse;
+
+#include <vector>
+using std::vector;
+
+#include "base/basictypes.h"
+#include "base/logging.h"
+
+// Returns the sign of x:
+// -1 if x < 0,
+// +1 if x > 0,
+// 0 if x = 0.
+// Consider instead using MathUtil::Sign below for readability
+// and floating-point correctness.
+template <class T>
+inline T sgn(const T x) {
+ return (x == 0 ? 0 : (x < 0 ? -1 : 1));
+}
+// HACK ALERT
+// So here's the deal: There's a ton of junk defined in mathlimits.h that should be moved into
+// mathlimits.cc. But the only thing that uses mathlimits.cc/h is this, mathutil.cc/h.
+// So I moved a class definition into this .h file before the stuff that references it and stuck
+// mathutil.cc into mathlimits.cc. Voila!
+#ifndef UTIL_MATH_MATHLIMITS_H__
+#define UTIL_MATH_MATHLIMITS_H__
+// Useful integer and floating point limits and type traits.
+// This is just for the documentation;
+// real members are defined in our specializations below.
+template<typename T> struct MathLimits {
+ // Type name.
+ typedef T Type;
+ // Unsigned version of the Type with the same byte size.
+ // Same as Type for floating point and unsigned types.
+ typedef T UnsignedType;
+ // If the type supports negative values.
+ static const bool kIsSigned;
+ // If the type supports only integer values.
+ static const bool kIsInteger;
+ // Magnitude-wise smallest representable positive value.
+ static const Type kPosMin;
+ // Magnitude-wise largest representable positive value.
+ static const Type kPosMax;
+ // Smallest representable value.
+ static const Type kMin;
+ // Largest representable value.
+ static const Type kMax;
+ // Magnitude-wise smallest representable negative value.
+ // Present only if kIsSigned.
+ static const Type kNegMin;
+ // Magnitude-wise largest representable negative value.
+ // Present only if kIsSigned.
+ static const Type kNegMax;
+ // Smallest integer x such that 10^x is representable.
+ static const int kMin10Exp;
+ // Largest integer x such that 10^x is representable.
+ static const int kMax10Exp;
+ // Smallest positive value such that Type(1) + kEpsilon != Type(1)
+ static const Type kEpsilon;
+ // Typical rounding error that is enough to cover
+ // a few simple floating-point operations.
+ // Slightly larger than kEpsilon to account for a few rounding errors.
+ // Is zero if kIsInteger.
+ static const Type kStdError;
+ // Number of decimal digits of mantissa precision.
+ // Present only if !kIsInteger.
+ static const int kPrecisionDigits;
+ // Not a number, i.e. result of 0/0.
+ // Present only if !kIsInteger.
+ static const Type kNaN;
+ // Positive infinity, i.e. result of 1/0.
+ // Present only if !kIsInteger.
+ static const Type kPosInf;
+ // Negative infinity, i.e. result of -1/0.
+ // Present only if !kIsInteger.
+ static const Type kNegInf;
+
+ // NOTE: Special floating point values behave
+ // in a special (but mathematically-logical) way
+ // in terms of (in)equalty comparison and mathematical operations
+ // -- see out unittest for examples.
+
+ // Special floating point value testers.
+ // Present in integer types for convenience.
+ static bool IsFinite(const Type x);
+ static bool IsNaN(const Type x);
+ static bool IsInf(const Type x);
+ static bool IsPosInf(const Type x);
+ static bool IsNegInf(const Type x);
+};
+// END HACK ALERT
+#endif //UTIL_MATH_MATHLIMITS_H
+// ========================================================================= //
+
+class MathUtil {
+ public:
+
+ // Return type of RealRootsForQuadratic (below). The enum values are
+ // chosen to be sensible if converted to bool or int, and should not be
+ // changed lightly.
+ enum QuadraticRootType {kNoRealRoots = 0, kAmbiguous = 1, kTwoRealRoots = 2};
+
+ // Returns the QuadraticRootType of the equation a * x^2 + b * x + c = 0.
+ // Normal cases are kNoRealRoots, in which case *r1 and *r2 are not
+ // changed; and kTwoRealRoots, in which case the root(s) are placed in
+ // *r1 and *r2, order not specified. The kAmbiguous return value
+ // indicates that the disciminant is zero, within floating-point error
+ // (i.e. that changing an input by epsilon<double> would change the sign
+ // of the discriminant). The resulting roots are equal, as if the
+ // discriminant were exactly zero.
+ //
+ // A special case occurs when a==0; see DegenerateQuadraticRoots().
+ // See also QuadraticIsAmbiguous() and RealQuadraticRoots().
+ static QuadraticRootType RealRootsForQuadratic(long double a,
+ long double b,
+ long double c,
+ long double *r1,
+ long double *r2);
+
+ // Returns the discriminant of the quadratic equation a * x^2 + b * x + c = 0.
+ static inline long double QuadraticDiscriminant(long double a,
+ long double b,
+ long double c) {
+ return b * b - 4 * a * c;
+ }
+
+ // Returns true if the discriminant is zero within floating-point error,
+ // in the sense that changing one of the coefficients by epsilon (e.g. a
+ // -> a + a*epsilon) could change the sign of the discriminant. [When the
+ // discriminant is exactly 0 the quadratic is (2*a*x + b)^2 = 0 and the
+ // root is - b / (2*a).]
+ static inline bool QuadraticIsAmbiguous(long double a,
+ long double b,
+ long double c,
+ long double discriminant,
+ long double epsilon) {
+ // Discriminants below kTolerance in absolute value are considered zero
+ // because changing the final bit of one of the inputs can change the
+ // sign of the discriminant.
+ const double kTolerance = epsilon * max(fabs(2 * b * b), fabs(4 * a * c));
+ return (fabs(discriminant) <= kTolerance);
+ }
+
+ // Returns in *r1 and *r2 the roots of a "normal" quadratic equation
+ // whose discriminant (b*b - 4*a*c) is known and positive. Preconditions
+ // (will DCHECK and return false if not satisfied): a != 0, discriminant > 0.
+ static inline bool RealQuadraticRoots(long double a,
+ long double b,
+ long double c,
+ long double discriminant,
+ long double *r1,
+ long double *r2) {
+ if (discriminant <= 0 || a == 0) {
+ // A case that should have been excluded by the caller.
+ DCHECK(false);
+ return false;
+ }
+
+ // The discriminant is positive so there are two distinct roots.
+ // According to Numerical Recipes (p. 184), it would be a mistake to
+ // solve for the roots using
+ //
+ // r1 = 2c / (-b + sqrt(b^2 - 4ac)),
+ // r2 = 2c / (-b - sqrt(b^2 - 4ac)).
+ //
+ // If a*c is small, then one of the roots above will involve the
+ // subtraction of b from a very nearly equal quantity (the discriminant),
+ // producing a very inaccurate root. Avoid the risk of cancellation with
+ // the following rearrangement. (Note we don't use sgn(b) because we
+ // need sgn(0) = +1 or -1.)
+ long double const q = -0.5 *
+ (b + ((b >= 0) ? sqrt(discriminant) : -sqrt(discriminant)));
+ *r1 = q / a; // If a is very small this produces +/- HUGE_VAL.
+ *r2 = c / q; // q cannot be too small.
+ return true;
+ }
+
+ // Returns the root of the degenerate quadratic equation b * x + c = 0,
+ // following the interface of RealRootsForQuadratic. To be consistent
+ // with that function as a->0, the degenerate quadratic is considered to
+ // have two real roots, one of which is +/- HUGE_VAL and one of which is
+ // -c / b. If both a and b are 0, so the equation is c = 0, the response
+ // is kNoRealRoots if c != 0 or kAmbiguous if c == 0 (since the
+ // discriminant is zero).
+ static QuadraticRootType DegenerateQuadraticRoots(long double b,
+ long double c,
+ long double *r1,
+ long double *r2);
+
+ // Solves for the real roots of x^3+ax^2+bx+c=0, returns true iff
+ // all three are real, in which case the roots are stored (in any
+ // order) in r1, r2, r3; otherwise, exactly one real root exists and
+ // it is stored in r1.
+ static bool RealRootsForCubic(long double a,
+ long double b,
+ long double c,
+ long double *r1,
+ long double *r2,
+ long double *r3);
+
+
+ // ----------------------------------------------------------------------
+ // Sigmoid
+ // A sigmoid function is a differentiably s curve that ranges between
+ // 0 and 1:
+ // f(x) = 1/(1+e^(-lambda x))
+ // --------------------------------------------------------------------
+ static double Sigmoid(double x, double lambda) {
+ return 1/(1+exp(-lambda*x));
+ }
+
+ // ----------------------------------------------------------------------
+ // InverseSigmoid
+ // Inverts Sigmoid such that InverseSigmoid(Sigmoid(x)) == x for all x
+ // Note that all inputs must be in (-1, 1)
+ // ----------------------------------------------------------------------
+ static double InverseSigmoid(double const x, double const lambda) {
+ return -log((1.0 / x - 1)) / lambda;
+ }
+
+ // ----------------------------------------------------------------------
+ // Sigmoid2
+ // A nicer way of specifying a sigmoid. A sigmoid is a smooth s curve
+ // that ranges from 0 to 1. We describe a sigmoid with three values:
+ //
+ // start: the x value at which f(x) = tolerance
+ // finish: the x value at which f(x) = 1-tolerance
+ //
+ // So if we was a smoothly transitioning function from, say, x=1 to
+ // x=10 with the property that anything outside the domain [1, 10]
+ // will still be within 10% of either f(1) or f(10) then we set: start
+ // = 1 finish = 10 tolerance = 0.1
+ // --------------------------------------------------------------------
+ static double Sigmoid2(double x, double start_x,
+ double finish_x, double tolerance) {
+ DCHECK_GT(tolerance, 0);
+ DCHECK_LT(tolerance, 1);
+ DCHECK_NE(finish_x - start_x, 0);
+ double lambda = log((1-tolerance)/tolerance)*2/(finish_x - start_x);
+ return Sigmoid(x - 0.5 * (start_x + finish_x), lambda);
+ }
+
+ // Returns the greatest common divisor of two unsigned integers x and y
+ static unsigned int GCD(unsigned int x, unsigned int y) {
+ while (y != 0) {
+ unsigned int r = x % y;
+ x = y;
+ y = r;
+ }
+ return x;
+ }
+
+ // Returns the greatest common divisor of two unsigned integers x and y,
+ // and assigns a, and b such that a*x + b*y = gcd(x, y).
+ static unsigned int ExtendedGCD(unsigned int x, unsigned int y,
+ int* a, int* b);
+
+ // Returns the least common multiple of two unsigned integers. Returns zero
+ // if either is zero.
+ static unsigned int LeastCommonMultiple(unsigned int a, unsigned int b) {
+ if (a > b) {
+ return (a / MathUtil::GCD(a, b)) * b;
+ } else if (a < b) {
+ return (b / MathUtil::GCD(b, a)) * a;
+ } else {
+ return a;
+ }
+ }
+
+ // Converts a non-zero double value representing an odds into its
+ // probability value.
+ static double OddsToProbability(double odds) {
+ DCHECK_GE(odds, 0.0);
+ return odds / (1.0 + odds);
+ }
+
+ // Converts a probability with range [0-1.0) into its odds value.
+ static double ProbabilityToOdds(double prob) {
+ DCHECK_GE(prob, 0.0);
+ DCHECK_LT(prob, 1.0);
+ return prob / (1.0 - prob);
+ }
+
+ // --------------------------------------------------------------------
+ // ShardsToRead
+ // Resharding helper. Suppose we have N input shards and M output
+ // shards sharded by modulo of the same hash function. If we want
+ // to write a subset of the output shards, which input shards should
+ // we read?
+ //
+ // Inputs:
+ // shards_to_write gives the desired subset of the M output shards.
+ // shards_to_read gives the number N of the input shards.
+ // Outputs:
+ // shards_to_read gives the subset of the N input shards to read.
+ // --------------------------------------------------------------------
+ static void ShardsToRead(const vector<bool>& shards_to_write,
+ vector<bool>* shards_to_read);
+
+ // --------------------------------------------------------------------
+ // Round, IntRound
+ // These functions round a floating-point number to an integer. They
+ // work for positive or negative numbers.
+ //
+ // Values that are halfway between two integers may be rounded up or
+ // down, for example IntRound(0.5) == 0 and IntRound(1.5) == 2. This
+ // allows these functions to be implemented efficiently on Intel
+ // processors (see the template specializations at the bottom of this
+ // file). You should not use these functions if you care about which
+ // way such half-integers are rounded.
+ //
+ // Example usage:
+ // double y, z;
+ // int x = IntRound(y + 3.7);
+ // int64 b = Round<int64>(0.3 * z);
+ //
+ // Note that the floating-point template parameter is typically inferred
+ // from the argument type, i.e. there is no need to specify it explicitly.
+ // --------------------------------------------------------------------
+ template <class IntOut, class FloatIn>
+ static IntOut Round(FloatIn x);
+
+ // Example usage: IntRound(3.6) (no need for IntRound<double>(3.6)).
+ template <class FloatIn>
+ static int IntRound(FloatIn x) { return Round<int>(x); }
+
+ // --------------------------------------------------------------------
+ // FastIntRound, FastInt64Round
+ // Fast routines for converting floating-point numbers to integers.
+ //
+ // These routines are approximately 6 times faster than the default
+ // implementation of IntRound() on Intel processors (12 times faster on
+ // the Pentium 3). They are also more than 5 times faster than simply
+ // casting a "double" to an "int" using static_cast<int>. This is
+ // because casts are defined to truncate towards zero, which on Intel
+ // processors requires changing the rounding mode and flushing the
+ // floating-point pipeline (unless programs are compiled specifically
+ // for the Pentium 4, which has a new instruction to avoid this).
+ //
+ // Numbers that are halfway between two integers may be rounded up or
+ // down. This is because the conversion is done using the default
+ // rounding mode, which rounds towards the closest even number in case
+ // of ties. So for example, FastIntRound(0.5) == 0, but
+ // FastIntRound(1.5) == 2. These functions should only be used with
+ // applications that don't care about which way such half-integers are
+ // rounded.
+ //
+ // There are template specializations of Round() which call these
+ // functions (for "int" and "int64" only), but it's safer to call them
+ // directly.
+ //
+ // This functions are equivalent to lrint() and llrint() as defined in
+ // the ISO C99 standard. Unfortunately this standard does not seem to
+ // widely adopted yet and these functions are not available by default.
+ // --------------------------------------------------------------------
+
+ static int32 FastIntRound(double x) {
+ // This function is not templatized because gcc doesn't seem to be able
+ // to deal with inline assembly code in templatized functions, and there
+ // is no advantage to passing an argument type of "float" on Intel
+ // architectures anyway.
+
+#if defined __GNUC__ && (defined __i386__ || defined __SSE2__)
+#if defined __SSE2__
+ // SSE2.
+ int32 result;
+ __asm__ __volatile__
+ ("cvtsd2si %1, %0"
+ : "=r" (result) // Output operand is a register
+ : "x" (x)); // Input operand is an xmm register
+ return result;
+#elif defined __i386__
+ // FPU stack. Adapted from /usr/include/bits/mathinline.h.
+ int32 result;
+ __asm__ __volatile__
+ ("fistpl %0"
+ : "=m" (result) // Output operand is a memory location
+ : "t" (x) // Input operand is top of FP stack
+ : "st"); // Clobbers (pops) top of FP stack
+ return result;
+#endif // if defined __x86_64__ || ...
+#else
+ return Round<int32, double>(x);
+#endif // if defined __GNUC__ && ...
+ }
+
+ static int64 FastInt64Round(double x) {
+#if defined __GNUC__ && (defined __i386__ || defined __x86_64__)
+#if defined __x86_64__
+ // SSE2.
+ int64 result;
+ __asm__ __volatile__
+ ("cvtsd2si %1, %0"
+ : "=r" (result) // Output operand is a register
+ : "x" (x)); // Input operand is an xmm register
+ return result;
+#elif defined __i386__
+ // There is no CVTSD2SI in i386 to produce a 64 bit int, even with SSE2.
+ // FPU stack. Adapted from /usr/include/bits/mathinline.h.
+ int64 result;
+ __asm__ __volatile__
+ ("fistpll %0"
+ : "=m" (result) // Output operand is a memory location
+ : "t" (x) // Input operand is top of FP stack
+ : "st"); // Clobbers (pops) top of FP stack
+ return result;
+#endif // if defined __i386__
+#else
+ return Round<int64, double>(x);
+#endif // if defined __GNUC__ && ...
+ }
+
+ // Return Not a Number.
+ // Consider instead using MathLimits<double>::kNaN directly.
+ static double NaN() { return MathLimits<double>::kNaN; }
+
+ // the sine cardinal function
+ static double Sinc(double x) {
+ if (fabs(x) < 1E-8) return 1.0;
+ return sin(x) / x;
+ }
+
+ // Returns an approximation An for the n-th element of the harmonic
+ // serices Hn = 1 + ... + 1/n. Sets error e such that |An-Hn| < e.
+ static double Harmonic(int64 n, double *e);
+
+ // Returns Stirling's Approximation for log(n!) which has an error
+ // of at worst 1/(1260*n^5).
+ static double Stirling(double n);
+
+ // Returns the log of the binomial coefficient C(n, k), known in the
+ // vernacular as "N choose K". Why log? Because the integer number
+ // for non-trivial N and K would overflow.
+ // Note that if k > 15, this uses Stirling's approximation of log(n!).
+ // The relative error is about 1/(1260*k^5) (which is 7.6e-10 when k=16).
+ static double LogCombinations(int n, int k);
+
+ // Rounds "f" to the nearest float which has its last "bits" bits of
+ // the mantissa set to zero. This rounding will introduce a
+ // fractional error of at most 2^(bits - 24). Useful for values
+ // stored in compressed files, when super-accurate numbers aren't
+ // needed and the random-looking low-order bits foil compressors.
+ // This routine should be really fast when inlined with "bits" set
+ // to a constant.
+ // Precondition: 1 <= bits <= 23, f != NaN
+ static float RoundOffBits(const float f, const int bits) {
+ const int32 f_rep = bit_cast<int32>(f);
+
+ // Set low-order "bits" bits to zero.
+ int32 g_rep = f_rep & ~((1 << bits) - 1);
+
+ // Round mantissa up if we need to. Note that we do round-to-even,
+ // a.k.a. round-up-if-odd.
+ const int32 lowbits = f_rep & ((1 << bits) - 1);
+ if (lowbits > (1 << (bits - 1)) ||
+ (lowbits == (1 << (bits - 1)) && (f_rep & (1 << bits)))) {
+ g_rep += (1 << bits);
+ // NOTE: overflow does a really nice thing here - if all the
+ // rest of the mantissa bits are 1, the carry carries over into
+ // the exponent and increments it by 1, which is exactly what we
+ // want. It even gets to +/-INF properly.
+ }
+ return bit_cast<float>(g_rep);
+ }
+ // Same, but for doubles. 1 <= bits <= 52, error at most 2^(bits - 53).
+ static double RoundOffBits(const double f, const int bits) {
+ const int64 f_rep = bit_cast<int64>(f);
+ int64 g_rep = f_rep & ~((1LL << bits) - 1);
+ const int64 lowbits = f_rep & ((1LL << bits) - 1);
+ if (lowbits > (1LL << (bits - 1)) ||
+ (lowbits == (1LL << (bits - 1)) && (f_rep & (1LL << bits)))) {
+ g_rep += (1LL << bits);
+ }
+ return bit_cast<double>(g_rep);
+ }
+
+ // Largest of two values.
+ // Works correctly for special floating point values.
+ // Note: 0.0 and -0.0 are not differentiated by Max (Max(0.0, -0.0) is -0.0),
+ // which should be OK because, although they (can) have different
+ // bit representation, they are observably the same when examined
+ // with arithmetic and (in)equality operators.
+ template<typename T>
+ static T Max(const T x, const T y) {
+ return MathLimits<T>::IsNaN(x) || x > y ? x : y;
+ }
+
+ // Smallest of two values
+ // Works correctly for special floating point values.
+ // Note: 0.0 and -0.0 are not differentiated by Min (Min(-0.0, 0.0) is 0.0),
+ // which should be OK: see the comment for Max above.
+ template<typename T>
+ static T Min(const T x, const T y) {
+ return MathLimits<T>::IsNaN(x) || x < y ? x : y;
+ }
+
+ // Absolute value of x
+ // Works correctly for unsigned types and
+ // for special floating point values.
+ // Note: 0.0 and -0.0 are not differentiated by Abs (Abs(0.0) is -0.0),
+ // which should be OK: see the comment for Max above.
+ template<typename T>
+ static T Abs(const T x) {
+ return x > 0 ? x : -x;
+ }
+
+ // The sign of x
+ // (works for unsigned types and special floating point values as well):
+ // -1 if x < 0,
+ // +1 if x > 0,
+ // 0 if x = 0.
+ // nan if x is nan.
+ template<typename T>
+ static T Sign(const T x) {
+ return MathLimits<T>::IsNaN(x) ? x : (x == 0 ? 0 : (x > 0 ? 1 : -1));
+ }
+
+ // Returns the square of x
+ template <typename T>
+ static T Square(const T x) {
+ return x * x;
+ }
+
+ // Absolute value of the difference between two numbers.
+ // Works correctly for signed types and special floating point values.
+ template<typename T>
+ static typename MathLimits<T>::UnsignedType AbsDiff(const T x, const T y) {
+ return x > y ? x - y : y - x;
+ }
+
+ // CAVEAT: Floating point computation instability for x86 CPUs
+ // can frequently stem from the difference of when floating point values
+ // are transferred from registers to memory and back,
+ // which can depend simply on the level of optimization.
+ // The reason is that the registers use a higher-precision representation.
+ // Hence, instead of relying on approximate floating point equality below
+ // it might be better to reorganize the code with volatile modifiers
+ // for the floating point variables so as to control when
+ // the loss of precision occurs.
+
+ // If two (usually floating point) numbers are within a certain
+ // absolute margin of error.
+ // NOTE: this "misbehaves" is one is trying to capture provisons for errors
+ // that are relative, i.e. larger if the numbers involved are larger.
+ // Consider using WithinFraction or WithinFractionOrMargin below.
+ //
+ // This and other Within* NearBy* functions below
+ // work correctly for signed types and special floating point values.
+ template<typename T>
+ static bool WithinMargin(const T x, const T y, const T margin) {
+ DCHECK_GE(margin, 0);
+ // this is a little faster than x <= y + margin && x >= y - margin
+ return AbsDiff(x, y) <= margin;
+ }
+
+ // If two (usually floating point) numbers are within a certain
+ // fraction of their magnitude.
+ // CAVEAT: Although this works well if computation errors are relative
+ // both for large magnitude numbers > 1 and for small magnitude numbers < 1,
+ // zero is never within a fraction of any
+ // non-zero finite number (fraction is required to be < 1).
+ template<typename T>
+ static bool WithinFraction(const T x, const T y, const T fraction);
+
+ // If two (usually floating point) numbers are within a certain
+ // fraction of their magnitude or within a certain absolute margin of error.
+ // This is the same as the following but faster:
+ // WithinFraction(x, y, fraction) || WithinMargin(x, y, margin)
+ // E.g. WithinFraction(0.0, 1e-10, 1e-5) is false but
+ // WithinFractionOrMargin(0.0, 1e-10, 1e-5, 1e-5) is true.
+ template<typename T>
+ static bool WithinFractionOrMargin(const T x, const T y,
+ const T fraction, const T margin);
+
+ // NearBy* functions below are geared as replacements for CHECK_EQ()
+ // over floating-point numbers.
+
+ // Same as WithinMargin(x, y, MathLimits<T>::kStdError)
+ // Works as == for integer types.
+ template<typename T>
+ static bool NearByMargin(const T x, const T y) {
+ return AbsDiff(x, y) <= MathLimits<T>::kStdError;
+ }
+
+ // Same as WithinFraction(x, y, MathLimits<T>::kStdError)
+ // Works as == for integer types.
+ template<typename T>
+ static bool NearByFraction(const T x, const T y) {
+ return WithinFraction(x, y, MathLimits<T>::kStdError);
+ }
+
+ // Same as WithinFractionOrMargin(x, y, MathLimits<T>::kStdError,
+ // MathLimits<T>::kStdError)
+ // Works as == for integer types.
+ template<typename T>
+ static bool NearByFractionOrMargin(const T x, const T y) {
+ return WithinFractionOrMargin(x, y, MathLimits<T>::kStdError,
+ MathLimits<T>::kStdError);
+ }
+
+ // Tests whether two values are close enough to each other to be considered
+ // equal. This function is intended to be used mainly as a replacement for
+ // equality tests of floating point values in CHECK()s, and as a replacement
+ // for equality comparison against golden files. It is the same as == for
+ // integer types. The purpose of AlmostEquals() is to avoid false positive
+ // error reports in unit tests and regression tests due to minute differences
+ // in floating point arithmetic (for example, due to a different compiler).
+ //
+ // We cannot use simple equality to compare floating point values
+ // because floating point expressions often accumulate inaccuracies, and
+ // new compilers may introduce further variations in the values.
+ //
+ // Two values x and y are considered "almost equals" if:
+ // (a) Both values are very close to zero: x and y are in the range
+ // [-standard_error, standard_error]
+ // Normal calculations producing these values are likely to be dealing
+ // with meaningless residual values.
+ // -or-
+ // (b) The difference between the values is small:
+ // abs(x - y) <= standard_error
+ // -or-
+ // (c) The values are finite and the relative difference between them is
+ // small:
+ // abs (x - y) <= standard_error * max(abs(x), abs(y))
+ // -or-
+ // (d) The values are both positive infinity or both negative infinity.
+ //
+ // Cases (b) and (c) are the same as MathUtils::NearByFractionOrMargin(x, y),
+ // for finite values of x and y.
+ //
+ // standard_error is the corresponding MathLimits<T>::kStdError constant.
+ // It is equivalent to 5 bits of mantissa error. See
+ // google3/util/math/mathlimits.cc.
+ //
+ // Caveat:
+ // AlmostEquals() is not appropriate for checking long sequences of
+ // operations where errors may cascade (like extended sums or matrix
+ // computations), or where significant cancellation may occur
+ // (e.g., the expression (x+y)-x, where x is much larger than y).
+ // Both cases may produce errors in excess of standard_error.
+ // In any case, you should not test the results of calculations which have
+ // not been vetted for possible cancellation errors and the like.
+ template<typename T>
+ static bool AlmostEquals(const T x, const T y) {
+ if (x == y) // Covers +inf and -inf, and is a shortcut for finite values.
+ return true;
+ if (!MathLimits<T>::IsFinite(x) || !MathLimits<T>::IsFinite(y))
+ return false;
+
+ if (MathUtil::Abs<T>(x) <= MathLimits<T>::kStdError &&
+ MathUtil::Abs<T>(y) <= MathLimits<T>::kStdError)
+ return true;
+
+ return MathUtil::NearByFractionOrMargin<T>(x, y);
+ }
+
+ // Returns the clamped value to be between low and high inclusively.
+ template<typename T>
+ static const T& Clamp(const T& low, const T& high, const T& value) {
+ return std::max(low, std::min(value, high));
+ }
+
+ // Clamps value to be between min and max inclusively.
+ template<typename T>
+ static void ClampValue(const T& low, const T& high, T* value) {
+ *value = Clamp(low, high, *value);
+ }
+};
+
+// ========================================================================= //
+
+#if (defined __i386__ || defined __x86_64__) && defined __GNUC__
+
+// We define template specializations of Round() to get the more efficient
+// Intel versions when possible. Note that gcc does not currently support
+// partial specialization of templatized functions.
+template<>
+inline int32 MathUtil::Round<int32, double>(double x) {
+ return FastIntRound(x);
+}
+
+template<>
+inline int32 MathUtil::Round<int32, float>(float x) {
+ return FastIntRound(x);
+}
+
+template<>
+inline int64 MathUtil::Round<int64, double>(double x) {
+ return FastInt64Round(x);
+}
+
+template<>
+inline int64 MathUtil::Round<int64, float>(float x) {
+ return FastInt64Round(x);
+}
+
+#endif
+
+template<typename T>
+bool MathUtil::WithinFraction(const T x, const T y, const T fraction) {
+ // not just "0 <= fraction" to fool the compiler for unsigned types
+ DCHECK((0 < fraction || 0 == fraction) && fraction < 1);
+
+ // Template specialization will convert the if() condition to a constant,
+ // which will cause the compiler to generate code for either the "if" part
+ // or the "then" part. In this way we avoid a compiler warning
+ // about a potential integer overflow in crosstool v12 (gcc 4.3.1).
+ if (MathLimits<T>::kIsInteger) {
+ return x == y;
+ } else {
+ // IsFinite checks are to make kPosInf and kNegInf not within fraction
+ return (MathLimits<T>::IsFinite(x) || MathLimits<T>::IsFinite(y)) &&
+ (AbsDiff(x, y) <= fraction * Max(Abs(x), Abs(y)));
+ }
+}
+
+template<typename T>
+bool MathUtil::WithinFractionOrMargin(const T x, const T y,
+ const T fraction, const T margin) {
+ // not just "0 <= fraction" to fool the compiler for unsigned types
+ DCHECK((0 < fraction || 0 == fraction) && fraction < 1 && margin >= 0);
+
+ // Template specialization will convert the if() condition to a constant,
+ // which will cause the compiler to generate code for either the "if" part
+ // or the "then" part. In this way we avoid a compiler warning
+ // about a potential integer overflow in crosstool v12 (gcc 4.3.1).
+ if (MathLimits<T>::kIsInteger) {
+ return x == y;
+ } else {
+ // IsFinite checks are to make kPosInf and kNegInf not within fraction
+ return (MathLimits<T>::IsFinite(x) || MathLimits<T>::IsFinite(y)) &&
+ (AbsDiff(x, y) <= Max(margin, fraction * Max(Abs(x), Abs(y))));
+ }
+}
+
+#endif // UTIL_MATH_MATHUTIL_H__
diff --git a/src/third_party/s2/util/math/matrix3x3-inl.h b/src/third_party/s2/util/math/matrix3x3-inl.h
new file mode 100755
index 00000000000..df88812cec0
--- /dev/null
+++ b/src/third_party/s2/util/math/matrix3x3-inl.h
@@ -0,0 +1,576 @@
+//
+// Copyright 2003 Google, Inc.
+//
+//
+// A simple class to handle 3x3 matrices
+// The aim of this class is to be able to manipulate 3x3 matrices
+// and 3D vectors as naturally as possible and make calculations
+// readable.
+// For that reason, the operators +, -, * are overloaded.
+// (Reading a = a + b*2 - c is much easier to read than
+// a = Sub(Add(a, Mul(b,2)),c) )
+//
+// Please be careful about overflows when using those matrices wth integer types
+// The calculations are carried with VType. eg : if you are using uint8 as the
+// base type, all values will be modulo 256.
+// This feature is necessary to use the class in a more general framework with
+// VType != plain old data type.
+
+#ifndef UTIL_MATH_MATRIX3X3_INL_H__
+#define UTIL_MATH_MATRIX3X3_INL_H__
+#include <iostream>
+using std::ostream;
+using std::cout;
+using std::endl;
+
+
+#include "util/math/mathutil.h"
+#include "util/math/vector3-inl.h"
+#include "util/math/matrix3x3.h"
+#include "base/basictypes.h"
+#include "base/logging.h"
+
+template <class VType>
+class Matrix3x3 {
+ private:
+ VType m_[3][3];
+ public:
+ typedef Matrix3x3<VType> Self;
+ typedef Vector3<VType> MVector;
+ // Initialize the matrix to 0
+ Matrix3x3() {
+ m_[0][2] = m_[0][1] = m_[0][0] = VType();
+ m_[1][2] = m_[1][1] = m_[1][0] = VType();
+ m_[2][2] = m_[2][1] = m_[2][0] = VType();
+ }
+
+ // Constructor explicitly setting the values of all the coefficient of
+ // the matrix
+ Matrix3x3(const VType &m00, const VType &m01, const VType &m02,
+ const VType &m10, const VType &m11, const VType &m12,
+ const VType &m20, const VType &m21, const VType &m22) {
+ m_[0][0] = m00;
+ m_[0][1] = m01;
+ m_[0][2] = m02;
+
+ m_[1][0] = m10;
+ m_[1][1] = m11;
+ m_[1][2] = m12;
+
+ m_[2][0] = m20;
+ m_[2][1] = m21;
+ m_[2][2] = m22;
+ }
+
+ // Copy constructor
+ Matrix3x3(const Self &mb) {
+ m_[0][0] = mb.m_[0][0];
+ m_[0][1] = mb.m_[0][1];
+ m_[0][2] = mb.m_[0][2];
+
+ m_[1][0] = mb.m_[1][0];
+ m_[1][1] = mb.m_[1][1];
+ m_[1][2] = mb.m_[1][2];
+
+ m_[2][0] = mb.m_[2][0];
+ m_[2][1] = mb.m_[2][1];
+ m_[2][2] = mb.m_[2][2];
+ }
+
+ // Casting constructor
+ template <class VType2>
+ static Self Cast(const Matrix3x3<VType2> &mb) {
+ return Self(static_cast<VType>(mb(0, 0)),
+ static_cast<VType>(mb(0, 1)),
+ static_cast<VType>(mb(0, 2)),
+ static_cast<VType>(mb(1, 0)),
+ static_cast<VType>(mb(1, 1)),
+ static_cast<VType>(mb(1, 2)),
+ static_cast<VType>(mb(2, 0)),
+ static_cast<VType>(mb(2, 1)),
+ static_cast<VType>(mb(2, 2)));
+ }
+
+ // Change the value of all the coefficients of the matrix
+ inline Self &
+ Set(const VType &m00, const VType &m01, const VType &m02,
+ const VType &m10, const VType &m11, const VType &m12,
+ const VType &m20, const VType &m21, const VType &m22) {
+ m_[0][0] = m00;
+ m_[0][1] = m01;
+ m_[0][2] = m02;
+
+ m_[1][0] = m10;
+ m_[1][1] = m11;
+ m_[1][2] = m12;
+
+ m_[2][0] = m20;
+ m_[2][1] = m21;
+ m_[2][2] = m22;
+ return (*this);
+ }
+
+ // Copy
+ inline Self& operator=(const Self &mb) {
+ m_[0][0] = mb.m_[0][0];
+ m_[0][1] = mb.m_[0][1];
+ m_[0][2] = mb.m_[0][2];
+
+ m_[1][0] = mb.m_[1][0];
+ m_[1][1] = mb.m_[1][1];
+ m_[1][2] = mb.m_[1][2];
+
+ m_[2][0] = mb.m_[2][0];
+ m_[2][1] = mb.m_[2][1];
+ m_[2][2] = mb.m_[2][2];
+ return (*this);
+ }
+
+ // Compare
+ inline bool operator==(const Self &mb) const {
+ return (m_[0][0] == mb.m_[0][0]) &&
+ (m_[0][1] == mb.m_[0][1]) &&
+ (m_[0][2] == mb.m_[0][2]) &&
+ (m_[1][0] == mb.m_[1][0]) &&
+ (m_[1][1] == mb.m_[1][1]) &&
+ (m_[1][2] == mb.m_[1][2]) &&
+ (m_[2][0] == mb.m_[2][0]) &&
+ (m_[2][1] == mb.m_[2][1]) &&
+ (m_[2][2] == mb.m_[2][2]);
+ }
+
+ // Matrix addition
+ inline Self& operator+=(const Self &mb) {
+ m_[0][0] += mb.m_[0][0];
+ m_[0][1] += mb.m_[0][1];
+ m_[0][2] += mb.m_[0][2];
+
+ m_[1][0] += mb.m_[1][0];
+ m_[1][1] += mb.m_[1][1];
+ m_[1][2] += mb.m_[1][2];
+
+ m_[2][0] += mb.m_[2][0];
+ m_[2][1] += mb.m_[2][1];
+ m_[2][2] += mb.m_[2][2];
+ return (*this);
+ }
+
+ // Matrix subtration
+ inline Self& operator-=(const Self &mb) {
+ m_[0][0] -= mb.m_[0][0];
+ m_[0][1] -= mb.m_[0][1];
+ m_[0][2] -= mb.m_[0][2];
+
+ m_[1][0] -= mb.m_[1][0];
+ m_[1][1] -= mb.m_[1][1];
+ m_[1][2] -= mb.m_[1][2];
+
+ m_[2][0] -= mb.m_[2][0];
+ m_[2][1] -= mb.m_[2][1];
+ m_[2][2] -= mb.m_[2][2];
+ return (*this);
+ }
+
+ // Matrix multiplication by a scalar
+ inline Self& operator*=(const VType &k) {
+ m_[0][0] *= k;
+ m_[0][1] *= k;
+ m_[0][2] *= k;
+
+ m_[1][0] *= k;
+ m_[1][1] *= k;
+ m_[1][2] *= k;
+
+ m_[2][0] *= k;
+ m_[2][1] *= k;
+ m_[2][2] *= k;
+ return (*this);
+ }
+
+ // Matrix addition
+ inline Self operator+(const Self &mb) const {
+ return Self(*this) += mb;
+ }
+
+ // Matrix subtraction
+ inline Self operator-(const Self &mb) const {
+ return Self(*this) -= mb;
+ }
+
+ // Change the sign of all the coefficients in the matrix
+ friend inline Self operator-(const Self &vb) {
+ return Self(-vb.m_[0][0], -vb.m_[0][1], -vb.m_[0][2],
+ -vb.m_[1][0], -vb.m_[1][1], -vb.m_[1][2],
+ -vb.m_[2][0], -vb.m_[2][1], -vb.m_[2][2]);
+ }
+
+ // Matrix multiplication by a scalar
+ inline Self operator*(const VType &k) const {
+ return Self(*this) *= k;
+ }
+
+ friend inline Self operator*(const VType &k, const Self &mb) {
+ return Self(mb)*k;
+ }
+
+ // Matrix multiplication
+ inline Self operator*(const Self &mb) const {
+ return Self(
+ m_[0][0] * mb.m_[0][0] + m_[0][1] * mb.m_[1][0] + m_[0][2] * mb.m_[2][0],
+ m_[0][0] * mb.m_[0][1] + m_[0][1] * mb.m_[1][1] + m_[0][2] * mb.m_[2][1],
+ m_[0][0] * mb.m_[0][2] + m_[0][1] * mb.m_[1][2] + m_[0][2] * mb.m_[2][2],
+
+ m_[1][0] * mb.m_[0][0] + m_[1][1] * mb.m_[1][0] + m_[1][2] * mb.m_[2][0],
+ m_[1][0] * mb.m_[0][1] + m_[1][1] * mb.m_[1][1] + m_[1][2] * mb.m_[2][1],
+ m_[1][0] * mb.m_[0][2] + m_[1][1] * mb.m_[1][2] + m_[1][2] * mb.m_[2][2],
+
+ m_[2][0] * mb.m_[0][0] + m_[2][1] * mb.m_[1][0] + m_[2][2] * mb.m_[2][0],
+ m_[2][0] * mb.m_[0][1] + m_[2][1] * mb.m_[1][1] + m_[2][2] * mb.m_[2][1],
+ m_[2][0] * mb.m_[0][2] + m_[2][1] * mb.m_[1][2] + m_[2][2] * mb.m_[2][2]);
+ }
+
+ // Multiplication of a matrix by a vector
+ inline MVector operator*(const MVector &v) const {
+ return MVector(
+ m_[0][0] * v[0] + m_[0][1] * v[1] + m_[0][2] * v[2],
+ m_[1][0] * v[0] + m_[1][1] * v[1] + m_[1][2] * v[2],
+ m_[2][0] * v[0] + m_[2][1] * v[1] + m_[2][2] * v[2]);
+ }
+
+ // Return the determinant of the matrix
+ inline VType Det(void) const {
+ return m_[0][0] * m_[1][1] * m_[2][2]
+ + m_[0][1] * m_[1][2] * m_[2][0]
+ + m_[0][2] * m_[1][0] * m_[2][1]
+ - m_[2][0] * m_[1][1] * m_[0][2]
+ - m_[2][1] * m_[1][2] * m_[0][0]
+ - m_[2][2] * m_[1][0] * m_[0][1];
+ }
+
+ // Return the trace of the matrix
+ inline VType Trace(void) const {
+ return m_[0][0] + m_[1][1] + m_[2][2];
+ }
+
+ // Return a pointer to the data array for interface with other libraries
+ // like opencv
+ VType* Data() {
+ return reinterpret_cast<VType*>(m_);
+ }
+ const VType* Data() const {
+ return reinterpret_cast<const VType*>(m_);
+ }
+
+ // Return matrix element (i,j) with 0<=i<=2 0<=j<=2
+ inline VType &operator()(const int i, const int j) {
+ DCHECK(i >= 0);
+ DCHECK(i < 3);
+ DCHECK(j >= 0);
+ DCHECK(j < 3);
+ return m_[i][j];
+ }
+ inline VType operator()(const int i, const int j) const {
+ DCHECK(i >= 0);
+ DCHECK(i < 3);
+ DCHECK(j >= 0);
+ DCHECK(j < 3);
+ return m_[i][j];
+ }
+
+ // Return matrix element (i/3,i%3) with 0<=i<=8 (access concatenated rows).
+ inline VType &operator[](const int i) {
+ DCHECK(i >= 0);
+ DCHECK(i < 9);
+ return reinterpret_cast<VType*>(m_)[i];
+ }
+ inline VType operator[](const int i) const {
+ DCHECK(i >= 0);
+ DCHECK(i < 9);
+ return reinterpret_cast<const VType*>(m_)[i];
+ }
+
+ // Return the transposed matrix
+ inline Self Transpose(void) const {
+ return Self(m_[0][0], m_[1][0], m_[2][0],
+ m_[0][1], m_[1][1], m_[2][1],
+ m_[0][2], m_[1][2], m_[2][2]);
+ }
+
+ // Return the transposed of the matrix of the cofactors
+ // (Useful for inversion for example)
+ inline Self ComatrixTransposed(void) const {
+ return Self(
+ m_[1][1] * m_[2][2] - m_[2][1] * m_[1][2],
+ m_[2][1] * m_[0][2] - m_[0][1] * m_[2][2],
+ m_[0][1] * m_[1][2] - m_[1][1] * m_[0][2],
+
+ m_[1][2] * m_[2][0] - m_[2][2] * m_[1][0],
+ m_[2][2] * m_[0][0] - m_[0][2] * m_[2][0],
+ m_[0][2] * m_[1][0] - m_[1][2] * m_[0][0],
+
+ m_[1][0] * m_[2][1] - m_[2][0] * m_[1][1],
+ m_[2][0] * m_[0][1] - m_[0][0] * m_[2][1],
+ m_[0][0] * m_[1][1] - m_[1][0] * m_[0][1]);
+ }
+ // Matrix inversion
+ inline Self Inverse(void) const {
+ VType det = Det();
+ CHECK(det != 0) << " Can't inverse. Determinant = 0.";
+ return (1/det) * ComatrixTransposed();
+ }
+
+ // Return the vector 3D at row i
+ inline MVector Row(const int i) const {
+ DCHECK(i >= 0);
+ DCHECK(i < 3);
+ return MVector(m_[i][0], m_[i][1], m_[i][2]);
+ }
+
+ // Return the vector 3D at col i
+ inline MVector Col(const int i) const {
+ DCHECK(i >= 0);
+ DCHECK(i < 3);
+ return MVector(m_[0][i], m_[1][i], m_[2][i]);
+ }
+
+ // Create a matrix from 3 row vectors
+ static inline Self FromRows(const MVector &v1,
+ const MVector &v2,
+ const MVector &v3) {
+ Self temp;
+ temp.Set(v1[0], v1[1], v1[2],
+ v2[0], v2[1], v2[2],
+ v3[0], v3[1], v3[2]);
+ return temp;
+ }
+
+ // Create a matrix from 3 column vectors
+ static inline Self FromCols(const MVector &v1,
+ const MVector &v2,
+ const MVector &v3) {
+ Self temp;
+ temp.Set(v1[0], v2[0], v3[0],
+ v1[1], v2[1], v3[1],
+ v1[2], v2[2], v3[2]);
+ return temp;
+ }
+
+ // Set the vector in row i to be v1
+ void SetRow(int i, const MVector &v1) {
+ DCHECK(i >= 0);
+ DCHECK(i < 3);
+ m_[i][0] = v1[0];
+ m_[i][1] = v1[1];
+ m_[i][2] = v1[2];
+ }
+
+ // Set the vector in column i to be v1
+ void SetCol(int i, const MVector &v1) {
+ DCHECK(i >= 0);
+ DCHECK(i < 3);
+ m_[0][i] = v1[0];
+ m_[1][i] = v1[1];
+ m_[2][i] = v1[2];
+ }
+
+ // Return a matrix M close to the original but verifying MtM = I
+ // (useful to compensate for errors in a rotation matrix)
+ Self Orthogonalize() const {
+ MVector r1, r2, r3;
+ r1 = Row(0).Normalize();
+ r2 = (Row(2).CrossProd(r1)).Normalize();
+ r3 = (r1.CrossProd(r2)).Normalize();
+ return FromRows(r1, r2, r3);
+ }
+
+ // Return the identity matrix
+ static inline Self Identity(void) {
+ Self temp;
+ temp.Set(1, 0, 0,
+ 0, 1, 0,
+ 0, 0, 1);
+ return temp;
+ }
+
+ // Return a matrix full of zeros
+ static inline Self Zero(void) {
+ return Self();
+ }
+
+ // Return a diagonal matrix with the coefficients in v
+ static inline Self Diagonal(const MVector &v) {
+ return Self(v[0], VType(), VType(),
+ VType(), v[1], VType(),
+ VType(), VType(), v[2]);
+ }
+
+ // Return the matrix vvT
+ static Self Sym3(const MVector &v) {
+ return Self(
+ v[0]*v[0], v[0]*v[1], v[0]*v[2],
+ v[1]*v[0], v[1]*v[1], v[1]*v[2],
+ v[2]*v[0], v[2]*v[1], v[2]*v[2]);
+ }
+ // Return a matrix M such that:
+ // for each u, M * u = v.CrossProd(u)
+ static Self AntiSym3(const MVector &v) {
+ return Self(VType(), -v[2], v[1],
+ v[2], VType(), -v[0],
+ -v[1], v[0], VType());
+ }
+
+ static Self Rodrigues(const MVector &rot) {
+ Self R;
+ VType theta = rot.Norm();
+ MVector w = rot.Normalize();
+ Self Wv = Self::AntiSym3(w);
+ Self I = Self::Identity();
+ Self A = Self::Sym3(w);
+ R = (1 - cos(theta)) * A + sin(theta) * Wv + cos(theta) * I;
+ return R;
+ }
+
+ // Returns v.Transpose() * (*this) * u
+ VType MulBothSides(const MVector &v, const MVector &u) const {
+ return ((*this) * u).DotProd(v);
+ }
+
+ // Use the 3x3 matrix as a projective transform for 2d points
+ Vector2<VType> Project(const Vector2<VType> &v) const {
+ MVector temp = (*this) * MVector(v[0], v[1], 1);
+ return Vector2<VType>(temp[0] / temp[2], temp[1] / temp[2]);
+ }
+
+ // Return the Frobenius norm of the matrix: sqrt(sum(aij^2))
+ VType FrobeniusNorm() const {
+ VType sum = VType();
+ for (int i = 0; i < 3; i++) {
+ for (int j = 0; j < 3; j++) {
+ sum += m_[i][j] * m_[i][j];
+ }
+ }
+ return sqrt(sum);
+ }
+
+ // Finds the eigen values of the matrix. Return the number of real eigenvalues
+ // found
+ int EigenValues(MVector *eig_val) {
+ long double r1, r2, r3; // NOLINT
+ // characteristic polynomial is
+ // x^3 + (a11*a22+a22*a33+a33*a11)*x^2 - trace(A)*x - det(A)
+ VType a = -Trace();
+ VType b = m_[0][0]*m_[1][1] + m_[1][1]*m_[2][2] + m_[2][2]*m_[0][0]
+ - m_[1][0]*m_[0][1] - m_[2][1]*m_[1][2] - m_[0][2]*m_[2][0];
+ VType c = -Det();
+ bool res = MathUtil::RealRootsForCubic(a, b, c, &r1, &r2, &r3);
+ (*eig_val)[0] = r1;
+ if (res) {
+ (*eig_val)[1] = r2;
+ (*eig_val)[2] = r3;
+ return 3;
+ }
+ return 1;
+ }
+
+ // Finds the eigen values and associated eigen vectors of a
+ // symmetric positive definite 3x3 matrix,eigen values are
+ // sorted in decreasing order, eig_val corresponds to the
+ // columns of the eig_vec matrix.
+ // Note: The routine will only use the lower diagonal part
+ // of the matrix, i.e.
+ // | a00, |
+ // | a10, a11, |
+ // | a20, a21, a22 |
+ void SymmetricEigenSolver(MVector *eig_val,
+ Self *eig_vec ) {
+ // Compute characteristic polynomial coefficients
+ double c2 = -(m_[0][0] + m_[1][1] + m_[2][2]);
+ double c1 = -(m_[1][0] * m_[1][0] - m_[0][0] * m_[1][1]
+ - m_[0][0] * m_[2][2] - m_[1][1] * m_[2][2]
+ + m_[2][0] * m_[2][0] + m_[2][1] * m_[2][1]);
+ double c0 = -(m_[0][0] * m_[1][1] * m_[2][2] - m_[2][0]
+ * m_[2][0] * m_[1][1] - m_[1][0] * m_[1][0]
+ * m_[2][2] - m_[0][0] * m_[2][1] * m_[2][1]
+ + 2 * m_[1][0] * m_[2][0] * m_[2][1]);
+
+ // Root finding
+ double q = (c2*c2-3*c1)/9.0;
+ double r = (2*c2*c2*c2-9*c2*c1+27*c0)/54.0;
+ // Assume R^3 <Q^3 so there are three real roots
+ if (q < 0) q = 0;
+ double sqrt_q = -2.0 * sqrt(q);
+ double theta = acos(r / sqrt(q * q * q));
+ double c2_3 = c2 / 3;
+ (*eig_val)[0] = sqrt_q * cos(theta / 3.0) - c2_3;
+ (*eig_val)[1] = sqrt_q * cos((theta + 2.0 * M_PI)/3.0) - c2_3;
+ (*eig_val)[2] = sqrt_q * cos((theta - 2.0 * M_PI)/3.0) - c2_3;
+
+ // Sort eigen value in decreasing order
+ Vector3<int> d_order = eig_val->ComponentOrder();
+ (*eig_val) = MVector((*eig_val)[d_order[2]],
+ (*eig_val)[d_order[1]],
+ (*eig_val)[d_order[0]]);
+ // Compute eigenvectors
+ for (int i = 0; i < 3; ++i) {
+ MVector r1 , r2 , r3 , e1 , e2 , e3;
+ r1[0] = m_[0][0] - (*eig_val)[i];
+ r2[0] = m_[1][0];
+ r3[0] = m_[2][0];
+ r1[1] = m_[1][0];
+ r2[1] = m_[1][1] - (*eig_val)[i];
+ r3[1] = m_[2][1];
+ r1[2] = m_[2][0];
+ r2[2] = m_[2][1];
+ r3[2] = m_[2][2] - (*eig_val)[i];
+
+ e1 = r1.CrossProd(r2);
+ e2 = r2.CrossProd(r3);
+ e3 = r3.CrossProd(r1);
+
+ // Make e2 and e3 point in the same direction as e1
+ if (e2.DotProd(e1) < 0) e2 = -e2;
+ if (e3.DotProd(e1) < 0) e3 = -e3;
+ MVector e = (e1 + e2 + e3).Normalize();
+ eig_vec->SetCol(i,e);
+ }
+ }
+
+ // Return true is one of the elements of the matrix is NaN
+ bool IsNaN() const {
+ for ( int i = 0; i < 3; ++i ) {
+ for ( int j = 0; j < 3; ++j ) {
+ if ( isnan(m_[i][j]) ) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ friend std::ostream &operator <<(std::ostream &out, const Self &mb) {
+ int i, j;
+ for (i = 0; i < 3; i++) {
+ if (i ==0) {
+ out << "[";
+ } else {
+ out << " ";
+ }
+ for (j = 0; j < 3; j++) {
+ out << mb(i, j) << " ";
+ }
+ if (i == 2) {
+ out << "]";
+ } else {
+ out << endl;
+ }
+ }
+ return out;
+ }
+};
+
+// TODO(user): Matrix3x3<T> does not actually satisfy the definition of a
+// POD type even when T is a POD. Pretending that Matrix3x3<T> is a POD
+// probably won't cause immediate problems, but eventually this should be fixed.
+PROPAGATE_POD_FROM_TEMPLATE_ARGUMENT(Matrix3x3);
+
+#endif // UTIL_MATH_MATRIX3X3_INL_H__
diff --git a/src/third_party/s2/util/math/matrix3x3.h b/src/third_party/s2/util/math/matrix3x3.h
new file mode 100755
index 00000000000..865eb74564c
--- /dev/null
+++ b/src/third_party/s2/util/math/matrix3x3.h
@@ -0,0 +1,26 @@
+//
+// Copyright 2003 Google, Inc.
+//
+//
+// A simple class to handle 3x3 matrices
+// The aim of this class is to be able to manipulate 3x3 matrices
+// and 3D vectors as naturally as possible and make calculations
+// readable.
+// For that reason, the operators +, -, * are overloaded.
+// (Reading a = a + b*2 - c is much easier to read than
+// a = Sub(Add(a, Mul(b,2)),c) )
+// This file only define the typenames, for API details, look into
+// matrix3x3-inl.h
+//
+
+#ifndef UTIL_MATH_MATRIX3X3_H__
+#define UTIL_MATH_MATRIX3X3_H__
+
+template <class VType>
+class Matrix3x3;
+
+typedef Matrix3x3<int> Matrix3x3_i;
+typedef Matrix3x3<float> Matrix3x3_f;
+typedef Matrix3x3<double> Matrix3x3_d;
+
+#endif // UTIL_MATH_MATRIX3X3_H__
diff --git a/src/third_party/s2/util/math/vector2-inl.h b/src/third_party/s2/util/math/vector2-inl.h
new file mode 100755
index 00000000000..6fd7bfc5432
--- /dev/null
+++ b/src/third_party/s2/util/math/vector2-inl.h
@@ -0,0 +1,361 @@
+// Copyright 2003 Google, Inc.
+// All Rights Reserved.
+//
+//
+// A simple class to handle vectors in 2D
+// The aim of this class is to be able to manipulate vectors in 2D
+// as naturally as possible and make calculations readable.
+// For that reason, the operators +, -, * are overloaded.
+// (Reading a = a + b*2 - c is much easier to read than
+// a = Sub(Add(a, Mul(b,2)),c) )
+// The code generated using this vector class is easily optimized by
+// the compiler and does not generate overhead compared to manually
+// writing the operations component by component
+// (e.g a.x = b.x + c.x; a.y = b.y + c.y...)
+//
+// Operator overload is not usually allowed, but in this case an
+// exemption has been granted by the C++ style committee.
+//
+// Please be careful about overflows when using those vectors with integer types
+// The calculations are carried with the same type as the vector's components
+// type. eg : if you are using uint8 as the base type, all values will be modulo
+// 256.
+// This feature is necessary to use the class in a more general framework with
+// VType != plain old data type.
+
+#ifndef UTIL_MATH_VECTOR2_INL_H__
+#define UTIL_MATH_VECTOR2_INL_H__
+
+#include "util/math/vector2.h"
+
+#include <math.h>
+#include "base/basictypes.h"
+#include "base/logging.h"
+#include "base/template_util.h"
+#include "base/type_traits.h"
+#include "util/math/mathutil.h"
+#include "util/math/vector3.h"
+#include "util/math/vector4.h"
+
+template <typename VType>
+Vector2<VType>::Vector2() {
+ Clear();
+}
+template <typename VType>
+Vector2<VType>::Vector2(const VType x, const VType y) {
+ c_[0] = x;
+ c_[1] = y;
+}
+template <typename VType>
+Vector2<VType>::Vector2(const Self &vb) {
+ c_[0] = vb.c_[0];
+ c_[1] = vb.c_[1];
+}
+template <typename VType>
+Vector2<VType>::Vector2(const Vector3<VType> &vb) {
+ c_[0] = vb.x();
+ c_[1] = vb.y();
+}
+template <typename VType>
+Vector2<VType>::Vector2(const Vector4<VType> &vb) {
+ c_[0] = vb.x();
+ c_[1] = vb.y();
+}
+
+template <typename VType> template <typename VType2>
+Vector2<VType> Vector2<VType>::Cast(const Vector2<VType2> &vb) {
+ return Self(static_cast<VType>(vb[0]),
+ static_cast<VType>(vb[1]));
+}
+
+template <typename VType>
+void Vector2<VType>::Set(const VType x, const VType y) {
+ c_[0] = x;
+ c_[1] = y;
+}
+
+template <typename VType>
+const Vector2<VType>& Vector2<VType>::operator=(const Self &vb) {
+ c_[0] = vb.c_[0];
+ c_[1] = vb.c_[1];
+ return (*this);
+}
+
+template <typename VType>
+Vector2<VType>& Vector2<VType>::operator+=(const Self &vb) {
+ c_[0] += vb.c_[0];
+ c_[1] += vb.c_[1];
+ return (*this);
+}
+
+template <typename VType>
+Vector2<VType>& Vector2<VType>::operator-=(const Self &vb) {
+ c_[0] -= vb.c_[0];
+ c_[1] -= vb.c_[1];
+ return (*this);
+}
+
+template <typename VType>
+Vector2<VType>& Vector2<VType>::operator*=(const VType k) {
+ c_[0] *= k;
+ c_[1] *= k;
+ return (*this);
+}
+
+template <typename VType>
+Vector2<VType>& Vector2<VType>::operator/=(const VType k) {
+ c_[0] /= k;
+ c_[1] /= k;
+ return (*this);
+}
+
+template <typename VType>
+Vector2<VType> Vector2<VType>::MulComponents(const Self &vb) const {
+ return Self(c_[0] * vb.c_[0], c_[1] * vb.c_[1]);
+}
+
+template <typename VType>
+Vector2<VType> Vector2<VType>::DivComponents(const Self &vb) const {
+ return Self(c_[0] / vb.c_[0], c_[1] / vb.c_[1]);
+}
+
+template <typename VType>
+Vector2<VType> Vector2<VType>::operator+(const Self &vb) const {
+ return Self(*this) += vb;
+}
+
+template <typename VType>
+Vector2<VType> Vector2<VType>::operator-(const Self &vb) const {
+ return Self(*this) -= vb;
+}
+
+template <typename VType>
+Vector2<VType> Vector2<VType>::operator-() const {
+ return Self(-c_[0], -c_[1]);
+}
+
+template <typename VType>
+VType Vector2<VType>::DotProd(const Self &vb) const {
+ return c_[0] * vb.c_[0] + c_[1] * vb.c_[1];
+}
+
+template <typename VType>
+Vector2<VType> Vector2<VType>::operator*(const VType k) const {
+ return Self(*this) *= k;
+}
+
+template <typename VType>
+Vector2<VType> Vector2<VType>::operator/(const VType k) const {
+ return Self(*this) /= k;
+}
+
+template <typename VType>
+VType Vector2<VType>::CrossProd(const Self &vb) const {
+ return c_[0] * vb.c_[1] - c_[1] * vb.c_[0];
+}
+
+template <typename VType>
+VType& Vector2<VType>::operator[](const int b) {
+ DCHECK(b >= 0);
+ DCHECK(b <= 1);
+ return c_[b];
+}
+
+template <typename VType>
+VType Vector2<VType>::operator[](const int b) const {
+ DCHECK(b >= 0);
+ DCHECK(b <= 1);
+ return c_[b];
+}
+
+template <typename VType>
+void Vector2<VType>::x(const VType &v) {
+ c_[0] = v;
+}
+
+template <typename VType>
+VType Vector2<VType>::x() const {
+ return c_[0];
+}
+
+template <typename VType>
+void Vector2<VType>::y(const VType &v) {
+ c_[1] = v;
+}
+
+template <typename VType>
+VType Vector2<VType>::y() const {
+ return c_[1];
+}
+
+
+
+template <typename VType>
+VType* Vector2<VType>::Data() {
+ return reinterpret_cast<VType*>(c_);
+}
+
+template <typename VType>
+const VType* Vector2<VType>::Data() const {
+ return reinterpret_cast<const VType*>(c_);
+}
+
+
+template <typename VType>
+VType Vector2<VType>::Norm2(void) const {
+ return c_[0]*c_[0] + c_[1]*c_[1];
+}
+
+
+template <typename VType>
+typename Vector2<VType>::FloatType Vector2<VType>::Norm(void) const {
+ return sqrt(Norm2());
+}
+
+template <typename VType>
+typename Vector2<VType>::FloatType Vector2<VType>::Angle(const Self &v) const {
+ return atan2(this->CrossProd(v), this->DotProd(v));
+}
+
+template <typename VType>
+Vector2<VType> Vector2<VType>::Normalize() const {
+ COMPILE_ASSERT(!base::is_integral<VType>::value, must_be_floating_point);
+ VType n = Norm();
+ if (n != 0) {
+ n = 1.0 / n;
+ }
+ return Self(*this) *= n;
+}
+
+template <typename VType>
+bool Vector2<VType>::operator==(const Self &vb) const {
+ return (c_[0] == vb.c_[0]) && (c_[1] == vb.c_[1]);
+}
+
+template <typename VType>
+bool Vector2<VType>::operator!=(const Self &vb) const {
+ return (c_[0] != vb.c_[0]) || (c_[1] != vb.c_[1]);
+}
+
+template <typename VType>
+bool Vector2<VType>::aequal(const Self &vb, FloatType margin) const {
+ return (fabs(c_[0]-vb.c_[0]) < margin) && (fabs(c_[1]-vb.c_[1]) < margin);
+}
+
+template <typename VType>
+bool Vector2<VType>::operator<(const Self &vb) const {
+ if ( c_[0] < vb.c_[0] ) return true;
+ if ( vb.c_[0] < c_[0] ) return false;
+ if ( c_[1] < vb.c_[1] ) return true;
+ return false;
+}
+
+template <typename VType>
+bool Vector2<VType>::operator>(const Self &vb) const {
+ return vb.operator<(*this);
+}
+
+template <typename VType>
+bool Vector2<VType>::operator<=(const Self &vb) const {
+ return !operator>(vb);
+}
+
+template <typename VType>
+bool Vector2<VType>::operator>=(const Self &vb) const {
+ return !operator<(vb);
+}
+
+template <typename VType>
+Vector2<VType> Vector2<VType>::Ortho() const {
+ return Self(-c_[1], c_[0]);
+}
+
+template <typename VType>
+Vector2<VType> Vector2<VType>::Sqrt() const {
+ return Self(sqrt(c_[0]), sqrt(c_[1]));
+}
+
+template <typename VType>
+Vector2<VType> Vector2<VType>::Fabs() const {
+ return Self(fabs(c_[0]), fabs(c_[1]));
+}
+
+template <typename VType>
+Vector2<VType> Vector2<VType>::Abs() const {
+ COMPILE_ASSERT(base::is_integral<VType>::value, use_Fabs_for_float_types);
+ COMPILE_ASSERT(static_cast<VType>(-1) == -1, type_must_be_signed);
+ COMPILE_ASSERT(sizeof(VType) <= sizeof(int), Abs_truncates_to_int);
+ return Self(abs(c_[0]), abs(c_[1]));
+}
+
+template <typename VType>
+Vector2<VType> Vector2<VType>::Floor() const {
+ return Self(floor(c_[0]), floor(c_[1]));
+}
+
+
+template <typename VType>
+Vector2<VType> Vector2<VType>::Ceil() const {
+ return Self(ceil(c_[0]), ceil(c_[1]));
+}
+
+
+template <typename VType>
+Vector2<VType> Vector2<VType>::FRound() const {
+ return Self(rint(c_[0]), rint(c_[1]));
+}
+
+template <typename VType>
+Vector2<int> Vector2<VType>::IRound() const {
+ return Vector2<int>(lrint(c_[0]), lrint(c_[1]));
+}
+
+template <typename VType>
+void Vector2<VType>::Clear() {
+ c_[1] = c_[0] = VType();
+}
+
+template <typename VType>
+bool Vector2<VType>::IsNaN() const {
+ return isnan(c_[0]) || isnan(c_[1]);
+}
+
+template <typename VType>
+Vector2<VType> Vector2<VType>::NaN() {
+ return Self(MathUtil::NaN(), MathUtil::NaN());
+}
+
+template <typename ScalarType, typename VType2>
+Vector2<VType2> operator*(const ScalarType k, const Vector2<VType2> v) {
+ return Vector2<VType2>( k * v[0], k * v[1]);
+}
+
+template <typename ScalarType, typename VType2>
+Vector2<VType2> operator/(const ScalarType k, const Vector2<VType2> v) {
+ return Vector2<VType2>(k / v[0], k / v[1]);
+}
+
+template <typename VType>
+Vector2<VType> Max(const Vector2<VType> &v1, const Vector2<VType> &v2) {
+ return Vector2<VType>(max(v1[0], v2[0]), max(v1[1], v2[1]));
+}
+
+template <typename VType>
+Vector2<VType> Min(const Vector2<VType> &v1, const Vector2<VType> &v2) {
+ return Vector2<VType>(min(v1[0], v2[0]), min(v1[1], v2[1]));
+}
+
+template <typename VType>
+std::ostream &operator <<(std::ostream &out, const Vector2<VType> &va) {
+ out << "["
+ << va[0] << ", "
+ << va[1] << "]";
+ return out;
+}
+
+// TODO(user): Vector2<T> does not actually satisfy the definition of a POD
+// type even when T is a POD. Pretending that Vector2<T> is a POD probably
+// won't cause any immediate problems, but eventually this should be fixed.
+PROPAGATE_POD_FROM_TEMPLATE_ARGUMENT(Vector2);
+
+#endif // UTIL_MATH_VECTOR2_INL_H__
diff --git a/src/third_party/s2/util/math/vector2.h b/src/third_party/s2/util/math/vector2.h
new file mode 100755
index 00000000000..f3f6d0e26df
--- /dev/null
+++ b/src/third_party/s2/util/math/vector2.h
@@ -0,0 +1,189 @@
+// Copyright 2003 Google, Inc.
+// All Rights Reserved.
+//
+//
+// A simple class to handle vectors in 2D
+// See the vector2-inl.h file for more details
+
+
+#ifndef UTIL_MATH_VECTOR2_H__
+#define UTIL_MATH_VECTOR2_H__
+
+#include <iostream>
+using std::ostream;
+using std::cout;
+using std::endl;
+ // NOLINT(readability/streams)
+#include "base/basictypes.h"
+
+template <typename VType> class Vector2;
+
+// TODO(user): Look into creating conversion operators to remove the
+// need to forward-declare Vector3 and Vector4.
+template <typename VType> class Vector3;
+template <typename VType> class Vector4;
+
+// Template class for 2D vectors.
+// All definitions for these functions are in vector2-inl.h. That header will
+// need to be included in order to actually use this class. This class can be
+// regarded to only forward-declare Vector2.
+template <typename VType>
+class Vector2 {
+ private:
+ VType c_[2];
+
+ // FloatType is the type returned by Norm() and Angle(). These methods are
+ // special because they return floating-point values even when VType is an
+ // integer.
+ typedef typename base::if_<base::is_integral<VType>::value,
+ double, VType>::type FloatType;
+
+ public:
+ typedef Vector2<VType> Self;
+ typedef VType BaseType;
+ // Create a new vector (0,0)
+ Vector2();
+ // Create a new vector (x,y)
+ Vector2(const VType x, const VType y);
+ // Create a new copy of the vector vb
+ Vector2(const Self &vb); // NOLINT(runtime/explicit)
+ // Keep only the two first coordinates of the vector vb
+ explicit Vector2(const Vector3<VType> &vb);
+ // Keep only the two first coordinates of the vector vb
+ explicit Vector2(const Vector4<VType> &vb);
+ // Convert from another vector type
+ template <typename VType2>
+ static Self Cast(const Vector2<VType2> &vb);
+ // Return the size of the vector
+ static int Size() { return 2; }
+ // Modify the coordinates of the current vector
+ void Set(const VType x, const VType y);
+ const Self& operator=(const Self &vb);
+ // Add two vectors, component by component
+ Self& operator+=(const Self &vb);
+ // Subtract two vectors, component by component
+ Self& operator-=(const Self &vb);
+ // Multiply a vector by a scalar
+ Self& operator*=(const VType k);
+ // Divide a vector by a scalar
+ Self& operator/=(const VType k);
+ // Multiply two vectors component by component
+ Self MulComponents(const Self &vb) const;
+ // Divide two vectors component by component
+ Self DivComponents(const Self &vb) const;
+ // Add two vectors, component by component
+ Self operator+(const Self &vb) const;
+ // Subtract two vectors, component by component
+ Self operator-(const Self &vb) const;
+ // Change the sign of the components of a vector
+ Self operator-() const;
+ // Dot product. Be aware that if VType is an integer type, the high bits of
+ // the result are silently discarded.
+ VType DotProd(const Self &vb) const;
+ // Multiplication by a scalar
+ Self operator*(const VType k) const;
+ // Division by a scalar
+ Self operator/(const VType k) const;
+ // Cross product. Be aware that if VType is an integer type, the high bits
+ // of the result are silently discarded.
+ VType CrossProd(const Self &vb) const;
+ // Access component #b for read/write operations
+ VType& operator[](const int b);
+ // Access component #b for read only operations
+ VType operator[](const int b) const;
+ // Labeled Accessor methods.
+ void x(const VType &v);
+ VType x() const;
+ void y(const VType &v);
+ VType y() const;
+
+ // return a pointer to the data array for interface with other libraries
+ // like opencv
+ VType* Data();
+ const VType* Data() const;
+ // Return the squared Euclidean norm of the vector. Be aware that if VType
+ // is an integer type, the high bits of the result are silently discarded.
+ VType Norm2(void) const;
+ // Return the Euclidean norm of the vector. Note that if VType is an
+ // integer type, the return value is correct only if the *squared* norm does
+ // not overflow VType.
+ FloatType Norm(void) const;
+ // return the angle between "this" and v in radians
+ FloatType Angle(const Self &v) const;
+ // Return a normalized version of the vector if the norm of the
+ // vector is not 0. Not to be used with integer types.
+ Self Normalize() const;
+ // Compare two vectors, return true if all their components are equal
+ // this operator is mostly useful for integer types
+ // for floating point types prefer "aequal"
+ bool operator==(const Self &vb) const;
+ bool operator!=(const Self &vb) const;
+ // Compare two vectors, return true if all their components are within
+ // a difference of margin.
+ bool aequal(const Self &vb, FloatType margin) const;
+
+ // Compare two vectors, these comparisons are mostly for interaction
+ // with STL.
+ bool operator<(const Self &vb) const;
+ bool operator>(const Self &vb) const;
+ bool operator<=(const Self &vb) const;
+ bool operator>=(const Self &vb) const;
+
+ // return a vector orthogonal to the current one
+ // with the same norm and counterclockwise to it
+ Self Ortho() const;
+ // take the sqrt of each component and return a vector containing those values
+ Self Sqrt() const;
+ // Take the fabs of each component and return a vector containing
+ // those values.
+ Self Fabs() const;
+ // Take the absolute value of each component and return a vector containing
+ // those values. This method should only be used when VType is a signed
+ // integer type that is not wider than "int".
+ Self Abs() const;
+ // take the floor of each component and return a vector containing
+ // those values
+ Self Floor() const;
+ // Take the ceil of each component and return a vector containing
+ // those values.
+ Self Ceil() const;
+ // take the round of each component and return a vector containing those
+ // values
+ Self FRound() const;
+ // take the round of each component and return an integer vector containing
+ // those values
+ Vector2<int> IRound() const;
+ // Reset all the coordinates of the vector to 0
+ void Clear();
+
+ // return true if one of the components is not a number
+ bool IsNaN() const;
+
+ // return an invalid floating point vector
+ static Self NaN();
+};
+
+// Multiply by a scalar.
+template <typename ScalarType, typename VType>
+Vector2<VType> operator*(const ScalarType k, const Vector2<VType> v);
+// perform k /
+template <typename ScalarType, typename VType>
+Vector2<VType> operator/(const ScalarType k, const Vector2<VType> v);
+// return a vector containing the max of v1 and v2 component by component
+template <typename VType2>
+Vector2<VType2> Max(const Vector2<VType2> &v1, const Vector2<VType2> &v2);
+// return a vector containing the min of v1 and v2 component by component
+template <typename VType2>
+Vector2<VType2> Min(const Vector2<VType2> &v1, const Vector2<VType2> &v2);
+// debug printing
+template <typename VType2>
+std::ostream &operator <<(std::ostream &out, // NOLINT
+ const Vector2<VType2> &va);
+
+// TODO(user): Declare extern templates for these types.
+typedef Vector2<uint8> Vector2_b;
+typedef Vector2<int> Vector2_i;
+typedef Vector2<float> Vector2_f;
+typedef Vector2<double> Vector2_d;
+
+#endif // UTIL_MATH_VECTOR2_H__
diff --git a/src/third_party/s2/util/math/vector3-inl.h b/src/third_party/s2/util/math/vector3-inl.h
new file mode 100755
index 00000000000..bf26f274b0b
--- /dev/null
+++ b/src/third_party/s2/util/math/vector3-inl.h
@@ -0,0 +1,428 @@
+// Copyright 2003 Google, Inc.
+// All Rights Reserved.
+//
+//
+// A simple class to handle vectors in 3D
+// The aim of this class is to be able to manipulate vectors in 3D
+// as naturally as possible and make calculations readable.
+// For that reason, the operators +, -, * are overloaded.
+// (Reading a = a + b*2 - c is much easier to read than
+// a = Sub(Add(a, Mul(b,2)),c) )
+// The code generated using this vector class is easily optimized by
+// the compiler and does not generate overhead compared to manually
+// writing the operations component by component
+// (e.g a.x = b.x + c.x; a.y = b.y + c.y...)
+//
+// Operator overload is not usually allowed, but in this case an
+// exemption has been granted by the C++ style committee.
+//
+// Please be careful about overflows when using those vectors with integer types
+// The calculations are carried with the same type as the vector's components
+// type. eg : if you are using uint8 as the base type, all values will be modulo
+// 256.
+// This feature is necessary to use the class in a more general framework with
+// VType != plain old data type.
+
+#ifndef UTIL_MATH_VECTOR3_INL_H__
+#define UTIL_MATH_VECTOR3_INL_H__
+
+#include "util/math/vector3.h"
+
+#include <algorithm>
+using std::min;
+using std::max;
+using std::swap;
+using std::reverse;
+
+#include <math.h>
+#include "base/basictypes.h"
+#include "base/logging.h"
+#include "base/template_util.h"
+#include "base/type_traits.h"
+#include "util/math/mathutil.h"
+#include "util/math/vector2.h"
+#include "util/math/vector4.h"
+
+template <typename VType>
+Vector3<VType>::Vector3() {
+ Clear();
+}
+
+template <typename VType>
+Vector3<VType>::Vector3(const VType x, const VType y, const VType z) {
+ c_[0] = x;
+ c_[1] = y;
+ c_[2] = z;
+}
+
+template <typename VType>
+Vector3<VType>::Vector3(const Vector2<VType> &vb, VType z) {
+ c_[0] = vb.x();
+ c_[1] = vb.y();
+ c_[2] = z;
+}
+
+template <typename VType>
+Vector3<VType>::Vector3(const Self &vb) {
+ c_[0] = vb.c_[0];
+ c_[1] = vb.c_[1];
+ c_[2] = vb.c_[2];
+}
+
+template <typename VType>
+Vector3<VType>::Vector3(const Vector4<VType> &vb) {
+ c_[0] = vb.x();
+ c_[1] = vb.y();
+ c_[2] = vb.z();
+}
+
+template <typename VType> template <typename VType2>
+Vector3<VType> Vector3<VType>::Cast(const Vector3<VType2> &vb) {
+ return Self(VType(vb[0]),
+ VType(vb[1]),
+ VType(vb[2]));
+}
+
+template <typename VType>
+bool Vector3<VType>::operator==(const Self& vb) const {
+ return (c_[0] == vb.c_[0]) && (c_[1] == vb.c_[1]) && (c_[2] == vb.c_[2]);
+}
+
+template <typename VType>
+bool Vector3<VType>::operator!=(const Self& vb) const {
+ return (c_[0] != vb.c_[0]) || (c_[1] != vb.c_[1]) || (c_[2] != vb.c_[2]);
+}
+
+template <typename VType>
+bool Vector3<VType>::aequal(const Self &vb, FloatType margin) const {
+ return (fabs(c_[0] - vb.c_[0]) < margin)
+ && (fabs(c_[1] - vb.c_[1]) < margin)
+ && (fabs(c_[2] - vb.c_[2]) < margin);
+}
+
+template <typename VType>
+bool Vector3<VType>::operator<(const Self &vb) const {
+ if ( c_[0] < vb.c_[0] ) return true;
+ if ( vb.c_[0] < c_[0] ) return false;
+ if ( c_[1] < vb.c_[1] ) return true;
+ if ( vb.c_[1] < c_[1] ) return false;
+ if ( c_[2] < vb.c_[2] ) return true;
+ return false;
+}
+
+template <typename VType>
+bool Vector3<VType>::operator>(const Self &vb) const {
+ return vb.operator<(*this);
+}
+
+template <typename VType>
+bool Vector3<VType>::operator<=(const Self &vb) const {
+ return !operator>(vb);
+}
+
+template <typename VType>
+bool Vector3<VType>::operator>=(const Self &vb) const {
+ return !operator<(vb);
+}
+
+template <typename VType>
+void Vector3<VType>::Set(const VType x, const VType y, const VType z) {
+ c_[0] = x;
+ c_[1] = y;
+ c_[2] = z;
+}
+
+template <typename VType>
+Vector3<VType>& Vector3<VType>::operator=(const Self& vb) {
+ c_[0] = vb.c_[0];
+ c_[1] = vb.c_[1];
+ c_[2] = vb.c_[2];
+ return (*this);
+}
+
+template <typename VType>
+Vector3<VType>& Vector3<VType>::operator+=(const Self &vb) {
+ c_[0] += vb.c_[0];
+ c_[1] += vb.c_[1];
+ c_[2] += vb.c_[2];
+ return (*this);
+}
+
+template <typename VType>
+Vector3<VType>& Vector3<VType>::operator-=(const Self &vb) {
+ c_[0] -= vb.c_[0];
+ c_[1] -= vb.c_[1];
+ c_[2] -= vb.c_[2];
+ return (*this);
+}
+
+template <typename VType>
+Vector3<VType>& Vector3<VType>::operator*=(const VType k) {
+ c_[0] *= k;
+ c_[1] *= k;
+ c_[2] *= k;
+ return (*this);
+}
+
+template <typename VType>
+Vector3<VType>& Vector3<VType>::operator/=(const VType k) {
+ c_[0] /= k;
+ c_[1] /= k;
+ c_[2] /= k;
+ return (*this);
+}
+
+template <typename VType>
+Vector3<VType> Vector3<VType>::MulComponents(const Self &vb) const {
+ return Self(c_[0] * vb.c_[0], c_[1] * vb.c_[1], c_[2] * vb.c_[2]);
+}
+
+template <typename VType>
+Vector3<VType> Vector3<VType>::DivComponents(const Self &vb) const {
+ return Self(c_[0] / vb.c_[0], c_[1] / vb.c_[1], c_[2] / vb.c_[2]);
+}
+
+template <typename VType>
+Vector3<VType> Vector3<VType>::operator+(const Self &vb) const {
+ return Self(*this) += vb;
+}
+
+template <typename VType>
+Vector3<VType> Vector3<VType>::operator-(const Self &vb) const {
+ return Self(*this) -= vb;
+}
+
+template <typename VType>
+VType Vector3<VType>::DotProd(const Self &vb) const {
+ return c_[0]*vb.c_[0] + c_[1]*vb.c_[1] + c_[2]*vb.c_[2];
+}
+
+template <typename VType>
+Vector3<VType> Vector3<VType>::operator*(const VType k) const {
+ return Self(*this) *= k;
+}
+
+template <typename VType>
+Vector3<VType> Vector3<VType>::operator/(const VType k) const {
+ return Self(*this) /= k;
+}
+
+template <typename VType>
+Vector3<VType> Vector3<VType>::CrossProd(const Self& vb) const {
+ return Self( c_[1] * vb.c_[2] - c_[2] * vb.c_[1],
+ c_[2] * vb.c_[0] - c_[0] * vb.c_[2],
+ c_[0] * vb.c_[1] - c_[1] * vb.c_[0]);
+}
+
+template <typename VType>
+VType& Vector3<VType>::operator[](const int b) {
+ DCHECK(b >=0);
+ DCHECK(b <=2);
+ return c_[b];
+}
+
+template <typename VType>
+VType Vector3<VType>::operator[](const int b) const {
+ DCHECK(b >=0);
+ DCHECK(b <=2);
+ return c_[b];
+}
+
+template <typename VType>
+void Vector3<VType>::x(const VType &v) {
+ c_[0] = v;
+}
+
+template <typename VType>
+VType Vector3<VType>::x() const {
+ return c_[0];
+}
+
+template <typename VType>
+void Vector3<VType>::y(const VType &v) {
+ c_[1] = v;
+}
+
+template <typename VType>
+VType Vector3<VType>::y() const {
+ return c_[1];
+}
+
+template <typename VType>
+void Vector3<VType>::z(const VType &v) {
+ c_[2] = v;
+}
+
+template <typename VType>
+VType Vector3<VType>::z() const {
+ return c_[2];
+}
+
+template <typename VType>
+VType* Vector3<VType>::Data() {
+ return reinterpret_cast<VType*>(c_);
+}
+
+template <typename VType>
+const VType* Vector3<VType>::Data() const {
+ return reinterpret_cast<const VType*>(c_);
+}
+
+template <typename VType>
+VType Vector3<VType>::Norm2(void) const {
+ return c_[0]*c_[0] + c_[1]*c_[1] + c_[2]*c_[2];
+}
+
+template <typename VType>
+typename Vector3<VType>::FloatType Vector3<VType>::Norm(void) const {
+ return sqrt(Norm2());
+}
+
+template <typename VType>
+Vector3<VType> Vector3<VType>::Normalize() const {
+ COMPILE_ASSERT(!base::is_integral<VType>::value, must_be_floating_point);
+ VType n = Norm();
+ if (n != 0) {
+ n = 1.0 / n;
+ }
+ return Self(*this) *= n;
+}
+
+template <typename VType>
+Vector3<VType> Vector3<VType>::Ortho() const {
+ int k = LargestAbsComponent() - 1;
+ if (k < 0) k = 2;
+ Self temp;
+ temp[k] = 1;
+ return (this->CrossProd(temp)).Normalize();
+}
+
+template <typename VType>
+int Vector3<VType>::LargestAbsComponent() const {
+ Self temp = Fabs();
+ if (temp[0] > temp[1]) {
+ if (temp[0] > temp[2]) {
+ return 0;
+ } else {
+ return 2;
+ }
+ } else {
+ if (temp[1] > temp[2]) {
+ return 1;
+ } else {
+ return 2;
+ }
+ }
+}
+
+template <typename VType>
+Vector3<int> Vector3<VType>::ComponentOrder() const {
+ Vector3<int> temp(0, 1, 2);
+ if (c_[temp[0]] > c_[temp[1]]) swap(temp[0], temp[1]);
+ if (c_[temp[1]] > c_[temp[2]]) swap(temp[1], temp[2]);
+ if (c_[temp[0]] > c_[temp[1]]) swap(temp[0], temp[1]);
+ return temp;
+}
+
+template <typename VType>
+typename Vector3<VType>::FloatType Vector3<VType>::Angle(const Self &va) const {
+ return atan2(this->CrossProd(va).Norm(), this->DotProd(va));
+}
+
+template <typename VType>
+Vector3<VType> Vector3<VType>::Sqrt() const {
+ return Self(sqrt(c_[0]), sqrt(c_[1]), sqrt(c_[2]));
+}
+
+template <typename VType>
+Vector3<VType> Vector3<VType>::Fabs() const {
+ return Self(fabs(c_[0]), fabs(c_[1]), fabs(c_[2]));
+}
+
+template <typename VType>
+Vector3<VType> Vector3<VType>::Abs() const {
+ COMPILE_ASSERT(base::is_integral<VType>::value, use_Fabs_for_float_types);
+ COMPILE_ASSERT(static_cast<VType>(-1) == -1, type_must_be_signed);
+ COMPILE_ASSERT(sizeof(VType) <= sizeof(int), Abs_truncates_to_int);
+ return Self(abs(c_[0]), abs(c_[1]), abs(c_[2]));
+}
+
+template <typename VType>
+Vector3<VType> Vector3<VType>::Floor() const {
+ return Self(floor(c_[0]), floor(c_[1]), floor(c_[2]));
+}
+
+template <typename VType>
+Vector3<VType> Vector3<VType>::Ceil() const {
+ return Self(ceil(c_[0]), ceil(c_[1]), ceil(c_[2]));
+}
+
+template <typename VType>
+Vector3<VType> Vector3<VType>::FRound() const {
+ return Self(rint(c_[0]), rint(c_[1]), rint(c_[2]));
+}
+
+template <typename VType>
+Vector3<int> Vector3<VType>::IRound() const {
+ return Vector3<int>(lrint(c_[0]), lrint(c_[1]), lrint(c_[2]));
+}
+
+template <typename VType>
+void Vector3<VType>::Clear() {
+ c_[2] = c_[1] = c_[0] = VType();
+}
+
+template <typename VType>
+bool Vector3<VType>::IsNaN() const {
+ return isnan(c_[0]) || isnan(c_[1]) || isnan(c_[2]);
+}
+
+template <typename VType>
+Vector3<VType> Vector3<VType>::NaN() {
+ return Self(MathUtil::NaN(), MathUtil::NaN(), MathUtil::NaN());
+}
+
+template <typename VType>
+Vector3<VType> operator-(const Vector3<VType> &vb) {
+ return Vector3<VType>(-vb[0], -vb[1], -vb[2]);
+}
+
+template <typename ScalarType, typename VType>
+Vector3<VType> operator*(const ScalarType k, const Vector3<VType> &v) {
+ return Vector3<VType>(k*v[0], k*v[1], k*v[2]);
+}
+
+template <typename ScalarType, typename VType>
+Vector3<VType> operator/(const ScalarType k, const Vector3<VType> &v) {
+ return Vector3<VType>(k/v[0], k/v[1], k/v[2]);
+}
+
+template <typename VType>
+Vector3<VType> Max(const Vector3<VType> &v1, const Vector3<VType> &v2) {
+ return Vector3<VType>(max(v1[0], v2[0]),
+ max(v1[1], v2[1]),
+ max(v1[2], v2[2]));
+}
+
+template <typename VType>
+Vector3<VType> Min(const Vector3<VType> &v1, const Vector3<VType> &v2) {
+ return Vector3<VType>(min(v1[0], v2[0]),
+ min(v1[1], v2[1]),
+ min(v1[2], v2[2]));
+}
+
+template <typename VType>
+std::ostream &operator <<(std::ostream &out, const Vector3<VType> &va) {
+ out << "["
+ << va[0] << ", "
+ << va[1] << ", "
+ << va[2] << "]";
+ return out;
+}
+
+// TODO(user): Vector3<T> does not actually satisfy the definition of a POD
+// type even when T is a POD. Pretending that Vector3<T> is a POD probably
+// won't cause any immediate problems, but eventually this should be fixed.
+PROPAGATE_POD_FROM_TEMPLATE_ARGUMENT(Vector3);
+
+#endif // UTIL_MATH_VECTOR3_INL_H__
diff --git a/src/third_party/s2/util/math/vector3.h b/src/third_party/s2/util/math/vector3.h
new file mode 100755
index 00000000000..813cc87254e
--- /dev/null
+++ b/src/third_party/s2/util/math/vector3.h
@@ -0,0 +1,189 @@
+// Copyright 2003 Google, Inc.
+// All Rights Reserved.
+//
+//
+// A simple class to handle vectors in 3D
+// See the vector3-inl.h file for more details
+
+
+#ifndef UTIL_MATH_VECTOR3_H__
+#define UTIL_MATH_VECTOR3_H__
+
+#include <iostream>
+using std::ostream;
+using std::cout;
+using std::endl;
+ // NOLINT(readability/streams)
+#include "base/basictypes.h"
+
+template <typename VType> class Vector3;
+// TODO(user): Look into creating conversion operators to remove the
+// need to forward-declare Vector2 and Vector4.
+template <typename VType> class Vector2;
+template <typename VType> class Vector4;
+
+// Template class for 3D vectors.
+// All definitions for these functions are in vector3-inl.h. That header will
+// need to be included in order to actually use this class. This class can be
+// regarded to only forward-declare Vector3.
+template <typename VType>
+class Vector3 {
+ private:
+ VType c_[3];
+
+ // FloatType is the type returned by Norm() and Angle(). These methods are
+ // special because they return floating-point values even when VType is an
+ // integer.
+ typedef typename base::if_<base::is_integral<VType>::value,
+ double, VType>::type FloatType;
+
+ public:
+ typedef Vector3<VType> Self;
+ typedef VType BaseType;
+ // Create a new vector (0,0,0)
+ Vector3();
+ // Create a new vector (x,y,z)
+ Vector3(const VType x, const VType y, const VType z);
+ // Create a new 3D vector using the two first coordinates of a 2D vectors
+ // and an additional z argument.
+ explicit Vector3(const Vector2<VType> &vb, VType z);
+ // Create a new copy of the vector vb
+ Vector3(const Self &vb);
+ // Keep only the three first coordinates of the 4D vector vb
+ explicit Vector3(const Vector4<VType> &vb);
+ // Convert from another vector type
+ template <typename VType2>
+ static Self Cast(const Vector3<VType2> &vb);
+ // Compare two vectors, return true if all their components are equal
+ bool operator==(const Self& vb) const;
+ bool operator!=(const Self& vb) const;
+ // Compare two vectors, return true if all their components are within
+ // a difference of margin.
+ bool aequal(const Self &vb, FloatType margin) const;
+ // Compare two vectors, these comparisons are mostly for interaction
+ // with STL.
+ bool operator<(const Self &vb) const;
+ bool operator>(const Self &vb) const;
+ bool operator<=(const Self &vb) const;
+ bool operator>=(const Self &vb) const;
+
+ // Return the size of the vector
+ static int Size() { return 3; }
+ // Modify the coordinates of the current vector
+ void Set(const VType x, const VType y, const VType z);
+ Self& operator=(const Self& vb);
+ // Add two vectors, component by component
+ Self& operator+=(const Self &vb);
+ // Subtract two vectors, component by component
+ Self& operator-=(const Self &vb);
+ // Multiply a vector by a scalar
+ Self& operator*=(const VType k);
+ // Divide a vector by a scalar
+ Self& operator/=(const VType k);
+ // Multiply two vectors component by component
+ Self MulComponents(const Self &vb) const;
+ // Divide two vectors component by component
+ Self DivComponents(const Self &vb) const;
+ // Add two vectors, component by component
+ Self operator+(const Self &vb) const;
+ // Subtract two vectors, component by component
+ Self operator-(const Self &vb) const;
+ // Dot product. Be aware that if VType is an integer type, the high bits of
+ // the result are silently discarded.
+ VType DotProd(const Self &vb) const;
+ // Multiplication by a scalar
+ Self operator*(const VType k) const;
+ // Divide by a scalar
+ Self operator/(const VType k) const;
+ // Cross product. Be aware that if VType is an integer type, the high bits
+ // of the result are silently discarded.
+ Self CrossProd(const Self& vb) const;
+ // Access component #b for read/write operations
+ VType& operator[](const int b);
+ // Access component #b for read only operations
+ VType operator[](const int b) const;
+ // Labeled Accessor methods.
+ void x(const VType &v);
+ VType x() const;
+ void y(const VType &v);
+ VType y() const;
+ void z(const VType &v);
+ VType z() const;
+ // return a pointer to the data array for interface with other libraries
+ // like opencv
+ VType* Data();
+ const VType* Data() const;
+ // Return the squared Euclidean norm of the vector. Be aware that if VType
+ // is an integer type, the high bits of the result are silently discarded.
+ VType Norm2(void) const;
+ // Return the Euclidean norm of the vector. Note that if VType is an
+ // integer type, the return value is correct only if the *squared* norm does
+ // not overflow VType.
+ FloatType Norm(void) const;
+ // Return a normalized version of the vector if the norm of the
+ // vector is not 0. Not to be used with integer types.
+ Self Normalize() const;
+ // return a vector orthogonal to this one
+ Self Ortho() const;
+ // return the index of the largest component (fabs)
+ int LargestAbsComponent() const;
+ // return the index of the smallest, median ,largest component of the vector
+ Vector3<int> ComponentOrder() const;
+ // return the angle between two vectors in radians
+ FloatType Angle(const Self &va) const;
+ // take the sqrt of each component and return a vector containing those values
+ Self Sqrt() const;
+ // take the fabs of each component and return a vector containing those values
+ Self Fabs() const;
+ // Take the absolute value of each component and return a vector containing
+ // those values. This method should only be used when VType is a signed
+ // integer type that is not wider than "int".
+ Self Abs() const;
+ // take the floor of each component and return a vector containing
+ // those values
+ Self Floor() const;
+ // take the ceil of each component and return a vector containing those values
+ Self Ceil() const;
+ // take the round of each component and return a vector containing those
+ // values
+ Self FRound() const;
+ // take the round of each component and return an integer vector containing
+ // those values
+ Vector3<int> IRound() const;
+ // Reset all the coordinates of the vector to 0
+ void Clear();
+
+ // return true if one of the components is not a number
+ bool IsNaN() const;
+
+ // return an invalid floating point vector
+ static Self NaN();
+};
+
+// Change the sign of the components of a vector
+template <typename VType>
+Vector3<VType> operator-(const Vector3<VType> &vb);
+// multiply by a scalar
+template <typename ScalarType, typename VType>
+Vector3<VType> operator*(const ScalarType k, const Vector3<VType> &v);
+// perform k /
+template <typename ScalarType, typename VType>
+Vector3<VType> operator/(const ScalarType k, const Vector3<VType> &v);
+// return a vector containing the max of v1 and v2 component by component
+template <typename VType>
+Vector3<VType> Max(const Vector3<VType> &v1, const Vector3<VType> &v2);
+// return a vector containing the min of v1 and v2 component by component
+template <typename VType>
+Vector3<VType> Min(const Vector3<VType> &v1, const Vector3<VType> &v2);
+// debug printing
+template <typename VType>
+std::ostream &operator <<(std::ostream &out, // NOLINT
+ const Vector3<VType> &va);
+
+// TODO(user): Declare extern templates for these types.
+typedef Vector3<uint8> Vector3_b;
+typedef Vector3<int> Vector3_i;
+typedef Vector3<float> Vector3_f;
+typedef Vector3<double> Vector3_d;
+
+#endif // UTIL_MATH_VECTOR3_H__
diff --git a/src/third_party/s2/util/math/vector4-inl.h b/src/third_party/s2/util/math/vector4-inl.h
new file mode 100755
index 00000000000..71946a315da
--- /dev/null
+++ b/src/third_party/s2/util/math/vector4-inl.h
@@ -0,0 +1,432 @@
+// Copyright 2003 Google, Inc.
+// All Rights Reserved.
+//
+//
+// A simple class to handle vectors in 4D
+// The aim of this class is to be able to manipulate vectors in 4D
+// as naturally as possible and make calculations readable.
+// For that reason, the operators +, -, * are overloaded.
+// (Reading a = a + b*2 - c is much easier to read than
+// a = Sub(Add(a, Mul(b,2)),c) )
+// The code generated using this vector class is easily optimized by
+// the compiler and does not generate overhead compared to manually
+// writing the operations component by component
+// (e.g a.x = b.x + c.x; a.y = b.y + c.y...)
+//
+// Operator overload is not usually allowed, but in this case an
+// exemption has been granted by the C++ style committee.
+//
+// Please be careful about overflows when using those vectors with integer types
+// The calculations are carried with the same type as the vector's components
+// type. eg : if you are using uint8 as the base type, all values will be modulo
+// 256.
+// This feature is necessary to use the class in a more general framework with
+// VType != plain old data type.
+
+#ifndef UTIL_MATH_VECTOR4_INL_H__
+#define UTIL_MATH_VECTOR4_INL_H__
+
+#include "util/math/vector4.h"
+
+#include <algorithm>
+using std::min;
+using std::max;
+using std::swap;
+using std::reverse;
+
+#include <math.h>
+#include "base/basictypes.h"
+#include "base/logging.h"
+#include "base/template_util.h"
+#include "base/type_traits.h"
+#include "util/math/mathutil.h"
+#include "util/math/vector2.h"
+#include "util/math/vector3.h"
+
+template <typename VType>
+Vector4<VType>::Vector4() {
+ Clear();
+}
+
+template <typename VType>
+Vector4<VType>::Vector4(const VType x, const VType y, const VType z,
+ const VType w) {
+ c_[0] = x;
+ c_[1] = y;
+ c_[2] = z;
+ c_[3] = w;
+}
+
+template <typename VType>
+Vector4<VType>::Vector4(const Self &vb) {
+ c_[0] = vb.c_[0];
+ c_[1] = vb.c_[1];
+ c_[2] = vb.c_[2];
+ c_[3] = vb.c_[3];
+}
+
+template <typename VType>
+Vector4<VType>::Vector4(const Vector2<VType> &vb, const VType z,
+ const VType w) {
+ c_[0] = vb.x();
+ c_[1] = vb.y();
+ c_[2] = z;
+ c_[3] = w;
+}
+
+template <typename VType>
+Vector4<VType>::Vector4(const Vector2<VType> &vb1, const Vector2<VType> &vb2) {
+ c_[0] = vb1.x();
+ c_[1] = vb1.y();
+ c_[2] = vb2.x();
+ c_[3] = vb2.y();
+}
+
+template <typename VType>
+Vector4<VType>::Vector4(const Vector3<VType> &vb, const VType w) {
+ c_[0] = vb.x();
+ c_[1] = vb.y();
+ c_[2] = vb.z();
+ c_[3] = w;
+}
+
+template <typename VType> template <typename VType2>
+Vector4<VType> Vector4<VType>::Cast(const Vector4<VType2> &vb) {
+ return Self(static_cast<VType>(vb[0]),
+ static_cast<VType>(vb[1]),
+ static_cast<VType>(vb[2]),
+ static_cast<VType>(vb[3]));
+}
+
+template <typename VType>
+bool Vector4<VType>::operator==(const Self& vb) const {
+ return (c_[0] == vb.c_[0])
+ && (c_[1] == vb.c_[1])
+ && (c_[2] == vb.c_[2])
+ && (c_[3] == vb.c_[3]);
+}
+
+template <typename VType>
+bool Vector4<VType>::operator!=(const Self& vb) const {
+ return (c_[0] != vb.c_[0])
+ || (c_[1] != vb.c_[1])
+ || (c_[2] != vb.c_[2])
+ || (c_[3] != vb.c_[3]);
+}
+
+template <typename VType>
+bool Vector4<VType>::aequal(const Self &vb, FloatType margin) const {
+ return (fabs(c_[0] - vb.c_[0]) < margin)
+ && (fabs(c_[1] - vb.c_[1]) < margin)
+ && (fabs(c_[2] - vb.c_[2]) < margin)
+ && (fabs(c_[3] - vb.c_[3]) < margin);
+}
+
+template <typename VType>
+bool Vector4<VType>::operator<(const Self &vb) const {
+ if ( c_[0] < vb.c_[0] ) return true;
+ if ( vb.c_[0] < c_[0] ) return false;
+ if ( c_[1] < vb.c_[1] ) return true;
+ if ( vb.c_[1] < c_[1] ) return false;
+ if ( c_[2] < vb.c_[2] ) return true;
+ if ( vb.c_[2] < c_[2] ) return false;
+ if ( c_[3] < vb.c_[3] ) return true;
+ return false;
+}
+
+template <typename VType>
+bool Vector4<VType>::operator>(const Self &vb) const {
+ return vb.operator<(*this);
+}
+
+template <typename VType>
+bool Vector4<VType>::operator<=(const Self &vb) const {
+ return !operator>(vb);
+}
+
+template <typename VType>
+bool Vector4<VType>::operator>=(const Self &vb) const {
+ return !operator<(vb);
+}
+
+template <typename VType>
+void Vector4<VType>::Set(const VType x, const VType y, const VType z,
+ const VType w) {
+ c_[0] = x;
+ c_[1] = y;
+ c_[2] = z;
+ c_[3] = w;
+}
+
+template <typename VType>
+Vector4<VType>& Vector4<VType>::operator=(const Self& vb) {
+ c_[0] = vb.c_[0];
+ c_[1] = vb.c_[1];
+ c_[2] = vb.c_[2];
+ c_[3] = vb.c_[3];
+ return (*this);
+}
+
+template <typename VType>
+Vector4<VType>& Vector4<VType>::operator+=(const Self& vb) {
+ c_[0] += vb.c_[0];
+ c_[1] += vb.c_[1];
+ c_[2] += vb.c_[2];
+ c_[3] += vb.c_[3];
+ return (*this);
+}
+
+template <typename VType>
+Vector4<VType>& Vector4<VType>::operator-=(const Self& vb) {
+ c_[0] -= vb.c_[0];
+ c_[1] -= vb.c_[1];
+ c_[2] -= vb.c_[2];
+ c_[3] -= vb.c_[3];
+ return (*this);
+}
+
+template <typename VType>
+Vector4<VType>& Vector4<VType>::operator*=(const VType k) {
+ c_[0] *= k;
+ c_[1] *= k;
+ c_[2] *= k;
+ c_[3] *= k;
+ return (*this);
+}
+
+template <typename VType>
+Vector4<VType>& Vector4<VType>::operator/=(const VType k) {
+ c_[0] /= k;
+ c_[1] /= k;
+ c_[2] /= k;
+ c_[3] /= k;
+ return (*this);
+}
+
+template <typename VType>
+Vector4<VType> Vector4<VType>::MulComponents(const Self &vb) const {
+ return Self(c_[0] * vb.c_[0], c_[1] * vb.c_[1],
+ c_[2] * vb.c_[2], c_[3] * vb.c_[3]);
+}
+
+template <typename VType>
+Vector4<VType> Vector4<VType>::DivComponents(const Self &vb) const {
+ return Self(c_[0] / vb.c_[0], c_[1] / vb.c_[1],
+ c_[2] / vb.c_[2], c_[3] / vb.c_[3]);
+}
+
+template <typename VType>
+Vector4<VType> Vector4<VType>::operator+(const Self &vb) const {
+ return Self(*this) += vb;
+}
+
+template <typename VType>
+Vector4<VType> Vector4<VType>::operator-(const Self &vb) const {
+ return Self(*this) -= vb;
+}
+
+template <typename VType>
+VType Vector4<VType>::DotProd(const Self &vb) const {
+ return c_[0]*vb.c_[0] + c_[1]*vb.c_[1] + c_[2]*vb.c_[2] + c_[3]*vb.c_[3];
+}
+
+template <typename VType>
+Vector4<VType> Vector4<VType>::operator*(const VType k) const {
+ return Self(*this) *= k;
+}
+
+template <typename VType>
+Vector4<VType> Vector4<VType>::operator/(const VType k) const {
+ return Self(*this) /= k;
+}
+
+template <typename VType>
+VType& Vector4<VType>::operator[](const int b) {
+ DCHECK(b >=0);
+ DCHECK(b <=3);
+ return c_[b];
+}
+
+template <typename VType>
+VType Vector4<VType>::operator[](const int b) const {
+ DCHECK(b >=0);
+ DCHECK(b <=3);
+ return c_[b];
+}
+
+template <typename VType>
+void Vector4<VType>::x(const VType &v) {
+ c_[0] = v;
+}
+
+template <typename VType>
+VType Vector4<VType>::x() const {
+ return c_[0];
+}
+
+template <typename VType>
+void Vector4<VType>::y(const VType &v) {
+ c_[1] = v;
+}
+
+template <typename VType>
+VType Vector4<VType>::y() const {
+ return c_[1];
+}
+
+template <typename VType>
+void Vector4<VType>::z(const VType &v) {
+ c_[2] = v;
+}
+
+template <typename VType>
+VType Vector4<VType>::z() const {
+ return c_[2];
+}
+
+template <typename VType>
+void Vector4<VType>::w(const VType &v) {
+ c_[3] = v;
+}
+
+template <typename VType>
+VType Vector4<VType>::w() const {
+ return c_[3];
+}
+
+template <typename VType>
+VType* Vector4<VType>::Data() {
+ return reinterpret_cast<VType*>(c_);
+}
+
+template <typename VType>
+const VType* Vector4<VType>::Data() const {
+ return reinterpret_cast<const VType*>(c_);
+}
+
+template <typename VType>
+VType Vector4<VType>::Norm2(void) const {
+ return c_[0]*c_[0] + c_[1]*c_[1] + c_[2]*c_[2] + c_[3]*c_[3];
+}
+
+template <typename VType>
+typename Vector4<VType>::FloatType Vector4<VType>::Norm(void) const {
+ return sqrt(Norm2());
+}
+
+template <typename VType>
+Vector4<VType> Vector4<VType>::Normalize() const {
+ COMPILE_ASSERT(!base::is_integral<VType>::value, must_be_floating_point);
+ VType n = Norm();
+ if (n != 0) {
+ n = 1.0 / n;
+ }
+ return Self(*this) *= n;
+}
+
+template <typename VType>
+Vector4<VType> Vector4<VType>::Sqrt() const {
+ return Self(sqrt(c_[0]), sqrt(c_[1]), sqrt(c_[2]), sqrt(c_[3]));
+}
+
+template <typename VType>
+Vector4<VType> Vector4<VType>::Fabs() const {
+ return Self(fabs(c_[0]), fabs(c_[1]), fabs(c_[2]), fabs(c_[3]));
+}
+
+template <typename VType>
+Vector4<VType> Vector4<VType>::Abs() const {
+ COMPILE_ASSERT(base::is_integral<VType>::value, use_Fabs_for_float_types);
+ COMPILE_ASSERT(static_cast<VType>(-1) == -1, type_must_be_signed);
+ COMPILE_ASSERT(sizeof(VType) <= sizeof(int), Abs_truncates_to_int);
+ return Self(abs(c_[0]), abs(c_[1]), abs(c_[2]), abs(c_[3]));
+}
+
+template <typename VType>
+Vector4<VType> Vector4<VType>::Floor() const {
+ return Self(floor(c_[0]),
+ floor(c_[1]),
+ floor(c_[2]),
+ floor(c_[3]));
+}
+
+template <typename VType>
+Vector4<VType> Vector4<VType>::Ceil() const {
+ return Self(ceil(c_[0]), ceil(c_[1]), ceil(c_[2]), ceil(c_[3]));
+}
+
+template <typename VType>
+Vector4<VType> Vector4<VType>::FRound() const {
+ return Self(rint(c_[0]), rint(c_[1]),
+ rint(c_[2]), rint(c_[3]));
+}
+
+template <typename VType>
+Vector4<int> Vector4<VType>::IRound() const {
+ return Vector4<int>(lrint(c_[0]), lrint(c_[1]),
+ lrint(c_[2]), lrint(c_[3]));
+}
+
+template <typename VType>
+void Vector4<VType>::Clear() {
+ c_[3] = c_[2] = c_[1] = c_[0] = VType();
+}
+
+template <typename VType>
+bool Vector4<VType>::IsNaN() const {
+ return isnan(c_[0]) || isnan(c_[1]) || isnan(c_[2]) || isnan(c_[3]);
+}
+
+template <typename VType>
+Vector4<VType> Vector4<VType>::NaN() {
+ return Self(MathUtil::NaN(), MathUtil::NaN(),
+ MathUtil::NaN(), MathUtil::NaN());
+}
+
+template <typename VType>
+Vector4<VType> operator-(const Vector4<VType> &vb) {
+ return Vector4<VType>( -vb[0], -vb[1], -vb[2], -vb[3]);
+}
+
+template <typename ScalarType, typename VType>
+Vector4<VType> operator*(const ScalarType k, const Vector4<VType> &v) {
+ return Vector4<VType>(k*v[0], k*v[1], k*v[2], k*v[3]);
+}
+
+template <typename ScalarType, typename VType>
+Vector4<VType> operator/(const ScalarType k, const Vector4<VType> &v) {
+ return Vector4<VType>(k/v[0], k/v[1], k/v[2], k/v[3]);
+}
+
+template <typename VType>
+Vector4<VType> Max(const Vector4<VType> &v1, const Vector4<VType> &v2) {
+ return Vector4<VType>(max(v1[0], v2[0]),
+ max(v1[1], v2[1]),
+ max(v1[2], v2[2]),
+ max(v1[3], v2[3]));
+}
+
+template <typename VType>
+Vector4<VType> Min(const Vector4<VType> &v1, const Vector4<VType> &v2) {
+ return Vector4<VType>(min(v1[0], v2[0]),
+ min(v1[1], v2[1]),
+ min(v1[2], v2[2]),
+ min(v1[3], v2[3]));
+}
+
+template <typename VType>
+std::ostream &operator <<(std::ostream &out, const Vector4<VType> &va) {
+ out << "["
+ << va[0] << ", "
+ << va[1] << ", "
+ << va[2] << ", "
+ << va[3] << "]";
+ return out;
+}
+
+// TODO(user): Vector4<T> does not actually satisfy the definition of a POD
+// type even when T is a POD. Pretending that Vector4<T> is a POD probably
+// won't cause any immediate problems, but eventually this should be fixed.
+PROPAGATE_POD_FROM_TEMPLATE_ARGUMENT(Vector4);
+
+#endif // UTIL_MATH_VECTOR4_INL_H__
diff --git a/src/third_party/s2/util/math/vector4.h b/src/third_party/s2/util/math/vector4.h
new file mode 100755
index 00000000000..1d3aa7339f7
--- /dev/null
+++ b/src/third_party/s2/util/math/vector4.h
@@ -0,0 +1,178 @@
+// Copyright 2003 Google, Inc.
+// All Rights Reserved.
+//
+//
+// A simple class to handle vectors in 4D
+// See the vector4-inl.h file for more details
+
+
+#ifndef UTIL_MATH_VECTOR4_H__
+#define UTIL_MATH_VECTOR4_H__
+
+#include <iostream>
+using std::ostream;
+using std::cout;
+using std::endl;
+ // NOLINT(readability/streams)
+#include "base/basictypes.h"
+
+template <typename VType> class Vector4;
+// TODO(user): Look into creating conversion operators to remove the
+// need to forward-declare Vector2 and Vector3.
+template <typename VType> class Vector2;
+template <typename VType> class Vector3;
+
+// Template class for 4D vectors
+template <typename VType>
+class Vector4 {
+ private:
+ VType c_[4];
+
+ // FloatType is the type returned by Norm(). This method is special because
+ // it returns floating-point values even when VType is an integer.
+ typedef typename base::if_<base::is_integral<VType>::value,
+ double, VType>::type FloatType;
+
+ public:
+ typedef Vector4<VType> Self;
+ typedef VType BaseType;
+ // Create a new vector (0,0)
+ Vector4();
+ // Create a new vector (x,y,z,w)
+ Vector4(const VType x, const VType y, const VType z, const VType w);
+ // Create a new copy of the vector vb
+ Vector4(const Self &vb);
+ // Create a new 4D vector from 2D vector and two scalars
+ // (vb.x,vb.y,z,w)
+ Vector4(const Vector2<VType> &vb, const VType z, const VType w);
+ // Create a 4D vector from two 2D vectors (vb1.x,vb1.y,vb2.x,vb2.y)
+ Vector4(const Vector2<VType> &vb1, const Vector2<VType> &vb2);
+ // Create a new 4D vector from 3D vector and scalar
+ // (vb.x,vb.y,vb.z,w)
+ Vector4(const Vector3<VType> &vb, const VType w);
+ // Convert from another vector type
+ template <typename VType2>
+ static Self Cast(const Vector4<VType2> &vb);
+ // Compare two vectors, return true if all their components are equal
+ bool operator==(const Self& vb) const;
+ bool operator!=(const Self& vb) const;
+ // Compare two vectors, return true if all their components are within
+ // a difference of margin.
+ bool aequal(const Self &vb, FloatType margin) const;
+ // Compare two vectors, these comparisons are mostly for interaction
+ // with STL.
+ bool operator<(const Self &vb) const;
+ bool operator>(const Self &vb) const;
+ bool operator<=(const Self &vb) const;
+ bool operator>=(const Self &vb) const;
+
+ // Return the size of the vector
+ static int Size() { return 4; }
+ // Modify the coordinates of the current vector
+ void Set(const VType x, const VType y, const VType z, const VType w);
+ Self& operator=(const Self& vb);
+ // add two vectors, component by component
+ Self& operator+=(const Self& vb);
+ // subtract two vectors, component by component
+ Self& operator-=(const Self& vb);
+ // multiply a vector by a scalar
+ Self& operator*=(const VType k);
+ // divide a vector by a scalar : implemented that way for integer vectors
+ Self& operator/=(const VType k);
+ // multiply two vectors component by component
+ Self MulComponents(const Self &vb) const;
+ // divide two vectors component by component
+ Self DivComponents(const Self &vb) const;
+ // add two vectors, component by component
+ Self operator+(const Self &vb) const;
+ // subtract two vectors, component by component
+ Self operator-(const Self &vb) const;
+ // Dot product. Be aware that if VType is an integer type, the high bits of
+ // the result are silently discarded.
+ VType DotProd(const Self &vb) const;
+ // Multiplication by a scalar
+ Self operator*(const VType k) const;
+ // Division by a scalar
+ Self operator/(const VType k) const;
+ // Access component #b for read/write operations
+ VType& operator[](const int b);
+ // Access component #b for read only operations
+ VType operator[](const int b) const;
+ // Labeled Accessor methods.
+ void x(const VType &v);
+ VType x() const;
+ void y(const VType &v);
+ VType y() const;
+ void z(const VType &v);
+ VType z() const;
+ void w(const VType &v);
+ VType w() const;
+ // return a pointer to the data array for interface with other libraries
+ // like opencv
+ VType* Data();
+ const VType* Data() const;
+ // Return the squared Euclidean norm of the vector. Be aware that if VType
+ // is an integer type, the high bits of the result are silently discarded.
+ VType Norm2(void) const;
+ // Return the Euclidean norm of the vector. Note that if VType is an
+ // integer type, the return value is correct only if the *squared* norm does
+ // not overflow VType.
+ FloatType Norm(void) const;
+ // Return a normalized version of the vector if the norm of the
+ // vector is not 0. Not to be used with integer types.
+ Self Normalize() const;
+ // take the sqrt of each component and return a vector containing those values
+ Self Sqrt() const;
+ // take the fabs of each component and return a vector containing those values
+ Self Fabs() const;
+ // Take the absolute value of each component and return a vector containing
+ // those values. This method should only be used when VType is a signed
+ // integer type that is not wider than "int".
+ Self Abs() const;
+ // take the floor of each component and return a vector containing
+ // those values
+ Self Floor() const;
+ // take the ceil of each component and return a vector containing those values
+ Self Ceil() const;
+ // take the round of each component and return a vector containing those
+ // values
+ Self FRound() const;
+ // take the round of each component and return an integer vector containing
+ // those values
+ Vector4<int> IRound() const;
+ // Reset all the coordinates of the vector to 0
+ void Clear();
+
+ // return true if one of the components is not a number
+ bool IsNaN() const;
+
+ // return an invalid floating point vector
+ static Self NaN();
+};
+
+// change the sign of the components of a vector
+template <typename VType>
+Vector4<VType> operator-(const Vector4<VType> &vb);
+// multiply by a scalar
+template <typename ScalarType, typename VType>
+Vector4<VType> operator*(const ScalarType k, const Vector4<VType> &v);
+// perform k /
+template <typename ScalarType, typename VType>
+Vector4<VType> operator/(const ScalarType k, const Vector4<VType> &v);
+// return a vector containing the max of v1 and v2 component by component
+template <typename VType>
+Vector4<VType> Max(const Vector4<VType> &v1, const Vector4<VType> &v2);
+// return a vector containing the min of v1 and v2 component by component
+template <typename VType>
+Vector4<VType> Min(const Vector4<VType> &v1, const Vector4<VType> &v2);
+// debug printing
+template <typename VType>
+std::ostream &operator <<(std::ostream &out, // NOLINT
+ const Vector4<VType> &va);
+
+typedef Vector4<uint8> Vector4_b;
+typedef Vector4<int> Vector4_i;
+typedef Vector4<float> Vector4_f;
+typedef Vector4<double> Vector4_d;
+
+#endif // UTIL_MATH_VECTOR4_H__