7 #include "MatchWildcard.hpp"
10 #include "Environment.h"
11 #include "ErrnoSaver.hpp"
12 #include "PlatformConstants.h"
14 #define MAKE_STR(x) _MAKE_STR(x)
15 #define _MAKE_STR(x) #x
17 template <class C
> static size_t tzlen(const C
*ptz
)
20 for (etz
= ptz
; *etz
; ++etz
);
24 template <class C
> static size_t tnzlen(const C
*ptz
, size_t n
)
27 for (i
= 0; i
< n
&& ptz
[i
]; ++i
);
32 unsigned long htoul(const char *str
, size_t maxlen
= (size_t)-1);
33 unsigned long atoul(const char *str
, size_t maxlen
= (size_t)-1);
35 // converts given hex digit to value between 0x0 and 0xf
36 // in case of error returns 0xff
37 template <class CHAR_T
>
38 unsigned char ParseHexDigit(const CHAR_T hex
)
40 if (hex
>= (CHAR_T
)'0' && hex
<= (CHAR_T
)'9')
41 return hex
- (CHAR_T
)'0';
42 if (hex
>= (CHAR_T
)'a' && hex
<= (CHAR_T
)'f')
43 return 10 + hex
- (CHAR_T
)'a';
44 if (hex
>= (CHAR_T
)'A' && hex
<= (CHAR_T
)'F')
45 return 10 + hex
- (CHAR_T
)'A';
50 // converts given two hex digits to value between 0x0 and 0xff
51 // in case of error returns 0
52 template <class CHAR_T
>
53 unsigned char ParseHexByte(const CHAR_T
*hex
)
55 const unsigned char rh
= ParseHexDigit(hex
[0]);
56 const unsigned char rl
= ParseHexDigit(hex
[1]);
57 if (rh
== 0xff || rl
== 0xff) {
60 return ((rh
<< 4) | rl
);
64 // converts given value between 0x0 and 0xf to lowercased hex digit
65 // in case of error returns 0
66 char MakeHexDigit(const unsigned char c
);
69 size_t StrStartsFrom(const StrT
&haystack
, const typename
StrT::value_type needle
)
71 return (!haystack
.empty() && haystack
.front() == needle
) ? 1 : 0;
74 template <class CharT
>
75 size_t StrStartsFrom(const CharT
*haystack
, const CharT
*needle
)
78 for (i
= 0; needle
[i
]; ++i
) {
79 if (haystack
[i
] != needle
[i
])
86 size_t StrStartsFrom(const StrT
&haystack
, const typename
StrT::value_type
*needle
)
89 for (i
= 0; needle
[i
]; ++i
) {
90 if (i
>= haystack
.size() || haystack
[i
] != needle
[i
])
97 size_t StrEndsBy(const StrT
&haystack
, const typename
StrT::value_type
*needle
)
99 const size_t l
= tzlen(needle
);
100 if (!l
|| haystack
.size() < l
)
103 return memcmp(haystack
.c_str() + haystack
.size() - l
, needle
, l
* sizeof(typename
StrT::value_type
)) ? 0 : l
;
107 const std::string
&GetMyHome();
109 void InMyPathChanged(); // NOT thread safe, can be called only before any concurrent use of InMy...
110 std::string
InMyConfig(const char *subpath
= NULL
, bool create_path
= true);
111 std::string
InMyCache(const char *subpath
= NULL
, bool create_path
= true);
112 std::string
InMyTemp(const char *subpath
= NULL
);
114 bool IsPathIn(const wchar_t *path
, const wchar_t *root
);
116 bool TranslateInstallPath_Bin2Share(std::wstring
&path
);
117 bool TranslateInstallPath_Bin2Share(std::string
&path
);
118 bool TranslateInstallPath_Lib2Share(std::wstring
&path
);
119 bool TranslateInstallPath_Lib2Share(std::string
&path
);
120 bool TranslateInstallPath_Share2Lib(std::wstring
&path
);
121 bool TranslateInstallPath_Share2Lib(std::string
&path
);
122 bool TranslateInstallPath_Bin2Lib(std::string
&path
);
125 // converts /some/path/to/filename.extension into form "filename@HASH"
126 // where HASH produced from path and extension and also filename has
127 // some special for ini files chars replaced by '_' and affected HASH
128 void FilePathHashSuffix(std::string
&pathname
);
130 void CheckedCloseFD(int &fd
);
131 void CheckedCloseFDPair(int *fd
);
133 size_t WriteAll(int fd
, const void *data
, size_t len
, size_t chunk
= (size_t)-1);
134 size_t ReadAll(int fd
, void *data
, size_t len
);
135 ssize_t
ReadWritePiece(int fd_src
, int fd_dst
);
138 int pipe_cloexec(int pipedes
[2]);
140 void PutZombieUnderControl(pid_t pid
);
142 void AbbreviateString(std::string
&path
, size_t needed_length
);
144 const wchar_t *FileSizeToFractionAndUnits(unsigned long long &value
);
145 std::wstring
FileSizeString(unsigned long long value
);
146 std::wstring
ThousandSeparatedString(unsigned long long value
);
148 std::string
StrPrintfV(const char *format
, va_list args
);
149 std::string
FN_PRINTF_ARGS(1) StrPrintf(const char *format
, ...);
151 template <class CharT
>
152 std::basic_string
<CharT
> EnsureNoSlashAtEnd(std::basic_string
<CharT
> str
, CharT slash
= '/')
154 for (size_t p
= str
.size(); p
&& str
[p
- 1] == slash
; ) {
160 template <class CharT
>
161 std::basic_string
<CharT
> EnsureNoSlashAtNestedEnd(std::basic_string
<CharT
> str
, CharT slash
= '/')
163 for (size_t p
= str
.size(); p
> 1 && str
[p
- 1] == slash
; ) {
170 template <class CharT
>
171 std::basic_string
<CharT
> EnsureSlashAtEnd(std::basic_string
<CharT
> str
, CharT slash
= '/')
173 const size_t p
= str
.size();
174 if (!p
|| str
[p
- 1] != slash
) {
180 template <class CharT
>
181 std::basic_string
<CharT
> ExtractFilePath(std::basic_string
<CharT
> str
, CharT slash
= '/')
183 const size_t p
= str
.rfind(slash
);
184 str
.resize( (p
!= std::string::npos
) ? p
: 0);
189 template <class CharT
>
190 std::basic_string
<CharT
> ExtractFileName(std::basic_string
<CharT
> str
, CharT slash
= '/')
192 const size_t p
= str
.rfind(slash
);
193 return (p
!= std::string::npos
) ? str
.substr( p
+ 1, str
.size() - (p
+ 1) ) : str
;
197 template <class CharT
>
198 bool CutToSlash(std::basic_string
<CharT
> &str
, bool include
= false)
200 size_t p
= str
.rfind('/');
201 if (p
== std::string::npos
)
204 str
.resize(include
? p
+ 1 : p
);
208 template <class CharT
>
209 void ReplaceFileNamePart(std::basic_string
<CharT
> &str
, const CharT
*replacement
)
211 if (CutToSlash(str
, true)) {
219 template <class CharT
>
220 void StrExplode(std::vector
<std::basic_string
<CharT
> > &out
, const std::basic_string
<CharT
> &str
, const CharT
*divs
)
222 for (size_t i
= 0, j
= 0; i
<= str
.size(); ++i
) {
223 const CharT
*d
= divs
;
224 if (i
!= str
.size()) {
225 for (; *d
&& *d
!= str
[i
]; ++d
);
229 out
.emplace_back(str
.substr(j
, i
- j
));
236 template <class CharT
>
237 void StrTrimRight(std::basic_string
<CharT
> &str
, const char *spaces
= " \t")
239 while (!str
.empty() && unsigned(str
.back()) <= 0x7f && strchr(spaces
, str
.back()) != NULL
) {
243 template <class CharT
>
244 void StrTrimLeft(std::basic_string
<CharT
> &str
, const char *spaces
= " \t")
246 while (!str
.empty() && unsigned(str
[0]) <= 0x7f && strchr(spaces
, str
[0]) != NULL
) {
251 template <class CharT
>
252 void StrTrim(std::basic_string
<CharT
> &str
, const char *spaces
= " \t")
254 StrTrimRight(str
, spaces
);
255 StrTrimLeft(str
, spaces
);
259 template <typename HaystackT
, typename NeedlesT
>
260 static const HaystackT
*FindAnyOfChars(const HaystackT
*haystack
, const NeedlesT
*needles
)
262 for(; *haystack
; ++haystack
)
264 for(size_t i
= 0; needles
[i
]; ++i
)
266 if (*haystack
== (HaystackT
)needles
[i
])
273 template <typename HaystackIT
, typename NeedlesT
>
274 static HaystackIT
FindAnyOfChars(HaystackIT haystack
, const HaystackIT haystack_end
, const NeedlesT
*needles
)
276 for(; haystack
!= haystack_end
; ++haystack
)
278 for(size_t i
= 0; needles
[i
]; ++i
)
280 if (*haystack
== (decltype(*haystack
))needles
[i
])
287 bool CaseIgnoreEngStrMatch(const std::string
&str1
, const std::string
&str2
);
288 bool CaseIgnoreEngStrMatch(const char *str1
, const char *str2
, size_t len
);
289 const char *CaseIgnoreEngStrChr(const char c
, const char *str
, size_t len
);
292 template <class POD_T
>
293 void ZeroFill(POD_T
&dst
)
295 static_assert ( std::is_pod
<POD_T
>::value
, "ZeroFill should be used with POD types only");
296 static_assert ( sizeof(dst
) != sizeof(void *), "ZeroFill should not be used with pointers");
297 memset(&dst
, 0, sizeof(dst
));
300 template <class STRING_T
, typename ARRAY_T
>
301 void StrAssignArray(STRING_T
&s
, const ARRAY_T
&a
)
303 static_assert ( sizeof(a
) != sizeof(void *), "StrAssignArray should be used with arrays but not pointers");
304 s
.assign(a
, tnzlen(a
, ARRAYSIZE(a
)));
307 template <class STRING_T
, typename ARRAY_T
>
308 void StrAppendArray(STRING_T
&s
, const ARRAY_T
&a
)
310 static_assert ( sizeof(a
) != sizeof(void *), "StrAppendArray should be used with arrays but not pointers");
311 s
.append(a
, tnzlen(a
, ARRAYSIZE(a
)));
315 template <class STRING_T
, typename ARRAY_T
>
316 bool StrMatchArray(STRING_T
&s
, const ARRAY_T
&a
)
318 static_assert ( sizeof(a
) != sizeof(void *), "StrMatchArray should be used with arrays but not pointers");
319 const size_t l
= tnzlen(a
, ARRAYSIZE(a
));
320 return s
.size() == l
&& s
.compare(0, std::string::npos
, a
, l
) == 0;
323 template <typename ARRAY_T
, class CHAR_T
>
324 void ArrayCpyZ(ARRAY_T
&dst
, const CHAR_T
*src
)
326 static_assert ( sizeof(dst
) != sizeof(void *), "ArrayCpyZ should be used with arrays but not pointers");
328 for (i
= 0; src
[i
] && i
+ 1 < ARRAYSIZE(dst
); ++i
) {
334 bool POpen(std::string
&result
, const char *command
);
335 bool POpen(std::vector
<std::wstring
> &result
, const char *command
);
337 #define DBGLINE fprintf(stderr, "%d %d @%s\n", getpid(), __LINE__, __FILE__)
339 bool IsCharFullWidth(wchar_t c
);
340 bool IsCharPrefix(wchar_t c
);
341 bool IsCharSuffix(wchar_t c
);
342 bool IsCharXxxfix(wchar_t c
);