lib.h 86 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645
  1. /* vim: set filetype=c : */
  2. #ifndef LIB_H
  3. # define LIB_H
  4. # ifndef _STDINT_H
  5. # define LIB_H_STDINT
  6. # define intmax_t long int
  7. # endif /* _STDINT_H */
  8. # ifndef _UNISTD_H
  9. # define LIB_H_UNISTD
  10. # define R_OK 4
  11. # define W_OK 2
  12. # define X_OK 1
  13. # define F_OK 0
  14. # endif /* _UNISTD_H */
  15. # ifndef NULL
  16. # define LIB_H_NULL
  17. # define NULL ((void *) 0)
  18. # endif /* NULL */
  19. # ifndef _STDBOOL_H
  20. # define LIB_H_STDBOOL
  21. # define bool unsigned char
  22. # define true 1
  23. # define false 0
  24. # endif /* _STDBOOL_H */
  25. /* --------------------------- START GLOBAL DEF ---------------------------- */
  26. # define ALLOC_FUNC void *(*alloc)(u64)
  27. # define FREE_FUNC void (*free)(void *)
  28. # define MACRO_STR_CONCAT_X(lhs, rhs) lhs ## rhs
  29. # define MACRO_STR_CONCAT(lhs, rhs) MACRO_STR_CONCAT_X(lhs, rhs)
  30. # define MACRO_STR_VALUE(arg) #arg
  31. # define MACRO_STR_VALUE_X(arg) MACRO_STR_VALUE(arg)
  32. # define BOOL2CSTR(bool) ((bool) ? "True" : "False")
  33. # define UNUSED(arg) (void) arg
  34. enum err {
  35. ERR_OK = 0,
  36. ERR_GENERAL_ERROR,
  37. ERR_NOT_INT,
  38. ERR_TOO_BIG,
  39. ERR_NULL_ARG,
  40. ERR_INVALID_ARG,
  41. ERR_NOT_FOUND,
  42. ERR_INDEX_TOO_LARGE,
  43. ERR_FAILED_OPEN,
  44. ERR_FAILED_CLOSE,
  45. ERR_FAILED_READ,
  46. ERR_FAILED_WRITE,
  47. ERR_FAILED_FORK,
  48. ERR_FAILED_WAITPID,
  49. ERR_WROTE_WRONG_AMOUNT,
  50. ERR_FAILED_ALLOC,
  51. ERR_FAILED_REALLOC,
  52. ERR_MKDIR_FAILED,
  53. ERR_FAILED_HASHING,
  54. ERR_STR_EMPTY,
  55. ERR_PATH_EMPTY,
  56. ERR_PATH_INVALID,
  57. ERR_PATH_FILE_EMPTY,
  58. ERR_PATH_FILE_FAILED_SEEK,
  59. ERR_CMD_NON_ZERO_EXIT_CODE,
  60. ERR_SGFX_POS_OUTSIDE_CANVAS
  61. };
  62. const char *err_to_name[] = {
  63. "ERR_OK",
  64. "ERR_GENERAL_ERROR",
  65. "ERR_NOT_INT",
  66. "ERR_TOO_BIG",
  67. "ERR_NULL_ARG",
  68. "ERR_INVALID_ARG",
  69. "ERR_NOT_FOUND",
  70. "ERR_INDEX_TOO_LARGE",
  71. "ERR_FAILED_OPEN",
  72. "ERR_FAILED_CLOSE",
  73. "ERR_FAILED_READ",
  74. "ERR_FAILED_WRITE",
  75. "ERR_FAILED_FORK",
  76. "ERR_FAILED_WAITPID",
  77. "ERR_WROTE_WRONG_AMOUNT",
  78. "ERR_FAILED_ALLOC",
  79. "ERR_FAILED_REALLOC",
  80. "ERR_MKDIR_FAILED",
  81. "ERR_FAILED_HASHING",
  82. "ERR_STR_EMPTY",
  83. "ERR_PATH_EMPTY",
  84. "ERR_PATH_INVALID",
  85. "ERR_PATH_FILE_EMPTY",
  86. "ERR_PATH_FILE_FAILED_SEEK",
  87. "ERR_CMD_NON_ZERO_EXIT_CODE",
  88. "ERR_SGFX_POS_OUTSIDE_CANVAS",
  89. };
  90. /* ---------------------------- END GLOBAL DEF ----------------------------- */
  91. /* ----------------------------- START INT DEF ----------------------------- */
  92. typedef long int i64;
  93. typedef unsigned long int u64;
  94. typedef int i32;
  95. typedef unsigned int u32;
  96. typedef short int i16;
  97. typedef unsigned short int u16;
  98. typedef char i8;
  99. typedef unsigned char u8;
  100. /* ------------------------------ END INT DEF ------------------------------ */
  101. void *malloc(u64 size);
  102. void *realloc(void *ptr, u64 new_size);
  103. void free(void *ptr);
  104. void *memcpy(void *dest, const void *src, u64 n);
  105. void *memset(void *s, int c, u64 n);
  106. char *getenv(const char *name);
  107. void abort(void);
  108. void exit(int exit_code);
  109. int execve(const char *path, char *const argv[],
  110. char *const envp[]);
  111. int fork(void);
  112. # ifndef WIFEXITED
  113. # error "Must import <sys/wait.h> before lib.h!"
  114. # endif
  115. /* ----------------------------- START LIB DEF ----------------------------- */
  116. # define TODO(msg) \
  117. do { \
  118. fprintf(stderr, "%s:%d "msg"\n", __FILE__, __LINE__); \
  119. abort(); \
  120. } while(0);
  121. # define LIB_COALESCE2(arg1, arg2) ((arg1 != Null) ? arg1 : arg2)
  122. # define LIB_SET_IF_NULL(var, val) \
  123. if ( (var) == NULL ) { \
  124. (var) = (val); \
  125. }
  126. # define LIB_SET_IF_NOT_NULL(var, err) \
  127. if ( var != NULL ) { \
  128. *var = err; \
  129. }
  130. # define LIB_ARG_IF_NOT_NULL_MUST_BE(arg, val, ret_val) \
  131. if ( arg != NULL ) { \
  132. if ( *arg != val ) { \
  133. return ret_val; \
  134. } \
  135. }
  136. # define LIB_ARG_IF_NOT_NULL_MUST_BE_RET_IT(arg, val) \
  137. if ( arg != NULL ) { \
  138. if ( *arg != val ) { \
  139. return *arg; \
  140. } \
  141. }
  142. # define LIB_ARG_MUST_NOT_BE_NULL_RET_ERR(arg) \
  143. if ( (arg) == NULL ) { \
  144. return ERR_NULL_ARG; \
  145. }
  146. # define LIB_ARG_MUST_NOT_BE_NULL(arg, err_var, ret_val) \
  147. if ( (arg) == NULL ) { \
  148. LIB_SET_IF_NOT_NULL(err_var, ERR_NULL_ARG); \
  149. return ret_val; \
  150. }
  151. # define LIB_ARG_MUST_NOT_BE_NULL_SET_RET_ERR(arg, err_var) \
  152. if ( (arg) == NULL ) { \
  153. LIB_SET_IF_NOT_NULL(err_var, ERR_NULL_ARG); \
  154. return ERR_NULL_ARG; \
  155. }
  156. # define LIB_STR_MUST_NOT_BE_EMPTY(arg, err_var, ret_val) \
  157. if ( (arg).data == NULL || (arg).size == 0 ) { \
  158. LIB_SET_IF_NOT_NULL(err_var, ERR_STR_EMPTY); \
  159. return ret_val; \
  160. }
  161. # define _r_ __restrict__
  162. # define SIZEOF_MEMBER(Struct, Member) sizeof(((Struct *)0)->Member)
  163. # define CAST(Type, Var) ((Type) (Var))
  164. # define LIB_FREE lib_free
  165. void lib_free(const void *ptr);
  166. # if defined(IMP) || defined(IMP_LIB)
  167. void
  168. lib_free(const void *ptr)
  169. {
  170. if ( ptr == NULL ) return;
  171. free((void *)ptr);
  172. }
  173. # endif /* defined(IMP) || defined(IMP_LIB) */
  174. /* ------------------------------ END LIB DEF ------------------------------ */
  175. /* ----------------------------- START VEC DEF ----------------------------- */
  176. # if defined(WANT_VEC2) || defined(WANT_ALL)
  177. # define _VEC2_STRUCT_DEF(type) \
  178. struct MACRO_STR_CONCAT(type, vec2) { \
  179. type x, y; \
  180. }; \
  181. struct MACRO_STR_CONCAT(type, vec2s) { \
  182. type w, h; \
  183. }
  184. _VEC2_STRUCT_DEF(i64);
  185. _VEC2_STRUCT_DEF(u64);
  186. _VEC2_STRUCT_DEF(i32);
  187. _VEC2_STRUCT_DEF(u32);
  188. _VEC2_STRUCT_DEF(i16);
  189. _VEC2_STRUCT_DEF(u16);
  190. _VEC2_STRUCT_DEF(i8);
  191. _VEC2_STRUCT_DEF(u8);
  192. # undef _VEC2_STRUCT_DEF
  193. # endif /* defined(WANT_VEC2) || defined(WANT_ALL) */
  194. /* ------------------------------ END VEC DEF ------------------------------ */
  195. /* ---------------------------- START CSTR DEF ----------------------------- */
  196. # if defined(WANT_CSTR) || defined(WANT_ALL)
  197. u64 cstr_len_max(const char *cstr, u64 max, bool *out_hit_max,
  198. enum err *out_err);
  199. # endif /* defined(WANT_CSTR) || defined(WANT_ALL) */
  200. /* ----------------------------- END CSTR DEF ------------------------------ */
  201. /* ---------------------------- START STR DEF ------------------------------ */
  202. # if defined(WANT_STR) || defined(WANT_ALL)
  203. # ifndef STR_SIZE_LIMIT
  204. # define STR_SIZE_LIMIT 1028
  205. # endif /* STR_SIZE_LIMIT */
  206. # define STR_DESTROY(Str) \
  207. if ( (Str).should_be_freed == true ) LIB_FREE((Str).data)
  208. # define DA2STR(Da, Str) \
  209. (Str).data = (Da).data; \
  210. (Str).size = (Da).size; \
  211. (Str).should_be_freed = true;
  212. struct str {
  213. const char *data;
  214. u64 size;
  215. bool should_be_freed;
  216. };
  217. const struct str STR_EMPTY = {"", 0, false};
  218. struct str_tokenizer {
  219. struct str str;
  220. u64 cur;
  221. char c;
  222. bool (*f)(char c);
  223. };
  224. struct str str_from_cstr(const char *cstr, u64 cstr_size,
  225. enum err *out_err);
  226. struct str str_from_cstr_ns(const char *cstr, enum err *out_err);
  227. struct str str_from_i64(i64 num, enum err *out_err);
  228. struct str str_from_i64_temp(i64 num);
  229. struct str str_dup(struct str str);
  230. struct str str_replace_escape_chars(const struct str *str, enum err *out_err);
  231. intmax_t str_to_int(struct str str, enum err *err);
  232. struct str str_rstrip(struct str str);
  233. struct str str_lstrip(struct str str);
  234. struct str str_strip(struct str str);
  235. u64 str_lindex(struct str str, char c);
  236. u64 str_rindex(struct str str, char c);
  237. struct str_tokenizer str_tokenize(struct str str, char c);
  238. struct str_tokenizer str_tokenize_func(struct str str, bool (*f)(char c));
  239. struct str str_tokenizer_next(struct str_tokenizer *st);
  240. struct str str_slice(struct str str, u64 from, u64 to);
  241. bool str_eq_cstr(struct str str, const char *cstr, u64 cstr_size);
  242. bool str_eq_str(struct str str1, struct str str2);
  243. bool str_startswith_cstr(struct str str, const char *cstr, u64 cstr_size);
  244. bool str_is_int(struct str str);
  245. struct str_builder {
  246. char *data;
  247. u64 size;
  248. u64 cap;
  249. };
  250. struct str str_builder_to_str(const struct str_builder *str_bldr);
  251. # if defined(IMP) || defined(IMP_STR)
  252. struct str
  253. str_replace_escape_chars(const struct str *str, enum err *out_err)
  254. {
  255. struct str empty = {0};
  256. struct str_builder ret = {0};
  257. u64 i = 0;
  258. LIB_ARG_IF_NOT_NULL_MUST_BE(out_err, ERR_OK, empty);
  259. LIB_ARG_MUST_NOT_BE_NULL(str, out_err, empty);
  260. LIB_STR_MUST_NOT_BE_EMPTY(*str, out_err, empty);
  261. ret.data = malloc(str->size);
  262. ret.size = 0;
  263. if ( ret.data == NULL ) {
  264. LIB_SET_IF_NOT_NULL(out_err, ERR_FAILED_ALLOC);
  265. return empty;
  266. }
  267. memset((void*)ret.data, 0, str->size);
  268. for ( i = 0; i < str->size; ++i ) {
  269. if ( str->data[i] == '\\' ) {
  270. if ( (i+1) < str->size ) {
  271. ++i;
  272. switch ( str->data[i] ) {
  273. case 'n': ret.data[ret.size++] = '\n'; break;
  274. case 'r': ret.data[ret.size++] = '\r'; break;
  275. case 't': ret.data[ret.size++] = '\t'; break;
  276. case 'e': ret.data[ret.size++] = '\033'; break;
  277. default: ret.data[ret.size++] = '\\';
  278. ret.data[ret.size++] = str->data[i];
  279. break;
  280. }
  281. continue;
  282. }
  283. }
  284. ret.data[ret.size++] = str->data[i];
  285. }
  286. return str_builder_to_str(&ret);
  287. }
  288. # endif /* defined(IMP) || defined(IMP_STR) */
  289. # endif /* defined(WANT_STR) || defined(WANT_ALL) */
  290. /* ----------------------------- END STR DEF ------------------------------- */
  291. /* -------------------------- START DYN ARR DEF ---------------------------- */
  292. # if defined(WANT_DYN_ARR) || defined(WANT_ALL)
  293. struct dyn_arr {
  294. void *data;
  295. u64 size;
  296. u64 cap;
  297. u16 elem_size;
  298. };
  299. struct dyn_arr dyn_arr_create(u16 elem_size, enum err *out_err);
  300. enum err dyn_arr_append(struct dyn_arr *da, void *elem, enum err *out_err);
  301. enum err dyn_arr_prepend(struct dyn_arr *da, void *elem, enum err *out_err);
  302. enum err dyn_arr_insert(struct dyn_arr *da, void *elem, u64 index,
  303. enum err *out_err);
  304. void *dyn_arr_pop(struct dyn_arr *da, u64 index, enum err *out_err);
  305. void *dyn_arr_pop_last(struct dyn_arr *da, enum err *out_err);
  306. enum err dyn_arr_destroy(struct dyn_arr *da, enum err *out_err);
  307. # if defined(IMP) || defined(IMP_DYN_ARR)
  308. struct dyn_arr
  309. dyn_arr_create(u16 elem_size, enum err *out_err)
  310. {
  311. struct dyn_arr empty = {0};
  312. struct dyn_arr da = {0};
  313. LIB_ARG_IF_NOT_NULL_MUST_BE(out_err, ERR_OK, empty);
  314. da.size = 0;
  315. da.cap = 64;
  316. da.elem_size = elem_size;
  317. da.data = malloc(da.elem_size * da.cap);
  318. if ( da.data == NULL ) {
  319. LIB_SET_IF_NOT_NULL(out_err, ERR_FAILED_ALLOC);
  320. return empty;
  321. }
  322. memset(da.data, 0, elem_size * da.cap);
  323. LIB_SET_IF_NOT_NULL(out_err, ERR_OK);
  324. return da;
  325. }
  326. enum err
  327. dyn_arr_insert(struct dyn_arr *da, void *elem, u64 index, enum err *out_err)
  328. {
  329. u64 new_size = 0;
  330. u64 i = 0;
  331. u8 *data = NULL;
  332. LIB_ARG_IF_NOT_NULL_MUST_BE_RET_IT(out_err, ERR_OK);
  333. LIB_ARG_MUST_NOT_BE_NULL_SET_RET_ERR(da, out_err);
  334. LIB_ARG_MUST_NOT_BE_NULL_SET_RET_ERR(da->data, out_err);
  335. LIB_ARG_MUST_NOT_BE_NULL_SET_RET_ERR(elem, out_err);
  336. new_size = da->size + 1;
  337. if ( index >= new_size ) {
  338. LIB_SET_IF_NOT_NULL(out_err, ERR_INDEX_TOO_LARGE);
  339. return ERR_INDEX_TOO_LARGE;
  340. }
  341. if ( new_size >= da->cap ) {
  342. da->cap *= 2;
  343. da->data = realloc(da->data, da->cap);
  344. if ( da->data == NULL ) {
  345. LIB_SET_IF_NOT_NULL(out_err, ERR_FAILED_ALLOC);
  346. return ERR_FAILED_ALLOC;
  347. }
  348. }
  349. data = (u8*) da->data;
  350. if ( da->size > 0 ) {
  351. for ( i = da->size-1; i > index; i-- ) {
  352. memcpy((data + i), (data + i - 1), da->elem_size);
  353. }
  354. }
  355. memcpy((data + index), elem, da->elem_size);
  356. ++da->size;
  357. LIB_SET_IF_NOT_NULL(out_err, ERR_OK);
  358. return ERR_OK;
  359. }
  360. enum err
  361. dyn_arr_append(struct dyn_arr *da, void *elem, enum err *out_err)
  362. {
  363. LIB_ARG_IF_NOT_NULL_MUST_BE_RET_IT(out_err, ERR_OK);
  364. LIB_ARG_MUST_NOT_BE_NULL_SET_RET_ERR(da, out_err);
  365. LIB_ARG_MUST_NOT_BE_NULL_SET_RET_ERR(da->data, out_err);
  366. LIB_ARG_MUST_NOT_BE_NULL_SET_RET_ERR(elem, out_err);
  367. return dyn_arr_insert(da, elem, da->size, out_err);
  368. }
  369. enum err
  370. dyn_arr_prepend(struct dyn_arr *da, void *elem, enum err *out_err)
  371. {
  372. LIB_ARG_IF_NOT_NULL_MUST_BE_RET_IT(out_err, ERR_OK);
  373. LIB_ARG_MUST_NOT_BE_NULL_SET_RET_ERR(da, out_err);
  374. LIB_ARG_MUST_NOT_BE_NULL_SET_RET_ERR(da->data, out_err);
  375. LIB_ARG_MUST_NOT_BE_NULL_SET_RET_ERR(elem, out_err);
  376. return dyn_arr_insert(da, elem, 0, out_err);
  377. }
  378. void *
  379. dyn_arr_pop(struct dyn_arr *da, u64 index, enum err *out_err)
  380. {
  381. static u8 temp_mem[256] = {0};
  382. u8 *data = NULL;
  383. u64 i = 0;
  384. LIB_ARG_IF_NOT_NULL_MUST_BE(out_err, ERR_OK, NULL);
  385. LIB_ARG_MUST_NOT_BE_NULL(da, out_err, NULL);
  386. LIB_ARG_MUST_NOT_BE_NULL(da->data, out_err, NULL);
  387. if ( index >= da->size ) {
  388. LIB_SET_IF_NOT_NULL(out_err, ERR_INDEX_TOO_LARGE);
  389. return NULL;
  390. }
  391. data = (u8*) da->data;
  392. memcpy(temp_mem, (data + index), da->elem_size);
  393. for ( i = index; i < da->size-1; ++i ) {
  394. memcpy((data + i), (data + i + 1), da->elem_size);
  395. }
  396. --da->size;
  397. LIB_SET_IF_NOT_NULL(out_err, ERR_OK);
  398. return temp_mem;
  399. }
  400. void *
  401. dyn_arr_pop_last(struct dyn_arr *da, enum err *out_err)
  402. {
  403. LIB_ARG_IF_NOT_NULL_MUST_BE(out_err, ERR_OK, NULL);
  404. LIB_ARG_MUST_NOT_BE_NULL(da, out_err, NULL);
  405. LIB_ARG_MUST_NOT_BE_NULL(da->data, out_err, NULL);
  406. return dyn_arr_pop(da, da->size-1, out_err);
  407. }
  408. enum err
  409. dyn_arr_destroy(struct dyn_arr *da, enum err *out_err)
  410. {
  411. LIB_ARG_IF_NOT_NULL_MUST_BE_RET_IT(out_err, ERR_OK);
  412. LIB_ARG_MUST_NOT_BE_NULL_SET_RET_ERR(da, out_err);
  413. LIB_ARG_MUST_NOT_BE_NULL_SET_RET_ERR(da->data, out_err);
  414. free(da->data);
  415. LIB_SET_IF_NOT_NULL(out_err, ERR_OK);
  416. return ERR_OK;
  417. }
  418. # endif /* defined(IMP) || defined(IMP_DYN_ARR) */
  419. # endif /* defined(WANT_DYN_ARR) || defined(WANT_ALL) */
  420. /* --------------------------- END DYN ARR DEF ----------------------------- */
  421. /* ---------------------------- START DA DEF ------------------------------- */
  422. # define DA_FOREACH(Da, Var) \
  423. for ( typeof((Da).data) (Var) = (Da).data; \
  424. (Var) < ((Da).data + (Da).size); \
  425. ++(Var) )
  426. # define DA_FOREACH_INDEX(Da, VarI) \
  427. for ( typeof((Da).size) (VarI) = 0; \
  428. (VarI) < (Da).size; \
  429. ++(VarI) )
  430. # define DA_APPEND(da, val, err_var) \
  431. do { \
  432. if ( err_var != NULL ) { \
  433. if ( *err_var != ERR_OK ) { \
  434. break; \
  435. } \
  436. } \
  437. if ( (da).size + 1 >= (da).cap ) { \
  438. (da).cap *= 2; \
  439. (da).data = realloc((da).data, (da).cap); \
  440. if ( (da).data == NULL ) { \
  441. LIB_SET_IF_NOT_NULL((err_var), ERR_FAILED_REALLOC); \
  442. break; \
  443. } \
  444. } \
  445. if ( (da).data == NULL ) { \
  446. if ( (da).cap == 0 ) { \
  447. (da).cap = 32; \
  448. (da).size = 0; \
  449. } \
  450. (da).data = malloc(sizeof(*(da).data) * (da).cap); \
  451. if ( (da).data == NULL ) { \
  452. LIB_SET_IF_NOT_NULL((err_var), ERR_FAILED_ALLOC); \
  453. break; \
  454. } \
  455. memset((da).data, 0, sizeof(*(da).data) * (da).cap); \
  456. } \
  457. (da).data[(da).size++] = (val); \
  458. LIB_SET_IF_NOT_NULL((err_var), ERR_OK); \
  459. } while(0)
  460. # define DA_APPEND_DATA(Da, Val, ItemNum, ErrVar) \
  461. do { \
  462. if ( (ErrVar) != NULL ) { \
  463. if ( *(ErrVar) != ERR_OK ) { \
  464. break; \
  465. } \
  466. } \
  467. if ( (Da).size + (ItemNum) >= (Da).cap ) { \
  468. (Da).cap += (ItemNum); \
  469. (Da).cap *= 2; \
  470. (Da).data = realloc((Da).data, (Da).cap); \
  471. if ( (Da).data == NULL ) { \
  472. LIB_SET_IF_NOT_NULL((ErrVar), ERR_FAILED_REALLOC); \
  473. break; \
  474. } \
  475. } \
  476. if ( (Da).data == NULL ) { \
  477. if ( (Da).cap == 0 ) { \
  478. (Da).cap = (ItemNum) * 2; \
  479. (Da).size = 0; \
  480. } \
  481. (Da).data = malloc(sizeof(*(Da).data) * (Da).cap); \
  482. if ( (Da).data == NULL ) { \
  483. LIB_SET_IF_NOT_NULL((ErrVar), ERR_FAILED_ALLOC); \
  484. break; \
  485. } \
  486. } \
  487. memcpy((Da).data, (Val), sizeof(*(Da).data) * (ItemNum)); \
  488. (Da).size += ItemNum; \
  489. LIB_SET_IF_NOT_NULL((ErrVar), ERR_OK); \
  490. } while(0)
  491. # define DAV_APPEND(Da, Val, ValSize, ErrVar) \
  492. do { \
  493. if ( ErrVar != NULL ) { \
  494. if ( *ErrVar != ERR_OK ) { \
  495. break; \
  496. } \
  497. } \
  498. /* printf("ValSize -> %5ld\tused_bytes -> %5ld\tcap_bytes -> %5ld\n", (ValSize), (Da).used_bytes, (Da).cap_bytes); */ \
  499. if ( (Da).used_bytes + (ValSize) >= (Da).cap_bytes ) { \
  500. (Da).cap_bytes *= 2; \
  501. (Da).data = realloc((Da).data, (Da).cap_bytes); \
  502. if ( (Da).data == NULL ) { \
  503. LIB_SET_IF_NOT_NULL((ErrVar), ERR_FAILED_REALLOC); \
  504. break; \
  505. } \
  506. } \
  507. if ( (Da).data == NULL ) { \
  508. if ( (Da).cap_bytes == 0 ) { \
  509. (Da).cap_bytes = 32; \
  510. (Da).size = 0; \
  511. (Da).used_bytes = 0; \
  512. } \
  513. (Da).data = malloc(sizeof(u64) * (Da).cap_bytes); \
  514. if ( (Da).data == NULL ) { \
  515. LIB_SET_IF_NOT_NULL((ErrVar), ERR_FAILED_ALLOC); \
  516. break; \
  517. } \
  518. } \
  519. memcpy(CAST(u8*, (Da).data) + (Da).used_bytes, (Val), (ValSize)); \
  520. (Da).used_bytes += (ValSize); \
  521. ++(Da).size; \
  522. LIB_SET_IF_NOT_NULL((ErrVar), ERR_OK); \
  523. } while(0)
  524. /* ----------------------------- END DA DEF -------------------------------- */
  525. /* ---------------------------- START MAP DEF ------------------------------ */
  526. # if defined(WANT_MAP) || defined(WANT_ALL)
  527. # define MAP_FOR_EACH(Map, VIndex, VKey) \
  528. for ( (VIndex = (Map)->indexs.data, VKey = (Map)->keys.data); \
  529. VIndex < ((Map)->indexs.data + (Map)->indexs.size); \
  530. (++VIndex, VKey = CAST(struct key_bytes *, CAST(u8*, VKey->key) + VKey->size)) )
  531. # define MAP_FOR_EACH_INDEXS(Map, Var) \
  532. for ( Var = (Map)->indexs.data; \
  533. Var < ((Map)->indexs.data + (Map)->indexs.size); \
  534. ++Var )
  535. # define MAP_GET_INDEX(Map, Index) \
  536. ((struct map_item *)(((u8*)(Map)->data) + ((Map)->_item_size * (Index))))
  537. struct key_bytes {
  538. u64 size;
  539. u8 key[1];
  540. };
  541. struct map_item {
  542. u64 key[4];
  543. u8 item[1];
  544. };
  545. struct map {
  546. struct map_item *data;
  547. u64 size;
  548. struct {
  549. u64 *data;
  550. u64 size;
  551. u64 cap;
  552. } indexs;
  553. struct {
  554. struct key_bytes *data;
  555. u64 size;
  556. u64 used_bytes;
  557. u64 cap_bytes;
  558. } keys;
  559. u64 _cap;
  560. u64 _size_bytes;
  561. u64 _item_size;
  562. u64 _elem_size;
  563. u64 *(*hash)(void *key, u64 key_size);
  564. };
  565. struct map map_create(u64 elem_size, u64 cap, enum err *_r_ out_err);
  566. enum err map_inc_cap(struct map *_r_ m, enum err *_r_ out_err);
  567. enum err map_add_hashed_key(struct map *_r_ m, u64 *_r_ key, void *_r_ elem,
  568. enum err *_r_ out_err);
  569. enum err map_add(struct map *_r_ m, void *_r_ key, u64 key_size, void *_r_ elem,
  570. enum err *_r_ out_err);
  571. void *map_get(struct map *_r_ m, void *_r_ key, u64 key_size, enum err *_r_ out_err);
  572. enum err map_set_hashed_key(struct map *_r_ m, u64 *_r_ key, void *_r_ elem,
  573. enum err *_r_ out_err);
  574. enum err map_set(struct map *_r_ m, void *_r_ key, u64 key_size,
  575. void *_r_ elem, enum err *_r_ out_err);
  576. void *map_pop(struct map *_r_ m, void *_r_ key, u64 key_size, enum err *_r_ out_err);
  577. enum err map_destroy(struct map *_r_ m, enum err *_r_ out_err);
  578. u64 *map_default_hasher(void *key, u64 key_size);
  579. # if defined(IMP) || defined(IMP_MAP)
  580. struct map
  581. map_create(u64 elem_size, u64 cap, enum err *out_err)
  582. {
  583. struct map empty = {0};
  584. struct map m = {0};
  585. LIB_ARG_IF_NOT_NULL_MUST_BE(out_err, ERR_OK, empty);
  586. m._cap = cap;
  587. m._elem_size = elem_size;
  588. m._item_size = SIZEOF_MEMBER(struct map_item, key) + m._elem_size + 1;
  589. m._size_bytes = m._item_size * m._cap;
  590. m.data = malloc(m._size_bytes);
  591. if ( m.data == NULL ) {
  592. LIB_SET_IF_NOT_NULL(out_err, ERR_FAILED_ALLOC);
  593. goto err_exit;
  594. }
  595. memset(m.data, 0, m._size_bytes);
  596. m.indexs.cap = m._cap;
  597. m.indexs.data = malloc(sizeof(*m.indexs.data) * m.indexs.cap);
  598. if ( m.indexs.data == NULL ) {
  599. LIB_SET_IF_NOT_NULL(out_err, ERR_FAILED_ALLOC);
  600. goto err_exit;
  601. }
  602. memset(m.indexs.data, 0, sizeof(*m.indexs.data) * m.indexs.cap);
  603. m.keys.cap_bytes = m._cap;
  604. m.keys.data = malloc(sizeof(u64) * m.keys.cap_bytes);
  605. if ( m.keys.data == NULL ) {
  606. LIB_SET_IF_NOT_NULL(out_err, ERR_FAILED_ALLOC);
  607. goto err_exit;
  608. }
  609. memset(m.keys.data, 0, m.keys.cap_bytes);
  610. m.hash = map_default_hasher;
  611. LIB_SET_IF_NOT_NULL(out_err, ERR_OK);
  612. return m;
  613. err_exit:
  614. if ( m.data != NULL ) free(m.data);
  615. if ( m.indexs.data != NULL ) free(m.indexs.data);
  616. if ( m.keys.data != NULL ) free(m.keys.data);
  617. return empty;
  618. }
  619. enum err
  620. map_inc_cap(struct map *_r_ m, enum err *_r_ out_err)
  621. {
  622. enum err err = ERR_OK;
  623. enum err *perr = &err;
  624. struct map old = {0};
  625. struct map nm = {0};
  626. u64 *index = 0;
  627. LIB_ARG_IF_NOT_NULL_MUST_BE_RET_IT(out_err, ERR_OK);
  628. LIB_ARG_MUST_NOT_BE_NULL_SET_RET_ERR(m , out_err);
  629. LIB_ARG_MUST_NOT_BE_NULL_SET_RET_ERR(m->data, out_err);
  630. if ( out_err != NULL ) {
  631. perr = out_err;
  632. }
  633. nm = map_create(m->_elem_size, (m->_cap * 2), perr);
  634. if ( *perr != ERR_OK ) {
  635. goto err_exit;
  636. }
  637. MAP_FOR_EACH_INDEXS(m, index) {
  638. struct map_item *mi = MAP_GET_INDEX(m, (*index));
  639. map_add_hashed_key(&nm, mi->key, mi->item, perr);
  640. if ( *perr != ERR_OK ) {
  641. goto err_exit;
  642. }
  643. }
  644. old = *m;
  645. m->data = nm.data;
  646. m->size = nm.size;
  647. m->indexs = nm.indexs;
  648. m->keys = nm.keys;
  649. m->_cap = nm._cap;
  650. m->_size_bytes = nm._size_bytes;
  651. m->_item_size = nm._item_size;
  652. m->_elem_size = nm._elem_size;
  653. m->hash = nm.hash;
  654. map_destroy(&old, NULL);
  655. LIB_SET_IF_NOT_NULL(out_err, ERR_OK);
  656. return ERR_OK;
  657. err_exit:
  658. map_destroy(&nm, NULL);
  659. return *perr;
  660. }
  661. enum err
  662. map_add_hashed_key(struct map *_r_ m, u64 *_r_ key, void *_r_ elem,
  663. enum err *_r_ out_err)
  664. {
  665. enum err err = ERR_OK;
  666. enum err *perr = &err;
  667. u64 i = 0;
  668. struct map_item *it = NULL;
  669. LIB_ARG_IF_NOT_NULL_MUST_BE_RET_IT(out_err, ERR_OK);
  670. LIB_ARG_MUST_NOT_BE_NULL_SET_RET_ERR(m, out_err);
  671. LIB_ARG_MUST_NOT_BE_NULL_SET_RET_ERR(m->data, out_err);
  672. LIB_ARG_MUST_NOT_BE_NULL_SET_RET_ERR(key, out_err);
  673. LIB_ARG_MUST_NOT_BE_NULL_SET_RET_ERR(elem, out_err);
  674. if ( out_err != NULL ) {
  675. perr = out_err;
  676. }
  677. i = (key[0] + key[1] + key[2] + key[3]) % m->_cap;
  678. do {
  679. if ( i >= m->_cap ) {
  680. map_inc_cap(m, perr);
  681. if ( *perr != ERR_OK ) {
  682. return *perr;
  683. }
  684. }
  685. it = MAP_GET_INDEX(m, i++);
  686. } while (it->key[0] != 0 || it->key[1] != 0
  687. || it->key[2] != 0 || it->key[3] != 0);
  688. /*
  689. printf("cap=%-5ld\telem_size=%-5ld\tsize_bytes=%-5ld\n",
  690. m->_cap, m->_elem_size, m->_size_bytes);
  691. */
  692. memcpy(it->key, key, sizeof(u64) * 4);
  693. memcpy(it->item, elem, m->_elem_size);
  694. DA_APPEND(m->indexs, i-1, perr);
  695. if ( *perr != ERR_OK ) {
  696. memset(it->key, 0, sizeof(u64) * 4);
  697. memset(it->item, 0, m->_elem_size);
  698. return *perr;
  699. }
  700. *perr = ERR_OK;
  701. return ERR_OK;
  702. }
  703. enum err
  704. map_add(struct map *m, void *key, u64 key_size, void *elem, enum err *out_err)
  705. {
  706. enum err err = ERR_OK;
  707. enum err *perr = &err;
  708. struct key_bytes *sb = NULL;
  709. u64 *hash = NULL;
  710. LIB_ARG_IF_NOT_NULL_MUST_BE_RET_IT(out_err, ERR_OK);
  711. LIB_ARG_MUST_NOT_BE_NULL_SET_RET_ERR(m, out_err);
  712. LIB_ARG_MUST_NOT_BE_NULL_SET_RET_ERR(m->data, out_err);
  713. LIB_ARG_MUST_NOT_BE_NULL_SET_RET_ERR(key, out_err);
  714. LIB_ARG_MUST_NOT_BE_NULL_SET_RET_ERR(elem, out_err);
  715. if ( out_err != NULL ) {
  716. perr = out_err;
  717. }
  718. hash = m->hash(key, key_size);
  719. if ( hash == NULL ) {
  720. *perr = ERR_FAILED_HASHING;
  721. return *perr;
  722. }
  723. map_add_hashed_key(m, hash, elem, perr);
  724. free(hash);
  725. if ( *perr != ERR_OK ) {
  726. return *perr;
  727. }
  728. sb = malloc(SIZEOF_MEMBER(struct key_bytes, size) + key_size);
  729. if ( sb == NULL ) {
  730. *perr = ERR_FAILED_ALLOC;
  731. return *perr;
  732. }
  733. memset(sb, 0, SIZEOF_MEMBER(struct key_bytes, size) + key_size);
  734. sb->size = key_size;
  735. memcpy(sb->key, key, key_size);
  736. DAV_APPEND(
  737. m->keys, sb,
  738. SIZEOF_MEMBER(struct key_bytes, size) + key_size,
  739. perr
  740. );
  741. /*
  742. do {
  743. if (perr != ((void * ) 0)) {
  744. if ( * perr != ERR_OK) {
  745. break;
  746. }
  747. }
  748. if ((m -> keys).used_bytes + (sizeof(((struct key_bytes * ) 0) -> size) + key_size) >= (m -> keys).cap_bytes) {
  749. (m -> keys).cap_bytes *= 2;
  750. (m -> keys).data = realloc((m -> keys).data, (m -> keys).cap_bytes);
  751. if ((m -> keys).data == ((void * ) 0)) {
  752. if ((perr) != ((void * ) 0)) {
  753. *(perr) = ERR_FAILED_REALLOC;
  754. };
  755. break;
  756. }
  757. }
  758. if ((m -> keys).data == ((void * ) 0)) {
  759. if ((m -> keys).cap_bytes == 0) {
  760. (m -> keys).cap_bytes = 32;
  761. (m -> keys).size = 0;
  762. (m -> keys).used_bytes = 0;
  763. }(m -> keys).data = malloc(sizeof(u64) * (m -> keys).cap_bytes);
  764. if ((m -> keys).data == ((void * ) 0)) {
  765. if ((perr) != ((void * ) 0)) {
  766. *(perr) = ERR_FAILED_ALLOC;
  767. };
  768. break;
  769. }
  770. }
  771. memcpy(((u8 * )((m -> keys).data)) + (m -> keys).used_bytes, (sb), (sizeof(((struct key_bytes * ) 0) -> size) + key_size));
  772. (m -> keys).used_bytes += (sizeof(((struct key_bytes * ) 0) -> size) + key_size);
  773. ++(m -> keys).size;
  774. if ((perr) != ((void * ) 0)) {
  775. *(perr) = ERR_OK;
  776. };
  777. } while (0);
  778. */
  779. free(sb);
  780. if ( *perr != ERR_OK ) {
  781. return *perr;
  782. }
  783. *perr = ERR_OK;
  784. return ERR_OK;
  785. }
  786. void *
  787. map_get(struct map *m, void *key, u64 key_size, enum err *out_err)
  788. {
  789. u64 i = 0;
  790. struct map_item *it = NULL;
  791. u64 *hash = NULL;
  792. LIB_ARG_IF_NOT_NULL_MUST_BE(out_err, ERR_OK, NULL);
  793. LIB_ARG_MUST_NOT_BE_NULL(m , out_err, NULL);
  794. LIB_ARG_MUST_NOT_BE_NULL(m->data, out_err, NULL);
  795. LIB_ARG_MUST_NOT_BE_NULL(key , out_err, NULL);
  796. hash = m->hash(key, key_size);
  797. i = (hash[0] + hash[1] + hash[2] + hash[3]) % m->_cap;
  798. do {
  799. if ( i >= m->_cap ) {
  800. LIB_SET_IF_NOT_NULL(out_err, ERR_NOT_FOUND);
  801. free(hash);
  802. return NULL;
  803. }
  804. it = MAP_GET_INDEX(m, i++);
  805. } while (it->key[0] != hash[0] || it->key[1] != hash[1]
  806. || it->key[2] != hash[2] || it->key[3] != hash[3]);
  807. free(hash);
  808. LIB_SET_IF_NOT_NULL(out_err, ERR_OK);
  809. return it->item;
  810. }
  811. enum err
  812. map_set_hashed_key(struct map *_r_ m, u64 *_r_ key, void *_r_ elem,
  813. enum err *_r_ out_err)
  814. {
  815. enum err err = ERR_OK;
  816. enum err *perr = &err;
  817. u64 i = 0;
  818. struct map_item *it = NULL;
  819. LIB_ARG_IF_NOT_NULL_MUST_BE_RET_IT(out_err, ERR_OK);
  820. LIB_ARG_MUST_NOT_BE_NULL_SET_RET_ERR(m, out_err);
  821. LIB_ARG_MUST_NOT_BE_NULL_SET_RET_ERR(m->data, out_err);
  822. LIB_ARG_MUST_NOT_BE_NULL_SET_RET_ERR(key, out_err);
  823. LIB_ARG_MUST_NOT_BE_NULL_SET_RET_ERR(elem, out_err);
  824. if ( out_err != NULL ) {
  825. perr = out_err;
  826. }
  827. i = (key[0] + key[1] + key[2] + key[3]) % m->_cap;
  828. do {
  829. if ( i >= m->_cap ) {
  830. *perr = ERR_NOT_FOUND;
  831. return *perr;
  832. }
  833. it = MAP_GET_INDEX(m, i++);
  834. } while (it->key[0] != key[0] || it->key[1] != key[1]
  835. || it->key[2] != key[2] || it->key[3] != key[3]);
  836. memcpy(it->item, elem, m->_elem_size);
  837. *perr = ERR_OK;
  838. return ERR_OK;
  839. }
  840. enum err
  841. map_set(struct map *_r_ m, void *_r_ key, u64 key_size, void *_r_ elem,
  842. enum err *_r_ out_err)
  843. {
  844. enum err err = ERR_OK;
  845. enum err *perr = &err;
  846. u64 *hash = NULL;
  847. LIB_ARG_IF_NOT_NULL_MUST_BE_RET_IT(out_err, ERR_OK);
  848. LIB_ARG_MUST_NOT_BE_NULL_SET_RET_ERR(m, out_err);
  849. LIB_ARG_MUST_NOT_BE_NULL_SET_RET_ERR(m->data, out_err);
  850. LIB_ARG_MUST_NOT_BE_NULL_SET_RET_ERR(key, out_err);
  851. LIB_ARG_MUST_NOT_BE_NULL_SET_RET_ERR(elem, out_err);
  852. if ( out_err != NULL ) {
  853. perr = out_err;
  854. }
  855. hash = m->hash(key, key_size);
  856. if ( hash == NULL ) {
  857. *perr = ERR_FAILED_HASHING;
  858. return *perr;
  859. }
  860. map_set_hashed_key(m, hash, elem, perr);
  861. if ( *perr != ERR_OK ) {
  862. free(hash);
  863. return *perr;
  864. }
  865. free(hash);
  866. *perr = ERR_OK;
  867. return ERR_OK;
  868. }
  869. void *map_pop(struct map *m, void *key, u64 key_size, enum err *out_err);
  870. enum err
  871. map_destroy(struct map *m, enum err *out_err)
  872. {
  873. LIB_ARG_IF_NOT_NULL_MUST_BE_RET_IT(out_err, ERR_OK);
  874. LIB_ARG_MUST_NOT_BE_NULL_SET_RET_ERR(m, out_err);
  875. if ( m->data != NULL ) free(m->data);
  876. if ( m->indexs.data != NULL ) free(m->indexs.data);
  877. if ( m->keys.data != NULL ) free(m->keys.data);
  878. LIB_SET_IF_NOT_NULL(out_err, ERR_OK);
  879. return ERR_OK;
  880. }
  881. u64 *
  882. map_default_hasher(void *key, u64 key_size)
  883. {
  884. u64 i = 0;
  885. u64 *k = NULL;
  886. k = malloc(sizeof(u64) * 4);
  887. if ( k == NULL ) {
  888. return NULL;
  889. }
  890. k[0] = 0;
  891. k[1] = 0;
  892. k[2] = 0;
  893. k[3] = 0;
  894. for ( i = 0; i < key_size; ++i ) {
  895. k[0] += ((u8*)key)[i] * 31;
  896. k[1] += ((u8*)key)[i] * 127;
  897. k[2] += ((u8*)key)[i] * 233;
  898. k[3] += ((u8*)key)[i] * 353;
  899. }
  900. return k;
  901. }
  902. # endif /* defined(IMP) || defined(IMP_MAP) */
  903. # endif /* defined(WANT_MAP) || defined(WANT_ALL) */
  904. /* ----------------------------- END MAP DEF ------------------------------- */
  905. /* ---------------------------- START ENV DEF ------------------------------ */
  906. # if defined(WANT_ENV) || defined(WANT_ALL)
  907. struct str getenv_as_str(const char *env, enum err *out_err);
  908. struct path getenv_as_path(const char *env, enum err *out_err);
  909. # endif /* defined(WANT_ENV) || defined(WANT_ALL) */
  910. /* ----------------------------- END ENV DEF ------------------------------- */
  911. /* ---------------------------- START PATH DEF ----------------------------- */
  912. # if defined(WANT_PATH) || defined(WANT_ALL)
  913. # ifndef PATH_SIZE_LIMIT
  914. # define PATH_SIZE_LIMIT 1024
  915. # endif /* PATH_SIZE_LIMIT */
  916. struct path {
  917. char data[PATH_SIZE_LIMIT];
  918. u64 size;
  919. };
  920. struct path path_from_str(struct str str, enum err *out_err);
  921. struct path path_from_cstr(const char *cstr, u64 cstr_size, enum err *out_err);
  922. struct path path_from_cstr_ns(const char *cstr, enum err *out_err);
  923. struct path path_get_xdg_state_home(enum err *out_err);
  924. struct path path_get_xdg_data_home(enum err *out_err);
  925. struct path path_dirname(struct path path, enum err *out_err);
  926. struct path path_join(struct path lhs, struct path rhs, enum err *out_err);
  927. struct path path_join_with_str(struct path lhs, struct str rhs,
  928. enum err *out_err);
  929. struct path path_join_with_cstr(struct path lhs,
  930. const char *rhs, u64 rhs_size,
  931. enum err *out_err);
  932. struct path path_join_with_cstr_ns(struct path lhs, const char *rhs,
  933. enum err *out_err);
  934. bool path_exists(struct path path, int (*access)(const char *, int));
  935. bool path_can_read(struct path path, int (*access)(const char *, int));
  936. bool path_can_write(struct path path, int (*access)(const char *, int));
  937. bool path_can_execute(struct path path, int (*access)(const char *, int));
  938. bool path_mkdir(struct path path, u32 mode, bool do_create_parents,
  939. int (*mkdir)(const char *, u32), enum err *out_err);
  940. bool path_touch(struct path path, int (*open)(const char *, int),
  941. enum err *out_err);
  942. struct file {
  943. u8 *data;
  944. u64 size;
  945. };
  946. struct file path_file_read_all(const struct path *path, enum err *out_err);
  947. enum err path_file_save(const struct path *path, const struct file *file,
  948. enum err *out_err);
  949. # endif /* defined(WANT_PATH) || defined(WANT_ALL) */
  950. /* ----------------------------- END PATH DEF ------------------------------ */
  951. /* ------------------------- START TOKENIZER DEF --------------------------- */
  952. # if defined(WANT_TOKENIZER) || defined(WANT_ALL)
  953. struct tokenizer;
  954. struct tokenizer_options {
  955. bool (*skip_token)(struct tokenizer *tkn, char c);
  956. bool (*is_id)(struct tokenizer *tkn, char c);
  957. bool (*is_id_start)(struct tokenizer *tkn, char c);
  958. bool (*is_digit)(struct tokenizer *tkn, char c);
  959. bool (*is_num_lit)(struct tokenizer *tkn, struct str str);
  960. bool (*is_str_lit_start)(struct tokenizer *tkn, char c);
  961. bool (*is_str_lit_end)(struct tokenizer *tkn, char c);
  962. bool (*is_str_lit)(struct tokenizer *tkn, struct str str);
  963. };
  964. enum tokenizer_loc_format {
  965. TLF_VIM = 0
  966. };
  967. enum token_type {
  968. TK_INVALID = -2,
  969. TK_EOF = -1,
  970. TK_NUL = '\0',
  971. TK_NL = '\n',
  972. TK_TAB = '\t',
  973. TK_SPACE = ' ',
  974. TK_ASTERISK = '*',
  975. TK_AMPERSAND = '&',
  976. TK_PLUS = '+',
  977. TK_MINUS = '-',
  978. TK_EQUAL = '=',
  979. TK_SLASH = '/',
  980. TK_BACKSLASH = '\\',
  981. TK_POUND = '#',
  982. TK_SEMICOLON = ';',
  983. TK_COLON = ':',
  984. TK_COMMA = ',',
  985. TK_DOT = '.',
  986. TK_UNDERSCORE = '_',
  987. TK_L_BRACES = '(',
  988. TK_R_BRACES = ')',
  989. TK_L_BRACKET = '[',
  990. TK_R_BRACKET = ']',
  991. TK_L_CUR_BRACES = '{',
  992. TK_R_CUR_BRACES = '}',
  993. TK_L_ANG_BRACKET = '<',
  994. TK_R_ANG_BRACKET = '>',
  995. TK_SINGLE_QUOTE = '\'',
  996. TK_DOUBLE_QUOTE = '"',
  997. TK_BACKTICK = '`',
  998. TK_TILDE = '~',
  999. TK_a = 'a',
  1000. TK_b = 'b',
  1001. TK_c = 'c',
  1002. TK_d = 'd',
  1003. TK_e = 'e',
  1004. TK_f = 'f',
  1005. TK_g = 'g',
  1006. TK_h = 'h',
  1007. TK_i = 'i',
  1008. TK_j = 'j',
  1009. TK_k = 'k',
  1010. TK_l = 'l',
  1011. TK_m = 'm',
  1012. TK_n = 'n',
  1013. TK_o = 'o',
  1014. TK_p = 'p',
  1015. TK_q = 'q',
  1016. TK_r = 'r',
  1017. TK_s = 's',
  1018. TK_t = 't',
  1019. TK_u = 'u',
  1020. TK_v = 'v',
  1021. TK_w = 'w',
  1022. TK_x = 'x',
  1023. TK_y = 'y',
  1024. TK_z = 'z',
  1025. TK_A = 'A',
  1026. TK_B = 'B',
  1027. TK_C = 'C',
  1028. TK_D = 'D',
  1029. TK_E = 'E',
  1030. TK_F = 'F',
  1031. TK_G = 'G',
  1032. TK_H = 'H',
  1033. TK_I = 'I',
  1034. TK_J = 'J',
  1035. TK_K = 'K',
  1036. TK_L = 'L',
  1037. TK_M = 'M',
  1038. TK_N = 'N',
  1039. TK_O = 'O',
  1040. TK_P = 'P',
  1041. TK_Q = 'Q',
  1042. TK_R = 'R',
  1043. TK_S = 'S',
  1044. TK_T = 'T',
  1045. TK_U = 'U',
  1046. TK_V = 'V',
  1047. TK_W = 'W',
  1048. TK_X = 'X',
  1049. TK_Y = 'Y',
  1050. TK_Z = 'Z',
  1051. TK_0 = '0',
  1052. TK_1 = '1',
  1053. TK_2 = '2',
  1054. TK_3 = '3',
  1055. TK_4 = '4',
  1056. TK_5 = '5',
  1057. TK_6 = '6',
  1058. TK_7 = '7',
  1059. TK_8 = '8',
  1060. TK_9 = '9',
  1061. TK_ID = 257,
  1062. TK_NUM_LIT,
  1063. TK_STR_LIT,
  1064. TK_LAST = 512
  1065. };
  1066. struct token {
  1067. enum token_type type;
  1068. u64 loc_start;
  1069. u64 loc_end;
  1070. struct str string;
  1071. void *extra; /* This is not used by the lib */
  1072. };
  1073. struct tokenizer {
  1074. u64 i;
  1075. struct tokenizer_options opts;
  1076. struct token last;
  1077. struct path src;
  1078. struct str code;
  1079. void *edata; /* This is not used by the lib */
  1080. };
  1081. struct tokenizer tokenizer_create(struct str code, struct path src,
  1082. struct tokenizer_options *opts,
  1083. enum err *out_err);
  1084. /* In normal use this function does not fail! */
  1085. struct token tokenizer_next_token(struct tokenizer *tkn, enum err *out_err);
  1086. enum token_type tokenizer_next_token_type(struct tokenizer *tkn,
  1087. enum err *out_err);
  1088. struct token tokenizer_peek_token(struct tokenizer *tkn, enum err *out_err);
  1089. enum token_type tokenizer_peek_token_type(struct tokenizer *tkn,
  1090. enum err *out_err);
  1091. bool tokenizer_is_next(struct tokenizer *tkn, enum token_type type,
  1092. struct token *out_tk, enum err *out_err);
  1093. bool tokenizer_is_next_id(struct tokenizer *tkn, struct str string,
  1094. struct token *out_tk, enum err *out_err);
  1095. enum err tokenizer_destroy(struct tokenizer *tkn, enum err *out_err);
  1096. const char *tokenizer_token_loc_temp(const struct tokenizer *tkn,
  1097. const struct token *tk,
  1098. enum tokenizer_loc_format format,
  1099. enum err *out_err);
  1100. const char *token_to_cstr(enum token_type type);
  1101. struct tokenizer_options tokenizer_options_defaultlyzer(
  1102. struct tokenizer_options *tkn_opts);
  1103. bool tokenizer_skip_token(struct tokenizer *tkn, char c);
  1104. bool tokenizer_is_id(struct tokenizer *tkn, char c);
  1105. bool tokenizer_is_id_start(struct tokenizer *tkn, char c);
  1106. bool tokenizer_is_digit(struct tokenizer *tkn, char c);
  1107. bool tokenizer_is_num_lit(struct tokenizer *tkn, struct str str);
  1108. bool tokenizer_is_str_lit_start(struct tokenizer *tkn, char c);
  1109. bool tokenizer_is_str_lit_end(struct tokenizer *tkn, char c);
  1110. bool tokenizer_is_str_lit(struct tokenizer *tkn, struct str str);
  1111. # if defined(IMP) || defined(IMP_TOKENIZER)
  1112. struct tokenizer
  1113. tokenizer_create(struct str code, struct path src,
  1114. struct tokenizer_options *opts, enum err *out_err)
  1115. {
  1116. struct tokenizer empty = {0};
  1117. struct tokenizer tkn = {0};
  1118. struct tokenizer_options defs = {0};
  1119. LIB_ARG_IF_NOT_NULL_MUST_BE(out_err, ERR_OK, empty);
  1120. if ( opts == NULL ) {
  1121. tkn.opts = defs;
  1122. } else {
  1123. tkn.opts = *opts;
  1124. }
  1125. tkn.opts = tokenizer_options_defaultlyzer(&tkn.opts);
  1126. tkn.i = 0;
  1127. tkn.code = code;
  1128. tkn.src = src;
  1129. return tkn;
  1130. }
  1131. struct token
  1132. tokenizer_next_token(struct tokenizer *tkn, enum err *out_err)
  1133. {
  1134. static struct {
  1135. char data[256];
  1136. u16 size;
  1137. } buf = {0};
  1138. struct token empty = {0};
  1139. struct token tk = {0};
  1140. char c = 0;
  1141. LIB_ARG_IF_NOT_NULL_MUST_BE(out_err, ERR_OK, empty);
  1142. LIB_ARG_MUST_NOT_BE_NULL(tkn, out_err, empty);
  1143. buf.size = 0;
  1144. if ( tkn->i >= tkn->code.size ) {
  1145. goto eof_tk;
  1146. }
  1147. c = tkn->code.data[tkn->i++];
  1148. while ( tkn->opts.skip_token(tkn, c) == true ) {
  1149. c = tkn->code.data[tkn->i++];
  1150. }
  1151. if ( tkn->opts.is_id_start(tkn, c) == true ) {
  1152. tk.type = TK_ID;
  1153. tk.loc_start = tkn->i-1;
  1154. do {
  1155. buf.data[buf.size++] = c;
  1156. c = tkn->code.data[tkn->i++];
  1157. } while ( tkn->opts.is_id(tkn, c) == true );
  1158. --tkn->i;
  1159. tk.string.data = buf.data;
  1160. tk.string.size = buf.size;
  1161. if ( tkn->opts.is_num_lit(tkn, tk.string) == true ) {
  1162. tk.type = TK_NUM_LIT;
  1163. }
  1164. tk.loc_end = tkn->i-1;
  1165. goto exit;
  1166. }
  1167. if ( tkn->opts.is_digit(tkn, c) == true ) {
  1168. tk.type = TK_NUM_LIT;
  1169. tk.loc_start = tkn->i-1;
  1170. do {
  1171. buf.data[buf.size++] = c;
  1172. c = tkn->code.data[tkn->i++];
  1173. } while ( tkn->opts.is_digit(tkn, c) == true );
  1174. --tkn->i;
  1175. tk.string.data = buf.data;
  1176. tk.string.size = buf.size;
  1177. tk.loc_end = tkn->i-1;
  1178. goto exit;
  1179. }
  1180. if ( tkn->opts.is_str_lit_start(tkn, c) == true ) {
  1181. tk.type = TK_STR_LIT;
  1182. tk.loc_start = tkn->i-1;
  1183. do {
  1184. buf.data[buf.size++] = c;
  1185. c = tkn->code.data[tkn->i++];
  1186. } while ( tkn->opts.is_str_lit_end(tkn, c) == false );
  1187. buf.data[buf.size++] = c;
  1188. tk.string.data = buf.data;
  1189. tk.string.size = buf.size - 1;
  1190. tk.loc_end = tkn->i-1;
  1191. goto exit;
  1192. }
  1193. tk.type = c;
  1194. if ( tkn->i >= tkn->code.size ) {
  1195. eof_tk:
  1196. tk.type = TK_EOF;
  1197. }
  1198. tk.loc_start = tkn->i-1;
  1199. tk.loc_end = tkn->i-1;
  1200. exit:
  1201. tkn->last = tk;
  1202. return tk;
  1203. }
  1204. enum token_type
  1205. tokenizer_next_token_type(struct tokenizer *tkn, enum err *out_err)
  1206. {
  1207. struct token tk = {0};
  1208. enum err err = ERR_OK;
  1209. enum err *perr = &err;
  1210. LIB_ARG_IF_NOT_NULL_MUST_BE(out_err, ERR_OK, TK_INVALID);
  1211. LIB_ARG_MUST_NOT_BE_NULL(tkn, out_err, TK_INVALID);
  1212. if ( out_err != NULL ) {
  1213. perr = out_err;
  1214. }
  1215. tk = tokenizer_next_token(tkn, perr);
  1216. if ( *perr != ERR_OK ) {
  1217. return TK_INVALID;
  1218. }
  1219. LIB_SET_IF_NOT_NULL(out_err, ERR_OK);
  1220. return tk.type;
  1221. }
  1222. struct token
  1223. tokenizer_peek_token(struct tokenizer *tkn, enum err *out_err)
  1224. {
  1225. enum err err = ERR_OK;
  1226. enum err *perr = &err;
  1227. u64 last_i = 0;
  1228. struct token empty = {0};
  1229. struct token tk = {0};
  1230. LIB_ARG_IF_NOT_NULL_MUST_BE(out_err, ERR_OK, empty);
  1231. LIB_ARG_MUST_NOT_BE_NULL(tkn, out_err, empty);
  1232. if ( out_err != NULL ) {
  1233. perr = out_err;
  1234. }
  1235. last_i = tkn->i;
  1236. tk = tokenizer_next_token(tkn, perr);
  1237. tkn->i = last_i;
  1238. return tk;
  1239. }
  1240. enum token_type
  1241. tokenizer_peek_token_type(struct tokenizer *tkn, enum err *out_err)
  1242. {
  1243. enum err err = ERR_OK;
  1244. enum err *perr = &err;
  1245. struct token tk = {0};
  1246. LIB_ARG_IF_NOT_NULL_MUST_BE(out_err, ERR_OK, TK_INVALID);
  1247. LIB_ARG_MUST_NOT_BE_NULL(tkn, out_err, TK_INVALID);
  1248. tk = tokenizer_peek_token(tkn, perr);
  1249. return tk.type;
  1250. }
  1251. bool
  1252. tokenizer_is_next(struct tokenizer *tkn, enum token_type type,
  1253. struct token *out_tk, enum err *out_err)
  1254. {
  1255. enum err err = ERR_OK;
  1256. struct token tk = {0};
  1257. u64 pi = 0;
  1258. LIB_ARG_IF_NOT_NULL_MUST_BE(out_err, ERR_OK, false);
  1259. LIB_ARG_MUST_NOT_BE_NULL(tkn, out_err, false);
  1260. pi = tkn->i;
  1261. tk = tokenizer_next_token(tkn, &err);
  1262. if ( tk.type != type ) {
  1263. tkn->i = pi;
  1264. return false;
  1265. }
  1266. LIB_SET_IF_NOT_NULL(out_tk, tk);
  1267. LIB_SET_IF_NOT_NULL(out_err, ERR_OK);
  1268. return true;
  1269. }
  1270. bool
  1271. tokenizer_is_next_id(struct tokenizer *tkn, struct str string,
  1272. struct token *out_tk, enum err *out_err)
  1273. {
  1274. enum err err = ERR_OK;
  1275. struct token tk = {0};
  1276. u64 pi = 0;
  1277. LIB_ARG_IF_NOT_NULL_MUST_BE(out_err, ERR_OK, false);
  1278. LIB_ARG_MUST_NOT_BE_NULL(tkn, out_err, false);
  1279. LIB_STR_MUST_NOT_BE_EMPTY(string, out_err, false);
  1280. pi = tkn->i;
  1281. tk = tokenizer_next_token(tkn, &err);
  1282. if ( tk.type != TK_ID ) {
  1283. tkn->i = pi;
  1284. return false;
  1285. }
  1286. if ( str_eq_str(tk.string, string) == false ) {
  1287. tkn->i = pi;
  1288. return false;
  1289. }
  1290. LIB_SET_IF_NOT_NULL(out_tk, tk);
  1291. LIB_SET_IF_NOT_NULL(out_err, ERR_OK);
  1292. return true;
  1293. }
  1294. enum err tokenizer_destroy(struct tokenizer *tkn, enum err *out_err);
  1295. const char *
  1296. tokenizer_token_loc_temp(const struct tokenizer *tkn, const struct token *tk,
  1297. enum tokenizer_loc_format format, enum err *out_err)
  1298. {
  1299. static struct {
  1300. char data[1024];
  1301. u64 size;
  1302. } buf = {0};
  1303. LIB_ARG_IF_NOT_NULL_MUST_BE(out_err, ERR_OK, NULL);
  1304. LIB_ARG_MUST_NOT_BE_NULL(tkn, out_err, NULL);
  1305. LIB_ARG_MUST_NOT_BE_NULL(tk, out_err, NULL);
  1306. buf.size = 0;
  1307. switch ( format ) {
  1308. case TLF_VIM: {
  1309. u64 col = 0;
  1310. memcpy(buf.data, tkn->src.data, tkn->src.size);
  1311. buf.size += tkn->src.size;
  1312. buf.data[buf.size++] = ':';
  1313. {
  1314. u64 i = 0;
  1315. u64 line = 0;
  1316. struct str line_str = {0};
  1317. for ( i = 0; i < tk->loc_start; ++i ) {
  1318. line += ( tkn->code.data[i] == '\n' );
  1319. }
  1320. line_str = str_from_i64_temp((i64)line);
  1321. memcpy(buf.data + buf.size, line_str.data, line_str.size);
  1322. buf.size += line_str.size;
  1323. /* Col values wrong */
  1324. while ( tkn->code.data[i] != '\n' && i > 0 ) {
  1325. --i;
  1326. }
  1327. col = tk->loc_start - i;
  1328. }
  1329. buf.data[buf.size++] = ':';
  1330. {
  1331. struct str col_str = {0};
  1332. col_str = str_from_i64_temp((i64)col);
  1333. memcpy(buf.data + buf.size, col_str.data, col_str.size);
  1334. buf.size += col_str.size;
  1335. }
  1336. buf.data[buf.size++] = ':';
  1337. buf.data[buf.size++] = 0;
  1338. } break;
  1339. default:
  1340. LIB_SET_IF_NOT_NULL(out_err, ERR_INVALID_ARG);
  1341. return NULL;
  1342. }
  1343. LIB_SET_IF_NOT_NULL(out_err, ERR_OK);
  1344. return buf.data;
  1345. }
  1346. const char *
  1347. token_to_cstr(enum token_type type)
  1348. {
  1349. switch ( type ) {
  1350. case TK_INVALID: return "TK_INVALID";
  1351. case TK_EOF: return "TK_EOF";
  1352. case TK_NUL: return "TK_NUL";
  1353. case TK_NL: return "TK_NL";
  1354. case TK_TAB: return "TK_TAB";
  1355. case TK_SPACE: return "TK_SPACE";
  1356. case TK_ASTERISK: return "TK_ASTERISK";
  1357. case TK_AMPERSAND: return "TK_AMPERSAND";
  1358. case TK_PLUS: return "TK_PLUS";
  1359. case TK_MINUS: return "TK_MINUS";
  1360. case TK_EQUAL: return "TK_EQUAL";
  1361. case TK_SLASH: return "TK_SLASH";
  1362. case TK_BACKSLASH: return "TK_BACKSLASH";
  1363. case TK_POUND: return "TK_POUND";
  1364. case TK_SEMICOLON: return "TK_SEMICOLON";
  1365. case TK_COLON: return "TK_COLON";
  1366. case TK_COMMA: return "TK_COMMA";
  1367. case TK_DOT: return "TK_DOT";
  1368. case TK_UNDERSCORE: return "TK_UNDERSCORE";
  1369. case TK_L_BRACES: return "TK_L_BRACES";
  1370. case TK_R_BRACES: return "TK_R_BRACES";
  1371. case TK_L_BRACKET: return "TK_L_BRACKET";
  1372. case TK_R_BRACKET: return "TK_R_BRACKET";
  1373. case TK_L_CUR_BRACES: return "TK_L_CUR_BRACES";
  1374. case TK_R_CUR_BRACES: return "TK_R_CUR_BRACES";
  1375. case TK_L_ANG_BRACKET: return "TK_L_ANG_BRACKET";
  1376. case TK_R_ANG_BRACKET: return "TK_R_ANG_BRACKET";
  1377. case TK_SINGLE_QUOTE: return "TK_SINGLE_QUOTE";
  1378. case TK_DOUBLE_QUOTE: return "TK_DOUBLE_QUOTE";
  1379. case TK_BACKTICK: return "TK_BACKTICK";
  1380. case TK_TILDE: return "TK_TILDE";
  1381. case TK_a: return "TK_a";
  1382. case TK_b: return "TK_b";
  1383. case TK_c: return "TK_c";
  1384. case TK_d: return "TK_d";
  1385. case TK_e: return "TK_e";
  1386. case TK_f: return "TK_f";
  1387. case TK_g: return "TK_g";
  1388. case TK_h: return "TK_h";
  1389. case TK_i: return "TK_i";
  1390. case TK_j: return "TK_j";
  1391. case TK_k: return "TK_k";
  1392. case TK_l: return "TK_l";
  1393. case TK_m: return "TK_m";
  1394. case TK_n: return "TK_n";
  1395. case TK_o: return "TK_o";
  1396. case TK_p: return "TK_p";
  1397. case TK_q: return "TK_q";
  1398. case TK_r: return "TK_r";
  1399. case TK_s: return "TK_s";
  1400. case TK_t: return "TK_t";
  1401. case TK_u: return "TK_u";
  1402. case TK_v: return "TK_v";
  1403. case TK_w: return "TK_w";
  1404. case TK_x: return "TK_x";
  1405. case TK_y: return "TK_y";
  1406. case TK_z: return "TK_z";
  1407. case TK_A: return "TK_A";
  1408. case TK_B: return "TK_B";
  1409. case TK_C: return "TK_C";
  1410. case TK_D: return "TK_D";
  1411. case TK_E: return "TK_E";
  1412. case TK_F: return "TK_F";
  1413. case TK_G: return "TK_G";
  1414. case TK_H: return "TK_H";
  1415. case TK_I: return "TK_I";
  1416. case TK_J: return "TK_J";
  1417. case TK_K: return "TK_K";
  1418. case TK_L: return "TK_L";
  1419. case TK_M: return "TK_M";
  1420. case TK_N: return "TK_N";
  1421. case TK_O: return "TK_O";
  1422. case TK_P: return "TK_P";
  1423. case TK_Q: return "TK_Q";
  1424. case TK_R: return "TK_R";
  1425. case TK_S: return "TK_S";
  1426. case TK_T: return "TK_T";
  1427. case TK_U: return "TK_U";
  1428. case TK_V: return "TK_V";
  1429. case TK_W: return "TK_W";
  1430. case TK_X: return "TK_X";
  1431. case TK_Y: return "TK_Y";
  1432. case TK_Z: return "TK_Z";
  1433. case TK_0: return "TK_0";
  1434. case TK_1: return "TK_1";
  1435. case TK_2: return "TK_2";
  1436. case TK_3: return "TK_3";
  1437. case TK_4: return "TK_4";
  1438. case TK_5: return "TK_5";
  1439. case TK_6: return "TK_6";
  1440. case TK_7: return "TK_7";
  1441. case TK_8: return "TK_8";
  1442. case TK_9: return "TK_9";
  1443. case TK_ID: return "TK_ID";
  1444. case TK_NUM_LIT: return "TK_NUM_LIT";
  1445. case TK_STR_LIT: return "TK_STR_LIT";
  1446. default: return "TK_UNKNOWN";
  1447. }
  1448. return "TK_UNKNOWN";
  1449. }
  1450. struct tokenizer_options
  1451. tokenizer_options_defaultlyzer(struct tokenizer_options *tkn_opts)
  1452. {
  1453. struct tokenizer_options defs = {0};
  1454. if ( tkn_opts != NULL ) {
  1455. defs = *tkn_opts;
  1456. }
  1457. LIB_SET_IF_NULL(defs.skip_token, tokenizer_skip_token);
  1458. LIB_SET_IF_NULL(defs.is_id, tokenizer_is_id);
  1459. LIB_SET_IF_NULL(defs.is_id_start, tokenizer_is_id_start);
  1460. LIB_SET_IF_NULL(defs.is_digit, tokenizer_is_digit);
  1461. LIB_SET_IF_NULL(defs.is_num_lit, tokenizer_is_num_lit);
  1462. LIB_SET_IF_NULL(defs.is_str_lit_start, tokenizer_is_str_lit_start);
  1463. LIB_SET_IF_NULL(defs.is_str_lit_end, tokenizer_is_str_lit_end);
  1464. LIB_SET_IF_NULL(defs.is_str_lit, tokenizer_is_str_lit);
  1465. LIB_SET_IF_NULL(defs.skip_token, tokenizer_skip_token);
  1466. return defs;
  1467. }
  1468. bool
  1469. tokenizer_skip_token(struct tokenizer *tkn, char c)
  1470. {
  1471. UNUSED(tkn);
  1472. return (c == ' ') || (c == '\n') || (c == '\r') || (c == '\t');
  1473. }
  1474. bool
  1475. tokenizer_is_id(struct tokenizer *tkn, char c)
  1476. {
  1477. UNUSED(tkn);
  1478. return (c == '_') || (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z');
  1479. }
  1480. bool
  1481. tokenizer_is_id_start(struct tokenizer *tkn, char c)
  1482. {
  1483. UNUSED(tkn);
  1484. return tokenizer_is_id(tkn, c);
  1485. }
  1486. bool
  1487. tokenizer_is_digit(struct tokenizer *tkn, char c)
  1488. {
  1489. UNUSED(tkn);
  1490. return (c >= '0' && c <= '9');
  1491. }
  1492. bool
  1493. tokenizer_is_num_lit(struct tokenizer *tkn, struct str str)
  1494. {
  1495. u64 i = 0;
  1496. UNUSED(tkn);
  1497. for ( i = 0; i < str.size; ++i ) {
  1498. if ( ! tokenizer_is_digit(tkn, str.data[i]) ) {
  1499. return false;
  1500. }
  1501. }
  1502. return true;
  1503. }
  1504. bool
  1505. tokenizer_is_str_lit_start(struct tokenizer *tkn, char c)
  1506. {
  1507. UNUSED(tkn);
  1508. return (c == '\'' || c == '"');
  1509. }
  1510. bool
  1511. tokenizer_is_str_lit_end(struct tokenizer *tkn, char c)
  1512. {
  1513. return tokenizer_is_str_lit_start(tkn, c);
  1514. }
  1515. bool
  1516. tokenizer_is_str_lit(struct tokenizer *tkn, struct str str)
  1517. {
  1518. UNUSED(tkn);
  1519. UNUSED(str);
  1520. return true;
  1521. }
  1522. # endif /* defined(IMP) || defined(IMP_TOKENIZER) */
  1523. # endif /* defined(WANT_TOKENIZER) || defined(WANT_ALL) */
  1524. /* -------------------------- END TOKENIZER DEF ---------------------------- */
  1525. /* ---------------------------- START CMD DEF ------------------------------ */
  1526. # if defined(WANT_CMD) || defined(WANT_ALL)
  1527. struct cmd {
  1528. char *exe;
  1529. struct {
  1530. char **data;
  1531. u64 size;
  1532. u64 cap;
  1533. } args;
  1534. };
  1535. # define cmd_create_ns(Exe, OutErr) \
  1536. cmd_create( \
  1537. (struct str) { \
  1538. .data=(Exe), \
  1539. .size=cstr_len_max((Exe), STR_SIZE_LIMIT, NULL, (OutErr)) \
  1540. }, \
  1541. (OutErr) \
  1542. )
  1543. struct cmd cmd_create(struct str exe, enum err *_r_ out_err);
  1544. # define cmd_set_exe_ns(Cmd, Exe, OutErr) \
  1545. cmd_set_exe( \
  1546. (Cmd), \
  1547. (struct str) { \
  1548. .data=(Exe), \
  1549. .size=cstr_len_max((Exe), STR_SIZE_LIMIT, NULL, (OutErr)) \
  1550. }, \
  1551. (OutErr) \
  1552. )
  1553. enum err cmd_set_exe(struct cmd *_r_ cmd, struct str exe,
  1554. enum err *_r_ out_err);
  1555. # define cmd_append_arg_ns(Cmd, Arg, OutErr) \
  1556. cmd_append_arg( \
  1557. (Cmd), \
  1558. (struct str) { \
  1559. .data=(Arg), \
  1560. .size=cstr_len_max((Arg), STR_SIZE_LIMIT, NULL, (OutErr)) \
  1561. }, \
  1562. (OutErr) \
  1563. )
  1564. enum err cmd_append_arg(struct cmd *_r_ cmd, struct str arg,
  1565. enum err *_r_ out_err);
  1566. enum err cmd_exec(struct cmd *_r_ cmd, enum err *_r_ out_err);
  1567. enum err cmd_destroy(struct cmd *cmd, enum err *out_err);
  1568. # if defined(IMP_CMD) || defined(IMP)
  1569. struct cmd
  1570. cmd_create(struct str exe, enum err *_r_ out_err)
  1571. {
  1572. struct cmd empty = {0};
  1573. struct cmd cmd = {0};
  1574. LIB_ARG_IF_NOT_NULL_MUST_BE(out_err, ERR_OK, empty);
  1575. LIB_ARG_MUST_NOT_BE_NULL(exe.data, out_err, empty);
  1576. cmd.exe = malloc(exe.size+1);
  1577. if ( cmd.exe == NULL ) {
  1578. LIB_SET_IF_NOT_NULL(out_err, ERR_FAILED_ALLOC);
  1579. goto exit_err;
  1580. }
  1581. cmd.exe[exe.size] = 0;
  1582. memcpy(cmd.exe, exe.data, exe.size);
  1583. cmd.args.cap = 32;
  1584. cmd.args.data = malloc(sizeof(*cmd.args.data) * cmd.args.cap);
  1585. if ( cmd.args.data == NULL ) {
  1586. LIB_SET_IF_NOT_NULL(out_err, ERR_FAILED_ALLOC);
  1587. goto exit_err;
  1588. }
  1589. DA_APPEND(cmd.args, cmd.exe, out_err);
  1590. LIB_SET_IF_NOT_NULL(out_err, ERR_OK);
  1591. return cmd;
  1592. exit_err:
  1593. LIB_FREE(cmd.exe);
  1594. LIB_FREE(cmd.args.data);
  1595. return (struct cmd){0};
  1596. }
  1597. enum err
  1598. cmd_set_exe(struct cmd *_r_ cmd, struct str exe, enum err *_r_ out_err)
  1599. {
  1600. LIB_ARG_IF_NOT_NULL_MUST_BE_RET_IT(out_err, ERR_OK);
  1601. LIB_ARG_MUST_NOT_BE_NULL_SET_RET_ERR(cmd, out_err);
  1602. LIB_ARG_MUST_NOT_BE_NULL_SET_RET_ERR(exe.data, out_err);
  1603. if ( cmd->exe != NULL ) {
  1604. LIB_FREE(cmd->exe);
  1605. }
  1606. cmd->exe = malloc(exe.size+1);
  1607. if ( cmd->exe == NULL ) {
  1608. LIB_SET_IF_NOT_NULL(out_err, ERR_FAILED_ALLOC);
  1609. return ERR_FAILED_ALLOC;
  1610. }
  1611. cmd->exe[exe.size] = 0;
  1612. memcpy(cmd->exe, exe.data, exe.size);
  1613. cmd->args.data[0] = cmd->exe;
  1614. LIB_SET_IF_NOT_NULL(out_err, ERR_OK);
  1615. return ERR_OK;
  1616. }
  1617. enum err
  1618. cmd_append_arg(struct cmd *_r_ cmd, struct str arg, enum err *_r_ out_err)
  1619. {
  1620. enum err err = ERR_OK;
  1621. enum err *perr = &err;
  1622. char *t = NULL;
  1623. LIB_ARG_IF_NOT_NULL_MUST_BE_RET_IT(out_err, ERR_OK);
  1624. LIB_ARG_MUST_NOT_BE_NULL_SET_RET_ERR(cmd, out_err);
  1625. LIB_ARG_MUST_NOT_BE_NULL_SET_RET_ERR(cmd->args.data, out_err);
  1626. LIB_ARG_MUST_NOT_BE_NULL_SET_RET_ERR(arg.data, out_err);
  1627. if ( out_err != NULL ) {
  1628. perr = out_err;
  1629. }
  1630. t = malloc(arg.size + 1);
  1631. if ( t == NULL ) {
  1632. LIB_SET_IF_NOT_NULL(out_err, ERR_FAILED_ALLOC);
  1633. return ERR_FAILED_ALLOC;
  1634. }
  1635. t[arg.size] = 0;
  1636. memcpy(t, arg.data, arg.size);
  1637. DA_APPEND(cmd->args, t, perr);
  1638. return *perr;
  1639. }
  1640. enum err
  1641. cmd_exec(struct cmd *_r_ cmd, enum err *_r_ out_err)
  1642. {
  1643. i32 pid = -1;
  1644. i32 status = 0;
  1645. LIB_ARG_IF_NOT_NULL_MUST_BE_RET_IT(out_err, ERR_OK);
  1646. LIB_ARG_MUST_NOT_BE_NULL_SET_RET_ERR(cmd, out_err);
  1647. LIB_ARG_MUST_NOT_BE_NULL_SET_RET_ERR(cmd->exe, out_err);
  1648. LIB_ARG_MUST_NOT_BE_NULL_SET_RET_ERR(cmd->args.data, out_err);
  1649. cmd->args.data[cmd->args.size] = NULL;
  1650. pid = fork();
  1651. if ( pid < 0 ) {
  1652. LIB_SET_IF_NOT_NULL(out_err, ERR_FAILED_FORK);
  1653. return ERR_FAILED_FORK;
  1654. }
  1655. if ( pid == 0 ) {
  1656. /*
  1657. printf("exe=`%s`\n", cmd->exe);
  1658. DA_FOREACH(cmd->args, it) {
  1659. printf("arg=`%s`\n", *it);
  1660. }
  1661. */
  1662. execve(cmd->exe, cmd->args.data, NULL);
  1663. exit(1);
  1664. }
  1665. if ( waitpid(pid, &status, 0) < 0 ) {
  1666. LIB_SET_IF_NOT_NULL(out_err, ERR_FAILED_WAITPID);
  1667. return ERR_FAILED_WAITPID;
  1668. }
  1669. if ( WIFEXITED(status) == true ) {
  1670. if ( WEXITSTATUS(status) != 0 ) {
  1671. LIB_SET_IF_NOT_NULL(out_err, ERR_CMD_NON_ZERO_EXIT_CODE);
  1672. return ERR_CMD_NON_ZERO_EXIT_CODE;
  1673. }
  1674. }
  1675. LIB_SET_IF_NOT_NULL(out_err, ERR_OK);
  1676. return ERR_OK;
  1677. }
  1678. enum err
  1679. cmd_destroy(struct cmd *cmd, enum err *out_err)
  1680. {
  1681. LIB_ARG_IF_NOT_NULL_MUST_BE_RET_IT(out_err, ERR_OK);
  1682. LIB_ARG_MUST_NOT_BE_NULL_SET_RET_ERR(cmd, out_err);
  1683. LIB_ARG_MUST_NOT_BE_NULL_SET_RET_ERR(cmd->exe, out_err);
  1684. LIB_ARG_MUST_NOT_BE_NULL_SET_RET_ERR(cmd->args.data, out_err);
  1685. LIB_FREE(cmd->exe);
  1686. DA_FOREACH(cmd->args, it) {
  1687. if ( *it == cmd->exe ) continue;
  1688. LIB_FREE(*it);
  1689. }
  1690. LIB_FREE(cmd->args.data);
  1691. LIB_SET_IF_NOT_NULL(out_err, ERR_OK);
  1692. return ERR_OK;
  1693. }
  1694. # endif /* defined(IMP_CMD) || defined(IMP) */
  1695. # endif /* defined(WANT_CMD) || defined(WANT_ALL) */
  1696. /* ----------------------------- END CMD DEF ------------------------------- */
  1697. /* ---------------------------- START SGFX DEF ----------------------------- */
  1698. # if defined(WANT_SGFX) || defined(WANT_ALL)
  1699. # ifndef SGFX_WIDTH
  1700. # define SGFX_WIDTH 800
  1701. # endif /* SGFX_WIDTH */
  1702. # ifndef SGFX_HEIGHT
  1703. # define SGFX_HEIGHT 600
  1704. # endif /* SGFX_HEIGHT */
  1705. # define SGFX_WIDTH_CSTR MACRO_STR_VALUE_X(SGFX_WIDTH)
  1706. # define SGFX_HEIGHT_CSTR MACRO_STR_VALUE_X(SGFX_HEIGHT)
  1707. struct sgfx_rgb {
  1708. u8 r, g, b;
  1709. };
  1710. struct sgfx_rgba {
  1711. u8 r, g, b, a;
  1712. };
  1713. struct sgfx_canvas {
  1714. u32 pixels[SGFX_WIDTH * SGFX_HEIGHT];
  1715. u64 width;
  1716. u64 height;
  1717. u64 cap;
  1718. };
  1719. enum err sgfx_canvas_populate(struct sgfx_canvas *canvas, enum err *out_err);
  1720. enum err sgfx_canvas_fill(struct sgfx_canvas *canvas, u32 color,
  1721. enum err *out_err);
  1722. enum err sgfx_canvas_fill_rect(struct sgfx_canvas *canvas,
  1723. struct u64vec2 pos, struct u64vec2s size,
  1724. u32 color,
  1725. enum err *out_err);
  1726. enum err sgfx_canvas_save_to_ppm(const struct sgfx_canvas *canvas,
  1727. struct path path, enum err *out_err);
  1728. # endif /* defined(WANT_SGFX) || defined(WANT_ALL) */
  1729. /* ----------------------------- END SGFX DEF ------------------------------ */
  1730. /* --------------------------- START RAYLIB DEF ---------------------------- */
  1731. # if defined(WANT_RAYLIB) || defined(WANT_ALL)
  1732. # if defined(RAYLIB_H)
  1733. enum err raylib_draw_str(const struct str_builder *str, Font font,
  1734. Vector2 position, float fontSize,
  1735. float spacing, Color tint, enum err *out_err);
  1736. # endif /* defined(RAYLIB_H) */
  1737. # endif /* defined(WANT_RAYLIB) || defined(WANT_ALL) */
  1738. /* ---------------------------- END RAYLIB DEF ----------------------------- */
  1739. /* ---------------------------- START GUI DEF ------------------------------ */
  1740. # if defined(WANT_GUI) || defined(WANT_ALL)
  1741. enum gui_unit_type {
  1742. GUT_ABSOLUTE = 0,
  1743. GUT_PERCENTAGE
  1744. };
  1745. enum gui_unit_reference {
  1746. GUR_TOP_LEFT = 0,
  1747. GUR_CENTER
  1748. };
  1749. struct gui_unit {
  1750. enum gui_unit_type type;
  1751. enum gui_unit_reference ref;
  1752. i64 value;
  1753. };
  1754. enum gui_item_type {
  1755. GIT_BUTTOM = 0
  1756. };
  1757. struct gui_item {
  1758. enum gui_item_type type;
  1759. struct gui_unit x;
  1760. struct gui_unit y;
  1761. struct gui_unit width;
  1762. struct gui_unit height;
  1763. };
  1764. struct gui {
  1765. struct {
  1766. struct gui_item *data;
  1767. u64 size;
  1768. u64 cap;
  1769. } items;
  1770. };
  1771. struct gui gui_open_window(const char *title, enum err *out_err);
  1772. bool gui_should_close(struct gui *gui, enum err *out_err);
  1773. enum err gui_start_loop(struct gui *gui, enum err *out_err);
  1774. enum err gui_add_buttom(struct gui *gui,
  1775. struct gui_unit x, struct gui_unit y,
  1776. struct gui_unit width, struct gui_unit height,
  1777. enum err *out_err);
  1778. enum err gui_end_loop(struct gui *gui, enum err *out_err);
  1779. enum err gui_close_window(struct gui *gui, enum err *out_err);
  1780. # if defined(IMP) || defined(IMP_STR)
  1781. struct gui
  1782. gui_open_window(const char *title, enum err *out_err)
  1783. {
  1784. struct gui empty = {0};
  1785. LIB_ARG_IF_NOT_NULL_MUST_BE(out_err, ERR_OK, empty);
  1786. LIB_ARG_MUST_NOT_BE_NULL(title, out_err, empty);
  1787. # if defined(RAYLIB_H)
  1788. InitWindow(800, 600, title);
  1789. SetWindowState(FLAG_WINDOW_RESIZABLE);
  1790. # endif /* defined(RAYLIB_H) */
  1791. LIB_SET_IF_NOT_NULL(out_err, ERR_OK);
  1792. return empty;
  1793. }
  1794. bool
  1795. gui_should_close(struct gui *gui, enum err *out_err)
  1796. {
  1797. LIB_ARG_IF_NOT_NULL_MUST_BE(out_err, ERR_OK, true);
  1798. LIB_ARG_MUST_NOT_BE_NULL(gui, out_err, true);
  1799. (void) gui;
  1800. # if defined(RAYLIB_H)
  1801. LIB_SET_IF_NOT_NULL(out_err, ERR_OK);
  1802. return WindowShouldClose();
  1803. # endif /* defined(RAYLIB_H) */
  1804. LIB_SET_IF_NOT_NULL(out_err, ERR_OK);
  1805. return true;
  1806. }
  1807. enum err
  1808. gui_start_loop(struct gui *gui, enum err *out_err)
  1809. {
  1810. LIB_ARG_IF_NOT_NULL_MUST_BE_RET_IT(out_err, ERR_OK);
  1811. LIB_ARG_MUST_NOT_BE_NULL_SET_RET_ERR(gui, out_err);
  1812. # if defined(RAYLIB_H)
  1813. BeginDrawing();
  1814. # endif /* defined(RAYLIB_H) */
  1815. LIB_SET_IF_NOT_NULL(out_err, ERR_OK);
  1816. return ERR_OK;
  1817. }
  1818. enum err
  1819. gui_add_buttom(struct gui *gui,
  1820. struct gui_unit x, struct gui_unit y,
  1821. struct gui_unit width, struct gui_unit height,
  1822. enum err *out_err)
  1823. {
  1824. # if defined(RAYLIB_H)
  1825. Color red = { 230, 41, 55, 255 };
  1826. # endif /* defined(RAYLIB_H) */
  1827. LIB_ARG_IF_NOT_NULL_MUST_BE_RET_IT(out_err, ERR_OK);
  1828. LIB_ARG_MUST_NOT_BE_NULL_SET_RET_ERR(gui, out_err);
  1829. # if defined(RAYLIB_H)
  1830. DrawRectangle((i32)x.value, (i32)y.value,
  1831. (i32)width.value, (i32)height.value, red);
  1832. # endif /* defined(RAYLIB_H) */
  1833. LIB_SET_IF_NOT_NULL(out_err, ERR_OK);
  1834. return ERR_OK;
  1835. }
  1836. enum err
  1837. gui_end_loop(struct gui *gui, enum err *out_err)
  1838. {
  1839. LIB_ARG_IF_NOT_NULL_MUST_BE_RET_IT(out_err, ERR_OK);
  1840. LIB_ARG_MUST_NOT_BE_NULL_SET_RET_ERR(gui, out_err);
  1841. # if defined(RAYLIB_H)
  1842. EndDrawing();
  1843. # endif /* defined(RAYLIB_H) */
  1844. LIB_SET_IF_NOT_NULL(out_err, ERR_OK);
  1845. return ERR_OK;
  1846. }
  1847. enum err
  1848. gui_close_window(struct gui *gui, enum err *out_err)
  1849. {
  1850. LIB_ARG_IF_NOT_NULL_MUST_BE_RET_IT(out_err, ERR_OK);
  1851. LIB_ARG_MUST_NOT_BE_NULL_SET_RET_ERR(gui, out_err);
  1852. # if defined(RAYLIB_H)
  1853. CloseWindow();
  1854. # endif /* defined(RAYLIB_H) */
  1855. LIB_SET_IF_NOT_NULL(out_err, ERR_OK);
  1856. return ERR_OK;
  1857. }
  1858. # endif /* defined(IMP) || defined(IMP_STR) */
  1859. # endif /* defined(WANT_GUI) || defined(WANT_ALL) */
  1860. /* ----------------------------- END GUI DEF ------------------------------- */
  1861. /* ---------------------------- START SLOP DEF ----------------------------- */
  1862. # if defined(WANT_SLOP) || defined(WANT_ALL)
  1863. u8 *slop_file_slurp(const char *_r_ path, u64 *_r_ out_size,
  1864. enum err *_r_ out_err);
  1865. enum err slop_file_save(const char *_r_ path, u8 *_r_ data, u64 size,
  1866. enum err *_r_ out_err);
  1867. # if defined(IMP) || defined(IMP_SLOP)
  1868. u8 *
  1869. slop_file_slurp(const char *_r_ path, u64 *_r_ out_size, enum err *_r_ out_err)
  1870. {
  1871. enum err err = ERR_OK;
  1872. enum err *perr = &err;
  1873. struct path p = {0};
  1874. struct file f = {0};
  1875. LIB_ARG_IF_NOT_NULL_MUST_BE(out_err, ERR_OK, NULL);
  1876. LIB_ARG_MUST_NOT_BE_NULL(path, out_err, NULL);
  1877. if ( out_err != NULL ) {
  1878. perr = out_err;
  1879. }
  1880. p = path_from_cstr_ns(path, perr);
  1881. f = path_file_read_all(&p, perr);
  1882. if ( out_size != NULL ) {
  1883. *out_size = f.size;
  1884. }
  1885. return f.data;
  1886. }
  1887. enum err slop_file_save(const char *_r_ path, u8 *_r_ data, u64 size,
  1888. enum err *_r_ out_err);
  1889. # endif /* defined(IMP) || defined(IMP_SLOP) */
  1890. # endif /* defined(WANT_SLOP) || defined(WANT_ALL) */
  1891. /* ----------------------------- END SLOP DEF ------------------------------ */
  1892. # if defined(IMP) || defined(IMP_STR)
  1893. # define _SET_IF_NOT_NULL(var, err) \
  1894. if ( var != NULL ) { \
  1895. *var = err; \
  1896. }
  1897. # define _ARG_IF_NOT_NULL_MUST_BE(arg, val, ret_val) \
  1898. if ( arg != NULL ) { \
  1899. if ( *arg != val ) { \
  1900. return ret_val; \
  1901. } \
  1902. }
  1903. # define _ARG_IF_NOT_NULL_MUST_BE_RET_IT(arg, val) \
  1904. if ( arg != NULL ) { \
  1905. if ( *arg != val ) { \
  1906. return *arg; \
  1907. } \
  1908. }
  1909. # define _ARG_MUST_NOT_BE_NULL_RET_ERR(arg) \
  1910. if ( (arg) == NULL ) { \
  1911. return ERR_NULL_ARG; \
  1912. }
  1913. # define _ARG_MUST_NOT_BE_NULL(arg, err_var, ret_val) \
  1914. if ( (arg) == NULL ) { \
  1915. _SET_IF_NOT_NULL(err_var, ERR_NULL_ARG); \
  1916. return ret_val; \
  1917. }
  1918. # define _ARG_MUST_NOT_BE_NULL_SET_RET_ERR(arg, err_var) \
  1919. if ( (arg) == NULL ) { \
  1920. _SET_IF_NOT_NULL(err_var, ERR_NULL_ARG); \
  1921. return ERR_NULL_ARG; \
  1922. }
  1923. # ifndef _CTYPE_H
  1924. # define LIB_H_CTYPE
  1925. # define isspace(c) ((c) == ' ' || (c) == '\f' \
  1926. || (c) == '\n' || (c) == '\r' \
  1927. || (c) == '\t' || (c) == '\v')
  1928. # define isdigit(c) ((c) >= '0' && (c) <= '9')
  1929. # endif /* _CTYPE_H */
  1930. # ifndef _STRING_H
  1931. # define LIB_H_STRING
  1932. void *_str_memcpy(void *dest, const void *src, u64 n);
  1933. void *
  1934. _str_memcpy(void *dest, const void *src, u64 n)
  1935. {
  1936. u64 i = 0;
  1937. char *_dest = (char *) dest;
  1938. char *_src = (char *) src;
  1939. for ( i = 0; i < n; ++i ) {
  1940. _dest[i] = _src[i];
  1941. }
  1942. return dest;
  1943. }
  1944. # define memcpy _str_memcpy
  1945. # endif /* _STRING_H */
  1946. /* ----------------------------- START LIB IMP ----------------------------- */
  1947. /* ------------------------------ END LIB IMP ------------------------------ */
  1948. /* ---------------------------- START CSTR IMP ----------------------------- */
  1949. # if defined(WANT_CSTR) || defined(WANT_ALL)
  1950. u64
  1951. cstr_len_max(const char *cstr, u64 max, bool *out_hit_max, enum err *out_err)
  1952. {
  1953. u64 ret = 0;
  1954. _ARG_IF_NOT_NULL_MUST_BE(out_err, ERR_OK, 0);
  1955. if ( cstr == NULL ) {
  1956. _SET_IF_NOT_NULL(out_err, ERR_NULL_ARG);
  1957. return 0;
  1958. }
  1959. _loop:
  1960. if ( ret >= max ) {
  1961. _SET_IF_NOT_NULL(out_hit_max, true);
  1962. goto _loop_end;
  1963. }
  1964. if ( cstr[ret] == '\0' ) {
  1965. goto _loop_end;
  1966. }
  1967. ++ret;
  1968. goto _loop;
  1969. _loop_end:
  1970. _SET_IF_NOT_NULL(out_err, ERR_OK);
  1971. return ret;
  1972. }
  1973. # endif /* defined(WANT_CSTR) || defined(WANT_ALL) */
  1974. /* ----------------------------- END CSTR IMP ------------------------------ */
  1975. /* ---------------------------- START STR DEF ------------------------------ */
  1976. # if defined(WANT_STR) || defined(WANT_ALL)
  1977. struct str
  1978. str_from_cstr(const char *cstr, u64 cstr_size, enum err *out_err)
  1979. {
  1980. struct str empty = {0};
  1981. struct str str = {0};
  1982. LIB_ARG_IF_NOT_NULL_MUST_BE(out_err, ERR_OK, empty);
  1983. if ( cstr == NULL ) {
  1984. LIB_SET_IF_NOT_NULL(out_err, ERR_NULL_ARG);
  1985. return empty;
  1986. }
  1987. if ( cstr_size >= STR_SIZE_LIMIT ) {
  1988. LIB_SET_IF_NOT_NULL(out_err, ERR_TOO_BIG);
  1989. return empty;
  1990. }
  1991. str.data = cstr;
  1992. str.size = cstr_size;
  1993. _SET_IF_NOT_NULL(out_err, ERR_OK);
  1994. return str;
  1995. }
  1996. struct str
  1997. str_from_cstr_ns(const char *cstr, enum err *out_err)
  1998. {
  1999. struct str empty = {0};
  2000. struct str str = {0};
  2001. bool too_big = false;
  2002. enum err err = ERR_OK;
  2003. if ( cstr == NULL ) {
  2004. _SET_IF_NOT_NULL(out_err, ERR_NULL_ARG);
  2005. return empty;
  2006. }
  2007. str.size = cstr_len_max(cstr, STR_SIZE_LIMIT, &too_big, &err);
  2008. if ( err ) {
  2009. _SET_IF_NOT_NULL(out_err, err);
  2010. return empty;
  2011. }
  2012. if ( too_big ) {
  2013. _SET_IF_NOT_NULL(out_err, ERR_TOO_BIG);
  2014. return empty;
  2015. }
  2016. str.data = cstr;
  2017. _SET_IF_NOT_NULL(out_err, ERR_OK);
  2018. return str;
  2019. }
  2020. struct str
  2021. str_from_i64(i64 num, enum err *out_err)
  2022. {
  2023. struct str empty = {0};
  2024. struct str str_temp = {0};
  2025. struct str ret = {0};
  2026. LIB_ARG_IF_NOT_NULL_MUST_BE(out_err, ERR_OK, empty);
  2027. str_temp = str_from_i64_temp(num);
  2028. ret.size = str_temp.size;
  2029. ret.should_be_freed = true;
  2030. ret.data = malloc(str_temp.size);
  2031. if ( ret.data == NULL ) {
  2032. LIB_SET_IF_NOT_NULL(out_err, ERR_FAILED_ALLOC);
  2033. return empty;
  2034. }
  2035. memcpy((void *)ret.data, str_temp.data, str_temp.size);
  2036. LIB_SET_IF_NOT_NULL(out_err, ERR_OK);
  2037. return ret;
  2038. }
  2039. struct str
  2040. str_from_i64_temp(i64 num)
  2041. {
  2042. static char buffer[32];
  2043. struct {
  2044. char data[24];
  2045. u8 size;
  2046. } buf = {0};
  2047. u64 _num = 0;
  2048. struct str ret = {0};
  2049. ret.data = buffer;
  2050. if ( num < 0 ) {
  2051. buf.data[buf.size++] = '-';
  2052. num *= -1;
  2053. }
  2054. _num = (u64)num;
  2055. while ( 1 ) {
  2056. u8 mod = (u8) (_num % 10);
  2057. buf.data[buf.size++] = (char) (mod + 48);
  2058. _num /= 10;
  2059. if ( buf.size >= 24 ) {
  2060. _loop:
  2061. buffer[ret.size++] = buf.data[--buf.size];
  2062. if ( buf.size > 0 ) {
  2063. goto _loop;
  2064. }
  2065. }
  2066. if ( _num == 0 ) {
  2067. break;
  2068. }
  2069. }
  2070. if ( buf.size == 0 ) {
  2071. goto exit;
  2072. }
  2073. _out_loop:
  2074. buffer[ret.size++] = buf.data[--buf.size];
  2075. if ( buf.size > 0 ) {
  2076. goto _out_loop;
  2077. }
  2078. exit:
  2079. buffer[ret.size] = 0;
  2080. return ret;
  2081. }
  2082. struct str
  2083. str_dup(struct str str)
  2084. {
  2085. struct str ret = str;
  2086. ret.data = malloc(ret.size * sizeof(*ret.data));
  2087. memcpy((char *)ret.data, str.data, str.size);
  2088. ret.should_be_freed = true;
  2089. return ret;
  2090. }
  2091. intmax_t
  2092. str_to_int(struct str str, enum err *out_err)
  2093. {
  2094. intmax_t res = 0;
  2095. u64 i = 0;
  2096. bool negative = false;
  2097. int digits[] = {
  2098. 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000
  2099. };
  2100. if ( ! str_is_int(str) ) {
  2101. _SET_IF_NOT_NULL(out_err, ERR_NOT_INT);
  2102. return -1;
  2103. }
  2104. if ( str.size > STR_SIZE_LIMIT ) {
  2105. _SET_IF_NOT_NULL(out_err, ERR_TOO_BIG);
  2106. return -1;
  2107. }
  2108. negative = (str.data[0] == '-');
  2109. if ( str.data[0] == '-' || str.data[0] == '+' ) {
  2110. ++str.data;
  2111. --str.size;
  2112. }
  2113. for ( i = 0; i < str.size; ++i ) {
  2114. intmax_t digit = digits[(str.size - (i + 1))];
  2115. res += (str.data[i] - 48) * digit;
  2116. }
  2117. if ( negative == true ) {
  2118. res *= -1;
  2119. }
  2120. _SET_IF_NOT_NULL(out_err, ERR_OK);
  2121. return res;
  2122. }
  2123. struct str
  2124. str_rstrip(struct str str)
  2125. {
  2126. while ( isspace(str.data[str.size-1]) ) {
  2127. --str.size;
  2128. }
  2129. return str;
  2130. }
  2131. struct str
  2132. str_lstrip(struct str str)
  2133. {
  2134. while ( isspace(*str.data) ) {
  2135. ++str.data;
  2136. --str.size;
  2137. }
  2138. return str;
  2139. }
  2140. struct str
  2141. str_strip(struct str str)
  2142. {
  2143. return str_lstrip(str_rstrip(str));
  2144. }
  2145. u64
  2146. str_lindex(struct str str, char c)
  2147. {
  2148. u64 i = 0;
  2149. for ( ; i < str.size; ++i ) {
  2150. if ( str.data[i] == c ) {
  2151. return i;
  2152. }
  2153. }
  2154. return (u64) -1;
  2155. }
  2156. u64
  2157. str_rindex(struct str str, char c)
  2158. {
  2159. u64 i = str.size - 1;
  2160. for ( ; i > 0; --i ) {
  2161. if ( str.data[i] == c ) {
  2162. return i;
  2163. }
  2164. }
  2165. if ( str.data[i] == c ) {
  2166. return i;
  2167. }
  2168. return (u64) -1;
  2169. }
  2170. struct str_tokenizer
  2171. str_tokenize(struct str str, char c)
  2172. {
  2173. struct str_tokenizer st = {0};
  2174. st.str = str;
  2175. st.c = c;
  2176. return st;
  2177. }
  2178. struct str_tokenizer
  2179. str_tokenize_func(struct str str, bool (*f)(char c))
  2180. {
  2181. struct str_tokenizer st = {0};
  2182. st.str = str;
  2183. st.f = f;
  2184. return st;
  2185. }
  2186. struct str
  2187. str_tokenizer_next(struct str_tokenizer *st)
  2188. {
  2189. struct str str;
  2190. if ( st == NULL ) {
  2191. goto ret_err;
  2192. }
  2193. if ( st->cur >= st->str.size ) {
  2194. goto ret_done;
  2195. }
  2196. if ( st->str.data[st->cur] == '\0' ) {
  2197. goto ret_done;
  2198. }
  2199. str = st->str;
  2200. str.data += st->cur;
  2201. str.size = 0;
  2202. if ( st->f != NULL ) {
  2203. while ( (! st->f(str.data[str.size]))
  2204. && st->cur < st->str.size ) {
  2205. ++str.size;
  2206. ++st->cur;
  2207. }
  2208. } else {
  2209. while ( str.data[str.size] != st->c
  2210. && st->cur < st->str.size ) {
  2211. ++str.size;
  2212. ++st->cur;
  2213. }
  2214. }
  2215. ++st->cur;
  2216. if ( str.size == 0 ) {
  2217. goto ret_empty;
  2218. }
  2219. return str;
  2220. ret_empty:
  2221. str.data = "";
  2222. str.size = 0;
  2223. return str;
  2224. ret_done:
  2225. str.data = "";
  2226. str.size = (u64) -1;
  2227. return str;
  2228. ret_err:
  2229. str.data = "";
  2230. str.size = (u64) -2;
  2231. return str;
  2232. }
  2233. struct str
  2234. str_slice(struct str str, u64 from, u64 to)
  2235. {
  2236. if ( from > str.size ) {
  2237. goto ret_err;
  2238. }
  2239. if ( from > to ) {
  2240. goto ret_err;
  2241. }
  2242. to = ( to > str.size ) * str.size \
  2243. + ( to <= str.size ) * to;
  2244. str.data += from;
  2245. str.size = to - from;
  2246. return str;
  2247. ret_err:
  2248. str.data = "";
  2249. str.size = (u64) -2;
  2250. return str;
  2251. }
  2252. bool
  2253. str_eq_cstr(struct str str, const char *cstr, u64 cstr_size)
  2254. {
  2255. u64 i = 0;
  2256. if ( str.size != cstr_size ) {
  2257. return false;
  2258. }
  2259. for ( i = 0; i < str.size; ++i ) {
  2260. if ( str.data[i] != cstr[i] ) {
  2261. return false;
  2262. }
  2263. }
  2264. return true;
  2265. }
  2266. bool
  2267. str_eq_str(struct str str1, struct str str2)
  2268. {
  2269. u64 i = 0;
  2270. if ( str1.size != str2.size ) {
  2271. return false;
  2272. }
  2273. for ( i = 0; i < str1.size; ++i ) {
  2274. if ( str1.data[i] != str2.data[i] ) {
  2275. return false;
  2276. }
  2277. }
  2278. return true;
  2279. }
  2280. bool
  2281. str_startswith_cstr(struct str str, const char *cstr, u64 cstr_size)
  2282. {
  2283. u64 i = 0;
  2284. if ( cstr_size > str.size ) {
  2285. return false;
  2286. }
  2287. for ( i = 0; i < cstr_size; ++i ) {
  2288. if ( str.data[i] != cstr[i] ) {
  2289. return false;
  2290. }
  2291. }
  2292. return true;
  2293. }
  2294. bool
  2295. str_is_int(struct str str)
  2296. {
  2297. u64 i = 0;
  2298. if ( str.size == 0 ) {
  2299. return false;
  2300. }
  2301. if ( str.size == 1 ) {
  2302. return isdigit(str.data[0]);
  2303. }
  2304. i += (str.data[0] == '-' || str.data[0] == '+');
  2305. for ( ; i < str.size; ++i ) {
  2306. if ( ! isdigit(str.data[i]) ) {
  2307. return false;
  2308. }
  2309. }
  2310. return true;
  2311. }
  2312. struct str
  2313. str_builder_to_str(const struct str_builder *str_bldr)
  2314. {
  2315. struct str str = {0};
  2316. str.data = str_bldr->data;
  2317. str.size = str_bldr->size;
  2318. str.should_be_freed = true;
  2319. return str;
  2320. }
  2321. # endif /* defined(WANT_STR) || defined(WANT_ALL) */
  2322. /* ----------------------------- END STR IMP ------------------------------- */
  2323. /* ---------------------------- START ENV IMP ------------------------------ */
  2324. # if defined(WANT_ENV) || defined(WANT_ALL)
  2325. struct str
  2326. getenv_as_str(const char *name, enum err *out_err)
  2327. {
  2328. struct str empty = {0};
  2329. struct str str = {0};
  2330. char *res = NULL;
  2331. LIB_ARG_IF_NOT_NULL_MUST_BE(out_err, ERR_OK, empty);
  2332. LIB_ARG_MUST_NOT_BE_NULL(name, out_err, empty);
  2333. res = getenv(name);
  2334. if ( res == NULL ) {
  2335. LIB_SET_IF_NOT_NULL(out_err, ERR_NOT_FOUND);
  2336. return str;
  2337. }
  2338. return str_from_cstr_ns(res, out_err);
  2339. }
  2340. struct path
  2341. getenv_as_path(const char *name, enum err *out_err)
  2342. {
  2343. struct path empty = {0};
  2344. struct str str = {0};
  2345. enum err err;
  2346. LIB_ARG_IF_NOT_NULL_MUST_BE(out_err, ERR_OK, empty);
  2347. LIB_ARG_MUST_NOT_BE_NULL(name, out_err, empty);
  2348. str = getenv_as_str(name, &err);
  2349. if ( err ) {
  2350. LIB_SET_IF_NOT_NULL(out_err, err);
  2351. return empty;
  2352. }
  2353. return path_from_str(str, out_err);
  2354. }
  2355. # endif /* defined(WANT_ENV) || defined(WANT_ALL) */
  2356. /* ----------------------------- END ENV IMP ------------------------------- */
  2357. /* ---------------------------- START PATH IMP ----------------------------- */
  2358. # if defined(WANT_PATH) || defined(WANT_ALL)
  2359. struct path
  2360. path_from_str(struct str str, enum err *out_err)
  2361. {
  2362. struct path path = {0};
  2363. if ( str.size > PATH_SIZE_LIMIT ) {
  2364. _SET_IF_NOT_NULL(out_err, ERR_TOO_BIG);
  2365. return path;
  2366. }
  2367. memcpy(path.data, str.data, str.size);
  2368. path.size = str.size;
  2369. _SET_IF_NOT_NULL(out_err, ERR_OK);
  2370. return path;
  2371. }
  2372. struct path
  2373. path_from_cstr(const char *cstr, u64 cstr_size, enum err *out_err)
  2374. {
  2375. enum err err;
  2376. struct str str;
  2377. struct path path = {0};
  2378. str = str_from_cstr(cstr, cstr_size, &err);
  2379. if ( err ) {
  2380. _SET_IF_NOT_NULL(out_err, err);
  2381. return path;
  2382. }
  2383. return path_from_str(str, out_err);
  2384. }
  2385. struct path
  2386. path_from_cstr_ns(const char *cstr, enum err *out_err)
  2387. {
  2388. enum err err;
  2389. struct str str;
  2390. struct path path = {0};
  2391. _ARG_IF_NOT_NULL_MUST_BE(out_err, ERR_OK, path);
  2392. str = str_from_cstr_ns(cstr, &err);
  2393. if ( err ) {
  2394. _SET_IF_NOT_NULL(out_err, err);
  2395. return path;
  2396. }
  2397. return path_from_str(str, out_err);
  2398. }
  2399. struct path
  2400. path_get_xdg_state_home(enum err *out_err)
  2401. {
  2402. struct path empty = {0};
  2403. struct path path = {0};
  2404. enum err err;
  2405. LIB_ARG_IF_NOT_NULL_MUST_BE(out_err, ERR_OK, empty);
  2406. path = getenv_as_path("XDG_STATE_HOME", &err);
  2407. if ( err == ERR_NOT_FOUND ) {
  2408. path = getenv_as_path("HOME", &err);
  2409. if ( err ) {
  2410. _SET_IF_NOT_NULL(out_err, err);
  2411. return empty;
  2412. }
  2413. path = path_join_with_cstr(path, ".local/state", 12, NULL);
  2414. } else if ( err ) {
  2415. _SET_IF_NOT_NULL(out_err, err);
  2416. return empty;
  2417. }
  2418. _SET_IF_NOT_NULL(out_err, ERR_OK);
  2419. return path;
  2420. }
  2421. struct path
  2422. path_get_xdg_data_home(enum err *out_err)
  2423. {
  2424. struct path empty = {0};
  2425. struct path path = {0};
  2426. enum err err;
  2427. LIB_ARG_IF_NOT_NULL_MUST_BE(out_err, ERR_OK, empty);
  2428. path = getenv_as_path("XDG_DATA_HOME", &err);
  2429. if ( err == ERR_NOT_FOUND ) {
  2430. path = getenv_as_path("HOME", &err);
  2431. if ( err ) {
  2432. _SET_IF_NOT_NULL(out_err, err);
  2433. return empty;
  2434. }
  2435. path = path_join_with_cstr(path, ".local/share", 12, NULL);
  2436. } else if ( err ) {
  2437. _SET_IF_NOT_NULL(out_err, err);
  2438. return empty;
  2439. }
  2440. _SET_IF_NOT_NULL(out_err, ERR_OK);
  2441. return path;
  2442. }
  2443. struct path
  2444. path_dirname(struct path path, enum err *out_err)
  2445. {
  2446. struct path empty = {0};
  2447. struct path ret = {0};
  2448. u64 i = 0;
  2449. if ( path.size == 0 || path.data[0] == 0 ) {
  2450. _SET_IF_NOT_NULL(out_err, ERR_PATH_EMPTY);
  2451. return empty;
  2452. }
  2453. i = path.size;
  2454. loop:
  2455. --i;
  2456. if ( path.data[i] == '/' ) {
  2457. goto exit_loop;
  2458. }
  2459. if ( i == 0 ) {
  2460. ret.data[0] = '.';
  2461. ret.data[1] = 0;
  2462. ret.size = 1;
  2463. goto ret_ok;
  2464. }
  2465. goto loop;
  2466. exit_loop:
  2467. memcpy(ret.data, path.data, i);
  2468. ret.size = i;
  2469. ret_ok:
  2470. _SET_IF_NOT_NULL(out_err, ERR_OK);
  2471. return ret;
  2472. }
  2473. struct path
  2474. path_join(struct path lhs, struct path rhs, enum err *out_err)
  2475. {
  2476. struct path path = {0};
  2477. if ( (lhs.size + rhs.size + 1) > PATH_SIZE_LIMIT ) {
  2478. _SET_IF_NOT_NULL(out_err, ERR_TOO_BIG);
  2479. return path;
  2480. }
  2481. /* TODO: Check if lhs or rhs have / at the end and start respectively */
  2482. path.size = (lhs.size + rhs.size + 1);
  2483. memcpy(path.data, lhs.data, lhs.size);
  2484. path.data[lhs.size] = '/';
  2485. memcpy(path.data + lhs.size + 1, rhs.data, rhs.size);
  2486. return path;
  2487. }
  2488. struct path
  2489. path_join_with_str(struct path lhs, struct str rhs, enum err *out_err)
  2490. {
  2491. struct path path = {0};
  2492. enum err err;
  2493. path = path_from_str(rhs, &err);
  2494. if ( err ) {
  2495. _SET_IF_NOT_NULL(out_err, err);
  2496. return path;
  2497. }
  2498. return path_join(lhs, path, out_err);
  2499. }
  2500. struct path
  2501. path_join_with_cstr(struct path lhs, const char *rhs, u64 rhs_size,
  2502. enum err *out_err)
  2503. {
  2504. struct path path = {0};
  2505. enum err err;
  2506. path = path_from_cstr(rhs, rhs_size, &err);
  2507. if ( err ) {
  2508. _SET_IF_NOT_NULL(out_err, err);
  2509. return path;
  2510. }
  2511. return path_join(lhs, path, out_err);
  2512. }
  2513. struct path
  2514. path_join_with_cstr_ns(struct path lhs, const char *rhs, enum err *out_err)
  2515. {
  2516. struct path empty = {0};
  2517. struct path path = {0};
  2518. enum err err;
  2519. _ARG_MUST_NOT_BE_NULL(rhs, out_err, empty);
  2520. path = path_from_cstr_ns(rhs, &err);
  2521. if ( err ) {
  2522. _SET_IF_NOT_NULL(out_err, err);
  2523. return empty;
  2524. }
  2525. return path_join(lhs, path, out_err);
  2526. }
  2527. bool
  2528. path_exists(struct path path, int (*access)(const char *, int))
  2529. {
  2530. return access(path.data, F_OK) == 0;
  2531. }
  2532. bool
  2533. path_can_read(struct path path, int (*access)(const char *, int))
  2534. {
  2535. return access(path.data, R_OK) == 0;
  2536. }
  2537. bool
  2538. path_can_write(struct path path, int (*access)(const char *, int))
  2539. {
  2540. return access(path.data, W_OK) == 0;
  2541. }
  2542. bool
  2543. path_can_execute(struct path path, int (*access)(const char *, int))
  2544. {
  2545. return access(path.data, X_OK) == 0;
  2546. }
  2547. bool
  2548. path_mkdir(struct path path, u32 mode, bool do_create_parents,
  2549. int (*mkdir)(const char *, u32), enum err *out_err)
  2550. {
  2551. u64 i = 0;
  2552. _ARG_MUST_NOT_BE_NULL(mkdir, out_err, false);
  2553. if ( path.size == 1 ) {
  2554. _SET_IF_NOT_NULL(out_err, ERR_PATH_INVALID);
  2555. return 1;
  2556. }
  2557. if ( do_create_parents ) {
  2558. for ( i = 1; i < path.size; ++i ) {
  2559. if ( path.data[i] == '/' ) {
  2560. path.data[i] = 0;
  2561. mkdir(path.data, mode);
  2562. path.data[i] = '/';
  2563. }
  2564. }
  2565. }
  2566. if ( ! mkdir(path.data, mode) ) {
  2567. _SET_IF_NOT_NULL(out_err, ERR_MKDIR_FAILED);
  2568. return false;
  2569. }
  2570. _SET_IF_NOT_NULL(out_err, ERR_OK);
  2571. return true;
  2572. }
  2573. /*
  2574. bool
  2575. path_touch(struct path path, int (*open)(const char *, int), enum err *out_err)
  2576. {
  2577. int fd = -1;
  2578. _ARG_IF_NOT_NULL_MUST_BE(out_err, ERR_OK, false);
  2579. _ARG_MUST_NOT_BE_NULL(open, out_err, false);
  2580. fd = open(path.data, 0100 | 00644);
  2581. if ( fd == -1 ) {
  2582. _SET_IF_NOT_NULL(out_err, ERR_PATH_FAILED_OPEN);
  2583. return false;
  2584. }
  2585. _SET_IF_NOT_NULL(out_err, ERR_OK);
  2586. return true;
  2587. }
  2588. */
  2589. /* TODO: Replace this */
  2590. #include <fcntl.h>
  2591. #include <stdlib.h>
  2592. #include <unistd.h>
  2593. #include <sys/stat.h>
  2594. struct file
  2595. path_file_read_all(const struct path *path, enum err *out_err)
  2596. {
  2597. struct file empty = {0};
  2598. struct file file = {0};
  2599. i64 file_size = -1;
  2600. i32 fd = -1;
  2601. _ARG_IF_NOT_NULL_MUST_BE(out_err, ERR_OK, empty);
  2602. _ARG_MUST_NOT_BE_NULL(path, out_err, empty);
  2603. fd = open(path->data, O_RDONLY);
  2604. if ( fd < 0 ) {
  2605. _SET_IF_NOT_NULL(out_err, ERR_FAILED_OPEN);
  2606. goto exit_err;
  2607. }
  2608. file_size = lseek(fd, 0, SEEK_END);
  2609. if ( file_size < 0 ) {
  2610. _SET_IF_NOT_NULL(out_err, ERR_PATH_FILE_FAILED_SEEK);
  2611. goto exit_err;
  2612. }
  2613. lseek(fd, 0, SEEK_SET);
  2614. file.size = (u64) file_size;
  2615. if ( file.size == 0 ) {
  2616. _SET_IF_NOT_NULL(out_err, ERR_PATH_FILE_EMPTY);
  2617. goto exit_err;
  2618. }
  2619. file.data = calloc(file.size + 1, sizeof(u8));
  2620. if ( file.data == NULL ) {
  2621. _SET_IF_NOT_NULL(out_err, ERR_FAILED_ALLOC);
  2622. goto exit_err;
  2623. }
  2624. {
  2625. i64 rd = read(fd, file.data, file.size);
  2626. if ( rd < 0 ) {
  2627. _SET_IF_NOT_NULL(out_err, ERR_FAILED_READ);
  2628. goto exit_err;
  2629. }
  2630. if ( rd == 0 ) {
  2631. _SET_IF_NOT_NULL(out_err, ERR_PATH_FILE_EMPTY);
  2632. goto exit_err;
  2633. }
  2634. }
  2635. if ( close(fd) != 0 ) {
  2636. /* It should be possible to handle EIO */
  2637. _SET_IF_NOT_NULL(out_err, ERR_FAILED_CLOSE);
  2638. return empty;
  2639. }
  2640. _SET_IF_NOT_NULL(out_err, ERR_OK);
  2641. return file;
  2642. exit_err:
  2643. if ( file.data != NULL ) {
  2644. free(file.data);
  2645. }
  2646. if ( fd > 0 ) {
  2647. if ( close(fd) != 0 ) {
  2648. /* It should be possible to handle EIO */
  2649. _SET_IF_NOT_NULL(out_err, ERR_FAILED_CLOSE);
  2650. return empty;
  2651. }
  2652. }
  2653. return empty;
  2654. }
  2655. enum err
  2656. path_file_save(const struct path *path, const struct file *file,
  2657. enum err *out_err)
  2658. {
  2659. enum err err = ERR_OK;
  2660. i64 wrote = -1;
  2661. i32 fd = -1;
  2662. _ARG_IF_NOT_NULL_MUST_BE_RET_IT(out_err, ERR_OK);
  2663. _ARG_MUST_NOT_BE_NULL_SET_RET_ERR(path, out_err);
  2664. _ARG_MUST_NOT_BE_NULL_SET_RET_ERR(file, out_err);
  2665. fd = open(path->data, O_WRONLY | O_CREAT | O_TRUNC,
  2666. S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
  2667. if ( fd < 0 ) {
  2668. err = ERR_FAILED_OPEN;
  2669. goto exit;
  2670. }
  2671. wrote = write(fd, file->data, file->size);
  2672. if ( wrote == -1 ) {
  2673. err = ERR_FAILED_WRITE;
  2674. goto exit;
  2675. }
  2676. if ( ((u64) wrote) != file->size ) {
  2677. err = ERR_WROTE_WRONG_AMOUNT;
  2678. goto exit;
  2679. }
  2680. err = ERR_OK;
  2681. exit:
  2682. if ( close(fd) != 0 ) {
  2683. /* It should be possible to handle EIO */
  2684. err = ERR_FAILED_CLOSE;
  2685. goto exit;
  2686. }
  2687. _SET_IF_NOT_NULL(out_err, err);
  2688. return err;
  2689. }
  2690. # endif /* defined(WANT_PATH) || defined(WANT_ALL) */
  2691. /* ----------------------------- END PATH IMP ------------------------------ */
  2692. /* ---------------------------- START SGFX IMP ----------------------------- */
  2693. # if defined(WANT_SGFX) || defined(WANT_ALL)
  2694. enum err
  2695. sgfx_canvas_populate(struct sgfx_canvas *canvas, enum err *out_err)
  2696. {
  2697. _ARG_IF_NOT_NULL_MUST_BE_RET_IT(out_err, ERR_OK);
  2698. _ARG_MUST_NOT_BE_NULL_SET_RET_ERR(canvas, out_err);
  2699. canvas->width = SGFX_WIDTH;
  2700. canvas->height = SGFX_HEIGHT;
  2701. canvas->cap = SGFX_WIDTH * SGFX_HEIGHT;
  2702. _SET_IF_NOT_NULL(out_err, ERR_OK)
  2703. return ERR_OK;
  2704. }
  2705. enum err
  2706. sgfx_canvas_fill(struct sgfx_canvas *canvas, u32 color, enum err *out_err)
  2707. {
  2708. u64 i = 0;
  2709. _ARG_IF_NOT_NULL_MUST_BE_RET_IT(out_err, ERR_OK);
  2710. _ARG_MUST_NOT_BE_NULL_SET_RET_ERR(canvas, out_err);
  2711. for ( i = 0; i < canvas->cap; ++i ) {
  2712. canvas->pixels[i] = color;
  2713. }
  2714. _SET_IF_NOT_NULL(out_err, ERR_OK)
  2715. return ERR_OK;
  2716. }
  2717. enum err
  2718. sgfx_canvas_fill_rect(struct sgfx_canvas *canvas,
  2719. struct u64vec2 pos, struct u64vec2s size, u32 color,
  2720. enum err *out_err)
  2721. {
  2722. u64 i = 0;
  2723. u64 j = 0;
  2724. u64 startp = 0;
  2725. u64 endp = 0;
  2726. _ARG_IF_NOT_NULL_MUST_BE_RET_IT(out_err, ERR_OK);
  2727. _ARG_MUST_NOT_BE_NULL_SET_RET_ERR(canvas, out_err);
  2728. /* TODO: Create a diferent error for when size lands outside canvas */
  2729. if ( pos.x > canvas->width || pos.y > canvas->height
  2730. || (pos.x + size.w) > canvas->width
  2731. || (pos.y + size.h) > canvas->height ) {
  2732. _SET_IF_NOT_NULL(out_err, ERR_SGFX_POS_OUTSIDE_CANVAS);
  2733. return ERR_SGFX_POS_OUTSIDE_CANVAS;
  2734. }
  2735. /*
  2736. printf("pos.x -> %ld || pos.y -> %ld\n", pos.x, pos.y);
  2737. printf("size.w -> %ld || size.h -> %ld\n", size.w, size.h);
  2738. printf("(pos.x + size.w) -> %ld || (pos.y + size.h) -> %ld\n", (pos.x + size.w), (pos.y + size.h));
  2739. */
  2740. startp = (canvas->width * pos.y) + pos.x;
  2741. endp = (canvas->width * (pos.y + size.h)) + (pos.x + size.w);
  2742. if ( endp >= canvas->cap ) {
  2743. endp = canvas->cap;
  2744. }
  2745. for ( i = startp; i < endp; i += canvas->width ) {
  2746. for ( j = i; j < i+size.w; ++j ) {
  2747. canvas->pixels[j] = color;
  2748. }
  2749. }
  2750. _SET_IF_NOT_NULL(out_err, ERR_OK);
  2751. return ERR_OK;
  2752. }
  2753. enum err
  2754. sgfx_canvas_save_to_ppm(const struct sgfx_canvas *canvas, struct path path,
  2755. enum err *out_err)
  2756. {
  2757. #define __T(s) s, cstr_len_max(s, 255, NULL, out_err)
  2758. /* enum err err = ERR_OK; */
  2759. /* u64 i = 0; */
  2760. /* i32 fd = -1; */
  2761. (void) path;
  2762. _ARG_IF_NOT_NULL_MUST_BE_RET_IT(out_err, ERR_OK);
  2763. _ARG_MUST_NOT_BE_NULL_SET_RET_ERR(canvas, out_err);
  2764. /* TODO: Check the errors */
  2765. /*
  2766. fd = open(path.data, O_RDWR | O_CREAT, 00644);
  2767. if ( err ) {
  2768. _SET_IF_NOT_NULL(out_err, err);
  2769. return err;
  2770. }
  2771. write(fd, __T("P6\n"));
  2772. write(fd, __T(SGFX_WIDTH_CSTR"\n"));
  2773. write(fd, __T(SGFX_HEIGHT_CSTR"\n"));
  2774. write(fd, __T("255\n"));
  2775. for ( i = 0; i < canvas->cap; ++i ) {
  2776. struct sgfx_rgb rgb = {0};
  2777. rgb.r = (u8)(canvas->pixels[i] >> 24);
  2778. rgb.g = (u8)(canvas->pixels[i] >> 16);
  2779. rgb.b = (u8)(canvas->pixels[i] >> 8);
  2780. write(fd, &rgb, sizeof(struct sgfx_rgb));
  2781. }
  2782. close(fd);
  2783. */
  2784. _SET_IF_NOT_NULL(out_err, ERR_OK);
  2785. return ERR_OK;
  2786. #undef __T
  2787. }
  2788. # endif /* defined(WANT_SGFX) || defined(WANT_ALL) */
  2789. /* ----------------------------- END SGFX IMP ------------------------------ */
  2790. /* --------------------------- START RAYLIB IMP ---------------------------- */
  2791. # if defined(WANT_RAYLIB) || defined(WANT_ALL)
  2792. # if defined(RAYLIB_H)
  2793. enum err
  2794. raylib_draw_str(const struct str_builder *str, Font font, Vector2 position,
  2795. float fontSize, float spacing, Color tint, enum err *out_err)
  2796. {
  2797. enum err err = ERR_OK;
  2798. char *cstr = NULL;
  2799. _ARG_IF_NOT_NULL_MUST_BE_RET_IT(out_err, ERR_OK);
  2800. cstr = calloc(str->size + 1, sizeof(char));
  2801. if ( cstr == NULL ) {
  2802. err = ERR_FAILED_ALLOC;
  2803. goto exit;
  2804. }
  2805. memcpy(cstr, str->data, str->size);
  2806. DrawTextEx(font, cstr, position, fontSize, spacing, tint);
  2807. err = ERR_OK;
  2808. exit:
  2809. if ( cstr != NULL ) {
  2810. free(cstr);
  2811. }
  2812. _SET_IF_NOT_NULL(out_err, err);
  2813. return err;
  2814. }
  2815. # endif /* defined(RAYLIB_H) */
  2816. # endif /* defined(WANT_RAYLIB) || defined(WANT_ALL) */
  2817. /* ---------------------------- END RAYLIB IMP ----------------------------- */
  2818. # ifdef LIB_H_CTYPE
  2819. # undef LIB_H_CTYPE
  2820. # undef isspace
  2821. # undef isdigit
  2822. # endif /* LIB_H_CTYPE */
  2823. # ifdef LIB_H_STRING
  2824. # undef LIB_H_STRING
  2825. # undef memcpy
  2826. # endif /* LIB_H_STRING */
  2827. # undef _SET_IF_NOT_NULL
  2828. # undef _ARG_IF_NOT_NULL_MUST_BE
  2829. # undef _ARG_MUST_NOT_BE_NULL
  2830. # endif /* defined(IMP) || defined(IMP_STR) */
  2831. # ifdef LIB_H_ALLOC_FUNC
  2832. # undef LIB_H_ALLOC_FUNC
  2833. # undef ALLOC_FUNC
  2834. # endif /* LIB_H_ALLOC_FUNC */
  2835. # ifdef LIB_H_STDBOOL
  2836. # undef LIB_H_STDBOOL
  2837. # undef bool
  2838. # undef true
  2839. # undef false
  2840. # endif /* LIB_H_STDBOOL */
  2841. # ifdef LIB_H_NULL
  2842. # undef LIB_H_NULL
  2843. # undef NULL
  2844. # endif /* LIB_H_NULL */
  2845. # ifdef LIB_H_UNISTD
  2846. # undef LIB_H_UNISTD
  2847. # undef R_OK
  2848. # undef W_OK
  2849. # undef X_OK
  2850. # undef F_OK
  2851. # endif /* LIB_H_UNISTD */
  2852. # ifdef LIB_H_STDINT
  2853. # undef LIB_H_STDINT
  2854. # undef intmax_t
  2855. # endif /* LIB_H_STDINT */
  2856. #endif /* LIB_H */