22
33#include < sourcemeta/core/uri.h>
44
5- #include < algorithm> // std::ranges::reverse
6- #include < cassert> // assert
7- #include < sstream> // std::istringstream
8- #include < string> // std::string, std::getline
9- #include < vector> // std::vector
5+ #include < algorithm> // std::ranges::reverse
6+ #include < cassert> // assert
7+ #include < filesystem> // std::filesystem::path
8+ #include < sstream> // std::istringstream
9+ #include < string> // std::string, std::getline
10+ #include < vector> // std::vector
1011
1112namespace {
1213
14+ // Strip all extensions from a filename (e.g., "user.schema.json" -> "user")
15+ auto strip_extensions (const std::string &filename) -> std::string {
16+ std::filesystem::path path{filename};
17+ while (path.has_extension ()) {
18+ path = path.stem ();
19+ }
20+ return path.string ();
21+ }
22+
1323// If the input looks like an absolute URI, extract its path segments.
24+ // For file URIs, only the filename (without extensions) is used.
25+ // For other URIs, all path segments are used with extensions stripped from
26+ // the last segment.
1427// Otherwise, add the input as a single segment.
1528// Note: segments are added in reverse order because the caller reverses
1629// the entire result at the end.
@@ -30,13 +43,23 @@ auto push_token_segments(std::vector<std::string> &result,
3043 }
3144 }
3245
33- // Reverse segments since the caller will reverse the entire result
34- std::ranges::reverse (segments);
35- for (const auto &path_segment : segments) {
36- result.emplace_back (path_segment);
37- }
46+ if (!segments.empty ()) {
47+ // Strip extensions from the last segment
48+ segments.back () = strip_extensions (segments.back ());
49+
50+ // For file URIs, only use the filename
51+ if (uri.is_file ()) {
52+ result.emplace_back (segments.back ());
53+ } else {
54+ // Reverse segments since the caller will reverse the entire result
55+ std::ranges::reverse (segments);
56+ for (const auto &path_segment : segments) {
57+ result.emplace_back (path_segment);
58+ }
59+ }
3860
39- return ;
61+ return ;
62+ }
4063 }
4164 }
4265 // NOLINTNEXTLINE(bugprone-empty-catch)
0 commit comments