MiKTeX 23.10-next
A scalable TeX distribution
Loading...
Searching...
No Matches
PathName.h
1/* miktex/Util/PathName.h:
2
3 Copyright (C) 1996-2021 Christian Schenk
4
5 This file is part of the MiKTeX Util Library.
6
7 The MiKTeX Util Library is free software; you can redistribute it
8 and/or modify it under the terms of the GNU General Public License
9 as published by the Free Software Foundation; either version 2, or
10 (at your option) any later version.
11
12 The MiKTeX Util Library is distributed in the hope that it will be
13 useful, but WITHOUT ANY WARRANTY; without even the implied warranty
14 of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with the MiKTeX Util Library; if not, write to the Free
19 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
20 02111-1307, USA. */
21
22#pragma once
23
24#if !defined(CF4C28E918A44B66B3B0BEF7E88AB721)
25#define CF4C28E918A44B66B3B0BEF7E88AB721
26
27#include <miktex/Util/config.h>
28
29#include <ostream>
30#include <string>
31#include <vector>
32
33#include <miktex/Util/CharBuffer>
34#include <miktex/Util/PathNameUtil>
35
36#include "OptionSet.h"
37
38MIKTEX_UTIL_BEGIN_NAMESPACE;
39
42{
44 ToUnix,
46 ToDos,
51#if defined(MIKTEX_WINDOWS)
54#endif
59};
60
63
64enum class DisplayPathNameOption
65{
66};
67
68typedef OptionSet<DisplayPathNameOption> DisplayPathNameOptions;
69
71class PathName :
72 public MiKTeX::Util::CharBuffer<char, MIKTEX_UTIL_PATHNAME_SIZE>
73{
74protected:
76
77public:
78 PathName() = default;
79
80public:
81 PathName(const PathName& other) = default;
82
83public:
84 PathName& operator=(const PathName& other) = default;
85
86public:
87 PathName(PathName&& other) noexcept = default;
88
89public:
90 PathName& operator=(PathName&& other) noexcept = default;
91
92public:
93 virtual ~PathName() noexcept = default;
94
97public:
98 explicit PathName(const char* path) :
99 Base(path)
100 {
101 }
102
105public:
106 explicit PathName(const wchar_t* path) :
107 Base(path)
108 {
109 }
110
113public:
114 explicit PathName(const std::string& path) :
115 Base(path)
116 {
117 }
118
121public:
122 explicit PathName(const std::wstring& path) :
123 Base(path)
124 {
125 }
126
127public:
128 PathName(size_t n) = delete;
129
133public:
134 PathName(const char* component1, const char* component2) :
135 Base(component1)
136 {
137 if (component2 != nullptr)
138 {
139 AppendComponent(component2);
140 }
141 }
142
146public:
147 PathName(const PathName& component1, const PathName& component2) :
148 PathName(component1.GetData(), component2.GetData())
149 {
150 }
151
152public:
153 PathName& operator=(const char* path)
154 {
155 Base::operator= (path);
156 return *this;
157 }
158
159public:
160 PathName& operator=(const wchar_t* path)
161 {
162 Base::operator= (path);
163 return *this;
164 }
165
166public:
167 PathName& operator=(const std::string& path)
168 {
169 Base::operator= (path);
170 return *this;
171 }
172
173public:
174 PathName& operator=(const std::wstring& path)
175 {
176 Base::operator= (path);
177 return *this;
178 }
179
182public:
183 MIKTEXUTILTHISAPI(std::size_t) GetHash() const;
184
185public:
186 static MIKTEXUTILCEEAPI(std::vector<std::string>) Split(const PathName& path);
187
188private:
189 static MIKTEXUTILCEEAPI(void) Split(const PathName& path, std::string& directoryName, std::string& fileNameWithoutExtension, std::string& extension);
190
191public:
192 PathName GetDirectoryName() const
193 {
194 std::string directoryName;
195 std::string fileNameWithoutExtension;
196 std::string extension;
197 Split(*this, directoryName, fileNameWithoutExtension, extension);
198 return PathName(directoryName);
199 }
200
201public:
202 PathName GetFileName() const
203 {
204 std::string directoryName;
205 std::string fileNameWithoutExtension;
206 std::string extension;
207 Split(*this, directoryName, fileNameWithoutExtension, extension);
208 return PathName(fileNameWithoutExtension + extension);
209 }
210
211public:
212 PathName GetFileNameWithoutExtension() const
213 {
214 std::string directoryName;
215 std::string fileNameWithoutExtension;
216 std::string extension;
217 Split(*this, directoryName, fileNameWithoutExtension, extension);
218 return PathName(fileNameWithoutExtension);
219 }
220
223public:
225 {
226 return CutOffLastComponent();
227 }
228
231public:
233 {
234 Base::Set(GetFileName());
235 return *this;
236 }
237
238public:
239 MIKTEXUTILTHISAPI(PathName&) SetToHomeDirectory();
240
241public:
242 MIKTEXUTILTHISAPI(PathName&) SetToLockDirectory();
243
246public:
247 MIKTEXUTILTHISAPI(PathName&) SetToCurrentDirectory();
248
251public:
252 MIKTEXUTILTHISAPI(PathName&) SetToTempDirectory();
253
256public:
257 MIKTEXUTILTHISAPI(PathName&) SetToTempFile();
258
262public:
263 MIKTEXUTILTHISAPI(PathName&) SetToTempFile(const PathName& directory);
264
267public:
268 MIKTEXUTILTHISAPI(PathName) GetMountPoint() const;
269
270public:
271 MIKTEXUTILTHISAPI(PathName&) Convert(ConvertPathNameOptions options);
272
275public:
277 {
278 return Convert({ ConvertPathNameOption::ToUnix });
279 }
280
281public:
282 PathName ToUnix() const
283 {
284 PathName result = *this;
285 result.Convert({ ConvertPathNameOption::ToUnix });
286 return result;
287 }
288
291public:
293 {
294 return Convert({ ConvertPathNameOption::ToDos });
295 }
296
297public:
298 PathName ToDos() const
299 {
300 PathName result = *this;
301 result.Convert({ ConvertPathNameOption::ToDos });
302 return result;
303 }
304
305#if defined(MIKTEX_WINDOWS)
306 PathName ToExtendedLengthPathName() const
307 {
308 PathName result = *this;
309 result.Convert({ ConvertPathNameOption::ToExtendedLengthPathName });
310 return result;
311 }
312#endif
313
314public:
315 std::wstring ToWideCharString() const
316 {
317 return MiKTeX::Util::StringUtil::UTF8ToWideChar(GetData());
318 }
319
320#if defined(MIKTEX_WINDOWS)
321public:
322 std::wstring ToNativeString() const
323 {
324 return ToExtendedLengthPathName().ToWideCharString();
325 }
326#else
327public:
328 std::string ToNativeString() const
329 {
330 return ToString();
331 }
332#endif
333
334public:
335 MIKTEXUTILTHISAPI(std::string) ToDisplayString(DisplayPathNameOptions options = {}) const;
336
339public:
341 {
342#if defined(MIKTEX_WINDOWS)
343 return Convert({ ConvertPathNameOption::ToUnix, ConvertPathNameOption::MakeLower });
344#else
345 return *this;
346#endif
347 }
348
349public:
350 bool IsFullyQualified() const
351 {
352 return MiKTeX::Util::PathNameUtil::IsFullyQualifiedPath(ToString());
353 }
354
355public:
356 bool IsAbsolute() const
357 {
358 return MiKTeX::Util::PathNameUtil::IsAbsolutePath(ToString());
359 }
360
361public:
362 bool IsComparable() const
363 {
364#if defined(MIKTEX_WINDOWS)
365 for (const char* lpsz = GetData(); *lpsz != 0; ++lpsz)
366 {
367 if (*lpsz == MiKTeX::Util::PathNameUtil::DosDirectoryDelimiter || (*lpsz >= 'A' && *lpsz <= 'Z'))
368 {
369 return false;
370 }
371 }
372 return true;
373#else
374 return true;
375#endif
376 }
377
378public:
379 PathName& Canonicalize()
380 {
381 return Convert({ ConvertPathNameOption::Canonicalize });
382 }
383
386public:
388 {
389 return Convert({ ConvertPathNameOption::MakeFullyQualified });
390 }
391
392public:
393 bool HasExtension() const
394 {
395 return !GetExtension().empty();
396 }
397
401public:
402 bool HasExtension(const char* extension) const
403 {
404 std::string currentExtension = GetExtension();
405 if (currentExtension.empty())
406 {
407 return false;
408 }
409 if (extension[0] == '.')
410 {
411 extension += 1;
412 }
413 return PathName::Compare(currentExtension.substr(1), extension) == 0;
414 }
415
419public:
420 MIKTEXUTILTHISAPI(std::string) GetExtension() const;
421
427public:
428 MIKTEXUTILTHISAPI(PathName&) SetExtension(const char* extension, bool override);
429
434public:
435 PathName& SetExtension(const char* extension)
436 {
437 return SetExtension(extension, true);
438 }
439
444public:
445 PathName& SetExtension(const std::string& extension)
446 {
447 return SetExtension(extension.c_str(), true);
448 }
449
450public:
451 PathName& AppendExtension(const char* extension)
452 {
453 if (!HasExtension(extension))
454 {
455 if (*extension != '.')
456 {
457 Base::Append('.');
458 }
459 Base::Append(extension);
460 }
461 return *this;
462 }
463
464public:
465 PathName& AppendExtension(const std::string& extension)
466 {
467 return AppendExtension(extension.c_str());
468 }
469
472public:
474 {
475 std::size_t l = GetLength();
476 return l > 0 && (MiKTeX::Util::PathNameUtil::IsDirectoryDelimiter(Base::operator[](l - 1)));
477 }
478
484public:
485 PathName& Append(const char* lpsz, bool appendDirectoryDelimiter)
486 {
487 if (appendDirectoryDelimiter && !Empty() && !MiKTeX::Util::PathNameUtil::IsDirectoryDelimiter(lpsz[0]))
488 {
489 AppendDirectoryDelimiter();
490 }
491 Base::Append(lpsz);
492 return *this;
493 }
494
495public:
496 PathName& Append(const std::string& str, bool appendDirectoryDelimiter)
497 {
498 return Append(str.c_str(), appendDirectoryDelimiter);
499 }
500
504public:
505 PathName& AppendComponent(const char* component)
506 {
507 return Append(component, true);
508 }
509
513public:
514 PathName& operator/=(const char* component)
515 {
516 return AppendComponent(component);
517 }
518
522public:
523 PathName& operator/=(const PathName& component)
524 {
525 return AppendComponent(component.GetData());
526 }
527
531public:
532 PathName& operator/=(const std::string& component)
533 {
534 return AppendComponent(component.c_str());
535 }
536
539public:
540 MIKTEXUTILTHISAPI(PathName&) CutOffLastComponent(bool allowSelfCutting);
541
544public:
546 {
547 return CutOffLastComponent(false);
548 }
549
552public:
553 MIKTEXUTILTHISAPI(PathName&) AppendDirectoryDelimiter();
554
555#if defined(MIKTEX_WINDOWS)
556public:
557 MIKTEXUTILTHISAPI(PathName&) AppendAltDirectoryDelimiter();
558#endif
559
560public:
561 bool IsExplicitlyRelative() const
562 {
563 return MiKTeX::Util::PathNameUtil::IsExplicitlyRelative(ToString());
564 }
565
566public:
574 static MIKTEXUTILCEEAPI(int) Compare(const char* lpszPath1, const char* lpszPath2, std::size_t count);
575
576public:
577 static int Compare(const PathName& path1, const PathName& path2, std::size_t count)
578 {
579 return Compare(path1.GetData(), path2.GetData(), count);
580 }
581
589public:
590 static MIKTEXUTILCEEAPI(int) Compare(const char* lpszPath1, const char* lpszPath2);
591
599public:
600 static int Compare(const PathName& path1, const PathName& path2)
601 {
602 return Compare(path1.GetData(), path2.GetData());
603 }
604
612public:
613 static int Compare(const std::string& path1, const std::string& path2)
614 {
615 return Compare(path1.c_str(), path2.c_str());
616 }
617
618public:
619 static bool Equals(const PathName& path1, const PathName& path2)
620 {
621 return Compare(path1, path2) == 0;
622 }
623
628public:
629 static MIKTEXUTILCEEAPI(bool) Match(const char* lpszPattern, const char* lpszPath);
630
631public:
632 static bool Match(const char* lpszPattern, const PathName& path)
633 {
634 return Match(lpszPattern, path.GetData());
635 }
636};
637
638inline bool operator<(const PathName& lhs, const PathName& rhs)
639{
640 return PathName::Compare(lhs, rhs) < 0;
641}
642
647inline bool operator==(const PathName& lhs, const PathName& rhs)
648{
649 return PathName::Compare(lhs, rhs) == 0;
650}
651
656inline bool operator!=(const PathName& lhs, const PathName& rhs)
657{
658 return PathName::Compare(lhs, rhs) != 0;
659}
660
661inline PathName operator/(const PathName& lhs, const PathName& rhs)
662{
663 PathName result = lhs;
664 result /= rhs;
665 return result;
666}
667
668inline std::ostream& operator<<(std::ostream& os, const PathName& path)
669{
670 return os << path.ToDisplayString();
671}
672
673MIKTEX_UTIL_END_NAMESPACE;
674
675namespace std
676{
677 template<> struct hash<MiKTeX::Util::PathName>
678 {
679 std::size_t operator()(const MiKTeX::Util::PathName& path) const
680 {
681 return path.GetHash();
682 }
683 };
684}
685
686#endif
Instances of this class store characters.
Definition: CharBuffer.h:41
Definition: OptionSet.h:37
Instances of this class can be used to store path names.
Definition: PathName.h:73
PathName & SetExtension(const char *extension)
Definition: PathName.h:435
PathName & MakeFullyQualified()
Definition: PathName.h:387
bool EndsWithDirectoryDelimiter() const
Definition: PathName.h:473
PathName & operator/=(const std::string &component)
Definition: PathName.h:532
PathName & AppendComponent(const char *component)
Definition: PathName.h:505
MIKTEXUTILTHISAPI(PathName &) SetExtension(const char *extension
static int Compare(const char *lpszPath1, const char *lpszPath2)
MIKTEXUTILTHISAPI(PathName &) CutOffLastComponent(bool allowSelfCutting)
MIKTEXUTILTHISAPI(PathName &) SetToTempDirectory()
MIKTEXUTILTHISAPI(std::string) GetExtension() const
PathName(const std::wstring &path)
Definition: PathName.h:122
PathName & CutOffLastComponent()
Definition: PathName.h:545
static int Compare(const PathName &path1, const PathName &path2)
Definition: PathName.h:600
PathName & operator/=(const char *component)
Definition: PathName.h:514
MIKTEXUTILTHISAPI(PathName &) AppendDirectoryDelimiter()
PathName & SetExtension(const std::string &extension)
Definition: PathName.h:445
PathName(const wchar_t *path)
Definition: PathName.h:106
MIKTEXUTILTHISAPI(std::size_t) GetHash() const
static int Compare(const std::string &path1, const std::string &path2)
Definition: PathName.h:613
PathName & ConvertToUnix()
Definition: PathName.h:276
MIKTEXUTILTHISAPI(PathName &) SetToTempFile(const PathName &directory)
PathName & RemoveFileSpec()
Definition: PathName.h:224
static int Compare(const char *lpszPath1, const char *lpszPath2, std::size_t count)
PathName(const std::string &path)
Definition: PathName.h:114
PathName & operator/=(const PathName &component)
Definition: PathName.h:523
MIKTEXUTILTHISAPI(PathName &) SetToCurrentDirectory()
MIKTEXUTILTHISAPI(PathName &) SetToTempFile()
MIKTEXUTILTHISAPI(PathName) GetMountPoint() const
PathName & TransformForComparison()
Definition: PathName.h:340
PathName & ConvertToDos()
Definition: PathName.h:292
bool HasExtension(const char *extension) const
Definition: PathName.h:402
PathName(const char *path)
Definition: PathName.h:98
PathName & RemoveDirectorySpec()
Definition: PathName.h:232
PathName & Append(const char *lpsz, bool appendDirectoryDelimiter)
Definition: PathName.h:485
PathName(const char *component1, const char *component2)
Definition: PathName.h:134
PathName(const PathName &component1, const PathName &component2)
Definition: PathName.h:147
static bool Match(const char *lpszPattern, const char *lpszPath)
static bool IsDirectoryDelimiter(int ch)
Definition: PathNameUtil.h:108
ConvertPathNameOption
Path name conversion option enum class.
Definition: PathName.h:42
@ MakeUpper
Replaces small letters with their capital letter counterpart.
@ Canonicalize
Resolve symbolic links.
@ MakeFullyQualified
Makes the path name fully qualified.
@ ToDos
Replaces slashes with backslashes.
@ ToUnix
Replaces backslashes with slashes.
@ MakeLower
Replaces capital letters with their small letter counterpart.
@ ToExtendedLengthPathName
Prefix with \?\ to create an extended-length path name.