Commit 620bf695e8

Vexu <git@vexu.eu>
2019-12-16 06:43:18
organize tests
1 parent ab60c8e
Changed files (1)
test/translate_c.zig
@@ -162,6 +162,270 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
         \\}
     });
 
+    cases.add_both("enums",
+        \\enum Foo {
+        \\    FooA,
+        \\    FooB,
+        \\    Foo1,
+        \\};
+    , &[_][]const u8{
+        \\pub const enum_Foo = extern enum {
+        \\    A,
+        \\    B,
+        \\    @"1",
+        \\};
+    ,
+        \\pub const FooA = enum_Foo.A;
+    ,
+        \\pub const FooB = enum_Foo.B;
+    ,
+        \\pub const Foo1 = enum_Foo.@"1";
+    ,
+        \\pub const Foo = enum_Foo;
+    });
+
+    cases.add_both("enums",
+        \\enum Foo {
+        \\    FooA = 2,
+        \\    FooB = 5,
+        \\    Foo1,
+        \\};
+    , &[_][]const u8{
+        \\pub const enum_Foo = extern enum {
+        \\    A = 2,
+        \\    B = 5,
+        \\    @"1" = 6,
+        \\};
+    ,
+        \\pub const FooA = enum_Foo.A;
+    ,
+        \\pub const FooB = enum_Foo.B;
+    ,
+        \\pub const Foo1 = enum_Foo.@"1";
+    ,
+        \\pub const Foo = enum_Foo;
+    });
+
+    cases.add_both("typedef of function in struct field",
+        \\typedef void lws_callback_function(void);
+        \\struct Foo {
+        \\    void (*func)(void);
+        \\    lws_callback_function *callback_http;
+        \\};
+    , &[_][]const u8{
+        \\pub const lws_callback_function = extern fn () void;
+        \\pub const struct_Foo = extern struct {
+        \\    func: ?extern fn () void,
+        \\    callback_http: ?lws_callback_function,
+        \\};
+    });
+
+    cases.add_both("pointer to struct demoted to opaque due to bit fields",
+        \\struct Foo {
+        \\    unsigned int: 1;
+        \\};
+        \\struct Bar {
+        \\    struct Foo *foo;
+        \\};
+    , &[_][]const u8{
+        \\pub const struct_Foo = @OpaqueType()
+    ,
+        \\pub const struct_Bar = extern struct {
+        \\    foo: ?*struct_Foo,
+        \\};
+    });
+
+    cases.add_both("macro with left shift",
+        \\#define REDISMODULE_READ (1<<0)
+    , &[_][]const u8{
+        \\pub const REDISMODULE_READ = 1 << 0;
+    });
+
+    cases.add_both("double define struct",
+        \\typedef struct Bar Bar;
+        \\typedef struct Foo Foo;
+        \\
+        \\struct Foo {
+        \\    Foo *a;
+        \\};
+        \\
+        \\struct Bar {
+        \\    Foo *a;
+        \\};
+    , &[_][]const u8{
+        \\pub const struct_Foo = extern struct {
+        \\    a: [*c]Foo,
+        \\};
+    ,
+        \\pub const Foo = struct_Foo;
+    ,
+        \\pub const struct_Bar = extern struct {
+        \\    a: [*c]Foo,
+        \\};
+    ,
+        \\pub const Bar = struct_Bar;
+    });
+
+    cases.add_both("simple struct",
+        \\struct Foo {
+        \\    int x;
+        \\    char *y;
+        \\};
+    , &[_][]const u8{
+        \\const struct_Foo = extern struct {
+        \\    x: c_int,
+        \\    y: [*c]u8,
+        \\};
+    ,
+        \\pub const Foo = struct_Foo;
+    });
+
+    cases.add_both("self referential struct with function pointer",
+        \\struct Foo {
+        \\    void (*derp)(struct Foo *foo);
+        \\};
+    , &[_][]const u8{
+        \\pub const struct_Foo = extern struct {
+        \\    derp: ?extern fn ([*c]struct_Foo) void,
+        \\};
+    ,
+        \\pub const Foo = struct_Foo;
+    });
+
+    cases.add_both("struct prototype used in func",
+        \\struct Foo;
+        \\struct Foo *some_func(struct Foo *foo, int x);
+    , &[_][]const u8{
+        \\pub const struct_Foo = @OpaqueType();
+    ,
+        \\pub extern fn some_func(foo: ?*struct_Foo, x: c_int) ?*struct_Foo;
+    ,
+        \\pub const Foo = struct_Foo;
+    });
+
+    cases.add_both("#define an unsigned integer literal",
+        \\#define CHANNEL_COUNT 24
+    , &[_][]const u8{
+        \\pub const CHANNEL_COUNT = 24;
+    });
+
+    cases.add_both("#define referencing another #define",
+        \\#define THING2 THING1
+        \\#define THING1 1234
+    , &[_][]const u8{
+        \\pub const THING1 = 1234;
+    ,
+        \\pub const THING2 = THING1;
+    });
+
+    cases.add_both("circular struct definitions",
+        \\struct Bar;
+        \\
+        \\struct Foo {
+        \\    struct Bar *next;
+        \\};
+        \\
+        \\struct Bar {
+        \\    struct Foo *next;
+        \\};
+    , &[_][]const u8{
+        \\pub const struct_Bar = extern struct {
+        \\    next: [*c]struct_Foo,
+        \\};
+    ,
+        \\pub const struct_Foo = extern struct {
+        \\    next: [*c]struct_Bar,
+        \\};
+    });
+
+    cases.add_both("#define string",
+        \\#define  foo  "a string"
+    , &[_][]const u8{
+        \\pub const foo = "a string";
+    });
+
+    cases.add_both("zig keywords in C code",
+        \\struct comptime {
+        \\    int defer;
+        \\};
+    , &[_][]const u8{
+        \\pub const struct_comptime = extern struct {
+        \\    @"defer": c_int,
+        \\};
+    ,
+        \\pub const @"comptime" = struct_comptime;
+    });
+
+    cases.add_both("macro with parens around negative number",
+        \\#define LUA_GLOBALSINDEX        (-10002)
+    , &[_][]const u8{
+        \\pub const LUA_GLOBALSINDEX = -10002;
+    });
+
+    cases.add_both(
+        "u integer suffix after 0 (zero) in macro definition",
+        "#define ZERO 0U",
+        &[_][]const u8{
+            "pub const ZERO = @as(c_uint, 0);",
+        },
+    );
+
+    cases.add_both(
+        "l integer suffix after 0 (zero) in macro definition",
+        "#define ZERO 0L",
+        &[_][]const u8{
+            "pub const ZERO = @as(c_long, 0);",
+        },
+    );
+
+    cases.add_both(
+        "ul integer suffix after 0 (zero) in macro definition",
+        "#define ZERO 0UL",
+        &[_][]const u8{
+            "pub const ZERO = @as(c_ulong, 0);",
+        },
+    );
+
+    cases.add_both(
+        "lu integer suffix after 0 (zero) in macro definition",
+        "#define ZERO 0LU",
+        &[_][]const u8{
+            "pub const ZERO = @as(c_ulong, 0);",
+        },
+    );
+
+    cases.add_both(
+        "ll integer suffix after 0 (zero) in macro definition",
+        "#define ZERO 0LL",
+        &[_][]const u8{
+            "pub const ZERO = @as(c_longlong, 0);",
+        },
+    );
+
+    cases.add_both(
+        "ull integer suffix after 0 (zero) in macro definition",
+        "#define ZERO 0ULL",
+        &[_][]const u8{
+            "pub const ZERO = @as(c_ulonglong, 0);",
+        },
+    );
+
+    cases.add_both(
+        "llu integer suffix after 0 (zero) in macro definition",
+        "#define ZERO 0LLU",
+        &[_][]const u8{
+            "pub const ZERO = @as(c_ulonglong, 0);",
+        },
+    );
+
+    cases.add_both(
+        "bitwise not on u-suffixed 0 (zero) in macro definition",
+        "#define NOT_ZERO (~0U)",
+        &[_][]const u8{
+            "pub const NOT_ZERO = ~@as(c_uint, 0);",
+        },
+    );
+
     /////////////// Cases that pass for only stage2 ////////////////
 
     cases.add_2("Parameterless function prototypes",
@@ -202,22 +466,6 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
         \\}
     });
 
