You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

296 lines
7.3 KiB
C

#ifndef SHARED_H
#define SHARED_H
#define ZeroStruct(Struct) ZeroSize(&Struct, sizeof(Struct))
inline void ZeroSize(void* Ptr, size_t Size) {
u8* Byte = (u8*)Ptr;
// todo(jax): @Speed: Check performance of the two code blocks
#if 0
for (size_t i = 0; i < Size; ++i) {
*Byte++ = 0;
}
#else
while (Size--) {
*Byte++ = 0;
}
#endif
}
#define CopyArray(Dest, Source, Count) MemoryCopy((Dest), (Source), (Count)*sizeof(*(Source)))
inline void* MemoryCopy(void* _Dest, void* _Source, size_t Size) {
#if 0
return memcpy(_Dest, _Source, Size);
#else //NO CRT VERSION HERE!
if (_Source == 0) {
ZeroSize(_Dest, Size);
return _Dest;
}
u8* Source = (u8*)_Source;
u8* Dest = (u8*)_Dest;
while (Size--) {
*Dest++ = *Source++;
}
return _Dest;
#endif
}
inline u8* Advance(string* String, umm Count) {
u8 *Result = 0;
if(String->Count >= Count) {
Result = String->Data;
String->Data += Count;
String->Count -= Count;
} else {
String->Data += String->Count;
String->Count = 0;
}
return(Result);
}
inline b32 IsSpacing(char C) {
b32 Result = ((C == ' ') || (C == '\t') || (C == '\v') ||(C == '\f'));
return(Result);
}
inline b32 IsEndOfLine(char Value) {
b32 Result = ((Value == '\n') || (Value == '\r'));
return Result;
}
inline b32 IsWhitespace(char Value, bool IncludeEOL = false) {
b32 Result = ((Value == ' ') || (Value == '\t') || (Value == '\v') || (Value == '\f') || ( IncludeEOL ? IsEndOfLine(Value) : 1));
return Result;
}
inline b32 IsAlphabetical(char Value) {
b32 Result = (((Value >= 'a') && (Value <= 'z')) || ((Value >= 'A') && (Value <= 'Z')));
return Result;
}
inline b32 IsNumeric(char Value) {
b32 Result = ((Value >= '0') && (Value <= '9'));
return Result;
}
inline char* GetNextLine(char** Contents) {
char* Text = *Contents;
if (!*Text) {
return nullptr;
}
char* Line = Text;
while (*Text && (*Text != '\n') && (*Text != '\r')) {
++Text;
}
char* End = Text;
++End;
if (*Text == '\r') {
if (*End == '\n') {
++End;
}
*Text = '\0';
}
*Contents = End;
return Line;
}
inline int StringLength(char* String) {
int Count = 0;
while (*String++) {
++Count;
}
return Count;
}
inline string make_string(char* String) {
string Result = {};
Result.Data = (u8*)String;
Result.Count = StringLength(String);
return Result;
}
inline char* Substring(char* Source, char* String) {
while (*Source) {
char *Begin = Source;
char *Pattern = String;
// If first character of sub string match, check for whole string
while (*Source && *Pattern && *Source == *Pattern) {
Source++;
Pattern++;
}
// If complete sub string match, return starting address
if (!*Pattern)
return Begin;
Source = Begin + 1;
}
return NULL;
}
// note: _Char is expected to be an ASCII character
inline char* FindFirstChar(char* String, int _Char) {
char Char = (char)_Char;
while (*String != Char) {
if (!*String++) {
return NULL;
}
}
return (char*)String;
}
// todo(jax): Consider using while loops for Append and StringCopy?? Query performance benefit.
inline char* Append(char* Dest, size_t DestSize, char* Source) {
// todo(jax): Do we need to terminate annd or allocate needed memory?
Dest = (char*)malloc(DestSize + (1 + StringLength(Source) * sizeof(char)));
MemoryCopy(Dest + StringLength(Dest), Source, DestSize + 1);
return Dest;
}
inline char* StringCopy(char* String) {
char* Result = (char*)malloc(sizeof(char) * (StringLength(String) + 1));
MemoryCopy(Result, String, sizeof(char) * (StringLength(String) + 1));
return Result;
}
inline bool StringsMatch(char* A, char* B) {
while (*A && *B) {
if (*A != *B){
return false;
}
++A;
++B;
}
if (*A != *B){
return false;
} else {
return true;
}
}
inline void CatStrings(size_t SourceACount, char* SourceA, size_t SourceBCount, char* SourceB, size_t DestCount, char* Dest) {
// todo(jax): Bounds check the Destination. This code is risky!
for (int Index = 0; Index < SourceACount; ++Index) {
*Dest++ = *SourceA++;
}
for (int Index = 0; Index < SourceBCount; ++Index) {
*Dest++ = *SourceB++;
}
*Dest++ = 0;
}
//
// NOT REALLY SURE IF WE WANT TO USE THE FOLLOWING CODE!
//
#if 1
void __cdecl __va_start(va_list*, ...);
#define _crt_va_start(ap, x) ((void)(__va_start(&ap, x)))
#define _crt_va_arg(ap, t) \
((sizeof(t) > sizeof(__int64) || (sizeof(t) & (sizeof(t) - 1)) != 0) \
? **(t**)((ap += sizeof(__int64)) - sizeof(__int64)) \
: *(t* )((ap += sizeof(__int64)) - sizeof(__int64)))
#define _crt_va_end(ap) ((void)(ap = (va_list)0))
#else
#define _crt_va_start(ap, v) va_start(ap, v)
#define _crt_va_arg(ap, t) va_arg(ap, t)
#define _crt_va_end(ap) va_end(ap)
#endif
inline int32 StringToI32_(char** AtInit) {
int32 Result = {};
char* At = *AtInit;
while ((*At >= '0') && (*At <= '9')) {
Result *= 10;
Result += (*At - '0');
++At;
}
*AtInit = At;
return Result;
}
inline int32 StringToI32(char* At) {
char* Ignored = At;
int32 Result = StringToI32_(&Ignored);
return Result;
}
struct format_dest;
void OutChar(format_dest* Dest, char Value);
void OutChars(format_dest* Dest, char* Value);
void U64ToASCII(format_dest* Dest, u64 Value, u32 Base, char* Digits);
void F64ToASCII(format_dest* Dest, f64 Value, u32 Precision);
// note(jax): This function serves as a replacement to `stdio.h` sprintf()
API_EXPORT umm FormatArgList(umm DestSize, char* DestInit, char* Format, va_list ArgList);
inline umm Format(umm DestSize, char* Dest, char* Format, ...) {
va_list ArgList;
_crt_va_start(ArgList, Format);
umm Result = FormatArgList(DestSize, Dest, Format, ArgList);
_crt_va_end(ArgList);
return Result;
}
inline int _crt_sprintf(char* Buffer, size_t Count, char* Format, ...) {
int Result;
va_list ArgList;
__crt_va_start(ArgList, Format);
Result = _vsprintf_s_l(Buffer, Count, Format, NULL, ArgList);
__crt_va_end(ArgList);
return Result;
}
inline umm ae_sprintf(char* Dest, char* Format, ...) {
va_list ArgList;
_crt_va_start(ArgList, Format);
umm Result = FormatArgList(sizeof(Dest), Dest, Format, ArgList);
_crt_va_end(ArgList);
return Result;
}
inline umm ae_sprintf(char* Dest, char* Format, va_list ArgList) {
umm Result = FormatArgList(sizeof(Dest), Dest, Format, ArgList);
return Result;
}
inline umm ae_printf(char* Format, ...) {
char Buffer[1024];
va_list ArgList;
_crt_va_start(ArgList, Format);
umm Result = FormatArgList(1024, Buffer, Format, ArgList);
_crt_va_end(ArgList);
fwrite(Buffer, sizeof(char), StringLength(Buffer), stdout);
fflush(stdout);
return Result;
}
#endif