#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