-    cases.add_2("field struct",
-        \\union OpenGLProcs {
-        \\    struct {
-        \\        int Clear;
-        \\    } gl;
-        \\};
-    , &[_][]const u8{
-        \\pub const union_OpenGLProcs = extern union {
-        \\    gl: extern struct {
-        \\        Clear: c_int,
-        \\    },
-        \\};
-    ,
-        \\pub const OpenGLProcs = union_OpenGLProcs;
-    });
-
     cases.add_2("enums",
         \\typedef enum {
         \\    a,
@@ -408,54 +656,19 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
     , &[_][]const u8{
         \\pub inline fn BASIC(c: var) @TypeOf(c * 2) {
         \\    return c * 2;
-        \\}
-    });
-
-    cases.add_2("macro escape sequences",
-        \\#define FOO "aoeu\xab derp"
-        \\#define FOO2 "aoeu\a derp"
-    , &[_][]const u8{
-        \\pub const FOO = "aoeu\xab derp";
-    ,
-        \\pub const FOO2 = "aoeu\x07 derp";
-    });
-
-    /////////////// Cases for only stage1 which are TODO items for stage2 ////////////////
-
-    cases.add_both("typedef of function in struct field",
-        \\typedef void lws_callback_function(void);
-        \\struct Foo {
-        \\    void (*func)(void);
-        \\    lws_callback_function *callback_http;
-        \\};
-    , &[_][]const u8{
-        \\pub const lws_callback_function = extern fn () void;
-        \\pub const struct_Foo = extern struct {
-        \\    func: ?extern fn () void,
-        \\    callback_http: ?lws_callback_function,
-        \\};
+        \\}
     });
 
