Commit 2f795d8fc50d81641d95723d9ddd92795886bed3

Jacques Germishuys 2014-07-12T14:45:56

Cleanup portability/compatibility layer * Removes mingw-compat.h * Cleans up separation of compiler/platform idiosyncrasies * Unifies mingw/msvc stat structures and functions * (Tries to) hide more compiler specific implementation details (even in our internal API)

diff --git a/src/path.h b/src/path.h
index 3e6efe3..e10aeb0 100644
--- a/src/path.h
+++ b/src/path.h
@@ -8,6 +8,7 @@
 #define INCLUDE_path_h__
 
 #include "common.h"
+#include "posix.h"
 #include "buffer.h"
 #include "vector.h"
 
diff --git a/src/posix.h b/src/posix.h
index 965cd98..9ef3487 100644
--- a/src/posix.h
+++ b/src/posix.h
@@ -12,23 +12,61 @@
 #include <time.h>
 #include "fnmatch.h"
 
+/* stat: file mode type testing macros */
 #ifndef S_IFGITLINK
 #define S_IFGITLINK 0160000
 #define S_ISGITLINK(m) (((m) & S_IFMT) == S_IFGITLINK)
 #endif
 
+#ifndef S_IFLNK
+#define S_IFLNK 0120000
+#undef _S_IFLNK
+#define _S_IFLNK S_IFLNK
+#endif
+
+#ifndef S_IXUSR
+#define S_IXUSR 00100
+#endif
+
+#ifndef S_ISLNK
+#define S_ISLNK(m) (((m) & _S_IFMT) == _S_IFLNK)
+#endif
+
+#ifndef S_ISDIR
+#define S_ISDIR(m) (((m) & _S_IFMT) == _S_IFDIR)
+#endif
+
+#ifndef S_ISREG
+#define S_ISREG(m) (((m) & _S_IFMT) == _S_IFREG)
+#endif
+
+#ifndef S_ISFIFO
+#define S_ISFIFO(m) (((m) & _S_IFMT) == _S_IFIFO)
+#endif
+
 /* if S_ISGID is not defined, then don't try to set it */
 #ifndef S_ISGID
 #define S_ISGID 0
 #endif
 
-#if !defined(O_BINARY)
+#ifndef O_BINARY
 #define O_BINARY 0
 #endif
-#if !defined(O_CLOEXEC)
+#ifndef O_CLOEXEC
 #define O_CLOEXEC 0
 #endif
 
+/* access() mode parameter #defines	*/
+#ifndef F_OK
+#define F_OK 0 /* existence check */
+#endif
+#ifndef W_OK
+#define W_OK 2 /* write mode check */
+#endif
+#ifndef R_OK
+#define R_OK 4 /* read mode check */
+#endif
+
 /* Determine whether an errno value indicates that a read or write failed
  * because the descriptor is blocked.
  */
@@ -38,6 +76,12 @@
 #define GIT_ISBLOCKED(e) ((e) == EAGAIN)
 #endif
 
+/* define some standard errnos that the runtime may be missing.  for example,
+ * mingw lacks EAFNOSUPPORT. */
+#ifndef EAFNOSUPPORT
+#define EAFNOSUPPORT (INT_MAX-1)
+#endif
+
 typedef int git_file;
 
 /**
@@ -56,8 +100,6 @@ typedef int git_file;
 extern int p_read(git_file fd, void *buf, size_t cnt);
 extern int p_write(git_file fd, const void *buf, size_t cnt);
 
-#define p_fstat(f,b) fstat(f, b)
-#define p_lseek(f,n,w) lseek(f, n, w)
 #define p_close(fd) close(fd)
 #define p_umask(m) umask(m)
 
@@ -66,30 +108,6 @@ extern int p_creat(const char *path, mode_t mode);
 extern int p_getcwd(char *buffer_out, size_t size);
 extern int p_rename(const char *from, const char *to);
 
-#ifndef GIT_WIN32
-
-#define p_stat(p,b) stat(p, b)
-#define p_chdir(p) chdir(p)
-#define p_rmdir(p) rmdir(p)
-#define p_chmod(p,m) chmod(p, m)
-#define p_access(p,m) access(p,m)
-#define p_ftruncate(fd, sz) ftruncate(fd, sz)
-#define p_recv(s,b,l,f) recv(s,b,l,f)
-#define p_send(s,b,l,f) send(s,b,l,f)
-typedef int GIT_SOCKET;
-#define INVALID_SOCKET -1
-
-#define p_localtime_r localtime_r
-#define p_gmtime_r gmtime_r
-
-#else
-
-typedef SOCKET GIT_SOCKET;
-extern struct tm * p_localtime_r (const time_t *timer, struct tm *result);
-extern struct tm * p_gmtime_r (const time_t *timer, struct tm *result);
-
-#endif
-
 /**
  * Platform-dependent methods
  */
