/
custom_library_example.h
13965 lines (12425 loc) · 538 KB
/
custom_library_example.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
/*
* 2023, Gregory Cohen <gregorycohennew@gmail.com>
*
*
* DONATION REQUEST: If this free software has helped you and you find
* it valuable, please consider making a donation to support the ongoing
* development and maintenance of this project. Your contribution helps
* ensure the availability of this library to the community and encourages
* further improvements.
*
*
* Donations can be made at:
* https://www.paypal.com/paypalme/cfoundationallib
*
*
*
* This code is in the public domain.
*
* You are free to use it for any commercial or noncommercial purpose.
*
*/
#ifndef MY_COMPANY__FOUNDATIONAL_LIB_HEADER_GUARD
#define MY_COMPANY__FOUNDATIONAL_LIB_HEADER_GUARD
#ifdef _WIN32
#define _CRT_RAND_S
#endif
#include <stdint.h> /* FOR SIZE_MAX */
#include <ctype.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
/* Make sure memmem() is defined in all cases to avoid warnings or errors. */
void *memmem(const void *haystack, size_t haystacklen, const void *needle, size_t needlelen);
// structs (types)
struct MY_COMPANY_Dict;
struct MY_COMPANY_FrozenDict;
struct MY_COMPANY_Set;
struct MY_COMPANY_FrozenSet;
#ifndef MY_COMPANY_FOUNDATIONAL_LIB_AGGRESSIVE_DIE_TYPE
/**
* @brief Type of the aggressive die variable.
*
* This macro defines the type of the aggressive die variable, which
* uses 1 byte of overhead by default. It can be configured as static
* or nonstatic based on user preference.
*/
#define MY_COMPANY_FOUNDATIONAL_LIB_AGGRESSIVE_DIE_TYPE unsigned char
#endif
/*
* ---------------------------------------------------------------------
*
* This code is in the Public domain. It is 100% original code, and
* wholly in the public domain.
*
* It is by Gregory Cohen <gregorycohennew@gmail.com>, No Copyright, 2023.
*
* ---------------------------------------------------------------------
*
* This code is quite usable. While more and more tests can
* be added (currently there is the initial test program, and
* another test program that is designed to stress-test every
* single function, and a third work-in-progress test suite),
* it does not change the fact that this code fundamentally
* works. Try out the `run_test_suite` script, and if
* everything works, it will tell you in green text that
* things work on your system. Any errors or warnings are not
* tolerated. This code should be usable for production.
* Configure to your needs. Generate your own with a custom
* prefix with the script at the top-level of the code.
* Philosophy of this is in the 'Articles' folder - and it is
* very unequivocal. -Gregory
*
* ---------------------------------------------------------------------
*/
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wpragmas"
#pragma GCC diagnostic ignored "-Wformat"
#pragma GCC diagnostic ignored "-Wformat-extra-args"
/* -DMY_COMPANY_FOUNDATIONAL_LIB_UNSAFE_FUNCTIONS_ENABLED=0 to turn off popen() and MY_COMPANY_backticks() and MY_COMPANY_shellescape(). */
/** @brief
* Disable this section if you are maybe getting compilation errors (-DMY_COMPANY_FOUNDATIONAL_LIB_USE_STATIC_ASSERTS_FOR_SAFETY=0).
* Or you can try using a modern compiler C11, C++11, though this is not necessary. Foundationallib should work with all
* C and C++ compilers.
*/
#ifndef MY_COMPANY_FOUNDATIONAL_LIB_USE_STATIC_ASSERTS_FOR_SAFETY
#define MY_COMPANY_FOUNDATIONAL_LIB_USE_STATIC_ASSERTS_FOR_SAFETY 1
#endif
#if MY_COMPANY_FOUNDATIONAL_LIB_USE_STATIC_ASSERTS_FOR_SAFETY
#ifdef __cplusplus
#ifndef MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_Static_assert
#define MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_Static_assert static_assert
#endif
#else
#ifndef MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_Static_assert
#define MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_Static_assert _Static_assert
#endif
#endif
#define MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_STATIC_ASSERT_MSG(true_cond, failure_message) MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_Static_assert((true_cond), failure_message)
#define MY_COMPANY_FOUNDATIONAL_LIB_STATIC_ASSERT(true_cond) MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_Static_assert((true_cond), "(" #true_cond ") failed")
#define MY_COMPANY_FOUNDATIONAL_LIB_SIZE_STRING_OF_NUMBER_SIZE_PLUS_ZERO_TERMINATOR 21 /* length of "18446744073709551615" plus 1 == 21 */
MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_STATIC_ASSERT_MSG((sizeof(size_t) <= 8 && MY_COMPANY_FOUNDATIONAL_LIB_SIZE_STRING_OF_NUMBER_SIZE_PLUS_ZERO_TERMINATOR >= 21), "Increase SIZE_STRING_OF_NUMBER_SIZE_PLUS_ZERO_TERMINATOR to more than 21");
#endif
#ifndef MY_COMPANY_FOUNDATIONAL_LIB_UNSAFE_FUNCTIONS_ENABLED
/* Default true */
#define MY_COMPANY_FOUNDATIONAL_LIB_UNSAFE_FUNCTIONS_ENABLED 1
#endif
#ifndef MY_COMPANY_FOUNDATIONAL_LIB_VA_LIST
#define MY_COMPANY_FOUNDATIONAL_LIB_VA_LIST va_list
#endif
#ifndef MY_COMPANY_FOUNDATIONAL_LIB_VA_START
#define MY_COMPANY_FOUNDATIONAL_LIB_VA_START va_start
#endif
#ifndef MY_COMPANY_FOUNDATIONAL_LIB_VA_ARG
#define MY_COMPANY_FOUNDATIONAL_LIB_VA_ARG va_arg
#endif
#ifndef MY_COMPANY_FOUNDATIONAL_LIB_VA_END
#define MY_COMPANY_FOUNDATIONAL_LIB_VA_END va_end
#endif
#ifdef __GNUC__
#ifndef MY_COMPANY_FOUNDATIONAL_LIB_LIBC_LOCKING_IO_OPERATIONS
/* MY_COMPANY_Set this to 0 to make the IO faster. */
#define MY_COMPANY_FOUNDATIONAL_LIB_LIBC_LOCKING_IO_OPERATIONS 1
#endif
#ifndef MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_ISSPACE
#define MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_ISSPACE __builtin_isspace
#endif
#ifndef MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_ISALPHA
#define MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_ISALPHA __builtin_isalpha
#endif
#ifndef MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_ISALNUM
#define MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_ISALNUM __builtin_isalnum
#endif
#ifndef MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_ISDIGIT
#define MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_ISDIGIT __builtin_isdigit
#endif
#ifndef MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_ISPRINT
#define MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_ISPRINT __builtin_isprint
#endif
#ifndef MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_ISUPPER
#define MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_ISUPPER __builtin_isupper
#endif
#ifndef MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_ISLOWER
#define MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_ISLOWER __builtin_islower
#endif
#ifndef MY_COMPANY_MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_STRLEN
#define MY_COMPANY_MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_STRLEN __builtin_strlen
#endif
#ifndef MY_COMPANY_MY_COMPANY_MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_PRINTF
#define MY_COMPANY_MY_COMPANY_MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_PRINTF __builtin_printf
#endif
#ifndef MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_SPRINTF
#define MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_SPRINTF __builtin_sprintf
#endif
#ifndef MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_SNPRINTF
#define MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_SNPRINTF __builtin_snprintf
#endif
#ifndef MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_VSNPRINTF
#define MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_VSNPRINTF __builtin_vsnprintf
#endif
#ifndef MY_COMPANY_MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_FPRINTF
#if MY_COMPANY_FOUNDATIONAL_LIB_LIBC_LOCKING_IO_OPERATIONS /* Default mode IS thread-safe. */
#define MY_COMPANY_MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_FPRINTF __builtin_fprintf
#else
#define MY_COMPANY_MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_FPRINTF __builtin_fprintf /* GLIBC doesn't have an unlocked version of this. This is not a good thing. */
#endif
#endif
#ifndef MY_COMPANY_MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_FPUTS
#if MY_COMPANY_FOUNDATIONAL_LIB_LIBC_LOCKING_IO_OPERATIONS /* Default mode IS thread-safe. */
#define MY_COMPANY_MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_FPUTS __builtin_fputs
#else
#define MY_COMPANY_MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_FPUTS __builtin_fputs_unlocked
#endif
#endif
#ifndef MY_COMPANY_MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_PUTCHAR
#if MY_COMPANY_FOUNDATIONAL_LIB_LIBC_LOCKING_IO_OPERATIONS /* Default mode IS thread-safe. */
#define MY_COMPANY_MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_PUTCHAR __builtin_putchar
#else
#define MY_COMPANY_MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_PUTCHAR __builtin_putchar_unlocked
#endif
#endif
#ifndef MY_COMPANY_MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_FPUTC
#if MY_COMPANY_FOUNDATIONAL_LIB_LIBC_LOCKING_IO_OPERATIONS /* Default mode IS thread-safe. */
#define MY_COMPANY_MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_FPUTC __builtin_fputc
#else
#define MY_COMPANY_MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_FPUTC __builtin_fputc_unlocked
#endif
#endif
#ifndef MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_STRPBRK
#define MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_STRPBRK __builtin_strpbrk
#endif
/*
* benchmark_libc.c output
*
* memcpy 0.000010
*
* memcpy copy 0.000005
* __builtin_memcpy 0.000003
* Custom memcpy() (probably using __builtin_memcpy()) is 2.000000 times faster than default memcpy()
* __builtin_memcpy() is 3.333333 times faster than default memcpy()
*
* This means, theoretically, a 6-day operation could take less than 2 days. That's speed.
*
*/
#ifndef MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_MEMCPY
#define MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_MEMCPY __builtin_memcpy
#endif
#ifndef MY_COMPANY_MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_STRLEN
#define MY_COMPANY_MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_STRLEN __builtin_strlen
#endif
#ifndef MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_STRCMP
#define MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_STRCMP __builtin_strcmp
#endif
#ifndef MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_MEMCMP
#define MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_MEMCMP __builtin_memcmp
#endif
#ifndef MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_MEMMOVE
#define MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_MEMMOVE __builtin_memmove
#endif
#ifndef MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_STRCHR
#define MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_STRCHR __builtin_strchr
#endif
#ifndef MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_MEMCHR
#define MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_MEMCHR __builtin_memchr
#endif
#ifndef MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_STRSTR
#define MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_STRSTR __builtin_strstr
#endif
#define MY_COMPANY_MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_NONNULL __attribute__((nonnull))
#define MY_COMPANY_MY_COMPANY_MY_COMPANY_MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_PRINTF_FUNC __attribute__((format(printf, 1, 2)))
#define MY_COMPANY_MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_WARN_UNUSED_RESULT __attribute__((warn_unused_result))
#define MY_COMPANY_MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_NOTHROW __attribute__((nothrow))
#define MY_COMPANY_MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_MALLOC __attribute__((malloc))
#define MY_COMPANY_MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_CONST __attribute__((const))
#define MY_COMPANY_MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_PURE __attribute__((pure))
#else /* ifdef GNUC */
#ifndef MY_COMPANY_MY_COMPANY_MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_PRINTF
#define MY_COMPANY_MY_COMPANY_MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_PRINTF printf
#endif
#ifndef MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_SPRINTF
#define MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_SPRINTF sprintf
#endif
#ifdef MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_SNPRINTF
#define MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_SNPRINTF snprintf
#endif
#ifndef MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_VSNPRINTF
#define MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_VSNPRINTF vsnprintf
#endif
#ifndef MY_COMPANY_MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_FPRINTF
#define MY_COMPANY_MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_FPRINTF fprintf
#endif
#ifndef MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_MEMCPY
#define MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_MEMCPY memcpy
#endif
#ifndef MY_COMPANY_MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_STRLEN
#define MY_COMPANY_MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_STRLEN strlen
#endif
#ifndef MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_STRCMP
#define MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_STRCMP strcmp
#endif
#ifndef MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_MEMCMP
#define MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_MEMCMP memcmp
#endif
#ifndef MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_MEMMOVE
#define MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_MEMMOVE memmove
#endif
#ifndef MY_COMPANY_MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_FPUTS
#define MY_COMPANY_MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_FPUTS fputs
#endif
#ifndef MY_COMPANY_MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_PUTCHAR
#define MY_COMPANY_MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_PUTCHAR putchar
#endif
#ifndef MY_COMPANY_MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_FPUTC
#define MY_COMPANY_MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_FPUTC fputc
#endif
#ifndef MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_STRPBRK
#define MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_STRPBRK strpbrk
#endif
#ifndef MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_STRCHR
#define MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_STRCHR strchr
#endif
#ifndef MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_MEMCHR
#define MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_MEMCHR memchr
#endif
#ifndef MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_STRSTR
#define MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_STRSTR strstr
#endif
#ifndef MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_ISSPACE
#define MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_ISSPACE isspace
#endif
#ifndef MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_ISALPHA
#define MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_ISALPHA isalpha
#endif
#ifndef MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_ISALNUM
#define MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_ISALNUM isalnum
#endif
#ifndef MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_ISDIGIT
#define MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_ISDIGIT isdigit
#endif
#ifndef MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_ISPRINT
#define MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_ISPRINT isprint
#endif
#ifndef MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_ISUPPER
#define MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_ISUPPER isupper
#endif
#ifndef MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_ISLOWER
#define MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_ISLOWER islower
#endif
#if _WIN32
#include <sal.h>
/* All the functions that use nonnull, also work with declspec. */
#define MY_COMPANY_MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_NONNULL __declspec(noalias)
#define MY_COMPANY_MY_COMPANY_MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_PRINTF _Printf_format_string_impl_
#define MY_COMPANY_MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_WARN_UNUSED_RESULT /* not defined for Windows at present. */
#define MY_COMPANY_MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_NOTHROW /* not defined for Windows at present. */
#define MY_COMPANY_MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_MALLOC /* not defined for Windows at present. */
#define MY_COMPANY_MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_CONST /* not defined for Windows at present. */
#define MY_COMPANY_MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_PURE /* not defined for Windows at present. */
#else /* if WIN32 */
/* All the functions that use nonnull, also work with declspec. */
#define MY_COMPANY_MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_NONNULL /* not defined */
#define MY_COMPANY_MY_COMPANY_MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_PRINTF /* not defined */
#define MY_COMPANY_MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_WARN_UNUSED_RESULT /* not defined */
#define MY_COMPANY_MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_NOTHROW /* not defined */
#define MY_COMPANY_MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_MALLOC /* not defined */
#define MY_COMPANY_MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_CONST /* not defined */
#define MY_COMPANY_MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_PURE /* not defined */
#endif /* if WIN32 */
#endif /* if GNUC */
/* For the capacities of MY_COMPANY_FrozenDict and MY_COMPANY_FrozenSet. */
#ifndef MY_COMPANY_FOUNDATIONAL_LIB_FROZEN_INITIALIZATION_SIZE_MULTIPLIER
#define MY_COMPANY_FOUNDATIONAL_LIB_FROZEN_INITIALIZATION_SIZE_MULTIPLIER 3
#endif
/* If allocating new strings (an array), how many should be allocated? */
#ifndef MY_COMPANY_FOUNDATIONAL_LIB_INITIAL_STRING_ARRAY_ALLOC_COUNT
#define MY_COMPANY_FOUNDATIONAL_LIB_INITIAL_STRING_ARRAY_ALLOC_COUNT 0
#endif
/* If allocating new strings (an array), how much memory should be allocated at first? */
#ifndef MY_COMPANY_FOUNDATIONAL_LIB_INITIAL_STRING_ARRAY_ALLOC_SIZE
#define MY_COMPANY_FOUNDATIONAL_LIB_INITIAL_STRING_ARRAY_ALLOC_SIZE (sizeof(char *) * 1)
#endif
#if defined(__GNUC__) || defined(__clang__)
#define MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_LIKELY(x) __builtin_expect(!!(x), 1)
#define MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_UNLIKELY(x) __builtin_expect(!!(x), 0)
#else
#define MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_LIKELY(x) (x)
#define MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_UNLIKELY(x) (x)
#endif
#ifndef MY_COMPANY_FOUNDATIONAL_LIB_ASSERT_ARGUMENT_CHECKING
#define MY_COMPANY_FOUNDATIONAL_LIB_ASSERT_ARGUMENT_CHECKING 0 /* Argument NULL checks. Disabled by default. */
#endif
#ifndef MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_ASSERT_ARGUMENT_IF_ENABLED
#if MY_COMPANY_FOUNDATIONAL_LIB_ASSERT_ARGUMENT_CHECKING
#define MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_ASSERT_ARGUMENT_IF_ENABLED(x) assert(x)
#else
#define MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_ASSERT_ARGUMENT_IF_ENABLED(x) /* */
#endif
#endif /* assert checking. */
#ifdef __GNUC__
/**
* @brief
* Safely multiply 2 numbers to avoid unsigned integer overflows and security
* and stability issues. We never, NEVER want any of those things. Ever.
*/
MY_COMPANY_MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_NOTHROW
MY_COMPANY_MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_PURE
static inline size_t FOUNDATIONAL_LIB_safe_mul(size_t a, size_t b)
{
size_t result;
if (MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_UNLIKELY(__builtin_mul_overflow(a, b, &result)))
{
/* 0 on error (overflow). */
return 0;
}
return result;
}
/** @brief Safely multiply 2 numbers to avoid unsigned integer overflows and security and stability issues. We never, NEVER want any of those things. Ever. */
MY_COMPANY_MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_NOTHROW
static inline size_t FOUNDATIONAL_LIB_safe_mul_ptr(size_t a, size_t b, size_t *ptr)
{
if (MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_UNLIKELY(__builtin_mul_overflow(a, b, ptr)))
{
/* 0 on error (overflow). */
return 0;
}
return 1;
}
/** @brief Safely add 2 numbers to avoid unsigned integer overflows and security and stability issues. We never, NEVER want any of those things. Ever. */
MY_COMPANY_MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_NOTHROW
MY_COMPANY_MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_CONST
static inline size_t FOUNDATIONAL_LIB_safe_add_2(size_t a, size_t b)
{
size_t result;
if (MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_UNLIKELY(__builtin_add_overflow(a, b, &result)))
{
/* 0 on error (overflow). */
return 0;
}
return result;
}
/** @brief Safely add 3 numbers to avoid unsigned integer overflows and security and stability issues. We never, NEVER want any of those things. Ever. */
MY_COMPANY_MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_NOTHROW
MY_COMPANY_MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_CONST
static inline size_t FOUNDATIONAL_LIB_safe_add_3(size_t a, size_t b, size_t c)
{
size_t result;
if (MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_UNLIKELY(__builtin_add_overflow(a, b, &result)) || MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_UNLIKELY(__builtin_add_overflow(result, c, &result)))
{
/* 0 on error (overflow). */
return 0;
}
return result;
}
MY_COMPANY_MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_NOTHROW
/** @brief Safely add 3 numbers to avoid unsigned integer overflows and security and stability issues. We never, NEVER want any of those things. Ever. */
static inline int FOUNDATIONAL_LIB_safe_add_3_ptr(size_t a, size_t b, size_t c, size_t *out)
{
if (MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_UNLIKELY(__builtin_add_overflow(a, b, out)) || MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_UNLIKELY(__builtin_add_overflow(*out, c, out)))
{
/* 0 on error (overflow). */
return 0;
}
return 1;
}
MY_COMPANY_MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_NOTHROW
/** @brief Safely add 3 numbers to avoid unsigned integer overflows and security and stability issues. We never, NEVER want any of those things. Ever. */
static inline int FOUNDATIONAL_LIB_safe_add_2_ptr(size_t a, size_t b, size_t *out)
{
if (MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_UNLIKELY(__builtin_add_overflow(a, b, out)))
{
/* 0 on error (overflow). */
return 0;
}
return 1;
}
#else /* GNUC */
/**
* @brief
* Safely multiply 2 numbers to avoid unsigned integer overflows and security
* and stability issues. We never, NEVER want any of those things. Ever.
*/
MY_COMPANY_MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_NOTHROW
MY_COMPANY_MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_PURE
static inline size_t FOUNDATIONAL_LIB_safe_mul(size_t a, size_t b)
{
size_t result;
if (b != 0 && a > SIZE_MAX / b)
{
/* Overflow */
return 0;
}
result = a * b;
return result;
}
/** @brief Safely multiply 2 numbers to avoid unsigned integer overflows and security and stability issues. We never, NEVER want any of those things. Ever. */
MY_COMPANY_MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_NOTHROW
static inline size_t FOUNDATIONAL_LIB_safe_mul_ptr(size_t a, size_t b, size_t *ptr)
{
if (b != 0 && a > SIZE_MAX / b)
{
/* Overflow */
return 0;
}
*ptr = a * b;
return 1;
}
/** @brief Safely add 2 numbers to avoid unsigned integer overflows and security and stability issues. We never, NEVER want any of those things. Ever. */
MY_COMPANY_MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_NOTHROW
MY_COMPANY_MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_CONST
static inline size_t FOUNDATIONAL_LIB_safe_add_2(size_t a, size_t b)
{
size_t result;
if (a > SIZE_MAX - b || a + b > SIZE_MAX - c)
{
/* Overflow */
return 0;
}
result = a + b;
return result;
}
/** @brief Safely add 3 numbers to avoid unsigned integer overflows and security and stability issues. We never, NEVER want any of those things. Ever. */
MY_COMPANY_MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_NOTHROW
MY_COMPANY_MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_CONST
static inline size_t FOUNDATIONAL_LIB_safe_add_3(size_t a, size_t b, size_t c)
{
size_t result;
if (a > SIZE_MAX - b || b > SIZE_MAX - c)
{
/* Overflow */
return 0;
}
result = a + b + c;
return result;
}
/** @brief Safely add 2 numbers to avoid unsigned integer overflows and security and stability issues. We never, NEVER want any of those things. Ever. */
MY_COMPANY_MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_NOTHROW
static inline size_t FOUNDATIONAL_LIB_safe_add_2_ptr(size_t a, size_t b, size_t *ptr)
{
if (a > SIZE_MAX - b)
{
/* Overflow */
return 0;
}
*ptr = a + b;
return 1;
}
/** @brief Safely add 3 numbers to avoid unsigned integer overflows and security and stability issues. We never, NEVER want any of those things. Ever. */
MY_COMPANY_MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_NOTHROW
static inline int FOUNDATIONAL_LIB_safe_add_3_ptr(size_t a, size_t b, size_t c, size_t *ptr)
{
if (a > SIZE_MAX - b || b > SIZE_MAX - c)
{
/* Overflow */
return 0;
}
*ptr = a + b + c;
return 1;
}
#endif /* GNUC */
#define MY_COMPANY_FOUNDATIONAL_LIB_safe_increment(variable, label_if_fails) \
if (MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_UNLIKELY(FOUNDATIONAL_LIB_safe_add_2_ptr((variable), 1, &(variable)) == 0)) \
goto label_if_fails;
// Adjust as needed. On embedded platforms or low memory systems, you might want to change the algorithm to be somewhat lower than 1.5x
// new len calculations need to be checked, before and after this, for overflow.
#ifndef MY_COMPANY_FOUNDATIONAL_LIB_LOW_MEMORY_USAGE
#define MY_COMPANY_FOUNDATIONAL_LIB_LOW_MEMORY_USAGE 12
#endif
#ifndef MY_COMPANY_FOUNDATIONAL_LIB_ALLOCATOR_DIV_AMOUNT
#define MY_COMPANY_FOUNDATIONAL_LIB_ALLOCATOR_DIV_AMOUNT 2
#endif
// Takes an argument and makes it at least 1 bigger.
#ifdef __GNUC__ // Check if GCC compiler is being used
MY_COMPANY_MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_NOTHROW
MY_COMPANY_MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_CONST
static inline size_t FOUNDATIONAL_LIB_REALLOC_REALLOCATION_ALGORITHM(size_t old_size_to_add_at_least_one_to)
{
size_t addition;
// In 49 / 50 for example, Would equal 0. We need at least 1 of an increase.
// Default div_amount is 2 or in low memory mode 12.
// On embedded you could use low amounts.
const size_t div_amount = old_size_to_add_at_least_one_to < MY_COMPANY_FOUNDATIONAL_LIB_ALLOCATOR_DIV_AMOUNT ? 1 /* divide by 1 and so double it. */
: MY_COMPANY_FOUNDATIONAL_LIB_ALLOCATOR_DIV_AMOUNT
/*
* not a really small number (under div amount),
* and so use the div amount
*/
;
if (__builtin_add_overflow(old_size_to_add_at_least_one_to, old_size_to_add_at_least_one_to / div_amount, &addition))
{
/* 0 on error. */
return 0;
}
return addition;
}
#else /* GNUC */
// Fallback implementation for other compilers
MY_COMPANY_MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_NOTHROW
MY_COMPANY_MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_PURE
static inline size_t FOUNDATIONAL_LIB_REALLOC_REALLOCATION_ALGORITHM(size_t siz)
{
// In 49 / 50 for example, Would equal 0. We need at least 1 of an increase.
// Default div_amount is 2 or in low memory mode 12.
// On embedded you could use low amounts.
const size_t div_amount = old_size_to_add_at_least_one_to < MY_COMPANY_FOUNDATIONAL_LIB_ALLOCATOR_DIV_AMOUNT ? 1 /* divide by 1 and so double it. */
: MY_COMPANY_FOUNDATIONAL_LIB_ALLOCATOR_DIV_AMOUNT
/*
* not a really small number (under div amount),
* and so use the div amount
*/
;
// Check for potential overflow before performing the addition
if (siz > SIZE_MAX / 2 || siz > (SIZE_MAX - siz) / 2)
{
/* 0 on error (overflow). */
return 0;
}
// Calculate the new size after 1.5x reallocation
const size_t addition = siz + (siz / div_amount);
// Return the result of the addition
return addition;
}
#endif
/* For MY_COMPANY_copy_file() */
#ifndef MY_COMPANY_FOUNDATIONAL_LIB_COPY_SIZE_AMOUNT
#define MY_COMPANY_FOUNDATIONAL_LIB_COPY_SIZE_AMOUNT 4096
#endif
#if MY_COMPANY_FOUNDATIONAL_LIB_UNSAFE_FUNCTIONS_ENABLED
/* For MY_COMPANY_backticks() */
#ifndef MY_COMPANY_MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_POPEN_INITIAL_ALLOC_SIZE
#define MY_COMPANY_MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_POPEN_INITIAL_ALLOC_SIZE 4096
#endif
#endif
/* Choose which functions you want. */
#ifndef MY_COMPANY_FOUNDATIONAL_LIB_ATOI
#define MY_COMPANY_FOUNDATIONAL_LIB_ATOI atoi
#endif
/* File IO */
#if MY_COMPANY_FOUNDATIONAL_LIB_UNSAFE_FUNCTIONS_ENABLED
#ifdef _WIN32
#define MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_POPEN _popen
#define MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_PCLOSE _pclose
#else
#define MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_POPEN popen
#define MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_PCLOSE pclose
#endif
#endif
#ifndef MY_COMPANY_FOUNDATIONAL_LIB_FERROR
#define MY_COMPANY_FOUNDATIONAL_LIB_FERROR ferror
#endif
#ifdef _WIN32
#ifndef MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_FSEEKO
#define MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_FSEEKO _fseeki64
#endif
#ifndef MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_FTELLO
#define MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_FTELLO _ftelli64
#endif
#else
#ifndef MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_FSEEKO
#define MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_FSEEKO fseeko
#endif
#ifndef MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_FTELLO
#define MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_FTELLO ftello
#endif
#endif
#ifndef MY_COMPANY_FOUNDATIONAL_LIB_FREAD
#define MY_COMPANY_FOUNDATIONAL_LIB_FREAD fread
#endif
#ifndef MY_COMPANY_FOUNDATIONAL_LIB_FWRITE
#define MY_COMPANY_FOUNDATIONAL_LIB_FWRITE fwrite
#endif
#ifndef MY_COMPANY_FOUNDATIONAL_LIB_FOPEN
#define MY_COMPANY_FOUNDATIONAL_LIB_FOPEN fopen
#endif
#ifndef MY_COMPANY_FOUNDATIONAL_LIB_FCLOSE
#define MY_COMPANY_FOUNDATIONAL_LIB_FCLOSE fclose
#endif
/* Memory allocation macros that you can customize */
#ifndef MY_COMPANY_FOUNDATIONAL_LIB_MEMORY_ALLOCATOR_MALLOC
#define MY_COMPANY_FOUNDATIONAL_LIB_MEMORY_ALLOCATOR_MALLOC malloc
#endif
#ifndef MY_COMPANY_FOUNDATIONAL_LIB_MEMORY_ALLOCATOR_REALLOC
#define MY_COMPANY_FOUNDATIONAL_LIB_MEMORY_ALLOCATOR_REALLOC realloc
#endif
#ifndef MY_COMPANY_FOUNDATIONAL_LIB_MEMORY_ALLOCATOR_CALLOC
#define MY_COMPANY_FOUNDATIONAL_LIB_MEMORY_ALLOCATOR_CALLOC calloc
#endif
#ifndef MY_COMPANY_FOUNDATIONAL_LIB_MEMORY_ALLOCATOR_FREE
#define MY_COMPANY_FOUNDATIONAL_LIB_MEMORY_ALLOCATOR_FREE free
#endif
#ifndef MY_COMPANY_FOUNDATIONAL_LIB_MEMORY_ALLOCATOR_STRDUP
#define MY_COMPANY_FOUNDATIONAL_LIB_MEMORY_ALLOCATOR_STRDUP strdup
#endif
/**
* @brief Networking functions, disabled by default.
*/
#ifndef MY_COMPANY_FOUNDATIONAL_LIB_NETWORK_FUNCTIONS_ENABLED
#define MY_COMPANY_FOUNDATIONAL_LIB_NETWORK_FUNCTIONS_ENABLED 0
#endif
#if MY_COMPANY_FOUNDATIONAL_LIB_NETWORK_FUNCTIONS_ENABLED
#define MY_COMPANY_FOUNDATIONAL_LIB_INITIAL_NETWORK_DOWNLOAD_BUFFER_SIZE 8192
#endif
#ifndef MY_COMPANY_FOUNDATIONAL_LIB_HASH_INITIAL_CAPACITY
/**
* @brief Initial capacity for hash tables (dict, frozendict, set, frozenset).
*
* This macro defines the initial capacity for hash tables used in `dict`,
* `frozendict`, `set`, and `frozenset` in the foundational library.
* It sets the default size when these hash-based data structures are created.
*/
#define MY_COMPANY_FOUNDATIONAL_LIB_HASH_INITIAL_CAPACITY 16
#endif
#ifndef MY_COMPANY_FOUNDATIONAL_LIB_HASH_LOAD_FACTOR_THRESHOLD
/**
* @brief Load factor threshold for hash tables in the foundational library.
*
* This macro defines the load factor threshold for hash tables as
* `MY_COMPANY_FOUNDATIONAL_LIB_HASH_LOAD_FACTOR_THRESHOLD` if not already defined.
* It represents the maximum load factor before a hash table triggers
* resizing to maintain performance and prevent excessive collisions.
*/
#define MY_COMPANY_FOUNDATIONAL_LIB_HASH_LOAD_FACTOR_THRESHOLD 0.75
#endif
#ifndef MY_COMPANY_FOUNDATIONAL_LIB_FUNC
/*
* One thing you can do, if you want "strict mode" on, you can define this to be MY_COMPANY_MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_WARN_UNUSED_RESULT and have -Werror on.
* That way, if any errors are not accounted for, instead of dealing with error handlers, the code just won't compile.
*/
#define MY_COMPANY_FOUNDATIONAL_LIB_FUNC static inline
#endif
#ifndef MY_COMPANY_FOUNDATIONAL_LIB_THREAD_FUNCTIONS_ENABLED
/**
* @brief Enable or disable foundational library thread functions.
*
* If not already defined, this macro enables foundational library
* thread functions by default. Users can toggle it to control the
* behavior of the library's thread-related functions.
*/
#define MY_COMPANY_FOUNDATIONAL_LIB_THREAD_FUNCTIONS_ENABLED 1
#endif
/**
* @brief Global variable to control aggressive die behavior.
*
* When set to true, the functions in the foundational library kill
* the program on error; when set to false, they fail silently. This
* variable, aggressive_die, is the only global declared, utilizing
* 1 byte of overhead. It provides a centralized control over the
* error-handling behavior of the library functions.
*
* Default die behavior is true, which is suitable for scenarios
* like scripting.
*/
MY_COMPANY_FOUNDATIONAL_LIB_AGGRESSIVE_DIE_TYPE FOUNDATIONAL_LIB_aggressive_die = 1;
/**
* @brief Macro to set the aggressive die mode.
*
* This macro sets the aggressive die mode based on the specified
* parameter (mode). It allows dynamic control over the aggressive
* die behavior.
*/
#define MY_COMPANY_FOUNDATIONAL_LIB_set_aggressive_die(mode) \
{ \
FOUNDATIONAL_LIB_aggressive_die = (mode); \
}
/**
* @brief Macro to get the current aggressive die mode.
*
* This macro retrieves the current aggressive die mode,
* providing insight into the error-handling behavior.
*/
#define MY_COMPANY_FOUNDATIONAL_LIB_get_aggressive_die() FOUNDATIONAL_LIB_aggressive_die
#ifndef MY_COMPANY_FOUNDATIONAL_LIB_die_aggressively_if_enabled
/**
* @brief Macro to die aggressively if enabled.
*
* This macro, when used, checks if aggressive die is enabled.
* If enabled, it prints an error message including the function
* name and the error description, then terminates the program
* with EXIT_FAILURE.
*/
#define MY_COMPANY_FOUNDATIONAL_LIB_die_aggressively_if_enabled() \
if (MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_UNLIKELY(FOUNDATIONAL_LIB_aggressive_die)) \
{ \
MY_COMPANY_MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_FPRINTF(stderr, "Error: %s: %s.\n", __func__, strerror(errno)); \
exit(EXIT_FAILURE); /* Use default exit, only place in library this is used, adjust as needed. */ \
}
#endif
/**
* @brief Frees a dynamic array and its elements up to one level deep.
*
* This function releases the memory allocated for the array and its elements,
* assuming a two-dimensional structure with one level of indirection.
*
* @param array The pointer to the dynamic array.
* @param len The length of the array.
*/
MY_COMPANY_MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_NONNULL
MY_COMPANY_MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_NOTHROW
static inline void free_array(void **array, size_t len)
{
while (len--)
{
MY_COMPANY_FOUNDATIONAL_LIB_MEMORY_ALLOCATOR_FREE(array[len]);
}
MY_COMPANY_FOUNDATIONAL_LIB_MEMORY_ALLOCATOR_FREE(array);
}
/**
* @brief Frees a dynamic string array and its elements up to one level deep.
*
* This function releases the memory allocated for the string array and its elements,
* assuming a two-dimensional structure with one level of indirection.
*
* @param array The pointer to the array of strings
* @param len The length of the array.
*/
MY_COMPANY_MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_NONNULL
MY_COMPANY_MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_NOTHROW
static inline void free_string_array(char **array, size_t len)
{
while (len--)
{
MY_COMPANY_FOUNDATIONAL_LIB_MEMORY_ALLOCATOR_FREE(array[len]);
}
MY_COMPANY_FOUNDATIONAL_LIB_MEMORY_ALLOCATOR_FREE(array);
}
/**
* @brief Converts an integer to its string representation.
*
* This function takes an integer as input and returns a dynamically allocated
* character array containing its string representation.
*
* @param number The integer to be converted.
* @return A pointer to the dynamically allocated string representation.
*/
MY_COMPANY_MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_WARN_UNUSED_RESULT
MY_COMPANY_MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_NONNULL
MY_COMPANY_MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_NOTHROW
MY_COMPANY_MY_COMPANY_MY_COMPANY_FOUNDATIONAL_LIB_MALLOC
MY_COMPANY_FOUNDATIONAL_LIB_FUNC char *MY_COMPANY_int_to_string(long long int number)
{
// Allocate a fixed-size buffer for the string
char buffer[MY_COMPANY_FOUNDATIONAL_LIB_SIZE_STRING_OF_NUMBER_SIZE_PLUS_ZERO_TERMINATOR + 1 /* sign */];
char *p;
long long a;
char *b;
char temp;
unsigned long long u;
p = buffer;
if (number < 0)
{
*p++ = '-';
number = 0 - number;
}
u = (long long)number;
b = p;
do
{
a = u % 10;
u /= 10;
*p++ = a + '0';
} while (u > 0);
*p-- = '\0';
do
{
temp = *p;
*p = *b;
*b = temp;
--p;
++b;
} while (b < p);
// Duplicate the buffer using strdup
char *return_value = strdup(buffer);