-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathstandard.h
More file actions
201 lines (171 loc) · 4.63 KB
/
standard.h
File metadata and controls
201 lines (171 loc) · 4.63 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
/*
Standard includes, and checks of those standards.
Also generic functions that would be in a standard.
*/
#ifndef STANDARD_H
#define STANDARD_H
#include <stdint.h>
#include <ctype.h>
#include <stddef.h>
#include <stdlib.h>
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include <setjmp.h>
#include <gtk/gtk.h>
#ifdef C2X_COMPAT
typedef uint8_t char8_t; // uchar.h
#define UINT64_WIDTH 64 // IEC_60559_BFP_EXT_C23
// stdbit.h
#define stdc_count_ones(arg) __builtin_popcountg(arg)
#define stdc_first_trailing_one(arg) (__builtin_ctzg(arg, -1) + 1U)
#else
#include <uchar.h>
#include <stdbit.h>
#endif
#undef NULL
#define NULL nullptr
// weird bugs with sprintf when using _Floatn, but as long as we can assert...
// float/double will be fine.
typedef _Float16 float16_t;
//typedef _Float32 float32_t;
//typedef _Float64 float64_t;
typedef float float32_t;
typedef double float64_t;
//typedef _Float128 float128_t; // currently unnecessary
// we're dealing with a byte-packed little-endian ABI.
static_assert(__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__);
static_assert(CHAR_BIT == 8);
static_assert(sizeof(void) == 1); // void pointer arithmatic
static_assert(sizeof(char) == 1);
static_assert(sizeof(char8_t) == 1);
static_assert(sizeof(uint8_t) == 1);
static_assert(sizeof(uint16_t) == 2);
static_assert(sizeof(uint32_t) == 4);
static_assert(sizeof(uint64_t) == 8);
static_assert(sizeof(int8_t) == 1);
static_assert(sizeof(int16_t) == 2);
static_assert(sizeof(int32_t) == 4);
static_assert(sizeof(int64_t) == 8);
static_assert(sizeof(float16_t) == 2);
static_assert(sizeof(float32_t) == 4);
static_assert(sizeof(float64_t) == 8);
//static_assert(sizeof(float128_t) == 16);
#pragma pack(push, 1)
static_assert(sizeof(struct {uint32_t a; uint8_t b; float32_t c;}) == 9);
static_assert(sizeof(struct {int8_t a; uint64_t b; uint8_t c;}) == 10);
#pragma pack(pop)
#include "qnotation.h"
#include "npt_ints.h"
#include "semver.h"
/******************************************************************************/
#define lengthof(array) (sizeof(array)/sizeof(array[0]))
#define sizeof_flex_array(array, count) (sizeof((array)[0]) * (count))
#define sizeof_flex(struct_p, array, count) (\
offsetof(typeof(*(struct_p)), array)\
+ sizeof_flex_array((struct_p)->array, count)\
)
#define fall __attribute__((fallthrough))
#define __unused __attribute__((unused))
#define __nonstring __attribute__((nonstring))
#define __counted_by_nest(member) // nested flex is not supported; ignore
#define __counted_by_indir(member) // substruct.member doesn't work; ignore
#if __has_attribute(counted_by)
#undef __counted_by
#define __counted_by(member) __attribute__((counted_by(member)))
#elifndef __counted_by
#define __counted_by(member)
#endif
// !!(x) is bool convert
#define likely(x) __builtin_expect(!!(x), true)
#define unlikely(x) __builtin_expect(!!(x), false)
// TODO stroll that considers 0b prefix?
int64_t
strtoll_2(
char const* str
);
uint64_t
strtoull_2(
char const* str
);
bool
is_number( // test string if it's a decimal integer
char const* str
);
char*
stopcopy( // stpcpy; copy string, returns pointer to \0
char* restrict dest,
char const* restrict src
);
bool
char_in_string( // test if character ch appears anywhere in string
char ch,
char const* str
);
size_t
length_of_word(
char const* str
);
enum error_severity:uint8_t {
NO_ERROR = 0,
ERROR_WARNING = 1, // print a warning message and return
ERROR_ABORT = 2, // jongjump back to set destination
ERROR_CRASH = 3, // gracefully crash
};
struct error { // sorta intended to be a static variable
char message[128];
enum error_severity severity;
jmp_buf env;
};
void // may not return
error_emit( // severity and message must be set before calling
struct error* err,
char const* message
);
// convienence macro meant to replace assert() ; msg can by dynamic
// The intent is an error/warning message system that would replace assert()
#define error_assert(err, sev, msg, test) do {\
struct error* const errptr = (err);\
if (unlikely(!(test))) {\
assert(0);\
errptr->severity = sev;\
error_emit(errptr, (msg));\
}\
} while(0)
void*
cralloc( // crashes if not enough space
size_t size
);
void*
crealloc(
void* old,
size_t size
);
void*
cralloc0( // zero-allocates
size_t size
);
struct mem_arena {
void* start;
void* pos;
void* end;
};
void
arena_init( // initialise a new arena
struct mem_arena* arena,
size_t arena_size,
bool zeroed
);
void*
arena_alloc(
struct mem_arena* arena,
struct error* err, // required. Errors if here isn't enough room
size_t alloc_size
);
uint32_t
fletcher32(
const void* data,
size_t length
);
#endif