From a27ecff0e684aeb0ccb25ff1d43247e165e2cc01 Mon Sep 17 00:00:00 2001
From: Ary Borenszweig <aborenszweig@manas.com.ar>
Date: Thu, 21 Aug 2014 16:08:29 -0300
Subject: [PATCH] CFileIO working in windows when cross compiling

---
 samples/windows.cr  | 104 ++++++++++++++++++++++++++++++++++++++++++++
 src/io/c_file_io.cr |  23 ++++++++--
 src/prelude.cr      |   2 +-
 3 files changed, 124 insertions(+), 5 deletions(-)
 create mode 100644 samples/windows.cr

diff --git a/samples/windows.cr b/samples/windows.cr
new file mode 100644
index 0000000000..9f598397d7
--- /dev/null
+++ b/samples/windows.cr
@@ -0,0 +1,104 @@
+# (work in progress)
+#
+# Compile (in linux or mac) with:
+#
+#     --prelude=empty --single-module --cross-compile="windows x86"
+#
+# and then compile with clang on Windows from a VisualC++ command prompt:
+#
+#     clang-cl windows.bc msvcrt.lib
+#
+# This generates windows.exe
+
+require "intrinsics"
+require "c"
+require "macros"
+require "object"
+require "reference"
+# require "exception"
+require "value"
+require "struct"
+require "function"
+# require "thread"
+require "gc"
+require "gc/null"
+# require "gc/boehm"
+require "class"
+require "comparable"
+require "nil"
+require "bool"
+require "char"
+require "number"
+require "int"
+require "float"
+require "enumerable"
+require "pointer"
+require "slice"
+require "range"
+require "char_reader"
+require "string"
+require "symbol"
+require "static_array"
+require "array"
+require "hash"
+require "set"
+require "tuple"
+require "box"
+# require "math"
+# require "process"
+require "io"
+require "argv"
+# require "env"
+# require "exec"
+# require "file"
+# require "dir"
+# require "time"
+# require "random"
+# require "regex"
+# require "raise"
+# require "errno"
+# require "main"
+
+class Exception
+  getter message
+  getter cause
+  getter backtrace
+
+  def initialize(message = nil : String?, cause = nil : Exception?)
+    @message = message
+    @cause = cause
+    # @backtrace = caller
+  end
+end
+
+class EmptyEnumerable < Exception
+  def initialize(message = "Empty enumerable")
+    super(message)
+  end
+end
+
+class IndexOutOfBounds < Exception
+  def initialize(message = "Index out of bounds")
+    super(message)
+  end
+end
+
+class ArgumentError < Exception
+  def initialize(message = "Argument error")
+    super(message)
+  end
+end
+
+class MissingKey < Exception
+end
+
+class DivisionByZero < Exception
+  def initialize(message = "Division by zero")
+    super(message)
+  end
+end
+
+def raise(*args)
+end
+
+puts "Hello Windows!"
diff --git a/src/io/c_file_io.cr b/src/io/c_file_io.cr
index 0757b1d225..a8bd2c22df 100644
--- a/src/io/c_file_io.cr
+++ b/src/io/c_file_io.cr
@@ -1,5 +1,12 @@
 lib C
-  type File : Void*
+  ifdef windows
+    struct IoBuf
+      data : Int32[8]
+    end
+    type File : IoBuf*
+  else
+    type File : Void*
+  end
 
   fun fopen(filename : UInt8*, mode : UInt8*) : File
   fun fwrite(buf : UInt8*, size : C::SizeT, count : C::SizeT, fp : File) : SizeT
@@ -34,6 +41,8 @@ lib C
     $stdin : File
     $stdout : File
     $stderr : File
+  elsif windows
+    fun __iob_func : File
   end
 
   SEEK_SET = 0
@@ -73,6 +82,12 @@ struct CFileIO
   end
 end
 
-STDIN = CFileIO.new(C.stdin)
-STDOUT = CFileIO.new(C.stdout)
-STDERR = CFileIO.new(C.stderr)
+ifdef windows
+  STDIN = CFileIO.new(C.__iob_func)
+  STDOUT = CFileIO.new(C.__iob_func + 1)
+  STDERR = CFileIO.new(C.__iob_func + 2)
+else
+  STDIN = CFileIO.new(C.stdin)
+  STDOUT = CFileIO.new(C.stdout)
+  STDERR = CFileIO.new(C.stderr)
+end
diff --git a/src/prelude.cr b/src/prelude.cr
index 5b300ad113..2d956ad7ad 100644
--- a/src/prelude.cr
+++ b/src/prelude.cr
@@ -31,6 +31,7 @@ require "array"
 require "hash"
 require "set"
 require "tuple"
+require "box"
 require "math"
 require "process"
 require "io"
@@ -44,7 +45,6 @@ require "random"
 require "regex"
 require "raise"
 require "errno"
-require "box"
 require "main"
 
 def loop
-- 
GitLab