You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

670 lines
21 KiB

  1. /* /////////////////////////////////////////////////////////////////////////
  2. * File: unixstl/system/system_traits.hpp
  3. *
  4. * Purpose: Contains the system_traits template class, and ANSI and
  5. * Unicode specialisations thereof.
  6. *
  7. * Created: 15th November 2002
  8. * Updated: 10th September 2011
  9. *
  10. * Home: http://stlsoft.org/
  11. *
  12. * Copyright (c) 2002-2011, Matthew Wilson and Synesis Software
  13. * All rights reserved.
  14. *
  15. * Redistribution and use in source and binary forms, with or without
  16. * modification, are permitted provided that the following conditions are
  17. * met:
  18. *
  19. * - Redistributions of source code must retain the above copyright notice,
  20. * this list of conditions and the following disclaimer.
  21. * - Redistributions in binary form must reproduce the above copyright
  22. * notice, this list of conditions and the following disclaimer in the
  23. * documentation and/or other materials provided with the distribution.
  24. * - Neither the name(s) of Matthew Wilson and Synesis Software nor the
  25. * names of any contributors may be used to endorse or promote products
  26. * derived from this software without specific prior written permission.
  27. *
  28. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
  29. * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
  30. * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  31. * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
  32. * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  33. * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  34. * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  35. * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
  36. * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  37. * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  38. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  39. *
  40. * ////////////////////////////////////////////////////////////////////// */
  41. /** \file unixstl/system/system_traits.hpp
  42. *
  43. * \brief [C++ only] Definition of the unixstl::system_traits traits
  44. * class
  45. * (\ref group__library__system "System" Library).
  46. */
  47. #ifndef UNIXSTL_INCL_UNIXSTL_SYSTEM_HPP_SYSTEM_TRAITS
  48. #define UNIXSTL_INCL_UNIXSTL_SYSTEM_HPP_SYSTEM_TRAITS
  49. #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
  50. # define UNIXSTL_VER_UNIXSTL_SYSTEM_HPP_SYSTEM_TRAITS_MAJOR 5
  51. # define UNIXSTL_VER_UNIXSTL_SYSTEM_HPP_SYSTEM_TRAITS_MINOR 4
  52. # define UNIXSTL_VER_UNIXSTL_SYSTEM_HPP_SYSTEM_TRAITS_REVISION 1
  53. # define UNIXSTL_VER_UNIXSTL_SYSTEM_HPP_SYSTEM_TRAITS_EDIT 111
  54. #endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */
  55. /* /////////////////////////////////////////////////////////////////////////
  56. * Includes
  57. */
  58. #ifndef UNIXSTL_INCL_UNIXSTL_H_UNIXSTL
  59. # include <unixstl/unixstl.h>
  60. #endif /* !UNIXSTL_INCL_UNIXSTL_H_UNIXSTL */
  61. #ifndef STLSOFT_INCL_STLSOFT_INTERNAL_H_SAFESTR
  62. # include <stlsoft/internal/safestr.h>
  63. #endif /* !STLSOFT_INCL_STLSOFT_INTERNAL_H_SAFESTR */
  64. #if defined(_WIN32) || \
  65. defined(_WIN64)
  66. # include <ctype.h>
  67. #endif /* Windows */
  68. #ifndef STLSOFT_INCL_H_ERRNO
  69. # define STLSOFT_INCL_H_ERRNO
  70. # include <errno.h>
  71. #endif /* !STLSOFT_INCL_H_ERRNO */
  72. #ifndef STLSOFT_INCL_H_FCNTL
  73. # define STLSOFT_INCL_H_FCNTL
  74. # include <fcntl.h>
  75. #endif /* !STLSOFT_INCL_H_FCNTL */
  76. #if defined(_WIN32) || \
  77. defined(_WIN64)
  78. # include <io.h>
  79. # if defined(STLSOFT_COMPILER_IS_INTEL) || \
  80. defined(STLSOFT_COMPILER_IS_MSVC)
  81. # include <direct.h>
  82. # endif /* os && compiler */
  83. #endif /* Windows */
  84. #ifndef STLSOFT_INCL_H_DLFCN
  85. # define STLSOFT_INCL_H_DLFCN
  86. # include <dlfcn.h>
  87. #endif /* !STLSOFT_INCL_H_DLFCN */
  88. #ifndef STLSOFT_INCL_H_LIMITS
  89. # define STLSOFT_INCL_H_LIMITS
  90. # include <limits.h>
  91. #endif /* !STLSOFT_INCL_H_LIMITS */
  92. #ifndef STLSOFT_INCL_H_STDIO
  93. # define STLSOFT_INCL_H_STDIO
  94. # include <stdio.h>
  95. #endif /* !STLSOFT_INCL_H_STDIO */
  96. #ifndef STLSOFT_INCL_H_STDLIB
  97. # define STLSOFT_INCL_H_STDLIB
  98. # include <stdlib.h>
  99. #endif /* !STLSOFT_INCL_H_STDLIB */
  100. #ifndef STLSOFT_INCL_H_STRING
  101. # define STLSOFT_INCL_H_STRING
  102. # include <string.h>
  103. #endif /* !STLSOFT_INCL_H_STRING */
  104. #ifndef STLSOFT_INCL_H_UNISTD
  105. # define STLSOFT_INCL_H_UNISTD
  106. # include <unistd.h>
  107. #endif /* !STLSOFT_INCL_H_UNISTD */
  108. #ifndef STLSOFT_INCL_H_WCHAR
  109. # define STLSOFT_INCL_H_WCHAR
  110. # include <wchar.h>
  111. #endif /* !STLSOFT_INCL_H_WCHAR */
  112. #ifndef STLSOFT_INCL_SYS_H_TYPES
  113. # define STLSOFT_INCL_SYS_H_TYPES
  114. # include <sys/types.h>
  115. #endif /* !STLSOFT_INCL_SYS_H_TYPES */
  116. #ifndef STLSOFT_INCL_SYS_H_STAT
  117. # define STLSOFT_INCL_SYS_H_STAT
  118. # include <sys/stat.h>
  119. #endif /* !STLSOFT_INCL_SYS_H_STAT */
  120. /* /////////////////////////////////////////////////////////////////////////
  121. * Namespace
  122. */
  123. #ifndef _UNIXSTL_NO_NAMESPACE
  124. # if defined(_STLSOFT_NO_NAMESPACE) || \
  125. defined(STLSOFT_DOCUMENTATION_SKIP_SECTION)
  126. /* There is no stlsoft namespace, so must define ::unixstl */
  127. namespace unixstl
  128. {
  129. # else
  130. /* Define stlsoft::unixstl_project */
  131. namespace stlsoft
  132. {
  133. namespace unixstl_project
  134. {
  135. # endif /* _STLSOFT_NO_NAMESPACE */
  136. #endif /* !_UNIXSTL_NO_NAMESPACE */
  137. /* /////////////////////////////////////////////////////////////////////////
  138. * Classes
  139. */
  140. #ifdef STLSOFT_DOCUMENTATION_SKIP_SECTION
  141. /** Traits for accessing the correct system functions for a given
  142. * character type.
  143. *
  144. * \ingroup group__library__system
  145. *
  146. * system_traits is a traits class for determining the correct system
  147. * structures and functions for a given character type.
  148. *
  149. * \param C The character type (e.g. \c char, \c wchar_t)
  150. */
  151. template <ss_typename_param_k C>
  152. struct system_traits
  153. {
  154. /// \name Types
  155. /// @{
  156. public:
  157. /// The character type
  158. typedef C char_type;
  159. /// The size type
  160. typedef us_size_t size_type;
  161. /// The difference type
  162. typedef us_ptrdiff_t difference_type;
  163. /// The current instantion of the type
  164. typedef system_traits<C> class_type;
  165. /// The (signed) integer type
  166. typedef us_int_t int_type;
  167. /// The Boolean type
  168. typedef us_bool_t bool_type;
  169. /// The type of a handle to a dynamically loaded module
  170. typedef void* module_type;
  171. /// The type of a handle to a kernel object
  172. typedef int handle_type;
  173. /// The type of system result codes
  174. typedef int result_code_type;
  175. /// The type of system error codes
  176. typedef int error_type;
  177. /// @}
  178. /// \name General string handling
  179. /// @{
  180. public:
  181. /// Copies a specific number of characters from the source to the destination
  182. static char_type* char_copy(char_type* dest, char_type const* src, size_type n);
  183. #if !defined(STLSOFT_USING_SAFE_STR_FUNCTIONS) || \
  184. defined(_CRT_SECURE_NO_DEPRECATE)
  185. /// Copies the contents of \c src to \c dest
  186. static char_type* str_copy(char_type* dest, char_type const* src);
  187. /// Copies the contents of \c src to \c dest, up to cch \c characters
  188. static char_type* str_n_copy(char_type* dest, char_type const* src, size_type cch);
  189. /// Appends the contents of \c src to \c dest
  190. static char_type* str_cat(char_type* dest, char_type const* src);
  191. /// Appends the contents of \c src to \c dest, up to cch \c characters
  192. static char_type* str_n_cat(char_type* dest, char_type const* src, size_type cch);
  193. #endif /* !STLSOFT_USING_SAFE_STR_FUNCTIONS || _CRT_SECURE_NO_DEPRECATE */
  194. /// Comparies the contents of \c src and \c dest
  195. static int_type str_compare(char_type const* s1, char_type const* s2);
  196. /// Comparies the contents of \c src and \c dest in a case-insensitive fashion
  197. static int_type str_compare_no_case(char_type const* s1, char_type const* s2);
  198. /// Comparies the contents of \c src and \c dest up to \c cch characters
  199. static int_type str_n_compare(char_type const* s1, char_type const* s2, size_type cch);
  200. /// Comparies the contents of \c src and \c dest up to \c cch characters
  201. static int_type str_n_compare_no_case(char_type const* s1, char_type const* s2, size_type cch);
  202. /// Evaluates the length of \c src
  203. static size_type str_len(char_type const* src);
  204. /// Finds the given character \c ch in \c s
  205. static char_type* str_chr(char_type const* s, char_type ch);
  206. /// Finds the rightmost instance \c ch in \c s
  207. static char_type* str_rchr(char_type const* s, char_type ch);
  208. /// Finds the given substring \c sub in \c s
  209. static char_type* str_str(char_type const* s, char_type const* sub);
  210. /// Finds one of a set of characters in \c s
  211. static char_type* str_pbrk(char_type const* s, char_type const* charSet);
  212. /// Returns a pointer to the end of the string
  213. static char_type* str_end(char_type const* s);
  214. /// Sets each character in \c s to the character \c c
  215. ///
  216. /// \return s + n
  217. static char_type* str_set(char_type* s, size_type n, char_type c);
  218. /// @}
  219. /// \name Dynamic Loading
  220. /// @{
  221. public:
  222. /// Loads the given executable module
  223. static module_type load_library(char_type const* name);
  224. /// Closes the given executable module
  225. static bool_type free_library(module_type hModule);
  226. /// Retrieves the given symbol from the library
  227. static void* find_symbol(module_type hModule, char const* symbolName);
  228. /// @}
  229. /// \name Kernel object control
  230. /// @{
  231. public:
  232. /// Closes the given operating system handle
  233. static bool_type close_handle(handle_type h);
  234. /// @}
  235. /// \name Error
  236. /// @{
  237. public:
  238. /// Gives the last error
  239. static error_type get_last_error();
  240. /// Sets the last error
  241. static void set_last_error(error_type er);
  242. /// @}
  243. /// \name Environment
  244. /// @{
  245. public:
  246. /// Gets an environment variable into the given buffer
  247. ///
  248. /// \param name The name of the variable to find
  249. /// \param buffer The buffer in which to write the variable. If this is NULL, then the required length is returned
  250. /// \param cchBuffer The size of the buffer, in characters
  251. static size_type get_environment_variable(char_type const* name, char_type* buffer, size_type cchBuffer);
  252. /// Expands environment strings in \c src into \c buffer, up to a maximum \c cchDest characters
  253. static size_type expand_environment_strings(char_type const* src, char_type* buffer, size_type cchBuffer);
  254. /// @}
  255. };
  256. #else /* ? STLSOFT_DOCUMENTATION_SKIP_SECTION */
  257. template <ss_typename_param_k C>
  258. struct system_traits;
  259. STLSOFT_TEMPLATE_SPECIALISATION
  260. struct system_traits<us_char_a_t>
  261. {
  262. public:
  263. typedef us_char_a_t char_type;
  264. typedef us_size_t size_type;
  265. typedef us_ptrdiff_t difference_type;
  266. typedef system_traits<us_char_a_t> class_type;
  267. typedef us_int_t int_type;
  268. typedef us_bool_t bool_type;
  269. typedef void* module_type;
  270. typedef int handle_type;
  271. typedef int result_code_type;
  272. typedef int error_type;
  273. public:
  274. static char_type* char_copy(char_type* dest, char_type const* src, size_type n)
  275. {
  276. return static_cast<char_type*>(::memcpy(dest, src, sizeof(char_type) * n));
  277. }
  278. #if !defined(STLSOFT_USING_SAFE_STR_FUNCTIONS) || \
  279. defined(_CRT_SECURE_NO_DEPRECATE)
  280. static char_type* str_copy(char_type* dest, char_type const* src)
  281. {
  282. return ::strcpy(dest, src);
  283. }
  284. static char_type* str_n_copy(char_type* dest, char_type const* src, size_type cch)
  285. {
  286. return ::strncpy(dest, src, cch);
  287. }
  288. static char_type* str_cat(char_type* dest, char_type const* src)
  289. {
  290. return ::strcat(dest, src);
  291. }
  292. static char_type* str_n_cat(char_type* dest, char_type const* src, size_type cch)
  293. {
  294. return ::strncat(dest, src, cch);
  295. }
  296. #endif /* !STLSOFT_USING_SAFE_STR_FUNCTIONS || _CRT_SECURE_NO_DEPRECATE */
  297. static int_type str_compare(char_type const* s1, char_type const* s2)
  298. {
  299. return ::strcmp(s1, s2);
  300. }
  301. static int_type str_compare_no_case(char_type const* s1, char_type const* s2);
  302. static int_type str_n_compare(char_type const* s1, char_type const* s2, size_type cch)
  303. {
  304. return ::strncmp(s1, s2, cch);
  305. }
  306. #ifdef _MSC_VER
  307. static int_type str_n_compare_no_case(char_type const* s1, char_type const* s2, size_type cch)
  308. {
  309. UNIXSTL_ASSERT(NULL != s1);
  310. UNIXSTL_ASSERT(NULL != s2);
  311. return ::_strnicmp(s1, s2, cch);
  312. }
  313. #else
  314. static int_type str_n_compare_no_case(char_type const* s1, char_type const* s2, size_type cch);
  315. #endif
  316. static size_type str_len(char_type const* src)
  317. {
  318. return static_cast<size_type>(::strlen(src));
  319. }
  320. static char_type* str_chr(char_type const* s, char_type ch)
  321. {
  322. return const_cast<char_type*>(::strchr(s, ch));
  323. }
  324. static char_type* str_rchr(char_type const* s, char_type ch)
  325. {
  326. return const_cast<char_type*>(::strrchr(s, ch));
  327. }
  328. static char_type* str_str(char_type const* s, char_type const* sub)
  329. {
  330. return const_cast<char_type*>(::strstr(s, sub));
  331. }
  332. static char_type* str_pbrk(char_type const* s, char_type const* charSet)
  333. {
  334. return const_cast<char_type*>(::strpbrk(s, charSet));
  335. }
  336. static char_type* str_end(char_type const* s)
  337. {
  338. UNIXSTL_ASSERT(NULL != s);
  339. for(; *s != '\0'; ++s)
  340. {}
  341. return const_cast<char_type*>(s);
  342. }
  343. static char_type* str_set(char_type* s, size_type n, char_type c)
  344. {
  345. UNIXSTL_ASSERT(NULL != s || 0u == n);
  346. for(; 0u != n; --n, ++s)
  347. {
  348. *s = c;
  349. }
  350. return s;
  351. }
  352. public:
  353. static module_type load_library(char_type const* name)
  354. {
  355. return ::dlopen(name, RTLD_NOW);
  356. }
  357. static bool_type free_library(module_type hModule)
  358. {
  359. return 0 == ::dlclose(hModule);
  360. }
  361. static void* find_symbol(module_type hModule, char const* symbolName)
  362. {
  363. return ::dlsym(hModule, symbolName);
  364. }
  365. public:
  366. static bool_type close_handle(handle_type h)
  367. {
  368. #if defined(_WIN32) && \
  369. ( defined(STLSOFT_COMPILER_IS_MSVC) || \
  370. defined(STLSOFT_COMPILER_IS_INTEL))
  371. return 0 == ::_close(h);
  372. #else /* ? _WIN32 */
  373. return 0 == ::close(h);
  374. #endif /* _WIN32 */
  375. }
  376. public:
  377. static error_type get_last_error()
  378. {
  379. return errno;
  380. }
  381. static void set_last_error(error_type er = error_type())
  382. {
  383. errno = er;
  384. }
  385. public:
  386. #if ( defined(STLSOFT_COMPILER_IS_MSVC) || \
  387. defined(STLSOFT_COMPILER_IS_INTEL)) && \
  388. defined(STLSOFT_USING_SAFE_STR_FUNCTIONS)
  389. # if _MSC_VER >= 1200
  390. # pragma warning(push)
  391. # endif /* compiler */
  392. # pragma warning(disable : 4996)
  393. #endif /* compiler */
  394. static size_type get_environment_variable(char_type const* name, char_type* buffer, size_type cchBuffer)
  395. {
  396. char const* var = ::getenv(name);
  397. if(NULL == var)
  398. {
  399. return 0;
  400. }
  401. else
  402. {
  403. us_size_t var_len = str_len(var);
  404. if(NULL == buffer)
  405. {
  406. return var_len;
  407. }
  408. else
  409. {
  410. size_type writtenLen = (var_len < cchBuffer) ? var_len : cchBuffer;
  411. char_copy(buffer, var, writtenLen);
  412. if(writtenLen < cchBuffer)
  413. {
  414. buffer[writtenLen] = '\0';
  415. }
  416. return (var_len < cchBuffer) ? var_len : cchBuffer;
  417. }
  418. }
  419. }
  420. #if ( defined(STLSOFT_COMPILER_IS_MSVC) || \
  421. defined(STLSOFT_COMPILER_IS_INTEL)) && \
  422. defined(STLSOFT_USING_SAFE_STR_FUNCTIONS)
  423. # if _MSC_VER >= 1200
  424. # pragma warning(pop)
  425. # else /* ? compiler */
  426. # pragma warning(default : 4996)
  427. # endif /* _MSC_VER */
  428. #endif /* compiler */
  429. static size_type expand_environment_strings(char_type const* src, char_type* buffer, size_type cchBuffer);
  430. };
  431. STLSOFT_TEMPLATE_SPECIALISATION
  432. struct system_traits<us_char_w_t>
  433. {
  434. public:
  435. typedef us_char_w_t char_type;
  436. typedef us_size_t size_type;
  437. typedef us_ptrdiff_t difference_type;
  438. typedef system_traits<us_char_a_t> class_type;
  439. typedef us_int_t int_type;
  440. typedef us_bool_t bool_type;
  441. typedef void* module_type;
  442. typedef int handle_type;
  443. typedef int result_code_type;
  444. typedef int error_type;
  445. public:
  446. static char_type* char_copy(char_type* dest, char_type const* src, size_type n)
  447. {
  448. return static_cast<char_type*>(::memcpy(dest, src, sizeof(char_type) * n));
  449. }
  450. #if !defined(STLSOFT_USING_SAFE_STR_FUNCTIONS) || \
  451. defined(_CRT_SECURE_NO_DEPRECATE)
  452. static char_type* str_copy(char_type* dest, char_type const* src)
  453. {
  454. return ::wcscpy(dest, src);
  455. }
  456. static char_type* str_n_copy(char_type* dest, char_type const* src, size_type cch)
  457. {
  458. return ::wcsncpy(dest, src, cch);
  459. }
  460. static char_type* str_cat(char_type* dest, char_type const* src)
  461. {
  462. return ::wcscat(dest, src);
  463. }
  464. static char_type* str_n_cat(char_type* dest, char_type const* src, size_type cch)
  465. {
  466. return ::wcsncat(dest, src, cch);
  467. }
  468. #endif /* !STLSOFT_USING_SAFE_STR_FUNCTIONS || _CRT_SECURE_NO_DEPRECATE */
  469. static int_type str_compare(char_type const* s1, char_type const* s2)
  470. {
  471. return ::wcscmp(s1, s2);
  472. }
  473. static int_type str_compare_no_case(char_type const* s1, char_type const* s2);
  474. static int_type str_n_compare(char_type const* s1, char_type const* s2, size_type cch)
  475. {
  476. return ::wcsncmp(s1, s2, cch);
  477. }
  478. #ifdef _MSC_VER
  479. static int_type str_n_compare_no_case(char_type const* s1, char_type const* s2, size_type cch)
  480. {
  481. UNIXSTL_ASSERT(NULL != s1);
  482. UNIXSTL_ASSERT(NULL != s2);
  483. return ::_wcsnicmp(s1, s2, cch);
  484. }
  485. #else
  486. static int_type str_n_compare_no_case(char_type const* s1, char_type const* s2, size_type cch);
  487. #endif
  488. static size_type str_len(char_type const* src)
  489. {
  490. return static_cast<size_type>(::wcslen(src));
  491. }
  492. static char_type* str_chr(char_type const* s, char_type ch)
  493. {
  494. return const_cast<char_type*>(::wcschr(s, ch));
  495. }
  496. static char_type* str_rchr(char_type const* s, char_type ch)
  497. {
  498. return const_cast<char_type*>(::wcsrchr(s, ch));
  499. }
  500. static char_type* str_str(char_type const* s, char_type const* sub)
  501. {
  502. return const_cast<char_type*>(::wcsstr(s, sub));
  503. }
  504. static char_type* str_pbrk(char_type const* s, char_type const* charSet)
  505. {
  506. return const_cast<char_type*>(::wcspbrk(s, charSet));
  507. }
  508. static char_type* str_end(char_type const* s)
  509. {
  510. UNIXSTL_ASSERT(NULL != s);
  511. for(; *s != L'\0'; ++s)
  512. {}
  513. return const_cast<char_type*>(s);
  514. }
  515. static char_type* str_set(char_type* s, size_type n, char_type c)
  516. {
  517. UNIXSTL_ASSERT(NULL != s || 0u == n);
  518. for(; 0u != n; --n, ++s)
  519. {
  520. *s = c;
  521. }
  522. return s;
  523. }
  524. public:
  525. static module_type load_library(char_type const* name);
  526. static bool_type free_library(module_type hModule)
  527. {
  528. return 0 == ::dlclose(hModule);
  529. }
  530. static void* find_symbol(module_type hModule, char const* symbolName)
  531. {
  532. return ::dlsym(hModule, symbolName);
  533. }
  534. public:
  535. static bool_type close_handle(handle_type h)
  536. {
  537. #if defined(_WIN32) && \
  538. defined(STLSOFT_COMPILER_IS_MSVC)
  539. return 0 == ::_close(h);
  540. #else /* ? _WIN32 */
  541. return 0 == ::close(h);
  542. #endif /* _WIN32 */
  543. }
  544. public:
  545. static error_type get_last_error()
  546. {
  547. return errno;
  548. }
  549. static void set_last_error(error_type er = error_type())
  550. {
  551. errno = er;
  552. }
  553. public:
  554. static size_type get_environment_variable(char_type const* name, char_type* buffer, size_type cchBuffer);
  555. static size_type expand_environment_strings(char_type const* src, char_type* buffer, size_type cchBuffer);
  556. };
  557. #endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */
  558. /* /////////////////////////////////////////////////////////////////////////
  559. * Unit-testing
  560. */
  561. #ifdef STLSOFT_UNITTEST
  562. # include "./unittest/system_traits_unittest_.h"
  563. #endif /* STLSOFT_UNITTEST */
  564. /* ////////////////////////////////////////////////////////////////////// */
  565. #ifndef _UNIXSTL_NO_NAMESPACE
  566. # if defined(_STLSOFT_NO_NAMESPACE) || \
  567. defined(STLSOFT_DOCUMENTATION_SKIP_SECTION)
  568. } // namespace unixstl
  569. # else
  570. } // namespace unixstl_project
  571. } // namespace stlsoft
  572. # endif /* _STLSOFT_NO_NAMESPACE */
  573. #endif /* !_UNIXSTL_NO_NAMESPACE */
  574. /* ////////////////////////////////////////////////////////////////////// */
  575. #endif /* UNIXSTL_INCL_UNIXSTL_SYSTEM_HPP_SYSTEM_TRAITS */
  576. /* ///////////////////////////// end of file //////////////////////////// */