diff --git a/src/unix/posix.h b/src/unix/posix.h
index ccdc753..0c8732a 100644
--- a/src/unix/posix.h
+++ b/src/unix/posix.h
@@ -10,7 +10,16 @@
 #include <stdio.h>
 #include <sys/param.h>
 
+typedef int GIT_SOCKET;
+#define INVALID_SOCKET -1
+
+#define p_strcasecmp(s1, s2) strcasecmp(s1, s2)
+#define p_strncasecmp(s1, s2, c) strncasecmp(s1, s2, c)
+
+#define p_lseek(f,n,w) lseek(f, n, w)
+#define p_fstat(f,b) fstat(f, b)
 #define p_lstat(p,b) lstat(p,b)
+
 #define p_readlink(a, b, c) readlink(a, b, c)
 #define p_symlink(o,n) symlink(o, n)
 #define p_link(o,n) link(o, n)
@@ -18,6 +27,10 @@
 #define p_mkdir(p,m) mkdir(p, m)
 #define p_fsync(fd) fsync(fd)
 
+#define p_recv(s,b,l,f) recv(s,b,l,f)
+#define p_send(s,b,l,f) send(s,b,l,f)
+#define p_inet_pton(a, b, c) inet_pton(a, b, c)
+
 /* The OpenBSD realpath function behaves differently */
 #if !defined(__OpenBSD__)
 # define p_realpath(p, po) realpath(p, po)
@@ -28,9 +41,17 @@ char *p_realpath(const char *, char *);
 #define p_vsnprintf(b, c, f, a) vsnprintf(b, c, f, a)
 #define p_snprintf(b, c, f, ...) snprintf(b, c, f, __VA_ARGS__)
 #define p_mkstemp(p) mkstemp(p)
-#define p_inet_pton(a, b, c) inet_pton(a, b, c)
+#define p_stat(p,b) stat(p, b)
+#define p_chdir(p) chdir(p)
+#define p_chmod(p,m) chmod(p, m)
+#define p_rmdir(p) rmdir(p)
+#define p_access(p,m) access(p,m)
+#define p_ftruncate(fd, sz) ftruncate(fd, sz)
 
 /* see win32/posix.h for explanation about why this exists */
 #define p_lstat_posixly(p,b) lstat(p,b)
 
+#define p_localtime_r(c, r) localtime_r(c, r)
+#define p_gmtime_r(c, r) gmtime_r(c, r)
+
 #endif
diff --git a/src/win32/mingw-compat.h b/src/win32/mingw-compat.h
index 059e39c..83ee287 100644
--- a/src/win32/mingw-compat.h
+++ b/src/win32/mingw-compat.h
@@ -9,18 +9,11 @@
 
 #if defined(__MINGW32__)
 
-/* use a 64-bit file offset type */
-# undef lseek
-# define lseek _lseeki64
-# undef stat
-# define stat _stati64
-# undef fstat
-# define fstat _fstati64
-
-/* stat: file mode type testing macros */
-# define _S_IFLNK 0120000
-# define S_IFLNK _S_IFLNK
-# define S_ISLNK(m) (((m) & _S_IFMT) == _S_IFLNK)
+#if _WIN32_WINNT >= 0x0601
+#define stat __stat64
+#else
+#define stat _stati64
+#endif
 
 #endif
 
diff --git a/src/win32/msvc-compat.h b/src/win32/msvc-compat.h
index fa4e291..efbc8ee 100644
--- a/src/win32/msvc-compat.h
+++ b/src/win32/msvc-compat.h
@@ -9,32 +9,10 @@
 
 #if defined(_MSC_VER)
 
-/* access() mode parameter #defines	*/
-#	define F_OK 0 /* existence check */
-#	define W_OK 2 /* write mode check */
-#	define R_OK 4 /* read mode check */
+/* 64-bit stat information, regardless of USE_32BIT_TIME_T define */
+#define stat __stat64
 
-#	define lseek _lseeki64
-#	define stat __stat64
-#	define fstat _fstat64
-
-/* stat: file mode type testing macros */
-#	define _S_IFLNK 0120000
-#	define S_IFLNK _S_IFLNK
-#	define S_IXUSR 00100
-
-#	define S_ISDIR(m)	(((m) & _S_IFMT) == _S_IFDIR)
-#	define S_ISREG(m)	(((m) & _S_IFMT) == _S_IFREG)
-#	define S_ISFIFO(m) (((m) & _S_IFMT) == _S_IFIFO)
-#	define S_ISLNK(m) (((m) & _S_IFMT) == _S_IFLNK)
-
-#	define mode_t unsigned short
-
-/* case-insensitive string comparison */
-#	define strcasecmp	_stricmp
-#	define strncasecmp _strnicmp
-
-/* MSVC doesn't define ssize_t at all */
+typedef unsigned short mode_t;
 typedef SSIZE_T ssize_t;
 
 /* define snprintf using variadic macro support if available */
