Commit Graph

321 Commits

Author SHA1 Message Date
Andrey Semashev
a6eb102f3d Added missing status inspection functions for directory_entry and error_code.
Also, removed incorrect noexcept markup for the overloads not taking error_code.
2020-06-04 23:42:32 +03:00
Antons Jeļkins
5e54f77425 is_symlink(directory_entry) should use symlink_status().
This fixes a problem that is_symlink(directory_entry) always returns
false, even if directory_entry is indeed a symlink. This change makes
is_symlink(directory_entry) behave the same as is_symlink(path) and
use symlink_status().
2020-06-04 21:59:00 +02:00
Andrey Semashev
559b0c291a In copy, support symlink creation when target directory is not current.
When the source path is not absolute and copy_options::create_symlinks is
specified, deduce the relative path from the target location to the source
file to create a symlink. This allows to copy to a path that is not the current
path.

Also, added absolute overloads taking error_code argyment.

Also, when current_path() is used as a default argument to other operations,
and the operation also accepts error_code, use current_path(ec) to report
errors through the error code rather than throwing an exception.

Also, added a test for copy operation.
2020-05-11 15:10:23 +03:00
Andrey Semashev
448c145b54 Added copyright. 2020-05-11 00:28:24 +03:00
Andrey Semashev
80709a9411 Reworked copy operation. Added create_directory with two paths.
The updated copy implementation follows C++20 [fs.op.copy] definition
and implements additional copy options.

The new create_directory overloads accepting two paths are functionally
similar to copy_directory, but are compliant with C++20
[fs.op.create.directory]. The copy_directory operation has been deprecated
in favor of create_directory.
2020-05-10 03:02:32 +03:00
Andrey Semashev
4e6317e4b0 Make copy_file return bool, indicating whether file has been copied.
This corresponds to C++20.
2020-05-09 19:38:50 +03:00
Andrey Semashev
ac02dbed2e Added support for copy_options::update_existing to copy_file. 2020-05-09 19:19:33 +03:00
Andrey Semashev
dea37d899e Added support for copy_options::skip_existing. 2020-05-08 19:09:39 +03:00
Andrey Semashev
ba864a1727 Removed trailing comma in enum.
Fixes compiler warnings.

Closes https://github.com/boostorg/filesystem/issues/143.
2020-05-06 15:39:41 +03:00
Andrey Semashev
f199152b7d Refactored copy_file, added copy_options, deprecated copy_option.
The copy_file operation implementation has been inlined into the
detail::copy_file function. The part that copies the file body has been
extracted to a separate function, so that addition of specialized copy
implementations later is possible.

Added copy_options enum, which reflects the enum from C++20. Currently,
only overwrite_existing option is supported. Other options will be added
later.

The old enum copy_option is deprecated in favor of copy_options.

Updated docs to reflect recent changes to copy_file behavior.
2020-05-05 18:34:20 +03:00
Andrey Semashev
4f3d762a31 Added BOOST_OVERRIDE markup for virtual methods.
Closes https://github.com/boostorg/filesystem/issues/135.
2020-05-05 14:54:06 +03:00
Glen Fernandes
45e06be049 Include the public quoted header from IO 2019-12-16 19:43:21 -05:00
Andrey Semashev
dfd4387c7e Don't define static constants when C++17 inline variables are enabled.
This silences compiler warnings about using deprecated language features,
which is out-of-class definition of static constant data members.

Closes https://github.com/boostorg/filesystem/pull/121.
2019-10-05 23:31:38 +03:00
Andrey Semashev
03c797998f Added directory_options::skip_dangling_symlinks.
The new option allows to skip dangling directory symlinks when iterating
over a directory using recursive_directory_iterator.

This also updates the operations_test, which failed spuriously because
the test created dangling symlinks for some of its checks. Since the order
of iteration is undefined, the tests sometimes passed, when the dangling
symlinks were encountered late during the iteration.
2019-08-20 19:02:56 +03:00
Andrey Semashev
9a14c37d6f Added directory_options. Set recursive_dir_iterator to end or pop on errors.
The directory_options enum reflects the same-named enum from C++20. It is now
supported by both directory_iterator and recursive_directory_iterator. In
particular, both iterators now support skip_permission_denied option.

