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 }