1 /* This header will cause a mismatch with any mingw-w64 header by including a
2    system header and then getting included before user headers in the hsc file.
3    So let's define the default to be mingw-w64 C99 so we have any hope of
4    getting GHC to compile with GCC 9+.  */
5 #if defined(_WIN32) && !defined(__USE_MINGW_ANSI_STDIO)
6 #  define __USE_MINGW_ANSI_STDIO 1
7 #endif
8 
9 /* We need stddef to be able to use size_t. Hopefully this won't cause
10    any problems along the lines of ghc trac #2897. */
11 #include <stddef.h>
12 
13 /* hsc_* are defined in the generated utils.c */
14 int hsc_printf(const char *format, ...);
15 int hsc_toupper(int c);
16 int hsc_tolower(int c);
17 int hsc_putchar(int c);
18 /* "void" should really be "FILE", but we aren't able to refer to "FILE"
19    as we don't want to include <stdio.h> here */
20 int hsc_fputs(const char *s, void *stream);
21 /* "void" should really be "FILE", but we aren't able to refer to "FILE"
22    as we don't want to include <stdio.h> here */
23 void *hsc_stdout(void);
24 
25 /* For the single-argument macros we make the macros variadic (the
26    argument is x... rather than simply x) so that arguments containing
27    commas work. See trac #590. */
28 
29 #ifndef offsetof
30 #define offsetof(t, f) ((size_t) &((t *)0)->f)
31 #endif
32 
33 #if __NHC__
34 #define hsc_line(line, file) \
35     hsc_printf ("# %d \"%s\"\n", line, file);
36 #define hsc_column(column)
37 #else
38 #define hsc_line(line, file) \
39     hsc_printf ("{-# LINE %d \"%s\" #-}\n", line, file);
40 #define hsc_column(column) \
41     hsc_printf ("{-# COLUMN %d #-}", column);
42 #endif
43 
44 #define hsc_const(x...)                               \
45     if ((x) < 0)                                      \
46         hsc_printf ("%lld", (long long)(x));          \
47     else                                              \
48         hsc_printf ("%llu", (unsigned long long)(x));
49 
50 #define hsc_const_str(x...)                                       \
51     {                                                             \
52         const char *s = (x);                                      \
53         hsc_printf ("\"");                                        \
54         while (*s != '\0')                                        \
55         {                                                         \
56             if (*s == '"' || *s == '\\')                          \
57                 hsc_printf ("\\%c", *s);                          \
58             else if (*s >= 0x20 && *s <= 0x7E)                    \
59                 hsc_printf ("%c", *s);                            \
60             else                                                  \
61                 hsc_printf ("\\%d%s",                             \
62                         (unsigned char) *s,                       \
63                         s[1] >= '0' && s[1] <= '9' ? "\\&" : ""); \
64             ++s;                                                  \
65         }                                                         \
66         hsc_printf ("\"");                                        \
67     }
68 
69 #define hsc_type(t...)                                      \
70     if ((t)(int)(t)1.4 == (t)1.4)                           \
71         hsc_printf ("%s%lu",                                \
72                 (t)(-1) < (t)0 ? "Int" : "Word",            \
73                 (unsigned long)sizeof (t) * 8);             \
74     else                                                    \
75         hsc_printf ("%s",                                   \
76                 sizeof (t) >  sizeof (double) ? "LDouble" : \
77                 sizeof (t) == sizeof (double) ? "Double"  : \
78                 "Float");
79 
80 #define hsc_peek(t, f) \
81     hsc_printf ("(\\hsc_ptr -> peekByteOff hsc_ptr %ld)", \
82                 (long) offsetof (t, f));
83 
84 #define hsc_poke(t, f) \
85     hsc_printf ("(\\hsc_ptr -> pokeByteOff hsc_ptr %ld)", \
86                 (long) offsetof (t, f));
87 
88 #define hsc_ptr(t, f) \
89     hsc_printf ("(\\hsc_ptr -> hsc_ptr `plusPtr` %ld)", \
90                 (long) offsetof (t, f));
91 
92 #define hsc_offset(t, f) \
93     hsc_printf("(%ld)", (long) offsetof (t, f));
94 
95 #define hsc_size(t...) \
96     hsc_printf("(%ld)", (long) sizeof(t));
97 
98 #define hsc_alignment(x...)                                           \
99   do {                                                                \
100     struct __anon_x__ {                                               \
101       char a;                                                         \
102       x b;                                                            \
103     };                                                                \
104     hsc_printf("%lu", (unsigned long)offsetof(struct __anon_x__, b)); \
105   } while (0)
106 
107 #define hsc_enum(t, f, print_name, x)                   \
108     print_name;                                         \
109     hsc_printf (" :: %s\n", #t);                        \
110     print_name;                                         \
111     hsc_printf (" = %s ", #f);                          \
112     if ((x) < 0)                                        \
113         hsc_printf ("(%lld)\n", (long long)(x));        \
114     else                                                \
115         hsc_printf ("%llu\n", (unsigned long long)(x));
116 
117 #define hsc_haskellize(x...)                                       \
118     {                                                              \
119         const char *s = (x);                                       \
120         int upper = 0;                                             \
121         if (*s != '\0')                                            \
122         {                                                          \
123             hsc_putchar (hsc_tolower (*s));                        \
124             ++s;                                                   \
125             while (*s != '\0')                                     \
126             {                                                      \
127                 if (*s == '_')                                     \
128                     upper = 1;                                     \
129                 else                                               \
130                 {                                                  \
131                     hsc_putchar (upper ? hsc_toupper (*s)          \
132                                        : hsc_tolower (*s));        \
133                     upper = 0;                                     \
134                 }                                                  \
135                 ++s;                                               \
136             }                                                      \
137         }                                                          \
138     }
139