recursive_directory_iterator is now set to end by default on errors, as
required by C++20. An additional directory_options::pop_on_error policy
is added to allow the iterator recover from an error. When this option is
specified and an error occurs, the iterator repeatedly pops the recursion level
until the pop completes successfully or the end state is reached.

recursive_directory_iterator that have standard counterparts (level,
no_push_pending, no_push_request and no_push) are now deprecated and can be
removed by defining BOOST_FILESYSTEM_NO_DEPRECATED. These members will be
removed in a future release.

Docs and tests updated accordingly. Also, in docs reconstructed release history
for the past releases from Boost release notes.

Fixes https://github.com/boostorg/filesystem/issues/112
Fixes https://github.com/boostorg/filesystem/issues/113
2019-08-02 19:43:46 +03:00
Andrey Semashev
c758552338 Moved directory tools to separate files. Reworked readdir_r support.
Directory iteration components were moved to separate files to simplify
maintenance of operations.hpp/cpp.

directory_iterator implementation on POSIX platforms has been reworked
to only allocate internal buffer when readdir_r is used. When readdir
is used, the dirent structure returned by readdir is used directly, which
eliminates the potential of buffer overrun in case if some directory name
exceeds the buffer size. This also removes the need to copy dirent members
into the buffer, which improves performance and simplifies maintenance.

For buffer size we now use the max path size as opposed to max filename
size. This is done to minimize the possibility of buffer overruns when
readdir_r is used.

On Windows, use Boost.WinAPI to configure the default target Windows version.
This removes WINVER and _WIN32_WINNT defines in Boost.Filesystem as these
macros should be defined by Boost.WinAPI now.

Additionally, exception.hpp and directory.hpp includes in operations.hpp are
marked as deprecated as operations.hpp do not need those components. Users
are encouraged to include the new headers explicitly in their code, as needed.
2019-08-01 20:34:39 +03:00
Andrey Semashev
400f02590c Fixed linking on MinGW and Cygwin.
GCC on Windows doesn't export vtable for filesystem_error if its destructor
is exported.
2019-08-01 14:52:07 +03:00
Andrey Semashev
f4769bd4c7 Extracted file_status and error handling helpers to separate headers.
This simplifies maintenance of the operations.hpp/cpp files.

Also, moved BOOST_FILESYSTEM_SOURCE definition to the build system files
instead of defining it in every source file.
2019-07-31 23:12:56 +03:00
Andrey Semashev
68ec5b1fb6 Extracted filesystem_error to a separate header and translation unit.
This simplifies maintenance of the operations.hpp header and should also
reduce size of the generated users' code.
2019-07-31 22:58:40 +03:00
Andrey Semashev
2376d16e24 Nonessential corrections in asserts and code formatting. 2019-07-31 20:26:21 +03:00
Andrey Semashev
812cb9bad3 Marked hash_value for path noexcept. 2019-06-19 15:09:39 +03:00
Andrey Semashev
701ae40549 Fixed rvalue-aware operator/ return type, leverage NRVO.
The rvalue-aware operator/ needs to return an rvalue, not an rvalue reference
so that binding its result to a const reference in the caller's code doesn't
leave a dangling reference. This hampers operator/ efficiency to some degree,
but it is still better than the non-rvalue-aware version as it still allows
to avoid copying the path body.

The non-rvalue-aware operator/ is now creating an automatic variable which will
be returned to leverage NRVO. The previous implementation used to return
an lvalue reference to a temporary, which did not match NRVO criteria[1].

Fixes https://github.com/boostorg/filesystem/issues/110.
Closes https://github.com/boostorg/filesystem/pull/111.

[1]: https://en.cppreference.com/w/cpp/language/copy_elision
2019-06-19 14:57:23 +03:00
Andrey Semashev
b9a6648b93 Fixed a typo in the comment. 2019-04-16 12:17:05 +03:00
Andrey Semashev
192866fb0e
Merge pull request #24 from muggenhor/wince-missing-current-directory
WinCE has no current directory
2019-04-16 12:16:19 +03:00
Marcel Raad
1cf17855b2
Fix -Wextra-semi clang warnings
Remove superfluous semicola.
2019-02-25 10:26:56 +01:00
Andrey Semashev
015d414fca Fixed use of std::move in a constexpr condtructor. Formatting changes.
std::move is not constexpr in C++11, so we can't use it in a constexpr move
constructor. Also, directory_entry move constructor now uses move constructors
of its data members instead of assignment.