-    cases.add_both("pointer to struct demoted to opaque due to bit fields",
-        \\struct Foo {
-        \\    unsigned int: 1;
-        \\};
-        \\struct Bar {
-        \\    struct Foo *foo;
-        \\};
+    cases.add_2("macro escape sequences",
+        \\#define FOO "aoeu\xab derp"
+        \\#define FOO2 "aoeu\a derp"
     , &[_][]const u8{
-        \\pub const struct_Foo = @OpaqueType()
+        \\pub const FOO = "aoeu\xab derp";
     ,
-        \\pub const struct_Bar = extern struct {
-        \\    foo: ?*struct_Foo,
-        \\};
+        \\pub const FOO2 = "aoeu\x07 derp";
     });
 
-    cases.add_both("macro with left shift",
-        \\#define REDISMODULE_READ (1<<0)
-    , &[_][]const u8{
-        \\pub const REDISMODULE_READ = 1 << 0;
-    });
+    /////////////// Cases for only stage1 which are TODO items for stage2 ////////////////
 
     if (builtin.os != builtin.Os.windows) {
         // Windows treats this as an enum with type c_int
@@ -594,31 +807,6 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
         \\}
     });
 
-    cases.add_both("double define struct",
-        \\typedef struct Bar Bar;
-        \\typedef struct Foo Foo;
-        \\
-        \\struct Foo {
-        \\    Foo *a;
-        \\};
-        \\
-        \\struct Bar {
-        \\    Foo *a;
-        \\};
-    , &[_][]const u8{
-        \\pub const struct_Foo = extern struct {
-        \\    a: [*c]Foo,
-        \\};
-    ,
-        \\pub const Foo = struct_Foo;
-    ,
-        \\pub const struct_Bar = extern struct {
-        \\    a: [*c]Foo,
-        \\};
-    ,
-        \\pub const Bar = struct_Bar;
-    });
-
     cases.addAllowWarnings("simple data types",
         \\#include <stdint.h>
         \\int foo(char a, unsigned char b, signed char c);
@@ -643,70 +831,12 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
         \\}
     });
 
