main 3a10209

struct_test.c RawHistoryFolder

1// SPDX-License-Identifier: Apache-2.0
2// SPDX-FileCopyrightText: 2024 The Ebitengine Authors
3
4#include <stdint.h>
5#include <stdio.h>
6#include <stdlib.h>
7
8// Empty is empty
9struct Empty {};
10
11// NoStruct tests that an empty struct doesn't cause issues
12uint64_t NoStruct(struct Empty e) {
13    return 0xdeadbeef;
14}
15
16struct EmptyEmpty {
17    struct Empty x;
18};
19
20uint64_t EmptyEmpty(struct EmptyEmpty e) {
21    return 0xdeadbeef;
22}
23
24uint64_t EmptyEmptyWithReg(unsigned int x, struct EmptyEmpty e, unsigned int y) {
25    return (x << 16) | y;
26}
27
28// GreaterThan16Bytes is 24 bytes on 64 bit systems
29struct GreaterThan16Bytes {
30   int64_t  *x, *y, *z;
31};
32
33// GreaterThan16Bytes is a basic test for structs bigger than 16 bytes
34uint64_t GreaterThan16Bytes(struct GreaterThan16Bytes g) {
35    return *g.x + *g.y + *g.z;
36}
37
38// AfterRegisters tests to make sure that structs placed on the stack work properly
39uint64_t AfterRegisters(intptr_t a, intptr_t b, intptr_t c, intptr_t d, intptr_t e, intptr_t f, intptr_t g, intptr_t h, struct GreaterThan16Bytes bytes) {
40    intptr_t registers = a + b + c + d + e + f + g + h;
41    int64_t stack =  *bytes.x + *bytes.y + *bytes.z;
42    if (registers != stack) {
43        return 0xbadbad;
44    }
45    if (stack != 0xdeadbeef) {
46        return 0xcafebad;
47    }
48    return stack;
49}
50
51uint64_t BeforeRegisters(struct GreaterThan16Bytes bytes, int64_t a, int64_t b) {
52    return *bytes.x + *bytes.y + *bytes.z + a + b;
53}
54
55struct GreaterThan16BytesStruct {
56    struct {
57        int64_t  *x, *y, *z;
58    } a ;
59};
60
61uint64_t GreaterThan16BytesStruct(struct GreaterThan16BytesStruct g) {
62    return *(g.a.x) + *(g.a.y) + *(g.a.z);
63}
64
65struct IntLessThan16Bytes {
66    int64_t x, y;
67};
68
69uint64_t IntLessThan16Bytes(struct IntLessThan16Bytes l) {
70    return l.x + l.y;
71}
72
73struct FloatLessThan16Bytes {
74    float x, y;
75};
76
77float FloatLessThan16Bytes(struct FloatLessThan16Bytes f) {
78    return f.x + f.y;
79}
80
81struct ThreeSmallFields {
82    float x, y, z;
83};
84
85float ThreeSmallFields(struct ThreeSmallFields f) {
86    return f.x + f.y + f.z;
87}
88
89struct FloatAndInt {
90    float x;
91    int   y;
92};
93
94float FloatAndInt(struct FloatAndInt f) {
95    return f.x + f.y;
96}
97
98struct DoubleStruct {
99    double x;
100};
101
102double DoubleStruct(struct DoubleStruct d) {
103    return d.x;
104}
105
106struct TwoDoubleStruct {
107    double x, y;
108};
109
110double TwoDoubleStruct(struct TwoDoubleStruct d) {
111    return d.x + d.y;
112}
113
114struct TwoDoubleTwoStruct {
115    struct {
116        double x, y;
117    } s;
118};
119
120double TwoDoubleTwoStruct(struct TwoDoubleTwoStruct d) {
121    return d.s.x + d.s.y;
122}
123
124struct ThreeDoubleStruct {
125    double x, y, z;
126};
127
128double ThreeDoubleStruct(struct ThreeDoubleStruct d) {
129    return d.x + d.y + d.z;
130}
131
132struct LargeFloatStruct {
133    double a, b, c, d, e, f;
134};
135
136double LargeFloatStruct(struct LargeFloatStruct s) {
137    return s.a + s.b + s.c + s.d + s.e + s.f;
138}
139
140double LargeFloatStructWithRegs(double a, double b, double c, struct LargeFloatStruct s) {
141    return a + b + c + s.a + s.b + s.c + s.d + s.e + s.f;
142}
143
144struct Rect {
145    double x, y, w, h;
146};
147
148double Rectangle(struct Rect rect) {
149    return rect.x + rect.y + rect.w + rect.h;
150}
151
152double RectangleSubtract(struct Rect rect) {
153    return (rect.x + rect.y) - (rect.w + rect.h);
154}
155
156double RectangleWithRegs(double a, double b, double c, double d, double e, struct Rect rect) {
157    return a + b + c + d + e + rect.x + rect.y + rect.w + rect.h;
158}
159
160struct FloatArray {
161    double a[2];
162};
163
164double FloatArray(struct FloatArray f) {
165    return f.a[0] + f.a[1];
166}
167
168struct UnsignedChar4Bytes {
169    unsigned char a, b, c, d;
170};
171
172unsigned int UnsignedChar4Bytes(struct UnsignedChar4Bytes b) {
173    return (((int)b.a)<<24) | (((int)b.b)<<16) | (((int)b.c)<<8) | (((int)b.d)<<0);
174}
175
176struct UnsignedChar4BytesStruct {
177    struct {
178        unsigned char a;
179    } x;
180    struct {
181        unsigned char b;
182    } y;
183    struct {
184        unsigned char c;
185    } z;
186    struct {
187        unsigned char d;
188    } w;
189};
190
191unsigned int UnsignedChar4BytesStruct(struct UnsignedChar4BytesStruct b) {
192    return (((int)b.x.a)<<24) | (((int)b.y.b)<<16) | (((int)b.z.c)<<8) | (((int)b.w.d)<<0);
193}
194
195struct Short {
196    unsigned short a, b, c, d;
197};
198
199uint64_t Short(struct Short s) {
200    return (uint64_t)s.a << 48 | (uint64_t)s.b << 32 | (uint64_t)s.c << 16 | (uint64_t)s.d << 0;
201}
202
203struct Int {
204    unsigned int a, b;
205};
206
207uint64_t Int(struct Int i) {
208    return (uint64_t)i.a << 32 | (uint64_t)i.b << 0;
209}
210
211struct Long {
212    uint64_t a;
213};
214
215uint64_t Long(struct Long l) {
216    return l.a;
217}
218
219struct Char8Bytes {
220    signed char a, b, c, d, e, f, g, h;
221};
222
223int Char8Bytes(struct Char8Bytes b) {
224    return (int)b.a + (int)b.b + (int)b.c + (int)b.d + (int)b.e + (int)b.f + (int)b.g + (int)b.h;
225}
226
227struct Odd {
228    unsigned char a, b, c;
229};
230
231int Odd(struct Odd o) {
232    return (int)o.a + (int)o.b + (int)o.c;
233}
234
235struct Char2Short1 {
236    unsigned char a, b;
237    unsigned short c;
238};
239
240int Char2Short1s(struct Char2Short1 s) {
241    return (int)s.a + (int)s.b + (int)s.c;
242}
243
244struct SignedChar2Short1 {
245    signed char a, b;
246    signed short c;
247};
248
249int SignedChar2Short1(struct SignedChar2Short1 s) {
250    return s.a + s.b + s.c;
251}
252
253struct Array4UnsignedChars {
254    unsigned char a[4];
255};
256
257unsigned int Array4UnsignedChars(struct Array4UnsignedChars a) {
258    return (((int)a.a[0])<<24) | (((int)a.a[1])<<16) | (((int)a.a[2])<<8) | (((int)a.a[3])<<0);
259}
260
261struct Array3UnsignedChar {
262    unsigned char a[3];
263};
264
265unsigned int Array3UnsignedChars(struct Array3UnsignedChar a) {
266    return (((int)a.a[0])<<24) | (((int)a.a[1])<<16) | (((int)a.a[2])<<8) | 0xef;
267}
268
269struct Array2UnsignedShort {
270    unsigned short a[2];
271};
272
273unsigned int Array2UnsignedShorts(struct Array2UnsignedShort a) {
274    return (((int)a.a[0])<<16) | (((int)a.a[1])<<0);
275}
276
277struct Array4Chars {
278    signed char a[4];
279};
280
281int Array4Chars(struct Array4Chars a) {
282    return (int)a.a[0] + (int)a.a[1] + (int)a.a[2] + (int)a.a[3];
283}
284
285struct Array2Short {
286    short a[2];
287};
288
289int Array2Shorts(struct Array2Short a) {
290    return (int)a.a[0] + (int)a.a[1];
291}
292
293struct Array3Short {
294    short a[3];
295};
296
297int Array3Shorts(struct Array3Short a) {
298    return (int)a.a[0] + (int)a.a[1] + (int)a.a[2];
299}
300
301struct BoolStruct {
302    _Bool b;
303};
304
305_Bool BoolStruct(struct BoolStruct b) {
306    return b.b;
307}
308
309struct BoolFloat {
310    _Bool b;
311    float f;
312};
313
314float BoolFloat(struct BoolFloat s) {
315    if (s.b)
316        return s.f;
317    return -s.f;
318}
319
320struct Content {
321      struct { double x, y; } point;
322      struct { double width, height; } size;
323};
324
325uint64_t InitWithContentRect(int *win, struct Content c, int style, int backing, _Bool flag) {
326  if (win == 0)
327      return 0xBAD;
328  if (!flag)
329      return 0xF1A6; // FLAG
330  return (uint64_t)(c.point.x + c.point.y + c.size.width + c.size.height) / (style - backing);
331}
332
333struct GoInt4 {
334    intptr_t a, b, c, d;
335};
336
337intptr_t GoInt4(struct GoInt4 g) {
338    return g.a + g.b - g.c + g.d;
339}
340
341struct GoUint4 {
342    uintptr_t a, b, c, d;
343};
344
345uintptr_t GoUint4(struct GoUint4 g) {
346    return g.a + g.b + g.c + g.d;
347}
348
349uintptr_t TakeGoUintAndReturn(uintptr_t a) {
350    return a;
351}
352
353struct FloatAndBool {
354    float value;
355    _Bool has_value;
356};
357
358int FloatAndBool(struct FloatAndBool f) {
359    return f.has_value;
360}
361
362struct FourInt32s {
363    int32_t f0;
364    int32_t f1;
365    int32_t f2;
366    int32_t f3;
367};
368
369int32_t FourInt32s(struct FourInt32s s) {
370    return s.f0 + s.f1 + s.f2 + s.f3;
371}
372
373struct PointerWrapper {
374    void* ctx;
375};
376
377uintptr_t ExtractPointer(struct PointerWrapper wrapper) {
378    return (uintptr_t)wrapper.ctx;
379}
380
381struct TwoPointers {
382    void* ptr1;
383    void* ptr2;
384};
385
386uintptr_t AddPointers(struct TwoPointers wrapper) {
387    return (uintptr_t)wrapper.ptr1 + (uintptr_t)wrapper.ptr2;
388}
389
390// Identity functions for round-trip testing of struct arguments
391
392struct OneInt64 {
393    int64_t a;
394};
395
396struct OneInt64 IdentityOneInt64(struct OneInt64 s) {
397    return s;
398}
399
400struct IntLessThan16Bytes IdentityIntLessThan16Bytes(struct IntLessThan16Bytes s) {
401    return s;
402}
403
404struct TwoDoubleStruct IdentityTwoDoubleStruct(struct TwoDoubleStruct s) {
405    return s;
406}
407
408struct FourFloat32 {
409    float a, b, c, d;
410};
411
412struct FourFloat32 IdentityFourFloat32(struct FourFloat32 s) {
413    return s;
414}
415
416struct FloatAndInt IdentityFloatAndInt(struct FloatAndInt s) {
417    return s;
418}
419
420struct ThreeInt64 {
421    int64_t a, b, c;
422};
423
424struct ThreeInt64 IdentityThreeInt64(struct ThreeInt64 s) {
425    return s;
426}
427
428struct PtrInt64Ptr {
429    int64_t *a;
430    int64_t b;
431    int64_t *c;
432};
433
434struct PtrInt64Ptr IdentityPtrInt64Ptr(struct PtrInt64Ptr s) {
435    return s;
436}
437
438struct IntLessThan16Bytes IdentityTwoInt64AfterPrims(int64_t x, double y, struct IntLessThan16Bytes s) {
439    return s;
440}
441
442struct FloatLessThan16Bytes IdentityTwoFloat32AfterFloats(double x, double y, struct FloatLessThan16Bytes s) {
443    return s;
444}
445
446struct Mixed5Args {
447    int64_t *a;
448    int32_t b;
449    float c;
450    int32_t d;
451};
452
453struct Mixed5Args IdentityMixed5Args(struct Mixed5Args s) {
454    return s;
455}

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 1

Tags 102

↑↓ moveenter openesc close