Done some formatting changes to make the code look a bit more unified.
2018-12-11 18:03:19 +03:00
Andrey Semashev
f6306bae0f Silence MSVC warning C4250 about overriding virtual functions from iostream base classes. 2018-12-09 18:43:40 +03:00
Andrey Semashev
4e639c353e Fixed compilation in C++03 mode caused by incorrect casts of scoped enums. 2018-12-09 17:10:22 +03:00
Andrey Semashev
3a90694383 Export dir_entry members instead of the class. Move rdit impl to the library.
This should silence MSVC warnings about path not being exported when used in
directory_entry. This should also remove unnecessary references to the library
for the inline members of directory_entry.

Removed library exports markup for file_status as there were nothing to export.
Also marked its methods constexpr.

Moved recursive_directory_iterator implementation to the library. MSVC should
not issue warnings since we're only exporting member functions.

Updated BOOST_SCOPED_ENUM emulation use to the more recent macros. Made sure
recursive_directory_iterator implementation uses binary compatible
representation for scoped enums between the library and user's code regardless
of C++ versions used.
2018-12-09 15:51:35 +03:00
Andrey Semashev
1428b4f55c Changed the way path exports are declared. Some code cleanup.
Instead of exporting the whole path class, export only the functions that
are actually implemented in the shared library and leave the rest inline.
Also, move the definition of the static constants of the path class to
the header to avoid problems with exporting them from the shared library,
as observed with various MSVC versions and also gcc 7.3 from MinGW-w64.

Also, reduced code duplication and added a more efficient operator/
implementation when rvalue references are available.
2018-12-09 01:26:24 +03:00
Andrey Semashev
6ffe7f09cc Updated status functions for directory_entry. 2018-11-24 21:33:56 +03:00
Andrey Semashev
f8a3d096f7
Merge pull request #78 from datadiode/develop
path.hpp: Unify coding style of path_traits::convert() calls
2018-11-24 21:06:09 +03:00
emmett-b
4731ce79de Added directory_entry overloads for status query functions 2018-11-24 20:52:12 +03:00
Andrey Semashev
8de281773f Added definitions for path static constants.
This fixes compilation if user's code attempts to ODR-use the constants.

Fixes https://svn.boost.org/trac10/ticket/12759.
Closes https://github.com/boostorg/filesystem/pull/40.
2018-11-24 20:34:44 +03:00
Andrey Semashev
8e4a631231 Fixed termination on OOM in directory iterators. Added non-throwing rdit::pop().
When an out-of-memory condition is detected (either by catching std::bad_alloc
or by receiving null on memory allocation), do not propagate the exception and
set an appropriate error code instead. This fix only concerns directory_iterator
and recursive_directory_iterator for now; it is possible that other operations
remain not ready for memory allocation failures.

Also, added recursive_directory_iterator::pop() that returns error code instead
of throwing an exception. This overload is present in C++17.

Fixes https://github.com/boostorg/filesystem/issues/58.
Closes https://github.com/boostorg/filesystem/pull/63.
2018-11-24 18:36:54 +03:00
Andrey Semashev
498a090b53 Added support for movability to directory iterators, code cleanup.
Switched directory_iterator and recursive_directory_iterator to use
intrusive_ptr internally to reduce the iterator size and avoid virtual
function calls. The iterators now support move semantics. Fixed a warning
about deprecated in C++20 implicit generation of copy constructor and
assignment operator if there is a user-defined destructor.

Also updated a few includes to refer to non-deprecated headers. Trimmed
trailing spaces in headers and sources.
2018-11-24 15:06:01 +03:00
Peter Dimov
c0528ab880 Extend bitmask enum types to 32 bits to placate ubsan 2018-09-06 02:22:58 +03:00
Peter Dimov
d32190fab7 Remove dependency on Range 2018-09-05 08:14:32 +03:00
Peter Dimov
f13aa18a93 Fix BOOST_FOREACH support; add test 2018-09-05 07:59:20 +03:00
datadiode
c155593fe2 path.hpp: Fix a few cases of trying to dereference (w)string::end() 2018-07-14 09:20:13 +02:00
Beman
170f483655 Add test/config_info.cpp to increase macro state reporting in hopes of easing debugging on remote machines. 2017-01-08 15:23:42 -05:00
Beman
5004d7b177 Fix #12578 - Bug in directory_iterator, recursive_directory_iterator, equality testing of copied iterator also at end. 2016-11-23 09:21:32 -05:00
Beman
48faf2b1ee Add deprecated path::generic() 2016-11-22 16:51:45 -05:00
Felix Bruns
fcb98ee37e Rename generic() to generic_path(), since generic is a keyword in C++/CX.
When using Boost.Filesystem from a project compiled as C++/CX code,
compilation fails with a syntax error, because generic is a keyword.

    error C2059: syntax error: 'generic'