-    cases.add_both("enums",
-        \\enum Foo {
-        \\    FooA,
-        \\    FooB,
-        \\    Foo1,
-        \\};
-    , &[_][]const u8{
-        \\pub const enum_Foo = extern enum {
-        \\    A,
-        \\    B,
-        \\    @"1",
-        \\};
-    ,
-        \\pub const FooA = enum_Foo.A;
-    ,
-        \\pub const FooB = enum_Foo.B;
-    ,
-        \\pub const Foo1 = enum_Foo.@"1";
-    ,
-        \\pub const Foo = enum_Foo;
-    });
-
-    cases.add_both("enums",
-        \\enum Foo {
-        \\    FooA = 2,
-        \\    FooB = 5,
-        \\    Foo1,
-        \\};
-    , &[_][]const u8{
-        \\pub const enum_Foo = extern enum {
-        \\    A = 2,
-        \\    B = 5,
-        \\    @"1" = 6,
-        \\};
-    ,
-        \\pub const FooA = enum_Foo.A;
-    ,
-        \\pub const FooB = enum_Foo.B;
-    ,
-        \\pub const Foo1 = enum_Foo.@"1";
-    ,
-        \\pub const Foo = enum_Foo;
-    });
-
     cases.add("restrict -> noalias",
         \\void foo(void *restrict bar, void *restrict);
     , &[_][]const u8{
         \\pub extern fn foo(noalias bar: ?*c_void, noalias arg1: ?*c_void) void;
     });
 