diff --git a/src/win32/posix.h b/src/win32/posix.h
index 22ea6a5..8472837 100644
--- a/src/win32/posix.h
+++ b/src/win32/posix.h
@@ -12,30 +12,18 @@
 #include "utf-conv.h"
 #include "dir.h"
 
-/* define some standard errnos that the runtime may be missing.  for example,
- * mingw lacks EAFNOSUPPORT. */
+typedef SOCKET GIT_SOCKET;
 
-#ifndef EAFNOSUPPORT
-# define EAFNOSUPPORT (INT_MAX-1)
-#endif
-
-#if defined(_MSC_VER) && _MSC_VER >= 1500
-# define p_ftruncate(fd, sz) _chsize_s(fd, sz)
-#else  /* MinGW */
-# define p_ftruncate(fd, sz) _chsize(fd, sz)
-#endif
+#define p_strcasecmp(s1, s2) _stricmp(s1, s2)
+#define p_strncasecmp(s1, s2, c) _strnicmp(s1, s2, c)
 
-GIT_INLINE(int) p_link(const char *old, const char *new)
-{
-	GIT_UNUSED(old);
-	GIT_UNUSED(new);
-	errno = ENOSYS;
-	return -1;
-}
+#define p_lseek(f,n,w) _lseeki64(f, n, w)
+#define p_fstat(f,b) _fstat64(f, b)
+extern int p_lstat(const char *file_name, struct stat *buf);
 
-extern int p_mkdir(const char *path, mode_t mode);
+extern int p_link(const char *old, const char *new);
 extern int p_unlink(const char *path);
-extern int p_lstat(const char *file_name, struct stat *buf);
+extern int p_mkdir(const char *path, mode_t mode);
 extern int p_readlink(const char *path, char *buf, size_t bufsiz);
 extern int p_symlink(const char *old, const char *new);
 extern char *p_realpath(const char *orig_path, char *buffer);
@@ -47,15 +35,15 @@ extern int p_chdir(const char* path);
 extern int p_chmod(const char* path, mode_t mode);
 extern int p_rmdir(const char* path);
 extern int p_access(const char* path, mode_t mode);
+extern int p_ftruncate(int fd, long size);
 extern int p_fsync(int fd);
-extern int p_open(const char *path, int flags, ...);
-extern int p_creat(const char *path, mode_t mode);
-extern int p_getcwd(char *buffer_out, size_t size);
-extern int p_rename(const char *from, const char *to);
 extern int p_recv(GIT_SOCKET socket, void *buffer, size_t length, int flags);
 extern int p_send(GIT_SOCKET socket, const void *buffer, size_t length, int flags);
 extern int p_inet_pton(int af, const char* src, void* dst);
 
+extern struct tm * p_localtime_r (const time_t *timer, struct tm *result);
+extern struct tm * p_gmtime_r (const time_t *timer, struct tm *result);
+
 /* p_lstat is almost but not quite POSIX correct.  Specifically, the use of
  * ENOTDIR is wrong, in that it does not mean precisely that a non-directory
  * entry was encountered.  Making it correct is potentially expensive,
diff --git a/src/win32/posix_w32.c b/src/win32/posix_w32.c
index a74fcaa..7df8100 100644
--- a/src/win32/posix_w32.c
+++ b/src/win32/posix_w32.c
@@ -51,6 +51,15 @@ static int utf8_to_16_with_errno(git_win32_path dest, const char *src)
 	return len;
 }
 
+int p_ftruncate(int fd, long size)
+{
+#if defined(_MSC_VER) && _MSC_VER >= 1500
+	return _chsize_s(fd, size);
+#else
+	return _chsize(fd, size);
+#endif
+}
+
 int p_mkdir(const char *path, mode_t mode)
 {
 	git_win32_path buf;
@@ -63,6 +72,14 @@ int p_mkdir(const char *path, mode_t mode)
 	return _wmkdir(buf);
 }
 
+int p_link(const char *old, const char *new)
+{
+	GIT_UNUSED(old);
+	GIT_UNUSED(new);
+	errno = ENOSYS;
+	return -1;
+}
+
 int p_unlink(const char *path)
 {
 	git_win32_path buf;