[DebianGIS-dev] r2520 - in liblas/trunk: . debian debian/patches

frankie at alioth.debian.org frankie at alioth.debian.org
Tue Oct 6 16:51:32 UTC 2009


Author: frankie
Date: 2009-10-06 16:51:32 +0000 (Tue, 06 Oct 2009)
New Revision: 2520

Added:
   liblas/trunk/debian/
   liblas/trunk/debian/README.source
   liblas/trunk/debian/changelog
   liblas/trunk/debian/compat
   liblas/trunk/debian/control
   liblas/trunk/debian/copyright
   liblas/trunk/debian/docs
   liblas/trunk/debian/liblas-bin.install
   liblas/trunk/debian/liblas-dev.install
   liblas/trunk/debian/liblas1.install
   liblas/trunk/debian/patches/
   liblas/trunk/debian/patches/missing.diff
   liblas/trunk/debian/patches/series
   liblas/trunk/debian/rules
   liblas/trunk/debian/watch
Log:
[svn-inject] Applying Debian modifications to trunk


Property changes on: liblas/trunk/debian
___________________________________________________________________
Added: mergeWithUpstream
   + 1

Added: liblas/trunk/debian/README.source
===================================================================
--- liblas/trunk/debian/README.source	                        (rev 0)
+++ liblas/trunk/debian/README.source	2009-10-06 16:51:32 UTC (rev 2520)
@@ -0,0 +1,18 @@
+liblas for Debian
+-----------------
+
+This package uses quilt to manage all modifications to the upstream
+source.  Changes are stored in the source package as diffs in
+debian/patches and applied during the build.  Please see:
+
+    /usr/share/doc/quilt/README.source
+
+for more information on how to apply the patches, modify patches, or
+remove a patch.
+
+Currently libLAS is taken from the mercurial repository by
+hg clone http://hg.liblas.org/main
+and using the stable branch to create a suitable snapshot tarball. 
+Note that you will need autotools to generate required additional
+files by autogen.sh. Occasionally, Howard Butler takes snapshots
+and publish them as libLAS and PyPI.

