From 12082b01c280150e5906140ccd804a75efc459b0 Mon Sep 17 00:00:00 2001 From: Bruno Santos Date: Wed, 12 Nov 2008 22:34:49 +0000 Subject: [PATCH] Add compatibility to MS Visual C Add support for the MS Visual C compiler in 'git-compat-util.h' for FLEX_ARRAY and NORETURN. Include the new header 'compat/msvc.h' that provides configuration suport for building with the MS Visual C (with some help of an external library for posix compatiblity). Implemented the configuration helpers in compat/msvc.c, this configuration helpers are need because we should not use hardcoded paths in Windows. Signed-off-by: Bruno Santos --- compat/msvc.c | 133 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ compat/msvc.h | 44 ++++++++++++++++++ git-compat-util.h | 21 +++++++-- 3 files changed, 193 insertions(+), 5 deletions(-) create mode 100644 compat/msvc.c create mode 100644 compat/msvc.h diff --git a/compat/msvc.c b/compat/msvc.c new file mode 100644 index 0000000000..9ece1cdf2a --- /dev/null +++ b/compat/msvc.c @@ -0,0 +1,133 @@ +#include "../git-compat-util.h" +#include + +inline void utf16_to_utf8(char *dst, const wchar_t *src, size_t len) +{ + if (!WideCharToMultiByte(CP_UTF8, 0, src, len, dst, len, NULL, NULL)) + die("failed to convert from UTF-16 to UTF-8: %d", GetLastError()); +} + +const char *msvc_get_exec_path() +{ + static char *exe_path; + + if (!exe_path) { + wchar_t *wpath = NULL; + size_t wlen = MAX_PATH / 4; + char *path; + size_t len; + + do { + wlen *= 4; + wpath = xrealloc(wpath, wlen * sizeof(wchar_t)); + len = GetModuleFileNameW(NULL, wpath, wlen); + + } while (len == wlen); + + path = xmalloc((len + 1) * sizeof(wchar_t)); + utf16_to_utf8(path, wpath, len + 1); + free(wpath); + + len = (strrchr(path, '\\') - path); + assert(len != ((char*) NULL - path)); + path[len] = '\0'; + exe_path = xrealloc(path, len + 1); + } + + return exe_path; +} + +const char *msvc_get_etc_gitconfig() +{ + static char *etc_path; + + if (!etc_path) { + static const char etc[] = "/etc/gitconfig"; + const char *epath = msvc_get_exec_path(); + char *path; + size_t len = strlen(epath); + + path = xmalloc(len + sizeof(etc)); + memcpy(path, epath, len); + memcpy(path + len, etc, sizeof(etc)); + etc_path = path; + } + + return etc_path; +} + +const char *msvc_get_man_path() +{ + static char *man_path; + + if (!man_path) { + static const char man[] = "/man"; + const char *epath = msvc_get_exec_path(); + char *path; + size_t len = strlen(epath); + + path = xmalloc(len + sizeof(man)); + memcpy(path, epath, len); + memcpy(path + len, man, sizeof(man)); + man_path = path; + } + + return man_path; +} + +const char *msvc_get_info_path() +{ + static char *info_path; + + if (!info_path) { + static const char info[] = "/info"; + const char *epath = msvc_get_exec_path(); + char *path; + size_t len = strlen(epath); + + path = xmalloc(len + sizeof(info)); + memcpy(path, epath, len); + memcpy(path + len, info, sizeof(info)); + info_path = path; + } + + return info_path; +} + +const char *msvc_get_html_path() +{ + static char *html_path; + + if (!html_path) { + static const char html[] = "/html"; + const char *epath = msvc_get_exec_path(); + char *path; + size_t len = strlen(epath); + + path = xmalloc(len + sizeof(html)); + memcpy(path, epath, len); + memcpy(path + len, html, sizeof(html)); + html_path = path; + } + + return html_path; +} + +const char *msvc_get_template_path() +{ + static char *template_path; + + if (!template_path) { + static const char template[] = "/template"; + const char *epath = msvc_get_exec_path(); + char *path; + size_t len = strlen(epath); + + path = xmalloc(len + sizeof(template)); + memcpy(path, epath, len); + memcpy(path + len, template, sizeof(template)); + template_path = path; + } + + return template_path; +} diff --git a/compat/msvc.h b/compat/msvc.h new file mode 100644 index 0000000000..dccb40b057 --- /dev/null +++ b/compat/msvc.h @@ -0,0 +1,44 @@ +#ifndef GIT_COMPAT_MSVC_H +#define GIT_COMPAT_MSVC_H + +#if !defined(_MSC_VER) || (_MSC_VER < 1400) +# error You need at least Visual Studio 2005 +#endif + +#define inline __inline +#define va_copy(d, s) do { (d) = (s); } while(0) + +#define SHA1_HEADER "mozilla-sha1/sha1.h" + +#define NO_OPENSSL +#define NO_ICONV + +#define NO_MKDTEMP /* support for this may be added later */ +#define NO_STRCASESTR +#define NO_STRLCPY +#define NO_STRTOUMAX +#define NO_MEMMEM +#define INTERNAL_QSORT /* use internal qsort to benefit from ltcg */ + +#include + +#define GIT_EXEC_PATH msvc_get_exec_path() +#define ETC_GITCONFIG msvc_get_etc_gitconfig() +#define GIT_MAN_PATH msvc_get_man_path() +#define GIT_INFO_PATH msvc_get_info_path() +#define GIT_HTML_PATH msvc_get_html_path() +#define DEFAULT_GIT_TEMPLATE_DIR msvc_get_template_path() +#define GIT_USER_AGENT "git/" GIT_VERSION + +const char *msvc_get_exec_path(); +const char *msvc_get_etc_gitconfig(); /* GIT_EXEC_PATH "/etc/gitconfig" */ +const char *msvc_get_man_path(); /* GIT_EXEC_PATH "/man" */ +const char *msvc_get_info_path(); /* GIT_EXEC_PATH "/info" */ +const char *msvc_get_html_path(); /* GIT_EXEC_PATH "/html" */ +const char *msvc_get_template_path(); /* GIT_EXEC_PATH "/template" */ + +#define has_dos_drive_prefix(path) (isalpha(path[0]) && path[1] == ':') +#define is_dir_sep(c) (c == '/' || c == '\\') +#define PATH_SEP ';' + +#endif /* GIT_COMPAT_MSVC_H */ diff --git a/git-compat-util.h b/git-compat-util.h index cf89cdf459..63200ed515 100644 --- a/git-compat-util.h +++ b/git-compat-util.h @@ -15,6 +15,8 @@ # else # define FLEX_ARRAY 0 /* older GNU extension */ # endif +#elif defined(_MSVC_VER) +# define FLEX_ARRAY /* empty */ #endif /* @@ -71,6 +73,9 @@ #include #include #include +#include +#include +#ifndef _MSC_VER #include #ifndef NO_SYS_SELECT_H #include @@ -79,8 +84,6 @@ #include #include #include -#include -#include #if defined(__CYGWIN__) #undef _XOPEN_SOURCE #include @@ -90,7 +93,10 @@ #include #define _ALL_SOURCE 1 #endif -#else /* __MINGW32__ */ +#else +#include "compat/msvc.h" +#endif /* _MSC_VER */ +#else /* pull in Windows compatibility stuff */ #include "compat/mingw.h" #endif /* __MINGW32__ */ @@ -142,10 +148,15 @@ #define __attribute__(x) #endif #endif +#ifdef _MSC_VER +#define MSC_NORETURN __declspec(noreturn) +#else +#define MSC_NORETURN +#endif /* General helper functions */ -extern void usage(const char *err) NORETURN; -extern void die(const char *err, ...) NORETURN __attribute__((format (printf, 1, 2))); +extern MSC_NORETURN void usage(const char *err) NORETURN; +extern MSC_NORETURN void die(const char *err, ...) NORETURN __attribute__((format (printf, 1, 2))); extern int error(const char *err, ...) __attribute__((format (printf, 1, 2))); extern void warning(const char *err, ...) __attribute__((format (printf, 1, 2))); -- 2.11.4.GIT