See section "Generic interfaces" in C++/CX here:

    https://msdn.microsoft.com/en-us/library/hh755792.aspx
2016-04-27 14:11:08 +02:00
Beman
de527c6862 Refactor push_directory() logic so it is easier to reason about. 2016-04-18 10:41:07 -04:00
Giel van Schijndel
413240cc09 WinCE has no current directory
So reject attempts to change it and treat the root as the current
directory.
2015-12-16 18:09:33 +01:00
Beman
2f6391b931 Add class path constexpr constants separator and dot of the type appropriate for the platform, and add class path member query functions filename_is_dot() and filename_is_dot_dot(). These add convenience and the implementations may be more efficient that user coded equivalent functions. Also add detail functions is_directory_separator() and is_element_separator(), and replace all uses of local is_separator() in path.cpp with detail::is_directory_separator(). 2015-12-01 10:17:45 -05:00
Beman
3c344a5f0b Revert to lexical functions back to being members of class path. This is not the time to redesign the library's lexical vs operational conventions. It would break existing users mental model of lexical vs operational.
See doc/relative_proposal.html#Add-lexical-functions for additional rationale.
2015-10-25 13:28:49 -04:00
Beman
06968ee032 Fix pull request 17, 'some_function() noexcept = default;' from Antony Polukhin, by never relying on "= default". Antony's pull request would have fixed the problem interaction with noexcept by eliminating the noexcept. I preferred to retain the noexcept rather than the "= default", as applying "= default" has been exceedingly troublesome for both VC++ and GCC due to interactions between the two C++11 features. GCC interactions varied not just for the version, but also for the platform. 2015-10-08 07:19:55 -04:00
Beman
c026d612f2 String file feature cleanup: Add string_file.hpp to filesystem.hpp. Change string_file.hpp to use boost/filesystem/fstream.hpp for I/O. Add string_file_tests function to operations_unit_test.cpp. 2015-10-07 10:11:18 -04:00
Beman Dawes
719fc1f18d Merge pull request #16 from MarcelRaad/patch-1
Remove unused deprecated include
2015-09-16 15:28:00 -04:00
Beman
f4644ef881 Define BOOST_FILESYSTEM_NO_CXX11_DEFAULTED_RVALUE_REFS for GCC <= 4; GCC 4.8.5 was failing on FreeBSD although not on other platforms. Since move semantics is an optimization, it doesn't break anything to be conservative. 2015-09-15 07:38:28 -04:00
Marcel Raad
53c502cb47 Remove unused deprecated include
The comment in boost/iterator.hpp mentions that the file is obsolete and will be deprecated, and it is not used anyway.
2015-09-13 21:40:29 +02:00
Beman
9befbd2448 Fix bug in file_status and recursive_directory_iterator: C++ turns an explicit constructor with all arguments except first defaulted into non-explicit single argument constructor. 2015-09-12 09:27:39 -04:00
Beman
2d4035269b Add GCC 4.4 to compilers that did not support defaulted rvalue refs. 2015-09-11 15:11:46 -04:00
Beman
320423af98 Added size() function to class path. Resolves #6874, Path should have a size() member function. 2015-09-08 16:46:05 -04:00
Beman
9d5415d579 Add move constructor, move assignment, where called for in Filesystem TS. 2015-09-06 21:18:01 -04:00
Beman
353851e144 First pass of applying BOOST_NOEXCEPT. For recursive_directory_iterator only, began process of supporting both old and new names for functions whose name changed in the Filesystem TS. Planning started for adding move constructors and move assignments per the TS. 2015-09-06 08:30:58 -04:00
Beman
1c82e5d39e Apply BOOST_NOEXCEPT, and a few other drive by corrections. 2015-09-05 17:55:14 -04:00
Beman
5610f974be Merge branch 'feature/relative2' into develop 2015-09-04 15:24:22 -04:00
Beman
8cd5522161 Initial implementation and docs for path::reverse_iterator. 2015-09-04 11:25:22 -04:00
Beman
efe50fad52 Work issue, but no fix yet 2015-08-30 16:32:44 -04:00
Beman
0ab46a3315 Fix #9454, Boost Filesystem [library build] not compiling when BOOST_FILESYSTEM_NO_DEPRECATED is defined, by applying a patch submitted by Makesim 2015-08-29 09:57:09 -04:00
Beman
23759ba8ec Add lexically_proximate and proximate functions. 2015-08-25 15:05:17 -04:00
Beman
732609a2da Change member normal() and relative() to non-member lexically_normal() and lexically_relative(). See doc/relative_proposal.html#Add-lexical-functions-as-non-members for rationale. 2015-08-23 09:33:21 -04:00
Beman
cb11081a7d Finish initial proposed wording section of relative_proposal.html. Drive-by tweaks to other stuff. Add example/directory_symlink_parent_resolution.cpp, include/boost/filesystem/string_file.hpp, and related infrastructure. 2015-08-12 17:26:03 -04:00
Beman
7d6429554a Bring operational functions weakly_canonical() and relative() up to production quality: move implementations to operations.cpp, add error handling, replace tail recursion with iteration, rename weak_canonical to weakly_canonical. The weak_canonical name grated on me every type I used it. 2015-08-10 07:10:59 -04:00
Beman
2101376680 Replace tail recursion with iteration. 2015-08-09 09:53:05 -04:00
Beman
34dd2c7718 Add a new path member function: "path normal() const;" and change the old deprecated normalize() non-const function to be implemented in terms of the new function. The implementation remains the same, except for returning by value rather than modifying in place. Motivation: Jamie Alsop has identified removal of redundant .. and . elements (i.e. normalization) as a need closely related to the relative path functionality requested by numerous Boost issue requests, the C++ LWG, and NB comments to the Filesystem TS. Given that both lexical and operational relative functionality is needed, there is less risk in providing a well-documented path::normal() lexical function. 2015-08-08 16:29:44 -04:00
Beman
6e92c9a8b2 Add experimental path::generic() function returning generic formatted (i.e. separators are forward slashes). Motivation: may be simpler than having a family of generic_*string functions. 2015-08-08 12:11:35 -04:00
Beman
5b8b9db1c9 Cleanup missed edits. 2015-08-08 06:18:08 -04:00
Beman
8a8c8abecc Rename semi_canonical() to weak_canonical. The STL uses "weak" to denote reduced requirements. 2015-08-08 05:56:55 -04:00
Beman
9706dbb9b1 Revert "Change the name of path::relative to path::relative_to to distinguish it a bit from path::relative_path."
This reverts commit d5fb8323f8.