-    cases.add_both("simple struct",
-        \\struct Foo {
-        \\    int x;
-        \\    char *y;
-        \\};
-    , &[_][]const u8{
-        \\const struct_Foo = extern struct {
-        \\    x: c_int,
-        \\    y: [*c]u8,
-        \\};
-    ,
-        \\pub const Foo = struct_Foo;
-    });
-
     cases.add("qualified struct and enum",
         \\struct Foo {
         \\    int x;
@@ -731,174 +861,24 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
         \\pub const BarA = enum_Bar.A;
     ,
         \\pub const BarB = enum_Bar.B;
-    ,
-        \\pub extern fn func(a: [*c]struct_Foo, b: [*c]([*c]enum_Bar)) void;
-    ,
-        \\pub const Foo = struct_Foo;
-    ,
-        \\pub const Bar = enum_Bar;
-    });
-
-    cases.add("constant size array",
-        \\void func(int array[20]);
-    , &[_][]const u8{
-        \\pub extern fn func(array: [*c]c_int) void;
-    });
-
-    cases.add_both("self referential struct with function pointer",
-        \\struct Foo {
-        \\    void (*derp)(struct Foo *foo);
-        \\};
-    , &[_][]const u8{
-        \\pub const struct_Foo = extern struct {
-        \\    derp: ?extern fn ([*c]struct_Foo) void,
-        \\};
-    ,
-        \\pub const Foo = struct_Foo;
-    });
-
-    cases.add_both("struct prototype used in func",
-        \\struct Foo;
-        \\struct Foo *some_func(struct Foo *foo, int x);
-    , &[_][]const u8{
-        \\pub const struct_Foo = @OpaqueType();
-    ,
-        \\pub extern fn some_func(foo: ?*struct_Foo, x: c_int) ?*struct_Foo;
-    ,
-        \\pub const Foo = struct_Foo;
-    });
-
-    cases.add("#define a char literal",
-        \\#define A_CHAR  'a'
-    , &[_][]const u8{
-        \\pub const A_CHAR = 97;
-    });
-
-    cases.add_both("#define an unsigned integer literal",
-        \\#define CHANNEL_COUNT 24
-    , &[_][]const u8{
-        \\pub const CHANNEL_COUNT = 24;
-    });
-
-    cases.add_both("#define referencing another #define",
-        \\#define THING2 THING1
-        \\#define THING1 1234
-    , &[_][]const u8{
-        \\pub const THING1 = 1234;
-    ,
-        \\pub const THING2 = THING1;
-    });
-
-    cases.add_both("circular struct definitions",
-        \\struct Bar;
-        \\
-        \\struct Foo {
-        \\    struct Bar *next;
-        \\};
-        \\
-        \\struct Bar {
-        \\    struct Foo *next;
-        \\};
-    , &[_][]const u8{
-        \\pub const struct_Bar = extern struct {
-        \\    next: [*c]struct_Foo,
-        \\};
-    ,
-        \\pub const struct_Foo = extern struct {
-        \\    next: [*c]struct_Bar,
-        \\};
-    });
-
-    cases.add("generate inline func for #define global extern fn",
-        \\extern void (*fn_ptr)(void);
-        \\#define foo fn_ptr
-        \\
-        \\extern char (*fn_ptr2)(int, float);
-        \\#define bar fn_ptr2
-    , &[_][]const u8{
-        \\pub extern var fn_ptr: ?extern fn () void;
-    ,
-        \\pub inline fn foo() void {
-        \\    return fn_ptr.?();
-        \\}
-    ,
-        \\pub extern var fn_ptr2: ?extern fn (c_int, f32) u8;
-    ,
-        \\pub inline fn bar(arg0: c_int, arg1: f32) u8 {
-        \\    return fn_ptr2.?(arg0, arg1);
-        \\}
-    });
-
-    cases.add_both("#define string",
-        \\#define  foo  "a string"
-    , &[_][]const u8{
-        \\pub const foo = "a string";
-    });
-
-    cases.add("__cdecl doesn't mess up function pointers",
-        \\void foo(void (__cdecl *fn_ptr)(void));
-    , &[_][]const u8{
-        \\pub extern fn foo(fn_ptr: ?extern fn () void) void;
-    });
-
-    cases.add("comment after integer literal",
-        \\#define SDL_INIT_VIDEO 0x00000020  /**< SDL_INIT_VIDEO implies SDL_INIT_EVENTS */
-    , &[_][]const u8{
-        \\pub const SDL_INIT_VIDEO = 32;
-    });
-
-    cases.add("u integer suffix after hex literal",
-        \\#define SDL_INIT_VIDEO 0x00000020u  /**< SDL_INIT_VIDEO implies SDL_INIT_EVENTS */
-    , &[_][]const u8{
-        \\pub const SDL_INIT_VIDEO = @as(c_uint, 32);
-    });
-
-    cases.add("l integer suffix after hex literal",
-        \\#define SDL_INIT_VIDEO 0x00000020l  /**< SDL_INIT_VIDEO implies SDL_INIT_EVENTS */
-    , &[_][]const u8{
-        \\pub const SDL_INIT_VIDEO = @as(c_long, 32);
-    });
-
-    cases.add("ul integer suffix after hex literal",
-        \\#define SDL_INIT_VIDEO 0x00000020ul  /**< SDL_INIT_VIDEO implies SDL_INIT_EVENTS */
-    , &[_][]const u8{
-        \\pub const SDL_INIT_VIDEO = @as(c_ulong, 32);
-    });
-
-    cases.add("lu integer suffix after hex literal",
-        \\#define SDL_INIT_VIDEO 0x00000020lu  /**< SDL_INIT_VIDEO implies SDL_INIT_EVENTS */
-    , &[_][]const u8{
-        \\pub const SDL_INIT_VIDEO = @as(c_ulong, 32);
-    });
-
-    cases.add("ll integer suffix after hex literal",
-        \\#define SDL_INIT_VIDEO 0x00000020ll  /**< SDL_INIT_VIDEO implies SDL_INIT_EVENTS */
-    , &[_][]const u8{
-        \\pub const SDL_INIT_VIDEO = @as(c_longlong, 32);
-    });
-
-    cases.add("ull integer suffix after hex literal",
-        \\#define SDL_INIT_VIDEO 0x00000020ull  /**< SDL_INIT_VIDEO implies SDL_INIT_EVENTS */
-    , &[_][]const u8{
-        \\pub const SDL_INIT_VIDEO = @as(c_ulonglong, 32);
+    ,
+        \\pub extern fn func(a: [*c]struct_Foo, b: [*c]([*c]enum_Bar)) void;
+    ,
+        \\pub const Foo = struct_Foo;
+    ,
+        \\pub const Bar = enum_Bar;
     });
 
