summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2014-01-09 21:08:11 -0800
committerKaz Kylheku <kaz@kylheku.com>2014-01-09 21:08:11 -0800
commit439bd03e10053c088eac26da28c0a85be0c325a4 (patch)
treebfb2a5bd8e7a74ceb3db4fec8b4378d72aa441f3
parent0b86366870e0a1e45955881a2d3206175061271e (diff)
downloadtxr-439bd03e10053c088eac26da28c0a85be0c325a4.tar.gz
txr-439bd03e10053c088eac26da28c0a85be0c325a4.tar.bz2
txr-439bd03e10053c088eac26da28c0a85be0c325a4.zip
Long overdue MinGW port maintenance.
* Makefile: Use new EXE variable from config.mk. * configure (exe, have_windows_h): New variables. Handle situations with .exe suffix; on MiGW, the rm command doesn't work on executables if the .exe suffix is not given. New tests for localtime_r and gmtime_r. * lib.c: Supply declarations which are missing on MinGW because we use gcc -ansi, because MinGW doesn't follow established conventions like -D_POSIX_SOURCE. Supply definitions for gmtime_r, localtime_r, setenv and unsetenv. * parser.l: Supply declarations which are missing on MinGW. * signal.h (async_sig_enabled): Declare differently based on HAVE_POSIX_SIGS. Misspelled typedef fixed in the code for !HAVE_POSIX_SIGS that has hitherto not been compiled. (sig_mask): Wrap declaration in #ifdef HAVE_POSIX_SIGS because it relies on sigset_t. * stream.c: Supply declarations which are missing on MinGW. Include <windows.h> if we have it. (sleep): Define for Windows. (statf): Handle missing st_blksize and st_blocks members in struct stat. (stream_init): Handle numerous missing S_* macros. * utf8.c: Supply declarations which are missing on MinGW.
-rw-r--r--ChangeLog34
-rw-r--r--Makefile6
-rwxr-xr-xconfigure79
-rw-r--r--lib.c51
-rw-r--r--parser.l4
-rw-r--r--signal.h8
-rw-r--r--stream.c91
-rw-r--r--utf8.c4
8 files changed, 245 insertions, 32 deletions
diff --git a/ChangeLog b/ChangeLog
index 81684acb..61bdf165 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,37 @@
+2013-01-09 Kaz Kylheku <kaz@kylheku.com>
+
+ Long overdue MinGW port maintenance.
+
+ * Makefile: Use new EXE variable from config.mk.
+
+ * configure (exe, have_windows_h): New variables.
+ Handle situations with .exe suffix; on MiGW, the rm command
+ doesn't work on executables if the .exe suffix is not given.
+ New tests for localtime_r and gmtime_r.
+
+ * lib.c: Supply declarations which are missing on MinGW because
+ we use gcc -ansi, because MinGW doesn't follow established conventions
+ like -D_POSIX_SOURCE. Supply definitions for gmtime_r, localtime_r,
+ setenv and unsetenv.
+
+ * parser.l: Supply declarations which are missing on MinGW.
+
+ * signal.h (async_sig_enabled): Declare differently based on
+ HAVE_POSIX_SIGS.
+ Misspelled typedef fixed in the code for !HAVE_POSIX_SIGS
+ that has hitherto not been compiled.
+ (sig_mask): Wrap declaration in #ifdef HAVE_POSIX_SIGS because
+ it relies on sigset_t.
+
+ * stream.c: Supply declarations which are missing on MinGW.
+ Include <windows.h> if we have it.
+ (sleep): Define for Windows.
+ (statf): Handle missing st_blksize and st_blocks members in struct
+ stat.
+ (stream_init): Handle numerous missing S_* macros.
+
+ * utf8.c: Supply declarations which are missing on MinGW.
+
2013-01-08 Kaz Kylheku <kaz@kylheku.com>
Version 73
diff --git a/Makefile b/Makefile
index 3b8b78ca..99d0b66f 100644
--- a/Makefile
+++ b/Makefile
@@ -78,7 +78,7 @@ rebuild: clean repatch $(PROG)
.PHONY: clean
clean: conftest.clean
- rm -f $(PROG) $(OBJS) $(OBJS-y) \
+ rm -f $(PROG)$(EXE) $(OBJS) $(OBJS-y) \
y.tab.c lex.yy.c y.tab.h y.output $(TESTS:.ok=.out)
.PHONY: repatch
@@ -195,6 +195,6 @@ conftest.ccver:
.PHONY: conftest.clean
conftest.clean:
- @rm -f conftest conftest.[co] \
- conftest2 conftest[12].[oc] \
+ @rm -f conftest$(EXE) conftest.[co] \
+ conftest2$(EXE) conftest[12].[oc] \
conftest.err conftest.syms
diff --git a/configure b/configure
index a08d9ab4..791f6c6e 100755
--- a/configure
+++ b/configure
@@ -72,6 +72,7 @@ compiler_prefix=
ccname=gcc
cc='$(cross)$(compiler_prefix)$(ccname)'
intptr=
+exe=
tool_prefix=
lex='$(cross)$(tool_prefix)flex'
lexlib=-lfl
@@ -100,6 +101,7 @@ have_patch=
have_unistd=
have_timegm=
have_syslog=
+have_windows_h=
have_posix_sigs=
need_svid_source=
need_bsd_source=
@@ -586,6 +588,9 @@ debug_support := $debug_support
# MPI version
mpi_version := $mpi_version
+# EXE suffix
+exe := $exe
+
CC := $cc
LEX := $lex
LEXLIB := $lexlib
@@ -639,7 +644,7 @@ int main(void)
}
!
-rm -f conftest
+rm -f conftest conftest.exe
if ! $make conftest > conftest.err 2>&1 || ! [ -x conftest ] ; then
printf "failed\n\n"
printf "Errors from compilation: \n\n"
@@ -647,9 +652,19 @@ if ! $make conftest > conftest.err 2>&1 || ! [ -x conftest ] ; then
exit 1
fi
-rm -f conftest
printf "okay\n"
+printf "Checking whether executables have that idiotic .exe suffix ... "
+
+if ls conftest.exe > /dev/null ; then
+ echo "yes"
+ exe=.exe
+else
+ echo "no"
+fi
+
+rm -f conftest$exe
+
#
# Check for annoying clashes from non-conforming BSD-derived systems that don't
# honor Unix/POSIX feature selection macros!
@@ -684,7 +699,7 @@ int $ident(void);
int main(void) { return 0; }
!
- rm -f conftest
+ rm -f conftest$exe
if ! $make conftest > conftest.err 2>&1 || ! [ -x conftest ] ; then
printf "#define %s txr_%s\n" $ident $ident >> config.h
have_unistd=y
@@ -1048,7 +1063,7 @@ $inline int func(void)
return 0;
}
!
- rm -f conftest2
+ rm -f conftest2$exe
if ! $make conftest2 > conftest.err 2>&1 || ! [ -x conftest2 ] ; then
continue
fi
@@ -1146,7 +1161,7 @@ int main(void)
return 0;
}
!
-rm -f conftest
+rm -f conftest$exe
if ! $make conftest > conftest.err 2>&1 || ! [ -x conftest ] ; then
printf "no\n"
else
@@ -1170,7 +1185,7 @@ int main(void)
return 0;
}
!
-rm -f conftest
+rm -f conftest$exe
if ! $make conftest > conftest.err 2>&1 || ! [ -x conftest ] ; then
printf "no\n"
else
@@ -1195,7 +1210,7 @@ int main(void)
return 0;
}
!
-rm -f conftest
+rm -f conftest$exe
if ! $make conftest > conftest.err 2>&1 || ! [ -x conftest ] ; then
printf "no\n"
else
@@ -1218,12 +1233,13 @@ int main(void)
return 0;
}
!
-rm -f conftest
+rm -f conftest$exe
if ! $make conftest > conftest.err 2>&1 || ! [ -x conftest ] ; then
printf "no\n"
else
printf "yes\n"
printf "#define HAVE_GETENVIRONMENTSTRINGS 1\n" >> config.h
+ have_windows_h=y
fi
#
@@ -1250,7 +1266,7 @@ int main(int argc, char **argv)
return 0;
}
!
-rm -f conftest
+rm -f conftest$exe
if ! $make conftest > conftest.err 2>&1 || ! [ -x conftest ] ; then
printf "no\n"
else
@@ -1308,7 +1324,7 @@ int main(void)
return 0;
}
!
-rm -f conftest
+rm -f conftest$exe
if ! $make EXTRA_FLAGS='-D_SVID_SOURCE' conftest > conftest.err 2>&1 || ! [ -x conftest ] ; then
printf "no\n"
else
@@ -1331,7 +1347,7 @@ int main(void)
return 0;
}
!
- rm -f conftest
+ rm -f conftest$exe
if ! $make EXTRA_FLAGS='-D_BSD_SOURCE' conftest > conftest.err 2>&1 || ! [ -x conftest ] ; then
printf "no\n"
else
@@ -1351,7 +1367,7 @@ int main(void)
return 0;
}
!
-rm -f conftest
+rm -f conftest$exe
if ! $make conftest > conftest.err 2>&1 || ! [ -x conftest ] ; then
printf "no\n"
else
@@ -1359,6 +1375,31 @@ else
printf "#define HAVE_TZSET 1\n" >> config.h
fi
+printf "Checking for localtime_r and gmtime_r functions ... "
+
+cat > conftest.c <<!
+#include <time.h>
+
+int main(int argc, char **argv)
+{
+ struct tm stm;
+ time_t t;
+
+ localtime_r(&t, &stm);
+ gmtime_r(&t, &stm);
+ return 0;
+}
+!
+rm -f conftest$exe
+if ! $make conftest > conftest.err 2>&1 || ! [ -x conftest ] ; then
+ printf "no\n"
+else
+ printf "yes\n"
+ printf "#define HAVE_GMTIME_R 1\n" >> config.h
+ have_unistd=y
+fi
+
+
printf "Checking for POSIX sleep function ... "
cat > conftest.c <<!
@@ -1370,7 +1411,7 @@ int main(int argc, char **argv)
return 0;
}
!
-rm -f conftest
+rm -f conftest$exe
if ! $make conftest > conftest.err 2>&1 || ! [ -x conftest ] ; then
printf "no\n"
else
@@ -1389,7 +1430,7 @@ int main(int argc, char **argv)
return daemon(0, 0);
}
!
-rm -f conftest
+rm -f conftest$exe
if ! $make conftest > conftest.err 2>&1 || ! [ -x conftest ] ; then
printf "no\n"
else
@@ -1409,7 +1450,7 @@ int main(void)
return 0;
}
!
-rm -f conftest
+rm -f conftest$exe
if ! $make conftest > conftest.err 2>&1 || ! [ -x conftest ] ; then
printf "no\n"
else
@@ -1432,7 +1473,7 @@ int main(void)
return 0;
}
!
-rm -f conftest
+rm -f conftest$exe
if ! $make conftest > conftest.err 2>&1 || ! [ -x conftest ] ; then
printf "no\n"
else
@@ -1459,7 +1500,7 @@ int main(void)
return 0;
}
!
-rm -f conftest
+rm -f conftest$exe
if ! $make conftest > conftest.err 2>&1 || ! [ -x conftest ] ; then
printf "no\n"
else
@@ -1476,6 +1517,10 @@ if [ -n "$have_unistd" ] ; then
printf "#define HAVE_UNISTD_H 1\n" >> config.h
fi
+if [ -n "$have_windows_h" ] ; then
+ printf "#define HAVE_WINDOWS_H 1\n" >> config.h
+fi
+
#
# Extra debugging.
#
diff --git a/lib.c b/lib.c
index 0939bd9a..54927f81 100644
--- a/lib.c
+++ b/lib.c
@@ -60,6 +60,15 @@
#define max(a, b) ((a) > (b) ? (a) : (b))
#define min(a, b) ((a) < (b) ? (a) : (b))
+#if HAVE_WINDOWS_H
+int putenv(const char *);
+int tzset(void);
+#endif
+
+#if !HAVE_POSIX_SIGS
+int async_sig_enabled = 0;
+#endif
+
val packages;
val system_package, keyword_package, user_package;
@@ -5086,6 +5095,29 @@ val time_sec_usec(void)
return cons(num(tv.tv_sec), num(tv.tv_usec));
}
+#if !HAVE_GMTIME_R
+/*
+ * Ugly hacks for MingW, which uses the Microsft C Run Time Library,
+ * whic in turn is stuck in the Dark Ages * without _r functions.
+ */
+struct tm *gmtime_r(const time_t *timep, struct tm *result);
+struct tm *localtime_r(const time_t *timep, struct tm *result);
+
+struct tm *gmtime_r(const time_t *timep, struct tm *result)
+{
+ struct tm *hack = gmtime(timep);
+ *result = *hack;
+ return hack;
+}
+
+struct tm *localtime_r(const time_t *timep, struct tm *result)
+{
+ struct tm *hack = localtime(timep);
+ *result = *hack;
+ return hack;
+}
+#endif
+
static val string_time(struct tm *(*break_time_fn)(const time_t *, struct tm *),
char *format, time_t time)
{
@@ -5158,6 +5190,25 @@ val make_time(val year, val month, val day,
return make_time_impl(mktime, year, month, day, hour, minute, second, isdst);
}
+#if !HAVE_SETENV
+static void
+setenv(const char *name, const char *value, int overwrite)
+{
+ int len = strlen(name)+1+strlen(value)+1;
+ char *str = (char *) chk_malloc(len);
+ (void) overwrite;
+ sprintf(str, "%s=%s", name, value);
+ putenv(str);
+}
+
+static void
+unsetenv(const char *name)
+{
+ setenv(name, "", 1);
+}
+
+#endif
+
#if !HAVE_TIMEGM
static time_t timegm_hack(struct tm *tm)
{
diff --git a/parser.l b/parser.l
index bdac7a6a..6ffc4db8 100644
--- a/parser.l
+++ b/parser.l
@@ -50,6 +50,10 @@
#include "hash.h"
#include "parser.h"
+#if HAVE_WINDOWS_H
+int fileno(FILE *stream);
+#endif
+
#define YY_INPUT(buf, result, max_size) \
do { \
val c = get_byte(yyin_stream); \
diff --git a/signal.h b/signal.h
index 8882c259..32281e9a 100644
--- a/signal.h
+++ b/signal.h
@@ -76,6 +76,7 @@ typedef struct {
((EJB).rv = (ARG), longjmp((EJB).jb, 1))
extern sigset_t sig_blocked_cache;
+extern volatile sig_atomic_t async_sig_enabled;
#else
@@ -85,14 +86,13 @@ extern sigset_t sig_blocked_cache;
#define sig_restore_enable do { } while (0); } while (0)
#define sig_restore_disable do { } while (0); } while (0)
-tyedef jmp_buf extended_jmp_buf;
+typedef jmp_buf extended_jmp_buf;
#define extended_setjmp(EJB) setjmp(EJB)
#define extended_longjmp(EJB, ARG) longjmp(EJB, ARG)
+extern int async_sig_enabled;
#endif
-extern volatile sig_atomic_t async_sig_enabled;
-
extern val sig_hup, sig_int, sig_quit, sig_ill, sig_trap, sig_abrt, sig_bus;
extern val sig_fpe, sig_kill, sig_usr1, sig_segv, sig_usr2, sig_pipe, sig_alrm;
extern val sig_term, sig_chld, sig_cont, sig_stop, sig_tstp, sig_ttin;
@@ -104,4 +104,6 @@ void sig_init(void);
val set_sig_handler(val signo, val lambda);
val get_sig_handler(val signo);
val sig_check(void);
+#if HAVE_POSIX_SIGS
int sig_mask(int how, const sigset_t *set, sigset_t *oldset);
+#endif
diff --git a/stream.c b/stream.c
index a9be6fd2..60d98800 100644
--- a/stream.c
+++ b/stream.c
@@ -45,6 +45,9 @@
#if HAVE_SYS_STAT
#include <sys/stat.h>
#endif
+#if HAVE_WINDOWS_H
+#include <windows.h>
+#endif
#include "lib.h"
#include "gc.h"
#include "signal.h"
@@ -52,6 +55,11 @@
#include "stream.h"
#include "utf8.h"
+#if HAVE_WINDOWS_H
+int fileno(FILE *stream);
+int pclose(FILE *stream);
+#endif
+
val std_input, std_output, std_debug, std_error, std_null;
val output_produced;
@@ -405,6 +413,20 @@ static void tail_calc(unsigned long *state, int *sec, int *mod)
*mod = 1;
}
+#if !HAVE_POSIX_SLEEP && HAVE_WINDOWS_H
+
+int sleep(int sec);
+
+int sleep(int sec)
+{
+ Sleep(sec * 1000);
+ return 0;
+}
+
+#else
+#error port me!
+#endif
+
static void tail_strategy(val stream, unsigned long *state)
{
struct stdio_handle *h = (struct stdio_handle *) stream->co.handle;
@@ -983,7 +1005,6 @@ static struct strm_ops dir_ops = {
0 /* set_prop */
};
-
static val make_stdio_stream_common(FILE *f, val descr, struct cobj_ops *ops)
{
struct stdio_handle *h = (struct stdio_handle *) chk_malloc(sizeof *h);
@@ -1835,8 +1856,13 @@ val statf(val path)
gid_k, num(st.st_gid),
rdev_k, num(st.st_rdev),
size_k, num(st.st_size),
+#if !HAVE_WINDOWS_H
blksize_k, num(st.st_blksize),
blocks_k, num(st.st_blocks),
+#else
+ blksize_k, zero,
+ blocks_k, zero,
+#endif
atime_k, num(st.st_atime),
mtime_k, num(st.st_mtime),
ctime_k, num(st.st_ctime),
@@ -2139,12 +2165,59 @@ void stream_init(void)
real_time_k = intern(lit("real-time"), keyword_package);
name_k = intern(lit("name"), keyword_package);
- s_ifmt = num(S_IFMT); s_iflnk = num(S_IFLNK);
+ s_ifmt = num(S_IFMT);
+
+#ifdef S_IFLNK
+ s_iflnk = num(S_IFLNK);
+#endif
+
s_ifreg = num(S_IFREG); s_ifblk = num(S_IFBLK); s_ifdir = num(S_IFDIR);
- s_ifchr = num(S_IFCHR); s_ififo = num(S_IFIFO); s_isuid = num(S_ISUID);
- s_isgid = num(S_ISGID); s_isvtx = num(S_ISVTX); s_irwxu = num(S_IRWXU);
- s_irusr = num(S_IRUSR); s_iwusr = num(S_IWUSR); s_ixusr = num(S_IXUSR);
- s_irwxg = num(S_IRWXG); s_irgrp = num(S_IRGRP); s_iwgrp = num(S_IWGRP);
- s_ixgrp = num(S_IXGRP); s_irwxo = num(S_IRWXO); s_iroth = num(S_IROTH);
- s_iwoth = num(S_IWOTH); s_ixoth = num(S_IXOTH);
-}
+ s_ifchr = num(S_IFCHR); s_ififo = num(S_IFIFO);
+
+#ifdef S_ISUID
+ s_isuid = num(S_ISUID);
+#endif
+
+#ifdef S_ISGID
+ s_isgid = num(S_ISGID);
+#endif
+
+#ifdef S_ISVTX
+ s_isvtx = num(S_ISVTX);
+#endif
+
+ s_irwxu = num(S_IRWXU); s_irusr = num(S_IRUSR); s_iwusr = num(S_IWUSR);
+ s_ixusr = num(S_IXUSR);
+
+#ifdef S_IRWXG
+ s_irwxg = num(S_IRWXG);
+#endif
+
+#ifdef S_IRGRP
+ s_irgrp = num(S_IRGRP);
+#endif
+
+#ifdef S_IWGRP
+ s_iwgrp = num(S_IWGRP);
+#endif
+
+#ifdef S_IXGRP
+ s_ixgrp = num(S_IXGRP);
+#endif
+
+#ifdef S_IRWXO
+ s_irwxo = num(S_IRWXO);
+#endif
+
+#ifdef S_IROTH
+ s_iroth = num(S_IROTH);
+#endif
+
+#ifdef S_IWOTH
+ s_iwoth = num(S_IWOTH);
+#endif
+
+#ifdef S_IXOTH
+ s_ixoth = num(S_IXOTH);
+#endif
+}
diff --git a/utf8.c b/utf8.c
index 36354277..c37e7d8d 100644
--- a/utf8.c
+++ b/utf8.c
@@ -36,6 +36,10 @@
#include "unwind.h"
#include "utf8.h"
+#if HAVE_WINDOWS_H
+FILE *popen(const char *path, const char *mode);
+#endif
+
#if WCHAR_MAX > 65535
#define FULL_UNICODE
#endif