Leave possible renaming for bikeshed discussions. KISS.
2015-08-08 05:44:30 -04:00
Beman
d5fb8323f8 Change the name of path::relative to path::relative_to to distinguish it a bit from path::relative_path. 2015-08-07 16:50:47 -04:00
Beman
6da5f657fb Remove lexically_relative() free function. Add path::rel 2015-08-07 16:41:06 -04:00
Beman
dc794ea95b Merge branch 'feature/relative' into feature/relative2 2015-08-06 08:08:46 -04:00
Beman
eb9cac384e Edit comments to clarify dependencies. 2015-01-10 11:35:47 -05:00
Beman
c0b5754ab8 Fix ticket #10388, an occasional failure of temp_directory_path to deal correctly with the trailing separator. A path member function remove_trailing_separator() was added publicly since this may be useful to users. 2015-01-10 09:31:44 -05:00
Beman
bb5a0ff09d Clear warnings, including new warnings from VC++ 2015 preview. 2015-01-05 10:34:24 -05:00
Beman
0dfb7171fb Finalize issue reporting before requesting comments. Also fix some inspect issues. 2014-12-29 09:18:12 -05:00
Beman
490c2c3298 For all path_traits convert() and dispatch() functions provide two overloads, one with a "const codecvt_type&" argument, and one without. The overload without a codecvt argument calls path::codecvt() iff a conversion actually needs to be performed. Change all uses of path_traits convert() and dispatch() functions call the appropriate overload, rather than calling with path::codecvt() as a default. This limits the impact of locale("") initialization failures on Linux and other non-BSD POSIX systems to programs that actually depend on locale(""). It further ensures that exceptions thrown as a result of such failures occur after main() has started, and so can be caught. 2014-10-27 19:20:17 -04:00
Beman
1262a9f0d2 Fix C++03 compile failures for previous commit. 2014-10-24 11:46:50 -04:00
Beman
d57509c558 For compiled operational function detail::copy_file, pass detail::copy_options, a plain-old enum, rather than a BOOST_SCOPED_ENUM. We cannot pass a BOOST_SCOPED_ENUM to a compled function because it will result in an undefined reference if the library is compiled with -std=c++0x but the use is compiled in C++03 mode, or vise versa. Fixes tickets #6124, #6779, and #10038. 2014-10-24 10:58:42 -04:00
Beman
76d209567f Refactor dot_path and dot_dot_path into functions, to prevent path constructor being called before main() starts. In theory that is harmless when path::value_type is the same as value_type of the ctor Source, but eliminating it simplifies reasoning about program correctness. 2014-08-22 11:31:42 -04:00
Beman
4d64f34c01 Add non-const overloads for the value_type and string_type to avoid calling codecvt(). Fixes ticket #9219. 2014-08-17 09:22:32 -04:00
Beman
750a82e20d Revert "Merge branch 'develop' of github.com:boostorg/filesystem into develop"
This reverts commit 4610afc49e, reversing
changes made to 6623bde4fe.
2014-08-05 09:16:57 -04:00
Beman
4635e93d02 Add move semantics to file_status per DTS. Fix incorrect synonym in perms. Add file_status constructor test cases. 2014-07-24 15:38:48 -04:00
Beman
f0ce9bd649 Missed a few perms value changes that were on next DTS page. 2014-07-23 15:58:04 -04:00
Beman
038bce7e2d DTS: enum perms changed to enum class perms. Constant names have changed; synonyms provided. 2014-07-23 15:35:44 -04:00
Beman
21a66a331a Update enum class file_type constant values per DTS. 2014-07-23 14:16:53 -04:00
Beman
98b29a72e5 Fix-up of prior merge conflict resolution from develop. 2014-07-23 09:39:26 -04:00
Beman
99a94662b2 Merge branch 'develop' into ts-develop
Conflicts:
	include/boost/filesystem/operations.hpp
	test/operations_test.cpp