-    cases.add("llu integer suffix after hex literal",
-        \\#define SDL_INIT_VIDEO 0x00000020llu  /**< SDL_INIT_VIDEO implies SDL_INIT_EVENTS */
+    cases.add("constant size array",
+        \\void func(int array[20]);
     , &[_][]const u8{
-        \\pub const SDL_INIT_VIDEO = @as(c_ulonglong, 32);
+        \\pub extern fn func(array: [*c]c_int) void;
     });
 
-    cases.add_both("zig keywords in C code",
-        \\struct comptime {
-        \\    int defer;
-        \\};
+    cases.add("__cdecl doesn't mess up function pointers",
+        \\void foo(void (__cdecl *fn_ptr)(void));
     , &[_][]const u8{
-        \\pub const struct_comptime = extern struct {
-        \\    @"defer": c_int,
-        \\};
-    ,
-        \\pub const @"comptime" = struct_comptime;
+        \\pub extern fn foo(fn_ptr: ?extern fn () void) void;
     });
 
     cases.add("macro defines string literal with hex",
@@ -925,12 +905,6 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
         \\pub const FOO_CHAR = 63;
     });
 
-    cases.add_both("macro with parens around negative number",
-        \\#define LUA_GLOBALSINDEX        (-10002)
-    , &[_][]const u8{
-        \\pub const LUA_GLOBALSINDEX = -10002;
-    });
-
     cases.addC("post increment",
         \\unsigned foo1(unsigned a) {
         \\    a++;
@@ -1658,44 +1632,6 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
         \\}
     });
 
-    cases.add("macros with field targets",
-        \\typedef unsigned int GLbitfield;
-        \\typedef void (*PFNGLCLEARPROC) (GLbitfield mask);
-        \\typedef void(*OpenGLProc)(void);
-        \\union OpenGLProcs {
-        \\    OpenGLProc ptr[1];
-        \\    struct {
-        \\        PFNGLCLEARPROC Clear;
-        \\    } gl;
-        \\};
-        \\extern union OpenGLProcs glProcs;
-        \\#define glClearUnion glProcs.gl.Clear
-        \\#define glClearPFN PFNGLCLEARPROC
-    , &[_][]const u8{
-        \\pub const GLbitfield = c_uint;
-    ,
-        \\pub const PFNGLCLEARPROC = ?extern fn (GLbitfield) void;
-    ,
-        \\pub const OpenGLProc = ?extern fn () void;
-    ,
-        \\pub const union_OpenGLProcs = extern union {
-        \\    ptr: [1]OpenGLProc,
-        \\    gl: extern struct {
-        \\        Clear: PFNGLCLEARPROC,
-        \\    },
-        \\};
-    ,
-        \\pub extern var glProcs: union_OpenGLProcs;
-    ,
-        \\pub const glClearPFN = PFNGLCLEARPROC;
-    ,
-        \\pub inline fn glClearUnion(arg0: GLbitfield) void {
-        \\    return glProcs.gl.Clear.?(arg0);
-        \\}
-    ,
-        \\pub const OpenGLProcs = union_OpenGLProcs;
-    });
-
     cases.add("variable name shadowing",
         \\int foo(void) {
         \\    int x = 1;
@@ -1762,12 +1698,6 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
         \\}
     });
 
-    cases.add("macro pointer cast",
-        \\#define NRF_GPIO ((NRF_GPIO_Type *) NRF_GPIO_BASE)
-    , &[_][]const u8{
-        \\pub const NRF_GPIO = if (@typeId(@TypeOf(NRF_GPIO_BASE)) == @import("builtin").TypeId.Pointer) @ptrCast([*c]NRF_GPIO_Type, NRF_GPIO_BASE) else if (@typeId(@TypeOf(NRF_GPIO_BASE)) == @import("builtin").TypeId.Int) @intToPtr([*c]NRF_GPIO_Type, NRF_GPIO_BASE) else @as([*c]NRF_GPIO_Type, NRF_GPIO_BASE);
-    });
-
     cases.add("if on non-bool",
         \\enum SomeEnum { A, B, C };
         \\int if_none_bool(int a, float b, void *c, enum SomeEnum d) {
@@ -1869,70 +1799,6 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
         \\}
     });
 
