Standard setup for writing C inspired by Casey Muratori, Ryan Fleury, Mr. 4th Programmer, and others in the handmade community.
Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.
 
 
 
 

228 linhas
5.8 KiB

  1. #ifndef CORE_H
  2. #define CORE_H
  3. // cstdlib includes
  4. #include <math.h>
  5. #include <stdint.h> // necessary for int type sizes
  6. #include <stdio.h>
  7. #include <time.h> // TODO(dledda): try not to depend on this one
  8. #if OS_WINDOWS
  9. #include "Windows.h"
  10. #elif OS_LINUX
  11. #include <sys/mman.h>
  12. #include <sys/stat.h>
  13. #else
  14. #error Development environment not supported.
  15. #endif
  16. // ### Misc macros ###
  17. #if ENABLE_ASSERT
  18. #define Assert(expression) if (!(expression)) {*(volatile int *)0 = 0;}
  19. #else
  20. #define Assert(expression)
  21. #endif
  22. #define function static
  23. #define global static
  24. #define local_persist static
  25. // ### Types ###
  26. typedef int8_t int8;
  27. typedef int16_t int16;
  28. typedef int32_t int32;
  29. typedef int64_t int64;
  30. typedef uint8_t uint8;
  31. typedef uint16_t uint16;
  32. typedef uint32_t uint32;
  33. typedef uint64_t uint64;
  34. typedef uint8_t byte;
  35. typedef float real32;
  36. typedef double real64;
  37. // ### Sizes and Numbers ###
  38. #define Bytes(n) (n)
  39. #define Kilobytes(n) (n << 10)
  40. #define Megabytes(n) (n << 20)
  41. #define Gigabytes(n) (((uint64)n) << 30)
  42. #define Terabytes(n) (((uint64)n) << 40)
  43. #define Thousand(n) ((n)*1000)
  44. #define Million(n) ((n)*1000000)
  45. #define Billion(n) ((n)*1000000000LL)
  46. #define ArrayCount(arr) (sizeof(arr) / sizeof((arr)[0]))
  47. // ### Arenas ###
  48. struct Arena {
  49. void *memory;
  50. size_t capacity;
  51. size_t head;
  52. };
  53. struct Scratch {
  54. Arena *arena;
  55. size_t start;
  56. };
  57. void *pushSize(Arena *arena, size_t bytes);
  58. Arena *arenaAlloc(size_t capacity);
  59. void arenaFree(Arena *arena);
  60. void arenaFreeFrom(Arena *arena, size_t pos);
  61. void initialiseCore();
  62. Scratch scratchStart(Arena **conflicts, size_t conflictCount);
  63. void scratchEnd(Scratch scratch);
  64. #define PushArray(arena, type, size) (type *)pushSize(arena, sizeof(type) * (size))
  65. #define PushStruct(arena, type) (type *)pushSize(arena, sizeof(type))
  66. // ### Vectors ###
  67. template <typename T>
  68. union Vector2 {
  69. struct {
  70. T x;
  71. T y;
  72. };
  73. T vec[2];
  74. };
  75. template <typename T>
  76. inline function Vector2<T> vec2(T x, T y) {
  77. Vector2<T> result = {0};
  78. result.x = x;
  79. result.y = y;
  80. return result;
  81. }
  82. template <typename T>
  83. union Vector3 {
  84. struct {
  85. T x;
  86. T y;
  87. T z;
  88. };
  89. T vec[3];
  90. };
  91. template <typename T>
  92. inline function Vector3<T> vec3(T x, T y, T z) {
  93. Vector3<T> result = {0};
  94. result.x = x;
  95. result.y = y;
  96. result.z = z;
  97. return result;
  98. }
  99. template <typename T>
  100. union Vector4 {
  101. struct {
  102. T x;
  103. T y;
  104. T z;
  105. T w;
  106. };
  107. T vec[4];
  108. };
  109. template <typename T>
  110. inline function Vector4<T> vec4(T x, T y, T z, T w) {
  111. Vector4<T> result = {0};
  112. result.x = x;
  113. result.y = y;
  114. result.z = z;
  115. result.w = w;
  116. return result;
  117. }
  118. // ### Lists ###
  119. template <typename T>
  120. struct list {
  121. T* data;
  122. size_t length;
  123. size_t head;
  124. };
  125. #define PushList(arena, type, size) (list<type>{ PushArray(arena, type, size), size, 0 })
  126. #define PushFullList(arena, type, size) (list<type>{ PushArray(arena, type, size), size, size })
  127. template <typename T> T *appendList(list<T> *list, T element);
  128. template <typename T> void zeroList(list<T> *list);
  129. template <typename T> void zeroListFull(list<T> *list);
  130. template <typename T> list<T> listSlice(list<T> l, size_t start, size_t stop = 0);
  131. // ### Strings ###
  132. struct string {
  133. char *str;
  134. size_t length;
  135. };
  136. #define STB_SPRINTF_DECORATE(name) stb_##name // define this before including if you want to change the names
  137. #include "vendor/stb_sprintf.h"
  138. #define strlit(lit) (string{(char *)(lit), sizeof(lit) - 1})
  139. #define PushString(arena, length) (string{ (char *)pushSize(arena, length), (length) })
  140. // C Strings
  141. const char *cstring(Arena *arena, list<char> buf);
  142. const char *cstring(Arena *arena, string str);
  143. size_t calcStringLen(const char *str);
  144. string strFromCString(Arena *arena, const char *str);
  145. bool strEql(string s1, string s2);
  146. bool stringContains(string str, char c);
  147. string strReverse(Arena *arena, string str);
  148. string strSlice(string str, size_t start, size_t stop = 0);
  149. string strSlice(char *data, size_t start, size_t stop = 0);
  150. list<string> strSplit(Arena *arena, string splitStr, string inputStr);
  151. string strPrintfv(Arena *arena, const char *fmt, va_list args);
  152. string strPrintf(Arena *arena, const char *fmt, ...);
  153. int8 parsePositiveInt(string str, size_t *lengthPointer);
  154. real32 parsePositiveReal32(Arena *arena, string str, size_t *lengthPointer);
  155. inline function bool isNumeric(char c);
  156. // ### File IO ###
  157. string readEntireFile(Arena *arena, string filename);
  158. bool writeEntireFile(Arena *arena, string filename, const byte *contents, size_t contentsLength);
  159. bool fileAppend(Arena *arena, string filename, const byte *contents, size_t contentsLength);
  160. // ### Cmdline ###
  161. list<string> getArgs(Arena *arena, int argc, char **argv);
  162. // ### Time ###
  163. typedef uint64 UnixTimestamp;
  164. typedef tm Timestamp;
  165. UnixTimestamp getSystemUnixTime();
  166. Timestamp timestampFromUnixTime(UnixTimestamp *unixTimestamp);
  167. string formatTimeHms(Arena *arena, UnixTimestamp time);
  168. string formatTimeHms(Arena *arena, Timestamp *time);
  169. string formatTimeYmd(Arena *arena, UnixTimestamp time);
  170. string formatTimeYmd(Arena *arena, Timestamp *time);
  171. // ### Linked Lists ###
  172. // TODO(dledda): implement basic linked lists (based on arenas?)
  173. // ### Logging ###
  174. enum LogTarget {
  175. LogTarget_stdout,
  176. LogTarget_stdin,
  177. LogTarget_stderr,
  178. LogTarget_count,
  179. };
  180. void log(list<int> l, LogTarget target = LogTarget_stdout);
  181. void log(list<string> l, LogTarget target = LogTarget_stdout);
  182. void log(const char *fmt, ...);
  183. void logError(const char *fmt, ...);
  184. // ### Loops ###
  185. #define EachIn(list, it) size_t it = 0; it < list.length; it++
  186. #define EachInReversed(list, it) size_t it = list.length - 1; it >= 0 && it < list.length; it--
  187. #define EachInArray(arr, it) size_t it = 0; it < ArrayCount(arr); ++it
  188. // ### Misc ###
  189. int intCompare(const void *a, const void *b);
  190. #endif