-
Notifications
You must be signed in to change notification settings - Fork 10
/
UtilsCodegen.hs
88 lines (79 loc) · 3.01 KB
/
UtilsCodegen.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
module UtilsCodegen where
{-
Generate the utility code for hsc2hs.
We don't want to include C headers in template-hsc.h
See GHC trac #2897
-}
import Control.Monad
import C
import Common
import Flags
withUtilsObject :: Config -> FilePath -> FilePath
-> (FilePath -> IO a)
-> IO a
withUtilsObject config outDir outBase f = do
let beVerbose = cVerbose config
flags = cFlags config
possiblyRemove = if cKeepFiles config
then flip const
else finallyRemove
cUtilsName = outDir ++ outBase ++ "_hsc_utils.c"
oUtilsName = outDir ++ outBase ++ "_hsc_utils.o"
possiblyRemove cUtilsName $ do
writeBinaryFile cUtilsName $ unlines $
-- These header will cause a mismatch with any mingw-w64 header by
-- including system headers before user headers in the hsc file.
-- We *MUST* include user headers *BEFORE* automatic ones. */
[outTemplateHeaderCProg (cTemplate config),
"",
"#include <stddef.h>",
"#include <string.h>",
"#include <stdio.h>",
"#include <stdarg.h>",
"#include <ctype.h>",
"",
"int hsc_printf(const char *format, ...) {",
" int r;",
" va_list argp;",
" va_start(argp, format);",
" r = vprintf(format, argp);",
" va_end(argp);",
" return r;",
"}",
"",
"int hsc_toupper(int c) {",
" return toupper(c);",
"}",
"",
"int hsc_tolower(int c) {",
" return tolower(c);",
"}",
"",
"int hsc_putchar(int c) {",
" return putchar(c);",
"}",
"",
-- "void" should really be "FILE", but we aren't able to
-- refer to "FILE" in template-hsc.h as we don't want to
-- include <stdio.h> there. We cast to FILE * so as to
-- allow compiling with g++.
"int hsc_fputs(const char *s, void *stream) {",
" return fputs(s, (FILE *)stream);",
"}",
"",
-- "void" should really be "FILE", but we aren't able to
-- refer to "FILE" in template-hsc.h as we don't want to
-- include <stdio.h> there. We explicitly cast to void *
-- to allow compiling with g++.
"void *hsc_stdout(void) {",
" return (void *)stdout;",
"}"
]
possiblyRemove oUtilsName $ do
unless (cNoCompile config) $
rawSystemL outDir (outBase ++ "_utils") ("compiling " ++ cUtilsName)
beVerbose
(cCompiler config)
(["-c", cUtilsName, "-o", oUtilsName] ++
[cFlag | CompFlag cFlag <- flags])
f oUtilsName