-    cases.add_both(
-        "u integer suffix after 0 (zero) in macro definition",
-        "#define ZERO 0U",
-        &[_][]const u8{
-            "pub const ZERO = @as(c_uint, 0);",
-        },
-    );
-
-    cases.add_both(
-        "l integer suffix after 0 (zero) in macro definition",
-        "#define ZERO 0L",
-        &[_][]const u8{
-            "pub const ZERO = @as(c_long, 0);",
-        },
-    );
-
-    cases.add_both(
-        "ul integer suffix after 0 (zero) in macro definition",
-        "#define ZERO 0UL",
-        &[_][]const u8{
-            "pub const ZERO = @as(c_ulong, 0);",
-        },
-    );
-
-    cases.add_both(
-        "lu integer suffix after 0 (zero) in macro definition",
-        "#define ZERO 0LU",
-        &[_][]const u8{
-            "pub const ZERO = @as(c_ulong, 0);",
-        },
-    );
-
-    cases.add_both(
-        "ll integer suffix after 0 (zero) in macro definition",
-        "#define ZERO 0LL",
-        &[_][]const u8{
-            "pub const ZERO = @as(c_longlong, 0);",
-        },
-    );
-
-    cases.add_both(
-        "ull integer suffix after 0 (zero) in macro definition",
-        "#define ZERO 0ULL",
-        &[_][]const u8{
-            "pub const ZERO = @as(c_ulonglong, 0);",
-        },
-    );
-
-    cases.add_both(
-        "llu integer suffix after 0 (zero) in macro definition",
-        "#define ZERO 0LLU",
-        &[_][]const u8{
-            "pub const ZERO = @as(c_ulonglong, 0);",
-        },
-    );
-
-    cases.add_both(
-        "bitwise not on u-suffixed 0 (zero) in macro definition",
-        "#define NOT_ZERO (~0U)",
-        &[_][]const u8{
-            "pub const NOT_ZERO = ~@as(c_uint, 0);",
-        },
-    );
-
     cases.addC("implicit casts",
         \\#include <stdbool.h>
         \\
@@ -2073,4 +1939,122 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
         \\pub export fn foo() void {}
         \\pub export fn bar() void {}
     });
