1 /// Translated from C to D
2 module soundio.util;
3 
4 extern(C): nothrow: __gshared: // TODO: @nogc:
5 
6 import core.stdc.stdarg;
7 import core.stdc.stdio;
8 import core.stdc.stdlib;
9 import core.stdc..string;
10 import core.stdc.assert_;
11 
12 @nogc void soundio_panic(const(char)* format, ...);
13 @nogc char* soundio_alloc_sprintf(int* len, const(char)* format, ...);
14 
15 /// printf but to stderr instead of stdout
16 // Workaround for the fact that stderr is uninitialized (null) on MSVC Windows with betterC
17 // https://issues.dlang.org/show_bug.cgi?id=20532
18 @nogc void printf_stderr(const(char)* format, ...);
19 
20 pragma(mangle, printf_stderr.mangleof)
21 void printf_stderr_fakenogc(const(char)* format, ...) {
22     va_list ap;
23     va_start(ap, format);
24     if (stderr == null) {
25         vprintf(format, ap);
26     } else {
27         vfprintf(stderr, format, ap);
28     }
29     va_end(ap);
30 }
31 
32 // workaround for va_start not being @nogc
33 pragma(mangle, soundio_panic.mangleof)
34 void soundio_panic_fakenogc(const(char)* format, ...) {
35     va_list ap;
36     va_start(ap, format);
37     if (stderr == null) {
38         vprintf(format, ap);
39         printf("\n");
40     } else {
41         vfprintf(stderr, format, ap);
42         fprintf(stderr, "\n");
43     }
44     va_end(ap);
45     abort();
46 }
47 
48 pragma(mangle, soundio_alloc_sprintf.mangleof)
49 char* soundio_alloc_sprintf_fakenogc(int* len, const(char)* format, ...) {
50     va_list ap;va_list ap2;
51     va_start(ap, format);
52     va_copy(ap2, ap);
53 
54     int len1 = vsnprintf(null, 0, format, ap);
55     assert(len1 >= 0);
56 
57     size_t required_size = len1 + 1;
58     char* mem = ALLOCATE!(char)(required_size);
59     if (!mem)
60         return null;
61 
62     int len2 = vsnprintf(mem, required_size, format, ap2);
63     assert(len2 == len1);
64 
65     va_end(ap2);
66     va_end(ap);
67 
68     if (len)
69         *len = len1;
70     return mem;
71 }
72 
73 @nogc:
74 
75 auto ALLOCATE_NONZERO(Type)(size_t count) {
76     return cast(Type*) malloc((count) * Type.sizeof);
77 }
78 
79 auto ALLOCATE(Type)(size_t count) {
80     return cast(Type*) calloc(count, Type.sizeof);
81 }
82 
83 auto REALLOCATE_NONZERO(Type)(void* old, size_t new_count) {
84     return cast(Type*) realloc(old, new_count * Type.sizeof);
85 }
86 
87 alias SOUNDIO_ATTR_NORETURN = typeof(assert(0));
88 
89 pragma(inline, true)
90 int soundio_int_min(int a, int b) {
91     return (a <= b) ? a : b;
92 }
93 
94 pragma(inline, true)
95 int soundio_int_max(int a, int b) {
96     return (a >= b) ? a : b;
97 }
98 
99 package:
100 pragma(inline, true)
101 int soundio_int_clamp(int min_value, int value, int max_value) {
102     return soundio_int_max(soundio_int_min(value, max_value), min_value);
103 }
104 
105 pragma(inline, true)
106 double soundio_double_min(double a, double b) {
107     return (a <= b) ? a : b;
108 }
109 
110 pragma(inline, true)
111 double soundio_double_max(double a, double b) {
112     return (a >= b) ? a : b;
113 }
114 
115 pragma(inline, true)
116 double soundio_double_clamp(double min_value, double value, double max_value) {
117     return soundio_double_max(soundio_double_min(value, max_value), min_value);
118 }
119 
120 pragma(inline, true)
121 char* soundio_str_dupe(const(char)* str, int str_len) {
122     char* out_ = ALLOCATE_NONZERO!char(str_len + 1);
123     if (!out_)
124         return null;
125     memcpy(out_, str, str_len);
126     out_[str_len] = 0;
127     return out_;
128 }
129 
130 pragma(inline, true)
131 bool soundio_streql(const(char)* str1, int str1_len, const(char)* str2, int str2_len) {
132     if (str1_len != str2_len)
133         return false;
134     return memcmp(str1, str2, str1_len) == 0;
135 }
136 
137 pragma(inline, true)
138 int ceil_dbl_to_int(double x) {
139     const(double) truncation = cast(int)x;
140     return cast(int) (truncation + (truncation < x));
141 }
142 
143 pragma(inline, true)
144 double ceil_dbl(double x) {
145     const(double) truncation = cast(long) x;
146     const(double) ceiling = truncation + (truncation < x);
147     return ceiling;
148 }