mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-06 15:48:51 +00:00
vendor/libc: a bunch of additions
All these additions are to allow Dear ImGui to be compiled natively.
This commit is contained in:
Vendored
+33
@@ -0,0 +1,33 @@
|
|||||||
|
package odin_libc
|
||||||
|
|
||||||
|
@(require, linkage="strong", link_name="isdigit")
|
||||||
|
isdigit :: proc "c" (c: i32) -> b32 {
|
||||||
|
switch c {
|
||||||
|
case '0'..='9': return true
|
||||||
|
case: return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@(require, linkage="strong", link_name="isblank")
|
||||||
|
isblank :: proc "c" (c: i32) -> b32 {
|
||||||
|
switch c {
|
||||||
|
case '\t', ' ': return true
|
||||||
|
case: return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@(require, linkage="strong", link_name="isspace")
|
||||||
|
isspace :: proc "c" (c: i32) -> b32 {
|
||||||
|
switch c {
|
||||||
|
case '\t', ' ', '\n', '\v', '\f', '\r': return true
|
||||||
|
case: return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@(require, linkage="strong", link_name="toupper")
|
||||||
|
toupper :: proc "c" (c: i32) -> i32 {
|
||||||
|
if c >= 'a' && c <= 'z' {
|
||||||
|
return c - ('a' - 'A')
|
||||||
|
}
|
||||||
|
return c
|
||||||
|
}
|
||||||
Vendored
+21
@@ -0,0 +1,21 @@
|
|||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
void *alloca(size_t); /* built-in for gcc */
|
||||||
|
|
||||||
|
#if defined(__GNUC__) && __GNUC__ >= 3
|
||||||
|
/* built-in for gcc 3 */
|
||||||
|
#undef alloca
|
||||||
|
#undef __alloca
|
||||||
|
#define alloca(size) __alloca(size)
|
||||||
|
#define __alloca(size) __builtin_alloca(size)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
Vendored
+12
@@ -1,3 +1,9 @@
|
|||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
#ifdef NDEBUG
|
#ifdef NDEBUG
|
||||||
#define assert(e) ((void)0)
|
#define assert(e) ((void)0)
|
||||||
#else
|
#else
|
||||||
@@ -14,3 +20,9 @@ void __odin_libc_assert_fail(const char *, const char *, int, const char *);
|
|||||||
(__builtin_expect(!(e), 0) ? __odin_libc_assert_fail(__func__, __ASSERT_FILE_NAME, __LINE__, #e) : (void)0)
|
(__builtin_expect(!(e), 0) ? __odin_libc_assert_fail(__func__, __ASSERT_FILE_NAME, __LINE__, #e) : (void)0)
|
||||||
|
|
||||||
#endif /* NDEBUG */
|
#endif /* NDEBUG */
|
||||||
|
|
||||||
|
#define static_assert _Static_assert
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|||||||
Vendored
+15
@@ -0,0 +1,15 @@
|
|||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
int isdigit(int c);
|
||||||
|
int isblank(int c);
|
||||||
|
int isspace(int c);
|
||||||
|
|
||||||
|
int toupper(int c);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
Vendored
Vendored
+47
-2
@@ -1,21 +1,66 @@
|
|||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
#define INFINITY (1.0 / 0.0)
|
||||||
|
#define NAN (0.0 / 0.0)
|
||||||
|
|
||||||
float sqrtf(float);
|
float sqrtf(float);
|
||||||
float cosf(float);
|
float cosf(float);
|
||||||
float sinf(float);
|
float sinf(float);
|
||||||
float atan2f(float, float);
|
float atan2f(float, float);
|
||||||
bool isnan(float);
|
|
||||||
bool isinf(float);
|
float floorf(float x);
|
||||||
double floor(double x);
|
double floor(double x);
|
||||||
|
float ceilf(float x);
|
||||||
double ceil(double x);
|
double ceil(double x);
|
||||||
double sqrt(double x);
|
double sqrt(double x);
|
||||||
|
float powf(float x, float y);
|
||||||
double pow(double x, double y);
|
double pow(double x, double y);
|
||||||
|
float fmodf(float x, float y);
|
||||||
double fmod(double x, double y);
|
double fmod(double x, double y);
|
||||||
double cos(double x);
|
double cos(double x);
|
||||||
|
float acosf(float x);
|
||||||
double acos(double x);
|
double acos(double x);
|
||||||
|
float fabsf(float x);
|
||||||
double fabs(double x);
|
double fabs(double x);
|
||||||
int abs(int);
|
int abs(int);
|
||||||
double ldexp(double, int);
|
double ldexp(double, int);
|
||||||
double exp(double);
|
double exp(double);
|
||||||
|
float logf(float);
|
||||||
double log(double);
|
double log(double);
|
||||||
double sin(double);
|
double sin(double);
|
||||||
|
double trunc(double);
|
||||||
|
double log2(double);
|
||||||
|
double log10(double);
|
||||||
|
double asin(double);
|
||||||
|
double atan(double);
|
||||||
|
double tan(double);
|
||||||
|
double atan2(double, double);
|
||||||
|
double modf(double, double*);
|
||||||
|
|
||||||
|
bool __isnanf(float);
|
||||||
|
bool __isnand(double);
|
||||||
|
#define isnan(x) \
|
||||||
|
( sizeof(x) == sizeof(float) ? __isnanf((float)(x)) \
|
||||||
|
: : __isnand((double)(x)))
|
||||||
|
|
||||||
|
bool __isinff(float);
|
||||||
|
bool __isinfd(double);
|
||||||
|
#define isinf(x) \
|
||||||
|
( sizeof(x) == sizeof(float) ? __isinff((float)(x)) \
|
||||||
|
: : __isinfd((double)(x)))
|
||||||
|
|
||||||
|
bool __isfinitef(float);
|
||||||
|
bool __isfinited(double);
|
||||||
|
#define isfinite(x) \
|
||||||
|
( sizeof(x) == sizeof(float) ? __isfinitef((float)(x)) \
|
||||||
|
: : __isfinited((double)(x)))
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|||||||
Vendored
+56
-2
@@ -1,8 +1,14 @@
|
|||||||
#include <stddef.h>
|
#ifdef __cplusplus
|
||||||
#include <stdarg.h>
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <alloca.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
typedef struct {} FILE;
|
typedef struct {} FILE;
|
||||||
|
|
||||||
#define SEEK_SET 0
|
#define SEEK_SET 0
|
||||||
@@ -12,6 +18,8 @@ typedef struct {} FILE;
|
|||||||
#define stdout ((FILE *)2)
|
#define stdout ((FILE *)2)
|
||||||
#define stderr ((FILE *)3)
|
#define stderr ((FILE *)3)
|
||||||
|
|
||||||
|
#define EOF -1
|
||||||
|
|
||||||
FILE *fopen(const char *, char *);
|
FILE *fopen(const char *, char *);
|
||||||
int fclose(FILE *);
|
int fclose(FILE *);
|
||||||
int fseek(FILE *, long, int);
|
int fseek(FILE *, long, int);
|
||||||
@@ -21,6 +29,10 @@ size_t fwrite(const void *, size_t, size_t, FILE *);
|
|||||||
|
|
||||||
int vfprintf(FILE *, const char *, va_list);
|
int vfprintf(FILE *, const char *, va_list);
|
||||||
int vsnprintf(char *, size_t, const char *, va_list);
|
int vsnprintf(char *, size_t, const char *, va_list);
|
||||||
|
int vsprintf(char *, const char *, va_list);
|
||||||
|
|
||||||
|
int putchar(int ch);
|
||||||
|
int getchar();
|
||||||
|
|
||||||
static inline int snprintf(char *buf, size_t size, const char *fmt, ...) {
|
static inline int snprintf(char *buf, size_t size, const char *fmt, ...) {
|
||||||
va_list args;
|
va_list args;
|
||||||
@@ -30,6 +42,14 @@ static inline int snprintf(char *buf, size_t size, const char *fmt, ...) {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline int sprintf(char *buf, const char *fmt, ...) {
|
||||||
|
va_list args;
|
||||||
|
va_start(args, fmt);
|
||||||
|
int result = vsprintf(buf, fmt, args);
|
||||||
|
va_end(args);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
static inline int fprintf(FILE *f, const char *fmt, ...) {
|
static inline int fprintf(FILE *f, const char *fmt, ...) {
|
||||||
va_list args;
|
va_list args;
|
||||||
va_start(args, fmt);
|
va_start(args, fmt);
|
||||||
@@ -45,3 +65,37 @@ static inline int printf(const char *fmt, ...) {
|
|||||||
va_end(args);
|
va_end(args);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int __sscanf(const char *str, const char *format, void *ptrs);
|
||||||
|
|
||||||
|
static inline int vsscanf(const char *str, const char *format, va_list ap) {
|
||||||
|
int count = 0;
|
||||||
|
for (int i = 0; format[i]; i++) {
|
||||||
|
if (format[i] == '%') {
|
||||||
|
if (format[i+1] == '%') {
|
||||||
|
i++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void **ptrs = (void **)(alloca(count*sizeof(void *)));
|
||||||
|
for (int i = 0; i < count; i++) {
|
||||||
|
ptrs[i] = va_arg(ap, void *);
|
||||||
|
}
|
||||||
|
|
||||||
|
return __sscanf(str, format, ptrs);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int sscanf(const char *str, const char *format, ...) {
|
||||||
|
va_list args;
|
||||||
|
va_start(args, format);
|
||||||
|
int res = vsscanf(str, format, args);
|
||||||
|
va_end(args);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|||||||
Vendored
+25
@@ -1,3 +1,9 @@
|
|||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
void *malloc(size_t size);
|
void *malloc(size_t size);
|
||||||
@@ -17,3 +23,22 @@ long long atoll(const char *);
|
|||||||
double atof(const char *);
|
double atof(const char *);
|
||||||
|
|
||||||
long strtol(const char *, char **, int);
|
long strtol(const char *, char **, int);
|
||||||
|
double strtod(const char *, char **);
|
||||||
|
|
||||||
|
void abort();
|
||||||
|
void exit(int exit_code);
|
||||||
|
|
||||||
|
#define ATEXIT_MAX 32
|
||||||
|
|
||||||
|
int atexit(typeof(void (void)) *);
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
long int quot;
|
||||||
|
long int rem;
|
||||||
|
} ldiv_t;
|
||||||
|
|
||||||
|
ldiv_t ldiv(long int number, long int denom);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|||||||
Vendored
+11
@@ -1,9 +1,16 @@
|
|||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
void *memcpy(void *, const void *, size_t);
|
void *memcpy(void *, const void *, size_t);
|
||||||
void *memset(void *, int, size_t);
|
void *memset(void *, int, size_t);
|
||||||
void *memmove(void *, void *, size_t);
|
void *memmove(void *, void *, size_t);
|
||||||
int memcmp(const void *, const void *, size_t);
|
int memcmp(const void *, const void *, size_t);
|
||||||
|
void *memchr(const void *, int, size_t);
|
||||||
|
|
||||||
unsigned long strlen(const char *str);
|
unsigned long strlen(const char *str);
|
||||||
|
|
||||||
@@ -19,3 +26,7 @@ int strcmp(const char *, const char *);
|
|||||||
int strncmp(const char *, const char *, size_t);
|
int strncmp(const char *, const char *, size_t);
|
||||||
|
|
||||||
char *strstr(const char *, const char *);
|
char *strstr(const char *, const char *);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|||||||
Vendored
+16
@@ -0,0 +1,16 @@
|
|||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
typedef int64_t clock_t;
|
||||||
|
typedef clock_t time_t;
|
||||||
|
|
||||||
|
clock_t clock();
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
Vendored
+115
-9
@@ -14,23 +14,28 @@ cosf :: proc "c" (v: f32) -> f32 {
|
|||||||
return math.cos(v)
|
return math.cos(v)
|
||||||
}
|
}
|
||||||
|
|
||||||
@(require, linkage="strong", link_name="sinf")
|
|
||||||
sinf :: proc "c" (v: f32) -> f32 {
|
|
||||||
return math.sin(v)
|
|
||||||
}
|
|
||||||
|
|
||||||
@(require, linkage="strong", link_name="atan2f")
|
@(require, linkage="strong", link_name="atan2f")
|
||||||
atan2f :: proc "c" (v: f32, v2: f32) -> f32 {
|
atan2f :: proc "c" (v: f32, v2: f32) -> f32 {
|
||||||
return math.atan2(v, v2)
|
return math.atan2(v, v2)
|
||||||
}
|
}
|
||||||
|
|
||||||
@(require, linkage="strong", link_name="isnan")
|
@(require, linkage="strong", link_name="__isnanf")
|
||||||
isnan :: proc "c" (v: f32) -> bool {
|
isnanf :: proc "c" (v: f32) -> bool {
|
||||||
return math.is_nan(v)
|
return math.is_nan(v)
|
||||||
}
|
}
|
||||||
|
|
||||||
@(require, linkage="strong", link_name="isinf")
|
@(require, linkage="strong", link_name="__isnand")
|
||||||
isinf :: proc "c" (v: f32) -> bool {
|
isnand :: proc "c" (v: f64) -> bool {
|
||||||
|
return math.is_nan(v)
|
||||||
|
}
|
||||||
|
|
||||||
|
@(require, linkage="strong", link_name="__isinff")
|
||||||
|
isinff :: proc "c" (v: f32) -> bool {
|
||||||
|
return math.is_inf(v)
|
||||||
|
}
|
||||||
|
|
||||||
|
@(require, linkage="strong", link_name="__isinfd")
|
||||||
|
isinfd :: proc "c" (v: f64) -> bool {
|
||||||
return math.is_inf(v)
|
return math.is_inf(v)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -39,21 +44,41 @@ sqrt :: proc "c" (x: f64) -> f64 {
|
|||||||
return math.sqrt(x)
|
return math.sqrt(x)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@(require, linkage="strong", link_name="floorf")
|
||||||
|
floorf :: proc "c" (x: f32) -> f32 {
|
||||||
|
return math.floor(x)
|
||||||
|
}
|
||||||
|
|
||||||
@(require, linkage="strong", link_name="floor")
|
@(require, linkage="strong", link_name="floor")
|
||||||
floor :: proc "c" (x: f64) -> f64 {
|
floor :: proc "c" (x: f64) -> f64 {
|
||||||
return math.floor(x)
|
return math.floor(x)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@(require, linkage="strong", link_name="ceilf")
|
||||||
|
ceilf :: proc "c" (x: f32) -> f32 {
|
||||||
|
return math.ceil(x)
|
||||||
|
}
|
||||||
|
|
||||||
@(require, linkage="strong", link_name="ceil")
|
@(require, linkage="strong", link_name="ceil")
|
||||||
ceil :: proc "c" (x: f64) -> f64 {
|
ceil :: proc "c" (x: f64) -> f64 {
|
||||||
return math.ceil(x)
|
return math.ceil(x)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@(require, linkage="strong", link_name="powf")
|
||||||
|
powf :: proc "c" (x, y: f32) -> f32 {
|
||||||
|
return math.pow(x, y)
|
||||||
|
}
|
||||||
|
|
||||||
@(require, linkage="strong", link_name="pow")
|
@(require, linkage="strong", link_name="pow")
|
||||||
pow :: proc "c" (x, y: f64) -> f64 {
|
pow :: proc "c" (x, y: f64) -> f64 {
|
||||||
return math.pow(x, y)
|
return math.pow(x, y)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@(require, linkage="strong", link_name="fmodf")
|
||||||
|
fmodf :: proc "c" (x, y: f32) -> f32 {
|
||||||
|
return math.mod(x, y)
|
||||||
|
}
|
||||||
|
|
||||||
@(require, linkage="strong", link_name="fmod")
|
@(require, linkage="strong", link_name="fmod")
|
||||||
fmod :: proc "c" (x, y: f64) -> f64 {
|
fmod :: proc "c" (x, y: f64) -> f64 {
|
||||||
return math.mod(x, y)
|
return math.mod(x, y)
|
||||||
@@ -64,11 +89,21 @@ cos :: proc "c" (x: f64) -> f64 {
|
|||||||
return math.cos(x)
|
return math.cos(x)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@(require, linkage="strong", link_name="acosf")
|
||||||
|
acosf :: proc "c" (x: f32) -> f32 {
|
||||||
|
return math.acos(x)
|
||||||
|
}
|
||||||
|
|
||||||
@(require, linkage="strong", link_name="acos")
|
@(require, linkage="strong", link_name="acos")
|
||||||
acos :: proc "c" (x: f64) -> f64 {
|
acos :: proc "c" (x: f64) -> f64 {
|
||||||
return math.acos(x)
|
return math.acos(x)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@(require, linkage="strong", link_name="fabsf")
|
||||||
|
fabsf :: proc "c" (x: f32) -> f32 {
|
||||||
|
return math.abs(x)
|
||||||
|
}
|
||||||
|
|
||||||
@(require, linkage="strong", link_name="fabs")
|
@(require, linkage="strong", link_name="fabs")
|
||||||
fabs :: proc "c" (x: f64) -> f64 {
|
fabs :: proc "c" (x: f64) -> f64 {
|
||||||
return math.abs(x)
|
return math.abs(x)
|
||||||
@@ -89,6 +124,11 @@ exp :: proc "c" (x: f64) -> f64 {
|
|||||||
return math.exp(x)
|
return math.exp(x)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@(require, linkage="strong", link_name="logf")
|
||||||
|
logf :: proc "c" (x: f32) -> f32 {
|
||||||
|
return math.ln(x)
|
||||||
|
}
|
||||||
|
|
||||||
@(require, linkage="strong", link_name="log")
|
@(require, linkage="strong", link_name="log")
|
||||||
log :: proc "c" (x: f64) -> f64 {
|
log :: proc "c" (x: f64) -> f64 {
|
||||||
return math.ln(x)
|
return math.ln(x)
|
||||||
@@ -98,3 +138,69 @@ log :: proc "c" (x: f64) -> f64 {
|
|||||||
sin :: proc "c" (x: f64) -> f64 {
|
sin :: proc "c" (x: f64) -> f64 {
|
||||||
return math.sin(x)
|
return math.sin(x)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@(require, linkage="strong", link_name="sinf")
|
||||||
|
sinf :: proc "c" (v: f32) -> f32 {
|
||||||
|
return math.sin(v)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@(require, linkage="strong", link_name="trunc")
|
||||||
|
trunc :: proc "c" (x: f64) -> f64 {
|
||||||
|
return math.trunc(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
@(require, linkage="strong", link_name="__isfinitef")
|
||||||
|
isfinitef :: proc "c" (x: f32) -> bool {
|
||||||
|
switch math.classify(x) {
|
||||||
|
case .Normal, .Subnormal, .Zero, .Neg_Zero: return true
|
||||||
|
case .Inf, .Neg_Inf, .NaN: return false
|
||||||
|
case: unreachable()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@(require, linkage="strong", link_name="__isfinited")
|
||||||
|
isfinited :: proc "c" (x: f64) -> bool {
|
||||||
|
switch math.classify(x) {
|
||||||
|
case .Normal, .Subnormal, .Zero, .Neg_Zero: return true
|
||||||
|
case .Inf, .Neg_Inf, .NaN: return false
|
||||||
|
case: unreachable()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@(require, linkage="strong", link_name="log2")
|
||||||
|
log2 :: proc "c" (x: f64) -> f64 {
|
||||||
|
return math.log2(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
@(require, linkage="strong", link_name="log10")
|
||||||
|
log10 :: proc "c" (x: f64) -> f64 {
|
||||||
|
return math.log10(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
@(require, linkage="strong", link_name="asin")
|
||||||
|
asin :: proc "c" (x: f64) -> f64 {
|
||||||
|
return math.asin(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
@(require, linkage="strong", link_name="atan")
|
||||||
|
atan :: proc "c" (x: f64) -> f64 {
|
||||||
|
return math.atan(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
@(require, linkage="strong", link_name="tan")
|
||||||
|
tan :: proc "c" (x: f64) -> f64 {
|
||||||
|
return math.tan(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
@(require, linkage="strong", link_name="atan2")
|
||||||
|
atan2 :: proc "c" (y: f64, x: f64) -> f64 {
|
||||||
|
return math.atan2(y, x)
|
||||||
|
}
|
||||||
|
|
||||||
|
@(require, linkage="strong", link_name="modf")
|
||||||
|
modf :: proc "c" (num: f64, iptr: ^f64) -> f64 {
|
||||||
|
integral, fractional := math.modf(num)
|
||||||
|
iptr^ = integral
|
||||||
|
return fractional
|
||||||
|
}
|
||||||
|
|||||||
Vendored
+412
-1
@@ -1,18 +1,23 @@
|
|||||||
#+build !freestanding
|
#+build !freestanding
|
||||||
package odin_libc
|
package odin_libc
|
||||||
|
|
||||||
|
import "base:runtime"
|
||||||
|
|
||||||
import "core:c"
|
import "core:c"
|
||||||
import "core:io"
|
import "core:io"
|
||||||
import "core:os"
|
import "core:os"
|
||||||
|
import "core:strconv"
|
||||||
|
|
||||||
import stb "vendor:stb/sprintf"
|
import stb "vendor:stb/sprintf"
|
||||||
|
|
||||||
FILE :: uintptr
|
FILE :: uintptr
|
||||||
|
|
||||||
|
EOF :: -1
|
||||||
|
|
||||||
@(require, linkage="strong", link_name="fopen")
|
@(require, linkage="strong", link_name="fopen")
|
||||||
fopen :: proc "c" (path: cstring, mode: cstring) -> FILE {
|
fopen :: proc "c" (path: cstring, mode: cstring) -> FILE {
|
||||||
context = g_ctx
|
context = g_ctx
|
||||||
unimplemented("odin_libc.fopen")
|
unimplemented("vendor/libc: fopen")
|
||||||
}
|
}
|
||||||
|
|
||||||
@(require, linkage="strong", link_name="fseek")
|
@(require, linkage="strong", link_name="fseek")
|
||||||
@@ -63,6 +68,31 @@ fwrite :: proc "c" (buffer: [^]byte, size: uint, count: uint, file: FILE) -> uin
|
|||||||
return uint(max(0, n))
|
return uint(max(0, n))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@(require, linkage="strong", link_name="putchar")
|
||||||
|
putchar :: proc "c" (char: c.int) -> c.int {
|
||||||
|
context = g_ctx
|
||||||
|
|
||||||
|
n, err := os.write_byte(os.stdout, byte(char))
|
||||||
|
if n == 0 || err != nil {
|
||||||
|
return EOF
|
||||||
|
}
|
||||||
|
return char
|
||||||
|
}
|
||||||
|
|
||||||
|
@(require, linkage="strong", link_name="getchar")
|
||||||
|
getchar :: proc "c" () -> c.int {
|
||||||
|
when #defined(os.stdin) {
|
||||||
|
ret: [1]byte
|
||||||
|
n, err := os.read(os.stdin, ret[:])
|
||||||
|
if n == 0 || err != nil {
|
||||||
|
return EOF
|
||||||
|
}
|
||||||
|
return c.int(ret[0])
|
||||||
|
} else {
|
||||||
|
return EOF
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@(require, linkage="strong", link_name="vsnprintf")
|
@(require, linkage="strong", link_name="vsnprintf")
|
||||||
vsnprintf :: proc "c" (buf: [^]byte, count: uint, fmt: cstring, args: ^c.va_list) -> i32 {
|
vsnprintf :: proc "c" (buf: [^]byte, count: uint, fmt: cstring, args: ^c.va_list) -> i32 {
|
||||||
i32_count := i32(count)
|
i32_count := i32(count)
|
||||||
@@ -70,6 +100,11 @@ vsnprintf :: proc "c" (buf: [^]byte, count: uint, fmt: cstring, args: ^c.va_list
|
|||||||
return stb.vsnprintf(buf, i32_count, fmt, args)
|
return stb.vsnprintf(buf, i32_count, fmt, args)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@(require, linkage="strong", link_name="vsprintf")
|
||||||
|
vsprintf :: proc "c" (buf: [^]byte, fmt: cstring, args: ^c.va_list) -> i32 {
|
||||||
|
return stb.vsprintf(buf, fmt, args)
|
||||||
|
}
|
||||||
|
|
||||||
@(require, linkage="strong", link_name="vfprintf")
|
@(require, linkage="strong", link_name="vfprintf")
|
||||||
vfprintf :: proc "c" (file: FILE, fmt: cstring, args: ^c.va_list) -> i32 {
|
vfprintf :: proc "c" (file: FILE, fmt: cstring, args: ^c.va_list) -> i32 {
|
||||||
context = g_ctx
|
context = g_ctx
|
||||||
@@ -105,3 +140,379 @@ vfprintf :: proc "c" (file: FILE, fmt: cstring, args: ^c.va_list) -> i32 {
|
|||||||
|
|
||||||
return i32(len(buf))
|
return i32(len(buf))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Derived from musl libc - MIT licensed - Copyright © 2005-2020 Rich Felker, et al.
|
||||||
|
*/
|
||||||
|
@(require, linkage="strong", link_name="__sscanf")
|
||||||
|
_sscanf :: proc "c" (str, fmt: [^]byte, orig_ptrs: [^]rawptr) -> i32 {
|
||||||
|
Size :: enum u8 {
|
||||||
|
None,
|
||||||
|
hh,
|
||||||
|
h,
|
||||||
|
l,
|
||||||
|
L,
|
||||||
|
ll,
|
||||||
|
}
|
||||||
|
|
||||||
|
store_int :: proc(dest: rawptr, size: Size, i: u64) {
|
||||||
|
if dest == nil { return }
|
||||||
|
#partial switch size {
|
||||||
|
case .hh:
|
||||||
|
(^c.char)(dest)^ = c.char(i)
|
||||||
|
case .h:
|
||||||
|
(^c.short)(dest)^ = c.short(i)
|
||||||
|
case .None:
|
||||||
|
(^c.int)(dest)^ = c.int(i)
|
||||||
|
case .l:
|
||||||
|
(^c.long)(dest)^ = c.long(i)
|
||||||
|
case .ll:
|
||||||
|
(^c.longlong)(dest)^ = c.longlong(i)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
context = g_ctx
|
||||||
|
|
||||||
|
str := str
|
||||||
|
ptrs := orig_ptrs
|
||||||
|
|
||||||
|
// TODO: implement wide char variants
|
||||||
|
|
||||||
|
pos: u64
|
||||||
|
dest: rawptr
|
||||||
|
ch, t: byte
|
||||||
|
// wcs: [^]c.wchar_t
|
||||||
|
s: [^]byte
|
||||||
|
k, i, width: int
|
||||||
|
alloc: bool
|
||||||
|
scanset: [257]byte
|
||||||
|
invert: u8
|
||||||
|
matches: i32
|
||||||
|
size: Size
|
||||||
|
input_fail, match_fail, fmt_fail, alloc_fail: bool
|
||||||
|
|
||||||
|
main_loop: for p := fmt; p[0] != 0; p = p[1:] {
|
||||||
|
alloc = false
|
||||||
|
|
||||||
|
if isspace(i32(p[0])) {
|
||||||
|
for isspace(i32(p[0])) {
|
||||||
|
p = p[1:]
|
||||||
|
}
|
||||||
|
for isspace(i32(str[0])) {
|
||||||
|
str = str[1:]
|
||||||
|
pos += 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if p[0] != '%' || p[1] == '%' {
|
||||||
|
if p[0] == '%' {
|
||||||
|
p = p[1:]
|
||||||
|
}
|
||||||
|
ch = str[0]
|
||||||
|
if ch != p[0] {
|
||||||
|
if ch == 0 {
|
||||||
|
input_fail = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
match_fail = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
pos += 1
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
p = p[1:]
|
||||||
|
if p[0] == '*' {
|
||||||
|
dest = nil
|
||||||
|
p = p[1:]
|
||||||
|
} else if isdigit(i32(p[0])) && p[1] == '$' {
|
||||||
|
dest = orig_ptrs[p[0] - '0']
|
||||||
|
p = p[2:]
|
||||||
|
} else {
|
||||||
|
dest = ptrs[0]
|
||||||
|
ptrs = ptrs[1:]
|
||||||
|
}
|
||||||
|
|
||||||
|
for width = 0; isdigit(i32(p[0])); p = p[1:] {
|
||||||
|
width = 10 * width + int(p[0] - '0')
|
||||||
|
}
|
||||||
|
|
||||||
|
if p[0] == 'm' {
|
||||||
|
// wcs = nil
|
||||||
|
s = nil
|
||||||
|
alloc = dest != nil
|
||||||
|
p = p[1:]
|
||||||
|
} else {
|
||||||
|
alloc = false
|
||||||
|
}
|
||||||
|
|
||||||
|
size = .None
|
||||||
|
p = p[1:]
|
||||||
|
switch p[-1] {
|
||||||
|
case 'h':
|
||||||
|
size = .h
|
||||||
|
if p[0] == 'h' {
|
||||||
|
p = p[1:]
|
||||||
|
size = .hh
|
||||||
|
}
|
||||||
|
case 'l':
|
||||||
|
size = .l
|
||||||
|
if p[0] == 'l' {
|
||||||
|
p = p[1:]
|
||||||
|
size = .ll
|
||||||
|
}
|
||||||
|
case 'j':
|
||||||
|
size = .ll
|
||||||
|
case 'z', 't':
|
||||||
|
size = .l
|
||||||
|
case 'L':
|
||||||
|
size = .L
|
||||||
|
case 'd', 'i', 'o', 'u', 'x',
|
||||||
|
'a', 'e', 'f', 'g',
|
||||||
|
'A', 'E', 'F', 'G', 'X',
|
||||||
|
's', 'c', '[',
|
||||||
|
'S', 'C', 'p', 'n':
|
||||||
|
p = p[-1:]
|
||||||
|
case:
|
||||||
|
fmt_fail = true
|
||||||
|
break main_loop
|
||||||
|
}
|
||||||
|
|
||||||
|
t = p[0]
|
||||||
|
|
||||||
|
switch t {
|
||||||
|
case 'C':
|
||||||
|
t = 'c'
|
||||||
|
size = .l
|
||||||
|
case 'S':
|
||||||
|
t = 's'
|
||||||
|
size = .l
|
||||||
|
}
|
||||||
|
|
||||||
|
switch t {
|
||||||
|
case 'c':
|
||||||
|
if width < 1 {
|
||||||
|
width = 1
|
||||||
|
}
|
||||||
|
case '[':
|
||||||
|
case 'n':
|
||||||
|
store_int(dest, size, pos)
|
||||||
|
continue
|
||||||
|
case:
|
||||||
|
for isspace(i32(str[0])) {
|
||||||
|
str = str[1:]
|
||||||
|
pos += 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if str[0] == 0 {
|
||||||
|
input_fail = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
if width == 0 {
|
||||||
|
width = max(int)
|
||||||
|
}
|
||||||
|
|
||||||
|
switch t {
|
||||||
|
case 's', 'c', '[':
|
||||||
|
if t == 'c' || t == 's' {
|
||||||
|
runtime.memset(&scanset, -1, size_of(scanset))
|
||||||
|
scanset[0] = 0
|
||||||
|
if t == 's' {
|
||||||
|
scanset['\t'] = 0
|
||||||
|
scanset['\n'] = 0
|
||||||
|
scanset['\v'] = 0
|
||||||
|
scanset['\f'] = 0
|
||||||
|
scanset['\r'] = 0
|
||||||
|
scanset[' '] = 0
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
p = p[1:]
|
||||||
|
invert = 0
|
||||||
|
if p[0] == '^' {
|
||||||
|
p = p[1:]
|
||||||
|
invert = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
runtime.memset(&scanset, i32(invert), size_of(scanset))
|
||||||
|
scanset[0] = 0
|
||||||
|
if p[0] == '-' {
|
||||||
|
p = p[1:]
|
||||||
|
scanset['-'] = 1 - invert
|
||||||
|
} else if p[0] == ']' {
|
||||||
|
p = p[1:]
|
||||||
|
scanset[']'] = 1 - invert
|
||||||
|
}
|
||||||
|
|
||||||
|
for ; p[0] != ']'; p = p[1:] {
|
||||||
|
if p[0] == 0 {
|
||||||
|
fmt_fail = true
|
||||||
|
break main_loop
|
||||||
|
}
|
||||||
|
if p[0] == '-' && p[1] != ']' {
|
||||||
|
c := p
|
||||||
|
p = p[1:]
|
||||||
|
for ch = c[0]; c[0] < p[0]; c, ch = c[1:], c[0] {
|
||||||
|
scanset[ch] = 1 - invert
|
||||||
|
}
|
||||||
|
scanset[p[0]] = 1 - invert
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// wcs = nil
|
||||||
|
s = nil
|
||||||
|
i = 0
|
||||||
|
k = t == 'c' ? width + 1 : 31
|
||||||
|
if size == .l {
|
||||||
|
unimplemented("vendor/libc: sscanf wide character support")
|
||||||
|
} else if alloc {
|
||||||
|
s = make([^]byte, k)
|
||||||
|
if s == nil {
|
||||||
|
alloc_fail = true
|
||||||
|
break main_loop
|
||||||
|
}
|
||||||
|
|
||||||
|
for ch = str[0]; scanset[ch] != 0 && i < width; {
|
||||||
|
s[i] = ch
|
||||||
|
i += 1
|
||||||
|
if i == k {
|
||||||
|
old_size := k
|
||||||
|
k += k + 1
|
||||||
|
tmp, _ := runtime.non_zero_mem_resize(s, old_size, k)
|
||||||
|
if tmp == nil {
|
||||||
|
alloc_fail = true
|
||||||
|
break main_loop
|
||||||
|
}
|
||||||
|
s = raw_data(tmp)
|
||||||
|
}
|
||||||
|
|
||||||
|
str = str[1:]
|
||||||
|
ch = str[0]
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
s = cast([^]byte)dest
|
||||||
|
if s != nil {
|
||||||
|
for ch = str[0]; scanset[ch] != 0 && i < width; {
|
||||||
|
s[i] = ch
|
||||||
|
i += 1
|
||||||
|
|
||||||
|
str = str[1:]
|
||||||
|
ch = str[0]
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for ; scanset[str[0]] != 0 && i < width; str = str[1:] {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if i == 0 {
|
||||||
|
match_fail = true
|
||||||
|
break main_loop
|
||||||
|
}
|
||||||
|
|
||||||
|
str = str[-1:]
|
||||||
|
|
||||||
|
if t == 'c' && i != width {
|
||||||
|
match_fail = true
|
||||||
|
break main_loop
|
||||||
|
}
|
||||||
|
|
||||||
|
if alloc {
|
||||||
|
(^rawptr)(dest)^ = s
|
||||||
|
}
|
||||||
|
|
||||||
|
if t != 'c' {
|
||||||
|
if s != nil {s[i] = 0}
|
||||||
|
}
|
||||||
|
case:
|
||||||
|
base := -1
|
||||||
|
switch t {
|
||||||
|
case 'p', 'X', 'x':
|
||||||
|
base = 16
|
||||||
|
if i + 2 < width && str[0] == '0' && str[1] == 'x' {
|
||||||
|
str = str[2:]
|
||||||
|
}
|
||||||
|
case 'o':
|
||||||
|
base = 8
|
||||||
|
if i + 1 < width && str[0] == '0' {
|
||||||
|
str = str[1:]
|
||||||
|
}
|
||||||
|
case 'd', 'u':
|
||||||
|
base = 10
|
||||||
|
case 'i':
|
||||||
|
base = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
odin_str := string(cstring(str))
|
||||||
|
odin_str = odin_str[:min(len(odin_str), width-i)]
|
||||||
|
cnt: int
|
||||||
|
if base >= 0 {
|
||||||
|
x: i64
|
||||||
|
if base == 0 {
|
||||||
|
x, _ = strconv.parse_i64_maybe_prefixed(odin_str, &cnt)
|
||||||
|
} else {
|
||||||
|
x, _ = strconv.parse_i64_of_base(odin_str, base, &cnt)
|
||||||
|
}
|
||||||
|
|
||||||
|
if cnt == 0 {
|
||||||
|
match_fail = true
|
||||||
|
break main_loop
|
||||||
|
}
|
||||||
|
|
||||||
|
if t == 'p' && dest != nil {
|
||||||
|
(^rawptr)(dest)^ = rawptr(uintptr(x))
|
||||||
|
} else {
|
||||||
|
store_int(dest, size, u64(x))
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// should be a guarantee bcs of validation above.
|
||||||
|
// switch t {
|
||||||
|
// case 'a', 'A',
|
||||||
|
// 'e', 'E',
|
||||||
|
// 'f', 'F',
|
||||||
|
// 'g', 'G':
|
||||||
|
// }
|
||||||
|
x, _ := strconv.parse_f64(odin_str, &cnt)
|
||||||
|
|
||||||
|
if cnt == 0 {
|
||||||
|
match_fail = true
|
||||||
|
break main_loop
|
||||||
|
}
|
||||||
|
|
||||||
|
if dest != nil {
|
||||||
|
#partial switch size {
|
||||||
|
case .None:
|
||||||
|
(^c.float)(dest)^ = c.float(x)
|
||||||
|
case .l:
|
||||||
|
(^c.double)(dest)^ = c.double(x)
|
||||||
|
case .L:
|
||||||
|
(^c.double)(dest)^ = c.double(x) // longdouble
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pos += u64(cnt)
|
||||||
|
str = str[cnt:]
|
||||||
|
}
|
||||||
|
|
||||||
|
if dest != nil {
|
||||||
|
matches += 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if fmt_fail || alloc_fail || input_fail {
|
||||||
|
if matches == 0 {
|
||||||
|
matches = -1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if match_fail {
|
||||||
|
if alloc {
|
||||||
|
free(s)
|
||||||
|
// free(wcs)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return matches
|
||||||
|
}
|
||||||
|
|||||||
Vendored
+72
-1
@@ -1,8 +1,10 @@
|
|||||||
package odin_libc
|
package odin_libc
|
||||||
|
|
||||||
|
import "base:intrinsics"
|
||||||
import "base:runtime"
|
import "base:runtime"
|
||||||
|
|
||||||
import "core:c"
|
import "core:c"
|
||||||
|
import "core:os"
|
||||||
import "core:slice"
|
import "core:slice"
|
||||||
import "core:sort"
|
import "core:sort"
|
||||||
import "core:strconv"
|
import "core:strconv"
|
||||||
@@ -108,12 +110,81 @@ atof :: proc "c" (str: cstring) -> f64 {
|
|||||||
@(require, linkage="strong", link_name="strtol")
|
@(require, linkage="strong", link_name="strtol")
|
||||||
strtol :: proc "c" (str: cstring, str_end: ^cstring, base: i32) -> c.long {
|
strtol :: proc "c" (str: cstring, str_end: ^cstring, base: i32) -> c.long {
|
||||||
context = g_ctx
|
context = g_ctx
|
||||||
|
|
||||||
sstr := string(str)
|
sstr := string(str)
|
||||||
sstr = strings.trim_left_space(sstr)
|
sstr = strings.trim_left_space(sstr)
|
||||||
|
|
||||||
n: int
|
n: int
|
||||||
i, _ := strconv.parse_i64_of_base(sstr, int(base), &n)
|
i, _ := strconv.parse_i64_of_base(sstr, int(base), &n)
|
||||||
str_end ^= cstring(raw_data(sstr)[n:])
|
str_end ^= cstring(raw_data(sstr)[n:])
|
||||||
|
if str_end != nil {
|
||||||
|
str_end ^= cstring(raw_data(sstr)[n:])
|
||||||
|
}
|
||||||
return c.long(clamp(i, i64(min(c.long)), i64(max(c.long))))
|
return c.long(clamp(i, i64(min(c.long)), i64(max(c.long))))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@(require, linkage="strong", link_name="strtod")
|
||||||
|
strtod :: proc "c" (str: cstring, str_end: ^cstring) -> c.double {
|
||||||
|
context = g_ctx
|
||||||
|
|
||||||
|
sstr := string(str)
|
||||||
|
sstr = strings.trim_left_space(sstr)
|
||||||
|
|
||||||
|
n: int
|
||||||
|
val, _ := strconv.parse_f64(sstr, &n)
|
||||||
|
if str_end != nil {
|
||||||
|
str_end ^= cstring(raw_data(sstr)[n:])
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.double(val)
|
||||||
|
}
|
||||||
|
|
||||||
|
@(require, linkage="strong", link_name="abort")
|
||||||
|
abort :: proc "c" () -> ! {
|
||||||
|
intrinsics.trap()
|
||||||
|
}
|
||||||
|
|
||||||
|
ATEXIT_MAX :: 32
|
||||||
|
|
||||||
|
@(private)
|
||||||
|
atexit_functions: [ATEXIT_MAX]proc "c" ()
|
||||||
|
@(private)
|
||||||
|
atexit_functions_count: int
|
||||||
|
|
||||||
|
@(require, linkage="strong", link_name="atexit")
|
||||||
|
atexit :: proc "c" (function: proc "c" ()) -> i32 {
|
||||||
|
entry := intrinsics.atomic_add(&atexit_functions_count, 1)
|
||||||
|
if entry >= ATEXIT_MAX {
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
|
||||||
|
atexit_functions[entry] = function
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@(require, linkage="strong", link_name="exit")
|
||||||
|
exit :: proc "c" (exit_code: c.int) -> ! {
|
||||||
|
finish_atexit()
|
||||||
|
os.exit(int(exit_code))
|
||||||
|
}
|
||||||
|
|
||||||
|
@(private, fini)
|
||||||
|
finish_atexit :: proc "c" () {
|
||||||
|
n := intrinsics.atomic_exchange(&atexit_functions_count, 0)
|
||||||
|
for function in atexit_functions[:n] {
|
||||||
|
function()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ldiv_t :: struct {
|
||||||
|
quot: c.long,
|
||||||
|
rem: c.long,
|
||||||
|
}
|
||||||
|
|
||||||
|
@(require, linkage="strong", link_name="ldiv")
|
||||||
|
ldiv :: proc "c" (number: c.long, denom: c.long) -> ldiv_t {
|
||||||
|
return {
|
||||||
|
quot = number / denom,
|
||||||
|
rem = number %% denom,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Vendored
+10
@@ -5,6 +5,7 @@ import "base:intrinsics"
|
|||||||
import "core:c"
|
import "core:c"
|
||||||
import "core:strings"
|
import "core:strings"
|
||||||
import "core:mem"
|
import "core:mem"
|
||||||
|
import "core:bytes"
|
||||||
|
|
||||||
// NOTE: already defined by Odin.
|
// NOTE: already defined by Odin.
|
||||||
// void *memcpy(void *, const void *, size_t);
|
// void *memcpy(void *, const void *, size_t);
|
||||||
@@ -109,3 +110,12 @@ strstr :: proc "c" (str: cstring, substr: cstring) -> cstring {
|
|||||||
return cstring(([^]byte)(str)[idx:])
|
return cstring(([^]byte)(str)[idx:])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@(require, linkage="strong", link_name="memchr")
|
||||||
|
memchr :: proc "c" (str: [^]byte, c: i32, n: uint) -> [^]byte {
|
||||||
|
idx := bytes.index_byte(str[:n], u8(c))
|
||||||
|
if idx < 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return str[idx:]
|
||||||
|
}
|
||||||
|
|||||||
Vendored
+10
@@ -0,0 +1,10 @@
|
|||||||
|
package odin_libc
|
||||||
|
|
||||||
|
import "core:time"
|
||||||
|
|
||||||
|
clock_t :: i64
|
||||||
|
|
||||||
|
@(require, linkage="strong", link_name="clock")
|
||||||
|
clock :: proc "c" () -> clock_t {
|
||||||
|
return time.tick_now()._nsec
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user