Added: liblas/trunk/debian/changelog
===================================================================
--- liblas/trunk/debian/changelog	                        (rev 0)
+++ liblas/trunk/debian/changelog	2009-10-06 16:51:32 UTC (rev 2520)
@@ -0,0 +1,6 @@
+liblas (1.2.1-1) unstable; urgency=low
+
+  * Initial release.
+    (closes: #532415)
+
+ -- Francesco Paolo Lovergine <frankie at debian.org>  Fri, 02 Oct 2009 12:36:21 +0200

Added: liblas/trunk/debian/compat
===================================================================
--- liblas/trunk/debian/compat	                        (rev 0)
+++ liblas/trunk/debian/compat	2009-10-06 16:51:32 UTC (rev 2520)
@@ -0,0 +1 @@
+7

Added: liblas/trunk/debian/control
===================================================================
--- liblas/trunk/debian/control	                        (rev 0)
+++ liblas/trunk/debian/control	2009-10-06 16:51:32 UTC (rev 2520)
@@ -0,0 +1,60 @@
+Source: liblas
+Section: science
+Priority: extra
+Maintainer: Debian GIS Project <pkg-grass-devel at lists.alioth.debian.org>
+Uploaders: Francesco Paolo Lovergine <frankie at debian.org>
+Build-Depends: cdbs (>= 0.4.49), debhelper (>= 7), autotools-dev, libgeotiff-dev, libgdal1-dev
+Standards-Version: 3.8.3
+Homepage: http://liblas.org/
+Vcs-Browser: http://svn.debian.org/viewsvn/pkg-grass/packages/liblas/trunk
+Vcs-Svn: svn://svn.debian.org/svn/pkg-grass/packages/liblas/trunk
+
+Package: liblas1
+Architecture: any
+Section: libs
+Suggests: libgeotiff-epsg
+Depends: ${shlibs:Depends}, ${misc:Depends}
+Description: ASPRS LiDAR data translation library
+ libLAS is a C/C++ library for reading and writing ASPRS LAS versions
+ 1.0, 1.1 and 1.2 data. The LAS format is a sequential binary format
+ used to store data from sensors and as intermediate processing storage
+ by some LiDAR-related applications. LiDAR (Light Detection and Ranging)
+ is an optical remote sensing technology that measures properties of
+ scattered light to find range and/or other information of a distant
+ target. The prevalent method to determine distance to an object or
+ surface is to use laser pulses.
+ .
+ This package contains the shared library used by applications.
+
+Package: liblas-dev
+Architecture: any
+Section: libdevel
+Depends: liblas1 (= ${binary:Version}), ${shlibs:Depends}, ${misc:Depends}
+Description: ASPRS LiDAR data translation library - development 
+ libLAS is a C/C++ library for reading and writing ASPRS LAS versions
+ 1.0, 1.1 and 1.2 data. The LAS format is a sequential binary format
+ used to store data from sensors and as intermediate processing storage
+ by some LiDAR-related applications. LiDAR (Light Detection and Ranging)
+ is an optical remote sensing technology that measures properties of
+ scattered light to find range and/or other information of a distant
+ target. The prevalent method to determine distance to an object or
+ surface is to use laser pulses.
+ .
+ This package contains the development files to build applications.
+
+Package: liblas-bin
+Architecture: any
+Depends: liblas1 (= ${binary:Version}), ${shlibs:Depends}, ${misc:Depends}
+Suggests: libgeotiff-epsg
+Description: ASPRS LiDAR data translation toolset
+ libLAS is a C/C++ library for reading and writing ASPRS LAS versions
+ 1.0, 1.1 and 1.2 data. The LAS format is a sequential binary format
+ used to store data from sensors and as intermediate processing storage
+ by some LiDAR-related applications. LiDAR (Light Detection and Ranging)
+ is an optical remote sensing technology that measures properties of
+ scattered light to find range and/or other information of a distant
+ target. The prevalent method to determine distance to an object or
+ surface is to use laser pulses.
+ .
+ This package contains the essential toolset to manage LiDAR data:
+ lasinfo, lasmerge, las2las, las2txt, txt2las, las2ogr.

Added: liblas/trunk/debian/copyright
===================================================================
--- liblas/trunk/debian/copyright	                        (rev 0)
+++ liblas/trunk/debian/copyright	2009-10-06 16:51:32 UTC (rev 2520)
@@ -0,0 +1,53 @@
+This work was packaged for Debian by:
+
+    Francesco Paolo Lovergine <frankie at debian.org> on Fri, 02 Oct 2009 12:36:21 +0200
+
+It was downloaded from http://liblas.org/
+
+Upstream Authors:
+
+	Martin Isenburg and Jonathan Shewchuk <isenburg at cs.unc.edu> (original authors)
+	Mateusz Loskot <mateusz at loskot.net>
+	Howard Butler <hobu.inc at gmail.com>
+	Martin Vales <mrodriguez at stereocarto.com>
+	Phillipe Vachon <philippe at cowpig.ca>
+	Frank Warmerdam <warmerdam at pobox.com>
+	Martin Rodriguez <mrodriguez at stereocarto.com>
+
+Copyrights:
+
+		Copyright (c) 2008, Xiuguang Zhou (ESRI)
+		Copyright (c) 1999, Frank Warmerdam
+		Copyright (c) 2008, Mateusz Loskot
+		Copyright (c) 2008, Howard Butler
+		Copyright (c) 2008, Phil Vachon
+		Copyright (c) 2007, Martin Isenburg 
+		Copyright (c) 2008, Martin Rodriguez
+
+License:
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted under the terms of the BSD License.
+
+    THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
+
+On Debian systems, the complete text of the BSD License can be
+found in `/usr/share/common-licenses/BSD'.
+
+The Debian packaging is:
+
+    Copyright (C) 2009 Francesco Paolo Lovergine <frankie at debian.org>
+
+and is licensed under the GPL version 3, 
+see `/usr/share/common-licenses/GPL-3'.
+

Added: liblas/trunk/debian/docs
===================================================================
--- liblas/trunk/debian/docs	                        (rev 0)
+++ liblas/trunk/debian/docs	2009-10-06 16:51:32 UTC (rev 2520)
@@ -0,0 +1,3 @@
+NEWS
+README
+AUTHORS

Added: liblas/trunk/debian/liblas-bin.install
===================================================================
--- liblas/trunk/debian/liblas-bin.install	                        (rev 0)
+++ liblas/trunk/debian/liblas-bin.install	2009-10-06 16:51:32 UTC (rev 2520)
@@ -0,0 +1,6 @@
+/usr/bin/las2las
+/usr/bin/las2ogr
+/usr/bin/las2txt
+/usr/bin/lasinfo
+/usr/bin/txt2las
+/usr/bin/lasmerge

Added: liblas/trunk/debian/liblas-dev.install
===================================================================
--- liblas/trunk/debian/liblas-dev.install	                        (rev 0)
+++ liblas/trunk/debian/liblas-dev.install	2009-10-06 16:51:32 UTC (rev 2520)
@@ -0,0 +1,4 @@
+usr/lib/liblas.a
+usr/lib/liblas.so
+usr/include
+usr/bin/liblas-config

Added: liblas/trunk/debian/liblas1.install
===================================================================
--- liblas/trunk/debian/liblas1.install	                        (rev 0)
+++ liblas/trunk/debian/liblas1.install	2009-10-06 16:51:32 UTC (rev 2520)
@@ -0,0 +1,2 @@
+usr/lib/liblas.so.1
+usr/lib/liblas.so.1.0.0

Added: liblas/trunk/debian/patches/missing.diff
===================================================================
--- liblas/trunk/debian/patches/missing.diff	                        (rev 0)
+++ liblas/trunk/debian/patches/missing.diff	2009-10-06 16:51:32 UTC (rev 2520)
@@ -0,0 +1,2481 @@
+
+This patch adds missing files to 1.2.1 tarball.
+
+diff -urN liblas-1.2.1/test/unit/common.hpp main/test/unit/common.hpp
+--- liblas-1.2.1/test/unit/common.hpp	1970-01-01 01:00:00.000000000 +0100
++++ main/test/unit/common.hpp	2009-10-02 16:46:22.000000000 +0200
+@@ -0,0 +1,88 @@
++// $Id$
++//
++// (C) Copyright Mateusz Loskot 2008, mateusz at loskot.net
++// Distributed under the BSD License
++// (See accompanying file LICENSE.txt or copy at
++// http://www.opensource.org/licenses/bsd-license.php)
++//
++#include <liblas/liblas.hpp>
++#include <liblas/laspoint.hpp>
++#include <liblas/lasheader.hpp>
++
++
++namespace tut
++{
++
++// Predicate testing LASPoint against given XY coordinates
++// and tolerance.
++struct is_xy
++{
++    is_xy(double x, double y, double tolerance)
++        : x(x), y(y), t(tolerance)
++    {}
++
++    bool operator()(liblas::LASPoint const& p)
++    {
++        double const dx = x - p.GetX();
++        double const dy = y - p.GetY();
++
++        return ((dx <= t && dx >= -t) && (dy <= t && dy >= -t));
++    }
++
++    double x;
++    double y;
++    double t;
++};
++
++// Functor to calculate bounding box of a set of points
++struct bbox_calculator
++{
++    // bbox object will store operation result
++    bbox_calculator(liblas::detail::Extents<double>& bbox)
++        : empty(true), bbox(bbox)
++    {}
++
++    void operator()(liblas::LASPoint const& p)
++    {
++        // Box initialization during first iteration only
++        if (empty)
++        {
++            bbox.min.x = bbox.max.x = p.GetX();
++            bbox.min.y = bbox.max.y = p.GetY();
++            bbox.min.z = bbox.max.z = p.GetZ();
++            empty = false;
++        }
++
++        // Expand bounding box to include given point
++        bbox.min.x = std::min(bbox.min.x, p.GetX());
++        bbox.min.y = std::min(bbox.min.y, p.GetY());
++        bbox.min.z = std::min(bbox.min.z, p.GetZ());
++        bbox.max.x = std::max(bbox.max.x, p.GetX());
++        bbox.max.y = std::max(bbox.max.y, p.GetY());
++        bbox.max.z = std::max(bbox.max.z, p.GetZ());
++    }
++
++    bool empty;
++    liblas::detail::Extents<double>& bbox;
++};
++
++// Common test procedure for default constructed point data.
++void test_default_point(liblas::LASPoint const& p);
++
++// Common test procedure for default constructed header data.
++void test_default_header(liblas::LASHeader const& h);
++
++// Test of header data in trunk/test/data/TO_core_last_clip.las file
++void test_file10_header(liblas::LASHeader const& h);
++
++// Test of 1st point record in trunk/test/data/TO_core_last_clip.las file
++void test_file10_point1(liblas::LASPoint const& p);
++
++// Test of 2nd point record in trunk/test/data/TO_core_last_clip.las file
++void test_file10_point2(liblas::LASPoint const& p);
++
++// Test of 4th point record in trunk/test/data/TO_core_last_clip.las file
++void test_file10_point4(liblas::LASPoint const& p);
++
++} // namespace tut
++
+diff -urN liblas-1.2.1/test/unit/liblas_test.hpp main/test/unit/liblas_test.hpp
+--- liblas-1.2.1/test/unit/liblas_test.hpp	1970-01-01 01:00:00.000000000 +0100
++++ main/test/unit/liblas_test.hpp	2009-10-02 16:46:22.000000000 +0200
+@@ -0,0 +1,18 @@
++// $Id$
++//
++// (C) Copyright Mateusz Loskot 2008, mateusz at loskot.net
++// Distributed under the BSD License
++// (See accompanying file LICENSE.txt or copy at
++// http://www.opensource.org/licenses/bsd-license.php)
++//
++#ifndef LIBLAS_TEST_HPP_INCLUDED
++#define LIBLAS_TEST_HPP_INCLUDED
++
++namespace tut
++{
++    // full path to trunk/test/data
++    extern std::string g_test_data_path;
++}
++
++#endif // LIBLAS_TEST_HPP_INCLUDED
++
+diff -urN liblas-1.2.1/test/unit/tut/README main/test/unit/tut/README
+--- liblas-1.2.1/test/unit/tut/README	1970-01-01 01:00:00.000000000 +0100
++++ main/test/unit/tut/README	2009-10-02 16:46:36.000000000 +0200
+@@ -0,0 +1,516 @@
++--------------------------------------------------------------------
++TUT: C++ Template Unit Test Framework
++
++Version:  TUT-2007-07-06
++Homepage: http://tut-framework.sourceforge.net/
++--------------------------------------------------------------------
++
++Documentation TUT How-To minimum steps to make TUT work for you
++
++What is TUT
++
++TUT is a pure C++ unit test framework. Its name - TUT - stands for 
++Template Unit Tests.
++
++Features
++
++TUT provides all features required for unit testing:
++
++    * Similar tests can be grouped together into test groups. Each 
++      test group has its unique name and is located in a separate 
++      compilation unit. One group can contain almost unlimited number 
++      of tests (actually, the limit is the compiler template 
++      recursion depth).
++    * User can run all the tests (regression), or just some selected 
++      groups or even some tests in these groups.
++    * TUT provides special template functions to check the condition 
++      validity at run-time and to force test failure if required. 
++      Since C++ doesn't provide a facility for obtaining stack trace 
++      of the throwed exception and TUT avoids macros, those functions 
++      accept string marker to allow users easely determine the source 
++      of exception.
++    * TUT contains callback that can be implemented by the calling code 
++      to integrate with an IDE, for example. Callbacks tell listener 
++      when a new test run started, when test runner switches to the 
++      next tests group, when a test was completed (and what result it 
++      has), and when test run was finished. The callbacks allow users 
++      to produce their own visualization format for test process and results.
++    * Being a template library, it doesn't need compilation; just 
++      include the <tut.h> header into the test modules.
++
++TUT tests organization
++
++Test application
++
++C++ produces executable code, so tests have to be compiled into a single 
++binary called test application. The application can be built in automated 
++mode to perform nightly tests. They also can be built manually when a 
++developer hunts for bugs.
++
++The test application contains tests, organized into test groups.
++
++Test groups
++
++The functionality of a tested application can be divided into a few separate 
++function blocks (e.g. User Rights, Export, Processing, ...). It is natural 
++to group together tests for each block. TUT invokes this test group. Each 
++test group has a unique human-readable name and normally is located in a 
++separate file.
++
++Tests
++
++Each single test usually checks only one specific element of functionality. 
++For example, for a container a test could check whether size() call 
++returns zero after the successful call to the clear() method.
++
++Writing simple test
++
++Preamble
++
++You are going to create a new class for your application. You decided to 
++write tests for the class to be sure it works while you are developing or, 
++possibly, enhancing it. Let's consider your class is shared pointer: 
++std::auto_ptr-alike type that shares the same object among instances.
++
++Prior to test writing, you should decide what to test. Maximalist's 
++approach requires to write so many tests that altering any single 
++line of your production code will break at least one of them. 
++Minimalist's approach allows one to write tests only for the most 
++general or the most complex use cases. The truth lies somewhere in 
++between, but only you, developer, know where. You should prepare 
++common successful and unsuccessful scenarios, and the scenarios for 
++testing any other functionality you believe might be broken in some way.
++
++For our shared_ptr we obviosly should test constructors, assignment operators, referencing and passing ownership.
++
++Skeleton
++
++If you don't have any implemented class to test yet, it would be good to 
++implement it as a set of stubs for a first time. Thus you'll get an 
++interface, and be able to write your tests. Yes, that's correct: you 
++should write your tests before writing code! First of all, writing tests 
++often helps to understand oddities in the current interface, and fix it. 
++Secondly, with the stubs all your tests will fail, so you'll be sure 
++they do their job.
++
++Creating Test Group
++
++Since we're writing unit tests, it would be a good idea to group the 
++tests for our class in one place to be able to run them separately. 
++It's also natural in C++ to place all the grouped tests into one 
++compilation unit (i.e. source file). So, to begin, we should create 
++a new file. Let's call it test_shared_ptr.cpp. (Final variant of the 
++test group can be found in examples/shared_ptr subdirectory of the 
++distribution package)
++
++// test_shared_ptr.cpp
++#include <tut.h>
++
++namespace tut
++{
++};
++            
++
++As you see, you need to include TUT header file (as expected) and 
++use namespace tut for tests. You may also use anonymous namespace if 
++your compiler allows it (you will need to instantiate methods from 
++tut namespace and some compilers refuse to place such instantiations 
++into the anonymous namespace).
++
++A test group in TUT framework is described by the special template 
++test_group<T>. The template parameter T is a type that will hold all 
++test-specific data during the test execution. Actually, the data 
++stored in T are member data of the test. Test object is inherited 
++from T, so any test can refer to the data in T as its member data.
++
++For simple test groups (where all data are stored in test local 
++variables) type T is an empty struct.
++
++#include <tut.h>
++
++namespace tut
++{
++  struct shared_ptr_data
++  { 
++  };
++}
++            
++But when tests have complex or repeating creation phase, you may put 
++data members into the T and provide constructor (and, if required, 
++destructor) for it. For each test, a new instance of T will be 
++created. To prepare your test for execution TUT will use default 
++constructor. Similarly, after the test has been finished, TUT 
++calls the destructor to clean up T. I.e.:
++
++#include <tut.h>
++
++namespace tut
++{
++  struct complex_data
++  {
++    connection* con;
++    complex_data(){ con = db_pool.get_connection(); }
++    ~complex_data(){ db_pool.release_connection(con); }
++  };
++
++  // each test from now will have con data member initialized
++  // by constructor:
++  ...
++  con->commit();
++  ...
++            
++
++What will happen if the constructor throws an exception? TUT will treat 
++it as if test itself failed with exception, so this test will 
++not be executed. You'll see an exception mark near the test, and 
++if the constructor throwed something printable, a certain message will appear.
++
++Exception in destructor is threated a bit different. Reaching destruction 
++phase means that the test is passed, so TUT marks test with warning 
++status meaning that test itself was OK, but something bad has happend 
++after the test.
++
++Well, all we have written so far is just a type declaration. To work 
++with a group we have to have an object, so we must create the test group 
++object. Since we need only one test group object for each unit, we can 
++(and should, actually) make this object static. To prevent name clash with 
++other test group objects in the namespace tut, we should provide a 
++descriptive name, or, alternatively, we may put it into the anonymous 
++namespace. The former is more correct, but a descriptive name usually works 
++well too, unless you're too terse in giving names to objects.
++
++#include <tut.h>
++
++namespace tut
++{
++    struct shared_ptr_data
++    {
++
++    };
++
++    typedef test_group<shared_ptr_data> tg;
++    tg shared_ptr_group("shared_ptr");
++};
++            
++As you see, any test group accepts a single parameter - its human-readable 
++name. This name is used to identify the group when a programmer wants to 
++execute all tests or a single test within the group. So this name shall 
++also be descriptive enough to avoid clashes. Since we're writing tests 
++for a specific unit, it's enough to name it after the unit name.
++
++Test group constructor will be called at unspecified moment at the test 
++application startup. The constructor performs self-registration; it calls 
++tut::runner and asks it to store the test group object name and location. 
++Any other test group in the system undergoes the same processing, i.e. 
++each test group object registers itself. Thus, test runner can iterate 
++all test groups or execute any test group by its name.
++
++Newly created group has no tests associated with it. To be more precise, 
++it has predefined set of dummy tests. By default, there are 50 tests in a 
++group, including dummy ones. To create a test group with higher volume 
++(e.g. when tests are generated by a script and their number is higher) 
++we must provide a higher border of test group size when it is instantiated:
++
++#include <tut.h>
++
++namespace tut
++{
++    struct huge_test_data
++    {
++    };
++
++    // test group with maximum 500 tests
++    typedef test_group<huge_test_data,500> testgroup;
++    testgroup huge_test_testgroup("huge group");
++};
++            
++
++Note also, that your compiler will possibly need a command-line switch 
++or pragma to enlarge recursive instantiation depth. For g++, for 
++example, you should specify at least --ftemplate-depth-501 to increase 
++the depth. For more information see your compiler documentation.
++
++Creating Tests
++
++Now it's time to fill our test group with content.
++
++In TUT, all tests have unique numbers inside the test group. Some 
++people believe that textual names better describe failed tests in 
++reports. I agree; but in reality C++ templates work good with numbers 
++because they are compile-time constants and refuse to do the same 
++with strings, since strings are in fact addresses of character 
++buffers, i.e. run-time data.
++
++As I mentioned above, our test group already has a few dummy tests; 
++and we can replace any of them with something real just by writing 
++our own version:
++
++#include <tut.h>
++
++namespace tut
++{
++    struct shared_ptr_data{};
++
++    typedef test_group<shared_ptr_data> testgroup;
++    typedef testgroup::object testobject;
++    testgroup shared_ptr_testgroup("shared_ptr");
++
++    template<>
++    template<>
++    void testobject::test<1>()
++    {
++        // do nothing test
++    }
++};
++        
++
++So far this test does nothing, but it's enough to illustrate the concept.
++
++All tests in the group belong to the type test_group<T>::object. This 
++class is directly inherited from our test data structure. In our case, it is
++
++class object : public shared_ptr_data { ... }
++        
++This allows to access members of the data structure directly, since at 
++the same time they are members of the object type. We also typedef the 
++type with testobject for brevity.
++
++We mark our test with number 1. Previously, test group had a dummy test 
++with the same number, but now, since we've defined our own version, it 
++replaces the dummy test as more specialized one. It's how C++ template 
++ordering works.
++
++The test we've written always succeeds. Successful test returns with no 
++exceptions. Unsuccessful one either throws an exception, or fails at 
++fail() or ensure() methods (which anyway just throw the exception when failed).
++
++First real test
++
++Well, now we know enough to write the first real working test. This test 
++will create shared_ptr instances and check their state. We will define a 
++small structure (keepee) to use it as shared_ptr stored object type.
++
++#include <tut.h>
++#include <shared_ptr.h>
++
++namespace tut
++{
++    struct shared_ptr_data
++    {
++        struct keepee{ int data; };
++    };
++
++    typedef test_group<shared_ptr_data> testgroup;
++    typedef testgroup::object testobject;
++    testgroup shared_ptr_testgroup("shared_ptr");
++
++    /**
++     * Checks default constructor.
++     */
++    template<>
++    template<>
++    void testobject::test<1>()
++    {
++        shared_ptr<keepee> def;
++        ensure("null",def.get() == 0);
++    }
++};
++        
++
++That's all! The first line creates shared_ptr. If constructor throws 
++an exception, test will fail (exceptions, including '...', are catched 
++by the TUT framework). If the first line succeeds, we must check 
++whether the kept object is null one. To do this, we use test object 
++member function ensure(), which throws std::logic_error with a given 
++message if its second argument is not true. Finally, if destructor of 
++shared_ptr fails with exception, TUT also will report this test as failed.
++
++It's equally easy to write a test for the scenario where we expect to get 
++an exception: let's consider our class should throw an exception if it 
++has no stored object, and the operator -> is called.
++
++/**
++ * Checks operator -> throws instead of returning null.
++ */
++template<>
++template<>
++void testobject::test<2>()
++{
++    try
++    {
++        shared_ptr<keepee> sp;
++        sp->data = 0;
++        fail("exception expected");
++    }
++    catch( const std::runtime_error& ex )
++    {
++        // ok
++    }
++}
++        
++
++Here we expect the std::runtime_error. If operator doesn't throw it, 
++we'll force the test to fail using another member function: fail(). It 
++just throws std::logic_error with a given message. If operator throws 
++anything else, our test will fail too, since we intercept only 
++std::runtime_error, and any other exception means the test has failed.
++
++NB: our second test has number 2 in its name; it can, actually, be any 
++in range 1..Max; the only requirement is not to write tests with the 
++same numbers. If you did, compiler will force you to fix them anyway.
++
++And finally, one more test to demonstrate how to use the 
++ensure_equals template member function:
++
++/**
++ * Checks keepee counting.
++ */
++template<>
++template<>
++void testobject::test<3>()
++{
++    shared_ptr<keepee> sp1(new keepee());
++    shared_ptr<keepee> sp2(sp1);
++    ensure_equals("second copy at sp1",sp1.count(),2);
++    ensure_equals("second copy at sp2",sp2.count(),2);
++}
++        
++
++The test checks if the shared_ptr correctly counts references during 
++copy construction. What's interesting here is the template member 
++ensure_equals. It has an additional functionality comparing with similar 
++call ensure("second_copy",sp1.count()==2); it uses operator == to check 
++the equality of the two passed parameters and, what's more important, it 
++uses std::stream to format the passed parameters into a human-readable 
++message (smth like: "second copy: expected 2, got 1"). It means that 
++ensure_equals cannot be used with the types that don't have operator <<; 
++but for those having the operator it provides much more informational message.
++
++In contrast to JUnit assertEquals, where the expected value goes before 
++the actual one, ensure_equals() accepts the expected after the actual 
++value. I believe it's more natural to read ensure_equals("msg", count, 5) 
++as "ensure that count equals to 5" rather than JUnit's 
++"assert that 5 is the value of the count".
++
++Running tests
++
++Tests are already written, but an attempt to run them will be unsuccessful. 
++We need a few other bits to complete the test application.
++
++First of all, we need a main() method, simply because it must be in all 
++applications. Secondly, we need a test runner singleton. Remember I said 
++each test group should register itself in singleton? So, we need that 
++singleton. And, finally, we need a kind of a callback handler to visualize 
++our test results.
++
++The design of TUT doesn't strictly set a way the tests are visualized; 
++instead, it provides an opportunity to get the test results by means of 
++callbacks. Moreover it allows user to output the results in any format he 
++prefers. Of course, there is a "reference implementation" in the 
++example/subdirectory of the project.
++
++Test runner singleton is defined in tut.h, so all we need to activate it 
++is to declare an object of the type tut::test_runner_singleton in the main 
++module with a special name tut::runner.
++
++Now, with the test_runner we can run tests. Singleton has method get() 
++returning a reference to an instance of the test_runner class, which in 
++turn has methods run_tests() to run all tests in all groups, 
++run_tests(const std::string& groupname) to run all tests in a given group 
++and run_test(const std::string& grp,int n) to run one test in the specified group.
++
++// main.cpp
++#include <tut.h>
++
++namespace tut
++{
++    test_runner_singleton runner;
++}
++
++int main()
++{
++    // run all tests in all groups
++    runner.get().run_tests();
++
++    // run all tests in group "shared_ptr"
++    runner.get().run_tests("shared_ptr");
++
++    // run test number 5 in group "shared_ptr"
++    runner.get().run_test("shared_ptr",5);
++
++    return 0;
++}
++  
++It's up to user to handle command-line arguments or GUI messages and map those 
++arguments/messages to actual calls to test runner. Again, as you see, TUT 
++doesn't restrict user here.
++
++But, the last question is still unanswered: how do we get our test results? 
++The answer lies inside tut::callback interface. User shall create its subclass, 
++and write up to three simple methods. He also can omit any method since they 
++have default no-op implementation. Each corresponding method is called in the 
++following cases:
++
++    * a new test run started;
++    * test finished;
++    * test run finished.
++
++Here is a minimal implementation:
++
++class visualizator : public tut::callback
++{
++public:
++  void run_started(){ }
++
++  void test_completed(const tut::test_result& tr)
++  {
++      // ... show test result here ...
++  }
++
++  void run_completed(){ }
++};        
++
++The most important is the test_completed() method; its parameter has type 
++test_result, and contains everything about the finished test, from its group 
++name and number to the exception message, if any. Member result is an enum 
++that contains status of the test: ok, fail or ex. Take a look at the 
++examples/basic/main.cpp for more complete visualizator.
++
++Visualizator should be passed to the test_runner before run. Knowing that, 
++we are ready to write the final version of our main module:
++
++// main.cpp
++#include <tut.h>
++
++namespace tut
++{
++  test_runner_singleton runner;
++}
++
++class callback : public tut::callback
++{
++public:
++  void run_started(){ std::cout << "\nbegin"; }
++
++  void test_completed(const tut::test_result& tr)
++  {
++    std::cout << tr.test_pos << "=" << tr.result << std::flush;
++  }
++
++  void run_completed(){ std::cout << "\nend"; }
++};
++
++int main()
++{
++  callback clbk;
++  runner.get().set_callback(&clbk);
++
++  // run all tests in all groups
++  runner.get().run_tests();
++  return 0;
++}
++        
++That's it. You are now ready to link and run our test application. Do it as often as possible; 
++once a day is a definite must. I hope, TUT will help you to make your application more 
++robust and relieve your testing pain. Feel free to send your questions, suggestions and 
++critical opinions to me; I'll do my best to address them asap.
+diff -urN liblas-1.2.1/test/unit/tut/tut.hpp main/test/unit/tut/tut.hpp
+--- liblas-1.2.1/test/unit/tut/tut.hpp	1970-01-01 01:00:00.000000000 +0100
++++ main/test/unit/tut/tut.hpp	2009-10-02 16:46:36.000000000 +0200
+@@ -0,0 +1,1211 @@
++#ifndef TUT_H_GUARD
++#define TUT_H_GUARD
++
++#include <iostream>
++#include <map>
++#include <vector>
++#include <string>
++#include <sstream>
++#include <typeinfo>
++// NOTE: mloskot added for ensure_equals<double,double> specialization
++#include <iomanip>
++#include <limits>
++
++#if defined(TUT_USE_SEH)
++#include <windows.h>
++#include <winbase.h>
++#endif
++
++/**
++ * Template Unit Tests Framework for C++.
++ * http://tut.dozen.ru
++ *
++ * @author Vladimir Dyuzhev, Vladimir.Dyuzhev at gmail.com
++ */
++namespace tut
++{
++
++/**
++ * The base for all TUT exceptions.
++ */
++struct tut_error : public std::exception
++{
++    tut_error(const std::string& msg)
++        : err_msg(msg)
++    {
++    }
++    
++    ~tut_error() throw()
++    {
++    }
++    
++    const char* what() const throw()
++    {
++        return err_msg.c_str();
++    }
++    
++private:
++
++    std::string err_msg;
++};
++
++/**
++ * Exception to be throwed when attempted to execute 
++ * missed test by number.
++ */
++struct no_such_test : public tut_error
++{
++    no_such_test() 
++        : tut_error("no such test")
++    {
++    }
++    
++    ~no_such_test() throw()
++    {
++    }
++};
++
++/**
++ * No such test and passed test number is higher than
++ * any test number in current group. Used in one-by-one
++ * test running when upper bound is not known.
++ */
++struct beyond_last_test : public no_such_test
++{
++    beyond_last_test()
++    {
++    }
++    
++    ~beyond_last_test() throw()
++    {
++    }
++};
++
++/**
++ * Group not found exception.
++ */
++struct no_such_group : public tut_error
++{
++    no_such_group(const std::string& grp) 
++        : tut_error(grp)
++    {
++    }
++    
++    ~no_such_group() throw()
++    {
++    }
++};
++
++/**
++ * Internal exception to be throwed when 
++ * no more tests left in group or journal.
++ */
++struct no_more_tests
++{
++    no_more_tests()
++    {
++    }
++    
++    ~no_more_tests() throw()
++    {
++    }
++};
++
++/**
++ * Internal exception to be throwed when 
++ * test constructor has failed.
++ */
++struct bad_ctor : public tut_error
++{
++    bad_ctor(const std::string& msg) 
++        : tut_error(msg)
++    {
++    }
++    
++    ~bad_ctor() throw()
++    {
++    }
++};
++
++/**
++ * Exception to be throwed when ensure() fails or fail() called.
++ */
++struct failure : public tut_error
++{
++    failure(const std::string& msg) 
++        : tut_error(msg)
++    {
++    }
++    
++    ~failure() throw()
++    {
++    }
++};
++
++/**
++ * Exception to be throwed when test desctructor throwed an exception.
++ */
++struct warning : public tut_error
++{
++    warning(const std::string& msg) 
++        : tut_error(msg)
++    {
++    }
++    
++    ~warning() throw()
++    {
++    }
++};
++
++/**
++ * Exception to be throwed when test issued SEH (Win32)
++ */
++struct seh : public tut_error
++{
++    seh(const std::string& msg) 
++        : tut_error(msg)
++    {
++    }
++    
++    ~seh() throw()
++    {
++    }
++};
++
++/**
++ * Return type of runned test/test group.
++ *
++ * For test: contains result of test and, possible, message
++ * for failure or exception.
++ */
++struct test_result
++{
++    /**
++     * Test group name.
++     */
++    std::string group;
++
++    /**
++     * Test number in group.
++     */
++    int test;
++
++    /**
++     * Test name (optional)
++     */
++    std::string name;
++
++    /**
++     * ok - test finished successfully
++     * fail - test failed with ensure() or fail() methods
++     * ex - test throwed an exceptions
++     * warn - test finished successfully, but test destructor throwed
++     * term - test forced test application to terminate abnormally
++     */
++    enum result_type
++    { 
++        ok, 
++        fail, 
++        ex, 
++        warn, 
++        term, 
++        ex_ctor 
++    };
++    
++    result_type result;
++
++    /**
++     * Exception message for failed test.
++     */
++    std::string message;
++    std::string exception_typeid;
++
++    /**
++     * Default constructor.
++     */
++    test_result()
++        : test(0),
++          result(ok)
++    {
++    }
++
++    /**
++     * Constructor.
++     */
++    test_result(const std::string& grp, int pos,
++                const std::string& test_name, result_type res)
++        : group(grp), 
++          test(pos), 
++          name(test_name), 
++          result(res)
++    {
++    }
++
++    /**
++     * Constructor with exception.
++     */
++    test_result(const std::string& grp,int pos,
++                const std::string& test_name, result_type res,
++                const std::exception& ex)
++        : group(grp), 
++          test(pos), 
++          name(test_name), 
++          result(res),
++          message(ex.what()),
++          exception_typeid(typeid(ex).name())
++    {
++    }
++};
++
++/**
++ * Interface.
++ * Test group operations.
++ */
++struct group_base
++{
++    virtual ~group_base()
++    {
++    }
++
++    // execute tests iteratively
++    virtual void rewind() = 0;
++    virtual test_result run_next() = 0;
++
++    // execute one test
++    virtual test_result run_test(int n) = 0;
++};
++
++/**
++ * Test runner callback interface.
++ * Can be implemented by caller to update
++ * tests results in real-time. User can implement 
++ * any of callback methods, and leave unused 
++ * in default implementation.
++ */
++struct callback
++{
++    /**
++     * Virtual destructor is a must for subclassed types.
++     */
++    virtual ~callback()
++    {
++    }
++
++    /**
++     * Called when new test run started.
++     */
++    virtual void run_started()
++    {
++    }
++
++    /**
++     * Called when a group started
++     * @param name Name of the group
++     */
++    virtual void group_started(const std::string& /*name*/)
++    {
++    }
++
++    /**
++     * Called when a test finished.
++     * @param tr Test results.
++     */
++    virtual void test_completed(const test_result& /*tr*/)
++    {
++    }
++
++    /**
++     * Called when a group is completed
++     * @param name Name of the group
++     */
++    virtual void group_completed(const std::string& /*name*/)
++    {
++    }
++
++    /**
++     * Called when all tests in run completed.
++     */
++    virtual void run_completed()
++    {
++    }
++};
++
++/**
++ * Typedef for runner::list_groups()
++ */
++typedef std::vector<std::string> groupnames;
++
++/**
++ * Test runner.
++ */
++class test_runner
++{
++
++public:
++    
++    /**
++     * Constructor
++     */
++    test_runner() 
++        : callback_(&default_callback_)
++    {
++    }
++
++    /**
++     * Stores another group for getting by name.
++     */
++    void register_group(const std::string& name, group_base* gr)
++    {
++        if (gr == 0)
++        {
++            throw tut_error("group shall be non-null");
++        }
++
++        // TODO: inline variable
++        groups::iterator found = groups_.find(name);
++        if (found != groups_.end())
++        {
++            std::string msg("attempt to add already existent group " + name);
++            // this exception terminates application so we use cerr also
++            // TODO: should this message appear in stream?
++            std::cerr << msg << std::endl;
++            throw tut_error(msg);
++        }
++
++        groups_[name] = gr;
++    }
++
++    /**
++     * Stores callback object.
++     */
++    void set_callback(callback* cb)
++    {
++        callback_ = cb == 0 ? &default_callback_ : cb;
++    }
++
++    /**
++     * Returns callback object.
++     */
++    callback& get_callback() const
++    {
++        return *callback_;
++    }
++
++    /**
++     * Returns list of known test groups.
++     */
++    const groupnames list_groups() const
++    {
++        groupnames ret;
++        const_iterator i = groups_.begin();
++        const_iterator e = groups_.end();
++        while (i != e)
++        {
++            ret.push_back(i->first);
++            ++i;
++        }
++        return ret;
++    }
++
++    /**
++     * Runs all tests in all groups.
++     * @param callback Callback object if exists; null otherwise
++     */
++    void run_tests() const
++    {
++        callback_->run_started();
++
++        const_iterator i = groups_.begin();
++        const_iterator e = groups_.end();
++        while (i != e)
++        {
++            callback_->group_started(i->first);
++            try
++            {
++                run_all_tests_in_group_(i);
++            }
++            catch (const no_more_tests&)
++            {
++                callback_->group_completed(i->first);
++            }
++
++            ++i;
++        }
++
++        callback_->run_completed();
++    }
++
++    /**
++     * Runs all tests in specified group.
++     */
++    void run_tests(const std::string& group_name) const
++    {
++        callback_->run_started();
++
++        const_iterator i = groups_.find(group_name);
++        if (i == groups_.end())
++        {
++            callback_->run_completed();
++            throw no_such_group(group_name);
++        }
++
++        callback_->group_started(group_name);
++        try
++        {
++            run_all_tests_in_group_(i);
++        }
++        catch (const no_more_tests&)
++        {
++            // ok
++        }
++
++        callback_->group_completed(group_name);
++        callback_->run_completed();
++    }
++
++    /**
++     * Runs one test in specified group.
++     */
++    test_result run_test(const std::string& group_name, int n) const
++    {
++        callback_->run_started();
++
++        const_iterator i = groups_.find(group_name);
++        if (i == groups_.end())
++        {
++            callback_->run_completed();
++            throw no_such_group(group_name);
++        }
++
++        callback_->group_started(group_name);
++        try
++        {
++            test_result tr = i->second->run_test(n);
++            callback_->test_completed(tr);
++            callback_->group_completed(group_name);
++            callback_->run_completed();
++            return tr;
++        }
++        catch (const beyond_last_test&)
++        {
++            callback_->group_completed(group_name);
++            callback_->run_completed();
++            throw;
++        }
++        catch (const no_such_test&)
++        {
++            callback_->group_completed(group_name);
++            callback_->run_completed();
++            throw;
++        }
++    }
++
++protected:
++    
++    typedef std::map<std::string, group_base*> groups;
++    typedef groups::iterator iterator;
++    typedef groups::const_iterator const_iterator;
++    groups groups_;
++
++    callback  default_callback_;
++    callback* callback_;
++
++
++private:
++
++    void run_all_tests_in_group_(const_iterator i) const
++    {
++        i->second->rewind();
++        for ( ;; )
++        {
++            test_result tr = i->second->run_next();
++            callback_->test_completed(tr);
++
++            if (tr.result == test_result::ex_ctor)
++            {
++                throw no_more_tests();
++            }
++        }
++    }
++};
++
++/**
++ * Singleton for test_runner implementation.
++ * Instance with name runner_singleton shall be implemented
++ * by user.
++ */
++class test_runner_singleton
++{
++public:
++
++    static test_runner& get()
++    {
++        static test_runner tr;
++        return tr;
++    }
++};
++
++extern test_runner_singleton runner;
++
++/**
++ * Test object. Contains data test run upon and default test method 
++ * implementation. Inherited from Data to allow tests to  
++ * access test data as members.
++ */
++template <class Data>
++class test_object : public Data
++{
++public:
++
++    /**
++     * Default constructor
++     */
++    test_object()
++    {
++    }
++
++    void set_test_name(const std::string& current_test_name)
++    {
++        current_test_name_ = current_test_name;
++    }
++
++    const std::string& get_test_name() const
++    {
++        return current_test_name_;
++    }
++
++    /**
++     * Default do-nothing test.
++     */
++    template <int n>
++    void test()
++    {
++        called_method_was_a_dummy_test_ = true;
++    }
++
++    /**
++     * The flag is set to true by default (dummy) test.
++     * Used to detect usused test numbers and avoid unnecessary
++     * test object creation which may be time-consuming depending
++     * on operations described in Data::Data() and Data::~Data().
++     * TODO: replace with throwing special exception from default test.
++     */
++    bool called_method_was_a_dummy_test_;
++
++private:
++
++    std::string current_test_name_;
++};
++
++namespace
++{
++
++/**
++ * Tests provided condition.
++ * Throws if false.
++ */
++void ensure(bool cond)
++{
++    if (!cond)
++    {
++        // TODO: default ctor?
++        throw failure("");
++    }
++}
++
++/**
++ * Tests provided condition.
++ * Throws if true.
++ */
++void ensure_not(bool cond)
++{
++    ensure(!cond);
++}
++
++/**
++ * Tests provided condition.
++ * Throws if false.
++ */
++template <typename T>
++void ensure(const T msg, bool cond)
++{
++    if (!cond)
++    {
++        throw failure(msg);
++    }
++}
++
++/**
++ * Tests provided condition.
++ * Throws if true.
++ */
++template <typename T>
++void ensure_not(const T msg, bool cond)
++{
++    ensure(msg, !cond);
++}
++
++/**
++ * Tests two objects for being equal.
++ * Throws if false.
++ *
++ * NB: both T and Q must have operator << defined somewhere, or
++ * client code will not compile at all!
++ */
++template <class T, class Q>
++void ensure_equals(const char* msg, const Q& actual, const T& expected)
++{
++    if (expected != actual)
++    {
++        std::stringstream ss;
++        ss << (msg ? msg : "") 
++            << (msg ? ":" : "") 
++            << " expected '" 
++            << expected 
++            << "' actual '" 
++            << actual
++            << '\'';
++        throw failure(ss.str().c_str());
++    }
++}
++
++template <class T, class Q>
++void ensure_equals(const Q& actual, const T& expected)
++{
++    ensure_equals<>(0, actual, expected);
++}
++
++/**
++ * Specialization of ensure_equals for double type.
++ * NOTE: unofficial extension added by mloskot
++ */
++template <>
++void ensure_equals<double, double>(const char* msg, const double& actual, const double& expected)
++{
++    const double epsilon = std::numeric_limits<double>::epsilon(); 
++    const double diff = actual - expected;
++
++    if ( !((diff <= epsilon) && (diff >= -epsilon )) )
++    {
++        std::stringstream ss;
++        ss << (msg?msg:"") << (msg?": ":"")
++            << std::scientific << std::showpoint << std::setprecision(16)
++            << "expected " << expected
++            << " actual " << actual
++            << " with precision " << epsilon;
++        throw failure(ss.str().c_str());
++    }
++}
++
++template <>
++void ensure_equals<double, double>(const double& actual, const double& expected)
++{
++    ensure_equals<>(0, actual, expected);
++}
++
++/**
++ * Tests two objects for being at most in given distance one from another.
++ * Borders are excluded.
++ * Throws if false.
++ *
++ * NB: T must have operator << defined somewhere, or
++ * client code will not compile at all! Also, T shall have
++ * operators + and -, and be comparable.
++ */
++template <class T>
++void ensure_distance(const char* msg, const T& actual, const T& expected,
++    const T& distance)
++{
++    if (expected-distance >= actual || expected+distance <= actual)
++    {
++        std::stringstream ss;
++        ss << (msg ? msg : "") 
++            << (msg? ":" : "") 
++            << " expected (" 
++            << expected-distance 
++            << " - "
++            << expected+distance 
++            << ") actual '" 
++            << actual
++            << '\'';
++        throw failure(ss.str().c_str());
++    }
++}
++
++template <class T>
++void ensure_distance(const T& actual, const T& expected, const T& distance)
++{
++    ensure_distance<>(0, actual, expected, distance);
++}
++
++/**
++ * Unconditionally fails with message.
++ */
++void fail(const char* msg = "")
++{
++    throw failure(msg);
++}
++
++} // end of namespace
++
++/**
++ * Walks through test tree and stores address of each
++ * test method in group. Instantiation stops at 0.
++ */
++template <class Test, class Group, int n>
++struct tests_registerer
++{
++    static void reg(Group& group)
++    {
++        group.reg(n, &Test::template test<n>);
++        tests_registerer<Test, Group, n - 1>::reg(group);
++    }
++};
++
++template <class Test, class Group>
++struct tests_registerer<Test, Group, 0>
++{
++    static void reg(Group&)
++    {
++    }
++};
++
++/**
++ * Test group; used to recreate test object instance for
++ * each new test since we have to have reinitialized 
++ * Data base class.
++ */
++template <class Data, int MaxTestsInGroup = 50>
++class test_group : public group_base
++{
++    const char* name_;
++
++    typedef void (test_object<Data>::*testmethod)();
++    typedef std::map<int, testmethod> tests;
++    typedef typename tests::iterator tests_iterator;
++    typedef typename tests::const_iterator tests_const_iterator;
++    typedef typename tests::const_reverse_iterator
++    tests_const_reverse_iterator;
++    typedef typename tests::size_type size_type;
++
++    tests tests_;
++    tests_iterator current_test_;
++
++    /**
++     * Exception-in-destructor-safe smart-pointer class.
++     */
++    template <class T>
++    class safe_holder
++    {
++        T* p_;
++        bool permit_throw_in_dtor;
++
++        safe_holder(const safe_holder&);
++        safe_holder& operator=(const safe_holder&);
++
++    public:
++        safe_holder() 
++            : p_(0),
++              permit_throw_in_dtor(false)
++        {
++        }
++
++        ~safe_holder()
++        {
++            release();
++        }
++
++        T* operator->() const
++        {
++            return p_;
++        }
++        
++        T* get() const
++        {
++            return p_;
++        }
++
++        /**
++         * Tell ptr it can throw from destructor. Right way is to
++         * use std::uncaught_exception(), but some compilers lack
++         * correct implementation of the function.
++         */
++        void permit_throw()
++        {
++            permit_throw_in_dtor = true;
++        }
++
++        /**
++         * Specially treats exceptions in test object destructor; 
++         * if test itself failed, exceptions in destructor
++         * are ignored; if test was successful and destructor failed,
++         * warning exception throwed.
++         */
++        void release()
++        {
++            try
++            {
++                if (delete_obj() == false)
++                {
++                    throw warning("destructor of test object raised"
++                        " an SEH exception");
++                }
++            }
++            catch (const std::exception& ex)
++            {
++                if (permit_throw_in_dtor)
++                {
++                    std::string msg = "destructor of test object raised"
++                        " exception: ";
++                    msg += ex.what();
++                    throw warning(msg);
++                }
++            }
++            catch( ... )
++            {
++                if (permit_throw_in_dtor)
++                {
++                    throw warning("destructor of test object raised an"
++                        " exception");
++                }
++            }
++        }
++
++        /**
++         * Re-init holder to get brand new object.
++         */
++        void reset()
++        {
++            release();
++            permit_throw_in_dtor = false;
++            p_ = new T();
++        }
++
++        bool delete_obj()
++        {
++#if defined(TUT_USE_SEH)
++            __try
++            {
++#endif
++                T* p = p_;
++                p_ = 0;
++                delete p;
++#if defined(TUT_USE_SEH)
++            }
++            __except(handle_seh_(::GetExceptionCode()))
++            {
++                if (permit_throw_in_dtor)
++                {
++                    return false;
++                }
++            }
++#endif
++            return true;
++        }
++    };
++
++public:
++
++    typedef test_object<Data> object;
++
++    /**
++     * Creates and registers test group with specified name.
++     */
++    test_group(const char* name)
++        : name_(name)
++    {
++        // register itself
++        runner.get().register_group(name_,this);
++
++        // register all tests
++        tests_registerer<object, test_group, MaxTestsInGroup>::reg(*this);
++    }
++
++    /**
++     * This constructor is used in self-test run only.
++     */
++    test_group(const char* name, test_runner& another_runner)
++        : name_(name)
++    {
++        // register itself
++        another_runner.register_group(name_, this);
++
++        // register all tests
++        tests_registerer<test_object<Data>, test_group, 
++            MaxTestsInGroup>::reg(*this);
++    };
++
++    /**
++     * Registers test method under given number.
++     */
++    void reg(int n, testmethod tm)
++    {
++        tests_[n] = tm;
++    }
++
++    /**
++     * Reset test position before first test.
++     */
++    void rewind()
++    {
++        current_test_ = tests_.begin();
++    }
++
++    /**
++     * Runs next test.
++     */
++    test_result run_next()
++    {
++        if (current_test_ == tests_.end())
++        {
++            throw no_more_tests();
++        }
++
++        // find next user-specialized test
++        safe_holder<object> obj;
++        while (current_test_ != tests_.end())
++        {
++            try
++            {
++                return run_test_(current_test_++, obj);
++            }
++            catch (const no_such_test&)
++            {
++                continue;
++            }
++        }
++
++        throw no_more_tests();
++    }
++
++    /**
++     * Runs one test by position.
++     */
++    test_result run_test(int n)
++    {
++        // beyond tests is special case to discover upper limit
++        if (tests_.rbegin() == tests_.rend())
++        {
++            throw beyond_last_test();
++        }
++        
++        if (tests_.rbegin()->first < n)
++        {
++            throw beyond_last_test();
++        }
++
++        // withing scope; check if given test exists
++        tests_iterator ti = tests_.find(n);
++        if (ti == tests_.end())
++        {
++            throw no_such_test();
++        }
++
++        safe_holder<object> obj;
++        return run_test_(ti, obj);
++    }
++
++private:
++
++    /**
++     * VC allows only one exception handling type per function,
++     * so I have to split the method.
++     * 
++     * TODO: refactoring needed!
++     */
++    test_result run_test_(const tests_iterator& ti, safe_holder<object>& obj)
++    {
++        std::string current_test_name;
++        try
++        {
++            if (run_test_seh_(ti->second,obj, current_test_name) == false)
++            {
++                throw seh("seh");
++            }
++        }
++        catch (const no_such_test&)
++        {
++            throw;
++        }
++        catch (const warning& ex)
++        {
++            // test ok, but destructor failed
++            if (obj.get())
++            {
++                current_test_name = obj->get_test_name();
++            }
++            test_result tr(name_,ti->first, current_test_name, 
++                test_result::warn, ex);
++            return tr;
++        }
++        catch (const failure& ex)
++        {
++            // test failed because of ensure() or similar method
++            if (obj.get())
++            {
++                current_test_name = obj->get_test_name();
++            }
++            test_result tr(name_,ti->first, current_test_name, 
++                test_result::fail, ex);
++            return tr;
++        }
++        catch (const seh& ex)
++        {
++            // test failed with sigsegv, divide by zero, etc
++            if (obj.get())
++            {
++                current_test_name = obj->get_test_name();
++            }
++            test_result tr(name_, ti->first, current_test_name, 
++                test_result::term, ex);
++            return tr;
++        }
++        catch (const bad_ctor& ex)
++        {
++            // test failed because test ctor failed; stop the whole group
++            if (obj.get())
++            {
++                current_test_name = obj->get_test_name();
++            }
++            test_result tr(name_, ti->first, current_test_name, 
++                test_result::ex_ctor, ex);
++            return tr;
++        }
++        catch (const std::exception& ex)
++        {
++            // test failed with std::exception
++            if (obj.get())
++            {
++                current_test_name = obj->get_test_name();
++            }
++            test_result tr(name_, ti->first, current_test_name, 
++                test_result::ex, ex);
++            return tr;
++        }
++        catch (...)
++        {
++            // test failed with unknown exception
++            if (obj.get())
++            {
++                current_test_name = obj->get_test_name();
++            }
++            test_result tr(name_, ti->first, current_test_name, 
++                test_result::ex);
++            return tr;
++        }
++
++        // test passed
++        test_result tr(name_,ti->first, current_test_name, test_result::ok);
++        return tr;
++    }
++
++    /**
++     * Runs one under SEH if platform supports it.
++     */
++    bool run_test_seh_(testmethod tm, safe_holder<object>& obj, 
++        std::string& current_test_name)
++    {
++#if defined(TUT_USE_SEH)
++        __try
++        {
++#endif
++        if (obj.get() == 0)
++        {
++            reset_holder_(obj);
++        }
++            
++        obj->called_method_was_a_dummy_test_ = false;
++
++#if defined(TUT_USE_SEH)
++
++            __try
++            {
++#endif
++                (obj.get()->*tm)();
++#if defined(TUT_USE_SEH)
++            }
++            __except(handle_seh_(::GetExceptionCode()))
++            {
++                // throw seh("SEH");
++                current_test_name = obj->get_test_name();
++                return false;
++            }
++#endif
++
++        if (obj->called_method_was_a_dummy_test_)
++        {
++            // do not call obj.release(); reuse object
++            throw no_such_test();
++        }
++
++        current_test_name = obj->get_test_name();
++        obj.permit_throw();
++        obj.release();
++#if defined(TUT_USE_SEH)
++        }
++        __except(handle_seh_(::GetExceptionCode()))
++        {
++            return false;
++        }
++#endif
++        return true;
++    }
++
++    void reset_holder_(safe_holder<object>& obj)
++    {
++        try
++        {
++            obj.reset();
++        }
++        catch (const std::exception& ex)
++        {
++            throw bad_ctor(ex.what());
++        }
++        catch (...)
++        {
++            throw bad_ctor("test constructor has generated an exception;"
++                " group execution is terminated");
++        }
++    }
++};
++
++#if defined(TUT_USE_SEH)
++/**
++ * Decides should we execute handler or ignore SE.
++ */
++inline int handle_seh_(DWORD excode)
++{
++    switch(excode)
++    {
++    case EXCEPTION_ACCESS_VIOLATION:
++    case EXCEPTION_DATATYPE_MISALIGNMENT:
++    case EXCEPTION_BREAKPOINT:
++    case EXCEPTION_SINGLE_STEP:
++    case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:
++    case EXCEPTION_FLT_DENORMAL_OPERAND:
++    case EXCEPTION_FLT_DIVIDE_BY_ZERO:
++    case EXCEPTION_FLT_INEXACT_RESULT:
++    case EXCEPTION_FLT_INVALID_OPERATION:
++    case EXCEPTION_FLT_OVERFLOW:
++    case EXCEPTION_FLT_STACK_CHECK:
++    case EXCEPTION_FLT_UNDERFLOW:
++    case EXCEPTION_INT_DIVIDE_BY_ZERO:
++    case EXCEPTION_INT_OVERFLOW:
++    case EXCEPTION_PRIV_INSTRUCTION:
++    case EXCEPTION_IN_PAGE_ERROR:
++    case EXCEPTION_ILLEGAL_INSTRUCTION:
++    case EXCEPTION_NONCONTINUABLE_EXCEPTION:
++    case EXCEPTION_STACK_OVERFLOW:
++    case EXCEPTION_INVALID_DISPOSITION:
++    case EXCEPTION_GUARD_PAGE:
++    case EXCEPTION_INVALID_HANDLE:
++        return EXCEPTION_EXECUTE_HANDLER;
++    };
++
++    return EXCEPTION_CONTINUE_SEARCH;
++}
++#endif
++}
++
++#endif
++
+diff -urN liblas-1.2.1/test/unit/tut/tut_reporter.hpp main/test/unit/tut/tut_reporter.hpp
+--- liblas-1.2.1/test/unit/tut/tut_reporter.hpp	1970-01-01 01:00:00.000000000 +0100
++++ main/test/unit/tut/tut_reporter.hpp	2009-10-02 16:46:36.000000000 +0200
+@@ -0,0 +1,227 @@
++#ifndef TUT_REPORTER
++#define TUT_REPORTER
++
++#include <tut/tut.hpp>
++
++/**
++ * Template Unit Tests Framework for C++.
++ * http://tut.dozen.ru
++ *
++ * @author Vladimir Dyuzhev, Vladimir.Dyuzhev at gmail.com
++ */
++namespace
++{
++    
++std::ostream& operator<<(std::ostream& os, const tut::test_result& tr)
++{
++    switch(tr.result)
++    {
++    case tut::test_result::ok:
++        os << '.';
++        break;
++    case tut::test_result::fail:
++        os << '[' << tr.test << "=F]";
++        break;
++    case tut::test_result::ex_ctor:
++        os << '[' << tr.test << "=C]";
++        break;
++    case tut::test_result::ex:
++        os << '[' << tr.test << "=X]";
++        break;
++    case tut::test_result::warn:
++        os << '[' << tr.test << "=W]";
++        break;
++    case tut::test_result::term:
++        os << '[' << tr.test << "=T]";
++        break;
++    }
++
++    return os;
++}
++
++} // end of namespace
++
++namespace tut
++{
++
++/**
++ * Default TUT callback handler.
++ */
++class reporter : public tut::callback
++{
++    std::string current_group;
++    typedef std::vector<tut::test_result> not_passed_list;
++    not_passed_list not_passed;
++    std::ostream& os;
++
++public:
++
++    int ok_count;
++    int exceptions_count;
++    int failures_count;
++    int terminations_count;
++    int warnings_count;
++
++    reporter() 
++        : os(std::cout)
++    {
++        init();
++    }
++
++    reporter(std::ostream& out) 
++        : os(out)
++    {
++        init();
++    }
++
++    void run_started()
++    {
++        init();
++    }
++
++    void test_completed(const tut::test_result& tr)
++    {
++        if (tr.group != current_group)
++        {
++            os << std::endl << tr.group << ": " << std::flush;
++            current_group = tr.group;
++        }
++
++        os << tr << std::flush;
++        if (tr.result == tut::test_result::ok)
++        {
++            ok_count++;
++        }
++        else if (tr.result == tut::test_result::ex)
++        {
++            exceptions_count++;
++        }
++        else if (tr.result == tut::test_result::ex_ctor)
++        {
++            exceptions_count++;
++        }
++        else if (tr.result == tut::test_result::fail)
++        {
++            failures_count++;
++        }
++        else if (tr.result == tut::test_result::warn)
++        {
++            warnings_count++;
++        }
++        else
++        {
++            terminations_count++;
++        }
++
++        if (tr.result != tut::test_result::ok)
++        {
++            not_passed.push_back(tr);
++        }
++    }
++
++    void run_completed()
++    {
++        os << std::endl;
++
++        if (not_passed.size() > 0)
++        {
++            not_passed_list::const_iterator i = not_passed.begin();
++            while (i != not_passed.end())
++            {
++                tut::test_result tr = *i;
++
++                os << std::endl;
++
++                os << "---> " << "group: " << tr.group
++                << ", test: test<" << tr.test << ">"
++                << (!tr.name.empty() ? (std::string(" : ") + tr.name) : std::string())
++                << std::endl;
++
++                os << "     problem: ";
++                switch(tr.result)
++                {
++                case test_result::fail:
++                    os << "assertion failed" << std::endl;
++                    break;
++                case test_result::ex:
++                case test_result::ex_ctor:
++                    os << "unexpected exception" << std::endl;
++                    if( tr.exception_typeid != "" )
++                    {
++                        os << "     exception typeid: "
++                        << tr.exception_typeid << std::endl;
++                    }
++                    break;
++                case test_result::term:
++                    os << "would be terminated" << std::endl;
++                    break;
++                case test_result::warn:
++                    os << "test passed, but cleanup code (destructor) raised"
++                        " an exception" << std::endl;
++                    break;
++                default:
++                    break;
++                }
++
++                if (!tr.message.empty())
++                {
++                    if (tr.result == test_result::fail)
++                    {
++                        os << "     failed assertion: \"" << tr.message << "\"" 
++                            << std::endl;
++                    }
++                    else
++                    {
++                        os << "     message: \"" << tr.message << "\"" 
++                            << std::endl;
++                    }
++                }
++
++                ++i;
++            }
++        }
++
++        os << std::endl;
++
++        os << "tests summary:";
++        if (terminations_count > 0)
++        {
++            os << " terminations:" << terminations_count;
++        }
++        if (exceptions_count > 0)
++        {
++            os << " exceptions:" << exceptions_count;
++        }
++        if (failures_count > 0)
++        {
++            os << " failures:" << failures_count;
++        }
++        if (warnings_count > 0)
++        {
++            os << " warnings:" << warnings_count;
++        }
++        os << " ok:" << ok_count;
++        os << std::endl;
++    }
++
++    bool all_ok() const
++    {
++        return not_passed.empty();
++    }
++
++private:
++
++    void init()
++    {
++        ok_count = 0;
++        exceptions_count = 0;
++        failures_count = 0;
++        terminations_count = 0;
++        warnings_count = 0;
++        not_passed.clear();
++    }
++};
++
++}
++
++#endif
+diff -urN liblas-1.2.1/test/unit/tut/tut_restartable.hpp main/test/unit/tut/tut_restartable.hpp
+--- liblas-1.2.1/test/unit/tut/tut_restartable.hpp	1970-01-01 01:00:00.000000000 +0100
++++ main/test/unit/tut/tut_restartable.hpp	2009-10-02 16:46:36.000000000 +0200
+@@ -0,0 +1,394 @@
++#ifndef TUT_RESTARTABLE_H_GUARD
++#define TUT_RESTARTABLE_H_GUARD
++
++#include <tut/tut.hpp>
++#include <fstream>
++#include <iostream>
++#include <stdexcept>
++
++/**
++ * Template Unit Tests Framework for C++.
++ * http://tut.dozen.ru
++ *
++ * Optional restartable wrapper for test_runner. Allows to restart test runs
++ * finished due to abnormal test application termination (such as segmentation
++ * fault or math error).
++ *
++ * @author Vladimir Dyuzhev, Vladimir.Dyuzhev at gmail.com
++ */
++
++namespace tut
++{
++    
++namespace util
++{
++    
++/**
++ * Escapes non-alphabetical characters in string.
++ */
++std::string escape(const std::string& orig)
++{
++    std::string rc;
++    std::string::const_iterator i,e;
++    i = orig.begin();
++    e = orig.end();
++
++    while (i != e)
++    {
++        if ((*i >= 'a' && *i <= 'z') ||
++                (*i >= 'A' && *i <= 'Z') ||
++                (*i >= '0' && *i <= '9') )
++        {
++            rc += *i;
++        }
++        else
++        {
++            rc += '\\';
++            rc += ('a'+(((unsigned int)*i) >> 4));
++            rc += ('a'+(((unsigned int)*i) & 0xF));
++        }
++
++        ++i;
++    }
++    return rc;
++}
++
++/**
++ * Un-escapes string.
++ */
++std::string unescape(const std::string& orig)
++{
++    std::string rc;
++    std::string::const_iterator i,e;
++    i = orig.begin();
++    e = orig.end();
++
++    while (i != e)
++    {
++        if (*i != '\\')
++        {
++            rc += *i;
++        }
++        else
++        {
++            ++i;
++            if (i == e)
++            {
++                throw std::invalid_argument("unexpected end of string");
++            }
++            unsigned int c1 = *i;
++            ++i;
++            if (i == e)
++            {
++                throw std::invalid_argument("unexpected end of string");
++            }
++            unsigned int c2 = *i;
++            rc += (((c1 - 'a') << 4) + (c2 - 'a'));
++        }
++
++        ++i;
++    }
++    return rc;
++}
++
++/**
++ * Serialize test_result avoiding interfering with operator <<.
++ */
++void serialize(std::ostream& os, const tut::test_result& tr)
++{
++    os << escape(tr.group) << std::endl;
++    os << tr.test << ' ';
++    switch(tr.result)
++    {
++    case test_result::ok:
++        os << 0;
++        break;
++    case test_result::fail:
++        os << 1;
++        break;
++    case test_result::ex:
++        os << 2;
++        break;
++    case test_result::warn:
++        os << 3;
++        break;
++    case test_result::term:
++        os << 4;
++        break;
++    default:
++        throw std::logic_error("operator << : bad result_type");
++    }
++    os << ' ' << escape(tr.message) << std::endl;
++}
++
++/**
++ * deserialization for test_result
++ */
++void deserialize(std::istream& is, tut::test_result& tr)
++{
++    std::getline(is,tr.group);
++    if (is.eof())
++    {
++        throw tut::no_more_tests();
++    }
++    tr.group = unescape(tr.group);
++
++    tr.test = -1;
++    is >> tr.test;
++    if (tr.test < 0)
++    {
++        throw std::logic_error("operator >> : bad test number");
++    }
++
++    int n = -1;
++    is >> n;
++    switch(n)
++    {
++    case 0:
++        tr.result = test_result::ok;
++        break;
++    case 1:
++        tr.result = test_result::fail;
++        break;
++    case 2:
++        tr.result = test_result::ex;
++        break;
++    case 3:
++        tr.result = test_result::warn;
++        break;
++    case 4:
++        tr.result = test_result::term;
++        break;
++    default:
++        throw std::logic_error("operator >> : bad result_type");
++    }
++
++    is.ignore(1); // space
++    std::getline(is,tr.message);
++    tr.message = unescape(tr.message);
++    if (!is.good())
++    {
++        throw std::logic_error("malformed test result");
++    }
++}
++};
++
++/**
++ * Restartable test runner wrapper.
++ */
++class restartable_wrapper
++{
++    test_runner& runner_;
++    callback* callback_;
++
++    std::string dir_;
++    std::string log_; // log file: last test being executed
++    std::string jrn_; // journal file: results of all executed tests
++
++public:
++    /**
++     * Default constructor.
++     * @param dir Directory where to search/put log and journal files
++     */
++    restartable_wrapper(const std::string& dir = ".")
++        : runner_(runner.get()), 
++          callback_(0), 
++          dir_(dir)
++    {
++        // dozen: it works, but it would be better to use system path separator
++        jrn_ = dir_ + '/' + "journal.tut";
++        log_ = dir_ + '/' + "log.tut";
++    }
++
++    /**
++     * Stores another group for getting by name.
++     */
++    void register_group(const std::string& name, group_base* gr)
++    {
++        runner_.register_group(name,gr);
++    }
++
++    /**
++     * Stores callback object.
++     */
++    void set_callback(callback* cb)
++    {
++        callback_ = cb;
++    }
++
++    /**
++     * Returns callback object.
++     */
++    callback& get_callback() const
++    {
++        return runner_.get_callback();
++    }
++
++    /**
++     * Returns list of known test groups.
++     */
++    groupnames list_groups() const
++    {
++        return runner_.list_groups();
++    }
++
++    /**
++     * Runs all tests in all groups.
++     */
++    void run_tests() const
++    {
++        // where last run was failed
++        std::string fail_group;
++        int fail_test;
++        read_log_(fail_group,fail_test);
++        bool fail_group_reached = (fail_group == "");
++
++        // iterate over groups
++        tut::groupnames gn = list_groups();
++        tut::groupnames::const_iterator gni,gne;
++        gni = gn.begin();
++        gne = gn.end();
++        while (gni != gne)
++        {
++            // skip all groups before one that failed
++            if (!fail_group_reached)
++            {
++                if (*gni != fail_group)
++                {
++                    ++gni;
++                    continue;
++                }
++                fail_group_reached = true;
++            }
++
++            // first or restarted run
++            int test = (*gni == fail_group && fail_test >= 0) ? fail_test + 1 : 1;
++            while(true)
++            {
++                // last executed test pos
++                register_execution_(*gni,test);
++
++                try
++                {
++                    tut::test_result tr = runner_.run_test(*gni,test);
++                    register_test_(tr);
++                }
++                catch (const tut::beyond_last_test&)
++                {
++                    break;
++                }
++                catch(const tut::no_such_test&)
++                {
++                    // it's ok
++                }
++
++                ++test;
++            }
++
++            ++gni;
++        }
++
++        // show final results to user
++        invoke_callback_();
++
++        // truncate files as mark of successful finish
++        truncate_();
++    }
++
++private:
++    /**
++     * Shows results from journal file.
++     */
++    void invoke_callback_() const
++    {
++        runner_.set_callback(callback_);
++        runner_.get_callback().run_started();
++
++        std::string current_group;
++        std::ifstream ijournal(jrn_.c_str());
++        while (ijournal.good())
++        {
++            // read next test result
++            try
++            {
++                tut::test_result tr;
++                util::deserialize(ijournal,tr);
++                runner_.get_callback().test_completed(tr);
++            }
++            catch (const no_more_tests&)
++            {
++                break;
++            }
++        }
++
++        runner_.get_callback().run_completed();
++    }
++
++    /**
++     * Register test into journal.
++     */
++    void register_test_(const test_result& tr) const
++    {
++        std::ofstream ojournal(jrn_.c_str(), std::ios::app);
++        util::serialize(ojournal, tr);
++        ojournal << std::flush;
++        if (!ojournal.good())
++        {
++            throw std::runtime_error("unable to register test result in file "
++                + jrn_);
++        }
++    }
++
++    /**
++     * Mark the fact test going to be executed
++     */
++    void register_execution_(const std::string& grp, int test) const
++    {
++        // last executed test pos
++        std::ofstream olog(log_.c_str());
++        olog << util::escape(grp) << std::endl << test << std::endl << std::flush;
++        if (!olog.good())
++        {
++            throw std::runtime_error("unable to register execution in file "
++                + log_);
++        }
++    }
++
++    /**
++     * Truncate tests.
++     */
++    void truncate_() const
++    {
++        std::ofstream olog(log_.c_str());
++        std::ofstream ojournal(jrn_.c_str());
++    }
++
++    /**
++     * Read log file
++     */
++    void read_log_(std::string& fail_group, int& fail_test) const
++    {
++        // read failure point, if any
++        std::ifstream ilog(log_.c_str());
++        std::getline(ilog,fail_group);
++        fail_group = util::unescape(fail_group);
++        ilog >> fail_test;
++        if (!ilog.good())
++        {
++            fail_group = "";
++            fail_test = -1;
++            truncate_();
++        }
++        else
++        {
++            // test was terminated...
++            tut::test_result tr(fail_group, fail_test, "", tut::test_result::term);
++            register_test_(tr);
++        }
++    }
++};
++
++}
++
++#endif
++

Added: liblas/trunk/debian/patches/series
===================================================================
--- liblas/trunk/debian/patches/series	                        (rev 0)
+++ liblas/trunk/debian/patches/series	2009-10-06 16:51:32 UTC (rev 2520)
@@ -0,0 +1,2 @@
+# no patches
+missing.diff

Added: liblas/trunk/debian/rules
===================================================================
--- liblas/trunk/debian/rules	                        (rev 0)
+++ liblas/trunk/debian/rules	2009-10-06 16:51:32 UTC (rev 2520)
@@ -0,0 +1,9 @@
+#!/usr/bin/make -f
+
+include /usr/share/cdbs/1/rules/debhelper.mk
+include /usr/share/cdbs/1/class/autotools.mk
+include /usr/share/cdbs/1/rules/patchsys-quilt.mk
+
+DEB_CONFIGURE_EXTRA_FLAGS = --with-gdal=/usr/bin/gdal-config --with-geotiff=/usr
+DEB_MAKE_CHECK_TARGET = check
+


Property changes on: liblas/trunk/debian/rules
___________________________________________________________________
Added: svn:executable
   + *

Added: liblas/trunk/debian/watch
===================================================================
--- liblas/trunk/debian/watch	                        (rev 0)
+++ liblas/trunk/debian/watch	2009-10-06 16:51:32 UTC (rev 2520)
@@ -0,0 +1,6 @@
+# Rename this file to "watch" and then you can run the "uscan" command
+# to check for upstream updates and more.
+# See uscan(1) for format
+# Compulsory line, this is a version 3 file
+version=3
+http://liblas.org/wiki/1.2.1 http://liblas.org/raw-attachment/wiki/1.2.1/liblas-src-([\d\.]+).tar.bz2




More information about the Pkg-grass-devel mailing list