BDE 4.14.0 Production release
Loading...
Searching...
No Matches
bdls_pathutil.h
Go to the documentation of this file.
1/// @file bdls_pathutil.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// bdls_pathutil.h -*-C++-*-
8#ifndef INCLUDED_BDLS_PATHUTIL
9#define INCLUDED_BDLS_PATHUTIL
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id: $")
13
14/// @defgroup bdls_pathutil bdls_pathutil
15/// @brief Provide portable file path manipulation.
16/// @addtogroup bdl
17/// @{
18/// @addtogroup bdls
19/// @{
20/// @addtogroup bdls_pathutil
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#bdls_pathutil-purpose"> Purpose</a>
25/// * <a href="#bdls_pathutil-classes"> Classes </a>
26/// * <a href="#bdls_pathutil-description"> Description </a>
27/// * <a href="#bdls_pathutil-terminology"> Terminology </a>
28/// * <a href="#bdls_pathutil-separator"> Separator </a>
29/// * <a href="#bdls_pathutil-path"> Path </a>
30/// * <a href="#bdls_pathutil-root"> Root </a>
31/// * <a href="#bdls_pathutil-unix-root"> Unix Root </a>
32/// * <a href="#bdls_pathutil-windows-root"> Windows Root </a>
33/// * <a href="#bdls_pathutil-leaf"> Leaf (a.k.a. Basename) </a>
34/// * <a href="#bdls_pathutil-extension"> Extension </a>
35/// * <a href="#bdls_pathutil-dirname"> Dirname </a>
36/// * <a href="#bdls_pathutil-parsing-and-performance"> Parsing and Performance </a>
37/// * <a href="#bdls_pathutil-usage"> Usage </a>
38/// * <a href="#bdls_pathutil-example-1-basic-syntax"> Example 1: Basic Syntax </a>
39/// * <a href="#bdls_pathutil-example-2-parsing-a-path-using-splitfilename"> Example 2: Parsing a path using splitFilename </a>
40///
41/// # Purpose {#bdls_pathutil-purpose}
42/// Provide portable file path manipulation.
43///
44/// # Classes {#bdls_pathutil-classes}
45///
46/// - bdls::PathUtil: Portable utility methods for manipulating paths
47///
48/// @see bdls_filesystemutil
49///
50/// # Description {#bdls_pathutil-description}
51/// This component provides utility methods for manipulating
52/// strings that represent paths in the filesystem. Class methods of
53/// `bdls::PathUtil` include platform-independent operations to add or remove
54/// filenames or relative paths at the end of a path string (by "filenames" we
55/// are referring to the names of any filesystem item, including regular files
56/// and directories). There are also methods to parse the path to delimit the
57/// "root" as defined for the current platform; see {Parsing and Performance
58/// (`rootEnd` argument)} below.
59///
60/// Paths that have a root are called *absolute* paths, whereas paths that do
61/// not have a root are *relative* paths.
62///
63/// Note that this component does not perform filesystem operations. In
64/// particular, no effort is made to verify the existence or accessibility of
65/// any segment of any path.
66///
67/// ## Terminology {#bdls_pathutil-terminology}
68///
69///
70/// To introduce the terminology explored in this section, lets start with a
71/// Unix example:
72/// @code
73/// "/foo/bar/myfile.txt"
74/// @endcode
75/// The elements of this path would be:
76/// @code
77/// Path: "/foo/bar/myfile.txt"
78/// Root: "/" # the starting separator(s)
79/// Leaf(Basename): "myfile.txt"
80/// Extension: ".txt"
81/// Dirname: "/foo/bar/"
82/// @endcode
83///
84/// ### Separator {#bdls_pathutil-separator}
85///
86///
87/// A platform dependent character that separates elements of a path, such as
88/// directory names from each other and file names. The separator character is
89/// the `/` (slash) on Unix (and the like) systems and '\' (backslash) on
90/// Windows systems.
91///
92/// ### Path {#bdls_pathutil-path}
93///
94///
95/// An optional root, followed by optional directories, followed by an optional
96/// filename.
97///
98/// ### Root {#bdls_pathutil-root}
99///
100///
101/// The root, if present, is at the beginning of a path and its presence
102/// determines if a path is absolute (the root is present) or relative (the root
103/// is not present). The textual rules for what a root is are platform
104/// dependent. See @ref bdls_pathutil-unix-root-and-ref-bdls_pathutil-windows-root .
105///
106/// See also [](#Parsing and Performance} for important notes about speeding up
107/// functions (especially on Windows) by not reparsing roots every time a
108/// function is called.
109///
110/// #### Unix Root {#bdls_pathutil-unix-root}
111///
112///
113/// The Unix root consists of the separator characters at the beginning of a
114/// path, so the root of "/one" is "/", the root of "//two" is "//", while the
115/// root of "somefile" is "" (there is no root, relative path).
116///
117/// #### Windows Root {#bdls_pathutil-windows-root}
118///
119///
120/// The Windows root is much more complicated than the Unix root, because
121/// Windows has three different flavors of paths: local (LFS), UNC, and Long UNC
122/// UNC (LUNC):
123///
124/// LFS: root consists of a drive letter followed by a colon (the name part)
125/// and then zero or more separators (the directory part). E.g.,
126/// "c:\hello.txt", root is "c:\"; "c:tmp" root is "c:"
127///
128/// UNC: root consists of two separators followed by a hostname and
129/// separator (the name part), and then a shared folder followed by one
130/// or more separators (the directory part). e.g.,
131/// "\\servername\sharefolder\output\test.t" root is
132/// "\\servername\sharefolder\"
133///
134/// LUNC: root starts with "\\?\". Then follows either "UNC" followed by
135/// a UNC root, or an LFS root. The "\\?\" is included as part of
136/// the root name. e.g.,
137/// "\\?\UNC\servername\folder\hello" root is "\\?\UNC\servername\dir\"
138/// while "\\?\c:\windows\test" root is "\\?\\c:\"
139///
140/// ### Leaf (a.k.a. Basename) {#bdls_pathutil-leaf}
141///
142///
143/// The leaf is the rightmost name following the root, in other words: the last
144/// element of the path. Note that several methods in this utility require a
145/// leaf to be present to function (such as `getDirname`). Note that a relative
146/// path may contain a leaf only. Examples:
147/// @code
148/// Path Leaf
149/// ---- ----
150/// "/tmp/foo/bar.txt" "bar.txt"
151/// "c:\tmp\foo\bar.txt" "bar.txt"
152/// "\\server\share\tmp\foo.txt" "foo.txt"
153/// "/tmp/foo/" "foo"
154/// "/tmp/" "tmp"
155/// "/" Not Present
156/// @endcode
157///
158/// ### Extension {#bdls_pathutil-extension}
159///
160///
161/// An extension is a suffix of a leaf that begins with a dot and that does
162/// not contain additional dots. There are a few caveats. The special leaf
163/// names "." and ".." are considered to not have extensions. Furthermore,
164/// if a leaf's name begins with a dot, such dot is not considered when
165/// determining the extension. For example, the leaf ".bashrc" does not have
166/// an extension, but ".bbprofile.log" does, and its extension is ".log".
167/// We will say that a path has an extension if it has a leaf and its leaf
168/// has an extension. Note that for consistency reasons, our implementation
169/// differs from other standard implementations in the same way `getLeaf`
170/// does: the path "/foo/bar.txt/" is considered to have an extension and
171/// its extension is ".txt". Examples:
172/// @code
173/// Path Extension
174/// ---- -------
175/// "/tmp/foo/bar.txt" ".txt"
176/// "/tmp/foo/bar" Not Present
177/// "/tmp/foo/bar.longextension" ".longextension"
178/// "/a/b.txt/" ".txt"
179/// "/a/b.txt/." Not present
180/// "/a.txt/b.txt/.." Not present
181/// "/a/.profile" Not present
182/// "/a/.profile.backup" ".backup"
183/// "foo.txt" ".txt"
184/// @endcode
185///
186/// ### Dirname {#bdls_pathutil-dirname}
187///
188///
189/// Dirname is the part of the path that contains the root but not the leaf.
190/// Note that the `getDirname` utility method requires a leaf to be present to
191/// function. Examples:
192/// @code
193/// Path Dirname
194/// ---- -------
195/// "/tmp/foo/bar.txt" "/tmp/foo/"
196/// "c:\tmp\foo\bar.txt" "c:\tmp\foo\"
197/// "\\server\share\tmp\foo.txt" "\\server\share\tmp\"
198/// "/tmp/foo/" "/tmp"
199/// "/tmp/" "/"
200/// "/" no leaf -> error
201/// "foo.txt" empty
202/// @endcode
203///
204/// ## Parsing and Performance {#bdls_pathutil-parsing-and-performance}
205///
206///
207/// Most methods of this component will perform basic parsing of the beginning
208/// part of the path to determine what part of it is the "root" as defined for
209/// the current platform. This parsing is trivial on Unix platforms but is
210/// slightly more involved for the Windows operating system. To accommodate
211/// client code which is willing to store parsing results in order to maximize
212/// performance, all methods which parse the "root" of the path accept an
213/// optional argument delimiting the "root"; if this argument is specified,
214/// parsing is skipped.
215///
216/// ## Usage {#bdls_pathutil-usage}
217///
218///
219/// This section illustrates intended use of this component.
220///
221/// ### Example 1: Basic Syntax {#bdls_pathutil-example-1-basic-syntax}
222///
223///
224/// We start with strings representing an absolute native path and a relative
225/// native path, respectively:
226/// @code
227/// #ifdef BSLS_PLATFORM_OS_WINDOWS
228/// bsl::string tempPath = "c:\\windows\\temp";
229/// bsl::string otherPath = "22jan08\\log.txt";
230/// #else
231/// bsl::string tempPath = "/var/tmp";
232/// bsl::string otherPath = "22jan08/log.txt";
233/// #endif
234/// @endcode
235/// `tempPath` is an absolute path, since it has a root. It also has a leaf
236/// element ("temp"):
237/// @code
238/// assert(false == bdls::PathUtil::isRelative(tempPath));
239/// assert(true == bdls::PathUtil::isAbsolute(tempPath));
240/// assert(true == bdls::PathUtil::hasLeaf(tempPath));
241/// @endcode
242/// We can add filenames to the path one at a time, or we can add another path
243/// if is relative. We can also remove filenames from the end of the path one
244/// at a time:
245/// @code
246/// bdls::PathUtil::appendRaw(&tempPath, "myApp");
247/// bdls::PathUtil::appendRaw(&tempPath, "logs");
248///
249/// assert(true == bdls::PathUtil::isRelative(otherPath));
250/// assert(0 == bdls::PathUtil::appendIfValid(&tempPath, otherPath));
251/// assert(true == bdls::PathUtil::hasLeaf(tempPath));
252///
253/// bdls::PathUtil::popLeaf(&tempPath);
254/// bdls::PathUtil::appendRaw(&tempPath, "log2.txt");
255///
256/// #ifdef BSLS_PLATFORM_OS_WINDOWS
257/// assert("c:\\windows\\temp\\myApp\\logs\\22jan08\\log2.txt" == tempPath);
258/// #else
259/// assert("/var/tmp/myApp/logs/22jan08/log2.txt" == tempPath);
260/// #endif
261/// @endcode
262/// A relative path may be appended to any other path, even itself. An absolute
263/// path may not be appended to any path, or undefined behavior will result:
264/// @code
265/// assert(0 == bdls::PathUtil::appendIfValid(&otherPath, otherPath)); // OK
266/// /* bdls::PathUtil::append(&otherPath, tempPath); */ // UNDEFINED BEHAVIOR!
267/// @endcode
268/// Note that there is no attempt to distinguish filenames that are regular
269/// files from filenames that are directories, or to verify the existence of
270/// paths in the filesystem.
271/// @code
272/// #ifdef BSLS_PLATFORM_OS_WINDOWS
273/// assert("c:\\windows\\temp\\myApp\\logs\\22jan08\\log2.txt" == tempPath);
274/// #else
275/// assert("/var/tmp/myApp/logs/22jan08/log2.txt" == tempPath);
276/// #endif
277/// @endcode
278///
279/// ### Example 2: Parsing a path using splitFilename {#bdls_pathutil-example-2-parsing-a-path-using-splitfilename}
280///
281///
282/// Suppose we need to obtain all filenames from the path.
283///
284/// First, we create a path for splitting and a storage for filenames:
285/// @code
286/// #ifdef BSLS_PLATFORM_OS_WINDOWS
287/// const char *splitPath = "c:\\one\\two\\three\\four";
288/// #else
289/// const char *splitPath = "//one/two/three/four";
290/// #endif
291/// bsl::vector<bsl::string_view> filenames;
292/// @endcode
293/// Then, we run a cycle to sever filenames from the end one by one:
294/// @code
295/// bsl::string_view head;
296/// bsl::string_view tail;
297/// bsl::string_view path(splitPath);
298///
299/// do {
300/// bdls::PathUtil::splitFilename(&head, &tail, path);
301/// filenames.push_back(tail);
302/// path = head;
303/// } while (!tail.empty());
304/// @endcode
305/// Now, verify the resulting values:
306/// @code
307/// assert(5 == filenames.size());
308///
309/// assert("four" == filenames[0]);
310/// assert("three" == filenames[1]);
311/// assert("two" == filenames[2]);
312/// assert("one" == filenames[3]);
313/// assert("" == filenames[4]);
314/// @endcode
315/// Finally, make sure that only the root remains of the original value:
316/// @code
317/// #ifdef BSLS_PLATFORM_OS_WINDOWS
318/// assert("c:\\" == head);
319/// #else
320/// assert("//" == head);
321/// #endif
322/// @endcode
323/// @}
324/** @} */
325/** @} */
326
327/** @addtogroup bdl
328 * @{
329 */
330/** @addtogroup bdls
331 * @{
332 */
333/** @addtogroup bdls_pathutil
334 * @{
335 */
336
337#include <bdlscm_version.h>
338
339#include <bsls_assert.h>
340#include <bsls_libraryfeatures.h>
341#include <bsls_platform.h>
342#include <bsls_review.h>
343
344#include <bsl_string.h>
345#include <bsl_string_view.h>
346
347#include <string> // 'std::string', 'std::pmr::string'
348
349
350namespace bdls {
351
352 // ===============
353 // struct PathUtil
354 // ===============
355
356/// This struct contains utility methods for platform-independent manipulation
357/// of filesystem paths. No method of this struct provides any filesystem
358/// operations or accesses the filesystem as part of its implementation.
359struct PathUtil {
360
361 // PUBLIC CLASS DATA
362 static const char k_SEPARATOR;
363 // character used as a preferred path separator; use
364 // of this constant is strongly discouraged (as
365 // platforms, like Windows, may support multiple
366 // separators in different contexts), instead prefer
367 // functions to join and split path strings
368
369 // CLASS METHODS
370
371 static int appendIfValid(bsl::string *path,
372 const bsl::string_view& filename);
373 /// Append the specified `filename` to the end of the specified `path`
374 /// if `filename` represents a relative path. Return 0 on success, and
375 /// a non-zero value otherwise. Note that any filesystem separator
376 /// characters at the end of `filename` or `path` will be discarded.
377 /// See @ref bdls_pathutil-terminology for the definition of separator.
378 static int appendIfValid(std::string *path,
379 const bsl::string_view& filename);
380#ifdef BSLS_LIBRARYFEATURES_HAS_CPP17_PMR_STRING
381 static int appendIfValid(std::pmr::string *path,
382 const bsl::string_view& filename);
383#endif
384
385 static void appendRaw(bsl::string *path,
386 const char *filename,
387 int length = -1,
388 int rootEnd = -1);
389 /// Append the specified `filename` up to the optionally specified `length`
390 /// to the end of the specified `path`. If `length` is negative, append
391 /// the entire string. If the optionally specified `rootEnd` offset is
392 /// non-negative, it is taken as the position in `path` of the character
393 /// following the root. The behavior is undefined if `filename` represents
394 /// an absolute path or if either `filename` or `path` ends with the
395 /// filesystem separator character. The behavior is also undefined if
396 /// `filename` points to any part of `path` (i.e., `filename` may not be an
397 /// alias for `path`). See @ref bdls_pathutil-parsing-and-performance .
398 static void appendRaw(std::string *path,
399 const char *filename,
400 int length = -1,
401 int rootEnd = -1);
402#ifdef BSLS_LIBRARYFEATURES_HAS_CPP17_PMR_STRING
403 static void appendRaw(std::pmr::string *path,
404 const char *filename,
405 int length = -1,
406 int rootEnd = -1);
407#endif
408
409 static int popLeaf(bsl::string *path, int rootEnd = -1);
410 /// Remove from the specified `path` the rightmost filename following the
411 /// root; that is, remove the leaf element. If the optionally specified
412 /// `rootEnd` offset is non-negative, it is taken as the position in `path`
413 /// of the character following the root. Return 0 on success, and a
414 /// nonzero value otherwise; in particular, return a nonzero value if
415 /// `path` does not have a leaf. See @ref bdls_pathutil-parsing-and-performance . See
416 /// also @ref bdls_pathutil-terminology for the definition of leaf and root.
417 static int popLeaf(std::string *path, int rootEnd = -1);
418#ifdef BSLS_LIBRARYFEATURES_HAS_CPP17_PMR_STRING
419 static int popLeaf(std::pmr::string *path, int rootEnd = -1);
420#endif
421
422 static int getBasename(bsl::string *leaf,
423 const bsl::string_view& path,
424 int rootEnd = -1);
425 /// Load into the specified `leaf` the value of the rightmost name in the
426 /// specified `path` that follows the root; that is, the leaf element. If
427 /// the optionally specified `rootEnd` offset is non-negative, it is taken
428 /// as the position in `path` of the character following the root. Return
429 /// 0 on success, and a non-zero value otherwise; in particular, return
430 /// nonzero if `path` does not have a leaf. Note that `getBasename` is a
431 /// synonym for `getLeaf`. See @ref bdls_pathutil-parsing-and-performance . See also
432 /// @ref bdls_pathutil-terminology for the definition of leaf and root.
433 static int getBasename(std::string *leaf,
434 const bsl::string_view& path,
435 int rootEnd = -1);
436#ifdef BSLS_LIBRARYFEATURES_HAS_CPP17_PMR_STRING
437 static int getBasename(std::pmr::string *leaf,
438 const bsl::string_view& path,
439 int rootEnd = -1);
440#endif
441
442 static int getDirname(bsl::string *dirname,
443 const bsl::string_view& path,
444 int rootEnd = -1);
445 /// Load into the specified `dirname` the value of the directory part of
446 /// the specified `path`, that is, the root if it exists and all the
447 /// filenames except the last one (the leaf). If the optionally specified
448 /// `rootEnd` offset is non-negative, it is taken as the position in `path`
449 /// of the character following the root. Return 0 on success, and a
450 /// non-zero value otherwise; in particular, return a nonzero value if
451 /// `path` does not have a leaf. Note that in the case of a relative path
452 /// with a single filename, the function will succeed and `dirname` will be
453 /// the empty string. See @ref bdls_pathutil-parsing-and-performance . See also
454 /// @ref bdls_pathutil-terminology for the definition of directories and root.
455 static int getDirname(std::string *dirname,
456 const bsl::string_view& path,
457 int rootEnd = -1);
458#ifdef BSLS_LIBRARYFEATURES_HAS_CPP17_PMR_STRING
459 static int getDirname(std::pmr::string *dirname,
460 const bsl::string_view& path,
461 int rootEnd = -1);
462#endif
463
464 static int getLeaf(bsl::string *leaf,
465 const bsl::string_view& path,
466 int rootEnd = -1);
467 /// Load into the specified `leaf` the value of the rightmost name in the
468 /// specified `path` that follows the root; that is, the leaf element. If
469 /// the optionally specified `rootEnd` offset is non-negative, it is taken
470 /// as the position in `path` of the character following the root. Return
471 /// 0 on success, and a non-zero value otherwise; in particular, return
472 /// nonzero if `path` does not have a leaf. Note that `getBasename` is a
473 /// synonym for `getLeaf`. See @ref bdls_pathutil-parsing-and-performance . See also
474 /// @ref bdls_pathutil-terminology for the definition of leaf and root.
475 static int getLeaf(std::string *leaf,
476 const bsl::string_view& path,
477 int rootEnd = -1);
478#ifdef BSLS_LIBRARYFEATURES_HAS_CPP17_PMR_STRING
479 static int getLeaf(std::pmr::string *leaf,
480 const bsl::string_view& path,
481 int rootEnd = -1);
482#endif
483
484 static int getExtension(bsl::string *extension,
485 const bsl::string_view& path,
486 int rootEnd = -1);
487 /// Load into the specified `extension` the extension of `path`. If the
488 /// optionally specified `rootEnd` offset is non-negative, it is taken as
489 /// the position in `path` of the character following the root. Return 0
490 /// if the path has an extension, and a non-zero value otherwise. See
491 /// @ref bdls_pathutil-parsing-and-performance-see-also-ref-bdls_pathutil-terminology for the
492 /// definition of leaf and root.
493 static int getExtension(std::string *extension,
494 const bsl::string_view& path,
495 int rootEnd = -1);
496#ifdef BSLS_LIBRARYFEATURES_HAS_CPP17_PMR_STRING
497 static int getExtension(std::pmr::string *extension,
498 const bsl::string_view& path,
499 int rootEnd = -1);
500#endif
501
502 static int getRoot(bsl::string *root,
503 const bsl::string_view& path,
504 int rootEnd = -1);
505 /// Load into the specified 'root' the value of the root part of the
506 /// specified 'path'. If the optionally specified 'rootEnd' offset is
507 /// non-negative, it is taken as the position in 'path' of the character
508 /// following the root. Return 0 on success, and a non-zero value
509 /// otherwise; in particular, return a nonzero value if 'path' is relative.
510 /// Note that the meaning of the root part is platform-dependent. See
511 /// @ref bdls_pathutil-parsing-and-performance-see-also-ref-bdls_pathutil-terminology for the
512 /// definition of root.
513 static int getRoot(std::string *root,
514 const bsl::string_view& path,
515 int rootEnd = -1);
516#ifdef BSLS_LIBRARYFEATURES_HAS_CPP17_PMR_STRING
517 static int getRoot(std::pmr::string *root,
518 const bsl::string_view& path,
519 int rootEnd = -1);
520#endif
521
522 /// Load the last pathname component from the specified `path` into the
523 /// specified `tail` and everything leading up to that to the specified
524 /// `head`. If the optionally specified `rootEnd` offset is
525 /// non-negative, it is taken as the position in `path` of the character
526 /// following the root. The `tail` part never contains a slash; if
527 /// `path` ends in a slash, `tail` is empty. If there is no slash in
528 /// `path`, `head` is empty. If `path` is empty, both `head` and `tail`
529 /// are empty. Trailing slashes are stripped from `head` unless it is
530 /// the root.
531 /// @code
532 /// +------------------+------------+---------+
533 /// | PATH | HEAD | TAIL |
534 /// +==================+============+=========+
535 /// | "one" | "" | "one" |
536 /// +------------------+------------+---------+
537 /// | "/one/two/three" | "/one/two" | "three" |
538 /// +------------------+------------+---------+
539 /// | "//one/two///" | "/one/two" | "" |
540 /// +------------------+------------+---------+
541 /// | "c:\\one\\two" | "c:\\one" | "two" |
542 /// +------------------+------------+---------+
543 /// @endcode
544 /// See {`Terminology`} for the definition of root. The behavior is
545 /// undefined unless `head != tail` and `INT_MAX >= path.length()`.
546 /// Note that `head` or `tail` may point to the `path` object when the
547 /// method is called.
549 bsl::string_view *tail,
550 const bsl::string_view& path,
551 int rootEnd = -1);
552
553 /// Return `true` if the specified `path` is absolute (has a root), and
554 /// `false` otherwise. If the optionally specified `rootEnd` offset is
555 /// non-negative, it is taken as the position in `path` of the character
556 /// following the root. See @ref bdls_pathutil-parsing-and-performance . See also
557 /// @ref bdls_pathutil-terminology for the definition of root.
558 static bool isAbsolute(const bsl::string_view& path, int rootEnd = -1);
559
560 /// Return `true` if the specified `path` is relative (lacks a root), and
561 /// `false` otherwise. If the optionally specified `rootEnd` offset is
562 /// non-negative, it is taken as the position in `path` of the character
563 /// following the root. See @ref bdls_pathutil-parsing-and-performance . See also
564 /// @ref bdls_pathutil-terminology for the definition of root.
565 static bool isRelative(const bsl::string_view& path, int rootEnd = -1);
566
567 /// Return `true` if the specified `path` has a filename following the
568 /// root, and `false` otherwise. If the optionally specified `rootEnd`
569 /// offset is non-negative, it is taken as the position in `path` of the
570 /// character following the root. See @ref bdls_pathutil-parsing-and-performance . See
571 /// also @ref bdls_pathutil-terminology for the definition of root.
572 static bool hasLeaf(const bsl::string_view& path, int rootEnd = -1);
573
574 /// Return the 0-based position in the specified `path` of the character
575 /// following the root. Note that a return value of 0 indicates a relative
576 /// path. See @ref bdls_pathutil-parsing-and-performance-see-also-ref-bdls_pathutil-terminology for
577 /// the definition of root.
578 static int getRootEnd(const bsl::string_view& path);
579};
580
581// ============================================================================
582// INLINE DEFINITIONS
583// ============================================================================
584
585 // --------------
586 // class PathUtil
587 // --------------
588
589// CLASS METHODS
590inline
592 const bsl::string_view& path,
593 int rootEnd)
594{
595 BSLS_ASSERT(leaf);
596
597 return getLeaf(leaf, path, rootEnd);
598}
599
600inline
601int PathUtil::getBasename(std::string *leaf,
602 const bsl::string_view& path,
603 int rootEnd)
604{
605 BSLS_ASSERT(leaf);
606
607 return getLeaf(leaf, path, rootEnd);
608}
609
610#ifdef BSLS_LIBRARYFEATURES_HAS_CPP17_PMR_STRING
611inline
612int PathUtil::getBasename(std::pmr::string *leaf,
613 const bsl::string_view& path,
614 int rootEnd)
615{
616 BSLS_ASSERT(leaf);
617
618 return getLeaf(leaf, path, rootEnd);
619}
620#endif
621
622} // close package namespace
623
624
625#endif
626
627// ----------------------------------------------------------------------------
628// Copyright 2015 Bloomberg Finance L.P.
629//
630// Licensed under the Apache License, Version 2.0 (the "License");
631// you may not use this file except in compliance with the License.
632// You may obtain a copy of the License at
633//
634// http://www.apache.org/licenses/LICENSE-2.0
635//
636// Unless required by applicable law or agreed to in writing, software
637// distributed under the License is distributed on an "AS IS" BASIS,
638// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
639// See the License for the specific language governing permissions and
640// limitations under the License.
641// ----------------------------- END-OF-FILE ----------------------------------
642
643/** @} */
644/** @} */
645/** @} */
Definition bslstl_stringview.h:441
Definition bslstl_string.h:1281
#define BSLS_ASSERT(X)
Definition bsls_assert.h:1804
#define BSLS_IDENT(str)
Definition bsls_ident.h:195
Definition bdls_fdstreambuf.h:412
Definition bdls_pathutil.h:359
static bool isAbsolute(const bsl::string_view &path, int rootEnd=-1)
static void appendRaw(std::string *path, const char *filename, int length=-1, int rootEnd=-1)
static int getLeaf(std::string *leaf, const bsl::string_view &path, int rootEnd=-1)
static int getRootEnd(const bsl::string_view &path)
static int appendIfValid(bsl::string *path, const bsl::string_view &filename)
static void appendRaw(bsl::string *path, const char *filename, int length=-1, int rootEnd=-1)
static int getExtension(bsl::string *extension, const bsl::string_view &path, int rootEnd=-1)
static bool isRelative(const bsl::string_view &path, int rootEnd=-1)
static int appendIfValid(std::string *path, const bsl::string_view &filename)
static int getExtension(std::string *extension, const bsl::string_view &path, int rootEnd=-1)
static int getBasename(bsl::string *leaf, const bsl::string_view &path, int rootEnd=-1)
Definition bdls_pathutil.h:591
static const char k_SEPARATOR
Definition bdls_pathutil.h:362
static int getDirname(std::string *dirname, const bsl::string_view &path, int rootEnd=-1)
static void splitFilename(bsl::string_view *head, bsl::string_view *tail, const bsl::string_view &path, int rootEnd=-1)
static int getRoot(std::string *root, const bsl::string_view &path, int rootEnd=-1)
static int popLeaf(std::string *path, int rootEnd=-1)
static int getDirname(bsl::string *dirname, const bsl::string_view &path, int rootEnd=-1)
static int popLeaf(bsl::string *path, int rootEnd=-1)
static bool hasLeaf(const bsl::string_view &path, int rootEnd=-1)
static int getLeaf(bsl::string *leaf, const bsl::string_view &path, int rootEnd=-1)
static int getRoot(bsl::string *root, const bsl::string_view &path, int rootEnd=-1)