2014-07-22 20:55:58 -04:00
Beman
040be88815 Rework the recursive_directory_iterator::increment function to always make progress, even when errors occur. 2014-07-20 16:44:28 -04:00
Beman
2774f0e927 Merge comments from abandoned revision; they were helpful even though the code changes were premature. 2014-07-20 09:31:06 -04:00
Beman
ecce3f06d7 Revert "Merge branch 'avdv-fix-5403' into develop"
This reverts commit eaa5f27fc1, reversing
changes made to 23d2fcb9e0.

Although the changes made by the pull request fixed the presenting symptom, the lack of an "always makes progress" invariant is the real problem. The plan is to attack the lack of invariant first, then make further changes are needed.
2014-07-20 09:15:17 -04:00
Beman
eaa5f27fc1 Merge branch 'avdv-fix-5403' into develop 2014-07-19 14:42:08 -04:00
Beman
044b98373c All char16_t/char32_t dependencies #ifdef'ed out. All test/msvc/filesystem.sln tests pass. 2014-07-10 14:43:22 -04:00
Beman
fcb9600f91 Merge updates from Beman's Github repo. Unstable. 2014-07-09 14:47:13 -04:00
Claudio Bley
2cf9db8570 Fix trac ticket 5403
This resolves a bug where the directory_iterator at the top of the stack
is invalid (ie. an end iterator) if an error occurs. So, you cannot
dereference it, and you cannot use any other method (e.g. no_push) on
it, otherwise std::abort will be called.

Avoid pushing an end iterator onto the directory stack.

[1] https://svn.boost.org/trac/boost/ticket/5403
[2] https://svn.boost.org/trac/boost/ticket/6821#comment:5
2014-07-09 07:57:45 +02:00
Beman
b1b1cea3c4 Rename relative to lexically_relative. Add semi_canonical() and relative(). 2014-05-29 15:42:11 -04:00