Mingw support, and refactor a bit gdTest on Windows, simplifies

master
Pierre Joye 2021-08-27 18:16:19 +07:00
parent 1b3f6fbe94
commit 6b5946fea0
1 changed files with 74 additions and 63 deletions

View File

@ -8,6 +8,7 @@
#include <string.h>
#include <math.h>
#include <limits.h>
#include <time.h>
#ifdef HAVE_DIRENT_H
#include <dirent.h>
@ -22,10 +23,14 @@
#include <sys/types.h>
#endif
#ifdef _WIN32
#if defined(_WIN32) && !defined(__MINGW32__) && !defined(__MINGW64__)
#include "readdir.h"
#include <errno.h>
#endif
#if defined(__MINGW32__) && defined(__MINGW64__)
# define lstat stat
#endif
#include "gd_intern.h"
/* GDTEST_TOP_DIR is defined in other compile ways except msys
* test_config.h is created by windows/msys/run_test.sh*/
@ -94,7 +99,7 @@ static void _clean_dir(const char *dir)
if (strcmp(de->d_name, ".") == 0 || strcmp(de->d_name, "..") == 0)
continue;
#ifdef _WIN32
#if defined(_WIN32) && !defined(__MINGW32__) && !defined(__MINGW64__)
{
WIN32_FILE_ATTRIBUTE_DATA data;
@ -133,26 +138,7 @@ static void tmpdir_cleanup(void)
free(tmpdir_base);
}
#ifdef _WIN32
char* strrstr (char* haystack, char* needle)
{
int needle_length = strlen(needle);
char * haystack_end = haystack + strlen(haystack) - needle_length;
char * p;
int i;
for(p = haystack_end; p >= haystack; --p)
{
for(i = 0; i < needle_length; ++i) {
if(p[i] != needle[i])
goto next;
}
return p;
next:;
}
return 0;
}
#if defined(_WIN32) && !defined(__MINGW32__) && !defined(__MINGW64__)
typedef VOID (WINAPI *MyGetSystemTimeAsFileTime)(LPFILETIME lpSystemTimeAsFileTime);
@ -203,6 +189,39 @@ static int getfilesystemtime(struct timeval *tv)
return 0;
}
#endif
#if defined(_WIN32)
static void randtemplate(char *template, size_t l) {
for (int i = l - 6; i < l; i++) {
int r = rand ();
if ((r / (RAND_MAX + 1)) > ((RAND_MAX + 1) / 2))
template[i] = 'A' + (double) rand () / (RAND_MAX + 1) * ('Z' - 'A');
else
template[i] = 'a' + (double) rand () / (RAND_MAX + 1) * ('z' - 'a');
}
}
char* strrstr (char* haystack, char* needle)
{
int needle_length = strlen(needle);
char * haystack_end = haystack + strlen(haystack) - needle_length;
char * p;
int i;
for(p = haystack_end; p >= haystack; --p)
{
for(i = 0; i < needle_length; ++i) {
if(p[i] != needle[i])
goto next;
}
return p;
next:;
}
return 0;
}
static char *
mkdtemp (char *tmpl)
@ -214,45 +233,32 @@ mkdtemp (char *tmpl)
struct timeval tv;
__int64 value;
int count;
size_t l;
char attempts = 5;
int res = 0;
/* find the last occurrence of "XXXXXX" */
XXXXXX = strrstr(tmpl, "XXXXXX");
if (!XXXXXX || strncmp (XXXXXX, "XXXXXX", 6)) {
if (tmpl == NULL) {
errno = EINVAL;
return NULL;
}
/* Get some more or less random data. */
getfilesystemtime(&tv);
value = (tv.tv_usec ^ tv.tv_sec) + counter++;
for (count = 0; count < 100; value += 7777, ++count) {
__int64 v = value;
/* Fill in the random bits. */
XXXXXX[0] = letters[v % NLETTERS];
v /= NLETTERS;
XXXXXX[1] = letters[v % NLETTERS];
v /= NLETTERS;
XXXXXX[2] = letters[v % NLETTERS];
v /= NLETTERS;
XXXXXX[3] = letters[v % NLETTERS];
v /= NLETTERS;
XXXXXX[4] = letters[v % NLETTERS];
v /= NLETTERS;
XXXXXX[5] = letters[v % NLETTERS];
/* tmpl is in UTF-8 on Windows, thus use g_mkdir() */
if (mkdir(tmpl) == 0) {
return tmpl;
}
printf("failed to create directory\n");
if (errno != EEXIST)
/* Any other error will apply also to other names we might
* try, and there are 2^32 or so of them, so give up now.
*/
return NULL;
l = strlen (tmpl);
if (l < 6 || strcmp (&tmpl[l - 6], "XXXXXX") != 0) {
errno = EINVAL;
return NULL;
}
srand(time (NULL));
do {
randtemplate (tmpl, l);
res = mkdir(tmpl);
attempts--;
} while (attempts > 0 && res != 0 );
if (res == 0) {
return tmpl;
}
if (errno != EEXIST) {
return NULL;
}
/* We got out of the loop because we ran out of combinations to try. */
@ -265,22 +271,27 @@ const char *gdTestTempDir(void)
{
if (tmpdir_base == NULL) {
char *tmpdir;
#ifdef _WIN32
char tmpdir_root[MAX_PATH];
#if defined(_WIN32) && !defined(__MINGW32__) && !defined(__MINGW64__)
char tmpdir_root[MAXPATHLEN];
size_t tmpdir_root_len = GetTempPath(MAX_PATH, tmpdir_root);
gdTestAssert(!(tmpdir_root_len > MAX_PATH || (tmpdir_root_len == 0)));
gdTestAssert((tmpdir_root_len + 30 < MAX_PATH));
#else
char *tmpdir_root;
tmpdir_root = getenv("TMPDIR");
if (tmpdir_root == NULL)
tmpdir_root = "/tmp";
if (tmpdir_root == NULL) {
// Mingw defines it
tmpdir_root = getenv("TMP");
if (tmpdir_root == NULL) {
tmpdir_root = "/tmp";
}
}
#endif
/* The constant here is a lazy over-estimate. */
tmpdir = malloc(strlen(tmpdir_root) + 30);
gdTestAssert(tmpdir != NULL);
#ifdef _WIN32
#if defined(_WIN32)
sprintf(tmpdir, "%sgdtest.XXXXXX", tmpdir_root);
#else
sprintf(tmpdir, "%s/gdtest.XXXXXX", tmpdir_root);
@ -299,7 +310,7 @@ char *gdTestTempFile(const char *template)
const char *tempdir = gdTestTempDir();
char *ret;
#ifdef _WIN32
#if defined(_WIN32) && !defined(__MINGW32__) && !defined(__MINGW64__)
{
char *tmpfilename;
UINT error;
@ -364,7 +375,7 @@ char *gdTestFilePathV(const char *path, va_list args)
strcpy(file, GDTEST_TOP_DIR);
p = path;
do {
#ifdef _WIN32
#if defined(_WIN32) && !defined(__MINGW32__) && !defined(__MINGW64__)
strcat(file, "\\");
#else
strcat(file, "/");