on master help sign in
Set C language standard to C99 in runtime and codegen (#4308)

* Fix tests for compilation under Windows C preprocessor tests for detecting Windows were inconsistent across the code base, and in some cases wrong. This change makes the detection uniform and correct at all places. * Write `usleep` in terms of `nanosleep` `usleep` is deprecated and a compiler warning is issued if it's used with a POSIX compiler flag set. As an added bonus, it's range has been increased. * Set C language standard to C99 in runtime and codegen Currently the exact C language used by the runtime and the C code generator is not set and therefore different compilers may use different standards depending on their default behaviour. This may lead to inconsistencies in builds, such a sucessful build in one machine failing in another.

commita4c183c83762c8ef75c0c927fde3479ce356b0a4 authorAlex Queiroz <asandroq@gmail.com> dateSat 27 Jan 2018, 10:23 (9 years ago) parent183ae43
10 files changed+31−17
config.mk+1−1 libs/base/System.idr+3−3 libs/effects/Effect/System.idr+2−2 rts/idris_main.c+6−2 rts/idris_net.c+2−2 rts/idris_net.h+1−1 rts/idris_rts.c+8 rts/idris_rts.h+2 rts/idris_stdfgn.c+5−5 src/IRTS/CodegenC.hs+1−1
config.mk+1−1
@@ -14,7 +14,7 @@ RANLIB ?=ranlib
1414CABAL :=cabal
1515# IDRIS_ENABLE_STATS should not be set in final release
1616# Any flags defined here which alter the RTS API must also be added to src/IRTS/CodegenC.hs
17−CFLAGS :=-O2 -Wall -DHAS_PTHREAD -DIDRIS_ENABLE_STATS $(CFLAGS)
17+CFLAGS :=-O2 -Wall -std=c99 -D_POSIX_C_SOURCE=200809L -DHAS_PTHREAD -DIDRIS_ENABLE_STATS $(CFLAGS)
1818
1919# CABALFLAGS :=
2020CABALFLAGS += --enable-tests
libs/base/System.idr+3−3
@@ -93,9 +93,9 @@ time : IO Integer
9393time = do MkRaw t <- foreign FFI_C "idris_time" (IO (Raw Integer))
9494 pure t
9595
96−||| Specify interval to sleep for, must be in range [0, 1000000]
97−usleep : (i : Int) -> { auto prf : So (i >= 0 && i <= 1000000) } -> IO ()
98−usleep i = foreign FFI_C "usleep" (Int -> IO ()) i
96+||| Specify interval to sleep for in microseconds, must be nonnegative
97+usleep : (i : Int) -> { auto prf : So (i >= 0) } -> IO ()
98+usleep i = foreign FFI_C "idris_usleep" (Int -> IO ()) i
9999
100100||| Execute a program and returns its exit status code.
101101system : String -> IO Int
libs/effects/Effect/System.idr+2−2
@@ -15,7 +15,7 @@ data System : Effect where
1515 Time : sig System Integer
1616 GetEnv : String -> sig System (Maybe String)
1717 CSystem : String -> sig System Int
18− Usleep : (i : Int) -> (inbounds : So (i >= 0 && i <= 1000000)) -> sig System ()
18+ Usleep : (i : Int) -> (inbounds : So (i >= 0)) -> sig System ()
1919
2020implementation Handler System IO where
2121 handle () Args k = do x <- getArgs; k x ()
@@ -48,5 +48,5 @@ getEnv s = call $ GetEnv s
4848system : String -> Eff Int [SYSTEM]
4949system s = call $ CSystem s
5050
51−usleep : (i : Int) -> { auto prf : So (i >= 0 && i <= 1000000) } -> Eff () [SYSTEM]
51+usleep : (i : Int) -> { auto prf : So (i >= 0) } -> Eff () [SYSTEM]
5252usleep i {prf} = call $ Usleep i prf
rts/idris_main.c+6−2
@@ -4,8 +4,11 @@
44#include "idris_stats.h"
55
66void _idris__123_runMain_95_0_125_(VM* vm, VAL* oldbase);
7−#if defined(WIN32) || defined(__WIN32) || defined(__WIN32__)
7+
8+#ifdef _WIN32
9+
810#include <Windows.h>
11+
912int win32_get_argv_utf8(int *argc_ptr, char ***argv_ptr)
1013{
1114 int argc;
@@ -26,6 +29,7 @@ int win32_get_argv_utf8(int *argc_ptr, char ***argv_ptr)
2629 *argv_ptr = argv;
2730 return 0;
2831}
32+
2933#endif
3034
3135// The default options should give satisfactory results under many circumstances.
@@ -35,7 +39,7 @@ RTSOpts opts = {
3539 .show_summary = 0
3640};
3741
38−#if defined(WIN32) || defined(__WIN32) || defined(__WIN32__)
42+#ifdef _WIN32
3943int main() {
4044 int argc;
4145 char **argv;
rts/idris_net.c+2−2
@@ -8,7 +8,7 @@
88#include <stdio.h>
99#include <string.h>
1010
11−#ifndef WIN32
11+#ifndef _WIN32
1212#include <netinet/in.h>
1313#include <arpa/inet.h>
1414#else
@@ -58,7 +58,7 @@ void idrnet_free(void* ptr) {
5858
5959
6060int idrnet_socket(int domain, int type, int protocol) {
61−#ifdef WIN32
61+#ifdef _WIN32
6262 if (!check_init()) {
6363 return -1;
6464 }
rts/idris_net.h+1−1
@@ -2,7 +2,7 @@
22#define IDRISNET_H
33
44// Includes used by the idris-file.
5−#ifdef WIN32
5+#ifdef _WIN32
66#include <winsock2.h>
77#include <Ws2tcpip.h>
88#else
rts/idris_rts.c+8
@@ -1225,6 +1225,14 @@ void idris_disableBuffering(void) {
12251225 setvbuf(stdout, NULL, _IONBF, 0);
12261226}
12271227
1228+int idris_usleep(int usec) {
1229+ struct timespec t;
1230+ t.tv_sec = usec / 1000000;
1231+ t.tv_nsec = (usec % 1000000) * 1000;
1232+
1233+ return nanosleep(&t, NULL);
1234+}
1235+
12281236void stackOverflow(void) {
12291237 fprintf(stderr, "Stack overflow");
12301238 exit(-1);
rts/idris_rts.h+2
@@ -442,6 +442,8 @@ const char *idris_getArg(int i);
442442// disable stdin/stdout buffering
443443void idris_disableBuffering(void);
444444
445+int idris_usleep(int usec);
446+
445447// Handle stack overflow.
446448// Just reports an error and exits.
447449
rts/idris_stdfgn.c+5−5
@@ -10,7 +10,7 @@
1010#include <time.h>
1111#include <dirent.h>
1212
13−#if defined(WIN32) || defined(__WIN32) || defined(__WIN32__)
13+#ifdef _WIN32
1414int win_fpoll(void* h);
1515FILE *win32_u8fopen(const char *path, const char *mode);
1616FILE *win32_u8popen(const char *path, const char *mode);
@@ -25,7 +25,7 @@ void putStr(char* str) {
2525}
2626
2727void *fileOpen(char *name, char *mode) {
28−#if defined(WIN32) || defined(__WIN32) || defined(__WIN32__)
28+#ifdef _WIN32
2929 FILE *f = win32_u8fopen(name, mode);
3030#else
3131 FILE *f = fopen(name, mode);
@@ -97,7 +97,7 @@ char* idris_nextDirEntry(void* h) {
9797}
9898
9999int idris_mkdir(char* dname) {
100−#if defined(WIN32) || defined(__WIN32) || defined(__WIN32__)
100+#ifdef _WIN32
101101 return mkdir(dname);
102102#else
103103 return mkdir(dname, S_IRWXU | S_IRGRP | S_IROTH);
@@ -119,7 +119,7 @@ int idris_writeStr(void* h, char* str) {
119119
120120int fpoll(void* h)
121121{
122−#if defined(WIN32) || defined(__WIN32) || defined(__WIN32__)
122+#ifdef _WIN32
123123 return win_fpoll(h);
124124#else
125125 FILE* f = (FILE*)h;
@@ -138,7 +138,7 @@ int fpoll(void* h)
138138}
139139
140140void *do_popen(const char *cmd, const char *mode) {
141−#if defined(WIN32) || defined(__WIN32) || defined(__WIN32__)
141+#ifdef _WIN32
142142 FILE *f = win32_u8popen(cmd, mode);
143143#else
144144 FILE *f = popen(cmd, mode);
src/IRTS/CodegenC.hs+1−1
@@ -83,7 +83,7 @@ codegenC' defs out exec incs objs libs flags exports iface dbg
8383 let args = gccDbg dbg ++
8484 gccFlags iface ++
8585 -- # Any flags defined here which alter the RTS API must also be added to config.mk
86− ["-DHAS_PTHREAD", "-DIDRIS_ENABLE_STATS",
86+ ["-std=c99", "-D_POSIX_C_SOURCE=200809L", "-DHAS_PTHREAD", "-DIDRIS_ENABLE_STATS",
8787 "-I."] ++ objs ++ envFlags ++
8888 (if (exec == Executable) then [] else ["-c"]) ++
8989 [tmpn] ++