+
+    cases.add("#define a char literal",
+        \\#define A_CHAR  'a'
+    , &[_][]const u8{
+        \\pub const A_CHAR = 97;
+    });
+
+    cases.add("generate inline func for #define global extern fn",
+        \\extern void (*fn_ptr)(void);
+        \\#define foo fn_ptr
+        \\
+        \\extern char (*fn_ptr2)(int, float);
+        \\#define bar fn_ptr2
+    , &[_][]const u8{
+        \\pub extern var fn_ptr: ?extern fn () void;
+    ,
+        \\pub inline fn foo() void {
+        \\    return fn_ptr.?();
+        \\}
+    ,
+        \\pub extern var fn_ptr2: ?extern fn (c_int, f32) u8;
+    ,
+        \\pub inline fn bar(arg0: c_int, arg1: f32) u8 {
+        \\    return fn_ptr2.?(arg0, arg1);
+        \\}
+    });
+    cases.add("comment after integer literal",
+        \\#define SDL_INIT_VIDEO 0x00000020  /**< SDL_INIT_VIDEO implies SDL_INIT_EVENTS */
+    , &[_][]const u8{
+        \\pub const SDL_INIT_VIDEO = 32;
+    });
+
+    cases.add("u integer suffix after hex literal",
+        \\#define SDL_INIT_VIDEO 0x00000020u  /**< SDL_INIT_VIDEO implies SDL_INIT_EVENTS */
+    , &[_][]const u8{
+        \\pub const SDL_INIT_VIDEO = @as(c_uint, 32);
+    });
+
+    cases.add("l integer suffix after hex literal",
+        \\#define SDL_INIT_VIDEO 0x00000020l  /**< SDL_INIT_VIDEO implies SDL_INIT_EVENTS */
+    , &[_][]const u8{
+        \\pub const SDL_INIT_VIDEO = @as(c_long, 32);
+    });
+
+    cases.add("ul integer suffix after hex literal",
+        \\#define SDL_INIT_VIDEO 0x00000020ul  /**< SDL_INIT_VIDEO implies SDL_INIT_EVENTS */
+    , &[_][]const u8{
+        \\pub const SDL_INIT_VIDEO = @as(c_ulong, 32);
+    });
+
+    cases.add("lu integer suffix after hex literal",
+        \\#define SDL_INIT_VIDEO 0x00000020lu  /**< SDL_INIT_VIDEO implies SDL_INIT_EVENTS */
+    , &[_][]const u8{
+        \\pub const SDL_INIT_VIDEO = @as(c_ulong, 32);
+    });
+
+    cases.add("ll integer suffix after hex literal",
+        \\#define SDL_INIT_VIDEO 0x00000020ll  /**< SDL_INIT_VIDEO implies SDL_INIT_EVENTS */
+    , &[_][]const u8{
+        \\pub const SDL_INIT_VIDEO = @as(c_longlong, 32);
+    });
+
+    cases.add("ull integer suffix after hex literal",
+        \\#define SDL_INIT_VIDEO 0x00000020ull  /**< SDL_INIT_VIDEO implies SDL_INIT_EVENTS */
+    , &[_][]const u8{
+        \\pub const SDL_INIT_VIDEO = @as(c_ulonglong, 32);
+    });
+
+    cases.add("llu integer suffix after hex literal",
+        \\#define SDL_INIT_VIDEO 0x00000020llu  /**< SDL_INIT_VIDEO implies SDL_INIT_EVENTS */
+    , &[_][]const u8{
+        \\pub const SDL_INIT_VIDEO = @as(c_ulonglong, 32);
+    });
+
+    cases.add("macros with field targets",
+        \\typedef unsigned int GLbitfield;
+        \\typedef void (*PFNGLCLEARPROC) (GLbitfield mask);
+        \\typedef void(*OpenGLProc)(void);
+        \\union OpenGLProcs {
+        \\    OpenGLProc ptr[1];
+        \\    struct {
+        \\        PFNGLCLEARPROC Clear;
+        \\    } gl;
+        \\};
+        \\extern union OpenGLProcs glProcs;
+        \\#define glClearUnion glProcs.gl.Clear
+        \\#define glClearPFN PFNGLCLEARPROC
+    , &[_][]const u8{
+        \\pub const GLbitfield = c_uint;
+    ,
+        \\pub const PFNGLCLEARPROC = ?extern fn (GLbitfield) void;
+    ,
+        \\pub const OpenGLProc = ?extern fn () void;
+    ,
+        \\pub const union_OpenGLProcs = extern union {
+        \\    ptr: [1]OpenGLProc,
+        \\    gl: extern struct {
+        \\        Clear: PFNGLCLEARPROC,
+        \\    },
+        \\};
+    ,
+        \\pub extern var glProcs: union_OpenGLProcs;
+    ,
+        \\pub const glClearPFN = PFNGLCLEARPROC;
+    ,
+        \\pub inline fn glClearUnion(arg0: GLbitfield) void {
+        \\    return glProcs.gl.Clear.?(arg0);
+        \\}
+    ,
+        \\pub const OpenGLProcs = union_OpenGLProcs;
+    });
+
+    cases.add("macro pointer cast",
+        \\#define NRF_GPIO ((NRF_GPIO_Type *) NRF_GPIO_BASE)
+    , &[_][]const u8{
+        \\pub const NRF_GPIO = if (@typeId(@TypeOf(NRF_GPIO_BASE)) == @import("builtin").TypeId.Pointer) @ptrCast([*c]NRF_GPIO_Type, NRF_GPIO_BASE) else if (@typeId(@TypeOf(NRF_GPIO_BASE)) == @import("builtin").TypeId.Int) @intToPtr([*c]NRF_GPIO_Type, NRF_GPIO_BASE) else @as([*c]NRF_GPIO_Type, NRF_GPIO_BASE);
+    });
+
 }