From 92a07003b2ce449b22709fbd9b4f1e49b3a2fd3e Mon Sep 17 00:00:00 2001 From: Howard Hinnant Date: Thu, 22 Sep 2011 19:10:18 +0000 Subject: [PATCH] Partial Windows port by Ruben Van Boxem git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@140328 91177308-0d34-0410-b5e6-96231b3b80d8 --- CREDITS.TXT | 4 + include/__config | 8 + include/__locale | 22 ++- include/cerrno | 316 ++++++++++++++++++++++++++++++++ include/locale | 2 + include/support/win32/locale.h | 37 ++++ include/support/win32/support.h | 15 ++ include/type_traits | 2 +- lib/CMakeLists.txt | 10 +- src/support/win32/support.cpp | 22 +++ 10 files changed, 433 insertions(+), 5 deletions(-) create mode 100644 include/support/win32/locale.h create mode 100644 include/support/win32/support.h create mode 100644 src/support/win32/support.cpp diff --git a/CREDITS.TXT b/CREDITS.TXT index 619968c42..093bfc5ac 100644 --- a/CREDITS.TXT +++ b/CREDITS.TXT @@ -24,3 +24,7 @@ D: Initial regex prototype N: David Chisnall E: theraven at theravensnest dot org D: FreeBSD port and libcxxrt support. + +N: Ruben Van Boxem +E: vanboxem dot ruben at gmail dot com +D: Initial Windows patches. diff --git a/include/__config b/include/__config index 84a7dddee..6f983223a 100644 --- a/include/__config +++ b/include/__config @@ -50,6 +50,10 @@ #ifdef _WIN32 # define _LIBCPP_LITTLE_ENDIAN 1 # define _LIBCPP_BIG_ENDIAN 0 +// Compiler intrinsics (GCC or MSVC) +# if (defined(_MSC_VER) && _MSC_VER >= 1400) || (__GNUC__ >= 4 && __GNUC_MINOR__ > 3) +# define _LIBCP_HAS_IS_BASE_OF +# endif #endif // _WIN32 #if !defined(_LIBCPP_LITTLE_ENDIAN) || !defined(_LIBCPP_BIG_ENDIAN) @@ -164,6 +168,10 @@ typedef __char32_t char32_t; #define _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS #endif +#if __has_feature(is_base_of) +# define _LIBCP_HAS_IS_BASE_OF +#endif + // Objective-C++ features (opt-in) #if __has_feature(objc_arc) #define _LIBCPP_HAS_OBJC_ARC diff --git a/include/__locale b/include/__locale index 7ae1a343a..42c9c5ae7 100644 --- a/include/__locale +++ b/include/__locale @@ -19,7 +19,11 @@ #include #include #include -#include +#if _WIN32 +# include +#else // _WIN32 +# include +#endif // _WIN32 #pragma GCC system_header @@ -314,7 +318,19 @@ public: static const mask punct = _ISpunct; static const mask xdigit = _ISxdigit; static const mask blank = _ISblank; -#else // __GLIBC__ +#elif _WIN32 + typedef unsigned __int32 mask; + static const mask space = _SPACE; + static const mask print = _BLANK|_PUNCT|_ALPHA|_DIGIT; + static const mask cntrl = _CONTROL; + static const mask upper = _UPPER; + static const mask lower = _LOWER; + static const mask alpha = _ALPHA; + static const mask digit = _DIGIT; + static const mask punct = _PUNCT; + static const mask xdigit = _HEX; + static const mask blank = _BLANK; +#else // __GLIBC__ || _WIN32 #if __APPLE__ typedef __uint32_t mask; #elif __FreeBSD__ @@ -330,7 +346,7 @@ public: static const mask punct = _CTYPE_P; static const mask xdigit = _CTYPE_X; static const mask blank = _CTYPE_B; -#endif // __GLIBC__ +#endif // __GLIBC__ || _WIN32 static const mask alnum = alpha | digit; static const mask graph = alnum | punct; diff --git a/include/cerrno b/include/cerrno index e8c2e578e..71084a14a 100644 --- a/include/cerrno +++ b/include/cerrno @@ -72,4 +72,320 @@ const int __elast2 = 105; #endif // !defined(EOWNERDEAD) || !defined(ENOTRECOVERABLE) +// supply errno values likely to be missing, particularly on Windows + +#ifndef EAFNOSUPPORT +#define EAFNOSUPPORT 9901 +#endif + +#ifndef EADDRINUSE +#define EADDRINUSE 9902 +#endif + +#ifndef EADDRNOTAVAIL +#define EADDRNOTAVAIL 9903 +#endif + +#ifndef EISCONN +#define EISCONN 9904 +#endif + +#ifndef EBADMSG +#define EBADMSG 9905 +#endif + +#ifndef ECONNABORTED +#define ECONNABORTED 9906 +#endif + +#ifndef EALREADY +#define EALREADY 9907 +#endif + +#ifndef ECONNREFUSED +#define ECONNREFUSED 9908 +#endif + +#ifndef ECONNRESET +#define ECONNRESET 9909 +#endif + +#ifndef EDESTADDRREQ +#define EDESTADDRREQ 9910 +#endif + +#ifndef EHOSTUNREACH +#define EHOSTUNREACH 9911 +#endif + +#ifndef EIDRM +#define EIDRM 9912 +#endif + +#ifndef EMSGSIZE +#define EMSGSIZE 9913 +#endif + +#ifndef ENETDOWN +#define ENETDOWN 9914 +#endif + +#ifndef ENETRESET +#define ENETRESET 9915 +#endif + +#ifndef ENETUNREACH +#define ENETUNREACH 9916 +#endif + +#ifndef ENOBUFS +#define ENOBUFS 9917 +#endif + +#ifndef ENOLINK +#define ENOLINK 9918 +#endif + +#ifndef ENODATA +#define ENODATA 9919 +#endif + +#ifndef ENOMSG +#define ENOMSG 9920 +#endif + +#ifndef ENOPROTOOPT +#define ENOPROTOOPT 9921 +#endif + +#ifndef ENOSR +#define ENOSR 9922 +#endif + +#ifndef ENOTSOCK +#define ENOTSOCK 9923 +#endif + +#ifndef ENOSTR +#define ENOSTR 9924 +#endif + +#ifndef ENOTCONN +#define ENOTCONN 9925 +#endif + +#ifndef ENOTSUP +#define ENOTSUP 9926 +#endif + +#ifndef ECANCELED +#define ECANCELED 9927 +#endif + +#ifndef EINPROGRESS +#define EINPROGRESS 9928 +#endif + +#ifndef EOPNOTSUPP +#define EOPNOTSUPP 9929 +#endif + +#ifndef EWOULDBLOCK +#define EWOULDBLOCK 9930 +#endif + +#ifndef EOWNERDEAD +#define EOWNERDEAD 9931 +#endif + +#ifndef EPROTO +#define EPROTO 9932 +#endif + +#ifndef EPROTONOSUPPORT +#define EPROTONOSUPPORT 9933 +#endif + +#ifndef ENOTRECOVERABLE +#define ENOTRECOVERABLE 9934 +#endif + +#ifndef ETIME +#define ETIME 9935 +#endif + +#ifndef ETXTBSY +#define ETXTBSY 9936 +#endif + +#ifndef ETIMEDOUT +#define ETIMEDOUT 9938 +#endif + +#ifndef ELOOP +#define ELOOP 9939 +#endif + +#ifndef EOVERFLOW +#define EOVERFLOW 9940 +#endif + +#ifndef EPROTOTYPE +#define EPROTOTYPE 9941 +#endif + +#ifndef ENOSYS +#define ENOSYS 9942 +#endif + +#ifndef EINVAL +#define EINVAL 9943 +#endif + +#ifndef ERANGE +#define ERANGE 9944 +#endif + +#ifndef EILSEQ +#define EILSEQ 9945 +#endif + +// Windows Mobile doesn't appear to define these: + +#ifndef E2BIG +#define E2BIG 9946 +#endif + +#ifndef EDOM +#define EDOM 9947 +#endif + +#ifndef EFAULT +#define EFAULT 9948 +#endif + +#ifndef EBADF +#define EBADF 9949 +#endif + +#ifndef EPIPE +#define EPIPE 9950 +#endif + +#ifndef EXDEV +#define EXDEV 9951 +#endif + +#ifndef EBUSY +#define EBUSY 9952 +#endif + +#ifndef ENOTEMPTY +#define ENOTEMPTY 9953 +#endif + +#ifndef ENOEXEC +#define ENOEXEC 9954 +#endif + +#ifndef EEXIST +#define EEXIST 9955 +#endif + +#ifndef EFBIG +#define EFBIG 9956 +#endif + +#ifndef ENAMETOOLONG +#define ENAMETOOLONG 9957 +#endif + +#ifndef ENOTTY +#define ENOTTY 9958 +#endif + +#ifndef EINTR +#define EINTR 9959 +#endif + +#ifndef ESPIPE +#define ESPIPE 9960 +#endif + +#ifndef EIO +#define EIO 9961 +#endif + +#ifndef EISDIR +#define EISDIR 9962 +#endif + +#ifndef ECHILD +#define ECHILD 9963 +#endif + +#ifndef ENOLCK +#define ENOLCK 9964 +#endif + +#ifndef ENOSPC +#define ENOSPC 9965 +#endif + +#ifndef ENXIO +#define ENXIO 9966 +#endif + +#ifndef ENODEV +#define ENODEV 9967 +#endif + +#ifndef ENOENT +#define ENOENT 9968 +#endif + +#ifndef ESRCH +#define ESRCH 9969 +#endif + +#ifndef ENOTDIR +#define ENOTDIR 9970 +#endif + +#ifndef ENOMEM +#define ENOMEM 9971 +#endif + +#ifndef EPERM +#define EPERM 9972 +#endif + +#ifndef EACCES +#define EACCES 9973 +#endif + +#ifndef EROFS +#define EROFS 9974 +#endif + +#ifndef EDEADLK +#define EDEADLK 9975 +#endif + +#ifndef EAGAIN +#define EAGAIN 9976 +#endif + +#ifndef ENFILE +#define ENFILE 9977 +#endif + +#ifndef EMFILE +#define EMFILE 9978 +#endif + +#ifndef EMLINK +#define EMLINK 9979 +#endif + #endif // _LIBCPP_CERRNO diff --git a/include/locale b/include/locale index e40a04ce1..2c532a724 100644 --- a/include/locale +++ b/include/locale @@ -186,7 +186,9 @@ template class messages_byname; #endif #include #include +#if !_WIN32 #include +#endif // !_WIN32 #pragma GCC system_header diff --git a/include/support/win32/locale.h b/include/support/win32/locale.h new file mode 100644 index 000000000..c53b27a95 --- /dev/null +++ b/include/support/win32/locale.h @@ -0,0 +1,37 @@ +// -*- C++ -*- +//===--------------------------- support/win32/locale.h --------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Locale stuff +// FIXME: the *_l functions are fairly new, only available on Vista?/7+ +#include // +#define locale_t _locale_t +#define strtoll_l _strtoi64_l +#define strtoull_l _strtoui64_l +// FIXME: current msvcrt does not know about long double +#define strtold_l _strtod_l +#define isdigit_l _isdigit_l +#define isxdigit_l _isxdigit_l +#define newlocale _create_locale +#define freelocale _free_locale +// FIXME: first call _configthreadlocale(_ENABLE_PER_THREAD_LOCALE) somewhere +// FIXME: return types are different, need to make locale_t from char* +inline locale_t uselocale(locale_t newloc) +{ + return newlocale( LC_ALL, setlocale(LC_ALL, newloc->locinfo->lc_category[LC_ALL].locale) ); +} + +#define LC_COLLATE_MASK _M_COLLATE +#define LC_CTYPE_MASK _M_CTYPE +#define LC_MONETARY_MASK _M_MONETARY +#define LC_NUMERIC_MASK _M_NUMERIC +#define LC_TIME_MASK _M_TIME +#define LC_MESSAGES_MASK _M_MESSAGES + +enum { NL_SETD=0, NL_CAT_LOCALE=1 }; diff --git a/include/support/win32/support.h b/include/support/win32/support.h new file mode 100644 index 000000000..1a464bf7b --- /dev/null +++ b/include/support/win32/support.h @@ -0,0 +1,15 @@ +// -*- C++ -*- +//===--------------------------- support/win32/support.h --------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +/* + Functions and constants used in libc++ that are missing from the Windows C library. + */ + +int vasprintf( char **sptr, const char *__restrict__ fmt , va_list ap ); diff --git a/include/type_traits b/include/type_traits index 58d160ee6..c6a20e245 100644 --- a/include/type_traits +++ b/include/type_traits @@ -725,7 +725,7 @@ template struct _LIBCPP_VISIBLE is_convertible // is_base_of -#if __has_feature(is_base_of) +#ifdef _LIBCP_HAS_IS_BASE_OF template struct _LIBCPP_VISIBLE is_base_of diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt index d8065cdcf..f4af4e069 100644 --- a/lib/CMakeLists.txt +++ b/lib/CMakeLists.txt @@ -1,9 +1,17 @@ # Get sources -file(GLOB_RECURSE sources ../src/*.cpp) +file(GLOB sources ../src/*.cpp) +if(WIN32) + file(GLOB win32_sources ../src/support/win32/*.cpp) + list(APPEND sources ${win32_sources}) +endif() # Add all the headers to the project for IDEs. if (MSVC_IDE OR XCODE) file(GLOB_RECURSE headers ../include/*) + if(WIN32) + file( GLOB win32_headers ../include/support/win32/*.h) + list(APPEND headers ${win32_headers}) + endif() # Force them all into the headers dir on MSVC, otherwise they end up at # project scope because they don't have extensions. if (MSVC_IDE) diff --git a/src/support/win32/support.cpp b/src/support/win32/support.cpp new file mode 100644 index 000000000..7033809bd --- /dev/null +++ b/src/support/win32/support.cpp @@ -0,0 +1,22 @@ +// -*- C++ -*- +//===--------------------------- support/win32/support.h --------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +int vasprintf( char **sptr, const char *__restrict__ fmt, va_list ap ) +{ + *sptr = NULL + int count = vsnprintf( *sptr, 0, fmt, ap ); + if( (count >= 0) && ((*sptr = malloc(count+1)) != NULL) ) + { + vsprintf( *sptr, fmt, ap ); + sptr[count] = '\0'; + } + + return count; +}