summaryrefslogtreecommitdiffstatshomepage
path: root/src/lib/util/path.cpp
blob: bdfb7f4443f171a13012f6268f35a113bd22d5d1 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
// license:BSD-3-Clause
// copyright-holders:Aaron Giles, Nathan Woods
/***************************************************************************

    path.cpp

    Path and filename utilities.

***************************************************************************/

#include "path.h"

#include <algorithm>
#include <cctype>
#include <iterator>


/***************************************************************************
    FILENAME UTILITIES
***************************************************************************/

// -------------------------------------------------
// core_filename_extract_base - extract the base
// name from a filename; note that this makes
// assumptions about path separators
// -------------------------------------------------

std::string_view core_filename_extract_base(std::string_view name, bool strip_extension) noexcept
{
	// find the start of the basename
	auto const start = std::find_if(name.rbegin(), name.rend(), &util::is_directory_separator);
	if (start == name.rbegin())
		return std::string_view();

	// find the end of the basename
	auto const chop_position = strip_extension
		? std::find(name.rbegin(), start, '.')
		: start;
	auto const end = ((chop_position != start) && (std::next(chop_position) != start))
		? std::next(chop_position)
		: name.rbegin();

	return std::string_view(&*start.base(), end.base() - start.base());
}


// -------------------------------------------------
// core_filename_extract_extension
// -------------------------------------------------

std::string_view core_filename_extract_extension(std::string_view filename, bool strip_period) noexcept
{
	auto loc = filename.find_last_of('.');
	if (loc != std::string_view::npos)
		return filename.substr(loc + (strip_period ? 1 : 0));
	else
		return std::string_view();
}


// -------------------------------------------------
// core_filename_ends_with - does the given
// filename end with the specified extension?
// -------------------------------------------------

bool core_filename_ends_with(std::string_view filename, std::string_view extension) noexcept
{
	auto namelen = filename.length();
	auto extlen = extension.length();

	// first if the extension is bigger than the name, we definitely don't match
	bool matches = namelen >= extlen;

	// work backwards checking for a match
	while (matches && extlen > 0 && namelen > 0)
	{
		if (std::tolower(uint8_t(filename[--namelen])) != std::tolower(uint8_t(extension[--extlen])))
			matches = false;
	}

	return matches;
}